/* Ariadne — one design system for the public page and the console.

   Quiet neutral surfaces, one accent (the brand's brown), one typeface, one
   type scale, one spacing step, three radii and three shadows. A rule that
   wants a colour, a size, a gap or a corner asks for a token below rather
   than inventing one, and `tests/test_opsui_static.py` holds it there: text
   pairs are re-measured for WCAG AA, status hues for perceptual distance from
   the brand, and every font-size, weight, radius and spacing step against
   this block.

   Structure follows three rules. A panel is the only box on a page; inside
   it, things are separated by hairlines or a tinted fill, never a second
   border. Colour carries a state only alongside text or a shape. And there is
   no decoration that is not information: no accent bars, no gradients, no
   capitals outside table headers and chart axes.

   Inter is served from this origin (the CSP is `default-src 'self'`): the
   Latin subset, upright, one variable file for every weight. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/static/fonts/inter-latin-wght.woff2") format("woff2");
}

:root {
  /* Neutrals: a warm stone ramp, close to grey, so the brown accent is the
     only colour on a page that is not carrying a state. */
  --ink: #1c1917;          /* 17.49:1 on --panel */
  --ink-inverse: #fafaf9;  /* 16.74:1 on --navy */
  --muted: #6b6460;        /*  5.81:1 on --panel, 5.32:1 on --sunken */
  --muted-strong: #44403c; /* 10.27:1 on --panel */
  --line: #e7e5e4;
  --line-strong: #d6d3d1;
  --panel: #ffffff;
  --bg: #fafaf9;
  --sunken: #f5f5f4;

  /* The dark surfaces (the demo bar, tooltips). Kept under the old names. */
  --navy: #1c1917;
  --navy-soft: #292524;

  /* The single accent, which is also the brand. 6.10:1 on white; -strong is
     for text that must hold at small sizes, and the wash is the one tint. */
  --accent: #805a3b;
  --accent-strong: #6c4c32;
  --accent-wash: #f6efe8;

  /* Status. `--warn` is burnt orange, not amber: amber sits on the brand's
     hue, and #8a5a00 against #805a3b is OKLab ΔE 4.6, the same colour to the
     eye. #c2410c is ΔE 12.5. Each status reads on its own wash. */
  --warn: #c2410c;         /* 4.57:1 on --warn-wash */
  --warn-wash: #fdeee3;
  --critical: #9b1c1c;     /* 7.00:1 on --critical-wash */
  --critical-wash: #fbeae7;
  --ok: #1f6f43;           /* 5.32:1 on --ok-wash */
  --ok-wash: #e7f1e9;
  /* What patients said happened, in charts. Five lightness steps (OKLab L
     0.31, 0.43, 0.64, 0.75, 0.87) as well as hues, so "worked" and "didn't
     work" stay apart for a colour-blind reader and in greyscale. The old
     green and red were L 0.48 and 0.45: one colour to many eyes. */
  --chart-worked: #4c9e6e;
  --chart-amber: #dba24a;
  --chart-failed: #8f1d1d;
  --chart-worsened: #5a1414;

  /* Corners: controls, cards, then panels and floating surfaces. -xs is for
     marks inside text and charts. */
  --radius-xs: 3px;
  --radius-sm: 6px;
  --radius: 8px;
  --radius-lg: 10px;
  /* Elevation: a control, a card under the pointer, a floating surface. */
  --shadow-xs: 0 1px 2px rgb(28 25 23 / 0.05);
  --shadow-sm: 0 1px 2px rgb(28 25 23 / 0.04), 0 4px 12px -2px rgb(28 25 23 / 0.08);
  --shadow-lg: 0 16px 40px -8px rgb(28 25 23 / 0.18), 0 4px 10px -4px rgb(28 25 23 / 0.08);
  --shadow: var(--shadow-xs);
  --ring: 0 0 0 3px rgb(128 90 59 / 0.22);
  --control-h: 2rem;
  --gutter: clamp(1rem, 3vw, 2rem);

  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* The landing page's names, kept as aliases so its rules resolve to this
     palette instead of a second one. */
  --brand: var(--accent);
  --brand-strong: var(--accent-strong);
  --brand-wash: var(--bg);
  --brand-wash-2: var(--sunken);
  --brand-line: var(--line);

  /* One type scale (#235). Every font-size in this file is one of these, an
     `em` inside a run of text, or `inherit`. The body is 14px, --fs-md. */
  --fs-2xs: 0.6875rem;   /* 11: table headers, chart axes */
  --fs-xs: 0.75rem;      /* 12: badges, meta */
  --fs-sm: 0.8125rem;    /* 13: notes, secondary text */
  --fs-md: 0.875rem;     /* 14: body, controls, table cells */
  --fs-base: 0.9375rem;  /* 15: lead prose */
  --fs-lg: 1rem;         /* 16: panel titles */
  --fs-xl: 1.25rem;      /* 20: view titles */
  --fs-2xl: 1.5rem;      /* 24: metric figures */
  --fs-display: 2rem;    /* 32: the one headline number */
  /* SVG text is in user units, so it scales with its drawing: px, three steps. */
  --fs-svg-sm: 10px;
  --fs-svg: 11px;
  --fs-svg-lg: 12px;
  /* The signed-out landing page only. */
  --fs-landing-section: clamp(1.5rem, 3vw, 2rem);
  --fs-landing-hero: clamp(2.1rem, 5vw, 3.25rem);
  /* One 4px spacing step. */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-7: 1.75rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
}

* { box-sizing: border-box; }

html { accent-color: var(--accent); }
body {
  margin: 0;
  font: 14px/1.5 var(--font-sans);
  font-feature-settings: "cv11", "ss01";
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  -webkit-text-size-adjust: 100%;
}
a { color: var(--accent-strong); text-underline-offset: 2px; }
::selection { background: var(--accent-wash); color: var(--ink); }

/* One visible focus treatment everywhere, including inside the SVGs. Keyboard
   only — a mouse click on a card should not leave a ring behind. Controls
   draw it as a soft ring instead of an outline. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 50;
  background: var(--panel);
  color: var(--accent-strong);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
  font-weight: 500;
}
.skip-link:focus { left: var(--space-3); top: var(--space-3); }

h1, h2, h3, h4 { font-weight: 600; letter-spacing: -0.011em; line-height: 1.25; }
h1 { font-size: var(--fs-lg); margin: 0; }
h2 { font-size: var(--fs-lg); margin: 0 0 var(--space-3); }
h3 { font-size: var(--fs-md); margin: var(--space-5) 0 var(--space-2); color: var(--ink); }
h4 { font-size: var(--fs-md); }
.sub { margin: var(--space-1) 0 0; color: var(--muted); font-size: var(--fs-sm); max-width: 46rem; }

/* =====================================================================
   Header
   One white bar: the mark and name, what the page is reading (therapy
   area, the seat it is read as) as quiet selects, and the person's own
   account behind one menu. The tab row below shares its surface, so the
   chrome reads as one piece with a single hairline under it.
   ===================================================================== */

header {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  align-items: center;
  min-height: 3.5rem;
  padding: var(--space-2) var(--gutter);
  background: var(--panel);
  color: var(--ink);
}
header .brand { display: flex; align-items: center; gap: var(--space-1) var(--space-3); flex-wrap: wrap; }
header .brand .sub { flex: 1 1 100%; }
/* The posture line is empty once signed in; an empty line is not chrome. */
header .brand .sub:empty { display: none; }
header h1 { font-size: var(--fs-lg); letter-spacing: -0.015em; }
.brand-logo { width: 28px; height: 28px; align-self: center; border-radius: var(--radius-sm); }
/* The descriptor reads as a second name beside the first; the page title and
   the landing hero already say what the product is. */
.wordmark { display: none; }

.header-context { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4); margin-left: auto; }
.context-control[hidden], .area-context[hidden] { display: none; }
.context-label { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--muted); font-size: var(--fs-sm); }
.context-label select { max-width: 17rem; font-weight: 500; }
.area-context { display: inline-flex; align-items: center; gap: var(--space-2); margin: 0; font-size: var(--fs-sm); color: var(--muted); }
.area-context .area-name { color: var(--ink); font-weight: 500; font-size: var(--fs-md); }

.session { display: flex; align-items: center; gap: var(--space-2); font-size: var(--fs-sm); }
.identity { color: var(--muted); }
.identity:empty { display: none; }
.demo-pill {
  padding: var(--space-1) var(--space-2);
  border-radius: 999px;
  background: var(--accent-wash);
  color: var(--accent-strong);
  font-size: var(--fs-xs);
  font-weight: 500;
}

.account-menu { position: relative; }
.account-menu summary {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-2) var(--space-1) var(--space-1);
  border-radius: 999px;
  color: var(--ink);
  font-size: var(--fs-md);
  font-weight: 500;
  cursor: pointer;
  list-style: none;
  transition: background-color 0.12s ease;
}
.account-menu summary::-webkit-details-marker { display: none; }
.account-menu summary::after {
  content: "";
  width: 0.375rem;
  height: 0.375rem;
  margin: 0 var(--space-1) 0.2rem var(--space-1);
  border-right: 1.5px solid var(--muted);
  border-bottom: 1.5px solid var(--muted);
  transform: rotate(45deg);
}
.account-menu summary:hover, .account-menu[open] summary { background: var(--sunken); }
.avatar {
  display: inline-grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  background: var(--accent);
  color: var(--ink-inverse);
  font-size: var(--fs-2xs);
  font-weight: 600;
}
.account-panel, .nav-more-panel {
  position: absolute;
  top: calc(100% + var(--space-2));
  right: 0;
  z-index: 30;
  padding: var(--space-1);
  background: var(--panel);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}
.account-panel { min-width: 16rem; }
.account-detail {
  margin: 0 0 var(--space-1);
  padding: var(--space-2) var(--space-3) var(--space-3);
  border-bottom: 1px solid var(--line);
  color: var(--muted);
  font-size: var(--fs-sm);
  line-height: 1.4;
}
.account-panel button, .nav-more-panel button {
  display: block;
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  box-shadow: none;
  color: var(--ink);
  font-weight: 400;
  text-align: left;
}
.account-panel button[hidden] { display: none; }
.account-panel button:hover, .account-panel button:focus-visible,
.nav-more-panel button:hover, .nav-more-panel button:focus-visible { background: var(--sunken); color: var(--ink); }

/* =====================================================================
   Controls
   Every button is the secondary button unless it says otherwise: white,
   a control-coloured border, a hairline shadow. One primary (the accent),
   one ghost (no chrome until hovered). Disabled reads as disabled by its
   fill, not by fading the whole control.
   ===================================================================== */

