/* Webfonts the token set assumes (--fb / --fl). Imported here so every report
   that links meter.css gets the intended typeface without a per-report <link>.
   @import must stay at the very top of the file (before any other rule). */
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap');

/* ============================================================================
   METER — Runnable report design system
   Analyst report, not a dashboard. All color via var(--token); zero raw hex
   in report markup. Tokens defined here on the theme wrapper.
   ========================================================================= */

.meter {
  /* ---- core palette ---- */
  --bg:   #ffffff;
  --sf:   #ffffff;
  --sf2:  #f1efe8;
  --ink:  #1a1b1e;
  --mut:  #5e6066;
  --ln:   #e2ded4;
  --ac:   #1e2a52;   /* brand accent — identity / selection / match anchors ONLY */
  --aci:  #ffffff;
  --acs:  #e8ebf3;
  --dt:   #566879;   /* data intensity scale */
  --dt2:  #8998a6;
  --dt3:  #c9d0d7;
  --c1:   #566879;
  --c2:   #8998a6;
  --c3:   #c9d0d7;
  --c4:   #9f7a38;
  --c5:   #1e2a52;
  --gd:   #2f8f5b;  --gds: #e6f3ec;
  --wn:   #b6791f;  --wns: #f7eedd;
  --bd:   #c0392b;  --bds: #f7e4e1;
  /* ---- verdict sentiment scale — FIXED, independent of --ac so the brand accent
     can be recoloured per customer without breaking strong/caution/weak. Defaults
     to navy today; strong reuses no brand token. Caution/weak alias warn/bad. ---- */
  --vs:   #1e2a52;  --vss: #eef0f6;   /* strong / neutral */
  --vc:   #b6791f;  --vcs: #f7eedd;   /* caution (= warn) */
  --vw:   #c0392b;  --vws: #f7e4e1;   /* weak    (= bad)  */
  /* ---- geometry & type ---- */
  --r:  16px;
  --rs: 10px;
  --bw: 1px;
  --sh:  0 1px 2px rgba(26,27,30,.05);
  --shl: 0 6px 16px rgba(26,27,30,.06);
  --fb: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --fl: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
  /* ---- spacing scale (B4) — one 4px-based rhythm for gaps & rhythm-defining space.
     Used for the common gap values; large section paddings stay deliberate literals. */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 24px;
  --s6: 32px;
  /* ---- type scale (B5) — the readable body tier, collapsed to four steps (no more
     13/13.5/14/14.5/15/15.5 drift). Mono-meta sizes (10.5/12) stay literal by role;
     display/headline sizes are per-component (19–60px) and intentionally not tokenized. */
  --t-sm:   13px;   /* small body · dense captions */
  --t-body: 14px;   /* default body · table text */
  --t-md:   15px;   /* emphasized body · leads */
  --t-lg:   16px;   /* large body */

  background: var(--bg);
  color: var(--ink);
  font-family: var(--fb);
  font-size: var(--t-lg);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

* { box-sizing: border-box; }
body { margin: 0; }

/* Keyboard a11y — visible focus for the interactive surfaces (folds, tie-back links) */
.meter a:focus-visible,
.meter summary:focus-visible,
.meter button:focus-visible {
  outline: 2px solid var(--ac);
  outline-offset: 2px;
  border-radius: 4px;
}

.wrap {
  max-width: 960px;   /* optimal content width for the analyst-document format; body prose is separately capped at ~74ch */
  margin: 0 auto;
  padding: 28px 28px 72px;
}

/* ---- masthead strip ---- */
.masthead {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--s4); flex-wrap: wrap;
  font-family: var(--fl);
  font-size: 12px; letter-spacing: 0.06em;
  color: var(--mut);
  margin-bottom: 14px;
}
.masthead .answers {
  color: var(--ac);
  font-weight: 600;
  text-transform: uppercase;
}
.masthead .answers b { font-weight: 600; }

/* ============================================================================
   THE SHEET — one continuous bordered article, hairline dividers, no gaps
   ========================================================================= */
.sheet {
  background: var(--sf);
  border: 1.5px solid var(--ink);
  border-radius: var(--r);
  box-shadow: var(--shl);
  overflow: hidden;
}
.sheet > section { padding: 30px 36px; border-top: 1px solid var(--ln); }
.sheet > section:first-child { border-top: none; }

.eyebrow {
  font-family: var(--fl);
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--mut); margin: 0 0 14px;
}

/* ============================================================================
   MODULE CONTRACT HELPERS — stable wrappers for generated reports
   ========================================================================= */
.module { position: relative; }
.module-head {
  display: grid;
  gap: 6px;
  margin-bottom: 16px;
}
.module-title {
  font-size: 20px;
  line-height: 1.25;
  letter-spacing: -0.01em;
  font-weight: 650;
  margin: 0;
}
.module-deck {
  font-size: var(--t-body);
  line-height: 1.5;
  color: var(--mut);
  margin: 0;
  max-width: 74ch;
}
.module-scroll {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  /* C8 — horizontal-scroll affordance: a soft shadow appears at whichever edge
     still has hidden content and auto-hides at the ends. The white "cover"
     gradients ride with the content (background-attachment: local); the shadow
     gradients are fixed to the box (scroll), so they only show while scrollable. */
  background:
    linear-gradient(to right, var(--sf) 30%, transparent) left center,
    linear-gradient(to left,  var(--sf) 30%, transparent) right center,
    radial-gradient(farthest-side at 0 50%,   rgba(26,27,30,.10), transparent) left center,
    radial-gradient(farthest-side at 100% 50%, rgba(26,27,30,.10), transparent) right center;
  background-repeat: no-repeat;
  background-size: 36px 100%, 36px 100%, 12px 100%, 12px 100%;
  background-attachment: local, local, scroll, scroll;
}
.module-scroll > .tbl,
.module-scroll > .heat { min-width: 680px; }
.module-note {
  font-family: var(--fl); font-size: 11.5px; color: var(--mut);
  margin-top: 12px;
  line-height: 1.5;
  max-width: 84ch;
}

/* ============================================================================
   EVIDENCE / PROVENANCE  (which tool retrieved each fact — quiet, glyph-led)
   A tool is provenance, not data: mono, muted, never an accent/fill/logo. The
   retrieval METHOD is a monochrome glyph; the specific tool name follows in mono.
   Inference is the one method flagged visually distinct (italic + faded glyph)
   so a guessed fact never looks like a crawled one. Survives grayscale + print.
   ========================================================================= */
.tool-tag {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--fl); font-size: 11px; letter-spacing: 0.04em;
  color: var(--mut); white-space: nowrap;
}
.tool-tag::before {
  content: attr(data-glyph);
  font-size: 11px; line-height: 1; color: var(--mut);
}
.tool-tag.inferred { color: var(--mut); font-style: italic; }
.tool-tag.inferred::before { opacity: 0.7; }
.tool-tag b { color: var(--ink); font-weight: 500; }   /* the tool name carries the meaning */

/* ============================================================================
   HERO
   ========================================================================= */
.hero { padding: 36px 36px 32px; position: relative; }
.hero::after { content: ""; display: block; clear: both; }   /* contain the floated verdict capsule */
/* Magazine layout (§6): the verdict capsule is a top-right inset; company, byline, and
   the headline/body flow on the left — wrapping beside the capsule and reclaiming full
   width once below it. No grid, so a tall capsule never opens a void beside the left
   rail. The capsule MUST be the first child of .hero so the float anchors top-right. */
.hero > .verdict,
.hero > .score-zone,
.hero > .rank-zone,
.hero > .match-zone,
.hero > .tier-zone,
.hero > .asset-zone { float: right; width: 208px; margin: 0 0 18px 28px; }
.hero .company { margin: 0 0 12px; }
.hero .expert-byline { margin: 0 0 18px; }
.hero-body { margin-top: 4px; }
/* the hero visual summary always drops below the capsule (never wraps half-width beside
   it on a short-headline report) */
.hero .moats { clear: right; }
.hero .company {
  font-family: var(--fl); font-size: 12px; letter-spacing: 0.04em;
  color: var(--mut); margin: 0 0 12px;
}
/* Expert byline — avatar + "Assessed by X's Runnable" + profession · method.
   The face/name behind the Runnable, near the top of the hero. */
.expert-byline { display: flex; align-items: center; gap: 11px; margin: 0 0 18px; }
.expert-avatar {
  flex: none; width: 34px; height: 34px; border-radius: 999px;
  background: var(--ac); color: var(--aci);
  font-family: var(--fl); font-size: 12px; font-weight: 600; letter-spacing: 0.02em;
  display: flex; align-items: center; justify-content: center;
}
.expert-name { font-size: var(--t-body); font-weight: 600; color: var(--ink); line-height: 1.2; }
.expert-meta { font-family: var(--fl); font-size: 12px; color: var(--mut); margin-top: 2px; }
/* Reader's question — the buyer's ask, rendered as the first line of the hero body
   (above the kicker/headline) so the report visibly answers the question it was built for. */
.hero-q {
  font-family: var(--fl); font-size: 12px; letter-spacing: 0.04em;
  color: var(--mut); margin: 0 0 12px;
}
.hero-kicker {
  margin: 0 0 14px;
}
.hero h1 {
  font-size: 42px; line-height: 1.08; letter-spacing: -0.02em;
  font-weight: 600; margin: 0 0 16px; max-width: 24ch;
  text-wrap: balance;   /* no orphaned last word on the verdict headline */
}
.hero .sub {
  font-size: 19px; line-height: 1.5; color: var(--mut);
  max-width: 52ch; margin: 0 0 18px;
}
.hero .method {
  font-family: var(--fl); font-size: 12px; color: var(--mut);
  letter-spacing: 0.03em;
}
/* score zone (right) */
.score-zone { text-align: right; }
.score-num {
  font-size: 54px; line-height: 1; font-weight: 650; letter-spacing: -0.03em;
}
.score-zone.good .score-num { color: var(--gd); }
.score-zone.warn .score-num { color: var(--wn); }
.score-zone.bad .score-num { color: var(--bd); }
.score-zone.accent .score-num { color: var(--ac); }
.score-num small { font-size: 20px; color: var(--mut); font-weight: 500; }
.score-sub {
  font-family: var(--fl); font-size: 10.5px; color: var(--mut);
  text-transform: uppercase; letter-spacing: 0.08em; margin-top: 6px;
}
.score-band {
  width: 100%;
  height: 7px;
  border-radius: 999px;
  background: var(--sf2);
  overflow: hidden;
  margin-top: 14px;
}
.score-band span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--dt);
}
/* HERO EXCEPTION: the hero is the one screenshot-first surface, so hue may track
   the score here (and only here) — vividness earns the share. Body modules stay
   slate. Accent only for match/recommendation anchors (selection). */
.score-band span.good { background: var(--gd); }
.score-band span.warn { background: var(--wn); }
.score-band span.bad  { background: var(--bd); }
.score-band span.accent { background: var(--ac); }
.confidence {
  font-family: var(--fl); font-size: 11px; color: var(--mut);
  margin-top: 14px; line-height: 1.4;
}

/* Hero exhibit — one primary-source artifact in the hero's because-slot.
   Optional + singular; substitutes for the driver-bar visual summary (never both).
   The tone rail follows the verdict (hero hue exception). Body forms:
   quote · redline · stat · absence. */
.hero-exhibit { border-left: 3px solid var(--ln); padding: 2px 0 2px 18px; margin: 4px 0 18px; max-width: 60ch; }
.hero-exhibit.good   { border-left-color: var(--gd); }
.hero-exhibit.warn   { border-left-color: var(--wn); }
.hero-exhibit.bad    { border-left-color: var(--bd); }
.hero-exhibit.accent { border-left-color: var(--ac); }
.ex-eyebrow { font-family: var(--fl); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--mut); margin: 0 0 8px; }
.ex-quote { font-size: 18px; line-height: 1.45; font-weight: 500; margin: 0; }
.ex-source { font-family: var(--fl); font-size: 12px; color: var(--mut); margin: 6px 0 0; }
.ex-redline { font-size: 17px; line-height: 1.5; margin: 0; }
.ex-stat { display: flex; align-items: baseline; gap: 10px; }
.ex-stat-val { font-size: 34px; font-weight: 650; letter-spacing: -0.02em; line-height: 1; }
.ex-stat-label { font-size: var(--t-body); color: var(--mut); }
.ex-absence { margin: 0; padding-left: 18px; }
.ex-absence li { font-size: var(--t-lg); line-height: 1.5; margin: 0 0 4px; }
.ex-interp { font-size: var(--t-body); line-height: 1.5; color: var(--mut); margin: 12px 0 0; }

/* Score-left orientation (sanctioned): float the verdict capsule LEFT instead of
   right, so the headline wraps on its right. Same magazine principle, mirrored. */
.hero.score-left > .verdict,
.hero.score-left > .score-zone { float: left; margin: 0 28px 18px 0; }
.hero.score-left .score-zone { text-align: left; }
.hero.score-left .score-band { max-width: 180px; }
.hero-compact .hero h1,
.hero.hero-compact h1 { font-size: 40px; max-width: 20ch; }
.rank-zone, .asset-zone { text-align: right; }
.rank-big, .asset-big {
  font-size: 48px;
  line-height: 1;
  letter-spacing: -0.03em;
  font-weight: 650;
}
.rank-sub, .asset-sub {
  font-family: var(--fl);
  font-size: 10.5px;
  color: var(--mut);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-top: 7px;
}

/* status/selection pill (filled; accent is selection or match only) */
.pill {
  display: inline-block; padding: 4px 11px; border-radius: 999px;
  font-size: 12.5px; font-weight: 600; line-height: 1.2;
}
.pill.good { background: var(--gds); color: var(--gd); }
.pill.warn { background: var(--wns); color: var(--wn); }
.pill.bad  { background: var(--bds); color: var(--bd); }
.pill.accent { background: var(--acs); color: var(--ac); }
.pill.neutral { background: var(--sf2); color: var(--mut); }

/* evidence pill (outlined = evidence) */
.epill {
  display: inline-block; padding: 3px 9px; border-radius: var(--rs);
  font-family: var(--fl); font-size: 11px; letter-spacing: 0.02em;
  background: transparent; border: 1px solid var(--ln); color: var(--mut);
}
.epill.confirmed { border-color: var(--gd); color: var(--gd); }
.epill.inferred  { border-style: dashed; }
.epill.notfound  { border-color: var(--bd); color: var(--bd); }

/* visual summary bars in hero */
.moats, .module-visual-summary { margin-top: 26px; display: grid; gap: 14px; }
.moat-row { display: grid; grid-template-columns: 150px 1fr; gap: var(--s4); align-items: center; }
.moat-label { font-size: var(--t-body); font-weight: 600; }
.moat-label .verdict { font-family: var(--fl); font-size: 10.5px; color: var(--mut); font-weight: 400; display: block; margin-top: 2px; background: none; padding: 0; min-width: 0; border-radius: 0; }
.moat-track { background: var(--sf2); border-radius: 999px; height: 18px; position: relative; overflow: hidden; }
/* Magnitude stays slate even in the hero (same discipline as vs-breakdown): the
   judgment rides on the verdict word under the label and the value — never a full
   sentiment fill. The verdict's driver (.bad) reads darkest, not loudest. */
.moat-fill {
  height: 100%; border-radius: 999px; display: flex; align-items: center;
  padding: 0 10px; background: var(--dt);
  font-family: var(--fl); font-size: 11px; font-weight: 600; color: var(--aci);
}
.moat-fill.good, .moat-fill.warn, .moat-fill.accent { background: var(--dt); }
.moat-fill.bad { background: var(--ink); }
.moat-row:has(.moat-fill.good) .moat-label .verdict { color: var(--gd); font-weight: 600; }
.moat-row:has(.moat-fill.warn) .moat-label .verdict { color: var(--wn); font-weight: 600; }
.moat-row:has(.moat-fill.bad)  .moat-label .verdict { color: var(--bd); font-weight: 600; }
/* Low-value fallback: a fill under ~15% can't hold its % inside without clipping.
   Add `.low` to the row and drop the % into a trailing `.moat-pct` (mirrors the
   funnel's `.fpct-out`) — the bar keeps its true magnitude, the label stays legible. */
.moat-row.low { grid-template-columns: 150px 1fr auto; }
.moat-row.low .moat-fill { padding: 0; }
.moat-pct { font-family: var(--fl); font-size: 13px; font-weight: 600; color: var(--ink); white-space: nowrap; }
.moat-note { font-size: 12px; color: var(--mut); margin-top: 5px; }

/* ---- classification tier (hero B) ---- */
.tier-zone { text-align: right; }
.tier-label { font-family: var(--fl); font-size: 11px; color: var(--mut); text-transform: uppercase; letter-spacing: 0.08em; }
.tier-big { font-size: 30px; font-weight: 600; margin: 6px 0 14px; }
.tier-bar { display: flex; gap: 5px; justify-content: flex-end; }
.tier-seg { width: 34px; height: 10px; border-radius: 3px; background: var(--sf2); }
.tier-seg.on { background: var(--ac); }

/* ---- recommendation (hero C) ---- */
.match-zone { text-align: right; }
.match-pct { font-size: 60px; font-weight: 600; color: var(--ac); letter-spacing: -0.02em; line-height: 1; }
.match-sub { font-family: var(--fl); font-size: 10.5px; color: var(--mut); text-transform: uppercase; letter-spacing: 0.08em; margin-top: 6px; }
.rationale { margin: 16px 0 0; padding: 0; list-style: none; display: grid; gap: var(--s2); }
.rationale li { display: flex; gap: 10px; font-size: var(--t-md); }
.rationale .n { font-family: var(--fl); color: var(--ac); font-weight: 600; }
.runnerup {
  margin-top: 18px; padding: 14px 16px; background: var(--sf2);
  border-radius: var(--rs); font-size: var(--t-body); color: var(--mut);
}
.runnerup b { color: var(--ink); }

