/* ==========================================================================
   Video intro — scroll-expanding pill with kinetic typography.

   Converted from a React/GSAP ScrollTrigger reference to vanilla CSS + JS:
   the section is tall, a sticky viewport pins inside it, and vhero.js maps
   scroll progress onto the pill's insets (pill → full-bleed) and the word
   layer (fade / scale / blur). No dependencies.

   Colours are the site's own: Satoshi 900 in white and lavender for the
   sans words, the serif italic word in dawn coral, clock timestamps coral
   on muted labels.
   ========================================================================== */

.vhero {
  position: relative;
  height: 260vh; /* scroll distance: ~1.6 viewports of scrub after the pin */
}

.vhero__sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  min-height: 520px;
  overflow: hidden;
}

/* ── Kinetic words ─────────────────────────────────────────────────────── */
.vhero__words {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  transform-origin: center;
  will-change: transform, opacity, filter;
}

.vhero__word {
  position: absolute;
  font-weight: 900;
  letter-spacing: -0.04em;
  line-height: 0.95;
  white-space: nowrap;
}
.vhero__word--top {
  top: 2%;
  left: 0; right: 0;
  text-align: center;
  color: var(--text);
  font-size: clamp(3.2rem, 11vw, 10.5rem);
}
.vhero__word--right {
  right: 3%;
  top: 38%;
  color: var(--accent);
  font-size: clamp(3.2rem, 11vw, 10.5rem);
}
/* Phone-only caption, hung off "find you" rather than positioned as a fourth
   word: it inherits that block's centring and moves with it, so the tuned
   mobile stack cannot drift apart. Hidden elsewhere — on desktop the hero
   lede sits a short scroll below and already says the number. */
.vhero__tag { display: none; }