button {
  padding: 0.375rem var(--space-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--panel);
  box-shadow: var(--shadow-xs);
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-md);
  font-weight: 500;
  line-height: 1.25;
  cursor: pointer;
  transition: background-color 0.12s ease, border-color 0.12s ease, color 0.12s ease, box-shadow 0.12s ease;
}
button:hover { background: var(--sunken); }
button:active { background: var(--line); }
button:focus-visible { outline: none; border-color: var(--accent); box-shadow: var(--ring); }
button[disabled] {
  background: var(--sunken);
  border-color: var(--line);
  box-shadow: none;
  color: var(--muted);
  cursor: not-allowed;
}

/* The primary action. One rule for every one of them, so a new primary
   button looks like the others by joining this list. */
.btn-primary, #signin, #save-password, .inline-confirm .confirm-yes,
.tour-primary, .guide-start, .signin-open, .landing-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--ink-inverse);
  box-shadow: var(--shadow-xs), inset 0 1px 0 rgb(255 255 255 / 0.1);
}
.btn-primary:hover, #signin:hover, #save-password:hover, .inline-confirm .confirm-yes:hover,
.tour-primary:hover, .guide-start:hover, .signin-open:hover, .signin-open[aria-expanded="true"],
.landing-primary:hover {
  background: var(--accent-strong);
  border-color: var(--accent-strong);
  color: var(--ink-inverse);
}
.btn-primary[disabled], #signin:disabled { background: var(--accent); border-color: var(--accent); color: var(--ink-inverse); opacity: 0.6; cursor: progress; }

/* The ghost: an action that should not compete with the content beside it. */
.btn-ghost, .tour-hide, .tour-back, .tour-close, .back-link {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  color: var(--muted-strong);
}
.btn-ghost:hover, .tour-hide:hover, .tour-back:hover, .tour-close:hover, .back-link:hover {
  background: var(--sunken);
  color: var(--ink);
}

/* Text fields and selects: the button's height, border and focus ring. */
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]), select, textarea {
  max-width: 100%;
  padding: 0.375rem var(--space-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--panel);
  box-shadow: var(--shadow-xs);
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-md);
  line-height: 1.25;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
select { padding-right: var(--space-2); cursor: pointer; }
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):hover, select:hover, textarea:hover { border-color: var(--muted); }
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--ring);
}
input::placeholder, textarea::placeholder { color: var(--muted); opacity: 1; }

/* Scoped to the console's own nav by id, not to the `nav` element. A bare
   `nav` selector also claimed the landing page's navs — its header links
   carry overrides for exactly that, and the footer's grew a white panel and
   a flex row the moment it was added. `app.js` only ever reaches this one
   through getElementById("nav").

   The view nav reads as tabs on the header's own surface: one row of labels,
   the active one in ink with the accent underline and `aria-current`, so the
   active view is not carried by colour alone. */
#nav {
  display: flex;
  flex-wrap: nowrap;
  gap: 0 var(--space-1);
  scrollbar-width: thin;
  padding: 0 var(--gutter);
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  overflow: visible;
}
#nav:empty { display: none; }
#nav button {
  position: relative;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  padding: var(--space-3) var(--space-2);
  color: var(--muted);
  font-weight: 500;
  white-space: nowrap;
}
#nav button::after {
  content: "";
  position: absolute;
  left: var(--space-2);
  right: var(--space-2);
  bottom: -1px;
  height: 2px;
  border-radius: var(--radius-xs) var(--radius-xs) 0 0;
  background: transparent;
}
#nav button:hover { color: var(--ink); }
#nav button:focus-visible { box-shadow: none; outline: 2px solid var(--accent); outline-offset: -4px; border-radius: var(--radius-sm); }
#nav button.active { color: var(--ink); }
#nav button.active::after { background: var(--accent); }

/* The demo is said once, quietly, above everything: a thin dark bar rather
   than an alert strip, because nothing is wrong. */
.demo-banner {
  margin: 0;
  padding: 0.375rem var(--gutter);
  background: var(--navy);
  color: var(--ink-inverse);
  font-size: var(--fs-xs);
  font-weight: 500;
  text-align: center;
}

main {
  padding: var(--space-6) var(--gutter) var(--space-12);
  max-width: 88rem;
  margin: 0 auto;
}
.status { min-height: 1.25rem; color: var(--muted); font-size: var(--fs-sm); margin: 0 0 var(--space-2); }
.status:empty { min-height: 0; margin: 0; }
.status.error { color: var(--critical); font-weight: 500; }
.status.error::before { content: "⚠ "; }

/* The one box on a page. */
.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  margin-bottom: var(--space-4);
}
.panel > h2 { margin: 0 0 var(--space-3); font-size: var(--fs-lg); }
.panel > h2 + .note, .panel > h2 + p.muted { margin-top: calc(var(--space-2) * -1); margin-bottom: var(--space-4); }

/* A disclosure: a line of text with a chevron that turns. Where it opens a
   panel, it is the panel's title and takes the title's size. */
details.disclosure > summary, details.withheld-rows > summary {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  font-weight: 500;
  font-size: var(--fs-md);
  color: var(--ink);
  list-style: none;
}
.panel > details.disclosure:first-child > summary { font-size: var(--fs-lg); font-weight: 600; letter-spacing: -0.011em; }
details.disclosure + details.disclosure { margin-top: var(--space-2); }
details.disclosure > summary::-webkit-details-marker, details.withheld-rows > summary::-webkit-details-marker { display: none; }
details.disclosure > summary::before, details.withheld-rows > summary::before {
  content: "";
  flex: none;
  width: 0.4rem;
  height: 0.4rem;
  margin: 0 var(--space-1) 0 0.15rem;
  border-right: 1.5px solid var(--muted);
  border-bottom: 1.5px solid var(--muted);
  transform: rotate(-45deg);
  transition: transform 0.15s ease;
}
details.disclosure[open] > summary { margin-bottom: var(--space-3); }
details.disclosure[open] > summary::before, details.withheld-rows[open] > summary::before { transform: rotate(45deg); }

/* Wide tables scroll inside their panel rather than stretching the page. */
.table-scroll { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: var(--fs-md); font-variant-numeric: tabular-nums; }
th, td { text-align: left; padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--line); vertical-align: middle; }
thead th {
  color: var(--muted);
  font-weight: 500;
  font-size: var(--fs-2xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
}
tbody tr { transition: background-color 0.1s ease; }
tbody tr:hover { background: var(--bg); }
tbody tr:last-child > td { border-bottom: 0; }
th.num, td.num { text-align: right; font-variant-numeric: tabular-nums; }

dl.kv {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-2) var(--space-6);
  margin: var(--space-1) 0 0;
  font-size: var(--fs-md);
}
dl.kv dt { color: var(--muted); }
dl.kv dd { margin: 0; font-variant-numeric: tabular-nums; }

/* One tag: a tinted label the height of a line of small text. Status tags
   take their status's wash; `suppressed` is the one with an edge, dotted,
   because it marks something that is not there. */
.badge {
  display: inline-block;
  padding: 0.0625rem var(--space-2);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: var(--sunken);
  color: var(--muted-strong);
  font-size: var(--fs-xs);
  font-weight: 500;
  line-height: 1.4;
  vertical-align: 0.05em;
}
.badge.analyst-only { background: var(--warn-wash); color: var(--warn); }
.badge.suppressed { background: transparent; border: 1px dotted var(--line-strong); color: var(--muted); }
.badge.neutral { background: var(--sunken); color: var(--muted); }
.suppressed-item { color: var(--muted); opacity: 0.55; cursor: help; }
.badge.report-ready { background: var(--ok-wash); color: var(--ok); }
.badge.critical { background: var(--critical-wash); color: var(--critical); }
.badge.warn { background: var(--warn-wash); color: var(--warn); }
.badge.info { background: var(--accent-wash); color: var(--accent-strong); }
.badge.ok { background: var(--ok-wash); color: var(--ok); }

.note { color: var(--muted); font-size: var(--fs-sm); margin: var(--space-3) 0 0; }
.limitations {
  background: var(--sunken);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  margin: var(--space-3) 0 0;
  color: var(--muted-strong);
  font-size: var(--fs-sm);
}
.limitations .badge { background: var(--panel); }

.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr)); gap: var(--space-3); }
.blocker-columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6); }
.blocker-column { min-width: 0; }
.blocker-column h3 { margin: 0 0 var(--space-2); }
.blocker-list { margin: 0; padding-left: var(--space-5); }
.specificity-graph { display: block; width: 100%; min-height: 11rem; margin: var(--space-4) 0; }
.outcome-flow-frame { position: relative; }
.specificity-solution { cursor: help; }
.specificity-solution:focus { outline: none; }
.specificity-solution:focus .specificity-node.solution { stroke: var(--accent-strong); stroke-width: 2; }
/* The hover readout: a tooltip, so it floats rather than sitting in a box. */
.outcome-summary {
  display: grid;
  gap: var(--space-1);
  min-height: 0;
  width: fit-content;
  max-width: min(28rem, 100%);
  margin: calc(var(--space-1) * -1) 0 var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--navy);
  color: var(--ink-inverse);
  box-shadow: var(--shadow-sm);
  font-size: var(--fs-sm);
}
.outcome-summary:empty { display: none; }
.outcome-summary strong { font-size: var(--fs-sm); font-weight: 600; }
.specificity-node { stroke: var(--line-strong); stroke-width: 1; }
.specificity-node.blocker { fill: var(--critical-wash); }
.specificity-node.solution { fill: var(--ok-wash); }
.specificity-node-label { fill: var(--ink); font-size: var(--fs-svg-lg); font-weight: 600; }
.outcome-fraction { fill: var(--muted-strong); font-size: var(--fs-svg); }
.outcome-link { fill: none; stroke-linecap: round; stroke-opacity: 0.72; }
.outcome-link.source { stroke: var(--accent); stroke-opacity: 0.42; }
.outcome-link.helped { stroke: var(--chart-worked); }
.outcome-link.no-effect { stroke: var(--chart-failed); }
.outcome-link.worsened { stroke: #7f1d1d; }
.outcome-link.mixed { stroke: var(--chart-amber); }
.outcome-edge-label rect { fill: var(--panel); stroke: var(--line); }
.outcome-edge-label text { fill: var(--muted-strong); font-size: var(--fs-svg-sm); font-weight: 600; }
.outcome-node { stroke-width: 1; }
.outcome-node.helped { fill: var(--ok-wash); stroke: var(--ok); }
.outcome-node.no-effect { fill: var(--critical-wash); stroke: var(--critical); }
.outcome-node.worsened { fill: var(--critical-wash); stroke: #7f1d1d; }
.outcome-node.mixed { fill: var(--warn-wash); stroke: var(--chart-amber); }
.card {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--space-4);
  background: var(--panel);
}
.card h4 { margin: 0 0 var(--space-1); font-size: var(--fs-md); }
.card ul { margin: var(--space-2) 0 0; padding-left: var(--space-4); font-size: var(--fs-sm); word-break: break-word; }

.item { border-top: 1px solid var(--line); padding: var(--space-3) 0; }
.item:first-of-type { border-top: none; }
.item .controls { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; margin-top: var(--space-2); }
.item .controls input { flex: 1 1 18rem; }
.history { font-size: var(--fs-xs); color: var(--muted); margin: var(--space-1) 0 0; padding-left: var(--space-4); }

.controls-bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  margin-bottom: var(--space-4);
  font-size: var(--fs-md);
}
.controls-bar label { color: var(--muted-strong); font-weight: 500; }
.controls-bar input[type="search"] { flex: 1 1 16rem; max-width: 26rem; }

