/* ==========================================================================
   Crawford Coaching — /assets/theme.css
   Path per STRATEGY-REVIEW-2026-08-16.md. Generated from theme.json.

   Reconciled against the two design authorities:
     crawford-coaching/CLAUDE.md -> Design System   (live)
     crawford-projects/crawford-ui-style-guide.md   (historical, token history)

   HOUSE RULES OBEYED HERE — see CLAUDE.md anti-patterns:
     * radii are 1-4px only. No pills. No border-radius: 999px.
     * no box-shadow for card depth; use background contrast.
     * only Cormorant Garamond / Libre Baskerville / Jost. No system stacks.

   SCOPE. Tokens through phases 0-2; the HERO COMPONENT landed here at
   phase 3 (2026-08-20), which is where the spec always intended it. The
   four photo heroes — homepage, whole, coaching, synergize — share the
   scrim and spine below. `.svc-card` is still NOT here; it belongs with
   the service-card work, which is a separate tracked item.

   Panel heroes (about, contact, growth-zone), centred text heroes
   (subscribe, unsubscribe), the members page header and the blog
   `.article-hero` are DIFFERENT components that merely share a name.
   Do not fold them in.

   AXES (inert until phase 4 sets the attributes)
     data-theme  -> ground   light-white | light-warm | light-crisp | dark
     data-ground -> light|dark   picks which end of each brand hue applies
     data-brand  -> service  coaching | synergize | whole | growth
   ========================================================================== */

