/* Workbench layout.
 *
 * A run is the unit of work and runs accumulate, so the list of them is
 * permanent furniture rather than a tab you navigate away to. The main pane
 * shows exactly one run — composing it, watching it, or reading it.
 */

/* ═══ Frame ════════════════════════════════════════════════════════════ */

.workbench {
  display: grid;
  grid-template-columns: var(--sidebar-width) 1fr;
  height: 100vh;
  height: 100dvh;          /* mobile browsers shrink the viewport on scroll */
  overflow: hidden;         /* each pane scrolls independently */
  transition: grid-template-columns var(--duration-base) var(--ease);
}
/* Collapsing hides the rail's content but keeps a 52px strip, because the
   toggle lives inside it: a zero-width sidebar took its own reopen control
   with it, and the state is persisted, so a reload did not recover either. */
.workbench[data-collapsed="true"] { grid-template-columns: 52px 1fr; }
.workbench[data-collapsed="true"] .brand__name,
.workbench[data-collapsed="true"] .new-run span,
.workbench[data-collapsed="true"] .new-run .kbd,
.workbench[data-collapsed="true"] .runlist,
.workbench[data-collapsed="true"] .capacity__label,
.workbench[data-collapsed="true"] .bare-select { display: none; }
.workbench[data-collapsed="true"] .sidebar__head { padding: 0 var(--space-2); justify-content: center; }
.workbench[data-collapsed="true"] .brand { display: none; }
.workbench[data-collapsed="true"] .new-run { justify-content: center; margin-inline: var(--space-2); padding-inline: 0; }
.workbench[data-collapsed="true"] .sidebar__foot { justify-content: center; padding-inline: var(--space-2); }

/* ═══ Sidebar ══════════════════════════════════════════════════════════ */

.sidebar {
  display: flex;
  flex-direction: column;
  min-width: 0;
  border-right: 1px solid var(--border-subtle);
  background: var(--bg-sidebar);
  overflow: hidden;
}

.sidebar__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  height: var(--header-height);
  padding: 0 var(--space-3) 0 var(--space-5);
  flex-shrink: 0;
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  flex: 1;
  color: var(--text-primary);
}
.brand:hover { color: var(--text-primary); }
.brand__mark {
  width: 24px; height: 24px;
  display: block;
  flex-shrink: 0;
}
.brand__name {
  font-family: var(--font-serif);
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.icon-btn {
  width: 30px; height: 30px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-md);
  color: var(--text-tertiary);
  flex-shrink: 0;
  transition: background var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease);
}
.icon-btn svg { width: 16px; height: 16px; }
.icon-btn:hover { background: var(--bg-hover); color: var(--text-primary); }

/* ── New run ── */
.new-run {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: var(--space-1) var(--space-4) var(--space-4);
  padding: 9px var(--space-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  box-shadow: var(--shadow-sm);
  color: var(--text-primary);
  font-size: var(--text-base);
  font-weight: 500;
  white-space: nowrap;
  transition: background var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease);
}
.new-run svg { width: 15px; height: 15px; flex-shrink: 0; color: var(--accent); }
.new-run:hover {
  border-color: var(--accent-border);
  box-shadow: var(--shadow-md);
}

.kbd {
  margin-left: auto;
  padding: 0 6px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  background: var(--bg-overlay);
  color: var(--text-tertiary);
  font-family: var(--font-mono);
  font-size: 10px;
  line-height: 1.7;
}

/* ── Run list ── */
.runsearch {
  margin: 0 var(--space-4) var(--space-3);
  padding: 7px var(--space-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--bg-input);
  color: var(--text-primary);
  font-size: var(--text-sm);
}
.runsearch::placeholder { color: var(--text-disabled); }
.runsearch:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-ring);
}
.runlist__more {
  display: block;
  width: 100%;
  margin-top: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px dashed var(--border-default);
  border-radius: var(--radius-md);
  color: var(--text-secondary);
  font-size: var(--text-sm);
}
.runlist__more:hover { color: var(--accent); border-color: var(--accent); }
.runlist__note {
  margin-top: var(--space-3);
  padding: 0 var(--space-2);
  color: var(--text-tertiary);
  font-size: var(--text-xs);
  line-height: var(--leading-normal);
}

.runlist {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 0 var(--space-3) var(--space-3);
  min-height: 0;
}

