/* EZ Coaching — stylesheet
   ============================================================
   TOKEN DISCIPLINE (run-binding constraint A): every colour, font, radius,
   shadow and motion value is declared ONCE in :root below and referenced via
   var() everywhere else. There are NO hardcoded hex values, font stacks, radii
   or shadows anywhere else in this file or in any HTML. rgba() values derived
   from token colours are declared in :root too (--border-hairline, the shadow
   tokens), never inline. Source of truth: 04-brief/tokens.json (DTCG).

   BREAKPOINT DERIVATION — RULE-DRIVEN, DECLARED ONCE (site-generator rule 8):
   Desktop is authored against the tokens; tablet (<=900px) and mobile (<=600px)
   are derived by these FIXED rules, never hand-tweaked per viewport:
     1. Type: display sizes use clamp() with a vw middle term, so the scale
        steps down one ratio notch fluidly toward the 36px H1 mobile floor
        (lowered 40->36 in the mobile-polish pass: at 375px the 40px floor put
        the long home hero H1 at the wrapping cliff — 5 lines at 390px ballooned
        to 8 at 375px — which pushed the Boca chip + CTA off the fold; 36px holds
        the composition and keeps the headline prominent. Desktop is untouched:
        the 5vw middle term dominates above ~720px, so the floor only bites on
        phones/small tablets).
     2. Spacing: --section-padding is one clamp() token reused by every section;
        it steps down one notch fluidly. Edge padding floor is --space-md (24px).
     3. Multi-column blocks (text|visual pairs, router, footer, comparison,
        how-it-works) STACK in source order — text before visual unless the
        component reverses it explicitly.
     4. Tap targets grow to >=48px min-height with >=8px gaps below 900px.
     5. Images crop subject-preserving via object-fit:cover + object-position
        tuned per composition_rule; no image ships wider than 2x its render box.
     6. Off-canvas nav toggles `inert` via matchMedia in js/main.js so hidden
        links are not Tab stops.
   MOTION: one structural easing token (--ease-structural) reused everywhere;
   one overshoot token (--ease-overshoot) reserved for the primary CTA only.
   ============================================================ */

/* ---- Fonts: self-hosted variable woff2, latin subset, display:swap ---- */
@font-face {
  font-family: "Sora";
  src: url("../fonts/sora-latin-var.woff2") format("woff2");
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("../fonts/plusjakartasans-latin-var.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}

/* ---- Tokens (the ONLY place hex/rgba/font/radius/shadow literals live) ---- */
:root {
  /* color */
  --color-ground: #F8F6F2;
  --color-layer: #FFFFFF;
  --color-panel: #EBE7E0;
  --color-ink: #1E3E39;
  --color-ink-structure: #2B645A;
  --color-ink-on-dark: #F8F6F2;
  --color-accent: #D18847;
  /* Accessible terracotta (ADDED in repair G2-06/G4-03; --color-accent unchanged, stays for
     large/decorative use). >=4.5:1 both as CTA fill w/ cream text AND as small text on
     cream/white/panel: onCream 5.32, onWhite 5.75, onPanel 4.66, cream-on-fill 5.32. */
  --color-accent-cta: #985520;
  --color-text-secondary: #5A5E58;
  --border-hairline: rgba(30, 62, 57, 0.07);
  /* derived rgba from token colours (declared here, never inline) */
  --accent-soft: rgba(209, 136, 71, 0.10);
  --accent-ring: rgba(209, 136, 71, 0.40);
  --ink-scrim: rgba(30, 62, 57, 0.55);
  --ink-scrim-strong: rgba(30, 62, 57, 0.72);
  --ink-hairline-dark: rgba(248, 246, 242, 0.16);
  --focus-ring: rgba(209, 136, 71, 0.55);

  /* typography */
  --font-display: "Sora", system-ui, sans-serif;
  --font-body: "Plus Jakarta Sans", system-ui, sans-serif;
  --fs-h1: clamp(2.25rem, 5vw, 3.75rem);
  --fs-h2: clamp(1.75rem, 3.5vw, 2.5rem);
  --fs-h3: clamp(1.25rem, 2vw, 1.5rem);
  --fs-body: 1.125rem;
  --fs-small: 0.9375rem;
  --fs-eyebrow: 0.8125rem;
  --lh-h1: 1.08;
  --lh-h2: 1.15;
  --lh-h3: 1.25;
  --lh-body: 1.6;
  --ls-h1: -0.02em;
  --ls-h2: -0.01em;
  --ls-eyebrow: 0.12em;

  /* spacing */
  --space-xs: 8px;
  --space-sm: 16px;
  --space-md: 24px;
  --space-lg: 48px;
  --space-xl: 80px;
  --section-padding: clamp(4rem, 9vw, 7.5rem);
  --container-max: 1152px;
  --container-narrow: 760px;
  --measure: 68ch;

  /* radius */
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 12px;

  /* shadow */
  --shadow-ambient: 0 1px 3px rgba(30, 62, 57, 0.04), 0 8px 24px rgba(30, 62, 57, 0.05);
  --shadow-cta-overshoot: 0 2px 8px rgba(209, 136, 71, 0.28);

  /* motion */
  --ease-structural: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-overshoot: cubic-bezier(0.34, 1.4, 0.64, 1);
  --dur-hover: 150ms;
  --dur-reveal: 350ms;
}

/* ---- Defensive reset: any author display rule must not defeat [hidden] ---- */
[hidden] { display: none !important; }

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 88px; scroll-padding-bottom: 72px; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--color-ground);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* overflow-wrap:anywhere (NOT break-word): a display-scale word longer than the ~320px
   content box (e.g. the 40px H1 floor rendering "communication") breaks onto the next line
   instead of forcing horizontal overflow. `anywhere` — unlike `break-word` — also reduces the
   element's intrinsic MIN-CONTENT, so its grid/flex track can shrink to the viewport. Only
   triggers below ~360px; at 375px+ the composition is unchanged (rule 11). */
h1, h2, h3, h4 { font-family: var(--font-display); margin: 0 0 var(--space-sm); color: var(--color-ink); overflow-wrap: anywhere; }
h1 { font-size: var(--fs-h1); font-weight: 700; line-height: var(--lh-h1); letter-spacing: var(--ls-h1); text-wrap: balance; }
h2 { font-size: var(--fs-h2); font-weight: 700; line-height: var(--lh-h2); letter-spacing: var(--ls-h2); text-wrap: balance; }
h3 { font-size: var(--fs-h3); font-weight: 600; line-height: var(--lh-h3); }
p { margin: 0 0 var(--space-sm); max-width: var(--measure); overflow-wrap: anywhere; }
a { color: var(--color-ink-structure); text-underline-offset: 0.15em; }
a:hover { color: var(--color-accent); }
img { max-width: 100%; height: auto; display: block; }
strong { font-weight: 700; }
:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 2px; border-radius: var(--radius-sm); }