:root{
  /* --sans is the value 22 of 26 live pages already declare. Do not add
     'Helvetica Neue' here: it is a system face, and only crawford-timer
     and crawford-quick-emom carry that variant. They keep it locally. */
  --serif-display:'Cormorant Garamond',Georgia,serif;
  --serif-body:'Libre Baskerville',Georgia,serif;
  --sans:'Jost',sans-serif;

  /* House shape language: sharp, not rounded.
     NAMED --radius-*, not --r-*, deliberately. crawford-quick-emom.html
     already owns --r-sm/--r-md/--r-lg at 10px/14px/22px with ~20 uses;
     reusing those names would silently reshape that app. */
  --radius-sm:1px; --radius-md:2px; --radius-lg:4px;

  /* --cream is the OLD --white. crawford-ui-style-guide.md documents
     --white: #f5f3ef; CLAUDE.md documents the Apr 2026 brightening to
     #ffffff. The 139 surviving rgba(245,243,239,a) literals across 24
     files are orphans of that change. Declaring it stops them being
     invisible to a token swap. */
  --cream:#f5f3ef;

  /* legacy aliases — the 12-token block these pages used to declare
     inline, plus the sub-brand accents. Keep until phase 2 retires the
     last consumer. Values are byte-for-byte what the pages carried. */
  --ink:#0e0f10; --slate:#1c2330; --slate-mid:#232f3e; --fog:#3d4a58;
  --mist:#a4b6c8; --pale:#dde8f2; --white:#ffffff;
  --brand-blue:#2d86c4; --brand-blue-light:#4fa3d8;
  --syn-orange:#e8632b; --syn-orange-light:#f2844e; --syn-amber:#f5a623;
  /* Sage moved from WHOLE to Growth Zone, 2026-08-20 (Scott). It suits growth
     on-message, and the switch was nearly free: crawford-whole.html used sage
     ZERO times — the WHOLE page is entirely --brand-blue — so it was WHOLE's
     colour on paper only. WHOLE keeps --brand-blue in practice until it is
     built out and gets a deliberate colour; it is far enough down the pipeline
     that nothing is lost. */
  --gz-sage:#7a9b6d; --gz-sage-light:#96b48a;

  /* ---- RGB TRIPLETS (phase 2) ---------------------------------------
     Bare "r,g,b" channel lists, for building translucent values as
     rgba(var(--white-rgb), 0.45).

     PHASE 2 IS DONE for --cream (2026-08-22): it was the pre-Apr-2026 --white,
     and the rgba literals derived from it were orphaned by the brightening to
     #ffffff. All 34 remaining consumers were migrated — 31 to --white-rgb
     where they veil a DARK surface, and 3 to --text-rgb where they sat on a
     light one and were rendering invisible. --cream/--cream-rgb are still
     declared below but now have no consumer in this repo; left in place rather
     than deleted because theme.css is served publicly and something outside
     this repo may still reference it.

     RESKIN-SPEC.md §4 specifies color-mix(in srgb, var(--cream) 45%,
     transparent) instead. Measured, that is the wrong tool here:

       * it computes to `color(srgb 0.960784 ... / 0.45)`, not `rgba()`.
         A different serialisation means every converted declaration reads
         as a diff, which would blind the phase 0/1 verification harness
         on the one phase with 673 edits to check.
       * it is not even exactly equal: at alpha 0.025 legacy rgba
         quantises to 0.024 while color-mix keeps 0.025.

     rgba(var(--x-rgb), a) was compared against the literal across all 44
     alphas in use x 8 tokens — 352 combinations, zero mismatches. It is
     exactly equivalent and stays diffable. theme.json already carries an
     "rgb" field per brand, so this is the modelled path anyway.       */
  --ink-rgb:14,15,16;
  --slate-rgb:28,35,48;
  --slate-mid-rgb:35,47,62;
  --fog-rgb:61,74,88;
  --mist-rgb:164,182,200;
  --pale-rgb:221,232,242;
  --white-rgb:255,255,255;
  --cream-rgb:245,243,239;
  --brand-blue-rgb:45,134,196;
  --brand-blue-light-rgb:79,163,216;
  --syn-orange-rgb:232,99,43;
  --syn-orange-light-rgb:242,132,78;
  --syn-amber-rgb:245,166,35;
  --gz-sage-rgb:122,155,109;

  /* Hero scrim shade. Separate from --ink-rgb so the scrim's COLOUR can be
     softened independently of its opacity — Scott, 2026-08-20: "softer"
     meant a softer shade, not only a lower alpha. Currently the near-black
     ink; --slate-rgb (28,35,48, a lifted blue-grey) is the obvious warmer
     alternative and is a one-line change here. */
  --hero-scrim-rgb: var(--ink-rgb);

  /* ---- The 2026-04 brightening is now COMPLETE ----------------------
     That change updated --mist, --pale and --white but left every rgba()
     literal derived from them behind. RESKIN-SPEC.md found one of the three
     (--white -> --cream, above). The other two were found 2026-08-20 and
     retired the same day on Scott's ruling:

       --mist  #7a8fa3 -> #a4b6c8   149 references across 20 files
       --pale  #c8d4de -> #dde8f2     6 references in 1 file

     Both old values are named in CLAUDE.md as never-reintroduce
     anti-patterns (contrast was too low), so they were bumped to the
     current tokens rather than preserved. --mist-legacy / --pale-legacy
     existed only long enough to make them greppable, and are now gone.

     --cream is NOT the same case: #f5f3ef is a deliberate warm off-white
     still in active use, not a superseded value. It stays.              */

  /* ---- ROLE LAYER (phase 1) ----------------------------------------
     These describe THE SITE AS IT IS TODAY: dark. They are aliases onto
     the legacy palette rather than literals, so changing --ink or --white
     moves the role with it — generalising what crawford-timer.html
     already does locally, rather than inventing a parallel scheme.

     The light grounds live in the [data-theme] blocks below and stay
     inert until phase 4 sets the attribute. Do NOT make a light ground
     the default here. Until phase 0 this block held the light-white
     values, which was harmless only because nothing consumed them; the
     first page to use var(--bg) would have turned white on its own.

     NO color-scheme IN THIS BLOCK. It is a real property, not a custom
     one, so it applies the moment the sheet loads. Phase 0 shipped
     `color-scheme: light` here and flipped all 42 pages from `normal` to
     `light` — that drives native form-control and scrollbar rendering,
     on a site that is entirely dark, across the 19 pages carrying 112
     form controls. Reverted 2026-08-20. color-scheme belongs on the
     [data-theme] blocks, where it switches on with the ground it
     actually describes.                                                */
  --bg: var(--ink);
  --surface: var(--slate);
  --surface-2: var(--slate-mid);
  --text: var(--white);
  --text-muted: var(--pale);
  --text-faint: var(--mist);
  --border: var(--fog);
  --on-accent: var(--white);

  /* Role triplets (phase 4). A page going light needs its TRANSLUCENT values
     to follow the ground too — a fixed rgba(--ink-rgb, 0.85) nav backdrop
     stays black on a white page. These are the rgb forms of the roles above,
     redeclared per ground below. */
  --bg-rgb: var(--ink-rgb);
  --surface-rgb: var(--slate-rgb);
  --surface-2-rgb: var(--slate-mid-rgb);
  --text-rgb: var(--white-rgb);
  --text-muted-rgb: var(--pale-rgb);
  --text-faint-rgb: var(--mist-rgb);
  --border-rgb: var(--fog-rgb);
}

