/* Spectra — the workbench layer.
 *
 * Sits on top of tokens.css, which is copied verbatim from the Brieflings app.
 * That file is the shared contract: if Brieflings retunes its palette or type,
 * Spectra tracks it, and the article-preview pane keeps rendering prose exactly
 * as a reader will see it.
 *
 * This file deliberately does NOT track Brieflings' density. Brieflings is a
 * reading surface — 16-20px radii, 32px card padding, 44px tap targets, soft
 * shadows. Spectra is a workbench: 30px rows, 13px body, 3px radii, and state
 * colours that stay legible at 11px in a table. Everything here lives in the
 * --wb-* namespace so the two systems never collide.
 *
 * Dark is the default. This is a tool opened at 06:45 with three panes of dense
 * data; ink is the right default. The three theme states are handled in the
 * usual way, inverted: bare :root is dark, a system light preference wins unless
 * the operator explicitly chose dark, and an explicit choice always wins.
 *
 * Contrast ratios for every ink/surface and state/surface pair are computed and
 * printed in stylebook/pages/00-foundations.html. If you change a colour here,
 * regenerate them — the page is the argument for the palette, not decoration.
 */

/* ══════════════════════════════════════════════════════════════ 1. Theme ══ */

:root {
  /* — Surfaces. The canvas is the void between panes; panes float above it. — */
  --wb-canvas: #14120f;
  --wb-surface: #1c1916;
  --wb-surface-2: #232019;   /* toolbars, table header, raised card */
  --wb-surface-3: #2b2721;   /* row hover, active tab, input well */
  --wb-surface-4: #35302a;   /* popover, command palette, dropdown */

  /* — Three border weights, three jobs. The split matters: WCAG 1.4.11 wants
   *   3:1 on the boundary of an interactive control, but a row separator is
   *   decorative and a 3:1 hairline across 40 rows is a cage. — */
  --wb-line: #3e3931;           /* decorative hairline: row + pane edges */
  --wb-line-strong: #595146;    /* pane divider, non-interactive emphasis */
  --wb-control-border: #6e6457; /* interactive boundary — 3:1, non-negotiable */

  /* — Ink. Four steps is enough; a fifth always ends up unreadable. — */
  --wb-ink: #efe9e0;
  --wb-ink-2: #b5aea4;       /* secondary */
  --wb-ink-3: #9d9790;       /* muted, column headers, placeholders */
  --wb-ink-4: #80786d;       /* disabled only */

  /* — One saturated accent, split by job. The fill can stay punchy because
   *   the text on it is dark; accent-coloured TEXT on a dark surface has to
   *   be lighter to clear 4.5:1 on surface-4. One token doing both jobs
   *   fails one of them. Brieflings' cadence pastels sit at ~30% saturation
   *   and can carry neither, which is why the terracotta family is pushed. — */
  --wb-accent: #d2704a;        /* fills: buttons, meters, dots, rail */
  --wb-accent-text: #d88261;   /* accent text on a dark surface: links, badges */
  --wb-accent-hover: #e08258;
  --wb-accent-quiet: rgb(210 112 74 / 0.16);
  --wb-accent-line: rgb(210 112 74 / 0.42);
  --wb-accent-ink: #2a1006;    /* text ON the accent fill */

  /* — State. Warm family, but saturated enough to read at 11px. — */
  --wb-ok: #86bb80;
  --wb-warn: #e0aa52;
  --wb-error: #ec8279;
  --wb-info: #86b0cc;
  --wb-ok-quiet: rgb(134 187 128 / 0.15);
  --wb-warn-quiet: rgb(224 170 82 / 0.15);
  --wb-error-quiet: rgb(236 130 121 / 0.15);
  --wb-info-quiet: rgb(134 176 204 / 0.15);

  /* — Severity. The critic panel's vocabulary, used everywhere a challenge
   *   appears. Deliberately the same ramp as state, so the eye only learns
   *   one mapping. — */
  --wb-sev-must: var(--wb-error);
  --wb-sev-should: var(--wb-warn);
  --wb-sev-note: var(--wb-ink-3);

  /* Section identity, reused verbatim from the reader's publication.css so a
   * section looks like itself in both products. Only the saturated accent is
   * used here — the 4px imposition rail and identity swatches. */
  --sec-politics: #6b8060;
  --sec-economy: #9a8352;
  --sec-sport: #5c8378;
  --sec-culture: #96617a;
  --sec-science: #6d74a3;
  --sec-world: #9c6b54;

  --wb-selection: rgb(210 112 74 / 0.3);
  --wb-shadow-pane: none;
  --wb-pane-edge: inset 0 1px 0 rgb(255 255 255 / 0.04);

  /* ── Type ──────────────────────────────────────────────────────────── */
  --wb-font-ui: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --wb-font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  --wb-font-display: 'Fraunces', 'Source Serif 4', Georgia, serif;
  --wb-font-prose: 'Newsreader', 'Source Serif 4', Georgia, serif;

  --ui-3xs: 0.625rem;  /* 10 — kbd, micro-labels */
  --ui-2xs: 0.6875rem; /* 11 — eyebrows, column headers */
  --ui-xs: 0.75rem;    /* 12 — table cells, meta lines */
  --ui-sm: 0.8125rem;  /* 13 — THE WORKHORSE */
  --ui-md: 0.875rem;   /* 14 — inputs, primary list rows */
  --ui-lg: 1rem;       /* 16 — pane titles */
  --ui-xl: 1.25rem;    /* 20 — page title */
  --ui-2xl: 1.625rem;  /* 26 — the one display moment per screen */

  --ui-line-tight: 1.25;
  --ui-line: 1.45;
  --ui-line-loose: 1.6;

  /* ── Density ───────────────────────────────────────────────────────── */
  --wb-1: 2px;
  --wb-2: 4px;
  --wb-3: 6px;
  --wb-4: 8px;
  --wb-5: 12px;
  --wb-6: 16px;
  --wb-7: 24px;
  --wb-8: 32px;
  --wb-9: 48px;

  --h-xs: 22px;  /* inline chip, row action */
  --h-sm: 26px;  /* toolbar button, filter pill, segmented control */
  --h-md: 30px;  /* THE DEFAULT — inputs, selects, primary buttons */
  --h-lg: 36px;  /* the one hero action per screen */
  --row: 30px;
  --row-comfortable: 38px;

  --wb-r-1: 3px;  /* chips, inputs */
  --wb-r-2: 5px;  /* buttons, panes, cards */
  --wb-r-3: 8px;  /* popovers, modals */

  --rail-w: 220px;
  --rail-w-collapsed: 52px;
  --topbar-h: 44px;
  --statusbar-h: 24px;
  --imposition-w: 4px;

  /* ── Motion. 150ms feels laggy when you are scanning 40 rows. ──────── */
  --dur-instant: 80ms;
  --dur-quick: 150ms;
  --dur-standard: 250ms;
  --ease: cubic-bezier(0.2, 0, 0.13, 1);
}

