/* ╔═══════════════════════════════════════════════════════════════════════╗
   ║  HEAL-AI · css/style.css                                              ║
   ║  Stanford Health Care — Health AI Evaluation Lab                         ║
   ╠═══════════════════════════════════════════════════════════════════════╣
   ║                                                                       ║
   ║  TABLE OF CONTENTS                                                    ║
   ║  ──────────────────                                                   ║
   ║   §1  DESIGN TOKENS · :root variables                                 ║
   ║         • Colors (Stanford palette)                                   ║
   ║         • Typography                                                  ║
   ║         • Spacing, motion, elevation                                  ║
   ║   §2  RESET & GLOBAL ELEMENTS                                         ║
   ║   §3  LAYOUT PRIMITIVES (.section, .page, grids)                      ║
   ║   §4  LOADER                                                          ║
   ║   §5  TOP NAVIGATION + MOBILE MENU                                    ║
   ║   §6  HERO (canvas, badges, tooltip, scroll cue)                      ║
   ║   §7  CONTENT BLOCKS — home page (about, stats, flow, signup)         ║
   ║   §8  PROCESS PAGE (FURM card, 5-step grid, coming-soon)              ║
   ║   §9  VIDEOS (grid cards + modal player)                              ║
   ║   §10 RESOURCES (tabbed library + sample-report grid)                 ║
   ║   §11 PATIENT PANEL (split layout + accordion)                        ║
   ║   §12 PLAYBOOK (hero + card grid)                                     ║
   ║   §13 ABOUT (cards + team grid)                                       ║
   ║   §14 FOOTER                                                          ║
   ║   §15 RESPONSIVE BREAKPOINTS                                          ║
   ║   §16 ACCESSIBILITY & MOTION PREFERENCES                              ║
   ║                                                                       ║
   ║  EDIT-HERE QUICK MAP                                                  ║
   ║   • Brand colors ............... §1, --cardinal + neighbors           ║
   ║   • Spacing / radii ............ §1                                   ║
   ║   • Breakpoint widths .......... §15 (and explained inline below)     ║
   ║                                                                       ║
   ║  ARCHITECTURAL NOTES (why this file is shaped this way)               ║
   ║   • CSS custom properties give us one-line theme changes. NEVER       ║
   ║     hard-code a brand color anywhere outside §1 — always reference    ║
   ║     a variable like var(--cardinal). If you find a hard-coded color,  ║
   ║     promote it to a token.                                            ║
   ║   • Structural styles (page, section, grid) come BEFORE component     ║
   ║     styles. This mirrors the document outline and minimizes the cost  ║
   ║     of cascade overrides.                                             ║
   ║   • Animations use cubic-bezier(.2,.6,.2,1) — a soft "ease-out-ish"   ║
   ║     curve that feels right for both opening UI and content reveal.    ║
   ║     Stored as --ease so it stays consistent across the whole site.    ║
   ║   • All interactive elements have :focus-visible rings (§16). DO NOT  ║
   ║     remove them with `outline:none` — they are the only way keyboard  ║
   ║     users can see where they are.                                     ║
   ║                                                                       ║
   ╚═══════════════════════════════════════════════════════════════════════╝ */


/* ═══════════════════════════════════════════════════════════════════════
   §1 · DESIGN TOKENS
   ───────────────────────────────────────────────────────────────────────
   The Stanford brand palette + typographic scale + motion + spacing.
   To re-skin the entire site, only this block needs to change.

   COLOR RATIONALE
     --cardinal        Stanford's official Cardinal Red. Primary accent.
     --cardinal-dark   Pressed/hovered state, and the gradient anchor on the
                       signup CTA block.
     --cardinal-light  Used sparingly for borders on dashed "Coming soon"
                       cards so they read as branded rather than generic.
     --cardinal-tint   Subtle background fill for chips, eyebrow underlines,
                       hover states. Calculated as ~8% cardinal-on-white.
     --bg              Pure white panels.
     --bg-soft         Off-white #F9F9F9 — used for alternating bands so
                       sections never feel like one giant wall of white.
     --bg-warm         Slightly warmer neutral, used on the patient-panel
                       Stanford side to differentiate it from the external
                       side without leaving the white→off-white palette.
     --ink             Charcoal text. Replaces pure black for readability.
     --ink-mid         Body copy.
     --ink-low         Eyebrows, captions, footnotes.
     --line            Generic 1px border / divider.

     NOTE: Per the rebrand, NO GOLD anywhere. If you see a gold-like value
           in this codebase later, it crept in by mistake — please remove.
   ─────────────────────────────────────────────────────────────────────── */
:root {
  /* ── Brand (EDIT HERE) ─────────────────────────────────────────────── */
  --cardinal:        #8C1515;
  --cardinal-dark:   #6D1010;
  --cardinal-light:  #B83A3A;
  --cardinal-tint:   rgba(140, 21, 21, 0.08);
  --cardinal-soft:   rgba(140, 21, 21, 0.04);

  /* ── Neutrals ─────────────────────────────────────────────────────── */
  --bg:              #FFFFFF;
  --bg-soft:         #F9F9F9;
  --bg-warm:         #F2EFEA;

  --ink:             #2E2D29;   /* primary text · ~13:1 on white */
  --ink-mid:         #4D4F53;   /* body / sub copy · ~8:1 on white */
  --ink-low:         #6B6D71;   /* eyebrows, captions · ~5:1 on white — WCAG AA */
  --ink-dim:         rgba(46, 45, 41, 0.18);

  --line:            rgba(46, 45, 41, 0.10);
  --line-strong:     rgba(46, 45, 41, 0.18);

  /* ── Typography ───────────────────────────────────────────────────── */
  --serif: 'Source Serif Pro', Georgia, serif;
  --sans:  'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --mono:  'JetBrains Mono', ui-monospace, monospace;

  /* ── Motion (centralized for cross-component consistency) ──────────── */
  --ease:   cubic-bezier(.2, .6, .2, 1);  /* soft, slightly overshooting ease */
  --t-fast: .18s;                          /* hover, focus, micro */
  --t-med:  .32s;                          /* panel open/close, page swap */
  --t-slow: .55s;                          /* hero entry, large reveals */

  /* ── Radii & shadows ──────────────────────────────────────────────── */
  --radius-sm: 6px;
  --radius:    10px;
  --radius-lg: 14px;
  --radius-xl: 18px;
  --shadow-1:  0 1px 4px rgba(0,0,0,.03);
  --shadow-2:  0 8px 22px rgba(0,0,0,.06);
  --shadow-3:  0 16px 40px rgba(0,0,0,.10);
}


/* ═══════════════════════════════════════════════════════════════════════
   §2 · RESET & GLOBAL ELEMENTS
   ───────────────────────────────────────────────────────────────────────
   Modest reset — we don't strip everything because we want sensible
   defaults for headings/lists/buttons. Just unify box-sizing and zero
   the universally-noisy margins/paddings.
   ─────────────────────────────────────────────────────────────────────── */
*,
*::before,
*::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  /* Hard guard against horizontal scroll at 200% zoom or narrow widths.
     Paired with body { overflow-x:hidden } for belt-and-suspenders. */
  overflow-x: hidden;
}

body {
  font-family: var(--sans);
  background: var(--bg);
  color: var(--ink);
  line-height: 1.55;
  font-weight: 400;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

a       { color: inherit; text-decoration: none; }
button  { font-family: inherit; cursor: pointer; background: none; border: none; color: inherit; }
img,
svg     { display: block; max-width: 100%; }

/* a11y · visually hidden but still announced */
.sr {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0);
  white-space: nowrap; border: 0;
}


/* ═══════════════════════════════════════════════════════════════════════
   §3 · LAYOUT PRIMITIVES
   ───────────────────────────────────────────────────────────────────────
   .page    — full-viewport routed container (one per "page"). Only the
              .active one is visible.
   .section — opinionated horizontal container with brand-correct padding.
              Variants: .narrow (max-width tighter), .tight (less vertical
              padding), .section-band (off-white band), and the dark
              cardinal gradient used inside the signup card itself.

   ARCHITECTURAL NOTE — why position:fixed on .page
     We use fixed positioning + opacity transitions on every .page so the
     route change is genuinely instant (no scroll thrash, no layout
     calculation) and the focus order stays clean.
   ─────────────────────────────────────────────────────────────────────── */
.page {
  position: fixed; inset: 0;
  overflow-y: auto; overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  background: var(--bg);
  opacity: 0; visibility: hidden;
  /* No opacity/visibility transition on purpose.
     Previously we crossfaded pages over 320ms, but the outgoing and
     incoming pages overlapped mid-transition at ~50% opacity — text at
     50% on a white background reads as pale grey, which looked like a
     "loading" flash between tabs. Instant swap eliminates it entirely. */
}
.page.active { opacity: 1; visibility: visible; }

/*
   SECTION CONTAINERS
   Horizontal padding uses `clamp()` so the layout stays graceful under
   200% browser zoom and on narrow viewports:
     min 24px  (compact phones / 200% zoom on small laptops)
     ideal 5vw (smooth scaling)
     max 80px  (caps the gutter on huge monitors)
   No more hard 80px gutters that would clip into the canvas at 200% zoom.
*/
.section          { padding: 96px clamp(24px, 5vw, 80px); max-width: 1320px; margin: 0 auto; }
.section.narrow   { max-width: 1080px; }
.section.tight    { padding: 64px clamp(24px, 5vw, 80px); }
.section-band     { background: var(--bg-soft); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }


/* ═══════════════════════════════════════════════════════════════════════
   §4 · LOADER — liquid-fill brand splash
   ───────────────────────────────────────────────────────────────────────
   Two copies of the same logo, both turned into flat silhouettes via
   mask-image (the logo file itself is the mask/stencil, so this works
   with the one existing SVG asset — no separately-colored file needed):
     .loader-logo-outline → light gray, always fully visible underneath.
     .loader-logo-fill    → solid cardinal, clipped by an animated
                            wavy-edged polygon that rises from the bottom
                            (rest state, 0% filled) to the top (100%
                            filled) — see @keyframes loader-rise below.
   The polygon keeps the same 9 vertices at every keyframe (7 wave points
   across the top edge + 2 fixed bottom corners) with only their Y values
   changing — that vertex-count consistency is what lets the browser
   interpolate a smooth, wobbly "waterline" between keyframes instead of
   just snapping between shapes.
   ─────────────────────────────────────────────────────────────────────── */
#loader {
  position: fixed; inset: 0;
  background: var(--bg);
  z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  transition: opacity .6s ease .1s, visibility .6s ease .1s;
}
#loader.exit { opacity: 0; visibility: hidden; }

.loader-fill-wrap {
  position: relative;
  width: clamp(220px, 34vw, 420px);
  aspect-ratio: 540 / 200;   /* intrinsic ratio of heal-ai-logo-cardinal.svg */
}
.loader-logo-outline,
.loader-logo-fill {
  position: absolute; inset: 0;
  -webkit-mask: url('../assets/heal-ai-logo-cardinal.svg') center / contain no-repeat;
          mask: url('../assets/heal-ai-logo-cardinal.svg') center / contain no-repeat;
}
.loader-logo-outline { background: var(--line-strong); }
.loader-logo-fill {
  background: var(--cardinal);
  animation: loader-rise 1.6s cubic-bezier(.4, 0, .2, 1) forwards;
}
@keyframes loader-rise {
  0%   { clip-path: polygon(0% 100%, 16% 101%, 33% 100%, 50% 102%, 67% 100%, 84% 101%, 100% 100%, 100% 100%, 0% 100%); }
  35%  { clip-path: polygon(0% 72%, 16% 68%, 33% 74%, 50% 67%, 67% 73%, 84% 69%, 100% 72%, 100% 100%, 0% 100%); }
  65%  { clip-path: polygon(0% 42%, 16% 46%, 33% 40%, 50% 47%, 67% 41%, 84% 45%, 100% 42%, 100% 100%, 0% 100%); }
  88%  { clip-path: polygon(0% 16%, 16% 12%, 33% 18%, 50% 11%, 67% 17%, 84% 13%, 100% 16%, 100% 100%, 0% 100%); }
  100% { clip-path: polygon(0% -6%, 16% -6%, 33% -6%, 50% -6%, 67% -6%, 84% -6%, 100% -6%, 100% 100%, 0% 100%); }
}


