/* Palette constants, above the themes and shared by all of them. The four brand
   hues need two readers: each theme's own --brand, and the four swatches in the
   theme menu, which are on screen together and so cannot read the active theme.
   Writing the hex twice is how a re-branded theme keeps its old dot. */
:root {
  --brand-cobalt: #1d4268;
  --brand-olive: #5a6140;
  --brand-wood: #7d4a26;
  --brand-slate: #2a2a2a;
}

html[data-theme="cobalt"],
:root {
  color-scheme: light;
  --canvas: #e3d9cc;
  --paper: #f6efe6;
  --paper-raised: #fffaf3;
  --paper-muted: #f0e7db;
  --paper-strong: #e7dac9;
  --ink: #221f1c;
  --ink-soft: #443c34;
  --muted: #6b5f55;
  --muted-light: #72675b;
  --disabled: #918374;
  --border: #d8ccbc;
  --border-strong: #9e876a;
  --brand: var(--brand-cobalt);
  --brand-strong: #14304c;
  --header: #14304c;
  --brand-soft: #a8c1d8;
  --brand-line: #9db2c6;
  --brand-wash: #e1eaf1;
  --accent: #1b3fd0;
  --accent-wash: #e7ebff;
  --success: #35644c;
  --success-wash: #e4eee7;
  --warning: #80591b;
  --warning-wash: #f4ead4;
  --danger: #8b3728;
  --danger-wash: #f7e3da;
  --info: #315b7d;
  --info-wash: #e2edf4;
  --focus: #1b3fd0;
  --shadow: 0 1px 2px rgb(34 31 28 / 7%), 0 18px 42px -24px rgb(34 31 28 / 38%);
  --shadow-soft: 0 10px 28px -24px rgb(34 31 28 / 45%);
}

html[data-theme="olive"] {
  color-scheme: light;
  --canvas: #dedbcc;
  --paper: #f4f1e5;
  --paper-raised: #fbf9ef;
  --paper-muted: #ebe8d9;
  --paper-strong: #dddbc7;
  --ink: #24231d;
  --ink-soft: #454438;
  --muted: #616051;
  --muted-light: #6a6959;
  --disabled: #878671;
  --border: #d2d1bd;
  --border-strong: #8d8d67;
  --brand: var(--brand-olive);
  --brand-strong: #434829;
  --header: #434829;
  --brand-soft: #c3c7a8;
  --brand-line: #adb192;
  --brand-wash: #e4e6d5;
  --accent: #8f6631;
  --accent-wash: #f1e5d2;
  --success: #4e6848;
  --success-wash: #e3ecdf;
  --warning: #7d591a;
  --warning-wash: #f3e9d2;
  --danger: #873d2d;
  --danger-wash: #f3e2da;
  --info: #5c6448;
  --info-wash: #e7e9dc;
  --focus: #8b5f27;
  --shadow: 0 1px 2px rgb(36 35 29 / 7%), 0 18px 42px -24px rgb(36 35 29 / 38%);
  --shadow-soft: 0 10px 28px -24px rgb(36 35 29 / 45%);
}

html[data-theme="wood"] {
  color-scheme: light;
  --canvas: #e5d9ca;
  --paper: #f7efe4;
  --paper-raised: #fff9f0;
  --paper-muted: #f1e5d6;
  --paper-strong: #e7d4bf;
  --ink: #271f19;
  --ink-soft: #4b3b30;
  --muted: #6c5a4d;
  --muted-light: #756458;
  --disabled: #94816f;
  --border: #dbc8b4;
  --border-strong: #ad8258;
  --brand: var(--brand-wood);
  --brand-strong: #5e3619;
  --header: #4a2a12;
  --brand-soft: #dcbc9b;
  --brand-line: #c2a184;
  --brand-wash: #f0dfcd;
  --accent: #9b3f2e;
  --accent-wash: #f4dfd8;
  --success: #526342;
  --success-wash: #e7eddf;
  --warning: #815418;
  --warning-wash: #f5e9cf;
  --danger: #903727;
  --danger-wash: #f7e1d8;
  --info: #74543b;
  --info-wash: #eee1d6;
  --focus: #9b3f2e;
  --shadow: 0 1px 2px rgb(39 31 25 / 7%), 0 18px 42px -24px rgb(39 31 25 / 38%);
  --shadow-soft: 0 10px 28px -24px rgb(39 31 25 / 45%);
}

html[data-theme="slate"] {
  color-scheme: light;
  --canvas: #e4e4e4;
  --paper: #f5f5f5;
  --paper-raised: #fafafa;
  --paper-muted: #ececec;
  --paper-strong: #dfdfdf;
  --ink: #1a1a1a;
  --ink-soft: #3a3a3a;
  --muted: #636363;
  --muted-light: #6b6b6b;
  --disabled: #888888;
  --border: #d0d0d0;
  --border-strong: #8e8e8e;
  --brand: var(--brand-slate);
  --brand-strong: #111111;
  --header: #111111;
  --brand-soft: #c4c4c4;
  --brand-line: #adadad;
  --brand-wash: #ebebeb;
  --accent: #4a4a4a;
  --accent-wash: #ececec;
  --success: #3f5f4a;
  --success-wash: #e6eee8;
  --warning: #7b5e25;
  --warning-wash: #f2ead8;
  --danger: #7a3a32;
  --danger-wash: #f3e4df;
  --info: #4a4a4a;
  --info-wash: #ececec;
  --focus: #2a2a2a;
  --shadow: 0 1px 2px rgb(26 26 26 / 7%), 0 18px 42px -24px rgb(26 26 26 / 38%);
  --shadow-soft: 0 10px 28px -24px rgb(26 26 26 / 45%);
}

* { box-sizing: border-box; }

/* Present to assistive tech, absent from the page. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Every heading rule below is more specific than this, so this only reaches
   headings no rule claims -- which previously rendered at the UA default 2em
   (30px), a size on no rung of the type ladder. Margins are left to the UA. */
h1, h2, h3, h4, h5, h6 { font-size: 16px; font-weight: 700; line-height: 1.5; }

html {
  min-width: 320px;
  background: var(--canvas);
  scroll-behavior: smooth;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--canvas);
  color: var(--ink);
  font-family: "Vazirmatn", Tahoma, sans-serif;
  font-size: 15px;
  font-variant-numeric: tabular-nums;
  line-height: 1.75;
  text-rendering: optimizeLegibility;
}

button,
input,
select,
textarea { font: inherit; }

button,
a { -webkit-tap-highlight-color: transparent; }

a { color: var(--brand-strong); }
a:hover { color: var(--ink); }

img,
svg { display: block; max-width: 100%; }

::selection { background: var(--brand); color: var(--paper); }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
}

[hidden] { display: none !important; }

/* Mode visibility only ever HIDES; it never re-shows. `display: revert` used to
   do the showing, but revert drops to the user-agent value and discarded the
   author's own display: every `.button` here is an `<a>`, so inline-flex became
   inline and min-height: 44px stopped applying — five operator buttons rendered
   19-22px tall. Hiding with :not() leaves each element's own display intact. */
html:not([data-mode="operator"]) .operator-only { display: none !important; }
html[data-mode="operator"] .simple-only { display: none !important; }

.skip-link {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  position: fixed;
  inset-block-start: 10px;
  inset-inline-start: 10px;
  z-index: 100;
  padding: 8px 12px;
  border-radius: 6px;
  background: var(--ink);
  color: var(--paper);
  transform: translateY(-160%);
  transition: transform 160ms ease;
}
.skip-link:focus { transform: translateY(0); }

.shell {
  width: min(1180px, calc(100% - 32px));
  margin-inline: auto;
}

.app-header {
  position: sticky;
  inset-block-start: 0;
  z-index: 40;
  background: var(--header);
  /* Borders in this system are 1px. A dark band on a light canvas separates
     itself; the 3px rule here was three times the weight of any other line. */
  border-block-end: 1px solid var(--ink);
  color: var(--paper);
}

.app-header__inner {
  min-height: 66px;
  display: flex;
  align-items: center;
  gap: 20px;
}