/* Light — applied when the operator has not explicitly chosen dark. Note the
 * inversion: the canvas is DARKER than the panes, so panes read as paper laid
 * on a desk rather than cards floating on grey. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme='dark']) {
    --wb-canvas: #e8e2d7;
    --wb-surface: #faf7f2;
    --wb-surface-2: #ffffff;
    --wb-surface-3: #f1ebe1;
    --wb-surface-4: #ffffff;

    --wb-line: #d5cbba;
    --wb-line-strong: #b5a791;
    --wb-control-border: #9f8d71;

    --wb-ink: #1a1816;
    --wb-ink-2: #57524b;
    --wb-ink-3: #6f6961;
    --wb-ink-4: #8e867c;

    --wb-accent: #a8481f;
    --wb-accent-text: #a8481f;
    --wb-accent-hover: #8d3a17;
    --wb-accent-quiet: rgb(168 72 31 / 0.1);
    --wb-accent-line: rgb(168 72 31 / 0.35);
    --wb-accent-ink: #fffaf7;

    --wb-ok: #3f6b3d;
    --wb-warn: #7d5810;
    --wb-error: #a4322a;
    --wb-info: #2f5d7a;
    --wb-ok-quiet: rgb(63 107 61 / 0.12);
    --wb-warn-quiet: rgb(125 88 16 / 0.13);
    --wb-error-quiet: rgb(164 50 42 / 0.11);
    --wb-info-quiet: rgb(47 93 122 / 0.11);

    --wb-selection: rgb(168 72 31 / 0.2);
    --wb-shadow-pane: 0 1px 0 rgb(0 0 0 / 0.03), 0 2px 6px rgb(0 0 0 / 0.06);
    --wb-pane-edge: none;

    --sec-politics: #b4c6a8;
    --sec-economy: #d8c49c;
    --sec-sport: #a9cdc3;
    --sec-culture: #e0b4c1;
    --sec-science: #b7bcdb;
    --sec-world: #d8a793;
  }
}

/* An explicit choice wins in both directions. */
:root[data-theme='light'] {
  --wb-canvas: #e8e2d7;
  --wb-surface: #faf7f2;
  --wb-surface-2: #ffffff;
  --wb-surface-3: #f1ebe1;
  --wb-surface-4: #ffffff;

  --wb-line: #d5cbba;
  --wb-line-strong: #b5a791;
  --wb-control-border: #9f8d71;

  --wb-ink: #1a1816;
  --wb-ink-2: #57524b;
  --wb-ink-3: #6f6961;
  --wb-ink-4: #8e867c;

  --wb-accent: #a8481f;
  --wb-accent-text: #a8481f;
  --wb-accent-hover: #8d3a17;
  --wb-accent-quiet: rgb(168 72 31 / 0.1);
  --wb-accent-line: rgb(168 72 31 / 0.35);
  --wb-accent-ink: #fffaf7;

  --wb-ok: #3f6b3d;
  --wb-warn: #7d5810;
  --wb-error: #a4322a;
  --wb-info: #2f5d7a;
  --wb-ok-quiet: rgb(63 107 61 / 0.12);
  --wb-warn-quiet: rgb(125 88 16 / 0.13);
  --wb-error-quiet: rgb(164 50 42 / 0.11);
  --wb-info-quiet: rgb(47 93 122 / 0.11);

  --wb-selection: rgb(168 72 31 / 0.2);
  --wb-shadow-pane: 0 1px 0 rgb(0 0 0 / 0.03), 0 2px 6px rgb(0 0 0 / 0.06);
  --wb-pane-edge: none;

  --sec-politics: #b4c6a8;
  --sec-economy: #d8c49c;
  --sec-sport: #a9cdc3;
  --sec-culture: #e0b4c1;
  --sec-science: #b7bcdb;
  --sec-world: #d8a793;
}

/* ═════════════════════════════════════════════ 2. Section identity ══ */

/* The --sec-* values live in the theme blocks above, so there are exactly three
 * palette blocks to keep in step rather than six. All that is left here is the
 * mapping from a section slug to the ambient accent the imposition rail and the
 * identity swatches read. */
[data-section='politics'] { --section-accent: var(--sec-politics); }
[data-section='economy']  { --section-accent: var(--sec-economy); }
[data-section='sport']    { --section-accent: var(--sec-sport); }
[data-section='culture']  { --section-accent: var(--sec-culture); }
[data-section='science']  { --section-accent: var(--sec-science); }
[data-section='world']    { --section-accent: var(--sec-world); }

/* ═══════════════════════════════════════════════════ 3. Element base ══ */

body {
  background: var(--wb-canvas);
  color: var(--wb-ink);
  font-family: var(--wb-font-ui);
  font-size: var(--ui-sm);
  line-height: var(--ui-line);
  letter-spacing: -0.006em;
  /* tnum: every number in this app sits in a column. cv05: a lowercase l with
   * a tail, so l/1/I are distinguishable in an id at 11px. */
  font-feature-settings: 'tnum' 1, 'cv05' 1;
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--wb-selection); }

h1, h2, h3, h4, h5, h6 {
  font-weight: 600;
  line-height: var(--ui-line-tight);
  letter-spacing: -0.011em;
}

a { color: var(--wb-accent-text); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--wb-accent-hover); }

code, pre, kbd, samp { font-family: var(--wb-font-mono); }

/* One focus treatment everywhere. Keyboard is a primary input here, so it has
 * to be unmistakable without being loud enough to hurt at 40 rows. */
:focus-visible {
  outline: 2px solid var(--wb-accent);
  outline-offset: 1px;
  border-radius: var(--wb-r-1);
}
:focus:not(:focus-visible) { outline: none; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ═══════════════════════════════════════════════════ 4. Type helpers ══ */

.wb-mono { font-family: var(--wb-font-mono); font-feature-settings: 'tnum' 1; }
.wb-num  { font-variant-numeric: tabular-nums; text-align: right; }

/* The eyebrow: 11px caps, tracked. Column headers, pane labels, group titles. */
.wb-eyebrow {
  font-size: var(--ui-2xs);
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--wb-ink-3);
}

/* The one display moment per screen. Used once. Twice is a mistake. */
.wb-display {
  font-family: var(--wb-font-display);
  font-size: var(--ui-2xl);
  font-weight: 600;
  font-optical-sizing: auto;
  letter-spacing: -0.015em;
  color: var(--wb-ink);
}

.wb-page-title {
  font-family: var(--wb-font-display);
  font-size: var(--ui-xl);
  font-weight: 600;
  letter-spacing: -0.012em;
}

.wb-muted { color: var(--wb-ink-3); }
.wb-dim   { color: var(--wb-ink-4); }

