/* ==========================================================================
   Broker AI — application styles
   Built entirely on tokens.css. No raw hex, no raw px, no raw radius below:
   anything tokens.css did not provide is added to the :root block here.
   ========================================================================== */

:root {
  /* ---- Density. tokens.css carries the source system's airy scale; this is
     a working tool used daily, so the control and type steps tighten. See
     design.md §Density. ---------------------------------------------------- */
  --text-body: 14.5px;
  --text-secondary: 13px;
  --text-micro: 11.5px;
  --text-label: 10.5px;
  --text-nav: 13px;

  --size-control: 32px;
  --size-control-lg: 38px;
  --size-control-sm: 26px;
  --size-input: 38px;
  --size-nav-item: 30px;
  --width-nav: 224px;
  --nav-w: var(--width-nav);
  /* The collapsed rail. DESIGN_SYSTEM.md §6 reads it at ~72px, but that is
     measured off the 280px sidebar; this shell runs a notch tighter
     throughout (224 not 280, 30px nav items not 38), so the strip follows the
     same ratio rather than the literal number. */
  --width-rail: 56px;
  --size-nav-icon: 18px;
  --size-nav-badge: 14px;
  /* The account menu once the rail is too narrow to hold it. */
  --width-acct-menu: 208px;

  /* ---- Sizes this stylesheet needs and tokens.css does not carry --------- */
  --border-width-thick: 2px;
  --size-swatch: 8px;
  --size-dot: 6px;
  --size-knob: 18px;
  --size-switch-w: 38px;
  --size-switch-h: 22px;
  --size-switch-travel: 16px;
  --size-expander: 22px;
  --size-avatar: 26px;
  --size-mark: 22px;
  --size-spinner: 14px;
  --size-spinner-lg: 22px;
  --size-step-dot: 22px;
  --size-bar: 4px;
  --width-bar: 80px;
  --size-qr: 208px;
  --width-list-pane: 268px;
  --width-role-name: 200px;
  --width-head-text: 340px;
  --width-detail-key: 62px;
  /* The key column of a settings row. Wide enough for the longest key on the
     label pane, so the controls line up down the block. */
  --width-setting-key: 76px;
  --width-tag-cell: 260px;
  --width-name-cell: 320px;
  --width-funnel-n: 64px;
  --width-why-cell: 380px;
  /* The model's one-line reason beside a comparable. Narrower than
     --width-why-cell so nine columns of figures still fit a pane without
     pushing the reason itself out of sight. */
  --width-why-note: 220px;
  --height-pre: 320px;
  /* The market table's scroll box. Deep enough that a broker scans a screenful
     of sales without the page itself moving under them. */
  --height-market: 560px;
  --offset-inset: 2px;
  --size-hairline: 1px;
  --radius-xl: 24px;
  --size-orb: 96px;

  /* ---- Compact layout (the phone and tablet shell). The rail becomes a
     drawer behind a menu button; these are the sizes that shell needs.
     Breakpoints have to be written literally in the media queries — custom
     properties cannot be used there — so they are listed here to be findable:
       1080px  the two-up workspaces go one-up
        900px  compact — the rail becomes a drawer
        620px  narrow  — the last two-up grids stack
     ---------------------------------------------------------------------- */
  --size-topbar: 52px;
  --width-drawer: min(84vw, 288px);
  /* The key column of a stacked table row. Wide enough for the longest
     heading any of them carries, so the values line up down the card. */
  --width-stack-key: 92px;
  --size-touch: 44px; /* the smallest comfortable tap target */
  --text-input-touch: 16px; /* below this iOS zooms the page on focus */
  --z-topbar: 55;
  --z-scrim: 60;
  --z-drawer: 65;
  /* The same wash the walkthrough lays over Today, so the two overlays match. */
  --color-scrim: color-mix(in srgb, var(--color-page) 62%, transparent);

  /* ---- WhatsApp label colours. Data-driven — WhatsApp cycles a fixed
     palette and we render its dot. Tokenised so no component holds a hex. -- */
  --label-0: #5a9ef8;
  --label-1: #4bbb8a;
  --label-2: #d4a03c;
  --label-3: #e8796d;
  --label-4: #9b7fe8;
  --label-5: #3fb6c4;
  --label-6: #e07ab0;
  --label-7: #7a8794;
  --label-8: #c2703f;
  --label-9: #6b9e3f;

  /* ---- Liquid-metal border sheen: metallic greys with faint iridescence,
     kept as tokens so no component holds a raw hex. ----------------------- */
  --lm-steel: #6f747c;
  --lm-silver: #e9edf2;
  --lm-grey: #a7adb7;
  --lm-gold: #f6e3c4;
  --lm-blue: #bcd0f0;
  --lm-mauve: #ecccea;
}

/* ============================== BASE ================================== */

* {
  box-sizing: border-box;
}

/* An author `display` beats the UA's [hidden] rule, so anything laid out with
   flex or grid stays on screen when JS sets .hidden. Every use of the attribute
   in this app means "take it away", so say it once here. */
[hidden] {
  display: none !important;
}

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

body {
  font-family: var(--font-sans);
  font-size: var(--text-secondary);
  line-height: var(--leading-normal);
  background: var(--color-page);
  color: var(--color-text-primary);
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}

#view {
  height: 100%;
}

::selection {
  background: var(--color-surface-sunk);
}

/* ============================== TYPE ================================== */

.t-title {
  font-size: var(--text-title);
  font-weight: var(--weight-bold);
  letter-spacing: var(--track-title);
  line-height: var(--leading-tight);
  margin: 0;
}
.t-title .dim {
  color: var(--color-text-muted);
}
.t-section {
  font-size: var(--text-section);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--track-section);
  line-height: var(--leading-snug);
  margin: 0;
}
.t-card {
  font-size: var(--text-card);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--track-section);
  margin: 0;
}
.t-body {
  font-size: var(--text-body);
}
.t-secondary {
  font-size: var(--text-secondary);
  color: var(--color-text-secondary);
}
.t-micro {
  font-size: var(--text-micro);
  color: var(--color-text-secondary);
}
.t-muted {
  color: var(--color-text-muted);
}
.t-label {
  font-size: var(--text-label);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.num {
  font-variant-numeric: tabular-nums;
}
.measure {
  max-width: var(--measure);
}
.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

/* ============================ CONTROLS ================================= */

.btn {
  all: unset;
  box-sizing: border-box;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: var(--size-control);
  padding: 0 var(--space-4);
  border-radius: var(--radius-pill);
  border: var(--border-width) solid transparent;
  font-size: var(--text-secondary);
  font-weight: var(--weight-strong);
  white-space: nowrap;
  transition:
    background var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease);
}
.btn:focus-visible {
  outline: var(--border-width-thick) solid var(--color-focus);
  outline-offset: var(--offset-inset);
}
.btn--primary {
  background: var(--color-action);
  color: var(--color-action-label);
}
.btn--primary:hover {
  background: var(--color-action-hover);
}
.btn--secondary {
  background: var(--color-surface);
  color: var(--color-text-primary);
  border-color: var(--color-border);
}
.btn--secondary:hover {
  background: var(--color-surface-sunk);
  border-color: var(--color-border-strong);
}
.btn--ghost {
  background: transparent;
  color: var(--color-text-secondary);
}
.btn--ghost:hover {
  background: var(--color-surface-sunk);
  color: var(--color-text-primary);
}
/* Outlined rather than filled: the destructive button should read as the
   deliberate choice, not the obvious one. Cancel keeps the solid treatment. */
.btn--crit {
  background: var(--color-surface);
  color: var(--color-crit);
  border-color: var(--color-crit);
}
.btn--crit:hover {
  background: var(--color-crit-bg);
}
.btn[disabled],
.btn[aria-disabled="true"] {
  background: var(--color-surface-sunk);
  border-color: transparent;
  color: var(--color-text-muted);
  cursor: not-allowed;
}
.btn--lg {
  height: var(--size-control-lg);
  padding: 0 var(--space-6);
  font-size: var(--text-body);
}
.btn--sm {
  height: var(--size-control-sm);
  padding: 0 var(--space-3);
  font-size: var(--text-micro);
}

.input,
.select {
  all: unset;
  box-sizing: border-box;
  display: block;
  width: 100%;
  height: var(--size-input);
  padding: 0 var(--space-4);
  background: var(--color-surface-sunk);
  border-radius: var(--radius-input);
  border: var(--border-width) solid transparent;
  font-family: var(--font-sans);
  font-size: var(--text-body);
  color: var(--color-text-primary);
  transition:
    border-color var(--dur-fast) var(--ease),
    background var(--dur-fast) var(--ease);
}
.input::placeholder {
  color: var(--color-text-muted);
}
.input:hover,
.select:hover {
  border-color: var(--color-border);
}
.input:focus,
.select:focus {
  background: var(--color-surface);
  border-color: var(--color-border-strong);
  outline: var(--border-width-thick) solid var(--color-focus);
  outline-offset: var(--size-hairline);
}
.input--sm {
  height: var(--size-control-sm);
  padding: 0 var(--space-3);
  font-size: var(--text-micro);
}
.input--num {
  width: var(--space-16);
  text-align: center;
  font-variant-numeric: tabular-nums;
}
/* disabled is a distinct fill, not an opacity trick — DESIGN_SYSTEM.md §5 */
.input[disabled] {
  background: transparent;
  border-color: var(--color-border);
  border-style: dashed;
  color: var(--color-text-muted);
  cursor: not-allowed;
}
/* Multi-line input: same skin as .input but height follows content. */
.textarea {
  height: auto;
  min-height: calc(var(--size-input) * 2);
  padding: var(--space-3) var(--space-4);
  line-height: var(--leading-normal);
  resize: vertical;
  white-space: pre-wrap;
}
/* Data / uploads table extras. */
.linkish {
  all: unset;
  cursor: pointer;
  margin-left: var(--space-2);
  font-size: var(--text-micro);
  color: var(--color-text-muted);
  text-decoration: underline;
}
.linkish:hover {
  color: var(--color-text-primary);
}
.cell-action {
  text-align: right;
  width: var(--size-control);
}
/* Direct child only. A descendant selector here also caught every cell of the
   comparables table nested inside, which is how long property names ended up
   printed over the column beside them. */
