/* =========================================================
   ASI Redesign Prototype — Notion-style baseline
   Palette tokens live here. Swap to WTW colors by editing
   the :root variables only — no other CSS needs to change.
   ========================================================= */

:root {
  /* =========================================================
     WTW palette · 60-30-10 discipline
     60 % — white / off-white / black / Gray Matter Light
     30 % — structural grays, sparingly seasoned with WTW darks
     10 % — semantic accents drawn from WTW Light scale
     ========================================================= */

  /* 60 — canvas (neutral dominance) */
  --bg: #FAFAF9;
  --bg-elevated: #FFFFFF;

  /* 30 — structure (Gray Matter family + near-black ink) */
  --ink: #1F1F1F;
  --ink-soft: #4B4B4B;
  --ink-muted: #808080;         /* WTW Gray Matter Dark */
  --line: #e6e6e6;
  --line-strong: #BFBFBF;       /* WTW Gray Matter */

  /* 10 — brand accents */
  --accent: #7f35b2;            /* WTW Ultraviolet — primary brand accent */
  --accent-mid: #7B3FB8;        /* interpolated Ultraviolet mid, used sparingly */
  --accent-soft: #F3EEF9;       /* Ultraviolet Light tint — safe backgrounds */
  --on-accent: #FFFFFF;         /* text/fill when laid ON an accent-colored surface */

  /* 10 — semantic (pulled from WTW Light scale for gentleness) */
  --risk: #C900AC;              /* Fireworks — bold accent stroke only */
  --risk-bg: #FFE5EF;           /* Coral Reef Light tint */
  --risk-ink: #8C2050;          /* readable text on risk-bg */

  --safe: #007D61;              /* Infinity Dark — readable */
  --safe-bg: #E8F8F5;           /* Infinity Light tint */
  --safe-ink: #005A46;

  --plan: #7f35b2;              /* Ultraviolet */
  --plan-bg: #F3EEF9;           /* Ultraviolet Light tint */
  --plan-ink: #7f35b2;

  --warn: #B68400;              /* Submarine Dark — readable amber */
  --warn-bg: #FDF6E1;           /* Submarine Light tint */

  --warn-ink: #6E5200;

  /* Swarm dots — solid fills, no borders */
  --swarm-normal: #c3d7fe;           /* Stratosphere Light — normal + unselected */
  --swarm-normal-selected: #327fef;  /* Stratosphere — normal + selected */
  --swarm-risk: #e377dc;             /* Fireworks Light — EUPTD + unselected */
  --swarm-risk-selected: #c900ac;    /* Fireworks — EUPTD + selected */

  /* Typography */
  --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* Rhythm */
  --radius: 10px;
  --radius-sm: 6px;
  --radius-lg: 16px;
  --shadow-sm: 0 1px 2px rgba(15, 15, 15, 0.04);
  --shadow: 0 1px 3px rgba(15, 15, 15, 0.06), 0 8px 24px rgba(15, 15, 15, 0.04);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; }

/* ------- Layout ------- */
.wrap { max-width: 1160px; margin: 0 auto; padding: 0 32px; }
.wrap-narrow { max-width: 780px; margin: 0 auto; padding: 0 32px; }

.nav {
  position: sticky; top: 0; z-index: 40;
  background: rgba(250, 250, 249, 0.85);
  backdrop-filter: saturate(140%) blur(8px);
  border-bottom: 1px solid var(--line);
}
.nav-inner { display: flex; align-items: center; justify-content: space-between; height: 60px; }
.brand { display: flex; align-items: center; gap: 10px; font-weight: 600; letter-spacing: -0.01em; }
.brand-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--accent); }
.nav-links { display: flex; gap: 24px; color: var(--ink-soft); font-size: 14px; }
.nav-links a:hover { color: var(--ink); }
.btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 16px;
  background: var(--ink); color: #fff;
  border: 1px solid var(--ink);
  border-radius: var(--radius-sm);
  font-size: 14px; font-weight: 500;
  transition: transform 120ms ease, background 120ms ease;
}
.btn:hover { transform: translateY(-1px); }
.btn-ghost { background: transparent; color: var(--ink); border: 1px solid var(--line-strong); }
.btn-ghost:hover { background: var(--accent-soft); }

/* ------- Hero ------- */
.hero { padding: 120px 0 80px; }
.eyebrow {
  display: inline-block;
  padding: 4px 10px;
  background: var(--accent-soft);
  border-radius: 999px;
  font-size: 12px; font-weight: 500;
  color: var(--ink-soft);
  letter-spacing: 0.02em;
  margin-bottom: 24px;
}
.hero h1 {
  font-size: clamp(40px, 6vw, 68px);
  line-height: 1.04;
  letter-spacing: -0.025em;
  font-weight: 600;
  margin: 0 0 20px;
}
.hero h1 .accent {
  position: relative;
  display: inline-block;
  padding: 0 6px;
}
.hero h1 .accent svg {
  position: absolute; left: 0; bottom: 4px;
  width: 100%; height: 12px; overflow: visible;
}
.hero p.lede {
  font-size: 20px;
  color: var(--ink-soft);
  max-width: 640px;
  margin: 0 0 36px;
}
.hero-cta { display: flex; gap: 12px; flex-wrap: wrap; }

/* ------- Sections ------- */
section.block { padding: 80px 0; border-top: 1px solid var(--line); }
.section-label {
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--ink-muted); margin-bottom: 12px;
}
.section-title {
  font-size: clamp(28px, 4vw, 40px);
  font-weight: 600; letter-spacing: -0.02em;
  margin: 0 0 16px;
}
.section-sub { color: var(--ink-soft); max-width: 680px; font-size: 17px; margin-bottom: 48px; }