/* ═══════════════════════════════════════════════════════════════════════
   §5 · TOP NAVIGATION + MOBILE MENU
   ───────────────────────────────────────────────────────────────────────
   The desktop nav is a row of tab buttons. The mobile menu is a full-width
   slide-down panel that appears below the header.

   a11y NOTE
     • Nav buttons get role="tab" / aria-selected attributes in app.js.
     • The hamburger toggles aria-expanded on itself and aria-hidden on
       the menu container.
   ─────────────────────────────────────────────────────────────────────── */
nav.topnav {
  position: fixed; top: 0; left: 0; right: 0;
  z-index: 500;
  height: 68px;
  padding: 0 44px;
  display: flex; align-items: center; justify-content: space-between;
  background: rgba(255, 255, 255, .86);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--line);
}

.nav-logo {
  display: flex; align-items: center; gap: 12px;
  cursor: pointer;
  padding: 6px; margin: -6px;
  border-radius: 8px;
}
.logo-mark {
  height: 42px;              
  width: auto;               
  max-width: 240px;          
  object-fit: contain;
  flex-shrink: 0;
}
.logo-name { font-size: 14px; font-weight: 600; color: var(--ink); letter-spacing: .02em; line-height: 1.15; }
.logo-sub  { font-family: var(--mono); font-size: 9px; letter-spacing: .14em;
             color: var(--ink-low); text-transform: uppercase; margin-top: 1px; }

.nav-center { display: flex; gap: 2px; }

/* ──  Tab button (used in both desktop nav and mobile menu) ── */
.nav-tab {
  color: var(--ink-mid);
  font-size: 13.5px; font-weight: 500;
  padding: 9px 14px;
  border-radius: 8px;
  min-height: 44px;                      /* a11y · touch-target floor */
  /* Uniform ease-in-out micro-interaction across the whole UI */
  transition: all .25s ease-in-out;
}
.nav-tab:hover { color: var(--ink); background: var(--cardinal-tint); }
.nav-tab.active {
  color: var(--cardinal);
  background: var(--cardinal-tint);
  font-weight: 600;
}

.nav-right { display: flex; gap: 10px; align-items: center; }

/* ── Primary CTA (Sign up) ── */
.btn-cta {
  background: var(--cardinal);
  color: #fff;
  border-radius: 8px;
  padding: 11px 22px;
  font-size: 13px; font-weight: 600;
  letter-spacing: .01em;
  min-height: 44px;
  display: inline-flex; align-items: center; gap: 6px;
  /* Uniform ease-in-out micro-interaction */
  transition: all .25s ease-in-out;
}
.btn-cta:hover {
  background: var(--cardinal-dark);
  transform: translateY(-1px);
  box-shadow: 0 10px 22px rgba(140, 21, 21, .22);
}

/* A CTA standing in for something not available yet — currently the sample
   report modal's download, for reports whose file has no host (see
   openReportDetail() in app.js). Reads as inert, and the hover lift is
   suppressed so it doesn't invite a click. */
.btn-cta.is-unavailable {
  background: var(--line-strong);
  color: var(--ink-low);
  cursor: default;
}
.btn-cta.is-unavailable:hover { background: var(--line-strong); transform: none; box-shadow: none; }
.btn-cta.outline {
  background: transparent;
  color: var(--cardinal);
  border: 1.5px solid var(--cardinal);
}
.btn-cta.outline:hover { background: var(--cardinal); color: #fff; }

/* ── Hamburger toggle (mobile only) ── */
.nav-toggle {
  display: none;
  width: 44px; height: 44px;
  border-radius: 8px;
  align-items: center; justify-content: center;
  color: var(--ink);
}
.nav-toggle svg {
  width: 22px; height: 22px;
  stroke: currentColor; stroke-width: 2;
  fill: none;
}

/* ── Mobile menu panel ── */
.mobile-menu {
  position: fixed; inset: 68px 0 0 0;
  background: var(--bg);
  z-index: 499;
  overflow-y: auto;
  padding: 24px;
  display: flex; flex-direction: column; gap: 4px;
  transform: translateY(-100%);
  transition: transform var(--t-med) var(--ease);
}
.mobile-menu.open { transform: translateY(0); }
.mobile-menu .nav-tab {
  font-size: 18px;
  padding: 16px 12px;
  text-align: left;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  justify-content: flex-start;
  display: flex;
}
.mobile-menu .btn-cta { margin-top: 20px; justify-content: center; }


/* ═══════════════════════════════════════════════════════════════════════
   §6 · HERO
   ───────────────────────────────────────────────────────────────────────
   The hero is full-viewport. A <canvas> draws the cardinal mesh in the
   background; everything else is positioned over it.

   The 3D mesh has nothing to do with layout — if you remove the canvas
   entirely the hero still renders fine because the radial-gradient
   background on .hero provides the same visual base.
   ─────────────────────────────────────────────────────────────────────── */
/* .hero-scroll-track's height is set inline by initHeroScrollIntro() in
   app.js (100vh + SETTLE_DISTANCE) — .hero stays pinned via position:sticky
   for exactly that extra distance, so the crossfade plays out with the
   hero fully framed in the viewport instead of scrolling away mid-animation,
   then un-pins and scrolls normally once the intro has fully settled. */
.hero-scroll-track { position: relative; }

.hero {
  position: sticky; top: 0;
  width: 100%;
  height: 100vh; min-height: 680px;
  overflow: hidden;
  background: radial-gradient(
    1100px 800px at 64% 44%,
    #fff 22%,
    #fafafa 50%,
    var(--cardinal-soft) 100%
  );
  /* Scroll-linked crossfade state, all set every frame by
     initHeroScrollIntro()/updateHeroScrollIntro() in app.js as #page-home
     scrolls — NOT CSS transitions, so they track the scroll gesture
     directly rather than animating on a timer.
       --hero-progress → raw 0→1 over the full settle distance; drives
                          the canvas zoom and the human-layer collapse,
                          neither of which clash with anything else so
                          they can stay continuous.
       --hero-out       → 0→1 over the FIRST 35% of the distance; the
                          intro tagline + scroll cue fade out on this.
       --hero-in        → 0→1 over the LAST 35% (50%→85%); the real
                          headline/sub/buttons fade in on this instead —
                          staggered rather than simultaneous with --hero-out,
                          so the two text layers never sit at ~50% opacity
                          on top of each other mid-scroll. */
  --hero-progress: 0;
  --hero-out: 0;
  --hero-in: 0;
}
/* Sits behind #hero-canvas (z-index 0 vs 1) — see the index.html comment
   above the <canvas> tags for why this is a wholly separate canvas/node
   system rather than a second layer drawn onto the same one. */
/* #3 — collapses into the AI mesh as the user scrolls: fades out AND
   shrinks toward the AI mesh's own node-cluster center (66%/42% — matches
   cx/cy in initHeroCanvas()'s build()), so by full settle only the red
   mesh remains, and it visually reads as "emerging from" the human layer
   rather than the human layer just disappearing on its own. Tied to the
   continuous --hero-progress (not the staggered --hero-out/--hero-in
   used for text) since this is the canvas layer, not competing text. */
#human-canvas {
  position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0;
  transform-origin: 66% 42%;
  opacity: calc(1 - var(--hero-progress, 0));
  transform: scale(calc(1 - var(--hero-progress, 0) * 0.35));
}
#hero-canvas {
  position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1;
  /* Slight zoom-out as the intro settles, so the mesh visibly "minimizes"
     alongside the text crossfade instead of just sitting there while text
     changes around it. */
  transform: scale(calc(1 + (1 - var(--hero-progress, 0)) * 0.12));
}

/* Full-bleed intro tagline — the only text visible at --hero-progress: 0.
   Fades and drifts up as the user scrolls; see .hero-content below for
   the mirror-image animation (fades/slides in as this fades/slides out). */
/* Anchored bottom-left with the SAME padding as .hero-content below, so
   the label sits exactly where .hero-eye (the settled eyebrow) will
   appear once the crossfade completes — an understated corporate label,
   not a decorative centered headline. */
.hero-intro {
  position: absolute; inset: 0; z-index: 2;
  display: flex; align-items: flex-end;
  padding: 0 72px 84px;
  pointer-events: none;
  opacity: calc(1 - var(--hero-out, 0));
}
.hero-intro-tagline {
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--cardinal-dark);
  /* The whole line travels straight up as it fades — a simple block
     morph, not a per-letter effect. Lands close to where .hero-eye
     (the settled eyebrow) sits, so the handoff into --hero-in reads as
     one continuous upward motion rather than two disconnected states. */
  transform: translateY(calc(var(--hero-out, 0) * -30px));
}

/* NOTE: Legacy decorative chrome (`.hai-badge`, `.hero-meta`, `.hm-dot`,
   `@keyframes pulseDot`, `.quote-mark`) was removed per the brand cleanup
   pass — the affiliate badge, the "live · v1.0" strip, and the pull-quote
   glyph above the about-statement were creating typographic noise. */

/* Tooltip on hero canvas research nodes */
#node-tooltip {
  position: fixed;
  padding: 14px 16px;
  max-width: 260px;
  pointer-events: none;
  z-index: 600;
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, .98);
  border: 1px solid var(--line-strong);
  box-shadow: 0 16px 40px rgba(0, 0, 0, .10), 0 0 0 1px var(--cardinal-tint);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  opacity: 0;
  transition: opacity var(--t-fast);
}
#node-tooltip.show { opacity: 1; }
.nt-meta {
  display: flex; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 9px;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--cardinal);
  margin-bottom: 6px;
}
.nt-meta::before {
  content: '';
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--cardinal);
}
.nt-title { font-size: 13px; font-weight: 500; color: var(--ink); line-height: 1.5; }
.nt-hint  { font-family: var(--mono); font-size: 9px; color: var(--ink-low);
            margin-top: 8px; letter-spacing: .06em; text-transform: uppercase; }

/* Hero text + buttons (positioned bottom-left of the hero). Mirror image
   of .hero-intro-tagline: hidden/offset at --hero-progress: 0, fades and
   slides up into its normal resting position as the user scrolls. */
.hero-content {
  position: relative; z-index: 3;
  height: 100%;
  padding: 0 72px 84px;
  max-width: 1320px;
  display: flex; flex-direction: column; justify-content: flex-end;
  pointer-events: none;                  /* let canvas hover pass through */
  opacity: var(--hero-in, 0);
  transform: translateY(calc((1 - var(--hero-in, 0)) * 26px));
}
/* Buttons/links only become clickable once the intro has meaningfully
   settled — otherwise they'd sit invisibly clickable over the full-bleed
   intro moment. Toggled by initHeroScrollIntro() in app.js. */
.hero.hero-settled .hero-content > * { pointer-events: auto; }

.hero-eye {
  display: flex; align-items: center; gap: 10px;
  font-family: var(--mono); font-size: 10px;
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--cardinal); font-weight: 500;
  margin-bottom: 22px;
}
.hero-eye-bar { width: 24px; height: 1.5px; background: var(--cardinal); }

