/* ===========================================================================
   style.css — Phases 1–2.
   Fixed full-screen WebGL canvas + a tall scroll spacer that drives progress t.
   Adds the loader (signature draw-on) + Enter gate, the nav bar, mute control,
   film-grain + vignette overlays, and reveal transitions. Colours from §4.
   =========================================================================== */

:root {
  --night:   #0B1622;
  --dusk:    #1C2E40;
  --steel:   #2E4255;
  --haze:    #5C7A99;
  --firefly: #FFD37A;
  --ember:   #F4A259;
  --cream:   #F5EBDC;
  --rust:    #8A4B38;

  /* Easing tokens — the site's single easing language (JS twins in js/easing.js).
     glide=nav travel/silky tails · settle=easing to rest · drama=hero moments ·
     veil=fades/dissolves. Use these; never 'ease' or 'linear'. */
  --ease-glide:  cubic-bezier(0.22, 1, 0.36, 1);
  --ease-settle: cubic-bezier(0.45, 0.05, 0.15, 1);
  --ease-drama:  cubic-bezier(0.60, 0, 0.18, 1);
  --ease-veil:   cubic-bezier(0.33, 0, 0.20, 1);

  /* Spacing scale — system of record for UI-chrome rhythm (4px base, doubling toward
     the top). Prefer these for component margins/gaps; small optical nudges (1–3px)
     are intentional and stay as literals per the "optical over mathematical" rule. */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 64px;
  /* Type scale — a ~1.25 modular progression for headings/UI (clamped where fluid). */
  --fs-micro: 11px; --fs-ui: 12px; --fs-body: 15px; --fs-h4: 20px;
  --fs-h3: 24px;    --fs-h2: 30px; --fs-h1: clamp(42px, 7.5vw, 78px);
}

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

body {
  background: var(--night);
  color: var(--cream);
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  overflow-x: hidden;
}

/* Fixed full-viewport render surface */
#scene {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  display: block;
  z-index: 0;
}

/* The scroll spine — its height is what we scroll through (long forest journey) */
#scroll-spacer {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 2800vh; /* longer, unhurried journey (scroll-feel rework) */
  pointer-events: none;
}

/* Screen-reader-only heading / copy */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---- Atmosphere overlays: film grain + vignette ------------------------- */
#grain, #vignette {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}
#vignette {
  /* gentle edge darkening (the main vignette is now in the grade pass) */
  background: radial-gradient(ellipse 85% 85% at 50% 45%,
              rgba(0,0,0,0) 60%, rgba(4,9,15,0.22) 100%);
}
#grain {
  opacity: 0.06;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 160px 160px;
  animation: grainshift 0.6s steps(2) infinite;
}
@keyframes grainshift {
  0%   { background-position: 0 0; }
  50%  { background-position: 30px -20px; }
  100% { background-position: -15px 25px; }
}

/* ---- Nav bar ------------------------------------------------------------- */
#nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  padding: var(--sp-4) 24px;   /* 24 (not 26) so the edge inset sits on the grid */
  gap: var(--sp-4);
  transition: opacity 0.9s var(--ease-veil), transform 0.9s var(--ease-glide);
}
#nav.nav-hidden { opacity: 0; transform: translateY(-14px); pointer-events: none; }

#nav-logo { display: inline-flex; align-items: center; text-decoration: none; }
.sig-mask {
  display: block;
  width: 78px; height: 44px;
  background: var(--cream);
  -webkit-mask: url("../assets/img/Poonno%20Signature.svg") no-repeat center / contain;
          mask: url("../assets/img/Poonno%20Signature.svg") no-repeat center / contain;
  opacity: 0.92;
  transition: opacity 0.3s var(--ease-veil), filter 0.3s var(--ease-veil);
}
#nav-logo:hover .sig-mask { opacity: 1; filter: drop-shadow(0 0 8px rgba(255,211,122,0.5)); }

#nav-links { display: flex; align-items: center; gap: 18px; margin-left: auto; margin-right: 50px; }  /* hug right; leave room for the fixed mute toggle */
#nav-links a, #nav-links button {
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--cream);
  background: none;
  border: 0;
  cursor: pointer;
  text-decoration: none;
  opacity: 0.72;
  transition: opacity 0.25s var(--ease-veil), color 0.25s var(--ease-veil), text-shadow 0.3s var(--ease-glide);
}
/* considered hover: a faint comet-glow ignites (same language as .nav-active), so
   hovering previews the "you are here" state instead of a bare colour swap. */
#nav-links a:hover, #nav-links button:hover {
  opacity: 1; color: #fff;
  /* brighter, layered white bloom — the same comet-head light as the scroll timeline */
  text-shadow:
    0 0 8px  rgba(255, 255, 255, 0.9),
    0 0 20px rgba(255, 250, 245, 0.6),
    0 0 34px rgba(255, 248, 240, 0.35);
}
/* current-section highlight — a soft WHITE comet-glow (matches the scroll timeline),
   no colour tint, no underline */
#nav-links button.nav-active {
  opacity: 1; color: #fff;
  text-shadow:
    0 0 8px  rgba(255, 255, 255, 0.92),
    0 0 22px rgba(255, 250, 245, 0.62),
    0 0 40px rgba(255, 248, 240, 0.4);
  transition: opacity 0.4s var(--ease-veil), color 0.4s var(--ease-veil), text-shadow 0.4s var(--ease-veil);
}
#cv-link {
  border: 1px solid rgba(245,235,220,0.35) !important;
  border-radius: 999px;
  padding: 7px 14px;
  transition: opacity 0.25s var(--ease-veil), color 0.25s var(--ease-veil),
              text-shadow 0.3s var(--ease-glide), border-color 0.25s var(--ease-glide),
              box-shadow 0.3s var(--ease-glide);
}
/* CV pill hovers with the SAME white bloom as the other items (was an orange border) —
   the pill's rim lights up white and blooms, instead of tinting ember. */
#cv-link:hover {
  border-color: rgba(255, 255, 255, 0.7) !important;
  box-shadow: 0 0 16px rgba(255, 250, 245, 0.4), inset 0 0 10px rgba(255, 255, 255, 0.06);
}

/* Sound toggle — a top-level control, pinned so it stays reachable even when the nav
   fades (top-right on desktop, bottom-left on small screens). It signals sound state
   like a nav item: when ON, the ♪ carries the SAME white comet-bloom as an active
   station name (gently breathing so it reads as live audio); when muted it goes dark
   + rust-red + struck-through. */
#mute-btn {
  position: fixed; top: 21px; right: 24px; z-index: 25;
  font-size: 17px; line-height: 1;
  width: 34px; height: 34px; border-radius: 50%;
  color: #fff;
  border: 1px solid rgba(245, 235, 220, 0.5);
  background: rgba(245, 235, 220, 0.05);
  display: inline-flex; align-items: center; justify-content: center;
  transition: border-color 0.3s var(--ease-glide), background 0.3s var(--ease-glide),
              color 0.3s var(--ease-veil), transform 0.25s var(--ease-glide);
  /* SOUND ON — a broad soft white HALO around the whole control, the same wide bloom
     that haloes an active nav word (a text-shadow on the tiny ♪ alone spreads too thin
     to match it). Breathes so it reads as live audio. */
  animation: soundHalo 2.8s ease-in-out infinite;
}
/* the glyph itself burns bright white with its own tight comet-bloom */
#mute-btn .mute-ico {
  text-shadow:
    0 0 5px  rgba(255, 255, 255, 0.98),
    0 0 12px rgba(255, 255, 255, 0.8),
    0 0 24px rgba(255, 250, 245, 0.55),
    0 0 40px rgba(255, 248, 240, 0.4);
  animation: soundGlyph 2.8s ease-in-out infinite;
}
#mute-btn:hover {
  border-color: rgba(255, 255, 255, 0.95);
  background: rgba(255, 255, 255, 0.12);
  transform: scale(1.08);
}
#mute-btn.is-muted {                                 /* muted → rust-red, no halo */
  color: rgba(226, 120, 100, 0.95);
  border-color: rgba(178, 58, 46, 0.7);
  background: rgba(178, 58, 46, 0.08);
  animation: none;
}
#mute-btn.is-muted .mute-ico {                       /* kill the glow when silenced */
  opacity: 0.8; text-decoration: line-through;
  text-shadow: none; animation: none;
}
/* the wide button halo — matched to an active nav word's glow (whose brightest layer is
   ~0.92 white), so it reads with the same visual weight; a strong floor so it never
   dims below "clearly on", breathing up from there. */
@keyframes soundHalo {
  0%, 100% { box-shadow: 0 0 16px 2px rgba(255,255,255,0.70), 0 0 34px 5px rgba(255,250,245,0.44), 0 0 56px 9px rgba(255,248,240,0.26); }
  50%      { box-shadow: 0 0 24px 3px rgba(255,255,255,0.92), 0 0 48px 8px rgba(255,250,245,0.58), 0 0 74px 14px rgba(255,248,240,0.38); }
}
/* the glyph's own tight bloom, breathing in sync */
@keyframes soundGlyph {
  0%, 100% { text-shadow: 0 0 5px rgba(255,255,255,0.9),  0 0 12px rgba(255,255,255,0.65), 0 0 24px rgba(255,250,245,0.42); }
  50%      { text-shadow: 0 0 7px rgba(255,255,255,1),    0 0 16px rgba(255,255,255,0.9),  0 0 32px rgba(255,250,245,0.62); }
}
@media (prefers-reduced-motion: reduce) { #mute-btn, #mute-btn .mute-ico { animation: none; } }

/* Whistle rope — a detailed hanging pull: ceiling mount, braided cord, knot,
   brass ring + turned-wood handle + tassel. Pivots from the ceiling on pull. */
#whistle-rope {
  position: absolute;
  left: 50%; top: 0;
  transform: translateX(-50%);
  background: none; border: 0; cursor: pointer;
  display: flex; flex-direction: column; align-items: center;
  padding: 0 8px 8px;
  transform-origin: 50% 0;            /* swing from the ceiling */
  /* animating `top` (not transform) leaves the sway/pull transforms free to work */
  transition: top 0.6s cubic-bezier(0.34, 1.32, 0.64, 1), opacity 0.45s var(--ease-veil);
}
/* stowed: hoisted up out of frame while the train is stopped (or before boarding).
   It falls back into view when the journey resumes. */