.brand {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--paper);
  text-decoration: none;
  white-space: nowrap;
}
.brand:hover { color: var(--paper); }
.brand strong {
  display: block;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .14em;
}
.brand small {
  display: block;
  color: var(--brand-soft);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0;
}

.app-nav {
  display: flex;
  align-items: center;
  gap: 18px;
}
.app-nav a {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  color: var(--brand-soft);
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
}
.app-nav a:hover,
.app-nav a[aria-current="page"] { color: var(--paper); }

.app-header__tools {
  margin-inline-start: auto;
  display: flex;
  align-items: center;
  gap: 9px;
}

.segmented-control {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--brand-line);
  border-radius: 999px;
  overflow: hidden;
}
.segmented-control button {
  min-height: 44px;
  /* The width floor matters here and only shows under 760px, where the padding
     drops to 9px and "ساده" fell to 40.5px. Phase 2 swept this at desktop only. */
  min-width: 44px;
  padding: 0 11px;
  border: 0;
  border-inline-start: 1px solid var(--brand-line);
  background: transparent;
  color: var(--brand-soft);
  cursor: pointer;
  font-size: 11px;
  font-weight: 600;
}
.segmented-control button:first-child { border-inline-start: 0; }
.segmented-control button[aria-pressed="true"] {
  background: var(--paper);
  color: var(--brand-strong);
}

.theme-switcher { position: relative; }
.theme-switcher > summary {
  min-height: 44px;
  padding: 0 11px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border: 1px solid var(--brand-line);
  border-radius: 999px;
  color: var(--brand-soft);
  cursor: pointer;
  font-size: 11px;
  font-weight: 600;
  list-style: none;
}
.theme-switcher > summary::-webkit-details-marker { display: none; }
.theme-switcher[open] > summary,
.theme-switcher > summary:hover { color: var(--paper); }
.theme-switcher__panel {
  position: absolute;
  inset-block-start: calc(100% + 9px);
  inset-inline-end: 0;
  width: 184px;
  padding: 7px;
  display: grid;
  gap: 4px;
  border: 1px solid var(--border-strong);
  border-radius: 9px;
  background: var(--paper-raised);
  box-shadow: var(--shadow);
}
.theme-option {
  min-height: 44px;
  padding: 0 9px;
  display: flex;
  align-items: center;
  gap: 8px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
  text-align: start;
  font-size: 12px;
}
.theme-option:hover { background: var(--paper-muted); color: var(--ink); }
/* Selection carries three signals -- ground, weight and a tick -- so it is never
   mistaken for the hover state it used to share a background with. */
.theme-option[aria-pressed="true"] {
  background: var(--brand-wash);
  color: var(--brand-strong);
  font-weight: 700;
}
.theme-option[aria-pressed="true"]::after {
  content: "";
  width: 12px;
  height: 7px;
  margin-inline-start: auto;
  border-inline-start: 2px solid currentColor;
  border-block-end: 2px solid currentColor;
  transform: rotate(-45deg) translate(1px, -2px);
}
.theme-option__swatch {
  width: 12px;
  height: 12px;
  border: 2px solid var(--paper-raised);
  border-radius: 50%;
  box-shadow: 0 0 0 1px var(--border-strong);
}
.theme-option[data-theme-value="cobalt"] .theme-option__swatch { background: var(--brand-cobalt); }
.theme-option[data-theme-value="wood"] .theme-option__swatch { background: var(--brand-wood); }
.theme-option[data-theme-value="olive"] .theme-option__swatch { background: var(--brand-olive); }
.theme-option[data-theme-value="slate"] .theme-option__swatch { background: var(--brand-slate); }

.logout-form { margin: 0; }
.header-link,
.logout-button {
  min-height: 44px;
  /* The height floor was here from the start; the width was not, so "خروج"
     rendered a 26px-wide target. PRODUCT.md binds 44px in the SMALLEST
     dimension, which for a two-glyph label is the horizontal one. */
  min-width: 44px;
  padding: 5px 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: transparent;
  color: var(--brand-soft);
  cursor: pointer;
  font-size: 12px;
  text-decoration: none;
}
.header-link:hover,
.logout-button:hover { color: var(--paper); }

.mode-flag {
  padding: 2px 8px;
  border: 1px solid var(--brand-line);
  border-radius: 999px;
  color: var(--brand-soft);
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}

/* One shell, both modes. The header treatment is identical in simple and
   operator; only its density changes. No colour may shift with the mode —
   every header colour comes from the active theme's own tokens. */
html[data-mode="operator"] .app-header__inner { min-height: 56px; }

.mobile-nav {
  position: fixed;
  inset-inline: 0;
  inset-block-end: 0;
  z-index: 45;
  display: none;
  grid-template-columns: repeat(3, 1fr);
  border-block-start: 1px solid var(--border);
  background: var(--paper-muted);
  /* Content scrolls underneath it, which is the Floating Test. */
  box-shadow: var(--shadow);
}
.mobile-nav a,
.mobile-nav button {
  min-height: 52px;
  padding: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  border: 0;
  background: none;
  color: var(--muted);
  cursor: pointer;
  font-size: 11px;
  font-weight: 600;
  text-decoration: none;
}
.mobile-nav > :nth-child(2) { border-inline: 1px solid var(--border); }
.mobile-nav svg { width: 17px; height: 17px; }
.mobile-nav a[aria-current="page"] {
  border-block-end: 2px solid var(--brand);
  color: var(--ink);
}
.mobile-nav form { margin: 0; display: flex; }
.mobile-nav form button { flex: 1; }

.page {
  min-height: calc(100vh - 106px);
  margin-block: 20px 40px;
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--paper);
  /* Sheet, not Floater: the page frame scrolls with the document and nothing
     passes underneath it. --shadow is reserved for dismissible overlays. */
  box-shadow: var(--shadow-soft);
}

.page-content { padding: 30px 34px 42px; }
.page-content--narrow { width: min(760px, 100%); margin-inline: auto; }
.page-content--wide { width: 100%; }

.workflow-rail {
  padding: 14px 28px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  border-block-end: 1px solid var(--border);
  background: var(--paper-muted);
}
.workflow-rail__compact,
.workflow-rail__progress { display: none; }
.workflow-rail__steps {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.workflow-step {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--disabled);
  font-size: 12px;
  font-weight: 400;
  line-height: 1.5;
}
.workflow-step + .workflow-step::before {
  content: "";
  width: 22px;
  height: 1px;
  margin-inline-end: 1px;
  background: var(--border);
}
.workflow-step.is-linked::before { height: 2px; background: var(--brand-line); }
.workflow-step__mark {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  color: var(--muted);
  /* 11px is the floor of the ladder and it applies to a numeral too; the mark
     grew by two pixels rather than the number shrinking below the floor. */
  font: 700 11px/1 ui-monospace, monospace;
}
.workflow-step__mark svg { width: 10px; height: 10px; }
.workflow-step__lock { width: 14px; height: 14px; flex: 0 0 auto; }
.workflow-step a,
.workflow-step > span { color: inherit; text-decoration: none; }
/* Rail steps are navigation, so they carry the same 44px floor as any control.
   An invisible hit-area overlay was tried first and lost to neighbouring rows. */
.workflow-step a {
  min-height: 44px;
  min-width: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.workflow-step a:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 4px; }
.workflow-step.is-complete { color: var(--brand-strong); font-weight: 700; }
.workflow-step.is-complete .workflow-step__mark { border-color: var(--brand); background: var(--brand); color: var(--paper); }
.workflow-step.is-current { color: var(--ink); font-weight: 700; }
.workflow-step.is-current .workflow-step__mark { border-color: var(--ink); background: var(--ink); color: var(--paper); }
.workflow-step.is-available { color: var(--muted); }
.workflow-step.is-locked { color: var(--disabled); }

.workflow-rail__lock {
  margin: 0;
  color: var(--muted-light);
  font-size: 12px;
  line-height: 1.6;
}
.workflow-rail__rewind {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 10px;
  color: var(--muted);
  font-size: 11px;
}
/* The rewind controls are buttons now, not underlined text. Baseline alignment was
   for a row of words; a row of controls centres. */