.hero h1 {
  font-family: var(--serif);
  font-size: clamp(40px, 6.4vw, 86px);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -.018em;
  color: var(--ink);
  max-width: 920px;
}
.hero h1 em { font-style: italic; color: var(--cardinal); font-weight: 500; }

.hero-sub {
  font-size: 17px; color: var(--ink-mid);
  max-width: 560px; margin-top: 22px;
  font-weight: 400; line-height: 1.65;
}

.hero-btns { display: flex; gap: 12px; margin-top: 36px; flex-wrap: wrap; }

/* Big rounded primary/secondary buttons used in the hero only */
.btn-prime {
  background: var(--cardinal); color: #fff;
  border-radius: 50px;
  padding: 14px 28px;
  font-size: 14px; font-weight: 600;
  min-height: 48px;                       /* a11y · touch target */
  display: inline-flex; align-items: center; gap: 8px;
  /* Uniform ease-in-out micro-interaction */
  transition: all .25s ease-in-out;
}
.btn-prime:hover {
  background: var(--cardinal-dark);
  transform: translateY(-1px);
  box-shadow: 0 14px 28px rgba(140, 21, 21, .24);
}
.btn-second {
  background: rgba(255, 255, 255, .65);
  border: 1.5px solid var(--line-strong);
  color: var(--ink);
  border-radius: 50px;
  padding: 14px 28px;
  font-size: 14px; font-weight: 500;
  min-height: 48px;
  display: inline-flex; align-items: center; gap: 8px;
  backdrop-filter: blur(8px);
  /* Uniform ease-in-out micro-interaction */
  transition: all .25s ease-in-out;
}
.btn-second:hover {
  border-color: var(--cardinal);
  color: var(--cardinal);
  background: #fff;
}

/* Decorative "Scroll" indicator at bottom-right of hero */
.scroll-cue {
  position: absolute; bottom: 32px; right: 64px; z-index: 3;
  display: flex; align-items: center; gap: 12px;
  font-family: var(--mono); font-size: 10px;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--ink-low);
  /* It's a "scroll to continue" hint for the full-bleed intro — fade it
     out early (by 40% progress) rather than lingering the whole crossfade. */
  opacity: calc(1 - var(--hero-out, 0));
}
.scroll-bar {
  width: 36px; height: 1.5px;
  background: var(--line-strong);
  overflow: hidden; border-radius: 2px;
}
.scroll-bar::after {
  content: '';
  display: block; width: 100%; height: 100%;
  background: var(--cardinal);
  transform: translateX(-100%);
  animation: scrollslide 2.2s ease-in-out infinite;
}
@keyframes scrollslide {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}


/* ═══════════════════════════════════════════════════════════════════════
   §7 · HOME PAGE — content blocks
   ───────────────────────────────────────────────────────────────────────
   Eyebrows, section headings, the About block, stats row, Get Started
   flow grid, and the cardinal signup CTA card.
   ─────────────────────────────────────────────────────────────────────── */

/* ── Shared editorial marks ── */
.eyebrow {
  font-family: var(--mono); font-size: 10px;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--cardinal); font-weight: 500;
  margin-bottom: 24px;
  display: flex; align-items: center; gap: 10px;
}
.eyebrow::before { content: ''; width: 24px; height: 1.5px; background: var(--cardinal); }
.eyebrow.on-dark { color: #fff; }
.eyebrow.on-dark::before { background: #fff; }
/* About section's eyebrow drops the little rule mark — quieter, more
   like a plain editorial category label than a marketing accent. */
.eyebrow-plain::before { content: none; }

.h2 {
  font-family: var(--serif);
  font-size: clamp(32px, 4vw, 52px);
  font-weight: 500; line-height: 1.12;
  letter-spacing: -.012em;
  color: var(--ink);
}
.h2 em { font-style: italic; color: var(--cardinal); font-weight: 500; }
.h2.on-dark, .h2.on-dark em { color: #fff; }

.h3 {
  font-family: var(--serif);
  font-size: 24px; font-weight: 500;
  line-height: 1.25; color: var(--ink);
}

.lede {
  font-size: 16px; color: var(--ink-mid);
  line-height: 1.75; max-width: 600px;
  font-weight: 400;
}

/* ── About / positioning block ── */
.about-block {
  display: grid;
  /* Resilient asymmetric layout. At ≥760px we get the intended 1.1 : 1
     split; below that, the responsive media query in §15 collapses to
     a single column. `align-items: start` prevents the side bullets
     from stretching to match the statement height. */
  grid-template-columns: 1.1fr 1fr;
  gap: 72px;
  align-items: start;
}
.about-statement {
  font-family: var(--serif);
  font-size: clamp(24px, 2.4vw, 32px);
  font-weight: 400; line-height: 1.5;
  letter-spacing: -.005em;
  color: var(--ink);
  max-width: 640px;
}
.about-statement em { font-style: italic; color: var(--cardinal); font-weight: 500; }

/* Evidence-block list, not feature cards: a hairline-divided column
   (border-top on the container, border-bottom per row) instead of
   individually-boxed, tinted, rounded cards — reads as a policy-report
   principles list rather than a SaaS feature grid. */
.about-side-label {
  font-family: var(--mono); font-size: 11px;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-low); font-weight: 500;
  margin-bottom: 4px;
}
.about-side { display: flex; flex-direction: column; border-top: 1px solid var(--line); }
.about-bullet {
  display: flex; gap: 16px; align-items: flex-start;
  padding: 20px 0;
  border-bottom: 1px solid var(--line);
}
.about-bullet-icon {
  font-family: var(--mono); font-size: 11px; font-weight: 600;
  letter-spacing: .04em;
  color: var(--cardinal);
  width: 20px; flex-shrink: 0;
  padding-top: 3px;
}
.about-bullet h4 { font-size: 14px; font-weight: 600; color: var(--ink); margin-bottom: 4px; }
.about-bullet p  { font-size: 13px; color: var(--ink-mid); line-height: 1.6; }

/* ── Stats row ── */
.stats-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  background: var(--bg);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.stat { padding: 56px 44px; border-right: 1px solid var(--line); }
.stat:last-child { border-right: none; }
.stat-n {
  font-family: var(--serif);
  font-size: 56px; font-weight: 500;
  color: var(--cardinal);
  line-height: 1;
  letter-spacing: -.015em;
  margin-bottom: 10px;
}
.stat-l { font-size: 13.5px; color: var(--ink-mid); line-height: 1.65; font-weight: 400; }
.stat-l strong { color: var(--ink); font-weight: 600; }

/* ── Get Started flow ── */
.flow-head {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 48px; flex-wrap: wrap;
  margin-bottom: 56px;
}
.flow-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  position: relative;
}
.flow-step {
  padding: 32px 22px 28px;
  border: 1px solid var(--line);
  background: var(--bg);
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 16px;
  min-height: 240px;
  cursor: pointer;
  position: relative;
  /* Uniform ease-in-out micro-interaction */
  transition: all .25s ease-in-out;
}
.flow-step:not(:last-child) { border-right: none; }
.flow-step:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 30px rgba(0,0,0,.06);
  border-color: var(--cardinal);
  z-index: 2;
}
.flow-num { font-family: var(--mono); font-size: 11px; letter-spacing: .16em;
            color: var(--cardinal); font-weight: 600; }
.flow-icon {
  width: 44px; height: 44px;
  border-radius: 10px;
  background: var(--cardinal-tint); color: var(--cardinal);
  display: flex; align-items: center; justify-content: center;
}
.flow-icon svg {
  width: 22px; height: 22px;
  stroke: currentColor; stroke-width: 1.8;
  fill: none; stroke-linecap: round; stroke-linejoin: round;
}
.flow-step h4 { font-family: var(--serif); font-size: 19px; font-weight: 500;
                color: var(--ink); line-height: 1.25; }
.flow-step p  { font-size: 13px; color: var(--ink-mid); line-height: 1.6; }
.flow-arrow {
  position: absolute; right: -9px; top: 50%;
  transform: translateY(-50%);
  width: 18px; height: 18px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  z-index: 3;
}
.flow-arrow svg { width: 10px; height: 10px; stroke: var(--cardinal); stroke-width: 2; fill: none; }

/* ── Sign-up CTA card (cardinal gradient) ── */
.signup-card {
  position: relative;
  padding: 64px 56px;
  border-radius: var(--radius-xl);
  background: linear-gradient(135deg, var(--cardinal) 0%, var(--cardinal-dark) 100%);
  color: #fff;
  display: grid; grid-template-columns: 1.4fr 1fr;
  gap: 48px;
  align-items: center;
  overflow: hidden;
}
.signup-card::after {
  /* decorative soft glow in the top-right corner */
  content: '';
  position: absolute; right: -80px; top: -80px;
  width: 320px; height: 320px;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255,255,255,.10), transparent);
  pointer-events: none;
}
.signup-card h2 {
  font-family: var(--serif);
  font-size: clamp(28px, 3.4vw, 40px);
  font-weight: 500; line-height: 1.15;
  margin-bottom: 12px;
}
.signup-card p {
  font-size: 15px; line-height: 1.7;
  color: rgba(255, 255, 255, .85);
  max-width: 520px;
}
.signup-card .btn-cta {
  background: #fff; color: var(--cardinal);
  font-size: 14px;
  padding: 14px 28px;
  justify-content: center;
  min-height: 48px;
}
.signup-card .btn-cta:hover { background: rgba(255,255,255,.92); transform: translateY(-1px); }

.signup-side {
  display: flex; flex-direction: column; gap: 14px;
  justify-content: flex-end; align-items: flex-end;
  position: relative; z-index: 1;
}
/* ─── SIGN-UP FORM ───────────────────────────────────────────────────────
   The same three fields render in two places: inline on the cardinal
   .signup-card (white-on-red), and in #signup-modal on white. Shared
   structure lives in .signup-form/.signup-field; the .signup-card
   overrides below are what invert it for the dark panel. */
.signup-form { display: flex; flex-direction: column; gap: 12px; width: 100%; }
.signup-field { display: flex; flex-direction: column; gap: 5px; }
.signup-field span {
  font-family: var(--mono); font-size: 10px;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-low);
}
.signup-field input {
  font-family: inherit; font-size: 14px; color: var(--ink);
  padding: 10px 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--bg);
  width: 100%;
}
.signup-field input:focus { outline: none; border-color: var(--cardinal); }

/* Off-screen rather than display:none — a bot that skips undisplayed
   inputs should still see this one. aria-hidden + tabindex=-1 in the
   markup keep it away from real users. */
.signup-honeypot {
  position: absolute; left: -9999px;
  width: 1px; height: 1px; overflow: hidden;
}

.signup-status { font-size: 12.5px; line-height: 1.5; min-height: 18px; }
.signup-status.is-error { color: var(--cardinal); }
.signup-status.is-ok    { color: var(--ink); font-weight: 600; }

/* Inline-on-the-card variant: the card is cardinal, so labels and the
   status line invert, and inputs go translucent-white. */
