/* Sourceglass — one design system for the workbench and the account pages.
   Density lives in the chrome; prose keeps a comfortable measure (~65ch).
   Every page links THIS file: there is no second stylesheet and no inline <style>
   anywhere (the app's CSP is `style-src 'self'`, so an inline block is simply dropped
   and the page renders unstyled — that is how the usage dashboard shipped in Times New
   Roman). One palette, one spacing rhythm, one radius set, one type scale. */

:root {
  color-scheme: dark;

  /* ---- surfaces (dark -> light) ------------------------------------------------- */
  --bg: #0e1116;
  --sunken: #0b0e13; /* inputs, code, the deepest wells */
  --sunken-2: #10151d; /* nested strips inside a panel */
  --panel: #141922; /* the default raised surface */
  --panel-2: #1a202b; /* chrome bars and headers */
  --panel-sub: #121821; /* a secondary/grouped row */
  --panel-hover: #171e29;
  --panel-sel: #1b2433; /* the selected row */

  --line: #242c38;
  --line-2: #2f3947;

  --ink: #d7dee8;
  --ink-2: #aab6c5;
  --ink-3: #8b97a7;

  --accent: #6ea8fe;
  --accent-strong: #4f8cff;
  --accent-ink: #08111f;
  --accent-wash: #16233a;
  --focus: #9cc2ff;

  --ok: #7ee08a;
  --ok-bg: #0f1c13;
  --ok-line: #1f4d2b;
  --warn: #e3c06a;
  --warn-bg: #1d1a11;
  --warn-line: #5c4a1f;
  --bad: #ff8b84;
  --bad-bg: #1d1111;
  --bad-line: #5c1f1f;
  --spot: #e3b341;

  /* The saturated fills of the three claim pills, the host-match row and a passage
     highlight. These were literal hexes scattered through the file; a literal colour is a
     colour that cannot be themed, so every one of them is a token now. */
  --ok-fill: #0f2a17;
  --warn-fill: #2a2410;
  --bad-fill: #2a1010;
  --row-highlight: #1f2733;
  --mark-bg: #2a2410;
  --mark-ink: #f0d98a;
  --sunken-hover: #0c1018;
  /* The edge shade on a horizontally scrollable table. Dark over a dark surface; in light it
     must be a *lighter* shade of the same idea or the table edge turns into a bruise. */
  --scroll-shade: rgba(0, 0, 0, 0.45);

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

  /* ---- type scale --------------------------------------------------------------- */
  --fs-micro: 10.5px; /* eyebrow labels, status pills */
  --fs-mono: 11.5px; /* numeric/telemetry */
  --fs-chrome: 12px; /* bars and buttons */
  --fs-ui: 12.5px; /* the default UI size */
  --fs-body: 13px; /* account-page body copy */
  --fs-prose: 15px; /* answers and documents */
  --fs-h3: 13px;
  --fs-h2: 15px;
  --fs-h1: 21px;
  --measure: 65ch;

  /* ---- spacing rhythm (4px base) ------------------------------------------------ */
  --s0: 4px;
  --s1: 6px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 24px;
  --s6: 32px;
  --s7: 48px;

  /* ---- radii: three steps, nothing else ----------------------------------------- */
  --r-sm: 3px; /* inline pills, chips, status marks */
  --r-md: 5px; /* buttons, inputs, rows */
  --r-lg: 8px; /* cards, popovers, panels */

  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-2: 0 12px 28px rgba(0, 0, 0, 0.5);

  /* The account/document pages share one column width so every page lines up. */
  --page-measure: 720px;
  --page-measure-wide: 1040px;
}

/* ---- the light theme -------------------------------------------------------------
   `/theme.js` resolves the user's local preference (light | dark | system) to a concrete
   'light' or 'dark' on <html data-theme>, BEFORE the first paint. Only the resolved value is
   read here, so the palette is written exactly once — a second copy under a `system` media
   query would be a second palette to keep in sync, and it would drift.

   This is a real inversion of the ramp, not a filter. In dark, `--panel` is LIGHTER than
   `--bg` (raised chrome on a black field); in light the same relationship holds the same way
   (white cards on a soft grey field), so every existing rule that leans on "panel sits above
   bg" keeps working without being touched.

   Every ink/surface pair below was chosen against WCAG, not by eye: `--ink` is ~15:1 on
   `--bg`, `--ink-2` ~7.7:1 and `--ink-3` ~5.3:1 on white, and `--accent` ~5.3:1 — because the
   dense workbench spends most of its pixels on 11-12.5px secondary text, which is exactly
   where a lazily-inverted theme becomes unreadable. */
:root[data-theme='light'] {
  color-scheme: light;

  --bg: #eef1f5;
  --sunken: #ffffff; /* an input is a white well in light, not a darker one */
  --sunken-2: #f4f6f9;
  --panel: #ffffff;
  --panel-2: #f7f9fc;
  --panel-sub: #f3f5f9;
  --panel-hover: #eaeff7;
  --panel-sel: #e1ebfb;

  --line: #d7dde6;
  --line-2: #bac4d2;

  --ink: #171d28;
  --ink-2: #434e60;
  --ink-3: #5c687d;

  --accent: #1458c8;
  --accent-strong: #0f49a8;
  --accent-ink: #ffffff;
  --accent-wash: #e3edfd;
  --focus: #0f49a8;

  --ok: #11662a;
  --ok-bg: #e9f6ec;
  --ok-line: #a5d8b3;
  --warn: #74550d;
  --warn-bg: #fbf3dd;
  --warn-line: #ddc27c;
  --bad: #a81d15;
  --bad-bg: #fdeceb;
  --bad-line: #f0aea8;
  --spot: #7a5600;

  --ok-fill: #ddf1e3;
  --warn-fill: #f8ecce;
  --bad-fill: #fbdedb;
  --row-highlight: #fdf4de;
  --mark-bg: #fdeebb;
  --mark-ink: #4a3600;
  --sunken-hover: #f2f5fa;
  --scroll-shade: rgba(23, 29, 40, 0.18);

  /* Shadows are how a light UI says "raised". The dark theme's near-black drops read as
     grime on a white field, so they are re-tinted rather than reused. */
  --shadow-1: 0 1px 2px rgba(23, 29, 40, 0.08);
  --shadow-2: 0 12px 28px rgba(23, 29, 40, 0.16);
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--fs-ui);
  line-height: 1.45;
  overflow: hidden;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--accent-strong);
  color: var(--accent-ink);
  padding: 10px 14px;
  border-radius: 0 0 8px 0;
  font-weight: 600;
}
.skip-link:focus {
  left: 0;
}

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

/* ---- app shell: three fixed regions, never overlapping ---- */

.app {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr) 384px;
  grid-template-rows: auto minmax(0, 1fr);
  height: 100dvh;
  overflow: hidden;
}

.topbar {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: 0 var(--s3);
  min-height: 42px;
  background: var(--panel-2);
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-chrome);
  flex-wrap: wrap;
}
.brand {
  color: var(--ink);
  font-weight: 650;
  letter-spacing: 0.2px;
  font-size: 13px;
  /* The scope tabs were jammed against the wordmark; a rule separates identity from
     navigation without adding another border colour. */
  padding-right: var(--s3);
  margin-right: var(--s0);
  border-right: 1px solid var(--line);
  line-height: 24px;
  white-space: nowrap;
}
.topbar-grow {
  flex: 1;
  min-width: 0;
}
/* The three state chips are one group, so they read as a set rather than three loose
   controls drifting between the tabs and the About menu. */
.topbar-tools {
  display: inline-flex;
  align-items: center;
  gap: var(--s0);
}

/* ---- settings/about popover (privacy link + mode note live here, not the footer) ---- */

.about {
  position: relative;
  display: inline-flex;
}
.about-toggle[aria-expanded="true"] {
  border-color: var(--accent);
  color: var(--ink);
}
.about-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 40;
  min-width: 268px;
  max-width: min(340px, calc(100vw - 16px));
  padding: var(--s2) 0;
  background: var(--panel-2);
  border: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-2);
  display: flex;
  flex-direction: column;
  gap: 0;
}
.about-menu[hidden] {
  display: none;
}
/* Three labelled groups with rules between them, instead of eight heterogeneous items
   in one undivided stack. */
.about-title {
  margin: 0;
  padding: var(--s1) var(--s3) var(--s0);
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.about-title + .about-title,
.about-group + .about-group {
  margin-top: var(--s1);
  border-top: 1px solid var(--line);
  padding-top: var(--s2);
}
/* `[hidden]` must win over this `display`. The account group swaps "Sign in with a key" for
   "Sign out" by toggling the hidden attribute, and an author `display` silently defeats the
   UA rule — so a signed-in user was shown BOTH, which reads as a broken session. */
.about-link[hidden],
.about-account[hidden] {
  display: none;
}
.about-link,
.about-account {
  display: block;
  padding: var(--s1) var(--s3);
  color: var(--ink-2);
  font-size: var(--fs-ui);
  text-decoration: none;
  border-left: 2px solid transparent;
}
.about-link:hover,
.about-account:hover {
  background: var(--panel);
  color: var(--ink);
  border-left-color: var(--accent);
  text-decoration: none;
}
/* Account affordances in the About menu. Styled as links, but they are <button>s so the menu
   keeps exactly one anchor (the privacy link). */
.about-account {
  appearance: none;
  width: 100%;
  background: none;
  font: inherit;
  font-size: var(--fs-ui);
  text-align: left;
  cursor: pointer;
  border-top: 0;
  border-right: 0;
  border-bottom: 0;
}

.mode-toggle {
  display: inline-flex;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--sunken);
}
.mode-toggle button {
  appearance: none;
  border: 0;
  border-right: 1px solid var(--line);
  background: transparent;
  color: var(--ink-2);
  font: inherit;
  font-weight: 600;
  padding: var(--s1) var(--s3);
  min-height: 28px;
  cursor: pointer;
  white-space: nowrap;
}
.mode-toggle button:last-child {
  border-right: 0;
}
.mode-toggle button:hover {
  color: var(--ink);
  background: var(--panel);
}
.mode-toggle button[aria-selected="true"] {
  background: var(--accent-strong);
  color: var(--accent-ink);
}
.mode-toggle button[aria-selected="true"]:hover {
  background: var(--accent);
  color: var(--accent-ink);
}
.mode-toggle button:focus-visible {
  outline-offset: -3px;
}

/* ---- cost badges on the scope tabs + the Deep toggle ----
   Users could not see what a click costs. The badge is a small numeral tucked against the
   label, not a separate pill: the tab row is the densest strip in the product and a bordered
   pill on each of five tabs would double the row's width at 360. The number is written by
   app.js from the tariff the SERVER serves out of meter.mjs — never typed in this file or in
   the markup. */
.mode-toggle button,
.deep-toggle {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
}
.tab-cost {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  color: var(--ink-3);
  opacity: 0.85;
}
/* Empty until the tariff arrives: no badge, and no stray gap where one will be. */
.tab-cost:empty {
  display: none;
}
.mode-toggle button:hover .tab-cost {
  color: var(--ink-2);
}
/* On the selected tab the badge sits on the accent fill, so it needs the accent's ink. */
.mode-toggle button[aria-selected="true"] .tab-cost,
.deep-toggle[aria-pressed="true"] .tab-cost {
  color: inherit;
  opacity: 0.75;
}

