/* The scrub hero: pinned region, sticky stage, caption bands over live footage. */

.hero{position:relative;height:520vh}
.stage{
  position:sticky;top:0;height:100vh;width:100%;
  overflow:hidden;background:var(--canvas-deep);
}

.poster,.stage video{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;
}
.poster{background-size:cover;background-position:center;transition:opacity .9s var(--ease)}
.stage video{
  opacity:0;transition:opacity .9s var(--ease);
  transform:translateZ(0);will-change:transform;
}
.stage.video-ready video{opacity:1}
.stage.video-ready .poster{opacity:0}
.stage.video-failed video{display:none}

/* 1. The global base scrim: no frame is ever raw behind the page */
.scrim{
  position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse 120% 90% at 50% 45%,rgba(8,10,16,0) 34%,rgba(8,10,16,.64) 100%);
}

/* The loading ring, honest progress while the blob streams */
.ringwrap{
  position:absolute;left:50%;bottom:8vh;transform:translateX(-50%);
  color:rgba(255,255,255,.82);z-index:5;
  transition:opacity .5s var(--ease);
}
.stage.video-ready .ringwrap{opacity:0;pointer-events:none}
.ring{width:48px;height:48px;transform:rotate(-90deg)}
.ring circle{transition:stroke-dashoffset .18s linear}
.chev{width:26px;height:26px;opacity:.8;animation:chevbob 2.6s var(--ease) -.6s infinite}
@keyframes chevbob{0%,100%{transform:translateY(0)}50%{transform:translateY(7px)}}

/* Caption bands */
.band{
  position:absolute;inset:0;
  display:grid;align-content:center;
  padding-inline:clamp(20px,7vw,110px);
  opacity:0;pointer-events:none;
  color:#F4F6F8;text-shadow:var(--tshadow);
  z-index:3;
}
.band .btn{text-shadow:none}

/* 2. The per-band scrim: dims exactly while that band's text is on, and nowhere else */
.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,50%) var(--sy,50%),
    rgba(4,6,11,.68) 0%,rgba(4,6,11,.46) 46%,rgba(4,6,11,0) 76%);
}
.band > *{position:relative}

.band-top{align-content:start;padding-top:16vh}
.band-mid{align-content:center}
.band-end{align-content:center}

.kicker{
  font-family:var(--mono);font-weight:500;
  font-size:.7rem;letter-spacing:.2em;text-transform:uppercase;
  color:rgba(244,246,248,.78);margin-bottom:1.1rem;
  display:block;
}

.band h2,.band .h{
  font-family:var(--display);font-weight:800;font-stretch:120%;
  font-size:clamp(2.6rem,7.6vw,6.4rem);
  line-height:.92;letter-spacing:-.025em;
  margin:0;
}
.band .sub{
  font-family:var(--body);font-weight:400;
  font-size:clamp(1.05rem,2.1vw,1.6rem);
  line-height:1.4;margin-top:1.1rem;
  max-width:38ch;
  color:rgba(244,246,248,.92);
}

/* The inverted beat. Band 3 sits entirely inside the white-out, which is the
   brightest footage in the film, so light type there fails the worst frame.
   The type flips dark and the scrim lifts instead of deepening. */
.band-invert{color:#0B1116;text-shadow:0 1px 2px rgba(240,246,250,.9),0 3px 14px rgba(240,246,250,.75)}
.band-invert::before{
  background:radial-gradient(ellipse 74% 62% at var(--sx,50%) var(--sy,50%),
    rgba(244,249,252,.72) 0%,rgba(244,249,252,.5) 46%,rgba(244,249,252,0) 76%);
}
.band-invert .sub{color:#25323A}
.band-invert .kicker,.band-invert .where{color:#33424C}
.band-invert .btn.ghost{border-color:#12202A;color:#0B1116;background:rgba(248,251,253,.42)}
.band-invert .btn.ghost:hover{background:rgba(248,251,253,.72)}

/* Split-text machinery. transform + opacity only, scrubbed off --k. */
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.vis{display:block}
.w{display:inline-block;white-space:pre}
.c{display:inline-block;will-change:transform,opacity}

/* (a) drift-down: echoes falling snow */
.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));
}
/* (b) scatter: echoes gusting snow */
.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)));
}
/* (c) blur-to-sharp: echoes focus arriving out of the white-out.
   The relative wrapper stacks the two copies WITHOUT disturbing the band's own
   position:absolute, which a `position` on .e-blur itself would override. */