.view-row > td {
  background: var(--color-surface-sunk);
  /* A table cell sizes to its widest child, so a comparables table inside an
     expanded row was stretching the whole uploads table and pushing its last
     columns off screen. Zero here means "claim no width of your own": the cell
     still spans the row, and wide children scroll inside their own box. */
  max-width: 0;
}
.doc-text {
  white-space: pre-wrap;
  font-size: var(--text-micro);
  color: var(--color-text-secondary);
  line-height: var(--leading-normal);
  max-height: 320px;
  overflow: auto;
  padding: var(--space-2) 0;
}

/* What we read out of an uploaded file, shown inside the row it belongs to.
   The broker checking this against their own file is the only thing standing
   between a bad extraction and a wrong number in a client's message, so it is
   laid out to be read rather than to be compact. */
.extract {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-3) 0 var(--space-4);
}
.extract__sum {
  font-size: var(--text-secondary);
  color: var(--color-text-primary);
  line-height: var(--leading-normal);
}
/* Where the numbers came from: which sheet, which row the headings were on,
   what the export itself says it was filtered to. A figure whose provenance is
   invisible cannot be checked, only believed. */
.extract__prov {
  font-size: var(--text-micro);
  color: var(--color-text-muted);
  line-height: var(--leading-normal);
  white-space: pre-wrap;
}
.extract .stats {
  align-self: flex-start;
  background: var(--color-surface);
}
/* The comparables. A nested table inherits the page's sticky uppercase header
   and 40px rows, which is right for a screen and wrong for a block inside one,
   so both are turned down here. */
.comparables-wrap {
  max-height: var(--height-pre);
  overflow: auto;
  border-radius: var(--radius-card);
  background: var(--color-surface);
}
/* The Market tab is the table, not a block inside a longer read, so it gets
   the height rather than sitting in the same box as a file's summary. */
.comparables-wrap--tall {
  max-height: var(--height-market);
  border: var(--border-width) solid var(--color-border);
}

/* The Market tab. The Files tab beside it goes flush so its rows meet the pane
   edge; a table of figures with its own scroll box needs the margin back. */
.market {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
}
.market .stats {
  margin: 0;
}
/* Size to the content, not to the box. The base rule is width:100%, which
   squeezed the columns while their contents refused to wrap, so long property
   names printed over the column beside them. Let the table be as wide as it
   needs and let the wrapper scroll. */
.comparables {
  width: max-content;
  min-width: 100%;
}
.comparables th {
  position: static;
  background: var(--color-surface);
  font-size: var(--text-micro);
  padding: var(--space-2) var(--space-3);
}
.comparables td {
  height: auto;
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-micro);
  white-space: nowrap;
}
.comparables tbody tr:last-child td {
  border-bottom: 0;
}
/* The model's reason for pointing at a comparable. It never carries a figure —
   those are attached from the row it names — so it stays visibly secondary. */
.extract__why {
  font-size: var(--text-micro);
  color: var(--color-text-secondary);
  white-space: normal;
  /* Capped, or max-content sizing would let one long sentence set the width of
     the whole table. */
  max-width: var(--width-why-note);
}
/* Inline checkbox row — label + native control. */
.check {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-secondary);
  color: var(--color-text-secondary);
  cursor: pointer;
  margin-top: var(--space-3);
}
.check input {
  accent-color: var(--color-action);
  width: var(--space-4);
  height: var(--space-4);
}
/* Two-up field grid — used by the voice editor. Collapses to one column. */
.field-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}
@media (max-width: 720px) {
  .field-grid {
    grid-template-columns: 1fr;
  }
}
/* The 3-question prompt wizard, inset on the label detail. */
.wizbox {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--color-surface-sunk);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-card);
}

/* The delete confirm borrows the wizbox, but sits above a flush table, so it
   needs the margin the table rows do not have. */
.wizbox--confirm {
  margin: var(--space-4);
  border-color: var(--color-crit);
}

.field {
  display: block;
}
.field > .field__label {
  display: block;
  font-size: var(--text-secondary);
  color: var(--color-text-secondary);
  margin-bottom: var(--space-2);
}

.segmented {
  display: inline-flex;
  gap: var(--offset-inset);
  background: var(--color-surface-sunk);
  padding: var(--space-1);
  border-radius: var(--radius-pill);
}
.segmented button {
  all: unset;
  cursor: pointer;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--text-micro);
  color: var(--color-text-secondary);
  white-space: nowrap;
  transition:
    background var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease);
}
.segmented button:hover {
  color: var(--color-text-primary);
}
.segmented button:focus-visible {
  outline: var(--border-width-thick) solid var(--color-focus);
  outline-offset: calc(-1 * var(--border-width-thick));
}
.segmented button[aria-selected="true"],
.segmented button[aria-pressed="true"] {
  background: var(--color-surface);
  color: var(--color-text-primary);
  font-weight: var(--weight-strong);
  box-shadow: var(--shadow-pill);
}
.segmented--sm button {
  font-size: var(--text-label);
  padding: var(--space-1) var(--space-3);
}
/* An option that ships before the engine behind it (Report). A distinct
   colour and a dead cursor, not an opacity trick — DESIGN_SYSTEM.md §5. */
.segmented button[disabled],
.segmented button[disabled]:hover {
  color: var(--color-text-muted);
  cursor: not-allowed;
}
/* Labels list filter — a dropdown like the mirror's, level with the title. */
.label-filter {
  position: relative;
}
.flt-btn {
  all: unset;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--color-surface-sunk);
  color: var(--color-text-primary);
  font-size: var(--text-label);
  transition: background var(--dur-fast) var(--ease);
}
.flt-btn:hover {
  background: var(--color-surface-raised);
}
.flt-btn:focus-visible {
  outline: var(--border-width-thick) solid var(--color-focus);
  outline-offset: calc(-1 * var(--border-width-thick));
}
.flt-caret {
  transform: rotate(90deg);
  font-size: var(--text-micro);
  opacity: 0.7;
}
.flt-menu {
  position: absolute;
  top: calc(100% + var(--space-2));
  right: 0;
  z-index: 20;
  min-width: calc(var(--width-nav) * 0.7);
  padding: var(--space-1);
  background: var(--color-surface-raised);
  border-radius: var(--radius-card);
  border: var(--border-width) solid var(--color-border);
  box-shadow: var(--shadow-float);
  display: flex;
  flex-direction: column;
}
.flt-menu[hidden] {
  display: none;
}
.flt-menu-item {
  all: unset;
  box-sizing: border-box;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  height: var(--size-nav-item);
  padding: 0 var(--space-3);
  border-radius: var(--radius-input);
  font-size: var(--text-secondary);
  color: var(--color-text-primary);
  white-space: nowrap;
}
.flt-menu-item:hover {
  background: var(--color-surface-sunk);
}
.flt-menu-item[aria-checked="true"] {
  font-weight: var(--weight-semibold);
}
.flt-count {
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

/* Today first-run — the "we read your client conversations" rundown. */
.today-first {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.today-first-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--width-list-pane), 1fr));
  gap: var(--space-4);
  align-items: start;
}
.insight-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.insight-list li {
  font-size: var(--text-secondary);
  color: var(--color-text-secondary);
}
.insight-list b {
  color: var(--color-text-primary);
  font-weight: var(--weight-semibold);
}
.phrase {
  margin-top: var(--space-2);
  font-size: var(--text-secondary);
  color: var(--color-text-secondary);
  font-style: italic;
}

/* Post-onboarding walkthrough — clean cards floating over Today. */
.walk,
.relink {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-8) var(--space-6);
  overflow-y: auto;
  background: color-mix(in srgb, var(--color-page) 72%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
/* The reconnect card. Narrower than the walkthrough — it asks one thing. */
.relink .onb__col {
  max-width: 440px;
}
/* One action and one way out, stacked and centred under the copy. The primary
   spans the column: at this width a natural-width button leaves the panel
   looking like it lost something. */
.relink__actions {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-3);
  width: 100%;
}
.relink__actions .btn {
  width: 100%;
}
/* The quiet way out stretches with the column too, so its label needs telling
   where to sit — left of a full-width row reads as a stray link. */