.skip-link {
  position: absolute; left: var(--space-sm); top: -100px;
  background: var(--color-ink); color: var(--color-ink-on-dark);
  padding: var(--space-xs) var(--space-md); border-radius: var(--radius-md);
  z-index: 200; transition: top var(--dur-hover) var(--ease-structural);
}
.skip-link:focus { top: var(--space-sm); color: var(--color-ink-on-dark); }

/* ---- Layout helpers ---- */
.container { width: 100%; max-width: var(--container-max); margin-inline: auto; padding-inline: var(--space-md); }
.container-narrow { max-width: var(--container-narrow); }
.section { padding-block: var(--section-padding); }
.section--layer { background: var(--color-layer); }
.section--panel { background: var(--color-panel); }
.eyebrow {
  font-family: var(--font-body); font-weight: 600; font-size: var(--fs-eyebrow);
  line-height: 1.2; letter-spacing: var(--ls-eyebrow); text-transform: uppercase;
  color: var(--color-accent-cta); margin: 0 0 var(--space-sm);
}
.lede { font-size: 1.25rem; color: var(--color-text-secondary); max-width: 60ch; }
.text-secondary { color: var(--color-text-secondary); }
.fs-small { font-size: var(--fs-small); }
.w-full { width: 100%; }
.brand--on-dark { color: var(--color-ink-on-dark); }
.brand--on-dark:hover { color: var(--color-ink-on-dark); }
.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
/* Hero H1 emphasis is display-scale TEXT, so it takes the accessible token even though large
   text needs only 3:1 (old --color-accent was 2.66:1 on ground, failing even large-text). */
.accent-italic { font-style: italic; color: var(--color-accent-cta); }
.chip {
  display: inline-flex; align-items: center; gap: var(--space-xs);
  font-family: var(--font-body); font-size: var(--fs-small); font-weight: 600;
  color: var(--color-ink); background: var(--accent-soft);
  padding: 6px var(--space-sm); border-radius: var(--radius-sm);
}
/* Chip TEXT moved to --color-ink (repair-6 G2-ADV): terracotta text on the terracotta-tint
   accent-soft fill measured ~Lc21. Fill stays warm; the accent survives in the .dot. */
.chip .dot { width: 7px; height: 7px; border-radius: var(--radius-sm); background: var(--color-accent); }

/* ---- Buttons ---- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-xs);
  min-height: 48px; padding: 0 var(--space-lg);
  font-family: var(--font-body); font-size: 1.0625rem; font-weight: 600;
  border-radius: var(--radius-md); border: 2px solid transparent; cursor: pointer;
  text-decoration: none; transition: background var(--dur-hover) var(--ease-structural),
    box-shadow var(--dur-hover) var(--ease-overshoot), transform var(--dur-hover) var(--ease-overshoot);
}
.btn-primary { background: var(--color-accent-cta); color: var(--color-ink-on-dark); }
.btn-primary:hover { color: var(--color-ink-on-dark); box-shadow: var(--shadow-cta-overshoot); transform: translateY(-1px); }
.btn-secondary {
  background: transparent; color: var(--color-ink); padding: 0 var(--space-sm);
  min-height: 44px; font-weight: 600;
}
.btn-secondary .arrow { color: var(--color-accent-cta); transition: transform var(--dur-hover) var(--ease-structural); }
.btn-secondary:hover { color: var(--color-ink); }
.btn-secondary:hover .arrow { transform: translateX(4px); }
.btn-on-dark { background: var(--color-accent-cta); color: var(--color-ink-on-dark); }
.btn-ghost-on-dark { background: transparent; color: var(--color-ink-on-dark); border-color: var(--ink-hairline-dark); }

/* ---- Header / nav ---- */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: var(--color-ground); border-bottom: 1px solid var(--border-hairline);
}
.nav {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-md);
  min-height: 72px; padding-block: var(--space-xs);
}
.brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; color: var(--color-ink); font-family: var(--font-display); font-weight: 700; font-size: 1.25rem; }
.brand:hover { color: var(--color-ink); }
.brand__mark { width: 34px; height: 34px; flex: none; color: var(--color-ink-structure); }
/* Full inline nav (>1150px): sized to fit the 1152px container with margin.
   The phone number is icon-only in the top bar at EVERY width (its digits live in
   the tel: aria-label, the always-visible footer NAP, and the mobile call bar), the
   link gap is tightened to --space-sm, and the CTA uses --space-md padding. Measured
   intrinsic ~1031px < 1104px container content, so the full nav never overflows the
   viewport at any width >=1151 (repair pass-2 G4-12). */
