/* Workbench Studio — hand-authored, no build step, no CDN.
   Design tokens on :root (light, default); dark redefines tokens only,
   under prefers-color-scheme. */

:root {
  color-scheme: light;

  /* accent: deep viridian/teal */
  --accent-50: #ecfaf6;
  --accent-100: #d2f1e8;
  --accent-300: #6fcdb2;
  --accent-500: #0f9d7f;
  --accent-600: #0b8069;
  --accent-700: #086554;
  --accent-contrast: #ffffff;

  --ground: #f6f8f8;
  --surface: #ffffff;
  --surface-raised: #ffffff;
  --surface-sunken: #f1f4f3;
  --border: #e2e8e6;
  --border-strong: #cdd8d5;

  /* #8a9c97 measured 2.7:1 on --ground -- fails WCAG AA (4.5:1) for normal
     text. This darker value holds >=4.8:1 on both --ground and --surface;
     verified with a relative-luminance contrast check, not eyeballed. */
  --text-primary: #10201c;
  --text-secondary: #52645f;
  --text-tertiary: #5f716c;
  --text-on-accent: #ffffff;

  --danger-50: #fdecec;
  --danger-500: #d84a4a;
  --danger-700: #a3312f;

  --warn-50: #fff6e6;
  --warn-500: #c9871a;
  --warn-700: #93630f;

  --shadow-sm: 0 1px 2px rgba(16, 32, 28, 0.06), 0 1px 1px rgba(16, 32, 28, 0.04);
  --shadow-md: 0 6px 20px rgba(16, 32, 28, 0.08), 0 2px 6px rgba(16, 32, 28, 0.05);
  --shadow-lg: 0 16px 40px rgba(16, 32, 28, 0.14), 0 4px 12px rgba(16, 32, 28, 0.08);

  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;

  /* Healthcare-internal-tool pairing: Figtree for headings/UI labels (a
     little more geometric, reads as "product"), Noto Sans for body/chat
     (very broad glyph coverage, calm and neutral for long-form reading).
     Both loaded from Google Fonts (the one CDN artifacts are allowed to
     reach) with a full system fallback stack so the page is never blocked
     on the network for text to render. */
  --font-heading: "Figtree", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-sans: "Noto Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;

  --topbar-h: 56px;

  /* -- semantic roles (WCAG-first token layer) -----------------------------
     Component rules should reach for these, not raw hex or the accent-NNN
     scale directly, for anything filling a "primary action" / "focus ring" /
     "destructive" role -- the scale above stays as the source palette, this
     layer names what each step is FOR. */
  --color-primary: var(--accent-600); /* solid buttons: accent-600, not -500 -- -500 under white text is 3.4:1, fails AA; -600 is 4.9:1 */
  --color-primary-hover: var(--accent-700);
  --color-on-primary: var(--text-on-accent);
  --color-accent: var(--accent-500); /* non-text-carrying accents: dots, borders, thin fills */
  --color-muted: var(--text-tertiary);
  --color-border: var(--border);
  --color-destructive: var(--danger-500);
  --color-on-destructive: #ffffff;
  --color-ring: var(--accent-600);
  --color-success: var(--accent-600);
  --color-warning: var(--warn-500);
  --color-danger: var(--danger-500);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --accent-50: #0e2620;
    --accent-100: #123a30;
    --accent-300: #2f7f68;
    --accent-500: #29b995;
    --accent-600: #3fd1ac;
    --accent-700: #7ee3c7;
    --accent-contrast: #06120f;

    --ground: #0c1412;
    --surface: #121b19;
    --surface-raised: #16211e;
    --surface-sunken: #0e1614;
    --border: #223330;
    --border-strong: #2d423d;

    --text-primary: #eef5f2;
    --text-secondary: #a9bcb6;
    /* #718b83 measured 4.78:1 on --surface -- technically passes but with
       almost no margin; this holds a healthier >=5.5:1 on both surfaces. */
    --text-tertiary: #82a099;
    --text-on-accent: #06120f;

    --danger-50: #2a1414;
    --danger-500: #e0645f;
    --danger-700: #f1938e;

    --warn-50: #2a2211;
    --warn-500: #dba237;
    --warn-700: #edc06a;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 6px 20px rgba(0, 0, 0, 0.45);
    --shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.55);

    /* dark mode: accent-500 on the near-black surfaces already clears
       4.5:1 as button text, so primary can stay on the brighter step
       rather than needing dark mode's own darker override. */
    --color-primary: var(--accent-500);
    --color-primary-hover: var(--accent-600);
    --color-ring: var(--accent-500);
  }
}

:root[data-theme="dark"] {
  --color-primary: var(--accent-500);
  --color-primary-hover: var(--accent-600);
  --color-ring: var(--accent-500);
}

* { box-sizing: border-box; }

/* The native `hidden` attribute and any author `.btn`/`.btn-icon`/etc class
   both have a single-selector specificity (0,1,0); per the cascade, author
   styles win over the UA stylesheet's `[hidden] { display: none; }` at
   equal specificity, so a hidden element with a `display`-setting class can
   silently render anyway. Caught live: #btn-resume (class="btn btn-ghost
   btn-sm", hidden whenever the environment isn't stopped) was rendering in
   the topbar the entire time, quietly stealing ~70px it didn't need to --
   invisible on a spacious desktop viewport, but exactly what pushed the
   topbar into horizontal overflow on a phone. `!important` is otherwise
   unused in this file by design, but "hidden means hidden, full stop,
   regardless of what other classes an element has" is the one rule worth
   the exception -- this makes every element-specific `.foo[hidden] {
   display: none; }` rule elsewhere in this file redundant (harmlessly so;
   left in place rather than churning an unrelated diff). */
[hidden] { display: none !important; }