.workflow-rail__rewind { align-items: center; }
.workflow-rail__rewind small {
  flex: 1 1 100%;
  color: var(--muted-light);
  font-size: 11px;
  line-height: 1.6;
}
.workflow-rail__rewind > a:not(.button) {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  color: var(--ink-soft);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 4px;
}

.page-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 28px;
  margin-block-end: 26px;
}
.page-heading--compact { margin-block-end: 22px; }
/* A heading leads; its supporting line sits underneath. Never above it —
   a label stacked over a heading is the eyebrow the craft floor bans. */
.page-heading__project,
.subtitle { margin: 5px 0 0; color: var(--muted); font-size: 14px; }
.page-heading h1 {
  max-width: 34ch;
  margin: 0;
  color: var(--ink);
  font-size: clamp(24px, 3vw, 35px);
  font-weight: 800;
  letter-spacing: -.045em;
  line-height: 1.35;
  text-wrap: balance;
}
.page-heading h2 { margin: 0; }
.page-heading p { max-width: 68ch; margin: 7px 0 0; color: var(--muted); text-wrap: pretty; }
.page-heading__meta { margin-block-start: 10px; display: flex; flex-wrap: wrap; gap: 7px 13px; color: var(--muted); font-size: 12px; }

.kicker {
  margin: 0 0 6px;
  color: var(--brand-strong);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .03em;
}

.lede { color: var(--muted); font-size: 14px; }

.button {
  min-height: 44px;
  padding: 0 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  border: 1px solid transparent;
  border-radius: 6px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  transition: transform 120ms ease, background-color 120ms ease, border-color 120ms ease;
}
.button:hover { transform: translateY(-1px); }
.button:active { transform: translateY(0); }
/* An inactive control gets its own colours, not a faded copy of the active ones.
   `opacity: .55` over --brand took the label of the source-confirm button to roughly
   2.4:1 — and that is the one label a reader has to be able to read, because the hint
   beside it is what explains why the button is off. --muted on --paper-strong is held
   at 4.5:1 across all four themes by tests/test_theme_contrast_contract.py. */
.button:disabled {
  border-color: var(--border-strong);
  background: var(--paper-strong);
  color: var(--muted);
  cursor: not-allowed;
  transform: none;
}
.button:disabled:hover { border-color: var(--border-strong); background: var(--paper-strong); color: var(--muted); }
.button--primary { background: var(--brand); color: var(--paper); }
.button--primary:hover { background: var(--brand-strong); color: var(--paper); }
.button--secondary { border-color: var(--border-strong); background: var(--paper-raised); color: var(--ink-soft); }
.button--secondary:hover { border-color: var(--ink); color: var(--ink); }
.button--quiet { border-color: transparent; background: transparent; color: var(--muted); }
.button--quiet:hover { background: var(--paper-muted); color: var(--ink); }
.button--danger { border-color: var(--danger); background: transparent; color: var(--danger); }
.button--danger:hover { background: var(--danger-wash); color: var(--danger); }
.button--danger-solid { background: var(--danger); color: var(--paper); }
.button--danger-solid:hover { background: var(--danger); color: var(--paper); filter: brightness(.92); }
.button--full { width: 100%; }
.button--small { min-height: 44px; padding-inline: 11px; font-size: 11px; }

.form-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 9px;
}
.form-actions--split { justify-content: space-between; }
.form-actions--end { justify-content: flex-end; }

.card,
.form-sheet,
.interpretation,
.data-panel,
.audio-player,
.empty-state {
  border: 1px solid var(--border);
  border-radius: 9px;
  background: var(--paper-raised);
  box-shadow: var(--shadow-soft);
}

.card { padding: 17px; }
.form-sheet { padding: 22px; display: grid; gap: 19px; }
/* An aside inside a form sheet is separated by a rule, never by a second card:
   both grounds are --paper-raised, so the nested panel drew a border around
   nothing. DESIGN.md: dense information is carried by type and rules. */
.form-sheet__aside { padding-block-start: 19px; border-block-start: 1px solid var(--border); }
.form-sheet__aside h2 { margin: 0 0 7px; font-size: 16px; font-weight: 700; }
.field { display: grid; gap: 7px; }
.field > span,
.field > label { color: var(--ink-soft); font-size: 12px; font-weight: 700; }
.field small { color: var(--muted); font-size: 12px; font-weight: 400; }
.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  background: var(--paper);
  color: var(--ink);
}
.field textarea { resize: vertical; line-height: 1.8; }
.field input:hover,
.field select:hover,
.field textarea:hover { border-color: var(--muted-light); }
.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--brand);
  outline: 2px solid var(--focus);
  outline-offset: 1px;
  box-shadow: 0 0 0 4px var(--brand-wash);
}
.field [aria-invalid="true"] { border-color: var(--danger); border-width: 1.5px; }
.field-error {
  margin: 0;
  display: flex;
  align-items: flex-start;
  gap: 7px;
  color: var(--danger);
  font-size: 13px;
  font-weight: 700;
  line-height: 1.7;
}
.field-error svg { width: 14px; height: 14px; flex: 0 0 auto; margin-block-start: 4px; }
.field-hint { margin: 0; color: var(--muted); font-size: 13px; }
.field--large textarea { font-size: 17px; line-height: 1.9; }
.field-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }

.choice-group {
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  border: 0;
}
.choice-group legend { width: 100%; margin-block-end: 6px; color: var(--ink-soft); font-size: 12px; font-weight: 700; }
.choice-group label { position: relative; }
.choice-group input { position: absolute; opacity: 0; pointer-events: none; }
.choice-group span {
  min-height: 44px;
  padding: 0 13px;
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: var(--paper);
  color: var(--muted);
  cursor: pointer;
  font-size: 12px;
}
.choice-group input:checked + span { border-color: var(--brand); background: var(--brand-wash); color: var(--brand-strong); font-weight: 700; }
.choice-group input:focus-visible + span { outline: 2px solid var(--focus); outline-offset: 3px; }

.notice {
  margin-block: 15px;
  padding: 15px 17px;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: var(--paper-muted);
}
.notice p { margin: 5px 0 0; }
.notice--success { border-color: var(--success); background: var(--success-wash); }
.notice--warning { border-color: var(--warning); background: var(--warning-wash); }
.notice--danger { border-color: var(--danger); background: var(--danger-wash); }
.notice--info { border-color: var(--info); background: var(--info-wash); }

/* attention-panel is a rule-and-type divider, not a boxed notice: it never
   shared .notice's border/background, so it no longer shares the selector
   either -- the two blocks used to collide, with this one winning outright
   on every property and leaving the shared declaration dead. */
.attention-panel {
  margin-block: 20px;
  padding: 14px 0 0;
  display: grid;
  gap: 12px;
  border-block-start: 1px solid var(--ink);
}
.attention-panel__line {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px 10px;
}
.attention-panel__label {
  margin: 0;
  color: var(--ink);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .05em;
}
.attention-panel__dot { color: var(--muted-light); }
.attention-panel__ask { color: var(--muted); font-size: 12px; }
.attention-panel p { max-width: 62ch; margin: 0; color: var(--ink-soft); font-size: 14px; text-wrap: pretty; }
.attention-panel__actions { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }

.quality-notes-disclosure { margin-block-start: 12px; display: grid; gap: 8px; }
.quality-notes-disclosure h3 { margin: 0; color: var(--ink-soft); font-size: 13px; font-weight: 700; }
.quality-notes-disclosure > p { margin: 0; color: var(--muted); font-size: 12px; }

.quality-notes {
  margin: 0;
  padding: 0;
  display: grid;
  gap: 7px;
  list-style: none;
  color: var(--ink-soft);
  font-size: 13px;
  line-height: 1.6;
}
.quality-notes--informational { color: var(--muted); font-size: 12px; }

/* An optional sub-form toggle, same family as .search-path: the summary is
   the only thing styled, native marker kept, children grid-spaced without
   a body wrapper since the fields sit directly under <details>. */
.disclosure { display: grid; gap: 14px; }
.disclosure > summary {
  width: fit-content;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  color: var(--muted);
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
}
.disclosure > summary:hover { color: var(--ink); }