.nav__links { display: flex; align-items: center; gap: var(--space-sm); list-style: none; margin: 0; padding: 0; }
.nav__links a { color: var(--color-ink); text-decoration: none; font-weight: 500; font-size: 1rem; white-space: nowrap; }
.nav__links a:hover { color: var(--color-accent); }
/* Current-page marker is a persistent state -> accessible token (repair pass-2 item 4). */
.nav__links a[aria-current="page"] { color: var(--color-accent-cta); }
.nav__actions { display: flex; align-items: center; gap: var(--space-sm); }
.nav__call {
  display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 var(--space-sm);
  color: var(--color-ink-structure); text-decoration: none; font-weight: 600; font-size: 1rem;
  border-radius: var(--radius-md); white-space: nowrap;
}
.nav__call:hover { color: var(--color-accent); }
.nav__call .ico { width: 18px; height: 18px; }
/* Icon-only across all widths; digits remain in the tel: aria-label + footer NAP + call bar. */
.nav__call .label { display: none; }
.nav__cta { white-space: nowrap; padding: 0 var(--space-md); }
.nav__toggle { display: none; }

/* Nav collapses to the hamburger at <=1150px, not 900px: with 7 links + phone + CTA the
   full inline nav only fits cleanly at 1140px+ (G4 measured), so the 901-1139 mid-band
   overflowed. Hamburger up to 1150 closes that band. js/main.js matchMedia mirrors 1150
   so the off-canvas links stay inert (no invisible Tab stops). (repair G2-05 + G4-02) */
@media (max-width: 1150px) {
  .nav__links {
    position: fixed; inset: 72px 0 auto 0; flex-direction: column; align-items: stretch;
    gap: 0; background: var(--color-layer); border-bottom: 1px solid var(--border-hairline);
    padding: var(--space-sm) var(--space-md) var(--space-lg);
    transform: translateY(-120%); transition: transform 300ms var(--ease-structural);
    box-shadow: var(--shadow-ambient);
  }
  .nav__links a { padding: var(--space-sm) 0; min-height: 48px; display: flex; align-items: center; border-bottom: 1px solid var(--border-hairline); }
  .nav[data-open="true"] .nav__links { transform: translateY(0); }
  .nav__toggle {
    display: inline-flex; align-items: center; justify-content: center; width: 48px; height: 48px;
    background: transparent; border: 1px solid var(--border-hairline); border-radius: var(--radius-md);
    color: var(--color-ink); cursor: pointer; order: 3;
  }
  .nav__toggle .ico { width: 22px; height: 22px; }
  /* 601-1150: hamburger menu, but call + CTA persist in the bar (P0.6). Measured header
     row brand+toggle+call+cta ~525px < 553px container at 601px, so no phone-width overflow. */
  .nav__cta { font-size: 0.95rem; }
}
/* <=600: the sticky mobile call bar (below) carries BOTH the call and the Book CTA, so the
   header row drops to brand + toggle only -> fits at 320px (~237px < 272px container). The
   phone number stays visible at every breakpoint in the footer NAP + call bar (rule 11 met
   by preserved visibility, not by this redundant top-bar instance). (repair pass-2 G4-11) */
@media (max-width: 600px) {
  .nav__call, .nav__cta { display: none; }
}

/* ---- Hero (Session Frame) ---- */
.hero { position: relative; overflow: hidden; }
.hero__grid {
  display: grid; grid-template-columns: 1.05fr 0.95fr; gap: var(--space-xl); align-items: center;
  padding-block: clamp(3rem, 7vw, 6rem);
}
.hero__copy { max-width: 40ch; }
.hero h1 { margin-bottom: var(--space-md); }
.hero__sub { font-size: 1.1875rem; color: var(--color-text-secondary); max-width: 46ch; margin-bottom: var(--space-md); }
.hero__chip { display: flex; flex-wrap: wrap; gap: var(--space-xs); margin-bottom: var(--space-lg); }
.hero__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-md); }
.hero__frame { position: relative; }

/* Home hero — full-bleed soft-fade study frame (design-direction.json hero rhythm:
   "full-bleed, soft-fade image into cream ground"). Desktop: the person-less study image
   covers the band; the copy overlays the image's upper-left pale-wall negative space; a
   token-only cream soft-fade guarantees headline contrast (light-mode-craft device, no new
   tokens). Mobile: the band flows normally — copy first, then a capped 3:4 study frame. */
.hero--bleed { position: relative; overflow: hidden; background: var(--color-ground); display: grid; align-items: center; min-height: clamp(28rem, 42vw, 38rem); }
.hero--bleed .container { position: relative; z-index: 1; }
.hero--bleed .hero__copy { max-width: 40ch; padding-block: clamp(3rem, 7vw, 6rem); }
.hero--bleed .hero__media { position: absolute; inset: 0; z-index: 0; }
.hero--bleed .hero__media picture { display: block; width: 100%; height: 100%; }
.hero--bleed .hero__media img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: center 40%; }
/* Opaque stop extended 30%->55% in repair-6 (G4-R4-01): the copy column right edge sits at
   ~37-39% of viewport across 1024/1280/1440 (container 1152 capped), so the sub wrapped into
   the fade band over the study backdrop (3.01:1 @1440). Copy now sits fully on opaque ground;
   the study still reveals across the right ~45%. */