/* ------- Timeline (SVG draw) ------- */
.timeline {
  position: relative;
  display: grid; grid-template-columns: 1fr; gap: 0;
}
.timeline svg.spine {
  position: absolute; left: 24px; top: 0;
  width: 2px; height: 100%;
  overflow: visible;
}
.step {
  position: relative;
  padding: 28px 0 28px 72px;
  opacity: 0;
  transform: translateY(16px);
}
.step.in { opacity: 1; transform: translateY(0); transition: opacity 600ms ease, transform 600ms ease; }
.step .dot {
  position: absolute; left: 16px; top: 32px;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--bg);
  border: 2px solid var(--ink);
  display: grid; place-items: center;
  font-size: 10px; font-weight: 600;
  transform: scale(0);
}
.step.in .dot { transform: scale(1); transition: transform 400ms cubic-bezier(.2,.8,.2,1.2) 200ms; }
.step h3 { margin: 0 0 6px; font-size: 20px; letter-spacing: -0.01em; }
.step p { margin: 0; color: var(--ink-soft); max-width: 620px; }
.step .kicker {
  display: inline-block; font-size: 12px; color: var(--ink-muted);
  letter-spacing: 0.08em; text-transform: uppercase; margin-bottom: 6px;
}

/* ------- Feature grid ------- */
.grid-3 {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px;
}
@media (max-width: 860px) { .grid-3 { grid-template-columns: 1fr; } }
.card {
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 24px;
  box-shadow: var(--shadow-sm);
  transition: transform 160ms ease, box-shadow 160ms ease;
}
.card:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
.card h4 { margin: 12px 0 8px; font-size: 17px; letter-spacing: -0.01em; }
.card p { color: var(--ink-soft); margin: 0; font-size: 14px; }
.card .icon {
  width: 36px; height: 36px; border-radius: 8px;
  background: var(--accent-soft);
  display: grid; place-items: center;
}

footer.foot {
  padding: 60px 0 80px; border-top: 1px solid var(--line);
  color: var(--ink-muted); font-size: 13px;
}

/* =========================================================
   APP PAGE
   ========================================================= */
.app-shell { min-height: 100vh; }

.dropzone {
  border: 1.5px dashed var(--line-strong);
  background: var(--bg-elevated);
  border-radius: var(--radius-lg);
  padding: 56px 32px;
  text-align: center;
  transition: border-color 160ms ease, background 160ms ease, transform 160ms ease;
}
.dropzone.hover { border-color: var(--ink); background: var(--accent-soft); transform: scale(1.005); }
.dropzone h2 { margin: 8px 0; font-size: 24px; letter-spacing: -0.01em; }
.dropzone p { color: var(--ink-soft); margin: 0 0 18px; }
.dropzone input[type=file] { display: none; }
.dropzone .hint { margin-top: 16px; font-size: 13px; color: var(--ink-muted); }

/* Stats strip */
.stats {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px;
  margin: 24px 0;
}
@media (max-width: 860px) { .stats { grid-template-columns: repeat(2, 1fr); } }
.stat {
  background: var(--bg-elevated); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 18px;
}
.stat .label { font-size: 12px; color: var(--ink-muted); text-transform: uppercase; letter-spacing: 0.1em; }
.stat .value { font-size: 26px; font-weight: 600; letter-spacing: -0.02em; margin-top: 4px; }
.stat .delta { font-size: 13px; color: var(--ink-soft); margin-top: 4px; }

/* Panels — layout responds to the active tab (Patch 5c.3).
   Gap grid tab: single column full-width, cohort lens hidden.
   Landscape tab: two-column with sticky cohort lens on the right.
   The class toggle is driven by the tab switcher handler in app.js. */
.panels {
  display: grid;
  gap: 24px;
  margin-top: 12px;
}
.panels.tab-grid-active {
  grid-template-columns: minmax(0, 1fr);
}
.panels.tab-grid-active #cohortPanel {
  display: none;
}
/* Patch 5c.4 — roster panel is also hidden on the Gap grid tab so the
   grid gets the full vertical real estate. The roster is only
   meaningful next to the scatter drill-down flow (click a dot → land
   in roster → click the row → read the cohort lens). */
.panels.tab-grid-active #rosterPanel {
  display: none;
}
.panels.tab-landscape-active {
  grid-template-columns: minmax(0, 1fr) minmax(420px, 1.15fr);
}
/* Explicit display restore on Landscape so the cohort lens definitely
   un-hides from the Gap grid state — belt-and-suspenders against any
   browser cascade oddness. */
.panels.tab-landscape-active #cohortPanel {
  display: block;
}
.panels.tab-landscape-active #rosterPanel {
  display: block;
}
@media (max-width: 1100px) {
  .panels.tab-landscape-active {
    grid-template-columns: 1fr;
  }
}
.main-left { min-width: 0; } /* prevents grid blowout when inner content is wide */
.panel {
  background: var(--bg-elevated); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 20px;
  min-height: 420px;
}
.panel h3 { margin: 0 0 4px; font-size: 16px; letter-spacing: -0.01em; }
.panel .sub { font-size: 13px; color: var(--ink-muted); margin-bottom: 16px; }

/* Scatter */
.scatter { width: 100%; height: 460px; }
.scatter .axis line, .scatter .axis path { stroke: var(--line-strong); }
.scatter .axis text { font-size: 11px; fill: var(--ink-muted); }
.scatter .grid line { stroke: var(--line); stroke-dasharray: 2 3; }
.scatter .midline { stroke: var(--ink-muted); stroke-dasharray: 4 4; }
.scatter .dot-emp {
  cursor: pointer;
  transition: r 160ms ease, stroke-width 160ms ease;
}
.scatter .dot-emp:hover { stroke-width: 3; }
/* .dot-emp.risk color handled via fill in JS */
/* .dot-emp.selected color handled via fill in JS */

/* Cohort view */
.cohort-bar { position: relative; height: 165px; margin: 32px 0 14px; }
.cohort-track {
  position: absolute; left: 0; right: 0; top: 60px; height: 4px;
  background: var(--line); border-radius: 2px;
}
.cohort-fill {
  position: absolute; top: 60px; height: 4px; background: var(--accent); border-radius: 2px;
}
.cohort-marker {
  position: absolute; top: 44px; width: 2px; height: 36px; background: var(--ink-soft);
}
.cohort-marker .tag { display: none; }
.cohort-person {
  position: absolute; top: 53px; width: 16px; height: 16px; margin-left: -8px;
  border-radius: 50%; background: var(--accent); border: 2px solid #fff;
  box-shadow: 0 0 0 3px rgba(127, 53, 178, 0.18), var(--shadow-sm);
}