.relink__actions .walk-skip {
  width: 100%;
  text-align: center;
}
.walk-options {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
  width: 100%;
}
.walk-opt {
  all: unset;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-5);
  border-radius: var(--radius-panel);
  /* Same barely-there shade as the number-cards. No border. */
  background: color-mix(in srgb, var(--color-text-primary) 5%, var(--color-surface));
  transition:
    background var(--dur-fast) var(--ease),
    transform var(--dur-fast) var(--ease);
}
.walk-opt:hover {
  background: color-mix(in srgb, var(--color-text-primary) 8%, var(--color-surface));
  transform: translateY(calc(-1 * var(--space-1)));
}
.walk-opt:focus-visible {
  outline: var(--border-width-thick) solid var(--color-focus);
  outline-offset: var(--offset-inset);
}
.walk-opt[aria-pressed="true"] {
  background: color-mix(in srgb, var(--color-text-primary) 11%, var(--color-surface));
}
.walk-opt__tag {
  font-size: var(--text-label);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.walk-opt__msg {
  font-size: var(--text-body);
  line-height: var(--leading-normal);
  color: var(--color-text-primary);
}
.walk-blurb {
  max-width: 46ch;
  text-align: center;
  font-size: var(--text-secondary);
  color: var(--color-text-secondary);
  line-height: var(--leading-normal);
  margin: 0;
}
.walk-skip {
  all: unset;
  cursor: pointer;
  font-size: var(--text-micro);
  color: var(--color-text-muted);
}
.walk-skip:hover {
  color: var(--color-text-secondary);
}
/* Walkthrough card: one neat, central card per step. Title and dots live
   inside it; no border, no dividers. Bigger than the onboarding card. */
.walk .onb__col {
  max-width: 800px;
}
/* Two neat shaded number-cards, side by side. */
.walk-figures {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
  width: 100%;
}
.walk-figure {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-6);
  /* Only a hair lighter than the card — barely there. */
  background: color-mix(in srgb, var(--color-text-primary) 5%, var(--color-surface));
  border-radius: var(--radius-panel);
}
.walk-figure__n {
  font-size: var(--text-title);
  font-weight: var(--weight-bold);
  letter-spacing: var(--track-title);
  line-height: var(--leading-tight);
  font-variant-numeric: tabular-nums;
}
.walk-figure__k {
  font-size: var(--text-secondary);
  color: var(--color-text-secondary);
}
.walk-missed {
  margin: 0;
  font-size: var(--text-body);
  color: var(--color-text-secondary);
}
.walk-missed b {
  color: var(--color-text-primary);
  font-weight: var(--weight-strong);
  font-variant-numeric: tabular-nums;
}

/* Final step: preferences, then a thinking orb, then a success message. */
.walk-q {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  width: 100%;
}
.walk-q + .walk-q {
  margin-top: var(--space-6);
}
.walk-q__label {
  font-size: var(--text-body);
  font-weight: var(--weight-semibold);
  color: var(--color-text-primary);
}
.walk-choices {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2);
}
.walk-choice {
  all: unset;
  cursor: pointer;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--color-text-primary) 5%, var(--color-surface));
  color: var(--color-text-secondary);
  font-size: var(--text-secondary);
  transition:
    background var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease);
}
.walk-choice:hover {
  color: var(--color-text-primary);
}
.walk-choice:focus-visible {
  outline: var(--border-width-thick) solid var(--color-focus);
  outline-offset: var(--offset-inset);
}
.walk-choice[aria-pressed="true"] {
  background: var(--color-action);
  color: var(--color-action-label);
  font-weight: var(--weight-strong);
}
/* The creation sequence. The card is the fixed container; stages cross-fade
   inside it. The orb is a canvas of monochrome particles on tilted orbits. */
.walk-card--seq {
  justify-content: center;
}
.walk-fade {
  transition:
    opacity var(--dur-base) var(--ease),
    transform var(--dur-base) var(--ease);
}
.walk-fade--out {
  opacity: 0;
  transform: translateY(var(--space-1));
  pointer-events: none;
}
.walk-stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-6);
  flex: 1;
  width: 100%;
}
.walk-orb {
  width: calc(var(--size-orb) + var(--space-6));
  height: calc(var(--size-orb) + var(--space-6));
  color: var(--color-text-primary);
  display: block;
}
.walk-status {
  margin: 0;
  font-size: var(--text-secondary);
  color: var(--color-text-muted);
}
/* A line being typed is momentarily empty, which collapses the paragraph to
   nothing and bounces everything under it. Hold one line's height always. */
.walk-status,
.type-line {
  min-height: calc(var(--text-secondary) * var(--leading-normal, 1.5));
  line-height: var(--leading-normal, 1.5);
}
.walk-done-mark svg {
  width: calc(var(--space-16) + var(--space-2));
  height: calc(var(--space-16) + var(--space-2));
  display: block;
}
.walk-done-ring {
  fill: none;
  stroke: var(--color-border-strong);
  stroke-width: 1.5;
  stroke-dasharray: 189;
  stroke-dashoffset: 189;
  transform: rotate(-90deg);
  transform-origin: center;
  animation: walk-draw 0.9s var(--ease) forwards;
}
.walk-done-tick {
  fill: none;
  stroke: var(--color-text-primary);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 34;
  stroke-dashoffset: 34;
  animation: walk-draw 0.5s var(--ease) 0.55s forwards;
}
@keyframes walk-draw {
  to {
    stroke-dashoffset: 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  .walk-fade {
    transition: none;
  }
  .walk-done-ring,
  .walk-done-tick {
    animation: none;
    stroke-dashoffset: 0;
  }
}
.walk-card {
  position: relative;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-10);
  text-align: center;
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-float);
}
/* Larger, better-spaced title for the overlay card. */
.walk-card .onb__title {
  font-size: var(--text-title);
  letter-spacing: var(--track-title);
}
/* The inner box: a slightly lighter panel nested in the card, holding the
   step's core content (the reference's "box inside the box"). */
.walk-panel {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-8);
  background: color-mix(in srgb, var(--color-text-primary) 5%, var(--color-surface));
  border-radius: var(--radius-panel);
}
.walk-hope {
  max-width: 42ch;
  margin: 0;
  font-size: var(--text-body);
  line-height: var(--leading-normal);
  color: var(--color-text-secondary);
}
.walk-hope b {
  color: var(--color-text-primary);
  font-weight: var(--weight-strong);
}
.walk-card__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
}
.walk-card__body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-5);
  width: 100%;
}
.walk-card__foot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  width: 100%;
}
.walk .stats {
  background: transparent;
}
.walk .stat {
  padding: var(--space-2) var(--space-4);
}
.walk .stat + .stat {
  border-left: none;
}

.switch {
  all: unset;
  cursor: pointer;
  width: var(--size-switch-w);
  height: var(--size-switch-h);
  border-radius: var(--radius-pill);
  background: var(--color-border-strong);
  position: relative;
  flex: none;
  transition: background var(--dur-base) var(--ease);
}
.switch::after {
  content: "";
  position: absolute;
  top: var(--offset-inset);
  left: var(--offset-inset);
  width: var(--size-knob);
  height: var(--size-knob);
  border-radius: var(--radius-round);
  background: var(--color-surface);
  box-shadow: var(--shadow-pill);
  transition: transform var(--dur-base) var(--ease);
}
.switch[aria-checked="true"] {
  background: var(--color-action);
}
.switch[aria-checked="true"]::after {
  transform: translateX(var(--size-switch-travel));
}
.switch:focus-visible {
  outline: var(--border-width-thick) solid var(--color-focus);
  outline-offset: var(--offset-inset);
}

/* a quiet inline link — a pointer to another screen, not an action */
.linkish {
  all: unset;
  cursor: pointer;
  font-size: var(--text-micro);
  color: var(--color-text-muted);
  text-decoration: underline;
  text-underline-offset: var(--offset-inset);
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease);
}
.linkish:hover {
  color: var(--color-text-primary);
}
.linkish:focus-visible {
  outline: var(--border-width-thick) solid var(--color-focus);
  outline-offset: var(--offset-inset);
}

.icon-btn {
  all: unset;
  cursor: pointer;
  width: var(--size-avatar);
  height: var(--size-avatar);
  flex: none;
  border-radius: var(--radius-input);
  display: grid;
  place-items: center;
  color: var(--color-text-muted);
  font-size: var(--text-micro);
  transition:
    background var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease);
}
.icon-btn:hover {
  background: var(--color-surface-sunk);
  color: var(--color-text-primary);
}
.icon-btn:focus-visible {
  outline: var(--border-width-thick) solid var(--color-focus);
  outline-offset: calc(-1 * var(--border-width-thick));
}

/* A knowledge section: a title, the text, and the way to drop it. The remove
   sits at the end of the row rather than stretched across it — full width it
   reads as the thing you are meant to press. */
.k-section .btn {
  align-self: flex-end;
}

/* ============================ SURFACES ================================= */

.card {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-card);
  padding: var(--space-5);
  min-width: 0;
}
.card h3 {
  margin: 0 0 var(--space-1);
  font-size: var(--text-secondary);
  font-weight: var(--weight-semibold);
}
.card p {
  margin: 0 0 var(--space-4);
  font-size: var(--text-secondary);
  color: var(--color-text-secondary);
}
.card p:last-child {
  margin-bottom: 0;
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--text-micro);
  font-weight: var(--weight-strong);
  background: var(--color-surface-sunk);
  color: var(--color-text-secondary);
  white-space: nowrap;
}
.badge--success {
  background: var(--color-success-bg);
  color: var(--color-success);
}
.badge--warn {
  background: var(--color-warn-bg);
  color: var(--color-warn);
}
.badge--crit {
  background: var(--color-crit-bg);
  color: var(--color-crit);
}
.badge--accent {
  background: var(--color-surface-sunk);
  color: var(--color-text-primary);
}

.notice {
  background: var(--color-surface-sunk);
  border-radius: var(--radius-card);
  padding: var(--space-4) var(--space-5);
  font-size: var(--text-secondary);
  color: var(--color-text-secondary);
}
.notice b {
  color: var(--color-text-primary);
  font-weight: var(--weight-semibold);
}
.notice--warn {
  background: var(--color-warn-bg);
  color: var(--color-warn);
}
.notice--warn b {
  color: var(--color-warn);
}
.notice--crit {
  background: var(--color-crit-bg);
  color: var(--color-crit);
}
.notice--crit b {
  color: var(--color-crit);
}

