/* ==========================================================================
   Blink — light theme.

   Two reds live here on purpose and must never be swapped. --brand (#ed1c24)
   is the product's call to action: it is the ONLY red that ever fills a solid
   shape. --bad is a deeper, duller red reserved for danger semantics, and it
   only ever appears as text, a hairline border, or a pale wash. Break that
   rule and "Decline proposed" starts looking like a button.

   Every size in this file comes from a scale below — space, radius, type,
   icon, control. A raw px value in a rule is a bug unless it is a hand-tuned
   glyph or a content-driven column width, and those say so in a comment.
   ========================================================================== */

:root {
  color-scheme: light;

  --gray-25: #fcfcfd;
  --gray-50: #f9fafb;
  --gray-100: #f2f4f7;
  --gray-200: #e4e7ec;
  --gray-300: #d0d5dd;
  --gray-400: #98a2b3;
  --gray-500: #667085;
  --gray-600: #475467;
  --gray-700: #344054;
  --gray-900: #101828;

  --brand: #ed1c24;
  --brand-hover: #d3161d;
  --brand-active: #b31119;
  /* #ed1c24 only clears 4.4:1 against white, so brand-as-text uses this instead. */
  --brand-text: #c41219;
  --brand-surface: #fef3f2;
  --brand-border: #fecdca;

  --bg: var(--gray-50);
  --panel: #ffffff;
  --border: var(--gray-200);
  --border-strong: var(--gray-300);
  --text: var(--gray-900);
  --muted: var(--gray-500);
  --code: var(--gray-700);

  --good: #067647;
  --good-surface: #ecfdf3;
  --good-border: #abefc6;
  --bad: #b42318;
  --bad-surface: #fef3f2;
  --bad-border: #fecdca;
  --warn: #b54708;
  --warn-surface: #fffaeb;
  --warn-border: #fedf89;
  --info: #175cd3;
  --info-surface: #eff8ff;
  --info-border: #b2ddff;
  --violet: #6941c6;
  --teal: #107569;

  /* The six outcome tones, as values. `.db-tone-*` sets `color` for icons and counts; these are
     for the borders and bars that need the same colour without inheriting it as text colour. */
  --tone-ok: var(--good);
  --tone-teal: var(--teal);
  --tone-warn: var(--warn);
  --tone-danger: var(--bad);
  --tone-info: var(--info);
  --tone-muted: var(--gray-600);

  --shadow-xs: 0 1px 2px rgb(16 24 40 / 0.05);
  --shadow-sm: 0 1px 3px rgb(16 24 40 / 0.08), 0 1px 2px rgb(16 24 40 / 0.04);
  --shadow-md: 0 4px 8px -2px rgb(16 24 40 / 0.08), 0 2px 4px -2px rgb(16 24 40 / 0.04);

  --ring: 0 0 0 3px rgb(237 28 36 / 0.20);
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  /* Space — a 4px grid. The two half-steps exist because badges and pills sit
     inside 13px text, where 4px of vertical padding is already generous. */
  --space-0-5: 2px;
  --space-1: 4px;
  --space-1-5: 6px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-12: 48px;

  /* Radius — five steps and a pill. Nesting rule: a child pinned to the inside
     edge of a card drops exactly one step (lg card, md header). */
  --radius-xs: 3px;
  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 8px;
  --radius-xl: 10px;
  --radius-full: 999px;

  /* Type — nine steps, no fractional sizes. 2xs and xs are uppercase-only
     sizes; nothing sets running text below sm. 4xl is the home masthead and
     nothing else; no other screen has a line short enough to earn it. */
  --text-2xs: 11px;
  --text-xs: 12px;
  --text-sm: 13px;
  --text-md: 14px;
  --text-lg: 16px;
  --text-xl: 18px;
  --text-2xl: 21px;
  --text-3xl: 28px;
  --text-4xl: 36px;

  --icon-md: 16px;
  --icon-lg: 18px;

  /* Controls — three heights and nothing else: 32 for an inline add/remove
     affordance, 36 for any field, 40 for any button. Buttons set `height`
     rather than padding, so a primary and a secondary in the same bar are the
     same height instead of differing by whatever their font sizes imply. */
  --control-h-sm: 32px;
  --control-h: 36px;
  --control-h-lg: 40px;
  --control-pad-y: 8px;
  --control-pad-x: 12px;

  /* Layout — every bar and main share this box, so the wordmark, the flow
     title and the content beneath them start on one vertical line at every
     width. */
  --page-max: 1400px;
  --page-pad: var(--space-8);
  --chrome-h: 56px;

  --dur: 0.15s;
}

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

body {
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: var(--text-md);
  line-height: 1.5;
  min-height: 100dvh;
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--brand-border); color: var(--gray-900); }
::placeholder { color: var(--gray-400); opacity: 1; }

h1, h2, h3 { text-wrap: balance; }
p { text-wrap: pretty; }

/* One ring for the whole app. Keyboard users get a visible target on every
   control; pointer users never see it. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}
:where(a, button, input, select, textarea, summary):focus:not(:focus-visible) { outline: none; }
/* The skip-link target is focused programmatically; ringing the whole page is noise. */
main:focus, main:focus-visible { outline: none; }

/* Skip link — visible only once it has focus. -60px is far enough off the top
   edge to clear the link's own shadow, not a step on the space scale. */
.skip-link {
  position: absolute;
  left: var(--space-4);
  top: -60px;
  z-index: 30;
  padding: var(--space-3) var(--space-4);
  background: var(--panel);
  color: var(--brand-text);
  border: 1px solid var(--brand-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  font-weight: 600;
  text-decoration: none;
  transition: top var(--dur) ease;
}
.skip-link:focus-visible { top: var(--space-4); }

/* --- Chrome: top bar, flow bar ------------------------------------------ */

/* Both bars and main are the same box. That, and only that, is why the
   wordmark, the flow title and the content under them share a left edge. */
.topbar-inner,
.flowbar-inner,
main {
  max-width: var(--page-max);
  margin: 0 auto;
  padding-inline: var(--page-pad);
}

/* The 2px brand edge runs the full width of the window and is the one red in
   the app that is not a control: a document's header rule, not a button. */
.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--panel);
  border-top: 2px solid var(--brand);
  border-bottom: 1px solid var(--border);
}
.topbar-inner { height: var(--chrome-h); display: flex; align-items: stretch; gap: var(--space-6); }

.wordmark {
  display: inline-flex;
  align-items: center;
  flex: none;
  gap: var(--space-2);
  color: var(--text);
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: -0.02em;
  text-decoration: none;
}
.wordmark:hover { color: var(--brand-text); }
/* A reading mark rather than a logo: 3px of brand red standing one cap high. */
.wordmark-mark { flex: none; width: 3px; height: 15px; border-radius: 1px; background: var(--brand); }

.topnav { display: flex; align-items: stretch; gap: var(--space-5); }
.topnav-item {
  position: relative;
  display: inline-flex;
  align-items: center;
  flex: none;
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--dur) ease;
}
.topnav-item:hover { color: var(--text); }
.topnav-on { color: var(--text); font-weight: 600; }
/* The marker sits on the bar's own hairline, so the current tab reads as
   attached to the page below it instead of as a coloured chip. */
.topnav-item::after {
  content: '';
  position: absolute;
  inset: auto 0 -1px;
  height: 2px;
  background: transparent;
  transition: background var(--dur) ease;
}
.topnav-item:hover::after { background: var(--border-strong); }
.topnav-on::after, .topnav-on:hover::after { background: var(--brand); }

/* Both are laid out with `display`, which beats the UA's [hidden] rule — so the
   signed-out bar needs to be told, not just marked. */
.topnav[hidden], .account[hidden] { display: none; }

/* Who you are, then the way out. Pushed to the far edge so the flow tabs keep
   reading as one group rather than as a row that happens to end in a button. */