.status-label {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--ink-soft);
  font-size: 12px;
  font-weight: 700;
}
.status-label__mark { width: 11px; height: 11px; flex: 0 0 auto; }
span.status-label__mark {
  width: 9px;
  height: 9px;
  border: 1px solid currentColor;
  border-radius: 50%;
}
.status-label small { color: var(--muted); font-size: 11px; font-weight: 600; }
.status-label--running { color: var(--accent); }
.status-label--running span.status-label__mark { background: currentColor; animation: status-pulse 1.8s ease-in-out infinite; }
.status-label--attention { color: var(--warning); }
.status-label--success { color: var(--success); }
.status-label--danger { color: var(--danger); }
.status-label--neutral { color: var(--muted); }

.status-label--pill {
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--paper-muted);
  background: color-mix(in srgb, currentColor 12%, var(--paper));
  font-size: 11px;
}
.status-label--pill small { display: none; }

@keyframes status-pulse { 0%,100% { opacity: 1; } 50% { opacity: .3; } }

.section-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 18px;
  margin-block-end: 12px;
}
.section-heading h2,
.section-heading h3 { margin: 0; font-size: 16px; line-height: 1.5; }
.section-heading > span { color: var(--muted); font-size: 11px; }
/* A list that owns its section is introduced by a rule, the way a table head is. */
.section-heading--rule {
  margin-block-end: 0;
  padding-block-end: 11px;
  border-block-end: 1px solid var(--ink);
}
.section-heading--rule h2,
.section-heading--rule h3 { font-size: 12px; font-weight: 700; letter-spacing: .05em; }
.section-heading--rule > span { color: var(--muted); font-size: 13px; }

.section-block { margin-block-start: 28px; }
.section-block + .section-block { padding-block-start: 28px; border-block-start: 1px solid var(--border); }

.project-groups { display: grid; gap: 28px; }
.project-group { display: grid; gap: 0; }
.project-group__title {
  margin: 0 0 11px;
  padding-block-end: 11px;
  border-block-end: 1px solid var(--border);
  color: var(--ink);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .05em;
}
.project-group--attention .project-group__title { border-block-end-color: var(--ink); }
.project-list { display: grid; }
/* The row title keeps its type size; the tap area reaches down over the meta
   line, which carries no other target. */
.project-row h3 a { position: relative; }
.project-row h3 a::after {
  content: "";
  position: absolute;
  inset-block: -10px;
  inset-inline: -4px;
}

.project-row {
  padding: 14px 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 18px;
  border-block-end: 1px solid var(--border);
}
.project-row__main { min-width: 0; display: grid; gap: 6px; }
.project-row h3 { margin: 0; font-size: 16px; font-weight: 700; letter-spacing: -.02em; line-height: 1.45; text-wrap: pretty; }
.project-row h3 a { color: var(--ink); text-decoration: none; }
.project-row h3 a:hover { color: var(--brand); }
.project-meta {
  margin: 0;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 10px;
  color: var(--muted);
  font-size: 12px;
}
.project-meta__dot { color: var(--muted-light); }
.project-meta__attention { color: var(--ink); font-weight: 700; }
.project-row__technical { margin: 0; color: var(--muted-light); font-size: 11px; overflow-wrap: anywhere; }
.project-row .button { flex: none; white-space: nowrap; }

.project-search {
  margin-block-end: 18px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.project-search input { max-width: 360px; }

.empty-state { padding: 52px 34px; text-align: center; }
.empty-state h2 { margin: 0; font-size: clamp(20px, 2.4vw, 26px); font-weight: 800; }
.empty-state p { max-width: 54ch; margin: 10px auto 20px; color: var(--muted); }
.empty-inline { padding: 24px; display: grid; gap: 5px; border: 1px dashed var(--border-strong); border-radius: 8px; color: var(--muted); }
.empty-inline strong { color: var(--ink); }

.summary-list { display: grid; }
.summary-row { padding: 10px 0; display: grid; grid-template-columns: minmax(0, 145px) minmax(0, 1fr); gap: 18px; border-block-end: 1px solid var(--border); }
.summary-row:last-child { border-block-end: 0; }
.summary-row dt { color: var(--muted); font-size: 11px; overflow-wrap: anywhere; }
.summary-row dd { margin: 0; min-width: 0; color: var(--ink-soft); }

/* Readiness: the verdict leads, three groups summarise, the full list waits
   one click below. The leading rail marks the blocking group only. */
/* The readiness verdict now uses `.coverage-verdict`; this pairs its tone label with
   the subtitle on one line so the ruling keeps a mark without needing a tinted box. */
.coverage-verdict__label {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 10px;
}
.coverage-verdict__label .subtitle { margin: 0; }
.readiness-groups { display: grid; }
.readiness-group {
  padding: 13px 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  border-block-end: 1px solid var(--border);
  font-size: 14px;
}
.readiness-group:first-child { border-block-start: 1px solid var(--border); }
.readiness-group__title { color: var(--ink-soft); font-weight: 700; }
/* The blocking group is marked by ground and by its own status label. No rail:
   this is a blocked category, not the row the reader is standing on, and the
   Current-Row Rule does not stretch that far. */
.readiness-group.is-blocking {
  padding-inline: 13px;
  background: var(--paper-strong);
}
.readiness-all > summary,
.readiness-technical > summary {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  color: var(--brand-strong);
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
}
.readiness-technical { margin-block-start: 15px; }
.readiness-technical dd { overflow-wrap: anywhere; }

.timeline { margin: 0; padding: 0; display: grid; gap: 10px; list-style: none; }
.timeline li {
  display: grid;
  grid-template-columns: 13px minmax(0, 1fr) 7.5rem;
  align-items: baseline;
  gap: 14px;
  color: var(--ink-soft);
  font-size: 13px;
  line-height: 1.8;
}
.timeline__mark {
  width: 13px;
  height: 13px;
  align-self: start;
  margin-block-start: 5px;
  border: 2px solid var(--border-strong);
  border-radius: 50%;
  color: var(--brand);
}
.timeline__mark--done { border: 0; }
.timeline__mark--done svg { width: 13px; height: 13px; }
.timeline__mark--running { border-color: var(--accent); animation: status-pulse 1.8s ease-in-out infinite; }
.timeline__current { color: var(--ink); font-weight: 700; }
.timeline time { color: var(--muted-light); font-size: 12px; }

.drop-zone {
  padding: 16px 18px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
  border: 1px dashed var(--border-strong);
  border-radius: 8px;
  background: var(--paper-muted);
}
.drop-zone.is-dragging { border-color: var(--brand); background: var(--brand-wash); }
.drop-zone__icon { width: 20px; height: 20px; flex: 0 0 auto; color: var(--ink-soft); }
.drop-zone__copy { min-width: 0; flex: 1; }
.drop-zone__title { margin: 0; color: var(--ink); font-size: 14px; font-weight: 700; }
.drop-zone__hint { margin: 2px 0 0; color: var(--muted); font-size: 12px; }
.drop-zone__picker { position: relative; overflow: hidden; flex: none; }
.drop-zone__picker input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

.search-path > summary {
  width: fit-content;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  color: var(--muted);
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
}
.search-path > summary:hover { color: var(--ink); }
.search-path__body {
  margin-block-start: 12px;
  padding: 18px;
  display: grid;
  gap: 12px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: var(--paper-raised);
}
.search-path__body > p { margin: 0; color: var(--muted); font-size: 12px; }
.search-path__body form { display: grid; gap: 12px; }

.search-candidate-list,
.transcript-list,
.chunk-list { display: grid; gap: 8px; }
.source-list { display: grid; }
.search-candidate,
.quality-row,
.chunk-row {
  padding: 15px 16px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--paper-raised);
}
.search-candidate p { margin: 7px 0; color: var(--muted); font-size: 12px; }
.search-candidate__url { overflow-wrap: anywhere; }

.source-row {
  padding: 14px 0;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: 12px 16px;
  border-block-end: 1px solid var(--border);
}
/* The 44px target here is the adjacent `for`-associated label, which spans the
   row. The box itself only has to be seen, and 15px was small for the one
   control that answers "is this source in my corpus?". */
