/* The scrub hero. Engineering standard per references/scrub-pipeline.md. */

.hero{
  position:relative;
  height:540vh;              /* 440vh of scroll range, 6 beats incl. the brand-title opener; Chris's pacing pick */
  z-index:2;
}

.stage{
  position:sticky;
  top:0;
  height:100vh;
  overflow:hidden;
  background:var(--canvas);
}

.stage .poster,
.stage video{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit:cover;
}

.stage .poster{
  background-position:center;
  background-size:cover;
  transition:opacity .6s var(--ease);
}

.stage video{
  opacity:0;
  transition:opacity .6s var(--ease);
  will-change:transform;
  transform:translateZ(0);
}
.stage.video-ready video{opacity:1}
.stage.video-ready .poster{opacity:0}
.stage.video-failed video{display:none}

/* layer 1 of the legibility system: the global base scrim */
.scrim{
  position:absolute;
  inset:0;
  pointer-events:none;
  background:radial-gradient(ellipse 120% 90% at 50% 45%,rgba(10,10,18,0) 35%,rgba(10,10,18,.62) 100%);
}

/* ---------- caption bands ---------- */

.bands{
  position:absolute;
  inset:0;
  pointer-events:none;
}

.band{
  position:absolute;
  left:var(--gut);
  right:var(--gut);
  top:50%;
  transform:translateY(-50%);
  max-width:1200px;
  margin-inline:auto;
  opacity:0;
  text-shadow:var(--tshadow);
}

/* layer 2, 12 September 2026 v2: the per-caption scrim is gone. Even with
   closest-side sizing it read as a dark shape sitting behind the words, and
   Chris called it. Legibility for the story now comes from .grade below, a
   full-bleed horizontal darkening that has no edges to see, plus the text
   shadow. Screen one has no scrim at all; frame zero is dark where it lands. */
.grade{
  position:absolute;
  inset:0;
  pointer-events:none;
  background:linear-gradient(180deg,
    rgba(14,20,32,0)   0%,
    rgba(14,20,32,.68) 32%,
    rgba(14,20,32,.68) 68%,
    rgba(14,20,32,0)   100%);
  opacity:clamp(0,calc((var(--p,0) - .12)*9),1);
}

/* 12 September 2026, Phase 1: hero type moved to Archivo 200 with tight
   tracking, sizes lifted to suit the lighter face */
.band h2,.band .h{
  font-family:var(--headline);
  font-weight:200;
  font-size:clamp(34px,5.2vw,70px);
  line-height:1.05;
  letter-spacing:-.015em;
  margin:0;
  max-width:20ch;
}

.band h1{
  font-family:var(--headline);
  font-weight:200;
  font-size:clamp(36px,6vw,80px);
  line-height:1.05;
  letter-spacing:-.015em;
  margin:0;
  max-width:18ch;
}

/* the support tier: the quiet second line of each beat, revealed after the statement */
.band .support{
  display:block;
  font-family:var(--body);
  font-weight:300;
  font-size:clamp(15px,1.5vw,19px);
  letter-spacing:.02em;
  color:var(--text-secondary);
  margin-top:14px;
  opacity:clamp(0,calc((var(--k,0) - .45)*2.4),1);
  transform:translateY(calc((1 - clamp(0,calc((var(--k,0) - .45)*2.4),1))*8px));
}

/* ---------- screen one, 12 September 2026 ----------
   The whole pitch on the first viewport: emblem, wordmark, two-tone tagline,
   subhead, two CTAs, scroll cue. Top-anchored rather than centred so it reads
   as a composition under the nav, and so the emblem has a fixed home to fly
   from when it docks into the nav. */

.emblem{
  position:absolute;
  top:12vh;
  left:50%;
  width:clamp(150px,26vh,260px);
  height:auto;
  margin-left:calc(clamp(150px,26vh,260px)/-2);
  transform-origin:center;
  will-change:transform,opacity;
  filter:drop-shadow(0 6px 24px rgba(5,5,10,.55));
  animation:emblemin 1.1s var(--ease-out);
}
@keyframes emblemin{
  from{opacity:0;transform:scale(.9)}
  to{opacity:1;transform:none}
}

.band.b1{
  text-align:center;
  top:calc(12vh + clamp(150px,26vh,260px) + 22px);
  transform:none;
  max-width:880px;
}
/* 12 September 2026, readability without a box: a frosted layer behind the
   screen-one copy. It blurs and dims the footage under the words rather than
   covering it, and a radial mask feathers it to nothing before any edge, so
   the glass stays in view and the letters stop fighting sharp shard edges.
   The emblem sits above this band and stays crisp. */