#whistle-rope.rope-stowed {
  top: -190px; opacity: 0; pointer-events: none;
}
/* the ceiling anchor — a corroded dark fitting */
#whistle-rope .rope-mount {
  width: 10px; height: 4px; border-radius: 0 0 3px 3px;
  background: linear-gradient(#2c241a, #17110a);
  box-shadow: 0 1px 2px rgba(0,0,0,0.6);
}
/* old braided cord — dusty, faded, greyed-out fibres with grime, not glossy.
   ::before/::after add a couple of stray frayed strands poking out. */
#whistle-rope .rope-cord {
  position: relative;
  width: 4px; height: 30px;
  background:
    repeating-linear-gradient(46deg, #6f6047 0 2px, #463a2a 2px 4px, #595038 4px 6px);
  border-radius: 2px;
  box-shadow: inset -1px 0 1px rgba(0,0,0,0.55), inset 1px 0 1px rgba(190,170,130,0.10);
  filter: saturate(0.6) brightness(0.92);
  transform: rotate(5deg);                 /* a slight lean so it doesn't hang dead-straight */
  transform-origin: 50% 0%;
}
/* splayed frayed tufts (several hairs each) bursting out along the cord */
#whistle-rope .rope-cord::before,
#whistle-rope .rope-cord::after {
  content: ""; position: absolute; width: 6px; height: 8px; opacity: 0.6;
  background: repeating-linear-gradient(92deg, #5a4e38 0 0.6px, transparent 0.6px 1.9px);
}
#whistle-rope .rope-cord::before { left: -5px; top: 28%; transform: rotate(28deg); }
#whistle-rope .rope-cord::after  { right: -5px; top: 56%; transform: rotate(-32deg); }
/* worn, fuzzy knot where the cord meets the handle — more stray fibres splay out.
   margin-left keeps it under the leaned cord's lower end (the kink point). */
#whistle-rope .rope-knot {
  position: relative;
  width: 9px; height: 9px; margin-top: -1px; margin-left: 3px; border-radius: 50%;
  background: radial-gradient(circle at 38% 32%, #7a6748, #3a2c1a);
  box-shadow: 0 1px 2px rgba(0,0,0,0.5);
}
#whistle-rope .rope-knot::before,
#whistle-rope .rope-knot::after {
  content: ""; position: absolute; width: 7px; height: 8px; opacity: 0.7; top: -4px;
  background: repeating-linear-gradient(90deg, #574a35 0 0.6px, transparent 0.6px 2px);
}
#whistle-rope .rope-knot::before { left: 0; transform: rotate(22deg); }
#whistle-rope .rope-knot::after  { right: 0; transform: rotate(-26deg); }
#whistle-rope .rope-pull {
  display: flex; flex-direction: column; align-items: center;
  margin-left: 3px;                        /* follow the kink offset */
  transition: transform 0.14s cubic-bezier(0.34,1.56,0.64,1);
}
/* tarnished, patinated brass ring — dull olive-bronze, no shine, pitted */
#whistle-rope .pull-ring {
  width: 12px; height: 12px; margin-top: -1px;
  border-radius: 50%;
  border: 2.5px solid transparent;
  background:
    linear-gradient(#181208, #181208) padding-box,
    linear-gradient(160deg, #8f8758, #5c5a37 50%, #3a3320) border-box;
  box-shadow: inset 0 0 3px rgba(0,0,0,0.5);
  filter: saturate(0.7);
}
/* weathered, scuffed wood grip — dark, dull, with a hairline crack (::after) */
#whistle-rope .pull-grip {
  position: relative;
  width: 13px; height: 26px; margin-top: -1px;
  border-radius: 6px / 7px;
  background:
    linear-gradient(90deg, #241910 0%, #4a3623 40%, #6a4e32 52%, #3e2c1b 70%, #1d140b 100%);
  box-shadow: inset 0 5px 5px rgba(180,150,105,0.10), inset 0 -7px 8px rgba(0,0,0,0.6),
              0 2px 5px rgba(0,0,0,0.55);
  filter: saturate(0.7) brightness(0.92);
}
#whistle-rope .pull-grip::after {            /* a worn hairline crack down the grip */
  content: ""; position: absolute; left: 58%; top: 18%;
  width: 1px; height: 60%;
  background: rgba(0,0,0,0.5);
  transform: rotate(6deg);
}
/* frayed, torn rope-end — many splayed fibres via a jagged clip-path, no glow */
#whistle-rope .pull-tip {
  width: 16px; height: 16px; margin-top: -2px;
  background: repeating-linear-gradient(90deg, #5a4d38 0 1px, #322819 1px 2.2px);
  clip-path: polygon(0 0, 100% 0, 95% 30%, 100% 52%, 87% 40%, 93% 96%, 79% 46%, 84% 100%, 68% 48%, 60% 92%, 50% 100%, 40% 92%, 32% 48%, 16% 100%, 21% 46%, 7% 96%, 13% 40%, 0 52%, 5% 30%);
  filter: saturate(0.6) brightness(0.85);
  opacity: 0.95;
}
/* pull feedback — the handle assembly drops on hover/press */
#whistle-rope:hover .rope-pull { transform: translateY(3px); }
#whistle-rope:active .rope-pull,
#whistle-rope.pulled .rope-pull { transform: translateY(8px); }
/* idle invitation — a gentle pendulum sway from the ceiling to catch the eye */
#whistle-rope.invite { animation: ropeSway 2.4s ease-in-out infinite; }
@keyframes ropeSway {
  0%, 100% { transform: translateX(-50%) rotate(-3.2deg); }
  50%      { transform: translateX(-50%) rotate(3.2deg); }
}

/* Pull-the-whistle hint — small top-centre label with an arrow up to the rope */
#whistle-hint {
  position: fixed; left: 50%; top: 70px;
  transform: translateX(-50%);
  z-index: 46; pointer-events: none;
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  opacity: 0; will-change: opacity, transform;
  text-align: center;
}
#whistle-hint .wh-arrow {
  width: 12px; height: 12px;
  border-left: 1.5px solid var(--firefly);
  border-top: 1.5px solid var(--firefly);
  transform: rotate(45deg);            /* chevron pointing UP to the rope */
  opacity: 0.9; animation: whBob 1.5s ease-in-out infinite;
}
#whistle-hint .wh-label {
  font-family: 'Space Mono', monospace;
  font-size: 11px; letter-spacing: 0.34em; text-transform: uppercase;
  color: var(--cream);
  padding: 7px 16px; border-radius: 999px;
  background: rgba(8,12,18,0.5);
  border: 1px solid rgba(244,162,89,0.22);
  box-shadow: 0 6px 24px rgba(0,0,0,0.4);
  backdrop-filter: blur(6px);
}
@keyframes whBob { 0%,100% { transform: translateY(0) rotate(45deg); } 50% { transform: translateY(-4px) rotate(45deg); } }

@media (prefers-reduced-motion: reduce) {
  #whistle-rope.invite { animation: none; }
  #whistle-hint .wh-arrow { animation: none; }
}

/* ---- HUD (debug; hidden unless toggled with 'h') ------------------------- */
#hud {
  position: fixed;
  left: 18px; bottom: 16px;
  z-index: 5;
  pointer-events: none; user-select: none;
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.65);
}
#hud.hud-hidden { display: none; }
#hud-beat {
  font-family: 'Fraunces', Georgia, serif;
  font-weight: 600; font-size: 15px;
  letter-spacing: 0.3px; opacity: 0.92;
}
#hud-meta {
  margin-top: 3px; font-size: 11px;
  letter-spacing: 1.6px; text-transform: uppercase; opacity: 0.55;
}
#hud-hold { margin-left: 6px; color: var(--firefly); font-weight: 600; }

/* ---- Fly-in focus veil --------------------------------------------------
   Dims the world's edges while the newspaper takes the stage (opacity driven
   per-frame from main.js on the fly-in envelope; centre stays clear so the
   paper itself remains lit). */
#focus-veil {
  position: fixed; inset: 0; z-index: 25; pointer-events: none; opacity: 0;
  background: radial-gradient(ellipse 78% 68% at 50% 46%, transparent 40%, rgba(4, 9, 15, 0.6) 100%);
}

/* ---- Paper-fill backdrop -------------------------------------------------
   Full-bleed aged newsprint behind the article overlay. Fades in the instant
   the 3D paper reaches full frame, bridging its irregular folded edges so the
   WHOLE screen reads as paper before the article emerges (opacity driven from
   news.js). */
/* Full-screen sheet the flying paper "becomes": color-matched to the article
   page (.news-page) so the article emerges from it seamlessly, with a soft
   amber mottle + vignette so it reads as aged newsprint, not a flat fill. */
#paper-fill {
  position: fixed; inset: 0; z-index: 40; pointer-events: none; opacity: 0;
  background:
    radial-gradient(ellipse 90% 70% at 30% 25%, rgba(180, 148, 70, 0.16), transparent 70%),
    radial-gradient(ellipse 80% 90% at 75% 80%, rgba(150, 118, 58, 0.20), transparent 72%),
    radial-gradient(ellipse 120% 120% at 50% 44%, #e6d4a0 45%, #cdbb80 100%);
}

/* ---- Top scroll timeline (1:1 with ciaoenergy.com) --------------------------
   Measured from their canvas: a 1px WHITE hairline, inset from the top edges.
   A ~20%-white unfilled track; the filled portion is SOLID white (no gradient);
   the only glow is a small soft-white comet-head bloom at the leading tip. */
/* The line itself is drawn by a WebGL fragment shader (js/scroll-timeline.js); this
   wrapper is just a fixed top strip tall enough to hold the downward bloom, sitting
   BELOW the nav (z18) so nav text stays crisp over the glow. */
#scroll-timeline {
  position: fixed; top: 0; left: 0; width: 100%; height: 240px;
  z-index: 18; pointer-events: none;
  transition: opacity 0.8s var(--ease-veil);
}
#scroll-timeline.stl-hidden { opacity: 0; }
#stl-canvas { display: block; width: 100%; height: 100%; }

/* ---- Site-wide vignette (WebGL, js/vignette.js) — smooth dithered edge-darkening,
   clear through the centre, above the scene + content overlays. ---- */
#vignette-canvas {
  position: fixed; inset: 0; width: 100%; height: 100%;
  z-index: 47; pointer-events: none;
}

