/* ============================================================
   Hero — the container. It owns the band's height, the stack layout, the
   gap (the only spacing in here) and the type scale its atoms wear. The
   atoms themselves know none of this.

   Ported from the prototype's .dhero (styles/home.css). Deltas, deliberate:
     · one uniform 28px gap replaces the mockup's 24/28/36 margins, because
       spacing is the container's job and a single value is the contract;
     · the second title line is a plain <br> instead of a span dimmed to 90%
       white, so the whole title stays one editable RichText;
     · 9vw / 2.1vw become 9cqi / 2.1cqi, so the type scales with the SECTION.
       The editor canvas is not the viewport, and vw would lie there.
   ============================================================ */
.vt-hero {
  display: flex;
  align-items: center;
}
.vt-hero--screen { min-height: 100svh; }
/* the unified page hero's own height (mockup styles/hero.css .uhero): tall
   enough that the content centres with air above and below, never taller than
   a laptop viewport */
.vt-hero--tall { min-height: clamp(620px, 84svh, 860px); }

.vt-hero__inner {
  /* the type scale this section imposes on its atoms — front-page values */
  --vt-eyebrow-size: 12px;
  --vt-title-size: clamp(52px, 9cqi, 132px);
  --vt-title-weight: 200;
  --vt-title-leading: 0.92;
  --vt-title-tracking: -0.045em;
  --vt-text-size: clamp(16px, 2.1cqi, 21px);
  --vt-text-weight: var(--fw-light);
  --vt-text-leading: 1.55;
}

/* The stack. Two selectors because a hero WITH an image wraps its atoms in
   __body and turns __inner into the two-column grid, while a hero without one
   keeps the markup it always had — the atoms directly inside __inner. The type
   scale above is declared once, on __inner, and inherits into __body. */
.vt-hero__inner,
.vt-hero__body {
  display: flex;
  flex-direction: column;
  align-items: var(--vt-align);
  gap: 28px;
}

/* ------------------------------------------------------------
   The `page` type scale — the mockup's unified .uhero (styles/hero.css), worn
   by every hero that is not the front page. Only the numbers differ; the
   markup, the axes and the gap are the display hero's.

   Child selectors throughout: WordPress inlines this file BEFORE the theme's
   sheets, so a rule that only ties with .vt-section__inner on specificity
   loses. See BLOCKS.md trap 2.
   ------------------------------------------------------------ */
.vt-hero--scale-page > .vt-hero__inner {
  --vt-eyebrow-size: 14px;
  --vt-eyebrow-weight: var(--fw-regular);
  --vt-eyebrow-tracking: 0.16em;
  /* dark purple, not the subtle grey: 7.4:1 where light purple was 4.11:1 and
     failed AA as small uppercase text (the mockup's own note) */
  --vt-eyebrow-color: var(--color-dark-purple);
  --vt-eyebrow-dot: var(--color-light-purple);
  --vt-eyebrow-dot-ring: 0;

  --vt-title-size: clamp(30px, 6cqi, 64px);
  --vt-title-leading: 1.05;
  --vt-title-tracking: -0.03em;

  --vt-text-size: clamp(15px, 2.3cqi, 19px);
  --vt-text-leading: 1.5;
  --vt-text-measure: 640px;

  /* This hero is not full-screen, so vertical centring cannot be trusted to
     clear the fixed header the way it does on the front page — the mockup
     spends 200px of padding on it. Stated as air + the header's real height
     (--vt-header-height, measured in tokens.css) so the `air` axis still means
     something: with air `l` that is 96 + 104 = 200px, the mockup's number. */
  padding-top: calc(var(--vt-air) + var(--vt-header-height, 104px));
}
.vt-hero--scale-page.is-dark > .vt-hero__inner {
  /* on a dark page hero the kicker is white, not dark purple */
  --vt-eyebrow-color: var(--vt-fg);
}