.account { display: flex; align-items: center; flex: none; gap: var(--space-3); margin-left: auto; }
.account-email { color: var(--muted); font-size: var(--text-sm); }
.account-out {
  height: var(--control-h-sm);
  padding: 0 var(--space-3);
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  cursor: pointer;
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 500;
  white-space: nowrap;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}
.account-out:hover { background: var(--gray-50); border-color: var(--gray-400); }
.account-out:active { background: var(--gray-100); }
.account-out:disabled { color: var(--muted); cursor: progress; }

/* Deliberately not sticky. On a decision brief or a two-hundred-row diff the
   screen is worth more than a second line of chrome that never changes. */
.flowbar { background: var(--panel); border-bottom: 1px solid var(--border); }
.flowbar-inner {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: var(--space-2) var(--space-6);
  padding-block: var(--space-4);
}
.flowbar-title { margin: 0; font-size: var(--text-xl); font-weight: 600; letter-spacing: -0.02em; }
.flowbar-lead { grid-column: 1 / -1; margin: 0; color: var(--muted); font-size: var(--text-sm); max-width: 90ch; }

.steps { display: flex; flex-wrap: wrap; gap: var(--space-4); margin: 0; padding: 0; list-style: none; }
.step { display: inline-flex; align-items: baseline; gap: var(--space-1-5); color: var(--gray-400); font-size: var(--text-sm); }
.step-no { font-family: var(--mono); font-size: var(--text-2xs); font-variant-numeric: tabular-nums; }
.step-done { color: var(--muted); }
.step-on { color: var(--text); font-weight: 600; }
.step-on .step-no { color: var(--brand-text); }

main { padding-block: var(--space-6) var(--space-12); }

[hidden] { display: none !important; }

/* --- Primitives --------------------------------------------------------- */

/* One card. Ten screens used to declare this same block ten times; what
   actually differs between them is padding and whether the card clips its
   children, so that is all each one still says for itself.

   A hairline is the whole of a card's elevation. Ten identical drop shadows on
   one screen is what made every surface read as equally important; shadow is
   now spent only on the three things that genuinely sit above the page — the
   sticky bar, the status line and the brief's hero. */
.upload-panel,
.form-block,
.run-card,
.rv-form,
.db-card,
.d2c-done,
.cf-card,
.qd-summary,
.qs-panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

/* An eyebrow: the small uppercase line that names a block. */
.file-list-head,
.models legend,
.section-heading,
.db-subhead {
  color: var(--muted);
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* A micro-cap: a one-word verdict in a corner — badge, severity, status.
   Shape only; every caller brings its own tone. */
.badge,
.field-status,
.sel-yes,
.sel-no,
.qa-a,
.conf,
.cap-role,
.sev {
  font-size: var(--text-2xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* Every table header in the app. */
.members-table th,
.tx-table th,
.uw-findings th,
.qd-table th {
  color: var(--muted);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-align: left;
}

/* Every pill: badge counts, tier verdicts, filter chips, tags. One padding, so
   a row of them has one silhouette however they are coloured. */
.summary-pill,
.db-level-pill,
.db-count,
.tier-badge,
.uw-chip,
.qd-chip {
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
}

/* Secondary button — the default. Every bare <button> in a bar is one of
   these, which is why the question-set actions no longer render as raw
   browser chrome next to the primary. */
.download-bar button,
.review-bar button,
.qs-actions button:not(.submit-btn),
.bar-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: var(--control-h-lg);
  padding: 0 var(--space-4);
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  cursor: pointer;
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 500;
  white-space: nowrap;
  text-decoration: none;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}
.download-bar button:hover,
.review-bar button:hover,
.qs-actions button:not(.submit-btn):hover,
.bar-link:hover { background: var(--gray-50); border-color: var(--gray-400); }
.download-bar button:active,
.review-bar button:active,
.qs-actions button:not(.submit-btn):active,
.bar-link:active { background: var(--gray-100); }

/* Primary. Solid brand red, and the only button that ever is. */
.submit-btn,
.download-bar button.primary,
.review-bar button.primary {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
  font-weight: 600;
}
.submit-btn:hover:not(:disabled),
.download-bar button.primary:hover,
.review-bar button.primary:hover { background: var(--brand-hover); border-color: var(--brand-hover); }
.submit-btn:active:not(:disabled),
.download-bar button.primary:active,
.review-bar button.primary:active { background: var(--brand-active); border-color: var(--brand-active); }

.submit-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: var(--control-h-lg);
  padding: 0 var(--space-5);
  font: inherit;
  font-size: var(--text-md);
  font-weight: 600;
  border: 1px solid var(--brand);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}
/* Disabled here always means "working" — the uploader and the sign-in card are
   the only things that set it, and both swap the label at the same time. Hence
   progress, not not-allowed: the button is busy, not forbidden. */
.submit-btn:disabled {
  background: var(--gray-300);
  border-color: var(--gray-300);
  color: var(--gray-600);
  cursor: progress;
}

/* One field. Two screens used to size their inputs differently by a couple of
   pixels each, and a text input, a date input and a select all landed on
   different heights because padding rather than a token was setting them. */
.rv-form input[type='text'],
.rv-form input[type='number'],
.rv-form input[type='date'],
.rv-form select,
.rv-notes,
.cf-field input:not(.cf-tag-input),
.cf-field select,
.cf-field textarea {
  width: 100%;
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: var(--text-sm);
  transition: border-color var(--dur) ease, box-shadow var(--dur) ease;
}
/* Single-line controls take the height from the token, so a row of fields is
   one unbroken row whatever each field happens to contain. */
.rv-form input[type='text'],
.rv-form input[type='number'],
.rv-form input[type='date'],
.rv-form select,
.cf-field input:not(.cf-tag-input),
.cf-field select {
  height: var(--control-h);
  padding: 0 var(--control-pad-x);
}
/* A textarea has to grow, so the token is a floor rather than the height. */
.rv-notes,
.cf-field textarea {
  min-height: var(--control-h);
  padding: var(--control-pad-y) var(--control-pad-x);
  resize: vertical;
  line-height: 1.5;
}
.rv-form select,
.cf-field select { cursor: pointer; }
.rv-form input:focus-visible,
.rv-form select:focus-visible,
.rv-notes:focus-visible,
.cf-field input:not(.cf-tag-input):focus-visible,
.cf-field select:focus-visible,
.cf-field textarea:focus-visible { border-color: var(--brand); box-shadow: var(--ring); outline: none; }

/* --- Upload panel ------------------------------------------------------- */

.upload-panel {
  padding: var(--space-5);
  margin-bottom: var(--space-6);
}
/* One column. The drop zone is the tallest thing on the panel, and sitting the
   engine picker and the submit beside it left both stranded against its middle. */
.upload-panel form { display: grid; gap: var(--space-4); }
.upload-actions { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-3) var(--space-4); }
.upload-actions .submit-btn { margin-left: auto; }

.file-list {
  background: var(--gray-50);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-1-5);
  font-size: var(--text-sm);
}
.file-list-head { margin-bottom: var(--space-1); }

/* 72px is the thumbnail, and the grid's first column has to be exactly it. */
.file-row {
  display: grid;
  grid-template-columns: 72px 1fr auto;
  gap: var(--space-4);
  align-items: center;
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--border);
}
.file-row:last-child { border-bottom: none; }
.file-row-thumb {
  width: 72px;
  height: 72px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  background: var(--gray-100);
  border: 1px solid var(--border-strong);
  display: block;
}
.file-row-thumb.is-pdf {
  display: grid;
  place-items: center;
  background: var(--gray-100);
  color: var(--muted);
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.08em;
}
.file-row-info { min-width: 0; }
.file-row-name { word-break: break-all; font-weight: 500; }
.file-row-meta { color: var(--muted); font-size: var(--text-xs); margin-top: var(--space-0-5); font-variant-numeric: tabular-nums; }
.file-row-form { color: var(--muted); font-size: var(--text-xs); display: flex; gap: var(--space-1-5); align-items: center; }
.file-row-form input {
  width: 60px;
  height: var(--control-h-sm);
  padding: 0 var(--space-2);
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
}
.file-row-form input:focus-visible { border-color: var(--brand); box-shadow: var(--ring); outline: none; }