/* ---- Scroll progress rail ---------------------------------------------- */
#progress {
  position: fixed; right: 20px; top: 50%; transform: translateY(-50%);
  width: 2px; height: 230px; z-index: 6;
  background: rgba(245, 235, 220, 0.12); border-radius: 2px;
}
#progress-fill {
  position: absolute; top: 0; left: 0; width: 100%; height: 0%;
  background: linear-gradient(var(--firefly), var(--ember));
  box-shadow: 0 0 8px rgba(255, 211, 122, 0.7); border-radius: 2px;
}
#progress .ptick {
  position: absolute; left: 50%; width: 5px; height: 5px; margin: -2.5px 0 0 -2.5px;
  border-radius: 50%; background: rgba(245, 235, 220, 0.4);
  transition: background 0.3s var(--ease-glide), box-shadow 0.3s var(--ease-glide), transform 0.3s var(--ease-glide);
}
#progress .ptick.tick-active {
  background: var(--firefly); transform: scale(1.5);
  box-shadow: 0 0 8px rgba(255, 211, 122, 0.9);
}
@media (max-width: 720px) { #progress { display: none; } }

/* ---- Night-cut (long nav jumps): fade to black, snap, fade back in -------- */
/* opacity is driven per-frame from main.js (updateNavJourney), so no CSS transition */
#nav-cut {
  position: fixed; inset: 0; z-index: 300; pointer-events: none;
  background: #05080d; opacity: 0;
}

/* ---- Scroll hint -------------------------------------------------------- */
#scroll-hint {
  position: fixed;
  left: 50%; bottom: 26px;
  transform: translateX(-50%);
  z-index: 5;
  font-size: 11px; letter-spacing: 3px; text-transform: uppercase;
  color: var(--cream); opacity: 0;
  pointer-events: none;
  transition: opacity 0.8s var(--ease-veil);
  animation: hintbob 2.4s ease-in-out infinite;
}
#scroll-hint.show { opacity: 0.6; }
@keyframes hintbob {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50%      { transform: translateX(-50%) translateY(5px); }
}

/* ---- Loader + Enter gate ------------------------------------------------ */
#loader {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000;
  transition: opacity 1.1s var(--ease-veil);
}
#loader.loader-gone { opacity: 0; pointer-events: none; }
#loader-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-5);
}
#loader-sig { position: relative; width: 340px; max-width: 86vw; }

/* ---- Night-train ticket loader ---- */
.tl-wrap { width: 100%; }
.tl-perf {
  display: flex;
  align-items: stretch;
  border: 1px solid rgba(245,235,220,0.22);
  border-radius: 4px;
  overflow: hidden;
  background: #0a0a0a;
}
.tl-holes {
  width: 18px;
  flex-shrink: 0;
  background: repeating-linear-gradient(
    to bottom,
    transparent 0px, transparent 8px,
    rgba(245,235,220,0.12) 8px, rgba(245,235,220,0.12) 12px,
    transparent 12px, transparent 20px
  );
  border-right: 1px dashed rgba(245,235,220,0.12);
}
.tl-holes:last-child { border-right: none; border-left: 1px dashed rgba(245,235,220,0.12); }
.tl-body {
  flex: 1;
  padding: 18px 20px 16px;
  font-family: 'Space Mono', monospace;
  color: var(--cream);
}
.tl-name {
  font-size: 11px;
  letter-spacing: 5px;
  opacity: 0.5;
  text-align: center;
  margin-bottom: 10px;
}
.tl-rule {
  height: 1px;
  background: rgba(245,235,220,0.18);
  margin: 10px 0;
}
.tl-row {
  display: flex;
  gap: 10px;
  font-size: 10px;
  letter-spacing: 1.5px;
  line-height: 1.9;
  text-transform: uppercase;
}
.tl-k { opacity: 0.38; min-width: 44px; }
.tl-v { opacity: 0.82; }
.tl-pct-row {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 3px;
  margin-top: 14px;
}
.tl-pct {
  font-size: 48px;
  letter-spacing: -2px;
  line-height: 1;
  color: var(--cream);
  font-variant-numeric: tabular-nums;
}
.tl-pct-sign {
  font-size: 20px;
  opacity: 0.5;
  align-self: flex-end;
  padding-bottom: 4px;
}
.tl-status {
  font-size: 9px;
  letter-spacing: 4px;
  text-align: center;
  opacity: 0.38;
  margin-top: 6px;
  text-transform: uppercase;
}

/* Enter gate — a clean outlined pill in the Noomo language: thin rim, a twinkling
   spark, generous tracking. It's MAGNETIC (ui.js leans it toward the cursor and drifts
   the label a touch further), so the whole button moves/sticks with the pointer.
   Transform is owned by the JS magnetic loop — CSS never sets transform here. */
#enter-btn {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: 'Space Mono', monospace;
  font-size: 12px; letter-spacing: 0.28em; text-transform: uppercase;
  color: var(--cream);
  background: rgba(255,255,255,0.03);
  border: 1px solid rgba(255,255,255,0.34);
  border-radius: 999px;
  padding: 15px 30px;
  cursor: pointer;
  opacity: 0;
  /* soft WHITE resting halo (same language as the sound toggle's glow) so it reads
     as lit even before you hover, then blooms brighter on hover/lean. */
  box-shadow: 0 0 16px 1px rgba(255,255,255,0.16), 0 0 32px 3px rgba(255,255,255,0.08);
  transition: opacity 0.9s var(--ease-veil), border-color 0.45s var(--ease-glide),
              background 0.45s var(--ease-glide), box-shadow 0.45s var(--ease-glide);
  will-change: transform, opacity;
}
#enter-btn.enter-hidden { display: none; }
#enter-btn.enter-show { opacity: 1; }
#enter-btn:hover {
  border-color: rgba(255,255,255,0.85);
  background: rgba(255,255,255,0.08);
  box-shadow: 0 0 22px 2px rgba(255,255,255,0.4), 0 0 46px 6px rgba(255,255,255,0.22);
}
.enter-inner { display: inline-flex; align-items: center; gap: 11px; will-change: transform; }
.enter-spark {
  width: 13px; height: 13px; display: inline-flex; color: #fff;
  filter: drop-shadow(0 0 4px rgba(255,255,255,0.85)) drop-shadow(0 0 9px rgba(255,255,255,0.5));
  animation: enterSpark 3.4s ease-in-out infinite;
}
.enter-spark svg { width: 100%; height: 100%; display: block; }
.enter-label { display: inline-block; }
@keyframes enterSpark {
  0%, 100% { opacity: 0.72; transform: scale(0.84) rotate(0deg); }
  50%      { opacity: 1;    transform: scale(1.12) rotate(90deg); }
}

/* ---- Reduced motion ----------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  #scroll-hint, #enter-btn, .enter-spark, #grain { animation: none; }
  /* the last two infinite idle loops that were still running for motion-sensitive
     users: the card hero's drifting glow and the article "next" chevron bob */
  .card-hero::after, #read-next { animation: none; }
}

/* ===========================================================================
   Phase 4 — cab click-guidance + designed-card modals
   =========================================================================== */

/* One-time hint banner + "Tap to explore" labels */
.cab-hint {
  position: fixed;
  left: 50%; bottom: var(--sp-8);
  transform: translateX(-50%) translateY(10px);
  z-index: 30;
  padding: 11px 20px;
  border-radius: 999px;
  background: rgba(11, 22, 34, 0.7);
  border: 1px solid rgba(255, 211, 122, 0.3);
  color: var(--cream);
  font-size: 13px; letter-spacing: 0.4px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.7s var(--ease-veil), transform 0.7s var(--ease-glide);
}
.cab-hint.show { opacity: 1; transform: translateX(-50%) translateY(0); }

.tap-tip {
  position: fixed;
  z-index: 30;
  transform: translate(-50%, -150%);
  padding: 5px 12px;
  border-radius: 999px;
  background: rgba(244, 162, 89, 0.16);
  border: 1px solid var(--firefly);
  color: var(--firefly);
  font-size: 10px; letter-spacing: 2px; text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.4s var(--ease-veil);
  animation: tipbob 2s ease-in-out infinite;
}
.tap-tip.show { opacity: 0.95; }
@keyframes tipbob { 0%,100% { margin-top: 0; } 50% { margin-top: -5px; } }

/* Modal overlay */
.modal-root {
  position: fixed; inset: 0;
  z-index: 200;
  display: flex; align-items: center; justify-content: center;
  padding: var(--sp-5);
  background: rgba(5, 9, 15, 0.62);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.32s var(--ease-veil);
}
.modal-root.open { opacity: 1; pointer-events: auto; }