/* ---------------- grounds ----------------
   --text-faint was DARKENED on all three light grounds, 2026-08-20, after the
   first page went light. Each value had been calibrated against --bg only, and
   failed 4.5:1 on the darker surfaces in its own ground: on light-white it gave
   4.67 on --bg but 4.34 on --surface and 4.09 on --surface-2, so
   .page-hero__sub and .about__cred both failed the moment about.html flipped.
   A ground's text tokens must clear the bar against EVERY surface in that
   ground, not just the page background. light-warm (4.24) and light-crisp
   (4.49) had the same flaw and were corrected with it, though neither is in use.

   IN USE: light-white and dark only (Scott, 2026-08-20). light-warm and
   light-crisp stay defined but unused. Committing to one light ground keeps
   --accent-bright above its 3:1 bar for coaching, synergize and whole — every
   marginal or failing case in the table below was on warm or crisp. Do not
   adopt either without re-checking contrast.                              */
[data-theme="light-white"]{ /* Light · White */
  /* Rebalanced 2026-08-20 after about.html went light and read washed out.
     The surfaces were near-white greys — chroma 3% and 6%, separated from each
     other by 1.077:1 and 1.060:1, steps small enough to be invisible. Now
     chroma 8% and 14% at 1.164 and 1.118, so the page has structure and blue.

     Every text token moved with them: darkening a surface eats the contrast
     above it, so --text-faint and --accent were re-solved against the DARKEST
     surface in the ground, not against --bg. Worst ratios in the ground now:
     text 13.36, muted 5.08, faint 4.61, accent 4.57, accent-bright 3.03. */
  color-scheme:light;
  --bg:#ffffff;
  --surface:#e5eff8;
  --surface-2:#d2e4f3;
  --text:#0d1b2a;
  --text-muted:#4c5f70;
  --text-faint:#546576;
  --border:#b0cde4;
  --on-accent:#ffffff;
  --bg-rgb:255,255,255;
  --surface-rgb:229,239,248;
  --surface-2-rgb:210,228,243;
  --text-rgb:13,27,42;
  --text-muted-rgb:76,95,112;
  --text-faint-rgb:84,101,118;
  --border-rgb:176,205,228;
}
[data-theme="light-warm"]{ /* Light · Warm */
  color-scheme:light;
  --bg:#f7f5f1;
  --surface:#ffffff;
  --surface-2:#efeae2;
  --text:#14202b;
  --text-muted:#535e69;
  --text-faint:#6d6961;
  --border:#e2ddd4;
  --on-accent:#ffffff;
  --bg-rgb:247,245,241;
  --surface-rgb:255,255,255;
  --surface-2-rgb:239,234,226;
  --text-rgb:20,32,43;
  --text-muted-rgb:83,94,105;
  --text-faint-rgb:109,105,97;
  --border-rgb:226,221,212;
}
[data-theme="light-crisp"]{ /* Light · Crisp */
  color-scheme:light;
  --bg:#fbfcfd;
  --surface:#ffffff;
  --surface-2:#eef4f9;
  --text:#08192b;
  --text-muted:#3f5468;
  --text-faint:#5d7184;
  --border:#d3e2ee;
  --on-accent:#ffffff;
  --bg-rgb:251,252,253;
  --surface-rgb:255,255,255;
  --surface-2-rgb:238,244,249;
  --text-rgb:8,25,43;
  --text-muted-rgb:63,84,104;
  --text-faint-rgb:93,113,132;
  --border-rgb:211,226,238;
}
[data-theme="dark"]{ /* Dark — current site, unchanged */
  color-scheme:dark;
  --bg:#0e0f10;
  --surface:#1c2330;
  --surface-2:#232f3e;
  --text:#ffffff;
  --text-muted:#dde8f2;
  --text-faint:#a4b6c8;
  --border:#3d4a58;
  --on-accent:#0e0f10;
  --bg-rgb:14,15,16;
  --surface-rgb:28,35,48;
  --surface-2-rgb:35,47,62;
  --text-rgb:255,255,255;
  --text-muted-rgb:221,232,242;
  --text-faint-rgb:164,182,200;
  --border-rgb:61,74,88;
}