/* 1.5px dashed reads as a drop target where 1px reads as a disabled field —
   and now the target keeps that promise. The native input is stretched over the
   whole zone at zero opacity, so the browser handles both the click and the
   drop itself; the JS only paints the hover state a drag cannot express in CSS. */
.file-drop {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  background: var(--gray-25);
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--radius-md);
  padding: var(--space-6) var(--space-4);
  cursor: pointer;
  text-align: center;
  transition: border-color var(--dur) ease, background var(--dur) ease;
}
.file-drop:hover, .file-drop-over { border-color: var(--brand); background: var(--brand-surface); }
.file-drop:focus-within { border-color: var(--brand); box-shadow: var(--ring); }
.file-drop input[type=file] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }
.file-drop svg { width: var(--space-6); height: var(--space-6); color: var(--gray-400); transition: color var(--dur) ease; }
.file-drop:hover svg, .file-drop-over svg { color: var(--brand); }
.file-label { font-size: var(--text-md); font-weight: 500; color: var(--text); }
.file-spec { font-size: var(--text-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
.file-name { font-size: var(--text-xs); font-weight: 600; color: var(--brand-text); word-break: break-all; }
.file-name:empty { display: none; }

.models {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
  background: var(--gray-25);
}
.models legend { padding: 0 var(--space-1-5); }
/* A checkbox in a bordered chip that takes the brand when it is on: three bare
   checkboxes in a row gave no indication which engines a run would actually use. */
.models label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: var(--control-h);
  padding: 0 var(--space-3);
  background: var(--panel);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  cursor: pointer;
  transition: border-color var(--dur) ease, background var(--dur) ease;
}
.models label:hover { border-color: var(--gray-400); }
.models label:has(input:checked) { border-color: var(--brand); background: var(--brand-surface); color: var(--brand-text); font-weight: 500; }
.models input[type=checkbox] { accent-color: var(--brand); width: var(--icon-md); height: var(--icon-md); cursor: pointer; }

/* --- Bars --------------------------------------------------------------- */

.results-panel { display: flex; flex-direction: column; gap: var(--space-6); }
.forms-pane { display: flex; flex-direction: column; gap: var(--space-6); }

.download-bar { display: flex; gap: var(--space-2); justify-content: flex-end; }

/* --- Extraction: form blocks and run cards ------------------------------ */

.form-block { overflow: hidden; }
.form-block-header {
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--border);
  background: var(--gray-25);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-4);
}
.form-block-header h2 { margin: 0; font-size: var(--text-lg); font-weight: 600; }
.form-block-meta { color: var(--muted); font-size: var(--text-xs); }
/* 280px is the width a page thumbnail has to be to be legible, not a step. */
.form-block-body {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: var(--space-6);
  padding: var(--space-5);
}

.page-thumbs { display: flex; flex-direction: column; gap: var(--space-3); }
.page-thumb { margin: 0; }
.page-thumb img {
  width: 100%;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--panel);
  display: block;
}
.page-thumb-pdf { width: 100%; aspect-ratio: 1 / 1.35; border: 1px solid var(--border); border-radius: var(--radius-sm); background: #fff; display: block; }
.page-thumb figcaption { color: var(--muted); font-size: var(--text-xs); margin-top: var(--space-1); word-break: break-all; }

.runs-pane { display: flex; flex-direction: column; gap: var(--space-4); }

.run-card { overflow: hidden; }
.run-card header {
  background: var(--gray-25);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
}
.run-card header h3 { margin: 0; font-size: var(--text-md); font-weight: 600; }
.badge {
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-xs);
  border: 1px solid transparent;
}
.badge-ok { background: var(--good-surface); border-color: var(--good-border); color: var(--good); }
.badge-bad { background: var(--bad-surface); border-color: var(--bad-border); color: var(--bad); }
.run-card .meta {
  font-size: var(--text-xs);
  color: var(--muted);
  padding: var(--space-2) var(--space-4);
  background: var(--gray-25);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1-5) var(--space-4);
  border-bottom: 1px solid var(--border);
}
.run-card .body { padding: var(--space-4); }

/* 160px fits the longest demographic label, 80px the longest status word. */
.field-grid {
  display: grid;
  grid-template-columns: 160px 1fr 80px;
  gap: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
  align-items: baseline;
}
.field-label { color: var(--muted); }
.field-value { color: var(--text); word-break: break-word; font-family: var(--mono); }
.field-status { text-align: right; }
.status-parsed { color: var(--good); }
.status-missing { color: var(--bad); }
.status-suspect { color: var(--warn); }

.section-heading {
  margin: var(--space-4) 0 var(--space-2);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border);
}
.section-heading:first-child { padding-top: 0; border-top: none; margin-top: 0; }

.muted { color: var(--muted); }
.empty-row { font-size: var(--text-sm); color: var(--muted); padding: var(--space-2) 0; }

/* --- Tables ------------------------------------------------------------- */

.members-table, .tx-table, .uw-findings { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.members-table th, .members-table td,
.tx-table th, .tx-table td {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.members-table td, .tx-table td { text-align: left; }
.members-table th, .tx-table th { background: var(--gray-50); }
.members-table tr:last-child td, .tx-table tr:last-child td { border-bottom: none; }
.members-table tbody tr:hover, .tx-table tbody tr:hover { background: var(--gray-25); }
.members-table .cell-missing { color: var(--bad); }
.tx-table td { word-break: break-word; }

.tx-page + .tx-page { margin-top: var(--space-5); padding-top: var(--space-4); border-top: 1px solid var(--border); }
.tx-data-table td { font-family: var(--mono); font-size: var(--text-xs); }
.sel-yes { color: var(--good); }
/* "unselected" is the absence of a mark. It should read quieter than the
   micro-cap default, not shout alongside SELECTED. */
.sel-no { color: var(--muted); font-weight: 500; }
.tx-lines { margin-top: var(--space-3); font-size: var(--text-xs); }
.tx-lines summary { cursor: pointer; color: var(--muted); padding: var(--space-1) 0; }
.tx-lines summary:hover { color: var(--text); }
.tx-lines pre {
  background: var(--gray-50);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--space-3);
  overflow: auto;
  max-height: 280px;
  font-family: var(--mono);
  font-size: var(--text-xs);
  color: var(--code);
  margin: var(--space-1-5) 0 0;
  white-space: pre-wrap;
}

/* --- Declared-answer list ---------------------------------------------- */

.qa-list { display: flex; flex-direction: column; gap: var(--space-1-5); font-size: var(--text-sm); }
.qa-row { display: grid; grid-template-columns: 1fr auto; gap: var(--space-3); padding: var(--space-2) 0; border-bottom: 1px solid var(--border); }
.qa-row:last-child { border-bottom: none; }
.qa-q { color: var(--text); }
.qa-a {
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-xs);
  border: 1px solid transparent;
  align-self: start;
}
.qa-a-yes { background: var(--good-surface); border-color: var(--good-border); color: var(--good); }
.qa-a-no { background: var(--gray-100); border-color: var(--border-strong); color: var(--gray-600); }
/* "Not answered" is a fact about the form and "Could not read" a fact about the reading, so only
   the second one is a warning. Colouring them alike is what made a blank section look broken. */
.qa-a-blank { background: transparent; border-color: var(--border); color: var(--gray-400); }
.qa-a-unknown { background: var(--warn-surface); border-color: var(--warn-border); color: var(--warn); }
.qa-details { color: var(--muted); font-size: var(--text-xs); margin-top: var(--space-1); }

/* The stem a run of sub-questions shares, printed once above them. */
.qa-stem {
  color: var(--muted);
  font-size: var(--text-xs);
  padding: var(--space-2) 0 var(--space-1);
}
.qa-row-sub { padding-left: var(--space-4); }