.modal-card {
  position: relative;
  width: min(640px, 94vw);
  max-height: 86vh;
  overflow-y: auto;
  border-radius: 18px;
  background: linear-gradient(180deg, #15273a 0%, #101d2b 100%);
  border: 1px solid rgba(245, 235, 220, 0.14);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
  transform: translateY(26px) scale(0.98);
  opacity: 0;
  transition: transform 0.42s var(--ease-glide), opacity 0.42s var(--ease-veil);
}
.modal-card.in { transform: translateY(0) scale(1); opacity: 1; }

.modal-close {
  position: absolute; top: 12px; right: 14px;
  width: 34px; height: 34px;
  border-radius: 50%;
  border: 1px solid rgba(245, 235, 220, 0.2);
  background: rgba(0, 0, 0, 0.25);
  color: var(--cream);
  font-size: 20px; line-height: 1; cursor: pointer;
  transition: background 0.2s var(--ease-glide), border-color 0.2s var(--ease-glide);
  z-index: 2;
}
.modal-close:hover { background: rgba(244, 162, 89, 0.2); border-color: var(--ember); }

.modal-head { padding: 26px 28px 18px; display: flex; align-items: center; gap: 18px; }
.bb-head { background: linear-gradient(120deg, rgba(244,162,89,0.22), rgba(255,211,122,0.08)); border-bottom: 1px solid rgba(244,162,89,0.3); }
.bio-head { background: linear-gradient(120deg, rgba(46,66,85,0.5), rgba(244,162,89,0.06)); border-bottom: 1px solid rgba(245,235,220,0.12); }
.kicker { font-size: 11px; letter-spacing: 3px; text-transform: uppercase; color: var(--ember); opacity: 0.9; }
.modal-title { font-family: 'Fraunces', Georgia, serif; font-weight: 600; font-size: 27px; color: var(--cream); margin: 4px 0 0; line-height: 1.15; }

/* #27 jersey motif on the basketball header */
.jersey-motif {
  flex: 0 0 auto;
  width: 58px; height: 64px;
  display: grid; place-items: center;
  background: var(--brRed, #B23A2E);
  color: #F5F5F5;
  border-radius: 8px 8px 14px 14px;
  box-shadow: inset 0 6px 0 rgba(255,255,255,0.18), 0 0 16px rgba(255,211,122,0.25);
  font-family: 'Inter', sans-serif; font-weight: 800; font-size: 26px;
}
:root { --brRed: #B23A2E; }

/* Basketball blocks (court-pebble texture behind) */
.bb { background-image: radial-gradient(circle at 1px 1px, rgba(244,162,89,0.05) 1px, transparent 0); background-size: 9px 9px; }
.bb-grid { padding: 22px 28px 30px; display: grid; grid-template-columns: 1fr 1fr; gap: 20px 26px; }
.bio-body { padding: 22px 30px 30px; }

.blk-h { display: flex; align-items: center; gap: 9px; font-family: 'Fraunces', serif; font-weight: 600; font-size: 15px; color: var(--firefly); margin-bottom: 9px; }
.blk-ico { width: 20px; height: 20px; color: var(--ember); display: inline-flex; }
.blk-ico svg { width: 20px; height: 20px; }
.blk ul { margin: 0; padding-left: 2px; list-style: none; }
.blk li { position: relative; padding-left: 16px; margin: 5px 0; font-size: 13.5px; line-height: 1.5; color: var(--cream); opacity: 0.9; }
.blk li::before { content: '·'; position: absolute; left: 4px; color: var(--ember); font-weight: 700; }
.blk-quote { font-size: 13.5px; line-height: 1.6; color: var(--cream); opacity: 0.92; font-style: italic; margin: 0; }
.blk:last-child { grid-column: 1 / -1; border-top: 1px solid rgba(245,235,220,0.1); padding-top: 16px; }

.bio-body p { font-size: 14.5px; line-height: 1.66; color: var(--cream); opacity: 0.9; margin: 0 0 13px; }
.bio-body p.lead { font-family: 'Fraunces', serif; font-size: 18px; opacity: 1; color: var(--firefly); }

@media (max-width: 640px) {
  .bb-grid { grid-template-columns: 1fr; }
  .modal-title { font-size: 22px; }
}

@media (prefers-reduced-motion: reduce) {
  .tap-tip { animation: none; }
  .modal-card { transition: opacity 0.3s var(--ease-veil); transform: none; }
}


/* ---- custom cursor (minimal flat outline — no glow, no blend, no shadow) ---- */
#cursor, #cursor-dot {
  position: fixed; left: 0; top: 0; pointer-events: none; z-index: 9999;
  will-change: transform;
}
#cursor-dot {
  width: 5px; height: 5px; margin: -2.5px 0 0 -2.5px; border-radius: 50%;
  background: rgba(236, 230, 218, 0.8);
}
#cursor {
  width: 28px; height: 28px; margin: -14px 0 0 -14px;
  border: 1px solid rgba(236, 230, 218, 0.32); border-radius: 50%; background: none;
  transition: width 0.3s cubic-bezier(0.23,1,0.32,1), height 0.3s cubic-bezier(0.23,1,0.32,1),
              margin 0.3s cubic-bezier(0.23,1,0.32,1), border-color 0.3s var(--ease-glide);
}
#cursor.hot  { width: 46px; height: 46px; margin: -23px 0 0 -23px; border-color: rgba(236, 230, 218, 0.5); }
#cursor.down { width: 20px; height: 20px; margin: -10px 0 0 -10px; }
@media (hover: none), (prefers-reduced-motion: reduce) { #cursor, #cursor-dot { display: none; } }
/* hide the native cursor only while the custom one is active */
html.has-cursor, html.has-cursor * { cursor: none !important; }

/* ===========================================================================
   Phase 8 — finale contact panel + footer (Horizons Crossing)
   =========================================================================== */
#contact {
  position: fixed; inset: 0;
  z-index: 16;
  display: flex; align-items: flex-end; justify-content: center;
  padding: 0 var(--sp-5) 4vh;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(120% 80% at 50% 120%, rgba(6, 11, 18, 0.72), transparent 70%);
  transition: opacity 1s var(--ease-veil);
}
#contact.show { opacity: 1; }
.contact-inner { text-align: center; max-width: 620px; will-change: transform; }

/* staggered reveal of each row when shown */
.contact-kicker, .contact-head, .contact-sub, .contact-links, .site-footer {
  opacity: 0; transform: translateY(18px);
  transition: opacity 0.7s var(--ease-veil), transform 0.7s var(--ease-glide);
}
#contact.show .contact-kicker { opacity: 1; transform: none; transition-delay: 0.15s; }
#contact.show .contact-head   { opacity: 1; transform: none; transition-delay: 0.30s; }
#contact.show .contact-sub    { opacity: 1; transform: none; transition-delay: 0.45s; }
#contact.show .contact-links  { opacity: 1; transform: none; transition-delay: 0.60s; pointer-events: auto; }
#contact.show .site-footer    { opacity: 1; transform: none; transition-delay: 0.85s; }

.contact-kicker { font-family: 'Space Mono', monospace; font-size: var(--fs-ui); letter-spacing: 0.42em; text-transform: uppercase; color: var(--firefly); opacity: 0.85; }
/* same pairing as the station-approach overlay: Space Mono kicker + display serif name */
.contact-head { font-family: var(--font-display); font-weight: 500; font-size: var(--fs-h1); line-height: 0.98; letter-spacing: 0.005em; color: var(--cream); margin: var(--sp-4) 0 0; }
.contact-sub { font-family: 'Inter', sans-serif; font-size: var(--fs-body); color: var(--cream); opacity: 0.7; margin: var(--sp-3) 0 0; }

.contact-links { display: flex; gap: var(--sp-4); justify-content: center; flex-wrap: wrap; margin-top: var(--sp-6); }
.contact-link {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 12px 22px; border-radius: 999px;
  border: 1px solid rgba(245, 235, 220, 0.28);
  color: var(--cream); text-decoration: none;
  font-family: 'Space Mono', monospace; font-size: 12px; letter-spacing: 2px; text-transform: uppercase;
  transition: border-color 0.25s var(--ease-glide), background 0.25s var(--ease-glide), color 0.25s var(--ease-veil), transform 0.25s var(--ease-glide);
}
.contact-link svg { width: 17px; height: 17px; }
.contact-link:hover { border-color: var(--ember); background: rgba(244, 162, 89, 0.12); color: var(--ember); transform: translateY(-3px); }

/* footer pinned to the two bottom corners — copyright bottom-left, credit bottom-right —
   in white @ 80%. Lives OUTSIDE .contact-inner so it stays put (clear of the parallax). */
.site-footer {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; align-items: flex-end; justify-content: space-between;
  padding: 0 26px 18px; gap: var(--sp-4);
  font-family: 'Space Mono', monospace; font-size: 10px; letter-spacing: 1.5px;
  color: rgba(255, 255, 255, 0.8); line-height: 1.9;
}
.foot-copy   { text-align: left; }
.foot-credit { text-align: right; }
/* wipe-underline: an ember rule sweeps in from the left on hover (transform, not a
   colour flip) — reads as deliberate motion rather than a static default link. */
.site-footer a { color: #fff; text-decoration: none; position: relative; pointer-events: none; }
#contact.show .site-footer a { pointer-events: auto; }   /* Medha link clickable at the finale */
.site-footer a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 1px;
  background: var(--ember); transform: scaleX(0); transform-origin: left center;
  transition: transform 0.42s var(--ease-glide);
}
.site-footer a:hover { color: var(--ember); }
.site-footer a:hover::after { transform: scaleX(1); }

@media (max-width: 560px) {
  /* stack the two credits so they don't collide on a narrow screen */
  .site-footer { flex-direction: column; align-items: center; gap: 2px; padding: 0 16px 12px; }
  .foot-copy, .foot-credit { text-align: center; }
}

@media (max-width: 720px) {
  /* reserve the footer's strip so the action buttons can never land on it,
     and slim the pills so all three fit one row on a 360px screen */
  #contact { padding-bottom: calc(84px + env(safe-area-inset-bottom, 0px)); }
  .contact-links { gap: 10px; margin-top: var(--sp-5); }
  .contact-link { padding: 10px 13px; font-size: 11px; letter-spacing: 1.2px; gap: 7px; }
  .contact-link svg { width: 15px; height: 15px; }
}
@media (max-width: 420px) {
  /* three pills must hold ONE row even at 360px */
  .contact-links { gap: 8px; }
  .contact-link { padding: 9px 11px; font-size: 10.5px; letter-spacing: 0.8px; gap: 6px; }
}

@media (prefers-reduced-motion: reduce) {
  .contact-kicker, .contact-head, .contact-sub, .contact-links, .site-footer { transition: opacity 0.5s var(--ease-veil); transform: none; }
}

/* ===========================================================================
   Phase 9 — mobile hamburger nav + no-WebGL fallback
   =========================================================================== */
#nav-burger { display: none; background: none; border: 0; color: var(--cream); font-size: 22px; line-height: 1; cursor: pointer; opacity: 0.85; }
@media (max-width: 900px) {
  /* phones AND tablets: five nav words don't fit — the hamburger opens the
     split-flap timetable instead. Raw links stay in the DOM (timetable rows
     proxy-click them) but never render. */
  #nav-burger { display: block; }
  #nav-links { display: none; }
}

#no-webgl { position: fixed; inset: 0; z-index: 500; display: flex; align-items: center; justify-content: center; padding: 24px; background: radial-gradient(ellipse at 50% 40%, #14283c, #070e16); }
#no-webgl[hidden] { display: none; }
.nw-inner { text-align: center; max-width: 480px; color: var(--cream); }
.nw-mark { font-family: 'Sacramento', cursive; font-size: 58px; color: var(--cream); }
.nw-inner p { font-size: 15px; line-height: 1.6; opacity: 0.82; margin: 14px 0 24px; }
.nw-cv { display: inline-block; font-family: 'Space Mono', monospace; font-size: 12px; letter-spacing: 2px; text-transform: uppercase; color: var(--cream); border: 1px solid rgba(245, 235, 220, 0.35); border-radius: 999px; padding: 12px 22px; text-decoration: none; }
.nw-cv:hover { border-color: var(--ember); color: var(--ember); }
.nw-links { display: flex; gap: 18px; justify-content: center; margin-top: 22px; }
.nw-links a { font-family: 'Space Mono', monospace; font-size: 11px; letter-spacing: 2px; text-transform: uppercase; color: var(--haze); text-decoration: none; }
.nw-links a:hover { color: var(--ember); }