/* The chip: a small, low-emphasis toggle. One size everywhere it appears. */
.chip-btn {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--ink-2);
  font: inherit;
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: var(--s0) var(--s2);
  min-height: 28px;
  cursor: pointer;
  white-space: nowrap;
}
.chip-btn:hover {
  color: var(--ink);
  border-color: var(--line-2);
  background: var(--panel);
}
.chip-btn[aria-pressed="true"] {
  background: var(--accent-strong);
  border-color: var(--accent-strong);
  color: var(--accent-ink);
}
.chip-btn[aria-pressed="true"]:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}
.evidence-toggle,
.side-back {
  display: none;
}

/* ---- left rail ---- */

.rail {
  grid-column: 1;
  grid-row: 2;
  background: var(--panel);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.rail h2 {
  margin: 0;
  padding: var(--s2) var(--s3);
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  border-bottom: 1px solid var(--line);
}
.rail ul {
  list-style: none;
  margin: 0;
  padding: 3px 0;
  overflow: auto;
  flex: 1;
}
.rail li {
  display: flex;
  gap: 6px;
  align-items: baseline;
  padding: 6px 10px;
  font-size: var(--fs-ui);
  color: var(--ink-2);
  border-left: 2px solid transparent;
  overflow-wrap: anywhere;
}
.rail li.act {
  background: var(--panel-sel);
  border-left-color: var(--accent);
  color: var(--ink);
}
.rail li .n {
  margin-left: auto;
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--fs-mono);
}
.rail-foot {
  border-top: 1px solid var(--line);
  padding: var(--s1) var(--s3);
  color: var(--ink-3);
  font-size: var(--fs-chrome);
}
/* An empty thread rail should say what goes in it. */
.rail ul:empty::after {
  content: "No threads yet.";
  display: block;
  padding: var(--s3);
  color: var(--ink-3);
  font-size: var(--fs-chrome);
}
/* The two rail actions were a dashed lowercase button and a solid sentence-case one.
   They are one control type now; "new thread" is the primary of the pair. */
.rail-actions {
  display: flex;
  flex-direction: column;
  gap: var(--s0);
  padding: var(--s2) var(--s2) var(--s2);
  border-bottom: 1px solid var(--line);
}
.new-thread,
.export-thread {
  appearance: none;
  display: flex;
  align-items: center;
  margin: 0;
  padding: var(--s1) var(--s2);
  min-height: 28px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--sunken);
  color: var(--ink-2);
  font: inherit;
  font-size: var(--fs-chrome);
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}
.new-thread:hover,
.export-thread:hover {
  color: var(--ink);
  border-color: var(--accent);
  background: var(--panel-sub);
}
.export-thread {
  font-weight: 500;
  color: var(--ink-3);
}
/* The rail row is a button so the whole row is one keyboard-reachable target. */
.rail li {
  display: block;
  padding: 0;
  border-left: 0;
}
.thread-row {
  display: flex;
  gap: 6px;
  align-items: baseline;
  width: 100%;
  text-align: left;
  padding: 6px 10px;
  background: transparent;
  border: 0;
  border-left: 2px solid transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
  overflow-wrap: anywhere;
}
.rail li.act .thread-row {
  background: var(--panel-sel);
  border-left-color: var(--accent);
  color: var(--ink);
}
.thread-row:hover {
  color: var(--ink);
}
.thread-row .n {
  margin-left: auto;
}

/* ---- centre turn buffer ---- */

.buf {
  grid-column: 2;
  grid-row: 2;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  background: var(--bg);
  /* A query container: the centre pane's width is set by the two fixed side panes, not
     by the viewport, so "is there room for the options on one line?" is a question about
     THIS box. At 1024 the pane is 426px and the region/language/freshness row wrapped to
     three separate lines, spending ~85px of an already short laptop viewport. */
  container-type: inline-size;
  container-name: buf;
}

@container buf (max-width: 620px) {
  .search-options {
    display: grid;
    grid-template-columns: 1.25fr 1fr 0.9fr;
    gap: var(--s1);
    align-items: end;
  }
  .search-options .opt {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 3px;
    min-width: 0;
  }
  .search-options select {
    width: 100%;
    min-width: 0;
  }
}
.scroll {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
}
.turns {
  display: flex;
  flex-direction: column;
  min-height: 100%;
}
/* Bottom-anchored: content sits at the bottom and grows upward, so a short session
   rests against the input line. Long content scrolls from the top. */
.turns > .turn:first-child {
  margin-top: auto;
}

/* ---- cold start -------------------------------------------------------------------
   Shown only while the buffer is genuinely empty. `#turns` is filled by
   `turnsEl.replaceChildren(...)` with element children and the markup has no whitespace
   inside it, so `:empty` is an exact test for "no turns yet". */
.buf-intro {
  display: none;
}
.turns:empty {
  /* An empty buffer must not keep its `min-height: 100%` or it pushes the panel away. */
  min-height: 0;
  flex: 0 0 auto;
}
.turns:empty ~ .buf-intro {
  display: flex;
  flex: 1;
  min-height: 0;
  align-items: center;
  justify-content: center;
  padding: var(--s5) var(--s4);
}
.buf-intro-in {
  max-width: 54ch;
}
.buf-intro-eyebrow {
  margin: 0 0 var(--s2);
  color: var(--accent);
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.buf-intro-title {
  margin: 0 0 var(--s2);
  color: var(--ink);
  font-size: 22px;
  font-weight: 650;
  letter-spacing: -0.01em;
  line-height: 1.25;
}
.buf-intro-lede {
  margin: 0 0 var(--s4);
  color: var(--ink-2);
  font-size: var(--fs-prose);
  line-height: 1.55;
}
.buf-intro-scopes {
  list-style: none;
  margin: 0 0 var(--s4);
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--panel);
  overflow: hidden;
}
.buf-intro-scopes li {
  display: grid;
  grid-template-columns: 5.5em minmax(0, 1fr);
  gap: var(--s3);
  align-items: baseline;
  padding: var(--s2) var(--s3);
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-ui);
}
.buf-intro-scopes li:last-child {
  border-bottom: 0;
}
.buf-intro-scopes b {
  color: var(--ink);
  font-weight: 600;
}
.buf-intro-scopes span {
  color: var(--ink-3);
}
.buf-intro-foot {
  margin: 0;
  color: var(--ink-3);
  font-size: var(--fs-chrome);
}
@media (max-width: 820px) {
  .turns:empty ~ .buf-intro {
    align-items: flex-start;
    padding: var(--s4) var(--s3) var(--s5);
    overflow-y: auto;
  }
  .buf-intro-title {
    font-size: 19px;
  }
  .buf-intro-lede {
    margin-bottom: var(--s3);
    font-size: var(--fs-body);
  }
  .buf-intro-scopes {
    margin-bottom: var(--s3);
  }
  .buf-intro-scopes li {
    grid-template-columns: 4.75em minmax(0, 1fr);
    gap: var(--s2);
    padding: var(--s1) var(--s2);
    font-size: var(--fs-chrome);
  }
}

.turn {
  border-bottom: 1px solid var(--line);
}
.turn-head {
  display: flex;
  gap: 8px;
  align-items: baseline;
  width: 100%;
  text-align: left;
  padding: 6px 12px;
  background: var(--panel);
  border: 0;
  border-bottom: 1px solid var(--line);
  color: var(--ink-2);
  font: inherit;
  font-size: var(--fs-chrome);
  cursor: pointer;
  flex-wrap: wrap;
}
.turn-head:hover {
  color: var(--ink);
}
.turn-head .scope-label {
  color: var(--ink-3);
  font-weight: 600;
  white-space: nowrap;
}
.turn-head .q {
  color: var(--ink);
  font-weight: 600;
  min-width: 0;
  overflow-wrap: anywhere;
}
.turn-head .meta {
  margin-left: auto;
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  white-space: nowrap;
}
.turn.collapsed .turn-body,
.turn.collapsed .coverage-strip,
.turn.collapsed .action-toolbar,
.turn.collapsed .action-panel {
  display: none;
}
.turn-body {
  padding: 10px 12px 10px;
  min-width: 0;
}
.turn-body[hidden] {
  display: none;
}

.verdict-chip {
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  padding: 1px 6px;
  font-size: 10.5px;
  font-family: var(--mono);
  text-transform: lowercase;
  white-space: nowrap;
}
.verdict-chip.v-answered {
  border-color: var(--ok-line);
  background: var(--ok-bg);
  color: var(--ok);
}
.verdict-chip.v-partial {
  border-color: var(--warn-line);
  background: var(--warn-bg);
  color: var(--warn);
}
.verdict-chip.v-not_answered {
  border-color: var(--bad-line);
  background: var(--bad-bg);
  color: var(--bad);
}
.turn-counts {
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  white-space: nowrap;
}
.turn-mode {
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  padding: 1px 6px;
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: 10.5px;
  white-space: nowrap;
}

.prose {
  max-width: var(--measure);
  font-size: var(--fs-prose);
  line-height: 1.55;
  color: var(--ink);
  overflow-wrap: anywhere;
}
.prose p {
  margin: 0 0 0.6em;
}
.prose p:last-child {
  margin-bottom: 0;
}
.prose code {
  font-family: var(--mono);
  font-size: 0.86em;
  background: var(--sunken);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 0 3px;
  color: var(--spot);
  overflow-wrap: anywhere;
}
.prose pre {
  background: var(--sunken);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 8px;
  overflow-x: auto;
}
.prose h1,
.prose h2,
.prose h3,
.prose h4,
.prose h5,
.prose h6 {
  margin: 0.9em 0 0.35em;
  line-height: 1.25;
  color: var(--ink);
}
.prose h1 {
  font-size: 1.35em;
}
.prose h2 {
  font-size: 1.2em;
}
.prose h3 {
  font-size: 1.08em;
}
.prose h4,
.prose h5,
.prose h6 {
  font-size: 1em;
}
.prose > h1:first-child,
.prose > h2:first-child,
.prose > h3:first-child,
.prose > p:first-child {
  margin-top: 0;
}
.prose ul,
.prose ol {
  margin: 0 0 0.6em;
  padding-left: 1.4em;
}
.prose li {
  margin: 0.15em 0;
}
.prose li > p {
  margin: 0;
}
.prose blockquote {
  margin: 0 0 0.6em;
  padding: 2px 0 2px 10px;
  border-left: 3px solid var(--line-2);
  color: var(--ink-2);
}
.prose blockquote p {
  margin: 0;
}
.prose a {
  color: var(--accent);
  text-decoration: none;
  overflow-wrap: anywhere;
}
.prose a:hover {
  text-decoration: underline;
}
/* N-3: the destination host is model-supplied context, not the label; keep it muted so it
   reads as secondary text rather than as part of the link. */
.prose a .link-host {
  color: var(--ink-3);
  font-size: 0.86em;
  overflow-wrap: anywhere;
}
.prose pre code {
  border: 0;
  background: transparent;
  padding: 0;
  color: var(--ink);
  overflow-wrap: normal;
}
.answer-label {
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 0 0 6px;
}