.signup-card .signup-side-form { align-items: stretch; width: 100%; }
.signup-card .signup-field span { color: rgba(255,255,255,.72); }
.signup-card .signup-field input {
  background: rgba(255,255,255,.12);
  border-color: rgba(255,255,255,.28);
  color: #fff;
}
.signup-card .signup-field input::placeholder { color: rgba(255,255,255,.5); }
.signup-card .signup-field input:focus {
  border-color: #fff;
  background: rgba(255,255,255,.18);
}
.signup-card .signup-status           { color: rgba(255,255,255,.85) !important; max-width: none !important; }
.signup-card .signup-status.is-error  { color: #ffd9d9 !important; }
.signup-card .signup-status.is-ok     { color: #fff !important; font-weight: 600; }
.signup-card .btn-cta:disabled        { opacity: .6; cursor: not-allowed; transform: none; }

/* SIGN-UP MODAL — the same overlay pattern as #video-modal/#report-modal,
   on a light card since this is a form, not media. */
#signup-modal {
  position: fixed; inset: 0;
  z-index: 1000;
  padding: 40px 20px;
  background: rgba(20, 20, 20, .55);
  display: flex; align-items: center; justify-content: center;
  opacity: 0; visibility: hidden;
  transition: opacity var(--t-med), visibility var(--t-med);
}
#signup-modal.open { opacity: 1; visibility: visible; }
.sm-inner {
  position: relative;
  width: 100%; max-width: 440px;
  max-height: calc(100vh - 80px);
  overflow-y: auto;
  background: var(--bg);
  border-radius: var(--radius-lg);
  padding: 40px;
}
.sm-inner h3 {
  font-family: var(--serif);
  font-size: 26px; font-weight: 500; line-height: 1.2;
  color: var(--ink);
  margin: 6px 0 10px;
}
.sm-lede { font-size: 14px; line-height: 1.65; color: var(--ink-mid); margin-bottom: 22px; }
/* .vm-close is positioned above its dark overlay; on this light card it
   sits inside the padding instead. */
.sm-inner .vm-close {
  top: 14px; right: 14px;
  background: var(--bg-soft);
  color: var(--ink-mid);
}
.sm-inner .vm-close:hover { background: var(--line); }
.sm-inner .btn-prime:disabled { opacity: .6; cursor: not-allowed; transform: none; }


/* ═══════════════════════════════════════════════════════════════════════
   §8 · TOOLKIT PAGE (Process + Playbook + Resources, merged)
   ───────────────────────────────────────────────────────────────────────
   • Sub-page header (used by every non-home page)
   • Level-1 tab strip (.tk-bar/.tk-tab/.tk-panel) — Process | Playbook |
     Resources. Text-tab style, matching the site's institutional
     direction rather than a rounded-pill SaaS tab.
   • 4-step process grid (dotrow visualizes step number) — Process panel.
   ─────────────────────────────────────────────────────────────────────── */
.page-header {
  /* clamp() gutters mirror .section for consistent rhythm + zoom safety */
  padding: 128px clamp(24px, 5vw, 80px) 56px;
  max-width: 1320px; margin: 0 auto;
  border-bottom: 1px solid var(--line);
}
.page-eyebrow {
  font-family: var(--mono); font-size: 10px;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--cardinal); font-weight: 500;
  margin-bottom: 18px;
}
.page-h1 {
  font-family: var(--serif);
  font-size: clamp(40px, 5.2vw, 72px);
  font-weight: 500; line-height: 1.05;
  letter-spacing: -.018em;
  color: var(--ink);
  max-width: 1000px;
  margin-bottom: 18px;
}
.page-h1 em { font-style: italic; color: var(--cardinal); }
.page-sub   { font-size: 17px; color: var(--ink-mid); max-width: 680px; line-height: 1.65; }

/* Level-1 tab strip. Only 3 short labels, so this stays a plain static
   row (no horizontal scroll) at every viewport width. */
.tk-bar {
  display: flex; flex-wrap: wrap; gap: 4px;
  max-width: 1320px; margin: 0 auto;
  padding: 0 clamp(24px, 5vw, 80px);
  border-bottom: 1px solid var(--line);
}
.tk-tab {
  padding: 18px 6px; margin-right: 28px;
  font-family: var(--mono); font-size: 12px;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-mid);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color var(--t-fast), border-color var(--t-fast);
  white-space: nowrap;
}
.tk-tab:hover { color: var(--ink); }
.tk-tab.on { color: var(--cardinal); font-weight: 600; border-bottom-color: var(--cardinal); }

.tk-panel { display: none; padding: 56px clamp(24px, 5vw, 80px) 96px; max-width: 1320px; margin: 0 auto; }
.tk-panel.on { display: block; animation: fadeUp .35s var(--ease); }
.tk-h2 { margin-bottom: 40px; max-width: 760px; }
.tk-panel-lede { font-size: 15px; color: var(--ink-mid); line-height: 1.7; max-width: 680px; margin-bottom: 40px; }

/* 5-step grid */
.process-steps {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  margin-bottom: 72px;
}
/* Flex column so .dotrow can be pushed to the card's bottom edge — the cards
   stretch to equal height, so the dot gauges line up across the row no matter
   how long each step's description runs. */
.proc-step {
  padding: 36px 30px;
  border: 1px solid var(--line); border-right: none;
  background: var(--bg);
  position: relative;
  display: flex; flex-direction: column;
  transition: background var(--t-fast);
}
.proc-step:last-child { border-right: 1px solid var(--line); }
.proc-step:hover { background: var(--bg-soft); }
.proc-num { font-family: var(--mono); font-size: 11px; letter-spacing: .18em;
            color: var(--cardinal); font-weight: 600; margin-bottom: 14px; }
.proc-step h4 {
  font-family: var(--serif);
  font-size: 22px; font-weight: 500;
  color: var(--ink); line-height: 1.2;
  margin-bottom: 12px;
}
.proc-step p { font-size: 13.5px; color: var(--ink-mid); line-height: 1.65; }
.proc-step .dotrow { display: flex; align-items: center; gap: 6px; margin-top: auto; padding-top: 18px; }
.proc-step .dotrow .d {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--line-strong);
}
.proc-step .dotrow .d.on { background: var(--cardinal); }


/* ═══════════════════════════════════════════════════════════════════════
   §9 · VIDEOS
   ───────────────────────────────────────────────────────────────────────
   Phase-2 grid of 6 cards + accessible modal player. When SHOW_VIDEOS
   is false, the page falls back to .videos-hidden-notice.

   a11y NOTE for video cards
     • Each .video-card is keyboard-activatable in app.js (Enter / Space).
     • The modal traps focus visually with the dark overlay; closing it
       returns focus naturally (browser handles it because the card was
       the most-recently focused element).
   ─────────────────────────────────────────────────────────────────────── */
.videos-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 28px;
}
.video-card {
  display: flex; flex-direction: column;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  cursor: pointer;
  /* Uniform ease-in-out micro-interaction */
  transition: all .25s ease-in-out;
}
.video-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 18px 36px rgba(0, 0, 0, .08);
  border-color: var(--cardinal);
}

/* 16:9 cardinal-gradient poster with centered play button */
.video-poster {
  position: relative;
  aspect-ratio: 16 / 9;
  background: linear-gradient(135deg, var(--cardinal-dark), var(--cardinal));
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.video-poster::after {
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(circle at 60% 40%, rgba(255,255,255,.10), transparent 60%);
}
.video-poster .play {
  position: relative; z-index: 2;
  width: 54px; height: 54px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .95);
  display: flex; align-items: center; justify-content: center;
  transition: transform var(--t-fast);
}
.video-card:hover .play { transform: scale(1.07); }
.video-poster .play svg {
  width: 20px; height: 20px;
  margin-left: 3px;
  fill: var(--cardinal);
}
.video-meta {
  position: absolute; top: 14px; left: 14px;
  padding: 4px 10px;
  font-family: var(--mono); font-size: 10px;
  letter-spacing: .14em; font-weight: 600;
  color: #fff;
  background: rgba(0, 0, 0, .45);
  border-radius: 4px;
  backdrop-filter: blur(8px);
}
.video-duration {
  position: absolute; bottom: 14px; right: 14px;
  padding: 3px 8px;
  font-family: var(--mono); font-size: 10px; font-weight: 500;
  color: #fff;
  background: rgba(0, 0, 0, .65);
  border-radius: 4px;
}
.video-body { padding: 22px; }
.video-body h3 {
  font-family: var(--serif); font-size: 20px; font-weight: 500;
  color: var(--ink); line-height: 1.25;
  margin-bottom: 10px;
}
.video-body p { font-size: 13.5px; color: var(--ink-mid); line-height: 1.6; margin-bottom: 16px; }