/* --- The captured form -------------------------------------------------- */
/* What the model read, section by section, in the form's own words. The layout
   is deliberately uniform across sections: a MAF's own structure is unknown, so
   nothing here may assume a particular field, table, or ordering. */

/* Wider than .field-grid: these labels are the form's own wording ("Name of
   Employer / Sponsor"), not a fixed vocabulary that could be measured once. */
.cap-grid {
  display: grid;
  grid-template-columns: minmax(140px, 38%) 1fr auto;
  gap: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
  align-items: baseline;
}
.cap-grid .field-label { color: var(--muted); }

.cap-section + .cap-section {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
}
.cap-section-title {
  color: var(--text);
  font-size: var(--text-sm);
  font-weight: 600;
  margin-bottom: var(--space-3);
}

.cap-doctype {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
  padding-bottom: var(--space-3);
}

/* The page a value came from, so a wrong reading can be checked against the
   right scan without hunting. Muted to the point of being ignorable. */
.cap-page {
  margin-left: var(--space-1-5);
  color: var(--gray-400);
  font-family: var(--mono);
  font-size: var(--text-2xs);
  font-weight: 400;
}

.cap-conf, .qa-side { text-align: right; white-space: nowrap; }
.qa-side { display: flex; align-items: center; justify-content: flex-end; gap: var(--space-2); }

/* "high" gets no chip: the point is to draw the eye to what needs checking. */
.conf { border: 1px solid transparent; border-radius: var(--radius-full); padding: 0 var(--space-1-5); }
.conf-low { background: var(--warn-surface); border-color: var(--warn-border); color: var(--warn); }
.conf-medium { color: var(--gray-400); }

.cap-blank { color: var(--gray-400); }

.cap-table { margin-top: var(--space-3); }
.cap-table-caption {
  color: var(--muted);
  font-size: var(--text-xs);
  margin-bottom: var(--space-1-5);
}
.cap-role {
  margin-left: var(--space-1-5);
  color: var(--info);
  background: var(--info-surface);
  border: 1px solid var(--info-border);
  border-radius: var(--radius-full);
  padding: 0 var(--space-1-5);
}

/* A partly-read form still shows everything it did read; this says what is absent
   so a short capture is never mistaken for a complete one. */
.cap-partial {
  background: var(--warn-surface);
  border: 1px solid var(--warn-border);
  border-radius: var(--radius-md);
  color: var(--warn);
  font-size: var(--text-sm);
  padding: var(--space-3);
  margin-bottom: var(--space-4);
}
.cap-partial ul { margin: var(--space-2) 0 0; padding-left: var(--space-5); }
.cap-partial li + li { margin-top: var(--space-1); }

.summary-pill-warn { background: var(--warn-surface); border-color: var(--warn-border); color: var(--warn); }
.summary-pill-bad { background: var(--bad-surface); border-color: var(--bad-border); color: var(--bad); }

/* The read-only tail of the customer's review form: what the form printed beyond the
   fields the risk engine asks for. */
.rv-captured {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
  font-size: var(--text-sm);
}
.rv-captured summary {
  cursor: pointer;
  color: var(--muted);
  padding: var(--space-1) 0;
}
.rv-captured summary:hover { color: var(--text); }
.rv-captured > .cap-section:first-of-type { margin-top: var(--space-3); }

/* --- Error and status --------------------------------------------------- */

.error-block {
  background: var(--bad-surface);
  border: 1px solid var(--bad-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm);
}
.error-code { font-family: var(--mono); color: var(--bad); font-weight: 600; margin-bottom: var(--space-1); }
.error-message { color: var(--text); }

.summary-bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--gray-25);
  border-bottom: 1px solid var(--border);
  font-size: var(--text-xs);
  color: var(--muted);
}
/* The answer breakdown rides under the counts as a second row of the same bar. */
.summary-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  flex-basis: 100%;
}
.summary-pill { background: var(--panel); border: 1px solid var(--border); }
.summary-pill strong { color: var(--text); font-weight: 600; }

/* A log line, not a banner: read from the left behind a tone edge, with the
   clock pinned right so a wait that runs for minutes always ticks in one place. */
.status {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--panel);
  border: 1px solid var(--border);
  border-left: 3px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  font-size: var(--text-sm);
  color: var(--muted);
}
.status-text { flex: 1; min-width: 0; }
.status-elapsed {
  flex: none;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

.status-busy { border-color: var(--info-border); border-left-color: var(--info); background: var(--info-surface); color: var(--gray-700); }
.status-ok { border-color: var(--good-border); border-left-color: var(--good); background: var(--good-surface); color: var(--good); font-weight: 500; }
.status-error { border-color: var(--bad-border); border-left-color: var(--bad); background: var(--bad-surface); color: var(--bad); font-weight: 500; }

.status-spinner {
  flex: none;
  width: var(--icon-md);
  height: var(--icon-md);
  border: 2px solid var(--brand-border);
  border-top-color: var(--brand);
  border-radius: 50%;
  animation: status-spin 0.8s linear infinite;
}
@keyframes status-spin { to { transform: rotate(360deg); } }

.file-drop:has(input:disabled) { opacity: 0.55; cursor: not-allowed; }
.file-drop:has(input:disabled):hover { border-color: var(--border-strong); background: var(--gray-25); }

/* --- Review form (rv-) -------------------------------------------------- */

.review-bar { display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; }
.review-bar-spacer { flex: 1; }
.review-forms { display: flex; flex-direction: column; gap: var(--space-6); }

.rv-form { padding: var(--space-4) var(--space-5) var(--space-5); }
.rv-form-header { display: flex; gap: var(--space-3); align-items: baseline; flex-wrap: wrap; }
.rv-form-header h2 { margin: 0; font-size: var(--text-xl); font-weight: 600; }
.rv-form-meta { color: var(--muted); font-size: var(--text-xs); }
.rv-source { margin-left: auto; color: var(--muted); font-size: var(--text-xs); display: flex; gap: var(--space-1-5); align-items: center; }
.rv-source-empty { color: var(--warn); font-weight: 500; }

.rv-form .rv-unrecognized { border-color: var(--warn); background: var(--warn-surface); }

.rv-field-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--space-3); }
.rv-field { display: flex; flex-direction: column; gap: var(--space-1); }
.rv-field > span { color: var(--muted); font-size: var(--text-xs); font-weight: 500; }

.rv-members-table { width: 100%; border-collapse: collapse; }
.rv-members-table th { text-align: left; color: var(--muted); font-size: var(--text-xs); font-weight: 600; padding: var(--space-1) var(--space-1-5) var(--space-1-5) 0; }
.rv-members-table td { padding: var(--space-1) var(--space-1-5) var(--space-1) 0; vertical-align: middle; }

.rv-qa-list { display: flex; flex-direction: column; gap: var(--space-2); }
/* 110px is the width of the answer select, which holds one of three words. */
.rv-qa-row { display: grid; grid-template-columns: minmax(0, 3fr) 110px minmax(0, 2fr) auto; gap: var(--space-2); align-items: center; }
.rv-qa-answer.rv-a-yes { color: var(--bad); font-weight: 600; }
.rv-qa-answer.rv-a-no { color: var(--good); font-weight: 600; }
.rv-qa-answer.rv-a-blank { color: var(--muted); }
.rv-qa-answer.rv-a-unknown { color: var(--warn); }

.rv-add {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-top: var(--space-3);
  height: var(--control-h-sm);
  padding: 0 var(--space-3);
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: var(--text-xs);
  font-weight: 500;
  cursor: pointer;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}