.cite,
.citation {
  appearance: none;
  font-family: var(--mono);
  font-size: 0.74em;
  line-height: 1.4;
  color: var(--accent);
  background: var(--sunken);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  padding: 0 4px;
  min-width: 16px;
  text-align: center;
  cursor: pointer;
  vertical-align: baseline;
}
.cite:hover,
.citation:hover {
  border-color: var(--accent);
}
.citation-inline {
  margin: 0 1px;
}
.citation-degraded {
  font-family: var(--mono);
  font-size: 0.74em;
  color: var(--ink-3);
  border: 1px dashed var(--line-2);
  border-radius: var(--r-sm);
  padding: 0 4px;
  margin: 0 1px;
}
.citation-inert {
  font-family: var(--mono);
  font-size: 0.85em;
  color: inherit;
}
.citations {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}
.citations .citation {
  padding: 3px 8px;
  font-size: 11px;
}

/* ---- deep-mode reasoning panel (collapsed, escaped, labelled not-evidence) ---- */

.reasoning-panel {
  margin: 8px 0 0;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--sunken);
  max-width: var(--measure);
}
.reasoning-summary {
  display: flex;
  gap: 8px;
  align-items: baseline;
  padding: 5px 8px;
  cursor: pointer;
  font-family: var(--mono);
  font-size: var(--fs-mono);
  color: var(--ink-3);
  list-style: none;
}
.reasoning-summary::-webkit-details-marker {
  display: none;
}
.reasoning-summary::before {
  content: "▸";
}
.reasoning-panel[open] .reasoning-summary::before {
  content: "▾";
}
.reasoning-label {
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.reasoning-elapsed {
  margin-left: auto;
  color: var(--ink-3);
}
.reasoning-text {
  margin: 0;
  padding: 8px;
  border-top: 1px solid var(--line);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  color: var(--ink-2);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  max-height: 320px;
  overflow-y: auto;
}

/* ---- coverage strip ----------------------------------------------------------------
   This read as one unpunctuated run-on of nine numbers. It is now a label followed by
   evenly separated metrics, each number emphasised against a muted word, so the eye can
   land on a figure instead of parsing a sentence. The wording is unchanged. */
/* Deliberately a BLOCK with inline metrics, not a flex row: flex blockifies its items,
   so `innerText` returned one metric per line and the asserted "12 retrieved · 8 checked"
   contract broke. Inline items keep it one readable line; `nowrap` on each metric means a
   wrap can only happen at a separator, never inside "12 retrieved". */
.coverage-strip {
  display: block;
  padding: var(--s1) var(--s3);
  border-top: 1px solid var(--line);
  background: var(--sunken-2);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  line-height: 1.7;
  color: var(--ink-3);
}
/* Only the metrics are atomic. The separators keep their default `normal`, which is the
   row's ONLY break opportunity — a `.cov-sep` rule alone lost on specificity to this
   child selector and the strip stayed unbreakable. */
.coverage-strip > span:not(.cov-sep) {
  white-space: nowrap;
}
.cov-head {
  margin-right: var(--s1);
}
/* The separator must NOT be nowrap: inline boxes only break at whitespace, and with the
   spaces trapped inside a nowrap span the whole strip became one unbreakable line that
   ran off the pane and was silently clipped by `.scroll { overflow-x: hidden }` — an
   overflow no document-level check can see. The space either side of the middot is the
   only break opportunity in the row, so it has to stay breakable. */
.cov-sep {
  color: var(--line-2);
  user-select: none;
}
.cov-n {
  color: var(--ink-2);
  font-style: normal;
  font-variant-numeric: tabular-nums;
}
.cov-warn .cov-n,
.cov-bad .cov-n {
  color: inherit;
  font-weight: 600;
}
.cov-l {
  color: var(--ink-3);
}
.cov-warn .cov-l,
.cov-bad .cov-l {
  color: var(--ink-3);
}
.coverage-strip b {
  color: var(--ink-2);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
/* A severity colour is a marker, not an alarm: the number carries it, the word stays
   muted, so a Web or Images turn is not shouting red at a user who did not ask for
   grounded passages. */
.coverage-strip .cov-warn {
  color: var(--warn);
  opacity: 0.9;
}
.coverage-strip .cov-bad {
  color: var(--bad);
  opacity: 0.9;
}

/* ---- action toolbar + panels ---- */

.action-toolbar {
  display: flex;
  gap: 6px;
  align-items: center;
  padding: 6px 12px;
  border-top: 1px solid var(--line);
  background: var(--panel);
  flex-wrap: wrap;
}
.action-toolbar .sp {
  flex: 1;
}
/* One button. `display:inline-flex` + `text-decoration:none` so an <a class="btn"> (the
   account pages use one) is identical to a <button class="btn">. */
.btn {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s1);
  font: inherit;
  font-weight: 600;
  font-size: var(--fs-chrome);
  border-radius: var(--r-md);
  padding: var(--s1) var(--s3);
  min-height: 32px;
  cursor: pointer;
  border: 1px solid var(--line-2);
  background: var(--sunken);
  color: var(--ink-2);
  text-decoration: none;
  white-space: nowrap;
}
.btn:hover {
  color: var(--ink);
  border-color: var(--accent);
  background: var(--panel-sub);
  text-decoration: none;
}
.btn:active:not(:disabled) {
  background: var(--sunken);
  transform: translateY(1px);
}
.btn.primary {
  background: var(--accent-strong);
  border-color: var(--accent-strong);
  color: var(--accent-ink);
}
.btn.primary:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}
.btn.primary:active:not(:disabled) {
  background: var(--accent-strong);
}
/* A destructive/secondary-danger action reads as one. */
.btn.danger:hover {
  color: var(--bad);
  border-color: var(--bad-line);
  background: var(--bad-bg);
}
/* `.btn` is `display:inline-flex`, which beats the UA stylesheet's
   `[hidden] { display: none }` — the Cancel button rendered on every idle screen until
   this rule existed. Same class of bug as the admin lock screen's hidden flex card. */
.btn[hidden] {
  display: none;
}
/* Disabled is legible, not a ghost: a 0.45-opacity primary button on this background was
   effectively invisible. It is flattened to the secondary surface instead. */
.btn:disabled,
.btn[aria-disabled="true"],
.btn.primary:disabled {
  cursor: not-allowed;
  opacity: 1;
  background: var(--panel-sub);
  color: var(--ink-3);
  border-color: var(--line);
}
.btn:disabled:hover,
.btn[aria-disabled="true"]:hover,
.btn.primary:disabled:hover {
  color: var(--ink-3);
  border-color: var(--line);
  background: var(--panel-sub);
}
/* A button mid-request: busy, not broken. */
.btn[aria-busy="true"] {
  opacity: 0.7;
}
@media (prefers-reduced-motion: reduce) {
  .btn:active:not(:disabled) {
    transform: none;
  }
}

.action-panel {
  margin: 8px 12px 10px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--panel);
  overflow: hidden;
}
.action-panel[hidden] {
  display: none;
}
.panel-h {
  display: flex;
  gap: 8px;
  align-items: baseline;
  padding: 5px 8px;
  background: var(--panel-2);
  border-bottom: 1px solid var(--line);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.panel-h .sp {
  flex: 1;
}
.panel-b {
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.panel-b > .prose {
  font-size: var(--fs-ui);
  max-width: var(--measure);
}

/* verdict block (Verify) */
.verify-verdict {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  padding: 6px 8px;
  font-size: var(--fs-ui);
  margin-bottom: 4px;
}
.verify-verdict-label {
  margin: 0;
  font-weight: 650;
}
.verify-verdict-detail {
  margin: 0;
  color: inherit;
  opacity: 0.85;
  font-size: 12px;
}
.verify-verdict-answered {
  border-color: var(--ok-line);
  background: var(--ok-bg);
  color: var(--ok);
}
.verify-verdict-partial {
  border-color: var(--warn-line);
  background: var(--warn-bg);
  color: var(--warn);
}
.verify-verdict-not-answered {
  border-color: var(--bad-line);
  background: var(--bad-bg);
  color: var(--bad);
}
.verify-research {
  margin-top: 6px;
}
.verify-gaps {
  margin: 2px 0 4px;
}
.verify-gaps h4 {
  margin: 0 0 2px;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-3);
}
.verify-gaps ul {
  margin: 0;
  padding-left: 16px;
}
.verify-gaps li {
  overflow-wrap: anywhere;
  color: var(--ink-2);
  font-size: 12px;
}

.claim-list,
.checklist {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  display: grid;
  gap: 3px;
}
.claim,
.checklist-item {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr) auto;
  gap: 8px;
  align-items: baseline;
  padding: 4px 6px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--sunken);
  font-size: 12px;
  min-width: 0;
}
.checklist-item {
  grid-template-columns: minmax(0, 1fr) auto;
}
.claim-text,
.checklist-text {
  margin: 0;
  overflow-wrap: anywhere;
  min-width: 0;
  color: var(--ink);
}
.claim-status {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-align: center;
  border-radius: var(--r-sm);
  padding: 1px 4px;
  border: 1px solid transparent;
}
.claim-status.supported {
  background: var(--ok-fill);
  color: var(--ok);
  border-color: var(--ok-line);
}
.claim-status.unsupported {
  background: var(--bad-fill);
  color: var(--bad);
  border-color: var(--bad-line);
}
.claim-status.unresolved {
  background: var(--warn-fill);
  color: var(--warn);
  border-color: var(--warn-line);
}
.claim-citations,
.checklist-citations {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  justify-content: flex-end;
}
.claim-citations:empty,
.checklist-citations:empty {
  display: none;
}
.verify-unresolved,
.actionable-caveats {
  margin-top: 6px;
  border: 1px solid var(--warn-line);
  background: var(--warn-bg);
  border-radius: var(--r-sm);
  padding: 6px 8px;
  color: var(--warn);
  font-size: 12px;
}
.verify-unresolved h4,
.actionable-caveats h4 {
  margin: 0 0 3px;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.verify-unresolved ul,
.actionable-caveats ul {
  margin: 0;
  padding-left: 16px;
}
.verify-notes {
  margin-top: 6px;
}
.verify-notes p {
  color: var(--ink-3);
  font-size: 12px;
  margin: 2px 0 0;
}
.actionable-actions {
  margin-top: 8px;
}
.copy-status {
  margin-top: 6px;
  color: var(--ink-3);
  font-size: 12px;
}

.critique .verdict {
  margin: 0 0 6px;
  font-weight: 650;
}
.critique .verdict.supported {
  color: var(--ok);
}
.critique .verdict.not-supported {
  color: var(--bad);
}
.next-check {
  margin-top: 6px;
}
.next-check strong {
  display: block;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-3);
}

.panel-error,
.regenerate-error,
.turn-error {
  margin: 0 0 var(--s0);
  max-width: var(--measure);
  color: var(--bad);
  background: var(--bad-bg);
  border: 1px solid var(--bad-line);
  border-left-width: 3px;
  border-radius: var(--r-sm);
  padding: var(--s2) var(--s3);
  font-size: var(--fs-ui);
  line-height: 1.5;
  overflow-wrap: anywhere;
}
/* The literal upstream string is diagnostic detail, not the message: keep it present for
   support, but subordinate to the sentence above it. */
