/* Hero layout. The one place the system needs media queries: the flag's fixed type
   scale and the reel's horizontal position have to agree, and a percentage alone
   cannot know how wide the credential strip is.

   The side-by-side composition is designed for 1280 and up. Below that the hero
   becomes a single column with the reel below the flag, so copy never lands on
   footage and the flag never overflows its own height budget. */

.lo-hero {
  /* Flag metrics come from the pinned ring tokens (tokens/typography.css). They are set as
     custom properties, not font-size rules, because FlagHeadline sizes itself from inline
     vars: a class rule here would lose to the inline style and silently do nothing. */
  --flag-lead-size: var(--ring-lead); /* @kind font */
  --flag-lead-line: var(--ring-lead-line); /* @kind other */
  --ring-size: var(--ring-size-hero); /* @kind font */
  --lo-hero-h: 692px; /* @kind spacing */   /* 800 viewport minus 108 of masthead and nav */
  --lo-text-w: 48%;
  /* Reel mask geometry. Declared on the hero scope (custom properties inherit down to
     the masked element) rather than as a var() fallback, because a multi-token fallback
     like `auto 130%` does not survive the CSSOM when set from an inline style. */
  --lo-reel-mask-size: auto 130%; /* @kind other */
  --lo-reel-mask-pos: left top; /* @kind other */
  position: relative;
  background: var(--lo-paper-100);
  box-sizing: border-box;
}
.lo-hero__inner {
  position: relative;
  z-index: 2;
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--gutter);
  width: 100%;
  box-sizing: border-box;
  min-height: var(--lo-hero-h);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-7);
}
.lo-hero__col { width: var(--lo-text-w); min-width: 0; display: flex; flex-direction: column; }
/* Both class rules and the component's inline vars resolve to the same tokens, because the
   two flag implementations size differently: the design-system FlagHeadline carries an inline
   font-size (which beats any class rule), while the marketing-site copy in
   ui_kits/marketing_site/HeroReelOptions.jsx sets no font-size at all and depends on these
   rules. Remove either path and one of the two heroes loses the ring. */
.lo-hero__lead { font-size: var(--flag-lead-size); line-height: var(--flag-lead-line); }
.lo-hero__ring { font-size: var(--ring-size); }
/* Anchored to the container, not the raw viewport, so the composition holds its
   proportions on wide screens instead of drifting away from the text column.

   0.06, WAS 0.12. Ryan's ruling 9 Sep, after the gold came down to 96px and left 180px of empty
   column between the text and the mark. Measured at both widths before choosing, and the offsets
   behave identically at 1280 and 1440 -- the two edges move together, so this is one decision rather
   than a per-width one:

       offset   reel left (1440)   mark width   gap to painted text
       0.12     874                566          180
       0.08     822                618          128
       0.06     797                643          103   <- here
       0.04     771                669           77
       0.00     720                720           26

   MOVING LEFT COSTS THE TEXT NOTHING, which is what made it the right lever. The reel stays clear of
   the text column's edge (696px at 1440) at every offset down to 0.00 -- the gap closes against the
   PAINTED TEXT, not the column -- and the mark gets BIGGER on the way, 566 -> 643px. That is the
   opposite of the trade Ryan turned down earlier, where moving the reel RIGHT to buy a line break
   would have cost 210px of the mark.

   NOT GOING FURTHER. Ryan: "0.04 at 77px is where it starts crowding." 103px is about one
   arrowhead-width of breathing room and the value is a floor by decision, not by geometry.

   AND IT IS NO LONGER COUPLED TO THE CLAUSE. The old comment two files over claimed this position
   existed to clear a nowrap line that ran past the column; that coupling was measured false and is
   gone (see hero-extras.css). This offset is now a composition choice on its own, and the flag's
   clearance is asserted independently in dev/assert-layout.mjs rather than assumed from it. */
.lo-hero__reel {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: calc(50% + 0.06 * min(100vw, var(--container-max)));
  overflow: hidden;
}

/* Site nav. Below 1280 the link row tightens; below 1024 it collapses into a
   hamburger and a full-width drawer. Standard convention, kept quiet: paper ground,
   hairline dividers, display-serif links, the same dark CTA. */