/* ═════════════════════════════════════════════════════ 5. Primitives ══ */

/* ── Button ───────────────────────────────────────────────────────────── */

.wb-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--wb-3);
  block-size: var(--h-md);
  padding-inline: var(--wb-5);
  border: 1px solid var(--wb-control-border);
  border-radius: var(--wb-r-2);
  background: var(--wb-surface-2);
  color: var(--wb-ink);
  font: inherit;
  font-size: var(--ui-sm);
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur-instant) var(--ease),
              border-color var(--dur-instant) var(--ease);
}
.wb-btn:hover { background: var(--wb-surface-3); border-color: var(--wb-ink-4); }
.wb-btn:active { transform: translateY(0.5px); }

.wb-btn--primary {
  background: var(--wb-accent);
  border-color: var(--wb-accent);
  color: var(--wb-accent-ink);
  font-weight: 600;
}
.wb-btn--primary:hover { background: var(--wb-accent-hover); border-color: var(--wb-accent-hover); }

.wb-btn--ghost { background: transparent; border-color: transparent; color: var(--wb-ink-2); }
.wb-btn--ghost:hover { background: var(--wb-surface-3); border-color: transparent; color: var(--wb-ink); }

.wb-btn--danger { border-color: var(--wb-error); color: var(--wb-error); background: transparent; }
.wb-btn--danger:hover { background: var(--wb-error-quiet); }

.wb-btn--xs { block-size: var(--h-xs); padding-inline: var(--wb-3); font-size: var(--ui-xs); }
.wb-btn--sm { block-size: var(--h-sm); padding-inline: var(--wb-4); font-size: var(--ui-xs); }
.wb-btn--lg { block-size: var(--h-lg); padding-inline: var(--wb-6); font-size: var(--ui-md); }

.wb-btn[disabled], .wb-btn[aria-disabled='true'] {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}

/* ── Fields ───────────────────────────────────────────────────────────── */

.wb-input, .wb-select, .wb-textarea {
  inline-size: 100%;
  block-size: var(--h-md);
  padding-inline: var(--wb-4);
  border: 1px solid var(--wb-control-border);
  border-radius: var(--wb-r-1);
  background: var(--wb-surface-3);
  color: var(--wb-ink);
  font: inherit;
  font-size: var(--ui-md);
  transition: border-color var(--dur-instant) var(--ease);
}
.wb-textarea { block-size: auto; padding-block: var(--wb-3); line-height: var(--ui-line); resize: vertical; }
/* ink-3, not ink-4: placeholder text carries meaning and is not WCAG-exempt
 * the way a disabled control is. */
.wb-input::placeholder, .wb-textarea::placeholder { color: var(--wb-ink-3); }
.wb-input:hover, .wb-select:hover, .wb-textarea:hover { border-color: var(--wb-ink-4); }
.wb-input:focus, .wb-select:focus, .wb-textarea:focus {
  border-color: var(--wb-accent);
  background: var(--wb-surface-2);
}
.wb-select {
  appearance: none;
  padding-inline-end: var(--wb-7);
  background-image: linear-gradient(45deg, transparent 50%, currentcolor 50%),
                    linear-gradient(135deg, currentcolor 50%, transparent 50%);
  background-position: calc(100% - 14px) 55%, calc(100% - 9px) 55%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.wb-field { display: flex; flex-direction: column; gap: var(--wb-2); }
.wb-label {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--wb-4);
  font-size: var(--ui-2xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--wb-ink-3);
}

/* ── Chip / badge / dot ───────────────────────────────────────────────── */

.wb-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--wb-2);
  block-size: var(--h-xs);
  padding-inline: var(--wb-3);
  border: 1px solid var(--wb-control-border);
  border-radius: var(--wb-r-1);
  background: var(--wb-surface-3);
  color: var(--wb-ink-2);
  font-size: var(--ui-xs);
  white-space: nowrap;
}
.wb-chip--on { border-color: var(--wb-accent-line); background: var(--wb-accent-quiet); color: var(--wb-accent-text); }

.wb-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--wb-2);
  padding: 1px var(--wb-3);
  border-radius: var(--wb-r-1);
  font-size: var(--ui-2xs);
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.wb-badge--ok    { background: var(--wb-ok-quiet);    color: var(--wb-ok); }
.wb-badge--warn  { background: var(--wb-warn-quiet);  color: var(--wb-warn); }
.wb-badge--error { background: var(--wb-error-quiet); color: var(--wb-error); }
.wb-badge--info  { background: var(--wb-info-quiet);  color: var(--wb-info); }
.wb-badge--quiet { background: var(--wb-surface-3);   color: var(--wb-ink-3); }
.wb-badge--accent{ background: var(--wb-accent-quiet);color: var(--wb-accent-text); }

/* The run-state ramp. One vocabulary, used identically on badges, timeline
 * nodes and table dots, so the mapping is learned once. */
.wb-dot {
  inline-size: 7px;
  block-size: 7px;
  border-radius: 999px;
  flex: none;
  background: currentcolor;
}
.wb-dot--hollow { background: transparent; box-shadow: inset 0 0 0 1.5px currentcolor; }
.wb-dot--pulse { animation: wb-pulse 1.4s var(--ease) infinite; }

@keyframes wb-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

.is-queued    { color: var(--wb-ink-3); }
.is-running   { color: var(--wb-accent-text); }
.is-succeeded { color: var(--wb-ok); }
.is-nooutput  { color: var(--wb-ink-3); }
.is-held      { color: var(--wb-warn); }
.is-failed    { color: var(--wb-error); }
.is-cancelled { color: var(--wb-ink-4); }

/* ── Severity, for critic challenges ──────────────────────────────────── */