/* ------------------------------------------------------------
   The optional image beside the stack — the mockup's product hero
   (styles/product.css `.uhero--product`, the LLS1000 page's opening band).
   Rendered only when a hero HAS an image, so nothing about a text-only hero
   changes: no wrapper, no grid, no classes.

   Child selectors again, for BLOCKS.md trap 2: this file is inlined before the
   theme's, so `.vt-hero--has-media > .vt-hero__inner` (0,2,0) is what beats
   sections.css's `.vt-section__inner` (0,1,0).
   ------------------------------------------------------------ */
.vt-hero--has-media > .vt-hero__inner {
  display: grid;
  /* the copy column is the wider one — the mockup's 1.05 / 0.95 */
  grid-template-columns: 1.05fr 0.95fr;
  gap: clamp(28px, 5cqi, 80px);
  align-items: center;
}
.vt-hero--media-left.vt-hero--has-media > .vt-hero__inner { grid-template-columns: 0.95fr 1.05fr; }
/* The body is always FIRST in the DOM (see render.php); the side is done with
   `order`, so the reading order never depends on the visual arrangement. */
.vt-hero--media-left > .vt-hero__inner > .vt-hero__media { order: -1; }

/* The narrower copy column takes the mockup's smaller headline: 3.8cqi capped
   at 52px against the full-width hero's 6cqi capped at 64. A container owning
   the type its atoms wear is the whole contract here, and the column really is
   narrower — so this is the same fact stated once, not a second design channel.
   Weight 300 is the mockup's too. Amplitude now ships a real 200 and a real 500
   and nothing between, so CSS font matching resolves 300 DOWN to the 200 — the
   rule for a desired weight under 400 is to look lower first. That is the
   intended result here; it is stated so nobody "fixes" it into 500 later.
   See the theme's assets/fonts/README.md. */
.vt-hero--has-media.vt-hero--scale-page > .vt-hero__inner {
  --vt-title-size: clamp(30px, 3.8cqi, 52px);
  --vt-title-weight: 300;
}

.vt-hero__media {
  position: relative;
  margin: 0;
  text-align: center;
  justify-self: center;
}
.vt-hero__img {
  position: relative;
  z-index: 1;
  /* `block`, not the split's `inline-block`: an inline image carries its line
     box's descender space, which put 6px of nothing under the render — and the
     floor ellipse is positioned from the FIGURE's bottom edge, so those 6px
     pushed the shadow off the feet. The mockup states `display: block` too. */
  display: block;
  margin-inline: auto;
  width: auto;
  max-width: 100%;
  /* svh, NOT cqi. Everywhere else in this set a mockup `vw` becomes `cqi`,
     because the editor canvas is not the viewport — but this number is the
     mockup's `44vh`, and what it is doing is keeping the render inside the
     SCREEN's height so the hero fits without scrolling. A container's inline
     size cannot express that: 44cqi of a 1440px band is 633px, which the clamp
     then caps at 460 and the render comes out 64px taller than the design at
     every window height. `.vt-hero--tall` already states its own height in svh
     for the same reason. Measured against the mockup at 1440x900: 396px in
     both. */
  max-height: clamp(340px, 44svh, 460px);
  height: auto;
}
/* Two shadows, one toggle, and they are the mockup's own pair: a soft
   drop-shadow that follows the deep-etched silhouette, plus the elliptical
   floor it appears to stand on. Both go when the toggle does — a rectangular
   photo wants neither. No token carries an opacity, so every alpha is mixed
   here from --color-ink. */
.vt-hero__img--shadow {
  filter: drop-shadow(0 10px 16px color-mix(in srgb, var(--color-ink) 10%, transparent));
}
/* the floor. A shape, not a glyph — empty content, no text, the same idiom the
   lens table's sort arrows use — so nothing is exposed to a screen reader. It
   hangs off a class on the FIGURE rather than off `:has()` on the image, so the
   canvas and render.php can state the same thing the same way. */