.e-blur .blurwrap{position:relative}
.e-blur .soft{position:absolute;inset:0;filter:blur(11px);opacity:calc(1 - var(--k,0));pointer-events:none}
.e-blur .sharp{opacity:var(--k,0)}
/* (d) grid snap: echoes stripes laying down in reading order */
.e-grid .c{
  --kc:clamp(0,(var(--k,0) - var(--th,0))*3.1,1);
  opacity:var(--kc);
  transform:translateX(calc((1 - var(--kc)) * -30px));
}
/* (e) staged settle: the arrival */
.e-settle .w{
  --kc:clamp(0,(var(--k,0) - var(--th,0))*2.9,1);
  opacity:var(--kc);
  transform:translateY(calc((1 - var(--kc)) * 22px));
}
.e-settle .sub{--ks:clamp(0,(var(--k,0) - .60)*3.4,1);opacity:var(--ks);
  transform:translateY(calc((1 - var(--ks)) * 16px))}
.e-settle .ctarow{--kb:clamp(0,(var(--k,0) - .76)*4.4,1);opacity:var(--kb);
  transform:translateY(calc((1 - var(--kb)) * 14px))}
.e-settle .where{--kw:clamp(0,(var(--k,0) - .70)*4,1);opacity:var(--kw)}

.ctarow{display:flex;flex-wrap:wrap;gap:14px;align-items:center;margin-top:2rem}
.where{
  font-family:var(--mono);font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;
  color:rgba(244,246,248,.8);margin-top:1.4rem;
}

/* 4. The chip scrim for small text over footage */
.chip{
  background:rgba(8,10,16,.55);border:1px solid rgba(150,165,180,.3);
  border-radius:10px;backdrop-filter:blur(10px);
  text-shadow:0 1px 3px rgba(5,8,12,.85);
  padding:7px 13px;
}

.cue{
  position:absolute;left:50%;bottom:4.5vh;transform:translateX(-50%);
  z-index:4;display:flex;flex-direction:column;align-items:center;gap:9px;
  color:rgba(244,246,248,.72);
  transition:opacity .6s var(--ease);
}

/* The static hero: a designed layout, not an apology */
.static-hero{display:none;position:relative;min-height:88vh;overflow:hidden}
.static-hero .shot{position:absolute;inset:0;background-size:cover;background-position:center}
/* Light at the top so the sunrise survives; heavy only where the words land. */
.static-hero .shot::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(6,9,14,.22) 0%,rgba(6,9,14,.1) 34%,rgba(6,9,14,.62) 62%,rgba(6,9,14,.88) 100%);
}
.static-hero .inner{
  position:relative;z-index:2;min-height:88vh;
  display:flex;flex-direction:column;justify-content:flex-end;
  padding:clamp(24px,7vw,64px) var(--gutter) clamp(38px,9vw,74px);
  color:#F4F6F8;text-shadow:var(--tshadow);
}
.static-hero .sh-title{
  font-family:var(--display);font-weight:800;font-stretch:118%;
  font-size:clamp(2.3rem,9vw,4rem);line-height:.96;letter-spacing:-.022em;
  max-width:16ch;margin:0;
}
.static-hero .sub{margin-top:1.1rem;max-width:40ch;font-size:clamp(1rem,4vw,1.15rem);color:rgba(244,246,248,.93)}
@media (max-width:430px){
  .static-hero .kicker{font-size:.6rem;letter-spacing:.14em}
}
.static-hero .ctarow{margin-top:1.9rem}
.static-hero .btn{text-shadow:none}

/* THE FIVE STATIC-HERO GATES. These five strings match the JS exactly. */
@media (max-width: 720px){
  .hero{display:none}
  .static-hero{display:block}
}
@media (orientation: portrait) and (max-width: 1024px){
  .hero{display:none}
  .static-hero{display:block}
}
@media (orientation: portrait) and (pointer: coarse){
  .hero{display:none}
  .static-hero{display:block}
}
@media (orientation: landscape) and (pointer: coarse) and (max-height: 560px){
  .hero{display:none}
  .static-hero{display:block}
}
@media (prefers-reduced-motion: reduce){
  .hero{display:none}
  .static-hero{display:block}
}

/* Scrub-capable but short windows: keep the scrub, drop the overlays with no room */
@media (max-height:560px) and (pointer:fine){
  .cue,.ringwrap{display:none}
}

