/* g-hero — Hero category (full | split | stats). v3.41.0.
   Single skeleton; CSS repositions .ssla-g-hero-media per layout + gates the
   stats grid. Default (no class) = full. Squared UI (no border-radius). */

.ssla-g-hero {
  position: relative;
  /* v3.54.07 — parity hardening: the hero is its own stacking context. The
     full-layout media div paints as the absolute background at z-index:auto
     (v3.41.10); WITHOUT isolation, any future rule (overlay, theme skin,
     plugin CSS) that lands a negative z-index on the media/img could drop the
     photo BEHIND the section's own background-color (the bg_color scrim
     ground), rendering the hero as a flat dark gradient for that surface only.
     With isolation:isolate even negative-z children stay ABOVE the section's
     background (contained in this context), so the photo can never paint
     below the section's own fill. Internal order is unchanged (media auto →
     scrim ::after z:0 → inner z:1) and the in-media overlay pill still
     escapes the media div to the section context (media stays z:auto). */
  isolation: isolate;
  color: var(--g-hero-fg, var(--shell-fg, #ffffff));
  background: var(--g-hero-bg, var(--shell-bg, #1a1a1a));
  overflow: hidden;
  --g-hero-heading-family: var(--brand-heading-family);
  --g-hero-body-family:    var(--brand-body-family);
}
.ssla-g-hero-inner {
  position: relative;
  z-index: 1;
  /* v3.54.31 — border-box so the Height tiers mean what they say (Glenn
     2026-08-05: "that height affordance seems pretty tall, almost too tall …
     are we staying within norms, or did we overcompensate?").

     This element was content-box, so `min-height: 58vh` sized the CONTENT box
     and the 96px top + 96px bottom padding was added ON TOP — every tier
     overshot by exactly 192px. Measured at 1425x900 against the shipped bundle:
     standard rendered 714px / 79vh against an advertised 58vh (522 + 192 = 714,
     dead on), and TALL rendered 912px / 101vh — taller than the whole viewport.
     Compact came out 550px / 61vh, which is not compact by any reading.

     Not a regression from the v3.54.30 media cap: the TEXT column is the height
     driver in all three tiers, and the contained-media caps resolve to 44/50/54vh,
     comfortably underneath and never the constraint. This overshoot predates it.

     With border-box: standard = 58vh, tall = 80vh, as labelled. Compact still
     lands near 52vh because the 96px padding is a flat value rather than scaling
     per tier — a separate call, deliberately not bundled in here. */
  box-sizing: border-box;
  max-width: var(--g-hero-content-max-width, 1200px);
  margin: 0 auto;
  padding: var(--g-hero-section-padding, 96px 24px);
  display: flex;
  align-items: center;
}
.ssla-g-hero-content { max-width: 640px; }
.ssla-g-hero--text-align-center .ssla-g-hero-inner { justify-content: center; }
.ssla-g-hero--text-align-center .ssla-g-hero-content { text-align: center; }

/* Height */
.ssla-g-hero--height-tall .ssla-g-hero-inner     { min-height: 80vh; }
.ssla-g-hero--height-standard .ssla-g-hero-inner { min-height: 58vh; }
.ssla-g-hero--height-compact .ssla-g-hero-inner  { min-height: auto; }

/* Content */
.ssla-g-hero-eyebrow { display:inline-flex;align-items:center;gap:12px; font:700 12px/1.2 var(--g-hero-body-family,var(--shell-bf,system-ui)); letter-spacing:.12em; text-transform:uppercase; color:var(--g-hero-eyebrow,var(--brand-accent,#c9a227)); margin-bottom:16px; }
.ssla-g-hero-eyebrow:empty { display:none; }
.ssla-g-hero-heading { font:700 clamp(32px,5vw,56px)/1.05 var(--g-hero-heading-family,var(--shell-hf,system-ui)); font-weight:var(--paint-heading-weight,700); color:var(--g-hero-heading,inherit); margin:0 0 20px; }
.ssla-g-hero-body { font:400 clamp(16px,1.6vw,19px)/1.55 var(--g-hero-body-family,var(--shell-bf,system-ui)); color:var(--g-hero-body,inherit); margin:0 0 28px; }
.ssla-g-hero-body:empty { display:none; }
/* v3.54.04 — cta2: optional secondary button beside the primary (parity with
   g-hero-full v3.53.01). Same button tokens; hidden until it carries a label. */
.ssla-g-hero-cta,
.ssla-g-hero-cta2 { display:inline-block; padding:var(--g-hero-button-padding,14px 28px); background:var(--g-hero-button-fill,var(--brand-accent,#c9a227)); color:var(--ssla-button-text, var(--g-hero-button-text, #ffffff)); font-weight:700; text-decoration:none; }
.ssla-g-hero-cta2 { margin-left:12px; }
.ssla-g-hero-cta:empty,
.ssla-g-hero-cta2:empty { display:none; }

/* Media element — hidden by default; each layout positions it */
.ssla-g-hero-media { display:none; }
.ssla-g-hero-media img, .ssla-g-hero-media video, .ssla-g-hero-media iframe { display:block; width:100%; height:100%; object-fit:cover; }

/* ── FULL (default): media as background + scrim, stats hidden ── */
/* v3.41.10 (PL006) — media is the absolute background; z-index:auto (not 0) so it
   does NOT create a low stacking context that traps the overlay MEDIA pill behind
   the content (z-index:1). Render is preserved: the scrim (::after z-index:0) and
   the content (z-index:1) still paint above the image; but the pill (z-index:60,
   appended inside this div) now escapes to the section context and is clickable in
   edit mode. Was z-index:0 → pill unreachable on Full heroes. */
.ssla-g-hero--layout-full .ssla-g-hero-media,
.ssla-g-hero:not([class*="--layout-"]) .ssla-g-hero-media { display:block; position:absolute; inset:0; z-index:auto; }
/* v3.44.54 — left-weighted dark gradient overlay for text legibility over a
   full-bleed photo (matches the meeks-home reference hero: 90deg,
   .92 → .72@45% → .35). Near-neutral dark (brand-safe) so the heading/subhead/
   CTA on the left stay readable regardless of the photo behind them. */
.ssla-g-hero--layout-full::after,
.ssla-g-hero:not([class*="--layout-"])::after { content:""; position:absolute; inset:0; z-index:0; background: var(--g-hero-scrim, linear-gradient(90deg, rgba(10,15,25,.92) 0%, rgba(10,15,25,.72) 45%, rgba(10,15,25,.35) 100%)); }
.ssla-g-hero--layout-full .ssla-g-hero-stats,
.ssla-g-hero:not([class*="--layout-"]) .ssla-g-hero-stats { display:none; }

/* ── SPLIT: media beside content ──
   v3.41.07 — the SECTION is the 2-column track. In the single skeleton the media
   div is a SIBLING of .ssla-g-hero-inner (so FULL can use it as an absolute
   background); the old rule made .inner a 2-col grid, but the media wasn't inside
   .inner, so it dropped into normal flow and rendered full-width ABOVE the content
   instead of beside it. Making the section the grid puts media + inner in real
   side-by-side columns; `order` honours media_side. */
.ssla-g-hero--layout-split { background: var(--g-hero-bg, var(--shell-bg, #ffffff)); color: var(--g-hero-fg, var(--shell-fg, #1a1a1a)); display:grid; grid-template-columns:1fr 1fr; align-items:stretch; }
/* v3.54.29 — SPLIT text needs an OUTER gutter (Glenn 2026-08-05: "when the
   positioning is on the left, the text floats far too far to the left … it's up
   against the wall. When it's on the right, it has plenty").

   In FULL layout `.ssla-g-hero-inner` is `max-width:1200px; margin:0 auto`, and
   that cap plus the auto-margins is what actually creates the breathing room —
   the shared `padding: 96px 24px` only ever contributed 24px. Split drops BOTH
   (max-width:none, margin:0) so the inner spans its whole grid cell and the text
   is left with that bare 24px against the viewport edge.

   Only the outer edge reads as wrong because when media sits on the LEFT the
   media column itself supplies the separation on the text's inner side — the
   asymmetry Glenn described is real, so the fix is asymmetric too. Logical
   properties (padding-inline-start/end) rather than left/right, so the pair
   flips correctly with media_side and stays correct under RTL. */
.ssla-g-hero--layout-split .ssla-g-hero-inner {
  order:1; max-width:none; margin:0;
  padding-block: var(--g-hero-split-pad-block, 96px);
  padding-inline-start: var(--g-hero-split-pad-outer, clamp(24px, 5vw, 88px));
  padding-inline-end:   var(--g-hero-split-pad-inner, 48px);
}
/* Media on the LEFT ⇒ the text is the RIGHT column ⇒ its outer edge flips. */
.ssla-g-hero--layout-split.ssla-g-hero--media-side-left .ssla-g-hero-inner {
  padding-inline-start: var(--g-hero-split-pad-inner, 48px);
  padding-inline-end:   var(--g-hero-split-pad-outer, clamp(24px, 5vw, 88px));
}
.ssla-g-hero--layout-split .ssla-g-hero-media { display:block; position:relative; order:2; min-height:340px; align-self:stretch; }
.ssla-g-hero--layout-split.ssla-g-hero--media-side-left .ssla-g-hero-media { order:0; }
.ssla-g-hero--layout-split .ssla-g-hero-stats { display:none; }
/* v3.41.08 — media_fit: cover (default) = full-bleed, media fills its half edge-to-
   edge (align-self:stretch + object-fit:cover, set above). contain = the image sits
   padded within its half at natural aspect (the legacy g-hero-split "constrained"
   look), centered rather than stretched. */
/* v3.54.29 — CONTAINED media must not overflow its half (Glenn 2026-08-05:
   "it seems to be cutting off the top of the image and pushing it into the
   Chrome, especially when it's at the top of a page … happens in the standard
   and the tall").

   The bound was `max-height:100%` on the img — but its parent carried
   `align-self:center; min-height:0`, i.e. an AUTO height. A percentage
   max-height resolved against an auto-height parent does not resolve, so the
   declaration was silently ignored and the image laid out at natural size.
   Centered in the row and clipped by the section's `overflow:hidden`, the
   excess was shaved off the TOP and slid under the fixed site header — exactly
   the symptom, and exactly why it eased off at greater heights, where the row
   was finally tall enough to contain it.

   Two changes make the bound real:
     • `align-self:stretch` gives the cell a DEFINITE height (the grid row), so
       `max-height:100%` finally resolves against something.
     • the cell becomes a centering flex box, so the image is centred WITHIN the
       padded cell instead of overflowing a shrink-wrapped one.

   The `min()` cap is the belt: it keeps a very tall source image from inflating
   the row past its height tier, so Standard stays Standard. Tiers sit below
   their band's min-height (58/80vh) to leave room for the 32px padding and the
   header. */
/* v3.54.32 — the contained image must not SIZE the row, only fill it.
   (Glenn 2026-08-05: "fix compact so it's actually compact".)

   v3.54.31 made the tiers honest, and halving Compact's padding still left it at
   550px — identical to Standard — even with 79px of copy. Padding was never the
   constraint. The floor was the IMAGE: an in-flow <img> contributes its
   intrinsic height to grid row sizing, and at a ~712px half-column a 4:3 source
   scales to 486px, +64px padding = the 550px floor exactly. The
   `max-height: min(100%, cap)` bound could not prevent it — the row is sized
   during intrinsic sizing, and the cap only takes effect at paint, so the image
   was drawn at 396px inside a cell that had already been forced to 550px. That
   is also why Compact and Standard came out identical: both were pinned to the
   same image-derived floor, not to their own tiers.

   Taking the image OUT OF FLOW is what actually fixes it. Absolutely positioned
   against the cell with the padding expressed as insets, it contributes nothing
   to row sizing, so the row is finally driven by the text column and each tier's
   own height — Compact can be compact. `object-fit: contain` inside that inset
   box keeps the no-crop guarantee from v3.54.30, and because the box can never
   exceed the cell, the overflow-into-the-header defect cannot return either.

   `--g-hero-media-min` is the counterweight: with the image no longer holding
   the row open, a very short hero would otherwise shrink the media to a sliver. */
.ssla-g-hero--layout-split.ssla-g-hero--media-fit-contain .ssla-g-hero-media {
  align-self: stretch;
  position: relative;
  min-height: var( --g-hero-media-min, 220px );
  padding: 0;
  overflow: hidden;
}
.ssla-g-hero--layout-split.ssla-g-hero--media-fit-contain .ssla-g-hero-media img,
.ssla-g-hero--layout-split.ssla-g-hero--media-fit-contain .ssla-g-hero-media video {
  /* Explicit width/height rather than four insets: an <img> is a REPLACED
     element, so `height:auto` resolves to its INTRINSIC height and the
     top/bottom pair becomes over-constrained — the browser drops `bottom` and
     the image runs 32px past the cell (measured). calc() off the padding box is
     unambiguous for replaced content and needs no aspect-ratio guesswork;
     object-fit:contain then letterboxes inside that exact box. */
  position: absolute;
  top: 32px;
  left: 32px;
  width: calc( 100% - 64px );
  height: calc( 100% - 64px );
  object-fit: contain;
}
/* v3.54.32 — the per-tier --g-hero-media-cap values (44/50/70vh) are removed,
   not merely unset. They existed to stop the in-flow image inflating the row,
   which is now handled structurally by taking it out of flow; the image is
   bounded by its cell, so a vh cap has nothing left to do. Leaving them would
   imply the media still has an independent height budget — it does not. */

/* v3.54.32 — Compact scales its own padding (Glenn 2026-08-05: "fix compact so
   it's actually compact").

   v3.54.31 made the tiers honest but left Compact at 550px — level with
   Standard — because Compact is the one tier with `min-height: auto`, so
   nothing but content and padding sizes it, and the padding was a flat 96px
   top + bottom regardless of tier. 192px of chrome on ~358px of copy is over a
   third of the band, which is why it never read as compact.

   Halved to 48px for this tier only. Set on the SECTION so it reaches both
   layout paths through inheritance — the shorthand `--g-hero-section-padding`
   that full/stats consume, and the `--g-hero-split-pad-block` that the split
   inner consumes — without either rule needing to know about height tiers.

   Honest limit: past this point Compact is bound by its CONTENT, not its
   padding. A hero carrying eyebrow + two-line heading + body + CTA has a real
   floor around 450px no matter what; the tier gets genuinely small only when
   the copy is short, which is exactly when someone reaches for Compact. */
.ssla-g-hero--height-compact {
  --g-hero-section-padding: 48px 24px;
  --g-hero-split-pad-block: 48px;
}

/* ── STATS: no media, metrics bar below content ── */
/* v3.41.10 (PL007) — Stats no longer discards an uploaded image. When media is
   present it renders as a scrimmed background behind the metrics (reusing the Full
   treatment); when absent, the empty media div stays hidden and the section shows
   its plain tone surface. Non-destructive either way — the media attr is preserved
   across layout round-trips. :has() gates on real media (img/video/iframe). */
.ssla-g-hero--layout-stats .ssla-g-hero-media { display:none; }
.ssla-g-hero--layout-stats .ssla-g-hero-media:has(img, video, iframe) { display:block; position:absolute; inset:0; z-index:auto; }
.ssla-g-hero--layout-stats:has(.ssla-g-hero-media img, .ssla-g-hero-media video, .ssla-g-hero-media iframe)::after { content:""; position:absolute; inset:0; z-index:0; background: var(--g-hero-scrim, linear-gradient(to right, rgba(0,0,0,.6), rgba(0,0,0,.25))); }
.ssla-g-hero--layout-stats .ssla-g-hero-inner { flex-direction:column; align-items:flex-start; }
.ssla-g-hero--layout-stats.ssla-g-hero--text-align-center .ssla-g-hero-inner { align-items:center; }
.ssla-g-hero-stats { display:grid; grid-template-columns:repeat(3,auto); gap:40px; margin-top:40px; }
.ssla-g-hero--count-four .ssla-g-hero-stats { grid-template-columns:repeat(4,auto); }
/* v3.41.10 (PL008) — show exactly the active count of stats. Extra items left over
   from a later count-decrease (4→3) HIDE non-destructively (data preserved), so the
   editor reflects the count change live — no page reload needed. Default = 3. */
.ssla-g-hero-stats > .ssla-g-hero-stat:nth-child(n+4) { display:none; }
.ssla-g-hero--count-four .ssla-g-hero-stats > .ssla-g-hero-stat:nth-child(4) { display:block; }
.ssla-g-hero-stat-value { font:700 40px/1 var(--g-hero-heading-family,var(--shell-hf,system-ui)); color:var(--g-hero-stat-value,var(--brand-accent,#c9a227)); }
.ssla-g-hero-stat-label { font:500 14px/1.3 var(--g-hero-body-family,var(--shell-bf,system-ui)); margin-top:6px; opacity:.85; }

/* Tone (full uses a light scrim on tone-light) */
/* v3.41.05 — tone-dark was MISSING, so the section's default tone (dark) and any
   explicit tone-dark left --g-hero-bg unset → it fell back to --shell-bg (the
   preset's light shell, e.g. #faf7f2). On SPLIT/STATS layouts (no media covering
   the surface) that rendered a light background under light text, and flipping
   tones just produced slightly different creams ("strange bg color changes" —
   Glenn 2026-07-05). Every tone must set --g-hero-bg explicitly. */
.ssla-g-hero--tone-dark  { --g-hero-bg:#1a1a1a; --g-hero-fg:#f5f5f5; }
.ssla-g-hero--tone-light { --g-hero-bg:#ffffff; --g-hero-fg:#1a1a1a; }
.ssla-g-hero--tone-light.ssla-g-hero--layout-full::after { --g-hero-scrim: linear-gradient(to right, rgba(255,255,255,.85), rgba(255,255,255,.4)); }
/* accent ("Preset") — pulls the preset accent surface (parity with g-proof); light surface → dark fg + light scrim so overlaid text stays readable on full */
.ssla-g-hero--tone-accent { --g-hero-bg: var(--preset-accent-surface, #f7f3ec); --g-hero-fg: var(--preset-accent-fg, #1a1a1a); }
.ssla-g-hero--tone-accent.ssla-g-hero--layout-full::after { --g-hero-scrim: linear-gradient(to right, rgba(255,255,255,.72), rgba(255,255,255,.3)); }

@media (max-width:720px) {
  .ssla-g-hero--layout-split { grid-template-columns:1fr; }
  .ssla-g-hero--layout-split .ssla-g-hero-media { min-height:260px; }
  .ssla-g-hero-stats { grid-template-columns:repeat(2,auto); }
}
