/*!
 * hero-moment.css — Cinematic system, Hero Moment expression (Lane B3).
 *
 * Contract: design-systems/shared/RUNTIME-INTERFACE.md (§5 CSS custom
 * properties), design-systems/shared/hero-moment-base.css (generic
 * armed/settled states this file extends, never duplicates), and spec
 * docs/2026-07-10-indexed-hero-moment-design-system-spec.md §17.6/§18/§19.2.
 *
 * hero-moment-base.css already owns the GENERIC cross-system armed initial
 * states and settled resets for fade_in/mask_reveal/focus_resolve/light_ramp/
 * panel_converge/crop_glide/tracking_resolve/proof_cascade/line_draw (keyed
 * on .hm-anim-<primitive> — the runtime's own class names, spec §19). This
 * file adds ONLY:
 *   1. the split-panel CSS-grid layout hooks the new .hm-media-shell wrapper
 *      needs (the legacy .hero-split__media class carried them directly —
 *      see design-systems/cinematic/index.hm.html for the wrapper insertion);
 *   2. Cinematic's own "editorial drama" flourish on top of the generic
 *      states — the light-sweep matte (ported from 00ef938's
 *      .hero-mech--light-ramp::after, H7a ACCEPTED) — scoped to the shared
 *      hm-anim-light-ramp class, never a competing local class;
 *   3. armed-state gating: no-JS = the complete settled frame, because the
 *      sweep flourish is scoped to .hm-anim-light-ramp (and, for its armed
 *      variant, .hm-armed too) — both classes are ONLY ever added by
 *      initHeroMoment()'s own JS, never present in server markup, so this
 *      rule naturally never applies without JS. (The layout/CTA rules in
 *      items 1 and below are structural, not motion, and intentionally
 *      apply unconditionally regardless of JS/armed state.);
 *   4. the reduced-motion completeness this system's own sweep needs beyond
 *      hero-moment-base.css's generic reduced-motion block (H8 ACCEPTED —
 *      additive, non-colliding selectors, combined at the end of the
 *      existing @media(prefers-reduced-motion:reduce) block in styles.css'
 *      spirit, but authored here since styles.css is the untouched legacy
 *      file).
 *
 * Geometry hooks (WS-B checkpoint, spec §16/§17.6, tests 62/64/79): the
 * thirteen canonical hero geometries alias to a canonical ID upstream (WS-A)
 * before this stylesheet ever sees them. The resolved `data-hm-geometry`
 * (the 8th build token, WS-A commit dc2fbd06b) is now on all three hero
 * scenes' `heroMomentHeaderAttrs()` call. Every one of the profile's thirteen
 * `geometry_ids` gets an explicit `[data-hm-geometry="…"]` layout rule below
 * — set-equality with hero-expression-profiles.v1.json is asserted by
 * tests/cinematicHeroMechanics.test.js. All thirteen are expressed as CSS-only
 * layout/typography overrides on the SAME three existing DOM shapes this
 * variant's render functions produce (`.hero--full`, `.hero--full.hero--cinematic`,
 * `.hero--split`) — no new DOM, no new render function, matching the pattern
 * the five standard systems use for their own extra geometries. `fullbleed`
 * is the default/baseline (documented, empty rule — byte-for-byte today's
 * unattributed look); the other twelve are real, distinguishing overrides.
 */

/* --- Split-panel: shell is now the actual CSS-grid child --------------- */
/* (§19.2 wrapper insertion moved the grid item from .hero-split__media to
   .hm-media-shell; replicate the layout-critical rules the legacy class
   carried directly — styles.css:90-92 — onto the new wrapper.) */
.hero--split .hm-media-shell {
  position: relative;
  z-index: 0;
  min-height: 100vh;
  min-height: 100dvh;
}
.hero--split-reverse .hm-media-shell {
  grid-column: 2;
  grid-row: 1;
}

/* --- hm-cta: spacing within the hero copy column only; global .btn/.btn-row
       color treatment (styles.css:258) is left untouched. ------------------ */
.hero .hm-cta {
  margin-top: clamp(1.6rem, 3vh, 2.4rem);
}
.hero--split .hm-cta {
  margin-top: clamp(1.4rem, 3vh, 2.2rem);
}

/* v14 premium-input directives. Cinematic keeps a readable text mark when
   logo media is weak, and removes it entirely only for the explicit omitted
   treatment. These states are server-rendered and therefore hold in no-JS. */