/* ============================================================================
   VERDICT CAPSULE — one slot holds any verdict (score · % · rank · delta · status).
   Supersedes the five hero zones above (deprecated). Fixed anatomy: label · value ·
   band · meter? · note (+ runner-up / tier ladder, capsule-native). Tone carries
   sentiment via the FIXED verdict scale (--vs/--vc/--vw), NOT the brand accent.
   ========================================================================= */
.verdict {
  text-align: left; border-radius: var(--r); padding: 16px 18px; min-width: 220px;
  background: var(--vss);
}
.verdict.is-caution { background: var(--vcs); }
.verdict.is-weak    { background: var(--vws); }
.verdict-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.verdict-label {
  font-family: var(--fl); font-size: 11px; font-weight: 600; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--vs);
}
.verdict.is-caution .verdict-label { color: var(--vc); }
.verdict.is-weak    .verdict-label { color: var(--vw); }
.verdict-band {   /* qualitative read; thresholds live in the trust fold (§12) */
  font-family: var(--fl); font-size: 10px; font-weight: 600; letter-spacing: 0.05em;
  text-transform: uppercase; white-space: nowrap; padding: 4px 9px; border-radius: 999px;
  color: var(--vs); background: color-mix(in srgb, var(--vs) 14%, var(--sf));
}
.verdict.is-caution .verdict-band { color: var(--vc); background: color-mix(in srgb, var(--vc) 16%, var(--sf)); }
.verdict.is-weak    .verdict-band { color: var(--vw); background: color-mix(in srgb, var(--vw) 16%, var(--sf)); }
.verdict-value { font-size: 44px; font-weight: 700; letter-spacing: -0.02em; line-height: 1; color: var(--vs); }
.verdict-value small { font-size: 20px; font-weight: 500; color: var(--mut); letter-spacing: 0; }
.verdict.is-caution .verdict-value { color: var(--vc); }
.verdict.is-weak    .verdict-value { color: var(--vw); }
.verdict-value.is-text { font-size: 27px; line-height: 1.15; }   /* status verdicts: "Ready draft", "In review" */
/* meter — ONLY for bounded continuous values (score / % / coverage X-of-N) */
.verdict-meter { height: 7px; border-radius: 999px; background: color-mix(in srgb, var(--ink) 8%, transparent); margin-top: 14px; overflow: hidden; }
.verdict-meter > span { display: block; height: 100%; border-radius: 999px; background: var(--vs); }
.verdict.is-caution .verdict-meter > span { background: var(--vc); }
.verdict.is-weak    .verdict-meter > span { background: var(--vw); }
/* tier ladder — the classification variant of the meter (segments, one lit) */
.verdict-meter.tiers { display: flex; gap: 4px; height: 9px; background: none; overflow: visible; }
.verdict-meter.tiers i { flex: 1; border-radius: 999px; background: color-mix(in srgb, var(--ink) 10%, transparent); }
.verdict-meter.tiers i.on { background: var(--vs); }
.verdict.is-caution .verdict-meter.tiers i.on { background: var(--vc); }
.verdict.is-weak    .verdict-meter.tiers i.on { background: var(--vw); }
.verdict-note { font-family: var(--fl); font-size: 11.5px; color: var(--mut); margin-top: 12px; line-height: 1.45; }

/* Band scale under the verdict meter — makes the score self-interpreting without
   opening the trust fold (bands still documented there in full). Ticks split the
   meter track at the band boundaries; the caption names each band and bolds the
   active one (.on inherits the capsule's sentiment hue via currentColor). */
.verdict-meter { position: relative; }
.verdict-meter .tick {
  position: absolute; top: 0; bottom: 0; width: 2px;
  background: var(--sf); z-index: 1;
}
.verdict-bands {
  display: flex; flex-wrap: wrap; gap: 3px 10px;
  margin-top: 7px;
  font-family: var(--fl); font-size: 10.5px; letter-spacing: 0.02em;
  color: var(--mut); line-height: 1.4;
}
.verdict-bands span { white-space: nowrap; }
.verdict-bands .on { font-weight: 600; color: var(--vs); }
.verdict.is-caution .verdict-bands .on { color: var(--vc); }
.verdict.is-weak    .verdict-bands .on { color: var(--vw); }
/* runner-up — recommendation verdicts only; the honest second-best, capsule-native */
.verdict-runnerup { font-family: var(--fl); font-size: 11px; color: var(--mut); margin-top: 8px; padding-top: 10px; border-top: 1px solid color-mix(in srgb, var(--ink) 8%, transparent); }
.verdict-runnerup b { color: var(--ink); font-weight: 600; }

/* ============================================================================
   HOW WE ASSESSED  (trust layer)
   ========================================================================= */
.assess-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px 32px; }
.assess-item .k {
  font-family: var(--fl); font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--mut); margin-bottom: 5px;
}
.assess-item .v { font-size: var(--t-body); line-height: 1.5; }
.assess-item.full,
.assess-grid .assess-item:nth-child(4) {
  grid-column: 1 / -1;
  background: var(--sf2);
  border-radius: var(--rs);
  padding: 14px 16px;
}

/* ============================================================================
   FINDINGS
   ========================================================================= */
.finding {
  display: grid; grid-template-columns: 28px 1fr; gap: 14px;
  padding: 20px 0 4px;
  border-top: 1px solid var(--ln);   /* analyst-document list: hairline dividers, not cards — severity reads from the pill + the number */
  margin-top: 16px;
  scroll-margin-top: 16px;   /* anchor target from "Proves findings N" links */
}
.finding:first-of-type { margin-top: 0; border-top: none; padding-top: 4px; }
/* Landing cue when a tie-back anchor jumps here — a soft accent wash that fades */
.finding:target, .ev-block:target { animation: meter-target 1.6s ease-out 1; }
@keyframes meter-target {
  from { background: var(--acs); box-shadow: 0 0 0 8px var(--acs); }
  to   { background: transparent; box-shadow: 0 0 0 8px transparent; }
}
.finding .fnum {
  font-family: var(--fl);
  font-size: var(--t-lg);
  line-height: 1.2;
  color: var(--mut);
  font-weight: 600;
  padding-top: 2px;
}
.finding:has(.pill.bad) .fnum { color: var(--bd); }
.finding:has(.pill.warn) .fnum { color: var(--wn); }
.finding:has(.pill.good) .fnum { color: var(--gd); }
.finding:has(.pill.accent) .fnum { color: var(--ac); }
.finding .ftitle {
  font-size: 19px;
  font-weight: 650;
  letter-spacing: -0.01em;
  margin: 0 0 7px;
  line-height: 1.24;
}
.finding .fhead { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; margin-bottom: 7px; }
.finding .fhead .pill {
  padding: 4px 10px;
  font-size: 12px;
}
.finding .fhead .epill {
  padding: 3px 8px;
  font-size: 10px;
}
.finding .fdesc { font-size: var(--t-body); line-height: 1.5; color: var(--ink); margin: 0; max-width: 74ch; }
.finding .fdesc .mut { color: var(--mut); }
.finding-fix {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
  margin-top: 12px;
  padding: 9px 12px;
  border-radius: var(--rs);
  background: var(--acs);
  color: var(--ink);
}
.finding-fix .fix-k {
  font-family: var(--fl);
  font-size: 10.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ac);
}
.finding-fix .fix-title {
  font-size: var(--t-sm);
  font-weight: 650;
  line-height: 1.35;
}
.finding-fix .fix-pts {
  color: var(--gd);
  font-size: var(--t-sm);
  font-weight: 700;
  white-space: nowrap;
}
/* Inline evidence line — the proof shown WITH the claim (no drawer). Each finding's
   raw evidence is ≤45 words, short enough to sit under the interpretation as a quiet
   mono caption. Survives print/PDF where a collapsed <details> would vanish. */
.fev {
  margin: 10px 0 0;
  font-family: var(--fl); font-size: 11.5px; line-height: 1.6;
  color: var(--mut);
  max-width: 78ch;
}
.fev .fev-k {
  text-transform: uppercase; letter-spacing: 0.08em; font-size: 10px;
  color: var(--dt);
  margin-right: 6px;
}
/* legacy evidence drawer — superseded by .fev; kept for older reports */
details.ev {
  margin-top: 12px;
  border-top: 1px solid var(--ln);
  padding-top: 9px;
}
details.ev summary {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--fl); font-size: 12px; color: var(--ac);
  cursor: pointer; list-style: none; user-select: none;
  margin: 0;
  padding: 2px 0;
  letter-spacing: 0.03em;
}
details.ev summary:hover { color: var(--ink); }
details.ev summary::after {
  content: "+";
  width: 14px;
  height: 14px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid currentColor;
  border-radius: 999px;
  font-size: 10px;
  line-height: 1;
}
details.ev[open] summary::after { content: "-"; }
details.ev summary::-webkit-details-marker { display: none; }
details.ev .evbody {
  margin: 10px 0 0;
  background: var(--sf2);
  border: 1px solid var(--ln);
  border-radius: var(--rs);
  padding: 11px 12px;
  font-size: var(--t-sm); line-height: 1.5; color: var(--mut);
}

/* ============================================================================
   TABLES (scorecard / benchmark / gap)
   ========================================================================= */
.tbl, .meter-table { width: 100%; border-collapse: collapse; font-size: var(--t-body); }
.tbl th, .meter-table th {
  text-align: left; font-family: var(--fl); font-size: 10.5px;
  text-transform: uppercase; letter-spacing: 0.07em; color: var(--mut);
  font-weight: 500; padding: 0 12px 10px; border-bottom: 1px solid var(--ln);
}
.tbl td, .meter-table td { padding: 13px 12px; border-bottom: 1px solid var(--ln); vertical-align: top; line-height: 1.45; }
.tbl td:first-child, .tbl th:first-child, .meter-table td:first-child, .meter-table th:first-child { padding-left: 0; }
.tbl .crit, .meter-table .crit { font-weight: 600; }
/* Signed judgment cells (gap/delta columns): the verdict column carries the color,
   so the table scans in one pass — mono keeps digits aligned. */
.tbl td.pos, .meter-table td.pos { font-family: var(--fl); font-weight: 600; color: var(--gd); }
.tbl td.neg, .meter-table td.neg { font-family: var(--fl); font-weight: 600; color: var(--bd); }
.tbl tr.subtotal td, .meter-table tr.subtotal td { background: var(--sf2); font-weight: 600; }
.tbl .num, .meter-table .num { font-family: var(--fl); }
.severity-mark,
.evidence-mark {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  font-size: var(--t-body);
  font-weight: 650;
  color: var(--ink);
  white-space: nowrap;
}
.severity-mark::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--mut);
}
.severity-mark.good::before { background: var(--gd); }
.severity-mark.warn::before { background: var(--wn); }
.severity-mark.bad::before { background: var(--bd); }
.evidence-mark { color: var(--gd); }
.evidence-mark::before {
  content: "✓";
  font-weight: 750;
  color: var(--gd);
}
.evidence-mark.inferred,
.evidence-mark.partial {
  color: var(--mut);
  font-weight: 500;
}
.evidence-mark.inferred::before,
.evidence-mark.partial::before {
  content: "";
  width: 11px;
  height: 11px;
  border: 1.5px dashed var(--mut);
  border-radius: 999px;
}
.evidence-mark.notfound {
  color: var(--bd);
}
.evidence-mark.notfound::before {
  content: "×";
  color: var(--bd);
}
.module-scorecard .src-note {
  font-family: var(--fb);
  font-size: var(--t-sm);
}
.frame-line { font-size: var(--t-body); color: var(--mut); margin: 0 0 16px; max-width: 72ch; line-height: 1.5; }
.you-row td { background: var(--acs); }

/* ============================================================================
   OPTIONAL DATA-VIEWING MODULES
   ========================================================================== */
.kpi-grid {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s3);
}
.kpi-tile {
  border: 1px solid var(--ln); border-radius: var(--rs);
  background: var(--sf); padding: 16px 18px;
}
.kpi-value { font-size: 31px; line-height: 1; font-weight: 600; letter-spacing: -0.02em; color: var(--ink); }
.kpi-label {
  font-family: var(--fl); font-size: 10.5px; color: var(--mut);
  text-transform: uppercase; letter-spacing: 0.07em; margin-top: 9px;
}
.kpi-tile p { font-size: var(--t-sm); color: var(--mut); margin: 7px 0 0; line-height: 1.45; }
/* The flagged tile (the one that drives the verdict) is emphasized with a tone
   underline on its number — a thin rule MARK, not a tinted card. A row of tiles
   never reads as a grid of colour-graded panels. */
.kpi-tile .kpi-value { display: inline-block; }
.kpi-tile.good .kpi-value { box-shadow: inset 0 -3px 0 var(--gd); }
.kpi-tile.warn .kpi-value { box-shadow: inset 0 -3px 0 var(--wn); }
.kpi-tile.bad .kpi-value  { box-shadow: inset 0 -3px 0 var(--bd); }
.kpi-tile.accent .kpi-value { box-shadow: inset 0 -3px 0 var(--ac); }   /* accent = a selected/recommended metric */

.rank-bars { display: grid; gap: 9px; }
.rank-bar, .rank-threshold-row {
  display: grid; grid-template-columns: 28px minmax(120px, 1fr) minmax(160px, 2fr) 76px;
  gap: var(--s3); align-items: center;
}
.rank-n { font-family: var(--fl); color: var(--mut); font-size: var(--t-sm); }
.rank-label { font-size: var(--t-body); font-weight: 600; min-width: 0; }
.rank-track { height: 14px; background: var(--sf2); border-radius: 999px; overflow: hidden; position: relative; }
.rank-track span { display: block; height: 100%; background: var(--dt); border-radius: 999px; }
/* threshold marker, repeated per row at the same x so it reads as one line */
.rank-track .rank-mark {
  position: absolute; top: 0; bottom: 0; left: var(--th, 50%);
  width: 0; border-left: 1.5px dashed var(--mut); z-index: 2;
}
.rank-value { font-family: var(--fl); font-size: 12px; color: var(--mut); text-align: right; }
.rank-delta { display: block; font-size: 10.5px; color: var(--ac); margin-top: 2px; white-space: nowrap; }
/* fill + name weighting around the threshold: you is the only accent bar */
.rank-bar.above .rank-track span { background: var(--dt2); }
.rank-bar.below .rank-track span { background: var(--dt3); }
.rank-bar.below .rank-label { color: var(--mut); font-weight: 500; }
.rank-bar.below .rank-n { opacity: .6; }
.rank-bar.you { background: var(--acs); border-radius: var(--rs); padding: 8px 10px; margin: -2px -10px; }
.rank-bar.you .rank-track span { background: var(--ac); }
.rank-bar.you .rank-n, .rank-bar.you .rank-label, .rank-bar.you .rank-value { color: var(--ac); }
/* threshold flag row, aligned to the track column via the shared grid */
.rank-threshold-row { height: 15px; align-items: end; }
.rank-threshold-track { position: relative; height: 100%; }
.rank-th-flag {
  position: absolute; bottom: 0; left: var(--th, 50%); transform: translateX(-50%);
  white-space: nowrap; font-family: var(--fl); font-size: 9.5px; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--mut);
}

.tier-bands { display: grid; gap: 10px; }
.tier-band {
  display: grid; grid-template-columns: 42px minmax(0, 1fr) auto;
  gap: 14px; align-items: center;
  border: 1px solid var(--ln); border-radius: var(--rs);
  background: var(--sf); padding: 14px 16px;
}
.tier-band.strong { background: var(--acs); border-color: var(--ac); }
.tier-key {
  width: 34px; height: 34px; border-radius: var(--rs);
  display: grid; place-items: center;
  background: var(--sf2); color: var(--ink);
  font-family: var(--fl); font-weight: 600;
}
.tier-band.strong .tier-key { background: var(--ac); color: var(--aci); }
.tier-band h3 { font-size: var(--t-lg); font-weight: 600; margin: 0 0 3px; }
.tier-band p { font-size: var(--t-sm); color: var(--mut); margin: 0; line-height: 1.4; }
.tier-delta { font-family: var(--fl); font-size: 11px; color: var(--gd); white-space: nowrap; }
/* verdict chip — colored by MEANING, not all green: current read = navy, fallback = neutral, avoid = red */
.tier-verdict {
  font-family: var(--fl); font-size: 9px; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 4px 9px; border-radius: 999px; white-space: nowrap;
  background: var(--sf2); color: var(--mut);
}
.tier-verdict.current { background: var(--ac); color: var(--aci); }
.tier-verdict.avoid { background: var(--bds); color: var(--bd); }