.pill {
  display: inline-block; padding: 2px 10px; border-radius: 999px;
  font-size: 12px; font-weight: 500;
}
.pill.risk { background: var(--risk-bg); color: var(--risk-ink); }
.pill.safe { background: var(--safe-bg); color: var(--safe-ink); }
.pill.plan { background: var(--plan-bg); color: var(--plan-ink); }
.pill.warn { background: var(--warn-bg); color: var(--warn-ink); }

.reasoning {
  background: var(--accent-soft);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  font-size: 14px;
  color: var(--ink);
  margin-top: 14px;
  line-height: 1.6;
}
.reasoning b { font-weight: 600; }

/* Suggestion slider */
.suggest-row { display: flex; gap: 8px; margin-top: 14px; }
.suggest-row .opt {
  flex: 1; padding: 12px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--bg); cursor: pointer; transition: all 140ms ease;
}
.suggest-row .opt:hover { border-color: var(--ink-soft); }
.suggest-row .opt.active { border-color: var(--ink); background: var(--bg-elevated); box-shadow: var(--shadow-sm); }
.suggest-row .opt .opt-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-muted); }
.suggest-row .opt .opt-val { font-size: 18px; font-weight: 600; margin-top: 4px; }

/* Empty state */
.empty { text-align: center; padding: 60px 20px; color: var(--ink-muted); }
.empty svg { opacity: 0.4; }

/* Budget bar */
.budget {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 18px; background: var(--bg-elevated);
  border: 1px solid var(--line); border-radius: var(--radius);
  margin-bottom: 12px;
}
.budget .track { flex: 1; height: 8px; background: var(--line); border-radius: 4px; overflow: hidden; position: relative; }
.budget .fill { height: 100%; background: var(--ink); transition: width 400ms ease; }
.budget .fill.over { background: var(--risk); }

/* Table */
.table-wrap { overflow-x: auto; }
table.emp {
  width: 100%; border-collapse: collapse; font-size: 13px;
}
table.emp th, table.emp td {
  padding: 10px 12px; border-bottom: 1px solid var(--line);
  text-align: left; vertical-align: middle;
}
table.emp th {
  font-weight: 500; color: var(--ink-muted); text-transform: uppercase;
  font-size: 11px; letter-spacing: 0.08em;
}
table.emp tr { cursor: pointer; transition: background 120ms ease; }
table.emp tr:hover { background: var(--accent-soft); }
table.emp tr.selected { background: var(--accent-soft); }

/* Tooltip — global floating tooltip used by scatter dot hover (since
   Patch 1) and by cockpit label hover (since Patch 5c.4 rich tooltips). */
.tooltip {
  position: fixed; pointer-events: none;
  background: var(--ink); color: var(--on-accent);
  padding: 10px 14px; border-radius: 8px;
  font-size: 12px; line-height: 1.5;
  z-index: 100; opacity: 0;
  transition: opacity 140ms ease;
  max-width: 320px;
  box-shadow: 0 10px 30px rgba(15, 15, 15, 0.18);
}
.tooltip.show { opacity: 1; }
.tooltip b { font-weight: 600; color: var(--on-accent); }
.tooltip .tip-title {
  display: block;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--accent-soft);
  margin-bottom: 4px;
  font-weight: 600;
}

/* Elements wired for the rich tooltip pick up a subtle underline cue on
   hover so the user knows "this label has more info." */
[data-tip] { cursor: help; }
.cockpit [data-tip] { cursor: help; }


/* Sticky cohort panel — follows the scroll so selected-employee state stays in view */
#cohortPanel {
  position: sticky;
  top: 76px;
  max-height: calc(100vh - 100px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-right: 6px;
  align-self: start;
}

/* Leader-line label callouts — eliminates P25/Median/P75 label overlap */
.cohort-leader-svg {
  position: absolute; left: 0; top: 80px; width: 100%; height: 28px;
  pointer-events: none; overflow: visible;
}
.cohort-leader-svg line {
  stroke: var(--line-strong); stroke-width: 1; stroke-linecap: round;
}
.cohort-leader-label {
  position: absolute; top: 112px; width: 96px; margin-left: -48px;
  text-align: center; font-size: 12px; line-height: 1.35;
  color: var(--ink); font-variant-numeric: tabular-nums; font-weight: 500;
}
.cohort-leader-label .lbl {
  display: block; font-size: 10px; color: var(--ink-muted);
  text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 3px;
  font-weight: 400;
}

/* Filter bar */
.filters {
  display: flex; gap: 12px; margin-bottom: 16px; align-items: center; flex-wrap: wrap;
  padding: 14px 18px; background: var(--bg-elevated);
  border: 1px solid var(--line); border-radius: var(--radius);
}
.filters label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-muted); }
.filters select {
  padding: 8px 10px; border: 1px solid var(--line-strong); border-radius: 6px;
  font-family: inherit; font-size: 14px; background: var(--bg-elevated); color: var(--ink);
  cursor: pointer; min-width: 180px;
}
.filters select:focus { outline: none; border-color: var(--accent); }

/* =========================================================
   Position cards — Market vs Internal (Patch 5a.1)
   Two compact cards at the top of the cohort lens showing
   the selected employee's position vs market-mid and internal-mid.
   Layout inspired by Figures.hr, palette is WTW.
   ========================================================= */
