/* hero.css — Time Field landing experience. Default state hides everything so
 * gated-off visitors (iOS app, noscript, ?nohero=1) get exactly today's page.
 * gate.js adds hero-on / hero-lite / hero-poster to <html> pre-paint. */

#heroRoot { display: none; }
.hero-on #heroRoot, .hero-lite #heroRoot, .hero-poster #heroRoot { display: block; }

/* --- Skip link --- */
.skip-link {
  position: fixed; top: 8px; left: 8px; z-index: 200;
  padding: 8px 14px; border-radius: 6px;
  background: var(--surface2); color: var(--text);
  font: 500 12px var(--mono); text-decoration: none;
  transform: translateY(-60px); transition: transform .15s;
}
.skip-link:focus-visible { transform: none; }

/* --- Preloader curtain --- */
#heroPreloader { display: none; }
.hero-on #heroPreloader {
  display: flex; position: fixed; inset: 0; z-index: 100;
  flex-direction: column; align-items: center; justify-content: center; gap: 14px;
  background: var(--bg);
}
.pre-num { font: 800 64px/1 var(--display); color: var(--text); font-variant-numeric: tabular-nums; }
.pre-label { font: 400 11px var(--mono); letter-spacing: .3em; color: var(--muted); }
.pre-bar { width: min(320px, 60vw); height: 2px; background: var(--border); overflow: hidden; border-radius: 1px; }
.pre-bar span { display: block; height: 100%; background: var(--accent); transform: scaleX(0); transform-origin: left; }

/* Curtain exit is CSS-driven so it works before GSAP arrives */
.hero-on #heroPreloader { transition: transform .9s cubic-bezier(.76, 0, .24, 1); }
.hero-on #heroPreloader.pre-exit { transform: translateY(-100%); }

/* --- Canvas (full journey only) --- */
#heroCanvas { display: none; }
.hero-on #heroCanvas {
  display: block; position: fixed; inset: 0; z-index: 0;
  width: 100%; height: 100%; opacity: 0;          /* hero.js fades in after boot */
}
.hero-on .wrap { position: relative; z-index: 1; } /* dashboard above canvas (already z-1 in shared.css; explicit here) */
/* Parked until the finale lands it. The finale flash fires from the SCRUBBED
   timeline, which lags raw scroll by up to a second — a fast flick can scroll
   past the journey into the page below, streaking the dashboard tiles up the
   screen before the flash covers them. visibility (not display) keeps layout
   and ScrollTrigger measurements identical; finishJourney() removes hero-on
   behind the opaque flash, so the reveal is unchanged. */
.hero-on .wrap { visibility: hidden; }

/* --- ASCII mode (Konami / ?ascii=1): AsciiEffect's table replaces the canvas.
 * No font metrics here — the effect computes its own so the glyph grid tiles
 * exactly. text-shadow stands in for bloom (the composer is bypassed). --- */
#asciiFx { display: none; }
.hero-on.ascii-on #asciiFx {
  display: block; position: fixed; inset: 0; z-index: 0;
  background: #080c10; color: #7fb8ff; overflow: hidden;
  text-shadow: 0 0 2px rgba(127, 184, 255, .9), 0 0 10px rgba(79, 140, 255, .7), 0 0 26px rgba(49, 97, 157, .45);
}
/* visibility, NOT opacity — hero.js's render loop gates on canvas opacity */
.hero-on.ascii-on #heroCanvas { visibility: hidden; }

/* --- Journey scaffold: one sticky stage, 400vh of scroll room --- */
.hero-on #heroJourney { height: 400vh; position: relative; }
.hero-on .hero-stage {
  position: sticky; top: 0; height: 100vh; overflow: hidden; z-index: 2;
}