.hero--bleed .hero__media::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: linear-gradient(90deg, var(--color-ground) 0%, var(--color-ground) 55%, transparent 90%); }
@media (max-width: 900px) {
  .hero--bleed { display: block; min-height: 0; }
  .hero--bleed .hero__copy { max-width: none; }
  .hero--bleed .hero__media { position: static; inset: auto; z-index: auto; width: min(15rem, 62vw); aspect-ratio: 3 / 4; margin: var(--space-lg) auto 0; border-radius: var(--radius-lg); overflow: hidden; background: var(--color-panel); }
  .hero--bleed .hero__media::after { display: none; }
}

/* Session Frame — real photo state (soft-fade inner edge to cream) */
.session-frame {
  position: relative; border-radius: var(--radius-lg); overflow: hidden; background: var(--color-panel);
}
.session-frame img { width: 100%; height: 100%; object-fit: cover; }
/* Scene Session Frame — box governs the aspect so CLS stays 0 across the art-directed
   <picture> switch (16:9 desktop -> 3:4 at the stack breakpoint), independent of which
   source loads. Rule-driven per the header comment (images crop subject-preserving). */
.session-frame--scene { aspect-ratio: 16 / 9; }
@media (max-width: 900px) { .session-frame--scene { aspect-ratio: 3 / 4; } }

/* Founder REVIEW card — calm mono placeholder honoring the real-photo gate */
.founder-review {
  display: flex; flex-direction: column; justify-content: space-between; gap: var(--space-md);
  border: 1.5px dashed var(--color-ink-structure); border-radius: var(--radius-lg);
  background: var(--color-layer); color: var(--color-ink);
  /* Genuinely fluid: width fills the grid/flex column it sits in and min-width:0 lets that
     column shrink below the card's content, so aspect-ratio only ever sets HEIGHT from the
     actual column width -> the card can never force a min-width and never drives horizontal
     overflow at any viewport (repair pass-2 G4-13; the old vw-bound min-height forced a
     hard 448px width in any track >=622px and reopened 601-940px). */
  padding: var(--space-lg); aspect-ratio: 16 / 10; width: 100%; min-width: 0;
}
.founder-review--portrait { aspect-ratio: 3 / 4; }
.founder-review__tag {
  font-family: var(--font-body); font-size: var(--fs-eyebrow); font-weight: 600;
  letter-spacing: var(--ls-eyebrow); text-transform: uppercase; color: var(--color-accent-cta);
  display: inline-flex; align-items: center; gap: var(--space-xs);
}
.founder-review__frame { font-family: var(--font-display); font-weight: 600; font-size: 1.1875rem; }
.founder-review__instruction { font-size: var(--fs-small); color: var(--color-text-secondary); max-width: 42ch; }
.founder-review__note { font-size: 0.8125rem; color: var(--color-text-secondary); border-top: 1px solid var(--border-hairline); padding-top: var(--space-sm); }
.founder-review__icon { width: 26px; height: 26px; color: var(--color-ink-structure); }

/* ---- Posture band ---- */
.posture { }
.posture__grid { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: var(--space-xl); align-items: start; }
.posture__statement { font-family: var(--font-display); font-weight: 600; font-size: clamp(1.5rem, 3vw, 2.125rem); line-height: 1.25; letter-spacing: -0.01em; text-wrap: balance; max-width: 20ch; }
.posture__support { color: var(--color-text-secondary); max-width: 52ch; }

/* ---- Audience router ---- */
.router__head { max-width: 46ch; margin-bottom: var(--space-lg); }
.router__tabs { display: flex; flex-wrap: wrap; gap: var(--space-xs); background: var(--color-panel); padding: var(--space-xs); border-radius: var(--radius-lg); margin-bottom: var(--space-lg); }
.router__tab {
  flex: 1 1 auto; min-height: 48px; padding: 0 var(--space-md); border: none; cursor: pointer;
  background: transparent; color: var(--color-ink); font-family: var(--font-body); font-weight: 600; font-size: 1rem;
  border-radius: var(--radius-md); display: inline-flex; align-items: center; justify-content: center; gap: var(--space-xs);
  transition: background var(--dur-hover) var(--ease-structural), color var(--dur-hover) var(--ease-structural);
}
.router__tab .ico { width: 18px; height: 18px; color: var(--color-accent); }
.router__tab[aria-selected="true"] { background: var(--color-layer); color: var(--color-ink); box-shadow: var(--shadow-ambient); }
.router__panel { display: grid; grid-template-columns: 0.95fr 1.05fr; gap: var(--space-xl); align-items: center; }
.router__panel[hidden] { display: none; }
.router__value { font-family: var(--font-display); font-weight: 600; font-size: clamp(1.5rem, 2.6vw, 2rem); line-height: 1.2; text-wrap: balance; max-width: 18ch; margin-bottom: var(--space-md); }
.router__frame-label { font-size: var(--fs-small); color: var(--color-text-secondary); margin-bottom: var(--space-md); }
.router__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-md); }
.scope-microcue {
  display: inline-flex; align-items: center; gap: var(--space-xs); margin-top: var(--space-md);
  font-size: var(--fs-small); color: var(--color-ink-structure); text-decoration: none;
  border-left: 3px solid var(--color-accent); padding: var(--space-xs) var(--space-sm); background: var(--accent-soft);
  border-radius: var(--radius-sm);
}
.scope-microcue:hover { color: var(--color-accent); }
/* No-JS: panels stack full-width, tabs hidden */
.no-js .router__tabs { display: none; }
.no-js .router__panel[hidden] { display: grid; }
.no-js .router__panel { margin-bottom: var(--space-xl); }