.pos-cards {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
  margin-bottom: 24px;
}
.pos-card {
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-elevated);
  position: relative;
}
.pos-card.pos-safe    { background: var(--safe-bg); border-color: transparent; }
.pos-card.pos-warn    { background: var(--warn-bg); border-color: transparent; }
.pos-card.pos-risk    { background: var(--risk-bg); border-color: transparent; }
.pos-card.pos-over    { background: var(--plan-bg); border-color: transparent; }
.pos-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--ink-muted); font-weight: 500;
}
.pos-delta {
  font-size: 28px; font-weight: 600; letter-spacing: -0.02em;
  margin-top: 8px; font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.pos-card.pos-safe .pos-delta { color: var(--safe-ink); }
.pos-card.pos-warn .pos-delta { color: var(--warn-ink); }
.pos-card.pos-risk .pos-delta { color: var(--risk-ink); }
.pos-card.pos-over .pos-delta { color: var(--plan-ink); }
.pos-detail {
  font-size: 12px; color: var(--ink-soft); margin-top: 6px;
  font-variant-numeric: tabular-nums;
}
.pos-pill {
  margin-top: 10px;
}
.pos-pill .pill {
  font-size: 11px;
}

/* =========================================================
   Tri-band visualization (Patch 5a.2)
   Replaces position cards. Three horizontal salary bands
   stacked on a shared scale: Internal / Market / Peer cohort.
   Person marker sits on each band at their actual annualised
   salary, so visual triangulation is immediate.
   Palette is intentionally subtle — WTW tokens at 10–15% alpha.
   ========================================================= */
.band-stack {
  display: flex; flex-direction: column; gap: 26px;
  margin-bottom: 28px;
}
.band-row {
  display: grid;
  grid-template-columns: 110px 1fr;
  gap: 14px;
  align-items: center;
}
.band-row .band-header {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
  font-weight: 500;
  line-height: 1.4;
}
.band-row .band-header .band-status {
  display: block;
  font-size: 11px;
  margin-top: 4px;
  letter-spacing: normal;
  text-transform: none;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
  font-weight: 400;
}
.band-row .band-track {
  position: relative;
  height: 38px;
  margin-top: 4px;
}
.band-row .band-track .band-bg {
  position: absolute;
  top: 16px; height: 8px;
  border-radius: 4px;
}
.band-row .band-track .band-mid {
  position: absolute;
  top: 10px; height: 20px;
  width: 1px;
  background: var(--ink-muted);
  opacity: 0.65;
}
.band-row .band-track .band-mid-label {
  position: absolute;
  top: 32px;
  font-size: 10px;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
  transform: translateX(-50%);
  white-space: nowrap;
}
.band-row .band-track .band-edge-label {
  position: absolute;
  top: -2px;
  font-size: 10px;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.band-row .band-track .band-edge-label.right {
  transform: translateX(-100%);
}
.band-row .band-track .band-person {
  position: absolute;
  top: 12px;
  width: 16px; height: 16px;
  margin-left: -8px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid #fff;
  box-shadow: 0 0 0 2px rgba(127, 53, 178, 0.18);
  z-index: 2;
}

/* Subtle WTW-aligned band tints — at 12-18% alpha so they whisper, not shout */
.band-row.band-internal .band-bg { background: rgba(50, 127, 239, 0.16); }   /* Stratosphere */
.band-row.band-market .band-bg   { background: rgba(58, 220, 201, 0.18); }   /* Infinity */
.band-row.band-cohort .band-bg   { background: rgba(127, 53, 178, 0.12); }   /* Ultraviolet */

/* If a band is missing data, show a subtle "no data" treatment */
.band-row.band-empty .band-track {
  display: flex; align-items: center;
  font-size: 12px; color: var(--ink-muted); font-style: italic;
}

/* =========================================================
   Patch 5b.3 — Cohort gap grid (primary view) + tabs
   Replaces the scatter as the headline view. Scatter demoted
   to a second tab. Style discipline: only tokens from :root,
   left-border flag (not background fill), ghost rows for
   insufficient-data cohorts, thin vertical rule dividing the
   unadjusted and adjusted column groups.
   ========================================================= */

/* Tab switcher */
.tabs {
  display: flex; gap: 4px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 18px;
}
.tabs button {
  background: none; border: none;
  padding: 10px 16px;
  font-family: inherit; font-size: 14px; font-weight: 500;
  color: var(--ink-muted);
  border-bottom: 2px solid transparent;
  transition: color 140ms ease, border-color 140ms ease;
}
.tabs button:hover { color: var(--ink-soft); }
.tabs button.active {
  color: var(--ink);
  border-bottom-color: var(--accent);
}
.tab-panel { display: none; }
.tab-panel.active { display: block; }

/* Grid control bar — grain toggle + tunable disclosure threshold */
.grid-controls {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; margin-bottom: 18px; flex-wrap: wrap;
}
.grid-controls-left,
.grid-controls-right {
  display: flex; align-items: center; gap: 10px;
}
.grid-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--ink-muted); font-weight: 500;
}