.wb-sev {
  display: inline-flex;
  align-items: center;
  gap: var(--wb-2);
  font-size: var(--ui-2xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.wb-sev--must   { color: var(--wb-sev-must); }
.wb-sev--should { color: var(--wb-sev-should); }
.wb-sev--note   { color: var(--wb-sev-note); }

/* ── kbd ──────────────────────────────────────────────────────────────── */

/* Key names are SHORT TEXT, not Apple glyphs.
 *
 * Two reasons, both learned the hard way on the foundations page. The vendored
 * JetBrains Mono subsets are latin + latin-ext, so U+2318 (⌘), U+23CE (⏎) and
 * friends are not in them and fall back to whatever the system happens to have —
 * inconsistent everywhere and missing on some Linux installs. And ⌘ is a macOS
 * assumption in the first place: on Linux and Windows the modifier is Ctrl, so
 * printing ⌘ is not merely a rendering problem, it is wrong.
 *
 * Write Ctrl. keys.js rewrites it to ⌘ at runtime on macOS, where that glyph
 * is guaranteed to exist. One chip holds one key or one whole combo. */
.wb-kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-inline-size: 18px;
  block-size: 18px;
  padding-inline: 5px;
  border: 1px solid var(--wb-line-strong);
  border-radius: var(--wb-r-1);
  background: var(--wb-surface-2);
  color: var(--wb-ink-2);
  font-family: var(--wb-font-mono);
  font-size: var(--ui-2xs);
  line-height: 1;
  white-space: nowrap;
}

/* ── Meter ────────────────────────────────────────────────────────────── */

.wb-meter {
  block-size: 4px;
  inline-size: 100%;
  border-radius: 999px;
  background: var(--wb-surface-3);
  overflow: hidden;
}
.wb-meter__fill { block-size: 100%; background: var(--wb-accent); border-radius: 999px; }
.wb-meter__fill--warn { background: var(--wb-warn); }
.wb-meter__fill--error { background: var(--wb-error); }

/* ── Pane + imposition rail ───────────────────────────────────────────── */

.wb-pane {
  background: var(--wb-surface);
  border: 1px solid var(--wb-line);
  border-radius: var(--wb-r-2);
  box-shadow: var(--wb-shadow-pane), var(--wb-pane-edge);
}

/* Not navigation, not clickable. A 4px ambient identity band at the extreme
 * edge — the digital equivalent of the coloured tab on a physical file. Three
 * panes deep in a run inspector it is the only thing telling you whose
 * pipeline this is, and it costs 4px. */
.wb-imposition {
  inline-size: var(--imposition-w);
  background: var(--section-accent, var(--wb-line));
  flex: none;
}

.wb-rule { border: 0; border-block-start: 1px solid var(--wb-line); margin: 0; }

/* ═══════════════════════════════════════════════════════ 6. The shell ══ */

/* 4px imposition rail | 44px top bar | body | 24px status bar.
 * The shell owns the viewport; only pane interiors scroll. Nothing here is
 * responsive below 1024 on purpose — see .wb-toosmall at the end. */

.wb-shell {
  display: flex;
  block-size: 100dvh;
  overflow: hidden;
  background: var(--wb-canvas);
}
.wb-shell__main { display: flex; flex-direction: column; flex: 1; min-inline-size: 0; }

/* ── Top bar ──────────────────────────────────────────────────────── */

.wb-topbar {
  display: flex;
  align-items: center;
  gap: var(--wb-5);
  block-size: var(--topbar-h);
  flex: none;
  padding-inline: var(--wb-5);
  background: var(--wb-surface-2);
  border-block-end: 1px solid var(--wb-line);
}
.wb-wordmark {
  font-family: var(--wb-font-display);
  font-size: var(--ui-lg);
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--wb-ink);
  flex: none;
}
.wb-topbar__right { display: flex; align-items: center; gap: var(--wb-4); margin-inline-start: auto; flex: none; }