/* ===================== PHOTO HERO (no scroll journey) =====================
   The static hero becomes the only hero, shown at every width. It keeps the
   same bottom-weighted composition, sized up for desktop, and the five gate
   queries below it no longer have a scrub hero to switch away from. */
.photo-hero{display:block;min-height:92vh}
.photo-hero .inner{min-height:92vh;padding-bottom:clamp(44px,9vh,96px)}
.photo-hero .shot{background-position:50% 50%}
.photo-hero .shot::after{
  /* Two layers instead of one. The headline is left aligned, so the heavy wash
     runs left to right and clears by two thirds across, which keeps the type
     readable while the mower stripes on the right stay visible. The vertical
     layer is only there to ground the buttons. */
  background:
    linear-gradient(96deg,
      rgba(5,8,12,.88) 0%,
      rgba(5,8,12,.83) 28%,
      rgba(5,8,12,.62) 46%,
      rgba(5,8,12,.28) 64%,
      rgba(5,8,12,.07) 80%,
      rgba(5,8,12,0)   90%),
    linear-gradient(180deg,
      rgba(5,8,12,.26) 0%,
      rgba(5,8,12,.06) 26%,
      rgba(5,8,12,.07) 56%,
      rgba(5,8,12,.30) 82%,
      rgba(5,8,12,.46) 100%);
}
.photo-hero .kicker{color:rgba(246,249,251,.92)}
@media (min-width:760px){
  .photo-hero .sh-title{font-size:clamp(2.7rem,5vw,4.5rem);max-width:13ch}
  .photo-hero .sub{font-size:clamp(1.05rem,1.55vw,1.32rem);max-width:48ch}
}
/* Shown on every screen now, so the gate queries must not hide it */
@media (max-width: 720px){ .photo-hero{display:block} }
@media (orientation: portrait) and (max-width: 1024px){ .photo-hero{display:block} }
@media (orientation: portrait) and (pointer: coarse){ .photo-hero{display:block} }
@media (orientation: landscape) and (pointer: coarse) and (max-height: 560px){ .photo-hero{display:block} }
@media (prefers-reduced-motion: reduce){ .photo-hero{display:block} }

/* Small type over a photo cannot rely on a soft gradient. It gets its own
   backing chip, which is the same trick used for HUD labels over video. */
.photo-hero .kicker{
  align-self:flex-start;
  background:rgba(5,8,12,.9);
  border:1px solid rgba(190,205,218,.34);
  border-radius:999px;
  padding:7px 14px;
  color:rgba(247,250,252,.96);
  margin-bottom:1.3rem;
}
@media (max-width:430px){
  /* balance stops it orphaning the last town on a line of its own */
  .photo-hero .kicker{padding:6px 11px;letter-spacing:.09em;font-size:.56rem;text-wrap:balance;line-height:1.5}
}

/* On a phone the text runs the full width, so the side wash has nothing to clear
   into; the vertical gradient does the work alone. The phone image is cropped to
   drop most of the sky, which put darker ground behind the headline and bought
   enough contrast headroom to ease this wash back and let the mowing stripes show.
   Measured worst case on the headline: 4.18:1. */
@media (max-width:760px){
  .photo-hero .shot::after{
    background:linear-gradient(180deg,
      rgba(5,8,12,.26) 0%,
      rgba(5,8,12,.08) 24%,
      rgba(5,8,12,.48) 46%,
      rgba(5,8,12,.76) 66%,
      rgba(5,8,12,.76) 100%);
  }
}

/* Three sentences, three lines. The copy is a deliberate triplet, so it breaks
   on the sentences rather than wherever the box happens to run out. */
.photo-hero .sh-title span{display:block}
/* hug the longest line so the block does not stretch into the bright side of
   the photo, which would also make any contrast reading meaningless */
.photo-hero .sh-title{width:max-content;max-width:100%}
@media (max-width:430px){
  .photo-hero .sh-title{font-size:clamp(2.1rem,8.6vw,2.7rem)}
}

/* The hero used to be an inline background-image, which meant a phone at 390px
   downloaded the same 1800px file a desktop did. Declaring it here lets the
   media query hand small screens a file built for them. */
.photo-hero .shot{background-image:url('hero-photo.jpg')}
@media (max-width:800px){
  .photo-hero .shot{background-image:url('hero-photo-sm.jpg')}
}