/* Segmented two-button control (grain toggle) */
.segmented {
  display: inline-flex;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.segmented button {
  background: none; border: none;
  padding: 6px 14px;
  font-family: inherit; font-size: 12px;
  color: var(--ink-muted);
  transition: background 140ms ease, color 140ms ease;
}
.segmented button + button { border-left: 1px solid var(--line-strong); }
.segmented button:hover { color: var(--ink); }
.segmented button.active {
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 500;
}

/* Threshold input — small number field matching filter bar style */
.threshold-input {
  width: 54px; padding: 5px 8px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  font-family: inherit; font-size: 13px; text-align: right;
  font-variant-numeric: tabular-nums;
  background: var(--bg-elevated); color: var(--ink);
}
.threshold-input:focus { outline: none; border-color: var(--accent); }

/* The cohort grid table itself */
.gap-grid {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.gap-grid thead th {
  font-weight: 500;
  color: var(--ink-muted);
  text-align: left;
  padding: 8px 10px;
  border-bottom: 1px solid var(--line);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
}
.gap-grid thead tr.group-header th {
  font-size: 10px;
  padding-top: 12px;
  padding-bottom: 6px;
  border-bottom: none;
  text-align: center;
  color: var(--ink-muted);
  font-weight: 500;
}
.gap-grid thead tr.group-header th.g-spacer { text-align: left; }
.gap-grid th.num,
.gap-grid td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Vertical rule separating Unadjusted from Adjusted column groups.
   Beqom and Figures both do this to prevent reader-conflation of the
   two metrics — we reuse the same spatial cue. */
.gap-grid th.group-rule-left,
.gap-grid td.group-rule-left {
  border-left: 1px solid var(--line-strong);
  padding-left: 14px;
}

/* Body rows */
.gap-grid tbody tr {
  transition: background 120ms ease;
}
.gap-grid tbody tr:hover { background: var(--accent-soft); }
.gap-grid tbody td {
  padding: 11px 10px;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
  vertical-align: middle;
}
.gap-grid tbody td.cl {
  font-weight: 600;
  color: var(--ink);
  min-width: 40px;
}
.gap-grid tbody td.entity,
.gap-grid tbody td.ff {
  color: var(--ink-soft);
  font-size: 12px;
  max-width: 180px;
}
.gap-grid tbody td.ff { line-height: 1.3; }

/* Flagged row — LEFT BORDER FLAG, never a background fill.
   Defensibility over decoration: a red row reads as dashboard alarm,
   a left border reads as margin note. */
.gap-grid tbody tr.row-flag td:first-child {
  border-left: 3px solid var(--risk);
  padding-left: 12px;
}
.gap-grid tbody tr.row-flag td.cl {
  color: var(--risk-ink);
}

/* Sub-threshold cohort — greyed ghost row, not hidden.
   Keeping it in reading order preserves the regulatory picture of
   which cells could NOT be disclosed, rather than sanitising them. */
.gap-grid tbody tr.row-insufficient td {
  color: var(--ink-muted);
  background: transparent;
}
.gap-grid tbody tr.row-insufficient td.insufficient-cell {
  font-style: italic;
  font-size: 12px;
  text-align: center;
}
.gap-grid tbody tr.row-insufficient:hover { background: transparent; }

/* Muted individual cell (e.g., missing adjusted gap) */
.gap-grid td .cell-muted,
.gap-grid td.cell-muted {
  color: var(--ink-muted);
  font-style: italic;
}

/* Footer: non-binary exclusion count — EUPTD reporting is binary
   by directive scope, but we count NB/undeclared in a footnote so
   the population is acknowledged rather than erased. */
.gap-grid tfoot td {
  padding: 14px 10px 4px;
  font-size: 11px;
  color: var(--ink-muted);
  font-style: italic;
  border-top: 1px solid var(--line);
  line-height: 1.55;
}

/* Empty-state treatment when no rows render (e.g. aggressive filter) */
.gap-grid-empty {
  padding: 40px 20px;
  text-align: center;
  font-size: 13px;
  color: var(--ink-muted);
  font-style: italic;
}

/* =========================================================
   Patch 5c.1 — Cockpit (consolidated envelope + pools + stats)
   ---------------------------------------------------------
   Replaces the old envelope panel + stats strip + two budget
   bars with a single horizontal operational strip that lives
   directly under the nav. Compresses ~490px of chrome down
   to ~140px so the gap grid is above the fold on first load.
   Every existing element ID that renderStats writes to is
   preserved; this is a visual restructure only.
   ========================================================= */

.cockpit {
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 18px 12px;
  margin-bottom: 14px;
}

.cockpit-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 24px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 10px;
  flex-wrap: wrap;
}

.cockpit-title {
  display: flex;
  align-items: baseline;
  gap: 14px;
  flex-wrap: wrap;
}
.cockpit-title .title-eyebrow {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-muted);
  padding: 3px 10px;
  background: var(--accent-soft);
  border-radius: 999px;
}
.cockpit-title .title-total {
  font-size: 26px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  letter-spacing: -0.025em;
  line-height: 1;
}
.cockpit-title .title-pct {
  font-size: 11px;
  font-weight: 400;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.cockpit-title .title-pct #totalPct {
  font-weight: 600;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

.cockpit-stats {
  display: flex;
  align-items: baseline;
  gap: 22px;
  flex-wrap: wrap;
  font-variant-numeric: tabular-nums;
}
.cockpit-stats .stat-chip {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  padding: 6px 12px 8px;
  border-radius: var(--radius-sm);
  transition: background 180ms ease, transform 180ms ease, box-shadow 180ms ease;
  position: relative;
}
.cockpit-stats .stat-chip::after {
  content: "";
  position: absolute;
  left: 12px; right: 12px; bottom: 4px;
  height: 2px;
  background: var(--accent);
  border-radius: 1px;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 220ms ease;
}
.cockpit-stats .stat-chip:hover::after { transform: scaleX(0.4); }
.cockpit-stats .stat-chip.clickable {
  cursor: pointer;
}
.cockpit-stats .stat-chip.clickable:hover {
  background: var(--accent-soft);
  transform: translateY(-1px);
  box-shadow: var(--shadow-sm);
}
.cockpit-stats .stat-chip.clickable:hover::after { transform: scaleX(1); }

/* Toggled-on state for the Compression chip after the roster-isolation
   click. Persistent indicator so the user can see the filter is active. */
.cockpit-stats .stat-chip.active-filter {
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.cockpit-stats .stat-chip.active-filter::after {
  transform: scaleX(1);
}
.cockpit-stats .stat-chip.active-filter .label,
.cockpit-stats .stat-chip.active-filter .hint {
  color: var(--accent);
}
.cockpit-stats .stat-chip.active-filter .value {
  color: var(--accent);
}
.cockpit-stats .stat-chip .label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
  font-weight: 500;
  line-height: 1.3;
}
.cockpit-stats .stat-chip .value {
  font-size: 18px;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.015em;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.cockpit-stats .stat-chip .hint {
  font-size: 10px;
  color: var(--ink-muted);
  line-height: 1.3;
}

/* Pool rows — merit + non-disc with inline inputs + bar + status */
.pool-row {
  display: grid;
  grid-template-columns: 160px 84px 150px minmax(160px, 1fr) auto;
  gap: 14px;
  align-items: center;
  padding: 10px 0;
  font-size: 13px;
}
.pool-row + .pool-row { border-top: 1px solid var(--line); }

.pool-row .pool-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  font-weight: 600;
  cursor: help;
}

.pool-input-group {
  display: flex;
  align-items: center;
  gap: 4px;
}
.pool-input {
  padding: 5px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: 13px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  background: var(--bg);
  color: var(--ink);
  width: 56px;
}
.pool-input.pool-input-eur { width: 100px; flex: 0 0 auto; }
.pool-input:focus { outline: none; border-color: var(--accent); }
.pool-unit {
  font-size: 11px;
  color: var(--ink-muted);
}

.pool-track {
  position: relative;
  height: 8px;
  background: var(--line);
  border-radius: 4px;
  overflow: hidden;
}
.pool-fill {
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: 0;
  max-width: 100%;
  background: var(--ink);
  transition: width 380ms ease, background-color 200ms ease;
}
/* Default non-merit fill color — replaces the inline style that previously
   lost specificity fights with the .over rule and prevented the color flip. */
.pool-fill.pool-fill-plan { background: var(--plan); }
.pool-fill.over { background: var(--risk); }

.pool-status {
  font-size: 12px;
  font-weight: 500;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  text-align: right;
  min-width: 240px;
  white-space: nowrap;
  letter-spacing: -0.005em;
}
.pool-status .ps-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
  font-weight: 500;
  margin-right: 3px;
}
.pool-status .ps-value {
  font-weight: 600;
  color: var(--ink);
}
.pool-status .ps-pct {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 7px;
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 11px;
  font-weight: 600;
}
.pool-status.over .ps-pct {
  background: var(--risk-bg);
  color: var(--risk-ink);
}