.wb-env {
  display: inline-flex;
  align-items: center;
  gap: var(--wb-2);
  block-size: var(--h-xs);
  padding-inline: var(--wb-3);
  border-radius: var(--wb-r-1);
  background: var(--wb-info-quiet);
  color: var(--wb-info);
  font-size: var(--ui-2xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.wb-env--prod { background: var(--wb-error-quiet); color: var(--wb-error); }

.wb-avatar {
  display: grid;
  place-items: center;
  inline-size: 24px;
  block-size: 24px;
  border-radius: 999px;
  background: var(--wb-surface-3);
  border: 1px solid var(--wb-control-border);
  font-size: var(--ui-2xs);
  font-weight: 600;
  color: var(--wb-ink-2);
}

/* ── Breadcrumbs are navigation, not labels ───────────────────────── */

/* Each segment is a popover-menu button: clicking "v7" lists every version,
 * clicking a block lists every block. That is how you move sideways without
 * going back. A crumb that is only a label gets no chevron. */
.wb-crumbs { display: flex; align-items: center; gap: var(--wb-1); min-inline-size: 0; font-size: var(--ui-sm); }
.wb-crumb {
  display: inline-flex;
  align-items: center;
  gap: var(--wb-2);
  block-size: var(--h-sm);
  padding-inline: var(--wb-3);
  border: 1px solid transparent;
  border-radius: var(--wb-r-1);
  background: none;
  color: var(--wb-ink-2);
  font: inherit;
  cursor: pointer;
  white-space: nowrap;
}
.wb-crumb:hover { background: var(--wb-surface-3); color: var(--wb-ink); }
.wb-crumb[aria-expanded='true'] { background: var(--wb-surface-3); color: var(--wb-ink); border-color: var(--wb-line-strong); }
.wb-crumb--current { color: var(--wb-ink); font-weight: 500; }
.wb-crumb__caret { color: var(--wb-ink-4); font-size: 9px; }
.wb-crumbs__sep { color: var(--wb-ink-4); flex: none; }

.wb-popover {
  position: absolute;
  z-index: 40;
  min-inline-size: 220px;
  padding: var(--wb-2);
  background: var(--wb-surface-4);
  border: 1px solid var(--wb-line-strong);
  border-radius: var(--wb-r-3);
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.35);
}
.wb-popover__item {
  display: flex;
  align-items: center;
  gap: var(--wb-3);
  inline-size: 100%;
  block-size: var(--h-md);
  padding-inline: var(--wb-4);
  border: 0;
  border-radius: var(--wb-r-1);
  background: none;
  color: var(--wb-ink-2);
  font: inherit;
  font-size: var(--ui-sm);
  text-align: start;
  cursor: pointer;
}
.wb-popover__item:hover { background: var(--wb-surface-3); color: var(--wb-ink); }
.wb-popover__item[aria-current='true'] { color: var(--wb-accent-text); }
.wb-popover__meta { margin-inline-start: auto; font-size: var(--ui-2xs); color: var(--wb-ink-3); font-family: var(--wb-font-mono); }

/* ── Search field in the top bar ──────────────────────────────────── */

.wb-omnibar {
  display: flex;
  align-items: center;
  gap: var(--wb-3);
  inline-size: min(420px, 34vw);
  block-size: var(--h-sm);
  padding-inline: var(--wb-4);
  border: 1px solid var(--wb-control-border);
  border-radius: var(--wb-r-2);
  background: var(--wb-surface);
  color: var(--wb-ink-3);
  font-size: var(--ui-xs);
  cursor: text;
  margin-inline: auto;
}
.wb-omnibar:hover { border-color: var(--wb-ink-4); }

/* ── Body: rail + panes ───────────────────────────────────────────── */

.wb-body { display: flex; flex: 1; min-block-size: 0; }

/* The rail has three states, driven by one set of custom properties so the
 * collapsed styling is written once:
 *
 *   auto       collapse below 1440, expand above it   (the default)
 *   expanded   always full, whatever the viewport
 *   collapsed  always icons
 *
 * `auto` exists because of an arithmetic problem this mock surfaced. At the
 * minimum 1280 viewport, a full rail plus the authored list and inspector
 * widths left the primary pane at 384px — too narrow to read a rendered prompt
 * or edit an article in, which is the one thing the centre column is for.
 * Collapsing the rail below 1440 buys it back 168px. */
.wb-shell {
  --rail-current: var(--rail-w);
  --rail-pad-inline: var(--wb-4);
  --rail-label-display: block;
  --rail-item-justify: flex-start;
  --rail-item-pad: var(--wb-3);
}
.wb-shell[data-rail='collapsed'] {
  --rail-current: var(--rail-w-collapsed);
  --rail-pad-inline: var(--wb-3);
  --rail-label-display: none;
  --rail-item-justify: center;
  --rail-item-pad: 0;
}
@media (max-width: 1439px) {
  .wb-shell[data-rail='auto'] {
    --rail-current: var(--rail-w-collapsed);
    --rail-pad-inline: var(--wb-3);
    --rail-label-display: none;
    --rail-item-justify: center;
    --rail-item-pad: 0;
  }
}

.wb-rail {
  inline-size: var(--rail-current);
  flex: none;
  padding: var(--wb-5) var(--rail-pad-inline);
  background: var(--wb-surface-2);
  border-inline-end: 1px solid var(--wb-line);
  overflow-y: auto;
  overflow-x: hidden;
  transition: inline-size var(--dur-standard) var(--ease);
}

.wb-rail__group {
  font-size: var(--ui-2xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--wb-ink-4);
  padding-inline: var(--wb-3);
  margin-block: var(--wb-5) var(--wb-2);
}
.wb-rail__group:first-child { margin-block-start: 0; }
.wb-rail__group, .wb-rail__count { display: var(--rail-label-display); }
.wb-rail__label { display: var(--rail-label-display); }
.wb-rail__item {
  display: flex;
  align-items: center;
  justify-content: var(--rail-item-justify);
  gap: var(--wb-4);
  block-size: var(--h-md);
  padding-inline: var(--rail-item-pad);
  border-radius: var(--wb-r-1);
  color: var(--wb-ink-2);
  font-size: var(--ui-sm);
  text-decoration: none;
  white-space: nowrap;
}
.wb-rail__item:hover { background: var(--wb-surface-3); color: var(--wb-ink); }
.wb-rail__item[aria-current='page'] {
  background: var(--wb-accent-quiet);
  color: var(--wb-accent-text);
  font-weight: 500;
  box-shadow: inset 2px 0 0 var(--wb-accent);
}
.wb-rail__icon { inline-size: 16px; text-align: center; flex: none; color: var(--wb-ink-3); font-size: var(--ui-xs); }
.wb-rail__item[aria-current='page'] .wb-rail__icon { color: var(--wb-accent-text); }
.wb-rail__count {
  margin-inline-start: auto;
  font-family: var(--wb-font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--ui-2xs);
  color: var(--wb-ink-3);
}

/* ── Three-pane grammar ───────────────────────────────────────────── */

/* The same three panes on every heavy screen, so muscle memory transfers:
 * the set you are working through, the thing, and its properties. */
.wb-panes { display: flex; flex: 1; min-inline-size: 0; padding: var(--wb-4); gap: 0; }
.wb-panes > .wb-pane { display: flex; flex-direction: column; min-block-size: 0; overflow: hidden; }
/* Authored widths are the minimum that still work at a 1280 viewport, not the
 * most comfortable. Panes are resizable and persist per route, so an operator
 * on a large screen widens them once and never thinks about it again. */
.wb-pane--list { inline-size: 260px; flex: none; }
.wb-pane--primary { flex: 1; min-inline-size: 420px; }
.wb-pane--inspector { inline-size: 300px; flex: none; }
.wb-pane__scroll { overflow-y: auto; flex: 1; min-block-size: 0; }

.wb-grip {
  inline-size: var(--wb-4);
  flex: none;
  cursor: col-resize;
  position: relative;
  background: none;
  border: 0;
  padding: 0;
}
.wb-grip::after {
  content: '';
  position: absolute;
  inset-block: 12px;
  inset-inline-start: 50%;
  inline-size: 1px;
  background: var(--wb-line);
  transition: background var(--dur-instant) var(--ease), inline-size var(--dur-instant) var(--ease);
}
.wb-grip:hover::after, .wb-grip:focus-visible::after { background: var(--wb-accent); inline-size: 2px; }

/* ── Pane furniture ───────────────────────────────────────────────── */

.wb-pane__toolbar {
  display: flex;
  align-items: center;
  gap: var(--wb-4);
  block-size: 40px;
  flex: none;
  padding-inline: var(--wb-5);
  background: var(--wb-surface-2);
  border-block-end: 1px solid var(--wb-line);
}
.wb-pane__title { font-size: var(--ui-sm); font-weight: 600; white-space: nowrap; }
.wb-pane__tools { display: flex; align-items: center; gap: var(--wb-3); margin-inline-start: auto; }

/* Sticky, never a modal. A modal to save is an interruption; a bar that
 * appears when the thing is dirty is a status. */
.wb-savebar {
  display: flex;
  align-items: center;
  gap: var(--wb-4);
  block-size: 36px;
  flex: none;
  padding-inline: var(--wb-5);
  background: var(--wb-surface-2);
  border-block-start: 1px solid var(--wb-line);
  box-shadow: inset 2px 0 0 var(--wb-accent);
  font-size: var(--ui-xs);
  color: var(--wb-ink-2);
}
.wb-savebar__actions { display: flex; align-items: center; gap: var(--wb-3); margin-inline-start: auto; }

/* ── Status bar ───────────────────────────────────────────────────── */

/* Editors, DAWs and terminals have one. Admin panels don't — which is most of
 * why they read as admin panels. */
.wb-statusbar {
  display: flex;
  align-items: center;
  gap: var(--wb-5);
  block-size: var(--statusbar-h);
  flex: none;
  padding-inline: var(--wb-5);
  background: var(--wb-surface-2);
  border-block-start: 1px solid var(--wb-line);
  font-size: var(--ui-2xs);
  color: var(--wb-ink-3);
  white-space: nowrap;
}
.wb-statusbar__center { margin-inline: auto; display: flex; align-items: center; gap: var(--wb-3); }
/* Pinned right by its own auto margin rather than by the centre group's, because
 * the centre group is a `hidden` toast most of the time — and `hidden` is
 * display:none, so its auto margins contribute nothing. Relying on them left the
 * right group huddled against the spend meter mid-bar. */
.wb-statusbar__right { margin-inline-start: auto; display: flex; align-items: center; gap: var(--wb-5); }
.wb-statusbar strong { color: var(--wb-ink-2); font-weight: 600; }

.wb-spend { display: inline-flex; align-items: center; gap: var(--wb-3); }
.wb-spend__meter { inline-size: 56px; }

/* ── Command palette ──────────────────────────────────────────────── */

.wb-palette {
  position: fixed;
  inset-block-start: 12vh;
  inset-inline: 0;
  z-index: 60;
  inline-size: min(620px, 90vw);
  margin-inline: auto;
  background: var(--wb-surface-4);
  border: 1px solid var(--wb-line-strong);
  border-radius: var(--wb-r-3);
  box-shadow: 0 24px 64px rgb(0 0 0 / 0.45);
  overflow: hidden;
}
.wb-palette__input {
  inline-size: 100%;
  block-size: 44px;
  padding-inline: var(--wb-6);
  border: 0;
  border-block-end: 1px solid var(--wb-line);
  background: none;
  color: var(--wb-ink);
  font: inherit;
  font-size: var(--ui-md);
}
.wb-palette__input:focus { outline: none; }
.wb-palette__list { max-block-size: 46vh; overflow-y: auto; padding: var(--wb-2); }
.wb-palette__group {
  font-size: var(--ui-2xs); font-weight: 600; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--wb-ink-4);
  padding: var(--wb-4) var(--wb-4) var(--wb-2);
}
.wb-palette__item {
  display: flex; align-items: center; gap: var(--wb-4);
  inline-size: 100%; block-size: 32px; padding-inline: var(--wb-4);
  border: 0; border-radius: var(--wb-r-1); background: none;
  color: var(--wb-ink-2); font: inherit; font-size: var(--ui-sm);
  text-align: start; cursor: pointer;
}
.wb-palette__item[aria-selected='true'] { background: var(--wb-accent-quiet); color: var(--wb-accent-text); }
.wb-palette__hint { margin-inline-start: auto; display: flex; gap: var(--wb-2); }
.wb-palette__foot {
  display: flex; gap: var(--wb-5); align-items: center;
  padding: var(--wb-3) var(--wb-6);
  border-block-start: 1px solid var(--wb-line);
  background: var(--wb-surface-2);
  font-size: var(--ui-2xs); color: var(--wb-ink-3);
}
.wb-scrim { position: fixed; inset: 0; z-index: 50; background: rgb(0 0 0 / 0.45); }