.vt-hero__media--floor::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 34px;
  z-index: 0;
  transform: translateX(-50%);
  width: 58%;
  height: 26px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--color-ink) 30%, transparent);
  filter: blur(15px);
  pointer-events: none;
}

/* the scroll cue — decorative, aria-hidden in the markup */
.vt-hero__scroll {
  position: absolute;
  bottom: 32px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  font-family: var(--font-body);
  font-size: max(11px, var(--fs-floor, 0px));
  font-weight: var(--fw-regular);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--vt-fg) 50%, transparent);
}
.vt-hero__scroll-line {
  width: 1px;
  height: 28px;
  background: linear-gradient(180deg, transparent, color-mix(in srgb, var(--vt-fg) 60%, transparent));
  animation: vt-scroll-pulse 2.4s ease-in-out infinite;
}
@keyframes vt-scroll-pulse {
  0%, 100% { opacity: 0.3; transform: translateY(-4px); }
  50%      { opacity: 1;   transform: translateY(4px); }
}
@media (prefers-reduced-motion: reduce) {
  .vt-hero__scroll-line { animation: none; }
}

/* Phones. Everything lives on __inner because a block can never query its own
   container — .vt-hero IS the container here.

   The child selector is load-bearing, not decoration: WordPress inlines a
   block's style.css in the head BEFORE the theme's sheets, so a block rule that
   ties with the skeleton on specificity LOSES. `.vt-hero > .vt-hero__inner` is
   0,2,0 and beats sections.css's `.vt-section__inner` (0,1,0) whatever the load
   order turns out to be. Any block rule that refines a skeleton property needs
   the same treatment. */
@container vt-section (max-width: 760px) {
  .vt-hero > .vt-hero__inner {
    --vt-title-size: clamp(40px, 13cqi, 76px);
    /* clear the floating header, which overlaps a phone-height hero */
    padding-top: 110px;
  }
  /* the mockup lifts the phone floor to 38px: the 30px base read as too small,
     and 38px still keeps the longest product title to two lines at 390px.
     Top clearance is the mockup's own 150px — the desktop calc() would leave
     168px, and the header is shorter on a phone, not taller. */
  .vt-hero--scale-page > .vt-hero__inner,
  /* The two-column variant needs saying again, and the specificity is why: its
     own desktop rule is (0,3,0) and this one would otherwise be (0,2,0), so the
     52px cap would survive into the phone layout and the title would come out
     at 30px — under the 38px floor the line above exists to set. Once the
     columns have folded there is only one column, so the phone number is the
     same number. */
  .vt-hero--has-media.vt-hero--scale-page > .vt-hero__inner {
    --vt-title-size: clamp(38px, 10cqi, 46px);
    padding-top: 150px;
  }
  /* the page hero stops reserving height on a phone: the mockup drops its
     min-height entirely there, and 84svh of empty band is not a design */
  .vt-hero--tall { min-height: auto; }
}

/* The two-column hero folds one breakpoint earlier than the type does, because
   what runs out is the copy column and not the line length — the mockup folds at
   880px and 860 is this set's nearest container breakpoint. The image goes UNDER
   the copy, which is the product hero's own call (.uhero--product .uhero__media
   { order: 2 }) and the opposite of the split section's: in a split the image is
   half the argument, in a hero the headline is the whole of it. It is already
   second in the DOM, so nothing has to be reordered — only the `left` variant's
   order reset. */
@container vt-section (max-width: 860px) {
  .vt-hero--has-media > .vt-hero__inner {
    grid-template-columns: minmax(0, 1fr);
    gap: 30px;
  }
  .vt-hero--media-left > .vt-hero__inner > .vt-hero__media { order: 0; }
  .vt-hero--has-media > .vt-hero__inner > .vt-hero__media > .vt-hero__img {
    max-height: 340px;
    margin-inline: auto;
  }
}