.band.b1::before{
  content:"";
  position:absolute;
  inset:-22% -30%;
  z-index:-1;
  pointer-events:none;
  backdrop-filter:blur(14px) brightness(.76) saturate(1.05);
  -webkit-backdrop-filter:blur(14px) brightness(.76) saturate(1.05);
  -webkit-mask-image:radial-gradient(ellipse closest-side at 50% 50%,#000 36%,transparent 100%);
  mask-image:radial-gradient(ellipse closest-side at 50% 50%,#000 36%,transparent 100%);
  opacity:clamp(0,calc(var(--k,0)*1.4),1);
}

/* the wordmark, set the way the brand lockups set it: light, wide, AI bold */
.wordmark{
  font-family:var(--display);
  font-weight:300;
  font-size:clamp(14px,1.4vw,19px);
  letter-spacing:.2em;
  color:var(--text-primary);
  margin:0;
}
.wordmark b{font-weight:700}
.wordmark .inc{color:var(--text-secondary)}

/* the tagline, two lines, two tones */
.band.b1 h1.tag{
  font-family:var(--headline);
  font-weight:200;
  font-size:clamp(34px,5.4vw,74px);
  line-height:1.04;
  letter-spacing:-.015em;
  max-width:none;
  margin:0 auto;
}
.tag .l1,.tag .l2{display:block}
.tag .l2{color:var(--text-secondary)}
.tag b{font-weight:500}

.band.b1 .sub{
  margin:18px auto 0;
  max-width:56ch;
  font-size:clamp(15px,1.5vw,19px);
  font-weight:400;
  color:var(--text-primary);
  text-shadow:0 1px 2px rgba(5,5,10,.7),0 4px 22px rgba(5,5,10,.6);
}
.band.b1 .cta-row{justify-content:center;margin-top:26px}

/* staggered entrance on load, then it holds; keyed on beat one's --k */
.band.b1 .tag{--kk:clamp(0,calc((var(--k,0) - .08)*2.2),1);opacity:var(--kk);transform:translateY(calc((1 - var(--kk))*16px))}
.band.b1 .sub{--kk:clamp(0,calc((var(--k,0) - .32)*2.4),1);opacity:var(--kk);transform:translateY(calc((1 - var(--kk))*12px))}
.band.b1 .cta-row{--kk:clamp(0,calc((var(--k,0) - .48)*2.6),1);opacity:var(--kk);transform:translateY(calc((1 - var(--kk))*10px))}

/* ---------- the story beats, all pinned left ---------- */

/* left-column variant, unused since 12 September (every beat is .story now),
   kept for the static-hero copy and any future beat that wants the column */
.band.side-l{text-align:left}
.band.side-l h2,.band.side-l .h{max-width:16ch}

/* mono chapter eyebrow above each beat */
/* 13 September 2026, per Chris: at 12px the chapter label was getting lost
   against a 70px headline on a wide screen. Lifted to 13.5, then again to a
   fluid 14 to 17 on his second look, because a fixed size cannot keep up with
   a headline that scales to 76px on a wide monitor. */
.eyebrow{
  display:block;
  font-family:var(--mono);
  font-size:clamp(14px,1.15vw,17px);
  letter-spacing:.18em;
  text-transform:uppercase;
  color:var(--text-secondary);
  margin:0 0 16px;
  opacity:clamp(0,calc(var(--k,0)*2),1);
}

/* the brand's AI weight contrast, carried into headline copy */
.band h2 .w.em{font-weight:500}

/* ---------- scroll cue, screen one only ---------- */
.cue{
  position:absolute;
  left:50%;
  bottom:calc(var(--gut)*.7);
  transform:translateX(-50%);
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:10px;
  font-family:var(--mono);
  font-size:11px;
  letter-spacing:.22em;
  text-transform:uppercase;
  color:var(--text-primary);
  text-shadow:0 1px 3px rgba(5,5,10,.85);
  pointer-events:none;
  opacity:clamp(0,calc(1 - var(--p,0)*10),1);
}
.cue i{
  display:block;
  width:1px;
  height:40px;
  background:linear-gradient(180deg,var(--text-primary),transparent);
  filter:drop-shadow(0 0 2px rgba(5,5,10,.8));
  transform-origin:top;
  animation:cuepulse 2.2s var(--ease) infinite;
}
@keyframes cuepulse{
  0%,100%{transform:scaleY(.35);opacity:.35}
  50%{transform:scaleY(1);opacity:1}
}

/* ---------- chapter rail, the story's progress ----------
   A vertical circuit trace with node dots, one per beat, the active node
   lit. Same visual language as the emblem's ring. */
.rail{
  position:absolute;
  right:calc(var(--gut) + 4px);
  top:50%;
  transform:translateY(-50%);
  list-style:none;
  margin:0;
  padding:0 16px 0 0;
  display:flex;
  flex-direction:column;
  gap:24px;
  pointer-events:none;
  opacity:clamp(0,calc((var(--p,0) - .15)*20),1);
}
.rail::before{
  content:"";
  position:absolute;
  right:3.5px;
  top:6px;
  bottom:6px;
  width:1px;
  background:var(--hairline);
}
.rail li{
  position:relative;
  font-family:var(--mono);
  font-size:11px;
  letter-spacing:.16em;
  text-transform:uppercase;
  text-align:right;
  color:var(--text-secondary);
  opacity:.45;
  transition:opacity .4s var(--ease),color .4s var(--ease);
}
.rail li::after{
  content:"";
  position:absolute;
  right:-16px;
  top:50%;
  width:8px;
  height:8px;
  margin-top:-4px;
  border-radius:50%;
  border:1px solid var(--text-secondary);
  background:var(--canvas);
  transition:background .4s var(--ease),border-color .4s var(--ease);
}
.rail li.on{opacity:1;color:var(--text-primary)}
.rail li.on::after{background:var(--text-primary);border-color:var(--text-primary)}

/* the nav mark is hidden while the hero emblem is on screen, and takes over
   the moment the dock lands. hero.js drives the opacity; this is the easing. */
#nav-mark{transition:opacity .25s var(--ease)}

/* ---------- page progress, pinned to the top edge ---------- */
.hprog{
  position:fixed;
  top:0;left:0;right:0;
  height:2px;
  z-index:60;
  pointer-events:none;
}
.hprog i{
  display:block;
  height:100%;
  background:linear-gradient(90deg,var(--text-secondary),var(--text-primary));
  transform-origin:left;
  transform:scaleX(var(--sp,0));
}

/* entrance (f) drift-down, word level */
.e-drift .w{
  --kc:clamp(0,(var(--k,0) - var(--th,0))*2.8,1);
  opacity:var(--kc);
  transform:translateY(calc((1 - var(--kc))*-26px));
}

/* ---------- the story beats, centred, in the tagline's language ---------- */
.band.story{
  text-align:center;
  max-width:960px;
  text-shadow:0 1px 2px rgba(5,5,10,.6),0 6px 30px rgba(5,5,10,.55);
}
.band.story h2{
  margin-inline:auto;
  max-width:22ch;
  font-size:clamp(36px,5.6vw,76px);
  line-height:1.04;
}
/* 13 September 2026, per Chris: the second line of each beat carries half the
   sentence, so it was reading too quiet at 16 to 21. Lifted to 17 to 23, then
   to 18 to 25 on his second look. */
.band.story .support{
  margin-inline:auto;
  font-size:clamp(18px,1.9vw,25px);
  margin-top:16px;
}
.band.story .eyebrow{margin-bottom:18px}
.band.story .cta-row{justify-content:center;margin-top:30px}

.band .sub{
  font-family:var(--body);
  font-size:clamp(16px,1.7vw,20px);
  line-height:1.6;
  color:var(--text-primary);
  max-width:52ch;
  margin:22px 0 0;
}

.band .cta-row{
  display:flex;
  flex-wrap:wrap;
  gap:14px;
  margin-top:30px;
}

/* split text spans */
.w{display:inline-block;white-space:nowrap}
.c{display:inline-block;will-change:transform,opacity}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* entrance (a) scatter */
.e-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)));
}