html, body {
  height: 100%;
  margin: 0;
  /* Belt-and-suspenders: a fixed/absolute-positioned element (the rail
     drawer, its backdrop, the topbar overflow dropdown) contributes to
     document.documentElement.scrollWidth even while invisible
     (opacity:0/visibility:hidden still occupy layout space -- only
     display:none doesn't) if it renders past the edge of a narrow
     viewport, and position:fixed escapes any overflow:hidden set lower
     than html/body since its containing block is the viewport itself.
     This is the one place that actually stops a phone from ever scrolling
     sideways, on top of (not instead of) sizing each of those elements
     correctly -- internal scroll areas (chat log, conversation list, the
     race track) keep their own overflow-x/y and are unaffected. */
  overflow-x: hidden;
}

body {
  background: var(--ground);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, .brand-name, .btn, .rail-title, .settings-subhead {
  font-family: var(--font-heading);
}

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

a { color: var(--color-primary); }

/* Every interactive element gets the same visible, on-brand focus ring --
   never removed, never invisible. Component-specific :focus-visible rules
   below layer additional treatment (e.g. a colored border) on top of this,
   they don't replace it. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--color-ring);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Every clickable thing looks clickable, and reacts to hover -- not just
   the ones that happened to get a hover rule already. */
button, [role="button"], .conversation-item, .lane-card, a.ticket-chip, .cost-chip, .preset-suggestion-chip {
  cursor: pointer;
  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, transform 120ms ease;
}
button:disabled, [role="button"][aria-disabled="true"] {
  cursor: not-allowed;
}

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

/* Skip link: visually hidden until keyboard-focused, then a clear on-brand
   pill at the top-left -- lets a keyboard/screen-reader user jump straight
   past the conversations rail to where they'd actually type. */
.skip-link {
  position: absolute;
  top: -48px;
  left: 12px;
  z-index: 200;
  background: var(--color-primary);
  color: var(--color-on-primary);
  padding: 10px 16px;
  border-radius: var(--radius-sm);
  font-weight: 700;
  font-size: 13px;
  text-decoration: none;
  transition: top 150ms ease;
}
.skip-link:focus {
  top: 12px;
}

.app {
  height: 100vh;
  /* 100vh on a phone browser measures the viewport with the address bar
     collapsed, taller than what's actually visible with it showing --
     the composer ends up clipped behind browser chrome. 100dvh (dynamic
     viewport height) tracks the real visible height; falls back to the
     100vh above on browsers that don't support it. */
  height: 100dvh;
  display: flex;
  flex-direction: column;
}

/* -------------------------------------------------- topbar */

.topbar {
  min-height: var(--topbar-h);
  flex: none;
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 0 18px;
  /* viewport-fit=cover (index.html/login.html) lets the page extend under
     a notch/Dynamic Island -- without this the topbar's own content would
     render behind it in portrait. env() is 0 on a non-notched device/most
     browsers, so this is a no-op there. */
  padding-top: env(safe-area-inset-top, 0px);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

.topbar-brand {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 650;
  letter-spacing: -0.01em;
  color: var(--text-primary);
}

.brand-mark { color: var(--accent-500); flex: none; }
.brand-name { font-size: 15px; }

.topbar-env {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-radius: 999px;
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  font-variant-numeric: tabular-nums;
}

.env-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--accent-500);
  flex: none;
}
[data-state="stopped"] .env-dot { background: var(--text-tertiary); }
[data-state="provisioning"] .env-dot { background: var(--warn-500); }

.env-label {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-secondary);
}

.topbar-actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  position: relative; /* anchors .topbar-secondary-panel's dropdown below 768px */
}

/* Rail-drawer toggle/close and the topbar overflow trigger only exist for
   the sub-768px layout (see the responsive block at the end of this file,
   which switches these to display:inline-flex) -- hidden here so they take
   no space and aren't reachable by keyboard above that breakpoint. */
#btn-rail-toggle, #btn-rail-close, #btn-topbar-more { display: none; }

/* .topbar-secondary-panel wraps Race/Settings so the same two buttons
   (no duplication, no extra click-handler wiring) can be plain inline
   flex items here and a floating dropdown below 768px. display:contents
   makes the wrapper invisible to layout at this width -- its children
   become direct flex items of .topbar-actions, identical to before this
   wrapper existed. */
.topbar-secondary-panel { display: contents; }

/* A button's visible text label rides along in the DOM for the sub-768px
   dropdown (where an icon-only row is harder to scan) but stays out of the
   way of every icon-only rendering everywhere else. */
.btn-text-label { display: none; }
/* #btn-submit is the one place a text label is the default, everywhere
   above 768px -- "Submit for review" has always been visible text, not an
   icon-only button; only below 768px (see the responsive block) does it
   go icon-only to reclaim room. */
#btn-submit .btn-text-label { display: inline; }

.rail-backdrop { display: none; }

/* -------------------------------------------------- buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 8px 14px;
  min-height: 44px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: transform 120ms ease, box-shadow 120ms ease, background-color 120ms ease, border-color 120ms ease, color 120ms ease;
  background: var(--surface);
  color: var(--text-primary);
}
.btn:active { transform: translateY(1px); }
/* Redundant with the global button:focus-visible rule above by design --
   belt and suspenders so a more specific selector added later can't
   accidentally remove focus visibility from every button at once. */
.btn:focus-visible {
  outline: 3px solid var(--color-ring);
  outline-offset: 2px;
}

.btn-primary {
  background: var(--color-primary);
  color: var(--color-on-primary);
  box-shadow: var(--shadow-sm);
}
.btn-primary:hover { background: var(--color-primary-hover); box-shadow: var(--shadow-md); }

.btn-ghost {
  background: transparent;
  border-color: var(--border);
  color: var(--text-secondary);
}
.btn-ghost:hover { background: var(--surface-sunken); color: var(--text-primary); }

.btn-sm { padding: 5px 10px; min-height: 36px; font-size: 12.5px; }

.btn-icon {
  padding: 6px;
  min-width: 44px;
  min-height: 44px;
  border-color: var(--border);
  background: var(--surface);
  color: var(--text-secondary);
}
.btn-icon:hover { background: var(--surface-sunken); color: var(--text-primary); }
/* Icon buttons inside a dense toolbar (demo-chrome, cost/lane/preset panel
   headers) intentionally trade the full 44px for a still-comfortable 36px --
   never smaller, and always paired with generous spacing between them so
   mis-taps land on empty space, not a neighboring control. */