.bullet-list, .deviation-list, .range-list, .bridge-list { display: grid; gap: var(--s3); }
.bullet-row, .deviation-row, .range-row, .bridge-row {
  display: grid; grid-template-columns: minmax(120px, 1fr) minmax(180px, 2fr) 72px;
  gap: 14px; align-items: center;
}
.bullet-label, .deviation-label, .range-label, .bridge-row > span:first-child {
  font-size: var(--t-body); font-weight: 600;
}
.bullet-track, .range-track, .bridge-track {
  position: relative; height: 14px; border-radius: 999px;
  background: var(--sf2); overflow: hidden;
}
.deviation-track {
  position: relative;
  height: 14px;
  border-radius: 999px;
  overflow: visible;
  background:
    linear-gradient(to right, transparent calc(25% - .5px), var(--ln) calc(25% - .5px), var(--ln) calc(25% + .5px), transparent calc(25% + .5px)),
    linear-gradient(to right, transparent calc(75% - .5px), var(--ln) calc(75% - .5px), var(--ln) calc(75% + .5px), transparent calc(75% + .5px)),
    var(--sf2);
}
.bullet-fill, .bridge-track span {
  position: absolute; left: 0; top: 0; bottom: 0;
  background: var(--dt); border-radius: 999px;
}
/* bars carry magnitude (slate); the pass/miss judgment lives in the delta text + target flag */
.bullet-fill.good, .bullet-fill.warn, .bullet-fill.bad { background: var(--dt); }
.bullet-track { overflow: visible; }   /* let the target flag extend past the bar */
.bullet-target {
  position: absolute; top: -8px; bottom: -8px; width: 2px;
  background: var(--ink); z-index: 2;
}
.bullet-target::before {   /* triangle pointer so the target stays findable over a dark fill */
  content: ""; position: absolute; top: -6px; left: 50%; transform: translateX(-50%);
  border-left: 4px solid transparent; border-right: 4px solid transparent;
  border-top: 6px solid var(--ink);
}
.bullet-value, .deviation-value, .range-value, .bridge-row b {
  font-family: var(--fl); font-size: 12px; color: var(--mut); text-align: right; font-weight: 500;
}
.bullet-value { font-weight: 600; color: var(--ink); }
.bullet-value small { color: var(--mut); font-weight: 400; }
.bullet-delta { display: block; font-family: var(--fl); font-size: 10px; margin-top: 2px; }
.bullet-delta.miss { color: var(--bd); }
.bullet-delta.clear { color: var(--gd); }
.deviation-axis {
  position: absolute; top: -6px; bottom: -6px; left: 50%; width: 2px;
  background: var(--ink);
  z-index: 2;
}
.deviation-fill {
  position: absolute; top: 0; bottom: 0; border-radius: 999px;
  z-index: 1;
}
/* distance from baseline is magnitude (slate); side-of-axis + coloured value carry direction */
.deviation-fill.pos { background: var(--dt); }
.deviation-fill.neg { background: var(--dt); }
.deviation-value.pos { color: var(--gd); font-weight: 650; }
.deviation-value.neg { color: var(--bd); font-weight: 650; }
.deviation-scale {
  display: grid;
  /* must match .deviation-row columns exactly, or the scale ticks (and the "0")
     won't sit above the bar track / axis line */
  grid-template-columns: minmax(120px, 1fr) minmax(180px, 2fr) 72px;
  gap: 14px;
  align-items: end;
  margin: 4px 0 8px;
}
.deviation-scale-track {
  position: relative;
  height: 18px;
  font-family: var(--fl);
  font-size: 10px;
  color: var(--mut);
}
.deviation-scale-track span {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
}
.deviation-scale-track .t0 {
  color: var(--ink);
  font-weight: 650;
}
.deviation-note {
  margin: 12px 0 0 184px;
  font-family: var(--fl);
  font-size: 11px;
  color: var(--mut);
}
.range-band {
  position: absolute; top: 5px; bottom: 5px; border-radius: 999px;
  background: var(--dt3);
}
.range-dot {
  position: absolute; top: 50%; width: 14px; height: 14px;
  border-radius: 999px; background: var(--ac); border: 3px solid var(--sf);
  transform: translate(-50%, -50%); box-shadow: 0 0 0 1px var(--ac);
}

/* Percentile Spread (box plot): whiskers + box + median are neutral slate;
   navy is the "you" marker and only the "you" marker. */
.spread-list { display: grid; gap: var(--s3); }
.spread-row {
  display: grid; grid-template-columns: minmax(120px, 1fr) minmax(180px, 2fr) 72px;
  gap: 14px; align-items: center;
}
.spread-label { font-size: var(--t-body); font-weight: 600; }
.spread-track { position: relative; height: 22px; }   /* no pill bg — the whisker line is the range; marker overflows freely */
.spread-whisker {
  position: absolute; top: 50%; height: 2px; transform: translateY(-50%);
  background: var(--dt3); border-radius: 999px; z-index: 0;
}
.spread-whisker::before, .spread-whisker::after {   /* end caps at min / max */
  content: ""; position: absolute; top: -4px; width: 2px; height: 10px; background: var(--dt3);
}
.spread-whisker::before { left: 0; }
.spread-whisker::after { right: 0; }
.spread-box {   /* the middle 50% (Q1–Q3) */
  position: absolute; top: 4px; bottom: 4px; border-radius: var(--rs);
  background: var(--dt3); border: 1px solid var(--dt2); z-index: 1;
}
.spread-median {   /* median tick */
  position: absolute; top: 2px; bottom: 2px; width: 2px;
  background: var(--dt); transform: translateX(-1px); z-index: 2;
}
.spread-you { position: absolute; top: 50%; transform: translate(-50%, -50%); z-index: 3; }   /* the only navy on the rail */
.spread-dot {
  display: block; width: 14px; height: 14px; border-radius: 999px;
  background: var(--ac); border: 3px solid var(--sf); box-shadow: 0 0 0 1px var(--ac);
}
.spread-value {
  font-family: var(--fl); font-size: 12px; color: var(--mut); text-align: right; font-weight: 500;
}
/* bridge steps are magnitude (slate); the signed value carries gain/loss */
.bridge-row.gain .bridge-track span,
.bridge-row.loss .bridge-track span { background: var(--dt); }
.flow-lanes { display: grid; gap: 10px; }
.flow-lane {
  display: grid; grid-template-columns: minmax(110px, 1fr) minmax(160px, 2fr) minmax(120px, 1fr);
  gap: var(--s3); align-items: center;
}
/* one uniform type treatment for every row — the recommendation is carried by
   the navy fill + the "New route" chip, never by unexplained bold */
.flow-lane-label { font-size: var(--t-sm); color: var(--ink); }
.flow-lane-end { font-size: var(--t-sm); color: var(--ink); display: flex; align-items: center; gap: var(--s2); }
.flow-lane-path {
  position: relative; height: 22px; border-radius: 999px;
  background: var(--sf2); overflow: hidden;
}
.flow-lane-path span {
  position: absolute; left: 0; top: 0; bottom: 0;
  background: var(--dt2); border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
  color: var(--aci); font-family: var(--fl); font-size: 11px; font-weight: 500;
}
.flow-lane.chosen .flow-lane-path span { background: var(--ac); }
.flow-lane-chip {
  font-family: var(--fl); font-size: 9px; letter-spacing: 0.06em; text-transform: uppercase;
  background: var(--acs); color: var(--ac); padding: 3px 7px; border-radius: 999px; white-space: nowrap;
}

.composition-grid {
  display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(180px, .8fr);
  gap: 22px; align-items: center;
}
.stacked-bar {
  display: flex; height: 38px; overflow: hidden;
  border-radius: var(--rs); background: var(--sf2); border: 1px solid var(--ln);
}
.stacked-bar span {
  display: flex; align-items: center; justify-content: center;
  height: 100%; min-width: 0; overflow: hidden; white-space: nowrap;
  font-family: var(--fl); font-size: 11px; font-weight: 500; color: var(--ink);
}
.stacked-bar span:nth-child(1), .legend-list li:nth-child(1) .sw { background: var(--c1); }
.stacked-bar span:nth-child(2), .legend-list li:nth-child(2) .sw { background: var(--c2); }
.stacked-bar span:nth-child(3), .legend-list li:nth-child(3) .sw { background: var(--c3); }
.stacked-bar span:nth-child(4), .legend-list li:nth-child(4) .sw { background: var(--c4); }
.stacked-bar span:nth-child(1) { color: var(--aci); }   /* darkest slice: white share */
.legend-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 9px; }
.legend-list li { display: flex; align-items: center; gap: 9px; font-size: var(--t-sm); color: var(--mut); }
.legend-list .sw { width: 10px; height: 10px; border-radius: 3px; flex: 0 0 auto; }
.legend-list .legend-label { flex: 1; min-width: 0; }
.legend-list .legend-val { font-family: var(--fl); color: var(--ink); }
.legend-list li.gap { color: var(--ink); font-weight: 600; }
.legend-list li.gap .legend-val { color: var(--c4); }
/* ---- Donut / proportion ring (SVG; the conic-gradient version is retired) ----
   The ONE job a donut earns: "this much of the whole" as an instant gestalt.
   Arc = slate magnitude; in the highlighted-part variant the recommended slice is
   the only navy; the quoted figure always sits in the hole. Never for 3+ categories. */
.donut-wrap { display: grid; grid-template-columns: minmax(0, 220px) minmax(0, 1fr); gap: 28px; align-items: center; }
.donut { position: relative; width: 100%; max-width: 220px; margin: 0 auto; }
.donut svg { width: 100%; height: auto; display: block; }
.donut-track { stroke: var(--ln); }                 /* the remainder / "the rest" */
.donut-arc { stroke: var(--dt); }                   /* a share — slate magnitude */
.donut-arc-hi { stroke: var(--ac); }                /* the one highlighted / recommended part */
.donut-center {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  pointer-events: none;
}
.donut-fig { font-size: 40px; font-weight: 700; letter-spacing: -0.02em; line-height: 1; color: var(--ink); }
.donut-fig small { font-size: 0.5em; font-weight: 600; color: var(--mut); }
.donut-sub { font-family: var(--fl); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--mut); margin-top: 4px; }
.donut-legend { display: grid; gap: 7px; margin-top: 14px; }
.donut-key { display: flex; align-items: center; gap: var(--s2); font-size: var(--t-sm); color: var(--ink); }
.donut-key i { width: 12px; height: 12px; border-radius: 3px; flex: 0 0 auto; }
.donut-key.k-arc i { background: var(--dt); }
.donut-key.k-track i { background: var(--ln); }
.donut-key.k-hi i { background: var(--ac); }

/* ---- Score Spectrum / banded scale (a positioned reading on a fixed scale) ----
   Lead with the readout; the rail is supporting evidence. Rail stays neutral, the
   landed band gets a faint navy tint, navy is the marker ONLY. Encode score once:
   position carries it, the label names the band. */
.spectrum-readout { display: flex; align-items: baseline; gap: var(--s4); margin-bottom: 30px; }
.spectrum-score { font-size: 44px; font-weight: 700; letter-spacing: -0.02em; line-height: 1; color: var(--ac); }
.spectrum-score small { font-size: 20px; font-weight: 500; color: var(--mut); }
.spectrum-band-name { font-size: 20px; font-weight: 700; line-height: 1.1; }
.spectrum-delta { font-family: var(--fl); font-size: 12px; color: var(--mut); margin-top: 3px; }
.spectrum { position: relative; }
.spectrum-track {
  position: relative; height: 14px; border-radius: 999px;
  background: var(--sf2); overflow: hidden;
}
.spectrum-active { position: absolute; top: 0; bottom: 0; background: var(--acs); }   /* faint navy on the landed band */
.spectrum-div { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--sf); transform: translateX(-1px); }  /* hard band boundary */
.spectrum-marker { position: absolute; top: 7px; transform: translate(-50%, -50%); z-index: 2; }   /* the only navy on the rail */
.spectrum-dot {
  width: 18px; height: 18px; border-radius: 999px;
  background: var(--ac); box-shadow: 0 0 0 4px var(--sf);
}
.spectrum-bubble {
  position: absolute; bottom: calc(100% + 9px); left: 50%; transform: translateX(-50%);
  background: var(--ac); color: var(--aci); font-family: var(--fl); font-size: 12px; font-weight: 600;
  padding: 3px 8px; border-radius: var(--rs); line-height: 1; white-space: nowrap;
}
.spectrum-bubble::after {
  content: ""; position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  border: 4px solid transparent; border-top-color: var(--ac);
}
.spectrum-labels {
  display: flex; justify-content: space-between; margin-top: 12px;
  font-family: var(--fl); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--mut);
}
.spectrum-labels .active { color: var(--ac); font-weight: 600; }

.waffle {
  display: grid; grid-template-columns: repeat(10, 1fr); gap: var(--s1);
  max-width: 260px;
}
.waffle-cell { aspect-ratio: 1; border-radius: 3px; background: var(--sf2); }
.waffle-cell.on { background: var(--dt); }
.treemap {
  display: grid; grid-template-columns: 1.3fr .8fr .6fr; gap: 5px; min-height: 170px;
}
.treemap-cell {
  border-radius: var(--rs); background: var(--dt3); padding: 12px;
  display: flex; align-items: flex-end; font-size: var(--t-sm); font-weight: 600;
}
.treemap-cell.major { background: var(--dt); color: var(--aci); grid-row: span 2; }
.treemap-cell.mid { background: var(--dt2); color: var(--aci); }

.trend-list { display: grid; gap: 14px; }
.trend-row {
  display: grid; grid-template-columns: minmax(0, 1fr) 180px;
  gap: 18px; align-items: end;
  border: 1px solid var(--ln); border-radius: var(--rs);
  background: var(--sf); padding: 16px 18px;
}
.trend-row h3 { font-size: var(--t-lg); font-weight: 600; margin: 0 0 4px; }
.trend-row p { font-size: var(--t-sm); color: var(--mut); margin: 0; line-height: 1.45; }
.sparkline {
  height: 70px; display: flex; align-items: flex-end; gap: 6px;
  border-bottom: 1px solid var(--ln);
}
.sparkline span {
  flex: 1; min-width: 5px; background: var(--dt);
  border-radius: 2px 2px 0 0;
}

/* Slope (two-point change) + Rank Movement (bump, rank over time):
   peers are neutral hairlines; the subject's line is the only navy. */
.slope { display: grid; grid-template-columns: auto 1fr auto; gap: var(--s3); align-items: center; }
.slope-head {
  font-family: var(--fl); font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--mut);
}
.slope-head-r { text-align: right; }
.slope-plot { width: 100%; height: 130px; display: block; }
.bump-plot  { width: 100%; height: 150px; display: block; }
.slope-line, .bump-line {
  fill: none; stroke: var(--dt3); stroke-width: 1.5;
  stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke;
}
.slope-line.is-you, .bump-line.is-you { stroke: var(--ac); stroke-width: 2.5; }   /* the subject is the only navy line */

.slope-legend, .bump-legend {
  list-style: none; margin: var(--s4) 0 0; padding: 0;
  display: grid; gap: 6px; font-size: var(--t-sm); color: var(--ink);
}
.slope-legend li, .bump-legend li { display: flex; align-items: center; gap: var(--s2); }
.slope-legend li b, .bump-legend li b { font-weight: 600; }
.slope-legend .is-you b, .bump-legend .is-you b { color: var(--ac); }   /* "you" reads navy in the legend too */
.slope-delta, .bump-delta { font-family: var(--fl); font-size: 11px; margin-left: auto; }
.slope-delta.up,   .bump-delta.up   { color: var(--gd); }
.slope-delta.down, .bump-delta.down { color: var(--bd); }

.relation-plot {
  position: relative; min-height: 260px; border: 1px solid var(--ln);
  border-radius: var(--rs); background: var(--sf2);
}
.relation-plot::before, .relation-plot::after {
  content: ""; position: absolute; background: var(--ln);
}
.relation-plot::before { left: 0; right: 0; top: 50%; height: 1px; }
.relation-plot::after { top: 0; bottom: 0; left: 50%; width: 1px; }
.relation-point {
  position: absolute; width: 12px; height: 12px; border-radius: 999px;
  background: var(--dt); transform: translate(-50%, -50%);
}
.relation-point.you { background: var(--ac); box-shadow: 0 0 0 6px var(--acs); }
.venn {
  position: relative; display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center; gap: var(--s4); padding: 28px 24px 60px;
  border: 1px solid var(--ln); border-radius: var(--rs); background: var(--sf2);
}
/* labels live on the OUTER flanks — nothing can clip or cover them */
.venn-side b { display: block; font-size: var(--t-md); font-weight: 650; margin-bottom: 4px; }
.venn-side span { font-size: var(--t-sm); color: var(--mut); line-height: 1.4; }
.venn-left { text-align: right; }
.venn-right { text-align: left; }
.venn-diagram { position: relative; width: 220px; height: 150px; margin: 0 auto; }
.venn-circle {
  position: absolute; top: 0; width: 150px; height: 150px; border-radius: 999px;
  mix-blend-mode: multiply;   /* the intersection actually darkens — shows the overlap, not just asserts it */
}
.venn-circle.a { left: 0; background: var(--dt2); }
.venn-circle.b { right: 0; background: var(--dt3); }
.venn-overlap {
  position: absolute; left: 50%; bottom: 16px; transform: translateX(-50%);
  display: grid; justify-items: center;
}
.venn-leader { width: 1px; height: 26px; background: var(--mut); }
.venn-note {
  background: var(--sf); border: 1px solid var(--ac);
  border-radius: 999px; padding: 7px 14px; font-size: var(--t-sm); font-weight: 600;
  color: var(--ink); white-space: nowrap;
}

/* ---- Decision flow with outcomes ----
   A decision question (centered), org-chart connectors, and two outcome cards.
   The recommended branch is named, flagged (navy), and reasoned; the rejected one
   keeps its trade-off visible. Connectors are 1px hairlines drawn with pseudo-
   elements — a stem down from the question, a bus across, a drop into each card. */