.empty {
  border: var(--border-width) dashed var(--color-border);
  border-radius: var(--radius-card);
  padding: var(--space-10) var(--space-6);
  text-align: center;
}
.empty__title {
  font-size: var(--text-body);
  font-weight: var(--weight-semibold);
}
.empty__desc {
  font-size: var(--text-secondary);
  color: var(--color-text-secondary);
  margin: var(--space-1) auto 0;
  max-width: var(--measure);
}

.label-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-micro);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--color-surface-sunk);
}
.sq {
  display: inline-block;
  vertical-align: middle;
  width: var(--size-swatch);
  height: var(--size-swatch);
  border-radius: var(--offset-inset);
  flex: none;
  background: var(--color-text-muted);
}
.dot {
  width: var(--size-dot);
  height: var(--size-dot);
  border-radius: var(--radius-round);
  background: var(--color-success);
  flex: none;
}
@media (prefers-reduced-motion: no-preference) {
  .dot {
    animation: pulse 2.4s ease-in-out infinite;
  }
  @keyframes pulse {
    0%,
    100% {
      opacity: 1;
    }
    50% {
      opacity: 0.3;
    }
  }
}

.bar {
  height: var(--size-bar);
  border-radius: var(--radius-pill);
  background: var(--color-border);
  overflow: hidden;
  width: var(--width-bar);
  flex: none;
}
.bar--wide {
  width: 100%;
}
.bar i {
  display: block;
  height: 100%;
  background: var(--color-text-primary);
  transition: width var(--dur-base) var(--ease);
}

.spinner {
  width: var(--size-spinner);
  height: var(--size-spinner);
  flex: none;
  border-radius: var(--radius-round);
  border: var(--border-width-thick) solid var(--color-border-strong);
  border-top-color: var(--color-text-primary);
  display: inline-block;
  animation: spin 0.7s linear infinite;
}
.spinner--lg {
  width: var(--size-spinner-lg);
  height: var(--size-spinner-lg);
}
.spinner--inverse {
  border-color: var(--color-action-label);
  border-top-color: transparent;
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .spinner {
    animation-duration: 2s;
  }
}

/* ============================= TABLE =================================== */

.table-wrap {
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-card);
  overflow: auto;
  background: var(--color-surface);
}
table {
  border-collapse: collapse;
  width: 100%;
  font-size: var(--text-secondary);
}
th {
  text-align: left;
  font-size: var(--text-label);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--color-text-muted);
  padding: var(--space-3) var(--space-4);
  border-bottom: var(--border-width) solid var(--color-border);
  white-space: nowrap;
  background: var(--color-surface);
  position: sticky;
  top: 0;
  z-index: 1;
}
td {
  padding: var(--space-2) var(--space-4);
  height: var(--size-row);
  border-bottom: var(--border-width) solid var(--color-border);
  vertical-align: middle;
}
tbody tr:last-child td {
  border-bottom: 0;
}
tbody tr.r:hover {
  background: var(--color-surface-sunk);
}
.sub-cell {
  font-size: var(--text-micro);
  color: var(--color-text-muted);
}
.cell-right {
  text-align: right;
}

/* ============================= SHELL =================================== */

.wrap {
  height: 100%;
  display: grid;
  grid-template-columns: var(--nav-w) minmax(0, 1fr);
  overflow: hidden;
  background: var(--color-page);
  color: var(--color-text-primary);
  transition: grid-template-columns var(--dur-base) var(--ease);
}
.wrap--solo {
  grid-template-columns: minmax(0, 1fr);
}
/* Collapsed the rail narrows to the icon strip rather than disappearing —
   see the block after the nav for what the strip keeps and what it drops. */
.wrap[data-nav="closed"] {
  --nav-w: var(--width-rail);
}

.rail {
  padding: var(--space-4) var(--space-2);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  overflow: hidden;
  min-width: 0;
}
.brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0 var(--space-2);
}
.mark {
  width: var(--size-mark);
  height: var(--size-mark);
  border-radius: var(--radius-round);
  background: var(--color-accent);
  flex: none;
  position: relative;
  overflow: hidden;
}
.mark::before,
.mark::after {
  content: "";
  position: absolute;
  left: -30%;
  width: 160%;
  height: var(--offset-inset);
  background: var(--color-surface);
  transform: rotate(-38deg);
  opacity: 0.9;
}
.mark::before {
  top: 33%;
}
.mark::after {
  top: 58%;
}
.brand-name {
  font-weight: var(--weight-semibold);
  font-size: var(--text-secondary);
  letter-spacing: var(--track-section);
  white-space: nowrap;
}

.nav {
  display: flex;
  flex-direction: column;
  gap: var(--size-hairline);
  margin-top: var(--space-12);
}
.nav__group {
  font-size: var(--text-label);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--color-text-muted);
  padding: var(--space-3) var(--space-2) var(--space-1);
  white-space: nowrap;
}
.nav__group:first-child {
  padding-top: 0;
}
.nav__item {
  all: unset;
  cursor: pointer;
  position: relative;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  height: var(--size-nav-item);
  padding: 0 var(--space-2);
  border-radius: var(--radius-input);
  font-size: var(--text-nav);
  font-weight: var(--weight-medium);
  color: var(--color-text-secondary);
  border: var(--border-width) solid transparent;
  white-space: nowrap;
  overflow: hidden;
  transition:
    background var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease),
    padding var(--dur-base) var(--ease);
}
/* Open, the glyph is squeezed to nothing and the word carries the item;
   collapsed the two swap. Both stay in the markup so there is something to
   animate between — see the note in shell.js. */
.nav__icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 0;
  height: var(--size-nav-icon);
  opacity: 0;
  overflow: hidden;
  transition:
    width var(--dur-base) var(--ease),
    opacity var(--dur-fast) var(--ease);
}
.nav__icon svg {
  width: var(--size-nav-icon);
  height: var(--size-nav-icon);
  display: block;
}
.nav__label {
  min-width: 0;
  /* A fixed ceiling comfortably past the longest label ("Conversations"), not
     a percentage — the container is mid-transition when this animates. */
  max-width: 12rem;
  overflow: hidden;
  text-overflow: ellipsis;
  transition:
    max-width var(--dur-base) var(--ease),
    opacity var(--dur-fast) var(--ease);
}
.nav__item:hover {
  background: var(--color-surface);
  color: var(--color-text-primary);
}
.nav__item:focus-visible {
  outline: var(--border-width-thick) solid var(--color-focus);
  outline-offset: calc(-1 * var(--border-width-thick));
}
.nav__item[aria-current="true"] {
  background: var(--color-surface);
  border-color: var(--color-border);
  color: var(--color-text-primary);
  font-weight: var(--weight-strong);
}
.nav__count {
  margin-left: auto;
  font-size: var(--text-label);
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-semibold);
  background: var(--color-action);
  color: var(--color-action-label);
  border-radius: var(--radius-pill);
  padding: 0 var(--space-2);
}

/* The button that brings the rail back once it is collapsed. It sits in the
   rail under the mark, not floating in the corner of the sheet — there it
   came down on the page title, which is the first thing every view puts in
   that spot. Hidden entirely until there is a strip for it to sit in. */
.nav-open {
  display: none;
  flex: none;
  margin: 0 auto;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
}
.wrap[data-nav="closed"] .nav-open {
  display: grid;
}

/* ---------- the collapsed rail -----------------------------------------
   Collapsing used to leave nothing behind, which meant the only way back was
   a button floating over the sheet and no way at all to see where you were.
   The strip keeps the mark, the ten glyphs and the account avatar; it drops
   every word. Everything here is a squeeze rather than a display swap, so the
   rail narrowing and the labels going are one movement. Below the compact
   breakpoint the rail is a drawer instead and all of this is undone. */

.wrap[data-nav="closed"] .rail {
  /* the account menu flies out over the sheet rather than being clipped */
  overflow: visible;
}
.wrap[data-nav="closed"] .brand {
  padding: 0;
  justify-content: center;
}
.wrap[data-nav="closed"] .brand-name,
.wrap[data-nav="closed"] #nav-close {
  display: none;
}

/* Group headings become the hairline they were already implying. The first
   one goes entirely — a rule directly under the mark reads as a border. */
.wrap[data-nav="closed"] .nav__group {
  height: var(--size-hairline);
  padding: 0;
  margin: var(--space-3) var(--space-4) var(--space-2);
  background: var(--color-border);
  font-size: 0;
  color: transparent;
  overflow: hidden;
}
.wrap[data-nav="closed"] .nav__group:first-child {
  display: none;
}

/* No width is set here on purpose. The item is already stretched to the
   rail's inner width, so it narrows with the grid column — a fixed tile width
   would have to interpolate from `auto` and would snap instead of animating. */
.wrap[data-nav="closed"] .nav__item {
  padding: 0;
  gap: 0;
  justify-content: center;
}
.wrap[data-nav="closed"] .nav__icon {
  width: var(--size-nav-icon);
  opacity: 1;
}
.wrap[data-nav="closed"] .nav__label {
  max-width: 0;
  opacity: 0;
}
/* The pending count has no row left to sit at the end of, so it rides the
   glyph. Still a number, not a dot — "three waiting" is the whole point of it.
   The ring is what keeps it legible: at this size the badge lands on the
   corner of the icon, and without a cut-out the two line weights merge. */
.wrap[data-nav="closed"] .nav__count {
  position: absolute;
  top: var(--offset-inset);
  right: var(--offset-inset);
  margin-left: 0;
  min-width: var(--size-nav-badge);
  height: var(--size-nav-badge);
  padding: 0 var(--offset-inset);
  display: grid;
  place-items: center;
  line-height: 1;
  box-shadow: 0 0 0 var(--border-width-thick) var(--color-page);
}
/* The active item is a lighter fill than the rail, so its ring has to be too
   — and Today, the one item with a count, is the usual active item. */