.btn-icon.btn-sm { min-width: 36px; min-height: 36px; padding: 5px; }

.btn-send {
  flex: none;
  width: 44px; height: 44px;
  padding: 0;
  border-radius: var(--radius-sm);
  background: var(--color-primary);
  color: var(--color-on-primary);
  justify-content: center;
}
.btn-send:hover { background: var(--color-primary-hover); }
.btn-send:disabled { background: var(--border-strong); color: var(--surface); cursor: not-allowed; }
/* Interrupt/steer (docs/WORKBENCH.md "Flows borrowed from Claude Code"
   Tier 1): the send button becomes Stop while a turn is streaming and the
   composer is empty -- a distinct, calm color (not alarm-red; stopping on
   purpose isn't an error state) so it still reads as "this button does
   something different right now," not just a re-skinned send icon. */
.btn-send.is-stop { background: var(--warn-500); color: var(--text-on-accent); }
.btn-send.is-stop:hover { background: var(--warn-700); }

/* -------------------------------------------------- watchdog banner */

.watchdog-banner {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 18px;
  background: var(--warn-50);
  color: var(--warn-700);
  border-bottom: 1px solid var(--border);
  font-size: 13px;
}
.watchdog-banner[hidden] { display: none; }
.watchdog-text { flex: 1; }
.watchdog-dismiss {
  flex: none;
  background: transparent;
  border: none;
  color: inherit;
  cursor: pointer;
  padding: 4px;
  border-radius: 6px;
  display: flex;
}
.watchdog-dismiss:hover { background: rgba(0,0,0,0.06); }

/* -------------------------------------------------- workspace grid */

.workspace {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr) minmax(0, 1fr);
}

.mobile-view-switch { display: none; }

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

.rail {
  border-right: 1px solid var(--border);
  background: var(--surface);
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.rail-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 14px 10px;
}

.rail-header-actions {
  display: flex;
  align-items: center;
  gap: 6px;
}

.rail-title {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-tertiary);
  margin: 0;
}

.new-conversation-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 0 14px 12px;
}
.new-conversation-form[hidden] { display: none; }
.new-conversation-actions {
  display: flex;
  justify-content: flex-end;
  gap: 6px;
}

.input {
  width: 100%;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface-sunken);
  color: var(--text-primary);
}
.input:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: 1px;
}

.conversation-list {
  list-style: none;
  margin: 0;
  padding: 0 8px 12px;
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}

.conversation-item {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: flex-start;
  text-align: left;
  padding: 10px 10px;
  margin-bottom: 4px;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  background: transparent;
  cursor: pointer;
  color: var(--text-primary);
}
.conversation-item:hover { background: var(--surface-sunken); }
.conversation-item.is-current {
  background: var(--accent-50);
  border-color: var(--accent-100);
}

.conversation-item-row {
  display: flex;
  align-items: center;
  gap: 7px;
  width: 100%;
}

.conversation-state-dot {
  flex: none;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--accent-500);
}
.conversation-item[data-state="review_pending"] .conversation-state-dot { background: var(--warn-500); }
.conversation-item[data-state="idle"] .conversation-state-dot { background: var(--text-tertiary); }

.conversation-title {
  font-size: 13px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}

.conversation-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  padding-left: 14px;
}

.lane-chip {
  font-size: 12px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--surface-sunken);
  color: var(--text-secondary);
  border: 1px solid var(--border);
}

.turn-count {
  font-size: 12px;
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
}

.rail-empty {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  padding: 18px 14px;
  color: var(--text-tertiary);
  font-size: 12.5px;
}
.rail-empty-text { margin: 0; }

/* -------------------------------------------------- chat */

.chat {
  display: flex;
  flex-direction: column;
  min-height: 0;
  border-right: 1px solid var(--border);
  background: var(--ground);
}

.chat-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 20px 20px 8px;
}

.chat-empty {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: var(--text-tertiary);
  padding: 0 40px;
}

.chat-log {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 720px;
  margin: 0 auto;
}

@keyframes msg-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  @keyframes msg-in { from { opacity: 1; } to { opacity: 1; } }
}

.msg {
  animation: msg-in 220ms ease;
  max-width: 84%;
}

.msg-user {
  align-self: flex-end;
  background: var(--accent-500);
  color: var(--text-on-accent);
  padding: 10px 14px;
  border-radius: var(--radius-md) var(--radius-md) 4px var(--radius-md);
  box-shadow: var(--shadow-sm);
  white-space: pre-wrap;
}

.msg-assistant {
  align-self: flex-start;
  background: var(--surface);
  color: var(--text-primary);
  border: 1px solid var(--border);
  padding: 12px 14px;
  border-radius: var(--radius-md) var(--radius-md) var(--radius-md) 4px;
  box-shadow: var(--shadow-sm);
  white-space: pre-wrap;
}

.msg-progress {
  align-self: flex-start;
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text-tertiary);
  font-size: 12.5px;
  padding: 2px 4px;
}

.progress-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent-500);
  flex: none;
  animation: pulse 1.4s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) { .progress-dot { animation: none; } }
@keyframes pulse {
  0%, 100% { opacity: 0.35; transform: scale(0.85); }
  50% { opacity: 1; transform: scale(1); }
}

.msg-file {
  align-self: flex-start;
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-secondary);
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  padding: 6px 10px;
  border-radius: var(--radius-sm);
}

.msg-health {
  align-self: flex-start;
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
  color: var(--accent-700);
  padding: 2px 4px;
}
.msg-health.is-unhealthy { color: var(--danger-700); }

.msg-error {
  align-self: flex-start;
  background: var(--danger-50);
  color: var(--danger-700);
  border: 1px solid var(--danger-500);
  padding: 10px 14px;
  border-radius: var(--radius-md);
}

.msg-options {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}

.option-chip {
  border: 1px solid var(--accent-300);
  background: var(--accent-50);
  color: var(--accent-700);
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}
.option-chip:hover { background: var(--accent-100); }
.option-chip .option-key {
  font-weight: 700;
  margin-right: 4px;
  opacity: 0.75;
}