.turn-error .error-detail {
  display: block;
  margin-top: var(--s0);
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--fs-mono);
}
.panel-retry {
  margin: 0;
}
.stale-note {
  margin: 8px 0 0;
  color: var(--warn);
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
  border-radius: var(--r-sm);
  padding: 6px 8px;
  font-size: 12px;
}

/* ---- jump to latest ---- */

.jumplatest {
  display: flex;
  justify-content: center;
  padding: 4px 0 2px;
}
.jumplatest[hidden] {
  display: none;
}
.jumplatest button {
  appearance: none;
  border: 1px solid var(--line-2);
  background: var(--panel-2);
  color: var(--ink-2);
  border-radius: 999px;
  padding: 3px 12px;
  font: inherit;
  font-size: 11px;
  cursor: pointer;
}
.jumplatest button:hover {
  color: var(--ink);
  border-color: var(--accent);
}

/* ---- input + status ---- */

.input {
  display: flex;
  gap: var(--s2);
  align-items: center;
  padding: var(--s2) var(--s3) var(--s1);
  border-top: 1px solid var(--line);
  background: var(--panel-2);
  flex-wrap: wrap;
}
.input input {
  flex: 1 1 200px;
  min-width: 0;
  background: var(--sunken);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--fs-body);
  padding: var(--s2) var(--s3);
  min-height: 36px;
}
.input input::placeholder {
  color: var(--ink-3);
}
.input input:hover {
  border-color: var(--line-2);
  background: var(--sunken-hover);
}
.input input:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 1px;
}
.mode-note {
  margin: 0;
  color: var(--ink-3);
  font-size: 11px;
}
/* Request-side search options: a compact, optional region/language/freshness row. */
.search-options {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s1) var(--s4);
  align-items: center;
  padding: var(--s0) var(--s3) var(--s1);
  background: var(--panel-2);
  border-top: 1px solid var(--line);
}
.search-options .opt {
  display: inline-flex;
  gap: var(--s1);
  align-items: center;
  color: var(--ink-3);
  font-size: var(--fs-micro);
}
.search-options .opt span {
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
}
.search-options select {
  background: var(--sunken);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  color: var(--ink-2);
  font-family: var(--sans);
  font-size: var(--fs-chrome);
  padding: var(--s0) var(--s1);
  min-height: 26px;
  cursor: pointer;
}
.search-options select:hover {
  color: var(--ink);
  border-color: var(--line-2);
  background: var(--panel-sub);
}
.search-options select:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 1px;
}
/* "Did you mean: …?" — Brave's spellcheck correction, offered, never applied silently. */
.did-you-mean {
  margin: 6px 0 0;
  color: var(--ink-2);
  font-size: 12px;
}
.did-you-mean-link {
  background: none;
  border: none;
  padding: 0;
  color: var(--accent);
  font: inherit;
  text-decoration: underline;
  cursor: pointer;
}
.did-you-mean-link:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 1px;
}
/* An extra snippet is additional context for the SAME source, not a separate result. */
.passage-kind {
  display: inline-block;
  margin-right: 6px;
  padding: 0 4px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  color: var(--ink-3);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  vertical-align: 1px;
}
.status {
  display: flex;
  gap: var(--s3);
  align-items: center;
  padding: var(--s0) var(--s3);
  background: var(--sunken);
  border-top: 1px solid var(--line);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  color: var(--ink-3);
  flex-wrap: wrap;
  row-gap: 2px;
  min-height: 24px;
}
.status .on {
  color: var(--ok);
}
.status .status-grow {
  flex: 1;
}
.status.error {
  color: var(--bad);
}
.status.empty {
  color: var(--ink-2);
}
.status.canceled {
  color: var(--warn);
}
.status.loading::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 6px;
  border-radius: 50%;
  background: var(--accent);
  animation: pulse 1.1s ease-in-out infinite;
}
@keyframes pulse {
  0%,
  100% {
    opacity: 0.35;
  }
  50% {
    opacity: 1;
  }
}

/* ---- right evidence pane ---- */

.side {
  grid-column: 3;
  grid-row: 2;
  background: var(--panel);
  border-left: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}
.side-h {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--line);
  background: var(--panel-2);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
  flex-wrap: wrap;
}
.side-tabs {
  margin-left: auto;
  display: flex;
  gap: 4px;
}
.chip {
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  padding: 1px 6px;
  color: var(--ink-3);
  font-size: 10.5px;
  background: transparent;
  cursor: default;
}
.chip.on {
  background: var(--accent-strong);
  border-color: var(--accent-strong);
  color: var(--accent-ink);
}
button.chip {
  cursor: pointer;
  font: inherit;
  font-size: 10.5px;
}
button.chip:hover {
  color: var(--ink);
  border-color: var(--accent);
}
.side-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
}
/* The pane's empty/placeholder line was an italic fragment pinned to the top-left corner
   of a 384px column of black. Centre it and give it room. */
.side-body > .evidence-note:only-child,
.side-body > .src-empty:only-child {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 140px;
  padding: var(--s5) var(--s4);
  border-bottom: 0;
  color: var(--ink-3);
  font-size: var(--fs-ui);
  font-style: normal;
  text-align: center;
  line-height: 1.5;
}
.side-foot {
  border-top: 1px solid var(--line);
  padding: var(--s1) var(--s3);
  color: var(--ink-3);
  font-size: var(--fs-chrome);
  line-height: 1.45;
}
.side-foot[hidden] {
  display: none;
}

/* The source row: rank · include · title/host · passage count. `align-items: start`
   rather than `baseline` so the two-line title block and the right-hand count stay on the
   same top edge instead of the count drifting down with the first line's baseline. */
.src {
  display: grid;
  grid-template-columns: auto 22px minmax(0, 1fr) auto;
  gap: 0 var(--s2);
  align-items: start;
  padding: var(--s1) var(--s3);
  border-bottom: 1px solid var(--line);
  cursor: pointer;
}
.src:hover {
  background: var(--panel-hover);
}
.src.grouped {
  background: var(--panel-sub);
  padding-left: 24px;
}
.src.excluded {
  opacity: 0.6;
}
.src .rk {
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  text-align: right;
  min-width: 1.6em;
}
/* Pool position for a source the active turn did not ground on (F-8): shown inside the
   rank cell so it never reads as a citation ordinal and never shifts the row grid. */
.src .prk {
  color: var(--ink-4, var(--ink-3));
  opacity: 0.6;
  font-size: 0.85em;
  margin-left: 2px;
}
/* The pane is 384px and the title/host were each clamped to ONE line, so almost every
   row ended in an ellipsis mid-word and the host line read `date unkno…`. Two lines for
   the title and a wrapping meta line fit the real content instead of truncating it. */
.src .ti {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  color: var(--ink);
  font-size: var(--fs-ui);
  line-height: 1.35;
  overflow: hidden;
  overflow-wrap: anywhere;
}
.src .sub {
  display: block;
  margin-top: 1px;
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  line-height: 1.4;
  overflow-wrap: anywhere;
}
.src .rt {
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  white-space: nowrap;
  padding-top: 2px;
}
.src .rk {
  padding-top: 2px;
}
.src-check {
  padding-top: 1px;
}
.src .dup-mark {
  color: var(--ink-3);
}
/* Per-turn "used in this turn" marker (thread model Task 2). */
.src .used-mark {
  color: var(--ok);
  margin-right: 5px;
}
.src.used .ti {
  color: var(--ink);
}
.src-main {
  min-width: 0;
}
.src-open {
  appearance: none;
  display: block;
  width: 100%;
  min-width: 0;
  text-align: left;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  padding: 0;
  cursor: pointer;
}
.src-open:focus-visible {
  outline-offset: 0;
}
.answer-meta {
  margin: 8px 0 0;
  color: var(--ink-3);
  font-size: 11.5px;
}

/* ---- Web-mode centre results list (rank · title · host · date · snippet) ---- */

.results {
  display: grid;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--panel);
  max-width: 100%;
}
.result {
  display: grid;
  grid-template-columns: 2.2em minmax(0, 1fr);
  gap: 0 8px;
  padding: 7px 10px;
  border-bottom: 1px solid var(--line);
  cursor: pointer;
}
.result:last-child {
  border-bottom: 0;
}
.result:hover {
  background: var(--panel-hover);
}
.result.selected {
  background: var(--panel-sel);
  box-shadow: inset 2px 0 0 var(--accent);
}
.result.grouped {
  background: var(--panel-sub);
  padding-left: 24px;
}
.result .rk {
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  text-align: right;
  padding-top: 1px;
}
.result-main {
  min-width: 0;
}
.result .ti {
  display: block;
  color: var(--ink);
  font-size: 13px;
  font-weight: 600;
  overflow-wrap: anywhere;
}
.result .sub {
  display: block;
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  overflow-wrap: anywhere;
}
.result .dup-mark {
  color: var(--ink-3);
}
/* Direct links: the title and host navigate to the source page; the rest of the row selects.
   Keep them visually part of the row rather than browser-default blue/underline, and inherit
   the host colour so the host-match highlight still applies. */
.result a.ti {
  color: var(--ink);
  text-decoration: none;
}
.result a.ti:hover {
  color: var(--accent);
  text-decoration: underline;
}
.result .host-link {
  color: inherit;
  text-decoration: none;
}
.result .host-link:hover {
  color: var(--accent);
  text-decoration: underline;
}
.result .snip {
  grid-column: 2;
  margin: 3px 0 0;
  color: var(--ink-2);
  font-size: 12.5px;
  line-height: 1.45;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.result .snip.expanded {
  -webkit-line-clamp: unset;
  display: block;
}
.snip-toggle {
  grid-column: 2;
  justify-self: start;
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--accent);
  font: inherit;
  font-size: 11px;
  padding: 0;
  margin-top: 1px;
  cursor: pointer;
}
.result-more {
  appearance: none;
  display: block;
  width: 100%;
  text-align: left;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: var(--panel-sub);
  color: var(--ink-3);
  font: inherit;
  font-family: var(--mono);
  font-size: var(--fs-mono);
  padding: 5px 10px 5px 24px;
  cursor: pointer;
}
.result-more:hover {
  color: var(--ink);
}

/* ---- Web-mode host filter + Load more ------------------------------------------------ */

.web-results {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-width: 100%;
}
.host-filter-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.filter-affordance {
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  white-space: nowrap;
}
.filter-affordance:empty {
  display: none;
}
/* Explicit filter (Enter): non-matching rows are hidden. The list is complete otherwise. */
.result.filtered-out {
  display: none;
}
.host-filter {
  flex: 1;
  min-width: 0;
  background: var(--sunken);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 11.5px;
  padding: 5px 8px;
  min-height: 30px;
}
.host-filter:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 1px;
}
/* The host filter highlights and scrolls; it never removes a row. */
.result.host-match {
  background: var(--row-highlight);
  box-shadow: inset 2px 0 0 var(--spot);
}
.result.host-match .sub {
  color: var(--spot);
}
.load-more-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.load-more {
  appearance: none;
  width: 100%;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--panel-sub);
  color: var(--ink-2);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 7px 10px;
  min-height: 34px;
  cursor: pointer;
}
.load-more:hover:not(:disabled) {
  color: var(--ink);
  border-color: var(--accent);
}
.load-more:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
.web-end {
  margin: 0;
  padding: 4px 2px;
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--fs-mono);
}
/* Web rows carry no include checkbox, so they use three columns (rank · main · count) rather
   than the grounded row's four; without this the title lands in the 22px checkbox column. */
