/* 404 page (owner: pages, with assets/js/p-404.js).
   Full-viewport hero on the Fault glow (ink-deep): a centered "broken handoff". Your click sends a
   token toward the page, the wire is cut, the token falls, and a new route takes it home.
   The static markup is the final frame (no JS, reduced motion): bypass drawn, Home green,
   the chip reading "Route not found". */

.nf {
  position: relative; overflow: hidden; display: flex; align-items: center;
  min-height: 100vh; min-height: 100svh;
  padding: var(--hero-top) var(--gutter) clamp(64px, 8vw, 96px);
  background: var(--ink-deep); color: var(--cream); text-align: center;
}
.nf__wrap { position: relative; z-index: 1; width: 100%; display: flex; flex-direction: column; align-items: center; }
.nf__title { font-size: clamp(44px, 5.6vw, 84px); font-weight: 500; line-height: 1; letter-spacing: -.048em; color: var(--cream); }
.nf__title .serif { letter-spacing: -.02em; }
.nf__lede { max-width: 34em; margin-top: 24px; font-size: clamp(17px, 1.45vw, 20px); line-height: 1.6; color: var(--muted-light); }
.nf__actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 20px 36px; margin-top: 36px; }
.nf__links { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 12px 28px; }
.nf__links .link-soft { position: relative; }
.nf__links .link-soft::after { content: ''; position: absolute; inset: -12px -10px; }
.js .nf__lede { animation: fadeUp 1s var(--ease) .5s both; }
.js .nf__actions { animation: fadeUp .9s var(--ease) .65s both; }

/* ---------- The broken handoff (viewBox 520 x 180; overlays placed in the same units) ---------- */
.broken {
  --n: max(30px, calc(100cqw * 44 / 520));
  position: relative; isolation: isolate; container-type: inline-size;
  width: 100%; max-width: 600px; min-width: min(320px, 100%); aspect-ratio: 520 / 180;
  margin: 36px auto 44px;
}
.broken__svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }

/* Fault glow, centered on the cut; it flashes when the token falls */
.broken__glow, .broken__flash {
  position: absolute; z-index: -1; left: 50%; top: calc(60 / 180 * 100%); width: 680px; height: 680px; max-width: 160vw; max-height: 160vw; translate: -50% -50%;
  border-radius: 50%; pointer-events: none;
}
.broken__glow { background: radial-gradient(closest-side, rgba(239, 90, 76, .22), rgba(239, 90, 76, .14) 28%, rgba(239, 90, 76, .06) 56%, rgba(239, 90, 76, .018) 80%, rgba(239, 90, 76, 0)); }
.broken__flash { background: radial-gradient(closest-side, rgba(239, 90, 76, .25), rgba(239, 90, 76, .15) 28%, rgba(239, 90, 76, .06) 56%, rgba(239, 90, 76, .018) 80%, rgba(239, 90, 76, 0)); opacity: 0; }

/* Wires */
.broken__ghost { opacity: .45; }
.broken__on, .broken__by-on { stroke-dasharray: 1; stroke-dashoffset: 0; }
.broken__on { opacity: 0; }
.broken__end { fill: var(--red-bright); opacity: .8; }

