/* 404.css — the not-found page as a failed identity check, SIMPLIFIED
   (Sofia, 2026-08-14 r2). One full-viewport ink stage: the giant 4·0·4
   lockup where the zero is the capture HALO — the blue gradient ring
   turns once for 1.5s, then the verdict lands and the ring goes red
   (.is-settled via /js/behaviors/error-404.js). Title, sub, and the two
   standard buttons carry the exit. Reduced
   motion and no-JS land straight on the red verdict state. */

.p-notfound {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 100svh;
  overflow: hidden;
  background: var(--color-rich-black, var(--color-black));
  color: var(--color-white);
}

/* ---------- ambient: aurora blobs + faint dot grid ---------- */
.p-notfound .nf-aurora {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: radial-gradient(
    circle at 1px 1px,
    color-mix(in oklab, var(--color-white) 7%, transparent) 1px,
    transparent 0
  );
  background-size: 22px 22px;
}
.p-notfound .nf-blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  opacity: 0.55;
}
/* each blob stacks a blue layer and a red twin; the verdict crossfades
   the pair, washing the whole page in red subtones (Sofia, r3) */
.p-notfound .nf-blob::before,
.p-notfound .nf-blob::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  transition: opacity 1.8s cubic-bezier(0.65, 0, 0.35, 1);
}
.p-notfound .nf-blob::before {
  background: radial-gradient(closest-side, color-mix(in oklab, var(--color-blue-500) 42%, transparent), transparent 70%);
}
.p-notfound .nf-blob::after {
  background: radial-gradient(closest-side, color-mix(in oklab, var(--color-red-brand) 46%, transparent), transparent 70%);
  opacity: 0;
}
.p-notfound.is-settled .nf-blob::before { opacity: 0; }
.p-notfound.is-settled .nf-blob::after { opacity: 1; }
.p-notfound .nf-blob--1 {
  width: 44vw;
  height: 44vw;
  left: -12vw;
  top: -14vw;
}
.p-notfound .nf-blob--2 {
  width: 38vw;
  height: 38vw;
  right: -10vw;
  bottom: -12vw;
}

/* ---------- stage ---------- */
.p-notfound .nf-stage {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex: 1 0 auto;
  width: 100%;
  max-width: var(--container-large);
  margin-inline: auto;
  padding: 150px 20px 64px;
  text-align: center;
}

/* ---------- the 4 · halo · 4 lockup ---------- */
.p-notfound .nf-lockup {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(14px, 2.6vw, 36px);
  line-height: 1;
  user-select: none;
}
.p-notfound .nf-digit {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(120px, 23vw, 280px);
  letter-spacing: var(--track-tighter);
  color: var(--color-white);
}

/* the zero: the capture halo */
.p-notfound .nf-orb {
  position: relative;
  width: clamp(110px, 19vw, 236px);
  aspect-ratio: 1;
}
/* the ring IS the halo (r3: the grey disc + outer circle retired) —
   an open arc makes the turn unmistakable: two full rotations over 2s */
.p-notfound .nf-orb__ring {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  will-change: transform;
  /* the circle never opens — rotating the element sweeps only the
     GRADIENT around it. One slow, continuous turn, settling softly. */
  animation: nf-ring-turn 1.5s cubic-bezier(0.45, 0, 0.15, 1) 1 both;
}
@keyframes nf-ring-turn {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
/* verdict: the blue gradient arc crossfades to red */
.p-notfound .nf-orb__arc-red {
  opacity: 0;
  transition: opacity 1.2s cubic-bezier(0.65, 0, 0.35, 1);
}
.p-notfound.is-settled .nf-orb__arc-red { opacity: 1; }
.p-notfound .nf-orb__arc {
  transition: opacity 1.2s cubic-bezier(0.65, 0, 0.35, 1);
}
.p-notfound.is-settled .nf-orb__arc { opacity: 0; }

/* ---------- copy ---------- */
.p-notfound .nf-title {
  margin: clamp(28px, 4.5vh, 48px) 0 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(24px, 3vw, 34px);
  letter-spacing: var(--track-tighter);
  color: var(--color-white);
}
.p-notfound .nf-sub {
  max-width: 52ch;
  margin: 12px auto 0;
  font-size: var(--fs-body);
  line-height: 1.55;
  color: var(--color-grey-on-black, color-mix(in oklab, var(--color-white) 62%, transparent));
}

/* ---------- actions ---------- */
.p-notfound .nf-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin-top: clamp(24px, 3.4vh, 36px);
}

/* ---------- narrow viewports ---------- */
@media (max-width: 640px) {
  .p-notfound .nf-stage { padding-top: 120px; }
}

/* ---------- reduced motion: land on the red verdict state ---------- */
@media (prefers-reduced-motion: reduce) {
  .p-notfound .nf-orb__ring { animation: none; }
  .p-notfound .nf-orb__arc { opacity: 0; transition: none; }
  .p-notfound .nf-orb__arc-red { opacity: 1; transition: none; }
  .p-notfound .nf-blob::before,
  .p-notfound .nf-blob::after { transition: none; }
  .p-notfound .nf-blob::before { opacity: 0; }
  .p-notfound .nf-blob::after { opacity: 1; }
}