.lo-nav__links { display: flex; align-items: center; gap: var(--space-6); }
.lo-nav__links a { white-space: nowrap; }
.lo-nav__cta { white-space: nowrap; }
.lo-nav__burger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 0 10px;
  background: none;
  border: none;
  cursor: pointer;
  box-sizing: border-box;
}
.lo-nav__burger span {
  display: block;
  height: 2px;
  width: 100%;
  background: var(--lo-ink-900);
  transition: transform var(--dur-slow) var(--ease), opacity var(--dur-fast) var(--ease);
}
.lo-nav__drawer {
  display: none;
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  z-index: 40;
  background: var(--lo-paper-0);
  border-top: 2px solid var(--lo-gold-500);
  border-bottom: 1px solid var(--lo-gray-300);
  box-shadow: var(--elevation-chrome);
  padding: var(--space-5) var(--gutter) var(--space-7);
  flex-direction: column;
}

@media (max-width: 1279px) {
  .lo-nav__links { gap: var(--space-5); }
}
@media (max-width: 1023px) {
  .lo-nav__links { display: none; }
  .lo-nav__descriptor { display: none; }
  /* The CTA lives in the drawer at this width so the bar stays one clean line. */
  .lo-nav__cta-wrap { display: none; }
  .lo-nav__burger { display: flex; }
  .lo-nav__drawer { display: flex; }
}

/* ── Hub modules ───────────────────────────────────────────────────────────────
   Column templates live here, not in the components' inline styles: an inline
   template beats a stylesheet rule, so a breakpoint could never override it.
   Counts that need to stay configurable come through custom properties.
   Same 1280 / 1024 breaks as the hero and nav above. */

.lo-container {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--gutter);
  width: 100%;
  box-sizing: border-box;
}

/* ── Audience hub hero ──────────────────────────────────────────────────────────
   ONE design, three background modes. Type and layout are identical in every mode;
   only the ground and the ink/paper inversion change. Sizes live here rather than in
   the component so a mode can never quietly redefine them. */
.lo-pagehero {
  position: relative;
  overflow: hidden;
  box-sizing: border-box;
}
.lo-pagehero__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.lo-pagehero__scrim { position: absolute; inset: 0; background: linear-gradient(100deg, rgba(24,34,22,.95) 0%, rgba(24,34,22,.88) 38%, rgba(24,34,22,.42) 70%, rgba(24,34,22,.16) 100%); }
.lo-pagehero__base { position: absolute; left: 0; right: 0; bottom: 0; height: 5px; background: var(--lo-gold-500); z-index: 3; }
/* IN THE CONTAINER, like every other section on the page. This rule used to pad a
   full-bleed box with a 64px --lo-hero-pad-x instead of constraining it, so the hero's text
   started 64px from the raw screen edge while the rest of the page started at the container
   margin: 48px out at 1280, 207px out at 1772, and worse the wider the display. The
   composition read as a hero that had escaped the grid. Same three lines as
   .lo-hero__inner: max-width, auto margins, gutter padding. */
.lo-pagehero__inner {
  position: relative;
  z-index: 2;
  box-sizing: border-box;
  max-width: var(--container-max);
  margin: 0 auto;
  /* NOT viewport-sized. Fitting the hero to the screen is the homepage flag hero's rule
     and nowhere else: this hero is as tall as its content, measured against the longest
     rotation statement, plus the standard chapter padding. */
  padding: var(--chapter-pad-top, var(--section-y)) var(--gutter) var(--section-y-tight);
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: 0;
}
/* Text only. No figure column: the hub hero carries its statement on type alone, which is
   what the paper mode is for. */
.lo-pagehero__eyebrow { font-family: var(--font-label); font-size: 13px; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; margin-bottom: var(--section-head-gap); }
/* ROOT CAUSE OF THE THREE HEIGHT REPORTS, fixed here. Nothing in this system ever set a
   viewport height on the hub hero. The height came from THIS rule: at the homepage flag's
   display scale (104px at 21ch) the longest rotation statement runs three lines, the page
   then reserves that block so the beats cannot jump, and 309px of reserved headline plus
   96/64 of chapter padding plus the foot measured 739px, which reads as full viewport on a
   laptop. The hub hero is a page opener, not the flag: only the homepage may viewport-size.
   Content-height model: a display scale that keeps the longest statement to two lines at a
   24ch measure, so all three beats reserve the same modest block. */