body[data-hm-brand-mark-grade="suppress"] .intro-logo,
body[data-hm-brand-mark-grade="text_only"] .intro-logo,
body[data-hm-brand-mark-treatment="omitted"] .intro-logo,
body[data-hm-brand-mark-treatment="text_lockup"] .intro-logo,
body[data-hm-brand-mark-treatment="omitted"] .hero-split__logo,
body[data-hm-brand-mark-treatment="text_lockup"] .hero-split__logo {
  display: none;
}
.hero-split__text-lockup {
  display: block;
  max-width: 18ch;
  font: 500 clamp(1rem, 2vw, 1.45rem)/1.1 var(--sans, sans-serif);
  letter-spacing: 0;
}
.hm-root[data-hm-allow-primary-media="false"] .hm-media {
  opacity: 0.22;
  filter: saturate(0.35);
}

/* --- Cinematic light-ramp editorial flourish (ported from 00ef938's
       .hero-mech--light-ramp::after, H7a ACCEPTED) — a soft diagonal light
       sweep over the armed dim/desaturated frame, resolving away as the
       shared hm-anim-light-ramp armed state settles. Scoped to the shared
       runtime's OWN class names — no competing local mechanic class. -------- */
.hm-root.hm-op-light-ramp .hm-media::after,
.hm-root.hm-op-light-ramp .hm-media-camera::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, .38) 47%, transparent 64%);
  transform: translate(var(--hm-light-shift-x, -130%), var(--hm-light-shift-y, 0%)) scale(var(--hm-light-scale, 1));
  opacity: var(--hm-light-opacity, 0);
}
.hm-root.hm-armed.hm-op-light-ramp:not(.hm-settled) .hm-media::after,
.hm-root.hm-armed.hm-op-light-ramp:not(.hm-settled) .hm-media-camera::after {
  pointer-events: none;
}
.hm-root.hm-settled.hm-op-light-ramp .hm-media::after,
.hm-root.hm-settled.hm-op-light-ramp .hm-media-camera::after {
  opacity: 0;
}

/* line_draw uses the copy layer's existing box and a pseudo-element, so the
   adapter changes real pixels without inserting runtime DOM. */
.hm-root.hm-armed.hm-anim-line-draw .hm-copy {
  position: relative;
}
.hm-root.hm-armed .hm-copy::after {
  content: "";
  position: absolute;
  inset: auto auto 0 0;
  width: var(--hm-line-width, 100%);
  height: var(--hm-line-height, 1px);
  background: currentColor;
  transform-origin: var(--hm-line-origin, left center);
  transform: scaleX(var(--hm-line-progress, 1));
  opacity: .72;
  pointer-events: none;
}
.hm-root.hm-armed .hm-copy[style*="--hm-line-axis: vertical"]::after {
  transform: scaleY(var(--hm-line-progress, 1));
}

/* Note: the ::after sweep above needs .hm-media to be a CSS positioned
   element (for inset:0 to resolve against it). This is NOT re-declared here
   as a blanket ".hm-root .hm-media{position:relative}" rule — that would tie
   in specificity with legacy styles.css's ".hero--full .bg{position:absolute}"
   (same two-class specificity) and, landing later in the cascade, WIN,
   silently flipping the fullbleed/cinematic-video media from absolute back
   to relative and breaking the .hm-media-shell fill. All three legacy media
   classes (.bg, .hero-cinematic__media, .hero-split__media) already
   establish their own position (absolute or relative) in styles.css — a
   future geometry whose media class does not would need its own scoped rule
   here, not this blanket one. */

/* --- Reduced motion completeness (H8 ACCEPTED — additive, non-colliding
       selectors vs. hero-moment-base.css's own reduced-motion block; the
       sweep pseudo-element is scoped to hm-media, which base.css's
       reduced-motion list does not cover). ---------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .hm-root.hm-armed .hm-media::after {
    display: none !important;
    transition: none !important;
    transform: none !important;
  }
}

/* ══════════════════════════════════════════════════════════════════════
   Geometry: fullbleed (DEFAULT for the .hero--full family) — the byte-for-
   byte existing lower-left fullbleed look. Declared as an explicit (empty)
   rule for completeness/testability, not because there is a computed change.
   ══════════════════════════════════════════════════════════════════════ */
.hero--full.hm-root[data-hm-geometry="fullbleed"] {
}

/* ══════════════════════════════════════════════════════════════════════
   Geometry: full_bleed_media_with_centered_wordmark — symmetric centered
   lockup over fullbleed media (alias target of the legacy centered_editorial).
   ══════════════════════════════════════════════════════════════════════ */
.hero--full.hm-root[data-hm-geometry="full_bleed_media_with_centered_wordmark"] {
  display: flex;
  align-items: center;
  justify-content: center;
}
.hero--full.hm-root[data-hm-geometry="full_bleed_media_with_centered_wordmark"] .inner.hm-copy,
.hero--full.hm-root[data-hm-geometry="full_bleed_media_with_centered_wordmark"] .hero-cinematic__inner.hm-copy {
  position: relative;
  inset: auto;
  align-items: center;
  text-align: center;
  max-width: min(42rem, 88vw);
}
.hero--full.hm-root[data-hm-geometry="full_bleed_media_with_centered_wordmark"] .btn-row.hm-cta {
  justify-content: center;
}