.source-row__select { min-height: 44px; margin: 0; display: flex; align-items: center; gap: 8px; }
.source-row__select input[type="checkbox"] { width: 18px; height: 18px; margin: 0; accent-color: var(--ink); }
.source-row__icon { width: 16px; height: 16px; margin-block-start: 3px; color: var(--danger); }
.source-row__identity { min-width: 0; display: grid; gap: 6px; }
.source-row__identity > label,
.source-row__heading {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 10px;
}
.source-row__identity > label { min-height: 44px; display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; cursor: pointer; }
.source-row__identity strong { font-size: 14px; overflow-wrap: anywhere; }
.source-row__meta a {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}
.source-row__meta {
  margin: 0;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 10px;
  color: var(--muted);
  font-size: 12px;
}
.source-row__meta > span + span::before,
.source-row__meta > a::before { content: "·"; margin-inline-end: 10px; color: var(--border-strong); }
.source-row__summary { margin: 0; max-width: 58ch; color: var(--danger); font-size: 13px; text-wrap: pretty; }
.source-row__issue { margin: 0; color: var(--muted); font-size: 11px; }
.source-row__actions { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
.source-row__actions form { margin: 0; }
.source-row__locked { color: var(--muted); font-size: 11px; white-space: nowrap; }
.source-row.is-unusable { padding-inline: 14px; background: var(--danger-wash); }

.destructive-link {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  color: var(--danger);
  font-size: 12px;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 4px;
}
.destructive-link:hover { color: var(--danger); text-decoration-thickness: 2px; }

.technical-details { grid-column: 1 / -1; }
.technical-details > summary { width: fit-content; min-height: 44px; display: inline-flex; align-items: center; color: var(--ink); cursor: pointer; font-size: 12px; font-weight: 700; }
.technical-details__body { margin-block-start: 8px; padding: 11px 13px; border-radius: 6px; background: var(--paper-muted); color: var(--muted); font-size: 11px; overflow-wrap: anywhere; }
.technical-details__body p { margin: 0; }
.technical-details--wide { margin-block-start: 18px; padding-block-start: 12px; border-block-start: 1px solid var(--border); }
.technical-details--wide .technical-details__body { padding: 12px 16px; font-size: 12px; }

.sticky-confirmation {
  position: sticky;
  inset-block-end: 12px;
  margin-block-start: 24px;
  padding: 15px 17px;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 18px;
  border: 1px solid var(--border-strong);
  border-radius: 9px;
  background: var(--paper-raised);
  box-shadow: var(--shadow);
}
.sticky-confirmation h2 { margin: 0; font-size: 15px; }
.sticky-confirmation p { margin: 4px 0 0; color: var(--muted); font-size: 11px; }
.sticky-confirmation p.sticky-confirmation__names { color: var(--ink-soft); font-size: 12px; }

.stage-list {
  margin: 0;
  padding: 0;
  overflow: hidden;
  list-style: none;
  border: 1px solid var(--border);
  border-radius: 8px;
}
.stage-row {
  padding: 12px 18px;
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  border-block-end: 1px solid var(--border);
}
.stage-row:last-child { border-block-end: 0; }
.stage-row__mark {
  width: 12px;
  height: 12px;
  margin-inline-start: 2px;
  display: grid;
  place-items: center;
  border: 1.5px solid var(--border-strong);
  border-radius: 50%;
  color: var(--paper);
}
.stage-row__mark svg { width: 9px; height: 9px; }
.stage-row.is-complete .stage-row__mark { width: 16px; height: 16px; margin-inline-start: 0; border: 0; background: var(--brand); }
/* `is-current` says which stage the run is standing on. It never says how that stage
   is doing — that is what the status class carries, and only `is-running` earns the
   reserved accent. A blocked stage pulsing in accent was the interface claiming work
   was happening on the one row that had stopped to ask a question. */
.stage-row.is-current {
  padding-block: 14px;
  border-inline-start: 3px solid var(--border-strong);
  background: var(--paper-strong);
}
.stage-row.is-running { border-inline-start-color: var(--brand); }
.stage-row.is-blocked { border-inline-start-color: var(--warning); }
.stage-row.is-stopped { border-inline-start-color: var(--danger); }
.stage-row.is-current .stage-row__mark { border: 0; }
.stage-row.is-running .stage-row__mark { background: var(--accent); animation: status-pulse 1.8s ease-in-out infinite; }
.stage-row.is-blocked .stage-row__mark { background: var(--warning); }
.stage-row.is-stopped .stage-row__mark { background: var(--danger); }
/* Nothing is happening here yet, so the mark stays an outline rather than a fill. */
.stage-row.is-waiting .stage-row__mark { border: 1.5px solid var(--border-strong); }
.stage-row__copy { display: grid; gap: 3px; }
.stage-row__copy strong { color: var(--ink-soft); font-size: 14px; font-weight: 400; }
.stage-row__copy small { color: var(--muted); font-size: 13px; }
.stage-row__state { color: var(--muted-light); font-size: 12px; white-space: nowrap; }
.stage-row.is-current .stage-row__copy strong { color: var(--ink); font-weight: 700; }
.stage-row.is-current .stage-row__state { color: var(--muted); font-weight: 700; }
.stage-row.is-running .stage-row__state { color: var(--brand); }
.stage-row.is-blocked .stage-row__state { color: var(--warning); }
.stage-row.is-stopped .stage-row__state { color: var(--danger); }
.stage-row.is-pending .stage-row__copy strong,
.stage-row.is-pending .stage-row__state { color: var(--muted-light); font-weight: 400; }

.live-note {
  margin: 0;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 18px;
  color: var(--muted);
  font-size: 13px;
}
.live-note svg { width: 13px; height: 13px; color: var(--disabled); }
.live-note a { color: var(--ink); font-weight: 700; }

.error-recovery {
  margin-block: 15px;
  padding: 0;
  overflow: hidden;
  border: 1.5px solid var(--danger);
  border-radius: 8px;
  background: var(--paper-raised);
}
.error-recovery__body { padding: 18px 20px; display: grid; gap: 14px; }
.error-recovery__head { display: flex; align-items: flex-start; gap: 12px; color: var(--danger); }
.error-recovery__head svg { width: 18px; height: 18px; flex: 0 0 auto; margin-block-start: 5px; }
.error-recovery h2 { max-width: 46ch; margin: 0; color: var(--ink); font-size: 17px; line-height: 1.45; }
.error-recovery__head p { max-width: 60ch; margin: 7px 0 0; color: var(--ink-soft); font-size: 14px; text-wrap: pretty; }
.error-recovery__outcome {
  padding-inline-start: 30px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}
.error-recovery__outcome h3 { margin: 0; font-size: 12px; font-weight: 700; letter-spacing: .04em; }
.error-recovery__intact h3 { color: var(--brand); }
.error-recovery__unfinished h3 { color: var(--danger); }
.error-recovery__outcome p { margin: 6px 0 0; color: var(--ink-soft); font-size: 13px; }
.error-recovery__actions {
  padding-inline-start: 30px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}
.error-recovery__actions form { margin: 0; }
.error-recovery__attempt { color: var(--muted-light); font-size: 12px; }
.error-recovery__technical {
  padding: 12px 20px;
  border-block-start: 1px solid var(--danger);
  background: var(--danger-wash);
  color: var(--danger);
  font-size: 12px;
}
.error-recovery__technical > summary { min-height: 44px; display: inline-flex; align-items: center; cursor: pointer; font-weight: 700; }
.error-recovery__technical p { margin: 8px 0 0; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; overflow-wrap: anywhere; }
.error-recovery__hint { max-width: 60ch; margin: 0 0 15px; color: var(--muted); font-size: 13px; text-wrap: pretty; }

.impact-summary { display: grid; gap: 18px; }
.impact-summary__head {
  max-width: 64ch;
  display: flex;
  align-items: flex-start;
  gap: 14px;
  color: var(--danger);
}
.impact-summary__head svg { width: 20px; height: 20px; flex: 0 0 auto; margin-block-start: 7px; }
.impact-summary__head h1 {
  margin: 0;
  color: var(--ink);
  font-size: clamp(20px, 2.4vw, 26px);
  font-weight: 800;
  letter-spacing: -.045em;
  line-height: 1.35;
  text-wrap: balance;
}
.impact-summary__head p { margin: 9px 0 0; color: var(--ink-soft); text-wrap: pretty; }
.impact-summary__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 8px;
}
.impact-summary__column { padding: 16px 18px; display: grid; align-content: start; gap: 10px; }
.impact-summary__column--loss { border-inline-end: 1px solid var(--border); }
.impact-summary__column--keep { background: var(--paper-muted); }
.impact-summary__column h2 { margin: 0; font-size: 12px; font-weight: 700; letter-spacing: .05em; }
.impact-summary__column--loss h2 { color: var(--danger); }
.impact-summary__column--keep h2 { color: var(--brand); }
.impact-summary__column ul { margin: 0; padding-inline-start: 18px; display: grid; gap: 7px; color: var(--ink-soft); font-size: 13px; }
.impact-summary__rebuild {
  padding: 14px 16px;
  display: grid;
  gap: 6px;
  border: 1px solid var(--danger);
  border-radius: 8px;
  background: var(--danger-wash);
  color: var(--danger);
  font-size: 13px;
}
.impact-summary__rebuild p { margin: 0; }
.impact-summary__actions {
  padding-block-start: 16px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  border-block-start: 1px solid var(--border);
}
.impact-summary__actions form { margin: 0; }
/* The reason sits above the two buttons, not beside them: a field inside the
   action row stretches it and leaves the cancel button floating at its middle. */
