/* scroll-video-hero v2: hero stage, bands, scrims, entrances, static hero, gates.
   Tokens (--bg, --ink, --gold, --ease-*) come from css/site.css. */

:root {
  --tshadow: 0 1px 2px rgba(8, 6, 4, .95), 0 3px 12px rgba(8, 6, 4, .78), 0 10px 44px rgba(8, 6, 4, .8);
  --scrim-rgb: 8, 6, 4;
}

/* ---------- Structure ---------- */

.hero {
  position: relative;
  height: calc(var(--hero-vh, 400) * 1vh);
  background: var(--bg);
  color: var(--ink);
  --fx: 50%;
  --fy: 50%;
}

.hero .stage {
  position: sticky;
  top: 0;
  /* Pinned stage: the LARGE viewport, never svh. On iOS Safari / Chrome Android the visual viewport
     grows from svh to lvh on the first swipe (toolbar retracts); an svh stage would leave a strip of
     the hero's background under the frames for the whole journey. The lvh excess under an expanded
     toolbar is clipped, which is invisible. The in-flow static hero (below) uses svh on purpose. */
  height: 100vh;
  height: 100lvh;
  overflow: hidden;
  isolation: isolate;
  background: var(--bg);
}

.hero .media,
.hero .media > *,
.hero .media picture,
.hero .media img.poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
}

.hero .media { z-index: 0; }

.hero img.poster,
.hero video.scrub {
  object-fit: cover;
  object-position: var(--fx) var(--fy);
  display: block;
}

.hero canvas.frames,
.hero video.scrub {
  opacity: 0;
  transition: opacity .6s var(--ease-out);
  pointer-events: none;
}
/* Only the active medium exists: the other one is out of the tree, never a promoted full-viewport
   layer of its own; `will-change` sits on the active one alone. */
.hero.is-frames video.scrub,
.hero.is-video canvas.frames { display: none; }
.hero.is-frames canvas.frames,
.hero.is-video video.scrub { will-change: transform; }

.hero.is-frames.is-ready canvas.frames,
.hero.is-video.is-ready video.scrub { opacity: 1; }

/* Global base scrim: no frame is ever raw behind the page. */
.hero .scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(ellipse 120% 90% at 50% 45%, rgba(var(--scrim-rgb), 0) 35%, rgba(var(--scrim-rgb), .62) 100%);
}

/* ---------- Progress ring and scroll cue ---------- */

.hero .ring {
  position: absolute;
  z-index: 4;
  right: clamp(16px, 3vw, 40px);
  /* Anchored to the small viewport's bottom edge while the mobile toolbar is expanded. */
  bottom: calc(clamp(16px, 3vw, 40px) + (100lvh - 100svh));
  width: 40px;
  height: 40px;
  color: var(--gold);
  opacity: 0;
  transform: rotate(-90deg);
  transition: opacity .5s var(--ease-out);
  pointer-events: none;
}
.hero .ring circle { transition: stroke-dashoffset .12s linear; }
.hero .ring .track { stroke: rgba(242, 235, 224, .18); }
.hero.is-loading .ring { opacity: 1; }

.hero .cue {
  position: absolute;
  z-index: 4;
  left: 50%;
  bottom: calc(clamp(18px, 3.4vw, 40px) + (100lvh - 100svh));
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  border: 1px solid rgba(201, 166, 96, .3);
  border-radius: 999px;
  background: rgba(var(--scrim-rgb), .55);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  text-shadow: 0 1px 3px rgba(var(--scrim-rgb), .85);
  font: 500 12px/1 var(--font-body);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink);
  cursor: pointer;
  opacity: 0;
  /* Out of the tab order whenever it is not shown: visibility flips after the fade. */
  visibility: hidden;
  transition: opacity .6s var(--ease-out), transform .6s var(--ease-out), visibility 0s linear .6s;
}
.hero .cue svg { width: 14px; height: 14px; }
/* The arrow bobs only while the cue is shown, and four times, then rests: an infinite animation on
   a hidden or resting cue keeps the compositor drawing a frame every vsync for the whole session. */
.hero.is-ready .cue:not(.is-gone) .arrow { animation: cue-bob 2.8s var(--ease-inout) 4; }
.hero.is-ready .cue:not(.is-gone) { opacity: 1; visibility: visible; transition-delay: 0s; }
.hero .cue.is-gone { opacity: 0; pointer-events: none; }
@keyframes cue-bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(4px); }
}
@media (max-height: 560px) { .hero .cue, .hero .ring { display: none; } }