/* ---- Small screens (and tablets — everything below the burger breakpoint) ---- */
@media (max-width: 900px) {
  #nav { padding: var(--sp-3) var(--sp-4); }
  #nav-links { gap: var(--sp-3); margin-right: 0; }   /* dropdown is absolute here — no reserve */
  #nav-links a, #nav-links button { font-size: 10px; letter-spacing: 1px; }
  .sig-mask { width: 60px; height: 34px; }
  #loader-sig { width: 230px; }
  #nav-burger { margin-left: auto; }   /* keep the menu toggle hard right */
  /* the sound toggle lives bottom-left on small screens, clear of the hamburger menu */
  #mute-btn { top: auto; right: auto; bottom: 16px; left: 16px; z-index: 30; }
}

/* ============================================================================
   Newspaper article overlay (Scenes 2–3) — news.js drives opacity/blur/turn.
   ============================================================================ */
#news-overlay {
  position: fixed; inset: 0; z-index: 45; display: none;
  pointer-events: none; opacity: 0;
  will-change: opacity, filter;
  /* keep the dark world faintly behind the paper */
  background: radial-gradient(120% 120% at 50% 40%, rgba(10,16,26,0.35), rgba(6,9,16,0.78));
}
.news-vignette {
  position: absolute; inset: 0; pointer-events: none;
  box-shadow: inset 0 0 240px 60px rgba(6,8,14,0.85);
}
.news-wrap {
  position: absolute; left: 50%; top: 50%;
  width: min(92vw, 980px); height: min(92vh, 760px);
  transform: translate(-50%, -50%);
  margin: 0; /* JS sets translate/scale on an inner transform via the element below */
  perspective: 2400px;
}
/* JS targets .news-wrap transform, so wrap the centering on a parent */
#news-overlay > .news-wrap { left: 50%; top: 50%; }