.video-resources {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.vr-chip {
  font-family: var(--mono); font-size: 10px;
  letter-spacing: .04em; font-weight: 500;
  color: var(--cardinal);
  background: var(--cardinal-tint);
  padding: 5px 9px;
  border-radius: 4px;
  transition: background var(--t-fast), color var(--t-fast);
}
.vr-chip:hover { background: var(--cardinal); color: #fff; }

/* Modal player */
#video-modal {
  position: fixed; inset: 0;
  z-index: 1000;
  padding: 40px;
  background: rgba(20, 20, 20, .92);
  display: flex; align-items: center; justify-content: center;
  opacity: 0; visibility: hidden;
  transition: opacity var(--t-med), visibility var(--t-med);
}
#video-modal.open { opacity: 1; visibility: visible; }
.vm-inner { position: relative; width: 100%; max-width: 1100px; }
.vm-frame {
  position: relative;
  width: 100%; aspect-ratio: 16 / 9;
  background: #000;
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.vm-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.vm-meta {
  margin-top: 18px;
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 24px;
  color: #fff;
}
.vm-meta h3 { font-family: var(--serif); font-size: 24px; font-weight: 500; margin-bottom: 6px; }
.vm-meta p  { font-size: 13.5px; opacity: .75; max-width: 700px; line-height: 1.6; }
.vm-close {
  position: absolute; top: -46px; right: 0;
  width: 36px; height: 36px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .10);
  color: #fff;
  font-size: 22px;
  display: flex; align-items: center; justify-content: center;
  transition: background var(--t-fast);
}
.vm-close:hover { background: rgba(255, 255, 255, .22); }


/* Phase-1 fallback notice (SHOW_VIDEOS = false) */
.videos-hidden-notice {
  padding: 56px;
  text-align: center;
  background: var(--bg-warm);
  border: 1.5px dashed var(--cardinal-light);
  border-radius: var(--radius-lg);
}
.videos-hidden-notice h3 {
  font-family: var(--serif); font-size: 26px; font-weight: 500;
  margin-bottom: 10px; color: var(--ink);
}
.videos-hidden-notice p {
  font-size: 14px; color: var(--ink-mid);
  line-height: 1.7;
  max-width: 560px; margin: 0 auto;
}
.videos-hidden-notice .badge {
  display: inline-block;
  font-family: var(--mono); font-size: 10px;
  letter-spacing: .16em; font-weight: 600;
  color: var(--cardinal);
  background: var(--cardinal-tint);
  padding: 4px 12px;
  border-radius: 4px;
  text-transform: uppercase;
  margin-bottom: 18px;
}


/* ═══════════════════════════════════════════════════════════════════════
   §10 · RESOURCES (tabs)
   ───────────────────────────────────────────────────────────────────────
   Tab bar uses role="tablist"/role="tab"/role="tabpanel". Active state
   is communicated both visually (.on) AND via aria-selected (set in JS).
   ─────────────────────────────────────────────────────────────────────── */
/*
   RESOURCES TAB STRIP (Level 2, inside the Toolkit page's Resources panel)
   Icon-card tabs, one row of 3 equal-width boxes. The active tab gets a
   filled cardinal card + a downward-pointing triangle (::after, CSS
   clip-path) so it visually "points at" the panel content below it.
   A plain static grid at every width — auto-fit wraps to fewer columns
   on narrow screens instead of scrolling, which reads cleaner with only
   3 groups than the old 6-category horizontal-scroll carousel did.
*/
.rt-bar {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
  margin-bottom: 44px;
}

.rt-tab {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px;
  padding: 20px 12px 24px;
  border-radius: 10px;
  font-size: 13px; font-weight: 500; line-height: 1.35;
  color: var(--ink-mid);
  text-align: center;
  background: var(--bg);
  border: 1px solid var(--line);
  position: relative;
  /* Uniform ease-in-out micro-interaction across all interactive states */
  transition: all .25s ease-in-out;
}
.rt-tab-icon {
  display: flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
}
.rt-tab-icon svg { width: 100%; height: 100%; stroke: currentColor; stroke-width: 1.7; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.rt-tab:hover { color: var(--ink); border-color: var(--cardinal-light); }
.rt-tab.on    { background: var(--cardinal); color: #fff; font-weight: 600; border-color: var(--cardinal); }
/* The little downward-pointing tail — only on the active tab, points at
   the panel content that just appeared beneath the strip. */
.rt-tab.on::after {
  content: '';
  position: absolute; bottom: -8px; left: 50%; transform: translateX(-50%);
  width: 16px; height: 8px;
  background: var(--cardinal);
  clip-path: polygon(0 0, 100% 0, 50% 100%);
}
.rt-tab .n    { font-family: var(--mono); font-size: 10px; letter-spacing: .06em; opacity: .8; display: block; margin-bottom: 2px; }

/* Tabpanel fade-in (.on toggled by JS) */
.rt-panel { display: none; }
.rt-panel.on { display: block; animation: fadeUp .35s var(--ease); }
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/*
   RESOURCES TAB INTRO — the "Start here." / "How to use this section"
   asymmetric split. Uses `auto-fit` + `minmax(300px, 1fr)` so the grid
   self-collapses to a single column the moment either child would
   shrink below 300px — no media queries, no jagged half-wraps.
   `align-items: start` keeps the side card snug to the top instead of
   stretching to match the heading-paragraph block.
*/
/* Level-3: when a Level-2 group (Templates, Guides) has more than one
   RESOURCE_CATEGORIES entry, each renders as one of these stacked,
   labeled sub-sections rather than a third click-layer of tabs. */
.rt-subgroup { margin-bottom: 56px; }
.rt-subgroup:last-child { margin-bottom: 0; }
.rt-subgroup-eyebrow {
  font-family: var(--mono); font-size: 10px;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--ink-low); font-weight: 600;
  margin-bottom: 20px;
}

.rt-intro {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 48px;
  align-items: start;
  margin-bottom: 44px;
  padding-bottom: 36px;
  border-bottom: 1px solid var(--line);
}
.rt-intro h2 {
  font-family: var(--serif);
  font-size: 32px; font-weight: 500;
  color: var(--ink); line-height: 1.18;
  margin-bottom: 12px;
}
.rt-intro p { font-size: 14.5px; color: var(--ink-mid); line-height: 1.7; }
.rt-intro aside {
  padding: 24px;
  background: var(--bg-soft);
  border-radius: var(--radius);
  border-left: 3px solid var(--cardinal);
}
.rt-intro aside h4 {
  font-size: 12px;
  font-family: var(--mono);
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--cardinal); font-weight: 600;
  margin-bottom: 10px;
}
.rt-intro aside ul { list-style: none; display: flex; flex-direction: column; gap: 8px; }
.rt-intro aside li {
  font-size: 13px; color: var(--ink-mid); line-height: 1.5;
  display: flex; gap: 8px;
}
.rt-intro aside li::before { content: '→'; color: var(--cardinal); font-weight: 600; flex-shrink: 0; }

/* Resource items — a spotlight card (first item) + a single divided list
   (the rest), replacing a uniform grid of identical bordered boxes. A wall
   of same-size "boxes and boxes" reads as filler; one item earning a bigger
   treatment plus a clean scannable list reads as edited. */
.res-set { display: flex; flex-direction: column; gap: 26px; }

.res-spotlight {
  position: relative;
  display: flex; gap: 20px;
  padding: 28px 30px;
  background: var(--cardinal-soft);
  border: 1px solid var(--cardinal-tint);
  border-left: 3px solid var(--cardinal);
  border-radius: var(--radius-lg);
  transition: all .25s ease-in-out;
}
.res-spotlight.linked { cursor: pointer; }
.res-spotlight.linked:hover { box-shadow: var(--shadow-2); transform: translateY(-2px); }
.res-spotlight.soon {
  background: var(--bg-soft); border-color: var(--line); border-left-color: var(--ink-dim);
}
.res-spotlight .res-icon { width: 54px; height: 54px; }
.res-spotlight .res-icon svg { width: 25px; height: 25px; }
.res-spotlight .res-body h4 { font-family: var(--serif); font-size: 21px; font-weight: 500; margin-bottom: 8px; }
.res-spotlight .res-body p  { font-size: 14.5px; max-width: 620px; }
.res-spotlight .res-arrow  { align-self: center; }

/* ─── EQUAL PAIR ──────────────────────────────────────────────────────────
   Two resources side by side, used when a section has exactly two items
   (see resourceItemsHTML()). Deliberately NOT the cardinal-tinted
   spotlight treatment: two tinted cards competing for the same emphasis
   is louder than the section needs, and neither one is "featured" when
   there are only two. Neutral cards, equal weight.

   auto-fit collapses to a single column on narrow viewports without a
   media query, and stretch keeps both cards the same height when one
   description wraps to more lines than the other. */
.res-pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 18px;
  align-items: stretch;
}
.res-tile {
  position: relative;
  display: flex; flex-direction: column; gap: 14px;
  padding: 26px 26px 22px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  transition: all .25s ease-in-out;
}
.res-tile.linked { cursor: pointer; }
.res-tile.linked:hover {
  border-color: var(--cardinal-tint);
  box-shadow: var(--shadow-2);
  transform: translateY(-2px);
}
.res-tile.soon { background: var(--bg-soft); }
.res-tile .res-icon { width: 46px; height: 46px; }
.res-tile .res-icon svg { width: 21px; height: 21px; }
.res-tile .res-body h4 { font-family: var(--serif); font-size: 19px; font-weight: 500; margin-bottom: 7px; }
.res-tile .res-body p  { font-size: 14px; }
/* margin-top:auto pins the tag to the bottom so the tags line up across
   the pair regardless of description length. */
.res-tile .res-tag { margin-top: auto; padding-top: 12px; }
/* The open-in-new-tab arrow sits top-right rather than inline, since a
   column layout has no trailing edge to hang it on. */
.res-tile .res-arrow { position: absolute; top: 22px; right: 22px; }

.res-list { display: flex; flex-direction: column; border-top: 1px solid var(--line); }
.res-row {
  position: relative;
  display: flex; align-items: center; gap: 16px;
  padding: 17px 6px;
  border-bottom: 1px solid var(--line);
  transition: all .2s ease-in-out;
}
.res-row.linked { cursor: pointer; }
.res-row.linked:hover { padding-left: 12px; background: var(--cardinal-soft); }
.res-row.soon { opacity: .72; }
.res-row .res-icon { width: 36px; height: 36px; }
.res-row .res-icon svg { width: 16px; height: 16px; }
.res-row .res-body h4 { font-size: 14px; }
.res-row .res-body p  { font-size: 12.5px; }
.res-row .res-tag { margin-top: 4px; }

.res-icon {
  border-radius: var(--radius);
  background: var(--cardinal-tint); color: var(--cardinal);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.res-icon svg {
  stroke: currentColor; stroke-width: 1.8;
  fill: none; stroke-linecap: round; stroke-linejoin: round;
}
.res-body { flex: 1; min-width: 0; }
.res-body h4 { font-weight: 600; color: var(--ink); margin-bottom: 4px; line-height: 1.3; }
.res-body p  { color: var(--ink-mid); line-height: 1.55; }
.res-tag {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--mono); font-size: 10px;
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-low); font-weight: 500;
  margin-top: 10px;
}
.res-tag.soon { color: var(--cardinal); }
.res-arrow   { align-self: center; flex-shrink: 0; color: var(--ink-low);
               transition: color var(--t-fast), transform var(--t-fast); }
.res-spotlight.linked:hover .res-arrow,
.res-row.linked:hover .res-arrow { color: var(--cardinal); transform: translateX(3px); }

/* ─── SAMPLE REPORT BROWSER ───────────────────────────────────────────────
   Master–detail: report names down the left, the selected report on the
   right (see renderReportBrowser() in app.js). Replaced a tile grid plus a
   full-screen modal, so reading a second report is one click, not a
   close-then-reopen.

   The list is a fixed column and the detail pane takes the rest. `start`
   alignment keeps a short list from stretching to the pane's height. */
.report-browser {
  display: grid;
  grid-template-columns: minmax(200px, 270px) 1fr;
  gap: 18px;
  margin-top: 18px;
  align-items: start;
}

/* No inner scroll here on purpose. A max-height + overflow on this column
   clipped the first and last rows mid-height, which read as a rendering
   bug rather than as a scroll area. Instead the column is sticky: it sits
   at its natural height and stays pinned while a long report is read, so
   switching reports never means scrolling back up.

   Sticky works because .report-browser sets `align-items: start` — that
   keeps this item at content height while its grid area still spans the
   full row, giving the sticky element room to travel. Without it the item
   would stretch to the row height and have nowhere to stick. */
.rb-list {
  display: flex; flex-direction: column; gap: 6px;
  position: sticky;
  top: 88px;            /* 68px fixed nav + breathing room */
}
.rb-item {
  display: flex; align-items: flex-start; gap: 11px;
  width: 100%; text-align: left;
  padding: 12px 13px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-left: 3px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast);
}
.rb-item:hover { background: var(--bg-soft); }
.rb-item.on {
  background: var(--bg-soft);
  border-color: var(--line);
  border-left-color: var(--cardinal);
}
.rb-item-pill {
  font-family: var(--mono); font-size: 10.5px; font-weight: 600; letter-spacing: .04em;
  color: var(--cardinal); background: var(--cardinal-tint);
  padding: 3px 7px; border-radius: 4px;
  flex-shrink: 0;
}
/* min-width:0 so a long tool name wraps instead of widening the column. */
.rb-item-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.rb-item-name { font-size: 13.5px; font-weight: 600; color: var(--ink); line-height: 1.3; }
.rb-item-sub  { font-size: 11.5px; color: var(--ink-mid); line-height: 1.4; }
.rb-item.on .rb-item-name { color: var(--cardinal); }

.rb-detail {
  padding: 26px 28px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
}
.rb-detail:focus-visible { outline: 2px solid var(--cardinal); outline-offset: 2px; }
.rb-detail-head { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 22px; }
.rb-detail-pill {
  font-family: var(--mono); font-size: 11px; font-weight: 600; letter-spacing: .04em;
  color: var(--cardinal); background: var(--cardinal-tint);
  padding: 4px 9px; border-radius: 4px;
  flex-shrink: 0;
}
.rb-detail-name { font-family: var(--serif); font-size: 22px; font-weight: 500; color: var(--ink); line-height: 1.25; }
.rb-detail-sub  { font-size: 13px; color: var(--ink-mid); line-height: 1.5; margin-top: 3px; }

.rb-section { margin-bottom: 22px; }
.rb-section h5 {
  font-family: var(--mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--cardinal); margin-bottom: 8px;
}
.rb-section p  { font-size: 14px; color: var(--ink-mid); line-height: 1.65; }
.rb-section ul { padding-left: 18px; }
.rb-section li { font-size: 14px; color: var(--ink-mid); line-height: 1.6; margin-bottom: 8px; }

/* Download on the left, report stepper on the right. Wraps to two rows on
   a narrow pane rather than crushing either side. */
.rb-actions {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 14px;
  margin-top: 28px; padding-top: 22px;
  border-top: 1px solid var(--line);
}
.rb-actions .btn-cta { display: inline-flex; }