/* ---------------- brands ----------------
   --accent is AA-clean (>=4.5:1) on every ground it pairs with.
   --accent-bright is NOT, and it is the token used for the hero spine,
   rules and numerals, where the 3:1 bar applies (SC 1.4.3 large text /
   1.4.11 non-text). Measured against each light ground:

                    #ffffff   light-warm #f7f5f1   light-crisp #fbfcfd
     coaching        3.95 ok      3.63 ok               3.84 ok
     synergize       3.36 ok      3.09 marginal         3.27 ok
     whole           3.12 ok      2.86 FAIL             3.03 marginal
     growth (gold)   2.50 FAIL    2.29 FAIL             2.43 FAIL

   RESOLVED 2026-08-20, by two decisions rather than a token change:
     * only light-white is in use, so the warm/crisp columns do not apply;
     * the growth gold was not adopted — growth now maps to --brand-blue,
       which is 3.95:1 and clears the bar.
   Every brand in use therefore passes on the ground in use. If either
   decision is revisited, re-check this table first.                      */
/* Default brand = coaching, on the dark ground the site actually uses today.
   These deliberately mirror CURRENT values, not the AA-corrected ones in the
   [data-ground] blocks, so adopting a role token is never a visual change:

     --accent       var(--brand-blue) #2d86c4 — what every page uses now.
                    The dark block below moves it to #4fa3d8 for AA; that is
                    a phase 4 change, not a phase 1 one.
     --accent-soft  0.15 alpha — matches --brand-blue-dim as used by
                    core-values / growth-zone / task-triage.
     --accent-line  0.50 alpha — matches --brand-blue-border on those same
                    pages. NOTE the dark block below specifies 0.35; when
                    phase 4 turns it on, those hairlines get lighter. That
                    is a real (small) visual change and should be an
                    explicit decision, not a surprise.
     --on-accent    var(--white) — today's buttons are white text on
                    --syn-orange. The dark block flips this to ink for
                    contrast against the brightened accent, again phase 4. */
:root{ --accent: var(--brand-blue); --accent-bright: var(--brand-blue);
        --accent-soft:rgba(45,134,196,0.15); --accent-line:rgba(45,134,196,0.5); }
[data-ground="light"] [data-brand="coaching"], [data-ground="light"][data-brand="coaching"]{ /* Coaching — canon --brand-blue */
  --accent:#1868a1; --accent-rgb:24,104,161;   /* re-solved against the darker surfaces, 2026-08-20 */ --accent-bright:#2d86c4;
  --accent-soft:rgba(45,134,196,0.10); --accent-line:rgba(45,134,196,0.28);
  --on-accent:#ffffff;
}
[data-ground="dark"] [data-brand="coaching"], [data-ground="dark"][data-brand="coaching"]{ /* Coaching — canon --brand-blue */
  --accent:#4fa3d8; --accent-rgb:79,163,216; --accent-bright:#2d86c4;
  --accent-soft:rgba(45,134,196,0.15); --accent-line:rgba(45,134,196,0.35);
  --on-accent:#0e0f10;
}
[data-ground="light"] [data-brand="synergize"], [data-ground="light"][data-brand="synergize"]{ /* Synergize — canon --syn-orange */
  --accent:#b83f14; --accent-rgb:184,63,20; --accent-bright:#e8632b;
  --accent-soft:rgba(232,99,43,0.10); --accent-line:rgba(232,99,43,0.28);
  --on-accent:#ffffff;
}
[data-ground="dark"] [data-brand="synergize"], [data-ground="dark"][data-brand="synergize"]{ /* Synergize — canon --syn-orange */
  --accent:#f2844e; --accent-rgb:242,132,78; --accent-bright:#e8632b;
  --accent-soft:rgba(232,99,43,0.15); --accent-line:rgba(232,99,43,0.35);
  --on-accent:#0e0f10;
}
[data-ground="light"] [data-brand="whole"], [data-ground="light"][data-brand="whole"]{ /* WHOLE — --brand-blue until it gets its own */
  --accent:#1f6fa8; --accent-rgb:31,111,168; --accent-bright:#2d86c4;
  --accent-soft:rgba(45,134,196,0.10); --accent-line:rgba(45,134,196,0.28);
  --on-accent:#ffffff;
}
[data-ground="dark"] [data-brand="whole"], [data-ground="dark"][data-brand="whole"]{ /* WHOLE — --brand-blue until it gets its own */
  --accent:#4fa3d8; --accent-rgb:79,163,216; --accent-bright:#2d86c4;
  --accent-soft:rgba(45,134,196,0.15); --accent-line:rgba(45,134,196,0.35);
  --on-accent:#0e0f10;
}
/* Growth Zone — Scott's ruling 2026-08-20: the gold #c4a02d from
   branded-email-template.html was NOT adopted. It had never appeared on the
   site, so adopting it would have been a new brand decision inherited from an
   email rather than a correction. Growth Zone keeps --brand-blue as its main
   colour for the bulk of page treatment.

   Expected to gain PER-TOOL colours later: the physical tools (Minutes To Move
   and siblings) leaning to a softer orange as a nod to their Synergize origins,
   the productivity tools coloured differently. That is a design pass, not a
   token rename — do not pre-empt it here.

   Not adopting the gold also retires the worst --accent-bright contrast
   failure: #c4a02d was 2.50:1 on white, below the 3:1 bar on every light
   ground. --brand-blue is 3.95:1 and clears it.                            */
