/* ==========================================================================
   KJPTV — 404 furniture, all prefixed .nf-
   The page opens inside the lens: the whole stage is black because the pupil,
   scaled up, is covering the viewport. It pulls back at a constant rate until
   the lens sits where the 0 of 404 belongs. The lens is CSS geometry, not art:
   knurled focus ring, barrel, coated glass, nine-blade iris, pupil, glint.
   Linked by 404.html only.
   ========================================================================== */

.nf {
  --nf-d: clamp(96px, 17vw, 240px);          /* digit size, and the lens follows */
  --lens: calc(var(--nf-d) * 0.78);
  --foc: 1;                                   /* 1 sharp, 0 wide open and soft */
  --rot: 0deg;                                /* focus ring travel */
  --gx: 0px; --gy: 0px;                       /* glint offset, tracks the pointer */
  position: relative; overflow: hidden;
  min-height: 100vh; min-height: 100svh;
  display: flex; align-items: center;
  padding: calc(var(--nav-height) + 48px) 0 72px;
  background: var(--color-onyx);
}
.nf-pattern {
  position: absolute; inset: 0; z-index: 0; opacity: 0.028; pointer-events: none;
  background: url('assets/brand-pattern.png?v=59e9ff10') center / 320px repeat;
}
.nf-vignette {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: radial-gradient(58% 50% at 50% 46%, rgba(214,157,56,0.08) 0%, rgba(6,6,6,0) 60%),
              radial-gradient(80% 70% at 50% 48%, rgba(6,6,6,0.55) 0%, rgba(6,6,6,0.88) 62%, #060606 100%);
}
.nf .container { position: relative; z-index: 2; }
.nf-stage { display: grid; justify-items: center; text-align: center; }

/* Chrome stays out of the way until the shot lands. CSS-driven, so it reveals
   itself even if the page script never runs. */
@keyframes nfFade { to { opacity: 1; } }
.page-404 .navbar,
.page-404 .app-tabbar,
.page-404 .device-switcher,
.page-404 .view-as { opacity: 0; animation: nfFade 700ms var(--ease-out) 2050ms forwards; }

/* ---- Viewfinder overlay ---------------------------------------------------- */
.nf-vf {
  position: absolute; z-index: 3; pointer-events: none;
  inset: calc(var(--nav-height) + 16px) 20px 20px;
  opacity: 0; animation: nfFade 600ms var(--ease-out) 2150ms forwards;
}
.nf-corner { position: absolute; width: 26px; height: 26px; border: 2px solid rgba(255,210,107,0.5); }
.nf-corner.tl { top: 0; left: 0; border-right: 0; border-bottom: 0; }
.nf-corner.tr { top: 0; right: 0; border-left: 0; border-bottom: 0; }
.nf-corner.bl { bottom: 0; left: 0; border-right: 0; border-top: 0; }
.nf-corner.br { bottom: 0; right: 0; border-left: 0; border-top: 0; }
.nf-rec, .nf-tc, .nf-fmt {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: var(--size-meta); font-weight: 800; letter-spacing: 0.16em; text-transform: uppercase;
  color: rgba(245,245,245,0.62); font-variant-numeric: tabular-nums;
}
/* Readouts sit along the bottom edge, clear of the fixed chrome up top */
.nf-status { position: absolute; bottom: 2px; left: 40px; display: flex; align-items: center; gap: 20px; }
.nf-rec i { width: 9px; height: 9px; border-radius: 50%; background: #e5484d; box-shadow: 0 0 10px rgba(229,72,77,0.7); animation: nfBlink 1.4s steps(1, end) infinite; }
@keyframes nfBlink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0.18; } }
.nf-tc { letter-spacing: 0.1em; }
.nf-fmt { position: absolute; bottom: 2px; right: 40px; }

/* ---- 404 ------------------------------------------------------------------- */
.nf-title {
  display: flex; align-items: center; justify-content: center;
  gap: clamp(2px, 1vw, 16px); margin: 0;
  filter: blur(calc((1 - var(--foc)) * 8px));
  transition: filter 140ms var(--ease-out);
}
/* The focus settle after the move stops is slower than a hand on the ring */
.nf.is-settle .nf-title, .nf.is-settle .nf-copy { transition-duration: 800ms; }
.nf-digit {
  font-size: var(--nf-d); font-weight: 900; line-height: 0.82; letter-spacing: -0.06em;
  opacity: 0; transform: translateY(10px);
  animation: nfDigit 700ms var(--ease-out) 1750ms forwards;
}
@keyframes nfDigit { to { opacity: 1; transform: none; } }
.nf-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

/* ---- The lens -------------------------------------------------------------- */
.nf-lensbox { position: relative; width: var(--lens); height: var(--lens); flex: none; }
.nf-lens {
  position: absolute; inset: 0; border-radius: 50%; cursor: grab; touch-action: none;
  transform: scale(60);
  animation: nfPull 2200ms linear forwards;
  will-change: transform;
}
.nf-lens.is-dragging { cursor: grabbing; }
/* A dolly out reads as constant rate, so the scale steps down exponentially
   (60^(1-t)) rather than linearly. */
@keyframes nfPull {
  0%   { transform: scale(60); }
  25%  { transform: scale(21.6); }
  50%  { transform: scale(7.75); }
  75%  { transform: scale(2.78); }
  90%  { transform: scale(1.55); }
  100% { transform: scale(1); }
}