.decision-flow { display: block; }
.decision-q {
  position: relative;
  max-width: 64%;
  margin: 0 auto;
  background: var(--sf2);
  border: 1px solid var(--ln);
  border-radius: var(--rs);
  padding: 14px 20px;
  text-align: center;
}
.decision-q::after {   /* stem: question bottom → bus */
  content: ""; position: absolute; left: 50%; top: 100%;
  width: 1px; height: 20px; background: var(--ln);
}
.decision-q-k {
  font-family: var(--fl); font-size: 10.5px; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--mut); margin: 0 0 5px;
}
.decision-q-text { font-size: var(--t-lg); font-weight: 650; line-height: 1.3; margin: 0; }

.decision-branches {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s4); width: 100%;
  margin-top: 40px; position: relative;
}
.decision-branches::before {   /* horizontal bus connecting the two column centers */
  content: ""; position: absolute; top: -20px; left: 25%; right: 25%;
  height: 1px; background: var(--ln);
}
.decision-branch {
  position: relative;
  border: 1px solid var(--ln); border-radius: var(--r);
  background: var(--sf); padding: 18px 20px;
}
.decision-branch::before {   /* drop: bus → this card's top */
  content: ""; position: absolute; bottom: 100%; left: 50%;
  width: 1px; height: 20px; background: var(--ln);
}
.decision-branch.chosen { border: 1.5px solid var(--ac); background: var(--acs); }
.branch-head { display: flex; justify-content: space-between; align-items: center; gap: var(--s2); margin-bottom: 12px; }
.branch-when {
  font-family: var(--fl); font-size: 10.5px; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--mut);
}
/* the recommended flag is the one solid-navy mark in the module (selection) */
.branch-flag {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--fl); font-size: 10px; font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase;
  background: var(--ac); color: var(--aci);
  padding: 5px 11px; border-radius: 999px; white-space: nowrap;
}
.branch-flag::before { content: "\2713"; }   /* ✓ — survives grayscale */
.branch-title { font-size: 19px; font-weight: 650; letter-spacing: -0.01em; line-height: 1.25; margin: 0 0 7px; }
.decision-branch.chosen .branch-title { color: var(--ac); }
.branch-body { font-size: var(--t-body); line-height: 1.5; color: var(--mut); margin: 0; max-width: 46ch; }
.decision-branch.chosen .branch-body { color: var(--ink); }
.connect-list { display: grid; gap: var(--s2); }
.connect-node {
  border-left: 3px solid var(--dt); background: var(--sf2);
  border-radius: var(--rs); padding: 11px 14px;
  font-size: var(--t-body); color: var(--mut);
}
.connect-node b { color: var(--ink); }

.sequence { display: grid; gap: 0; }
.seq-item {
  display: grid; grid-template-columns: 42px minmax(0, 1fr);
  gap: 14px; padding: 0 0 20px; position: relative;
}
.seq-item:not(:last-child)::before {
  content: ""; position: absolute; left: 16px; top: 34px; bottom: 0;
  border-left: 1px solid var(--ln);
}
.seq-n {
  width: 32px; height: 32px; border-radius: var(--rs);
  display: grid; place-items: center;
  background: var(--ink); color: var(--aci);
  font-family: var(--fl); font-size: 11px; position: relative; z-index: 1;
}
.seq-item h3 { font-size: var(--t-lg); font-weight: 600; margin: 3px 0 4px; }
.seq-item p { font-size: var(--t-sm); color: var(--mut); margin: 0; line-height: 1.45; }

.spatial-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(76px, 1fr));
  gap: var(--s2);
}
.spatial-cell {
  min-height: 74px; border-radius: var(--rs); border: 1px solid var(--ln);
  background: var(--sf2); padding: 10px;
  display: flex; flex-direction: column; justify-content: space-between;
}
.spatial-cell b { font-family: var(--fl); font-size: 12px; }
.spatial-cell span { font-size: 12px; color: var(--mut); }
.spatial-cell.h1 { background: var(--dt3); border-color: var(--dt2); }
.spatial-cell.h1 b, .spatial-cell.h1 span { color: var(--ink); opacity: 1; }  /* AA contrast on the light tile */
.spatial-cell.h2 { background: var(--dt2); color: var(--aci); }
.spatial-cell.h2 span, .spatial-cell.h3 span { color: var(--aci); opacity: .9; }
.spatial-cell.h3 { background: var(--dt); color: var(--aci); }
.spatial-legend { display: flex; align-items: center; gap: 6px; margin-top: 10px; font-family: var(--fl); font-size: 10px; color: var(--mut); }
.spatial-legend i { width: 18px; height: 10px; border-radius: 3px; display: inline-block; }
.spatial-legend .s1 { background: var(--dt3); border: 1px solid var(--dt2); }
.spatial-legend .s2 { background: var(--dt2); }
.spatial-legend .s3 { background: var(--dt); }

/* ---- Spider / Radar (multi-axis comparison; paired with a readable value list) ---- */
.radar-wrap { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(160px, 1fr); gap: 22px; align-items: center; }
.radar { width: 100%; height: auto; max-width: 460px; display: block; margin: 0 auto; }
.radar-ring, .radar-spoke { fill: none; stroke: var(--ln); }
.radar-axis-label { fill: var(--mut); font-family: var(--fl); font-size: 10px; }
.radar-bench { fill: none; stroke: var(--dt2); stroke-width: 1.5; stroke-dasharray: 4 3; }
.radar-you { fill: var(--acs); fill-opacity: .55; stroke: var(--ac); stroke-width: 2; }
.radar-dot { fill: var(--ac); }
/* legend + value list make the data readable where the polygon alone can't be */
.radar-legend { display: grid; gap: var(--s3); align-content: start; }
.radar-keys { display: grid; gap: 7px; }
.radar-key { display: flex; align-items: center; gap: var(--s2); font-size: var(--t-sm); color: var(--ink); }
.radar-key i { width: 16px; border-top: 3px solid; display: inline-block; flex: 0 0 auto; }
.radar-key.you i { border-top-color: var(--ac); }
.radar-key.bench i { border-top: 0; border-bottom: 2px dashed var(--dt2); }
.radar-values { display: grid; gap: 6px; border-top: 1px solid var(--ln); padding-top: 10px; }
.radar-values .rv { display: grid; grid-template-columns: 1fr auto auto; gap: 10px; font-size: var(--t-sm); align-items: baseline; }
.radar-values .rv .rv-lbl { color: var(--mut); }
.radar-values .rv b { font-family: var(--fl); color: var(--ink); }
.radar-values .rv .rv-gap { font-family: var(--fl); font-size: 11px; min-width: 34px; text-align: right; }
.radar-values .rv .rv-gap.neg { color: var(--bd); }
.radar-values .rv .rv-gap.pos { color: var(--gd); }

.revision-pair {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s3);
}
.revision-box {
  border: 1px solid var(--ln); border-radius: var(--rs);
  background: var(--sf); padding: 16px 18px;
}
.revision-box.before { background: var(--sf2); }
.revision-box.after { border-color: var(--gd); }
.revision-label {
  font-family: var(--fl); font-size: 10.5px; text-transform: uppercase;
  letter-spacing: 0.07em; color: var(--mut); margin-bottom: 8px;
}
.revision-box p { font-size: var(--t-lg); line-height: 1.5; margin: 0; }
.redline {
  border: 1px solid var(--ln); border-radius: var(--rs);
  background: var(--sf); padding: 18px 20px; font-size: var(--t-lg); line-height: 1.7;
}
.redline-del { color: var(--bd); text-decoration: line-through; }
.redline-ins { color: var(--gd); font-weight: 600; }
.annotated-shot {
  border: 1px solid var(--ln); border-radius: var(--rs);
  background: var(--sf2); padding: 18px; display: grid; gap: 10px;
}
.annotation {
  display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 10px;
  font-size: var(--t-sm); color: var(--mut);
}
.annotation b {
  width: 24px; height: 24px; display: grid; place-items: center;
  background: var(--ac); color: var(--aci); border-radius: 999px;
  font-family: var(--fl); font-size: 11px;
}

/* ============================================================================
   DECISION / BUSINESS REPORT MODULES
   ========================================================================== */
/* straight row + column headers replace the rotated double-axis string —
   each cell's coordinates read off the headers like a table */
.priority-frame {
  display: grid;
  grid-template-columns: minmax(54px, auto) minmax(0, 1fr);
  grid-template-rows: auto 1fr;
  gap: 8px 12px;
  align-items: stretch;
}
.pm-col-heads {
  grid-column: 2; grid-row: 1;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s2);
}
.pm-col-heads span,
.pm-row-heads span {
  font-family: var(--fl); font-size: 10px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--mut); line-height: 1.25;
}
.pm-col-heads span { text-align: center; }
.pm-row-heads {
  grid-column: 1; grid-row: 2;
  display: grid; grid-template-rows: repeat(2, minmax(0, 1fr)); gap: var(--s2);
  align-content: stretch;
}
.pm-row-heads span { display: flex; align-items: center; max-width: 8ch; }
.priority-matrix {
  grid-column: 2; grid-row: 2;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s2);
  position: relative;
}
.priority-matrix::before,
.priority-matrix::after {
  content: "";
  position: absolute;
  background: var(--ln);
  pointer-events: none;
}
.priority-matrix::before { left: 0; right: 0; top: 50%; height: 1px; }
.priority-matrix::after { top: 0; bottom: 0; left: 50%; width: 1px; }
.pm-cell {
  min-height: 106px;
  border: 1px solid var(--ln); border-radius: var(--rs);
  background: var(--sf); padding: 14px 16px;
  position: relative;
  z-index: 1;
}
.pm-cell h3 {
  font-size: var(--t-md); font-weight: 650; margin: 0 0 3px;
}
.pm-cell p {   /* a caption that EARNS its space: what the quadrant means, not the coordinates */
  font-size: 12px; color: var(--mut);
  margin: 0 0 10px; line-height: 1.4;
}
.pm-cell span {
  display: inline-block;
  border-radius: var(--rs); background: var(--sf2);
  padding: 7px 10px; font-size: var(--t-sm); color: var(--ink);
}
/* No tinted quadrants. The recommended quadrant (Do now) carries the accent left
   rule — the single "act here" marker; the rest are hairline, Defer is dashed. */
.pm-cell.do-now { box-shadow: inset 3px 0 0 var(--ac); }
.pm-cell.plan { box-shadow: inset 3px 0 0 var(--ln); }
.pm-cell.quick { }
.pm-cell.avoid {   /* visibly de-prioritized via a dashed border, but still AA-readable */
  border-style: dashed;
  border-color: var(--ln);
}
.pm-cell.avoid span,
.pm-cell.quick span {
  color: var(--mut);
}

.risk-register { display: grid; gap: 10px; }
.risk-row {
  /* Score | body (title+desc) | fix — both text columns share space and wrap.
     Never use `auto` on the fix column: a long unwrapped fix crushes the title
     into one-word-per-line wrapping (and can overlap when height collapses). */
  display: grid;
  grid-template-columns: auto minmax(0, 1.35fr) minmax(0, 1fr);
  gap: 14px 16px;
  align-items: start;
  border: 1px solid var(--ln); border-radius: var(--rs);
  background: var(--sf); padding: 14px 16px;
}
.risk-score {   /* uniform width + a dot so the column scans as one aligned rail */
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  min-width: 66px; min-height: 26px; border-radius: 999px;
  font-family: var(--fl); font-size: 11px; font-weight: 600;
  background: var(--sf2); color: var(--mut);
  margin-top: 2px; /* optical align with title cap-height when align-items:start */
}
.risk-score::before { content: ""; width: 6px; height: 6px; border-radius: 999px; background: currentColor; flex: 0 0 auto; }
.risk-row.high .risk-score { background: var(--bds); color: var(--bd); }
.risk-row.med .risk-score { background: var(--wns); color: var(--wn); }
.risk-row.low .risk-score { background: var(--gds); color: var(--gd); }
.risk-body { min-width: 0; }
.risk-row h3 {
  font-size: var(--t-lg); font-weight: 650; margin: 0 0 4px;
  line-height: 1.3; overflow-wrap: break-word;
}
.risk-row p {
  font-size: var(--t-sm); color: var(--mut); margin: 0;
  line-height: 1.45; overflow-wrap: break-word;
}
/* Fix column: wrap long recommendations; keep a readable action tone */
.risk-fix { min-width: 0; text-align: left; }
.risk-fix-k {
  display: block; font-family: var(--fl); font-size: 9px;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--mut);
  margin-bottom: 4px;
}
.risk-row b, .risk-fix b {
  display: block;
  font-size: var(--t-sm); font-weight: 650; color: var(--ac);
  line-height: 1.4; overflow-wrap: break-word; white-space: normal;
}

.tradeoff-table tr.chosen td,
.tradeoff-table .chosen td {
  background: var(--acs);
}
.tradeoff-table th {
  padding-top: 4px;
  padding-bottom: 12px;
}
.tradeoff-table td {
  padding-top: 18px;
  padding-bottom: 18px;
}
.tradeoff-table tr.chosen td {
  border-top: 1px solid color-mix(in srgb, var(--ac) 20%, var(--ln));
  border-bottom: 1px solid color-mix(in srgb, var(--ac) 20%, var(--ln));
}
.tradeoff-table tr.chosen td:first-child {
  box-shadow: inset 3px 0 0 var(--ac);
  padding-left: 18px;
}
.tradeoff-table tr.chosen .crit::after {
  content: "← you";
  display: inline-flex;
  align-items: center;
  margin-left: 8px;
  padding: 3px 8px;
  border-radius: 999px;
  background: var(--ac);
  color: var(--aci);
  font-family: var(--fl);
  font-size: 10px;
  line-height: 1;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  vertical-align: middle;
}
.tradeoff-table td:last-child { white-space: nowrap; }

.scenario-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s3);
}
.scenario-card {
  border: 1px solid var(--ln); border-radius: var(--rs);
  background: var(--sf); padding: 16px 18px; position: relative;
}
.scenario-k {
  font-family: var(--fl); font-size: 10.5px; color: var(--mut);
  text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 8px;
}
/* keep a long eyebrow clear of the absolutely-positioned scenario chip */
.scenario-card:has(.scenario-chip) .scenario-k { padding-right: 92px; }
.scenario-card h3 {
  font-size: 30px; line-height: 1; letter-spacing: -0.02em;
  margin: 0 0 8px; font-weight: 700;
}
.scenario-card p { font-size: var(--t-sm); line-height: 1.45; color: var(--mut); margin: 0; }
.scenario-card h3 small { font-family: var(--fl); font-size: 12px; font-weight: 500; letter-spacing: 0; color: var(--mut); margin-left: 4px; }
/* the planning case is the recommended scenario → accent rule + accent chip, no fill */
.scenario-card.likely { box-shadow: inset 3px 0 0 var(--ac); }
.scenario-card.base h3 { color: var(--mut); }   /* de-emphasize the do-nothing / null case */
.scenario-chip {
  position: absolute; top: 14px; right: 14px;
  font-family: var(--fl); font-size: 9px; letter-spacing: 0.06em; text-transform: uppercase;
  background: var(--ac); color: var(--aci); padding: 3px 8px; border-radius: 999px;
}
.evidence-gallery {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s3);
}
.evidence-card {
  margin: 0; border: 1px solid var(--ln); border-radius: var(--rs);
  overflow: hidden; background: var(--sf);
}
.evidence-shot {
  min-height: 92px; display: grid; place-items: center;
  background: var(--sf2); color: var(--mut);
  font-family: var(--fl); font-size: 11px; letter-spacing: 0.05em;
  text-transform: uppercase;
}
.evidence-card.text-evidence {
  padding: 15px 16px;
  display: grid;
  gap: var(--s3);
}
.evidence-meta {
  display: flex;
  justify-content: space-between;
  gap: var(--s3);
  align-items: center;
  font-family: var(--fl);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--mut);
}
.evidence-meta b {
  color: var(--ac);
  font-weight: 500;
}
/* status chips — the module's one distinction (present vs. absent) made visible,
   colorblind/print-safe via the leading glyph */
.evidence-status {
  display: inline-flex; align-items: center; gap: var(--s1);
  font-family: var(--fl); font-size: 9px; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 3px 8px; border-radius: 999px;
}
.evidence-status.observed { background: var(--gds); color: var(--gd); }
.evidence-status.missing { background: var(--bds); color: var(--bd); }
/* draw the absence, don't just name it */
.evidence-missing {
  border: 1px dashed var(--bd); border-radius: var(--rs);
  padding: 11px 13px; display: grid; gap: 3px;
}
.evidence-missing .k {
  font-family: var(--fl); font-size: 9.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--bd);
}
.evidence-missing p { margin: 0; font-size: var(--t-sm); color: var(--bd); line-height: 1.4; }
.evidence-card blockquote {
  margin: 0;
  padding: 12px 14px;
  border-left: 3px solid var(--ln);
  background: var(--sf2);
  border-radius: var(--rs);
  font-size: var(--t-md);
  line-height: 1.45;
  color: var(--ink);
}
.evidence-card img {
  display: block; width: 100%; height: auto;
}
.evidence-card figcaption {
  padding: 13px 15px; display: grid; gap: var(--s1);
}
.evidence-card.text-evidence figcaption {
  padding: 0;
}
.evidence-card figcaption b { font-size: var(--t-body); }
.evidence-card figcaption span {
  font-size: var(--t-sm); line-height: 1.45; color: var(--mut);
}