/* --- Act I --- */
.hero-act1 {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  padding: 0 24px; pointer-events: none;
}
.hero-h1 {
  /* sized so "INTERVAL FUNDS" always fits one line; nowrap guarantees it */
  font: 800 clamp(30px, 7.2vw, 104px)/1.02 var(--display);
  letter-spacing: -.02em; color: var(--text); margin: 0 0 18px;
  white-space: nowrap;
}
.hero-sub {
  font: 500 clamp(13px, 1.5vw, 16px)/1.6 var(--mono);
  /* full-brightness text, no box — a layered dark halo keeps it readable
     over the particle field */
  color: var(--text); max-width: 60ch;
  text-shadow:
    0 1px 4px rgba(8, 12, 16, 1),
    0 0 12px rgba(8, 12, 16, .95),
    0 0 26px rgba(8, 12, 16, .8);
}
.hero-cue {
  position: absolute; bottom: 64px; left: 50%; transform: translateX(-50%);
  font: 500 10px var(--mono); letter-spacing: .4em; color: #8da8c6;
  text-shadow: 0 1px 8px rgba(8, 12, 16, .9);
  animation: hero-cue 2.2s ease-in-out infinite;
}
@keyframes hero-cue { 50% { opacity: .35; transform: translateX(-50%) translateY(4px); } }

/* SplitText line masks (hero.js splits .hero-h1 into lines) */
.hero-h1 .sp-line { display: block; overflow: hidden; }
.hero-h1 .sp-line > div { will-change: transform; }

/* --- Dive cards (DOM cards projected from 3D node positions) --- */
#diveCards { position: absolute; inset: 0; pointer-events: none; opacity: 0; perspective: 900px; }
.dive-card {
  position: absolute; left: 0; top: 0; opacity: 0; width: 300px;
  padding: 6px 0; display: flex; flex-direction: column;
  will-change: transform, opacity; pointer-events: none; white-space: nowrap;
  /* type floats raw over the field — layered halo instead of a box */
  text-shadow: 0 0 8px rgba(8, 12, 16, 1), 0 0 24px rgba(8, 12, 16, .95), 0 2px 5px rgba(8, 12, 16, .9);
}
/* clickable fund cards (JS toggles per-card pointer-events while visible);
   force-off whenever the dive isn't live so faded cards never catch clicks */