/* Back out of a drill-in: a named destination, not a bare arrow. */
.back-link { margin-left: calc(var(--space-2) * -1); padding-left: var(--space-2); }
.view-heading { margin: 0 0 var(--space-5); font-size: var(--fs-xl); letter-spacing: -0.015em; }
.view-heading:has(+ .view-subheading) { margin-bottom: var(--space-1); }
.view-subheading { margin: 0 0 var(--space-6); color: var(--muted); font-size: var(--fs-md); max-width: 70ch; }

/* Journey visuals — colors live here, geometry in SVG attributes (CSP-safe). */
svg.funnel { display: block; width: 100%; max-width: 40rem; height: auto; }
svg.stagebar { display: block; width: 100%; height: 8px; margin: var(--space-3) 0 var(--space-2); border-radius: 999px; overflow: hidden; }
.funnel-track { fill: var(--bg); stroke: var(--line); stroke-width: 1; }
.funnel-label { font-size: var(--fs-svg); fill: var(--muted); }
.funnel-label.wavering { fill: var(--warn); font-weight: 600; }
.funnel-value { font-size: var(--fs-svg); fill: var(--ink); font-variant-numeric: tabular-nums; }
.funnel-bar.stage-considering { fill: #e3d5c6; }
.funnel-bar.stage-initiating { fill: #c4a382; }
.funnel-bar.stage-titrating { fill: #9c7350; }
.funnel-bar.stage-maintaining { fill: #4f7a5a; }
.funnel-bar.stage-wavering { fill: #d39a3a; }
.funnel-bar.stage-discontinued { fill: #b04a3e; }
.funnel-bar.stage-switched { fill: #7d6b98; }
.funnel-bar.stage-restarted { fill: #4f8b86; }
.journey-controls { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; margin: var(--space-3) 0 0; }
/* Fixed pixel scale: the frame scrolls rather than the drawing stretching. */
.journey-atlas-frame { overflow-x: auto; margin-top: var(--space-2); }
.journey-atlas { display: block; max-width: none; margin: 0 auto; }
.journey-flow { fill: none; stroke: var(--accent); stroke-opacity: 0.38; stroke-linecap: round; }
.journey-flow.suppressed { stroke-opacity: 0.35; stroke-dasharray: 3 4; }
.journey-flow:hover { stroke-opacity: 0.6; }
.journey-bar { fill: var(--ok); }
.journey-box { fill: var(--panel); stroke: var(--critical); stroke-width: 1.2; }
.journey-node.withheld .journey-box { stroke: var(--line-strong); stroke-dasharray: 4 3; }
.journey-node.withheld .journey-label { fill: var(--muted); }
.journey-label { font-size: var(--fs-svg-lg); fill: var(--ink); }
.journey-count { font-size: var(--fs-svg); fill: var(--muted); font-variant-numeric: tabular-nums; }
.journey-lane-label { font-size: var(--fs-svg); fill: var(--muted); font-style: italic; }

/* Provenance walkthrough: spaCy-style inline entities, followed by the
   extracted relation so a reader can follow text → structured graph. */
.extraction-example + .extraction-example { margin-top: var(--space-6); padding-top: var(--space-6); border-top: 1px solid var(--line); }
.extraction-comment {
  padding: var(--space-4);
  border-radius: var(--radius);
  background: var(--sunken);
  line-height: 2.3;
}
.extraction-entity {
  display: inline;
  margin: 0 0.08rem;
  padding: 0.08rem 0.16rem var(--space-1);
  border-radius: var(--radius-xs);
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
button.extraction-entity {
  background: transparent;
  border: 0;
  color: inherit;
  cursor: pointer;
  font: inherit;
  text-align: inherit;
}
button.extraction-entity:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.extraction-entity.blocker { background: var(--critical-wash); border-bottom: 2px solid var(--critical); }
.extraction-entity.remedy { background: var(--ok-wash); border-bottom: 2px solid var(--ok); }
.ontology-graph {
  display: block;
  width: 100%;
  min-height: 12rem;
  margin: var(--space-3) 0;
  border-radius: var(--radius);
  background: var(--sunken);
}
.ontology-graph-edge { stroke: var(--accent); stroke-width: 1.5; stroke-opacity: 0.52; }
.ontology-graph-node rect { fill: var(--panel); stroke: var(--line-strong); stroke-width: 1; }
.ontology-graph-node.selected rect { fill: var(--ok-wash); stroke: var(--ok); stroke-width: 2; }
.ontology-graph-node.clickable { cursor: pointer; }
.ontology-graph-node.clickable:hover rect { stroke: var(--accent-strong); stroke-width: 2; }
.ontology-graph-label { fill: var(--ink); font-size: var(--fs-svg-lg); font-weight: 600; }
.ontology-graph-detail { fill: var(--muted-strong); font-size: var(--fs-svg-sm); }
.extraction-label {
  margin-left: 0.3rem;
  color: var(--muted-strong);
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.04em;
  vertical-align: super;
}
.extraction-relation {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-3);
}
.relation-node {
  display: grid;
  gap: 0.05rem;
  min-width: 9rem;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--sunken);
}
.relation-node strong { font-size: var(--fs-sm); font-weight: 600; }
.relation-node span { color: var(--muted); font-size: var(--fs-xs); }
.relation-node.blocker { background: var(--critical-wash); }
.relation-node.blocker span { color: var(--critical); }
.relation-node.remedy { background: var(--ok-wash); }
.relation-node.remedy span { color: var(--ok); }
.relation-edge {
  display: grid;
  justify-items: center;
  color: var(--muted);
  font-size: var(--fs-2xs);
}
.relation-arrow { color: var(--accent-strong); font-size: var(--fs-2xl); line-height: 1; }
@media (max-width: 540px) {
  .extraction-relation { align-items: stretch; flex-direction: column; }
  .relation-edge { grid-template-columns: auto auto; justify-content: start; gap: var(--space-2); }
}

/* My drugs — the landing view, so it is the one that has to be scannable at a
   glance: brand, then the molecule under it, then the counts, then the stage
   mix, then the single top reason people stop. */
.drug-card {
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.drug-card h4 { margin: 0; font-size: var(--fs-lg); }
.drug-card .molecule { margin: 0; color: var(--muted); font-size: var(--fs-sm); }
.drug-card .cohort-stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-4);
  margin: var(--space-2) 0 var(--space-1);
  font-size: var(--fs-sm);
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.drug-card .cohort-stats b { font-weight: 600; color: var(--ink); }
.drug-card:hover, .drug-card:focus-visible {
  border-color: var(--line-strong);
  box-shadow: var(--shadow-sm);
}
.drug-card .metric-value { font-size: var(--fs-2xl); }
.drilllink { margin: var(--space-2) 0 0; font-size: var(--fs-sm); color: var(--accent-strong); font-weight: 500; }
.empty-state {
  border-radius: var(--radius);
  background: var(--sunken);
  padding: var(--space-6) var(--space-4);
  color: var(--muted);
  font-size: var(--fs-md);
  text-align: center;
  margin: 0;
}

/* Kaplan-Meier chart */
svg.km { display: block; width: 100%; height: auto; margin: var(--space-1) 0 var(--space-3); }
.km-mark-guide { stroke: var(--accent); stroke-width: 1; stroke-dasharray: 3 3; opacity: 0.6; }
.km-mark { color: var(--accent); stroke: var(--panel); stroke-width: 2; }
.km-mark-label { font-size: var(--fs-svg-lg); font-weight: 600; fill: var(--ink); paint-order: stroke; stroke: var(--panel); stroke-width: 3px; }
.km-grid { stroke: var(--line); stroke-width: 1; }
.km-tick { font-size: var(--fs-svg-sm); fill: var(--muted); }
.km-line { stroke: var(--accent); stroke-width: 2; }
.km-band { fill: var(--accent); opacity: 0.12; stroke: none; }

/* Network graph — drug / blocker / remedy. Geometry is computed in JS and
   set as SVG attributes; everything visual lives here (CSP: no inline style). */
/* Fixed pixel scale: the frame scrolls rather than the drawing stretching,
   so names stay 12px on any window. */
.net-frame { overflow-x: auto; margin-top: var(--space-2); }
svg.network { display: block; max-width: none; margin: 0 auto; background: var(--bg); border-radius: var(--radius); }
.net-heading { font-size: var(--fs-svg); font-weight: 500; fill: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.net-node { cursor: pointer; }
.net-node:focus { outline: none; }
.net-box { fill: var(--panel); stroke: var(--line-strong); stroke-width: 1.2; }
.net-node:focus .net-box, .net-node:hover .net-box { stroke-width: 2; }
.net-node.kind-drug .net-box { stroke: var(--accent); }
.net-node.kind-driver .net-box { stroke: var(--critical); }
.net-node.kind-remedy .net-box { stroke: var(--ok); }
.net-dot { stroke: none; }
.net-label { font-size: var(--fs-svg-lg); fill: var(--ink); pointer-events: none; }
.net-count { font-size: var(--fs-svg); fill: var(--muted); font-variant-numeric: tabular-nums; pointer-events: none; }
.net-node.kind-drug .net-dot { fill: var(--accent); }
.net-node.kind-drug .net-label { font-weight: 600; }
.net-node.kind-driver .net-dot { fill: var(--critical); }
.net-node.kind-remedy .net-dot { fill: var(--ok); }

/* Edge width IS the finding: blocker -> remedy thickness is semantic
   specificity, so a remedy recommended for everything stays at band 1
   everywhere it appears. */
.net-edge { fill: none; stroke: var(--muted); stroke-opacity: 0.5; }
.net-edge.band-1 { stroke-width: 1; stroke-opacity: 0.35; }
.net-edge.band-2 { stroke-width: 1.8; }
.net-edge.band-3 { stroke-width: 2.8; }
.net-edge.band-4 { stroke-width: 4; }
.net-edge.band-5 { stroke-width: 5.5; stroke-opacity: 0.72; }
/* Two width scales, two encodings. drug -> blocker bands on the blocker's share
   of the drug's posts; blocker -> remedy on the remedy tables' specificity
   score (#211). Drawn identically
   they asserted one semantics for both, and the legend named only the second
   (#151). Hue separates them; the band still carries the magnitude. */
.net-edge.weight-share { stroke: var(--muted); }
.net-edge.weight-specificity { stroke: var(--accent); stroke-opacity: 0.6; }
/* Below the small-cell floor: the link is real, the count is not published. */
.net-edge.suppressed { stroke-dasharray: 2 3; stroke-opacity: 0.3; }
.net-node.suppressed .net-box { stroke: var(--line-strong); stroke-dasharray: 4 3; }
.net-node.suppressed .net-label { fill: var(--muted); }
/* The discount could not be computed at all — never dressed up as a ranking. */
.net-edge.unranked { stroke-dasharray: 5 3; stroke: var(--warn); }

/* Arrowheads follow the stroke they terminate, so direction reads as a
   property of the edge rather than as a third encoding (#151). `fill` and not
   `stroke`: a marker path is filled, and inheriting the edge's stroke here
   would draw an outline around a hollow triangle. */
.net-arrow path { fill: var(--muted); }
.net-arrow.weight-specificity path { fill: var(--accent); }

svg.network.focused .net-edge.dim { stroke-opacity: 0.06; }
svg.network.focused .net-node.dim { opacity: 0.25; }
svg.network.focused .net-node.lit .net-label { font-weight: 600; }
svg.network.focused .net-edge.lit { stroke: var(--accent); stroke-opacity: 0.9; }

.net-sample { flex: none; overflow: visible; }
.net-legend { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); align-items: center; margin-bottom: var(--space-3); font-size: var(--fs-sm); color: var(--muted-strong); }
.net-key { display: inline-flex; align-items: center; gap: var(--space-2); }
/* Key samples reuse the graph's own classes; they are not clickable. */
.net-sample .net-node { cursor: default; }

/* Drill-down: the route from a number to the sentences behind it (#151).
   Rendered under the table it was opened from, so the count and its evidence
   are on screen together and nobody has to hold one in their head. */
button.linkish {
  background: none;
  border: 0;
  padding: 0;
  box-shadow: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-align: left;
}
button.linkish:hover { background: none; }
button.linkish:hover .term-name, button.linkish:focus-visible .term-name { border-bottom-style: solid; }
.evidence-drawer:empty { display: none; }
.evidence-drawer {
  margin-top: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius);
  background: var(--sunken);
}
.evidence-drawer > h3:first-child, .evidence-drawer > h4:first-child { margin-top: 0; }
ul.evidence { margin: var(--space-2) 0 0; padding-left: var(--space-4); }
ul.evidence li { margin-bottom: var(--space-2); font-size: var(--fs-sm); }
/* Analyst-only material, and it should not be mistakable for prose the
   product wrote. */
.evidence-span { font-style: italic; }

/* Patient-reported candidate cards: additive and visually distinct */
.pr-card { border-style: dashed; background: var(--bg); }

/* Guide & glossary */
.term { cursor: help; }
.term-name { border-bottom: 1px dotted var(--muted); }
/* The second line under a driver's name (#242): the plain-language wording on
   a clinical seat, and the code on a seat that works with the pipeline's
   vocabulary. One name on the first line, so a column keeps its left edge. */
.term-sub {
  display: block;
  margin-top: 0.1rem;
  font-size: 0.8em;
  line-height: 1.35;
  color: var(--muted);
}
.term-sub > span { margin-left: 0; }
.term-sub > span + span { margin-left: 0.6em; }
.term-sub .code { font-size: 0.95em; }
/* A relative timestamp ('4 min ago') whose title carries the exact
   instant. Same affordance as .term: dotted underline means hover. */
.ts { border-bottom: 1px dotted var(--muted); cursor: help; }
/* The taxonomy code, kept beside the common name: still the shared vocabulary
   with the CLI, the AE lane and the export pack, but no longer the headline. */
.code {
  margin-left: 0.45em;
  font-family: var(--font-mono);
  font-size: 0.78em;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  white-space: nowrap;
}

/* The plain-language wording beside a clinical name (#203): secondary to the
   name a clinical seat reads first, but prose, not a code. */
.lay { color: var(--muted); }
.guide-section { margin-bottom: var(--space-4); }
.guide-section h3 { margin: 0 0 var(--space-1); color: var(--ink); }
.guide-body { margin: 0; color: var(--muted); font-size: var(--fs-sm); max-width: 46rem; }
.guide-section .controls { margin-top: var(--space-2); }
.guide-section .controls button { padding: var(--space-1) var(--space-3); font-size: var(--fs-sm); }
.guide-appendix {
  margin: var(--space-6) 0 var(--space-2); padding-top: var(--space-4); border-top: 1px solid var(--line);
  color: var(--muted); font-size: var(--fs-2xs); font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.04em;
}

/* Which build is serving, in the footer legend. The commit is set in the same
   monospace as .code: it is a thing you read character by character and quote
   into a bug report, not prose. */
.build { white-space: nowrap; }
.build[title] { cursor: help; }
.build-commit {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* The console's own footer, which carries no class. Scoped away from
   `.landing-footer` for the same reason as `#nav` above: a bare element
   selector handed the landing footer a flex row, its `.landing-inner`
   became a shrinking flex item 480px wide in a 1088px container, and the
   footer's columns collapsed behind it. */
footer:not(.landing-footer) {
  border-top: 1px solid var(--line);
  padding: var(--space-4) var(--gutter);
  color: var(--muted);
  font-size: var(--fs-xs);
  background: var(--bg);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-5);
}

/* Tablet and phone. Nothing is hidden at a narrow width — the chrome stacks,
   the nav scrolls horizontally, and wide tables scroll inside their panel. */
@media (max-width: 60rem) {
  .cards { grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }
}

@media (max-width: 44rem) {
  /* Brand and account on one line, the two selects on the next. */
  header .brand { flex: 1 1 auto; }
  .header-context { order: 3; flex: 1 1 100%; margin-left: 0; gap: var(--space-2) var(--space-3); padding-bottom: var(--space-1); }
  .context-label { flex: 1 1 10rem; }
  .context-label select { flex: 1 1 auto; max-width: none; min-width: 0; }
  .account-name { display: none; }
  #nav { flex-wrap: nowrap; }
  main { padding-top: var(--space-5); }
  .cards { grid-template-columns: 1fr; }
  .panel { padding: var(--space-4); }
  .blocker-columns { grid-template-columns: 1fr; }
  dl.kv { grid-template-columns: 1fr; gap: 0 0; }
  dl.kv dt { margin-top: var(--space-2); font-size: var(--fs-xs); }
  thead th { position: static; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}

/* =====================================================================
   Grouped navigation
   The sections are grouped by the kind of work they do — analysing the
   corpus, operating the pipeline, answering for either — because fourteen
   equal buttons in one wrapped row told a first-time reader nothing about
   where to start. The group label is the only new chrome; the buttons keep
   the underline-active treatment they already had.
   ===================================================================== */

.nav-group { display: flex; flex: none; align-items: center; gap: 0 var(--space-1); }
/* Groups are told apart by a little more space, not a rule; their names are
   the groups' accessible labels and tooltips rather than a row of capitals. */
.nav-group + .nav-group { margin-left: var(--space-4); }
/* Reference sits at the far end of the one row, where help usually lives. */
.nav-group.nav-end { margin-left: auto; }
.nav-more { position: relative; flex: none; margin-left: var(--space-2); }
.nav-more summary {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-2);
  color: var(--muted);
  font-size: var(--fs-md);
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  list-style: none;
}
.nav-more summary::-webkit-details-marker { display: none; }
.nav-more summary::after {
  content: "";
  width: 0.35rem;
  height: 0.35rem;
  margin-bottom: 0.2rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
}
.nav-more summary:hover, .nav-more[open] summary { color: var(--ink); }
.nav-more-panel { top: calc(100% - var(--space-1)); min-width: 13rem; }

/* =====================================================================
   Hero metric — the finding, at the size of a finding
   ===================================================================== */

.metric { margin: var(--space-2) 0 var(--space-3); }
.metric-value {
  font-size: var(--fs-display);
  line-height: 1.1;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
/* Nothing publishable is not a small number: it is not a number at all. */
.metric-value.muted { color: var(--muted); font-size: var(--fs-xl); font-weight: 500; }
.metric-label { font-size: var(--fs-sm); color: var(--muted-strong); margin-top: var(--space-1); }
.metric-sub { font-size: var(--fs-xs); color: var(--muted); margin-top: var(--space-1); }

details.disclosure .disclosure-body { padding-top: 0; }

/* =====================================================================
   Trials beside what patients say (#214) — two columns, never combined
   ===================================================================== */

.trial-panel .trial-title { margin: 0; font-weight: 600; color: var(--ink); }
.trial-panel .trial-head { margin: var(--space-1) 0 var(--space-3); font-size: var(--fs-md); color: var(--muted); }
.trial-panel h3 { margin: var(--space-5) 0 var(--space-2); }
.trial-panel .badge.warn { margin-top: var(--space-3); }
/* A code's posted terms stack one per line; its rates stack beside them. */
.trial-lines > div + div { margin-top: var(--space-1); }
.trial-map-note { color: var(--muted); font-size: var(--fs-xs); margin-top: var(--space-1); max-width: 20rem; }
.trial-citation { color: var(--muted); font-size: var(--fs-xs); margin: var(--space-4) 0 0; overflow-wrap: anywhere; }

/* =====================================================================
   Alerts — severity, then what happened, then the code that names it
   ===================================================================== */

.alert-row {
  display: grid;
  /* Severity, then the sentence, then the code. The code used to hold the
     middle column at `minmax(8rem, max-content)`, which made an identifier
     the most prominent text in the row and pushed what happened to the far
     right. The sentence takes the flexible column now; the code keeps only
     what it needs, at the end, where it is still greppable. */
  /* Not `1fr` for the sentence: on a wide screen that stretched the row to
     the full panel and threw the code a few hundred pixels to the right,
     where it reads as an unrelated column rather than as the name of the
     thing beside it. Capped and start-packed, the code sits just past the
     longest message and the rows still align. */
  grid-template-columns: 4.5rem minmax(0, 52rem) max-content;
  justify-content: start;
  gap: var(--space-3);
  align-items: baseline;
  margin: 0;
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-md);
}
.alert-row:last-child { border-bottom: none; }
.alert-code {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--muted);
}
.alert-message { color: var(--ink); }

@media (max-width: 700px) {
  .alert-row { grid-template-columns: 1fr; gap: var(--space-1); }
}

/* =====================================================================
   Sign in
   A card, the way sign-in looks everywhere: a heading, stacked labelled
   fields, a show-password toggle, one full-width button, and the error
   inside the card it is about. Still a real form, so password managers
   recognise it and Enter submits.
   ===================================================================== */

.signin-card[hidden] { display: none !important; }
.signin-card {
  max-width: 24rem;
  margin: var(--space-12) auto var(--space-8);
  padding: var(--space-7) var(--space-7) var(--space-6);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.signin-card h2 { font-size: var(--fs-xl); margin: 0 0 var(--space-1); letter-spacing: -0.015em; }
.signin-lead { margin: 0 0 var(--space-6); color: var(--muted); font-size: var(--fs-md); }
.signin-field { margin-bottom: var(--space-4); }
.signin-field label { display: block; margin-bottom: var(--space-2); font-size: var(--fs-md); font-weight: 500; color: var(--ink); }
.signin-field input {
  display: block;
  width: 100%;
  padding: var(--space-2) var(--space-3);
  font-size: var(--fs-base);
  line-height: 1.5;
}
.signin-password { position: relative; }
.signin-password input { padding-right: 4.2rem; }
#show-password {
  position: absolute;
  top: 50%;
  right: var(--space-1);
  transform: translateY(-50%);
  padding: var(--space-1) var(--space-2);
  border: 0;
  background: transparent;
  box-shadow: none;
  color: var(--accent-strong);
  font-size: var(--fs-sm);
  font-weight: 500;
}
#show-password:hover { background: var(--sunken); }
#signin {
  display: block;
  width: 100%;
  margin-top: var(--space-2);
  padding: var(--space-2) var(--space-4);
  font-size: var(--fs-md);
  line-height: 1.5;
}
.signin-error[hidden], .signin-hint[hidden] { display: none; }
.signin-error {
  margin: 0 0 var(--space-4);
  padding: var(--space-2) var(--space-3);
  background: var(--critical-wash);
  border-radius: var(--radius-sm);
  color: var(--critical);
  font-size: var(--fs-md);
}
.signin-hint { margin: var(--space-2) 0 0; color: var(--warn); font-size: var(--fs-sm); }
.signin-help { margin: var(--space-5) 0 0; color: var(--muted); font-size: var(--fs-sm); text-align: center; }

@media (max-width: 44rem) {
  .signin-card { margin: var(--space-6) auto; padding: var(--space-6) var(--space-5) var(--space-5); }
}

/* =====================================================================
   Change password
   A panel under the header rather than a modal: it is rare, deliberate,
   and the person using it should still see where they are.
   ===================================================================== */

#password-form[hidden] { display: none !important; }
#password-form {
  display: flex;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  flex-wrap: wrap;
  max-width: 88rem;
  margin: var(--space-4) auto 0;
  padding: var(--space-4) var(--space-5);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
}
@media (min-width: 44rem) {
  #password-form { margin-left: var(--gutter); margin-right: var(--gutter); }
}
#password-form .password-intro {
  flex: 1 1 100%;
  margin: 0 0 var(--space-1);
  color: var(--muted);
  font-size: var(--fs-sm);
}
#password-form label { color: var(--muted-strong); font-size: var(--fs-sm); font-weight: 500; }
#password-form input { width: 11rem; }
.password-note { font-size: var(--fs-sm); color: var(--muted); flex: 1 1 100%; }
.password-note:empty { display: none; }
.password-note.error { color: var(--critical); }

@media (max-width: 700px) {
  #password-form input { width: 100%; flex: 1 1 8rem; }
}

/* Journey tree (#208): one lane per question, boxes sized by authors. */
svg.journey-tree { display: block; max-width: none; }
.journey-tree-heading { font-size: var(--fs-svg); font-weight: 500; fill: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.journey-tree-link { fill: none; stroke: var(--accent); stroke-opacity: 0.22; }
.journey-tree-node rect { fill: var(--panel); stroke: var(--accent); stroke-width: 1.2; }
.journey-tree-node.level-start rect { fill: var(--accent); }
.journey-tree-node.level-start text { fill: var(--panel); }
.journey-tree-node.level-blocker rect { stroke: var(--critical); }
.journey-tree-node.level-remedy rect, .journey-tree-node.level-outcome rect { stroke: var(--ok); }
.journey-tree-node.withheld rect { stroke-dasharray: 4 3; }
.journey-tree-name { font-size: var(--fs-svg-lg); font-weight: 600; fill: var(--ink); }
.journey-tree-count { font-size: var(--fs-svg); fill: var(--muted); }
.journey-tree-rules { font-size: var(--fs-sm); color: var(--muted); margin: var(--space-2) 0 0; padding-left: var(--space-5); }

/* =====================================================================
   Patient-Reported Solutions: one section per blocker, what patients
   tried (with an outcome bar) beside the library's interventions.
   ===================================================================== */

.solutions-intro { margin: 0 0 var(--space-4); }
.solutions-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-8); }
.solutions-col h3 { margin: 0 0 var(--space-3); }
.tried-list { list-style: none; margin: 0; padding: 0; }
.tried-row { padding: var(--space-3) 0; border-top: 1px solid var(--line); }
.tried-row:first-child { border-top: 0; padding-top: 0; }
.tried-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-2); margin-bottom: var(--space-2); }
.tried-name { font-weight: 500; }
.tried-n { margin-left: auto; color: var(--muted); font-size: var(--fs-sm); font-variant-numeric: tabular-nums; }
/* Segments are split by a hairline of the panel's own white, so a sliver
   still reads as its own part. */