.rb-nav { display: flex; align-items: center; gap: 4px; }
.rb-nav-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 12px;
  font-size: 12.5px; font-weight: 600;
  color: var(--ink-mid);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: all .25s ease-in-out;
}
.rb-nav-btn:hover:not(:disabled) { border-color: var(--cardinal); color: var(--cardinal); }
.rb-nav-btn:disabled { opacity: .38; cursor: default; }
.rb-nav-btn svg { width: 13px; height: 13px; stroke: currentColor; stroke-width: 2; fill: none; }
/* Mirrors the same chevron glyph for the "previous" direction. */
.rb-nav-btn.prev svg { transform: rotate(180deg); }
.rb-nav-count {
  font-family: var(--mono); font-size: 11px; letter-spacing: .06em;
  color: var(--ink-low);
  padding: 0 10px;
  white-space: nowrap;
}
.rb-empty { font-size: 13.5px; color: var(--ink-low); margin-top: 18px; }


/* ═══════════════════════════════════════════════════════════════════════
   §11 · PATIENT PANEL
   ───────────────────────────────────────────────────────────────────────
   Two-column split. Left column = Stanford's implementation (warm tint).
   Right column = "Building a panel at your institution" accordion guide.

   ARCHITECTURAL NOTE — the accordion
     We animate max-height (not height:auto) because height:auto can't be
     transitioned. JS sets the inline max-height value to the measured
     scrollHeight when opening, and 0 when closing.
   ─────────────────────────────────────────────────────────────────────── */
.pp-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
}
.pp-side { padding: 64px 56px; }
/* --bg-warm per the root-variable doc comment ("used on the patient-panel
   Stanford side to differentiate it from the external side") — this had
   drifted to --bg-soft, which is exactly what footer-global's background
   also uses, so the two visually fused together with no seam once you
   scrolled to the bottom of this page. border-bottom adds a hard line on
   top of the color difference so the boundary reads clearly either way. */
.pp-side.stanford { background: var(--bg-warm); border-right: 1px solid var(--line); border-bottom: 1px solid var(--line-strong); }
.pp-side.external { background: var(--bg); border-bottom: 1px solid var(--line-strong); }

.pp-tag {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 11px;
  font-family: var(--mono); font-size: 10px;
  letter-spacing: .16em; font-weight: 600;
  color: var(--cardinal);
  background: var(--cardinal-tint);
  border-radius: 4px;
  text-transform: uppercase;
  margin-bottom: 18px;
}
.pp-side h2 {
  font-family: var(--serif);
  font-size: 30px; font-weight: 500;
  color: var(--ink); line-height: 1.15;
  margin-bottom: 16px;
}
.pp-side > p { font-size: 14.5px; color: var(--ink-mid); line-height: 1.7; margin-bottom: 28px; }

/* Columns follow however many stats PP_STATS holds, so removing one doesn't
   leave an empty cell. */
.pp-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 14px;
  margin-bottom: 32px;
}
.pp-stat {
  padding: 18px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  text-align: center;
}
.pp-stat .n {
  font-family: var(--serif);
  font-size: 32px; font-weight: 500;
  color: var(--cardinal);
  line-height: 1; margin-bottom: 6px;
}
.pp-stat .l { font-size: 11px; color: var(--ink-mid); line-height: 1.4; }

.pp-list { display: flex; flex-direction: column; gap: 14px; margin-bottom: 24px; }
.pp-list-item { display: flex; gap: 14px; align-items: flex-start; }
.pp-list-item .dot {
  width: 22px; height: 22px;
  border-radius: 50%;
  background: var(--cardinal-tint); color: var(--cardinal);
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700;
  flex-shrink: 0; margin-top: 1px;
}
.pp-list-item h4 { font-size: 14px; font-weight: 600; color: var(--ink); margin-bottom: 3px; }
.pp-list-item p  { font-size: 13px; color: var(--ink-mid); line-height: 1.55; }

/* External-side accordion */
.pp-acc { display: flex; flex-direction: column; gap: 10px; }
.pp-acc-item {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.pp-acc-head {
  width: 100%;
  display: flex; align-items: center; gap: 14px;
  padding: 16px 20px;
  text-align: left;
  transition: background var(--t-fast);
}
.pp-acc-head:hover { background: var(--bg-soft); }
.pp-acc-head .idx {
  font-family: var(--mono); font-size: 10px;
  letter-spacing: .12em; font-weight: 600;
  color: var(--cardinal);
  width: 24px; flex-shrink: 0;
}
.pp-acc-head h4 {
  flex: 1;
  font-family: var(--serif);
  font-size: 18px; font-weight: 500;
  color: var(--ink);
}
.pp-acc-head .chev { color: var(--ink-mid); transition: transform var(--t-fast); }
.pp-acc-head .chev svg {
  width: 18px; height: 18px;
  stroke: currentColor; stroke-width: 2; fill: none;
}
.pp-acc-item.open .pp-acc-head .chev { transform: rotate(180deg); }
.pp-acc-body {
  max-height: 0; overflow: hidden;
  transition: max-height var(--t-med) var(--ease);
}
.pp-acc-body-inner {
  padding: 0 20px 20px 60px;
  font-size: 13.5px;
  color: var(--ink-mid);
  line-height: 1.7;
}


/* ═══════════════════════════════════════════════════════════════════════
   §12 · TOOLKIT PAGE — Playbook tab
   ───────────────────────────────────────────────────────────────────────
   Accordion modeled structurally on .pp-acc above, but on .about-bullet's
   flatter, hairline-only visual language (no card background, no colored
   icon badge) — institutional documentation, not a feature-card grid.
   ─────────────────────────────────────────────────────────────────────── */
/* No margin-bottom: this used to separate the accordion from the
   "Considerations when evaluating" callout, which has been removed. The
   accordion is the panel's last child now, so .tk-panel's own bottom
   padding is the spacing. */
.pb-acc { display: flex; flex-direction: column; border-top: 1px solid var(--line); }
.pb-acc-item { border-bottom: 1px solid var(--line); }
.pb-acc-head {
  width: 100%; display: flex; align-items: flex-start; gap: 18px;
  padding: 26px 4px; text-align: left;
  transition: background var(--t-fast);
}
.pb-acc-head:hover { background: var(--bg-soft); }
.pb-acc-head .idx {
  font-family: var(--mono); font-size: 11px; font-weight: 600;
  letter-spacing: .1em; color: var(--cardinal);
  width: 28px; flex-shrink: 0; padding-top: 4px;
}
.pb-acc-headtext { flex: 1; }
.pb-acc-headtext h4 { font-family: var(--serif); font-size: 22px; font-weight: 500; color: var(--ink); margin-bottom: 6px; }
.pb-acc-headtext p  { font-size: 14px; color: var(--ink-mid); line-height: 1.6; max-width: 620px; }
.pb-acc-head .chev { color: var(--ink-mid); flex-shrink: 0; margin-top: 8px; transition: transform var(--t-fast); }
.pb-acc-head .chev svg { width: 18px; height: 18px; stroke: currentColor; stroke-width: 2; fill: none; }
.pb-acc-item.open .pb-acc-head .chev { transform: rotate(180deg); }
.pb-acc-body { max-height: 0; overflow: hidden; transition: max-height var(--t-med) var(--ease); }
.pb-acc-body-inner { padding: 0 4px 32px 46px; display: flex; flex-direction: column; }
.pb-acc-subitem { padding: 16px 0; border-top: 1px solid var(--line); }
.pb-acc-subitem:first-child { border-top: none; padding-top: 0; }
.pb-acc-subitem h5 { font-size: 14.5px; font-weight: 600; color: var(--ink); margin-bottom: 4px; }
.pb-acc-subitem p  { font-size: 13.5px; color: var(--ink-mid); line-height: 1.65; }



/* ═══════════════════════════════════════════════════════════════════════
   §13 · ABOUT
   ─────────────────────────────────────────────────────────────────────── */
/* auto-fit rather than a fixed 1fr 1fr — ABOUT_CARDS (data.js) can be down
   to a single card, and this keeps that card full-width instead of
   leaving a dead second column, same pattern as .team-grid. */
.two-col { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 18px; margin-bottom: 44px; }
.white-card {
  padding: 28px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
}
.white-card h3 {
  font-family: var(--serif);
  font-size: 22px; font-weight: 500;
  color: var(--ink);
  margin-bottom: 12px;
}
.white-card p { font-size: 13.5px; color: var(--ink-mid); line-height: 1.75; }

/*
   TEAM GRID — YC-style photo cards.
   Each card is a 4:5 photo with a bottom gradient and overlaid text
   (name, badge · affiliation, role). Hover: subtle lift + photo zoom.
   3 cols desktop, 2 cols tablet, 1 col mobile (handled by auto-fit).
*/
/* Team section flows directly under the About cards. Kill the top
   padding on the team section AND the bottom padding on the preceding
   section so the two clusters read as one continuous block with just
   a small breathing gap driven by .team-h2 margin. */
.section-team { padding-top: 0; }
#page-about .section:has(+ .section-team) { padding-bottom: 24px; }
/* That first section now holds just the single "What we believe" card
   (since "How we got here" was removed) — the default 96px top padding,
   stacked on .page-header's own 56px bottom padding, left an oversized
   gap under the H1 for how little content follows it. */
#page-about .section:first-of-type { padding-top: 48px; }
.section-team .eyebrow,
.section-partners .eyebrow {
  font-size: 13px;
}
.team-h2 {
  margin-top: 6px;
  margin-bottom: 32px;
  max-width: 680px;
}
.team-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
  margin-top: 8px;
  align-items: start;
}
.team-card {
  position: relative;
  aspect-ratio: 4 / 5;
  border-radius: 14px;
  overflow: hidden;
  background: #111;
  isolation: isolate;
  cursor: pointer;
  transition: transform .35s cubic-bezier(.2,.8,.2,1),
              box-shadow .35s cubic-bezier(.2,.8,.2,1);
}
.team-card:hover {
  transform: translateY(-4px);
  box-shadow:
    0 24px 40px -18px rgba(0, 0, 0, .28),
    0 8px 16px -10px rgba(140, 21, 21, .18);
}
.tc-media {
  position: absolute; inset: 0;
  z-index: 0;
}
.tc-media img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center 22%;
  transition: transform .6s cubic-bezier(.2,.8,.2,1);
}
.team-card:hover .tc-media img { transform: scale(1.04); }
.tc-fallback {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--serif);
  font-size: 92px;
  color: rgba(255, 255, 255, .35);
  background: linear-gradient(160deg, #2a0e0e, #0d0d0d 70%);
}
/* Gradient scrim from transparent → dark for text legibility */
.tc-overlay {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 1;
  padding: 22px 22px 20px;
  color: #fff;
  background: linear-gradient(
    180deg,
    rgba(0, 0, 0, 0) 0%,
    rgba(0, 0, 0, .55) 55%,
    rgba(0, 0, 0, .82) 100%
  );
}
.tc-name-wrap {
  margin: 0 0 6px;
  line-height: 1.15;
}
.tc-name {
  font-size: 22px;
  font-weight: 600;
  color: #fff;
  letter-spacing: -.01em;
  line-height: 1.15;
}
/* Link variant — inherits card typography, subtle underline slide-in on hover. */
.tc-name-link {
  text-decoration: none;
  color: #fff;
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  padding-bottom: 2px;
  background-image: linear-gradient(#fff, #fff);
  background-repeat: no-repeat;
  background-size: 0% 1.5px;
  background-position: 0 100%;
  transition: background-size .3s cubic-bezier(.2,.8,.2,1);
  position: relative;
  z-index: 2;   /* sits above the gradient scrim so clicks land on the link */
}
.tc-name-link:hover,
.tc-name-link:focus-visible {
  background-size: 100% 1.5px;
}
.tc-name-link:focus-visible {
  outline: 2px solid rgba(255, 255, 255, .8);
  outline-offset: 4px;
  border-radius: 2px;
}
.tc-name-arrow {
  font-size: 15px;
  opacity: .65;
  transition: transform .3s cubic-bezier(.2,.8,.2,1), opacity .2s ease;
  display: inline-block;
}
.tc-name-link:hover .tc-name-arrow {
  transform: translate(2px, -2px);
  opacity: 1;
}
.tc-sub {
  font-size: 13px;
  color: rgba(255, 255, 255, .78);
  margin: 0 0 10px;
  font-weight: 500;
  letter-spacing: -.005em;
}
.tc-role {
  font-size: 14px;
  color: rgba(255, 255, 255, .82);
  line-height: 1.5;
  margin: 0;
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height .4s cubic-bezier(.2,.8,.2,1),
              opacity .3s ease-out .05s,
              margin-top .3s ease-out;
}
.team-card:hover .tc-role,
.team-card:focus-within .tc-role {
  max-height: 120px;
  opacity: 1;
  margin-top: 2px;
}
@media (max-width: 640px) {
  /* On mobile, always reveal the role — no hover on touch. */
  .tc-role { max-height: 120px; opacity: 1; }
  .team-grid { gap: 20px; }
}

/* ─────────────────────────────────────────────────────────────────────────
   PARTNER LOGO MARQUEE — About page, below the team grid
─────────────────────────────────────────────────────────────────────────────
   Two identical copies of the track sit side by side (renderPartnerLogos()
   duplicates the array); @keyframes partner-scroll moves the whole thing
   left by exactly -50%, i.e. one copy's width, so the loop point is
   invisible — the track just keeps going. Grayscale-by-default + full
   color on hover is the standard "logo wall" treatment; it only reads
   clean because every source file is genuinely transparent (verified when
   these were added — see the PARTNER_LOGOS comment in data.js).
───────────────────────────────────────────────────────────────────────── */
.section-partners { padding-top: 8px; }
.partner-marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
}
.partner-track {
  display: flex;
  align-items: center;
  gap: 88px;
  width: max-content;
  animation: partner-scroll 36s linear infinite;
  will-change: transform;
  backface-visibility: hidden;
}
/* Site-wide Pause Media toggle (initPauseMediaControl in app.js) — the
   universal prefers-reduced-motion override in §16 already zeroes out
   animation-duration for OS-level motion sensitivity; this covers the
   manual, in-page toggle on top of that. */