.belief-map {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
}
.belief-stage {
  position: relative;
  border: 1px solid var(--ln); border-radius: var(--rs);
  background: var(--sf); padding: 18px 18px 20px;
  overflow: hidden;
}
.belief-stage::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0;
  height: 3px; background: var(--ln);
}
.belief-state {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  margin-bottom: 14px;
  font-family: var(--fl);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 650;
}
.belief-state::before {
  width: 18px;
  height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  font-family: var(--fb);
  font-size: 11px;
  line-height: 1;
}
/* No tinted cards. State is a SHAPE glyph (● established · ◐ partial · ○ missing)
   on a top rule; the missing belief is the actionable LEVER → the one accent stage. */
.belief-stage.established::before,
.belief-stage.done::before { background: var(--dt); }
.belief-stage.established .belief-state,
.belief-stage.done .belief-state { color: var(--mut); }
.belief-stage.established .belief-state::before,
.belief-stage.done .belief-state::before { content: "\25CF"; color: var(--ink); }   /* ● */
.belief-stage.partial::before { background: var(--dt2); }
.belief-stage.partial .belief-state { color: var(--mut); }
.belief-stage.partial .belief-state::before { content: "\25D0"; color: var(--ink); }   /* ◐ */
.belief-stage.missing,
.belief-stage.stuck {
  border-color: var(--ac);
}
.belief-stage.missing::before,
.belief-stage.stuck::before { background: var(--ac); }
.belief-stage.missing .belief-state,
.belief-stage.stuck .belief-state { color: var(--ac); }
.belief-stage.missing .belief-state::before,
.belief-stage.stuck .belief-state::before { content: "\25CB"; color: var(--ac); }   /* ○ — the lever */
.belief-stage h3 { font-size: var(--t-md); font-weight: 650; margin: 0 0 5px; }
.belief-stage p { font-size: var(--t-sm); color: var(--mut); line-height: 1.45; margin: 0; }

.checklist {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px 12px;
}
.check-item {
  border: 1px solid var(--ln); border-radius: var(--rs);
  background: var(--sf); padding: 12px 14px;
}
/* the three-state vocabulary is PRINTED: word + glyph + color, not a bare dot.
   Glyph carries the state with all color removed (colorblind / print safe). */
.check-state {
  display: inline-flex; align-items: center; gap: 5px; margin-bottom: 8px;
  font-family: var(--fl); font-size: 9px; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 3px 8px; border-radius: 999px;
}
.check-state::before { font-weight: 700; }
.check-item.done .check-state { background: var(--gds); color: var(--gd); }
.check-item.done .check-state::before { content: "\2713"; }      /* ✓ */
.check-item.partial .check-state { background: var(--wns); color: var(--wn); }
.check-item.partial .check-state::before { content: "\007E"; }   /* ~ */
.check-item.missing .check-state { background: var(--bds); color: var(--bd); }
.check-item.missing .check-state::before { content: "\2715"; }   /* ✕ — shape carries the state */
.check-item b { font-size: var(--t-body); display: block; }
.check-item p { margin: 3px 0 0; font-size: var(--t-sm); color: var(--mut); line-height: 1.4; }

.value-model {
  border: 1px solid var(--ln); border-radius: var(--rs);
  background: var(--sf); overflow: hidden;
}
.value-row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--s4); align-items: baseline;
  padding: 14px 16px; border-top: 1px solid var(--ln);
}
.value-row:first-child { border-top: none; }
.value-row span { font-size: var(--t-body); color: var(--mut); }
.value-row b {
  font-size: 20px; line-height: 1; font-weight: 700;
  letter-spacing: -0.02em;
}
.value-row.gain b { color: var(--gd); }
.value-row.loss b { color: var(--bd); }
.value-row.total {
  background: var(--sf2);
}
.value-row.total b { font-size: 26px; color: var(--ink); }

/* ============================================================================
   HEATMAP
   ========================================================================= */
.heat, .heatmap-table { border-collapse: collapse; font-size: 12px; }
.heat th, .heatmap-table th { font-family: var(--fl); font-size: 10px; color: var(--mut); font-weight: 500; padding: 6px 8px; text-align: center; letter-spacing: 0.03em; }
.heat th.row, .heatmap-table th.row { text-align: left; }
.heat td.row, .heatmap-table td.row { text-align: left; font-weight: 600; font-size: var(--t-sm); padding-right: 14px; white-space: nowrap; }
.heat td.cell, .heatmap-table td.cell { width: 64px; height: 38px; text-align: center; border: 2px solid var(--sf); color: var(--aci); font-family: var(--fl); font-size: 11px; }
.heat .h0, .heatmap-table .h0 { background: repeating-linear-gradient(45deg, var(--sf2), var(--sf2) 5px, var(--ln) 5px, var(--ln) 10px); color: var(--ink); }
.heat .h1, .heatmap-table .h1 { background: var(--dt3); color: var(--ink); }
.heat .h2, .heatmap-table .h2 { background: var(--dt2); }
.heat .h3, .heatmap-table .h3 { background: var(--dt); }
.src-note { font-family: var(--fl); font-size: 10.5px; color: var(--mut); margin-top: 12px; }

/* ============================================================================
   FUNNEL
   ========================================================================= */
.funnel, .funnel-chart { display: grid; grid-template-columns: 1fr 220px; gap: var(--s5); align-items: stretch; }
.funnel-stages { display: flex; flex-direction: column; gap: 0; justify-content: center; }
/* stage NAME lives in a left gutter; the bar carries only the % — no label can be
   mangled by a shrinking trapezoid */
.fstage-row { display: grid; grid-template-columns: 150px 1fr; gap: 14px; align-items: center; }
.fstage-name { font-size: var(--t-body); font-weight: 600; }
.fleak-chip {
  display: inline-block; margin-top: 6px;
  font-family: var(--fl); font-size: 9px; letter-spacing: 0.06em; text-transform: uppercase;
  background: var(--bds); color: var(--bd); padding: 3px 7px; border-radius: 999px;
}
.fbar { display: flex; align-items: center; gap: var(--s2); min-width: 0; }
/* plain proportional bar on a 100% track — one honest vocabulary, no trapezoid */
.fstage {
  height: 26px; background: var(--dt); color: var(--aci);
  border-radius: 5px;   /* squarer ends: a 7% stage stays a bar, not a blob */
  display: flex; align-items: center; justify-content: center;
  font-family: var(--fl); font-weight: 600; font-size: 11.5px; flex: 0 0 auto;
}
.fstage.leak { box-shadow: inset 4px 0 0 var(--bd); }   /* biggest leak = severity rule mark, not a red fill */
.fpct-out { font-family: var(--fl); font-size: 12px; font-weight: 600; color: var(--ink); }  /* % for a bar too thin to hold it */
/* step-to-step drop, annotated in the gap between bars, under the neck */
.fdrop { margin-left: 164px; text-align: center; font-family: var(--fl); font-size: 10.5px; color: var(--mut); padding: 4px 0; }
.fdrop.leak { color: var(--bd); }
.funnel-rail { display: flex; flex-direction: column; gap: 6px; }
.frail { padding: 12px 14px; border: 1px solid var(--ln); border-radius: var(--rs); background: var(--sf); }
.frail .pct { font-size: 22px; font-weight: 600; }
.frail .drop { font-family: var(--fl); font-size: 11px; color: var(--bd); }
.frail .lbl { font-size: 12px; color: var(--mut); }

/* ============================================================================
   QUADRANT / COMPETITIVE MAP
   ========================================================================= */
.quad-wrap, .competitive-map { display: grid; grid-template-columns: minmax(0, 1fr) 260px; gap: 22px; align-items: center; }
.quad {
  position: relative;
  aspect-ratio: 1.45/1;
  min-height: 260px;
  /* min-width:0 + max-width:100% stop the aspect-ratio from re-deriving a width
     from min-height (260×1.45≈377px) and overflowing a narrow grid column. */
  min-width: 0;
  max-width: 100%;
  border: 1px solid var(--ln);
  border-radius: var(--rs);
  background: color-mix(in srgb, var(--sf) 76%, var(--sf2));
  overflow: hidden;
}

/* ── Ported modules (restored from source): roadmap · message house · cluster map ── */
/* Roadmap — phased timeline (workstreams × time periods; bars carry duration via grid-column) */
.roadmap { display: grid; gap: 7px; font-family: var(--fl); }
.rm-head, .rm-row { display: grid; grid-template-columns: 130px 1fr; gap: 10px; align-items: center; }
.rm-periods, .rm-track { display: grid; grid-template-columns: repeat(var(--cols), 1fr); gap: 6px; }
.rm-period { font-size: 11px; letter-spacing: .04em; color: var(--mut); text-align: center; padding-bottom: 4px; border-bottom: 1px solid var(--ln); }
.rm-lane-label { font-size: var(--t-sm); color: var(--ink); font-weight: 600; }
.rm-bar { min-height: 30px; border-radius: var(--rs); background: var(--sf2); color: var(--ink); border: 1px solid var(--ln);
  display: flex; align-items: center; padding: 4px 9px; font-size: 12px; line-height: 1.2; }
.rm-bar.accent { background: var(--acs); border-color: var(--ac); color: var(--ac); font-weight: 600; }
.rm-bar.good { background: var(--gds); border-color: transparent; color: var(--gd); }
.rm-bar.warn { background: var(--wns); border-color: transparent; color: var(--wn); }
.rm-bar.bad  { background: var(--bds); border-color: transparent; color: var(--bd); }

/* Message house — positioning hierarchy: promise (roof) → pillars → proof (foundation) */
.msg-house { display: grid; gap: 10px; }
.mh-roof { background: var(--ink); color: var(--sf); text-align: center; padding: 14px 18px;
  border-radius: var(--r); font-size: var(--t-lg); font-weight: 600; line-height: 1.3; }
.mh-pillars { display: grid; grid-template-columns: repeat(var(--cols), 1fr); gap: 10px; }
.mh-pillar { border: 1px solid var(--ln); border-radius: var(--r); padding: 12px; background: var(--sf); }
.mh-pillar-head { font-weight: 600; font-size: var(--t-body); color: var(--ink);
  margin-bottom: 8px; padding-bottom: 8px; border-bottom: 2px solid var(--ac); }
.mh-proof { font-size: var(--t-sm); color: var(--mut); padding: 4px 0 4px 14px; position: relative; }
.mh-proof::before { content: "—"; position: absolute; left: 0; color: var(--ac); }
.mh-foundation { background: var(--sf2); border: 1px solid var(--ln); border-radius: var(--r);
  padding: 10px 14px; text-align: center; font-size: var(--t-sm); color: var(--mut); }

/* Cluster map — topic clusters: pillar (hub) → spokes (coverage by tone) */
.cluster-map { display: grid; gap: 18px; }
.cm-group { display: grid; gap: 10px; }
.cm-hub { justify-self: start; background: var(--ac); color: var(--aci); font-weight: 600;
  font-size: var(--t-body); padding: 8px 16px; border-radius: 999px; }
.cm-spokes { display: flex; flex-wrap: wrap; gap: 8px; padding-left: 18px; margin-left: 10px; border-left: 2px solid var(--ln); }
.cm-spoke { border: 1px solid var(--ln); border-radius: var(--rs); padding: 7px 11px; font-size: var(--t-sm); background: var(--sf); display: grid; gap: 2px; }
.cm-spoke b { color: var(--ink); font-weight: 600; }
.cm-spoke span { color: var(--mut); font-size: 11px; }
.cm-spoke.good { border-color: var(--gd); }
.cm-spoke.warn { border-color: var(--wn); }
.cm-spoke.bad  { border-left: 3px solid var(--bd); }

/* Competitive map needs ~377px for the plot + 260px for the verdict card; below
   that the two columns collide, so stack the verdict under the plot at tablet
   width (well before the generic 720px breakpoint). */
@media (max-width: 820px) {
  .quad-wrap, .competitive-map { grid-template-columns: 1fr; }
}
/* Below phone width the ~276px plot can't hold every point label without
   collisions, so drop the competitor names and keep only You + the target
   (the sanctioned "label 1-5 when crowded" rule). Dots still show the cluster;
   the verdict card + tier bands carry the named peers. */
@media (max-width: 480px) {
  .quad .dot:not(.you):not(.target) .nm { display: none; }
}
.quad .target-zone {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 50%;
  left: 50%;
  background: var(--acs);
  opacity: .55;
}
.quad .axis-x, .quad .axis-y { position: absolute; font-family: var(--fl); font-size: 10.5px; color: var(--mut); }
.quad .axis-x { bottom: 8px; left: 50%; transform: translateX(-50%); }
.quad .axis-y { top: 50%; left: 8px; transform: translateY(-50%) rotate(-90deg); transform-origin: left; }
.quad .midline-h { position: absolute; left: 0; right: 0; top: 50%; border-top: 1px dashed var(--ln); }
.quad .midline-v { position: absolute; top: 0; bottom: 0; left: 50%; border-left: 1px dashed var(--ln); }
.quad .q-label {
  position: absolute;
  z-index: 1;
  font-family: var(--fl);
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--mut);
}
.quad .q-label.top-left { top: 13px; left: 24px; }   /* clears the rotated y-axis label */
.quad .q-label.top-right { top: 13px; right: 14px; color: var(--ac); font-weight: 600; }
.quad .q-label.bottom-left { bottom: 34px; left: 24px; }
.quad .q-label.bottom-right { bottom: 34px; right: 14px; }
.dot { position: absolute; transform: translate(-50%,-50%); text-align: center; }
.dot .pt { width: 12px; height: 12px; border-radius: 999px; background: var(--mut); margin: 0 auto 4px; opacity: .5; }
.dot .nm { font-size: 11px; color: var(--mut); opacity: .65; }
.dot.you .pt { background: var(--ac); box-shadow: 0 0 0 6px var(--acs); opacity: 1; }
.dot.you .nm { color: var(--ac); font-weight: 600; opacity: 1; }
.dot.target .pt {
  width: 14px;
  height: 14px;
  background: var(--sf);
  border: 2px solid var(--ac);
  box-shadow: 0 0 0 5px var(--acs);
  opacity: 1;
}
.dot.target .nm { color: var(--ink); font-weight: 650; opacity: 1; }
.verdict-card { background: var(--sf); border: 1px solid var(--ln); border-radius: var(--rs); padding: 16px 18px; }
.verdict-card .vh { font-size: 17px; font-weight: 600; margin: 0 0 8px; line-height: 1.3; }
.verdict-card p { font-size: var(--t-body); color: var(--mut); margin: 0; line-height: 1.5; }

/* ============================================================================
   ACTION PLAN
   ========================================================================= */
.action {
  display: grid; grid-template-columns: 92px 1fr;
  gap: 18px;
  padding: 17px 18px;
  border: 1px solid var(--ln);
  border-radius: var(--rs);
  background: var(--sf);
  align-items: center;
  margin-top: 12px;
}
.action:first-of-type { margin-top: 0; }
.action .rank { display: none; }
.action .meta { text-align: left; min-width: 0; }
/* The impact value is the anchor: a COMPACT numeric magnitude (+12, +1.8%, −24%)
   rendered large. overflow-wrap guards against a stray long value spilling into the
   body — but long values belong in `.pts.label` (below), not here. */
.action .pts {
  display: block;
  color: var(--gd);
  font-weight: 750;
  font-size: 28px;
  line-height: 1;
  letter-spacing: -0.02em;
  overflow-wrap: anywhere;
}
/* Qualitative impact — for reports with no point system (recommendation, generated
   asset, sometimes benchmark): a short label, NOT a 28px number. Reads as a category
   tag, fits the column, and doesn't imply a numeric gain. Keep it ≤ ~12 chars. */
.action .pts.label {
  font-family: var(--fl); font-size: 12px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--mut); line-height: 1.3;
}
.action .pts small { font-size: 12px; font-weight: 600; color: var(--mut); letter-spacing: 0.02em; margin-left: 2px; }
.action .time { font-family: var(--fl); font-size: 11.5px; color: var(--mut); margin-top: 5px; }
.action .atitle { font-size: 17px; font-weight: 650; margin: 0 0 5px; line-height: 1.3; }
.action .closes { font-family: var(--fl); font-size: 11.5px; color: var(--ac); }
.action .why { font-size: var(--t-body); color: var(--mut); margin: 6px 0 0; line-height: 1.5; max-width: 64ch; }

/* ============================================================================
   BOTTOM LINE  (closing strip — verdict recap + the single next step)
   Bookends the argument: the last thing a skimmer reads restates the verdict
   and names the one move to start with. Follows the action plan in slot order.
   ========================================================================= */
.bottom-line { display: grid; gap: 7px; max-width: 74ch; }
.bl-verdict { font-size: 18px; font-weight: 650; letter-spacing: -0.01em; line-height: 1.4; margin: 0; }
.bl-next { font-size: var(--t-body); color: var(--mut); line-height: 1.55; margin: 0; }
.bl-next b { color: var(--ink); font-weight: 600; }

/* Sheet foot — quiet provenance strip closing the sheet (mirrors the masthead so
   an exported PDF's last page still names the subject). Not a numbered section. */
.sheet-foot {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--s4); flex-wrap: wrap;
  padding: 16px 36px;
  border-top: 1px solid var(--ln);
  background: var(--sf2);
  font-family: var(--fl); font-size: 11px; letter-spacing: 0.05em;
  color: var(--mut);
}

/* ============================================================================
   GENERATED ASSET
   ========================================================================= */