.rv-add:hover { background: var(--gray-50); border-color: var(--gray-400); }
.rv-remove {
  display: grid;
  place-items: center;
  width: var(--space-8);
  height: var(--space-8);
  background: var(--panel);
  color: var(--muted);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: var(--text-md);
  cursor: pointer;
  line-height: 1;
  transition: background var(--dur) ease, border-color var(--dur) ease, color var(--dur) ease;
}
.rv-remove:hover { color: var(--bad); border-color: var(--bad-border); background: var(--bad-surface); }

/* --- Underwriting and decision brief ------------------------------------ */

.assessment-body { display: flex; flex-direction: column; gap: var(--space-6); }

.uw-case { display: flex; flex-direction: column; gap: var(--space-4); }
.uw-case-header { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-5); flex-wrap: wrap; }
.uw-disclaimer { color: var(--muted); font-size: var(--text-sm); margin-top: var(--space-1); max-width: 70ch; }
.uw-verdict { display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-1-5); text-align: right; }
.uw-verdict-score, .uw-verdict-loading { font-size: var(--text-sm); color: var(--muted); }

.db-hero {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--space-3) var(--space-6);
  align-items: center;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-md);
  padding: var(--space-5);
}
.db-hero-score { display: flex; flex-direction: column; align-items: center; gap: var(--space-2); }
.db-hero-main { min-width: 0; }
.db-hero-main h2 { margin: 0 0 var(--space-1-5); font-size: var(--text-xl); font-weight: 600; }
.db-hero-sub {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-3);
  font-size: var(--text-sm);
  color: var(--muted);
  margin-bottom: var(--space-4);
}
.db-hero-sub code { font-family: var(--mono); color: var(--code); background: var(--gray-100); border-radius: var(--radius-xs); padding: var(--space-0-5) var(--space-1-5); }
.db-hero-sub span + span::before,
.db-hero-sub code + span::before { content: '· '; }
.db-hero-side { display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-1-5); text-align: right; }
.db-hero-note {
  grid-column: 1 / -1;
  margin: var(--space-1) 0 0;
  padding-top: var(--space-3);
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-size: var(--text-xs);
}

/* The gauge's own numbers are SVG user units on a 0 0 120 120 viewBox, not CSS
   pixels — they scale with the box and must not be swapped for type tokens. */
.db-gauge { width: 104px; height: 104px; }
.db-gauge-track { fill: none; stroke: var(--gray-200); stroke-width: 9; }
.db-gauge-sweep { fill: none; stroke: currentColor; stroke-width: 9; stroke-linecap: round; }
.db-gauge-score { fill: var(--text); font-size: 27px; font-weight: 700; text-anchor: middle; }
.db-gauge-max { fill: var(--muted); font-size: 11px; text-anchor: middle; }

.db-level-pill {
  font-size: var(--text-xs);
  font-weight: 600;
  border: 1px solid currentColor;
  background: color-mix(in srgb, currentColor 10%, #fff);
}

.db-stats { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-6); }
.db-stat-value { font-size: var(--text-2xl); font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.db-stat-label { font-size: var(--text-2xs); color: var(--muted); margin-top: var(--space-0-5); }
.db-stat-info { color: var(--info); }
.db-stat-muted { color: var(--gray-600); }

.db-critical {
  display: flex;
  align-items: center;
  gap: var(--space-1-5);
  color: var(--bad);
  font-size: var(--text-sm);
  font-weight: 600;
}
.db-critical svg { width: var(--icon-md); height: var(--icon-md); }
.db-override { color: var(--muted); font-size: var(--text-xs); }
.db-generated { color: var(--muted); font-size: var(--text-xs); }
.db-generated code { font-family: var(--mono); }

.db-card { overflow: hidden; }
.db-card-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
  background: var(--gray-25);
}
.db-card-head h3 { margin: 0; font-size: var(--text-md); font-weight: 600; }
.db-card-body { padding: var(--space-4); }
.db-subhead { margin: var(--space-4) 0 var(--space-1-5); }

details.db-card > summary.db-card-head { cursor: pointer; list-style: none; }
details.db-card > summary.db-card-head:hover { background: var(--gray-50); }
details.db-card > summary.db-card-head::-webkit-details-marker { display: none; }
/* A hand-tuned glyph: 7px square with a 1.7px stroke matches the icon set's
   stroke-width, and the translate is measured against that square. */
details.db-card > summary.db-card-head::after {
  content: '';
  margin-left: auto;
  width: 7px;
  height: 7px;
  border-right: 1.7px solid var(--muted);
  border-bottom: 1.7px solid var(--muted);
  transform: rotate(45deg) translate(-2px, -2px);
}
details.db-card[open] > summary.db-card-head::after { transform: rotate(-135deg) translate(-2px, -2px); }
details.db-card:not([open]) > summary.db-card-head { border-bottom: none; }

.db-chip {
  flex: none;
  display: grid;
  place-items: center;
  width: var(--space-8);
  height: var(--space-8);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, currentColor 12%, #fff);
}
.db-chip svg { width: var(--icon-lg); height: var(--icon-lg); }

.db-count {
  margin-left: auto;
  font-size: var(--text-xs);
  font-weight: 500;
  border: 1px solid color-mix(in srgb, currentColor 30%, #fff);
  background: color-mix(in srgb, currentColor 8%, #fff);
}
details.db-card > summary.db-card-head .db-count { margin-left: auto; margin-right: var(--space-3); }

.db-tone-info { color: var(--info); }
.db-tone-danger { color: var(--bad); }
.db-tone-warn { color: var(--warn); }
.db-tone-ok { color: var(--good); }
.db-tone-violet { color: var(--violet); }
.db-tone-teal { color: var(--teal); }
.db-tone-muted { color: var(--gray-600); }

.tier-badge {
  display: inline-block;
  font-size: var(--text-sm);
  font-weight: 600;
  border: 1px solid currentColor;
  background: color-mix(in srgb, currentColor 10%, #fff);
}
.tier-standard { color: var(--good); }
.tier-loading { color: var(--warn); }
.tier-refer { color: var(--info); }
.tier-decline { color: var(--bad); }

.uw-banner {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--warn-border);
  border-left: 3px solid var(--warn);
  border-radius: var(--radius-md);
  background: var(--warn-surface);
  color: var(--warn);
  font-size: var(--text-sm);
  line-height: 1.5;
}
.uw-banner svg { flex: none; width: var(--icon-md); height: var(--icon-md); margin-top: var(--space-0-5); }
.uw-summary { margin: 0; font-size: var(--text-md); line-height: 1.6; max-width: 90ch; color: var(--gray-700); }
.uw-summary > p { margin: 0 0 var(--space-3); }
.uw-summary > p:last-child { margin-bottom: 0; }
.uw-list { margin: 0; padding-left: var(--space-5); font-size: var(--text-sm); line-height: 1.65; }
.uw-list li + li { margin-top: var(--space-1); }
.uw-two-col { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-5); }

.uw-people { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--space-3); }
.uw-person { background: var(--gray-25); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-3) var(--space-4); }
.uw-person header { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-3); }
.uw-person h3 { margin: 0; font-size: var(--text-md); font-weight: 600; }
.uw-person-role { color: var(--muted); font-size: var(--text-xs); margin-top: var(--space-0-5); }
.uw-chips { display: flex; flex-wrap: wrap; gap: var(--space-1-5); margin: var(--space-3) 0 var(--space-2); }
.uw-chip { background: var(--panel); border: 1px solid var(--border-strong); font-size: var(--text-xs); color: var(--gray-700); }
.uw-score { font-size: var(--text-xs); color: var(--muted); }
.uw-score strong { color: var(--text); }
.uw-score-parts { color: var(--muted); }
.uw-flags { display: flex; flex-direction: column; gap: var(--space-1); margin-top: var(--space-2); }
.uw-flag { font-size: var(--text-xs); color: var(--warn); }