#diveCards:not(.live) .dive-card { pointer-events: none !important; }
.dive-card.clickable { cursor: pointer; }
.dive-card.clickable:hover .dv-ticker { color: #fff; }
.dive-card.clickable:hover .dv-name { color: #eaf2fb; }
/* stack order: deadline date / ticker / fund name */
.dv-date { order: 1; font: 700 15px var(--mono); letter-spacing: .05em; }
.dive-card.tk-hot .dv-date { color: var(--hot); }
.dive-card.tk-warm .dv-date { color: #7fb8ff; }
.dive-card.tk-cool .dv-date { color: #a9bdd6; }
.dv-top { order: 2; display: block; margin: 3px 0; }
.dv-ticker { font: 600 18px var(--mono); color: #fff; letter-spacing: .08em; }
.dv-name {
  order: 3; font: 500 12px/1.4 var(--mono); color: #b8cce4; margin: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 250px;
}
/* ghost countdown: outside edge, faint, behind the text */
.dv-badge {
  position: absolute; top: 50%; transform: translateY(-52%);
  font: 700 62px/1 var(--display); letter-spacing: -.03em;
  color: rgba(220, 232, 245, .14); z-index: -1; text-shadow: none;
}
.dive-card.tk-hot .dv-badge { color: rgba(255, 107, 102, .20); }
.dive-card.tk-warm .dv-badge { color: rgba(79, 156, 249, .18); }
/* mirrored composition: text hugs the beam side, ghost hugs the outside */
.dive-card.side-l { align-items: flex-end; text-align: right; padding-right: 50px; }
.dive-card.side-l .dv-badge { left: -34px; }
.dive-card.side-r { align-items: flex-start; text-align: left; padding-left: 50px; }
.dive-card.side-r .dv-badge { right: -34px; }
/* callout anchor pointing at the timeline beam */
.dive-card::before {
  content: ""; position: absolute; top: 50%; width: 34px; height: 1px;
  background: rgba(220, 232, 245, .45);
}
.dive-card::after {
  content: ""; position: absolute; top: calc(50% - 2px);
  width: 5px; height: 5px; border-radius: 50%; background: var(--accent2);
}
.dive-card.side-l::before { right: 8px; }
.dive-card.side-l::after { right: 6px; }
.dive-card.side-r::before { left: 8px; }
.dive-card.side-r::after { left: 6px; }

.month-marker {
  position: absolute; left: 0; top: 0; opacity: 0; white-space: nowrap;
  font: 800 64px/1 var(--display); letter-spacing: .12em;
  color: rgba(79, 156, 249, .16); will-change: transform, opacity;
  pointer-events: none;
}

/* --- Ticker tape (hero bottom edge + docked under the status bar) --- */
.hero-ticker {
  position: absolute; bottom: 0; left: 0; right: 0; z-index: 3;
  border-top: 1px solid var(--border);
  background: rgba(8, 12, 16, .72);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  overflow: hidden; padding: 9px 0;
}
.ticker-dock { display: none; border-bottom: 1px solid var(--border); overflow: hidden; padding: 8px 0; }
.hero-lite #tickerDock { display: block; }
.hero-on.hero-landed #tickerDock { display: block; }
.tk-track { display: inline-block; white-space: nowrap; will-change: transform; }
.tk-item { font: 500 11px var(--mono); letter-spacing: .06em; color: var(--muted); }
.tk-item b { font-weight: 500; }
.tk-item.tk-hot b { color: var(--hot); }
.tk-item.tk-warm b { color: var(--warm); }
.tk-item.tk-cool b { color: var(--cool); }
.tk-sep { color: var(--faint); margin: 0 14px; font-size: 11px; }

/* CSS-only marquee for lite mode (hero-on drives the track with GSAP instead) */
.hero-lite .tk-track, .hero-poster .tk-track { animation: tk-scroll var(--ticker-dur, 40s) linear infinite; }
@keyframes tk-scroll { to { transform: translateX(-50%); } }
.hero-lite .hero-ticker:hover .tk-track,
.hero-lite .ticker-dock:hover .tk-track { animation-play-state: paused; }

/* --- Lite mode: static hero block + animated CSS grid + ticker, no WebGL --- */
.hero-lite #heroJourney { position: relative; }
.hero-lite .hero-stage { position: relative; height: 88vh; overflow: hidden; }
.hero-lite #diveCards, .hero-lite .hero-cue { display: none; }
.hero-lite .hero-stage::before {
  content: ""; position: absolute; inset: -40% -20%;
  background-image:
    linear-gradient(rgba(79, 156, 249, .08) 1px, transparent 1px),
    linear-gradient(90deg, rgba(79, 156, 249, .08) 1px, transparent 1px);
  background-size: 34px 34px;
  transform: perspective(420px) rotateX(58deg);
  animation: hero-drift 9s linear infinite;
  mask-image: linear-gradient(transparent 18%, #000 60%);
  -webkit-mask-image: linear-gradient(transparent 18%, #000 60%);
}
@keyframes hero-drift { to { background-position: 0 34px; } }

/* --- Poster mode (reduced motion): static, nothing moves --- */
.hero-poster #heroJourney { position: relative; }
.hero-poster .hero-stage { position: relative; height: 70vh; overflow: hidden; }
.hero-poster #diveCards, .hero-poster .hero-cue,
.hero-poster .hero-ticker, .hero-poster #heroCanvas, .hero-poster #heroPreloader { display: none; }
.hero-poster .hero-stage::before {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(ellipse at 50% 80%, rgba(79, 156, 249, .14), transparent 60%);
}

/* Lenis helper CSS (vendored — lenis@1.3.23/dist/lenis.css) */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }

/* Small screens: keep the type inside the viewport */
@media (max-width: 600px) {
  .hero-cue { bottom: 84px; }
  .dive-card { width: 230px; }
  .dv-ticker { font-size: 16px; }
  .dv-date { font-size: 13px; }
  .dv-badge { font-size: 46px; }
}