.asset { background: var(--sf2); border: 1px solid var(--ln); border-radius: var(--r); padding: 26px 28px; }
.asset-head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--s4); margin-bottom: 16px; }
.asset .alogic { font-family: var(--fl); font-size: 10.5px; color: var(--mut); text-transform: uppercase; letter-spacing: 0.07em; line-height: 1.5; margin: 0; min-width: 0; }
/* Asset sub-headings sit BELOW the module title (.mod-title, 20px) in the hierarchy —
   they label sections inside the artifact, so they read as content, not a competing
   title. (A single-artifact asset with its own headline can still bump this locally.) */
.asset h3 { font-size: 19px; font-weight: 650; margin: 0 0 6px; letter-spacing: -0.01em; }
.asset h3 + h3, .asset p + h3 { margin-top: 18px; }   /* breathing room between stacked artifact sections */
.asset .asub { font-size: var(--t-md); color: var(--mut); margin: 0 0 18px; }
.asset p { font-size: var(--t-md); color: var(--ink); line-height: 1.6; margin: 0 0 12px; }
.asset p:last-child { margin-bottom: 0; }
.asset ol, .asset ul { margin: 0; padding-left: 20px; }
.asset li { font-size: var(--t-md); line-height: 1.6; margin-bottom: 7px; }
.asset .copy { flex: 0 0 auto; background: var(--ink); color: var(--aci); border: none; border-radius: 8px; padding: 7px 14px; font-size: 12px; font-weight: 600; font-family: var(--fb); cursor: pointer; }

/* ============================================================================
   BORROWED MODULES  (ported to Meter tokens — see Report Module Library)
   ========================================================================= */

/* ---- through-line: module shell (numbered tag · title · count badge) ---- */
.mod-shell { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 16px; }
.mod-tag { flex: 0 0 auto; font-family: var(--fl); font-size: var(--t-sm); font-weight: 600; color: var(--aci); background: var(--ink); border-radius: 7px; padding: 6px 9px; line-height: 1; }
.mod-title { font-size: 20px; line-height: 1.25; letter-spacing: -0.01em; font-weight: 650; margin: 1px 0 0; }
.mod-count { margin-left: auto; flex: 0 0 auto; font-family: var(--fl); font-size: 11px; letter-spacing: 0.04em; color: var(--c4); background: var(--wns); border-radius: 999px; padding: 6px 12px; line-height: 1; align-self: flex-start; }

/* ---- FIX FIRST card (navy "act here" hero — once per report) ---- */
.fixfirst { background: var(--ac); color: var(--aci); border-radius: var(--r); padding: 28px 30px; }
.ff-top { display: flex; justify-content: space-between; align-items: center; gap: var(--s4); }
.ff-eyebrow { font-family: var(--fl); font-size: 12px; text-transform: uppercase; letter-spacing: 0.14em; color: color-mix(in srgb, var(--c4) 62%, white); margin: 0; }
.ff-pill { font-family: var(--fl); font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase; font-weight: 600; color: var(--ac); background: color-mix(in srgb, var(--c4) 72%, white); padding: 6px 13px; border-radius: 999px; white-space: nowrap; }
.ff-title { font-size: 27px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.15; margin: 15px 0 0; max-width: 24ch; }
.ff-rule { height: 1px; background: color-mix(in srgb, white 20%, transparent); margin: 18px 0; }
.ff-rows { display: grid; gap: 13px; }
.ff-row { display: grid; grid-template-columns: 78px 1fr; gap: 18px; align-items: baseline; }
.ff-k { font-family: var(--fl); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: color-mix(in srgb, var(--c4) 62%, white); }
.ff-v { font-size: var(--t-lg); line-height: 1.5; color: color-mix(in srgb, white 90%, var(--ac)); }

/* ---- Now / Next / Later lanes (priority glyph fades full → half → hollow) ---- */
.lanes { display: grid; gap: 10px; }
.lane { display: grid; grid-template-columns: 210px 1fr; gap: 20px; border: 1px solid var(--ln); border-radius: var(--rs); background: var(--sf); padding: 16px 18px; }
.lane-when { display: grid; gap: var(--s1); align-content: start; }
.lane-when b { display: inline-flex; align-items: center; gap: 10px; font-size: var(--t-lg); font-weight: 650; color: var(--ink); }
.lane-when b::before { content: ""; width: 13px; height: 13px; border-radius: 999px; flex: 0 0 auto; }
.lane.now b::before { background: var(--ink); }
.lane.next b::before { background: linear-gradient(90deg, var(--ink) 50%, var(--dt3) 50%); }
.lane.later b::before { background: transparent; border: 1.5px solid var(--dt3); }
.lane-sub { font-family: var(--fl); font-size: 11px; color: var(--mut); line-height: 1.45; }
.lane-moves { display: grid; align-content: start; }
.lane-move { font-size: var(--t-body); color: var(--ink); padding: 8px 0; border-top: 1px solid var(--ln); }
.lane-move:first-child { border-top: none; padding-top: 1px; }
.lane.later .lane-move { color: var(--mut); }

/* ---- Priority list with status + chevron (one navy accent on #1) ---- */
.plist { display: grid; }
.plist-row { display: grid; grid-template-columns: 28px minmax(0, 1fr) auto auto 16px; gap: 18px; align-items: center; padding: 16px 2px; border-top: 1px solid var(--ln); }
.plist-row:first-child { border-top: none; }
.plist-n { font-family: var(--fl); font-size: var(--t-md); color: var(--mut); }
.plist-title { font-size: 17px; font-weight: 650; letter-spacing: -0.01em; color: var(--ink); }
.plist-time { font-family: var(--fl); font-size: 12px; color: var(--mut); white-space: nowrap; }
.plist-status { font-family: var(--fl); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; padding: 5px 11px; border-radius: 999px; white-space: nowrap; }
.plist-status.first { background: var(--ac); color: var(--aci); }
.plist-status.std { background: var(--sf2); color: var(--mut); }
.plist-status.later { background: transparent; border: 1px solid var(--ln); color: var(--mut); }
.plist-chev { color: var(--dt3); font-size: 17px; line-height: 1; }

/* ---- capability matrix helpers (feature rows × competitor columns) ---- */
.matrix th { text-align: center; }
.matrix th.row, .matrix td.row { text-align: left; }
.matrix td.c { text-align: center; }
.matrix td.c .evidence-mark { justify-content: center; }
.matrix th.youcol, .matrix td.youcol { background: var(--acs); }   /* the "you" column = navy tint (selection) */

/* ============================================================================
   CHAT CLOSER  (separate card)
   ========================================================================= */
.chat {
  margin-top: 32px; background: var(--sf); border: 1px solid var(--ln);
  border-radius: var(--r); box-shadow: var(--sh); padding: 24px 26px;
}
.chat-head { display: flex; align-items: center; gap: var(--s3); margin-bottom: 14px; }
.avatar { width: 40px; height: 40px; border-radius: 999px; background: var(--ac); color: var(--aci); display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: var(--t-lg); }
.chat-head .nm { font-weight: 600; font-size: var(--t-md); }
.chat-head .st { font-family: var(--fl); font-size: 11px; color: var(--gd); }
.chat-head .tag { font-size: var(--t-sm); color: var(--mut); }
.chat-opener { font-size: var(--t-md); line-height: 1.55; background: var(--sf2); border-radius: var(--rs); padding: 14px 16px; margin-bottom: 14px; }
.chips { display: flex; gap: var(--s2); flex-wrap: wrap; margin-bottom: 14px; }
.chip { background: transparent; border: 1px solid var(--ln); border-radius: 999px; padding: 7px 14px; font-size: var(--t-sm); cursor: pointer; font-family: var(--fb); color: var(--ink); }
.chip:hover { border-color: var(--ac); color: var(--ac); }
.chat-input { display: flex; gap: 10px; }
.chat-input input { flex: 1; border: 1px solid var(--ln); border-radius: 8px; padding: 11px 14px; font-size: var(--t-body); font-family: var(--fb); }
.chat-input button { background: var(--ink); color: var(--aci); border: none; border-radius: 8px; padding: 0 22px; font-weight: 600; font-size: var(--t-body); font-family: var(--fb); cursor: pointer; }

/* ============================================================================
   STICKY CHAT COMPOSER  (persistent report companion)
   Add .has-sticky-chat to body when this component is present.
   ========================================================================= */
/* the page only reserves the resting pill's height, so at most one line of a
   module can ever sit behind the composer */
.has-sticky-chat .wrap { padding-bottom: 92px; }
.sticky-chat {
  position: fixed;
  left: 50%; bottom: 22px; transform: translateX(-50%);
  z-index: 20;
  width: min(680px, calc(100vw - 32px));
  background: var(--sf); border: 1px solid var(--ln);
  box-shadow: var(--shl);
  /* RESTING: a slim ~44px pill — avatar + prompt + send. Anchored at the bottom
     so the expanded card grows UPWARD. */
  border-radius: 999px;
  padding: 6px 6px 6px 8px;
  transition: border-radius .12s ease, padding .12s ease;
}
.sticky-chat.expanded {
  /* COMPOSING: the full card, only while focused */
  border-radius: var(--r);
  padding: 14px;
}
/* head + chips belong to the expanded state only */
.sticky-chat-head,
.sticky-chat-chips { display: none; }
.sticky-chat.expanded .sticky-chat-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3); margin-bottom: 10px;
}
.sticky-chat.expanded .sticky-chat-chips { display: flex; margin-bottom: 10px; }
/* mini avatar rides in the resting pill; hidden once expanded (the head shows the full one) */
.sticky-chat-mini {
  width: 30px; height: 30px; border-radius: 999px; flex: 0 0 auto;
  background: var(--ac); color: var(--aci);
  display: flex; align-items: center; justify-content: center;
  font-size: var(--t-sm); font-weight: 600;
}
.sticky-chat.expanded .sticky-chat-mini { display: none; }
.sticky-chat-form { display: flex; gap: var(--s2); align-items: center; }
.sticky-chat-brand { display: flex; align-items: center; gap: 9px; min-width: 0; }
.sticky-chat-avatar {
  width: 28px; height: 28px; border-radius: 999px;
  background: var(--ac); color: var(--aci);
  display: flex; align-items: center; justify-content: center;
  font-size: var(--t-sm); font-weight: 600; flex: 0 0 auto;
}
.sticky-chat-name { font-size: var(--t-body); font-weight: 600; line-height: 1.1; }
.sticky-chat-status {
  font-family: var(--fl); font-size: 10.5px; color: var(--gd);
  margin-left: 5px; font-weight: 400;
}
.sticky-chat-context {
  font-family: var(--fl); font-size: 10.5px; letter-spacing: 0.06em;
  color: var(--mut); text-transform: uppercase;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sticky-chat-chips {
  gap: var(--s2); overflow-x: auto; scrollbar-width: none;
}
.sticky-chat-chips::-webkit-scrollbar { display: none; }
.sticky-chat-chip {
  border: 1px solid var(--ln); background: transparent; color: var(--ink);
  border-radius: 999px; padding: 6px 11px;
  font-family: var(--fb); font-size: 12px; line-height: 1;
  white-space: nowrap; cursor: pointer;
}
.sticky-chat-chip:hover { border-color: var(--ac); color: var(--ac); }
/* input + send: a pill while resting, square + labeled while composing */
.sticky-chat-form input {
  flex: 1; min-width: 0; border: 1px solid var(--ln);
  border-radius: 999px; padding: 10px 14px;
  font-family: var(--fb); font-size: var(--t-body);
}
.sticky-chat.expanded .sticky-chat-form input { border-radius: 8px; padding: 10px 12px; }
.sticky-chat-form button {
  flex: 0 0 auto; min-height: 40px; width: 40px; padding: 0; border-radius: 999px;
  border: 1px solid var(--ink); background: var(--ink); color: var(--aci);
  font-family: var(--fb); font-size: var(--t-sm); font-weight: 600; cursor: pointer;
}
.sticky-chat-form button .send-label { display: none; }
.sticky-chat-form button::after { content: "\2191"; font-size: var(--t-lg); }   /* ↑ while resting */
.sticky-chat.expanded .sticky-chat-form button { width: auto; padding: 0 16px; border-radius: 8px; }
.sticky-chat.expanded .sticky-chat-form button .send-label { display: inline; }
.sticky-chat.expanded .sticky-chat-form button::after { content: none; }

@media (min-width: 1880px) {
  .sticky-chat {
    left: auto; right: max(24px, calc((100vw - 1140px) / 2 - 360px));
    bottom: auto; top: 118px; transform: none; width: 330px;
  }
  .sticky-chat.expanded .sticky-chat-head { align-items: flex-start; flex-direction: column; }
  .sticky-chat.expanded .sticky-chat-chips { flex-wrap: wrap; overflow: visible; }
  .sticky-chat.expanded .sticky-chat-form { flex-direction: column; align-items: stretch; }
  .sticky-chat.expanded .sticky-chat-form button { width: 100%; }
}

/* ============================================================================
   CLOSER BAR  (separate card, varied actions)
   ========================================================================= */
.closer { margin-top: 16px; display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap; background: var(--sf); border: 1px solid var(--ln); border-radius: var(--r); box-shadow: var(--sh); padding: 16px 22px; }
.closer .lead { font-size: var(--t-body); color: var(--mut); flex: 1; min-width: 180px; }
.closer .btns { display: flex; gap: 10px; flex-wrap: wrap; }
.btn-out { background: transparent; border: 1px solid var(--ink); color: var(--ink); border-radius: 8px; padding: 9px 16px; font-size: var(--t-sm); font-weight: 600; font-family: var(--fb); cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; justify-content: center; min-height: 40px; }
.btn-fill { background: var(--ink); border: 1px solid var(--ink); color: var(--aci); border-radius: 8px; padding: 9px 16px; font-size: var(--t-sm); font-weight: 600; font-family: var(--fb); cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; justify-content: center; min-height: 40px; }

@media print {
  @page {
    size: auto;
    margin: 14mm 12mm;
  }
  body { background: var(--sf); }
  .wrap { max-width: none; padding: 0; }
  .sheet { box-shadow: none; border-color: var(--ink); }
  .masthead { margin: 0 0 8mm; }
  .sticky-chat, .closer, .copy, .chat, .softgate { display: none !important; }
  .has-sticky-chat .wrap { padding-bottom: 0; }
  .sheet > section,
  .module,
  .hero,
  .finding,
  .action,
  .asset,
  .revision-pair,
  .priority-matrix,
  .risk-row,
  .scenario-card,
  .evidence-card,
  .belief-stage,
  .check-item,
  .value-model,
  .quad-wrap,
  .funnel {
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .module-findings,
  .module-action-plan { break-before: auto; }
  /* The scroll container's edge gradients are a horizontal-scroll affordance;
     on paper they print as grey smudges. Widths are fine as-is: the PDF renderer
     lays out at the 960px design width and scales to the page, so the 680px
     table floor never overflows (see lib/report-print-document.ts). */
  .module-scroll { overflow: visible; background: none; }
  a { color: inherit; text-decoration: none; }
  .ev-block, .bottom-line { break-inside: avoid; page-break-inside: avoid; }
  /* Collapsed <details> content never prints (Chrome ignores CSS reveals on the
     closed slot) — reports must also ship the beforeprint hook that sets [open]
     on every details element (see components.html #compose). Belt for browsers
     that do honor it: */
  details > * { display: block; }
  .sheet-foot { background: none; }
}

/* ---- responsive ---- */
@media (max-width: 720px) {
  .assess-grid, .funnel, .quad-wrap,
  .composition-grid, .trend-row, .revision-pair,
  .decision-branches, .priority-matrix, .scenario-grid,
  .evidence-gallery, .belief-map, .checklist { grid-template-columns: 1fr; }
  /* stacked decision branches drop the org-chart connectors (they only read in 2 columns) */
  .decision-q { max-width: none; }
  .decision-branches { margin-top: var(--s3); }
  .decision-q::after, .decision-branches::before, .decision-branch::before { display: none; }
  /* Wide evidence tables stay horizontally scrollable (never break the page), but
     the first column — the row's identity — pins so the verdict columns scrolled
     into view keep their context. Pair with column order that puts Severity/Score
     right after the first column so the verdict shows before the reader scrolls
     (see Design a Report §7). Heatmaps keep plain horizontal scroll. */
  .module-scroll > .tbl { min-width: 560px; }
  .module-scroll .tbl th:first-child,
  .module-scroll .tbl td:first-child {
    position: sticky; left: 0; z-index: 1;
    background: var(--sf); box-shadow: 1px 0 0 var(--ln);
  }
  .module-scroll .tbl tr.subtotal td:first-child { background: var(--sf2); }
  /* Capability matrix: "you" is the reference, so pin the YOU column beside the
     feature column — both stay put while rival columns scroll. The feature column
     gets a fixed width so the youcol's sticky offset lands correctly. */
  .module-scroll .matrix th.row, .module-scroll .matrix td.row { width: 132px; min-width: 132px; }
  .module-scroll .matrix th.youcol, .module-scroll .matrix td.youcol {
    position: sticky; left: 132px; z-index: 1;   /* youcol already carries the --acs tint (opaque) */
    box-shadow: 1px 0 0 var(--ln);
  }
  /* module shell: let the count badge drop below a long title instead of squeezing it */
  .mod-shell { flex-wrap: wrap; }
  .mod-shell .mod-count { order: 3; margin: 8px 0 0 46px; }
  /* hero → un-float the capsule and stack: company, byline, then the WORDED verdict
     (question + headline + body), then the capsule. The reader gets the answer in
     words before the number — the capsule closes the hero instead of opening it. */
  .hero { display: flex; flex-direction: column; }
  .hero > .verdict,
  .hero > .score-zone,
  .hero > .rank-zone,
  .hero > .match-zone,
  .hero > .tier-zone,
  .hero > .asset-zone { float: none; width: auto; margin: 20px 0 0; order: 3; }
  .hero > .company, .hero > .expert-byline { order: 1; }
  .hero > .hero-body { order: 2; }
  .hero h1 { font-size: 32px; }
  .sheet > section, .hero { padding: 24px 20px; }
  .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rank-bar, .rank-threshold-row {
    grid-template-columns: 20px minmax(72px, 1fr) minmax(104px, 1.6fr) 42px;
    gap: 8px;
  }
  .tier-band { grid-template-columns: 38px minmax(0, 1fr); }
  .tier-delta, .tier-verdict { grid-column: 2; justify-self: start; }
  .bullet-row, .deviation-row, .range-row, .bridge-row,
  .spread-row, .risk-row {
    grid-template-columns: 1fr;
    gap: 7px;
  }
  .deviation-scale {
    grid-template-columns: 1fr;
    gap: var(--s1);
  }
  .deviation-scale > span { display: none; }
  .deviation-note { margin-left: 0; }
  .risk-row b, .risk-fix { text-align: left; }
  .quad { min-height: 240px; aspect-ratio: 1.25/1; }
  .quad .q-label { font-size: 8px; }
  .evidence-shot { min-height: 120px; }
  .value-row { grid-template-columns: 1fr; gap: 5px; }
  .flow-lane { grid-template-columns: 1fr; gap: 6px; }
  /* borrowed modules */
  .lane { grid-template-columns: 1fr; gap: 10px; }
  .ff-row { grid-template-columns: 1fr; gap: 3px; }
  .plist-row {
    grid-template-columns: 24px minmax(0, 1fr) auto;
    grid-template-areas: "n title status" ". meta meta";
    gap: 4px 12px;
  }
  .plist-n { grid-area: n; }
  .plist-title { grid-area: title; }
  .plist-status { grid-area: status; }
  .plist-time { grid-area: meta; }
  .plist-chev { display: none; }
  .action {
    grid-template-columns: 1fr;
    gap: var(--s2);
  }
  .action .meta {
    display: flex; align-items: baseline; gap: 10px;
  }
  .action > div:last-child { grid-column: 1 / -1; }
  .finding-fix {
    grid-template-columns: 1fr auto;
    gap: 5px 8px;
  }
  .finding-fix .fix-k { grid-column: 1 / -1; }
  .bullet-value, .deviation-value, .range-value, .bridge-row b { text-align: left; }
  .sparkline { height: 56px; }
  .venn { grid-template-columns: 1fr; gap: 10px; padding: 24px 18px 56px; justify-items: center; }
  .venn-left, .venn-right { text-align: center; }
  .radar-wrap { grid-template-columns: 1fr; gap: 14px; }
  /* C9 — on mobile the polygon's 10px axis labels strain, and the readable
     numbers live in the value list. Lead with the value list; demote + cap the
     polygon to a supporting glyph below it. */
  .radar-legend { order: -1; }
  .radar { max-width: 300px; }
  .donut-wrap { grid-template-columns: 1fr; gap: var(--s4); justify-items: center; }
  .priority-frame { grid-template-columns: 1fr; }
  .pm-col-heads, .pm-row-heads { display: none; }
  .fstage-row { grid-template-columns: 104px 1fr; }
  .fdrop { margin-left: 118px; }
  .has-sticky-chat .wrap { padding-bottom: 84px; }
  .sticky-chat {
    left: 10px; right: 10px; bottom: 10px;
    width: auto; transform: none; padding: 6px 6px 6px 8px;
  }
  .sticky-chat.expanded { padding: 12px; }
  .sticky-chat-head { margin-bottom: 8px; }
  .sticky-chat-context { display: none; }
  .sticky-chat-form input { font-size: var(--t-lg); }
  .sticky-chat-form button { padding: 0 13px; }
}

/* Phone-width hero headline — fixed step (not viewport-scaled), per Design a
   Report §3.1 (~27px below 430px). The 720px block already drops it to 32px. */
@media (max-width: 430px) {
  .hero h1 { font-size: 27px; }
}

/* =====================================================================
 * Visual-summary forms — the hero verdict visual.
 * One module, several forms; the form should match the answer type
 * (see "Report Module Library → Visual Summary"). `bars` (.moats/.moat-*,
 * defined far above) is the default 2-bar comparison; the forms below are
 * the purpose-specific alternatives. All colour via tokens. Magnitude is
 * slate (--dt); judgment uses --gd/--wn/--bd; navy (--ac) is selection/match.
 * Because the visual summary lives in the hero (the one screenshot-first
 * surface), hue may track the verdict here (the sanctioned §2 exception).
 * ===================================================================== */
.vs-cap { font-size: 12px; color: var(--mut); margin: 12px 0 0; max-width: 74ch; line-height: 1.5; }

/* breakdown — 2–3 component sub-scores that make up a headline score (diagnostic) */
.vs-breakdown { display: grid; gap: var(--s3); }
.vs-bd-row { display: grid; grid-template-columns: 150px 1fr 64px; gap: var(--s4); align-items: center; }
.vs-bd-label { font-size: var(--t-body); font-weight: 600; }
.vs-bd-track { background: var(--sf2); border-radius: 999px; height: 12px; overflow: hidden; }
/* Magnitude stays slate even in the hero — judgment rides on the value (colored
   number), matching the body's deviation-bar discipline. Full sentiment fills read
   dashboard, not analyst; the single verdict capsule keeps the monopoly on hue. */
.vs-bd-fill { display: block; height: 100%; border-radius: 999px; background: var(--dt); }
.vs-bd-fill.good, .vs-bd-fill.warn, .vs-bd-fill.bad { background: var(--dt); }
.vs-bd-val { font-family: var(--fl); font-size: var(--t-body); font-weight: 600; text-align: right; }
.vs-bd-val small { color: var(--mut); font-weight: 400; }
.vs-bd-row:has(.vs-bd-fill.good) .vs-bd-val { color: var(--gd); }
.vs-bd-row:has(.vs-bd-fill.warn) .vs-bd-val { color: var(--wn); }
.vs-bd-row:has(.vs-bd-fill.bad)  .vs-bd-val { color: var(--bd); }
.vs-bd-row:has(.vs-bd-fill.bad)  .vs-bd-fill { background: var(--ink); }  /* the verdict's driver reads darkest, not loudest */

/* tiers — segmented mini-bar marking the current type/tier (classification) */
.vs-tiers { display: grid; gap: 9px; }
.vs-seg-bar { display: flex; gap: 6px; }
.vs-seg { flex: 1; height: 12px; border-radius: 3px; background: var(--sf2); }
.vs-seg.on { background: var(--ac); }
.vs-seg-labels { display: flex; gap: 6px; }
.vs-seg-labels span { flex: 1; font-family: var(--fl); font-size: 10.5px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--mut); text-align: center; }
.vs-seg-labels span.here { color: var(--ac); font-weight: 600; }

/* delta — you-vs-peer signed bars around a centered baseline (rank / benchmark) */
.vs-delta { display: grid; gap: var(--s3); }
.vs-delta-row { display: grid; grid-template-columns: 150px 1fr 52px; gap: var(--s4); align-items: center; }
.vs-delta-label { font-size: var(--t-body); font-weight: 600; }
.vs-delta-track { position: relative; height: 14px; background: var(--sf2); border-radius: 5px; }
.vs-delta-axis { position: absolute; left: 50%; top: 0; bottom: 0; width: 1.5px; background: var(--ink); }
/* Slate fills, signed colored values — same discipline as the body deviation module. */
.vs-delta-fill { position: absolute; top: 3px; bottom: 3px; border-radius: 3px; background: var(--dt); }
.vs-delta-fill.pos { background: var(--dt); }
.vs-delta-fill.neg { background: var(--dt); }
.vs-delta-val { font-family: var(--fl); font-size: var(--t-body); font-weight: 600; text-align: right; }
.vs-delta-val.pos { color: var(--gd); }
.vs-delta-val.neg { color: var(--bd); }

/* meter — one score on a banded safe→exposed track (risk / readiness) */
.vs-meter { display: grid; gap: 9px; padding-top: 14px; }
.vs-meter-track { position: relative; display: flex; height: 22px; border-radius: 6px; overflow: visible; }
.vs-meter-band { height: 100%; }
.vs-meter-band:first-child { border-radius: 6px 0 0 6px; }
.vs-meter-band:last-child { border-radius: 0 6px 6px 0; }
.vs-meter-band.good { background: var(--gds); }
.vs-meter-band.warn { background: var(--wns); }
.vs-meter-band.bad  { background: var(--bds); }
.vs-meter-marker { position: absolute; top: -4px; bottom: -4px; width: 3px; background: var(--ink); transform: translateX(-50%); }
.vs-meter-val { position: absolute; top: -18px; left: 50%; transform: translateX(-50%); font-family: var(--fl); font-size: 12px; font-weight: 600; }
.vs-meter-labels { display: flex; justify-content: space-between; font-family: var(--fl); font-size: 10.5px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--mut); }