.news-page {
  position: absolute; inset: 0;
  transform-origin: left center; backface-visibility: hidden;
  display: block; overflow: hidden;
  padding: 30px 40px 26px;
  color: #211a10; isolation: isolate;
  background:
    radial-gradient(140% 90% at 50% 0%, rgba(252,244,208,0.85), rgba(0,0,0,0) 60%),
    repeating-linear-gradient(0deg, rgba(120,96,60,0.045) 0 2px, rgba(0,0,0,0) 2px 4px),
    linear-gradient(160deg, #ecdcac 0%, #e3d29a 55%, #d6c288 100%);   /* warmer aged newsprint (matches the 3D paper) */
  box-shadow: 0 30px 80px rgba(0,0,0,0.55), inset 0 0 0 1px rgba(120,96,60,0.25),
              inset 0 0 70px rgba(120,96,60,0.18);
  /* torn / worn edge */
  -webkit-mask-image: radial-gradient(circle at 1px 1px, #000 99%, transparent 100%);
  border-radius: 2px;
}
.news-page.page-under { z-index: 1; }
.news-page.page-top   { z-index: 2; }
.news-page::after { /* foxing / stain mottle */
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: -1; opacity: 0.5;
  background:
    radial-gradient(60px 40px at 18% 88%, rgba(126,92,46,0.16), transparent 70%),
    radial-gradient(90px 60px at 86% 14%, rgba(126,92,46,0.13), transparent 70%),
    radial-gradient(50px 50px at 70% 80%, rgba(96,70,40,0.10), transparent 70%);
}

.nm-head { text-align: center; }
.nm-rule { height: 3px; background: #211a10; margin: 2px 0; }
.nm-rule.thin { height: 1px; }
.nm-top { display: flex; justify-content: space-between; font-family: 'Space Mono', monospace;
  font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; padding: 5px 2px 6px; color: #4a3a22; }
.nm-name { font-family: 'Fraunces', Georgia, serif; font-weight: 600; font-size: clamp(30px, 5vw, 52px);
  letter-spacing: 0.01em; margin: 4px 0 6px; line-height: 1; color: #1a140c; }

.na-kicker { font-family: 'Space Mono', monospace; font-size: 11px; letter-spacing: 0.32em;
  text-transform: uppercase; color: #8a3b1e; margin-top: 12px; }
.na-headline { font-family: 'Fraunces', Georgia, serif; font-weight: 600;
  font-size: clamp(28px, 4.6vw, 50px); line-height: 1.02; margin: 4px 0 6px; color: #15100a; }
.na-byline { font-family: 'Fraunces', serif; font-style: italic; font-size: 13px; color: #5a4630; }
.na-rule.thin { height: 1px; background: #211a10; opacity: 0.55; margin: 10px 0; }

.na-figure { float: right; width: 38%; margin: 2px 0 10px 18px; }
.na-figure img { width: 100%; display: block; border: 1px solid rgba(33,26,16,0.5);
  filter: sepia(0.32) contrast(1.06) brightness(0.94) grayscale(0.18); }
.na-figure figcaption { font-family: 'Space Mono', monospace; font-size: 9.5px; letter-spacing: 0.06em;
  text-transform: uppercase; color: #5a4630; padding-top: 5px; }

.na-body { columns: 2; column-gap: 26px; column-rule: 1px solid rgba(33,26,16,0.22);
  font-family: 'Fraunces', Georgia, serif; font-size: 13.5px; line-height: 1.5; text-align: justify;
  color: #271e12; overflow: hidden; }
.na-body p { margin: 0 0 9px; }
.na-body p.drop::first-letter { font-weight: 600; font-size: 3.1em; line-height: 0.78;
  float: left; padding: 4px 7px 0 0; color: #15100a; }
.na-body strong { font-weight: 600; }

@media (max-width: 620px) {
  .news-page { padding: 22px 20px; }
  .na-body { columns: 1; }
  .na-figure { width: 46%; }
}

/* ---- Wind streaks (newspaper fly-in) ----------------------------------- */
#wind-streaks {
  position: fixed; inset: 0; z-index: 44;
  width: 100vw; height: 100vh;
  pointer-events: none; opacity: 0;
  transition: opacity 0.25s var(--ease-veil);
  mix-blend-mode: screen;
}

/* ---- Board-the-train prompt (Scene 4) ---------------------------------- */
#board-prompt {
  position: fixed; left: 50%; top: 50%;
  transform: translate(-50%, calc(-50% + 12px));
  z-index: 46; pointer-events: none;
  opacity: 0; filter: blur(8px);
  will-change: opacity, filter, transform;
  text-align: center;
  /* opacity & filter are driven directly by scroll (no time-lag); only the
     translate eases, so it dissolves in place without trailing into the next beat */
  transition: transform 0.8s cubic-bezier(0.23,1,0.32,1);
}
#board-prompt.show { transform: translate(-50%, -50%); }
#board-prompt span {
  display: inline-block;
  font-family: 'Fraunces', Georgia, serif;
  font-weight: 600;
  font-size: clamp(26px, 4.4vw, 50px);
  letter-spacing: 0.01em;
  color: var(--cream);
  text-shadow: 0 2px 30px rgba(0,0,0,0.6);
}
#board-prompt::after {
  content: ""; display: block; width: 0; height: 1px; margin: 14px auto 0;
  background: linear-gradient(90deg, transparent, var(--firefly), transparent);
  transition: width 0.9s cubic-bezier(0.23,1,0.32,1);
}
#board-prompt.show { opacity: 1; filter: blur(0); }
#board-prompt.show::after { width: 230px; }

/* ---- Article redesign: B&W grain, front-page grid, sidebar, poster ------- */
img.bw, .bw img { filter: grayscale(1) contrast(1.14) brightness(0.9); }
.na-figure.bw, .poster-stage, .poster-hero, .poster-inset { position: relative; }
.na-figure.bw::after, .poster-grain::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  mix-blend-mode: multiply; opacity: 0.42; z-index: 2;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)' opacity='0.6'/%3E%3C/svg%3E");
  background-size: 200px 200px;
}

/* --- Front page (Who is Poonno): main column + filler sidebar --- */
.np-frontgrid { display: grid; grid-template-columns: 1.9fr 1fr; gap: 26px;
  margin-top: 10px; height: calc(100% - 96px); }
.np-main { min-width: 0; display: flex; flex-direction: column; }
.na-headline.xl { font-size: clamp(34px, 5.4vw, 62px); margin: 2px 0 4px; }
.na-figure.big { float: none; width: 100%; margin: 10px 0 12px; }
.na-figure.big img { width: 100%; height: 32vh; max-height: 300px; object-fit: cover;
  border: 1px solid rgba(33,26,16,0.55); }
.na-body.two { columns: 2; column-gap: 24px; flex: 1; }

.np-side { border-left: 1px solid rgba(33,26,16,0.35); padding-left: 20px;
  display: flex; flex-direction: column; }
.side-item { padding-bottom: 13px; margin-bottom: 13px; border-bottom: 1px solid rgba(33,26,16,0.2); }
.side-kick { font-family: 'Space Mono', monospace; font-size: 9px; letter-spacing: 0.22em;
  text-transform: uppercase; color: #8a3b1e; }
.side-item h3 { font-family: 'Fraunces', serif; font-weight: 600; font-size: 19px;
  margin: 3px 0 5px; color: #15100a; line-height: 1.08; }
.side-item p { font-family: 'Fraunces', serif; font-size: 12px; line-height: 1.46; color: #34291b; margin: 0; }
.side-rule { height: 2px; background: #211a10; margin: 2px 0 10px; }
.side-foot { font-family: 'Fraunces', serif; font-style: italic; font-size: 13px; color: #5a4630; margin: 0; }

/* --- Basketball POSTER (page 2) --- */
.news-page.poster { padding: 0; overflow: hidden;
  display: flex; flex-direction: column;
  background:
    radial-gradient(120% 70% at 50% 0%, rgba(255,252,243,0.85), rgba(0,0,0,0) 55%),
    linear-gradient(165deg, #ece2cb, #ddcdaa 70%, #cdb98f); }
.poster-skew { position: absolute; top: 16px; left: -8px; z-index: 5;
  background: #1a140c; color: #f0e6cf; transform: rotate(-3.5deg);
  font-family: 'Fraunces', serif; font-weight: 600; font-style: italic; font-size: 15px;
  padding: 6px 16px; box-shadow: 3px 4px 0 rgba(0,0,0,0.25); }
.poster-top { text-align: center; padding: 16px 30px 4px; }
.poster-kick { font-family: 'Space Mono', monospace; font-size: 10px; letter-spacing: 0.3em;
  text-transform: uppercase; color: #8a3b1e; }
.poster-head { font-family: 'Fraunces', Georgia, serif; font-weight: 600; text-transform: uppercase;
  font-size: clamp(28px, 4.8vw, 54px); line-height: 0.9; color: #14100a; letter-spacing: -0.01em; margin: 4px 0 0; }
.poster-head span { color: #8a3b1e; }

.poster-stage { position: relative; flex: 1; margin: 6px 24px 0; min-height: 0; }
.poster-hero { position: absolute; left: 50%; bottom: 0; transform: translateX(-52%);
  height: 100%; width: auto; max-width: 64%; object-fit: contain; object-position: bottom;
  filter: grayscale(1) contrast(1.18) brightness(0.92) drop-shadow(0 10px 24px rgba(0,0,0,0.4)); }
.poster-inset { position: absolute; width: 27%; aspect-ratio: 1/1; object-fit: cover;
  border: 3px solid #f3ebd8; box-shadow: 0 6px 18px rgba(0,0,0,0.4); }
.poster-inset.a { left: 0; top: 8%; transform: rotate(-3deg); }
.poster-inset.b { right: 0; top: 26%; transform: rotate(3deg); }
.poster-name { position: absolute; left: 0; right: 0; bottom: 12%; text-align: center; z-index: 4;
  font-family: 'Fraunces', serif; font-weight: 600; font-size: clamp(26px, 4.6vw, 52px);
  color: #f3ead4; text-shadow: 0 3px 10px rgba(0,0,0,0.7); letter-spacing: 0.02em; }
.poster-name span { color: #e0a14a; font-size: 0.5em; }
.poster-sub { position: absolute; left: 0; right: 0; bottom: 8%; text-align: center; z-index: 4;
  font-family: 'Space Mono', monospace; font-size: 10px; letter-spacing: 0.32em; color: #f0e6cf; }

.poster-bottom { display: grid; grid-template-columns: 1fr 1fr 1.5fr; gap: 18px;
  padding: 12px 30px 18px; border-top: 2px solid #1a140c; margin: 8px 24px 0; }
.poster-col .pc-h { font-family: 'Space Mono', monospace; font-size: 9.5px; letter-spacing: 0.2em;
  text-transform: uppercase; color: #8a3b1e; margin-bottom: 5px; }
.poster-col p { font-family: 'Fraunces', serif; font-size: 12px; line-height: 1.4; color: #2a2012; margin: 0; }
.poster-col.wide p { font-style: italic; }

@media (max-width: 700px) {
  .np-frontgrid { grid-template-columns: 1fr; } .np-side { display: none; }
  .poster-bottom { grid-template-columns: 1fr; gap: 6px; }
}

/* ---- Display typography (Noomo-esque: The Seasons → Cormorant Garamond) --- */
:root { --font-display: 'Cormorant Garamond', 'Fraunces', Georgia, serif; }

/* ---- Station-approach announcement (#12) -------------------------------- */
#station-overlay {
  position: fixed; inset: 0; z-index: 47; display: none;
  align-items: center; justify-content: center;
  pointer-events: none; opacity: 0; will-change: opacity, filter;
  background: radial-gradient(130% 130% at 50% 50%, rgba(6,10,16,0.5), rgba(3,6,11,0.9));
}
.so-inner { text-align: center; max-width: 780px; padding: 0 var(--sp-6); }
.so-kick { font-family: 'Space Mono', monospace; font-size: var(--fs-ui); letter-spacing: 0.42em;
  text-transform: uppercase; color: var(--firefly); opacity: 0.85; margin-bottom: var(--sp-4); }
.so-name { font-family: var(--font-display); font-weight: 500;
  font-size: clamp(42px, 7.5vw, 92px); line-height: 0.98; color: var(--cream);
  margin: 0 0 var(--sp-4); letter-spacing: 0.005em; }
.so-tag { font-family: 'Cormorant Garamond', serif; font-style: italic;
  font-size: clamp(17px, 2.3vw, 24px); color: rgba(245,235,220,0.8); margin: 0 0 var(--sp-6); }
.so-explore span { font-family: 'Inter', sans-serif; font-size: 12px; letter-spacing: 0.32em;
  text-transform: uppercase; color: var(--cream); }
.so-explore::after { content: ""; display: block; height: 1px; width: 0; margin: 12px auto 0;
  background: linear-gradient(90deg, transparent, var(--firefly), transparent);
  transition: width 0.9s cubic-bezier(0.23,1,0.32,1); }
#station-overlay.show .so-explore::after { width: 210px; }

/* Apply the elegant display serif to the hero moments */
.nm-name, .so-name, #board-prompt span, .contact-head { font-family: var(--font-display) !important; font-weight: 500; }
.poster-head, .na-headline.xl { font-family: var(--font-display); font-weight: 600; }

/* basketball article side lists (simple news style) */
.side-kick { font-family: 'Space Mono', monospace; font-size: 9.5px; letter-spacing: 0.22em;
  text-transform: uppercase; color: #8a3b1e; margin-bottom: 5px; }
.na-list { margin: 3px 0 0; padding-left: 15px; font-family: 'Fraunces', Georgia, serif;
  font-size: 12.5px; line-height: 1.5; color: #2f2517; }
.na-list li { margin: 0 0 4px; }

/* ---- Article reading guide (next + scroll hint) ------------------------ */
#read-guide {
  position: fixed; left: 50%; bottom: 40px; transform: translateX(-50%);
  z-index: 47; display: flex; flex-direction: column; align-items: center; gap: 9px;
  opacity: 0; pointer-events: none;
  transition: opacity 0.7s var(--ease-glide);
}
#read-guide.show { opacity: 1; }
/* Printed straight ON the paper — dark ink, no chrome. A faint light halo keeps
   it legible if it ever grazes the dark strip below the page. */
#read-guide .rg-label {
  font-family: 'Space Mono', monospace; font-size: 11px; letter-spacing: 0.34em;
  text-transform: uppercase; color: #3a2c14; opacity: 0.85;
  text-shadow: 0 1px 2px rgba(250, 244, 220, 0.5);
}
#read-next {
  pointer-events: auto; cursor: pointer;
  width: 40px; height: 40px; border-radius: 50%;
  background: transparent; border: 1.5px solid rgba(58, 44, 20, 0.42);
  color: #3a2c14; display: grid; place-items: center;
  transition: transform 0.18s var(--ease-glide), background 0.25s var(--ease-glide), border-color 0.25s var(--ease-glide);
  animation: rgbob 2.2s ease-in-out infinite;
}
#read-next svg { display: block; }
#read-next:hover { background: rgba(58, 44, 20, 0.10); border-color: rgba(58, 44, 20, 0.7); }
#read-next:active { transform: scale(0.94); }
@keyframes rgbob { 0%,100% { translate: 0 0; } 50% { translate: 0 4px; } }

/* ===========================================================================
   Article layout v2 — responsive multi-column flow that fits the FULL text.
   Overrides the earlier fixed-grid article rules.
   =========================================================================== */
.news-wrap { width: min(94vw, 1120px); height: min(92vh, 900px); }
.news-page { display: flex !important; flex-direction: column; padding: clamp(16px, 2.4vw, 36px); overflow: hidden; }

.np-cols {
  flex: 1 1 auto; min-height: 0; margin-top: 8px;
  columns: 3; column-gap: clamp(15px, 1.6vw, 26px); column-rule: 1px solid rgba(33,26,16,0.16);
  font-family: 'Fraunces', Georgia, serif; font-size: clamp(10px, 0.92vw, 12.5px); line-height: 1.42;
  text-align: justify; color: #2a2114; overflow: hidden;
}
@media (min-width: 1200px) { .np-cols { columns: 4; } }
.np-cols > .na-kicker, .np-cols > .na-headline, .np-cols > .na-byline, .np-cols > .na-hr { column-span: all; break-inside: avoid; }
.np-cols .na-kicker { font-family: 'Space Mono', monospace; font-size: 10px; letter-spacing: 0.3em; text-transform: uppercase; color: #8a3b1e; margin-top: 4px; }
.np-cols .na-headline { font-family: var(--font-display); font-weight: 500; font-size: clamp(28px, 4.4vw, 56px); line-height: 1.0; margin: 3px 0 4px; color: #15100a; }
.np-cols .na-byline { font-family: 'Fraunces', serif; font-style: italic; font-size: 13px; color: #5a4630; }
.np-cols .na-hr { height: 1px; background: rgba(33,26,16,0.5); margin: 9px 0; }
.np-cols p { margin: 0 0 7px; }
.np-cols p.drop::first-letter { font-family: var(--font-display); font-weight: 600; font-size: 3em; line-height: 0.78; float: left; padding: 4px 6px 0 0; color: #15100a; }
.np-cols .na-figure { float: none; width: 100%; margin: 0 0 9px; break-inside: avoid; }
.np-cols .na-figure img { width: 100%; height: auto; display: block; border: 1px solid rgba(33,26,16,0.5); }
.np-cols .na-figure figcaption { font-family: 'Space Mono', monospace; font-size: 8.5px; letter-spacing: 0.05em; text-transform: uppercase; color: #5a4630; padding-top: 4px; }
.np-cols .sidebar { break-inside: avoid; border-top: 2px solid #23190f; padding-top: 7px; margin: 5px 0 9px; }
.np-cols .sidebar h4 { font-family: var(--font-display); font-weight: 500; font-size: 16px; margin: 3px 0 3px; color: #15100a; line-height: 1.05; }
.np-cols .sidebar p { font-size: 11px; }
.np-cols .na-list { margin: 3px 0 0; padding-left: 14px; }
.np-cols .na-list li { margin: 0 0 3px; }

@media (max-width: 900px) { .np-cols { columns: 2; font-size: 11.5px; } }
/* Phones: a single readable column that SCROLLS INSIDE the sheet. The journey is
   parked while reading (lenis stopped), so the page owns the touch; the bobbing
   ↓ button turns the page. Without this, everything past the fold was clipped
   invisible (overflow: hidden) — most of the article was unreadable on mobile. */
@media (max-width: 740px) {
  .news-wrap { width: 96vw; height: 94vh; }
  .np-cols {
    /* columns:auto (NOT 1): any multicol context overflows into hidden
       side-columns instead of scrolling vertically */
    columns: auto; column-rule: none;
    font-size: 13.5px; line-height: 1.55; text-align: left;
    overflow-y: auto; -webkit-overflow-scrolling: touch; touch-action: pan-y;
    overscroll-behavior: contain;
    pointer-events: auto;
    padding-bottom: 108px;  /* last lines clear the reading-guide pill */
    /* the swipe itself moves the article now — no visible scrollbar rail */
    scrollbar-width: none;              /* Firefox */
    -ms-overflow-style: none;           /* old Edge */
  }
  .np-cols::-webkit-scrollbar { width: 0; height: 0; display: none; }  /* WebKit */
  .np-cols .na-headline { font-size: clamp(30px, 9vw, 44px); }
  .np-cols .na-byline { font-size: 12px; }
  .np-cols p { margin: 0 0 10px; }
  .na-list { font-size: 13px; }

  /* Reading guide: keep it on ONE line, centred, and legible over the text so it
     never overlaps or wraps on narrow screens */
  #read-guide { bottom: 16px; gap: 8px; max-width: 92vw; }
  #read-guide .rg-label {
    white-space: nowrap; font-size: 10px; letter-spacing: 0.2em;
    padding: 6px 14px; border-radius: 999px;
    background: rgba(250, 244, 220, 0.82); backdrop-filter: blur(4px);
    box-shadow: 0 1px 8px rgba(0, 0, 0, 0.16); text-shadow: none;
  }
  #read-next { width: 36px; height: 36px; }
}


/* ============================================================================
   DEPARTURES — the split-flap station board: a physical black Solari board
   HANGING ON THE STATION WALL (a CSS3D plane driven by the scene camera —
   js/departures.js). White paint on black steel flaps, like the real thing;
   it hangs dormant and dark until the camera settles square on it.
   ============================================================================ */
/* #dep3d is the CSS3DRenderer layer (fixed, full screen, pointer-events:none
   — set inline by departures.js); only the board itself takes the pointer */
#dep3d .depb { pointer-events: auto; }

/* ---- the physical housing: old blackened steel, decades on the wall ---- */
.depb {
  position: relative; width: 1120px;
  padding: 26px 30px 18px;
  background:
    /* corner bolts, dulled by grime */
    radial-gradient(circle at 13px 13px, #303336 0 2.4px, rgba(0,0,0,0) 3.4px),
    radial-gradient(circle at calc(100% - 13px) 13px, #303336 0 2.4px, rgba(0,0,0,0) 3.4px),
    radial-gradient(circle at 13px calc(100% - 13px), #2a2c2f 0 2.4px, rgba(0,0,0,0) 3.4px),
    radial-gradient(circle at calc(100% - 13px) calc(100% - 13px), #2a2c2f 0 2.4px, rgba(0,0,0,0) 3.4px),
    /* uneven decades-old sheen: one tired highlight, smoke stains pooling low */
    linear-gradient(115deg, rgba(255,255,255,0.025) 0%, transparent 32%),
    radial-gradient(58% 42% at 12% 102%, rgba(0,0,0,0.55), transparent 72%),
    radial-gradient(52% 40% at 89% 98%, rgba(0,0,0,0.48), transparent 70%),
    radial-gradient(38% 30% at 72% -6%, rgba(0,0,0,0.35), transparent 70%),
    linear-gradient(180deg, #0c0d0e 0%, #08090a 44%, #040505 100%);
  border: 1px solid #000;
  border-radius: 4px;
  box-shadow:
    inset 0 0 0 2px #141517,
    inset 0 1px 0 rgba(255,255,255,0.045),
    inset 0 -24px 54px rgba(0,0,0,0.66),
    0 14px 40px rgba(0,0,0,0.72);
  /* fixed cell metrics — a physical object; PERSPECTIVE sizes it on screen */
  --sf-w: 18px;
  --sf-h: 27px;
  --sf-fs: 20px;
  /* dormant: the board's lamps are off until the camera arrives (.lit) */
  filter: brightness(0.4) saturate(0.85);
  transition: filter 1.2s ease;
}
.depb.lit { filter: none; }
/* while a case study is open the board recedes so the panel owns the light */
.depb.reading, .depb.lit.reading { filter: brightness(0.16) saturate(0.8); }
/* patina veil over the whole face (flaps included): dust film thickening at the
   edges, a faint diagonal wipe where someone once cleaned it */
.depb::after {
  content: ''; position: absolute; inset: 0; z-index: 9; pointer-events: none;
  border-radius: inherit;
  background:
    linear-gradient(168deg, transparent 42%, rgba(20,18,14,0.05) 58%, transparent 74%),
    radial-gradient(130% 105% at 50% -4%, transparent 58%, rgba(0,0,0,0.30) 100%);
}

/* ---- header strip: DEPARTURES flaps + painted station name ---- */
.dep-head {
  display: flex; align-items: center; gap: 14px;
  padding: 0 2px 12px;
  border-bottom: 1px solid rgba(255,255,255,0.08);
  margin-bottom: 14px;
}
.dep-head-station {
  margin-left: auto;
  font-family: 'Space Mono', monospace; font-size: 12px;
  letter-spacing: 0.34em; text-transform: uppercase; color: rgba(223,217,204,0.52);
  white-space: nowrap;
}

/* ---- flap cells: black steel flaps, white paint ---- */
.sf-line { display: inline-flex; gap: calc(var(--sf-w) * 0.14); }
.sf {
  position: relative; display: inline-block;
  width: var(--sf-w); height: var(--sf-h);
  border-radius: calc(var(--sf-w) * 0.12);
  background: #050607;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.8), 0 1px 0 rgba(255,255,255,0.02);
  perspective: calc(var(--sf-h) * 4);
  font-family: 'Space Mono', monospace; font-weight: 700;
  font-size: var(--sf-fs); color: #DFD9CC;   /* old white paint, yellowed by years */
  /* analog imperfection: each cartridge sits a hair off true (set per-cell in js) */
  transform: translateY(var(--jy, 0)) rotate(var(--jr, 0deg));
}
.sf > span {
  position: absolute; left: 0; width: 100%; height: 50%; overflow: hidden;
  background: linear-gradient(180deg, #121417 0%, #0a0c0e 100%);
  border-radius: calc(var(--sf-w) * 0.12) calc(var(--sf-w) * 0.12) 0 0;
}
.sf-a, .sf-c { top: 0; }
.sf-b, .sf-d {
  bottom: 0; border-radius: 0 0 calc(var(--sf-w) * 0.12) calc(var(--sf-w) * 0.12);
  background: linear-gradient(180deg, #0a0b0d 0%, #040506 100%);
}
.sf i {
  position: absolute; left: 0; top: 0; width: 100%; height: var(--sf-h);
  line-height: var(--sf-h); font-style: normal; text-align: center;
}
.sf-b i, .sf-d i { top: calc(var(--sf-h) * -0.5); }
/* the hinge line across the middle — shadow above, worn highlight below */
.sf::after {
  content: ''; position: absolute; left: 0; right: 0; top: 50%; height: 2px;
  background: linear-gradient(180deg, rgba(0,0,0,0.85), rgba(255,255,255,0.05));
  transform: translateY(-1px); z-index: 4;
}
/* animating halves sit above the statics; GPU-composited rotation only */
.sf-c { z-index: 3; transform-origin: 50% 100%; backface-visibility: hidden; will-change: transform; }
.sf-d { z-index: 3; transform-origin: 50% 0%; transform: rotateX(90deg); backface-visibility: hidden; will-change: transform; }

/* cell variants — all white paint, only intensity varies (ref: Solari board) */
.sf-amber .sf { color: #EFEAE0; }
.sf-dim .sf { color: rgba(223,217,204,0.45); }

/* ---- departure rows ---- */
.dep-rows { display: flex; flex-direction: column; gap: 9px; }
.dep-row {
  display: flex; flex-direction: column; gap: 5px;
  padding: 4px 8px;
  margin: 0 -8px;
  background: transparent; border: 0; border-radius: 3px;
  cursor: pointer; text-align: left;
  transition: background 0.35s ease, box-shadow 0.35s ease;
}
.dep-l1, .dep-l2 { display: flex; align-items: center; gap: calc(var(--sf-w) * 0.9); }
/* the "called" row — the row lamp behind the flaps warms up */
.dep-row.called {
  background: rgba(255,250,240,0.05);
  box-shadow: inset 0 0 0 1px rgba(255,250,240,0.13), 0 0 30px rgba(255,248,235,0.06);
}
.dep-row.called .sf { color: #FFFFFF; text-shadow: 0 0 12px rgba(255,250,238,0.42); }
.dep-row:focus-visible { outline: 1px solid rgba(255,255,255,0.45); outline-offset: 2px; }

/* ---- footer: etched maker's plate ---- */
.dep-foot {
  margin-top: 12px; padding-top: 9px;
  border-top: 1px solid rgba(255,255,255,0.06); text-align: center;
}
.dep-foot-hint {
  font-family: 'Space Mono', monospace; font-size: 10px;
  letter-spacing: 0.3em; text-transform: uppercase; color: rgba(223,217,204,0.3);
}

/* ---- narrow screens: the wall board is the folded two-line variant ---- */
.depb.m {
  width: 460px; padding: 20px 20px 14px;
  /* cells shrunk so the longest headline clears the board edges (matches board3d.js) */
  --sf-w: 16px; --sf-h: 24px; --sf-fs: 18px;
}
.depb.m .dep-l2 { --sf-w: 12px; --sf-h: 18px; --sf-fs: 13px; padding-left: 3px; }
.depb.m .dep-rows { gap: 12px; }
.depb.m .dep-head { flex-wrap: wrap; row-gap: 6px; }
.depb.m .dep-head-station { width: 100%; margin-left: 0; text-align: left; font-size: 10px; letter-spacing: 0.26em; }
.depb.m .dep-foot-hint { font-size: 9px; letter-spacing: 0.22em; }

/* ============================================================================
   DEP-DETAIL — the case study panel (opened from a departure row). The site's
   editorial reading panel: deep receding field, soft accent glow lower-left,
   the copy in a right-hand column. (Restored pre-rework design.)
   ============================================================================ */
#dep-detail {
  position: fixed; inset: 0; z-index: 48; pointer-events: none;
  opacity: 0; transition: opacity 0.55s cubic-bezier(0.23,1,0.32,1);
  --accent: #F4A259;
  background:
    radial-gradient(64% 74% at 24% 70%, color-mix(in srgb, var(--accent) 22%, transparent), transparent 62%),
    radial-gradient(90% 120% at 16% 50%, rgba(4,7,12,0.6) 0%, rgba(4,7,12,0.86) 46%, rgba(4,7,12,0.97) 100%),
    linear-gradient(180deg, rgba(4,7,12,0.5), rgba(2,4,8,0.84));
}
#dep-detail.show { opacity: 1; pointer-events: auto; }
#dep-detail .cd-close {
  position: absolute; top: 26px; right: 30px; width: 44px; height: 44px;
  z-index: 5;                       /* above .cd-scroll, whose transparent top would eat the click */
  border: 1px solid rgba(245,235,220,0.28); border-radius: 50%;
  background: rgba(8,12,18,0.4); color: var(--cream); font-size: 22px; line-height: 1;
  cursor: pointer; backdrop-filter: blur(6px); transition: border-color 0.3s, transform 0.3s;
}
#dep-detail .cd-close:hover { border-color: var(--accent); transform: rotate(90deg); }
#dep-detail .cd-scroll {
  position: absolute; top: 0; right: 0; height: 100%; z-index: 1;
  width: min(46vw, 560px); padding: 12vh 6vw 10vh 3vw;
  overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  transform: translateX(40px); transition: transform 0.6s cubic-bezier(0.23,1,0.32,1);
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 7vh, #000 90%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0, #000 7vh, #000 90%, transparent 100%);
}
#dep-detail.show .cd-scroll { transform: none; }
#dep-detail .cd-kicker { font-family: 'Space Mono', monospace; font-size: 12px; letter-spacing: 0.32em; text-transform: uppercase; color: var(--accent); opacity: 0.9; }
#dep-detail .cd-brand { font-family: var(--font-display); font-weight: 600; font-size: clamp(34px, 4.6vw, 60px); line-height: 1.0; color: var(--cream); margin: 14px 0 6px; }
#dep-detail .cd-titletxt { font-family: 'Cormorant Garamond', serif; font-style: italic; font-size: clamp(18px, 2vw, 23px); color: rgba(245,235,220,0.78); }
#dep-detail .cd-rule { height: 1px; width: 64px; margin: 24px 0; background: linear-gradient(90deg, var(--accent), transparent); }
#dep-detail .cd-block { margin: 0 0 26px; max-width: 46ch; }
#dep-detail .cd-label { font-family: 'Space Mono', monospace; font-size: 11px; letter-spacing: 0.28em; text-transform: uppercase; color: rgba(245,235,220,0.5); margin-bottom: 8px; }
#dep-detail .cd-block p { font-family: 'Inter', sans-serif; font-size: 15px; line-height: 1.62; color: rgba(245,235,220,0.86); margin: 0; }
#dep-detail .cd-tools { display: flex; flex-wrap: wrap; gap: 8px; }
#dep-detail .cd-tool { font-family: 'Space Mono', monospace; font-size: 11px; letter-spacing: 0.05em; color: rgba(245,235,220,0.82); border: 1px solid rgba(245,235,220,0.2); border-radius: 999px; padding: 6px 12px; }
#dep-detail .cd-links { display: flex; flex-direction: column; gap: 10px; margin-top: 30px; }
#dep-detail .cd-link {
  display: inline-flex; align-items: center; justify-content: space-between; gap: 14px;
  font-family: 'Space Mono', monospace; font-size: 13px; letter-spacing: 0.06em; text-decoration: none;
  color: var(--cream); border: 1px solid rgba(245,235,220,0.22); border-radius: 10px;
  padding: 14px 18px; transition: border-color 0.3s, background 0.3s, transform 0.3s;
}
#dep-detail .cd-link span { color: var(--accent); font-size: 16px; }
#dep-detail .cd-link:hover { border-color: var(--accent); background: rgba(244,162,89,0.07); transform: translateX(4px); }
/* "scroll to exit" guide — thin rail with a gentle drift */
#dep-detail .cd-exit-hint {
  position: absolute; left: 6vw; bottom: 6vh; display: flex; align-items: center; gap: 12px;
  font-family: 'Space Mono', monospace; font-size: 11px; letter-spacing: 0.26em; text-transform: uppercase;
  color: rgba(245,235,220,0.45); opacity: 0; transition: opacity 0.8s ease, color 0.8s ease; pointer-events: none;
}
#dep-detail .cd-exit-rail { position: relative; width: 22px; height: 34px; border: 1px solid rgba(245,235,220,0.4); border-radius: 11px; }
#dep-detail .cd-exit-rail::after {
  content: ''; position: absolute; left: 50%; top: 7px; width: 3px; height: 6px; border-radius: 2px;
  background: var(--accent); transform: translateX(-50%); animation: cdExitDrift 1.9s ease-in-out infinite;
}
@keyframes cdExitDrift { 0%,100% { transform: translate(-50%, 0); opacity: 0.4; } 50% { transform: translate(-50%, 12px); opacity: 1; } }
#dep-detail.show .cd-exit-hint { opacity: 0.55; }
#dep-detail.show.hint-on .cd-exit-hint { opacity: 0.95; color: rgba(245,235,220,0.72); }
@media (prefers-reduced-motion: reduce) { #dep-detail .cd-exit-rail::after { animation: none; } }
@media (max-width: 760px) {
  #dep-detail .cd-close { top: 14px; right: 14px; width: 40px; height: 40px; }
  #dep-detail .cd-exit-hint { left: 50%; transform: translateX(-50%); bottom: 4vh; }
  #dep-detail .cd-scroll { width: 100vw; padding: 14vh 8vw 12vh; }
  /* small screens read the copy over the full frame — the world behind must
     recede almost completely or the text fights the scene */
  #dep-detail {
    background:
      radial-gradient(80% 50% at 50% 110%, color-mix(in srgb, var(--accent) 14%, transparent), transparent 70%),
      linear-gradient(180deg, rgba(3,5,9,0.94), rgba(2,3,6,0.985));
  }
}

/* ============================================================================
   FLAP-MENU — the mobile nav as a full-screen split-flap station timetable
   (opened by the hamburger; rows proxy the real nav links)
   ============================================================================ */
#flap-menu {
  position: fixed; inset: 0; z-index: 19;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; pointer-events: none;
  transition: opacity 0.45s cubic-bezier(0.23,1,0.32,1);
  background:
    radial-gradient(120% 90% at 50% 40%, rgba(5,8,12,0.88) 0%, rgba(3,5,8,0.97) 100%);
}
#flap-menu.show { opacity: 1; pointer-events: auto; }
/* transient journey hints must not bleed through the open menu */
body.fm-open #board-prompt, body.fm-open #whistle-hint, body.fm-open #scroll-hint,
body.fm-open #station-overlay, body.fm-open #read-guide { opacity: 0 !important; }
#flap-menu .fm-board {
  /* 19 cells + gaps + padding must fit INSIDE the board (min(92vw,460px)) */
  --sf-w: clamp(11px, calc((min(92vw, 460px) - 96px) / 22.4), 20px);
  --sf-h: calc(var(--sf-w) * 1.5);
  --sf-fs: calc(var(--sf-h) * 0.74);
  position: relative;
  width: min(92vw, 460px);
  padding: 22px 20px 16px;
  /* SAME worn black steel as the station board (.depb): corner bolts, tired
     sheen, smoke stains pooling low, deep black base — not a grey modal. */
  background:
    radial-gradient(circle at 13px 13px, #303336 0 2.4px, rgba(0,0,0,0) 3.4px),
    radial-gradient(circle at calc(100% - 13px) 13px, #303336 0 2.4px, rgba(0,0,0,0) 3.4px),
    radial-gradient(circle at 13px calc(100% - 13px), #2a2c2f 0 2.4px, rgba(0,0,0,0) 3.4px),
    radial-gradient(circle at calc(100% - 13px) calc(100% - 13px), #2a2c2f 0 2.4px, rgba(0,0,0,0) 3.4px),
    linear-gradient(115deg, rgba(255,255,255,0.025) 0%, transparent 32%),
    radial-gradient(58% 42% at 12% 102%, rgba(0,0,0,0.55), transparent 72%),
    radial-gradient(52% 40% at 89% 98%, rgba(0,0,0,0.48), transparent 70%),
    radial-gradient(38% 30% at 72% -6%, rgba(0,0,0,0.35), transparent 70%),
    linear-gradient(180deg, #0c0d0e 0%, #08090a 44%, #040505 100%);
  border: 1px solid #000;
  border-radius: 4px;
  box-shadow:
    inset 0 0 0 2px #141517,
    inset 0 1px 0 rgba(255,255,255,0.045),
    inset 0 -24px 54px rgba(0,0,0,0.66),
    0 14px 40px rgba(0,0,0,0.72);
}
/* patina veil matching the station board — dust film + vignette at the top */
#flap-menu .fm-board::after {
  content: ''; position: absolute; inset: 0; z-index: 9; pointer-events: none;
  border-radius: inherit;
  background:
    linear-gradient(168deg, transparent 42%, rgba(20,18,14,0.05) 58%, transparent 74%),
    radial-gradient(130% 105% at 50% -4%, transparent 58%, rgba(0,0,0,0.30) 100%);
}
#flap-menu .fm-head {
  display: flex; align-items: center; gap: 10px;
  padding: 0 2px 14px; border-bottom: 1px solid rgba(255,255,255,0.07); margin-bottom: 16px;
}
#flap-menu .fm-head-icon { display: inline-flex; width: calc(var(--sf-h) * 0.8); color: #CFD2CF; opacity: 0.92; }
#flap-menu .fm-head-icon svg { width: 100%; height: auto; }
#flap-menu .fm-rows { display: flex; flex-direction: column; gap: calc(var(--sf-h) * 0.42); }
#flap-menu .fm-row {
  display: flex; align-items: center; gap: calc(var(--sf-w) * 0.7);
  background: transparent; border: 0; padding: calc(var(--sf-h) * 0.14) 6px;
  margin: 0 -6px; border-radius: 8px; cursor: pointer; text-align: left;
  transition: background 0.3s ease, box-shadow 0.3s ease;
}
#flap-menu .fm-row:hover, #flap-menu .fm-row:focus-visible {
  background: rgba(255,250,240,0.05);
  box-shadow: inset 0 0 0 1px rgba(255,250,240,0.14);
}
#flap-menu .fm-row:hover .sf, #flap-menu .fm-row:focus-visible .sf { color: #FFFFFF; }
#flap-menu .fm-row:focus-visible { outline: none; }
#flap-menu .fm-foot {
  margin-top: 16px; padding-top: 12px; border-top: 1px solid rgba(255,255,255,0.06); text-align: center;
}
#flap-menu .fm-foot span {
  font-family: 'Space Mono', monospace; font-size: 9px; letter-spacing: 0.28em;
  text-transform: uppercase; color: rgba(245,235,220,0.35);
}