.pool-hint-aside {
  display: none; /* hidden by default — renderStats still writes to it, but
                    the value is already visible in pool-status */
}

/* Collapsible non-disc composition ledger */
.cockpit-ledger {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}
.cockpit-ledger summary {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
  cursor: pointer;
  padding: 4px 0;
  list-style: none;
  user-select: none;
  font-weight: 600;
}
.cockpit-ledger summary::-webkit-details-marker { display: none; }
.cockpit-ledger summary::before { content: "▸ "; color: var(--ink-muted); }
.cockpit-ledger[open] summary::before { content: "▾ "; }
.cockpit-ledger summary:hover { color: var(--ink-soft); }
.cockpit-ledger .ledger-hint {
  text-transform: none;
  letter-spacing: normal;
  font-weight: 400;
  color: var(--ink-muted);
  font-size: 11px;
  margin-left: 4px;
}
.cockpit-ledger .ledger-body {
  padding: 10px 0 4px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  align-items: start;
}
@media (max-width: 860px) {
  .cockpit-ledger .ledger-body { grid-template-columns: 1fr; gap: 14px; }
}

/* Breakdown arithmetic — traceability from total back to components */
.ledger-breakdown {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
}
.breakdown-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 5px 0;
  font-size: 12px;
  color: var(--ink-soft);
}
.breakdown-line + .breakdown-line:not(.breakdown-total) {
  border-top: 1px dashed var(--line);
}
.breakdown-line .lb-label {
  display: flex;
  flex-direction: column;
  gap: 1px;
  color: var(--ink);
}
.breakdown-line .lb-sub {
  font-size: 10px;
  color: var(--ink-muted);
  font-weight: 400;
  line-height: 1.3;
}
.breakdown-line .lb-value {
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  color: var(--ink);
  font-size: 13px;
  white-space: nowrap;
}
.breakdown-line.breakdown-total {
  margin-top: 8px;
  padding-top: 10px;
  border-top: 2px solid var(--line-strong);
  font-weight: 600;
}
.breakdown-line.breakdown-total .lb-label { font-weight: 600; color: var(--ink); }
.breakdown-line.breakdown-total .lb-value {
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.01em;
}

/* Manual items block (right column of ledger-body grid) */
.ledger-items-block {
  padding: 0;
}
.ledger-items-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 8px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
  font-weight: 600;
}
.cockpit-ledger #nondiscList {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 13px;
}
.cockpit-ledger #addNondiscBtn {
  padding: 4px 10px;
  font-size: 11px;
}

/* Cohort lens empty-state collapse — when nothing is selected, the panel
   shrinks instead of holding a 420px-tall white box. The class is toggled
   by renderCohort() in app.js. */
#cohortPanel.cohort-empty {
  min-height: auto;
  padding-bottom: 22px;
}
#cohortPanel.cohort-empty #cohortTitle {
  color: var(--ink-muted);
}

/* Responsive — below 860px the cockpit stacks vertically */
@media (max-width: 860px) {
  .cockpit-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }
  .cockpit-stats { gap: 14px; }
  .pool-row {
    grid-template-columns: 1fr;
    gap: 6px;
    padding: 10px 0;
  }
  .pool-row .pool-track,
  .pool-row .pool-status { grid-column: 1 / -1; }
  .pool-status { text-align: left; min-width: 0; }
}

/* =========================================================
   Patch 5b.4 — Editable allocation inside the roster
   ---------------------------------------------------------
   Per-row proposed-salary input + inline signed delta chip +
   per-row reset (visible only when touched) + justification
   dropdown. Live budget cascade happens via renderStats; the
   chip/reset visibility are updated per-keystroke in place
   so the input keeps focus.
   ========================================================= */

table.emp td.proposed-cell,
table.emp td.justif-cell {
  white-space: nowrap;
  cursor: default;
}

.proposed-input {
  width: 94px;
  padding: 5px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  text-align: right;
  background: var(--bg-elevated);
  color: var(--ink);
  transition: border-color 140ms ease, background 140ms ease;
}
.proposed-input::placeholder {
  color: var(--ink-muted);
  font-style: italic;
}
.proposed-input:focus {
  outline: none;
  border-color: var(--accent);
}
.proposed-input.edited {
  border-color: var(--accent);
  background: var(--accent-soft);
  font-weight: 500;
}

.delta-chip {
  display: inline-block;
  margin-left: 6px;
  font-size: 11px;
  font-weight: 500;
  padding: 1px 7px;
  border-radius: var(--radius-sm);
  font-variant-numeric: tabular-nums;
  min-width: 54px;
  text-align: center;
  visibility: hidden;
}
.delta-chip.shown { visibility: visible; }
.delta-chip.safe { background: var(--safe-bg); color: var(--safe-ink); }
.delta-chip.risk { background: var(--risk-bg); color: var(--risk-ink); }
.delta-chip.neutral { background: var(--line); color: var(--ink-muted); }

.row-reset {
  display: none;
  margin-left: 4px;
  background: none;
  border: none;
  color: var(--ink-muted);
  font-size: 14px;
  padding: 2px 6px;
  cursor: pointer;
  line-height: 1;
  transition: color 120ms ease;
}
.row-reset.shown { display: inline-block; }
.row-reset:hover { color: var(--ink); }