.runlist__group {
  padding: var(--space-4) var(--space-2) var(--space-2);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

.runitem {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: 7px var(--space-2) 7px var(--space-3);
  border-radius: var(--radius-md);
  color: var(--text-secondary);
  font-size: var(--text-base);
  text-align: left;
  transition: background var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease);
}
.runitem:hover { background: var(--bg-hover); color: var(--text-primary); }
.runitem[aria-current="true"] {
  background: var(--bg-raised);
  color: var(--text-primary);
  box-shadow: var(--shadow-sm), inset 0 0 0 1px var(--border-subtle);
}

.runitem__state {
  width: 7px; height: 7px;
  border-radius: var(--radius-full);
  flex-shrink: 0;
  background: var(--text-disabled);
}
.runitem__state[data-state="running"] {
  background: var(--accent);
  animation: pulse-dot 1.8s var(--ease) infinite;
}
.runitem__state[data-state="completed"] { background: var(--success); }
.runitem__state[data-state="failed"]    { background: var(--danger); }
.runitem__state[data-state="cancelled"] { background: var(--text-disabled); }
.runitem__state[data-state="timeout"]   { background: var(--warning); }

@keyframes pulse-dot {
  0%, 100% { box-shadow: 0 0 0 0 var(--accent-ring); }
  55%      { box-shadow: 0 0 0 5px transparent; }
}

.runitem__label {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Admin view: the owner badge sits on a second line under the topic, so the
   topic keeps the rail's full width (sidebar.js render()). */
.runitem--owned { align-items: flex-start; }
.runitem--owned .runitem__state { margin-top: 0.55em; }
.runitem__text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
}
.runitem__text .runitem__label { flex: none; width: 100%; }

/* Only ever rendered for an admin request (RunSummary.owner_label) — which
   code ran this, so a merged multi-code history stays legible instead of
   reading as one undifferentiated list. */
.runitem__owner {
  flex-shrink: 0;
  max-width: 100%;
  padding: 1px var(--space-2);
  border-radius: var(--radius-full);
  background: var(--bg-overlay);
  color: var(--text-tertiary);
  font-size: var(--text-xs);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Buttons cannot nest inside a <button>, so the select button and the
   delete icon sit side by side in this row instead of one inside the
   other (see sidebar.js render()). */
.runitem-row {
  display: flex;
  align-items: center;
  gap: 2px;
}
.runitem-row .runitem { flex: 1; min-width: 0; }

/* Always rendered, never hover-gated: the person who owns these runs could
   not find a hover-only delete at all. It stays quiet at rest instead and
   turns red on hover, so it reads as available without competing with the
   topic it sits beside. */
.runitem__delete {
  flex-shrink: 0;
  color: var(--text-disabled);
  transition: background var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease);
}
.runitem__delete:hover,
.runitem__delete:focus-visible {
  background: var(--danger-subtle);
  color: var(--danger);
}

.runlist__empty {
  margin: var(--space-6) var(--space-2) 0;
  padding: var(--space-6) var(--space-4);
  border: 1px dashed var(--border-default);
  border-radius: var(--radius-lg);
  text-align: center;
  color: var(--text-tertiary);
  font-size: var(--text-sm);
}

/* ── Sidebar footer ── */
.sidebar__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  border-top: 1px solid var(--border-subtle);
  flex-shrink: 0;
}

/* Injected by api/main.py only when the saved-source locator is enabled.
   It takes a row of its own: sharing one with the capacity line and the
   language select overflowed the rail, and the capacity label ran under
   the select. */
#source-locator-link {
  flex-basis: 100%;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: var(--text-xs);
  font-weight: 500;
}
.workbench[data-collapsed="true"] #source-locator-link { display: none; }

.capacity {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex: 1;
  min-width: 0;
}
.capacity__dots { display: flex; gap: 3px; }
.capacity__dot {
  width: 6px; height: 6px;
  border-radius: var(--radius-full);
  background: var(--bg-active);
}
.capacity__dot[data-busy="true"] { background: var(--accent); }
.capacity__label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  white-space: nowrap;
}

.bare-select {
  padding: 3px var(--space-2);
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-tertiary);
  font-size: var(--text-xs);
  font-weight: 500;
  cursor: pointer;
  border-radius: var(--radius-sm);
}
.bare-select:hover { color: var(--text-primary); background: var(--bg-hover); }
.bare-select option { background: var(--bg-raised); color: var(--text-primary); }