.wrap[data-nav="closed"] .nav__item[aria-current="true"] .nav__count {
  box-shadow: 0 0 0 var(--border-width-thick) var(--color-surface);
}

/* The identity card keeps its border and its menu; it just loses the words. */
.wrap[data-nav="closed"] .who {
  justify-content: center;
  gap: 0;
}
.wrap[data-nav="closed"] .who__text,
.wrap[data-nav="closed"] .who__chev {
  display: none;
}
/* Anchored to the strip's right edge instead of spanning it — at 72px the
   menu would otherwise be a 72px-wide column of clipped words. */
.wrap[data-nav="closed"] .acct-menu {
  bottom: 0;
  left: calc(100% + var(--space-2));
  right: auto;
  width: var(--width-acct-menu);
}

/* ---------- compact shell: the bar and the scrim ------------------------
   Both are in the markup at every width and shown only by the compact media
   query, so the desktop layout carries no extra boxes. */
.topbar {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: var(--size-topbar);
  z-index: var(--z-topbar);
  align-items: center;
  gap: var(--space-3);
  padding: 0 var(--space-3);
  background: var(--color-page);
  border-bottom: var(--border-width) solid var(--color-border);
}
.topbar .brand-name {
  font-size: var(--text-body);
}
/* The menu button. Three rules that fold into an X while the drawer is open. */
.burger {
  all: unset;
  cursor: pointer;
  flex: none;
  display: grid;
  place-items: center;
  width: var(--size-touch);
  height: var(--size-touch);
  margin-left: calc(-1 * var(--space-2));
  border-radius: var(--radius-input);
  color: var(--color-text-primary);
}
.burger:hover {
  background: var(--color-surface);
}
.burger:focus-visible {
  outline: var(--border-width-thick) solid var(--color-focus);
  outline-offset: calc(-1 * var(--border-width-thick));
}
.burger__box {
  position: relative;
  width: var(--space-4);
  height: var(--space-3);
}
.burger__bar {
  position: absolute;
  left: 0;
  width: 100%;
  height: var(--size-hairline);
  background: currentColor;
  border-radius: var(--radius-pill);
  transition:
    transform var(--dur-fast) var(--ease),
    opacity var(--dur-fast) var(--ease);
}
.burger__bar:nth-child(1) {
  top: 0;
}
.burger__bar:nth-child(2) {
  top: 50%;
}
.burger__bar:nth-child(3) {
  top: 100%;
}
.wrap[data-drawer="open"] .burger__bar:nth-child(1) {
  transform: translateY(calc(var(--space-3) / 2)) rotate(45deg);
}
.wrap[data-drawer="open"] .burger__bar:nth-child(2) {
  opacity: 0;
}
.wrap[data-drawer="open"] .burger__bar:nth-child(3) {
  transform: translateY(calc(-1 * var(--space-3) / 2)) rotate(-45deg);
}

.scrim {
  display: none;
  position: fixed;
  inset: 0;
  z-index: var(--z-scrim);
  background: var(--color-scrim);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease);
}
.wrap[data-drawer="open"] .scrim {
  opacity: 1;
  pointer-events: auto;
}

/* Label filter above the contacts table. */
/* Onboarding's error state. Centred with the rest of the step rather than a
   left-aligned block, and readable rather than alarming — most of what lands
   here is recoverable. */
.onb-alert {
  max-width: 46ch;
  text-align: center;
  font-size: var(--text-secondary);
  line-height: var(--leading-normal);
  color: var(--color-text-primary);
  background: var(--color-surface-sunk);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-panel);
  padding: var(--space-4);
}
/* Voice: the brief the agent is given, and the rules it must not break. */
.voice-prompt {
  font-family: inherit;
  line-height: var(--leading-normal);
  min-height: 340px;
}
.v-rule {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-micro);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--color-surface-sunk);
  color: var(--color-text-primary);
}
.v-rule__x {
  all: unset;
  cursor: pointer;
  color: var(--color-text-muted);
  line-height: 1;
}
.v-rule__x:hover {
  color: var(--color-text-primary);
}
.contacts-filter {
  padding: var(--space-3) var(--space-4);
  border-bottom: var(--border-width) solid var(--color-border);
}
.rail-foot {
  margin-top: auto;
  /* anchors the account menu, which opens upward from here */
  position: relative;
}
/* The identity card is now a button that opens the account menu. */
.who {
  all: unset;
  cursor: pointer;
  box-sizing: border-box;
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-input);
  padding: var(--space-2);
  box-shadow: var(--shadow-pill);
}
.who:hover {
  border-color: var(--color-border-strong);
}
.who:focus-visible {
  outline: var(--border-width-thick) solid var(--color-focus);
  outline-offset: var(--offset-inset);
}
.who__chev {
  margin-left: auto;
  flex: none;
  color: var(--color-text-muted);
  font-size: var(--text-micro);
}

/* Opens upward: the card sits at the bottom of the rail. */
.acct-menu {
  position: absolute;
  bottom: calc(100% + var(--space-2));
  left: 0;
  right: 0;
  z-index: 20;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-panel);
  box-shadow: var(--shadow-float);
  padding: var(--space-2);
  display: grid;
  gap: var(--offset-inset);
  min-width: 0;
  overflow: hidden;
}
.acct-menu[hidden] {
  display: none;
}
.acct-item {
  all: unset;
  cursor: pointer;
  display: block;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-input);
  font-size: var(--text-secondary);
  color: var(--color-text-primary);
}
.acct-item:hover {
  background: var(--color-surface-sunk);
}
.acct-item:focus-visible {
  outline: var(--border-width-thick) solid var(--color-focus);
}
.acct-item--quiet {
  color: var(--color-text-secondary);
}
.acct-theme {
  display: flex;
  padding: var(--space-2) var(--space-3);
  min-width: 0;
}
/* The control spans the row and its halves share the width. Sized to its own
   text it overflowed the menu, so the selected pill sat outside the box. */
.acct-theme .segmented {
  display: flex;
  width: 100%;
  min-width: 0;
}
.acct-theme .segmented button {
  flex: 1;
  min-width: 0;
  text-align: center;
}
.acct-sep {
  height: var(--size-hairline);
  background: var(--color-border);
  margin: var(--offset-inset) var(--space-2);
}
.who__text {
  min-width: 0;
}
.who__name {
  font-size: var(--text-micro);
  font-weight: var(--weight-strong);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.who__role {
  font-size: var(--text-label);
  color: var(--color-text-muted);
  white-space: nowrap;
}
.avatar {
  width: var(--size-avatar);
  height: var(--size-avatar);
  border-radius: var(--radius-round);
  flex: none;
  background: var(--color-surface-sunk);
  display: grid;
  place-items: center;
  font-size: var(--text-label);
  font-weight: var(--weight-semibold);
  color: var(--color-text-secondary);
}

/* the sheet — a panel lying on the page ground */
.main {
  min-width: 0;
  overflow: hidden;
  display: flex;
  padding: var(--space-2) var(--space-2) var(--space-2) 0;
  position: relative;
}
.wrap--solo .main {
  padding: var(--space-2);
}
.sheet {
  background: var(--color-surface);
  border-radius: var(--radius-panel);
  flex: 1;
  min-width: 0;
  display: flex;
  overflow: hidden;
}
.view {
  display: flex;
  flex-direction: column;
  width: 100%;
  min-width: 0;
  padding: var(--space-6) var(--space-6) var(--space-5);
  gap: var(--space-5);
}
/* The shell mounts one view at a time; the attribute keeps the mockup's
   semantics without hiding the views that carry no attribute at all. */
.view[data-active="false"] {
  display: none;
}

.tabpanel {
  display: none;
}
.tabpanel[data-active="true"] {
  display: block;
}

.head {
  display: flex;
  align-items: flex-end;
  gap: var(--space-8);
  flex-wrap: wrap;
  flex: none;
}
.head-text {
  min-width: 0;
  flex: 1 1 var(--width-head-text);
}
.kicker {
  font-size: var(--text-label);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}
.lede {
  color: var(--color-text-secondary);
  margin: var(--space-2) 0 0;
  font-size: var(--text-secondary);
  max-width: var(--measure);
}

.stats {
  display: flex;
  background: var(--color-surface-sunk);
  border-radius: var(--radius-card);
  overflow: hidden;
  flex: none;
}
.stat {
  padding: var(--space-3) var(--space-5);
  min-width: 0;
}
.stat + .stat {
  border-left: var(--border-width) solid var(--color-border);
}
.stat .n {
  font-size: var(--text-section);
  font-weight: var(--weight-bold);
  letter-spacing: var(--track-title);
  font-variant-numeric: tabular-nums;
  line-height: var(--leading-tight);
}
.stat .k {
  font-size: var(--text-micro);
  color: var(--color-text-secondary);
  white-space: nowrap;
}
.stat .sub {
  font-size: var(--text-label);
  color: var(--color-text-muted);
  white-space: nowrap;
}

/* ============================ WORKSPACE ================================ */

.workspace {
  flex: 1;
  min-height: 0;
  display: grid;
  gap: var(--space-4);
}
.workspace.split {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
}
.workspace.split-narrow {
  grid-template-columns: var(--width-list-pane) minmax(0, 1fr);
}
/* stacked panels — a control panel above the table it governs */
.workspace--rows {
  grid-template-rows: minmax(0, 0.85fr) minmax(0, 1.15fr);
}
/* the same, where the control is two lines and stretching it to half the page
   would read as an empty screen with a switch lost in the middle of it */
.workspace--control {
  grid-template-rows: auto minmax(0, 1fr);
}

/* a run of swatches and tags on one line; it clips rather than wraps */
.cell-tags {
  max-width: var(--width-tag-cell);
}
.cell-name {
  max-width: var(--width-name-cell);
}
.tag-cell {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  overflow: hidden;
}

.pane {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-card);
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
  overflow: hidden;
}
.pane-head {
  padding: var(--space-3) var(--space-4);
  border-bottom: var(--border-width) solid var(--color-border);
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.pane-title {
  font-size: var(--text-secondary);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--track-flat);
}
.pane-sub {
  font-size: var(--text-micro);
  color: var(--color-text-muted);
}
.pane-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-4);
}
.pane-body.flush {
  padding: 0;
}
.pane-foot {
  padding: var(--space-3) var(--space-4);
  border-top: var(--border-width) solid var(--color-border);
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.spacer {
  margin-left: auto;
}
/* Pins an item to the left of a right-aligned row. */
.mr-auto {
  margin-right: auto;
}
.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.stack--tight {
  gap: var(--space-2);
}
/* A settings row: a fixed key column so every control in a block starts on the
   same x, and the key sits beside the control rather than above it. The key is
   sentence-case secondary — the uppercase label belongs above a group, not
   next to a control (DESIGN_SYSTEM.md §2). */
.settings {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.setting {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--size-control);
}
.setting__k {
  flex: none;
  width: var(--width-setting-key);
  font-size: var(--text-secondary);
  color: var(--color-text-secondary);
}
/* A caveat that belongs to the row above it, indented to sit under that row's
   control rather than under its key. Margin, not padding, so a --measure cap on
   the same element still buys a full line of prose. */
.setting__note {
  margin-left: calc(var(--width-setting-key) + var(--space-3));
}
/* A group header inside a pane. The section label plus a hairline to the pane
   edge — enough to break the body into parts without a heading heavy enough to
   compete with the pane title above it. */
.group {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-2);
}
.group::after {
  content: "";
  flex: 1;
  height: var(--size-hairline);
  background: var(--color-border);
}
/* Name-a-new-label row on the onboarding labels step. .row wraps by default
   and .input is full width, which pushed the button onto its own line. */