/* -------------------------------------------------- composer */

.composer {
  flex: none;
  display: flex;
  align-items: flex-end;
  gap: 10px;
  padding: 12px 20px 18px;
  background: var(--ground);
}

.composer-input {
  flex: 1;
  resize: none;
  max-height: 160px;
  padding: 10px 14px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text-primary);
  box-shadow: var(--shadow-sm);
}
.composer-input:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: 1px;
}

/* -------------------------------------------------- demo pane */

.demo-pane {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--surface);
}

.demo-chrome {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
}

.demo-url {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
  min-width: 0;
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 6px 12px;
}

.live-badge {
  flex: none;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--accent-700);
}
.live-badge[data-healthy="false"] { color: var(--text-tertiary); }

.live-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--accent-500);
  animation: pulse 1.8s ease-in-out infinite;
}
.live-badge[data-healthy="false"] .live-dot {
  background: var(--text-tertiary);
  animation: none;
}
@media (prefers-reduced-motion: reduce) { .live-dot { animation: none; } }

.demo-url-text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-secondary);
}

.demo-chrome-actions {
  flex: none;
  display: flex;
  gap: 6px;
}

.demo-frame-wrap {
  flex: 1;
  min-height: 0;
  position: relative;
  background: var(--surface-sunken);
}

.demo-frame {
  width: 100%;
  height: 100%;
  border: none;
  display: block;
}

.demo-frame-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 0 32px;
  color: var(--text-tertiary);
  pointer-events: none;
}

/* -------------------------------------------------- toast */

.toast {
  position: fixed;
  left: 50%;
  bottom: 28px;
  transform: translateX(-50%);
  background: var(--text-primary);
  color: var(--surface);
  padding: 10px 18px;
  border-radius: 999px;
  box-shadow: var(--shadow-lg);
  font-size: 13px;
  font-weight: 600;
  z-index: 50;
  animation: msg-in 180ms ease;
}
.toast[hidden] { display: none; }

/* -------------------------------------------------- chat: approval bubble */

.msg-approval {
  align-self: center;
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--accent-50);
  border: 1px solid var(--accent-300);
  color: var(--accent-700);
  padding: 10px 16px;
  border-radius: var(--radius-md);
  font-weight: 700;
}

/* -------------------------------------------------- top bar view switcher */

.btn-icon[data-view-target] { color: var(--text-secondary); }
.btn-icon[data-view-target].is-active {
  background: var(--accent-50);
  border-color: var(--accent-300);
  color: var(--accent-700);
}

/* -------------------------------------------------- admin views (Settings, The Race) */

.view-panel {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  background: var(--ground);
}
.view-panel[hidden] { display: none; }

.view-panel-inner {
  max-width: 640px;
  margin: 0 auto;
  padding: 28px 24px 60px;
}
.view-panel-inner-wide { max-width: 920px; }

.view-panel-back {
  margin-bottom: 16px;
}

.view-panel-header h1 {
  font-size: 20px;
  margin: 0 0 4px;
  letter-spacing: -0.01em;
}

.view-panel-sub {
  color: var(--text-secondary);
  font-size: 13px;
  margin: 0 0 20px;
}

/* -------------------------------------------------- settings form */

.settings-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
  box-shadow: var(--shadow-sm);
}

.settings-row {
  display: grid;
  grid-template-columns: 110px minmax(0, 1fr);
  align-items: center;
  gap: 12px;
}

.settings-row label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-secondary);
  text-transform: capitalize;
}

.settings-row-input {
  display: flex;
  align-items: center;
  gap: 10px;
}
.settings-row-input .input { flex: 1; }

.model-source {
  flex: none;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--surface-sunken);
  color: var(--text-tertiary);
  border: 1px solid var(--border);
  white-space: nowrap;
}
.model-source[data-source="admin"] {
  background: var(--accent-50);
  color: var(--accent-700);
  border-color: var(--accent-300);
}

.settings-plane { display: flex; flex-direction: column; gap: 12px; }
.plane-project-status {
  margin: 0;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  background: var(--surface-sunken);
  color: var(--text-secondary);
  border: 1px solid var(--border);
}
.plane-project-status[data-state="set"] {
  background: var(--accent-50);
  color: var(--accent-700);
  border-color: var(--accent-300);
}
.plane-project-status[data-state="unconfigured"] {
  background: var(--warn-50);
  color: var(--warn-700);
  border-color: var(--warn-500);
}
.plane-project-status[data-state="unavailable"] {
  background: var(--danger-50);
  color: var(--danger-700);
  border-color: var(--danger-500);
}

.settings-actions {
  display: flex;
  justify-content: flex-end;
  padding-top: 4px;
}

.settings-divider {
  height: 1px;
  background: var(--border);
  margin: 24px 0 16px;
}

.settings-toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
}
.settings-toggle input { width: 16px; height: 16px; accent-color: var(--accent-500); }

/* -------------------------------------------------- The Race */

.race-header h2 {
  font-size: 20px;
  margin: 0 0 4px;
  letter-spacing: -0.01em;
}

.race-sub {
  color: var(--text-secondary);
  font-size: 12.5px;
  margin: 0 0 18px;
  font-variant-numeric: tabular-nums;
}

.race-podium {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 22px;
}

.podium-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 8px 14px;
  box-shadow: var(--shadow-sm);
  font-size: 12.5px;
}

.podium-medal {
  flex: none;
  color: var(--warn-500);
  display: flex;
}

.podium-detail {
  color: var(--text-tertiary);
}

.race-track {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-bottom: 26px;
}

.race-lane {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.race-lane-label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
}

.avatar-dot {
  flex: none;
  width: 22px; height: 22px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 700;
  color: #fff;
}

.rider-name { font-weight: 600; }
.rider-points {
  margin-left: auto;
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
}

.race-lane-track {
  position: relative;
  height: 34px;
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-radius: 999px;
  overflow: visible;
}

.race-goal-line {
  position: absolute;
  right: 14px;
  top: 4px;
  bottom: 4px;
  width: 2px;
  background: var(--border-strong);
  border-radius: 1px;
}