.impact-summary__reason { padding-block-start: 16px; max-width: 46ch; }
.impact-summary__alternative { margin: 0; margin-inline-start: auto; color: var(--muted); font-size: 13px; }

.coverage-verdict { display: grid; gap: 10px; }
.coverage-verdict h2 {
  max-width: 30ch;
  margin: 0;
  color: var(--ink);
  font-size: clamp(20px, 2.4vw, 26px);
  font-weight: 800;
  letter-spacing: -.045em;
  line-height: 1.3;
  text-wrap: balance;
}
.coverage-verdict p { max-width: 60ch; margin: 0; color: var(--ink-soft); font-size: 15px; line-height: 1.85; text-wrap: pretty; }
.coverage-verdict strong { color: var(--ink); font-weight: 700; }

.segment-list { display: grid; }
.segment-row {
  padding: 13px 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: 14px;
  border-block-end: 1px solid var(--border);
}
.segment-row h3 { margin: 0; font-size: 16px; font-weight: 700; line-height: 1.5; }
.segment-row p { max-width: 56ch; margin: 5px 0 0; color: var(--ink-soft); font-size: 13px; text-wrap: pretty; }
.segment-row__minutes { color: var(--muted); font-size: 13px; white-space: nowrap; padding-block-start: 4px; }

.script-summary {
  margin-block: 18px;
  padding: 11px 16px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 24px;
  border-block-start: 1px solid var(--ink);
  background: var(--paper-muted);
  color: var(--ink-soft);
  font-size: 13px;
}
.script-summary .status-label { margin-inline-start: auto; }

.reading-column { width: min(68ch, 100%); }
.reading-column__title {
  margin: 26px 0 0;
  color: var(--ink);
  font-size: clamp(20px, 2.4vw, 26px);
  font-weight: 800;
  letter-spacing: -.03em;
  line-height: 1.4;
  text-wrap: balance;
}
.transcript-section { margin-block-start: 30px; }
.transcript-list { display: grid; gap: 0; }
.transcript-turn {
  padding-block-end: 16px;
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr);
  align-items: baseline;
  gap: 6px 16px;
}
.transcript-turn__speaker { color: var(--muted); font-size: 12px; font-weight: 700; }
.transcript-turn__text { margin: 0; color: var(--ink); font-size: 15px; line-height: 1.9; text-wrap: pretty; }
.transcript-turn__aside { grid-column: 2; margin: 0; color: var(--muted); font-size: 12px; overflow-wrap: anywhere; }
.transcript-turn__grounding {
  grid-column: 2;
  margin: 0;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.5;
}
.evidence-drawer { grid-column: 2; }
.evidence-claim-groups { display: grid; gap: 10px; }
.evidence-claim-group { margin-block-start: 10px; }
.evidence-drawer .evidence-claim-group:first-child { margin-block-start: 4px; }
.evidence-claim-group__title {
  margin: 0;
  color: var(--ink-soft);
  font-size: 13px;
  font-weight: 700;
  line-height: 1.7;
  text-wrap: pretty;
}
.evidence-claim-group__title--unavailable { color: var(--muted); font-weight: 400; }
.evidence-claim-group__status {
  margin: 2px 0 0;
  color: var(--muted);
  font-size: 11px;
}
.evidence-drawer > summary {
  width: fit-content;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  color: var(--brand);
  cursor: pointer;
  font-size: 12px;
  font-weight: 700;
}
.evidence-card {
  margin: 8px 0 0;
  padding-inline-start: 16px;
  border-inline-start: 2px solid var(--border-strong);
  color: var(--ink-soft);
  font-size: 14px;
  line-height: 1.85;
  text-wrap: pretty;
}
.evidence-card__kind {
  display: block;
  margin-block-start: 6px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
}
.evidence-card__file {
  margin: 6px 0 0;
  font-size: 12px;
}
.evidence-card__file a {
  color: var(--brand);
  text-decoration: none;
  font-weight: 700;
}
.evidence-card__file a:hover { text-decoration: underline; }
.evidence-context {
  margin-block-start: 8px;
  padding: 10px 12px;
  border-radius: 6px;
  background: var(--paper-muted);
}
.evidence-context__panel { display: grid; gap: 8px; }
.evidence-context__text {
  margin: 0;
  color: var(--ink-soft);
  font-size: 13px;
  line-height: 1.85;
  text-wrap: pretty;
  white-space: pre-wrap;
}
.evidence-context__text--current mark {
  background: color-mix(in srgb, var(--brand) 22%, transparent);
  color: inherit;
  padding: 0 0.1em;
}
.evidence-context__miss {
  margin: 0;
  color: var(--muted);
  font-size: 12px;
}
.evidence-context__neighbor > summary {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  color: var(--muted);
  cursor: pointer;
  font-size: 12px;
  font-weight: 700;
}
.evidence-card cite { display: block; margin-block-start: 8px; color: var(--muted); font-size: 13px; font-style: normal; }
.evidence-card .operator-only { color: var(--muted-light); font-size: 11px; }
div.evidence-card { display: grid; gap: 8px; font-size: 12px; }
div.evidence-card ul { margin: 0; padding-inline-start: 18px; }

.evidence-judgement {
  margin-block-start: 8px;
  display: grid;
  gap: 8px;
}
.evidence-judgement__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
}
.evidence-judgement__btn {
  min-height: 44px;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--brand);
  cursor: pointer;
  font: inherit;
  font-size: 12px;
  font-weight: 400;
}
.evidence-judgement__btn.is-selected { color: var(--ink); font-weight: 700; }
.evidence-judgement__btn--clear { color: var(--muted); }
.evidence-judgement__reason {
  display: grid;
  gap: 6px;
  margin: 0;
  padding: 8px 0 0;
  border: 0;
}
.evidence-judgement__reason-label {
  margin: 0;
  color: var(--muted);
  font-size: 12px;
}
.evidence-judgement__option {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  color: var(--ink-soft);
  font-size: 12px;
  line-height: 1.6;
}
.evidence-judgement__note {
  display: grid;
  gap: 4px;
  color: var(--muted);
  font-size: 12px;
}
.evidence-judgement__note textarea {
  width: 100%;
  min-height: 48px;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  resize: vertical;
}

.omitted-claims { display: grid; gap: 16px; }
.omitted-claim__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 14px;
  margin-block-end: 6px;
}
.omitted-claim__reason { margin: 0 0 6px; color: var(--ink-soft); font-size: 14px; text-wrap: pretty; }
.omitted-claim__head .omitted-claim__reason { margin: 0; flex: 1 1 18ch; }
/* The native marker stays suppressed, but only because this draws its own: a chevron
   that turns when the list opens. Suppressing both left `cursor: pointer` as the sole
   sign these headings were interactive, which no keyboard or touch reader ever sees. */