.add-label {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: nowrap;
}
.add-label .input {
  flex: 1;
  min-width: 0;
}
.add-label .btn {
  flex: none;
}
.row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

/* ============================ PICK LIST ================================ */

/* One border for the whole list, not one per item — design.md §Density. */
.queue {
  display: flex;
  flex-direction: column;
}
.pick {
  all: unset;
  display: block;
  cursor: pointer;
  padding: var(--space-3) var(--space-4);
  border-bottom: var(--border-width) solid var(--color-border);
  transition: background var(--dur-fast) var(--ease);
}
.pick:last-child {
  border-bottom: 0;
}
.pick:hover {
  background: var(--color-surface-sunk);
}
/* The rundown reuses .pick to list who it found, but those rows go nowhere.
   The class is written for the queue's buttons — reset, pointer cursor, hover
   fill, focus ring — so on a plain div it promised a click that nothing was
   listening for, and the screen read as broken. */
.pick--static {
  cursor: default;
}
.pick--static:hover {
  background: none;
}
.pick:focus-visible {
  outline: var(--border-width-thick) solid var(--color-focus);
  outline-offset: calc(-1 * var(--border-width-thick));
}
.pick[aria-current="true"] {
  background: var(--color-surface-sunk);
  box-shadow: inset var(--offset-inset) 0 0 var(--color-text-primary);
}
.pick__top {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  min-width: 0;
}
.pick__name {
  font-weight: var(--weight-semibold);
  font-size: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pick__name .sq {
  width: 10px;
  height: 10px;
  border-radius: var(--radius-round);
  margin-right: var(--space-1);
}
.pick__when {
  margin-left: auto;
  font-size: var(--text-label);
  color: var(--color-text-muted);
  flex: none;
  font-variant-numeric: tabular-nums;
}
/* Whether this label is actually sending. Sits where the role word sits, and
   is never squashed — it is the one thing in the row that must not be
   half-read. */
.pick__state {
  margin-left: auto;
  flex: none;
}
.pick__prev {
  font-size: var(--text-micro);
  color: var(--color-text-secondary);
  margin-top: var(--space-1);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pick__tags {
  margin-top: var(--space-2);
}
.group-label {
  font-size: var(--text-label);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--color-text-muted);
  padding: var(--space-4) var(--space-4) var(--space-2);
}

.detail-meta {
  margin: 0 0 var(--space-4);
  padding: 0;
  display: grid;
  gap: var(--space-1);
}
.detail-meta div {
  display: flex;
  gap: var(--space-4);
  align-items: baseline;
  font-size: var(--text-secondary);
  min-width: 0;
}
.detail-meta dt {
  flex: none;
  width: var(--width-detail-key);
  color: var(--color-text-muted);
  font-size: var(--text-micro);
}
.detail-meta dd {
  margin: 0;
  min-width: 0;
}
.detail-meta dd .q {
  color: var(--color-text-secondary);
}

.draft {
  padding: var(--space-4) var(--space-5);
  background: var(--color-surface-sunk);
  border-radius: var(--radius-card);
  font-size: var(--text-body);
  line-height: var(--leading-normal);
  max-width: var(--measure);
  white-space: pre-wrap;
}

/* The draft on Today, edited where it is read. Rewriting the message is the
   main action on that screen, so it is the same block at the same size rather
   than a quote with an edit control beside it. It grows with its content: a
   textarea that scrolls hides the end of the message being approved. */
.draft--edit {
  all: unset;
  box-sizing: border-box;
  display: block;
  width: 100%;
  max-width: var(--measure);
  padding: var(--space-4) var(--space-5);
  background: var(--color-surface-sunk);
  border: var(--border-width) solid transparent;
  border-radius: var(--radius-card);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--leading-normal);
  color: var(--color-text-primary);
  white-space: pre-wrap;
  overflow: hidden;
  resize: none;
  transition:
    border-color var(--dur-fast) var(--ease),
    background var(--dur-fast) var(--ease);
}
.draft--edit:hover {
  border-color: var(--color-border);
}
.draft--edit:focus {
  background: var(--color-surface);
  border-color: var(--color-border-strong);
  outline: var(--border-width-thick) solid var(--color-focus);
  outline-offset: var(--size-hairline);
}
.draft--edit + .notice {
  margin-top: var(--space-4);
}

/* ============================= WIZARD ================================== */

/* The panel fills; the prose inside it is capped at --measure. Capping the
   panel instead of the paragraph empties the screen — see design.md. */
/* ============================ ONBOARDING ==============================
   A small, centred, welcoming card per step — mark, clean title, sub, the
   box, one action, and minimal progress dots. Sized to the step: narrow for
   name/QR, wider for areas and labels. */
.onb {
  position: relative;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-8);
  padding: var(--space-8) var(--space-6);
}
.onb__theme {
  position: absolute;
  top: var(--space-6);
  right: var(--space-6);
}
/* Back mirrors the theme switch in the opposite corner — a neat arrow in a
   circle, the same control idiom as the dashboard's collapse button. */
.onb__back {
  position: absolute;
  top: var(--space-6);
  left: var(--space-6);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-round);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  font-size: var(--text-body);
}
.onb__back:hover {
  border-color: var(--color-border-strong);
  background: var(--color-surface-sunk);
  color: var(--color-text-primary);
}
.onb__col {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-5);
  width: 100%;
  max-width: 440px;
}
.onb--md .onb__col {
  max-width: 560px;
}
.onb--lg .onb__col {
  max-width: 680px;
}
.onb__mark {
  width: var(--space-12);
  height: var(--space-12);
  border-radius: var(--radius-panel);
}
.onb__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  text-align: center;
  align-items: center;
}
.onb__title {
  font-size: var(--text-section);
  font-weight: var(--weight-bold);
  letter-spacing: var(--track-section);
  line-height: var(--leading-tight);
  margin: 0;
}
.onb__title .dim {
  color: var(--color-text-muted);
}
.onb__sub {
  font-size: var(--text-secondary);
  color: var(--color-text-secondary);
  line-height: var(--leading-normal);
  margin: 0;
  /* Wide enough that a sentence sits on one line; ledes place their own
     line breaks between sentences (see onboarding.js), so this only has to
     avoid re-wrapping those lines. text-wrap: pretty tidies the fallback
     wrap on narrow viewports. */
  max-width: 54ch;
  text-wrap: pretty;
}
.onb--lg .onb__sub {
  max-width: 64ch;
}
.onb__card {
  width: 100%;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-panel);
  box-shadow: var(--shadow-float);
  overflow: hidden;
}
.onb__card-scroll {
  padding: var(--space-6);
  max-height: 56vh;
  overflow-y: auto;
}
.onb__card-foot {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-6);
  border-top: var(--border-width) solid var(--color-border);
  /* The action always sits on the right, every step, so the eye learns one
     place to look. Anything alongside it (a count, a note) goes left via
     .spacer on the button, which still resolves to the right-hand edge. */
  justify-content: flex-end;
}
/* A lone note with no button — centre it rather than stranding it right. */
.onb__card-foot:not(:has(.btn)) {
  justify-content: center;
}
/* Emphasised phrase inside a step subtext — bold, in the primary text colour
   (white in dark, near-black in light). */
.onb-emph {
  color: var(--color-text-primary);
  font-weight: var(--weight-strong);
}
/* The live "Broker AI will manage N chats" tally on the labels step. The text
   stays neutral; only the number turns green once at least one label is on. */