.src.web {
  grid-template-columns: auto minmax(0, 1fr) auto;
}
.source-link {
  color: var(--accent);
  text-decoration: none;
  overflow-wrap: anywhere;
}
.source-link:hover {
  text-decoration: underline;
}
.src-check {
  grid-column: 2;
  align-self: center;
  display: flex;
  justify-content: center;
}
.src-check input {
  width: 15px;
  height: 15px;
  accent-color: var(--accent-strong);
  cursor: pointer;
}
.src-passages {
  border-bottom: 1px solid var(--line);
  background: var(--sunken-2);
}
.src-passages[hidden] {
  display: none;
}
.src-passage {
  display: block;
  width: 100%;
  text-align: left;
  appearance: none;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: transparent;
  color: var(--ink-2);
  font: inherit;
  font-size: 12px;
  padding: 6px 10px 6px 32px;
  cursor: pointer;
  overflow-wrap: anywhere;
}
.src-passage:last-child {
  border-bottom: 0;
}
.src-passage:hover {
  background: var(--panel-hover);
  color: var(--ink);
}
.src-passage .pn {
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  margin-right: 6px;
}
.src-empty {
  padding: 6px 10px;
  color: var(--ink-3);
  font-size: 12px;
  font-style: italic;
}

/* selected-passage evidence view */
.evidence-passage {
  padding: 8px 10px;
  border-bottom: 1px solid var(--line);
}
.evidence-passage .ph {
  display: flex;
  gap: 8px;
  align-items: baseline;
  font-family: var(--mono);
  font-size: var(--fs-mono);
  color: var(--ink-3);
  margin-bottom: 4px;
  flex-wrap: wrap;
}
/* A pool passage the selected turn did not ground on is inspection only, never evidence
   (F-2): mute its header so it cannot be mistaken for a supporting passage. */