.justif-select {
  padding: 5px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: 12px;
  background: var(--bg-elevated);
  color: var(--ink);
  max-width: 170px;
  cursor: pointer;
}
.justif-select:focus {
  outline: none;
  border-color: var(--accent);
}

/* Small reminder ribbon above the roster when any edits exist.
   Lightweight alternative to the full sidecar panel (decision trail
   is deferred to Patch 5c). */
.edits-ribbon {
  display: none;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  margin-bottom: 14px;
  background: var(--accent-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: 12px;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}
.edits-ribbon.shown { display: flex; }
.edits-ribbon strong {
  color: var(--ink);
  font-weight: 600;
}
.edits-ribbon .ribbon-sep {
  color: var(--line-strong);
}
.edits-ribbon button {
  margin-left: auto;
  background: none;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  padding: 4px 10px;
  font-family: inherit;
  font-size: 11px;
  color: var(--ink-soft);
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}
.edits-ribbon button:hover {
  background: var(--bg-elevated);
  color: var(--ink);
}

/* =========================================================
   Patch 5b.5 — Structured reasoning card
   ---------------------------------------------------------
   Replaces the dense prose paragraph + separate suggested-
   range block inside the cohort lens. Three-block structure
   matching the Finding · Options · Recommendation pattern
   observed in Ravio / Complete / Assemble pay-equity UIs.
   Audit-narrative expand uses native <details>/<summary>
   so there is zero JS overhead for the collapse state.
   ========================================================= */

.reasoning-card {
  margin-top: 16px;
  padding: 16px 18px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.reasoning-card .finding {
  font-size: 14px;
  color: var(--ink);
  line-height: 1.55;
  margin-bottom: 14px;
}
.reasoning-card .finding b { font-weight: 600; }
.reasoning-card .finding .finding-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  margin-right: 8px;
  vertical-align: 1px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.reasoning-card .finding .finding-pill.risk  { background: var(--risk-bg); color: var(--risk-ink); }
.reasoning-card .finding .finding-pill.safe  { background: var(--safe-bg); color: var(--safe-ink); }
.reasoning-card .finding .finding-pill.warn  { background: var(--warn-bg); color: var(--warn-ink); }

/* Options table — three rows of remediation paths with cost + residual gap */
.options-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 6px;
  margin-bottom: 10px;
  font-size: 13px;
}
.options-table th {
  text-align: left;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
  font-weight: 500;
  padding: 6px 10px 8px;
  border-bottom: 1px solid var(--line);
}
.options-table th.num { text-align: right; }
.options-table td {
  padding: 9px 10px;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
}
.options-table td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.options-table tbody tr.recommended {
  background: var(--accent-soft);
}
.options-table tbody tr.recommended td:first-child {
  position: relative;
  padding-left: 22px;
  font-weight: 600;
}
.options-table tbody tr.recommended td:first-child::before {
  content: "→";
  position: absolute;
  left: 8px;
  color: var(--accent);
  font-weight: 600;
}
.options-table tbody tr:last-child td { border-bottom: none; }

/* Collapsible audit narrative — uses native <details>, no JS */
.reasoning-card details.audit-expand {
  margin-top: 8px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}
.reasoning-card details.audit-expand summary {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
  cursor: pointer;
  list-style: none;
  padding: 4px 0;
  user-select: none;
}
.reasoning-card details.audit-expand summary::-webkit-details-marker {
  display: none;
}
.reasoning-card details.audit-expand summary::before {
  content: "▸ ";
  color: var(--ink-muted);
  transition: transform 160ms ease;
  display: inline-block;
}
.reasoning-card details.audit-expand[open] summary::before {
  content: "▾ ";
}
.reasoning-card details.audit-expand summary:hover {
  color: var(--ink-soft);
}
.reasoning-card details.audit-expand .audit-body {
  font-size: 12px;
  color: var(--ink-soft);
  line-height: 1.6;
  padding: 10px 4px 4px;
}
.reasoning-card details.audit-expand .audit-body b {
  color: var(--ink);
  font-weight: 600;
}

/* When no remediation is needed (no flag), the finding block still has
   the merit line below it — but tighter than the flagged-options case. */
.reasoning-card.no-remediation .finding {
  margin-bottom: 10px;
}

/* Merit line — single actionable row for non-flagged cases, visually
   analogous to the recommended row in the options table. */
.merit-line {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 10px 14px;
  background: var(--accent-soft);
  border-radius: var(--radius-sm);
  font-size: 13px;
  color: var(--ink);
  margin-bottom: 10px;
}
.merit-line .merit-arrow {
  color: var(--accent);
  font-weight: 600;
}
.merit-line .merit-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
  font-weight: 500;
}
.merit-line .merit-value {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--ink);
  font-size: 14px;
}
.merit-line .merit-sub {
  color: var(--ink-soft);
  font-size: 12px;
  margin-left: auto;
}

/* =========================================================
   Patch 5c.2 — Cohort methodology block + gap-grid overflow
   safety + reveal/craft polish + scatter density tweaks
   ---------------------------------------------------------
   The "how cohorts are defined" info surface is a
   collapsible <details> block at the top of the gap grid
   panel so comp heads can verify the methodology before
   approving numbers. The block is closed by default so
   power users aren't slowed down, but the first line of
   each entry is scannable at a glance.
   ========================================================= */

.cohort-methodology {
  margin: -4px 0 18px;
  padding: 14px 16px;
  background: linear-gradient(
    to bottom right,
    var(--accent-soft),
    var(--bg-elevated) 80%
  );
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.cohort-methodology summary {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--accent);
  cursor: pointer;
  font-weight: 600;
  padding: 2px 0;
  list-style: none;
  user-select: none;
}
.cohort-methodology summary::-webkit-details-marker { display: none; }
.cohort-methodology summary::before {
  content: "▸ ";
  color: var(--accent);
  transition: transform 160ms ease;
  display: inline-block;
}
.cohort-methodology[open] summary::before { content: "▾ "; }
.cohort-methodology summary:hover { color: var(--ink); }