/* entrance (b) grid snap-align */
.e-grid .c{
  --kc:clamp(0,(var(--k,0) - var(--th,0))*2.8,1);
  opacity:var(--kc);
  transform:translateX(calc((1 - var(--kc))*var(--jx,0px)));
}

/* entrance (c) blur-to-sharp */
.e-blur{position:relative}
.e-blur .soft{position:absolute;inset:0;filter:blur(10px);opacity:calc(1 - var(--k,0))}
.e-blur .sharp{opacity:var(--k,0)}

/* entrance (d) word-punch with overshoot */
.e-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)));
}
.e-punch .w.em{--ov:0.24;--sd:0.16;--ss:2.6}

/* entrance (e) staged settle */
.e-settle .w{
  --kc:clamp(0,(var(--k,0) - var(--th,0))*2.8,1);
  opacity:var(--kc);
  transform:translateY(calc((1 - var(--kc))*26px));
}
.e-settle .sub{--ks:clamp(0,(var(--k,0) - .66)*4,1);opacity:var(--ks);transform:translateY(calc((1 - var(--ks))*16px))}
.e-settle .cta-row{--kb:clamp(0,(var(--k,0) - .78)*5,1);opacity:var(--kb);transform:translateY(calc((1 - var(--kb))*14px))}
.band .cta-row{pointer-events:auto}