.evidence-passage.non-evidence {
  border-left: 2px solid var(--line);
}
.evidence-passage.non-evidence .ph {
  color: var(--ink-3);
  opacity: 0.8;
}
.evidence-passage .pt {
  font-size: 13.5px;
  color: var(--ink);
  line-height: 1.5;
  max-width: var(--measure);
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}
.evidence-passage .pt mark {
  background: var(--mark-bg);
  color: var(--mark-ink);
  padding: 0 2px;
  border-radius: var(--r-sm);
}
.evidence-kv {
  display: flex;
  gap: 6px;
  padding: 5px 10px;
  font-family: var(--mono);
  font-size: var(--fs-mono);
  color: var(--ink-3);
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.evidence-kv b {
  color: var(--ink-2);
  font-weight: 500;
}
.evidence-note {
  padding: 6px 10px;
  color: var(--ink-3);
  font-size: 11.5px;
  border-bottom: 1px solid var(--line);
}

/* ---- secure source preview (display-only) ---- */

.preview-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--line);
}
.preview-actions .preview-button.on {
  border-color: var(--accent, var(--ink-2));
}
.preview-visit {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-3);
}
.preview-panel {
  border-bottom: 1px solid var(--line);
  padding: 6px 10px 10px;
}
.preview-head {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-2);
}
.preview-label {
  font-weight: 500;
}
.preview-host {
  color: var(--ink-3);
}
.preview-disclosure {
  margin: 4px 0 6px;
  font-size: 11px;
  color: var(--ink-3);
}
.preview-title {
  margin: 0 0 6px;
  font-size: 12.5px;
  color: var(--ink-1);
}
.preview-body {
  margin: 0;
  padding: 8px;
  max-height: 320px;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--ink-2);
  background: var(--sunken-2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
.preview-status,
.preview-note {
  margin: 4px 0 0;
  font-size: 11px;
  color: var(--ink-3);
}

/* ---- reading mode ---- */

@media (max-width: 1200px) {
  .app {
    grid-template-columns: 184px minmax(0, 1fr) 320px;
  }
}

body.reading .app {
  grid-template-columns: 200px minmax(0, 1fr) 44px;
}
@media (max-width: 1200px) {
  body.reading .app {
    grid-template-columns: 184px minmax(0, 1fr) 44px;
  }
}
body.reading .side {
  overflow: hidden;
}
body.reading .side .src,
body.reading .side .src-passages,
body.reading .side .evidence-passage,
body.reading .side .evidence-kv,
body.reading .side .evidence-note,
body.reading .side .side-h span,
body.reading .side .side-tabs,
body.reading .side .side-foot {
  display: none;
}
body.reading .side-h {
  justify-content: center;
}
.rail-toggle-affordance {
  display: none;
  appearance: none;
  border: 0;
  background: transparent;
  cursor: pointer;
  padding: 0;
}
body.reading .rail-toggle-affordance {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: center;
  writing-mode: vertical-rl;
  text-orientation: mixed;
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
body.reading .prose {
  max-width: 74ch;
  font-size: 16px;
}

/* ---- reduced motion ---- */

@media (prefers-reduced-motion: reduce) {
  .status.loading::before {
    animation: none;
  }
  * {
    scroll-behavior: auto !important;
  }
}

/* ---- mobile / narrow: single column, view swap (never overlapping) ---- */

@media (max-width: 820px) {
  .app {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
  }
  .rail {
    display: none;
  }
  .buf {
    grid-column: 1;
    grid-row: 2;
  }
  .side {
    display: none;
    grid-column: 1;
    grid-row: 2;
  }
  body.evidence-open .buf {
    display: none;
  }
  body.evidence-open .side {
    display: flex;
  }
  .evidence-toggle {
    display: inline-flex;
  }
  body.evidence-open .side-back {
    display: inline-flex;
  }
  .side-back {
    order: -1;
  }
  body.reading .app {
    grid-template-columns: minmax(0, 1fr);
  }
  body.reading .prose {
    max-width: none;
  }
  /* 44px touch targets on mobile */
  .chip-btn,
  .new-thread,
  .export-thread,
  .about-action,
  .jumplatest button,
  .snip-toggle,
  .result-more,
  .did-you-mean-link {
    min-height: 44px;
    padding: var(--s2) var(--s3);
  }
  .mode-toggle button {
    min-height: 44px;
    /* Five scope tabs must fit the narrowest supported width (360px) without clipping. */
    padding: 10px 10px;
  }
  .btn {
    min-height: 44px;
    padding: 10px 16px;
  }
  /* The region/language/freshness selects were ~26px tall — below the touch minimum the
     rest of this breakpoint already meets. */
  /* Three equal columns with the label stacked over the control: one row instead of
     three, a straight right edge instead of three different select widths, and a 44px
     target on each. */
  .search-options {
    display: grid;
    /* Not three equal columns: "United States" is the longest value in the set and was
       being clipped by the native select at 360. */
    grid-template-columns: 1.25fr 1fr 0.9fr;
    gap: var(--s1);
    padding: var(--s2) var(--s3);
  }
  .search-options .opt {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 3px;
    min-width: 0;
  }
  .search-options select {
    width: 100%;
    min-width: 0;
    min-height: 44px;
    padding: var(--s2);
    font-size: var(--fs-ui);
  }
  .about-link,
  .about-account {
    min-height: 44px;
    display: flex;
    align-items: center;
  }
  .about-menu {
    padding: var(--s1) 0;
  }
  /* The brand had a row of the topbar to itself at 390/360, and `.about`'s auto margin
     left a visible hole between "Deep" and "About". The tools group is one unit that
     wraps as a block, and the About button sits inside the same row. */
  .brand {
    padding-right: var(--s2);
    margin-right: 0;
  }
  .topbar {
    padding: var(--s0) var(--s2);
    gap: var(--s1);
    row-gap: var(--s0);
  }
  .topbar-grow {
    display: none;
  }
  .mode-toggle {
    order: 3;
    flex: 1 0 100%;
  }
  .mode-toggle button {
    flex: 1 1 0;
    min-width: 0;
  }
  .topbar-tools {
    margin-left: auto;
    gap: var(--s0);
  }
  .about {
    margin-left: var(--s0);
  }
  .topbar-tools .chip-btn,
  .about-toggle {
    min-height: 36px;
    padding: var(--s1) var(--s2);
  }
  .src {
    padding-top: 8px;
    padding-bottom: 8px;
  }
  .src-check input {
    width: 20px;
    height: 20px;
  }
  .turn-head {
    padding: 8px 10px;
  }
  .turn-head .meta {
    margin-left: 0;
    white-space: normal;
  }
  .turn-body {
    padding: 10px;
  }
  .coverage-strip,
  .action-toolbar {
    padding-left: 10px;
    padding-right: 10px;
  }
  .action-panel {
    margin-left: 10px;
    margin-right: 10px;
  }
  /* The query field and Send stay on one line: a 44px Send alone on its own row cost a
     whole band of a phone screen for one button. */
  .input {
    flex-wrap: nowrap;
    gap: var(--s1);
    padding: var(--s2) var(--s3);
  }
  .input input {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 44px;
  }
  .input .btn {
    flex: 0 0 auto;
    padding: 10px 14px;
  }
  /* The jump pill floated on an unpainted band that read as a separate toolbar. */
  .jumplatest {
    padding: var(--s1) 0 var(--s0);
  }
}

/* Below ~420px the masthead has to fit a wordmark and four controls on one line. The
   chips lose their padding before the bar is allowed to wrap to a third row. */
@media (max-width: 420px) {
  .topbar {
    gap: var(--s0);
  }
  .topbar-tools {
    gap: 3px;
  }
  .topbar-tools .chip-btn,
  .about-toggle {
    padding: var(--s2) var(--s1);
    font-size: 10px;
    letter-spacing: 0;
  }
}
@media (max-width: 360px) {
  .brand {
    font-size: 12px;
    padding-right: var(--s1);
  }
  .mode-toggle button {
    padding: 10px 6px;
    font-size: 11px;
  }
}

/* ---- Images + Videos scopes: proxied media grid (every <img> is same-origin /api/image) ---- */

/* `gap: 1px` over a `--line` background drew the grid rules — but an unfilled tail row
   then showed as one large grey PLATE where the missing cards would have been (two empty
   columns at 1440). Real borders on the cards draw the same rules and leave the tail
   transparent. */
.image-grid {
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 0;
  background: transparent;
}
.image-grid .image-card,
.image-grid .video-card {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 0;
  border: 0;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: var(--panel);
  min-width: 0;
}
.image-grid .image-card:hover,
.image-grid .video-card:hover {
  background: var(--panel-hover);
}
.image-grid .image-thumb {
  display: block;
  width: 100%;
  height: 130px;
  object-fit: cover;
  background: var(--sunken);
  /* V-1: hidden until it loads, so the alt text and the broken-image glyph never render while a
     thumbnail is deferred, loading, or failed. `.is-loaded` reveals it; `.is-broken` keeps it
     hidden and the placeholder beside it takes the space. */
  opacity: 0;
}
.image-grid .image-thumb.is-loaded {
  opacity: 1;
}
/* V-1: a thumbnail whose fetch failed is hidden and replaced by the placeholder beside it, so
   the browser's broken-image glyph and the alt text never render as in-card content. The
   `[hidden]` UA rule loses to the `display:block` above, so this must be class-driven. */
.image-grid .image-thumb.is-broken {
  display: none;
}
.image-grid .image-thumb-missing {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--sunken-2);
  color: var(--ink-3);
  font-size: var(--fs-mono);
}
/* The thumbnail well reads as a deliberate placeholder while it loads, not as a hole. */
.image-grid .image-thumb:not(.is-loaded) {
  background: var(--sunken-2);
}
.image-grid .image-meta {
  border-top: 1px solid var(--line);
}
.image-grid .image-meta {
  padding: 6px 8px 8px;
  min-width: 0;
}
.image-grid .ti {
  display: block;
  color: var(--ink);
  font-size: 12.5px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.image-grid .sub {
  display: block;
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.image-card.host-match,
.video-card.host-match {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* ---- About-menu notice (the no-CDN posture lives here, not the footer) ---- */
.about-note {
  margin: 0;
  padding: var(--s0) var(--s3) var(--s1);
  color: var(--ink-3);
  font-size: var(--fs-chrome);
  line-height: 1.5;
}
.mode-note {
  padding: var(--s0) var(--s3);
}
.about-group {
  display: flex;
  flex-direction: column;
}
/* Clearing the session is destructive, so it is the one item in the menu that is a
   bordered control rather than a row, and it hints danger on hover. */
.about-action {
  appearance: none;
  align-self: flex-start;
  margin: var(--s1) var(--s3) var(--s0);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--ink-2);
  font: inherit;
  font-size: var(--fs-chrome);
  font-weight: 600;
  padding: var(--s0) var(--s2);
  min-height: 28px;
  cursor: pointer;
}
/* Wiping this device's threads is destructive and hints danger on hover. Signing out is not
   the same act — it is reversible with the key the user already has — so it shares the shape
   but not the warning colour. Two controls that look equally dangerous teach the user to
   ignore the warning on the one that is. */
.about-action:hover {
  color: var(--bad);
  border-color: var(--bad-line);
  background: var(--bad-bg);
}
.about-action.neutral:hover {
  color: var(--ink);
  border-color: var(--accent);
  background: var(--accent-wash);
}

/* ---- Markdown export controls (Item 7) ---- */


/* "Export as Markdown" sat on an unpainted strip directly under the action toolbar, so a
   visible seam ran between two rows of the same control type. One continuous bar. */
.export-toolbar {
  display: flex;
  gap: var(--s1);
  padding: var(--s1) var(--s3) var(--s2);
  border-top: 1px solid var(--line);
  background: var(--panel);
  flex-wrap: wrap;
}
.action-toolbar + .export-toolbar {
  border-top: 0;
  padding-top: 0;
}
.action-toolbar:has(+ .export-toolbar) {
  padding-bottom: var(--s1);
}
.export-toolbar .btn {
  font-size: var(--fs-chrome);
}

/* ======================================================================================
   DOCUMENT PAGES — sign-in, top-up, payment success, usage, privacy, operator console.

   These are not the workbench grid: the body scrolls and the content is one centred
   column. They are, however, the SAME PRODUCT, so they are built from the same tokens as
   the workbench — identical palette, spacing rhythm, radii, type scale and controls. The
   shared shell is `body.page` > `.page-top` + `.page-main` + `.page-foot`.

   `body.auth` is kept as an alias of `body.page` because the account pages and the
   operator console both carry it.
   ====================================================================================== */

body.page,
body.auth {
  overflow: auto;
  /* Document pages set their own height; the workbench's `height:100%` lock would
     stop a long page from growing. A column layout lets a short page push its footer
     to the bottom of the viewport instead of leaving it marooned mid-screen. */
  height: auto;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  font-size: var(--fs-body);
}
body.page > .page-main,
body.auth > .auth-main,
body.page > .prose.privacy {
  flex: 1 0 auto;
  width: 100%;
}
body.page > .page-foot,
body.auth > .page-foot {
  flex: 0 0 auto;
  width: 100%;
}

/* ---- masthead ------------------------------------------------------------------- */

.page-top {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-height: 44px;
  padding: 0 var(--s4);
  background: var(--panel-2);
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-chrome);
  flex-wrap: wrap;
}
.page-brand {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  color: var(--ink);
  font-size: 13px;
  font-weight: 650;
  letter-spacing: 0.2px;
  text-decoration: none;
}
.page-brand:hover {
  color: var(--accent);
}
.page-nav {
  display: flex;
  align-items: center;
  gap: var(--s0);
  margin-left: auto;
  flex-wrap: wrap;
}
/* Nav items are the workbench's chip vocabulary, so the two surfaces read as one app. */
.page-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: var(--s0) var(--s2);
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  color: var(--ink-2);
  font-size: var(--fs-chrome);
  text-decoration: none;
  white-space: nowrap;
}
.page-nav a:hover {
  color: var(--ink);
  border-color: var(--line-2);
  background: var(--panel);
}
.page-nav a[aria-current="page"] {
  color: var(--ink);
  border-color: var(--line-2);
  background: var(--panel);
}

/* ---- column --------------------------------------------------------------------- */

.page-main,
.auth-main {
  max-width: var(--page-measure);
  margin: 0 auto;
  padding: var(--s6) var(--s4) var(--s7);
}
.page-main.wide,
.auth-main.wide {
  max-width: var(--page-measure-wide);
}

.page-head {
  margin: 0 0 var(--s5);
  padding-bottom: var(--s4);
  border-bottom: 1px solid var(--line);
}
.page-main h1,
.auth-main h1 {
  margin: 0 0 var(--s2);
  font-size: var(--fs-h1);
  font-weight: 650;
  letter-spacing: -0.01em;
  line-height: 1.2;
}
.page-main h2,
.auth-main h2 {
  margin: var(--s6) 0 var(--s3);
  font-size: var(--fs-h2);
  font-weight: 650;
  line-height: 1.3;
}
.page-main h2:first-of-type,
.auth-main h2:first-of-type {
  margin-top: var(--s5);
}
.page-main h3,
.auth-main h3 {
  margin: var(--s4) 0 var(--s2);
  font-size: var(--fs-h3);
  font-weight: 650;
}
.page-lede,
.auth-lede {
  color: var(--ink-2);
  max-width: 68ch;
  margin: 0;
  font-size: var(--fs-prose);
  line-height: 1.55;
}
.page-main p,
.auth-main p {
  max-width: 72ch;
}
/* One link vocabulary. Without this a bare <a> falls back to the UA's purple/blue, which
   is why the "Back to Sourceglass" links did not match the accent links beside them. */
.page-main a,
.auth-main a {
  color: var(--accent);
  text-decoration: none;
}
.page-main a:hover,
.auth-main a:hover {
  text-decoration: underline;
}
.page-main code,
.auth-main code {
  font-family: var(--mono);
  font-size: 0.9em;
  background: var(--sunken);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 1px 5px;
  color: var(--spot);
  overflow-wrap: anywhere;
}

.page-foot {
  max-width: var(--page-measure);
  margin: 0 auto;
  padding: var(--s4) var(--s4) var(--s6);
  border-top: 1px solid var(--line);
  color: var(--ink-3);
  font-size: var(--fs-chrome);
  display: flex;
  gap: var(--s3);
  align-items: center;
  flex-wrap: wrap;
}
.page-foot.wide {
  max-width: var(--page-measure-wide);
}
.page-foot a {
  color: var(--ink-2);
  text-decoration: none;
}
.page-foot a:hover {
  color: var(--accent);
  text-decoration: underline;
}
.page-foot .sp {
  flex: 1;
}

/* ---- cards and forms -------------------------------------------------------------- */

.auth-card {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--s2);
  max-width: 460px;
  padding: var(--s4);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
}
.auth-card label {
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-3);
}
.auth-card input {
  appearance: none;
  width: 100%;
  padding: var(--s2) var(--s3);
  min-height: 40px;
  background: var(--sunken);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
}
.auth-card input::placeholder {
  color: var(--ink-3);
}
.auth-card input:hover {
  border-color: var(--line-2);
}
.auth-card input:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 1px;
  border-color: var(--accent);
}
.auth-card input:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
/* A credential field is monospace: a pasted key is read character by character. */
.auth-card input[type="password"] {
  font-family: var(--mono);
  letter-spacing: 0.04em;
}
.auth-card .btn {
  align-self: flex-start;
  margin-top: var(--s0);
}
/* The hint belongs to the field above it, so it sits tight to it, not floating. */
.auth-card input + .auth-hint,
.auth-card input + .auth-status + .auth-hint {
  margin-top: calc(var(--s2) * -1 + 2px);
}
.auth-hint {
  margin: 0;
  color: var(--ink-3);
  font-size: var(--fs-chrome);
  line-height: 1.45;
  max-width: 62ch;
}
/* The status line reserves its height so a message never shifts the layout, but it is
   invisible rather than a visible empty gap inside the card. */
.auth-status {
  margin: 0;
  min-height: 1.2em;
  font-size: var(--fs-ui);
  color: var(--ink-2);
}
/* Only a classified message (an error, or the deliberate notice on the payment page)
   gets a box; a routine "Showing 8 recent operations" count is just a line of text. */
.auth-status[data-kind]:not([data-kind=""]):not(:empty),
.auth-card > .auth-status:not(:empty) {
  padding: var(--s2) var(--s3);
  border: 1px solid var(--line-2);
  border-left-width: 3px;
  border-radius: var(--r-sm);
  background: var(--sunken-2);
  line-height: 1.5;
}
.auth-status[data-kind="error"] {
  color: var(--bad);
}
.auth-status[data-kind="error"]:not(:empty) {
  border-color: var(--bad-line);
  border-left-color: var(--bad);
  background: var(--bad-bg);
}
.auth-note {
  color: var(--ink-3);
  font-size: var(--fs-ui);
  margin: var(--s5) 0 0;
}

/* ---- prepaid credit packs ---------------------------------------------------------- */

/* `auto-fill` orphaned the fourth pack on a row of its own at 1440. A fixed 2-up (and a
   4-up only when the column is genuinely wide) always fills its rows. */