/* ── Toast: transient, with an undo ───────────────────────────────── */

/* An 8-second undo beats a confirm dialog for a queue you are clearing fast. */
.wb-toast {
  display: inline-flex; align-items: center; gap: var(--wb-4);
  padding: var(--wb-2) var(--wb-4);
  border-radius: var(--wb-r-1);
  background: var(--wb-surface-3);
  border: 1px solid var(--wb-line-strong);
  font-size: var(--ui-2xs); color: var(--wb-ink-2);
}

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

/* The one screen that is not the shell: there is no navigation to show before
 * you are signed in. It also sits outside the 1024px floor on purpose — you
 * should be able to sign in from anything, and then be told to open a wider
 * window. */
.wb-signin { display: grid; place-items: center; min-block-size: 100dvh; padding: var(--wb-7); }
.wb-signin__card {
  inline-size: min(360px, 100%);
  padding: var(--wb-7);
  background: var(--wb-surface);
  border: 1px solid var(--wb-line);
  border-radius: var(--wb-r-3);
  box-shadow: var(--wb-shadow-pane), var(--wb-pane-edge);
  text-align: center;
}
.wb-signin__mark {
  font-family: var(--wb-font-display);
  font-size: var(--ui-2xl);
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--wb-ink);
}
.wb-signin__sub {
  margin-block: var(--wb-2) var(--wb-6);
  font-size: var(--ui-sm);
  color: var(--wb-ink-3);
}
.wb-signin__cta { inline-size: 100%; justify-content: center; margin-block-start: var(--wb-5); }

/* ═════════════════════════════════════════════════════ 7. Data table ══ */

/* The single most-reused component in the app — run lists, article lists,
 * agents, models, the audit log, the triage lane. Fixing it once is worth more
 * than fixing any screen.
 *
 * No zebra striping: rows separate on a hairline. Zebra fights row hover and
 * selection, and at 30px rows it turns a table into corduroy. */

.wb-table { inline-size: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--ui-xs); }

.wb-table thead th {
  position: sticky;
  inset-block-start: 0;
  z-index: 2;
  background: var(--wb-surface-2);
  border-block-end: 1px solid var(--wb-line-strong);
  padding: 0 var(--wb-4);
  block-size: 28px;
  font-size: var(--ui-2xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--wb-ink-3);
  text-align: start;
  white-space: nowrap;
}

/* Click cycles asc → desc → none. The sorted column gets a 1px accent underline
 * as well as a caret, so the sort is legible without reading the glyph. */
.wb-table__sort {
  display: inline-flex;
  align-items: center;
  gap: var(--wb-2);
  inline-size: 100%;
  block-size: 100%;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
}
.wb-table__sort:hover { color: var(--wb-ink); }
.wb-table__sort .caret { color: var(--wb-ink-4); font-size: 9px; }
.wb-table th[aria-sort] { color: var(--wb-ink); box-shadow: inset 0 -2px 0 var(--wb-accent); }
.wb-table th[aria-sort] .caret { color: var(--wb-accent-text); }
.wb-table th[data-align='end'] .wb-table__sort { justify-content: flex-end; }

