/* =============================================================
   Snap Zap Media — homepage hero

   Lifted from the approved hero.html and rebuilt against the
   mockup Robbie approved on 2026-09-16. The mechanism is signed
   off and is not redesigned here: one pinned frame, headline
   right, road left, a glowing arrow climbing the road, five steps
   lighting in turn.

   WHAT THE 2026-09-16 REBUILD CHANGED, and only this:
     · the frame stops directly beneath the sticky masthead, so
       the headline is never tucked under it at any scroll
       position
     · the frame carries the approved soft gradient, --hero-veil,
       instead of a flat fill
     · the dashed centre line is gone; the two glowing side lines
       and their glow stay, and the arrow now points RIGHT, its
       tip towards the step it is lighting
     · the H1 and the tagline never fade or move — only the body
       paragraph does
     · the two calls to action moved INTO the hero copy, beneath
       the tagline, and arrive at step 5
     · the step text is larger, and one step shows at a time

   Removed on the original porting, and still absent: the
   duplicated :root token block (tokens.css is the single source),
   and the rules tokens.css already owns — h1, .btn, .wrap,
   .site-head.

   There is NO inner scroll container. The page scrolls the
   window natively. An inner scroll wrapper was tried and killed.
   ============================================================= */

.hero{ position:relative; height:440vh }

/* THE PINNED FRAME. The box is a full viewport tall so the
   approved background reads at the scale it was approved at and
   runs edge to edge behind the masthead. Its CONTENT is not: the
   padding holds open a band exactly as tall as the masthead, so
   the stage — the frame the visitor actually sees — begins
   directly beneath it and the headline can never be tucked under
   the header. --mast-h is measured and set by the hero script;
   the 0px fallback is only ever used for the frames before it
   runs. */
.pin{ position:absolute; top:0; left:0; right:0; height:100svh;
  padding-top:var(--mast-h,0px);
  background:var(--hero-veil);
  will-change:transform }

.stage{ position:relative; width:var(--page); height:100%; margin-inline:auto }
.stage canvas{ position:absolute; inset:0; width:100%; height:100% }

/* Where the hero ends it fades into the page ground, so the foot
   of the frame — the darkest stop of --hero-veil — meets --ground
   with no visible seam. It only reaches the viewport at the
   moment the frame releases; for the whole of the scroll it is
   below the fold. */
.hero::after{
  content:''; position:absolute; left:0; right:0; bottom:0;
  height:clamp(72px,10vh,140px); pointer-events:none;
  background:linear-gradient(180deg, transparent 0%, var(--ground) 100%);
}

.hero-copy{ position:absolute; left:0; top:0; width:40% }

/* The tagline STAYS. It does not fade and it does not move —
   ruled 2026-09-16, replacing the fade it carried until then.
   Nothing collapses it, so it no longer needs to hide overflow. */
.hero-sub{ font-family:var(--display); font-weight:500; font-size:var(--step-2);
  line-height:1.25; letter-spacing:-.015em; color:var(--accent);
  margin:1.1rem 0 0 }

/* The body paragraph is the one piece of copy that clears the
   column. It says its piece on landing, then fades and collapses
   as the journey starts. It sits BELOW the buttons, so nothing
   above it moves when it goes. */
.hero-body{ margin:1.1rem 0 0; color:var(--ink-muted); font-size:var(--step-1);
  line-height:1.5; overflow:hidden }

/* THE CALLS TO ACTION, in the hero copy. Ruled by Robbie
   2026-09-16, replacing the pair that sat in a band below the hero
   until then.

   COLLAPSED TO NOTHING until step 5 — no height, no margin, no
   opacity — then they expand, fade and rise about 12px over
   progress 0.90 to 0.96 and stay. They are LAST in the copy,
   after the body paragraph, so the landing frame reads headline,
   tagline, body with no empty band held open beneath the tagline.
   The body collapses as the scroll starts, so by the time these
   open they arrive directly beneath the tagline, which is where
   the approved mockup has them.

   `visibility:hidden` is what keeps them out of the tab order, out
   of the accessibility tree and out of reach of a click while they
   are shut; `opacity:0` alone would not. The script turns it on as
   the expansion begins, and hands `max-height` back to `none` at
   the end of it so a focus ring is never clipped by the overflow.

   No transition: the expansion is driven by the scroll, frame by
   frame, and a transition would fight it.

   ★ The step band does NOT follow them. It reserves their full
   height from first paint whether they are open or shut, so the
   five steps never move and never meet them. */
.hero-buttons{
  display:flex; flex-wrap:wrap; gap:.9rem 1rem; align-items:center;
  margin:0; max-height:0; overflow:hidden;
  opacity:0; visibility:hidden; transform:translateY(12px);
}

/* The natural, fully open geometry, which is the only place the
   buttons' real height and margin are written down. The script
   borrows this class for one synchronous measurement per layout
   and drops it again in the same frame, so the band can reserve
   the full height while the buttons themselves stay shut.
   `visibility` is untouched by it: they are never painted, focusable
   or clickable in this state. */
.hero-buttons.is-measuring{ margin-top:1.4rem; max-height:none }