.race-rider {
  position: absolute;
  top: 50%;
  left: 0;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: 3px;
  transition: left 900ms cubic-bezier(0.22, 1, 0.36, 1);
}
@media (prefers-reduced-motion: reduce) {
  .race-rider { transition: none; }
}

.race-flag {
  display: flex;
  color: var(--accent-700);
}
.race-flag[hidden] { display: none; }

@keyframes race-puff {
  0% { opacity: 0; transform: translate(-6px, -2px) scale(0.6); }
  40% { opacity: 0.55; }
  100% { opacity: 0; transform: translate(-16px, -6px) scale(1.3); }
}
.race-rider.puff::before {
  content: "";
  position: absolute;
  left: -4px;
  top: 50%;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--text-tertiary);
  animation: race-puff 500ms ease-out;
}
@media (prefers-reduced-motion: reduce) {
  .race-rider.puff::before { animation: none; content: none; }
}

.race-lane.is-goal .race-lane-track { border-color: var(--accent-300); }

.race-lane-note {
  font-size: 12px;
  color: var(--text-tertiary);
  padding-left: 4px;
}
.race-lane-note[hidden] { display: none; }

.race-archive h3 {
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-tertiary);
  margin: 0 0 10px;
}

.archive-strip {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.archive-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 10px 14px;
  min-width: 160px;
  box-shadow: var(--shadow-sm);
}

.archive-week {
  font-size: 12px;
  font-weight: 700;
  color: var(--text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin-bottom: 6px;
}

.archive-podium {
  margin: 0;
  padding-left: 18px;
  font-size: 12.5px;
  color: var(--text-secondary);
}

.race-archive-empty {
  color: var(--text-tertiary);
  font-size: 12.5px;
}

.race-empty {
  color: var(--text-tertiary);
  font-size: 13px;
  padding: 16px 4px;
  margin: 0;
}

/* -------------------------------------------------- delight moments */

#delight-fireworks-canvas { pointer-events: none; }

body.delight-glow::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(circle at 50% 20%, var(--accent-100), transparent 60%);
  animation: delight-glow-fade 2.2s ease forwards;
  z-index: 79;
}
@keyframes delight-glow-fade {
  0% { opacity: 0; }
  20% { opacity: 0.9; }
  100% { opacity: 0; }
}

.delight-coffee-icon {
  display: inline-flex;
  margin-right: 4px;
  color: var(--warn-500);
  animation: delight-coffee-in 300ms ease;
}
@keyframes delight-coffee-in {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .delight-coffee-icon { animation: none; }
}

/* -------------------------------------------------- login page */

.login-body {
  height: 100vh;
  margin: 0;
  display: flex;
  background: var(--ground);
}

.login-shell {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

.login-card {
  width: 100%;
  max-width: 360px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 32px 28px;
}

.login-brand {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--accent-500);
  margin-bottom: 22px;
}
.login-brand .brand-name {
  color: var(--text-primary);
  font-weight: 650;
  font-size: 15px;
}

.login-title {
  font-size: 20px;
  margin: 0 0 4px;
  letter-spacing: -0.01em;
}

.login-sub {
  color: var(--text-secondary);
  font-size: 13px;
  margin: 0 0 22px;
}

.login-form {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.login-label {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-secondary);
  margin-top: 10px;
}
.login-label:first-child { margin-top: 0; }

.login-error {
  margin-top: 14px;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  background: var(--danger-50);
  color: var(--danger-700);
  border: 1px solid var(--danger-500);
  font-size: 12.5px;
}
.login-error[hidden] { display: none; }

.login-submit {
  margin-top: 18px;
  justify-content: center;
  width: 100%;
}

/* -------------------------------------------------- pending review pill + privacy notice */

.pending-review-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border-radius: 999px;
  background: var(--warn-50);
  color: var(--warn-700);
  border: 1px solid var(--warn-500);
  font-size: 12px;
  font-weight: 700;
}
.pending-review-pill[hidden] { display: none; }

.msg-notice {
  align-self: center;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  background: var(--warn-50);
  border: 1px solid var(--warn-500);
  color: var(--warn-700);
  padding: 10px 14px;
  border-radius: var(--radius-md);
  font-size: 13px;
  max-width: 100%;
}

.msg-privacy {
  align-self: flex-start;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  background: var(--surface);
  border: 1px dashed var(--border-strong);
  color: var(--text-secondary);
  padding: 10px 14px;
  border-radius: var(--radius-md);
}

/* -------------------------------------------------- top bar user menu */

.user-menu {
  position: relative;
}

.user-menu-button {
  display: flex;
  align-items: center;
  gap: 6px;
}

.user-menu-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: 6px;
  min-width: 160px;
  z-index: 40;
}
.user-menu-panel[hidden] { display: none; }

.user-menu-item {
  width: 100%;
  text-align: left;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  background: transparent;
  border: none;
  color: var(--text-primary);
  font-size: 13px;
  cursor: pointer;
}
.user-menu-item:hover { background: var(--surface-sunken); }

/* -------------------------------------------------- cost chip + itemized panel */

.settings-subhead {
  font-size: 15px;
  margin: 0 0 4px;
}

.cost-chip {
  display: inline-flex;
  align-items: center;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--surface-sunken);
  color: var(--text-secondary);
  border: 1px solid var(--border);
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}
.cost-chip:hover {
  background: var(--accent-50);
  color: var(--accent-700);
  border-color: var(--accent-300);
}

.cost-panel-overlay {
  position: fixed;
  inset: 0;
  background: rgba(16, 32, 28, 0.35);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 90;
}
.cost-panel-overlay[hidden] { display: none; }

.cost-panel {
  width: 100%;
  max-width: 420px;
  background: var(--surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 20px 22px 22px;
  animation: msg-in 160ms ease;
}

.cost-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 4px;
}
.cost-panel-header h2 {
  font-size: 16px;
  margin: 0;
}

.cost-panel-total {
  font-size: 26px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--accent-700);
  margin: 6px 0 16px;
}