/* ═══ Main ═════════════════════════════════════════════════════════════ */

.main {
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--bg-base);
}

/* The phone bar holds the only control that opens the overlay sidebar: the
   sidebar's own toggle sits inside the sidebar, which is off-screen there.
   It is in the flow, not fixed, so it never covers the run header. */
.mobilebar { display: none; }
.scrim {
  position: fixed;
  inset: 0;
  z-index: 55;
  background: var(--scrim);
  animation: fade-in var(--duration-base) var(--ease-out);
}
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

.pane {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

.pane__head {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding: var(--space-6) var(--space-10) var(--space-5);
  border-bottom: 1px solid var(--border-subtle);
  background: var(--bg-base);
  flex-shrink: 0;
}
.pane__heading { flex: 1; min-width: 0; }
.pane__title {
  font-size: var(--text-xl);
  font-weight: 600;
  letter-spacing: -0.012em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pane__meta {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-tertiary);
}
.pane__actions { display: flex; gap: var(--space-2); flex-shrink: 0; }
/* A finished run has five controls. In one unshrinking row they took the
   whole header on a narrow pane and left the heading no width at all. They
   keep to their own half and wrap inside it; the heading keeps the other. */
#pane-run .pane__actions,
#pane-compare .pane__actions { flex-wrap: wrap; justify-content: flex-end; max-width: 50%; }

/* Run metadata is saved output and can include long translated diagnostics.
   Let it wrap before it narrows its siblings to unusable columns. */
#pane-run .pane__meta { flex-wrap: wrap; min-width: 0; row-gap: var(--space-1); }
#pane-run .pane__meta > span {
  min-width: 0;
  max-width: 100%;
  overflow-wrap: anywhere;
}
#pane-run #run-pill,
#pane-run #run-elapsed {
  flex: 0 0 auto;
  white-space: nowrap;
}

/* Opt-in completion notice; shown only while the browser has not been asked. */
#pane-run .run-notify {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-decoration: underline dotted;
  text-underline-offset: 3px;
  cursor: pointer;
}
#pane-run .run-notify:hover { color: var(--text-secondary); }

/* Usage and its accounting caveats, and stage timing: folded behind one click, never removed. */
#pane-run .run-usage { min-width: 0; max-width: 100%; }
#pane-run .run-usage > summary {
  cursor: pointer;
  list-style: none;
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}
#pane-run .run-usage > summary::-webkit-details-marker { display: none; }
#pane-run .run-usage > summary:hover { color: var(--text-secondary); }
#pane-run .run-usage[open] { flex-basis: 100%; }
#pane-run .run-usage > #run-usage,
#pane-run .run-usage > #run-timing {
  display: block;
  margin-top: var(--space-1);
  overflow-wrap: anywhere;
}

/* Why a run ended and whether it spent one of today's runs: a full line under
   the metadata, in body text rather than the metadata's tertiary grey. */
#pane-run .run-outcome {
  margin: var(--space-2) 0 0;
  max-width: 72ch;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  overflow-wrap: anywhere;
}

.dot-sep {
  width: 3px; height: 3px;
  border-radius: var(--radius-full);
  background: var(--text-disabled);
}

.pane__body {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-8) var(--space-10) var(--space-12);
  min-height: 0;
}
/* A measure, not the window width — but 860px wasted most of a wide screen.
   Prose sets its own narrower limit further in; scorecards and source lists
   have short lines and benefit from the extra room. */
.pane__body > * { max-width: 1060px; margin-inline: auto; }
.pane__head > * { max-width: none; }
/* Centred with auto margins, not align-items: a flex-centred child taller
   than the pane (the composer with decision context open) overflowed upward,
   past the scroll origin, so its title could not be scrolled back into view.
   Auto margins centre a short child and collapse to zero for a tall one. */
.pane__body--centered {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: var(--space-10) var(--space-6);
}
.pane__body--centered > .compose { margin-block: auto; }

/* ═══ Composer ═════════════════════════════════════════════════════════ */

.compose { width: 100%; max-width: 700px; }

.compose__title {
  font-size: var(--text-3xl);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.12;
  text-align: center;
  margin-bottom: var(--space-4);
}
.compose__sub {
  font-size: var(--text-md);
  color: var(--text-tertiary);
  text-align: center;
  max-width: 56ch;
  margin: 0 auto var(--space-8);
}
/* Sits in the gap .compose__sub leaves, so the composer does not move down. */
.compose__samples {
  text-align: center;
  font-size: var(--text-sm);
  margin: calc(var(--space-6) * -1) 0 var(--space-6);
}
.compose__samples a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 3px var(--space-3);
  border-radius: var(--radius-full);
  background: var(--accent-subtle);
  font-weight: 500;
}