.plan-list-details > summary {
  min-height: 44px;
  cursor: pointer;
  list-style: none;
}
.plan-list-details > summary::-webkit-details-marker { display: none; }
.plan-list-details > summary.section-heading { align-items: center; margin-block-end: 12px; }
.plan-list-details[open] > summary.section-heading { margin-block-end: 12px; }
/* Two classes plus the type, because `.section-heading > span` would otherwise win
   and paint this the muted 11px of a count. */
.plan-list-details > summary .plan-list-details__marker {
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  color: var(--ink-soft);
  transform: rotate(90deg);
}
.plan-list-details > summary .plan-list-details__marker svg { width: 11px; height: 11px; }
.plan-list-details[open] > summary .plan-list-details__marker { transform: rotate(-90deg); }
.plan-list-details > summary:hover .plan-list-details__marker,
.plan-list-details > summary:focus-visible .plan-list-details__marker { border-color: var(--ink); color: var(--ink); }

.quality-summary { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.quality-row h3 { margin: 0; font-size: 14px; }
.quality-row p { margin: 7px 0 0; color: var(--muted); font-size: 12px; }

.listen-head { display: grid; gap: 10px; max-width: 34ch; margin-block-end: 18px; }
.listen-head h2 {
  margin: 0;
  color: var(--ink);
  font-size: clamp(20px, 2.4vw, 26px);
  font-weight: 800;
  letter-spacing: -.045em;
  line-height: 1.28;
  text-wrap: balance;
}
.listen-head p { margin: 0; color: var(--muted); font-size: 13px; }

.audio-player {
  padding: 16px 20px;
  display: grid;
  gap: 14px;
}
.audio-player audio { width: 100%; accent-color: var(--brand); }
.audio-player__actions {
  padding-block-start: 12px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  border-block-start: 1px solid var(--border);
}
.audio-player__actions svg { width: 14px; height: 14px; }
.chapter-list ol { margin: 0; padding: 0; list-style: none; }
.chapter-list li { border-block-end: 1px solid var(--border); }
/* The whole row is the control, so the tap target is the row height, not the words. */
.chapter-list button,
.chapter-list__title {
  width: 100%;
  min-height: 44px;
  padding: 8px 0;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  border: 0;
  background: none;
  color: var(--ink);
  font-size: 14px;
  font-weight: 700;
  text-align: start;
}
.chapter-list button { cursor: pointer; }
.chapter-list button:hover span:first-child { color: var(--brand); text-decoration: underline; text-underline-offset: 4px; }
.chapter-list__time { color: var(--muted); font-size: 13px; white-space: nowrap; }
.chapter-list__note { margin: 11px 0 0; color: var(--muted); font-size: 12px; }

.chunk-row audio { width: 100%; grid-column: 1 / -1; }

.data-panel { padding: 17px; }
.data-panel h2,
.data-panel h3 { margin: 0; font-size: 15px; }
.data-panel pre { max-width: 100%; overflow: auto; padding: 12px; border-radius: 6px; background: var(--ink); color: var(--paper); direction: ltr; text-align: left; }
.code-value,
code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  /* Data is a step, not a fraction of whatever it sits in: `.92em` inside an
     11px caption resolved to 10.12px, on exactly the Latin identifiers that
     have to be read one character at a time. */
  font-size: 12px;
}
/* Keep technical LTR values intact inside the RTL document (ids, ISO timestamps, states). */
.summary-row .code-value,
.code-value[dir="ltr"] {
  display: inline-block;
  max-width: 100%;
  direction: ltr;
  unicode-bidi: isolate;
  text-align: start;
  overflow-wrap: anywhere;
}

.check-list { display: grid; gap: 7px; }
.check-row { padding: 14px 15px; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px 16px; border: 1px solid var(--border); border-radius: 9px; background: var(--paper-raised); }
.check-row p { grid-column: 1 / -1; margin: 0; color: var(--muted); font-size: 12px; }

.auth-page { display: grid; place-items: center; padding: 28px 16px; }
.auth-shell { width: min(980px, 100%); }
.auth-layout {
  min-height: 600px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(360px, .82fr);
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--paper);
  box-shadow: var(--shadow);
}
.auth-story {
  padding: 54px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 36px;
  background: var(--brand);
  color: var(--paper);
}
.auth-story:has(.auth-story__note) { justify-content: space-between; }
.auth-story__lead {
  display: grid;
  justify-items: start;
  gap: 18px;
}
.auth-story .brand { width: fit-content; }
.auth-story h1 {
  max-width: 12em;
  margin: 0;
  font-size: clamp(24px, 3vw, 35px);
  line-height: 1.45;
  letter-spacing: -.04em;
}
.auth-story__lead > p {
  max-width: 38ch;
  margin: 0;
  color: var(--brand-soft);
  font-size: clamp(14px, 1.5vw, 16px);
  line-height: 1.7;
}
.auth-story__note {
  padding-block-start: 18px;
  border-block-start: 1px solid var(--brand-line);
  font-size: 12px;
}
.auth-story__note p { margin: 6px 0 0; color: var(--brand-soft); }
.auth-card { padding: 54px 42px; display: flex; flex-direction: column; justify-content: center; }
.auth-card h2 { margin: 0; font-size: 16px; letter-spacing: -.02em; line-height: 1.5; }
.auth-card .lede { margin-block: 8px 22px; }
.auth-card .form-sheet { padding: 0; border: 0; box-shadow: none; background: transparent; }
.auth-card__footer { margin-block-start: 20px; color: var(--muted); font-size: 11px; }
.otp-input { letter-spacing: .55em; text-align: center; font: 700 17px/1.9 ui-monospace, monospace; }
.dev-note { margin-block-start: 18px; color: var(--muted); font-size: 11px; }
.dev-note summary { cursor: pointer; }

@media (max-width: 980px) {
  .app-header__inner { flex-wrap: wrap; padding-block: 10px; }
  .app-nav { order: 3; width: 100%; padding-block-start: 7px; border-block-start: 1px solid var(--brand-line); }
  .auth-layout { grid-template-columns: 1fr; }
  .auth-story { min-height: 310px; padding: 38px; gap: 28px; }
  .auth-story__lead { gap: 14px; }
  .auth-card { padding: 38px; }
}

@media (max-width: 760px) {
  .shell { width: min(100% - 18px, 1180px); }
  .obs-waterfall__row { grid-template-columns: 1fr; }
  .page { margin-block-start: 9px; border-radius: 9px; }
  .page-content { padding: 24px 18px 32px; }
  .app-header { position: static; }
  .app-header__inner { gap: 12px; }
  .brand small { display: none; }
  .app-header__tools { width: 100%; margin-inline-start: 0; justify-content: space-between; }
  .app-nav a:not(.operator-only) { display: none; }
  html:not([data-mode="operator"]) .app-nav { display: none; }
  .mobile-nav { display: grid; }
  body:has(.mobile-nav) { padding-block-end: 62px; }
  .workflow-rail { padding: 10px 16px; gap: 6px; }
  /* The rail is the only in-project navigation under 760px — the header nav is
     hidden here too — so hiding it left a phone with no read-only way back to
     /sources or /brief. It scrolls sideways instead, connectors dropped. */
  .workflow-rail__steps {
    flex-wrap: nowrap;
    gap: 2px;
    overflow-x: auto;
    scrollbar-width: none;
    margin-inline: -16px;
    padding-inline: 16px;
  }
  .workflow-rail__steps::-webkit-scrollbar { display: none; }
  .workflow-step { flex: 0 0 auto; }
  .workflow-step + .workflow-step::before { width: 10px; }
  /* Padding tightens to fit more of the row on screen; the 44px floor does not
     move — the row scrolls, so there is nothing to gain by shrinking a target. */
  .workflow-step a { padding-inline: 6px; }
  .workflow-rail__compact {
    margin: 0;
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
  }
  .workflow-rail__compact strong { color: var(--ink); font-weight: 700; }
  .workflow-rail__compact span { margin-inline-start: auto; color: var(--muted-light); font-weight: 400; }
  .workflow-rail__progress { display: flex; gap: 4px; }
  .workflow-rail__progress span { height: 4px; flex: 1; background: var(--paper-strong); }
  .workflow-rail__progress .is-complete { background: var(--brand); }
  .workflow-rail__progress .is-current { background: var(--ink); }
  .page-heading { display: grid; gap: 16px; }
  .field-grid,
  .impact-summary__grid,
  .quality-summary { grid-template-columns: 1fr; }
  .impact-summary__column--loss { border-inline-end: 0; border-block-end: 1px solid var(--border); }
  .impact-summary__alternative { margin-inline-start: 0; }
  .project-row { grid-template-columns: 1fr; gap: 10px; }
  .project-row .button { width: 100%; }
  .attention-panel,
  .sticky-confirmation,
  .error-recovery__outcome { grid-template-columns: 1fr; }
  .error-recovery__outcome,
  .error-recovery__actions { padding-inline-start: 0; }
  .summary-row { grid-template-columns: 1fr; gap: 2px; }
  .source-row { grid-template-columns: auto minmax(0, 1fr); }
  .source-row > :last-child { grid-column: 2; }
  .stage-row { grid-template-columns: 24px 1fr; }
  .stage-row > :last-child { grid-column: 2; }
  .segment-row { grid-template-columns: 32px 1fr; }
  .segment-row > :last-child { grid-column: 2; }
  .transcript-turn { grid-template-columns: 1fr; gap: 4px; }
  .transcript-turn__aside,
  .evidence-drawer { grid-column: 1; }
  .auth-story { min-height: 240px; padding: 28px 24px; gap: 22px; }
  .auth-story__lead { gap: 12px; }
  .auth-card { padding: 30px 24px; }
  .theme-switcher__panel { inset-inline-end: auto; inset-inline-start: 0; }
}