[data-ground="light"] [data-brand="growth"], [data-ground="light"][data-brand="growth"]{ /* Growth Zone — --gz-sage */
  --accent:#456637; --accent-rgb:69,102,55; --accent-bright:#7a9b6d;
  --accent-soft:rgba(122,155,109,0.10); --accent-line:rgba(122,155,109,0.28);
  --on-accent:#ffffff;
}
[data-ground="dark"] [data-brand="growth"], [data-ground="dark"][data-brand="growth"]{ /* Growth Zone on dark — kept for completeness; GZ ships light */
  --accent:#96b48a; --accent-rgb:150,180,138; --accent-bright:#7a9b6d;
  --accent-soft:rgba(122,155,109,0.15); --accent-line:rgba(122,155,109,0.35);
  --on-accent:#0e0f10;
}


/* ---------------- logo ----------------
   cc-logo.png is a transparent PNG with a WHITE wordmark, so it disappears on
   a light ground. This swaps in the black-wordmark version wherever a light
   ground is set — one rule, no markup change on any page as they flip.

   `content` on an <img> replaces the rendered image while leaving the alt text
   in the accessibility tree; supported in Chrome, Firefox and Safari. If a
   browser ignores it the white logo shows through, which is degraded but not
   broken.

   cc-logo-light.png is still the stopgap cropped from cc-email-header.png
   (dev_inbox #29). It wants redrawing as a proper SVG pair — note its accent is
   #67c3ea, which is NOT --brand-blue #2d86c4. Settle that with the redraw.   */
[data-theme^="light"] .nav__logo img,
[data-theme^="light"] .footer__logo img{
  content: url("/cc-logo-light.png");
}
/* …but NOT inside a dark island. The selector above matches on ANY light
   ancestor, so on crawford-homepage.html — where the fixed nav sits inside the
   dark photo hero — it swapped in the BLACK wordmark over a dark photograph.
   Equal specificity, declared later, so this wins wherever both apply. */
[data-theme="dark"] .nav__logo img,
[data-theme="dark"] .footer__logo img{
  content: normal;
}

/* ==========================================================================
   HERO — the four photo heroes (phase 3)
   homepage · whole · coaching · synergize. Panel/centred/header heroes are
   different components and are deliberately not styled here.

   Structure (position, flex, height, padding) stays per page for now; what
   is shared is the part the spec actually decided: the scrim and the spine.
   ========================================================================== */

/* Softer scrim, unified. Base alpha 0.62, down from four different values —
   0.85 homepage, 0.97 whole, 0.80 coaching, 0.75 synergize. The mid-stops
   stay light so the photograph carries the middle of the frame; the top and
   bottom do the work of holding text legible. */
.hero__overlay{
  position:absolute; inset:0;
  background:
    /* Left gutter, so the spine has something to read against. Measured
       2026-08-20: a bare 5px spine sat at 1.29-2.30:1 against the photos
       (worst on WHOLE, blue on a blue-grey image) — below the 3:1 non-text
       bar and effectively invisible. No fixed spine colour can fix that,
       because the photograph underneath varies; darkening the strip it sits
       on can. 28px wide, fading out, so it reads as intent not as a band. */
    linear-gradient(to right,
      rgba(var(--hero-scrim-rgb),0.72)  0px,
      rgba(var(--hero-scrim-rgb),0.30) 14px,
      rgba(var(--hero-scrim-rgb),0)    28px),
    linear-gradient(to bottom,
      rgba(var(--hero-scrim-rgb),0.42)   0%,
      rgba(var(--hero-scrim-rgb),0.10)  40%,
      rgba(var(--hero-scrim-rgb),0.14)  60%,
      rgba(var(--hero-scrim-rgb),0.62) 100%);
}