/* The whole block is the control; the textarea inside has no chrome of its
   own, so focus is expressed by the container rather than by two nested
   outlines fighting each other. */
.composer {
  border: 1px solid var(--border-default);
  border-radius: var(--radius-xl);
  background: var(--bg-input);
  box-shadow: var(--shadow-md);
  transition: border-color var(--duration-base) var(--ease),
              box-shadow var(--duration-base) var(--ease);
}
.composer:focus-within {
  border-color: var(--accent);
  box-shadow: var(--shadow-md), 0 0 0 4px var(--accent-subtle);
}

.composer__input {
  display: block;
  width: 100%;
  max-height: 40vh;
  padding: var(--space-5) var(--space-5) var(--space-3);
  background: none;
  border: none;
  color: var(--text-primary);
  font-size: var(--text-lg);
  line-height: var(--leading-normal);
  resize: none;
  overflow-y: auto;
}
.composer__input::placeholder { color: var(--text-disabled); }

/* Focus is expressed once, by the container: base.css's outline would draw a
   second rectangle inside the first. Keyboard users lose nothing, because
   that border is the focus indicator. */
.composer__input:focus-visible {
  outline: none;
}
/* The chips and the send button keep base.css's outline. They sit inside the
   already-focused container, so tabbing between them changes nothing on its
   border, and the translucent 3px shadow that used to mark them stayed under
   3:1 against the bar in both themes: e2e/keyboard_smoke.py measured no
   pixel of it at that contrast. */

.composer__bar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3) var(--space-3) var(--space-4);
  flex-wrap: wrap;
}
.composer__spacer { flex: 1; min-width: var(--space-2); }
.composer__count {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
}

.chip-btn,
.chip-select {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 var(--space-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-full);
  background: var(--bg-raised);
  color: var(--text-secondary);
  font-size: var(--text-sm);
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease);
}
.chip-btn svg { width: 13px; height: 13px; }
.chip-btn:hover,
.chip-select:hover {
  background: var(--bg-hover);
  border-color: var(--border-strong);
  color: var(--text-primary);
}
.chip-btn[data-active="true"] {
  background: var(--accent-subtle);
  border-color: var(--accent-border);
  color: var(--accent);
}

.chip-select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 26px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%238a857c' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
}
.chip-select option { background: var(--bg-raised); color: var(--text-primary); }

.send-btn {
  width: 36px; height: 36px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-full);
  background: var(--accent);
  color: var(--on-accent);
  flex-shrink: 0;
  box-shadow: var(--shadow-sm);
  transition: background var(--duration-fast) var(--ease),
              opacity var(--duration-fast) var(--ease),
              transform var(--duration-fast) var(--ease);
}
.send-btn svg { width: 16px; height: 16px; }
.send-btn:hover:not(:disabled) { background: var(--accent-hover); }
.send-btn:active:not(:disabled) { transform: scale(0.94); }
.send-btn:disabled {
  background: var(--bg-active);
  color: var(--text-disabled);
  box-shadow: none;
  cursor: not-allowed;
}

.composer__attachment {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0 var(--space-4) var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--bg-overlay);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.composer__quota {
  color: var(--text-tertiary);
  font-size: var(--text-xs);
  white-space: nowrap;
}
.composer__quota--empty { color: var(--danger); }

.composer__privacy {
  margin: 0 var(--space-4) var(--space-4);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-subtle);
  color: var(--text-tertiary);
  font-size: var(--text-xs);
  line-height: 1.5;
}

/* Search-plan preview: the planner's reading of the topic, confirmed or
   edited before a code-funded run starts. */