/* ---------- Bands ---------- */

.hero .bands {
  position: absolute;
  inset: 0;
  z-index: 2;
}

.band {
  position: absolute;
  inset: 0;
  display: grid;
  padding: clamp(24px, 6vh, 72px) clamp(20px, 6vw, 96px);
  text-shadow: var(--tshadow);
  --k: 0;
  --sx: 50%;
  --sy: 50%;
  --scrim: .66;
}
/* Off bands leave the tree (their CTAs must not be reachable). Band one is the exception: it holds
   the page's only <h1> in frames mode, so it stays in the accessibility tree at opacity 0. */
.band.is-off:not(:first-child) { visibility: hidden; }
.band.is-off:first-child { pointer-events: none; }
.band .btn { text-shadow: none; }

/* Per-band scrim: rides the band's opacity, deepens with --k, dies out by 76%. */
.band::before {
  content: "";
  position: absolute;
  inset: -4%;
  pointer-events: none;
  opacity: calc(.25 + .75 * var(--k, 1));
  background: radial-gradient(ellipse 74% 62% at var(--sx) var(--sy),
    rgba(var(--scrim-rgb), var(--scrim)) 0%,
    rgba(var(--scrim-rgb), calc(var(--scrim) * .66)) 46%,
    rgba(var(--scrim-rgb), 0) 76%);
}

.band .copy {
  position: relative;
  align-self: var(--ay, center);
  justify-self: var(--ax, start);
  max-width: min(100%, 720px);
  text-align: var(--tx, left);
}

/* Positions: where the text lives in the footage's negative space. */
.band.pos-tl { --ax: start; --ay: start; --sx: 24%; --sy: 30%; padding-top: clamp(96px, 15vh, 170px); }
.band.pos-l  { --ax: start; --ay: center; --sx: 26%; --sy: 50%; }
.band.pos-r  { --ax: end;   --ay: center; --sx: 76%; --sy: 50%; --tx: right; }
.band.pos-b  { --ax: center; --ay: end;   --sx: 50%; --sy: 82%; --tx: center; }
.band.pos-bl { --ax: start; --ay: end;   --sx: 28%; --sy: 78%; }
.band.pos-c  { --ax: center; --ay: center; --sx: 50%; --sy: 46%; --tx: center; }
.band.pos-c .copy,
.band.pos-b .copy { max-width: min(100%, 900px); }
.band.pos-tl .line,
.band.pos-tl h1 { max-width: 12ch; font-size: clamp(2rem, 1.1rem + 3.3vw, 4.2rem); }
.band.pos-b .line { max-width: 24ch; margin-inline: auto; font-size: clamp(1.8rem, 1rem + 3vw, 3.8rem); }

.band .kicker {
  margin: 0 0 14px;
  font: 500 12px/1.2 var(--font-body);
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--gold-2);
}

.band .line,
.band h1 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -.012em;
  line-height: 1.04;
  font-size: clamp(2rem, 1.2rem + 3.6vw, 4.6rem);
  max-width: 18ch;
  text-wrap: balance;
}
.band.pos-c .line,
.band.pos-c h1 { max-width: 16ch; margin-inline: auto; }
.band.pos-c::before { background: radial-gradient(ellipse 60% 56% at var(--sx) var(--sy),
    rgba(var(--scrim-rgb), var(--scrim)) 0%,
    rgba(var(--scrim-rgb), calc(var(--scrim) * .7)) 46%,
    rgba(var(--scrim-rgb), 0) 76%); }
.band .brand-line {
  font-size: clamp(2.6rem, 1.4rem + 5vw, 6rem);
  letter-spacing: .02em;
}
.band .sub {
  margin: 18px 0 0;
  font: 400 clamp(1.05rem, .9rem + .7vw, 1.4rem)/1.4 var(--font-body);
  color: var(--ink-soft);
  max-width: 34ch;
}
.band.pos-c .sub { margin-inline: auto; }
.band .cta-row {
  margin-top: 28px;
  display: flex;
  gap: 14px;
  align-items: center;
  justify-content: var(--cj, flex-start);
}
.band.pos-c .cta-row { --cj: center; }

/* Split spans */
.band .vis { display: inline; }
.band .w { display: inline-block; white-space: nowrap; }
.band .c { display: inline-block; }
.band .w.em { color: var(--gold-2); }