.lo-pagehero__h1 {
  font-family: var(--font-display);
  font-size: var(--pagehero-h1-size);
  line-height: var(--pagehero-h1-line);
  font-weight: 600;
  letter-spacing: var(--pagehero-h1-tracking);
  margin: 0;
  max-width: var(--pagehero-h1-measure);
  text-wrap: balance;
}
.lo-pagehero__ring { font-style: italic; font-weight: 500; }
/* The headline box can be taller than its text: a rotating hero reserves the longest
   statement so nothing below it moves between beats. The slack therefore has to sit
   directly under the headline, and everything below the rule has to read as ONE group,
   or the reservation looks like a hole between the copy and the buttons. Gaps are the
   page's within-section rhythm, not distributed slack. */
.lo-pagehero__foot {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: var(--space-9);
  padding-top: var(--stack-gap);
}
/* A stat, when the spruce mode carries one, takes the full width under both. */
.lo-pagehero__foot > .lo-pagehero__stat { grid-column: 1 / -1; }
.lo-pagehero__body { font-family: var(--font-reading); font-size: 20px; line-height: 1.5; margin: 0; max-width: 46ch; text-wrap: pretty; }
.lo-pagehero__actions { display: flex; align-items: center; gap: var(--space-6); flex-wrap: wrap; justify-content: flex-end; }
.lo-pagehero__stat { flex: none; display: flex; flex-direction: column; gap: var(--space-2); border-left: 5px solid var(--lo-gold-500); padding-left: var(--space-5); }
.lo-pagehero__statValue { font-family: var(--font-numeral); font-size: var(--pagehero-stat-size); line-height: 1; font-weight: 600; letter-spacing: -.02em; color: var(--lo-gold-500); }
.lo-pagehero__statTk { font-family: var(--font-label); font-size: 13px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--lo-ink-900); background: var(--lo-gold-100); border: 1px dashed var(--lo-gold-600); border-radius: var(--radius-1); padding: 10px 14px; align-self: flex-start; }
.lo-pagehero__statLabel { font-family: var(--font-label); font-size: 13px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--lo-green-100); }

@media (max-width: 1023px) {
  .lo-pagehero__inner { padding: var(--section-y-tight) var(--gutter); }
  .lo-pagehero__body { font-size: 18px; }
  /* One column below 1024: the CTA pair drops under the subhead rather than squeezing it. */
  .lo-pagehero__foot { grid-template-columns: minmax(0, 1fr); gap: var(--stack-gap); align-items: start; }
  .lo-pagehero__actions { justify-content: flex-start; }
}
@media (max-width: 639px) {
  .lo-pagehero__h1 { max-width: none; }
  .lo-pagehero__actions { gap: var(--space-4); }
}

/* Build / Grow offering grid. */
.lo-servicegrid {
  display: grid;
  grid-template-columns: repeat(var(--lo-service-cols, 4), minmax(0, 1fr));
  gap: var(--space-5);
  align-items: stretch;
}

/* Proof figures and the quote/credentials split. */
.lo-proofstats {
  display: grid;
  grid-template-columns: repeat(var(--lo-proof-cols, 3), minmax(0, 1fr));
  gap: var(--space-8);
  padding-bottom: var(--space-8);
}
.lo-proofbody {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: var(--space-9);
  padding-top: var(--space-8);
  align-items: start;
}
.lo-proofbody[data-single='true'] { grid-template-columns: minmax(0, 1fr); }

/* Closing CTA. */
.lo-closingcta {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--gutter);
  box-sizing: border-box;
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
  gap: var(--space-9);
  align-items: start;
}
.lo-closingcta[data-single='true'] { grid-template-columns: minmax(0, 1fr); }

/* Vertical hub rows. */
.lo-verticalrow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr) auto;
  gap: var(--space-6);
  align-items: baseline;
}

@media (max-width: 1279px) {
  /* Four offerings across is the first thing to break: at this width the cards get
     narrower than their own headings. Two-up keeps the copy readable. */
  .lo-servicegrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lo-proofbody,
  .lo-closingcta { grid-template-columns: minmax(0, 1fr); gap: var(--space-7); }
  .lo-proofstats { gap: var(--space-6); }
}