.uw-findings th {
  border-bottom: 1px solid var(--border-strong);
  padding: var(--space-1-5) var(--space-3) var(--space-1-5) 0;
}
.uw-findings td { padding: var(--space-2) var(--space-3) var(--space-2) 0; border-bottom: 1px solid var(--border); vertical-align: top; }
.uw-findings tbody tr:hover { background: var(--gray-25); }
.uw-findings tbody tr:last-child td { border-bottom: none; }
.uw-source { color: var(--muted); font-size: var(--text-xs); margin-top: var(--space-1); }
.uw-rationale { color: var(--gray-700); max-width: 48ch; }
.sev-minor, .sev-low { color: var(--good); }
.sev-moderate, .sev-medium { color: var(--warn); }
.sev-major, .sev-high, .sev-critical, .sev-very_high { color: var(--bad); }

.db-level { font-weight: 600; }
.lvl-low { color: var(--good); }
.lvl-medium { color: var(--warn); }
.lvl-high, .lvl-critical { color: var(--bad); }
.db-narrative p { white-space: pre-wrap; }
.db-letter {
  background: var(--gray-25);
  border: 1px solid var(--border);
  border-left: 3px solid var(--brand);
  border-radius: var(--radius-md);
  padding: var(--space-4);
}
.db-note { margin: var(--space-2) 0; font-size: var(--text-sm); color: var(--muted); line-height: 1.55; }
.db-checks { list-style: none; margin: var(--space-2) 0; padding: 0; font-size: var(--text-xs); display: flex; flex-direction: column; gap: var(--space-1); }
.db-pass { color: var(--muted); }
.db-fail { color: var(--warn); font-weight: 500; }
.db-abnormal td { color: var(--bad); font-weight: 500; }

/* --- Home: masthead and flow index -------------------------------------- */

/* An index, not a grid of cards. Four numbered rules say "pick one" with less
   furniture than four boxes, they let each flow be described in one line
   instead of a paragraph, and this is the only screen in the app quiet enough
   to carry a headline.

   960px is how wide the index reads well: past that the meta column drifts
   away from the name it belongs to. A content measure, not a step. */
.home { max-width: 960px; }

.masthead { padding: var(--space-8) 0 var(--space-6); }
.masthead h1 {
  margin: 0 0 var(--space-3);
  max-width: 24ch;
  font-size: var(--text-4xl);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.15;
}
.masthead p { margin: 0; max-width: 62ch; color: var(--muted); font-size: var(--text-lg); line-height: 1.55; }

.index { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--border); }
.index > li { border-bottom: 1px solid var(--border); }
.index-row {
  position: relative;
  display: grid;
  grid-template-columns: var(--space-8) 1fr auto;
  align-items: baseline;
  gap: var(--space-2) var(--space-5);
  padding: var(--space-5) 0;
  color: inherit;
  text-decoration: none;
}
/* The marker grows in the left margin rather than indenting the row, so a
   pointer running down the list never shifts the line it is being read. */
.index-row::before {
  content: '';
  position: absolute;
  left: calc(var(--space-4) * -1);
  top: var(--space-5);
  bottom: var(--space-5);
  width: 3px;
  border-radius: 1px;
  background: var(--brand);
  opacity: 0;
  transition: opacity var(--dur) ease;
}
.index-row:hover::before { opacity: 1; }
.index-no {
  font-family: var(--mono);
  font-size: var(--text-md);
  font-variant-numeric: tabular-nums;
  color: var(--gray-300);
  transition: color var(--dur) ease;
}
.index-row:hover .index-no { color: var(--brand-text); }
.index-main { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.index-name { font-size: var(--text-xl); font-weight: 600; letter-spacing: -0.01em; }
.index-blurb { color: var(--muted); font-size: var(--text-sm); }
.index-meta {
  font-family: var(--mono);
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gray-400);
  white-space: nowrap;
}

.d2c-done { padding: var(--space-5); }
.d2c-done > .db-chip { margin-bottom: var(--space-3); }
.d2c-done h2 { margin: 0 0 var(--space-2); font-size: var(--text-lg); font-weight: 600; }
.d2c-done p { margin: 0 0 var(--space-3); font-size: var(--text-md); line-height: 1.65; max-width: 90ch; color: var(--gray-700); }
.d2c-done p:last-child { margin-bottom: 0; }
.d2c-done a { color: var(--brand-text); text-decoration: underline; text-underline-offset: 2px; }
.d2c-done a:hover { color: var(--brand-active); }
.d2c-done-note { color: var(--muted); font-size: var(--text-sm); }
.d2c-done-counts { font-weight: 500; }
.d2c-done .review-bar { margin-top: var(--space-4); }

.d2c-pages { margin: var(--space-4) 0; }
.d2c-pages summary { cursor: pointer; color: var(--muted); font-size: var(--text-sm); padding: var(--space-1) 0; }
.d2c-pages summary:hover { color: var(--text); }
/* 170px is the thumbnail strip's card width, not a step on the scale. */
.page-thumbs-row { flex-direction: row; overflow-x: auto; gap: var(--space-3); padding: var(--space-2) 0 var(--space-1); }
.page-thumbs-row .page-thumb { flex: 0 0 170px; width: 170px; }

.run-notes { font-size: var(--text-sm); color: var(--muted); }

/* --- Sign in ------------------------------------------------------------ */

/* Centred on the height of the window rather than pinned to the top: the card
   is the only thing on the screen, and a lone card under the bar reads as a
   page that failed to load the rest of itself. */
.login { display: grid; place-items: center; min-height: 70vh; padding: var(--space-12) 0; }
.login-card {
  display: grid;
  gap: var(--space-4);
  width: 100%;
  max-width: 380px;
  padding: var(--space-8);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.login-title { margin: 0; font-size: var(--text-2xl); font-weight: 600; letter-spacing: -0.02em; }
/* Pulled up under the title: the two are one block, and the card's own gap
   would otherwise set them as far apart as the fields below them. */
.login-lead { margin: calc(var(--space-3) * -1) 0 0; color: var(--muted); font-size: var(--text-sm); }
.login-field { display: grid; gap: var(--space-1-5); }
.login-field > span { color: var(--muted); font-size: var(--text-sm); font-weight: 500; }
.login-field input {
  width: 100%;
  height: var(--control-h);
  padding: 0 var(--control-pad-x);
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: var(--text-sm);
  transition: border-color var(--dur) ease, box-shadow var(--dur) ease;
}
.login-field input:focus-visible { border-color: var(--brand); box-shadow: var(--ring); outline: none; }
/* The card's only action, so it spans it rather than sitting in a corner. */
.login-card .submit-btn { width: 100%; margin-top: var(--space-2); }

/* --- Case form (cf-) ---------------------------------------------------- */

.case-form { display: flex; flex-direction: column; gap: var(--space-4); margin: var(--space-4) 0; }
.cf-card { padding: var(--space-4) var(--space-5) var(--space-5); }
/* The section counter ties the form back to the flow index and the step trail:
   one mono number, wherever the app asks you to work through something in order.
   A counter rather than markup, so the number stays out of the heading's text. */
.case-form { counter-reset: cf-section; }
.cf-card h2 {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  margin: 0 0 var(--space-4);
  font-size: var(--text-lg);
  font-weight: 600;
  counter-increment: cf-section;
}
.cf-card h2::before {
  content: counter(cf-section, decimal-leading-zero);
  flex: none;
  font-family: var(--mono);
  font-size: var(--text-xs);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--gray-300);
}
.cf-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4) var(--space-5); }
.cf-grid-3 { grid-template-columns: repeat(3, 1fr); }
.cf-span-2 { grid-column: 1 / -1; }
.cf-field { display: flex; flex-direction: column; gap: var(--space-1-5); min-width: 0; }
.cf-field > span { color: var(--gray-700); font-size: var(--text-xs); font-weight: 500; }
.cf-req { color: var(--brand-text); font-style: normal; margin-left: var(--space-1); }
.cf-hint { color: var(--muted); font-size: var(--text-xs); }
.cf-legend { margin: calc(var(--space-1-5) * -1) 0 var(--space-4); }
.cf-legend .cf-req { margin: 0 1px; }
.cf-validated .cf-field :invalid { border-color: var(--bad); background: var(--bad-surface); }
.cf-validated .cf-field :invalid:focus-visible { box-shadow: 0 0 0 3px rgb(180 35 24 / 0.18); }