/* ---- Scope-clarity band + comparison ---- */
.scope-band__grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-xl); align-items: start; }
.scope-statement { font-size: 1.1875rem; }
/* Multi-column data tables can't shrink below their cell content; on a phone the table
   scrolls horizontally INSIDE this focusable wrapper so the PAGE never overflows (repair
   pass-2, .compare table overflow class — home scope-band 2-col + coaching-vs-therapy 3-col). */
.table-scroll { position: relative; overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }
/* Mobile scroll affordance (mobile-polish): the 3-col comparison is the whole point
   of coaching-vs-therapy, but on a phone the table is wider than the viewport and the
   3rd column ("Coaching") was cut with NO cue that it scrolls — it read as a broken
   overflow. A right-edge fade toward the section ground signals "swipe for more";
   token-only gradient (transparent -> --color-ground), pointer-events:none so it never
   blocks the scroll/tap. Gated to <=600px, where the table always overflows. */
@media (max-width: 600px) {
  .table-scroll::after {
    content: ""; position: absolute; top: 0; right: 0; bottom: 0; width: 2.5rem;
    pointer-events: none; border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
    background: linear-gradient(90deg, transparent, var(--color-ground));
  }
  /* Tighter cells on phones (md 24 -> sm 16) so more of the 3rd column shows within
     the same scroll — still comfortable, and the fade cue carries the rest. */
  .compare th, .compare td { padding: var(--space-sm); }
}
.compare { border-collapse: collapse; width: 100%; background: var(--color-layer); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-ambient); }
.compare caption { text-align: left; font-family: var(--font-display); font-weight: 600; font-size: var(--fs-h3); margin-bottom: var(--space-sm); color: var(--color-ink); }
.compare th, .compare td { text-align: left; padding: var(--space-md); border-bottom: 1px solid var(--border-hairline); vertical-align: top; font-size: var(--fs-small); }
.compare thead th { font-family: var(--font-display); font-size: 1rem; color: var(--color-ink); background: var(--color-panel); }
.compare tbody tr:last-child td { border-bottom: none; }
.scope-disclaimer { font-size: var(--fs-small); color: var(--color-text-secondary); border-left: 3px solid var(--color-ink-structure); padding: var(--space-sm) var(--space-md); background: var(--color-layer); border-radius: var(--radius-sm); max-width: var(--measure); }
.scope-disclaimer strong { color: var(--color-ink); }

/* ---- How it works ---- */
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-lg); }
.step { }
.step__ico { width: 40px; height: 40px; color: var(--color-accent); margin-bottom: var(--space-md); }
.step__n { font-family: var(--font-body); font-size: var(--fs-eyebrow); font-weight: 600; letter-spacing: var(--ls-eyebrow); text-transform: uppercase; color: var(--color-accent-cta); }
.step h3 { margin-top: var(--space-xs); }
.tenure-anchor { margin-top: var(--space-xl); display: inline-flex; align-items: baseline; gap: var(--space-sm); border-top: 2px solid var(--color-accent); padding-top: var(--space-md); }
/* white-space:nowrap keeps the stat value "11+ years" as one unit: in the flex
   row the display-scale .big was allowed to shrink and broke "11+" / "years"
   across two lines on mobile (home how-it-works + about), weakening the headline
   number. nowrap holds it together; the label sibling still wraps freely, and
   overflow-wrap:anywhere on the value guards the sub-320px edge (mobile-polish). */
.tenure-anchor .big { font-family: var(--font-display); font-weight: 700; font-size: clamp(2rem, 4vw, 3rem); color: var(--color-ink); white-space: nowrap; }

/* ---- FAQ accordion ---- */
.faq { max-width: 820px; }
.faq__item { border-bottom: 1px solid var(--border-hairline); }
.faq__trigger {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: var(--space-md);
  background: transparent; border: none; cursor: pointer; text-align: left;
  padding: var(--space-md) 0; min-height: 56px; color: var(--color-ink);
  font-family: var(--font-display); font-weight: 600; font-size: 1.1875rem;
}
.faq__trigger:hover { color: var(--color-accent); }
.faq__icon { flex: none; width: 22px; height: 22px; color: var(--color-accent); transition: transform var(--dur-hover) var(--ease-structural); }
.faq__trigger[aria-expanded="true"] .faq__icon { transform: rotate(45deg); }
.faq__panel { padding: 0 0 var(--space-md); color: var(--color-text-secondary); }
.faq__panel p { color: var(--color-text-secondary); }
.faq__panel[hidden] { display: none; }

/* ---- CTA / contact inversion band ---- */
.cta-band { background: var(--color-ink); color: var(--color-ink-on-dark); }
.cta-band h2, .cta-band h3 { color: var(--color-ink-on-dark); }
.cta-band a { color: var(--color-ink-on-dark); }
.cta-band__grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-xl); align-items: start; }
.cta-band .lede { color: var(--color-ink-on-dark); opacity: 0.85; }
/* Eyebrow renders in the band's on-dark ink for AA contrast (10.79:1). The bright accent
   measured 4.06:1 on the forest band, below the 4.5 AA bar; the legal bar wins over the
   warmth aesthetic (repair G4-3-01, orchestrator adjudication). */