/* ring — match/fit proportion ring; navy arc is the match anchor (recommendation) */
.vs-ring { display: flex; align-items: center; gap: 22px; }
.vs-ring .donut { width: 116px; max-width: 116px; margin: 0; flex: none; }
.vs-ring-text b { display: block; font-size: 17px; font-weight: 650; }
.vs-ring-text span { font-size: var(--t-sm); color: var(--mut); }

/* versus — chosen option vs. its alternatives (recommendation); navy bar = the pick.
   Shows the decision gap, which the hero match-% anchor does not — never echo the anchor. */
.vs-versus { display: grid; gap: var(--s3); }
.vs-vs-row { display: grid; grid-template-columns: 170px 1fr 48px; gap: var(--s4); align-items: center; }
.vs-vs-label { font-size: var(--t-body); font-weight: 500; color: var(--mut); display: flex; align-items: center; gap: var(--s2); }
.vs-vs-row.pick .vs-vs-label { color: var(--ink); font-weight: 700; }
.vs-vs-chip { font-family: var(--fl); font-size: 9.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--aci); background: var(--ac); padding: 3px 8px; border-radius: 999px; }
.vs-vs-track { background: var(--sf2); border-radius: 999px; height: 18px; overflow: hidden; }
.vs-vs-fill { display: block; height: 100%; border-radius: 999px; background: var(--dt2); }
.vs-vs-row.pick .vs-vs-fill { background: var(--ac); }
.vs-vs-val { font-family: var(--fl); font-size: var(--t-body); font-weight: 600; text-align: right; color: var(--mut); }
.vs-vs-row.pick .vs-vs-val { color: var(--ac); }

/* inside — "what's inside" list of the produced artifact (generated asset) */
.vs-inside { display: grid; gap: 0; }
.vs-inside-item { display: flex; gap: 14px; align-items: baseline; padding: 9px 0; border-bottom: 1px solid var(--ln); }
.vs-inside-item:last-child { border-bottom: 0; }
.vs-inside-n { font-family: var(--fl); font-size: 12px; color: var(--ac); font-weight: 600; }
.vs-inside-label { font-size: var(--t-body); font-weight: 500; }

@media (max-width: 720px) {
  .vs-bd-row, .vs-delta-row, .vs-vs-row { grid-template-columns: 1fr; gap: var(--s1); }
  .vs-bd-val, .vs-delta-val, .vs-vs-val { text-align: left; }
  .vs-ring { flex-direction: column; align-items: flex-start; gap: 14px; }
}

/* ════════════════════════════════════════════════════════════════════════
   EXTENSION · (b) unified numbered section headers + (a) delivery-ownership
   routing + builderGoal toggle.  Additive & backward-compatible: a plain
   `.eyebrow` with no children still renders; existing reports are unaffected
   except for a slightly-less-quiet eyebrow.
   ════════════════════════════════════════════════════════════════════════ */

/* (b) Eyebrow — a bit less quiet, and now the ONE standard section-header label
   used on every section (spine + modules). Keeps mono/uppercase restraint. */
.eyebrow {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  color: color-mix(in srgb, var(--ink) 82%, var(--mut));
  font-weight: 600;
  font-size: 12.5px;
}
/* continuous section number — small ink chip that gives the eyebrow presence */
.eyebrow-n {
  flex: 0 0 auto;
  font-family: var(--fl); font-size: 11px; font-weight: 600; line-height: 1;
  color: var(--aci); background: var(--ink);
  border-radius: 6px; padding: 5px 7px; letter-spacing: 0.02em;
}
/* the muted qualifier/takeaway that trails the label on the same line */
.eyebrow-take { color: var(--mut); font-weight: 500; text-transform: none; letter-spacing: 0; }

/* The interpretive section title — the "what it concludes" headline that sits
   under the numbered label on analytical modules and heavier spine sections. */
.section-title {
  font-size: 20px; line-height: 1.25; letter-spacing: -0.01em; font-weight: 650;
  margin: 0 0 14px; max-width: 62ch;
}
.eyebrow + .section-title { margin-top: -4px; }

/* (a) Action CTA — WHO acts on a recommendation, as a way in (§5.5/§9).
   Replaces the passive route chip. Navy only (matches the sticky-chat composer it
   opens); ghost by default; exactly one .lead per report is filled. The verb is
   derived from `delivery` (diy/guided/done) in markup. */
.action-cta {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--fl); font-size: 11px; font-weight: 600;
  letter-spacing: 0.02em; line-height: 1; white-space: nowrap;
  padding: 7px 12px; border-radius: 999px; cursor: pointer;
  color: var(--ac); background: transparent; border: 1px solid var(--ac);
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.action-cta::after { content: "\2192"; font-weight: 600; }       /* → */
.action-cta:hover { background: var(--acs); }
.action-cta .cta-h {            /* Hagai avatar — echoes the sticky-chat composer */
  width: 18px; height: 18px; border-radius: 999px; margin-left: -3px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10px; font-weight: 700; background: var(--ac); color: var(--aci);
}
.action-cta.lead {              /* the one filled lead CTA — FIX FIRST or first action */
  color: var(--aci); background: var(--ac); border-color: var(--ac);
  padding: 11px 18px 11px 14px; gap: 9px;   /* roomier than the ghosts; tighter left pad balances the round avatar */
}
.action-cta.lead:hover { background: color-mix(in srgb, var(--ac) 88%, black); }
.action-cta.lead .cta-h { margin-left: 0; }   /* lead avatar sits on the honest left padding (no ghost tuck) */
.action-cta.lead .cta-h { background: var(--aci); color: var(--ac); }
/* FIX FIRST card sits on a navy field — its lead CTA inverts to read on the dark card */
.fixfirst .action-cta.lead { margin-top: 18px; background: var(--aci); color: var(--ac); border-color: var(--aci); }
.fixfirst .action-cta.lead:hover { background: color-mix(in srgb, var(--aci) 88%, var(--ac)); }
.fixfirst .action-cta.lead .cta-h { background: var(--ac); color: var(--aci); }

/* Plan CTA card — ONE way-in beneath a ranked action list. Rows stay quiet; this
   fuses the planContract (the who-acts split) with a single button. Inline .action-cta
   is used only on FIX FIRST and single-recommendation reports (§5.5/§9). */
.plan-cta {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
  flex-wrap: wrap; margin-top: var(--s4);
  padding: 16px 20px; background: var(--sf);
  border: 1px solid var(--ln); border-radius: var(--r); box-shadow: var(--sh);
}
.plan-cta-brand { display: flex; align-items: center; gap: 13px; min-width: 0; flex: 1 1 280px; }
.plan-cta-avatar {
  width: 38px; height: 38px; border-radius: 999px; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--ac); color: var(--aci); font-weight: 700; font-size: var(--t-md);
}
.plan-cta-copy { min-width: 0; }
.plan-cta-copy b { display: block; font-size: var(--t-md); font-weight: 650; color: var(--ink); line-height: 1.3; }
.plan-cta-copy span { font-size: var(--t-sm); color: var(--mut); line-height: 1.45; }   /* the planContract: who-acts split */
.plan-cta-copy strong { color: var(--ink); font-weight: 600; }
.plan-cta .action-cta.lead { flex: 0 0 auto; }   /* reuse the filled navy button */

/* DEPRECATED — superseded by .action-cta (§5.5/§9). Retained only so older sample
   reports still render; do not use in new reports. */
.route { font-family: var(--fl); font-size: 10.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.05em; line-height: 1;
  padding: 5px 9px; border-radius: 999px; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 6px; }
.route::before { content: ""; width: 6px; height: 6px; border-radius: 50%; flex: 0 0 auto; }
.route.diy { color: var(--mut); background: transparent; border: 1px solid var(--ln); }
.route.diy::before { background: var(--dt3); }
.route.guided { color: var(--ac); background: var(--acs); }
.route.guided::before { background: var(--ac); }
.route.done { color: var(--aci); background: var(--ac); }
.route.done::before { background: color-mix(in srgb, var(--c4) 80%, white); }

/* the action tie-back line now carries a route chip beside "Closes finding N" */
.action .closes-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 4px; }

/* The plan contract — one line under the "What to do" header stating ownership.
   Text is goal-driven (two variants in markup, swapped by the toggle below). */
.plan-contract { font-size: var(--t-sm); color: var(--mut); margin: 0 0 16px;
  padding: 11px 15px; background: var(--sf2); border-radius: var(--rs);
  border-left: 2px solid var(--ac); line-height: 1.5; }
.plan-contract b { color: var(--ink); font-weight: 600; }