.onb-managed {
  font-size: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  color: var(--color-text-secondary);
}
.onb-managed__n {
  color: var(--color-text-muted);
  transition: color var(--dur-fast) var(--ease);
}
.onb-managed__n--on {
  color: var(--color-success);
  font-weight: var(--weight-strong);
}
/* Vertically-centred step content — QR, spinners, the linked badge. */
.onb-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  text-align: center;
}
.onb__dots {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.onb__dot {
  width: var(--space-2);
  height: var(--space-2);
  border-radius: var(--radius-round);
  background: var(--color-border-strong);
  transition:
    width var(--dur-fast) var(--ease),
    background var(--dur-fast) var(--ease);
}
.onb__dot[data-state="now"] {
  width: var(--space-6);
  border-radius: var(--radius-pill);
  background: var(--color-action);
}
.onb__dot[data-state="done"] {
  background: var(--color-text-muted);
}
/* QR sits calmly inside the card, not stretched. */
.onb__card-scroll .qr,
.onb__card-scroll .qr img {
  max-width: 220px;
}

.wizard {
  width: 100%;
  display: flex;
  flex-direction: column;
  min-height: 0;
  gap: var(--space-5);
  flex: 1;
}

.wizsteps {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex: none;
  flex-wrap: wrap;
}
.wizstep {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}
.wizstep + .wizstep::before {
  content: "";
  width: var(--space-6);
  height: var(--size-hairline);
  background: var(--color-border);
  flex: none;
}
.wizstep__n {
  width: var(--size-step-dot);
  height: var(--size-step-dot);
  border-radius: var(--radius-round);
  flex: none;
  display: grid;
  place-items: center;
  font-size: var(--text-label);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  background: var(--color-surface-sunk);
  color: var(--color-text-muted);
}
.wizstep__t {
  font-size: var(--text-micro);
  color: var(--color-text-muted);
  white-space: nowrap;
}
.wizstep[data-state="done"] .wizstep__n {
  background: var(--color-success-bg);
  color: var(--color-success);
}
.wizstep[data-state="done"] .wizstep__t {
  color: var(--color-text-secondary);
}
.wizstep[data-state="now"] .wizstep__n {
  background: var(--color-action);
  color: var(--color-action-label);
}
.wizstep[data-state="now"] .wizstep__t {
  color: var(--color-text-primary);
  font-weight: var(--weight-strong);
}

/* chips — free entry, add and remove */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-2) var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--color-surface-sunk);
  border: var(--border-width) solid transparent;
  font-size: var(--text-micro);
  color: var(--color-text-primary);
  max-width: 100%;
}
.chip__x {
  all: unset;
  cursor: pointer;
  width: var(--space-4);
  height: var(--space-4);
  border-radius: var(--radius-round);
  display: grid;
  place-items: center;
  color: var(--color-text-muted);
  font-size: var(--text-label);
  flex: none;
}
.chip__x:hover {
  background: var(--color-border);
  color: var(--color-text-primary);
}
.chip__x:focus-visible {
  outline: var(--border-width-thick) solid var(--color-focus);
  outline-offset: var(--size-hairline);
}

.chip-add {
  all: unset;
  cursor: pointer;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  border: var(--border-width) dashed var(--color-border);
  font-size: var(--text-micro);
  color: var(--color-text-secondary);
  transition:
    border-color var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease);
}

/* .chip-add is dashed because it usually means "add one". When it carries
   aria-pressed it is a choice instead, and an unselected and selected choice
   looked identical — the only hint was the browser's focus ring. */
.chip-add[aria-pressed] {
  border-style: solid;
}
.chip-add[aria-pressed="true"] {
  background: var(--color-action);
  color: var(--color-action-label);
  border-color: transparent;
  font-weight: var(--weight-strong);
}
.chip-add[aria-pressed="true"]:hover {
  background: var(--color-action-hover);
}
.chip-add:hover {
  border-color: var(--color-border-strong);
  color: var(--color-text-primary);
}
.chip-add:focus-visible {
  outline: var(--border-width-thick) solid var(--color-focus);
  outline-offset: var(--offset-inset);
}
.chip-add[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
}

/* QR — scannable surfaces stay light in both themes */
.qr-frame {
  width: var(--size-qr);
  height: var(--size-qr);
  flex: none;
  display: grid;
  place-items: center;
  padding: var(--space-3);
  background: var(--color-scan-paper);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-card);
}
.qr-frame img {
  width: 100%;
  height: 100%;
  display: block;
  image-rendering: pixelated;
}
.qr-frame--waiting {
  background: var(--color-surface-sunk);
  border-style: dashed;
}

.steps-list {
  list-style: none;
  margin: var(--space-2) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.steps-list li {
  font-size: var(--text-micro);
  color: var(--color-text-secondary);
}

/* sync progress */
.sync-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) 0;
}
.sync-row + .sync-row {
  border-top: var(--border-width) solid var(--color-border);
}
.sync-row__t {
  font-size: var(--text-secondary);
  flex: 1;
  min-width: 0;
}
.sync-row__n {
  font-size: var(--text-micro);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
  flex: none;
}

/* role picker rows */
.role-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: var(--border-width) solid var(--color-border);
}
.role-row:last-child {
  border-bottom: 0;
}
.role-row__id {
  min-width: 0;
  flex: 1 1 var(--width-role-name);
}
.role-row__name {
  font-size: var(--text-secondary);
  font-weight: var(--weight-strong);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.role-row__meta {
  font-size: var(--text-micro);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}
.role-row[data-role="keep_warm"] {
  background: var(--color-surface-sunk);
}
.cadence {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-micro);
  color: var(--color-text-muted);
}

/* ============================= STATES ================================== */

.loading-screen {
  height: 100%;
  display: grid;
  place-items: center;
  gap: var(--space-3);
  color: var(--color-text-muted);
  font-size: var(--text-secondary);
}
.error-block {
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-card);
  background: var(--color-crit-bg);
  color: var(--color-crit);
  padding: var(--space-4) var(--space-5);
  font-size: var(--text-secondary);
  max-width: var(--measure);
}
.error-block b {
  font-weight: var(--weight-semibold);
}

/* ============================ RESPONSIVE ===============================
   Three widths. Above 1080px is the design as drawn; below that the two-up
   workspaces go one-up, below 900px the rail becomes a drawer behind the
   menu button, and below 620px the last two-up grids stack. Sizes come from
   the compact tokens in :root. */