@media (max-width: 470px) {
  /* At the declared 320px floor the header controls no longer fit on one line —
     more so since they carry the 44px touch floor. Let the shell wrap instead of
     pushing the whole header off the viewport, and keep the theme menu inside it. */
  .app-header__inner { flex-wrap: wrap; gap: 9px 12px; }
  .app-header__tools { gap: 7px; }
  /* Anchored to a 52px control near the edge, a 184px menu cannot fit at 320px.
     Drop the switcher's positioning context so the menu spans the header instead. */
  .theme-switcher { position: static; }
  .theme-switcher__panel { inset-inline: 12px; width: auto; }
  .app-nav { gap: 12px; overflow-x: auto; }
  .segmented-control button { padding-inline: 9px; }
  .theme-switcher > summary { padding-inline: 9px; }
  .header-link { display: none; }
  /* Primary, secondary, and danger buttons stretch for an easy mobile tap
     target; --quiet stays sized-to-content because it carries no fill or
     border, and a full-width transparent hit area with centred text reads as
     a dead zone rather than a control. --small is excluded on the same
     principle: a variant that opts into a compact size should not be
     silently overridden back to full width by a later, more general rule. */
  .form-actions > .button:not(.button--quiet):not(.button--small),
  .form-actions > form,
  .form-actions > form .button:not(.button--quiet):not(.button--small) { width: 100%; }
  .button:not(.button--quiet):not(.button--small) { width: 100%; }
  .choice-group { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .choice-group label,
  .choice-group span { width: 100%; }
  .choice-group span { justify-content: center; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto !important; }
  /* Scoped to the one looping animation in the system (status-pulse), not a
     blanket kill of every transition. The functional 120-180ms hover/focus
     transitions stay: they are brief, non-looping, and not the kind of motion
     prefers-reduced-motion targets. Freezing the mark at opacity 1 rather than
     removing the fill keeps the running state legible without motion --- it
     was already carried by fill + colour + the status word, never by the
     pulse alone, but a frozen, undimmed mark keeps the strongest of the three
     signals intact. */
  .status-label--running span.status-label__mark,
  .timeline__mark--running,
  .stage-row.is-running .stage-row__mark { animation: none !important; opacity: 1; }
}

.table-wrap { max-width: 100%; overflow-x: auto; }
.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}
.data-table th,
.data-table td {
  padding: 10px 12px;
  border-block-end: 1px solid var(--border);
  text-align: start;
  vertical-align: top;
}
.data-table th {
  color: var(--ink-soft);
  font-size: 12px;
  font-weight: 700;
}
.data-table tbody tr:hover { background: var(--paper-muted); }
.data-table td small { display: block; color: var(--muted); font-size: 12px; }
.promoted-mark {
  margin-inline-start: 6px;
  color: var(--brand);
  font-size: 12px;
  font-weight: 700;
}
.source-trace { margin: 0 0 6px; color: var(--muted); font-size: 13px; }
.source-trace span { display: block; }
.review-flags { margin: 12px 0 0; padding-inline-start: 1.2em; }
.overlay-forms { display: grid; gap: 18px; }
.overlay-forms .form-sheet h3 { margin: 0; font-size: 15px; }

.concept-graph__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  list-style: none;
  margin: 10px 0 12px;
  padding: 0;
  font-size: 13px;
  color: var(--ink-soft);
}
.concept-graph__legend li { display: flex; align-items: center; gap: 6px; }
.concept-graph__swatch {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 2px solid transparent;
}
.concept-graph__swatch--covered { background: var(--success); }
.concept-graph__swatch--omitted { background: var(--muted); }
.concept-graph__swatch--not-covered { background: var(--danger); }
.concept-graph__swatch--closure { background: none; border-color: var(--info); border-style: dashed; }
.concept-graph__swatch--tier1 { background: var(--brand); }
.concept-graph__swatch--tier2 { background: var(--brand-soft); }
.concept-graph__swatch--tier3 { background: var(--border-strong); }
.concept-graph {
  width: 100%;
  height: 420px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--paper-raised);
}
.concept-graph__empty { padding: 20px; color: var(--muted); text-align: center; }
.concept-graph__hint { margin: 8px 0 0; color: var(--muted); font-size: 12px; }
tr.is-highlighted { background: var(--accent-wash); transition: background 0.2s ease; }

/* Observability. Moved out of an inline <style> in the template, where it called
   --line and --surface — tokens this project never defined, so every fallback
   was a fixed grey-on-white that ignored all four themes.
   It then kept four more ways out of the system: its own 720px breakpoint, its
   own table, its own metric tile, and opacity where a token exists. All four had
   a system equivalent already in this file, so the island is now a modifier set
   on shared vocabulary: .card for the tiles, .data-table inside .table-wrap for
   the tables, the system's own breakpoints, and --muted for muted text. */
.obs-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 11px; }
.obs-metric strong { display: block; font-size: 16px; font-weight: 700; direction: ltr; text-align: right; }
.obs-waterfall { display: grid; gap: 9px; }
.obs-waterfall__row {
  display: grid;
  grid-template-columns: minmax(176px, 1fr) minmax(256px, 3fr) 96px;
  gap: 11px;
  align-items: center;
}
.obs-waterfall__track {
  position: relative;
  height: 18px;
  border-radius: 999px;
  background: color-mix(in srgb, currentColor 8%, transparent);
  overflow: hidden;
  direction: ltr;
}
.obs-waterfall__bar { position: absolute; inset-block: 0; border-radius: 999px; background: currentColor; min-width: 2px; }
.obs-tree,
.obs-tree ul { list-style: none; margin: 7px 0; padding-inline-start: 18px; }
.obs-tree li { border-inline-start: 1px solid var(--border); padding-inline-start: 11px; }
.obs-tree__node { display: flex; flex-wrap: wrap; gap: 9px; align-items: center; padding: 7px 9px; border-radius: 6px; }
.obs-tree__node--error,
.obs-tree__node--failed,
.obs-tree__node--rejected { background: var(--danger-wash); }
.obs-tree__node--running { background: var(--accent-wash); }
.obs-tree__kind { padding: 1px 7px; border: 1px solid var(--border-strong); border-radius: 999px; color: var(--muted); font-size: 11px; font-weight: 600; }
.obs-tree__truncated { margin: 4px 0 8px; color: var(--muted); font-size: 12px; }
.obs-pager { margin-block: 16px; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.obs-pager a {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  padding: 0 11px;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  text-decoration: none;
}
.obs-code { direction: ltr; text-align: left; overflow-wrap: anywhere; }