/* Tags sit in a box the same height as an empty field, so a row of inputs and
   a row of tags share one baseline. */
.cf-tags {
  background: var(--panel);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  min-height: var(--control-h);
  padding: var(--space-1) var(--space-2);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1-5);
  align-items: center;
}
.cf-tags:focus-within { border-color: var(--brand); box-shadow: var(--ring); }
.cf-tag-list { display: contents; }
.cf-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1-5);
  height: var(--space-6);
  background: var(--gray-100);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-full);
  padding: 0 var(--space-1) 0 var(--space-3);
  font-size: var(--text-xs);
}
.cf-tag button {
  display: grid;
  place-items: center;
  width: var(--space-5);
  height: var(--space-5);
  background: none;
  border: none;
  border-radius: 50%;
  color: var(--muted);
  cursor: pointer;
  font-size: var(--text-md);
  line-height: 1;
  padding: 0;
}
.cf-tag button:hover { color: var(--bad); background: var(--bad-surface); }
/* 180px keeps "Type a condition and press Enter" readable before it wraps. */
.cf-tag-input {
  flex: 1;
  min-width: 180px;
  background: none;
  border: none;
  color: var(--text);
  font: inherit;
  font-size: var(--text-sm);
  padding: 0 var(--space-0-5);
}
.cf-tag-input:focus { outline: none; }

/* --- Motion ------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .status-spinner { animation-duration: 2.4s; }
  *, *::before, *::after { transition-duration: 0.01ms !important; }
}

/* --- Responsive --------------------------------------------------------- */

/* One override moves the header and main together, because both read their
   horizontal padding from --page-pad. */
@media (max-width: 900px) {
  :root { --page-pad: var(--space-4); }
  main { padding-block: var(--space-5) var(--space-12); }
  .masthead { padding-top: var(--space-6); }
  .masthead h1 { font-size: var(--text-3xl); }
  .masthead p { font-size: var(--text-md); }
  .form-block-body { grid-template-columns: 1fr; }
  .uw-two-col { grid-template-columns: 1fr; }
  .submit-btn { width: 100%; }
}

@media (max-width: 860px) {
  .db-hero { grid-template-columns: auto 1fr; }
  .db-hero-side { grid-column: 1 / -1; align-items: flex-start; text-align: left; }
  .uw-verdict { align-items: flex-start; text-align: left; }
}

/* Below this the four tabs stop fitting beside the wordmark, so the bar takes a
   second row and the flow bar drops its trail under the title. */
@media (max-width: 720px) {
  .topbar-inner { height: auto; flex-wrap: wrap; gap: 0 var(--space-5); padding-top: var(--space-2); }
  .wordmark { order: 1; }
  .topnav { order: 3; flex-basis: 100%; height: var(--control-h-lg); gap: var(--space-4); overflow-x: auto; }
  /* Stays on the first row beside the wordmark; the tabs are what wrap. */
  .account { order: 2; align-self: center; }
  .topnav-item::after { bottom: 0; }
  .flowbar-inner { grid-template-columns: 1fr; }
  .index-row { grid-template-columns: var(--space-8) 1fr; }
  .index-meta { grid-column: 2; }
  .rv-qa-row { grid-template-columns: 1fr; }
  .cf-grid, .cf-grid-3 { grid-template-columns: 1fr; }
  .download-bar, .review-bar { flex-direction: column; align-items: stretch; }
  .review-bar-spacer { display: none; }
}

@media (max-width: 560px) {
  .db-hero { grid-template-columns: 1fr; justify-items: start; }
  .db-hero-score { flex-direction: row; align-items: center; }
  .db-gauge { width: 76px; height: 76px; }
  .db-card-head { flex-wrap: wrap; }
  /* Wrapped onto its own line, the count hangs under the title by clearing the
     chip and the head's gap. */
  .db-count { margin-left: calc(var(--space-8) + var(--space-3)); }
}

/* ==========================================================================
   Question set comparison. Reuses the brief's card, hero, gauge and tone
   classes on purpose — the two screens are the same product. Only what is
   genuinely new to a two-column diff lives here.
   ========================================================================== */

.qs-panel { padding: var(--space-4); }
.qs-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
.qs-pane { min-width: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.qs-pane-head { display: flex; align-items: center; gap: var(--space-2); }

/* The set name is an input that has to read as a heading until it is clicked. */
.qs-name {
  flex: 1;
  min-width: 0;
  font: inherit;
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--text);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-1-5);
}
.qs-name:hover { border-color: var(--border); }
.qs-name:focus-visible { border-color: var(--brand); box-shadow: var(--ring); outline: none; background: var(--panel); }

.qs-side {
  flex: none;
  display: grid;
  place-items: center;
  width: var(--space-5);
  height: var(--space-5);
  border-radius: var(--radius-xs);
  font-size: var(--text-2xs);
  font-weight: 700;
  font-family: var(--mono);
}
.qs-side-a, .qd-id-a { background: var(--brand-surface); color: var(--brand-text); border: 1px solid var(--brand-border); }
.qs-side-b, .qd-id-b { background: var(--info-surface); color: var(--info); border: 1px solid var(--info-border); }

.qs-tally { flex: none; font-size: var(--text-2xs); color: var(--gray-400); font-variant-numeric: tabular-nums; }
.qs-tally-set { color: var(--muted); }

.qs-input {
  width: 100%;
  font: inherit;
  font-size: var(--text-sm);
  line-height: 1.7;
  color: var(--text);
  background: var(--gray-25);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  resize: vertical;
}
.qs-input:focus-visible { border-color: var(--brand); box-shadow: var(--ring); outline: none; background: var(--panel); }
.qs-hint { margin: 0; font-size: var(--text-2xs); color: var(--muted); }

.qs-actions { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-4); }
.qs-actions-note { font-size: var(--text-2xs); color: var(--muted); margin-left: auto; max-width: 44ch; }

/* --- Question comparison ------------------------------------------------ */

.qd-summary {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-4);
}
.qd-sum-top { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-2) var(--space-6); flex-wrap: wrap; }
.qd-sum-title { margin: 0; font-size: var(--text-lg); font-weight: 600; display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.qd-sum-arrow { color: var(--gray-400); }
.qd-sum-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-0-5);
  font-size: var(--text-xs);
  color: var(--muted);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.qd-sum-meta code { font-family: var(--mono); color: var(--code); background: var(--gray-100); border-radius: var(--radius-xs); padding: var(--space-0-5) var(--space-1-5); }
.qd-sum-note { margin: 0; font-size: var(--text-2xs); color: var(--muted); }