/* Nodes (HTML .uv-agent over the SVG) */
.broken__n {
  position: absolute; left: calc(var(--x) / 520 * 100%); top: calc(var(--y) / 180 * 100%);
  width: var(--n); height: var(--n); margin: calc(var(--n) / -2) 0 0 calc(var(--n) / -2);
}
span.broken__node { --uv-size: var(--n); }
span.broken__node--click {
  --a-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linejoin='round' stroke-linecap='round'%3E%3Cpath d='M6 3.5l12.5 7.2-5.6 1.5-3 5.3z'/%3E%3Cpath d='M12.9 12.2l3.6 5.6'/%3E%3C/svg%3E");
  border-color: rgba(239, 90, 76, .6); box-shadow: 0 0 26px -4px rgba(215, 55, 43, .45);
}
span.broken__node--click.is-ping::after {
  content: ''; position: absolute; inset: -1px; border-radius: inherit; border: 1.5px solid var(--red-bright);
  animation: ping 1s var(--ease-out) both; pointer-events: none;
}
span.broken__node--page {
  --a-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linejoin='round' stroke-linecap='round'%3E%3Cpath d='M7 3h7l4 4v14H7z'/%3E%3Cpath d='M14 3v4h4'/%3E%3C/svg%3E");
  border-style: dashed; border-color: rgba(245, 239, 230, .34); background: transparent;
}
span.broken__node--home {
  --a-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linejoin='round' stroke-linecap='round'%3E%3Cpath d='M4 11.2L12 4l8 7.2'/%3E%3Cpath d='M6.5 9.5V20h11V9.5'/%3E%3Cpath d='M10.2 20v-5h3.6v5'/%3E%3C/svg%3E");
}
span.broken__node--home[data-state="done"] { border-color: var(--green); background: #14231a; box-shadow: 0 0 30px -6px rgba(120, 220, 150, .45); }
span.broken__node--home[data-state="done"]::before { background: #9fe8b5; }
span.broken__node--home[data-state="done"]::after { box-shadow: 0 0 0 2px var(--ink-deep); }

/* Labels and chips */
.broken__label {
  position: absolute; white-space: nowrap;
  font: 500 10.5px/1.2 'Geist Mono', ui-monospace, monospace; letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
}
.broken__label--click { left: calc(22 / 520 * 100%); top: calc(94 / 180 * 100%); }
.broken__label--page { right: calc(22 / 520 * 100%); top: calc(94 / 180 * 100%); }
.broken__homeinfo { position: absolute; left: calc(298 / 520 * 100%); top: calc(146 / 180 * 100%); }
.broken__homeinfo .broken__label { position: absolute; left: 0; top: 0; translate: 0 -50%; color: var(--muted-light); }
/* the chip hangs just under the label, so the label stays on the node's center line */
.broken__homeinfo .broken__back { position: absolute; left: 0; top: 13px; }
.broken__chip {
  position: absolute; left: 50%; top: calc(20 / 180 * 100%); translate: -50% -50%;
  display: inline-grid; justify-items: center;
  border-color: var(--red-bright); background: rgba(215, 55, 43, .14); color: var(--red-bright);
}
.broken__chip > span { grid-area: 1 / 1; transition: opacity .3s var(--ease); }
.broken__chip-a { opacity: 0; }

/* Tokens: wrappers travel (aomMotion.follow), the inner token falls */
.broken__tk { position: absolute; left: 0; top: 0; z-index: 2; width: 12px; height: 12px; pointer-events: none; will-change: transform; }
.broken__tk .uv-token { display: block; opacity: 0; }

/* Armed by p-404.js (it adds .is-live): before the fault, the chip is neutral and reads "Checking" */
.broken.is-live:not(.is-fault) .broken__chip { border-color: rgba(245, 239, 230, .2); background: transparent; color: var(--muted); }
.broken.is-live:not(.is-fault) .broken__chip-a { opacity: 1; }
.broken.is-live:not(.is-fault) .broken__chip-b { opacity: 0; }
.broken.is-live .broken__end { transition: opacity .3s var(--ease); }
.broken.is-live.is-fault .broken__end { opacity: 1; }

/* ---------- Entrance: glow fades, wires and nodes draw in ---------- */
@keyframes nfFade { from { opacity: 0; } }
@keyframes nfIn { from { opacity: 0; transform: translateY(8px) scale(.94); } }
@keyframes nfDraw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
.js .broken__glow { animation: nfFade .6s var(--ease) both; }
.js .broken__base { stroke-dasharray: 1; animation: nfDraw .8s var(--ease-io) .1s both; }
.js .broken__ghost, .js .broken__end { animation: nfFade .6s var(--ease) .55s both; }
.js .broken__n, .js .broken__label--click, .js .broken__label--page, .js .broken__homeinfo, .js .broken__chip {
  animation: nfIn .7s var(--ease-expo) calc(.12s + var(--i, 0) * .08s) both;
}
.js .broken__chip { --i: 3; }
/* until p-404.js arms the loop (.is-live) or settles on the final frame (.is-static), the bypass waits */
.js .broken:not(.is-live):not(.is-static) .broken__by-on { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .js .broken:not(.is-live) .broken__by-on { opacity: .85; } }

/* ---------- Phones: SVG full width, actions stacked at 48px ---------- */
@media (max-width: 599px) {
  .broken { margin: 28px auto 48px; }
  .broken__label { font-size: 10px; letter-spacing: .12em; }
  .broken__homeinfo .broken__back { top: 11px; padding: 4px 8px; font-size: 10px; }
  .broken__chip { padding: 4px 9px; font-size: 10px; }
  .nf__lede { margin-top: 20px; }
  .nf__actions { flex-direction: column; align-items: stretch; width: 100%; max-width: 420px; gap: 12px; margin-top: 32px; }
  .nf__actions .cta-spin, .nf__actions .cta-spin__inner { width: 100%; justify-content: center; }
  .nf__actions .cta-spin__inner { min-height: 48px; }
  .nf__links { flex-direction: column; align-items: stretch; gap: 8px; }
  .nf__links .link-soft {
    justify-content: center; min-height: 48px; padding: 0 20px; border: 1px solid var(--line-d2); border-radius: var(--r-pill);
    font-size: 15px; transition: border-color var(--dur-1), background var(--dur-1);
  }
  .nf__links .link-soft::after { content: none; }
  .nf__links .link-soft:active { border-color: rgba(239, 90, 76, .55); background: rgba(215, 55, 43, .08); }
}

/* ---------- Reduced motion: the final frame, still ---------- */
@media (prefers-reduced-motion: reduce) {
  .broken__flash { display: none; }
  .broken__tk { display: none; }
}