body.motion-paused .partner-track { animation-play-state: paused; }
@keyframes partner-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
.partner-logo {
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  height: 84px;
}
.partner-logo img {
  max-height: 100%; max-width: 220px; width: auto;
  object-fit: contain;
  filter: grayscale(1);
  opacity: .5;
  transition: filter var(--t-fast), opacity var(--t-fast);
}
.partner-logo:hover img { filter: grayscale(0); opacity: 1; }
@media (max-width: 640px) {
  .partner-track { gap: 56px; }
  .partner-logo  { height: 60px; }
}


/* ═══════════════════════════════════════════════════════════════════════
   §13.5 · NEWS
   ───────────────────────────────────────────────────────────────────────
   Landing page = spotlight card + 3 chronological feeds (.news-block),
   each capped at 5 items with a "View complete directory" link. The
   directory pages reuse the same .news-item row for their full,
   search-filtered listings — see renderNewsDirectory() in app.js.
   ─────────────────────────────────────────────────────────────────────── */
.news-spotlight {
  padding: 40px 44px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-left: 4px solid var(--cardinal);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2);
}
.news-spotlight-tag {
  display: inline-block;
  font-family: var(--mono); font-size: 10px;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--cardinal); font-weight: 600;
  margin-bottom: 14px;
}
.news-spotlight-title {
  font-family: var(--serif);
  font-size: clamp(24px, 3vw, 34px);
  font-weight: 500; line-height: 1.22;
  color: var(--ink);
  max-width: 820px;
  margin-bottom: 10px;
}
.news-spotlight-meta { font-size: 13.5px; color: var(--ink-mid); font-weight: 500; margin-bottom: 14px; }
.news-spotlight-desc { font-size: 15px; color: var(--ink-mid); line-height: 1.65; max-width: 720px; margin-bottom: 24px; }

/* Divider between the 3 feed blocks — first one flush against the spotlight's section. */
.news-block + .news-block { border-top: 1px solid var(--line); padding-top: 56px; }
.news-block-head {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 12px;
}
.news-block-head .eyebrow { margin-bottom: 0; }
.news-viewall {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 600;
  color: var(--cardinal);
  background: none; border: none; cursor: pointer;
  padding: 6px 2px;
}
.news-viewall span { display: inline-block; transition: transform var(--t-fast); }
.news-viewall:hover span { transform: translateX(3px); }

.news-back {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--mono); font-size: 12px; letter-spacing: .04em;
  color: var(--ink-mid);
  background: none; border: none; cursor: pointer;
  margin-bottom: 22px;
  transition: color var(--t-fast);
}
.news-back:hover { color: var(--cardinal); }

.news-list { display: flex; flex-direction: column; gap: 26px; margin-top: 26px; }
.news-item { display: flex; gap: 26px; padding-bottom: 26px; border-bottom: 1px solid var(--line); }
.news-item:last-child { border-bottom: none; padding-bottom: 0; }
.news-item-date {
  flex-shrink: 0; width: 96px;
  font-family: var(--mono); font-size: 12px; color: var(--ink-low);
  padding-top: 4px;
}
.news-item-body { flex: 1; min-width: 0; }
.news-item-tag {
  display: inline-block;
  font-family: var(--mono); font-size: 10px;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--cardinal); font-weight: 600;
  background: var(--cardinal-tint);
  padding: 3px 8px; border-radius: 4px;
  margin-bottom: 8px;
}
.news-item-title { font-family: var(--serif); font-size: 18px; font-weight: 500; line-height: 1.32; margin-bottom: 5px; }
.news-item-title a {
  color: var(--ink);
  display: inline-flex; align-items: baseline; gap: 6px;
  transition: color var(--t-fast);
}
.news-item-title a:hover { color: var(--cardinal); }
.news-item-arrow { font-size: 13px; opacity: .55; }
.news-item-sub  { font-size: 13px; font-weight: 500; color: var(--ink-mid); margin-bottom: 6px; }
.news-item-desc { font-size: 13.5px; color: var(--ink-mid); line-height: 1.6; max-width: 680px; }
.news-empty { font-size: 14px; color: var(--ink-mid); padding: 8px 0 24px; }

/* Directory-page search — visually matches the footer's site search (.fg-search). */
.news-dir-search { position: relative; max-width: 420px; margin-bottom: 8px; }
.news-dir-search-icon {
  position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
  width: 16px; height: 16px; color: var(--ink-low); pointer-events: none;
}
.news-dir-search input {
  width: 100%;
  padding: 12px 16px 12px 42px;
  font-size: 14px; color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  transition: border-color var(--t-fast);
}
.news-dir-search input:focus { border-color: var(--cardinal); outline: none; }

@media (max-width: 640px) {
  .news-spotlight { padding: 28px 24px; }
  .news-block + .news-block { padding-top: 40px; }
  .news-item { flex-direction: column; gap: 6px; }
  .news-item-date { width: auto; }
}


/* ═══════════════════════════════════════════════════════════════════════
   §14 · FOOTER
   ─────────────────────────────────────────────────────────────────────── */