/* Content plate. The scrim alone cannot hold text over a photograph: on the
   homepage the worst-case backdrop behind the EYEBROW measured (190,199,206)
   — a bright patch in the image — giving 1.71:1 against white. Shortening the
   hero moved the content up into the gradient's light middle band, and
   softening the scrim lightened it further.

   A plate local to the text fixes that without darkening the whole frame, so
   the photograph stays soft — which is the point of the softer scrim. WHOLE's
   .hero__content::before on mobile is the same idea; this is the house-rule
   version of it (no 24px radius, no drop shadow). Page rules load after this
   sheet, so an existing per-page plate still wins where one exists. */
/* z-index:2 gives .hero__content its own stacking context. Without it the
   plate below (z-index:-1) paints beneath .hero__overlay — a positioned
   sibling at z-index auto — and is invisible, which is exactly what the first
   attempt did: the eyebrow's worst case stayed at 1.78:1. */
.hero__content{ z-index:2; }
.hero__content::before{
  content:''; position:absolute;
  /* Bleed past the content box on purpose. .hero__content carries a max-width
     (900px homepage, 860px whole), so a plate at left:0/right:0 stopped dead at
     that edge and painted a shadowed left half with a hard vertical seam down
     the middle of the hero. .hero has overflow:hidden, so over-extending is
     clipped to the hero and the plate now spans the full width. */
  left:-100vw; right:-100vw; top:-2rem; bottom:0;
  background:linear-gradient(to bottom,
    rgba(var(--hero-scrim-rgb),0)    0%,
    rgba(var(--hero-scrim-rgb),0.48) 22%,
    rgba(var(--hero-scrim-rgb),0.68) 100%);
  z-index:-1; pointer-events:none;
}

/* Left spine — 5px, full hero height. Colour comes from --hero-spine so each
   page keeps its own accent: the eyebrows already differ (white on homepage,
   --brand-blue-light on whole and coaching, --syn-orange on synergize), and a
   single --accent-bright would have painted all four the same blue. At phase 4
   this collapses into the data-brand axis. */
.hero{ --hero-spine: var(--accent-bright); }
.hero::after{
  content:''; position:absolute; left:0; top:0; bottom:0;
  width:5px; background:var(--hero-spine); z-index:3;
}


/* ── HERO SCAFFOLDING (phase 3.1, extracted 2026-08-22) ──────────────────
   The structural declarations every hero of each type already shared, lifted
   out of the eight pages that repeated them. The spine and scrim above were
   phase 3.2 and shipped earlier.

   TWO components, not one, deliberately. The brief's "collapse .hero and
   .page-hero into one" would merge a full-bleed photo hero with a text panel
   on --surface; measured, they agree on almost nothing beyond this
   scaffolding. Only what ALL pages of a type share lives here — anything one
   page does differently stays on that page.

   .hero      photo heroes  — coaching, homepage, synergize, whole
   .page-hero text heroes   — about, contact, growth-zone, subscribe, unsubscribe

   The two rationales below moved here from the four pages, where they had been
   left describing declarations that no longer sat there.

   FLEX + PADDING-TOP clears the fixed nav (98px desktop / 90px mobile). Added
   2026-08-20: with .hero__content absolutely positioned, tall content grew
   UPWARD out of the shortened hero and ran under the nav — WHOLE's title sat
   15px behind it. In flow, the hero grows to fit instead.

   MIN-HEIGHT is the unified hero height (Scott, 2026-08-20): one shorter,
   clamped hero across all four photo heroes, replacing 100vh/min-600-700px.
   `svh` not `vh` — every existing mobile override already used 82svh, which
   avoids the jump as mobile browser chrome hides; on desktop the two are
   equivalent. A full screen of dark before any content reads cinematic on dark
   and as a wall on light, and homepage, coaching and whole all went light at
   phase 4. */
.hero{
  position:relative; display:flex; align-items:flex-end;
  height:auto; min-height:clamp(420px, 68svh, 680px);
  overflow:hidden; padding-top:7rem;
}
.hero__image{ position:absolute; inset:0; }
.hero__content{ position:relative; width:100%; }
.hero__eyebrow{ font-family:var(--sans); text-transform:uppercase; }
.hero__title{ font-family:var(--serif-display); font-weight:300; }
.hero__sub{ font-family:var(--serif-body); }

.page-hero__label{
  font-family:var(--sans); font-size:0.68rem; letter-spacing:0.3em;
  text-transform:uppercase; color:var(--accent);
  align-items:center; gap:0.8rem;
}
.page-hero__sub{ font-family:var(--serif-body); }