.cohort-methodology .method-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 24px;
  padding: 14px 0 4px;
}
@media (max-width: 860px) {
  .cohort-methodology .method-body { grid-template-columns: 1fr; gap: 12px; }
}

.cohort-methodology .method-item {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 12px;
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  transition: border-color 180ms ease, transform 180ms ease;
}
.cohort-methodology .method-item:hover {
  border-color: var(--accent);
  transform: translateY(-1px);
}
.cohort-methodology .method-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--ink);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  display: flex;
  align-items: center;
  gap: 6px;
}
.cohort-methodology .method-tag {
  display: inline-block;
  font-size: 9px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 1px 6px;
  background: var(--accent);
  color: var(--on-accent);
  border-radius: 999px;
}
.cohort-methodology .method-def {
  font-size: 12px;
  color: var(--ink-soft);
  line-height: 1.5;
}
.cohort-methodology .method-def code {
  font-family: var(--font-mono);
  font-size: 11px;
  padding: 1px 5px;
  background: var(--accent-soft);
  color: var(--accent);
  border-radius: 3px;
}
.cohort-methodology .method-def em {
  color: var(--ink);
  font-style: normal;
  font-weight: 600;
}

/* Gap grid horizontal overflow safety — at fine grain (14 cols) the
   table may exceed the panel width on narrower viewports. A scroll
   wrapper contains the overflow and keeps the panel border clean. */
.gap-grid-wrap {
  overflow-x: auto;
  overflow-y: hidden;
  margin: 0 -4px;
  padding: 0 4px;
}
.gap-grid-wrap::-webkit-scrollbar { height: 8px; }
.gap-grid-wrap::-webkit-scrollbar-track { background: transparent; }
.gap-grid-wrap::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  border-radius: 4px;
}

/* Gap grid row reveal — staggered fade+slide on first render and
   on grain toggle. Respects prefers-reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
  .gap-grid.reveal tbody tr {
    opacity: 0;
    transform: translateY(6px);
    animation: grid-row-reveal 420ms cubic-bezier(.2,.8,.2,1) forwards;
  }
  .gap-grid.reveal tbody tr:nth-child(1)  { animation-delay:   0ms; }
  .gap-grid.reveal tbody tr:nth-child(2)  { animation-delay:  20ms; }
  .gap-grid.reveal tbody tr:nth-child(3)  { animation-delay:  40ms; }
  .gap-grid.reveal tbody tr:nth-child(4)  { animation-delay:  60ms; }
  .gap-grid.reveal tbody tr:nth-child(5)  { animation-delay:  80ms; }
  .gap-grid.reveal tbody tr:nth-child(6)  { animation-delay: 100ms; }
  .gap-grid.reveal tbody tr:nth-child(7)  { animation-delay: 120ms; }
  .gap-grid.reveal tbody tr:nth-child(8)  { animation-delay: 140ms; }
  .gap-grid.reveal tbody tr:nth-child(9)  { animation-delay: 160ms; }
  .gap-grid.reveal tbody tr:nth-child(10) { animation-delay: 180ms; }
  .gap-grid.reveal tbody tr:nth-child(11) { animation-delay: 200ms; }
  .gap-grid.reveal tbody tr:nth-child(12) { animation-delay: 220ms; }
  .gap-grid.reveal tbody tr:nth-child(n+13) { animation-delay: 240ms; }
}
@keyframes grid-row-reveal {
  to { opacity: 1; transform: translateY(0); }
}

/* Cohort lens empty-state preview — instead of one sentence, give it a
   subtle three-band placeholder so the empty state communicates what
   the lens is going to show. Collapses inside #cohortPanel.cohort-empty. */
.cohort-empty-preview {
  margin-top: 20px;
  padding: 18px 4px 6px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.cohort-empty-preview .cep-row {
  display: grid;
  grid-template-columns: 100px 1fr;
  gap: 14px;
  align-items: center;
  opacity: 0.55;
}
.cohort-empty-preview .cep-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
  font-weight: 500;
}
.cohort-empty-preview .cep-bar {
  position: relative;
  height: 8px;
  background: var(--line);
  border-radius: 4px;
  overflow: hidden;
}
.cohort-empty-preview .cep-bar::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0; left: 20%; width: 55%;
  background: var(--line-strong);
  border-radius: 4px;
}
.cohort-empty-preview .cep-prompt {
  margin-top: 4px;
  text-align: center;
  font-size: 12px;
  color: var(--ink-muted);
  font-style: italic;
}
.cohort-empty-preview .cep-prompt kbd {
  display: inline-block;
  padding: 1px 6px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 4px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-soft);
  margin: 0 2px;
}

/* Loading state on the Load sample button */
.btn.is-loading {
  opacity: 0.7;
  pointer-events: none;
  position: relative;
}
.btn.is-loading::after {
  content: "";
  position: absolute;
  top: 50%; right: 12px;
  width: 10px; height: 10px;
  margin-top: -5px;
  border: 2px solid var(--accent);
  border-top-color: transparent;
  border-radius: 50%;
  animation: btn-spinner 700ms linear infinite;
}
@keyframes btn-spinner {
  to { transform: rotate(360deg); }
}

/* Count-up animation target: ensure tabular numerals during tween so the
   number doesn't jiggle horizontally as digits change. */
.count-up {
  font-variant-numeric: tabular-nums;
  display: inline-block;
}

/* Landscape scatter — dot alpha tweak so dense beeswarm regions breathe.
   Flagged dots stay at full opacity so they remain visible against the
   softer non-flagged background. */
.scatter .dot-emp { fill-opacity: 0.72; }
.scatter .dot-emp.risk { fill-opacity: 1; }
.scatter .dot-emp.selected { fill-opacity: 1; }

/* Clickable cursor hint on stat chip that's wired to filter */
.cockpit-stats .stat-chip.clickable::before {
  content: "";
  position: absolute;
  top: 6px; right: 10px;
  width: 6px; height: 6px;
  background: var(--accent);
  border-radius: 50%;
  opacity: 0;
  transition: opacity 180ms ease;
}
.cockpit-stats .stat-chip.clickable:hover::before { opacity: 1; }