/* layer 4: the chip scrim for small text over footage */
.chip{
  display:inline-block;
  font-family:var(--mono);
  font-size:12px;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--text-secondary);
  background:rgba(8,8,15,.55);
  border:1px solid rgba(96,96,126,.3);
  border-radius:10px;
  padding:7px 12px;
  backdrop-filter:blur(10px);
  text-shadow:0 1px 3px rgba(5,5,10,.85);
}

/* the loading ring */
.ring{
  position:absolute;
  right:calc(var(--gut));
  bottom:calc(var(--gut));
  width:48px;
  height:48px;
  color:var(--accent);
  opacity:.85;
  transition:opacity .4s var(--ease);
}
.stage.video-ready .ring{opacity:0}
.ring circle{transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .18s linear}

/* short screens: keep the scrub, drop the small overlays */
@media (max-height:560px){
  .ring,.hud{display:none}
}

/* ---------- the five static-hero gates ---------- */

@media (max-width: 720px),
       (orientation: portrait) and (max-width: 1024px),
       (orientation: portrait) and (pointer: coarse),
       (orientation: landscape) and (pointer: coarse) and (max-height: 560px),
       (prefers-reduced-motion: reduce){
  .hero{height:auto}
  /* 12 September 2026: floor raised so the taller static composition
     (emblem + wordmark + tagline + sub + CTAs) never climbs past the top */
  .stage{position:relative;height:auto;min-height:max(82vh,640px);display:flex;align-items:flex-end}
  .stage video,.stage .ring,.bands,.emblem,.cue,.rail,.grade{display:none}
  #nav-mark{opacity:1 !important}
  .stage .poster{
    position:absolute;inset:0;opacity:1;
    /* phones never run the video path, so the designed still loads here, from CSS,
       only when a static gate matches */
    background-image:url('hero-ending.jpg');
  }
  .stage::after{
    content:"";position:absolute;inset:0;
    /* 23 August 2026: hero-ending.jpg's bright center line always lands at the
       vertical mid-point of this box under cover-fit, no matter what
       background-position says, since the image is height-locked at this
       aspect ratio. Rather than fight the crop, darken through that band so
       the line stops competing with the headline sitting over it. */
    background:linear-gradient(180deg,rgba(14,20,32,.30) 0%,rgba(14,20,32,.55) 38%,rgba(14,20,32,.64) 58%,rgba(14,20,32,.82) 100%);
  }
  .static-hero{display:block}
}

.static-hero{
  display:none;
  position:relative;
  z-index:3;
  padding:8vh var(--gut) 8vh;
  width:100%;
  max-width:var(--maxw);
  margin-inline:auto;
  text-shadow:var(--tshadow);
}
.static-hero .emblem-s{
  display:block;
  width:clamp(76px,20vw,100px);
  height:auto;
  margin:0 auto 14px;
  filter:drop-shadow(0 6px 24px rgba(5,5,10,.55));
}
.static-hero .brand-title{
  font-family:var(--display);
  font-weight:300;
  font-size:clamp(15px,4.2vw,20px);
  letter-spacing:.2em;
  color:var(--text-primary);
  margin:0 0 5vh;
  text-align:center;
}
.static-hero .brand-title b{font-weight:700}
.static-hero .brand-title .inc{color:var(--text-secondary)}
.static-hero h1{font-size:clamp(34px,8.4vw,58px);max-width:15ch}
.static-hero h1 b{font-weight:500}
.static-hero .sub{margin-top:20px;font-size:17px;max-width:44ch;color:var(--text-primary)}
.static-hero .cta-row{margin-top:28px;display:flex;flex-wrap:wrap;gap:12px}

/* cascade fix, 23 August 2026: the display:block gate above sits before the
   base display:none, so the base always won and phones got no hero copy at all.
   This override re-states the gate after the base rule so it can actually win. */
@media (max-width: 720px),
       (orientation: portrait) and (max-width: 1024px),
       (orientation: portrait) and (pointer: coarse),
       (orientation: landscape) and (pointer: coarse) and (max-height: 560px),
       (prefers-reduced-motion: reduce){
  .static-hero{display:block}
}

/* overlay fix, 23 August 2026: .static-hero was a plain flow sibling after the
   82vh image block, so phones showed a blank image, then the headline only
   after scrolling past it. .hero-wrap ties the two together so the text can
   sit on top of the image where the design always intended it. */
.hero-wrap{position:relative}
@media (max-width: 720px),
       (orientation: portrait) and (max-width: 1024px),
       (orientation: portrait) and (pointer: coarse),
       (orientation: landscape) and (pointer: coarse) and (max-height: 560px),
       (prefers-reduced-motion: reduce){
  .hero-wrap .static-hero{position:absolute;left:0;right:0;bottom:0}
}