@media (max-width: 1023px) {
  .lo-servicegrid { grid-template-columns: minmax(0, 1fr); }
  .lo-proofstats { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: var(--space-7); }
  .lo-verticalrow {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-3);
    align-items: start;
  }
}

@media (max-width: 639px) {
  .lo-proofstats { grid-template-columns: minmax(0, 1fr); }
}

.lo-credstrip { flex-wrap: nowrap; white-space: nowrap; }

@media (max-width: 1279px) {
  .lo-hero {
    --flag-lead-size: var(--ring-lead-compact); /* @kind font */
    --ring-size: var(--ring-size-compact); /* @kind font */
    /* THE FOUR STEPS. --ring-size-compact is the 431-800px value (48px); these are the other three
       regimes. Each is inside its measured window with margin at both ends, verified at 16 widths.
       Ordered widest-first so a narrower rule wins. See typography.css for the window table. */
    --lo-hero-h: auto; /* @kind spacing */
    --lo-text-w: 100%;
    /* No viewport edge to bleed against once the hero stacks, so the crop loses its
       justification: show the whole mark. */
    --lo-reel-mask-size: contain; /* @kind other */
    --lo-reel-mask-pos: center; /* @kind other */
  }
  .lo-hero__inner { padding-top: var(--section-y-tight); padding-bottom: var(--space-7); }
  /* Size the band to the mark so it is not adrift in empty paper. */
  .lo-hero__reel {
    position: relative;
    left: auto;
    width: min(52vw, 340px);
    aspect-ratio: 674 / 787;
    height: auto;
    margin: 0 auto;
  }
  .lo-credstrip { flex-wrap: wrap; white-space: normal; }
}

/* ── THE RING'S OTHER THREE REGIMES. Widest first; a narrower rule overrides. ────────────────────
   1000-1279  70px   windows 67-96 at 1279 down to 53-72 at 1024, overlap [67,72]
    801-999   52px   windows 50-66 at 960 down to 42-56 at 820, overlap [50,56]
    431-800   48px   the base value in typography.css; the box is pinned at ~375px through here
      <=430   calc(12.5vw - 8px)   the box is viewport-minus-gutters again, so it tracks smoothly:
                                   430 -> 45.75 (window 40-53), 390 -> 40.75 (36-46),
                                   360 -> 37 (32-42), 320 -> 32 (28-36) */
/* ── THE CLEANER FORM, RECORDED AND NOT BUILT ───────────────────────────────────────────────────
   These four steps exist because no single px value and no single vw ratio fits every width -- the
   box has three regimes (see the window table in typography.css). But the requirement is CONSTANT
   as a fraction of the box: 0.109-0.164 at every width measured, near enough one eighth.

   CSS can say that directly, with container query units:

       .lo-hero__col { container-type: inline-size; }   /* or a wrapper at the flag's own 20ch */
       .lo-flag__ring { font-size: clamp(28px, 12.5cqi, 96px); }

   One declaration instead of four steps, and it would track the box automatically rather than
   approximating it per breakpoint.

   WHY IT IS NOT HERE. `cqi` resolves against the nearest container, and the column is NOT the box:
   at 768 the column is 704px while the flag's 20ch cap makes the box 375px, so 12.5cqi would compute
   88px against a required 41-54px. Making it correct needs a wrapper element carrying both the 20ch
   cap and the container context -- a markup change to the flag macro.

   Ryan's ruling 9 Sep: "not now. Four steps that are verified at 23 widths beat one line that needs
   a markup wrapper. Record it as the cleaner form if the wrapper ever exists for another reason."
   So: if a wrapper appears here for any other reason, this collapses to one line. Until then the
   steps are the honest version, and they are measured rather than derived. ── */
@media (min-width: 1000px) and (max-width: 1279px) { .lo-hero { --ring-size: 70px; } }
@media (min-width: 801px) and (max-width: 999px)   { .lo-hero { --ring-size: 52px; } }
@media (max-width: 430px)                          { .lo-hero { --ring-size: calc(12.5vw - 8px); } }