.cost-panel-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}
.cost-panel-table th {
  text-align: left;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-tertiary);
  font-weight: 700;
  padding: 6px 8px;
  border-bottom: 1px solid var(--border);
}
.cost-panel-table td {
  padding: 7px 8px;
  border-bottom: 1px solid var(--border);
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}
.cost-panel-table td:first-child {
  color: var(--text-primary);
  font-weight: 600;
  text-transform: capitalize;
}
.cost-panel-table tr:last-child td { border-bottom: none; }

/* -------------------------------------------------- lane picker */

.lane-status-dot {
  flex: none;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--text-tertiary);
}
.lane-status-dot[data-status="clean"] { background: var(--accent-500); }
.lane-status-dot[data-status="coordinate"] { background: var(--warn-500); }
.lane-status-dot[data-status="hotspot"] { background: var(--danger-500); }

.lane-picker-trigger {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface-sunken);
  color: var(--text-primary);
  font-size: 13px;
  cursor: pointer;
}
.lane-picker-trigger-chevron { margin-left: auto; color: var(--text-tertiary); flex: none; }
.lane-picker-trigger:hover { border-color: var(--accent-300); }
.preset-icon-slot { flex: none; display: inline-flex; color: var(--color-accent); }
.preset-icon-slot svg { display: block; }

.lane-panel-overlay {
  position: fixed;
  inset: 0;
  background: rgba(16, 32, 28, 0.35);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 95;
  padding: 24px;
}
.lane-panel-overlay[hidden] { display: none; }

.lane-panel {
  width: 100%;
  max-width: 480px;
  max-height: min(640px, 86vh);
  background: var(--surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 20px 22px 22px;
  display: flex;
  flex-direction: column;
  animation: msg-in 160ms ease;
}

.lane-picker-list {
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 8px;
}

.lane-group-label {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-tertiary);
  margin: 14px 0 4px;
}
.lane-group-label:first-child { margin-top: 4px; }

.lane-card {
  display: flex;
  flex-direction: column;
  gap: 3px;
  text-align: left;
  width: 100%;
  padding: 10px 12px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--surface);
  cursor: pointer;
}
.lane-card:hover { background: var(--surface-sunken); }
.lane-card.is-selected {
  background: var(--accent-50);
  border-color: var(--accent-300);
}

.lane-card-head {
  display: flex;
  align-items: center;
  gap: 7px;
}
.lane-card-name { font-weight: 600; font-size: 13px; }
.lane-card-desc {
  font-size: 12px;
  color: var(--text-secondary);
  padding-left: 15px;
}
.lane-card-note {
  font-size: 12px;
  color: var(--danger-700);
  padding-left: 15px;
  font-weight: 600;
}
.lane-card-occupied {
  font-size: 12px;
  color: var(--warn-700);
  padding-left: 15px;
}
.lane-card-occupied.is-hotspot {
  color: var(--danger-700);
  font-weight: 700;
}

/* Lane chips on conversation cards, colored by catalog status. */
.lane-chip[data-status="clean"] { background: var(--accent-50); color: var(--accent-700); border-color: var(--accent-300); }
.lane-chip[data-status="coordinate"] { background: var(--warn-50); color: var(--warn-700); border-color: var(--warn-500); }
.lane-chip[data-status="hotspot"] { background: var(--danger-50); color: var(--danger-700); border-color: var(--danger-500); }

/* -------------------------------------------------- starter presets */

.empty-suggestions-label {
  margin-top: 18px;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-tertiary);
}

.empty-suggestions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  max-width: 480px;
  margin: 8px auto 0;
}

.preset-suggestion-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-primary);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
}
.preset-suggestion-chip:hover { background: var(--accent-50); border-color: var(--accent-300); color: var(--accent-700); }

/* Conversation card preset icon, inline before the title. */
.conversation-preset-icon {
  flex: none;
  font-size: 13px;
  line-height: 1;
}

/* Ticket chip: number links out to Plane. */
.ticket-chip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--surface-sunken);
  color: var(--text-secondary);
  border: 1px solid var(--border);
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
}
.ticket-chip:hover { background: var(--accent-50); color: var(--accent-700); border-color: var(--accent-300); }

/* Chat: the ticket-opened confirmation line. */
.msg-ticket {
  align-self: center;
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--accent-300);
  color: var(--accent-700);
  padding: 9px 15px;
  border-radius: var(--radius-md);
  font-weight: 600;
  font-size: 13px;
}
.msg-ticket a { color: inherit; text-decoration: underline; }

/* Chat: the "kind":"integration" event that follows a run of "slice"
   events -- the lead's own report of the overall merge/health outcome,
   the "Done — here's what changed" moment the settled slice-group panel
   above it pairs with. */
.msg-integration {
  align-self: flex-start;
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--accent-300);
  color: var(--color-success);
  padding: 9px 15px;
  border-radius: var(--radius-md);
  font-weight: 600;
  font-size: 13px;
}
.msg-integration.is-failed { border-color: var(--danger-500); color: var(--color-danger); }

/* Chat: the local, client-synthesized result of a completed rewind (see
   showRevertConfirm in studio.js) -- same small icon-line treatment as
   .msg-integration, its own class only so the two stay independently
   styleable. */
.msg-rewind {
  align-self: flex-start;
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--accent-300);
  color: var(--color-success);
  padding: 9px 15px;
  border-radius: var(--radius-md);
  font-weight: 600;
  font-size: 13px;
}
.msg-rewind.is-unhealthy { border-color: var(--warn-500); color: var(--warn-700); }

/* Chat: plan approval (docs/WORKBENCH.md "Flows borrowed from Claude Code"
   Tier 1) -- a calm pause-and-check card, not an alarming gate: the plan
   itself read as a short list, one clear Approve action, and a reminder
   that free text in the composer is just as valid a response. */