.cta-band .eyebrow { color: var(--color-ink-on-dark); }
/* Crisis notice ALWAYS renders inside the white .form, so it is authored for a light
   context: ink text + a visible dark hairline (repair G2-01). The cream variant lives on
   the dark footer/inversion band as .footer__crisis and .crisis-notice--on-dark below. */
.crisis-notice {
  font-size: var(--fs-small); border: 1px solid var(--border-hairline); border-radius: var(--radius-md);
  padding: var(--space-md); margin-bottom: var(--space-md); color: var(--color-ink);
}
.crisis-notice strong { color: var(--color-ink); }
.crisis-notice a { text-decoration: underline; color: var(--color-ink-structure); font-weight: 600; }
/* Reserved dark-context modifier (footer already uses .footer__crisis; kept for any future
   crisis notice placed directly on a dark band). */
.crisis-notice--on-dark { border-color: var(--ink-hairline-dark); color: var(--color-ink-on-dark); }
.crisis-notice--on-dark strong, .crisis-notice--on-dark a { color: var(--color-ink-on-dark); }
/* NOTE: .scope-disclaimer and .booking-fallback inside .cta-band ALWAYS render within the
   white .form card, never directly on the dark band (verified across all 6 form pages). The
   former `.cta-band .scope-disclaimer`/`.cta-band .booking-fallback` cream overrides had no
   legitimate dark-context target and only leaked cream-on-white (1.08:1) into the form, so
   they are removed. Both now use their default light-context tokens: text-secondary body
   (6.4:1 on white), ink strong, ink-structure links (6.7:1). (repair pass-2 G2-NEW-01 / G4-14) */

/* Forms */
.form { background: var(--color-layer); border-radius: var(--radius-lg); padding: var(--space-lg); box-shadow: var(--shadow-ambient); color: var(--color-ink); }
.form h3 { color: var(--color-ink); }
.field { margin-bottom: var(--space-md); }
.field label { display: block; font-weight: 600; font-size: var(--fs-small); margin-bottom: 6px; color: var(--color-ink); }
.field input, .field select, .field textarea {
  width: 100%; min-width: 0; min-height: 48px; padding: 0 var(--space-sm); font-family: var(--font-body); font-size: 1rem;
  color: var(--color-ink); background: var(--color-ground); border: 1px solid var(--border-hairline);
  border-radius: var(--radius-md);
}
/* min-width:0 lets a <select> shrink below its longest option's intrinsic width instead of
   forcing the form card wider than a 320px viewport (repair pass-2, form-select overflow class). */
.field textarea { min-height: 96px; padding: var(--space-sm); resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus { outline: 3px solid var(--focus-ring); outline-offset: 1px; }
.field .hint { font-size: 0.8125rem; color: var(--color-text-secondary); margin-top: 4px; }
.consent { display: flex; gap: var(--space-sm); align-items: flex-start; margin-bottom: var(--space-md); }
.consent input { width: 22px; height: 22px; margin-top: 2px; flex: none; }
.consent label { font-size: var(--fs-small); color: var(--color-ink); font-weight: 500; }
.hp-field { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.form__error { color: var(--color-accent); font-weight: 600; font-size: var(--fs-small); margin-top: var(--space-sm); }
.form__error:not([hidden]) { display: block; }
.booking-fallback { font-size: var(--fs-small); color: var(--color-text-secondary); margin-top: var(--space-md); }
.booking-fallback a { color: var(--color-ink-structure); font-weight: 600; }
/* .cta-band .booking-fallback cream override removed (same root cause as above): it only ever
   matched the instance inside the white .form. Default light-context tokens apply. (G2-NEW-01) */
.cta-band .form { color: var(--color-ink); }

/* ---- Service / leaf page ---- */
.subhero { padding-block: clamp(2.5rem, 6vw, 5rem); }
.subhero__grid { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: var(--space-xl); align-items: center; }
.breadcrumbs { font-size: var(--fs-small); margin-bottom: var(--space-md); }
.breadcrumbs ol { list-style: none; display: flex; flex-wrap: wrap; gap: var(--space-xs); margin: 0; padding: 0; }
.breadcrumbs li { color: var(--color-text-secondary); }
.breadcrumbs a { color: var(--color-ink-structure); text-decoration: none; }
.breadcrumbs a:hover { color: var(--color-accent); }
.breadcrumbs .sep { color: var(--color-text-secondary); }
.facts-strip { list-style: none; margin: var(--space-lg) 0 0; padding: var(--space-md) 0 0; border-top: 1px solid var(--border-hairline); display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--space-md); }
.facts-strip li { display: flex; flex-direction: column; gap: 2px; }
.facts-strip__n { font-family: var(--font-display); font-weight: 700; font-size: 1.375rem; color: var(--color-ink); }
.facts-strip__l { font-size: 0.8125rem; color: var(--color-text-secondary); }
@media (max-width: 900px) { .facts-strip { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .facts-strip { grid-template-columns: 1fr 1fr; } }

.prose { max-width: var(--measure); }
.prose h2 { margin-top: var(--space-lg); }
.prose h3 { margin-top: var(--space-lg); }
.prose ul { padding-left: 1.2em; }
.prose li { margin-bottom: var(--space-xs); max-width: var(--measure); }
.answer-island { font-size: 1.1875rem; color: var(--color-ink); font-weight: 500; }
.focus-list { columns: 2; column-gap: var(--space-lg); }
.focus-list li { break-inside: avoid; }
.pullquote {
  font-family: var(--font-display); font-weight: 600; font-size: clamp(1.375rem, 2.6vw, 1.875rem);
  line-height: 1.3; color: var(--color-ink); border-left: 4px solid var(--color-accent);
  padding-left: var(--space-md); margin: var(--space-lg) 0; max-width: 28ch; text-wrap: balance;
}
.areas-served { background: var(--color-panel); border-radius: var(--radius-lg); padding: var(--space-lg); }

/* ---- Blog ---- */
/* min(100%, 320px) floor: below a 320px container the single column caps at 100% instead of
   forcing a 320px track wider than the viewport (repair pass-2, blog-grid overflow class). */
.blog-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr)); gap: var(--space-lg); }
/* Blog media reads as editorial thumbnails, NOT the 12px "Session Frame" corner: tighter
   md radius + a flatter 16:9 masthead crop distinguishes them from the founder frame (repair G2-07). */