/* Knurled focus ring */
.nf-ring {
  position: absolute; inset: 0; border-radius: 50%;
  background:
    repeating-conic-gradient(from 0deg, #232020 0 1.5deg, #0d0c0c 1.5deg 3deg),
    #141212;
  box-shadow: inset 0 0 0 1px rgba(214,157,56,0.16), inset 0 2px 6px rgba(0,0,0,0.8), var(--shadow-matte-lg);
  transform: rotate(var(--rot));
}
/* Index mark on the ring, so the travel is readable */
.nf-ring::after {
  content: ""; position: absolute; top: 2.5%; left: 50%; width: 2px; height: 7%;
  border-radius: 2px; background: var(--gold-mustard); transform: translateX(-50%);
  box-shadow: 0 0 8px rgba(255,210,107,0.6);
}
.nf-barrel {
  position: absolute; inset: 9%; border-radius: 50%;
  background: radial-gradient(circle at 50% 42%, #1b1818 0%, #0c0b0b 68%, #060606 100%);
  box-shadow: inset 0 3px 9px rgba(0,0,0,0.9), 0 0 0 1px rgba(214,157,56,0.10);
}
/* Coated front element: the amber bloom real glass throws back */
.nf-glass {
  position: absolute; inset: 16%; border-radius: 50%;
  background:
    radial-gradient(circle at 34% 28%, rgba(255,243,209,0.34) 0%, rgba(230,202,147,0.14) 22%, rgba(214,157,56,0.10) 40%, rgba(8,8,8,0.92) 68%, #050505 100%);
  box-shadow: inset 0 0 26px rgba(0,0,0,0.9);
}
.nf-glass::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: linear-gradient(118deg, rgba(255,255,255,0) 42%, rgba(255,243,209,0.16) 50%, rgba(255,255,255,0) 58%);
  opacity: calc(0.25 + var(--foc) * 0.75);
}
/* Nine blades */
.nf-iris {
  position: absolute; inset: 25%; border-radius: 50%;
  background: conic-gradient(from 12deg,
    #131111 0 40deg, #1d1a1a 40deg 80deg, #0f0e0e 80deg 120deg, #1a1717 120deg 160deg,
    #121010 160deg 200deg, #1e1b1b 200deg 240deg, #100f0f 240deg 280deg, #1b1818 280deg 320deg, #141212 320deg 360deg);
  box-shadow: inset 0 0 14px rgba(0,0,0,0.9);
}
.nf-pupil {
  position: absolute; inset: 33%;
  background: radial-gradient(circle at 50% 44%, #0a0908 0%, #020202 62%, #000 100%);
  clip-path: polygon(50% 0%, 82.1% 11.7%, 99.2% 41.3%, 93.3% 75%, 67.1% 97%, 32.9% 97%, 6.7% 75%, 0.8% 41.3%, 17.9% 11.7%);
  box-shadow: 0 0 30px 10px rgba(0,0,0,0.95);
}
.nf-glint {
  position: absolute; top: 17%; right: 19%; width: 28%; height: 17%;
  border-radius: 50%; pointer-events: none;
  background: linear-gradient(122deg, rgba(255,243,209,0.55), rgba(255,210,107,0.06));
  filter: blur(5px);
  transform: translate(var(--gx), var(--gy));
  opacity: calc(0.35 + var(--foc) * 0.65);
}
.nf-flare {
  position: absolute; inset: -14%; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle at 50% 50%, rgba(214,157,56,0.16) 0%, rgba(214,157,56,0) 62%);
  opacity: 0; animation: nfFade 700ms var(--ease-out) 2150ms forwards;
}

/* ---- Copy ------------------------------------------------------------------ */
.nf-copy {
  max-width: 560px; margin-top: 40px;
  opacity: 0; transform: translateY(14px);
  animation: nfCopy 700ms var(--ease-out) 1950ms forwards;
  filter: blur(calc((1 - var(--foc)) * 6px));
  transition: filter 220ms var(--ease-out);
}
@keyframes nfCopy { to { opacity: 1; transform: none; } }
.nf-copy .kicker { margin-bottom: 14px; }
.nf-lede { font-size: clamp(calc(var(--size-heading) * 0.5938), 2.4vw, calc(var(--size-heading) * 0.8125)); font-weight: 700; line-height: 1.25; letter-spacing: -0.03em; color: var(--text-heading); }
.nf-sub { margin-top: 14px; font-size: calc(var(--size-body) * 1.0714); line-height: 1.6; color: var(--text-body); }
.nf-acts { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 28px; }
.nf-hint {
  display: inline-flex; align-items: center; gap: 9px; margin-top: 26px;
  font-size: calc(var(--size-meta) * 1.0455); font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-muted);
}
.nf-hint svg { width: 15px; height: 15px; color: var(--gold-honey); }
.nf-hint.is-done { opacity: 0.35; }

@media (max-width: 760px) {
  .nf { --nf-d: clamp(76px, 21vw, 140px); padding: calc(var(--nav-height) + 28px) 0 96px; }
  .nf-vf { inset: calc(var(--nav-height) + 10px) 12px 84px; }
  .nf-status { left: 30px; gap: 14px; }
  .nf-fmt { right: 30px; }
  .nf-copy { margin-top: 32px; }
  .nf-acts .btn { flex: 1 1 100%; }
}

/* Nothing moves for anyone who asked for that: the lens is simply already
   parked where the 0 belongs. */
@media (prefers-reduced-motion: reduce) {
  .nf-lens { animation: none; transform: none; }
  .nf-digit, .nf-copy { animation: none; opacity: 1; transform: none; }
  .nf-vf, .nf-flare { animation: none; opacity: 1; }
  .page-404 .navbar, .page-404 .app-tabbar,
  .page-404 .device-switcher, .page-404 .view-as { animation: none; opacity: 1; }
  .nf-rec i { animation: none; }
}