.pack-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s3);
}
.pack-grid.cols-4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.pack {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--s1);
  padding: var(--s4);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  min-width: 0;
}
.pack-name {
  color: var(--ink);
  font-size: var(--fs-h2);
  font-weight: 650;
  overflow-wrap: anywhere;
}
.pack-price {
  color: var(--ink-2);
  font-size: var(--fs-ui);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.pack .auth-hint {
  overflow-wrap: anywhere;
}
.pack .btn {
  margin-top: var(--s3);
  width: 100%;
  text-align: center;
}
/* The buy page states the price once, as the headline. */
.pack-amount {
  color: var(--ink);
  font-size: 26px;
  font-weight: 650;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.pack-unit {
  color: var(--ink-2);
  font-size: var(--fs-ui);
}

/* ---- data tables (usage, privacy) --------------------------------------------------- */

/* Wrapped so a wide table scrolls INSIDE its own box instead of pushing the document
   sideways — the usage table overflowed the viewport by 44px at 390 and 75px at 360. */
.table-wrap {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--panel);
  /* Scroll shadows: a right-edge shade appears only while there is more table to the
     right, so a narrow screen says "this scrolls" instead of looking truncated. The
     `local` layers are the covers that hide each shade when that end is reached. */
  background-image:
    linear-gradient(to right, var(--panel), var(--panel)),
    linear-gradient(to right, var(--panel), var(--panel)),
    linear-gradient(to right, var(--scroll-shade), transparent),
    linear-gradient(to left, var(--scroll-shade), transparent);
  background-position: left center, right center, left center, right center;
  background-repeat: no-repeat;
  background-size: 24px 100%, 24px 100%, 14px 100%, 14px 100%;
  background-attachment: local, local, scroll, scroll;
}
.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-ui);
  font-variant-numeric: tabular-nums;
}
.data-table th,
.data-table td {
  text-align: left;
  padding: var(--s2) var(--s3);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
  vertical-align: baseline;
}
.data-table thead th {
  position: sticky;
  top: 0;
  background: var(--panel-2);
  color: var(--ink-3);
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  white-space: nowrap;
}
.data-table tbody tr:last-child td {
  border-bottom: 0;
}
.data-table tbody tr:hover td {
  background: var(--panel-hover);
}
.data-table .num,
.data-table td.dash-credits,
.data-table td.dash-tokens,
.data-table td.dash-total-credits,
.data-table td.dash-total-ops {
  text-align: right;
  font-family: var(--mono);
  font-size: var(--fs-mono);
}
.data-table th.num {
  text-align: right;
}
/* Opaque machine identifiers are reference data, not reading matter: monospace, muted,
   and bounded so one 36-character id cannot set the width of the whole table. */
.data-table td.dash-op {
  font-family: var(--mono);
  font-size: var(--fs-mono);
  color: var(--ink-3);
  max-width: 24ch;
  overflow: hidden;
  text-overflow: ellipsis;
}
.data-table td.dash-type,
.data-table td.dash-period {
  font-family: var(--mono);
  font-size: var(--fs-mono);
  color: var(--ink-2);
}
.data-table td.dash-created {
  font-family: var(--mono);
  font-size: var(--fs-mono);
  color: var(--ink-3);
}
.data-table td.dash-status {
  color: var(--ink-2);
}
.table-note {
  margin: 0 0 var(--s2);
  max-width: 72ch;
  color: var(--ink-3);
  font-size: var(--fs-chrome);
}
/* An empty table that still draws its header row reads as a loading failure. When the
   body has no rows the whole table is removed and only the empty note remains. */
.table-wrap:has(tbody:empty) {
  display: none;
}

/* An empty section says what would be here, not just that there is nothing. */
.empty-note {
  margin: 0;
  /* It stands in for a table, so it takes the table's width, not the prose measure. */
  max-width: none;
  padding: var(--s5) var(--s4);
  border: 1px dashed var(--line-2);
  border-radius: var(--r-lg);
  background: var(--panel-sub);
  color: var(--ink-3);
  font-size: var(--fs-ui);
  text-align: center;
}
.empty-note[hidden] {
  display: none;
}

/* ---- the privacy / transparency document -------------------------------------------- */

/* `.prose` alone has no margin and no padding: the privacy page was rendering flush
   against x=0 with its heading touching the viewport edge. */
.prose.privacy {
  max-width: var(--page-measure);
  margin: 0 auto;
  padding: var(--s6) var(--s4) var(--s7);
  font-size: var(--fs-prose);
}
.prose.privacy h1 {
  font-size: var(--fs-h1);
  margin: 0 0 var(--s3);
}
.prose.privacy h2 {
  margin: var(--s6) 0 var(--s2);
  font-size: var(--fs-h2);
}
.prose table {
  width: 100%;
  border-collapse: collapse;
  margin: var(--s3) 0 var(--s4);
  font-size: var(--fs-ui);
}
.prose table th,
.prose table td {
  text-align: left;
  vertical-align: top;
  padding: var(--s2) var(--s3);
  border-bottom: 1px solid var(--line);
  line-height: 1.5;
}
.prose table thead th {
  background: var(--panel-2);
  color: var(--ink-3);
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.prose table tbody td:first-child {
  width: 26%;
  color: var(--ink);
  font-weight: 600;
}
.prose table tbody tr:last-child td {
  border-bottom: 0;
}
.prose table tbody td {
  color: var(--ink-2);
}

/* ---- operator console --------------------------------------------------------------- */

/* The view switcher and the actions were one undifferentiated row of five buttons in three
   sizes. A segmented control reads as "pick a view"; the actions sit apart from it. */
.console-bar {
  display: flex;
  align-items: center;
  gap: var(--s2);
  margin: 0 0 var(--s4);
  padding: var(--s2) 0 0;
  flex-wrap: wrap;
}
.segmented {
  display: inline-flex;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  overflow: hidden;
}
.segmented button {
  appearance: none;
  border: 0;
  border-right: 1px solid var(--line-2);
  background: transparent;
  color: var(--ink-2);
  font: inherit;
  font-size: var(--fs-chrome);
  font-weight: 600;
  padding: var(--s1) var(--s3);
  min-height: 32px;
  cursor: pointer;
}
.segmented button:last-child {
  border-right: 0;
}
.segmented button:hover {
  color: var(--ink);
  background: var(--panel);
}
.segmented button[aria-pressed="true"] {
  background: var(--accent-strong);
  color: var(--accent-ink);
}
.segmented button:focus-visible {
  outline-offset: -3px;
}
.console-actions {
  display: flex;
  gap: var(--s1);
  margin-left: auto;
}
.console-actions .btn {
  font-size: var(--fs-chrome);
}

/* Sections need rhythm between them: the one-time-key panel and the key list below it
   were touching with no gap at 390. */
.auth-main section + section,
.auth-main section > p + ul,
.auth-main section > ul + p {
  margin-top: var(--s5);
}
.auth-main section > h2 + p {
  margin-top: 0;
}
.auth-main section > .auth-hint + .pack-grid {
  margin-top: var(--s3);
}

/* Stacked cards inside a console section were flush against each other — two cards with
   touching borders read as one broken card. */
.auth-main section > .auth-card + .auth-card,
.auth-main section > .auth-card + .pack-grid,
.auth-main section > .console-setup + .pack-grid,
.auth-main section > .pack-grid + .auth-card {
  margin-top: var(--s3);
}
/* The two setup forms are the same kind of thing, so they sit side by side and fill the
   console's width instead of stacking down the left third of it. */
.console-setup {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--s3);
  align-items: start;
}
.console-setup .auth-card {
  max-width: none;
  height: 100%;
}

/* A wallet/key/metric card is a labelled record, not a pricing card: a denser grid, a
   clear figure, and the opaque id demoted to monospace reference text. */
.record-grid {
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--s2);
}
.metric-grid {
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: var(--s2);
}
.record-grid .pack,
.metric-grid .pack {
  gap: var(--s0);
  padding: var(--s3);
}
.record-figure {
  color: var(--ink);
  font-size: 17px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  overflow-wrap: anywhere;
}
.record-figure.is-ok {
  color: var(--ok);
}
.record-figure.is-bad {
  color: var(--warn);
}
.record-label {
  color: var(--ink-3);
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
}
.record-unit,
.record-meta {
  color: var(--ink-3);
  font-size: var(--fs-chrome);
}
.record-unit {
  margin-top: -2px;
  margin-bottom: var(--s0);
}
.record-id {
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--fs-mono);
  overflow-wrap: anywhere;
}
.metric .record-figure {
  margin-top: var(--s0);
}
.pack .record-actions {
  display: flex;
  gap: var(--s1);
  margin-top: var(--s3);
  padding-top: var(--s3);
  border-top: 1px solid var(--line);
  flex-wrap: wrap;
}
.pack .record-actions .btn {
  margin-top: 0;
  width: auto;
  flex: 1 1 auto;
}
/* A one-time secret: it is the only thing on the page worth looking at while it shows. */
#issued .auth-card {
  max-width: none;
  border-color: var(--warn-line);
  background: var(--warn-bg);
}
#issued-key {
  display: block;
  padding: var(--s3);
  background: var(--sunken);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  color: var(--spot);
  font-family: var(--mono);
  font-size: 14px;
  overflow-wrap: anywhere;
  user-select: all;
}

/* The live/revoked state of a key, and the paused/open state of trials, must be visible
   at a glance rather than read out of a sentence. */
.state-badge {
  align-self: flex-start;
  padding: 1px var(--s1);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.pack[data-live="true"] .pack-price,
.state-badge.is-ok {
  color: var(--ok);
}
.pack[data-live="false"] .pack-price,
.state-badge.is-bad {
  color: var(--ink-3);
}

/* ---- narrow ------------------------------------------------------------------------- */

@media (max-width: 820px) {
  .page-main,
  .auth-main,
  .prose.privacy {
    padding: var(--s5) var(--s3) var(--s6);
  }
  .page-foot {
    padding: var(--s4) var(--s3) var(--s5);
  }
  .page-top {
    padding: var(--s1) var(--s3);
  }
  .pack-grid,
  .pack-grid.cols-4 {
    grid-template-columns: minmax(0, 1fr);
  }
  .auth-card {
    max-width: none;
  }
  .auth-card .btn,
  .console-actions .btn {
    align-self: stretch;
  }
  /* 44px touch targets. */
  .page-nav a {
    min-height: 44px;
    padding: var(--s2) var(--s3);
  }
  .segmented button {
    min-height: 44px;
    flex: 1 1 0;
  }
  .segmented {
    display: flex;
    width: 100%;
  }
  .console-actions {
    width: 100%;
    margin-left: 0;
  }
  .console-actions .btn {
    flex: 1 1 0;
  }
  .pack .record-actions .btn {
    flex: 1 1 100%;
  }
  .prose table tbody td:first-child {
    width: 34%;
  }
}

/* =====================================================================================
   THE FRONT DOOR, COST VISIBILITY, AND THE SETTINGS SURFACE
   =====================================================================================
   Three additions, all inside the fixed dense workbench (D-23) rather than beside it:

     * the balance chip in the masthead, so the cost of a click is never a surprise;
     * the signed-out front door and the three refusal panels, which replace a raw server
       string ("Authentication required") rendered as a turn error;
     * the Settings popover, which replaced the About popover and now has to hold a theme,
       the request-side selects, an account, a balance and a placeholder — so it scrolls
       inside itself instead of running off the bottom of a laptop screen.

   Nothing here introduces a literal colour. Every surface is a token, so all of it themes. */

/* ---- the balance chip ---- */

.balance-chip {
  display: inline-flex;
  align-items: baseline;
  gap: var(--s0);
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}
.balance-chip[hidden] {
  display: none;
}
.balance-dot {
  font-size: 8px;
  line-height: 1;
  color: var(--ok);
  transform: translateY(-1px);
}
.balance-total {
  font-weight: 700;
  color: var(--ink);
}
.balance-unit,
.balance-split {
  font-size: var(--fs-micro);
  color: var(--ink-3);
}
.balance-split:empty {
  display: none;
}
/* Amber at less than one Deep answer, red at nothing left. The thresholds are computed in
   app.js from the served tariff; this only paints the verdict. */
.balance-chip[data-tone="low"] {
  border-color: var(--warn-line);
}
.balance-chip[data-tone="low"] .balance-dot {
  color: var(--warn);
}
.balance-chip[data-tone="zero"] {
  border-color: var(--bad-line);
  background: var(--bad-bg);
}
.balance-chip[data-tone="zero"] .balance-dot,
.balance-chip[data-tone="zero"] .balance-total {
  color: var(--bad);
}

/* ---- the signed-out front door ----
   Shares the cold start's geometry (the `.buf-intro-*` type scale) so the two states feel
   like one room with the lights switched, not two different products. Which one appears is
   decided by the session probe, never guessed: before the probe answers NEITHER is shown,
   because flashing "invite only" at a paying customer and handing a product tour to a
   stranger are both wrong, and a few milliseconds of nothing is neither. */
.buf-gate {
  display: none;
}
body.session-in .turns:empty ~ .buf-intro {
  display: flex;
  flex: 1;
  min-height: 0;
  align-items: center;
  justify-content: center;
  padding: var(--s5) var(--s4);
}
body:not(.session-in) .turns:empty ~ .buf-intro {
  display: none;
}
body.session-out .turns:empty ~ .buf-gate {
  display: flex;
  flex: 1;
  min-height: 0;
  align-items: center;
  justify-content: center;
  padding: var(--s5) var(--s4);
}
.buf-gate-in {
  max-width: 54ch;
}
.buf-gate-terms {
  margin: 0 0 var(--s4);
  padding: var(--s3);
  border: 1px solid var(--line);
  border-left: 2px solid var(--accent);
  border-radius: var(--r-lg);
  background: var(--panel);
  color: var(--ink-2);
  font-size: var(--fs-ui);
  line-height: 1.55;
}
.buf-gate-terms b {
  color: var(--ink);
}
.buf-gate-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin: 0 0 var(--s4);
}
.buf-gate-foot {
  margin: 0 0 var(--s2);
  color: var(--ink-3);
  font-size: var(--fs-chrome);
  line-height: 1.5;
}
.buf-gate-foot:last-child {
  margin-bottom: 0;
}