.vhero__word--bottom {
  bottom: 2%;
  left: 0; right: 0;
  text-align: center;
  font-family: Georgia, 'Times New Roman', Cambria, serif;
  font-weight: 400;
  font-style: italic;
  letter-spacing: -0.02em;
  color: var(--dawn-4, #ff9b6a);
  font-size: clamp(3.6rem, 14vw, 12.5rem);
}

/* ── Live clocks (nationwide reach: ET / CT / PT) ──────────────────────── */
.vhero__clocks {
  position: absolute;
  left: clamp(1.25rem, 4vw, 5rem);
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace;
  font-size: clamp(9px, 1.1vw, 12px);
  letter-spacing: 0.15em;
  text-transform: uppercase;
}
.vhero__clock { display: flex; align-items: center; gap: clamp(0.5rem, 1.2vw, 1.5rem); }
.vhero__time {
  color: var(--accent-warm, #ff9b6a);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.vhero__city { color: var(--text-muted); }

/* ── The expanding pill ────────────────────────────────────────────────── */
/* Start insets live in custom props so vhero.js can read them per viewport
   (the mobile block overrides them). JS interpolates each to 0 on scroll. */
.vhero__pill {
  position: absolute;
  z-index: 2;
  top:    var(--pt, 18%);
  bottom: var(--pb, 18%);
  left:   var(--pl, 22%);
  right:  var(--pr, 18%);
  border-radius: 12px;
  overflow: hidden;
  background: var(--card, #131125);
  box-shadow: 0 40px 90px -40px rgba(0, 0, 0, 0.8);
  will-change: top, bottom, left, right, border-radius;
}
.vhero__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ── Mobile ────────────────────────────────────────────────────────────── */
@media (max-width: 720px) {
  .vhero { height: 220vh; }

  /* Phone composition, reading top to bottom:
       helping        (white)
       people         (lavender)   <- stacked, not off to the right
       [ video ]
       find you       (coral serif, the largest thing on screen)
     The whole thing still has to fit one screen with no scrolling, so the
     pill's insets are tuned against the word blocks above and below it. */
  /* Sit in the area the sticky nav actually leaves visible, so the
     composition is measured against the screen the viewer really has.
     Mobile only — desktop layout is untouched. */
  .vhero__sticky {
    top: var(--nav-h, 0px);
    height: calc(100svh - var(--nav-h, 0px));
    /* The base rule's flat 520px floor was written for the desktop case,
       where this box starts at the top of the screen. Here it starts BELOW
       the nav, so on a 320x568 phone the floor beat the height calc and hung
       the box 19px off the bottom of the screen, clipping the last line. The
       floor has to come down by the same nav height the top went down by. */
    min-height: calc(520px - var(--nav-h, 0px));
  }

  .vhero__pill { --pt: 30%; --pb: 22%; --pl: 8%; --pr: 8%; }

  .vhero__word--top { top: 10%; }

  /* Off the right edge on desktop; centred under "helping" on phones, where
     a word hanging past the frame just collides with the video.
     The offset is in em, not %, on purpose: a percentage compresses on a
     short screen while the clamped font size does not, and the two words
     collide. Tying the gap to the type keeps the pair stacked at any
     viewport height. */
  .vhero__word--right {
    top: calc(10% + 1.12em);
    right: auto;
    left: 0;
    width: 100%;
    text-align: center;
  }

  /* This line carries the promise, so on phones it gets to be the biggest
     thing on screen rather than matching the sans words. */
  /* Anchored by `bottom`, so the caption inside makes this block grow
     UPWARDS and "find you" climbs toward the video pill. The inset drops to
     pay for the caption's height; the pair still ends clear of the edge. */
  .vhero__word--bottom {
    bottom: 4%;
    font-size: clamp(4.4rem, 19vw, 7rem);
  }

  .vhero__tag {
    display: block;
    margin-top: 0.85em;
    padding: 0 12px;
    /* 3.2vw hits exactly 12px at 375px, so the common phone is unchanged and
       only narrower ones scale down. The line must never wrap: there are
       ~13px between it and the video pill, and a second line would land on
       top of the video. */
    font-size: clamp(10px, 3.2vw, 12px);
    font-weight: 700;
    /* Every one of these undoes something inherited from .vhero__word--bottom,
       which is 71px Georgia italic in coral. */
    font-family: var(--font);
    font-style: normal;
    letter-spacing: 0.10em;
    line-height: 1.35;
    text-transform: uppercase;
    white-space: normal;
    color: var(--text-soft);
  }

  .vhero__clocks { display: none; } /* would collide with the pill at 8% inset */
}

/* Short phones (SE, older Androids): same composition, tighter budget. */
@media (max-width: 720px) and (max-height: 700px) {
  .vhero__word--top { top: 6%; }
  .vhero__word--right { top: calc(6% + 1.12em); }
  .vhero__pill { --pt: 34%; --pb: 21%; }
  .vhero__word--bottom { bottom: 3%; font-size: clamp(3.4rem, 16vw, 5rem); }
}

/* ── Reduced motion: no pin, no scrub — one static screen ──────────────── */
@media (prefers-reduced-motion: reduce) {
  .vhero { height: auto; }
  .vhero__sticky { position: relative; height: 100vh; }
}

/* ==========================================================================
   The story beat after the video — same content as the old split hero,
   recomposed as a centered sequence so it reads as a continuation of the
   intro: promise (video) → statement (who this is for) → proof (the SERP)
   → stakes (the stat cards).
   ========================================================================== */
.hero-statement {
  text-align: center;
  padding-bottom: 40px;
}
.hero-statement .hero__badge { margin-bottom: 28px; }
.hero-statement .h-hero { max-width: 900px; margin-left: auto; margin-right: auto; }
.hero-statement .lede { max-width: 640px; margin-left: auto; margin-right: auto; }
.hero-statement .btn-row { justify-content: center; }

.hero-showcase { padding-top: 0; padding-bottom: 56px; }
.hero-showcase .serp { max-width: 780px; margin: 0 auto; }

/* ── Reveal-on-scroll ──────────────────────────────────────────────────────
   The intro animates; these let the beats after it arrive with the same
   energy instead of just being there. html.js is set by vhero.js, so with
   scripts off nothing is ever hidden. */
html.js [data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 650ms ease, transform 650ms ease;
}
html.js [data-reveal="2"] { transition-delay: 110ms; }
html.js [data-reveal="3"] { transition-delay: 220ms; }
html.js [data-reveal].is-revealed { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html.js [data-reveal] { opacity: 1; transform: none; transition: none; }
}