.qd-sum-rate { display: flex; align-items: center; gap: var(--space-4); }
.qd-rate { flex: none; font-size: var(--text-3xl); font-weight: 700; line-height: 1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.qd-rate-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.qd-rate-label { margin: 0; font-size: var(--text-xs); color: var(--muted); }

/* Six numbers in the footprint of one: the bar is the baseline set by outcome, and the detached
   tail is what the comparison added — same scale, so its length is readable against the rest,
   without folding it into a total it is not part of. The filter chips below are its legend.
   3px is the narrowest a segment can be and still be seen, not a step. */
.qd-bar { display: flex; align-items: center; gap: var(--space-1-5); height: var(--space-2); }
.qd-bar-main { display: flex; flex-basis: 0; height: 100%; border-radius: var(--radius-full); overflow: hidden; background: var(--gray-200); }
.qd-seg { flex-basis: 0; min-width: 3px; background: currentColor; }
/* Two adjacent greens are one green without this. */
.qd-seg + .qd-seg { border-left: 1px solid var(--panel); }
.qd-bar-new { flex-basis: 0; min-width: 3px; height: 100%; border-radius: var(--radius-full); background: currentColor; }

/* One row doing three jobs: the filter, the count, and the bar's legend. */
.qd-filters { display: flex; flex-wrap: wrap; gap: var(--space-1-5); margin: var(--space-3) 0; }
.qd-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1-5);
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--gray-600);
  background: var(--panel);
  border: 1px solid var(--border);
  cursor: pointer;
  transition: border-color var(--dur) ease, color var(--dur) ease;
}
.qd-chip:hover { border-color: var(--border-strong); color: var(--text); }
.qd-dot { flex: none; width: var(--space-2); height: var(--space-2); border-radius: 50%; background: currentColor; }
.qd-chip-n { font-family: var(--mono); font-size: var(--text-2xs); color: var(--gray-400); font-variant-numeric: tabular-nums; }
.qd-chip-on { background: var(--gray-900); border-color: var(--gray-900); color: #fff; }
.qd-chip-on .qd-chip-n { color: var(--gray-300); }

.qd-sections { display: flex; flex-direction: column; gap: var(--space-3); }

/* The rail repeats the bucket's colour down the card edge, so a long scroll never loses which
   bucket it is in. `overflow: visible` is what lets the header stick — .db-card clips. */
.qd-section { overflow: visible; border-left: 3px solid var(--qd-rail, var(--border)); }
.qd-head {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  padding: var(--space-2) var(--space-3);
  background: var(--panel);
  border-bottom: 1px solid var(--border);
  border-radius: var(--radius-md) var(--radius-md) 0 0;
}
.qd-head h3 { margin: 0; font-size: var(--text-md); font-weight: 600; }
.qd-head .db-chip { width: var(--space-6); height: var(--space-6); border-radius: var(--radius-sm); }
.qd-head .db-chip svg { width: var(--icon-md); height: var(--icon-md); }
.qd-head .db-count { margin-left: 0; }
.qd-blurb { margin: 0; flex: 1 1 22ch; min-width: 0; font-size: var(--text-xs); color: var(--muted); }
.qd-empty { margin: 0; padding: var(--space-3); font-size: var(--text-sm); color: var(--muted); }

/* A comparison IS tabular data, so it gets a table: the columns line up down the whole bucket,
   which is the only reason a hundred rows can be read by scanning rather than by reading. */
.qd-scroll { overflow-x: auto; }
.qd-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
/* 620px is the narrowest two question columns stay readable side by side. */
.qd-t-sides { min-width: 620px; }
.qd-table th {
  padding: var(--space-1-5) var(--space-2);
  background: var(--gray-25);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.qd-table th.qd-h-n { text-align: right; }
.qd-table th.qd-h-id { padding-right: 0; }
.qd-table td { padding: var(--space-1-5) var(--space-2); vertical-align: top; }
.qd-table th:first-child, .qd-table td:first-child { padding-left: var(--space-3); }
.qd-table th:last-child, .qd-table td:last-child { padding-right: var(--space-3); }

/* One tbody per entry, so the reason and the wording lead belong to the row that hovers. */
.qd-table tbody:hover { background: var(--gray-50); }
.qd-table tbody + tbody > tr:first-child > * { border-top: 1px solid var(--border); }

/* `width: 1px` on a nowrap cell is how auto table layout is told "take what you need and no
   more" — every pixel it gives up goes to the question text, which is what is being read. */
.qd-table th.qd-h-id, .qd-table th.qd-h-n, .qd-table td.qd-c-id, .qd-table td.qd-c-n {
  width: 1px;
  white-space: nowrap;
}
.qd-table th.qd-h-id, .qd-table td.qd-c-id { padding-right: 0; }
.qd-table th.qd-h-n, .qd-table td.qd-c-n { text-align: right; padding-left: var(--space-5); }
.qd-c-text { line-height: 1.45; overflow-wrap: anywhere; }
.qd-t-sides .qd-c-text { width: 50%; }

.qd-sub > td { padding-top: 0; padding-bottom: var(--space-2); font-size: var(--text-xs); color: var(--gray-600); line-height: 1.5; }

.qd-ids { display: inline-flex; gap: var(--space-1); }
.qd-id {
  display: inline-block;
  padding: var(--space-0-5) var(--space-1-5);
  border-radius: var(--radius-xs);
  font-family: var(--mono);
  font-size: var(--text-2xs);
  font-weight: 600;
}

/* A word one side has and the other does not. A wash, never a fill: the diff is a hint about
   wording, not a verdict, and --bad is reserved for danger. */
.qd-diff { background: var(--warn-surface); color: var(--warn); border-radius: var(--radius-xs); padding: 0 var(--space-0-5); }

.qd-num { font-weight: 600; font-variant-numeric: tabular-nums; }
.qd-conf-ok { color: var(--good); }
.qd-conf-warn { color: var(--warn); }
.qd-conf-low { color: var(--gray-500); }
.qd-exact { font-size: var(--text-xs); font-weight: 600; color: var(--good); }

.qd-word { font-weight: 500; color: var(--gray-500); font-variant-numeric: tabular-nums; }

.qd-lead {
  padding: 0 var(--space-1-5);
  border-radius: var(--radius-xs);
  background: var(--gray-100);
  border: 1px solid var(--border);
  color: var(--muted);
  font-size: var(--text-2xs);
  white-space: nowrap;
}
.qd-lead-n { font-variant-numeric: tabular-nums; color: var(--gray-500); }
.qd-notes { display: flex; flex-direction: column; gap: var(--space-1-5); }
.qd-notes p { margin: 0; }

@media (max-width: 900px) {
  .qs-grid { grid-template-columns: 1fr; }
  .qs-actions-note { margin-left: 0; }
  .qd-sum-meta { align-items: flex-start; text-align: left; }
  /* A sticky header is only worth its height on a screen tall enough to scroll under it. */
  .qd-head { position: static; }
}

/* --- Print -------------------------------------------------------------- */

@media print {
  :root {
    --bg: #fff;
    --panel: #fff;
    --border: #c8ccd5;
    --border-strong: #a9afbb;
    --shadow-xs: none;
    --shadow-sm: none;
    --shadow-md: none;
  }
  body { background: #fff !important; font-size: 11pt; }

  .topbar, .flowbar, .skip-link, .upload-panel, .download-bar, .status, .file-list,
  .home, .review-bar, .case-form, .qs-panel, .qd-filters {
    display: none !important;
  }
  main { padding: 0; max-width: none; }
  .results-panel, .forms-pane { gap: var(--space-4); }

  .form-block, .run-card, .db-card, .db-hero, .rv-form, .cf-card, .qd-summary {
    box-shadow: none !important;
    break-inside: avoid;
    page-break-inside: avoid;
  }
  /* A bucket of two hundred rows has to break across pages; each row still stays whole. */
  .qd-section { break-inside: auto !important; page-break-inside: auto !important; }
  .qd-table tbody { break-inside: avoid; page-break-inside: avoid; }
  .qd-head { position: static !important; }
  .qd-scroll { overflow: visible !important; }
  .qd-t-sides { min-width: 0 !important; }
  .form-block-header, .run-card header, .run-card .meta, .summary-bar, .db-card-head {
    background: #f6f7f9 !important;
  }
  .form-block-body { grid-template-columns: 200px 1fr; gap: var(--space-4); padding: var(--space-3); }
  .page-thumbs { gap: var(--space-2); }
  .summary-pill, .badge, .db-chip, .tier-badge, .uw-chip, .db-level-pill { border: 1px solid currentColor; }
  .db-gauge-track { stroke: #c8ccd5; }
  .uw-person { break-inside: avoid; }
  .rv-form input, .rv-form select, .rv-notes { background: #fff !important; color: #000 !important; }
  .rv-remove, .rv-add { display: none !important; }
  /* Everything collapsible is supporting detail: the raw lines, the page strip,
     and the extraction dump. A printed brief is the brief. */
  details { display: none !important; }
  a[href]::after { content: ''; }
}