/* The composer is inert until there is a session. It has to LOOK inert too: a live-looking
   field that silently refuses every keystroke is the same dead end in a quieter costume. */
.input input:disabled,
.mode-toggle button:disabled,
.chip-btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
.input input:disabled {
  background: var(--panel-sub);
}

/* ---- the refusal panels (401 / 402 / 403) ----
   A STATE, not an error. `.turn-error` is red because something broke; running out of credits
   is a bill, a dead session is a sign-in, and an unentitled feature is an upgrade — painting
   all three red teaches the user to ignore red. */
.gate-panel {
  margin: var(--s2) 0 0;
  padding: var(--s3);
  border: 1px solid var(--line-2);
  border-left: 2px solid var(--accent);
  border-radius: var(--r-lg);
  background: var(--panel-sub);
}
.gate-panel.gate-credits {
  border-left-color: var(--warn);
}
.gate-panel.gate-deep {
  border-left-color: var(--spot);
}
.gate-title {
  margin: 0 0 var(--s1);
  color: var(--ink);
  font-size: var(--fs-h3);
  font-weight: 650;
}
.gate-body {
  margin: 0 0 var(--s3);
  max-width: var(--measure);
  color: var(--ink-2);
  font-size: var(--fs-ui);
  line-height: 1.55;
}
.gate-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}
.gate-actions .btn {
  text-decoration: none;
}

/* ---- the Settings surface ----
   The About popover held three groups. Settings holds seven and will hold more, so it is
   bounded by the viewport and scrolls inside itself. Without this it simply ran off the
   bottom of a 900px laptop and the privacy link was unreachable. */
.settings-menu {
  max-height: calc(100vh - 64px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.settings-menu .search-options {
  background: transparent;
  border-top: 0;
  padding: var(--s0) var(--s3) var(--s2);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s2);
}
.settings-menu .search-options .opt {
  display: grid;
  /* `max-content`, not a fixed em width. A 5.5em column was narrower than the words in it:
     "LANGUAGE" and "FRESHNESS" are uppercase and letter-spaced, so they ran under the select
     and rendered as "LANGUAG" / "FRESHNES". Found by looking at the menu, not by any
     assertion — every id was present and every control was visible and clickable. */
  grid-template-columns: max-content minmax(0, 1fr);
  align-items: center;
  gap: var(--s2);
}
.settings-menu .search-options select {
  width: 100%;
  min-width: 0;
  min-height: 30px;
}

/* Theme: three segments, one row. A radio group rather than a cycling button, because a
   cycling button cannot say what the other two options are. */
.theme-field {
  margin: 0;
  padding: var(--s0) var(--s3) 0;
  border: 0;
}
.theme-choice {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  overflow: hidden;
}
.theme-option {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 30px;
  padding: var(--s0) var(--s1);
  border-right: 1px solid var(--line-2);
  color: var(--ink-2);
  font-size: var(--fs-chrome);
  font-weight: 600;
  cursor: pointer;
}
.theme-option:last-child {
  border-right: 0;
}
.theme-option:hover {
  background: var(--panel);
  color: var(--ink);
}
/* The radio itself is the accessible control and stays focusable; it is laid over the
   segment rather than hidden, so `:focus-visible` still draws a ring in the right place. */
.theme-option input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.theme-option:has(input:checked) {
  background: var(--accent-strong);
  color: var(--accent-ink);
}
.theme-option:has(input:focus-visible) {
  outline: 3px solid var(--focus);
  outline-offset: -3px;
}

/* The placeholder for a surface that does not exist yet. It is dimmed, disabled and labelled,
   and it is a <button> rather than an <a> precisely so it cannot navigate anywhere. */
.about-placeholder {
  appearance: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s2);
  width: 100%;
  margin: 0;
  padding: var(--s1) var(--s3);
  border: 0;
  border-left: 2px solid transparent;
  background: none;
  color: var(--ink-3);
  font: inherit;
  font-size: var(--fs-ui);
  text-align: left;
  cursor: not-allowed;
}
.about-soon {
  flex: 0 0 auto;
  padding: 0 var(--s1);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  color: var(--ink-3);
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

@media (max-width: 820px) {
  /* The split is the first thing to go when the masthead gets tight: the total is the number
     that matters at a glance, and Settings → Cost always carries the full breakdown. */
  .balance-split {
    display: none;
  }
}

@media (max-width: 420px) {
  /* The touch floor the rest of this breakpoint already meets. `.about-action` was 28px —
     it was the only control in the menu, and now it sits beside Sign out. */
  .about-action,
  .about-placeholder,
  .theme-option,
  .settings-menu .search-options select {
    min-height: 44px;
  }
  .settings-menu {
    max-height: calc(100vh - 56px);
  }
}

/* ---- where the balance lives, by width ----
   The masthead at 360 is full to the pixel: brand + the three tool chips + Settings already
   consume all 344 available, and the three-row topbar that once ate 135px of an 800px phone
   viewport is a closed defect, not a budget. So the chip is a DESKTOP affordance and the
   status line carries the balance on a phone — persistent either way, never both at once. */
.status-balance {
  display: none;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--ink);
}
.status-balance[data-tone="low"] {
  color: var(--warn);
}
.status-balance[data-tone="zero"] {
  color: var(--bad);
}

@media (max-width: 820px) {
  .balance-chip {
    display: none;
  }
  .status-balance {
    display: inline;
  }
}

/* On a phone the Settings popover is a bottom sheet anchored to the VIEWPORT, not to the
   Settings button. `.about` wraps away from the right edge at 360, and an absolutely
   positioned `right: 0` menu then hangs ~195px off the left of the screen — found by
   measuring the box, which is the only way to see it. */
@media (max-width: 480px) {
  .settings-menu {
    position: fixed;
    inset: auto var(--s2) var(--s2) var(--s2);
    max-width: none;
    max-height: min(72vh, calc(100vh - 96px));
  }
}

@media (max-width: 420px) {
  /* The masthead at 360 is full to the PIXEL: brand + the three tool chips + Settings came to
     343 of 344 usable. The Deep toggle's new cost badge pushed Settings onto a third row and
     the topbar back to 135px of an 800px viewport — the exact regression that was fixed once
     already, and one a DOM assertion cannot see. The badge is not negotiable (a price the
     user cannot read is the problem this release exists to fix), so the room comes out of
     horizontal padding and inter-chip gaps instead. Nothing vertical is touched: height is
     the touch dimension and the 44px floor stands. */
  .topbar-tools {
    gap: 2px;
  }
  .topbar-tools .chip-btn,
  .about-toggle {
    padding-left: 5px;
    padding-right: 5px;
  }
  .deep-toggle {
    gap: 3px;
  }
  .deep-toggle .tab-cost {
    font-size: 9.5px;
  }
}

@media (max-width: 820px) {
  /* The front door gets the same phone treatment the cold start already had. Vertically
     centred, it sat with a ~100px hole under the masthead at 360 and — on a short viewport —
     had no way to reach its own bottom. Top-aligned and scrollable instead. */
  body.session-out .turns:empty ~ .buf-gate {
    align-items: flex-start;
    padding: var(--s4) var(--s3) var(--s5);
    overflow-y: auto;
  }
  .buf-gate .buf-intro-title {
    font-size: 19px;
  }
  .buf-gate .buf-intro-lede {
    margin-bottom: var(--s3);
    font-size: var(--fs-body);
  }
  .buf-gate-terms {
    margin-bottom: var(--s3);
    padding: var(--s2);
    font-size: var(--fs-chrome);
  }
}

/* The Settings menu's vertical rhythm, tightened for ITS density only (the popover vocabulary
   is shared, so this is scoped and does not restyle anything else). At the shipped spacing the
   seven groups came to 943px against 834px of a 1440x900 laptop, and the Privacy group sat
   silently below a hard-cut bottom edge with nothing to say it was there. */
.settings-menu .about-title {
  padding-top: 3px;
  padding-bottom: 2px;
}
.settings-menu .about-note {
  padding-top: 2px;
}
.settings-menu .about-group + .about-group {
  margin-top: 0;
  padding-top: var(--s1);
}
/* When it DOES still overflow (a 768px laptop), SAY SO — with the native affordance rather
   than a gradient. A bottom-edge shade was tried first and is effectively invisible on the
   dark panel it has to sit on, which is worse than nothing: the menu simply looked finished
   where it was actually cut. `scrollbar-width: thin` opts out of Chromium's overlay
   scrollbar, and `scrollbar-gutter: stable` reserves the track so the content does not shift
   by a few pixels the moment it becomes scrollable. */
.settings-menu {
  scrollbar-width: thin;
  scrollbar-color: var(--line-2) transparent;
}
/* "Teaching (LYCEUM)" is one name and must read as one. Left to wrap it broke after
   "Teaching" and the placeholder looked like two separate dead entries. */
.about-placeholder > span:first-child {
  white-space: nowrap;
}