.plan-panel {
  margin-top: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--accent);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  box-shadow: var(--shadow-sm);
}
.plan-panel__title {
  margin: 0 0 var(--space-2);
  color: var(--text-primary);
  font-size: var(--text-md);
  font-weight: 600;
}
.plan-panel__lede {
  margin: 0 0 var(--space-4);
  color: var(--text-secondary);
  font-size: var(--text-sm);
  line-height: 1.6;
}
.plan-panel__label {
  display: block;
  margin-bottom: 6px;
  color: var(--text-secondary);
  font-size: var(--text-xs);
  font-weight: 600;
}
.plan-panel__group { display: block; margin-bottom: var(--space-3); }
.plan-panel__group input {
  width: 100%;
  min-width: 0;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--bg-input);
  color: var(--text-primary);
  font: inherit;
  font-size: var(--text-sm);
}
.plan-panel__group input:focus { outline: none; border-color: var(--accent); }
.plan-panel__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}
.plan-chip {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  max-width: 100%;
  padding: 2px 2px 2px 10px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-full);
  background: var(--bg-overlay);
  color: var(--text-primary);
  font-size: var(--text-sm);
  overflow-wrap: anywhere;
}
.plan-chip button {
  padding: 0 6px;
  border: 0;
  background: none;
  color: var(--text-tertiary);
  font-size: var(--text-md);
  line-height: 1;
  cursor: pointer;
}
.plan-chip button:hover { color: var(--text-primary); }
.plan-panel__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

.decision-context {
  margin-top: var(--space-4);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  transition: box-shadow var(--duration-base) var(--ease);
}
.decision-context[open] { box-shadow: var(--shadow-sm); }
.decision-context > summary {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 46px;
  padding: 0 var(--space-4);
  cursor: pointer;
  color: var(--text-primary);
  font-size: var(--text-sm);
  font-weight: 600;
  list-style: none;
}
.decision-context > summary::-webkit-details-marker { display: none; }
.decision-context > summary::after {
  content: "+";
  display: grid;
  place-items: center;
  width: 22px; height: 22px;
  margin-left: auto;
  border-radius: var(--radius-full);
  background: var(--bg-overlay);
  color: var(--text-secondary);
  font-size: var(--text-md);
  font-weight: 500;
  line-height: 1;
}
.decision-context[open] > summary::after { content: "−"; }
.decision-context__optional {
  padding: 1px var(--space-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-full);
  color: var(--text-tertiary);
  font-size: var(--text-xs);
  font-weight: 500;
}
.decision-context__lede,
.decision-context__note {
  margin: 0 var(--space-4) var(--space-4);
  color: var(--text-tertiary);
  font-size: var(--text-xs);
  line-height: 1.6;
}
.decision-context__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4) var(--space-3);
  padding: 0 var(--space-4) var(--space-4);
}
.decision-context__grid label {
  display: grid;
  gap: 6px;
  color: var(--text-secondary);
  font-size: var(--text-xs);
  font-weight: 600;
}
.decision-context__grid input,
.decision-context__grid textarea,
.decision-context__grid select {
  width: 100%;
  min-width: 0;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--bg-input);
  color: var(--text-primary);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 400;
  line-height: var(--leading-normal);
  transition: border-color var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease);
}
.decision-context__grid textarea { resize: vertical; }
.decision-context__grid select {
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  padding-right: var(--space-8);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%238a857c' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-3) center;
}
.decision-context__grid select option { background: var(--bg-raised); color: var(--text-primary); }
.decision-context__grid input::placeholder,
.decision-context__grid textarea::placeholder { color: var(--text-disabled); }
.decision-context__grid input:focus,
.decision-context__grid textarea:focus,
.decision-context__grid select:focus {
  border-color: var(--accent);
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-subtle);
}
.decision-context__wide { grid-column: 1 / -1; }
.decision-context__field { display: grid; gap: var(--space-2); align-content: start; }
.decision-picks { display: flex; flex-wrap: wrap; gap: var(--space-1); }
.decision-picks .chip-btn { height: 26px; font-size: var(--text-xs); }
.decision-context__status {
  margin: 0 var(--space-4) var(--space-4);
  color: var(--text-secondary);
  font-size: var(--text-xs);
  font-weight: 600;
}
.decision-context__more {
  margin: 0 var(--space-4) var(--space-4);
  border-top: 1px solid var(--border-default);
}
.decision-context__more > summary {
  padding: var(--space-3) 0;
  cursor: pointer;
  color: var(--text-secondary);
  font-size: var(--text-sm);
  font-weight: 600;
}
.decision-context__more > .decision-context__grid { padding: 0 0 var(--space-2); }

@media (max-width: 640px) {
  .decision-context__grid { grid-template-columns: 1fr; }
  .decision-context__wide { grid-column: auto; }
}