/* The navigational secondary wears the static polished chrome
   edge — Robbie's ruling 2026-09-16, the second and last thing on
   the site permitted it after the Visual Concepts feature card.
   Same --chrome-edge gradient, same 1px, same stillness: it does
   not move, shimmer or react to hover, and it must never be
   mistaken for the moving Liquid Metal rim on Book Discovery
   Call beside it, which is untouched.

   ★ NOT the feature card's mechanism, and it cannot be. That card
   paints the chrome to its border box and its face to its padding
   box, which works only because --fill-surface is opaque. This
   button's face is --fill-ghost, which is a translucent wash
   fading to nothing at its foot — painted the same way, the
   chrome reads straight through it and the whole button turns
   silver. Tried, seen, rejected.

   So the edge is a 1px ring instead: the gradient is painted over
   the button and then masked down to its own 1px rim, leaving the
   ghost face untouched behind it. The border comes off and its
   1px goes into the padding, so the button is exactly the size it
   was.

   Behind @supports, so a browser without mask compositing keeps
   the ordinary hairline border rather than a silver slab. And
   because there is no border left to colour, the shared
   .btn-secondary:hover has nothing to change — the edge holds
   still while the label and the glow answer hover as they always
   did. */
@supports ((-webkit-mask-composite: xor) or (mask-composite: exclude)){
  #home-hero-secondary{
    border:0;
    padding:calc(.95rem + 1px) calc(1.6rem + 1px);
  }
  #home-hero-secondary::before{
    content:''; position:absolute; inset:0; border-radius:inherit;
    padding:1px; background:var(--chrome-edge); pointer-events:none;
    -webkit-mask:linear-gradient(#fff 0 0) content-box,
                 linear-gradient(#fff 0 0);
    -webkit-mask-composite:xor;
            mask:linear-gradient(#fff 0 0) content-box,
                 linear-gradient(#fff 0 0);
            mask-composite:exclude;
  }
}

.steps{ position:absolute; inset:0; pointer-events:none }
.stop{ position:absolute; left:0; top:0; transform:translateY(-50%) }
.stop-rule{ width:26px; height:1px; background:var(--accent-deep); margin-bottom:.6rem;
  transition:width .3s ease, background-color .3s ease }
.stop.is-active .stop-rule{ width:58px; background:var(--accent) }
.stop-index{ font-size:.78rem; letter-spacing:.22em; text-transform:uppercase;
  color:var(--ink-faint); margin:0 0 .3rem; font-variant-numeric:tabular-nums }
.stop.is-active .stop-index{ color:var(--accent) }

/* Bigger, and only one of them lights at a time — ruled
   2026-09-16. The supporting line is now the tagline's own size
   and the heading colour, so a step reads as a statement rather
   than as a caption. */
.stop-label{ font-family:var(--display); font-weight:700;
  font-size:clamp(1.5rem,1.2rem + 1.2vw,2.2rem); line-height:1.08;
  letter-spacing:-.02em; margin:0; color:var(--ink); text-wrap:balance }
.stop-line{ margin:.4rem 0 0; font-size:var(--step-2); line-height:1.35;
  color:var(--ink); text-wrap:pretty; max-width:none }

/* ONE SENTENCE PER LINE. Robbie's wording of 2026-09-16 gives some
   stops two sentences, and they never run together: each is its own
   block inside .stop-line, so the second always starts on a new line.
   No extra space between them — they read as consecutive lines, not
   as separate paragraphs.

   ★ The size is NEVER reduced to make a sentence fit. On a narrow
   column a sentence wraps under itself and the step gets taller,
   which is approved and which the step band measures and allows
   for. */
.stop-line span{ display:block }

.rm-list{ display:none }
@media (prefers-reduced-motion:reduce){
  .hero{ height:auto }
  .hero::after{ display:none }
  .pin{ position:static; height:auto; padding-top:0; background:none }
  .stage{ display:none }
  .rm-list{ display:grid; gap:1.8rem; width:var(--page); margin-inline:auto;
    padding-block:2rem }
  /* ★ DEFECT FOUND IN THE APPROVED hero.html, fixed here — reported 2026-09-14.
     That file resets .rm-list .stop but never .hero-copy, so under
     prefers-reduced-motion the headline keeps position:absolute and lands on
     top of the step list, making both unreadable. Reproduced in hero.html
     itself, so it is not a porting error. DESIGN-SYSTEM §6 requires reduced
     motion to be respected "including in the hero". One line, and it touches
     nothing on the motion path. */
  .rm-list .hero-copy{ position:static; width:auto }

  /* There is no scroll-driven reveal here, so there is nothing to
     wait for: the buttons are simply visible, open and in place
     from the start. */
  .rm-list .hero-buttons{ margin-top:1.4rem; max-height:none; overflow:visible;
    opacity:1; visibility:visible; transform:none }

  .rm-list .stop{ position:static; transform:none; opacity:1!important; width:auto!important }
  .rm-list .stop-rule{ width:58px; background:var(--accent) }
  .rm-list .stop-index{ color:var(--accent) }
}