/* Text splitting scaffolding shared by every entrance */
.band .c,
.band .w { transform-origin: 50% 70%; }

/* ---------- Entrances (transform and opacity only, scrubbed off --k) ---------- */

/* (a) Scatter: per-character fly-in from seeded offsets. */
.band[data-entrance="scatter"] .c {
  --kc: clamp(0, (var(--k, 0) - var(--th, 0)) * 2.6, 1);
  opacity: var(--kc);
  transform: translate(calc((1 - var(--kc)) * var(--jx, 0px)), calc((1 - var(--kc)) * var(--jy, 0px)))
             rotate(calc((1 - var(--kc)) * var(--jr, 0deg)));
}

/* (d) Word punch with overshoot: word pops past 1 and eases back. */
.band[data-entrance="punch"] .w {
  --kc: clamp(0, (var(--k, 0) - var(--th, 0)) * 3, 1);
  --ks: clamp(0, (var(--k, 0) - var(--th, 0) - var(--sd, .1)) * var(--ss, 3.2), 1);
  opacity: var(--kc);
  transform: scale(calc(0.6 + (0.4 + var(--ov, .12)) * var(--kc) - var(--ov, .12) * var(--ks)));
}
.band[data-entrance="punch"] .w.em { --ov: .24; --sd: .16; --ss: 2.6; }

/* (e) Rise into a staged settle: words rise in reading order, then subline, then CTA. */
.band[data-entrance="rise"] .w {
  --kc: clamp(0, (var(--k, 0) - var(--th, 0)) * 3, 1);
  opacity: var(--kc);
  transform: translateY(calc((1 - var(--kc)) * 22px));
}
.band[data-entrance="rise"] .kicker {
  --kk: clamp(0, var(--k, 0) * 4, 1);
  opacity: var(--kk);
  transform: translateY(calc((1 - var(--kk)) * 8px));
}
.band[data-entrance="rise"] .sub {
  --ks: clamp(0, (var(--k, 0) - .66) * 4, 1);
  opacity: var(--ks);
  transform: translateY(calc((1 - var(--ks)) * 12px));
}
.band[data-entrance="rise"] .cta-row {
  --kb: clamp(0, (var(--k, 0) - .78) * 5, 1);
  opacity: var(--kb);
  transform: translateY(calc((1 - var(--kb)) * 12px));
}

/* (f) Drift down: each word starts above its resting spot. */
.band[data-entrance="drift"] .w {
  --kc: clamp(0, (var(--k, 0) - var(--th, 0)) * 2.8, 1);
  opacity: var(--kc);
  transform: translateY(calc((1 - var(--kc)) * -24px));
}

/* (c) Blur to sharp: static blur on the soft copy, opacity crossfade only. */
.band[data-entrance="blur"] [data-split] { position: relative; display: block; }
.band[data-entrance="blur"] .vis { opacity: var(--k, 0); }
.band[data-entrance="blur"] .vis.soft {
  position: absolute;
  inset: 0;
  filter: blur(10px);
  opacity: calc(1 - var(--k, 0));
}

/* (i) Weave: characters arrive alternating from above and below. */
.band[data-entrance="weave"] .c {
  --kc: clamp(0, (var(--k, 0) - var(--th, 0)) * 2.6, 1);
  opacity: var(--kc);
  transform: translateY(calc((1 - var(--kc)) * var(--jy, 0px)));
}

/* ---------- Chip: small labels over footage ---------- */

.chip {
  display: inline-block;
  padding: 6px 12px;
  background: rgba(var(--scrim-rgb), .55);
  border: 1px solid rgba(201, 166, 96, .3);
  border-radius: 10px;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  text-shadow: 0 1px 3px rgba(var(--scrim-rgb), .85);
  font: 500 12px/1.2 var(--font-mono);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink);
}

/* ---------- Static hero copy (poster + composed copy) ---------- */