/* Extraction makes an LLM call and takes several seconds. A static line of
   text is indistinguishable from a hang, so the row shimmers and carries the
   same pulsing dot the run stages use — one vocabulary for "working". */
.composer__attachment[data-loading="true"] {
  background: linear-gradient(90deg,
    var(--bg-overlay) 25%, var(--bg-hover) 50%, var(--bg-overlay) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s infinite linear;
  color: var(--text-tertiary);
}
.attachment__dot {
  width: 6px; height: 6px;
  border-radius: var(--radius-full);
  background: var(--accent);
  flex-shrink: 0;
  animation: pulse-dot 1.8s var(--ease) infinite;
}
@keyframes shimmer {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}

/* Drag state applies to the whole composer, so a file may be dropped
   anywhere over it rather than onto a small target. */
.composer[data-dragging="true"] {
  border-color: var(--accent);
  background: var(--accent-subtle);
}

/* ── Starters ── */
.starters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  justify-content: center;
  margin-top: var(--space-6);
}
.starter {
  padding: 6px var(--space-4);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--text-tertiary);
  font-size: var(--text-sm);
  transition: background var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease);
}
.starter:hover {
  background: var(--bg-raised);
  border-color: var(--accent-border);
  color: var(--accent);
}

/* ═══ Stages ═══════════════════════════════════════════════════════════ */

.stages {
  max-width: 620px;
  display: flex;
  flex-direction: column;
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
}

.stage {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  position: relative;
}
/* A connector line makes the sequence read as one pipeline rather than as
   five unrelated rows. */
.stage:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 5px;
  top: 28px;
  bottom: -4px;
  width: 1px;
  background: var(--border-strong);
}

.stage__dot {
  width: 12px; height: 12px;
  border-radius: var(--radius-full);
  /* Pending reads as a hollow ring, distinct from the background, so the
     pipeline shows its full length before anything has run. */
  border: 2px solid var(--text-disabled);
  background: var(--bg-raised);
  flex-shrink: 0;
  z-index: 1;
  transition: border-color var(--duration-base) var(--ease),
              background var(--duration-base) var(--ease);
}
.stage[data-state="active"] .stage__dot {
  border-color: var(--accent);
  background: var(--accent);
  animation: pulse-dot 1.8s var(--ease) infinite;
}
.stage[data-state="done"] .stage__dot {
  border-color: var(--success);
  background: var(--success);
}
.stage[data-state="failed"] .stage__dot {
  border-color: var(--danger);
  background: var(--danger);
}

.stage__label {
  flex: 1;
  font-size: var(--text-md);
  color: var(--text-tertiary);
}
.stage[data-state="active"] .stage__label { color: var(--text-primary); font-weight: 600; }
.stage[data-state="done"]   .stage__label { color: var(--text-secondary); }
.stage[data-state="failed"] .stage__label { color: var(--danger); }

.stage__meta {
  font-size: var(--text-sm);
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
}

/* ═══ Pills ════════════════════════════════════════════════════════════ */

.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 2px 9px;
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.pill--running   { background: var(--accent-subtle);  color: var(--accent); }
.pill--completed { background: var(--success-subtle); color: var(--success); }
.pill--failed    { background: var(--danger-subtle);  color: var(--danger); }
.pill--cancelled { background: var(--bg-overlay);     color: var(--text-tertiary); }
.pill--timeout   { background: var(--warning-subtle); color: var(--warning); }
.pill--unknown   { background: var(--bg-overlay);     color: var(--text-tertiary); }

/* ═══ Buttons ══════════════════════════════════════════════════════════ */

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--text-base);
  font-weight: 500;
  white-space: nowrap;
  transition: background var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease);
}
.btn svg { width: 14px; height: 14px; }
.btn--secondary {
  border: 1px solid var(--border-default);
  background: var(--bg-raised);
  box-shadow: var(--shadow-sm);
  color: var(--text-secondary);
}
.btn--secondary:hover {
  border-color: var(--border-strong);
  color: var(--text-primary);
}
.btn--danger {
  border: 1px solid var(--danger-border);
  background: transparent;
  color: var(--danger);
}
.btn--danger:hover { background: var(--danger-subtle); }
.btn--primary {
  justify-content: center;
  padding: 10px var(--space-4);
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
  box-shadow: var(--shadow-sm);
}
.btn--primary:hover:not(:disabled) { background: var(--accent-hover); color: var(--on-accent); }
.btn--primary:disabled { opacity: 0.6; cursor: not-allowed; }