.outcome-bar { display: block; width: 100%; height: 10px; border-radius: 999px; overflow: hidden; background: var(--sunken); }
.outcome-bar > rect { stroke: var(--panel); stroke-width: 2; vector-effect: non-scaling-stroke; }
.outcome-worked { fill: var(--chart-worked); }
.outcome-mixed { fill: var(--chart-amber); }
.outcome-did_not_work { fill: var(--chart-failed); }
.outcome-worsened { fill: var(--chart-worsened); }
.outcome-unstated { fill: var(--line-strong); }
/* Withheld: a hatch, never a colour, so it cannot be read as an outcome. */
.outcome-hatch-ground { fill: var(--panel); }
.outcome-hatch-line { stroke: var(--muted); stroke-width: 1; }
.tried-counts { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-4); margin: var(--space-2) 0 0; color: var(--muted-strong); font-size: var(--fs-sm); }
.outcome-count { display: inline-flex; align-items: center; gap: var(--space-1); cursor: default; }
.outcome-count b { font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.outcome-dot { width: 8px; height: 8px; margin-right: var(--space-1); border-radius: 50%; flex: none; }
.dot-worked { background: var(--chart-worked); }
.dot-mixed { background: var(--chart-amber); }
.dot-did_not_work { background: var(--chart-failed); }
.dot-worsened { background: var(--chart-worsened); }
.dot-unstated { background: var(--line-strong); }
.dot-withheld {
  background: repeating-linear-gradient(45deg, var(--muted) 0 1.5px, var(--panel) 1.5px 3.5px);
  box-shadow: inset 0 0 0 1px var(--line-strong);
}
.outcome-count.withheld { cursor: help; }
.outcome-count.withheld b { font-weight: 500; color: var(--muted-strong); }
.library-card { padding: var(--space-4); border-radius: var(--radius); background: var(--sunken); }
.library-card + .library-card { margin-top: var(--space-3); }
.library-card h4 { margin: 0 0 var(--space-1); }
.library-card p { margin: var(--space-2) 0 0; }
.library-card .badge { background: var(--panel); }
.library-badges { margin: 0 !important; }

@media (max-width: 44rem) {
  .solutions-grid { grid-template-columns: 1fr; gap: var(--space-6); }
}

/* Every risk window side by side (#237). Bars share one scale across all four
   columns, so a reader compares windows by length rather than by re-reading
   percentages. A window with nothing above the floor draws no bar at all.
   Drawn at its own size, not stretched: stretched, its 11px labels rendered
   at 24px on a wide screen. */
.windows-overview-frame { overflow-x: auto; margin-top: var(--space-2); }
.windows-overview { display: block; min-width: 42rem; max-width: 100%; height: auto; }
.windows-overview .wo-window { font-size: var(--fs-svg); font-weight: 600; fill: var(--ink); }
.windows-overview .wo-n { font-size: var(--fs-svg-sm); fill: var(--muted); }
.windows-overview .wo-empty { font-size: var(--fs-svg-sm); fill: var(--muted); font-style: italic; }
.windows-overview .wo-label { font-size: var(--fs-svg-sm); fill: var(--muted-strong); }
.windows-overview .wo-share { font-size: var(--fs-svg-sm); fill: var(--muted); font-variant-numeric: tabular-nums; }
.windows-overview .wo-bar rect { fill: var(--accent); fill-opacity: 0.78; }
.windows-overview .wo-bar:hover rect { fill-opacity: 1; }

/* Blocker coverage (#237): which blockers have a proposed lever and which do
   not. No magnitude on the library side — every card's expected effect is the
   literal string "unquantified" — so this carries tier and presence only. */
.coverage-strip {
  display: grid;
  grid-template-columns: minmax(12rem, 2fr) minmax(8rem, 1fr) auto;
  gap: var(--space-2) var(--space-4);
  align-items: center;
  margin-top: var(--space-2);
}
.coverage-strip .cov-head {
  font-size: var(--fs-2xs); font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--muted); border-bottom: 1px solid var(--line); padding-bottom: var(--space-2);
}
.coverage-strip .cov-tried { display: flex; align-items: center; gap: var(--space-2); }
.coverage-strip .cov-bar { width: 4.5rem; height: 8px; }
.coverage-strip .cov-bar rect { fill: var(--accent); fill-opacity: 0.72; }
.coverage-strip .cov-count { font-size: var(--fs-sm); font-variant-numeric: tabular-nums; color: var(--muted); }
.coverage-strip .cov-none { font-size: var(--fs-sm); color: var(--muted); font-style: italic; }
@media (max-width: 44rem) {
  .coverage-strip { grid-template-columns: 1fr; gap: var(--space-1); }
  .coverage-strip .cov-head { display: none; }
}