.msg-plan {
  align-self: flex-start;
  width: 100%;
  max-width: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 14px 16px;
}
.msg-plan-intro { margin: 0 0 10px; font-weight: 600; }
.msg-plan-slices {
  margin: 0 0 12px;
  padding-left: 20px;
  font-size: 13px;
  color: var(--text-secondary);
}
.msg-plan-slices li { margin-bottom: 4px; }
.msg-plan-slices strong { color: var(--text-primary); }
.msg-plan-actions { margin-bottom: 8px; }
.msg-plan-actions .btn svg { flex: none; }
.msg-plan-hint { margin: 0; font-size: 12px; color: var(--text-tertiary); }

/* Chat: "revert to here" (docs/WORKBENCH.md "Flows borrowed from Claude
   Code" Tier 1) -- a subtle, hover/focus-revealed affordance on every real
   assistant turn's own bubble. Always present in the DOM (never
   conditionally rendered) so it stays keyboard-reachable via Tab even
   though it's visually hidden until the bubble is hovered or the button
   itself gets focus. */
.msg-assistant.has-revert { position: relative; padding-right: 40px; }
.msg-revert-trigger {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-tertiary);
  opacity: 0;
  transition: opacity 150ms ease, color 150ms ease, border-color 150ms ease;
}
.msg-assistant.has-revert:hover .msg-revert-trigger,
.msg-revert-trigger:focus-visible {
  opacity: 1;
}
.msg-revert-trigger:hover { color: var(--color-primary); border-color: var(--color-primary); }
@media (prefers-reduced-motion: reduce) {
  .msg-revert-trigger { transition: none; }
}
/* A touch device has no hover -- the trigger has to just be visible
   there, or it's unreachable without a mouse's hover state at all. */
@media (hover: none) {
  .msg-revert-trigger { opacity: 1; }
}

.msg-revert-confirm {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
}
.msg-revert-confirm p {
  margin: 0 0 8px;
  font-size: 12.5px;
  font-weight: 400;
  color: var(--text-secondary);
}
.msg-revert-confirm-actions { display: flex; gap: 8px; }

/* Chat: a run of parallel "slice" events (docs/WORKBENCH.md "Codex agent
   teams") collapses into one panel -- a row per slice, updating in place,
   not one bubble per raw event. Calm and orderly by design: no bounce/
   overshoot easing, everything reduced-motion-safe (this is the moment the
   product person sees "a team is working," not a log to parse). */
.slice-group {
  align-self: stretch;
  width: 100%;
  max-width: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.slice-group-header {
  margin: 0;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-tertiary);
}
.slice-group.is-settled .slice-group-header { color: var(--color-success); }

.slice-rows { display: flex; flex-direction: column; gap: 4px; }

.slice-row { border-radius: var(--radius-sm); }

.slice-row-head {
  width: 100%;
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  border: none;
  background: transparent;
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font: inherit;
  text-align: left;
}
button.slice-row-head { cursor: pointer; }
button.slice-row-head:hover { background: var(--surface-sunken); }

.slice-state-dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--text-tertiary);
}
.slice-row[data-state="planned"] .slice-state-dot { background: var(--text-tertiary); }
.slice-row[data-state="running"] .slice-state-dot {
  background: var(--color-accent);
  animation: pulse 1.4s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .slice-row[data-state="running"] .slice-state-dot { animation: none; }
}
.slice-row[data-state="done"] .slice-state-dot { background: var(--color-success); }
.slice-row[data-state="failed"] .slice-state-dot { background: var(--color-danger); }