/* ══════════════════════════════════════════════════════════════════════
   Geometry: centered_wordmark_with_cta — centered lockup anchored low, a
   heavier bottom scrim, and a prominent CTA (poster-style close).
   ══════════════════════════════════════════════════════════════════════ */
.hero--full.hm-root[data-hm-geometry="centered_wordmark_with_cta"] .inner.hm-copy,
.hero--full.hm-root[data-hm-geometry="centered_wordmark_with_cta"] .hero-cinematic__inner.hm-copy {
  align-items: center;
  text-align: center;
}
.hero--full.hm-root[data-hm-geometry="centered_wordmark_with_cta"] .scrim {
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0.74) 100%);
}
.hero--full.hm-root[data-hm-geometry="centered_wordmark_with_cta"] .btn-row.hm-cta {
  justify-content: center;
  margin-top: clamp(1.8rem, 4vh, 3rem);
}

/* ══════════════════════════════════════════════════════════════════════
   Geometry: object_centered — the subject staged with generous negative
   space rather than fullbleed (mirrors the standard systems' object_stage).
   ══════════════════════════════════════════════════════════════════════ */
.hero--full.hm-root[data-hm-geometry="object_centered"] {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  padding-top: clamp(6rem, 14vh, 10rem);
}
.hero--full.hm-root[data-hm-geometry="object_centered"] .hm-media-shell {
  position: relative;
  inset: auto;
  height: min(48vh, 30rem);
  width: min(88vw, 40rem);
  margin: 0 auto clamp(2rem, 4vh, 3rem);
  overflow: hidden;
}
.hero--full.hm-root[data-hm-geometry="object_centered"] .inner.hm-copy,
.hero--full.hm-root[data-hm-geometry="object_centered"] .hero-cinematic__inner.hm-copy {
  position: relative;
  inset: auto;
  align-items: center;
  text-align: center;
}

/* ══════════════════════════════════════════════════════════════════════
   Geometry: typographic_editorial_offset — a type-led composition; the
   headline sits off-center with an asymmetric margin, media pushed quieter.
   ══════════════════════════════════════════════════════════════════════ */
.hero--full.hm-root[data-hm-geometry="typographic_editorial_offset"] .inner.hm-copy,
.hero--full.hm-root[data-hm-geometry="typographic_editorial_offset"] .hero-cinematic__inner.hm-copy {
  align-items: flex-start;
  text-align: left;
  max-width: min(46rem, 82vw);
  margin-left: clamp(2rem, 8vw, 7rem);
  margin-right: auto;
}
.hero--full.hm-root[data-hm-geometry="typographic_editorial_offset"] .scrim {
  background: linear-gradient(100deg, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0.05) 55%);
}

/* ══════════════════════════════════════════════════════════════════════
   Geometry: stacked_masthead — a masthead bar pinned to the top (eyebrow +
   title), media filling the remaining frame behind it.
   ══════════════════════════════════════════════════════════════════════ */
.hero--full.hm-root[data-hm-geometry="stacked_masthead"] .inner.hm-copy,
.hero--full.hm-root[data-hm-geometry="stacked_masthead"] .hero-cinematic__inner.hm-copy {
  justify-content: flex-start;
  padding-top: clamp(3rem, 8vh, 5rem);
}
.hero--full.hm-root[data-hm-geometry="stacked_masthead"] .scrim {
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.62) 0%, rgba(0, 0, 0, 0.05) 34%, rgba(0, 0, 0, 0.4) 100%);
}

/* ══════════════════════════════════════════════════════════════════════
   Geometry: corner_anchored_media — media anchored to one corner as a
   contained block; the rest of the frame is deliberate negative space.
   ══════════════════════════════════════════════════════════════════════ */