/* =====================================================================
   Rows below the floor, as one line of names (#243)
   ===================================================================== */
details.withheld-rows {
  margin-top: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--sunken);
  font-size: var(--fs-md);
}
details.withheld-rows > summary { color: var(--muted-strong); font-weight: 400; }
details.withheld-rows[open] > summary { margin-bottom: var(--space-2); }
.withheld-list {
  margin: 0;
  padding-left: var(--space-5);
  columns: 2 16rem;
  column-gap: var(--space-6);
  color: var(--muted-strong);
}
.withheld-list li { break-inside: avoid; margin: var(--space-1) 0; }
.withheld-meta { color: var(--muted); }
.driver-table > .empty-state, .panel > .empty-state { margin-top: var(--space-2); }

/* Stage colours, keyed once above the My drugs grid (#244). The same fills as
   .funnel-bar.stage-*, as backgrounds, since the key is HTML, not SVG. The set
   runs from sand through the brand's brown for the way in, then one muted hue
   per way out, so the accent is never mistaken for a stage. */
.stage-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-4);
  margin: 0 0 var(--space-4);
  font-size: var(--fs-sm);
  color: var(--muted-strong);
}
.stage-key { display: inline-flex; align-items: center; gap: var(--space-2); }
.stage-swatch { width: 0.625rem; height: 0.625rem; border-radius: var(--radius-xs); display: inline-block; }
.stage-swatch.stage-considering { background: #e3d5c6; }
.stage-swatch.stage-initiating { background: #c4a382; }
.stage-swatch.stage-titrating { background: #9c7350; }
.stage-swatch.stage-maintaining { background: #4f7a5a; }
.stage-swatch.stage-wavering { background: #d39a3a; }
.stage-swatch.stage-discontinued { background: #b04a3e; }
.stage-swatch.stage-switched { background: #7d6b98; }
.stage-swatch.stage-restarted { background: #4f8b86; }
.drug-card .metric-empty .metric-label { color: var(--muted-strong); padding: var(--space-2) 0; }

/* =====================================================================
   Phones (#247): tabs scroll sideways instead of hiding behind More, and
   driver tables stack each row as the name, then share · CI · n.
   ===================================================================== */
@media (max-width: 600px) {
  #nav.nav-strip {
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    -webkit-mask-image: linear-gradient(to right, #000 88%, transparent);
    mask-image: linear-gradient(to right, #000 88%, transparent);
  }
  #nav.nav-strip::-webkit-scrollbar { display: none; }
  #nav.nav-strip .nav-group.nav-end { margin-left: var(--space-2); padding-right: var(--space-8); }

  .driver-table .table-scroll { overflow: visible; }
  .driver-table table, .driver-table tbody { display: block; width: 100%; }
  .driver-table thead { display: none; }
  .driver-table tr {
    display: grid;
    grid-template-columns: repeat(3, auto) 1fr;
    align-items: baseline;
    gap: var(--space-1) var(--space-4);
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--line);
  }
  .driver-table tr:last-child { border-bottom: 0; }
  .driver-table tbody tr:hover { background: none; }
  .driver-table td { display: block; padding: 0; border: 0; text-align: left; }
  .driver-table td:nth-child(1) { grid-column: 1 / -1; order: 0; }
  .driver-table td:nth-child(6) { grid-column: 1 / -1; order: 1; }
  .driver-table td:nth-child(6):not(:has(.badge)) { display: none; }
  .driver-table td:nth-child(4) { order: 2; font-weight: 600; }
  .driver-table td:nth-child(5) { order: 3; }
  .driver-table td:nth-child(3) { order: 4; }
  .driver-table td:nth-child(2) { display: none; }
  .driver-table td:nth-child(n+3)::before {
    content: attr(data-label) " ";
    color: var(--muted);
    font-size: var(--fs-xs);
    font-weight: 400;
  }
}

/* =====================================================================
   Review queue (#249): filter chips, a list of one-line items, and the open
   item beside it (full width on a narrow screen).
   ===================================================================== */
.review-chips { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: 0 0 var(--space-2); }
.review-chip {
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--panel);
  box-shadow: none;
  color: var(--muted-strong);
  padding: var(--space-1) var(--space-3);
  font-size: var(--fs-sm);
}
.review-chip b { font-variant-numeric: tabular-nums; margin-left: var(--space-1); font-weight: 600; color: var(--muted); }
.review-chip:hover { background: var(--sunken); color: var(--ink); }
.review-chip.on { background: var(--ink); border-color: var(--ink); color: var(--ink-inverse); }
.review-chip.on b { color: var(--line-strong); }

.review-split {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  gap: var(--space-5);
  margin-top: var(--space-4);
  align-items: start;
}
/* The list and the open item are halves of one panel, split by a hairline,
   not two more boxes inside it. */
.review-list {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--line);
  max-height: 70vh;
  overflow-y: auto;
}
.review-pager { margin-top: var(--space-3); align-items: center; }
.review-row {
  display: grid;
  gap: var(--space-1);
  width: 100%;
  text-align: left;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  background: var(--panel);
  box-shadow: none;
  color: var(--ink);
  padding: var(--space-3);
  font-weight: 400;
}
.review-row:last-child { border-bottom: 0; }
.review-row:hover { background: var(--bg); }
.review-row.selected { background: var(--accent-wash); }
.review-row:focus-visible { box-shadow: inset 0 0 0 2px var(--accent); }
.review-row-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.review-row-reason {
  font-size: var(--fs-md);
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.review-row-meta { font-size: var(--fs-xs); color: var(--muted); font-family: var(--font-mono); }
.review-sla { font-size: var(--fs-xs); font-weight: 600; color: var(--warn); }
.review-sla.late { color: var(--critical); }

.review-detail {
  padding: 0 0 0 var(--space-5);
  border-left: 1px solid var(--line);
  min-width: 0;
}
.review-detail-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: 0; }
.review-detail-reason { margin: var(--space-3) 0 var(--space-4); font-size: var(--fs-lg); }
.review-detail dl.kv dd { overflow-wrap: anywhere; }
.review-controls { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin-top: var(--space-4); }
.review-detail .review-controls { flex-wrap: wrap; }
.review-detail .review-controls input { flex: 1 1 14rem; min-width: 0; }
.review-detail details.disclosure { margin-top: var(--space-5); }
.review-detail details.disclosure > summary { font-size: var(--fs-md); }
.review-back { display: none; }
.review-detail-empty {
  padding: var(--space-8) var(--space-4);
  color: var(--muted);
  font-size: var(--fs-md);
  text-align: center;
  margin: 0;
}

@media (max-width: 800px) {
  .review-split { grid-template-columns: minmax(0, 1fr); }
  .review-list { max-height: none; }
  .review-detail { padding: 0; border-left: 0; }
  .review-detail-empty { display: none; }
  .review-split.has-selection .review-list-col { display: none; }
  .review-back { display: inline-flex; margin-bottom: var(--space-3); }
}

/* A reference that cannot be followed must not look like one that can. */
.citations { margin: var(--space-2) 0 0; padding-left: var(--space-5); }
.citations li { font-size: var(--fs-sm); margin: var(--space-1) 0; overflow-wrap: anywhere; }
.citation-unresolved { color: var(--muted); }
.citation-gap { display: block; font-size: var(--fs-2xs); font-style: italic; opacity: 0.85; }
.citation-provenance { color: var(--muted); }
/* =====================================================================
   Why they stop (#246): the risk window as a segmented control — a sunken
   track with the chosen option raised onto it.
   ===================================================================== */
.segmented {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 2px;
  margin: 0 0 var(--space-5);
  padding: 2px;
  border-radius: var(--radius);
  background: var(--sunken);
  box-shadow: inset 0 0 0 1px var(--line);
  max-width: 100%;
}
.segmented button {
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  box-shadow: none;
  color: var(--muted-strong);
  padding: var(--space-1) var(--space-3);
  font-size: var(--fs-md);
  font-weight: 500;
  white-space: nowrap;
}
.segmented button:hover { background: none; color: var(--ink); }
.segmented button.on { background: var(--panel); color: var(--ink); box-shadow: var(--shadow-xs), 0 0 0 1px var(--line); }
@media (max-width: 600px) {
  .segmented { display: flex; }
  .segmented button { flex: 1 1 45%; }
}

/* The drug page opens on its finding (#245): a row of the numbers the
   rest of the page explains, as the page's first panel. */
.drug-headline {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-5) var(--space-10);
  margin: 0 0 var(--space-4);
  padding: var(--space-5);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
}
.drug-headline .metric { margin: 0; min-width: 0; max-width: 22rem; }
.drug-headline .metric-empty .metric-label { padding: var(--space-2) 0; }

/* Ingestion: a control that cannot be used still has to be legible, and a
   feed's posture has to read as a decision rather than a fault. */
.control-reason { color: var(--muted); font-size: var(--fs-sm); }
.feed-note { color: var(--muted-strong); font-size: var(--fs-sm); margin: var(--space-1) 0 var(--space-2); }
.muted { color: var(--muted); }
/* Ingestion's feed overview: the actions sit in a table cell. */
.controls.feed-actions { display: flex; align-items: center; margin: 0; gap: var(--space-2); flex-wrap: nowrap; }
/* A confirmation asked in place, not by the browser's dialog. */
.inline-confirm {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-1) var(--space-1) var(--space-3);
  background: var(--accent-wash);
  border-radius: var(--radius);
}
.inline-confirm-text { color: var(--ink); font-size: var(--fs-md); }
/* =====================================================================
   Ask (#215): a question, an answer whose every figure links to the field
   it came from, and the calls that produced it.
   ===================================================================== */
/* Ari is a drawer down the right, opened from the bar, over any view — not a
   tab you navigate to and lose your numbers behind. Modelled on .guide-rail
   further down: fixed, --panel, --shadow-lg, a [hidden] rule, a bottom-sheet
   breakpoint, and no animation under reduced motion. */

/* Pinned rather than em-sized: logo.png is a raster, and letting it track the
   font size is how it ends up either towering over the name or blurred. */
.ari-mark { flex: none; width: 1.5rem; height: 1.5rem; }

.ari-open[hidden] { display: none !important; }
.ari-open { display: inline-flex; align-items: center; gap: 0.4rem; }
.ari-open .ari-mark { width: 1.375rem; height: 1.375rem; }

.ari-panel[hidden] { display: none !important; }
.ari-panel {
  position: fixed;
  /* Anchored to the bottom-right and capped, like .guide-rail — not pinned to
     `top: 0`. A full-height slab covered the header's own controls and the tab
     row, which made asking a question look like the panel had taken the app
     over. Growing upward from the corner, with 13rem held back, leaves the
     chrome visible and clickable: the Ari launcher included, so the button
     that opened it can still close it.
     13rem rather than an offset measured at runtime because this file keeps
     geometry in CSS — app.js writes no inline styles anywhere, and the shell's
     CSP declares no style-src of its own. Measured with the demo banner up,
     the tallest the chrome gets: banner + bar + tabs end at 8.25rem, so the
     reservation clears it by about 3.5rem and needs nothing from script. */
  right: var(--space-5);
  bottom: var(--space-5);
  max-height: min(44rem, calc(100vh - 13rem));
  /* One above .guide-rail's 40. The tour rail is the only other fixed thing on
     this edge, and when both are open this one is in front. */
  z-index: 45;
  display: flex;
  flex-direction: column;
  width: min(26rem, calc(100vw - 2 * var(--space-5)));
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  animation: ari-in 0.18s ease-out;
}
@keyframes ari-in { from { transform: translateY(0.75rem); opacity: 0; } }

.ari-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--line);
}
.ari-head h2 { margin: 0; font-size: var(--fs-lg); letter-spacing: -0.015em; }
.ari-close { margin-left: auto; flex: none; }

/* The panel scrolls rather than folding anything away: an answer with its
   provenance measured ~1650px, and disclosure in this app is for version
   stamps and hashes, not for making a panel shorter. */
.ari-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-5);
}
.ari-body > .panel:first-child { margin-top: 0; }
.ari-note { margin: 0 0 var(--space-4); color: var(--muted); font-size: var(--fs-md); }