.wb-table tbody td {
  block-size: var(--row);
  padding: 0 var(--wb-4);
  border-block-end: 1px solid var(--wb-line);
  color: var(--wb-ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.wb-table tbody tr { transition: background var(--dur-instant) var(--ease); }
.wb-table tbody tr:hover td { background: var(--wb-surface-3); }
.wb-table tbody tr[aria-selected='true'] td { background: var(--wb-accent-quiet); }
.wb-table tbody tr[aria-selected='true'] td:first-child { box-shadow: inset 2px 0 0 var(--wb-accent); }
.wb-table tbody tr[data-focused] td { box-shadow: inset 0 0 0 1px var(--wb-accent-line); }
.wb-table .num { font-family: var(--wb-font-mono); font-variant-numeric: tabular-nums; text-align: end; }
.wb-table .id { font-family: var(--wb-font-mono); color: var(--wb-ink-3); }
.wb-table .grow { inline-size: 100%; max-inline-size: 0; }
.wb-table__check { inline-size: 32px; text-align: center; padding-inline: 0 !important; }

/* Inline editing: a dotted underline says "this is editable" without spending a
 * column on a pencil icon — but only on ROW HOVER. Showing it on all 40 rows at
 * once turns the table into corduroy and stops it meaning anything. */
.wb-cell-editable { cursor: text; text-decoration: underline dotted transparent; text-underline-offset: 3px; }
.wb-table tbody tr:hover .wb-cell-editable { color: var(--wb-ink); text-decoration-color: var(--wb-ink-4); }
.wb-cell-editable:hover { text-decoration-color: var(--wb-accent) !important; }
.wb-cell-edit {
  inline-size: 100%;
  block-size: 24px;
  padding-inline: var(--wb-3);
  border: 1px solid var(--wb-accent);
  border-radius: var(--wb-r-1);
  background: var(--wb-surface-2);
  color: var(--wb-ink);
  font: inherit;
  font-size: var(--ui-xs);
}

/* ── Filter strip + saved views ───────────────────────────────────── */

.wb-filters {
  display: flex;
  align-items: center;
  gap: var(--wb-3);
  padding: var(--wb-3) var(--wb-5);
  border-block-end: 1px solid var(--wb-line);
  background: var(--wb-surface);
  flex-wrap: wrap;
}
.wb-filters__search {
  display: flex; align-items: center; gap: var(--wb-3);
  inline-size: 240px; block-size: var(--h-sm);
  padding-inline: var(--wb-4);
  border: 1px solid var(--wb-control-border);
  border-radius: var(--wb-r-1);
  background: var(--wb-surface-3);
}
.wb-filters__search input { border: 0; background: none; color: var(--wb-ink); font: inherit; font-size: var(--ui-xs); inline-size: 100%; }
.wb-filters__search input:focus { outline: none; }
.wb-filters__count { margin-inline-start: auto; font-size: var(--ui-2xs); color: var(--wb-ink-3); font-family: var(--wb-font-mono); }

/* Filters serialise to the query string, so every view is a shareable URL and
 * a saved view is just a stored one. */
.wb-views { display: flex; align-items: center; gap: var(--wb-1); }
.wb-view {
  display: inline-flex; align-items: center; gap: var(--wb-2);
  block-size: var(--h-sm); padding-inline: var(--wb-4);
  border: 1px solid transparent; border-radius: var(--wb-r-1);
  background: none; color: var(--wb-ink-3);
  font: inherit; font-size: var(--ui-xs); cursor: pointer; white-space: nowrap;
}
.wb-view:hover { background: var(--wb-surface-3); color: var(--wb-ink-2); }
.wb-view[aria-current='true'] {
  background: var(--wb-surface-3); color: var(--wb-ink);
  border-color: var(--wb-line-strong); font-weight: 500;
}

/* ── Bulk bar ─────────────────────────────────────────────────────── */

/* Slides up from the bottom of the table area, not a modal. You keep looking at
 * the rows you selected while you decide what to do with them. */
.wb-bulkbar {
  display: flex;
  align-items: center;
  gap: var(--wb-4);
  block-size: 40px;
  flex: none;
  padding-inline: var(--wb-5);
  background: var(--wb-surface-4);
  border-block-start: 1px solid var(--wb-line-strong);
  box-shadow: 0 -6px 20px rgb(0 0 0 / 0.25);
  font-size: var(--ui-xs);
}
.wb-bulkbar__count { font-weight: 600; color: var(--wb-ink); }
.wb-bulkbar__actions { display: flex; align-items: center; gap: var(--wb-3); margin-inline-start: auto; }

/* ── Empty state: one line and the action. No illustration. ───────── */

.wb-empty { padding: var(--wb-8) var(--wb-5); color: var(--wb-ink-3); font-size: var(--ui-sm); }
.wb-empty__action { margin-block-start: var(--wb-4); }

/* ════════════════════════════════════════════════════ 8. Review desk ══ */

/* ── The queue: the day, not a paginated list ─────────────────────── */

/* Done rows fade but stay, so "7 to clear · 2 done" is honest and you can go
 * back to something you approved two minutes ago. */
.wb-queue { display: flex; flex-direction: column; }
.wb-queue__item {
  display: grid;
  grid-template-columns: 14px 1fr;
  gap: var(--wb-3);
  align-items: start;
  padding: var(--wb-4) var(--wb-5);
  border-block-end: 1px solid var(--wb-line);
  border-inline-start: 2px solid transparent;
  cursor: pointer;
  text-align: start;
  background: none;
  color: inherit;
  font: inherit;
}
.wb-queue__item:hover { background: var(--wb-surface-3); }
.wb-queue__item[aria-current='true'] {
  background: var(--wb-accent-quiet);
  border-inline-start-color: var(--wb-accent);
}
.wb-queue__item[data-done] { opacity: 0.45; }
.wb-queue__mark { font-size: var(--ui-xs); line-height: 1.4; }
.wb-queue__title { font-size: var(--ui-sm); line-height: 1.3; color: var(--wb-ink); }
.wb-queue__meta {
  display: flex; align-items: center; gap: var(--wb-3);
  font-size: var(--ui-2xs); color: var(--wb-ink-3); margin-block-start: var(--wb-2);
}
.wb-queue__swatch { inline-size: 6px; block-size: 6px; border-radius: 2px; background: var(--section-accent); flex: none; }

/* ── Editor field stack ───────────────────────────────────────────── */

.wb-editor { display: flex; flex-direction: column; gap: var(--wb-6); padding: var(--wb-6); }
.wb-editor__field { display: flex; flex-direction: column; gap: var(--wb-3); }
.wb-editor__label {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--wb-4);
  font-size: var(--ui-2xs); font-weight: 600; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--wb-ink-3);
}
/* Each label carries its focus letter on the right. Printing the shortcut on
 * the thing it drives is most of what makes a tool feel keyboard-first. */
.wb-editor__key { font-family: var(--wb-font-mono); color: var(--wb-ink-4); font-weight: 400; }
.wb-editor__count { font-family: var(--wb-font-mono); font-variant-numeric: tabular-nums; color: var(--wb-ink-3); }
.wb-editor__count[data-state='warn'] { color: var(--wb-warn); }
.wb-editor__count[data-state='over'] { color: var(--wb-error); font-weight: 600; }

.wb-headline-input {
  inline-size: 100%;
  padding: var(--wb-4);
  border: 1px solid var(--wb-control-border);
  border-radius: var(--wb-r-1);
  background: var(--wb-surface-3);
  color: var(--wb-ink);
  font-family: var(--wb-font-display);
  font-size: 1.375rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.015em;
}
.wb-standfirst-input {
  inline-size: 100%;
  padding: var(--wb-4);
  border: 1px solid var(--wb-control-border);
  border-radius: var(--wb-r-1);
  background: var(--wb-surface-3);
  color: var(--wb-ink-2);
  font-family: var(--wb-font-prose);
  font-size: 1rem;
  line-height: 1.5;
  resize: vertical;
}
.wb-headline-input:focus, .wb-standfirst-input:focus, .wb-body-input:focus {
  outline: none; border-color: var(--wb-accent); background: var(--wb-surface-2);
}

/* Markdown in a plain textarea, not a WYSIWYG. The pipeline's output IS
 * structured text; contenteditable would force a lossy HTML round-trip through
 * the very document downstream consumers read. The two previews deliver the
 * WYSIWYG benefit without the cost. */