/* ═══ Access gate ══════════════════════════════════════════════════════ */

.gate {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  background: var(--scrim);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.gate__card {
  width: min(400px, calc(100vw - var(--space-8)));
  max-height: calc(100dvh - var(--space-8));
  overflow-y: auto;
  padding: var(--space-8) var(--space-8) var(--space-6);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-xl);
  background: var(--bg-raised);
  box-shadow: var(--shadow-lg);
}
.gate__card form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.gate__title {
  font-size: var(--text-2xl);
  letter-spacing: -0.018em;
}
.gate__intro {
  margin-bottom: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background: var(--bg-overlay);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: var(--leading-normal);
}
.gate__sub {
  margin-bottom: var(--space-2);
  font-size: var(--text-base);
  color: var(--text-secondary);
  line-height: var(--leading-normal);
}
.gate__input {
  padding: 11px var(--space-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--bg-input);
  color: var(--text-primary);
  transition: border-color var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease);
}
.gate__input::placeholder { color: var(--text-disabled); }
.gate__input:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-ring);
}
/* One provider's answer per line. */
#byok-error { white-space: pre-line; }

.gate__error {
  font-size: var(--text-sm);
  color: var(--danger);
}
.gate__hint {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  line-height: var(--leading-normal);
  word-break: break-word;
}
.gate__switch {
  align-self: center;
  margin-top: var(--space-1);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  text-decoration: underline;
  text-decoration-color: var(--border-strong);
  text-underline-offset: 3px;
}
.gate__switch:hover { color: var(--accent); text-decoration-color: currentColor; }
/* These are one line of text, 19px tall: fine for a pointer, too small for a
   thumb. A button centres its label, so the height alone is enough. */
@media (pointer: coarse) {
  .gate__switch { min-height: 44px; margin-top: 0; }
  /* The composer bar's selects are fields and take the touch size (base.css).
     The button beside them keeps pace, or one row reads in two sizes. */
  .composer__bar .chip-btn { font-size: var(--text-touch); }
}
.gate__sep { margin: 0 var(--space-2); color: var(--text-disabled); }
/* Outside the forms, so it stays whichever one is up; shown only when the
   card was opened from the landing (app.js showGate). */
.gate__back { display: block; margin: var(--space-4) auto 0; }
/* A link that wraps has a box spanning two lines whose middle is nobody's
   text: a keyboard user's focus ring would enclose empty space, and the
   keyboard smoke reads that as a covered control. Keep each link one box. */
.gate__samples a { display: inline-block; }
.gate__hint a { display: inline-block; color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.gate__samples {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border-subtle);
  text-align: center;
  font-size: var(--text-sm);
}

select.gate__input {
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  padding-right: var(--space-8);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%238a857c' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-3) center;
}
select.gate__input option { background: var(--bg-raised); color: var(--text-primary); }

/* ═══ BYOK badge ═══════════════════════════════════════════════════════ */

.byok-badge {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin: 0 var(--space-4) var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--accent-border);
  border-radius: var(--radius-md);
  background: var(--accent-subtle);
  color: var(--accent);
  font-size: var(--text-xs);
  font-weight: 500;
}
.byok-badge #byok-exit,
.byok-badge #code-exit,
.byok-badge #account-manage,
.byok-badge #account-keys,
.byok-badge #account-console,
.byok-badge #account-exit {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
  flex-shrink: 0;
  white-space: nowrap;
}
/* An email can be long; the badge keeps one line and lets it ellipsize. */
.byok-badge--account #account-email {
  min-width: 0;
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.workbench[data-collapsed="true"] .byok-badge { display: none; }

/* Under the account badge until the address is verified. */
.verify-notice {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  margin: calc(-1 * var(--space-2)) var(--space-4) var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--accent-border);
  border-radius: var(--radius-md);
  background: var(--warning-subtle);
  color: var(--warning);
  font-size: var(--text-xs);
  line-height: 1.4;
}
.verify-notice[hidden] { display: none; }
.verify-notice #verify-resend {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
  flex-shrink: 0;
  white-space: nowrap;
}
.workbench[data-collapsed="true"] .verify-notice { display: none; }