@media (max-width: 44rem) {
  /* A bottom sheet: there is no room beside the content on a phone, so it
     takes the foot of the screen and leaves the bar above it. */
  .ari-panel {
    right: 0;
    left: 0;
    bottom: 0;
    width: auto;
    max-height: 80vh;
    border-width: 1px 0 0;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  }
  .ari-body { padding-bottom: calc(var(--space-5) + env(safe-area-inset-bottom)); }
}
@media (prefers-reduced-motion: reduce) {
  .ari-panel { animation: none; }
}

/* One column: 28rem has no room for the side column the full-page view had. */
.ask-layout { display: flex; flex-direction: column; gap: var(--space-5); }
.ask-main { min-width: 0; }
.ask-form { display: flex; gap: var(--space-2); }
.ask-form input { flex: 1 1 auto; min-width: 0; font-size: var(--fs-base); padding: var(--space-2) var(--space-3); line-height: 1.5; }
.ask-form button { flex: none; padding-left: var(--space-4); padding-right: var(--space-4); }
.ask-examples { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }
.ask-examples button { border-radius: 999px; box-shadow: none; color: var(--muted-strong); font-weight: 400; font-size: var(--fs-sm); }
.ask-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); margin-bottom: var(--space-2); }
.ask-toolbar .segmented { margin: 0; }
.ask-question { margin: var(--space-2) 0 var(--space-3); font-size: var(--fs-lg); }
.ask-sentence { font-size: var(--fs-base); line-height: 1.7; margin: 0 0 var(--space-2); max-width: 70ch; }
.fact {
  border: 0;
  border-bottom: 1.5px solid var(--accent);
  border-radius: var(--radius-xs);
  background: var(--accent-wash);
  box-shadow: none;
  color: var(--accent-strong);
  font-weight: 600;
  font-size: inherit;
  line-height: inherit;
  padding: 0 0.2rem;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}