.hero .static-copy {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: none;
  place-items: end start;
  padding: clamp(24px, 6vh, 72px) clamp(20px, 6vw, 96px);
  text-shadow: var(--tshadow);
}
.hero .static-copy::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(to top, rgba(var(--scrim-rgb), .82) 0%, rgba(var(--scrim-rgb), .46) 40%, rgba(var(--scrim-rgb), 0) 72%);
}
.hero .static-copy .copy { position: relative; max-width: 720px; }
.hero .static-copy .kicker {
  margin: 0 0 14px;
  font: 500 12px/1.2 var(--font-body);
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--gold-2);
}
.hero .static-copy h1 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -.012em;
  line-height: 1.04;
  font-size: clamp(2.2rem, 1.2rem + 4vw, 4.8rem);
  max-width: 16ch;
  text-wrap: balance;
}
.hero .static-copy .sub {
  margin: 16px 0 0;
  font: 400 clamp(1.05rem, .9rem + .7vw, 1.35rem)/1.4 var(--font-body);
  color: var(--ink-soft);
  max-width: 34ch;
}
.hero .static-copy .cta-row { margin-top: 26px; display: flex; gap: 14px; }
.hero .static-copy .btn { text-shadow: none; }

/* JS-decided static hero */
.hero.is-static { height: auto; }
.hero.is-static .stage { position: relative; height: 100vh; height: 100svh; }
.hero.is-static canvas.frames,
.hero.is-static video.scrub,
.hero.is-static .ring,
.hero.is-static .cue,
.hero.is-static .bands { display: none; }
.hero.is-static .static-copy { display: grid; }

/* ---------- The static-hero gates (character-identical to the GATES array in js/hero.js) ---------- */

/* Gate 5: reduced motion, always static. */
@media (prefers-reduced-motion: reduce) {
  .hero { height: auto; }
  .hero .stage { position: relative; height: 100vh; height: 100svh; }
  .hero canvas.frames,
  .hero video.scrub,
  .hero .ring,
  .hero .cue,
  .hero .bands { display: none; }
  .hero .static-copy { display: grid; }
  .hero .cue .arrow { animation: none !important; }
}

/* Gate 4: landscape phone, always static (no room for a journey). */
@media (orientation: landscape) and (pointer: coarse) and (max-height: 560px) {
  .hero { height: auto; }
  .hero .stage { position: relative; height: 100vh; height: 100svh; }
  .hero canvas.frames,
  .hero video.scrub,
  .hero .ring,
  .hero .cue,
  .hero .bands { display: none; }
  .hero .static-copy { display: grid; }
}

/* Gates 1 to 3: mobile. Static only when the hero opts out of the mobile scrub. */
@media (max-width: 720px), (orientation: portrait) and (max-width: 1024px), (orientation: portrait) and (pointer: coarse) {
  .hero[data-mobile="static"] { height: auto; }
  .hero[data-mobile="static"] .stage { position: relative; height: 100vh; height: 100svh; }
  .hero[data-mobile="static"] canvas.frames,
  .hero[data-mobile="static"] video.scrub,
  .hero[data-mobile="static"] .ring,
  .hero[data-mobile="static"] .cue,
  .hero[data-mobile="static"] .bands { display: none; }
  .hero[data-mobile="static"] .static-copy { display: grid; }

  /* Mobile scrub: tighter type and lower scrims tuned for the portrait crop. */
  .band { padding: clamp(20px, 5vh, 48px) 20px; }
  .band .line,
  .band h1 { font-size: clamp(1.9rem, 1.2rem + 4.5vw, 2.8rem); max-width: 14ch; }
  .band .brand-line { font-size: clamp(2.4rem, 1.4rem + 7vw, 3.6rem); }
  .band.pos-tl { --sy: 24%; --sx: 40%; padding-top: clamp(80px, 12vh, 120px); }
  .band.pos-tl .line, .band.pos-tl h1 { max-width: 12ch; }
  .band.pos-b { --sy: 80%; --sx: 50%; }
  .band.pos-b .line { max-width: 14ch; }
  .band.pos-bl { --sx: 40%; --sy: 78%; }
  /* Portrait crop: the subject fills the narrow frame edge to edge (gold crown, links), so the
     per-band scrim widens sideways and dies later; vertically it stays as short as on desktop. */
  .band::before,
  .band.pos-c::before {
    background: radial-gradient(ellipse 118% 58% at var(--sx) var(--sy),
      rgba(var(--scrim-rgb), var(--scrim)) 0%,
      rgba(var(--scrim-rgb), calc(var(--scrim) * .86)) 50%,
      rgba(var(--scrim-rgb), 0) 84%);
  }
  .band .cta-row { flex-wrap: wrap; }
  .hero .ring { right: 16px; bottom: calc(16px + (100lvh - 100svh)); }
}