.hero--full.hm-root[data-hm-geometry="corner_anchored_media"] {
  background: var(--ink, #0a0806);
}
.hero--full.hm-root[data-hm-geometry="corner_anchored_media"] .hm-media-shell {
  position: absolute;
  inset: auto clamp(1.5rem, 5vw, 4rem) clamp(1.5rem, 5vh, 4rem) auto;
  top: auto;
  left: auto;
  height: min(58vh, 34rem);
  width: min(44vw, 30rem);
  overflow: hidden;
}
.hero--full.hm-root[data-hm-geometry="corner_anchored_media"] .inner.hm-copy,
.hero--full.hm-root[data-hm-geometry="corner_anchored_media"] .hero-cinematic__inner.hm-copy {
  inset: auto;
  right: auto;
  bottom: auto;
  top: clamp(2rem, 8vh, 5rem);
  left: clamp(1.6rem, 6vw, 4.5rem);
  max-width: min(38rem, 46vw);
  align-items: flex-start;
  text-align: left;
}

/* ══════════════════════════════════════════════════════════════════════
   Geometry: offset_editorial_column — copy sits in a narrow offset column
   over fullbleed media, asymmetric rather than centered or corner-anchored.
   ══════════════════════════════════════════════════════════════════════ */
.hero--full.hm-root[data-hm-geometry="offset_editorial_column"] .inner.hm-copy,
.hero--full.hm-root[data-hm-geometry="offset_editorial_column"] .hero-cinematic__inner.hm-copy {
  align-items: flex-start;
  text-align: left;
  max-width: min(30rem, 70vw);
  margin-left: 0;
  margin-right: auto;
  padding-left: clamp(1.5rem, 6vw, 4.5rem);
  border-left: 1px solid rgba(255, 255, 255, 0.28);
}

/* ══════════════════════════════════════════════════════════════════════
   Split-panel family — five geometries, all real distinct panel ratios/sides
   on the SAME .hero--split DOM (spec §16, test 64 mobile strategies stack
   these to a single column, matching the standard systems' pattern).
   ══════════════════════════════════════════════════════════════════════ */
.hero--split.hm-root[data-hm-geometry="right_panel_60"] {
  grid-template-columns: minmax(360px, 1fr) minmax(0, 60%);
}
.hero--split.hm-root[data-hm-geometry="right_panel_60"] .hm-media-shell { grid-column: 2; grid-row: 1; }
.hero--split.hm-root[data-hm-geometry="right_panel_60"] .hero-split__panel { grid-column: 1; grid-row: 1; }

.hero--split.hm-root[data-hm-geometry="right_panel_55"] {
  grid-template-columns: minmax(360px, 1fr) minmax(0, 55%);
}
.hero--split.hm-root[data-hm-geometry="right_panel_55"] .hm-media-shell { grid-column: 2; grid-row: 1; }
.hero--split.hm-root[data-hm-geometry="right_panel_55"] .hero-split__panel { grid-column: 1; grid-row: 1; }

.hero--split.hm-root[data-hm-geometry="split_55_left"] {
  grid-template-columns: minmax(0, 55%) minmax(360px, 1fr);
}
.hero--split.hm-root[data-hm-geometry="split_55_left"] .hm-media-shell { grid-column: 1; grid-row: 1; }
.hero--split.hm-root[data-hm-geometry="split_55_left"] .hero-split__panel { grid-column: 2; grid-row: 1; }

.hero--split.hm-root[data-hm-geometry="left_panel_50"] {
  grid-template-columns: minmax(0, 50%) minmax(360px, 1fr);
}
.hero--split.hm-root[data-hm-geometry="left_panel_50"] .hm-media-shell { grid-column: 1; grid-row: 1; }
.hero--split.hm-root[data-hm-geometry="left_panel_50"] .hero-split__panel { grid-column: 2; grid-row: 1; }

.hero--split.hm-root[data-hm-geometry="left_panel_55"] {
  grid-template-columns: minmax(0, 55%) minmax(360px, 1fr);
}
.hero--split.hm-root[data-hm-geometry="left_panel_55"] .hm-media-shell { grid-column: 1; grid-row: 1; }
.hero--split.hm-root[data-hm-geometry="left_panel_55"] .hero-split__panel { grid-column: 2; grid-row: 1; }

@media (max-width: 640px) {
  /* Mobile: every geometry collapses to the existing single-column stack
     (spec §16 mobile_strategies_by_geometry, test 64) — none of the rules
     above may survive at this breakpoint. */
  .hero--full.hm-root[data-hm-geometry] .hm-media-shell,
  .hero--split.hm-root[data-hm-geometry] .hm-media-shell {
    position: relative;
    inset: auto;
    top: auto;
    left: auto;
    right: auto;
    bottom: auto;
    height: 42vh;
    width: 100%;
    margin: 0;
  }
  .hero--split.hm-root[data-hm-geometry] {
    grid-template-columns: none;
  }
}

/* --- No-JS / unknown contract (spec §18.1, tests 31/53): .hm-armed and
       .hm-anim-* are only ever added by initHeroMoment()'s own JS — every
       MOTION rule above (the light-ramp sweep) is scoped under one of them,
       so absent JS or an absent/invalid/static_fallback contract always
       renders the legacy template's own complete settled hero, byte-
       identical whether the mechanic is unknown or absent. The layout/CTA
       and geometry rules above are structural (grid placement, spacing) and
       apply unconditionally by design, gated only on the [data-hm-geometry]
       attribute value (empty/absent -> the untouched legacy look) — they are
       not part of the armed/settled motion contract and never hide content. */