.fact:hover, .fact:focus-visible { background: var(--accent); color: var(--ink-inverse); }
.ask-diff { margin: var(--space-1) 0 var(--space-3); font-size: var(--fs-md); font-weight: 500; }
.ask-diff.same { color: var(--ok); }
.ask-diff.moved { color: var(--warn); }
.ask-call {
  border-top: 1px solid var(--line);
  padding: var(--space-4) 0 0;
  margin-top: var(--space-4);
  min-width: 0;
}
.ask-call-head { margin: 0; }
.ask-endpoint {
  margin: var(--space-1) 0 var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  color: var(--muted-strong);
  overflow-wrap: anywhere;
}
.ask-facts { margin: var(--space-1) 0 var(--space-2); padding-left: var(--space-5); font-size: var(--fs-md); }
.fact-row { margin: var(--space-1) 0; border-radius: var(--radius-xs); transition: background 0.3s ease; }
.fact-row.hl { background: var(--accent-wash); }
.fact-value { font-weight: 600; font-variant-numeric: tabular-nums; }
.fact-path {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--muted);
  overflow-wrap: anywhere;
}
.ask-call dl.kv dd { overflow-wrap: anywhere; }
.ask-saved { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; border-top: 1px solid var(--line); }
.ask-saved li + li .review-row { border-top: 1px solid var(--line); }
@media (prefers-reduced-motion: reduce) {
  .fact-row { transition: none; }
}

/* Review queue: the work left is the default, and what is done is one toggle
   away rather than mixed into the list. New classes rather than edits to
   .review-chip / .review-row, which the Ask view also uses. */
.review-done-toggle {
  border: 1px dashed var(--line-strong);
  border-radius: 999px;
  background: none;
  box-shadow: none;
  color: var(--muted);
  padding: var(--space-1) var(--space-3);
  font-size: var(--fs-sm);
  margin-left: auto;
}
.review-done-toggle b { font-variant-numeric: tabular-nums; margin-left: var(--space-1); }
.review-done-toggle:hover { background: var(--sunken); color: var(--ink); }
.review-done-toggle.on { border-style: solid; background: var(--sunken); color: var(--muted-strong); }
.review-row-done { opacity: 0.62; }
.review-row-done .review-row-reason { text-decoration: line-through; text-decoration-thickness: 1px; }

/* =====================================================================
   Signed-out landing page
   After www.ariadnehealth.ai: a white header with the sections as links and
   sign-in at the top right, then the company's own story. The same tokens,
   type and buttons as the console, so the two read as one product.
   ===================================================================== */

.landing[hidden], .landing-links[hidden], .signin-open[hidden] { display: none !important; }

body.signed-out { background: var(--panel); }
body.signed-out header {
  position: sticky;
  top: 0;
  z-index: 20;
  min-height: 4rem;
  background: rgb(255 255 255 / 0.92);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
}
body.signed-out header .brand .sub { display: none; }
body.signed-out main { max-width: none; padding: 0; }
body.signed-out .status:empty { display: none; }

/* A nav, but not the console's tab bar: none of its strip styling. */
.landing-links { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-6); margin-left: auto; padding: 0; background: none; border: 0; }
.landing-links a { color: var(--muted-strong); font-size: var(--fs-md); font-weight: 500; text-decoration: none; padding: var(--space-1) 0; }
.landing-links a:hover { color: var(--ink); }

/* The sign-in card drops from the top-right button. */
.signin-anchor { position: relative; }
.signin-open { padding: var(--space-2) var(--space-4); }
.signin-card.popover {
  position: absolute;
  top: calc(100% + var(--space-3));
  right: 0;
  z-index: 30;
  width: min(23rem, calc(100vw - 2rem));
  margin: 0;
  padding: var(--space-6);
  color: var(--ink);
  box-shadow: var(--shadow-lg);
}

.landing { color: var(--muted-strong); }
.landing-inner { max-width: 68rem; margin: 0 auto; padding: 0 var(--gutter); }
.landing section { scroll-margin-top: 5rem; }
.landing h2 { font-size: var(--fs-landing-section); line-height: 1.15; margin: 0 0 var(--space-3); color: var(--ink); letter-spacing: -0.022em; }
.landing h3 { font-size: var(--fs-lg); margin: 0 0 var(--space-2); color: var(--ink); }
.landing p { margin: 0 0 var(--space-3); }
:where(.landing) a { color: var(--accent-strong); }
.landing-lead { font-size: var(--fs-lg); color: var(--muted-strong); max-width: 42rem; }
.landing-fine { color: var(--muted); font-size: var(--fs-md); }

.landing-hero {
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  padding: clamp(3rem, 8vw, 6rem) 0;
}
.landing-hero h2 { font-size: var(--fs-landing-hero); line-height: 1.05; letter-spacing: -0.03em; max-width: 19ch; margin-bottom: var(--space-5); }
.landing-hero p { font-size: var(--fs-lg); max-width: 42ch; color: var(--muted-strong); }
.landing-kicker { color: var(--accent-strong); font-size: var(--fs-md) !important; font-weight: 500; }
.landing-stat strong { color: var(--ink); font-weight: 600; }
.landing-actions { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-7); }
.landing-primary, .landing-secondary {
  display: inline-flex;
  align-items: center;
  padding: var(--space-2) var(--space-5);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: var(--fs-md);
  font-weight: 500;
  line-height: 1.5;
  text-decoration: none;
  cursor: pointer;
}
.landing-secondary { background: var(--panel); color: var(--ink); box-shadow: var(--shadow-xs); }
.landing-secondary:hover { background: var(--sunken); color: var(--ink); }

.landing-band { padding: var(--space-10) 0; background: var(--panel); border-bottom: 1px solid var(--line); }
.landing-eyebrow { font-size: var(--fs-sm); font-weight: 500; color: var(--muted); }
.landing-features { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: var(--space-4) 0 0; padding: 0; list-style: none; }
.landing-features li { padding: var(--space-1) var(--space-3); border-radius: 999px; background: var(--sunken); color: var(--muted-strong); font-size: var(--fs-sm); }

.landing-section { padding: clamp(3rem, 7vw, 5rem) 0; }
.landing-tinted { background: var(--bg); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.landing-subhead { margin-top: var(--space-8); color: var(--ink); }
.landing-role { color: var(--accent-strong); font-weight: 500; font-size: var(--fs-md); }

.landing-steps { counter-reset: step; display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: var(--space-4); margin: var(--space-6) 0 0; padding: 0; list-style: none; }
.landing-steps li { counter-increment: step; padding: var(--space-5); background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-lg); }
.landing-steps li::before { content: counter(step); display: inline-grid; place-items: center; width: 1.75rem; height: 1.75rem; margin-bottom: var(--space-3); border-radius: 50%; background: var(--accent-wash); color: var(--accent-strong); font-weight: 600; font-size: var(--fs-sm); }
.landing-steps p { font-size: var(--fs-md); color: var(--muted-strong); margin: 0; }

.landing-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: var(--space-4); margin: var(--space-5) 0 var(--space-5); }
.landing-cards article { padding: var(--space-6); background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-lg); }
.landing-cards p { font-size: var(--fs-md); }
.landing-cards ul, .landing-plain { margin: var(--space-2) 0 0; padding-left: var(--space-5); font-size: var(--fs-md); color: var(--muted-strong); }
.landing-cards li, .landing-plain li { margin-bottom: var(--space-1); }
.landing-links-row { display: flex; flex-wrap: wrap; gap: var(--space-3); margin: var(--space-3) 0 0 !important; font-size: var(--fs-md); }