footer {
  background: var(--ink);
  color: rgba(255, 255, 255, .7);
  /* clamp() gutters keep the footer comfortable on every viewport */
  padding: 64px clamp(24px, 5vw, 80px) 36px;
}
.foot-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: 48px;
  max-width: 1320px;
  margin: 0 auto 36px;
}
.foot-brand .logo-mark { margin-bottom: 14px; }
.foot-brand p          { font-size: 13.5px; line-height: 1.7; max-width: 340px; }
.foot-col h5 {
  font-family: var(--mono); font-size: 11px;
  letter-spacing: .16em; text-transform: uppercase;
  color: #fff; font-weight: 600;
  margin-bottom: 14px;
}
.foot-col a {
  display: block;
  font-size: 13px;
  color: rgba(255, 255, 255, .7);
  margin-bottom: 9px;
  transition: color var(--t-fast);
}
.foot-col a:hover { color: #fff; }

.foot-bottom {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 14px;
  max-width: 1320px;
  margin: 0 auto;
  padding-top: 24px;
  border-top: 1px solid rgba(255, 255, 255, .08);
  font-size: 12px;
  color: rgba(255, 255, 255, .5);
}
/* Dark-theme sibling of .fg-pause (footer-global uses a light background;
   footer-home is dark, so this needs its own contrast-appropriate styling
   rather than sharing the class). Same shared #motion-paused state either
   way — see initPauseMediaControl() in app.js. */
.foot-pause {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px;
  font-size: 12px; font-weight: 500; color: rgba(255, 255, 255, .7);
  background: transparent;
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: 999px;
  white-space: nowrap;
  transition: all var(--t-fast);
}
.foot-pause:hover { border-color: var(--cardinal-light); color: #fff; }
.foot-pause-icon  { font-size: 9px; letter-spacing: -1px; }
.foot-pause[aria-pressed="true"] .foot-pause-icon::before { content: '\25B6'; letter-spacing: 0; }

.hidden-footer { display: none; }

/* ─────────────────────────────────────────────────────────────────────────
   FOOTER-GLOBAL · every page but Home
─────────────────────────────────────────────────────────────────────────────
   Two zones, matching the reference: a light "tools" zone (brand + search +
   Pause Media + our own nav links) and a dark Stanford-system bottom bar
   (required legal links, unchanged in spirit from what Stanford's global
   footer looks like elsewhere on *.stanford.edu).
───────────────────────────────────────────────────────────────────────── */
#footer-global { padding: 0; background: var(--bg-soft); color: var(--ink); }

.fg-top {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 32px; flex-wrap: wrap;
  max-width: 1320px; margin: 0 auto;
  padding: 56px clamp(24px, 5vw, 80px) 40px;
}
.fg-brand { display: flex; align-items: center; }
/* SVG is a 540×200 wordmark (2.7:1) — height-constrained + object-fit so it
   scales proportionally instead of being squeezed into a square box. */
.fg-logo  { height: 56px; width: auto; max-width: 320px; object-fit: contain; flex-shrink: 0; }

.fg-tools { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

.fg-search { position: relative; width: 260px; }
.fg-search-icon {
  position: absolute; left: 13px; top: 50%; transform: translateY(-50%);
  width: 15px; height: 15px; color: var(--ink-low); pointer-events: none;
}
.fg-search input {
  width: 100%;
  padding: 11px 14px 11px 36px;
  font-size: 13.5px;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  transition: border-color var(--t-fast);
}
.fg-search input:focus { border-color: var(--cardinal); outline: none; }
.fg-search-results {
  position: absolute; top: calc(100% + 8px); left: 0; right: 0;
  max-height: 360px; overflow-y: auto;
  background: var(--bg);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-3);
  z-index: 20;
}
.fg-result {
  display: block; width: 100%; text-align: left;
  padding: 11px 14px;
  border-bottom: 1px solid var(--line);
  cursor: pointer;
}
.fg-result:last-child { border-bottom: none; }
.fg-result:hover, .fg-result.active { background: var(--cardinal-soft); }
.fg-result-title { font-size: 13px; font-weight: 600; color: var(--ink); }
.fg-result-meta  { font-size: 11px; color: var(--cardinal); font-family: var(--mono); text-transform: uppercase; letter-spacing: .04em; margin-left: 6px; }
.fg-result-sub   { font-size: 12px; color: var(--ink-mid); margin-top: 2px; line-height: 1.4; }
.fg-result-empty { padding: 14px; font-size: 13px; color: var(--ink-mid); }

.fg-pause {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 16px;
  font-size: 13px; font-weight: 500; color: var(--ink-mid);
  background: var(--bg);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  white-space: nowrap;
  transition: all var(--t-fast);
}
.fg-pause:hover { border-color: var(--cardinal); color: var(--cardinal); }
.fg-pause-icon  { font-size: 10px; letter-spacing: -1px; }
.fg-pause[aria-pressed="true"] .fg-pause-icon::before { content: '\25B6'; letter-spacing: 0; }

.fg-nav {
  display: flex; gap: 64px;
  max-width: 1320px; margin: 0 auto;
  padding: 0 clamp(24px, 5vw, 80px) 40px;
  border-top: 1px solid var(--line);
  padding-top: 32px;
}
.fg-nav-col h5 {
  font-family: var(--mono); font-size: 11px;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-low); font-weight: 600;
  margin-bottom: 14px;
}
.fg-nav-col a {
  display: block;
  font-size: 13.5px; color: var(--ink-mid);
  margin-bottom: 9px;
  transition: color var(--t-fast);
}
.fg-nav-col a:hover { color: var(--cardinal); }

.fg-bottom {
  display: flex; align-items: center; gap: 28px; flex-wrap: wrap;
  padding: 24px clamp(24px, 5vw, 80px);
  background: var(--ink);
}
.fg-su-logo { flex-shrink: 0; display: flex; }
.fg-su-logo img { height: 34px; width: auto; }
.fg-legal { display: flex; gap: 16px 22px; flex-wrap: wrap; flex: 1; }
.fg-legal a { font-size: 12px; color: rgba(255, 255, 255, .65); transition: color var(--t-fast); }
.fg-legal a:hover { color: #fff; }
.fg-copyright { font-size: 11.5px; color: rgba(255, 255, 255, .45); width: 100%; }


/* ═══════════════════════════════════════════════════════════════════════
   §15 · RESPONSIVE BREAKPOINTS
   ───────────────────────────────────────────────────────────────────────
   We use a "mobile-first reaction" approach — base styles are tuned for
   desktop, and these queries collapse things gracefully as the viewport
   shrinks. Three breakpoints intentionally:

     • 1100px ── "Tablet / small laptop"
                Switches dense multi-column grids (videos, flow, process)
                down to 2 columns; signup card stacks; team grid halves.

     • 900px  ── "Phone landscape / small tablet portrait"
                Activates the hamburger menu (hides .nav-center and the
                desktop sign-up button), drops every grid to a single
                column, removes the hero's right-corner ornaments,
                reduces section padding.

     • 560px  ── "Compact phone portrait"
                Final tightening — team grid halves down to 2 columns
                (not 1, to preserve density), patient panel stats stack.

   ARCHITECTURAL NOTE — why pixel breakpoints not container queries
     The site is content-driven and we want predictable behavior across
     all browsers (CQ support is recent). Once we have analytics on
     real viewport sizes we can revisit.
   ─────────────────────────────────────────────────────────────────────── */

/* ─── BREAKPOINT · ≤1100px (Tablet) ──────────────────────────────────── */
@media (max-width: 1100px) {
  .videos-grid       { grid-template-columns: repeat(2, 1fr); }
  .flow-grid         { grid-template-columns: repeat(2, 1fr); }
  /* Restore right border on flow cards now that they wrap into a 2-col grid */
  .flow-step         { border-right: 1px solid var(--line) !important; }
  .flow-arrow        { display: none; }
  .process-steps     { grid-template-columns: repeat(2, 1fr); }
  .proc-step         { border-right: 1px solid var(--line); }
  .signup-card       { grid-template-columns: 1fr; padding: 44px 32px; }
  .signup-side       { align-items: flex-start; }
  /* The report browser drops to one column at 900px, below. .team-grid is
     NOT overridden here because it uses `auto-fit minmax(...)` and
     self-collapses — a manual override would fight that. */
  .report-browser    { grid-template-columns: minmax(180px, 240px) 1fr; }
}

/* ─── BREAKPOINT · ≤900px (Phone / mobile activation) ─────────────────── */
@media (max-width: 900px) {
  /* Side-by-side stops working once the detail pane is narrower than its
     own text; list on top, report below. max-height caps the list so the
     content it controls stays visible without a long scroll past it. */
  /* Stacked, so the list is no longer a sidebar and must not be sticky —
     pinning it would cover the report the reader just chose. */
  .report-browser    { grid-template-columns: 1fr; }
  .rb-list           { position: static; top: auto; }
  .rb-detail         { padding: 22px 20px; }
  .rb-actions        { justify-content: flex-start; }
  nav.topnav         { padding: 0 18px; }
  .nav-center        { display: none; }
  .nav-toggle        { display: flex; }
  .nav-right .btn-cta{ display: none; }     /* sign-up moves to mobile menu */

  .section,
  .page-header       { padding-left: 24px; padding-right: 24px; }
  .section           { padding-top: 64px; padding-bottom: 64px; }
  .page-header       { padding-top: 108px; }

  .hero-content      { padding: 0 24px 80px; }
  .hero-intro        { padding: 0 24px 80px; }
  .hero-intro-tagline{ letter-spacing: .14em; }
  .hero h1           { font-size: clamp(36px, 8vw, 52px); }

  .stats-row         { grid-template-columns: 1fr; }
  .stat              { border-right: none; border-bottom: 1px solid var(--line); padding: 36px 24px; }
  .stat:last-child   { border-bottom: none; }

  .about-block,
  .rt-intro          { grid-template-columns: 1fr; gap: 32px; }

  .tk-tab            { padding: 14px 4px; margin-right: 18px; font-size: 11px; }
  .pb-acc-body-inner { padding-left: 4px; }

  .videos-grid       { grid-template-columns: 1fr; }

  .pp-split          { grid-template-columns: 1fr; }
  .pp-side           { padding: 48px 24px; }
  .pp-side.stanford  { border-right: none; border-bottom: 1px solid var(--line); }

  .two-col           { grid-template-columns: 1fr; }
  /* .team-grid auto-fits — no override needed here */

  /* Hero ornament selectors removed (badge + meta were deleted in cleanup) */
  .scroll-cue        { right: 24px; }

  .foot-grid         { grid-template-columns: 1fr 1fr; gap: 32px; }
  footer             { padding: 48px 24px 28px; }
  #footer-global     { padding: 0; }
  .fg-top            { padding: 40px 24px 28px; flex-direction: column; align-items: stretch; }
  .fg-tools          { flex-direction: column; align-items: stretch; }
  .fg-search         { width: 100%; }
  .fg-nav            { gap: 32px; padding: 0 24px 32px; padding-top: 28px; }
  .fg-bottom         { padding: 20px 24px; }

  .pp-stats          { gap: 8px; }
  .pp-stat           { padding: 12px; }
  .pp-stat .n        { font-size: 24px; }
}

/* ─── BREAKPOINT · ≤560px (Compact phones) ───────────────────────────── */
@media (max-width: 560px) {
  /* .team-grid auto-fits — no override needed */
  .pp-stats          { grid-template-columns: 1fr; }
  .foot-grid         { grid-template-columns: 1fr; }

  /* Narrower phones still wrap the intro tagline to two lines even at
     the .14em letter-spacing set at 900px — tighten further here. */
  .hero-intro-tagline{ font-size: 11px; letter-spacing: .08em; }
}


/* ═══════════════════════════════════════════════════════════════════════
   §16 · ACCESSIBILITY & MOTION PREFERENCES
   ───────────────────────────────────────────────────────────────────────
   • :focus-visible — visible ring for keyboard users, hidden for mouse.
   • prefers-reduced-motion — disable all transitions/animations.
   ─────────────────────────────────────────────────────────────────────── */
/*
   FOCUS RING — visible to keyboard users only (mouse/touch never see it).
   Uses Stanford Cardinal at high contrast against any background on the
   site (white panels, cardinal CTAs, charcoal footer). The white
   "halo" via box-shadow ensures the ring stays visible even when the
   focused element sits on a cardinal background.
*/
:focus-visible {
  outline: 2.5px solid var(--cardinal);
  outline-offset: 3px;
  border-radius: 4px;
  box-shadow: 0 0 0 4px rgba(255, 255, 255, .85);
}
/* On dark/cardinal surfaces, invert the halo so the ring remains visible */
.signup-card :focus-visible,
footer :focus-visible {
  outline-color: #fff;
  box-shadow: 0 0 0 4px rgba(140, 21, 21, .55);
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
    animation-iteration-count: 1 !important;
  }
  html { scroll-behavior: auto; }
}


/* ═══════════════════════════════════════════════════════════════════════
   §17 · PRINT
   ───────────────────────────────────────────────────────────────────────
   WHY this exists: every "page" is `position: fixed; inset: 0` (see .page
   above) so the JS router can instantly swap between tabs — great on
   screen, but browsers' print/PDF engines generally only paginate content
   that's in normal document flow. Combined with the hero's full-viewport
   canvas background and a scroll-spacer element whose HEIGHT IS SET
   INLINE BY JS (initHeroScrollIntro() in app.js, to `calc(100vh + 560px)`
   — hundreds of pixels taller than any content), printing without this
   section produces exactly the blank-page symptom this fixes.

   APPROACH: print exactly what's currently on screen (the active .page,
   whichever Toolkit/Resources tab is open, etc.) — not a dump of every
   tab's content — but force it into normal flow so the browser can
   actually paginate it, and strip UI that means nothing on paper (nav,
   canvases, buttons, modals, search).
   ─────────────────────────────────────────────────────────────────────── */
@media print {
  /* Chrome that only makes sense on a screen with a mouse/scroll */
  #loader,
  nav.topnav,
  .mobile-menu,
  .scroll-cue,
  .hero-intro,
  #human-canvas,
  #hero-canvas,
  #video-modal,
  #report-modal,
  .fg-search,
  .fg-pause,
  .foot-pause,
  .btn-cta,
  .btn-prime,
  .btn-second {
    display: none !important;
  }

  html, body { overflow: visible !important; height: auto !important; }

  /* Only the active page prints, in normal flow instead of a fixed
     full-viewport overlay — this alone fixes most of the blank-page
     symptom, since .page's default position:fixed is what the print
     engine was failing to paginate. */
  .page:not(.active) { display: none !important; }
  .page {
    position: static !important;
    inset: auto !important;
    opacity: 1 !important;
    visibility: visible !important;
    overflow: visible !important;
    height: auto !important;
  }

  /* Hero: skip the scroll-linked intro entirely and print the settled
     compact hero directly — --hero-in:1 forces .hero-content (normally
     opacity:0 until scrolled) fully visible. .hero-scroll-track's height
     is set INLINE by JS to comfortably more than 100vh purely so
     position:sticky has room to animate on screen; that's meaningless
     once .hero itself is static, and left alone would print several
     blank pages before the real content. */
  .hero-scroll-track { height: auto !important; }
  .hero {
    position: static !important;
    height: auto !important;
    min-height: 0 !important;
    --hero-progress: 1;
    --hero-out: 1;
    --hero-in: 1;
  }
  .hero-content {
    opacity: 1 !important;
    transform: none !important;
    pointer-events: auto !important;
  }

  /* Don't split a card/row across a page break where avoidable */
  .proc-step, .pb-acc-item, .about-bullet, .stat, .pp-acc-item,
  .rt-subgroup, .res-row, .res-spotlight, .rb-item, .rb-detail {
    break-inside: avoid-page;
    page-break-inside: avoid;   /* fallback for engines without break-inside support */
  }

  a { color: var(--ink) !important; text-decoration: underline; }
}