.slice-row-title {
  flex: none;
  font-weight: 600;
  font-size: 13px;
  max-width: 45%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.slice-row-text {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.slice-row[data-state="failed"] .slice-row-text { color: var(--color-danger); }

.slice-row-chevron {
  flex: none;
  color: var(--text-tertiary);
  transition: transform 150ms ease;
}
.slice-row-head[aria-expanded="true"] .slice-row-chevron { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) {
  .slice-row-chevron { transition: none; }
}

.slice-row-detail {
  padding: 6px 8px 10px 32px;
  font-size: 12.5px;
  color: var(--text-secondary);
}
.slice-row-history { margin: 0; padding-left: 18px; }
.slice-row-history li { margin-bottom: 2px; }
.slice-row-raw {
  margin: 8px 0 0;
  padding: 8px 10px;
  background: var(--surface-sunken);
  border-radius: var(--radius-sm);
  font-size: 12px;
}
.slice-row-raw dt {
  font-weight: 700;
  color: var(--text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-size: 11px;
}
.slice-row-raw dd { margin: 0 0 6px; font-family: monospace; word-break: break-all; }

@media (max-width: 480px) {
  /* Title + text no longer fit side by side at phone width -- stack them
     so both stay fully readable instead of truncating the interesting
     part (the live progress text). The chevron reorders (visually only,
     via flex `order` -- DOM stays as-is so the desktop layout, which
     relies on natural flex order to push it to the far right, is
     untouched) onto the first line next to the title, rather than
     trailing below the wrapped text where it reads as misplaced. */
  .slice-row-head { flex-wrap: wrap; }
  .slice-row-title, .slice-row-text { max-width: 100%; white-space: normal; }
  .slice-row-chevron { order: 1; }
  .slice-row-text { order: 2; flex-basis: 100%; padding-left: 18px; }
}

/* Admin: starter presets list/form. */
.preset-admin-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 14px;
}

.preset-admin-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
}
.preset-admin-row-icon { font-size: 15px; flex: none; }
.preset-admin-row-title { font-weight: 600; font-size: 13px; }
.preset-admin-row-desc {
  font-size: 12px;
  color: var(--text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}
.preset-admin-row-actions { display: flex; gap: 4px; flex: none; }

.preset-admin-textarea { resize: vertical; font-family: inherit; }

/* -------------------------------------------------- skeleton loaders */
/* Async panes (conversation list, cost breakdown, race board) show these
   instead of a blank pane while a fetch is in flight. */

.skeleton-line {
  display: block;
  border-radius: var(--radius-sm);
  background: linear-gradient(
    90deg,
    var(--surface-sunken) 25%,
    var(--border) 50%,
    var(--surface-sunken) 75%
  );
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.4s ease-in-out infinite;
}
@keyframes skeleton-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .skeleton-line { animation: none; background: var(--surface-sunken); }
}

.conversation-item-skeleton {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px;
}
.skeleton-line-title { width: 70%; height: 13px; }
.skeleton-line-sub { width: 45%; height: 11px; }
.skeleton-line-row { width: 100%; height: 13px; }
.skeleton-line-total { display: inline-block; width: 90px; height: 16px; vertical-align: middle; }
.skeleton-line-race { width: 100%; height: 34px; margin-bottom: 8px; border-radius: var(--radius-md); }

/* -------------------------------------------------- responsive breakpoints */
/* Deliberately last in the file: every selector these two blocks override
   (.demo-pane, .rail-title, .conversation-item, etc.) has its base,
   non-media rule defined earlier above -- a @media block has the same
   specificity as the rule it's meant to override, so cascade order alone
   decides the winner. Putting these here, after everything, is what makes
   them actually win at a narrow viewport instead of losing quietly to a
   same-specificity base rule that happens to appear later in the file. */

@media (max-width: 980px) {
  .workspace { grid-template-columns: 220px minmax(0, 1fr); }
  .demo-pane { display: none; }
}

@media (max-width: 768px) {
  /* Rail becomes an off-canvas drawer (a permanent icon strip still stole
     real width from a phone-size chat pane) -- .rail/.rail-backdrop below.
     Chat and the live demo pane stay mutually exclusive views switched by
     the toggle bar, since there's no room to show both without horizontal
     scroll; each gets its own explicit grid cell (the switch bar in row 1,
     chat/demo-pane sharing row 2) rather than relying on source-order
     auto-placement. */
  .workspace {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto 1fr;
    overflow-x: hidden;
  }
  .mobile-view-switch { grid-row: 1; }
  .chat, .demo-pane { grid-row: 2; min-height: 0; }
  .demo-pane { display: none; }
  .workspace.show-demo-mobile .chat { display: none; }
  .workspace.show-demo-mobile .demo-pane { display: flex; }

  .mobile-view-switch {
    display: flex;
    justify-content: flex-end;
    padding: 8px 12px;
    border-bottom: 1px solid var(--border);
    background: var(--ground);
  }

  /* -------- rail: off-canvas drawer -------- */
  /* Renders at its normal, full desktop width and content (titles, chips,
     the "+" form) -- it's an overlay now, not a squeezed-down strip, so
     none of the icon-only collapsing the old approach needed applies. */
  .rail {
    position: fixed;
    /* The topbar can grow past --topbar-h on a notched phone (its own
       env(safe-area-inset-top) padding) -- account for that so the drawer/
       backdrop start exactly at its actual bottom edge, not a fixed 56px
       that would leave a gap or overlap on such a device. */
    top: calc(var(--topbar-h) + env(safe-area-inset-top, 0px));
    left: 0;
    bottom: 0;
    width: min(84vw, 320px);
    z-index: 60;
    transform: translateX(-100%);
    transition: transform 200ms ease;
    box-shadow: 2px 0 24px rgba(0, 0, 0, 0.18);
  }
  .rail.is-open { transform: translateX(0); }
  @media (prefers-reduced-motion: reduce) {
    .rail { transition: none; }
  }
  #btn-rail-toggle, #btn-rail-close { display: inline-flex; }
  .rail-backdrop {
    display: block;
    position: fixed;
    /* The topbar can grow past --topbar-h on a notched phone (its own
       env(safe-area-inset-top) padding) -- account for that so the drawer/
       backdrop start exactly at its actual bottom edge, not a fixed 56px
       that would leave a gap or overlap on such a device. */
    top: calc(var(--topbar-h) + env(safe-area-inset-top, 0px));
    left: 0; right: 0; bottom: 0;
    background: rgba(16, 32, 28, 0.35);
    z-index: 55;
    opacity: 0;
    pointer-events: none;
    transition: opacity 200ms ease;
  }
  .rail-backdrop.is-open { opacity: 1; pointer-events: auto; }
  @media (prefers-reduced-motion: reduce) {
    .rail-backdrop { transition: none; }
  }

  /* -------- topbar: collapse to what fits a phone -------- */
  .env-label { display: none; }
  #btn-topbar-more { display: inline-flex; }
  .topbar-secondary-panel {
    display: flex;
    flex-direction: column;
    gap: 2px;
    position: absolute;
    top: calc(100% + 6px);
    right: 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    padding: 6px;
    min-width: 190px;
    z-index: 70;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-4px);
    transition: opacity 150ms ease, transform 150ms ease;
  }
  .topbar-secondary-panel.is-open { opacity: 1; visibility: visible; transform: translateY(0); }
  @media (prefers-reduced-motion: reduce) {
    .topbar-secondary-panel { transition: none; }
  }
  .topbar-secondary-panel .btn-icon {
    width: 100%;
    justify-content: flex-start;
    gap: 10px;
    min-height: 44px;
  }
  .topbar-secondary-panel .btn-text-label { display: inline; }
  /* Submit stays put (the primary action must stay directly reachable, not
     buried in the overflow menu with Race/Settings) -- icon-only here just
     reclaims the room its label needs everywhere else. */
  #btn-submit .btn-text-label { display: none; }

  /* -------- touch targets -------- */
  /* The dense-toolbar 36px exception (.btn-sm/.btn-icon.btn-sm) is a
     desktop-only affordance for a mouse cursor; touch needs the full
     44x44 regardless of how tight the toolbar looks. */
  .btn-sm { min-height: 44px; }
  .btn-icon.btn-sm { min-width: 44px; min-height: 44px; padding: 8px; }
  .preset-suggestion-chip { min-height: 44px; }
  /* Same reasoning as the dense-toolbar exception above -- 26px is a fine
     hover-revealed mouse target, not a fine touch one (also always-visible
     here per the "hover: none" rule already covering it). */
  .msg-revert-trigger { width: 44px; height: 44px; top: 4px; right: 4px; }
  .msg-assistant.has-revert { padding-right: 56px; }

  /* -------- composer: clear a phone's home-indicator / gesture area -------- */
  .composer { padding-bottom: calc(18px + env(safe-area-inset-bottom, 0px)); }
}