.post-card { position: relative; background: var(--color-layer); border-radius: var(--radius-md); overflow: hidden; box-shadow: var(--shadow-ambient); display: flex; flex-direction: column; transition: transform var(--dur-hover) var(--ease-structural); }
.post-card__media { aspect-ratio: 16 / 9; background: var(--color-panel); }
.post-card__media img { width: 100%; height: 100%; object-fit: cover; }
.post-card__body { padding: var(--space-md); display: flex; flex-direction: column; gap: var(--space-xs); flex: 1; }
.post-card__meta { font-size: 0.8125rem; color: var(--color-text-secondary); }
.post-card h3 { margin: 0; font-size: 1.25rem; }
.post-card h3 a { color: var(--color-ink); text-decoration: none; }
.post-card h3 a:hover { color: var(--color-accent); }
/* Stretched link (repair-10): the single card link's ::after covers the whole card,
   so the image, meta, dek and "Read the post" are all one click target. Exactly one
   link per card (the h3) — the media wrapper is a non-link div, so screen readers get
   one clean link named by the post title. */
.post-card h3 a::after { content: ""; position: absolute; inset: 0; }
.post-card__dek { font-size: var(--fs-small); color: var(--color-text-secondary); margin: 0; }
.post-card__more { margin-top: auto; font-weight: 600; color: var(--color-ink-structure); font-size: var(--fs-small); }
.post-card__more .arrow { display: inline-block; transition: transform var(--dur-hover) var(--ease-structural); }
/* Card-level hover affordance (repair-10), existing tokens only: lift + arrow nudge.
   The lift selector out-specifies `.js .reveal.is-in { transform:none }` (0,4,1 > 0,3,0)
   so it still applies after the reveal completes. Gated to fine-pointer/hover devices. */
@media (hover: hover) and (pointer: fine) {
  .post-card:hover, .js .reveal.is-in.post-card:hover { transform: translateY(-4px); }
  .post-card:hover .arrow { transform: translateX(4px); }
}

.about-environmentals { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-md); }
/* Stack at the site's declared 900px rule (was 600) so the 2-col band never runs tighter
   than the multi-column stacking notch (repair pass-2 G4-13, rule-consistent breakpoint). */
@media (max-width: 900px) { .about-environmentals { grid-template-columns: 1fr; } }
.article__hero-media { aspect-ratio: 16 / 9; border-radius: var(--radius-md); overflow: hidden; background: var(--color-panel); margin-bottom: var(--space-lg); max-width: var(--container-narrow); }
.article__hero-media img { width: 100%; height: 100%; object-fit: cover; }
.article__meta { font-size: var(--fs-small); color: var(--color-text-secondary); margin-bottom: var(--space-md); }
.article-body { max-width: var(--measure); }
.article-body h2 { margin-top: var(--space-lg); }
.article-body p { margin-bottom: var(--space-md); }
.author-card { display: flex; gap: var(--space-md); align-items: flex-start; background: var(--color-panel); border-radius: var(--radius-lg); padding: var(--space-lg); margin-top: var(--space-xl); max-width: var(--measure); }
.author-card__avatar { width: 56px; height: 56px; flex: none; border-radius: var(--radius-lg); background: var(--color-ink-structure); color: var(--color-ink-on-dark); display: flex; align-items: center; justify-content: center; font-family: var(--font-display); font-weight: 700; }
.related { border-top: 1px solid var(--border-hairline); padding-top: var(--space-lg); margin-top: var(--space-xl); }

/* ---- TODO block for needs_client_material (visible, clearly-marked) ---- */
.client-todo {
  border: 1.5px dashed var(--color-accent); border-radius: var(--radius-lg);
  background: var(--accent-soft); padding: var(--space-lg); max-width: var(--measure);
}
.client-todo__tag { font-family: var(--font-body); font-size: var(--fs-eyebrow); font-weight: 700; letter-spacing: var(--ls-eyebrow); text-transform: uppercase; color: var(--color-accent-cta); display: block; margin-bottom: var(--space-xs); }
.client-todo p { color: var(--color-ink); margin-bottom: 0; }