/* The dots sit on a hairline of their own: drawn as the list's background
   rule rather than a border, so it is a line through the dots, not an edge. */
.landing-timeline { position: relative; margin: var(--space-6) 0 0; padding: 0 0 0 var(--space-6); list-style: none; }
.landing-timeline::before { content: ""; position: absolute; left: 0.3rem; top: var(--space-2); bottom: var(--space-2); width: 1px; background: var(--line-strong); }
.landing-timeline li { position: relative; padding: 0 0 var(--space-6) var(--space-2); }
.landing-timeline li::before { content: ""; position: absolute; left: calc(var(--space-6) * -1); top: 0.4rem; width: 0.65rem; height: 0.65rem; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 3px var(--bg); }
.landing-when { display: inline-block; margin-bottom: var(--space-1); color: var(--accent-strong); font-size: var(--fs-sm); font-weight: 600; }
.landing-timeline p { color: var(--muted-strong); font-size: var(--fs-md); margin: 0; }

/* The hero was one column of text in a 68rem container, so on a laptop the
   right 55% was empty and the page read as a document rather than a product.
   The copy keeps the readable measure; the space beside it carries the figure. */
.landing-hero-grid { display: grid; gap: clamp(2rem, 5vw, 4rem); align-items: center; }
@media (min-width: 60rem) {
  .landing-hero-grid { grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); }
}
.landing-hero-copy > :last-child { margin-bottom: 0; }

/* Draws the sentence above it and nothing else — five people, three shaded.
   A curve here would be a shape nobody measured. */
.landing-figure {
  margin: 0; padding: var(--space-8); background: var(--panel);
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.landing-figure svg { display: block; width: 100%; height: auto; }
.landing-figure-person circle, .landing-figure-person path {
  fill: none; stroke: var(--line-strong); stroke-width: 2.5;
}
.landing-figure-person.is-stopped circle, .landing-figure-person.is-stopped path {
  fill: var(--accent); stroke: var(--accent);
}
.landing-figure figcaption {
  display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-5);
  margin-top: var(--space-4); font-size: var(--fs-sm); color: var(--muted);
}
.landing-figure-key { display: inline-flex; align-items: center; gap: var(--space-2); }
.landing-figure-key i {
  width: 0.65rem; height: 0.65rem; border-radius: 50%;
  border: 2px solid var(--line-strong);
}
.landing-figure-key i.is-stopped { background: var(--accent); border-color: var(--accent); }

/* A required safety line: set apart by size and colour so it is read as one,
   not shrunk into the body copy. */
.landing-hero .landing-note { font-size: var(--fs-sm); color: var(--muted); }

/* The credentials were all real and all at the foot of the page. A visitor
   decides whether to keep reading well before the timeline. */
.landing-trust { padding: var(--space-6) 0; background: var(--panel); border-bottom: 1px solid var(--line); }
.landing-trust-label {
  margin: 0 0 var(--space-4); font-size: var(--fs-2xs); font-weight: 500;
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted);
}
.landing-trust-list {
  display: grid; gap: var(--space-4) var(--space-6); margin: 0; padding: 0; list-style: none;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
}
.landing-trust-list li { color: var(--ink); font-weight: 500; font-size: var(--fs-md); }
.landing-trust-list span { display: block; color: var(--muted); font-weight: 400; font-size: var(--fs-sm); }

.landing-metrics {
  display: grid; gap: var(--space-5); margin: var(--space-6) 0 0;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
}
.landing-metrics dt {
  font-size: var(--fs-display); line-height: 1.1; font-weight: 600; letter-spacing: -0.02em;
  color: var(--ink); font-variant-numeric: tabular-nums;
}
.landing-metrics dd { margin: var(--space-1) 0 0; color: var(--muted); font-size: var(--fs-sm); }

.landing-footer { padding: var(--space-10) 0 var(--space-6); border-top: 1px solid var(--line); color: var(--muted); font-size: var(--fs-sm); background: var(--bg); }
.landing-footer p { margin: 0 0 var(--space-1); }
.landing-footer-grid {
  display: grid; gap: var(--space-6); margin-bottom: var(--space-8);
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}
.landing-footer-name { font-size: var(--fs-md); font-weight: 600; color: var(--ink); }
.landing-footer-brand p + p { color: var(--muted); max-width: 26rem; }
.landing-footer-head {
  font-size: var(--fs-sm); font-weight: 500;
  color: var(--ink); margin-bottom: var(--space-3) !important;
}
.landing-footer-nav ul { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--space-2); }
.landing-footer-nav a { color: var(--muted); text-decoration: none; }
.landing-footer-nav a:hover { color: var(--ink); }
.landing-footer-legal { color: var(--muted); font-size: var(--fs-sm); padding-top: var(--space-5); border-top: 1px solid var(--line); }
/* The version line: back to top on one side, the build on the other. */
.landing-footer-colophon {
  display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-4);
  justify-content: space-between; align-items: baseline;
  margin-top: var(--space-2) !important; font-size: var(--fs-xs);
}

/* The console's footer legend reports suppressed cells in the console's own
   tables. The landing page has no tables and carries the build in its own
   footer, so the second footer below it would be an empty bar. */
body.signed-out > footer { display: none; }

@media (max-width: 44rem) {
  .landing-links { display: none; }
  .signin-card.popover { position: fixed; top: 4.5rem; right: var(--space-4); left: var(--space-4); width: auto; }
}


/* Trial-snapshot copy age (#263). Its own classes, not the review or ingest
   badges: those carry a work state an operator acts on, and this carries how
   much to trust a copy. Only `re-check` is coloured as a prompt — an old copy
   of a settled registry record is reported, not flagged. */
.trial-age { font-size: var(--fs-sm); white-space: nowrap; }
.trial-age-current { color: var(--ok); }
.trial-age-settled { color: var(--muted); }
.trial-age-unknown { color: var(--muted); font-style: italic; }
.trial-age-recheck { color: var(--warn); font-weight: 600; }

/* Published-evidence chips on the remedy table (#213). Styled apart from the
   patient-outcome columns beside them and from the review/ingest badges: those
   carry a work state, these carry a published claim, so they are outlined
   where a badge is filled. `not reviewed` is absence, not a negative result,
   so it is muted rather than coloured. */
.evidence-chip { display: inline-block; font-size: var(--fs-xs); font-weight: 500; line-height: 1.4; white-space: nowrap;
                 border-radius: var(--radius-sm); padding: 0 var(--space-2); border: 1px solid var(--line-strong); }
.evidence-worked { color: var(--ok); border-color: var(--ok); }
.evidence-failed { color: var(--critical); border-color: var(--critical); }
.evidence-unstudied { color: var(--muted-strong); }
.evidence-unreviewed { color: var(--muted); border-style: dashed; }
.evidence-cite { font-variant-numeric: tabular-nums; opacity: 0.85; }

/* =====================================================================
   The guided tour: the Guide's main line one step at a time, on a card
   that floats at the bottom right, over the page rather than pushing it
   down. A header with the step and a close, the step itself, one thing to
   try, then progress and the two moves. Collapsed, it is a pill that says
   where the reader was. On a phone it is a sheet along the bottom edge.
   ===================================================================== */
.guide-rail {
  position: fixed;
  right: var(--space-6);
  bottom: var(--space-6);
  z-index: 40;
  width: min(23.75rem, calc(100vw - 2 * var(--space-4)));
  padding: var(--space-4) var(--space-5) var(--space-5);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  animation: tour-in 0.18s ease-out;
}
.guide-rail[hidden] { display: none; }
@keyframes tour-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}
.tour-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin: 0 0 var(--space-2); }
.tour-kicker { margin: 0; color: var(--muted); font-size: var(--fs-xs); font-weight: 500; font-variant-numeric: tabular-nums; }
.tour-close {
  display: inline-grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  margin-right: calc(var(--space-2) * -1);
  padding: 0;
  border-radius: var(--radius-sm);
  color: var(--muted);
  font-size: var(--fs-lg);
  line-height: 1;
}
.tour-title { margin: 0 0 var(--space-2); font-size: var(--fs-lg); color: var(--ink); }
.tour-body { margin: 0; color: var(--muted-strong); font-size: var(--fs-md); line-height: 1.55; }
.tour-try {
  margin: var(--space-4) 0 0;
  padding: var(--space-2) var(--space-3);
  background: var(--sunken);
  border-radius: var(--radius-sm);
  color: var(--ink);
  font-size: var(--fs-sm);
  line-height: 1.5;
}
.tour-try strong { color: var(--accent-strong); font-weight: 600; }
.tour-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-top: var(--space-5); }
.tour-dots { display: flex; gap: 6px; margin: 0; padding: 0; list-style: none; }
.tour-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--line-strong); transition: background-color 0.15s ease, width 0.15s ease; }
.tour-dot.done { background: var(--accent); opacity: 0.45; }
.tour-dot.current { width: 18px; border-radius: 999px; background: var(--accent); opacity: 1; }
.tour-actions { display: flex; gap: var(--space-2); margin-left: auto; }
.tour-actions .tour-primary { padding-left: var(--space-4); padding-right: var(--space-4); }

/* Collapsed: one pill where the card was. */
.guide-rail.collapsed {
  width: auto;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: none;
  box-shadow: none;
}
.tour-show {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4) var(--space-2) var(--space-3);
  border-color: var(--line);
  border-radius: 999px;
  background: var(--panel);
  box-shadow: var(--shadow-lg);
  color: var(--ink);
}
.tour-show::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
.tour-show .tour-show-step { color: var(--muted); font-variant-numeric: tabular-nums; }
.tour-show:hover { background: var(--panel); border-color: var(--line-strong); }

.guide-start { margin: var(--space-1) 0 var(--space-4); }

@media (max-width: 44rem) {
  .guide-rail {
    right: 0;
    bottom: 0;
    left: 0;
    width: auto;
    padding: var(--space-4) var(--space-4) calc(var(--space-4) + env(safe-area-inset-bottom));
    border-width: 1px 0 0;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  }
  .guide-rail.collapsed { left: auto; right: var(--space-4); bottom: var(--space-4); }
  /* The sheet covers the foot of the page; leave room to scroll past it. */
  body.touring main { padding-bottom: 18rem; }
}
@media (prefers-reduced-motion: reduce) {
  .guide-rail { animation: none; }
}

#try-demo[hidden], .landing-demo-note[hidden] { display: none; }
.landing-hero .landing-demo-note { margin-top: var(--space-4); font-size: var(--fs-sm); color: var(--muted); }