/* Account panel inside the gate card: laid out like the forms around it. */
#account-settings {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
#account-settings[hidden] { display: none; }
#account-settings form + form {
  margin-top: var(--space-3);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border-subtle);
}
/* The sample-report link belongs to a visitor deciding whether to come in. */
#account-settings:not([hidden]) ~ .gate__samples { display: none; }
.gate__section {
  font-size: var(--text-sm);
  font-weight: 600;
  margin: 0;
}
/* The Account panel's one switch: a native checkbox, so it reads and
   toggles with the keyboard like any other; the accent is the page's. */
.gate__choice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  cursor: pointer;
}
.gate__choice input {
  flex: none;
  width: 16px;
  height: 16px;
  margin: 2px 0 0;
  accent-color: var(--accent);
}
#settings-notify-row .gate__hint { margin-top: var(--space-1); }
.gate__danger {
  justify-content: center;
  border: 1px solid var(--danger-border);
  color: var(--danger);
  background: transparent;
}
.gate__danger:hover { background: var(--danger-subtle); }

/* ═══ Toasts ═══════════════════════════════════════════════════════════ */

.toasts {
  position: fixed;
  bottom: var(--space-6);
  left: 50%;
  transform: translateX(-50%);
  /* Above the gate: a verification link opened where nobody is signed in
     lands on the gate, and its answer must not be drawn underneath. Toasts
     take no clicks, so nothing behind them is harder to reach. */
  z-index: 300;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  pointer-events: none;
}
.toast {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  box-shadow: var(--shadow-lg);
  font-size: var(--text-base);
  color: var(--text-primary);
  /* Toasts are text-only and leave on their own after a few seconds, so they
     never take a click: on a phone two stacked toasts sat over the middle of
     the report, and a tap there landed on the notice instead of the text. */
  pointer-events: none;
  animation: toast-in var(--duration-slow) var(--ease-out);
}
.toast--error   { border-color: var(--danger-border); }
.toast--success { border-color: var(--success-border); }

@keyframes toast-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* ═══ Responsive ═══════════════════════════════════════════════════════
   Below 860px the sidebar overlays instead of taking a column: at that
   width a 264px rail leaves too little for the run itself. */
@media (max-width: 860px) {
  .workbench { grid-template-columns: 1fr; }
  .sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    width: min(var(--sidebar-width), 86vw);
    z-index: 60;
    box-shadow: var(--shadow-lg);
    transform: translateX(-100%);
    transition: transform var(--duration-base) var(--ease);
  }
  .workbench[data-sidebar-open="true"] .sidebar { transform: none; }
  .mobilebar {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    height: 48px;
    padding: 0 var(--space-3);
    border-bottom: 1px solid var(--border-subtle);
    background: var(--bg-base);
    flex-shrink: 0;
  }
  .mobilebar .brand { flex: 0 1 auto; }
  .pane__head, .pane__body { padding-left: var(--space-5); padding-right: var(--space-5); }
  .pane__head { padding-top: var(--space-5); }
  .pane__body { padding-top: var(--space-6); }
  .compose__title { font-size: var(--text-2xl); }
}

/* A completed run still exposes its actions on a phone; the heading owns the
   first row so those controls cannot compress the saved-status metadata. */
@media (max-width: 640px) {
  #pane-run .pane__head {
    flex-direction: column;
    align-items: stretch;
  }
  #pane-run .pane__heading,
  #pane-run .pane__actions,
  #pane-compare .pane__heading,
  #pane-compare .pane__actions { width: 100%; }
  /* Three equal columns, so five controls are always two rows whatever the
     font: wrapping by width gave three rows on a small phone and left the
     report under six lines. The download glyphs go; the labels say it. A
     resume button names what it does at length and takes a row to itself. */
  #pane-run .pane__actions {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    max-width: none;
  }
  #pane-run .pane__actions .btn { justify-content: center; min-width: 0; padding-inline: var(--space-2); }
  #pane-run .pane__actions .btn svg { display: none; }
  #pane-run .pane__actions [data-resume-run] { grid-column: 1 / -1; }
  #pane-compare .pane__head { flex-direction: column; align-items: stretch; }
  #pane-compare .pane__actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: none; }
  .pane__body--centered { padding-top: var(--space-8); }
  /* Compact and low on a phone, where the visible report is short. */
  .toasts {
    left: var(--space-3);
    right: var(--space-3);
    bottom: var(--space-3);
    transform: none;
    align-items: center;
  }
  .toast { padding: var(--space-2) var(--space-3); font-size: var(--text-sm); }
}