/* ---- Footer ---- */
.site-footer { background: var(--color-ink); color: var(--color-ink-on-dark); padding-block: var(--section-padding); }
.site-footer a { color: var(--color-ink-on-dark); }
.site-footer a:hover { color: var(--color-accent); }
.footer__grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1.2fr; gap: var(--space-lg); }
.footer__ip { font-family: var(--font-display); font-weight: 600; font-size: 1.25rem; line-height: 1.3; max-width: 22ch; text-wrap: balance; }
.footer__col h3 { color: var(--color-ink-on-dark); font-size: 1rem; margin-bottom: var(--space-md); }
.footer__col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-xs); }
.footer__col a { text-decoration: none; }
.footer__nap a { text-decoration: none; }
.footer__nap .row { display: flex; align-items: center; gap: var(--space-xs); margin-bottom: var(--space-xs); }
.footer__nap .ico { width: 16px; height: 16px; color: var(--color-accent); flex: none; }
.newsletter-note { font-size: var(--fs-small); opacity: 0.85; }
.newsletter { display: flex; gap: var(--space-xs); margin-top: var(--space-sm); flex-wrap: wrap; }
.newsletter input { flex: 1 1 160px; min-height: 44px; padding: 0 var(--space-sm); border-radius: var(--radius-md); border: 1px solid var(--ink-hairline-dark); background: transparent; color: var(--color-ink-on-dark); }
.newsletter input::placeholder { color: var(--color-ink-on-dark); opacity: 0.6; }
.footer__legal { border-top: 1px solid var(--ink-hairline-dark); margin-top: var(--space-lg); padding-top: var(--space-lg); display: grid; gap: var(--space-md); }
.footer__scope, .footer__crisis { font-size: var(--fs-small); opacity: 0.92; max-width: 80ch; }
.footer__crisis strong { color: var(--color-ink-on-dark); }
.footer__crisis a { text-decoration: underline; font-weight: 600; }
.footer__meta { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-md); font-size: 0.8125rem; opacity: 0.8; }

/* ---- Mobile sticky call bar (<=600px only; ATF CTA + this = rule 8) ---- */
.mobile-callbar { display: none; }
@media (max-width: 600px) {
  .mobile-callbar {
    display: flex; gap: var(--space-xs); position: fixed; inset: auto 0 0 0; z-index: 90;
    padding: var(--space-xs) var(--space-md) calc(var(--space-xs) + env(safe-area-inset-bottom, 0px));
    background: var(--color-ground); border-top: 1px solid var(--border-hairline);
  }
  .mobile-callbar .btn { flex: 1 1 auto; min-height: 48px; padding-inline: var(--space-sm); font-size: 1rem; }
  .mobile-callbar .btn-secondary { flex: 0 0 auto; border: 1px solid var(--border-hairline); }
  body { padding-bottom: 72px; }
}

/* ---- Reveal animation: visible-by-default, JS adds hiding class (P1.22) ---- */
.js .reveal { opacity: 0; transform: translateY(16px); transition: opacity var(--dur-reveal) var(--ease-structural), transform var(--dur-reveal) var(--ease-structural); }
.js .reveal.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
  .btn, .faq__icon, .btn-secondary .arrow, .post-card, .post-card__more .arrow { transition: none !important; }
}

/* ---- Responsive derivation (rules declared in header comment) ---- */
@media (max-width: 900px) {
  :root { --section-padding: clamp(3rem, 8vw, 5rem); }
  .hero__grid, .posture__grid, .router__panel, .scope-band__grid, .subhero__grid, .cta-band__grid { grid-template-columns: 1fr; gap: var(--space-lg); }
  .steps { grid-template-columns: 1fr; gap: var(--space-md); }
  .footer__grid { grid-template-columns: 1fr 1fr; }
  /* Router source order is copy-before-media in the HTML, so copy leads on mobile with no
     `order` override needed. The former `order:-1` faked a visual sequence that did not match
     the DOM (WCAG 1.3.2); the source now carries the meaningful order at every breakpoint
     (repair G4-3-02). */
  .focus-list { columns: 1; }
  /* Tap targets grow to the declared >=48px floor on the footer/breadcrumb/brand links too
     (repair G4-09); footer/breadcrumb lists already carry the 8px gap token. */
  .footer__col ul a, .footer__nap .row a { display: inline-flex; align-items: center; min-height: 48px; }
  .breadcrumbs a { display: inline-flex; align-items: center; min-height: 48px; padding-block: var(--space-xs); }
  .brand { min-height: 48px; }
}
@media (max-width: 600px) {
  .footer__grid { grid-template-columns: 1fr; }
  .router__tabs { flex-direction: column; }
  .router__tab { width: 100%; }
  .hero__actions .btn, .router__actions .btn { width: 100%; }
  /* Mobile-polish fold recovery (home hero): the 48px gap before the actions is
     the largest slab of dead space above the fold on a 667px phone. Step it down
     one notch (lg 48 -> md 24) so the value prop + Boca chip + CTA land with
     breathing room. Existing spacing token only. Verified: no reflow/CLS. */
  .hero__chip { margin-bottom: var(--space-md); }
  .hero--bleed .hero__copy { padding-block: var(--space-md) var(--space-lg); }
  .founder-review { padding: var(--space-md); }
  /* Tighter button padding on phones: the default 48px inline padding + a long label word
     (e.g. "conversation") pushed a full-width form button's min-content past a 320px viewport
     inside the 48px-padded .form card. 24px padding keeps the tap target while it fits. */
  .btn { padding-inline: var(--space-md); }
}

/* ---- Print reset: reveals composed, dark bands legible ---- */
@media print {
  .reveal { opacity: 1 !important; transform: none !important; }
  .site-header, .nav__toggle, .newsletter { display: none !important; }
  .cta-band, .site-footer { background: transparent !important; color: var(--color-ink) !important; }
  .cta-band h2, .cta-band h3, .cta-band a, .site-footer a, .footer__ip { color: var(--color-ink) !important; }
}