@media (max-width: 1080px) {
  .workspace.split {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---------------------------- COMPACT --------------------------------- */

@media (max-width: 900px) {
  /* The document scrolls rather than the sheet. Views are long on a phone,
     and a scrolling body keeps the browser's own chrome behaving. */
  body {
    overflow: auto;
  }
  .wrap {
    grid-template-columns: minmax(0, 1fr);
    height: auto;
    min-height: 100dvh;
    overflow: visible;
  }
  /* The drawer owns the scroll while it is open.
     Three things had to be true at once, hence the shape of this:
     overflow on .wrap does nothing (the viewport is the scroller, not .wrap);
     setting it on body alone relies on body→viewport propagation, which
     Chrome does not re-evaluate when the value changes mid-page; and locking
     the root on its own throws the scroll position away, so the page is back
     at the top when the drawer closes. Pinning the body at minus its own
     scroll offset holds the page still where the broker left it —
     --scroll-lock is set by setDrawer() in shell.js. */
  html:has(.wrap[data-drawer="open"]) {
    overflow: hidden;
  }
  body:has(.wrap[data-drawer="open"]) {
    position: fixed;
    top: var(--scroll-lock, 0px);
    left: 0;
    right: 0;
    width: 100%;
    overflow: hidden;
  }

  /* ---- controls grow to a comfortable tap target ---------------------- */
  .wrap,
  .onb,
  .walk {
    --size-control: var(--size-touch);
    --size-control-lg: 48px;
    --size-control-sm: 32px;
    --size-input: var(--size-touch);
    --size-nav-item: var(--size-touch);
  }
  /* iOS zooms the whole page when a focused field is under 16px. */
  .input,
  .select,
  .textarea,
  textarea,
  input[type="text"],
  input[type="email"],
  input[type="search"],
  input[type="number"] {
    font-size: var(--text-input-touch);
  }

  /* ---- the bar, the drawer, the scrim --------------------------------- */
  .topbar {
    display: flex;
  }
  .scrim {
    display: block;
  }
  /* The rail leaves the grid and becomes a drawer. Only `data-drawer` moves
     it now, so the desktop collapse state must not leave it invisible here. */
  .rail {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    width: var(--width-drawer);
    z-index: var(--z-drawer);
    flex-direction: column;
    gap: var(--space-4);
    padding: var(--space-4) var(--space-3);
    background: var(--color-surface);
    border-right: var(--border-width) solid var(--color-border);
    box-shadow: var(--shadow-float);
    overflow-y: auto;
    overscroll-behavior: contain;
    opacity: 1;
    pointer-events: auto;
    transform: translateX(-100%);
    transition: transform var(--dur-base) var(--ease);
  }
  /* The icon strip is a desktop idea. A drawer you have chosen to open should
     show you words, so `data-nav` is fully undone at this width — every rule
     in "the collapsed rail" block above has its counterpart here. */
  .wrap[data-nav="closed"] .rail {
    opacity: 1;
    pointer-events: auto;
    overflow-y: auto;
  }
  .wrap[data-drawer="open"] .rail {
    transform: none;
  }
  .wrap[data-nav="closed"] .brand {
    padding: 0 var(--space-2);
    justify-content: flex-start;
  }
  .wrap[data-nav="closed"] .brand-name,
  .wrap[data-nav="closed"] #nav-close {
    display: block;
  }
  .nav {
    flex-direction: column;
    margin-top: var(--space-4);
  }
  .nav__group,
  .wrap[data-nav="closed"] .nav__group,
  .wrap[data-nav="closed"] .nav__group:first-child {
    display: block;
    height: auto;
    padding: var(--space-3) var(--space-2) var(--space-1);
    margin: 0;
    background: none;
    font-size: var(--text-label);
    color: var(--color-text-muted);
  }
  .wrap[data-nav="closed"] .nav__item {
    width: auto;
    margin: 0;
    padding: 0 var(--space-2);
    gap: var(--space-2);
    justify-content: flex-start;
  }
  .wrap[data-nav="closed"] .nav__icon {
    width: 0;
    opacity: 0;
  }
  .wrap[data-nav="closed"] .nav__label {
    max-width: 12rem;
    opacity: 1;
  }
  .wrap[data-nav="closed"] .nav__count,
  .wrap[data-nav="closed"] .nav__item[aria-current="true"] .nav__count {
    position: static;
    margin-left: auto;
    min-width: 0;
    height: auto;
    padding: 0 var(--space-2);
    display: block;
    box-shadow: none;
  }
  .who,
  .wrap[data-nav="closed"] .who {
    display: flex;
    justify-content: flex-start;
    gap: var(--space-2);
  }
  .wrap[data-nav="closed"] .who__text,
  .wrap[data-nav="closed"] .who__chev {
    display: block;
  }
  .wrap[data-nav="closed"] .acct-menu {
    bottom: calc(100% + var(--space-2));
    left: 0;
    right: 0;
    width: auto;
  }
  .rail-foot {
    margin-top: auto;
    margin-left: 0;
    padding-top: var(--space-4);
  }
  /* Nothing to restore here — the burger does that. The collapse button
     stays, as the drawer's own close. */
  .nav-open,
  .wrap[data-nav="closed"] .nav-open {
    display: none;
  }
  #nav-close {
    width: var(--size-control);
    height: var(--size-control);
  }

  /* ---- the sheet sits under the bar ----------------------------------- */
  .main {
    overflow: visible;
    padding: var(--space-2);
    padding-top: calc(var(--size-topbar) + var(--space-2));
  }
  .sheet {
    display: block;
  }
  .view {
    padding: var(--space-5) var(--space-4);
  }

  /* ---- layouts that assumed two columns ------------------------------- */
  .workspace {
    grid-template-columns: minmax(0, 1fr) !important;
  }
  .workspace--rows {
    grid-template-rows: auto;
  }
  .today-first-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .stats {
    flex-wrap: wrap;
  }
  .t-title {
    font-size: var(--text-section);
  }
  .role-row {
    flex-wrap: wrap;
  }
  /* A fixed key column and a segmented control do not both fit. The key goes
     back above its control, which is the system's own field layout anyway. */
  .setting {
    align-items: flex-start;
    flex-direction: column;
    gap: var(--space-2);
  }
  .setting__k {
    width: auto;
  }
  .setting__note {
    margin-left: 0;
  }
  .settings {
    gap: var(--space-4);
  }
  /* Cells that clip to a fixed width on desktop have no room to here. */
  .cell-tags,
  .cell-name {
    max-width: none;
  }
  /* Tables keep their shape and scroll sideways inside their own frame
     rather than squashing columns into unreadable slivers. */
  .table-wrap {
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
  }
  th,
  td {
    padding-left: var(--space-3);
    padding-right: var(--space-3);
  }

  /* ---- onboarding and the walkthrough --------------------------------- */
  /* Both are their own full-page layouts — no rail, no bar — so they only
     need their corners and padding pulled in. */
  .onb {
    gap: var(--space-6);
    padding: var(--space-16) var(--space-4) var(--space-8);
  }
  .onb__theme {
    top: var(--space-4);
    right: var(--space-4);
  }
  .onb__back {
    top: var(--space-4);
    left: var(--space-4);
  }
  .onb__card-scroll {
    padding: var(--space-4);
    max-height: none;
  }
  .onb__card-foot {
    padding: var(--space-4);
  }
  .walk,
  .relink {
    padding: var(--space-6) var(--space-4);
    align-items: flex-start;
  }
}

/* ---------------------------- NARROW ---------------------------------- */

@media (max-width: 620px) {
  .view {
    padding: var(--space-4) var(--space-3);
  }
  .head {
    gap: var(--space-4);
  }
  /* The last of the two-up grids. Below this they are simply too tight. */
  .walk-figures,
  .walk-options,
  .field-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  /* Action rows wrap rather than shrink a button to a sliver. */
  .onb__card-foot {
    flex-wrap: wrap;
  }
  .onb__card-foot > .btn {
    flex: 1 1 auto;
    justify-content: center;
  }

  /* Tables become cards, one row each. Sideways scrolling inside a page that
     scrolls downward hides whole columns; see stackTable() in views.js, which
     stamps each cell with the column it came from. */
  .table--stack thead {
    display: none;
  }
  .table--stack,
  .table--stack tbody,
  .table--stack tr,
  .table--stack td {
    display: block;
    width: 100%;
  }
  .table--stack tr {
    padding: var(--space-3) var(--space-4);
    border-bottom: var(--border-width) solid var(--color-border);
  }
  .table--stack tbody tr:last-child {
    border-bottom: 0;
  }
  .table--stack td {
    display: flex;
    align-items: baseline;
    gap: var(--space-4);
    height: auto;
    padding: var(--space-1) 0;
    border-bottom: 0;
  }
  .table--stack td[data-k]::before {
    content: attr(data-k);
    flex: none;
    width: var(--width-stack-key);
    font-size: var(--text-label);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--color-text-muted);
  }
  /* The name leads the card, so it drops its label and takes the weight. */
  .table--stack td:first-child::before {
    display: none;
  }
  .table--stack td:first-child {
    font-size: var(--text-body);
    font-weight: var(--weight-semibold);
    padding-bottom: var(--space-2);
  }
  /* A column of controls sits on the right of the card, not in the stack. */
  .table--stack td.cell-action {
    justify-content: flex-end;
    text-align: right;
    width: 100%;
  }
  .table--stack .tag-cell {
    flex-wrap: wrap;
    overflow: visible;
  }
  /* The expandable document preview is a row of its own; it spans the card. */
  .table--stack tr.view-row td {
    padding: 0;
  }
  .table--stack tr.view-row td::before {
    display: none;
  }
}

/* ============================== DEV MODE =============================== */

/* The funnel. One row per stage of the loop: what it is, how many reached it,
   how far that is across the widest stage, and what was lost getting here.
   The gap between two rows is a population, so the rows sit tight together. */
.funnel {
  display: grid;
  gap: var(--space-1);
  margin-bottom: var(--space-5);
}
.funnel__row {
  display: grid;
  grid-template-columns:
    minmax(0, 1fr) var(--width-funnel-n)
    minmax(0, 1.1fr) var(--width-funnel-n);
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-2) 0;
  border-bottom: var(--border-width) solid var(--color-border);
}
.funnel__row:last-child {
  border-bottom: 0;
}
.funnel__text {
  min-width: 0;
}
.funnel__label {
  font-size: var(--text-body);
  font-weight: var(--weight-medium);
}
.funnel__note {
  font-size: var(--text-micro);
  color: var(--color-text-muted);
}
.funnel__n {
  font-size: var(--text-section);
  font-weight: var(--weight-bold);
  letter-spacing: var(--track-title);
  text-align: right;
}
.funnel__drop {
  font-size: var(--text-micro);
  color: var(--color-text-muted);
  text-align: right;
}

/* One skip group: how many, what it is, and the model's most common wording
   for it. Doubles as the filter for the table underneath. */
.group-pick {
  display: grid;
  grid-template-columns: var(--width-funnel-n) minmax(0, auto) minmax(0, 1fr);
  align-items: baseline;
  gap: var(--space-3);
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  background: var(--color-surface-sunk);
  border: var(--border-width) solid transparent;
  border-radius: var(--radius-card);
  padding: var(--space-2) var(--space-3);
  cursor: pointer;
}
.group-pick:hover {
  border-color: var(--color-border-strong);
}
.group-pick:focus-visible {
  outline: var(--border-width-thick) solid var(--color-focus);
  outline-offset: var(--offset-inset);
}
.group-pick[aria-pressed="true"] {
  border-color: var(--color-text-primary);
}
.group-pick__n {
  font-size: var(--text-card);
  font-weight: var(--weight-bold);
  text-align: right;
}
.group-pick__t {
  font-size: var(--text-secondary);
}
.group-pick__say {
  font-size: var(--text-micro);
  color: var(--color-text-muted);
}

/* The prompt, exactly as the model saw it. Long lines scroll inside this box;
   the page itself never scrolls sideways (design.md § Truncate). */
.trace-pre {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  line-height: var(--leading-normal);
  color: var(--color-text-secondary);
  background: var(--color-surface-sunk);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-card);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  max-height: var(--height-pre);
  overflow: auto;
}

@media (max-width: 620px) {
  .funnel__row {
    grid-template-columns: minmax(0, 1fr) var(--width-funnel-n);
    gap: var(--space-2);
  }
  .funnel__row .bar,
  .funnel__drop {
    display: none;
  }
  .group-pick {
    grid-template-columns: var(--width-funnel-n) minmax(0, 1fr);
  }
  .group-pick__say {
    display: none;
  }
}

/* .select fills its container by default, which in a flex head makes the run
   picker a full-width bar on its own line. Inline here, sized to its label. */
.run-pick {
  width: auto;
  max-width: 100%;
}

/* The model's sentence is the widest thing in the trace table and would push
   Time and Tokens off the panel. Capped like the other long cells. */
.trace-why {
  max-width: var(--width-why-cell);
}