/* FIX FIRST — declare ownership of the lead move inside the navy card */
.ff-route { display: block; margin-top: 16px;
  font-family: var(--fl); font-size: 11.5px; letter-spacing: 0.02em; line-height: 1.5;
  color: color-mix(in srgb, var(--c4) 72%, white); }
.ff-route b { color: var(--aci); font-weight: 600; }

/* ── builderGoal toggle: emphasis swaps only — content/score never change (§3) ── */
/* Reputation: the plan is the gift → soften the "done" routing, hide lead-gen CTAs. */
[data-goal="reputation"] .route.done { color: var(--ac); background: transparent; border: 1px dashed var(--ac); }
[data-goal="reputation"] .route.done::before { background: var(--ac); }
/* low-pressure: the in-plan lead CTA softens to a ghost (the FIX FIRST card keeps its inverted lead) */
[data-goal="reputation"] .action .action-cta.lead { color: var(--ac); background: transparent; border-color: var(--ac); padding: 7px 12px; }
[data-goal="reputation"] .action .action-cta.lead .cta-h { background: var(--ac); color: var(--aci); }
/* reputation: the plan CTA softens to a ghost (the plan is the gift, low-pressure) */
[data-goal="reputation"] .plan-cta .action-cta.lead { color: var(--ac); background: transparent; border-color: var(--ac); }
[data-goal="reputation"] .plan-cta .action-cta.lead .cta-h { background: var(--ac); color: var(--aci); }
[data-goal="reputation"] .goal-leadgen { display: none !important; }
[data-goal="reputation"] .plan-contract { border-left-color: var(--ln); }
/* Lead gen: surface the expert's moves → keep "done" solid navy, hide reputation CTAs. */
[data-goal="leadgen"] .goal-reputation { display: none !important; }

/* the suite goal-toggle control */
.goal-toggle { display: inline-flex; gap: 4px; align-items: center; }
.goal-toggle .gt-k { font-family: var(--fl); font-size: 10px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--mut); margin-right: 4px; }
.goal-toggle button { font-family: var(--fl); font-size: 11px; letter-spacing: 0.03em;
  border: 1px solid var(--ln); background: transparent; color: var(--mut);
  border-radius: var(--rs); padding: 5px 10px; cursor: pointer; }
.goal-toggle button[aria-pressed="true"] { background: var(--ink); color: var(--aci); border-color: var(--ink); }

@media (max-width: 430px) {
  .ff-route { font-size: 11px; }
  .goal-toggle { width: 100%; justify-content: flex-start; margin-top: 6px; }
}

/* ════════════════════════════════════════════════════════════════════════
   EXTENSION · progressive disclosure (native <details>, JS-free).
   Only two things collapse by default: the trust GRID (behind the one-line
   .trust-line teaser) via .chart-fold, and each finding's evidence drawer (.ev).
   Findings and the Evidence band are shown in full. See Design a Report §4.2.
   ════════════════════════════════════════════════════════════════════════ */

/* .chart-fold — fold ONLY a chart/grid, leaving the line above it (the trust
   teaser, or a module's conclusion) always visible. The inline "Show…" toggle. */
.chart-fold { margin-top: 2px; }
.chart-fold > summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center;
  gap: 6px; font-family: var(--fl); font-size: 12px; letter-spacing: 0.02em; color: var(--ac);
  padding: 6px 0 2px; }
.chart-fold > summary::-webkit-details-marker { display: none; }
.chart-fold > summary::after { content: "\25BE"; font-size: 11px; transition: transform 0.15s ease; }
.chart-fold[open] > summary::after { transform: rotate(180deg); }
.chart-fold > summary:hover { color: var(--ink); }
.chart-fold[open] > summary { margin-bottom: 12px; }

/* Trust layer — short, credibility-building line shown BY DEFAULT (confidence +
   basis + the key boundary); the full inputs/sources/not-checked grid expands. */
.trust-line { font-size: var(--t-sm); color: var(--ink); line-height: 1.55; margin: 2px 0 10px; max-width: 74ch; }
.trust-line b { font-weight: 600; }

/* Evidence band (Option B) — supporting modules grouped UNDER the findings as one
   "Evidence" section. Each module is a sub-block, visually SUBORDINATE to the finding
   titles, and names the finding(s) it backs (mirrors the action plan's "Closes finding N").
   This resolves the "modules read like new findings" ambiguity. */
.module-evidence .ev-block + .ev-block { border-top: 1px solid var(--ln); margin-top: 24px; padding-top: 24px; }
.ev-block { scroll-margin-top: 16px; }
.ev-block-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin: 0 0 3px; }
.ev-block-title { font-size: 16px; font-weight: 650; letter-spacing: -0.01em; margin: 0; }
.ev-backs { font-family: var(--fl); font-size: 11px; letter-spacing: 0.03em; color: var(--ac); white-space: nowrap; }
/* Traceability anchors — "Proves findings 1 & 4" / "Resolves finding 1" link to the
   finding they reference (ids f1…fN on .finding). Quiet dotted underline signals the
   jump without shouting; color stays the tie-back's own. */
.ev-backs a, .closes a {
  color: inherit;
  text-decoration: underline dotted;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.ev-backs a:hover, .closes a:hover { text-decoration-style: solid; }
.ev-deck { font-size: var(--t-sm); color: var(--mut); line-height: 1.5; margin: 4px 0 16px; max-width: 70ch; }

/* ============================================================================
   DARK SCHEME — token layer only. Every component draws from the variables, so
   remapping them here re-themes the whole system. Sentiment hues brighten (they
   sit on dark surfaces now); their soft surfaces become deep tints. The brand
   navy can't survive on near-black, so the accent lightens to a periwinkle of
   the same family.

   TWO theming modes, ONE token remap — pick a class on the .meter wrapper:
     • class="meter"        → light (default), regardless of OS.
     • class="meter light"  → forced light (same as default; explicit pin).
     • class="meter dark"   → forced dark, regardless of OS.

   Reports MUST theme by choosing the wrapper class — NEVER by overriding colors
   with raw hex or `!important` in report markup. Default is light so public
   embeds match builder previews; opt into dark with class="meter dark".
   ========================================================================= */

/* Forced dark — always dark, regardless of the viewer's OS. This is what a
   dark-themed report should set on its wrapper: class="meter dark". */
.meter.dark,
.meter.force-dark {
  color-scheme: dark;
  --bg:   #131417;
  --sf:   #1a1c20;
  --sf2:  #24262b;
  --ink:  #e9e9e6;
  --mut:  #a0a2a8;
  --ln:   #35373d;
  --ac:   #a5b6e8;
  --aci:  #131417;
  --acs:  #272d40;
  --dt:   #8ba0b3;   /* intensity inverts: on dark, stronger = lighter */
  --dt2:  #5d6c7a;
  --dt3:  #3b434d;
  --c1:   #8ba0b3;
  --c2:   #5d6c7a;
  --c3:   #3b434d;
  --c4:   #cf9c50;
  --c5:   #a5b6e8;
  --gd:   #5fc08c;  --gds: #1d3227;
  --wn:   #d9a251;  --wns: #352b18;
  --bd:   #e2745f;  --bds: #3a231e;
  --vs:   #a5b6e8;  --vss: #272d40;
  --vc:   #d9a251;  --vcs: #352b18;
  --vw:   #e2745f;  --vws: #3a231e;
  --sh:   0 1px 2px rgba(0,0,0,.45);
  --shl:  0 6px 16px rgba(0,0,0,.5);
}
.meter.dark .sheet,
.meter.force-dark .sheet { border-color: var(--ln); }
.meter.dark .verdict-meter .tick,
.meter.force-dark .verdict-meter .tick { background: var(--sf); }

/* ════════════════════════════════════════════════════════════════════════
   EXTENSION · LEAD GATE — intent-driven conversion surface (see #m48).
   Emitted ONLY when the run intent asks for a lead-gated report. The hero
   stays fully readable; everything after it sits inside .gate-zone: the
   content blurs (.gate-locked, also `inert` in markup), a veil frosts it,
   and the gate card — styled like a sealed section of the sheet itself,
   not a marketing popup — sticks over the locked region while the visitor
   scrolls the silhouette. The card slides in when the zone enters the
   viewport (script adds .gate-on); submit adds .gate-open, which lifts the
   blur in place. Client-side only: real gating moves server-side later.
   ════════════════════════════════════════════════════════════════════════ */
.gate-zone { position: relative; }

/* Locked content — blurred, unselectable, unclickable. Markup must also carry
   `inert aria-hidden="true"` so the teaser text never reaches AT or tab order. */
.gate-locked {
  filter: blur(7px) saturate(.85);
  pointer-events: none;
  user-select: none;
  transition: filter .8s ease .1s;
}
/* Sections nest one level deeper than `.sheet > section`, so the sheet's
   section rhythm is mirrored here. */
.sheet .gate-locked > section { padding: 30px 36px; border-top: 1px solid var(--ln); }

/* Frost veil — keeps the silhouette legible as *shape* (there IS a findings
   list, a chart, a plan) while killing any residual readability. */
.gate-veil {
  position: absolute; inset: 0;
  pointer-events: none;
  background: linear-gradient(to bottom,
    color-mix(in srgb, var(--sf) 14%, transparent),
    color-mix(in srgb, var(--sf) 46%, transparent) 34%,
    color-mix(in srgb, var(--sf) 72%, transparent));
}

/* Dock — full-height overlay column the card sticks inside. Never blocks
   scroll or the page behind it; only the card itself is interactive. */
.gate-dock {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center;
  padding: 56px 24px;
  pointer-events: none;
}
.gate-card {
  pointer-events: auto;
  position: sticky; top: clamp(24px, 12vh, 120px);
  width: min(440px, 100%);
  background: var(--sf);
  border: 1.5px solid var(--ink);
  border-radius: var(--r);
  box-shadow: var(--shl), 0 24px 64px color-mix(in srgb, var(--ink) 16%, transparent);
  padding: 24px 26px 22px;
}

/* card anatomy */
.gate-eyebrow {
  display: flex; align-items: center; gap: 8px;
  font-family: var(--fl); font-size: 11px; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--mut); margin: 0 0 14px;
}
.gate-eyebrow svg { flex: none; display: block; color: var(--ink); }
.gate-title {
  font-size: 21px; line-height: 1.3; letter-spacing: -0.01em;
  font-weight: 650; color: var(--ink);
  margin: 0 0 8px; text-wrap: balance;
}
.gate-sub { font-size: var(--t-body); line-height: 1.5; color: var(--mut); margin: 0 0 18px; }

/* what's locked — the report's OWN section numbers, so the card visibly points
   at the sheet behind it (chips echo .eyebrow-n) */
.gate-inside { display: grid; gap: 0; margin: 0 0 18px; padding: 0; list-style: none; }
.gate-inside li {
  display: flex; align-items: baseline; gap: 11px;
  padding: 9px 0; border-top: 1px solid var(--ln);
  font-size: var(--t-sm); line-height: 1.45; color: var(--mut);
}
.gate-inside li:last-child { border-bottom: 1px solid var(--ln); }
.gate-inside .gi-n {
  flex: 0 0 auto;
  font-family: var(--fl); font-size: 10.5px; font-weight: 600; line-height: 1;
  color: var(--aci); background: var(--ink);
  border-radius: 5px; padding: 4px 6px; letter-spacing: 0.02em;
}
.gate-inside b { color: var(--ink); font-weight: 600; }

/* form */
.gate-form { display: grid; gap: 12px; }
.gate-field { display: grid; gap: 5px; }
.gate-field label {
  font-family: var(--fl); font-size: 10.5px; font-weight: 500;
  letter-spacing: 0.07em; text-transform: uppercase; color: var(--mut);
}
.gate-field input {
  width: 100%; border: 1px solid var(--ln); border-radius: 9px;
  background: var(--sf); color: var(--ink);
  padding: 11px 13px; font-size: var(--t-md); font-family: var(--fb);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.gate-field input::placeholder { color: color-mix(in srgb, var(--mut) 62%, transparent); }
.gate-field input:focus { outline: none; border-color: var(--ac); box-shadow: 0 0 0 3px var(--acs); }
.gate-field input[aria-invalid="true"] { border-color: var(--bd); box-shadow: 0 0 0 3px var(--bds); }
.gate-err { font-size: 12px; color: var(--bd); margin: 0; }
.gate-err[hidden] { display: none; }
.gate-btn {
  width: 100%; border: 1px solid var(--ac); border-radius: 10px;
  background: var(--ac); color: var(--aci);
  padding: 13px 18px; font-family: var(--fb); font-size: var(--t-md); font-weight: 650;
  cursor: pointer; margin-top: 2px;
  transition: background .15s ease, translate .15s ease;
}
.gate-btn:hover { background: color-mix(in srgb, var(--ac) 88%, black); }
.gate-btn:active { translate: 0 1px; }
.gate-btn[disabled] { cursor: default; opacity: .85; }
.gate-note {
  font-family: var(--fl); font-size: 11px; line-height: 1.5;
  color: var(--mut); text-align: center; margin: 12px 0 0;
}

/* entrance — script marks the zone .gate-js on init (no-JS keeps everything
   visible), then .gate-on when the zone scrolls into view */
.gate-js .gate-veil { opacity: 0; transition: opacity .6s ease; }
.gate-js .gate-dock { opacity: 0; transition: opacity .55s ease; }
.gate-js .gate-card { translate: 0 26px; transition: translate .65s cubic-bezier(.2, .7, .2, 1); }
.gate-zone.gate-on .gate-veil,
.gate-zone.gate-on .gate-dock { opacity: 1; }
.gate-zone.gate-on .gate-card { translate: 0 0; }

/* reveal — submit adds .gate-open: blur lifts in place, chrome fades out
   (script removes veil/dock + inert after the transition) */
.gate-zone.gate-open .gate-locked { filter: none; pointer-events: auto; user-select: auto; }
.gate-zone.gate-open .gate-veil,
.gate-zone.gate-open .gate-dock { opacity: 0 !important; pointer-events: none !important; transition: opacity .45s ease; }
.gate-zone.gate-open .gate-card { translate: 0 -12px; }

@media (max-width: 720px) {
  .sheet .gate-locked > section { padding: 24px 20px; }
  .gate-dock { padding: 36px 14px; }
  .gate-card { padding: 20px 18px 18px; top: 16px; }
  .gate-title { font-size: 19px; }
}
@media (prefers-reduced-motion: reduce) {
  .gate-locked, .gate-veil, .gate-dock, .gate-card { transition: none !important; }
}
@media print {
  /* a locked report prints locked — the blur survives; the floating chrome
     collapses to nothing rather than printing mid-scroll */
  .gate-dock { display: none; }
}

/* ════════════════════════════════════════════════════════════════════════
   EXTENSION · SOFT GATE — end-of-report offer (see #m49). Lives inside
   article.sheet after sheet-foot (same bordered report card — not a sibling card).
   Two variants, chosen by whether the hard gate ran:
   · data-softgate="next"   — no hard gate: name + work email to receive the
                              NEXT runnable (dispatches `meter:subscribe`)
   · data-softgate="expert" — hard gate present: the lead is already captured,
                              so a one-click "request expert review" reusing it
                              (dispatches `meter:expert-review`). Ships `hidden`
                              in markup; the script reveals it after unlock.
   Nothing is blocked — this gate only offers.
   ════════════════════════════════════════════════════════════════════════ */
.softgate {
  margin-top: 16px;
  display: flex; align-items: center; gap: 24px 40px; flex-wrap: wrap;
  background: var(--sf);
  border: 1px solid var(--ln);
  border-radius: var(--r);
  box-shadow: var(--sh);
  padding: 26px 28px;
}
.softgate[hidden] { display: none; }
/* Inside the sheet — shares the report card border (good); not a nested card */
.sheet > .softgate {
  margin-top: 0;
  border: none;
  border-radius: 0;
  box-shadow: none;
  border-top: 1px solid var(--ln);
}
.sheet > .softgate .softgate-form,
.sheet > .softgate .softgate-cta,
.sheet > .softgate > .softgate-done { max-width: none; }
.softgate-copy { flex: 1 1 320px; min-width: 240px; }
.softgate-eyebrow {
  display: flex; align-items: center; gap: 8px;
  font-family: var(--fl); font-size: 11px; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--mut); margin: 0 0 10px;
}
.softgate-eyebrow svg { flex: none; display: block; color: var(--ac); }
.softgate-title {
  font-size: 19px; line-height: 1.3; letter-spacing: -0.01em;
  font-weight: 650; color: var(--ink);
  margin: 0 0 7px; text-wrap: balance;
}
.softgate-sub { font-size: var(--t-body); line-height: 1.5; color: var(--mut); margin: 0; max-width: 56ch; }
/* right column — the form (next) or the single button (expert), or the
   confirmation once either succeeds */
.softgate-form, .softgate-cta, .softgate > .softgate-done { flex: 1 1 300px; max-width: 380px; }
.softgate-form, .softgate-cta { display: grid; gap: 11px; }
.softgate .gate-btn { margin-top: 0; }
.softgate-note { font-family: var(--fl); font-size: 11px; color: var(--mut); margin: 0; line-height: 1.5; }
.softgate-done {
  display: flex; align-items: baseline; gap: 9px;
  font-size: var(--t-sm); line-height: 1.5; color: var(--ink); margin: 0;
}
.softgate-done::before { content: "✓"; color: var(--gd); font-weight: 700; flex: none; }
.softgate-done[hidden] { display: none; }

@media (max-width: 720px) {
  .softgate { padding: 20px 18px; }
  .softgate-form, .softgate-cta, .softgate > .softgate-done { max-width: none; }
}