.wb-mdtoolbar {
  display: flex; align-items: center; gap: var(--wb-1);
  padding: var(--wb-2) var(--wb-3);
  border: 1px solid var(--wb-control-border);
  border-block-end: 0;
  border-radius: var(--wb-r-1) var(--wb-r-1) 0 0;
  background: var(--wb-surface-2);
}
.wb-mdtoolbar button {
  inline-size: 24px; block-size: 22px;
  border: 0; border-radius: var(--wb-r-1);
  background: none; color: var(--wb-ink-3);
  font: inherit; font-size: var(--ui-xs); cursor: pointer;
}
.wb-mdtoolbar button:hover { background: var(--wb-surface-3); color: var(--wb-ink); }
.wb-mdtoolbar__spacer { margin-inline-start: auto; font-size: var(--ui-2xs); color: var(--wb-ink-3); }
.wb-body-input {
  inline-size: 100%;
  min-block-size: 220px;
  padding: var(--wb-5);
  border: 1px solid var(--wb-control-border);
  border-radius: 0 0 var(--wb-r-1) var(--wb-r-1);
  background: var(--wb-surface-3);
  color: var(--wb-ink);
  font-family: var(--wb-font-mono);
  font-size: var(--ui-xs);
  line-height: 1.7;
  resize: vertical;
}

/* ── Sources with a corroboration verdict ─────────────────────────── */

/* The verdict glyph comes from verification.claims in the Article Document.
 * This is what makes the sourcing attestation checkable rather than an act of
 * faith — you are ticking a box against evidence, not a feeling. */
.wb-sources { display: flex; flex-direction: column; }
.wb-source {
  display: grid;
  grid-template-columns: 14px 1fr auto;
  gap: var(--wb-4);
  align-items: center;
  padding: var(--wb-3) 0;
  border-block-end: 1px solid var(--wb-line);
  font-size: var(--ui-xs);
}
.wb-source__verdict { text-align: center; font-size: var(--ui-xs); }
.wb-source__verdict[data-verdict='corroborated'] { color: var(--wb-ok); }
.wb-source__verdict[data-verdict='single_source'] { color: var(--wb-warn); }
.wb-source__verdict[data-verdict='unsupported'] { color: var(--wb-error); }
.wb-source__publisher { font-family: var(--wb-font-mono); color: var(--wb-ink-3); font-size: var(--ui-2xs); }

/* ── Challenges the writer did not address ────────────────────────── */

/* The highest-value block on this screen. A reviewer reading these is checking
 * the machine's self-criticism rather than re-reading the piece from scratch. */
.wb-challenge {
  display: flex; flex-direction: column; gap: var(--wb-2);
  padding: var(--wb-4);
  border-inline-start: 2px solid var(--wb-line-strong);
  background: var(--wb-surface-3);
  border-radius: 0 var(--wb-r-1) var(--wb-r-1) 0;
  font-size: var(--ui-xs);
}
.wb-challenge[data-severity='must_address'] { border-inline-start-color: var(--wb-sev-must); }
.wb-challenge[data-severity='should_address'] { border-inline-start-color: var(--wb-sev-should); }
.wb-challenge__head { display: flex; align-items: center; gap: var(--wb-3); }
.wb-challenge__lens { font-family: var(--wb-font-mono); font-size: var(--ui-2xs); color: var(--wb-ink-3); }
.wb-challenge__body { color: var(--wb-ink-2); line-height: 1.45; }
.wb-challenge__why { color: var(--wb-ink-3); font-style: italic; }

/* ── Segmented control + checks ───────────────────────────────────── */

.wb-seg { display: inline-flex; border: 1px solid var(--wb-control-border); border-radius: var(--wb-r-1); overflow: hidden; }
.wb-seg button {
  block-size: var(--h-sm); padding-inline: var(--wb-5);
  border: 0; border-inline-end: 1px solid var(--wb-control-border);
  background: var(--wb-surface-3); color: var(--wb-ink-3);
  font: inherit; font-size: var(--ui-xs); cursor: pointer;
}
.wb-seg button:last-child { border-inline-end: 0; }
.wb-seg button:hover { color: var(--wb-ink); }
.wb-seg button[aria-pressed='true'] { background: var(--wb-accent); color: var(--wb-accent-ink); font-weight: 600; }

.wb-check {
  display: grid; grid-template-columns: 16px 1fr auto; gap: var(--wb-3);
  align-items: start; padding-block: var(--wb-3);
  font-size: var(--ui-xs); color: var(--wb-ink-2); cursor: pointer;
}
.wb-check input { margin-block-start: 2px; }

.wb-note {
  display: flex; align-items: flex-start; gap: var(--wb-3);
  padding: var(--wb-3) var(--wb-4);
  border-radius: var(--wb-r-1);
  font-size: var(--ui-2xs); line-height: 1.45;
}
.wb-note--warn { background: var(--wb-warn-quiet); color: var(--wb-warn); }
.wb-note--error { background: var(--wb-error-quiet); color: var(--wb-error); }

/* ── Reader-fidelity proof ────────────────────────────────────────── */

/* Renders at real publication sizes in the real faces. Nearly free — the type
 * is already vendored — and it is the difference between reviewing the artifact
 * and reviewing a description of it. */
.wb-proof { padding: var(--wb-6); max-inline-size: 62ch; }
.wb-proof__kicker {
  font-family: var(--wb-font-ui); font-size: var(--ui-2xs); font-weight: 600;
  letter-spacing: 0.09em; text-transform: uppercase; color: var(--wb-accent-text);
}
.wb-proof__headline {
  font-family: var(--wb-font-display); font-size: 1.875rem; font-weight: 600;
  line-height: 1.14; letter-spacing: -0.02em; font-optical-sizing: auto;
  margin-block: var(--wb-3) var(--wb-4); color: var(--wb-ink);
}
.wb-proof__standfirst {
  font-family: var(--wb-font-prose); font-size: 1.0625rem; line-height: 1.5;
  color: var(--wb-ink-2); margin-block-end: var(--wb-5);
}
.wb-proof__body { font-family: var(--wb-font-prose); font-size: 1rem; line-height: 1.62; color: var(--wb-ink); }
.wb-proof__body p + p { margin-block-start: var(--wb-5); }
.wb-proof__quote {
  font-family: var(--wb-font-display); font-size: 1.25rem; line-height: 1.35;
  color: var(--wb-ink); border-inline-start: 2px solid var(--section-accent, var(--wb-accent));
  padding-inline-start: var(--wb-5); margin-block: var(--wb-6);
}

/* ── Below 1024: decline, don't squeeze ───────────────────────────── */

.wb-toosmall { display: none; }
@media (max-width: 1023px) {
  .wb-shell { display: none; }
  .wb-toosmall {
    display: grid;
    place-items: center;
    block-size: 100dvh;
    padding: var(--wb-7);
    text-align: center;
    color: var(--wb-ink-2);
    font-size: var(--ui-md);
  }
}
