/* ==========================================================================
   chat.css — Claude chat drawer / panel (uses design tokens from tokens.css)
   All colors, fonts, spacing flow through CSS variables so light theme
   inherits automatically via [data-theme="light"] overrides in tokens.css.
   ========================================================================== */

/* ---------- Floating action button (FAB) ---------- */
.chat-toggle-fab,
.chat-fab {
  position: fixed;
  bottom: var(--chat-fab-bottom, var(--sp-5));
  right: var(--chat-fab-right, var(--sp-5));
  z-index: var(--z-modal);
  width: 56px;
  height: 56px;
  border-radius: var(--r-full);
  background: var(--accent);
  color: var(--text-inverse);
  border: none;
  font-family: var(--font-sans);
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  display: none;
  align-items: center;
  justify-content: center;
  transition: background var(--tr-fast), transform var(--tr-fast);
}
.chat-toggle-fab.visible,
.chat-fab.visible { display: flex; }
/* Closed pane, job still running: a dot on the launcher. */
#chat-fab.is-working::after {
  content: "";
  position: absolute;
  top: 6px;
  right: 6px;
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--text-inverse);
  box-shadow: 0 0 0 2px var(--accent);
}
/* Lift above the cookie bar so "C" isn't trapped under Got it. */
body:has(.cookie-banner[data-open="1"]) {
  --chat-fab-bottom: calc(var(--sp-5, 20px) + 88px);
}
.chat-toggle-fab:hover,
.chat-fab:hover { background: var(--accent-hover); transform: none; }

/* ---------- Drawer (legacy fixed-position variant) ---------- */
.chat-drawer {
  background: var(--bg-elevated);
  border-left: 1px solid var(--border-default);
  display: flex;
  flex-direction: column;
}

/* ---------- Panel header (in-layout, used by base.html) ----------
 * Solid non-scrolling chrome above #chat-log. Avoid permanent
 * will-change / translateZ / isolation here — those promote a GPU layer
 * that blanks while the sibling log scrolls (menu flicker). */
.chat-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--sp-2) var(--sp-3);
  border-bottom: 1px solid var(--border-default);
  background: var(--bg-elevated);
  height: var(--topbar-height);
  flex: 0 0 auto;
  flex-shrink: 0;
  gap: var(--sp-2);
  min-width: 0;
  position: relative;
  z-index: 200;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  filter: none !important;
  /* No permanent transform / will-change — see auto-collapse rules. */
  transform: none;
  will-change: auto;
}
.chat-panel-title {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: calc(15px * var(--ui-font-scale, 1));
  letter-spacing: -0.02em;
  line-height: 1.25;
  color: var(--text-primary);
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
}
.chat-panel-title-text {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Actions row: wraps to a second row when buttons can't fit, so every
 * icon stays reachable on narrow widths. We must NOT use overflow:auto
 * here — popovers inside (.chat-model-pop / .chat-tier-pop / etc.) are
 * position:absolute and would be clipped by an overflow ancestor. */
.chat-panel-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-1);
  row-gap: 4px;
  flex: 1 1 auto;
  min-width: 0;
  justify-content: flex-end;          /* keep buttons right-aligned */
  position: relative;
  z-index: 100;
}
/* Prevent any single button from being shrunk below its content size. */
.chat-panel-actions > * { flex-shrink: 0; }
/* When the header wraps to multiple rows, let it grow vertically so
 * nothing gets clipped by the fixed topbar height. */
.chat-panel-header {
  flex-wrap: wrap;
  height: auto;
  min-height: var(--topbar-height);
  row-gap: 4px;
}
.chat-panel-btn {
  background: transparent;
  border: 1px solid var(--border-default);
  color: var(--text-secondary);
  padding: var(--sp-1) var(--sp-2);
  border-radius: var(--r-sm);
  cursor: pointer;
  font-family: var(--font-sans);
  font-size: var(--fs-xs);
  transition: background var(--tr-fast), color var(--tr-fast), border-color var(--tr-fast);
}
.chat-panel-btn:hover {
  background: var(--bg-elevated-2);
  color: var(--text-primary);
  border-color: var(--border-strong);
}

/* Legacy header (kept for backward compatibility) */
.chat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--sp-2) var(--sp-3);
  border-bottom: 1px solid var(--border-default);
  background: var(--bg-elevated);
}
.chat-head .title {
  font-family: var(--font-sans);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-md);
  color: var(--text-primary);
}
.chat-head .meta { color: var(--text-muted); font-size: var(--fs-xs); }
.chat-head .actions button {
  background: transparent;
  border: 1px solid var(--border-default);
  color: var(--text-secondary);
  padding: var(--sp-1) var(--sp-2);
  margin-left: var(--sp-1);
  border-radius: var(--r-sm);
  cursor: pointer;
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  transition: background var(--tr-fast);
}
.chat-head .actions button:hover { background: var(--bg-elevated-2); color: var(--text-primary); }

/* ---------- Chat log ---------- */
.chat-log {
  flex: 1 1 0;
  min-height: 0;        /* CRITICAL: lets the flex child shrink and scroll
                           instead of growing the parent to fit content */
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--sp-4) var(--sp-4) var(--sp-3);
  --chat-read: calc(14px * var(--ui-font-scale, 1));
  --chat-read-lh: 1.65;
  font-family: var(--font-sans);
  font-size: var(--chat-read);
  font-weight: 400;
  line-height: var(--chat-read-lh);
  letter-spacing: 0;
  color: var(--text-primary);
  scroll-behavior: smooth;
}

/* All non-log children inside the drawer must not grow. Only .chat-log scrolls. */
.content-right > .chat-panel-header,
.content-right > .chat-plan-bar,
.content-right > .chat-todos,
.content-right > .chat-activity-bar,
.content-right > .chat-usage,
.content-right > .chat-status-bar,
.content-right > .chat-input-row { flex-shrink: 0; }

/* Drawer shell: never become the scroll container. If the panel itself
   scrolls, the header leaves the viewport with the transcript. */
.content-right,
#chat-drawer {
  overflow-x: hidden;
  overflow-y: hidden;
  overscroll-behavior: none;
}

/* Keep the dock-mode drawer locked to the viewport height so its inner
   flex column has a definite size to distribute. */
.content-right.mode-dock {
  height: 100%;
  max-height: 100%;
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* (Removed: container-type: inline-size on .content-right. It interacted
   badly with iOS Safari's flex layout, hiding the activity bar / status
   strip when it toggled from display:none to display:flex. Mobile layout
   is owned by the @media rules in responsive.css; narrow docked drawers
   on desktop now use the @media (max-width: 768px) fallback.) */

/* Each message is a row: [avatar] [content]. Mimics Claude desktop.
   Previous spacing summed to ~40px between turns (margin-bottom 16 +
   padding-bottom 12 + sibling padding-top 12), which read as
   uncomfortable scroll-space. Tightened to ~20px total between turns
   — still has the divider line, just less air. */
.chat-msg {
  display: grid;
  grid-template-columns: 28px 1fr;
  gap: var(--sp-3);
  margin-bottom: var(--sp-2);     /* 8px (was 16px) */
  padding-bottom: var(--sp-1);    /* 4px (was 12px) */
  border-bottom: 1px dashed transparent;
}
.chat-msg + .chat-msg {
  border-top: 1px solid var(--border-muted);
  padding-top: var(--sp-2);       /* 8px (was 12px) */
}
.chat-msg:last-child { margin-bottom: 0; padding-bottom: 0; }

/* User turns: bubble + avatar on the right (ChatGPT / iMessage style).
   DOM stays [who][msg-col]; grid places who in col 2. */
.chat-msg.user {
  grid-template-columns: 1fr 28px;
}
.chat-msg.user .who {
  grid-column: 2;
  grid-row: 1;
}
.chat-msg.user .msg-col {
  grid-column: 1;
  grid-row: 1;
  align-items: flex-end;
  justify-self: stretch;
}

/* Avatar / role chip in the left column */
.chat-msg .who {
  width: 28px;
  height: 28px;
  border-radius: var(--r-full);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  letter-spacing: 0;
  text-transform: none;
  margin: 0;
  flex-shrink: 0;
  user-select: none;
  background: var(--bg-elevated-2);
  color: var(--text-secondary);
  border: 1px solid var(--border-default);
}
.chat-msg.user .who {
  background: var(--accent);
  color: var(--text-inverse);
  border-color: var(--accent);
}
.chat-msg.assistant .who {
  background: var(--bg-elevated-2);
  color: var(--text-secondary);
  border-color: var(--border-default);
}

/* The avatar glyph is rendered as textContent by JS (user initial or ◐). */
.chat-msg .who { font-size: var(--fs-sm); }
.chat-msg.assistant .who { font-size: var(--fs-md); }

.chat-msg .body {
  min-width: 0; /* allow text-overflow inside grid cell */
}
.chat-msg.user .body {
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: var(--chat-read, calc(14px * var(--ui-font-scale, 1)));
  font-weight: 400;
  line-height: 1.55;
  letter-spacing: 0;
  background: var(--bg-elevated-2);
  border: 1px solid var(--border-muted);
  border-radius: var(--r-md);
  padding: var(--sp-2) var(--sp-3);
  /* Bubble hugs content and sits on the right; text stays LTR. */
  max-width: min(100%, 36em);
  width: fit-content;
  text-align: left;
  white-space: pre-wrap;
  word-break: break-word;
}
.chat-msg.user .chat-user-tasks {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 6px;
}
.chat-msg.user .chat-user-task {
  display: inline-flex;
  align-items: center;
  height: 22px;
  padding: 0 8px;
  border: 1px solid var(--border-default);
  border-radius: 999px;
  background: transparent;
  color: var(--text-primary);
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
}
.chat-msg.user .body p { margin: 0; }
.chat-msg.user .body p + p { margin-top: var(--sp-2); }
.chat-msg.assistant .body {
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: var(--chat-read, calc(14px * var(--ui-font-scale, 1)));
  font-weight: 400;
  line-height: var(--chat-read-lh, 1.65);
  letter-spacing: 0;
  white-space: normal;
}

/* Next questions under the answer. A hairline and quieter ink keep
   them out of the reply. Hidden until the reply has finished. */
.chat-followups {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  margin: 14px 0 2px;
  padding-top: 10px;
  border-top: 1px solid var(--border-default);
  max-width: 100%;
}
.chat-followups-label {
  margin: 0 0 4px;
  color: var(--text-muted);
  font-size: var(--fs-xs, 12px);
  font-weight: 400;
  line-height: 1.4;
}
.chat-followup {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: fit-content;
  max-width: 100%;
  min-height: 32px;
  margin: 0;
  padding: 4px 8px;
  border: 0;
  border-radius: var(--r-md, 8px);
  background: transparent;
  color: var(--text-secondary);
  font: inherit;
  font-size: var(--fs-sm, 13px);
  font-weight: 400;
  line-height: 1.35;
  text-align: left;
  cursor: pointer;
}
.chat-followup:hover {
  background: var(--bg-hover);
  color: var(--text-primary);
}
.chat-followup:active {
  transform: scale(0.98);
}
.chat-followup:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 1px;
}
.chat-followup .oc-ico {
  width: 14px;
  height: 14px;
  flex: 0 0 14px;
  color: var(--text-muted);
}
.chat-followup-text {
  min-width: 0;
}
.chat-msg.is-streaming .chat-followups,
.chat-msg.is-thinking .chat-followups {
  display: none;
}
@media (prefers-reduced-motion: reduce) {
  .chat-followup { transform: none; }
}

/* Ephemeral intermediate narration ("I'll pull the 13F…") — gray, calm,
   auto-fades after a few seconds so the final answer stays clean. */
.chat-interim {
  margin: 2px 12px 6px 44px;
  padding: 0 2px;
  font-family: var(--font-sans, system-ui, -apple-system, sans-serif);
  font-size: calc(13px * var(--ui-font-scale, 1));
  font-weight: 400;
  line-height: 1.55;
  color: var(--text-muted, #8b93a7);
  font-style: italic;
  opacity: 0.85;
  transition: opacity 0.45s ease, max-height 0.45s ease, margin 0.45s ease;
  max-height: 6em;
  overflow: hidden;
  pointer-events: none;
  user-select: none;
}
.chat-interim.is-fading {
  opacity: 0;
  max-height: 0;
  margin-top: 0;
  margin-bottom: 0;
}
@media (prefers-reduced-motion: reduce) {
  .chat-interim { transition: opacity 0.2s ease; }
}

/* Progressive markdown while streaming — same typography as final body.
   word-break helps long URLs/tokens mid-stream before soft-wrap settles. */
.chat-msg.assistant.is-streaming .body {
  word-break: break-word;
}

/* Dual-region stream scaffold (markdown.js paintStreaming).
   Committed blocks are frozen DOM; only .md-stream-open rewrites.
   Children inherit assistant body typography — no extra chrome. */
.chat-msg.assistant .body > .md-stream,
.an-msg__text > .md-stream {
  display: block;
}
.chat-msg.assistant .body .md-stream-committed,
.chat-msg.assistant .body .md-stream-open,
.an-msg__text .md-stream-committed,
.an-msg__text .md-stream-open {
  display: block;
  min-width: 0;
}
/* Layout isolation only. Paint containment clips tokens that arrive after
   the first layout, so the lower half of a live answer stays blank. */
.chat-msg.assistant.is-streaming .body .md-stream-open {
  contain: layout style;
}
.chat-msg.assistant.is-streaming .body .md-stream-open p:last-child {
  margin-bottom: 0;
}
/* Live caret while tokens arrive — moving accent dot (same motion family
   as the pre-stream thinking dots), not a blinking block cursor. */
.chat-msg.assistant.is-streaming .body .md-stream-open:not(:empty)::after,
.an-msg--streaming .an-msg__text .md-stream-open:not(:empty)::after,
/* Fallback when paint path has no dual-region scaffold yet */
.chat-msg.assistant.is-streaming .body:not(:has(.md-stream-open))::after {
  content: "";
  display: inline-block;
  width: 2px;
  height: 0.9em;
  margin-left: 3px;
  border-radius: 0;
  vertical-align: -0.1em;
  background: var(--text-muted);
  box-shadow: none;
  animation: md-stream-caret 1s steps(1, end) infinite;
  opacity: 0.8;
}
@keyframes md-stream-caret {
  0%, 49% { opacity: 0.85; }
  50%, 100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .chat-msg.assistant.is-streaming .body .md-stream-open:not(:empty)::after,
  .an-msg--streaming .an-msg__text .md-stream-open:not(:empty)::after,
  .chat-msg.assistant.is-streaming .body:not(:has(.md-stream-open))::after {
    animation: none;
    opacity: 0.7;
    transform: none;
  }
}

.chat-msg.assistant .body p {
  margin: 0 0 0.7em 0;
  text-align: left;
}
.chat-msg.assistant .body p:last-child { margin-bottom: 0; }

/* ---------- LaTeX / KaTeX (markdown math) ----------
   Isolate from chat body typography so Inter/mono never override KaTeX_Main /
   KaTeX_Math (italic variables, proper sub/sup, fraction bars, etc.). */
.chat-msg .body .md-math,
.an-msg__text .md-math {
  /* inline default; display class upgrades to block */
  line-height: 1.2;
}
.chat-msg .body .md-math-display,
.an-msg__text .md-math-display {
  display: block;
  margin: 0.85em 0;
  overflow-x: auto;
  overflow-y: hidden;
  text-align: center;
  -webkit-overflow-scrolling: touch;
  padding: 0.15em 0;
}
.chat-msg .body .md-math-inline,
.an-msg__text .md-math-inline {
  display: inline;
  white-space: nowrap;
  vertical-align: middle;
}
.chat-msg .body .md-math-fallback,
.an-msg__text .md-math-fallback {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.92em;
  padding: 0.05em 0.25em;
  border-radius: 3px;
  background: color-mix(in srgb, var(--bg-elevated, #1a1d21) 80%, transparent);
  color: var(--text-secondary, #8b949e);
}
/* Full KaTeX face stack — must beat .body { font-family: Inter } inheritance.
   Do not set a generic font-family on .katex that would flatten math italics. */
.chat-msg .body .katex,
.chat-msg .body .katex *,
.an-msg__text .katex,
.an-msg__text .katex * {
  /* color only; font faces come from katex.min.css per-glyph classes */
  border-color: currentColor;
}
.chat-msg .body .katex,
.an-msg__text .katex {
  font-size: 1.15em;
  color: inherit;
  line-height: 1.2;
  text-indent: 0;
  text-rendering: auto;
  /* Reset chat sans so KaTeX_Main / KaTeX_Math from vendor CSS win */
  font-family: KaTeX_Main, "Times New Roman", serif !important;
  font-style: normal;
  font-weight: 400;
}
/* Math italic / symbols — reinforce vendor faces against global code/body rules */
.chat-msg .body .katex .mathnormal,
.chat-msg .body .katex .mathit,
.an-msg__text .katex .mathnormal,
.an-msg__text .katex .mathit {
  font-family: KaTeX_Math, "Times New Roman", serif !important;
  font-style: italic;
}
.chat-msg .body .katex .mathrm,
.an-msg__text .katex .mathrm {
  font-family: KaTeX_Main, "Times New Roman", serif !important;
  font-style: normal;
}
.chat-msg .body .katex .mathbf,
.an-msg__text .katex .mathbf {
  font-family: KaTeX_Main, "Times New Roman", serif !important;
  font-weight: 700;
}
.chat-msg .body .katex .mathbb,
.chat-msg .body .katex .mathcal,
.chat-msg .body .katex .mathfrak,
.chat-msg .body .katex .mathscr,
.an-msg__text .katex .mathbb,
.an-msg__text .katex .mathcal,
.an-msg__text .katex .mathfrak,
.an-msg__text .katex .mathscr {
  /* faces defined in katex.min.css @font-face rules */
  font-style: normal;
}
/* Never style KaTeX internals as chat <code> mono */
.chat-msg .body .katex code,
.chat-msg .body .md-math .katex,
.an-msg__text .katex code {
  font-family: inherit !important;
  background: transparent !important;
  padding: 0 !important;
  border-radius: 0 !important;
  font-size: inherit !important;
  color: inherit !important;
}
.chat-msg .body .katex-display,
.an-msg__text .katex-display {
  display: block;
  margin: 0.5em 0;
  overflow-x: auto;
  overflow-y: hidden;
  text-align: center;
}
/* Fraction line / rules need currentColor in light+dark themes */
.chat-msg .body .katex .frac-line,
.chat-msg .body .katex .hline,
.chat-msg .body .katex .overline-line,
.chat-msg .body .katex .underline-line,
.an-msg__text .katex .frac-line {
  border-bottom-color: currentColor;
}

/* Lists */
.chat-msg.assistant .body ul,
.chat-msg.assistant .body ol {
  margin: 0 0 var(--sp-3) 0;
  padding-left: var(--sp-6);
}
.chat-msg.assistant .body ul { list-style-type: disc; }
.chat-msg.assistant .body ol { list-style-type: decimal; }
.chat-msg.assistant .body li {
  margin-bottom: 0.35em;
  padding-left: var(--sp-1);
  line-height: 1.6;
}
.chat-msg.assistant .body li::marker { color: var(--text-muted); }

/* Emphasis */
.chat-msg.assistant .body strong,
.chat-msg.assistant .body b {
  font-weight: 600;
  color: var(--text-primary);
}
.chat-msg.assistant .body em,
.chat-msg.assistant .body i {
  font-style: italic;
  color: var(--text-secondary);
}

/* Inline code */
.chat-msg.assistant .body code,
.chat-msg.user .body code {
  background: var(--bg-elevated-2);
  border: 1px solid var(--border-default);
  padding: 1px var(--sp-1);
  border-radius: var(--r-sm);
  font-family: var(--font-mono);
  font-size: calc(13px * var(--ui-font-scale, 1));
  line-height: 1.45;
  color: var(--text-primary);
}

/* Code blocks — Claude-desktop-style with a language header strip */
.chat-msg.assistant .body pre,
.chat-msg.user .body pre {
  background: var(--bg-code);
  border: 1px solid var(--border-default);
  padding: var(--sp-3);
  padding-top: var(--sp-3);
  border-radius: var(--r-md);
  overflow-x: auto;
  margin: 0 0 var(--sp-3) 0;
  line-height: 1.55;
  font-family: var(--font-mono);
  font-size: calc(13px * var(--ui-font-scale, 1));
  white-space: pre-wrap;
  word-break: break-word;
  position: relative;
}
.chat-msg.assistant .body pre[data-lang]:not([data-lang=""]),
.chat-msg.user .body pre[data-lang]:not([data-lang=""]) {
  padding-top: calc(var(--sp-5) + 4px);
}
.chat-msg .body pre .code-lang {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  padding: 2px var(--sp-3);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  background: var(--bg-elevated-2);
  border-bottom: 1px solid var(--border-default);
  border-radius: var(--r-md) var(--r-md) 0 0;
  text-transform: lowercase;
  letter-spacing: 0.05em;
}
.chat-msg.assistant .body pre code,
.chat-msg.user .body pre code {
  background: transparent;
  border: none;
  padding: 0;
  color: var(--text-primary);
  font-family: var(--font-mono);
  font-size: inherit;
  line-height: inherit;
}

/* Markdown fallback (when something goes wrong with the parser) */
.chat-msg .body pre.md-fallback {
  white-space: pre-wrap;
  color: var(--text-secondary);
}

/* Task lists */
.chat-msg .body li.task {
  list-style: none;
  margin-left: calc(-1 * var(--sp-5));
  padding-left: 0;
}
.chat-msg .body li.task .task-box {
  display: inline-block;
  width: 1.1em;
  margin-right: var(--sp-1);
  color: var(--text-muted);
  font-family: var(--font-mono);
}
.chat-msg .body li.task.done    { color: var(--text-muted); }
.chat-msg .body li.task.done    .task-box { color: var(--success); }
.chat-msg .body li.task.done > * { text-decoration: line-through; }

/* Headings inside messages */
.chat-msg.assistant .body h1,
.chat-msg.assistant .body h2,
.chat-msg.assistant .body h3,
.chat-msg.assistant .body h4 {
  font-family: var(--font-sans);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--text-primary);
  margin: 1.15em 0 0.4em 0;
  line-height: 1.3;
}
.chat-msg.assistant .body h1 { font-size: calc(20px * var(--ui-font-scale, 1)); }
.chat-msg.assistant .body h2 { font-size: calc(17px * var(--ui-font-scale, 1)); }
.chat-msg.assistant .body h3 { font-size: calc(15px * var(--ui-font-scale, 1)); letter-spacing: -0.015em; }
.chat-msg.assistant .body h4 { font-size: calc(15px * var(--ui-font-scale, 1)); font-weight: 600; letter-spacing: -0.01em; }
.chat-msg.assistant .body h1:first-child,
.chat-msg.assistant .body h2:first-child,
.chat-msg.assistant .body h3:first-child,
.chat-msg.assistant .body h4:first-child { margin-top: 0; }

/* Links */
.chat-msg.assistant .body a,
.chat-msg.user .body a {
  color: var(--accent);
  text-decoration: none;
  border-bottom: none;
  transition: color var(--tr-fast);
}
.chat-msg.assistant .body a:hover,
.chat-msg.user .body a:hover {
  color: var(--accent-hover);
  text-decoration: none;
}

/* Blockquotes (Claude-style callout bar) */
.chat-msg.assistant .body blockquote,
.chat-msg.user .body blockquote {
  margin: 0 0 var(--sp-3) 0;
  padding: var(--sp-2) var(--sp-3);
  background: var(--bg-elevated-2);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  color: var(--text-secondary);
  font-style: normal;
}
.chat-msg .body blockquote > :last-child { margin-bottom: 0; }

/* Horizontal rule */
.chat-msg.assistant .body hr {
  border: none;
  border-top: 1px solid var(--border-default);
  margin: var(--sp-4) 0;
}

/* Tables */
.chat-msg .body table {
  border-collapse: collapse;
  margin: 0 0 var(--sp-3) 0;
  font-size: calc(13.5px * var(--ui-font-scale, 1));
  line-height: 1.45;
  width: 100%;
  border: 1px solid var(--border-default);
  border-radius: var(--r-sm);
  overflow: hidden;
}
.chat-msg .body th,
.chat-msg .body td {
  border-bottom: 1px solid var(--border-muted);
  border-right: 1px solid var(--border-muted);
  padding: var(--sp-1) var(--sp-2);
  vertical-align: top;
}
.chat-msg .body th:last-child,
.chat-msg .body td:last-child { border-right: none; }
.chat-msg .body tr:last-child td { border-bottom: none; }
.chat-msg .body th {
  background: var(--bg-elevated-2);
  color: var(--text-primary);
  font-weight: 500;
  text-align: left;
}
.chat-msg .body tbody tr:nth-child(even) td { background: rgba(127,127,127,0.04); }

/* Financial grids: hairline rows, mono figures, totals ruled. */
.chat-msg .body table.oc-fin,
.th-chat-msg table.oc-fin,
.an-msg__text table.oc-fin,
.chat-render table.oc-fin {
  border: none;
  border-radius: 0;
  width: 100%;
  font-variant-numeric: tabular-nums;
}
.chat-msg .body table.oc-fin th,
.chat-msg .body table.oc-fin td,
.th-chat-msg.assistant table.oc-fin th,
.th-chat-msg.assistant table.oc-fin td,
.an-msg__text table.oc-fin th,
.an-msg__text table.oc-fin td,
.chat-render table.oc-fin th,
.chat-render table.oc-fin td {
  border: none;
  border-right: none;
  border-bottom: 1px solid var(--border-muted);
  text-align: left;
  vertical-align: baseline;
  padding: 4px 8px;
}
.chat-msg .body table.oc-fin .num,
.th-chat-msg.assistant table.oc-fin .num,
.an-msg__text table.oc-fin .num,
.chat-render table.oc-fin .num {
  text-align: right;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-variant-numeric: tabular-nums;
}
.chat-msg .body table.oc-fin .neg,
.th-chat-msg.assistant table.oc-fin .neg,
.an-msg__text table.oc-fin .neg,
.chat-render table.oc-fin .neg {
  color: var(--danger, #9b3a3a);
}
.chat-msg .body table.oc-fin tr.is-total td,
.th-chat-msg.assistant table.oc-fin tr.is-total td,
.an-msg__text table.oc-fin tr.is-total td,
.chat-render table.oc-fin tr.is-total td,
.chat-msg .body table.oc-fin tr.is-subtotal td,
.th-chat-msg.assistant table.oc-fin tr.is-subtotal td,
.an-msg__text table.oc-fin tr.is-subtotal td,
.chat-render table.oc-fin tr.is-subtotal td {
  font-weight: 600;
  border-top: 1px solid var(--text-primary);
}
.chat-msg .body table.oc-fin tr.is-section td,
.th-chat-msg.assistant table.oc-fin tr.is-section td,
.an-msg__text table.oc-fin tr.is-section td,
.chat-render table.oc-fin tr.is-section td {
  padding-top: 10px;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 600;
  border-bottom-color: transparent;
}

/* ---------- Tool call blocks ---------- */
.chat-tool {
  background: var(--bg-elevated-2);
  border-left: 2px solid var(--border-strong);
  padding: var(--sp-1) var(--sp-2);
  margin: var(--sp-1) 0;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  opacity: 0.6;
  transition: opacity var(--tr-fast);
  max-width: 90%;
  color: var(--text-muted);
}
.chat-tool:hover { opacity: 1; }
.chat-tool .tname {
  color: var(--text-secondary);
  font-weight: var(--fw-medium);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.chat-tool .tname::before {
  content: "⚙ ";
  color: var(--accent);
  margin-right: 2px;
}
.chat-tool .t-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-1);
  cursor: default;
}
.chat-tool .t-toggle {
  background: transparent;
  border: 1px solid var(--border-default);
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  padding: 0 var(--sp-1);
  border-radius: var(--r-sm);
  cursor: pointer;
  margin-left: auto;
}
.chat-tool .t-toggle:hover { background: var(--bg-elevated); color: var(--text-primary); }
.chat-tool .tin,
.chat-tool .tout {
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  margin-top: var(--sp-1);
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 120px;
  overflow: auto;
  line-height: var(--lh-tight);
}
.chat-tool .tin.collapsed { display: none; }

/* ---------- Input row ---------- */
/* Single full-width composer shell. Attach tools + send live *inside*
   one frosted plate (no inner borders / separator bands). Format "T"
   toolbar is disabled for now. (Liquid-glass face came from glass.css,
   deleted 2026-09-12 — the token fill below is the only face now.) */
.chat-input-row {
  border-top: none;
  padding: var(--sp-2);
  display: flex;
  align-items: stretch;
  gap: 0;
  background: transparent;
  flex-shrink: 0;
}
/* Legacy mobile "+" toggle — unused in the in-box layout. */
.chat-attach-toggle {
  display: none !important;
}
.chat-input-wrap {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0;
  min-width: 0;
  /* Face comes from tokens; the glass.css upgrade layer is gone */
  background: var(--bg-input);
  border: 1px solid var(--border-default);
  border-radius: var(--r-md);
  transition: border-color var(--dur-ui) var(--ease-out);
  overflow: hidden; /* clip children to rounded shell */
  isolation: isolate;
}
.chat-input-wrap:focus-within {
  border-color: var(--border-strong);
}

/* Parked in the composer until a new chat mounts them on the welcome. */
.chat-tasks { display: none; }
.chat-empty-welcome .chat-tasks {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  width: auto;
  max-width: 100%;
  margin: 0 0 4px;
  padding: 0;
}
.chat-task {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  height: 34px;
  margin: 0;
  padding: 0 14px;
  border: 1px solid var(--border-default);
  border-radius: 999px;
  background: transparent;
  color: var(--text-primary, var(--text));
  font-family: Inter, var(--font-sans);
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
}
.chat-task .oc-ico {
  width: 14px;
  height: 14px;
  flex: none;
}
.chat-task:hover {
  background: color-mix(in srgb, var(--text-primary) 6%, transparent);
}
.chat-task.is-on {
  border-color: color-mix(in srgb, var(--ai-neon-b, #7c3aed) 55%, var(--border-default));
  background: color-mix(in srgb, var(--ai-neon-b, #7c3aed) 10%, transparent);
}
.chat-task:focus-visible,
.chat-task-pill__x:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 1px;
}
/* Row is full width so pills wrap inside the box. Each pill hugs its label. */
.chat-task-pills {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: 6px;
  box-sizing: border-box;
  width: 100%;
  margin: 2px 0 8px;
  padding: 0 10px;
  background: none;
  border: 0;
}
.chat-task-pills[hidden] { display: none; }
.chat-task-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  width: auto;
  max-width: 100%;
  margin: 0;
  padding: 3px 3px 3px 8px;
  border: 1px solid transparent;
  border-radius: 999px;
  background:
    linear-gradient(var(--bg-elevated, var(--bg-input)), var(--bg-elevated, var(--bg-input))) padding-box,
    linear-gradient(135deg, var(--ai-neon-a, #06b6d4), var(--ai-neon-b, #7c3aed) 55%, var(--ai-neon-c, #db2777)) border-box;
}
.chat-task-pill__mark {
  flex: none;
  display: inline-block;
  width: 12px;
  height: 12px;
}
.chat-task-pill__name {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: Inter, var(--font-sans);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--text-primary, var(--text));
}
.chat-task-pill__x {
  flex: none;
  width: 20px;
  height: 20px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text-muted);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}
.chat-task-pill__x:hover {
  background: color-mix(in srgb, var(--text-primary) 8%, transparent);
  color: var(--text-primary, var(--text));
}

/* Bottom bar: tools left · status + send right — seamless (no divider) */
.chat-composer-bar {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 2px 6px 6px 8px;
  flex-shrink: 0;
  min-height: 36px;
  border: none;
  border-top: none;
  background: transparent;
  box-shadow: none;
}
.chat-composer-end {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  min-width: 0;
  margin-left: auto;
}

/* Empty-session layout: ChatGPT/Claude-style centered composer — narrower,
   pill-rounded, with comfortable side margins. When the first message
   lands and .is-empty-session is removed the row eases back to its
   default full-width / sharper-cornered look. */
.content-right.is-empty-session .chat-input-row {
  padding-left: clamp(16px, 8%, 80px);
  padding-right: clamp(16px, 8%, 80px);
  border-top-color: transparent;
  background: transparent;
  transition: padding 0.35s ease, background 0.35s ease, border-color 0.35s ease;
}
.content-right.is-empty-session .chat-input-wrap {
  border-radius: var(--r-md);
}
/* Match the rounded shell on the textarea and the rich-text toolbar inside
   the wrap so the corners don't look square against the pill border. */
.content-right.is-empty-session .chat-input-wrap > .chat-toolbar:not(.hidden) {
  border-radius: 24px 24px 0 0;
}
.content-right.is-empty-session .chat-input-wrap #chat-input {
  padding-left: 14px;
  padding-right: 14px;
}
.content-right.is-empty-session .chat-composer-bar {
  border: none;
  background: transparent;
}
/* Bottom rest state — sharper corners, full-width. Easing back from the
   pill on first-message send. */
.content-right:not(.is-empty-session) .chat-input-row {
  transition: padding 0.35s ease;
}
/* Send button — compact circle; product accent, no indigo/violet glow. */
:root {
  --send-c1: var(--accent);
  --send-c2: var(--accent);
  --send-c3: var(--accent);
  --send-glow: transparent;
}
[data-theme="dark"] {
  --send-c1: var(--accent);
  --send-c2: var(--accent);
  --send-c3: var(--accent);
  --send-glow: transparent;
}
.chat-composer-bar > button#chat-send,
.chat-input-wrap #chat-send,
#chat-send {
  flex: 0 0 auto;
  align-self: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  background: var(--accent);
  color: var(--text-inverse);
  border: 1px solid var(--accent);
  border-radius: 50%;
  padding: 0;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0; /* hide any stray text */
  line-height: 1;
  cursor: pointer;
  width: 32px;
  height: 32px;
  min-width: 32px;
  min-height: 32px;
  max-width: 32px;
  max-height: 32px;
  box-shadow: none;
  filter: none;
  transition:
    transform var(--dur-press) var(--ease-out),
    background var(--dur-ui) var(--ease-out),
    border-color var(--dur-ui) var(--ease-out);
}
#chat-send .send-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transform: none;
  transition: none;
  filter: none;
}
#chat-send .send-ico svg {
  width: 15px;
  height: 15px;
}
/* Label hidden — icon-only send sits in the lower-right corner. */
#chat-send .send-label {
  display: none !important;
}
#chat-send:hover:not(:disabled) {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
  filter: none;
  box-shadow: none;
}
#chat-send:hover:not(:disabled) .send-ico {
  transform: none;
}
#chat-send:focus-visible {
  outline: 1px solid color-mix(in srgb, var(--text-primary) 45%, transparent);
  outline-offset: 2px;
  box-shadow: none;
}
#chat-send:active:not(:disabled) {
  transform: scale(0.98);
  filter: none;
}
#chat-send:disabled {
  background: var(--bg-elevated-2);
  color: var(--text-muted);
  cursor: not-allowed;
  box-shadow: none;
  filter: none;
}
#chat-send:disabled .send-ico,
#chat-send:disabled .send-label {
  filter: none;
  text-shadow: none;
}
#chat-send.is-busy {
  animation: none;
  opacity: 0.7;
}
#chat-send.is-busy .send-ico {
  animation: none;
}
@keyframes chat-send-pulse {
  0%, 100% { opacity: 1;   transform: translateX(0) rotate(0deg); }
  50%      { opacity: 0.55; transform: translateX(1px) rotate(-4deg); }
}
@keyframes chat-send-shimmer {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

/* ---------- Rich text toolbar (disabled for now — re-visit later) ---------- */
.chat-toolbar,
.chat-toolbar.hidden,
#chat-toolbar,
.chat-fmt-toggle,
#chat-fmt-toggle {
  display: none !important;
  visibility: hidden !important;
  pointer-events: none !important;
}
.chat-toolbar-btn svg,
.chat-action-btn svg,
.chat-fmt-toggle svg {
  display: block;
  flex-shrink: 0;
  pointer-events: none;
}

/* Default (light + dark via tokens). Borderless flat tile that takes the
   theme's text + elevated background colors. The previous rule used
   hard-coded #f5f5f5 / #1a1a1a so dark mode kept rendering light icons on
   light tiles. Specificity now matches the input-row selector so the dark
   override block below actually wins. */
.chat-input-row .chat-toolbar .chat-toolbar-btn,
button.chat-toolbar-btn {
  background: transparent;
  color: var(--text-secondary);
  border: 1px solid transparent;
  border-radius: 6px;
  padding: 4px 8px;
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: 500;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
  min-width: 30px;
  min-height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.chat-input-row .chat-toolbar .chat-toolbar-btn:hover,
button.chat-toolbar-btn:hover {
  background: color-mix(in srgb, var(--accent, #5b8def) 12%, transparent);
  color: var(--text-default);
  border-color: color-mix(in srgb, var(--accent, #5b8def) 30%, transparent);
}
.chat-input-row .chat-toolbar .chat-toolbar-btn:active,
button.chat-toolbar-btn:active {
  background: color-mix(in srgb, var(--accent, #5b8def) 22%, transparent);
  transform: scale(0.96);
}
/* Active state (e.g. bold/italic currently applied to selection) — give
   the button a clearly distinct "pressed" look. */
.chat-input-row .chat-toolbar .chat-toolbar-btn.is-active,
button.chat-toolbar-btn.is-active,
.chat-input-row .chat-toolbar .chat-toolbar-btn[aria-pressed="true"],
button.chat-toolbar-btn[aria-pressed="true"] {
  background: color-mix(in srgb, var(--accent, #5b8def) 22%, transparent);
  color: var(--accent, #5b8def);
  border-color: color-mix(in srgb, var(--accent, #5b8def) 50%, transparent);
}

/* Dark-mode reinforcements — match the same nesting as the light rules so
   specificity ties go to the later declaration (the dark one). The
   previous `[data-theme="dark"] .chat-toolbar-btn` was a 3-class loser
   against `.chat-input-row .chat-toolbar .chat-toolbar-btn`, which is why
   the icons stayed light-on-light in dark mode. */
[data-theme="dark"] .chat-input-row .chat-toolbar,
[data-theme="dark"] .chat-toolbar {
  background: color-mix(in srgb, var(--bg-elevated) 65%, transparent);
  border-bottom-color: var(--border-default);
}
[data-theme="dark"] .chat-input-row .chat-toolbar .chat-toolbar-btn,
[data-theme="dark"] button.chat-toolbar-btn {
  background: transparent;
  color: var(--text-secondary, #c9d1d9);
  border-color: transparent;
}
[data-theme="dark"] .chat-input-row .chat-toolbar .chat-toolbar-btn:hover,
[data-theme="dark"] button.chat-toolbar-btn:hover {
  background: color-mix(in srgb, var(--accent, #58a6ff) 18%, transparent);
  color: #fff;
  border-color: color-mix(in srgb, var(--accent, #58a6ff) 40%, transparent);
}
[data-theme="dark"] .chat-input-row .chat-toolbar .chat-toolbar-btn:active,
[data-theme="dark"] button.chat-toolbar-btn:active {
  background: color-mix(in srgb, var(--accent, #58a6ff) 30%, transparent);
}

.chat-toolbar-sep {
  width: 1px;
  height: 18px;
  background: color-mix(in srgb, var(--border-default) 70%, transparent);
  margin: 0 4px;
  flex-shrink: 0;
}

/* ---------- Textarea container ---------- */
/* Single-line floor (1.5 × line-height). Grows with content via JS autoGrow. */
.chat-textarea-container {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 0;
  padding: 0;
  /* The slash-hint popover is portalled out of this box; clipping it here is
     what the quiet.css override used to prevent. Owned by the component now. */
  overflow: visible;
  background: transparent;
  border: none;
  border-radius: 0;
  flex: 0 1 auto;
  min-height: 0;
}

#chat-input {
  flex: 1;
  width: 100%;
  resize: none;
  background: transparent;
  color: var(--text-primary);
  border: none;
  outline: none;
  /* Floor tracks the transcript: 14px at 1.55, plus the padding. */
  --chat-input-lh: 1.55;
  --chat-input-fs: calc(14px * var(--ui-font-scale, 1));
  padding: 10px 14px 4px;
  font-family: var(--font-sans);
  font-size: var(--chat-input-fs);
  font-weight: 400;
  letter-spacing: 0;
  line-height: var(--chat-input-lh);
  min-height: calc(var(--chat-input-fs) * var(--chat-input-lh) * 1.5 + 8px);
  max-height: 200px;
  height: auto;
  overflow-y: auto;
  overflow-x: hidden;
  word-wrap: break-word;
  field-sizing: content; /* progressive enhancement where supported */
}
#chat-input::placeholder {
  color: var(--text-muted);
}

/* ---------- Attachments row ---------- */
/* Collapses to 0 height when there are no pill children, so the input
   wrap doesn't show phantom padding below the textarea. JS toggles the
   `.empty` class but the :empty pseudo-class is a belt-and-suspenders
   guard for the initial pre-JS render. */
.chat-attachments-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1);
  padding: var(--sp-2);
  min-height: 0;
}
.chat-attachments-row.empty,
.chat-attachments-row:empty {
  display: none;
}
.chat-attachment-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  background: var(--bg-elevated-2);
  color: var(--text-primary);
  border: 1px solid var(--border-default);
  border-radius: var(--r-sm);
  padding: var(--sp-1) var(--sp-2);
  font-size: var(--fs-sm);
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.chat-attachment-pill-remove {
  margin-left: auto;
  flex-shrink: 0;
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 0;
  font-size: var(--fs-xs);
  transition: color var(--tr-fast);
}
.chat-attachment-pill-remove:hover {
  color: var(--danger);
}
.chat-attachment-pill .dim { color: var(--text-muted); font-size: var(--fs-xs); }

/* Document chip on a user bubble (live + replayed from history). */
.chat-msg.user .chat-user-doc {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  margin-right: 6px;
  padding: 6px 10px;
  max-width: 100%;
  background: var(--bg-elevated-2, rgba(255,255,255,0.04));
  border: 1px solid var(--border-default);
  border-radius: 8px;
  font-size: var(--fs-sm, 13px);
  line-height: 1.3;
}
.chat-msg.user .chat-user-doc-icon { flex-shrink: 0; }
.chat-msg.user .chat-user-doc-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 220px;
}
.chat-msg.user .chat-user-doc .dim {
  color: var(--text-muted);
  font-size: var(--fs-xs, 11px);
  flex-shrink: 0;
}

/* Image attached to a user bubble (live + replayed from history). */
.chat-msg.user img.chat-user-image {
  display: block;
  max-width: 100%;
  max-height: 320px;
  margin-top: 6px;
  border-radius: 8px;
  border: 1px solid var(--border-default);
  background: var(--bg-input);
}

/* ---------- Action buttons (inside composer bar, bottom-left) ---------- */
.chat-action-buttons,
.chat-composer-bar .chat-action-buttons {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
}
.chat-composer-bar .chat-action-buttons .chat-action-btn,
.chat-input-wrap .chat-action-buttons .chat-action-btn,
button.chat-action-btn {
  background: transparent;
  color: var(--text-secondary, #6b7280);
  border: 1px solid transparent;
  border-radius: 8px;
  width: 32px;
  height: 32px;
  padding: 0;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
  flex-shrink: 0;
}
.chat-composer-bar .chat-action-buttons .chat-action-btn:hover,
.chat-input-wrap .chat-action-buttons .chat-action-btn:hover,
button.chat-action-btn:hover {
  background: color-mix(in srgb, var(--accent, #5b8def) 12%, transparent);
  color: var(--text-default, #111);
  border-color: color-mix(in srgb, var(--accent, #5b8def) 25%, transparent);
  transform: none;
}
.chat-composer-bar .chat-action-buttons .chat-action-btn:active,
.chat-input-wrap .chat-action-buttons .chat-action-btn:active,
button.chat-action-btn:active {
  transform: scale(0.94);
  background: color-mix(in srgb, var(--accent, #5b8def) 20%, transparent);
}
.chat-composer-bar .chat-action-buttons .chat-action-btn svg,
.chat-input-wrap .chat-action-buttons .chat-action-btn svg {
  width: 17px;
  height: 17px;
}
[data-theme="dark"] .chat-composer-bar .chat-action-buttons .chat-action-btn,
[data-theme="dark"] .chat-input-wrap .chat-action-buttons .chat-action-btn,
[data-theme="dark"] button.chat-action-btn {
  background: transparent;
  color: var(--text-secondary, #c9d1d9);
  border-color: transparent;
}
[data-theme="dark"] .chat-composer-bar .chat-action-buttons .chat-action-btn:hover,
[data-theme="dark"] .chat-input-wrap .chat-action-buttons .chat-action-btn:hover,
[data-theme="dark"] button.chat-action-btn:hover {
  background: color-mix(in srgb, var(--accent, #4a90e2) 16%, transparent);
  color: var(--text-default, #fff);
  border-color: color-mix(in srgb, var(--accent, #4a90e2) 35%, transparent);
}
[data-theme="dark"] .chat-composer-bar .chat-action-buttons .chat-action-btn:active,
[data-theme="dark"] .chat-input-wrap .chat-action-buttons .chat-action-btn:active,
[data-theme="dark"] button.chat-action-btn:active {
  background: color-mix(in srgb, var(--accent, #4a90e2) 26%, transparent);
}

/* ---------- Status (idle ready · model · trust) ---------- */
/* Sits left of Send inside .chat-composer-end — not a full-width row. */
.chat-status-bar {
  padding: 0;
  margin: 0;
  font-family: var(--font-sans);
  font-size: 11px;
  line-height: 1.2;
  color: var(--text-muted);
  border: none;
  background: transparent;
  flex: 1 1 auto;
  min-width: 0;
  max-width: 220px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: right;
  pointer-events: none;
  opacity: 1;
}
.chat-status-bar:empty { display: none; }
.chat-status-bar .err {
  color: var(--danger);
  opacity: 1;
  pointer-events: auto;
}

/* ---------- Todos / plan panel ---------- */
.chat-todos {
  display: none;
  border-bottom: 1px solid var(--border-default);
  background: var(--bg-base);
  max-height: 200px;
  overflow-y: auto;
}
.chat-todos.open { display: block; }
.chat-todos-head {
  font-family: var(--font-sans);
  font-size: calc(12px * var(--ui-font-scale, 1));
  text-transform: uppercase;
  letter-spacing: 0.04em;
  line-height: 1.3;
  color: var(--text-muted);
  padding: var(--sp-2) var(--sp-3) var(--sp-1);
  font-weight: 500;
}
.chat-todo-list {
  list-style: none;
  margin: 0;
  padding: 0 var(--sp-3) var(--sp-2);
  font-family: var(--font-sans);
  font-size: calc(13px * var(--ui-font-scale, 1));
  line-height: 1.5;
  font-weight: 400;
}
.chat-todo-list li {
  display: flex;
  align-items: baseline;
  gap: var(--sp-1);
  color: var(--text-secondary);
  padding: 2px 0;
}
.chat-todo-list .todo-mark {
  display: inline-block;
  width: 14px;
  text-align: center;
  color: var(--text-muted);
  font-family: var(--font-mono);
}
.chat-todo-list .todo-completed { color: var(--text-muted); }
.chat-todo-list .todo-completed .todo-text { text-decoration: line-through; }
.chat-todo-list .todo-completed .todo-mark { color: var(--success); }
.chat-todo-list .todo-in_progress { color: var(--warning); }
.chat-todo-list .todo-in_progress .todo-mark { color: var(--accent); }

/* ---------- Header button states ---------- */
#chat-plan.active {
  background: var(--warning) !important;
  color: var(--bg-base) !important;
  border-color: var(--warning) !important;
}

/* ---------- Persistent plan-mode directive bar ---------- */
.chat-plan-bar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  background: linear-gradient(
    to right,
    rgba(240, 180, 60, 0.18),
    rgba(240, 180, 60, 0.08)
  );
  border-top: 1px solid var(--warning);
  border-bottom: 1px solid var(--warning);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: var(--fs-xs);
  line-height: 1.45;
  flex-shrink: 0;
}
.chat-plan-bar.hidden { display: none; }
.chat-plan-bar-badge {
  flex-shrink: 0;
  background: var(--warning);
  color: var(--bg-base);
  font-weight: var(--fw-bold);
  font-size: 10px;
  letter-spacing: 0.08em;
  padding: 2px var(--sp-2);
  border-radius: var(--r-sm);
  text-transform: uppercase;
}
.chat-plan-bar-text {
  flex: 1;
  color: var(--text-secondary);
}
.chat-plan-bar-text b    { color: var(--text-primary); font-weight: var(--fw-semibold); }
.chat-plan-bar-text code {
  font-family: var(--font-mono);
  font-size: 11px;
  background: var(--bg-base);
  border: 1px solid var(--border-default);
  padding: 0 4px;
  border-radius: var(--r-sm);
  color: var(--accent);
}
.chat-plan-bar-off {
  flex-shrink: 0;
  background: transparent;
  border: 1px solid var(--warning);
  color: var(--warning);
  font-family: var(--font-sans);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  padding: 3px var(--sp-2);
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background var(--tr-fast), color var(--tr-fast);
}
.chat-plan-bar-off:hover {
  background: var(--warning);
  color: var(--bg-base);
}
#chat-cancel { display: none; }
#chat-cancel.show { display: inline-flex; align-items: center; }
#chat-cancel {
  border-color: var(--danger) !important;
  color: var(--danger) !important;
}

/* ---------- Token / usage meter ---------- */
.chat-usage {
  display: none;
  padding: var(--sp-1) var(--sp-3);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  background: var(--bg-base);
  border-top: 1px solid var(--border-default);
}
.chat-usage.show { display: block; }
.chat-usage .u-in    { color: var(--accent); }
.chat-usage .u-out   { color: var(--success); }
.chat-usage .u-cache { color: var(--warning); }
.chat-usage .u-cost  { color: var(--text-secondary); margin-left: var(--sp-1); }

/* ---------- Slash / mention / sessions popover ---------- */
.chat-pop {
  display: block;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(4px);
  transform-origin: bottom center;
  transition:
    opacity var(--dur-ui) var(--ease-out),
    transform var(--dur-ui) var(--ease-out),
    visibility 0s linear var(--dur-ui);
  list-style: none;
  margin: 0;
  padding: var(--sp-1) 0;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--r-md);
  max-height: 200px;
  overflow-y: auto;
  z-index: var(--z-dropdown);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  box-shadow: var(--shadow-sm);
}
.chat-pop.open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: none;
  transition:
    opacity var(--dur-ui) var(--ease-out),
    transform var(--dur-ui) var(--ease-out),
    visibility 0s linear 0s;
}
.chat-pop li {
  padding: var(--sp-1) var(--sp-3);
  cursor: pointer;
  display: flex;
  gap: var(--sp-2);
  align-items: baseline;
  color: var(--text-secondary);
}
.chat-pop li.active,
.chat-pop li:hover {
  background: var(--bg-elevated-2);
  color: var(--text-primary);
}
.chat-pop .p-name {
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
}
.chat-pop .p-desc {
  color: var(--text-muted);
  font-size: var(--fs-xs);
}
/* $TICKER / #PIPELINE mention dropdown — bold value + muted name. */
.chat-pop .m-primary {
  color: var(--text-primary);
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: var(--fs-sm);
}
.chat-pop .m-secondary {
  color: var(--text-muted);
  font-size: var(--fs-xs);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---------- Image attachments ---------- */
.chat-attachments {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1);
  margin-top: var(--sp-1);
  min-height: 0;
}
.chat-attachments:empty { display: none; }
.chat-attachments .att {
  position: relative;
  width: 48px;
  height: 48px;
  border: 1px solid var(--border-default);
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--bg-elevated-2);
}
.chat-attachments .att img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.chat-attachments .att .x {
  position: absolute;
  top: 0;
  right: 0;
  background: var(--danger);
  color: var(--text-inverse);
  border: 0;
  width: 16px;
  height: 16px;
  line-height: 16px;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  cursor: pointer;
  padding: 0;
}

/* ---------- Banners ---------- */
/* Notices read as a quiet line of the thread: no box, border or tint. */
.chat-banner {
  font-family: var(--font-sans);
  font-size: var(--fs-xs);
  padding: 0 12px;
  margin: var(--sp-1) 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--text-muted);
}
.chat-banner.info,
.chat-banner.ok { color: var(--text-muted); }
.chat-banner.warn { color: var(--warning); }
.chat-banner.err  { color: var(--danger); }

/* ---------- Code copy button ---------- */
.code-copy {
  position: absolute;
  top: var(--sp-1);
  right: var(--sp-1);
  background: var(--bg-elevated-2);
  border: 1px solid var(--border-default);
  color: var(--text-secondary);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  padding: 2px var(--sp-1);
  border-radius: var(--r-sm);
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--tr-fast), background var(--tr-fast);
  z-index: 1;
}
/* When the <pre> carries a language header strip, lift copy below it */
.chat-msg .body pre[data-lang]:not([data-lang=""]) .code-copy {
  top: 2px;
  right: var(--sp-1);
}
.chat-msg.assistant .body pre:hover .code-copy,
.chat-msg.user .body pre:hover .code-copy { opacity: 1; }
.code-copy:hover { background: var(--bg-elevated); color: var(--text-primary); }
.code-copy.copied { color: var(--success); }

/* ---------- Modal root + boxes ---------- */
.chat-modal-root {
  display: none;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.55);
  z-index: var(--z-modal);
  align-items: center;
  justify-content: center;
  padding: var(--sp-3);
}
.chat-modal-root.open { display: flex; }
.chat-modal-box {
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--r-md);
  padding: var(--sp-4);
  max-width: 360px;
  width: 100%;
  max-height: 80%;
  overflow-y: auto;
  box-shadow: var(--shadow-xl);
  color: var(--text-primary);
  font-family: var(--font-sans);
}
.chat-modal-box h4 {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-md);
  color: var(--accent);
  font-weight: var(--fw-semibold);
}
.chat-modal-box .modal-q {
  font-size: calc(15px * var(--ui-font-scale, 1));
  font-weight: 400;
  margin-bottom: var(--sp-2);
  line-height: 1.55;
}
.chat-modal-args {
  background: var(--bg-code);
  border: 1px solid var(--border-default);
  border-radius: var(--r-sm);
  padding: var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 200px;
  overflow: auto;
  margin-bottom: var(--sp-3);
  color: var(--text-secondary);
}
.chat-modal-box .btn-row {
  display: flex;
  gap: var(--sp-2);
  justify-content: flex-end;
  margin-top: var(--sp-2);
}
.btn-allow, .btn-deny, .btn-trust {
  border: none;
  border-radius: var(--r-sm);
  padding: var(--sp-2) var(--sp-3);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition: background var(--tr-fast);
}
.btn-allow { background: var(--success); color: var(--text-inverse); }
.btn-allow:hover { filter: brightness(1.1); }
.btn-deny { background: var(--danger); color: var(--text-inverse); }
.btn-deny:hover { filter: brightness(1.1); }
.btn-trust { background: var(--accent); color: var(--text-inverse); }
.btn-trust:hover { background: var(--accent-hover); }

/* ---------- Question modal options ---------- */
.q-opts { list-style: none; margin: 0 0 var(--sp-2); padding: 0; }
.q-opt {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--sp-2);
  margin-bottom: var(--sp-1);
  background: var(--bg-base);
  border: 1px solid var(--border-default);
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: border-color var(--tr-fast), background var(--tr-fast);
}
.q-opt:hover { border-color: var(--accent); background: var(--bg-elevated-2); }
.q-opt.selected { border-color: var(--accent); background: var(--accent-muted); }
.q-label {
  color: var(--text-primary);
  font-size: calc(14px * var(--ui-font-scale, 1));
  font-weight: 500;
  line-height: 1.4;
}
.q-desc { color: var(--text-muted); font-size: var(--fs-xs); }
.q-chip {
  display: inline-block;
  font-size: var(--fs-xs);
  background: var(--bg-elevated-2);
  color: var(--text-secondary);
  padding: 1px var(--sp-2);
  border-radius: var(--r-full);
  margin-bottom: var(--sp-1);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.q-other {
  width: 100%;
  background: var(--bg-input);
  border: 1px solid var(--border-default);
  color: var(--text-primary);
  border-radius: var(--r-sm);
  padding: var(--sp-1) var(--sp-2);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  margin-top: var(--sp-1);
  box-sizing: border-box;
  resize: vertical;
  min-height: 32px;
}
.q-other:focus { outline: none; border-color: var(--accent); }

/* ---------- Prism overrides ---------- */
.chat-msg.assistant .body pre[class*="language-"] {
  background: var(--bg-code);
  color: var(--text-primary);
  text-shadow: none;
}
.chat-msg.assistant .body code[class*="language-"] {
  text-shadow: none;
  font-family: var(--font-mono);
}

/* ---------- Session picker popover ---------- */
/* Positioned relative to .content-right (the chat drawer). Drops out of the
   header row, hugs the right side. Explicitly unsets bottom/left in case
   the element accidentally inherits the .chat-pop rule used elsewhere. */
.chat-sessions-pop {
  position: absolute;
  top: calc(var(--topbar-height) + 4px);
  right: var(--sp-3);
  bottom: auto;
  left: auto;
  width: min(360px, calc(100% - 2 * var(--sp-3)));
  max-height: 60vh;
  overflow-y: auto;
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  z-index: var(--z-dropdown);
  display: block;
  padding: 0;                 /* header / footer handle their own padding */
  margin: 0;
  list-style: none;
  font-family: var(--font-sans);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(-4px);
  transform-origin: top right;
  transition:
    opacity var(--dur-ui, 280ms) var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
    transform var(--dur-ui, 280ms) var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
    visibility 0s linear var(--dur-ui, 280ms);
}
.chat-sessions-pop.open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: none;
  transition:
    opacity var(--dur-ui) var(--ease-out),
    transform var(--dur-ui) var(--ease-out),
    visibility 0s linear 0s;
}

/* Sticky chrome: head + toolbar stick together so toolbar top never
   needs a magic offset that drifts when the head wraps/resizes. */
.chat-sessions-pop .sess-chrome {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--bg-elevated);
}
.chat-sessions-pop .sess-head {
  display: block;
  padding: 8px 8px 0;
  background: transparent;
  border-bottom: none;
}
.chat-sessions-pop .sess-rail {
  display: none;
}
.chat-sessions-pop .sess-head .sess-new {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  color: var(--text-primary);
  border: none;
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  letter-spacing: 0;
  text-transform: none;
  font-family: var(--font-sans);
}
.chat-sessions-pop .sess-head .sess-new:hover {
  background: color-mix(in srgb, var(--text-primary) 7%, transparent);
}

.chat-sessions-pop .sess-toolbar {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 4px 8px 8px;
  background: transparent;
  border-bottom: none;
}
.chat-sessions-pop .sess-search-wrap {
  position: relative;
  display: flex;
  align-items: center;
}
.chat-sessions-pop .sess-search-icon {
  position: absolute;
  left: 8px;
  color: var(--text-muted);
  font-size: 12px;
  pointer-events: none;
}
.chat-sessions-pop .sess-search {
  width: 100%;
  box-sizing: border-box;
  background: var(--bg-input, var(--bg-base));
  color: var(--text-primary);
  border: 1px solid var(--border-default);
  border-radius: var(--r-sm);
  padding: 5px 26px 5px 24px;
  font-size: var(--fs-xs);
  font-family: var(--font-sans);
}
.chat-sessions-pop .sess-search:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(99, 179, 237, 0.18);
}
.chat-sessions-pop .sess-search-clear {
  position: absolute;
  right: 4px;
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 2px 6px;
  border-radius: 4px;
}
.chat-sessions-pop .sess-search-clear:hover {
  color: var(--text-primary);
  background: var(--bg-elevated-2);
}
.chat-sessions-pop .sess-empty {
  padding: 16px 12px;
  color: var(--text-muted);
  font-size: 13px;
  line-height: 1.4;
}
.chat-sessions-pop .sess-empty.is-error { color: var(--danger); }
.chat-sessions-pop .sess-list {
  list-style: none;
  margin: 0;
  padding: 0 6px 8px;
}

/* Sticky footer (info / help text). */
.chat-sessions-pop .sess-foot {
  position: sticky;
  bottom: 0;
  padding: var(--sp-2) var(--sp-3);
  background: var(--bg-elevated);
  border-top: 1px solid var(--border-default);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  line-height: 1.4;
}
.chat-sessions-pop .sess-foot b { color: var(--text-secondary); font-weight: var(--fw-semibold); }
.chat-sessions-pop .sess-count {
  font-weight: var(--fw-normal);
  color: var(--text-muted);
  letter-spacing: 0;
  text-transform: none;
  margin-left: var(--sp-1);
}
.chat-sessions-pop li.sess-group {
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  user-select: none;
  padding: var(--sp-2) var(--sp-3) var(--sp-1);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: var(--bg-elevated);
  border-bottom: none;
  pointer-events: auto;
}
.chat-sessions-pop li.sess-group:hover {
  color: var(--text-primary);
  background: var(--bg-elevated-2);
}
.chat-sessions-pop li.sess-group .sess-group-chevron {
  width: 10px;
  font-size: 9px;
  opacity: 0.85;
}
.chat-sessions-pop li.sess-group .sess-group-label { flex: 1; min-width: 0; }
.chat-sessions-pop li.sess-group .sess-group-count {
  font-family: var(--font-mono);
  font-weight: var(--fw-medium);
  font-size: 10px;
  opacity: 0.75;
  text-transform: none;
  letter-spacing: 0;
}
.chat-sessions-pop li.sess-group.is-collapsed { opacity: 0.85; }
.chat-sessions-pop .sess-nav,
.chat-sessions-pop .sess-help,
.chat-sessions-pop .sess-all,
.chat-sessions-pop .sess-head-range,
.chat-sessions-pop .sess-count,
.chat-sessions-pop .s-rel {
  display: none;
}
.chat-sessions-pop .sess-more-wrap {
  padding: 4px 10px 10px;
  border-top: none;
}
.chat-sessions-pop .sess-more {
  width: 100%;
  background: transparent;
  color: var(--text-muted);
  border: none;
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  font-family: var(--font-sans);
  text-align: left;
}
.chat-sessions-pop .sess-more:hover:not(:disabled) {
  color: var(--text-primary);
  background: color-mix(in srgb, var(--text-primary) 7%, transparent);
}
.chat-sessions-pop .sess-more:disabled {
  opacity: 0.6;
  cursor: wait;
}
.chat-sessions-pop li {
  padding: var(--sp-2) var(--sp-3);
  display: flex;
  gap: var(--sp-2);
  align-items: flex-start;
  cursor: pointer;
  font-size: var(--fs-sm);
  color: var(--text-secondary);
  border-bottom: none;
}
.chat-sessions-pop li:last-child { border-bottom: none; }
.chat-sessions-pop li.empty { color: var(--text-muted); cursor: default; }
.chat-sessions-pop li:hover:not(.empty):not(.sess-group) {
  background: var(--bg-elevated-2);
  color: var(--text-primary);
}
.chat-sessions-pop li.sess.active {
  background: var(--accent-muted);
  color: var(--text-primary);
}
.chat-sessions-pop li.sess {
  position: relative;
  align-items: center;
  min-height: 32px;
  padding: 6px 8px;
  gap: 0;
  --sess-fade: var(--bg-elevated);
}
.chat-sessions-pop li.sess:hover:not(.active) { --sess-fade: var(--bg-elevated-2); }
.chat-sessions-pop li.sess.active { --sess-fade: var(--accent-muted); }
.chat-sessions-pop .s-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.3;
}
.chat-sessions-pop .s-trail {
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: 2px;
  z-index: 1;
  padding-left: 18px;
  background: linear-gradient(to right, transparent, var(--sess-fade) 14px);
}
.chat-sessions-pop .s-when {
  flex: 0 0 auto;
  color: var(--text-muted);
  font-family: var(--font-sans);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  white-space: nowrap;
  line-height: 1;
}
.chat-sessions-pop .s-rel { display: none; }
.chat-sessions-pop .s-rename,
.chat-sessions-pop .s-del {
  flex: 0 0 auto;
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 0;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  border-radius: var(--r-sm);
}
.chat-sessions-pop .s-del .oc-ico {
  width: 13px;
  height: 13px;
}
.chat-sessions-pop .s-rename {
  font-size: 13px;
  padding: 2px 6px;
}
.chat-sessions-pop .s-rename:hover {
  color: var(--accent);
  background: rgba(99, 179, 237, 0.10);
}
.chat-sessions-pop .s-del:hover { color: var(--danger); }

@media (hover: hover) and (pointer: fine) {
  .chat-sessions-pop .s-trail {
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--dur-ui, 180ms);
  }
  .chat-sessions-pop li.sess:hover .s-trail,
  .chat-sessions-pop li.sess:focus-within .s-trail {
    opacity: 1;
    pointer-events: auto;
  }
  .chat-sessions-pop li.sess:hover .s-label,
  .chat-sessions-pop li.sess:focus-within .s-label {
    text-overflow: clip;
    -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 6.75rem), transparent);
    mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 6.75rem), transparent);
  }
}
@media (hover: none), (pointer: coarse) {
  .chat-sessions-pop .s-trail {
    position: static;
    transform: none;
    opacity: 1;
    pointer-events: auto;
    flex: 0 0 auto;
    margin-left: auto;
    padding-left: 8px;
    background: none;
  }
}

/* Inline rename input replaces the .s-label in-place. */
.chat-sessions-pop .s-rename-input {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  color: var(--text-primary);
  background: var(--bg-base);
  border: 1px solid var(--accent);
  border-radius: var(--r-sm);
  padding: 3px 6px;
  outline: none;
  box-shadow: 0 0 0 2px rgba(99, 179, 237, 0.25);
}
.chat-sessions-pop .s-rename-input::placeholder {
  color: var(--text-muted);
  font-style: italic;
}
.chat-sessions-pop li.sess.editing {
  background: rgba(99, 179, 237, 0.06);
}
.chat-sessions-pop li.sess.editing .s-trail { display: none; }

/* ---------- Floating modal overlay (memory, permission, question) ---------- */
/* Note: this is for dynamically-created `<div class="chat-modal">` overlays.
   The static `.chat-modal-root` above is a different scoped variant. */
.chat-modal {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-4);
  animation: chat-modal-fade-in var(--dur-ui, 200ms) var(--ease-out, ease);
}
@keyframes chat-modal-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ---------- Memory editor ---------- */
.mem-modal .mem-box {
  max-width: 720px;
  width: 100%;
  max-height: min(90vh, 880px);
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--r-md);
  padding: 0;
  display: flex;
  flex-direction: column;
  box-shadow: var(--shadow-xl);
  color: var(--text-primary);
  font-family: var(--font-sans);
  overflow: hidden;
}

.mem-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--border-default);
  background: linear-gradient(to bottom, var(--bg-elevated-2), var(--bg-elevated));
}
.mem-title { display: flex; align-items: baseline; gap: var(--sp-2); flex-wrap: wrap; }
.mem-title-main {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--accent);
  letter-spacing: 0.2px;
}
.mem-title-user {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  background: var(--bg-base);
  padding: 2px var(--sp-2);
  border-radius: var(--r-sm);
  border: 1px solid var(--border-default);
}
.mem-close {
  background: transparent;
  border: none;
  color: var(--text-muted);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 8px;
  border-radius: var(--r-sm);
  transition: background var(--tr-fast), color var(--tr-fast);
}
.mem-close:hover { background: var(--bg-elevated-2); color: var(--text-primary); }

.mem-sub {
  margin: 0;
  padding: var(--sp-3) var(--sp-4) 0;
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: var(--text-secondary);
}
.mem-sub b { color: var(--text-primary); font-weight: var(--fw-semibold); }

.mem-help {
  margin: var(--sp-3) var(--sp-4) 0;
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.mem-help > summary {
  cursor: pointer;
  user-select: none;
  padding: 6px var(--sp-2);
  background: var(--bg-base);
  border: 1px solid var(--border-default);
  border-radius: var(--r-sm);
  font-size: var(--fs-xs);
  color: var(--text-secondary);
  list-style: none;
}
.mem-help > summary::before { content: "▸ "; color: var(--text-muted); }
.mem-help[open] > summary::before { content: "▾ "; }
.mem-help > summary:hover { color: var(--text-primary); }
.mem-help-body {
  margin-top: var(--sp-2);
  padding: var(--sp-3);
  background: var(--bg-base);
  border: 1px solid var(--border-default);
  border-radius: var(--r-sm);
  line-height: 1.5;
}
.mem-help-body b { color: var(--text-primary); font-weight: var(--fw-semibold); }

.mem-err {
  margin: var(--sp-3) var(--sp-4) 0;
  padding: var(--sp-2) var(--sp-3);
  background: rgba(220, 80, 80, 0.12);
  border: 1px solid var(--danger);
  border-radius: var(--r-sm);
  color: var(--danger);
  font-size: var(--fs-xs);
  font-family: var(--font-mono);
}

.mem-toolbar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4) var(--sp-2);
}
.mem-tool-btn {
  background: var(--bg-base);
  color: var(--text-secondary);
  border: 1px solid var(--border-default);
  border-radius: var(--r-sm);
  padding: 4px var(--sp-2);
  font-size: var(--fs-xs);
  font-family: var(--font-sans);
  cursor: pointer;
  transition: background var(--tr-fast), color var(--tr-fast), border-color var(--tr-fast);
}
.mem-tool-btn:hover {
  background: var(--bg-elevated-2);
  color: var(--text-primary);
  border-color: var(--accent);
}
.mem-counter {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  padding: 4px var(--sp-2);
  background: var(--bg-base);
  border: 1px solid var(--border-default);
  border-radius: var(--r-sm);
  transition: color var(--tr-fast), border-color var(--tr-fast), background var(--tr-fast);
}
.mem-counter.warn  { color: var(--warning); border-color: var(--warning); }
.mem-counter.over  { color: var(--danger);  border-color: var(--danger); background: rgba(220, 80, 80, 0.08); }

.mem-text {
  flex: 1;
  width: auto;
  margin: 0 var(--sp-4);
  min-height: 260px;
  background: var(--bg-input);
  color: var(--text-primary);
  border: 1px solid var(--border-default);
  border-radius: var(--r-sm);
  padding: var(--sp-3);
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  line-height: 1.5;
  resize: vertical;
  box-sizing: border-box;
  tab-size: 2;
}
.mem-text:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(var(--accent-rgb, 100 160 255), 0.15);
}

.mem-foot {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  margin-top: var(--sp-3);
  border-top: 1px solid var(--border-default);
  background: var(--bg-elevated-2);
}
.mem-foot-spacer { flex: 1; }
.mem-btn {
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  padding: 7px var(--sp-3);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition: background var(--tr-fast), color var(--tr-fast), border-color var(--tr-fast), filter var(--tr-fast);
}
.mem-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.mem-btn-primary {
  background: var(--accent);
  color: var(--text-inverse);
}
.mem-btn-primary:not(:disabled):hover { filter: brightness(1.08); }
.mem-btn-ghost {
  background: transparent;
  color: var(--text-secondary);
  border-color: var(--border-default);
}
.mem-btn-ghost:hover { background: var(--bg-base); color: var(--text-primary); }
.mem-btn-danger {
  background: transparent;
  color: var(--danger);
  border-color: var(--danger);
}
.mem-btn-danger:hover { background: var(--danger); color: var(--text-inverse); }

/* Legacy classes preserved for backwards compatibility (currently unused). */
.btn-mem-save   { background: var(--success); color: var(--text-inverse); }
.btn-mem-clear  { background: var(--warning); color: var(--bg-base); }
.btn-mem-cancel { background: var(--bg-elevated-2); color: var(--text-secondary); }

/* ---------- Per-message action row (copy / edit / retry) ---------- */
.chat-msg .msg-col {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
}
/* Action row (copy / edit / retry). Always reserves its vertical slot
   so messages don't shift up/down as the row fades in/out on hover or
   when streaming finishes. Visibility is gated purely by opacity. */
.chat-msg .msg-actions {
  display: flex;
  gap: var(--sp-1);
  flex-wrap: wrap;
  margin-top: var(--sp-1);
  min-height: 26px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 140ms ease;
}
.chat-msg.user .msg-actions {
  justify-content: flex-end;
}
.chat-msg:hover .msg-actions,
.chat-msg:focus-within .msg-actions,
.chat-msg.is-speaking .msg-actions {
  opacity: 1;
  pointer-events: auto;
}
@media (hover: none) and (pointer: coarse) {
  .chat-msg .msg-actions {
    opacity: 1;
    pointer-events: auto;
  }
}
.msg-act {
  appearance: none;
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-muted);
  font-size: var(--fs-xs);
  font-family: var(--font-sans);
  padding: 2px 8px;
  border-radius: var(--r-sm);
  cursor: pointer;
  letter-spacing: 0.01em;
  line-height: 1.6;
  transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}
.msg-act:hover {
  background: var(--bg-elevated);
  color: var(--text-primary);
  border-color: var(--border-default);
}
.msg-act:active {
  background: var(--bg-elevated-2);
}
.msg-act.ok {
  color: var(--success);
  border-color: var(--success);
}
.msg-act.is-on {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 35%, transparent);
}

/* ---------- Model picker ---------- */
.chat-model-wrap,
.chat-tier-wrap {
  position: relative;
  display: inline-flex;
}
.chat-model-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-width: 86px;
  justify-content: space-between;
}
.chat-model-btn .caret {
  font-size: 9px;
  opacity: 0.6;
  transform: translateY(1px);
}
.chat-model-btn[aria-expanded="true"] .caret { opacity: 1; }
.chat-model-pop {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  /* Belt-and-braces overrides in case anything cascades from .chat-pop. */
  bottom: auto;
  left: auto;
  min-width: 220px;
  max-width: 320px;
  max-height: 320px;
  overflow-y: auto;
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  padding: var(--sp-1) 0;
  margin: 0;
  list-style: none;
  z-index: 10000;
  display: block;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(-4px);
  transform-origin: top right;
  transition:
    opacity var(--dur-ui, 280ms) var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
    transform var(--dur-ui, 280ms) var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
    visibility 0s linear var(--dur-ui, 280ms);
}
.chat-model-pop.open,
.chat-tier-pop.open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: none;
  transition:
    opacity var(--dur-ui) var(--ease-out),
    transform var(--dur-ui) var(--ease-out),
    visibility 0s linear 0s;
}
.chat-model-pop li.grp {
  padding: 8px 10px 4px;
  font-size: calc(12px * var(--ui-font-scale, 1));
  line-height: 1.35;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text-muted);
  font-weight: 500;
}
.chat-model-pop li.mdl {
  display: flex;
  flex-direction: column;
  padding: 8px 10px;
  cursor: pointer;
  gap: 2px;
  border-left: none;
  border-radius: 10px;
}
.chat-model-pop li.mdl:hover {
  background: color-mix(in srgb, var(--text-primary) 7%, transparent);
}
.chat-model-pop li.mdl.active {
  border-left: none;
  background: color-mix(in srgb, var(--text-primary) 10%, transparent);
}
.chat-model-pop li.mdl .m-label {
  font-size: calc(13px * var(--ui-font-scale, 1));
  line-height: 1.35;
  color: var(--text-primary);
  font-weight: 500;
  letter-spacing: -0.01em;
}
.chat-model-pop li.mdl.active .m-label { color: var(--text-primary); }
.chat-model-pop li.mdl .m-id {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-muted);
}
.chat-model-pop li.mdl-foot {
  position: sticky;
  bottom: 0;
  margin-top: 4px;
  padding: 6px var(--sp-3) 8px;
  font-size: 11px;
  line-height: 1.4;
  color: var(--text-muted);
  background: var(--bg-elevated);
  border-top: 1px solid var(--border-default);
  list-style: none;
}
.chat-model-pop li.mdl-foot b { color: var(--text-primary); font-weight: 600; }
.chat-model-pop li.empty {
  padding: var(--sp-2) var(--sp-3);
  color: var(--text-muted);
  font-style: italic;
}

/* ---------- Resizer (drag left edge of chat drawer to widen) ---------- */
.chat-resizer {
  position: absolute;
  top: 0;
  left: 0;
  width: 5px;
  height: 100%;
  cursor: ew-resize;
  z-index: 50;
  background: transparent;
  transition: background 120ms ease;
}
.chat-resizer::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 1px;
  width: 3px;
  height: 36px;
  border-radius: 2px;
  background: color-mix(in srgb, var(--accent) 55%, var(--border-default));
  transform: translateY(-50%);
  opacity: 0;
  transition: opacity 120ms ease;
}
.chat-resizer:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.chat-resizer:hover::after { opacity: 0.85; }
body.chat-resizing .chat-resizer { background: color-mix(in srgb, var(--accent) 16%, transparent); }
body.chat-resizing .chat-resizer::after { opacity: 1; background: var(--accent); }
/* Hide the resize handle when collapsed. */
.content-right.collapsed .chat-resizer { display: none; }

/* Pre-paint collapse: read by the head bootstrap when localStorage says
   chatPanelCollapsed=true. Avoids the "drawer flashes open then snaps
   shut" race on pages with an already-collapsed chat. The late post-DOM
   JS still applies the proper .collapsed / .visible classes; these rules
   just keep the drawer hidden + the FAB visible until that happens. */
html[data-chat-init="collapsed"] #chat-drawer,
html[data-chat-init="collapsed"] .content-right {
  visibility: hidden !important;
  opacity: 0 !important;
  width: 0 !important;
  min-width: 0 !important;
  pointer-events: none !important;
}
html[data-chat-init="collapsed"] #chat-fab {
  display: flex !important;
}
/* Once the post-DOM JS adds .collapsed, the normal rules take over and
   the !important pre-paint clamp lifts because we no longer match this
   pre-init attribute (the JS only adds .collapsed, never sets the html
   attribute). To free the rule cleanly without flicker, the late JS also
   strips the bootstrap attribute. See base.html. */

/* ---------- Header menus: Layout + More (consolidated window controls) ---------- */
.chat-header-menu-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
}
.chat-layout-btn .chat-layout-ico {
  font-size: 13px;
  line-height: 1;
  margin-right: 2px;
}
.chat-layout-btn .chat-layout-txt,
.chat-more-btn .chat-more-txt {
  font-size: var(--fs-xs);
}
.chat-layout-btn .caret,
.chat-more-btn .caret,
.chat-tier-btn .caret,
.chat-model-btn .caret {
  font-size: 9px;
  opacity: 0.7;
  margin-left: 2px;
}
.chat-header-menu {
  display: flex;
  flex-direction: column;
  gap: 2px;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(-4px);
  transform-origin: top right;
  transition:
    opacity var(--dur-ui, 280ms) var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
    transform var(--dur-ui, 280ms) var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
    visibility 0s linear var(--dur-ui, 280ms);
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 400;
  min-width: 220px;
  max-width: min(280px, 92vw);
  padding: 6px;
  margin: 0;
  list-style: none;
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--r-md, 10px);
  box-shadow: var(--shadow-lg, 0 12px 32px rgba(0, 0, 0, 0.35));
}
.chat-header-menu.open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: none;
  transition:
    opacity var(--dur-ui) var(--ease-out),
    transform var(--dur-ui) var(--ease-out),
    visibility 0s linear 0s;
}
.chat-menu-section {
  padding: 8px 10px 4px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: -0.01em;
  text-transform: none;
  color: var(--text-muted);
  user-select: none;
}
.chat-menu-sep {
  height: 1px;
  margin: 4px 6px;
  background: var(--border-default);
  border: 0;
}
.chat-menu-item {
  appearance: none;
  display: grid;
  grid-template-columns: 22px 1fr;
  grid-template-rows: auto auto;
  column-gap: 8px;
  row-gap: 1px;
  align-items: center;
  width: 100%;
  text-align: left;
  padding: 8px 10px;
  border: 1px solid transparent;
  border-radius: var(--r-sm, 8px);
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-sans);
  font-size: var(--fs-sm, 13px);
  cursor: pointer;
  transition: background 100ms ease, color 100ms ease, border-color 100ms ease;
}
.chat-menu-item:hover {
  background: var(--bg-elevated-2, color-mix(in srgb, var(--text-primary) 6%, transparent));
  color: var(--text-primary);
}
.chat-menu-item:focus-visible {
  outline: 2px solid var(--accent, #6c8cff);
  outline-offset: -2px;
}
.chat-menu-ico {
  grid-row: 1 / span 2;
  grid-column: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  font-size: 14px;
  line-height: 1;
  color: var(--text-muted);
}
.chat-menu-item:hover .chat-menu-ico { color: var(--text-primary); }
.chat-menu-label {
  grid-column: 2;
  grid-row: 1;
  font-weight: var(--fw-medium, 500);
  color: inherit;
  line-height: 1.25;
}
.chat-menu-hint {
  grid-column: 2;
  grid-row: 2;
  font-size: 11px;
  color: var(--text-muted);
  line-height: 1.3;
}
.chat-menu-item:hover .chat-menu-hint,
.chat-menu-item:focus-visible .chat-menu-hint {
  color: var(--text-primary);
}
/* Items without an icon (More menu) span full width */
.chat-more-pop .chat-menu-item {
  grid-template-columns: 1fr;
}
.chat-more-pop .chat-menu-label,
.chat-more-pop .chat-menu-hint {
  grid-column: 1;
}
/* Active / pressed states for mode + toggles */
.chat-menu-item.is-active,
.chat-menu-item.active,
.chat-menu-item[aria-pressed="true"],
.content-right.mode-dock  #chat-win-dock,
.content-right.mode-float #chat-win-float,
.content-right.mode-mini  #chat-win-mini,
.content-right.mode-float.maximized #chat-win-max,
.content-right.shaded #chat-win-min,
.content-right.pinned #chat-pin {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 28%, transparent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}
.chat-menu-item.is-active .chat-menu-ico,
.chat-menu-item[aria-pressed="true"] .chat-menu-ico,
.content-right.mode-dock  #chat-win-dock .chat-menu-ico,
.content-right.mode-float #chat-win-float .chat-menu-ico,
.content-right.mode-mini  #chat-win-mini .chat-menu-ico,
.content-right.mode-float.maximized #chat-win-max .chat-menu-ico,
.content-right.shaded #chat-win-min .chat-menu-ico,
.content-right.pinned #chat-pin .chat-menu-ico {
  color: var(--accent);
}
/* Layout trigger shows accent when not in default dock (or pinned/shaded) */
.content-right.mode-float .chat-layout-btn,
.content-right.mode-mini .chat-layout-btn,
.content-right.shaded .chat-layout-btn,
.content-right.pinned .chat-layout-btn,
.content-right.mode-float.maximized .chat-layout-btn {
  border-color: color-mix(in srgb, var(--accent) 40%, var(--border-default));
  color: var(--accent);
}
/* Legacy class hooks (pin JS still toggles .chat-pin-btn aria) */
.chat-pin-btn[aria-pressed="true"] {
  color: var(--accent);
}

/* Drag grip in the title (visible only when floating). */
.chat-drag-grip {
  display: inline-block;
  margin-right: 6px;
  padding: 0 4px;
  color: var(--text-muted);
  cursor: grab;
  user-select: none;
  opacity: 0;
  transition: opacity 120ms ease;
}
.content-right.mode-float .chat-drag-grip,
.content-right.mode-mini  .chat-drag-grip {
  opacity: 0.7;
}
.chat-drag-grip:hover { opacity: 1; color: var(--text-primary); }
.chat-drag-grip:active { cursor: grabbing; }

/* ---------- Float mode (detached panel over content) ----------
 * Height MUST be definite (not content-sized). With height:auto the flex
 * column can grow with the transcript; scroll then moves the whole panel
 * and the top menu bar scrolls away. Lock height from top→bottom margins
 * like dock mode does with 100dvh, keep overflow on the drawer clipped,
 * and only let #chat-log scroll. */
.content-right.mode-float {
  position: fixed;
  top: var(--chat-fy, 80px);
  right: var(--chat-fx, calc((100vw - min(var(--chat-width-user, 50vw), 100vw - 32px)) / 2));
  bottom: 24px;
  width: var(--chat-width-user, 50vw);
  /* Definite height: top + bottom pins, with an explicit height so flex
     children get a real containing block to shrink into. */
  height: auto; /* filled by top/bottom; max-height caps extreme cases */
  max-height: calc(100vh - 48px);
  max-height: calc(100dvh - 48px);
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden; /* never scroll the panel chrome — only .chat-log */
  border: 1px solid var(--border-default);
  border-radius: var(--r-lg, 12px);
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.45);
  z-index: 9000;
}
.content-right.mode-float::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  border: 1px solid rgba(255, 255, 255, 0.04);
  z-index: 0;
}

/* Header is a flex sibling of #chat-log — NOT inside the scrollport. */
.content-right > .chat-panel-header,
#chat-drawer > .chat-panel-header {
  position: relative !important;
  top: auto !important;
  flex: 0 0 auto !important;
  flex-shrink: 0 !important;
  z-index: 200 !important;
  background: var(--bg-elevated, #161b22) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  filter: none !important;
  opacity: 1 !important;
  visibility: visible !important;
  /* Do NOT set transform here — conflicts with auto-collapse slide and
     creates a permanent compositor layer that flickers on log scroll. */
  transform: none;
  will-change: auto;
  box-shadow: none;
}
.content-right > .chat-log,
.content-right > #chat-log,
#chat-drawer > .chat-log,
#chat-drawer > #chat-log {
  flex: 1 1 0 !important;
  min-height: 0 !important;
  overflow-x: hidden !important;
  overflow-y: auto !important;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  position: relative;
  z-index: 1;
  /* No contain:paint — it clipped sticky fades and forced full-layer
     invalidation of the drawer chrome on every scroll frame. */
}
.content-right > .chat-input-row,
.content-right > .chat-plan-bar,
.content-right > .chat-todos,
.content-right > .chat-activity-bar,
.content-right > .chat-usage,
.content-right > .chat-status-bar,
#chat-drawer > .chat-input-row,
#chat-drawer > .chat-plan-bar,
#chat-drawer > .chat-todos,
#chat-drawer > .chat-activity-bar,
#chat-drawer > .chat-usage,
#chat-drawer > .chat-status-bar {
  flex-shrink: 0;
  position: relative;
  z-index: 2;
}

/* Maximized floating chat: fill the viewport. Overrides the centered
   --chat-fx/--chat-fy + user width so the panel stretches edge-to-edge.
   Removing the `.maximized` class restores the prior centered position. */
.content-right.mode-float.maximized {
  top: 8px !important;
  right: 8px !important;
  bottom: 8px !important;
  left: 8px !important;
  width: auto !important;
  min-width: 0 !important;
  height: auto !important;
  max-height: none !important;
  border-radius: var(--r-lg, 12px);
  overflow: hidden;
}

@property --chat-page-rail {
  syntax: "<length>";
  inherits: true;
  initial-value: 272px;
}

/* Full-page chat: float expands over the desk. Sessions sit in a left
   rail; the transcript and composer stay a centered reading column.
   Selectors are heavier than `.content-right.mode-float` because
   responsive.css (later in the cascade) sets display:flex on float. */
html[data-chat-page="1"]:not([data-chat-init="collapsed"]) body #chat-drawer.content-right,
html body #chat-drawer.content-right.mode-page {
  --chat-page-rail: 272px;
  --chat-page-col: 48rem;
  position: fixed !important;
  inset: 0 !important;
  top: 0 !important;
  right: 0 !important;
  bottom: 0 !important;
  left: 0 !important;
  width: auto !important;
  min-width: 0 !important;
  max-width: none !important;
  height: auto !important;
  max-height: none !important;
  display: grid !important;
  grid-template-columns: 272px minmax(0, 1fr) !important;
  grid-template-rows: auto auto auto minmax(0, 1fr) auto auto auto !important;
  align-content: stretch;
  align-items: stretch;
  flex-direction: unset;
  border-radius: 0 !important;
  border: none !important;
  box-shadow: none !important;
  z-index: 9000;
  overflow: hidden !important;
  background: var(--bg-base);
}
html body #chat-drawer.content-right.collapsed.mode-page,
html[data-chat-page="1"][data-chat-init="collapsed"] body #chat-drawer.content-right {
  display: none !important;
}
html body #chat-drawer.mode-page::before,
html body #chat-drawer.mode-page > .chat-resizer,
html body #chat-drawer.mode-page .chat-drag-grip {
  display: none !important;
}
html body #chat-drawer.mode-page > #chat-sessions-pop,
html body #chat-drawer.mode-page > #chat-sessions-pop.is-rail,
html body #chat-drawer.mode-page > #chat-sessions-pop.open {
  grid-column: 1;
  grid-row: 1 / -1;
  justify-self: stretch;
  align-self: stretch;
  position: relative !important;
  inset: auto !important;
  top: auto !important;
  right: auto !important;
  bottom: auto !important;
  left: auto !important;
  width: auto !important;
  max-width: none !important;
  min-width: 0 !important;
  max-height: none !important;
  height: auto !important;
  min-height: 0 !important;
  opacity: 1 !important;
  visibility: visible !important;
  pointer-events: auto !important;
  transform: none !important;
  margin: 0 !important;
  padding: 0 !important;
  border: none !important;
  border-right: 1px solid var(--border-default) !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  background: var(--bg-elevated) !important;
  z-index: 3;
  display: flex !important;
  flex-direction: column !important;
  overflow: hidden !important;
}
html body #chat-drawer.mode-page > #chat-sessions-pop .sess-chrome {
  position: static;
  flex: 0 0 auto;
}
html body #chat-drawer.mode-page > #chat-sessions-pop .sess-head {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 4px;
  padding: 12px 10px 0;
}
html body #chat-drawer.mode-page > #chat-sessions-pop .sess-rail {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  min-width: 28px;
  padding: 0;
  margin: 0;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  flex: 0 0 auto;
  order: 2;
}
html body #chat-drawer.mode-page > #chat-sessions-pop .sess-rail:hover {
  background: color-mix(in srgb, var(--text-primary) 7%, transparent);
  color: var(--text-primary);
}
html body #chat-drawer.mode-page > #chat-sessions-pop .sess-rail:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 1px;
}
html body #chat-drawer.mode-page > #chat-sessions-pop .sess-rail:active {
  transform: scale(0.98);
}
html body #chat-drawer.mode-page > #chat-sessions-pop .sess-rail .oc-ico {
  width: 18px;
  height: 18px;
}
html body #chat-drawer.mode-page.rail-anim > #chat-sessions-pop .sess-rail .oc-ico {
  transition: transform 320ms cubic-bezier(0.4, 0, 0.2, 1);
}
html body #chat-drawer.mode-page.rail-collapsed > #chat-sessions-pop .sess-rail .oc-ico {
  transform: scaleX(-1);
}
html body #chat-drawer.mode-page > #chat-sessions-pop .sess-head .sess-new {
  flex: 1 1 0;
  min-width: 0;
  max-width: 100%;
  width: auto;
  overflow: hidden;
  white-space: nowrap;
  order: 1;
}
html[data-chat-page="1"] body #chat-drawer.content-right.mode-page.rail-collapsed,
html body #chat-drawer.content-right.mode-page.rail-collapsed {
  --chat-page-rail: 48px;
  grid-template-columns: 48px minmax(0, 1fr) !important;
}
html body #chat-drawer.content-right.mode-page.rail-anim {
  transition:
    --chat-page-rail 320ms cubic-bezier(0.4, 0, 0.2, 1),
    grid-template-columns 320ms cubic-bezier(0.4, 0, 0.2, 1);
}
html body #chat-drawer.mode-page.rail-anim > #chat-sessions-pop .sess-head {
  transition: gap 320ms cubic-bezier(0.4, 0, 0.2, 1);
}
html body #chat-drawer.mode-page.rail-anim > #chat-sessions-pop .sess-head .sess-new {
  transition:
    opacity 220ms cubic-bezier(0.4, 0, 0.2, 1),
    max-width 320ms cubic-bezier(0.4, 0, 0.2, 1),
    padding 320ms cubic-bezier(0.4, 0, 0.2, 1),
    flex-grow 320ms cubic-bezier(0.4, 0, 0.2, 1),
    visibility 0s;
}
html body #chat-drawer.mode-page.rail-anim > #chat-sessions-pop .sess-toolbar,
html body #chat-drawer.mode-page.rail-anim > #chat-sessions-pop .sess-list,
html body #chat-drawer.mode-page.rail-anim > #chat-sessions-pop .sess-empty,
html body #chat-drawer.mode-page.rail-anim > #chat-sessions-pop .sess-more-wrap {
  transition: opacity 220ms cubic-bezier(0.4, 0, 0.2, 1), visibility 0s;
}
html body #chat-drawer.mode-page.rail-collapsed > #chat-sessions-pop .sess-head {
  gap: 0;
}
html body #chat-drawer.mode-page.rail-collapsed > #chat-sessions-pop .sess-toolbar,
html body #chat-drawer.mode-page.rail-collapsed > #chat-sessions-pop .sess-list,
html body #chat-drawer.mode-page.rail-collapsed > #chat-sessions-pop .sess-empty,
html body #chat-drawer.mode-page.rail-collapsed > #chat-sessions-pop .sess-more-wrap {
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
}
html body #chat-drawer.mode-page.rail-anim.rail-collapsed > #chat-sessions-pop .sess-toolbar,
html body #chat-drawer.mode-page.rail-anim.rail-collapsed > #chat-sessions-pop .sess-list,
html body #chat-drawer.mode-page.rail-anim.rail-collapsed > #chat-sessions-pop .sess-empty,
html body #chat-drawer.mode-page.rail-anim.rail-collapsed > #chat-sessions-pop .sess-more-wrap,
html body #chat-drawer.mode-page.rail-anim.rail-collapsed > #chat-sessions-pop .sess-new {
  transition:
    opacity 220ms cubic-bezier(0.4, 0, 0.2, 1),
    max-width 320ms cubic-bezier(0.4, 0, 0.2, 1),
    padding 320ms cubic-bezier(0.4, 0, 0.2, 1),
    flex-grow 320ms cubic-bezier(0.4, 0, 0.2, 1),
    visibility 0s linear 220ms;
}
html body #chat-drawer.mode-page.rail-collapsed > #chat-sessions-pop .sess-new {
  flex-grow: 0;
  max-width: 0;
  padding-left: 0;
  padding-right: 0;
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
}
html body #chat-drawer.mode-page > #chat-sessions-pop .sess-toolbar {
  flex-direction: column !important;
  align-items: stretch !important;
  padding: 4px 10px 8px;
}
html body #chat-drawer.mode-page > #chat-sessions-pop .sess-search-wrap {
  width: 100%;
}
html body #chat-drawer.mode-page > #chat-sessions-pop .sess-list,
html body #chat-drawer.mode-page > #chat-sessions-pop .sess-empty,
html body #chat-drawer.mode-page > #chat-sessions-pop > .empty {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}
html body #chat-drawer.mode-page > .chat-panel-header {
  grid-column: 2;
  grid-row: 1;
}
html body #chat-drawer.mode-page > #chat-plan-bar {
  grid-column: 2;
  grid-row: 2;
  width: min(100%, var(--chat-page-col));
  justify-self: center;
}
html body #chat-drawer.mode-page > #chat-todos {
  grid-column: 2;
  grid-row: 3;
  width: min(100%, var(--chat-page-col));
  justify-self: center;
}
html body #chat-drawer.mode-page > #chat-log {
  grid-column: 2;
  grid-row: 4;
  display: flex !important;
  flex-direction: column !important;
  flex: unset !important;
  align-items: center;
  padding-left: 24px !important;
  padding-right: 24px !important;
  min-height: 0 !important;
  overflow-x: hidden !important;
  overflow-y: auto !important;
}
html body #chat-drawer.mode-page.is-empty-session > #chat-log,
html:not([data-ui="classic"]) body:is(body, #oc-arc):is(body, #oc-arc-2) #chat-drawer.mode-page.is-empty-session > #chat-log {
  flex: unset !important;
  min-height: 0 !important;
  overflow-y: auto !important;
}
html body #chat-drawer.mode-page > #chat-log > *,
html body #chat-drawer.mode-page .chat-empty-welcome,
html:not([data-ui="classic"]) body:is(body, #oc-arc):is(body, #oc-arc-2) #chat-drawer.mode-page .chat-empty-welcome {
  width: 100% !important;
  max-width: var(--chat-page-col) !important;
}
/* Welcome is a drawer sibling (not inside #chat-log), so it must be
   placed on the stage and sit with the composer, not auto-flow under
   the header. */
html body #chat-drawer.mode-page > .chat-empty-welcome,
html body #chat-drawer.mode-page.is-empty-session > .chat-empty-welcome,
html:not([data-ui="classic"]) body:is(body, #oc-arc):is(body, #oc-arc-2) #chat-drawer.mode-page.is-empty-session > .chat-empty-welcome {
  grid-column: 2;
  grid-row: 4;
  justify-self: center;
  align-self: end;
  width: 100% !important;
  max-width: var(--chat-page-col) !important;
  margin-top: 0 !important;
  margin-bottom: 8px;
  flex: none !important;
}
html body #chat-drawer.mode-page.is-empty-session > .chat-input-row {
  margin-bottom: 0 !important;
}
html body #chat-drawer.mode-page.is-empty-session > #chat-log,
html:not([data-ui="classic"]) body:is(body, #oc-arc):is(body, #oc-arc-2) #chat-drawer.mode-page.is-empty-session > #chat-log {
  visibility: hidden;
  pointer-events: none;
  background: transparent !important;
}
html body #chat-drawer.mode-page > .chat-empty-welcome {
  position: relative;
  z-index: 5;
}
html body #chat-drawer.mode-page > #chat-jump-bottom {
  grid-column: 2;
  grid-row: 4;
  justify-self: center;
  align-self: end;
  position: relative;
  left: auto;
  transform: none;
  bottom: 16px;
  margin-bottom: 8px;
}
html body #chat-drawer.mode-page > #chat-activity-bar {
  grid-column: 2;
  grid-row: 5;
  width: min(100%, var(--chat-page-col));
  justify-self: center;
}
html body #chat-drawer.mode-page > #chat-usage {
  grid-column: 2;
  grid-row: 6;
  width: min(100%, var(--chat-page-col));
  justify-self: center;
}
html body #chat-drawer.mode-page > .chat-input-row {
  grid-column: 2;
  grid-row: 7;
  display: flex !important;
  flex-direction: column !important;
  align-items: center;
  padding-left: 24px !important;
  padding-right: 24px !important;
}
html body #chat-drawer.mode-page > .chat-input-row .chat-input-wrap,
html body #chat-drawer.mode-page > .chat-input-row .ai-notice {
  width: 100% !important;
  max-width: var(--chat-page-col) !important;
  margin-left: auto;
  margin-right: auto;
}
html body #chat-drawer.mode-page > #chat-modal-root {
  grid-column: 1 / -1;
  grid-row: 1 / -1;
}
html body #chat-drawer.mode-page #chat-sessions {
  display: none;
}
html body #chat-drawer.mode-page #chat-page.is-active,
html body #chat-drawer.mode-page #chat-page[aria-pressed="true"] {
  color: var(--accent);
}
body:has(#chat-drawer.mode-page:not(.collapsed)) {
  overflow: hidden;
}

@media (max-width: 820px) {
  #chat-page { display: none !important; }
  html body #chat-drawer.content-right.mode-page {
    grid-template-columns: minmax(0, 1fr) !important;
  }
  html body #chat-drawer.mode-page > #chat-sessions-pop {
    display: none !important;
  }
  html body #chat-drawer.mode-page #chat-sessions {
    display: inline-flex;
  }
}
@media (prefers-reduced-motion: reduce) {
  html body #chat-drawer.content-right.mode-page.rail-anim,
  html body #chat-drawer.mode-page.rail-anim > #chat-sessions-pop .sess-head,
  html body #chat-drawer.mode-page.rail-anim > #chat-sessions-pop .sess-head .sess-new,
  html body #chat-drawer.mode-page.rail-anim > #chat-sessions-pop .sess-toolbar,
  html body #chat-drawer.mode-page.rail-anim > #chat-sessions-pop .sess-list,
  html body #chat-drawer.mode-page.rail-anim > #chat-sessions-pop .sess-empty,
  html body #chat-drawer.mode-page.rail-anim > #chat-sessions-pop .sess-more-wrap,
  html body #chat-drawer.mode-page.rail-anim > #chat-sessions-pop .sess-rail .oc-ico {
    transition: none !important;
  }
}

/* ---------- Mini mode (compact floating window) ---------- */
.content-right.mode-mini {
  position: fixed;
  top: auto;
  bottom: var(--chat-fy-bottom, 16px);
  right: var(--chat-fx, 16px);
  width: 380px;
  height: 480px;
  max-height: calc(100vh - 80px);
  max-height: calc(100dvh - 80px);
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--border-default);
  border-radius: var(--r-lg, 12px);
  box-shadow: 0 12px 36px rgba(0, 0, 0, 0.4);
  z-index: 9000;
}
/* In mini mode, hide secondary chrome; keep sessions/tier/layout/close. */
.content-right.mode-mini #chat-sessions,
.content-right.mode-mini .chat-model-wrap,
.content-right.mode-mini .chat-more-wrap,
.content-right.mode-mini .chat-chips {
  display: none;
}
.content-right.mode-mini .chat-panel-title { font-size: var(--fs-sm); }
.content-right.mode-mini .chat-layout-txt { display: none; }

/* ---------- Collapsed (× close-to-FAB) in float / mini modes ----------
 * sidebar.css uses `width: 0` to hide the drawer when collapsed, which
 * works for dock mode but is overridden by `.content-right.mode-float`
 * and `.content-right.mode-mini` (both set explicit width + position:fixed
 * later in the cascade). Without this override, clicking × in float/mini
 * shows the FAB but leaves the panel on screen. Force-hide the floating
 * panel when collapsed, regardless of mode. */
.content-right.collapsed.mode-float,
.content-right.collapsed.mode-mini {
  display: none !important;
}

/* ---------- Genie close animation (float / mini) ----------
 * When the user clicks × on a floating chat, JS adds `.closing` for
 * one animation frame, then `.collapsed` (which hides via display:none).
 * The animation collapses the panel toward its bottom-right corner —
 * roughly where the FAB sits — with a fade. macOS-style genie effect. */
@keyframes oceanus-chat-genie-out {
  0% {
    transform: scale(1) translate(0, 0);
    opacity: 1;
    filter: blur(0);
  }
  60% {
    transform: scale(0.45) translate(20%, 30%);
    opacity: 0.55;
    filter: blur(1px);
  }
  100% {
    transform: scale(0.05) translate(40%, 60%);
    opacity: 0;
    filter: blur(3px);
  }
}
.content-right.mode-float.closing,
.content-right.mode-mini.closing {
  transform-origin: 100% 100%;
  animation: oceanus-chat-genie-out 240ms cubic-bezier(0.55, 0.06, 0.68, 0.19) forwards;
  pointer-events: none;
  will-change: transform, opacity, filter;
}
.content-right.closing,
#chat-drawer.closing {
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .content-right.mode-float.closing,
  .content-right.mode-mini.closing {
    animation: none;
    opacity: 0;
    transition: opacity 120ms linear;
  }
}

/* ---------- Shade mode (header-only) ---------- */
/* Distinct from × close-to-FAB: drawer remains in flow / on screen, but
   everything below the header is collapsed so it acts as a slim title bar. */
.content-right.shaded > :not(.chat-panel-header):not(.chat-resizer) {
  display: none !important;
}
.content-right.shaded.mode-dock {
  /* Dock already pads by the top bar. A height of only --topbar-height
     leaves a 0 content box (overflow:hidden), so the header — the only
     control that can leave shade — is clipped. Keep one header-row. */
  height: calc(var(--oc-topbar-stack, var(--topbar-height)) + var(--topbar-height));
  max-height: calc(var(--oc-topbar-stack, var(--topbar-height)) + var(--topbar-height));
  min-height: 0;
}
.content-right.shaded.mode-float,
.content-right.shaded.mode-mini {
  height: auto;
}
/* shade active state handled via .chat-menu-item rules above */

/* ---------- Long-text containment (no page expansion) ---------- */
.chat-msg .body {
  overflow-wrap: anywhere;
  word-break: break-word;
  max-width: 100%;
}
.chat-msg .body pre,
.chat-msg .body code {
  max-width: 100%;
}
.chat-msg .body pre {
  overflow-x: auto;
  white-space: pre;
}
.chat-msg .body table {
  display: block;
  overflow-x: auto;
  max-width: 100%;
}
.chat-msg .body img { max-width: 100%; height: auto; }
/* Force the chat log to never push the page wider than the drawer */
.chat-log { min-width: 0; max-width: 100%; }

/* ---------- Scroll-edge fades (mask, not sticky overlays) ----------
 * Sticky ::before/::after used to paint over the header. A mask on the
 * log itself is clipped to the scrollport, so the top menu stays put.
 * Bottom fade is always on so the transcript melts into the composer
 * without a hairline. Top fade appears once the log is scrolled down. */
.chat-log {
  --log-fade-top: 0px;
  --log-fade-bot: 28px;
  /* One mask the size of the log. auto + repeat tiles the gradient
     (about every 150px in some engines), so a long answer fades out
     in the middle and the lower part of the reply is blank. White
     stays opaque in both alpha and luminance masks. */
  -webkit-mask-image: linear-gradient(
    to bottom,
    transparent 0,
    #fff var(--log-fade-top),
    #fff calc(100% - var(--log-fade-bot)),
    transparent 100%
  );
  mask-image: linear-gradient(
    to bottom,
    transparent 0,
    #fff var(--log-fade-top),
    #fff calc(100% - var(--log-fade-bot)),
    transparent 100%
  );
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-mode: alpha;
  mask-mode: alpha;
}
.chat-log.faded-top { --log-fade-top: 28px; }
.chat-log.faded-bottom { --log-fade-bot: 40px; }
.content-right.is-empty-session .chat-log {
  -webkit-mask-image: none;
  mask-image: none;
}
.chat-log::before,
.chat-log::after {
  content: none !important;
  display: none !important;
}
@media (prefers-reduced-motion: reduce) {
  .chat-log,
  .chat-log.faded-top,
  .chat-log.faded-bottom {
    -webkit-mask-image: none;
    mask-image: none;
  }
}

/* Research trace above an answer, in the Agent run's step list.
   Open while the turn works, then a borderless spring collapse. */
.chat-trace {
  --ar-fg: var(--text-primary, #e7e5e4);
  --ar-2: var(--text-secondary, #a8a29e);
  --ar-mute: var(--text-muted, #8b93a7);
  --ar-accent: var(--accent, #7fa6d6);
  --ar-ok: var(--arc-success, #2f9e6b);
  --ar-hover: color-mix(in oklab, var(--ar-fg) 5%, transparent);
  /* Same working ink as the Agent run: secondary text, a quiet green. */
  --ar-live: color-mix(in oklab, var(--ar-ok) 22%, var(--ar-2));
  --ar-live: oklch(from var(--ar-2) l 0.045 146);
  --ar-ease: var(--arc-ease-enter, cubic-bezier(.16, 1, .3, 1));
  --ar-std: var(--arc-ease, cubic-bezier(.22, 1, .36, 1));
  --ar-spring: var(--arc-spring-curve, cubic-bezier(.22, 1, .36, 1));
  --ar-smooth: var(--arc-dur-smooth, 580ms);
  margin: 2px 12px 10px 44px;
  color: var(--ar-2);
  font-size: calc(13px * var(--ui-font-scale, 1));
  font-weight: 400;
  line-height: 1.45;
  border: 0;
  background: transparent;
}
.chat-trace .chat-ar__collapse {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  border: 0;
  transition: grid-template-rows var(--ar-smooth) var(--ar-spring), opacity 100ms var(--ar-std);
}
.chat-trace .chat-ar__collapse[data-open] {
  grid-template-rows: 1fr;
  opacity: 1;
  transition: grid-template-rows var(--ar-smooth) var(--ar-spring), opacity 160ms var(--ar-ease);
}
.chat-trace .chat-ar__collapse-in { min-height: 0; min-width: 0; overflow: clip; }
.chat-trace .chat-ar__fold {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 32px;
  padding: 2px 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  box-shadow: none;
  appearance: none;
  color: var(--ar-2);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.chat-trace .chat-ar__fold-text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.chat-trace .chat-ar__fold-ico { color: var(--ar-accent); }
.chat-trace .chat-ar__chevron { flex: none; width: 16px; height: 16px; color: var(--ar-mute); transition: transform 240ms var(--ar-std); }
.chat-trace .chat-ar__fold[aria-expanded="true"] .chat-ar__chevron { transform: rotate(180deg); }
@media (hover: hover) and (pointer: fine) {
  .chat-trace .chat-ar__fold:hover { background: var(--ar-hover); }
}
.chat-trace .chat-ar__fold:focus-visible { outline: 1px solid var(--ar-accent); outline-offset: 2px; }
.chat-trace .chat-ar__steps {
  display: grid;
  list-style: none;
  margin: 0;
  padding: 0;
}
.chat-trace .chat-ar__step {
  display: grid;
  grid-template-rows: 1fr;
  opacity: 1;
  border: 0;
  transition: grid-template-rows var(--ar-smooth) var(--ar-spring), opacity 160ms var(--ar-ease);
}
.chat-trace .chat-ar__step.is-enter { grid-template-rows: 0fr; opacity: 0; }
.chat-trace .chat-ar__step-in { min-height: 0; overflow: clip; }
.chat-trace .chat-ar__step-head {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-height: 28px;
  padding: 4px 0;
  border: 0;
  background: transparent;
  color: var(--ar-fg);
}
.chat-trace .chat-ar__step.is-child .chat-ar__step-head { padding-left: 22px; }
.chat-trace .chat-ar__mark {
  flex: none;
  width: 16px;
  height: 16px;
  margin-top: 2px;
}
.chat-trace .chat-ar__mark[hidden],
.chat-trace .chat-ar__step-ico[hidden] { display: none !important; }
.chat-trace .chat-ar__mark .activity-site {
  display: block;
  width: 16px;
  height: 16px;
  margin: 0;
}
.chat-trace .chat-ar__sites {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  width: 100%;
  margin-top: 4px;
}
.chat-trace .chat-ar__sites[hidden] { display: none !important; }
.chat-trace .chat-ar__sites .activity-site {
  width: 14px;
  height: 14px;
  margin-left: 0;
}
.chat-trace .chat-ar__turn {
  margin: 8px 0 2px;
  padding: 0;
  color: var(--ar-mute);
  font-size: calc(12px * var(--ui-font-scale, 1));
  list-style: none;
}
.chat-trace .chat-ar__steps > .chat-ar__turn:first-child { margin-top: 0; }
.chat-trace .chat-ar__step[data-kind="agent"] .chat-ar__verb,
.chat-trace .chat-ar__step[data-kind="task"] .chat-ar__verb { color: var(--ar-fg); }
.chat-trace .chat-ar__icon { width: 16px; height: 16px; flex: none; }
.chat-trace .chat-ar__step-ico { margin-top: 2px; color: var(--ar-mute); }
.chat-trace .chat-ar__step[data-kind="search"] .chat-ar__step-ico,
.chat-trace .chat-ar__step[data-kind="page"] .chat-ar__step-ico,
.chat-trace .chat-ar__step[data-kind="news"] .chat-ar__step-ico { color: var(--ar-ok, #2f9e6b); }
.chat-trace .chat-ar__step[data-status="running"] .chat-ar__step-ico { color: var(--ar-accent); }
.chat-trace .chat-ar__icon.is-spin { animation: chat-ar-spin 1s linear infinite; transform-origin: 50% 50%; }
.chat-trace .chat-ar__label {
  flex: 1;
  min-width: 0;
  color: var(--ar-fg);
}
.chat-trace .chat-ar__verb { margin-right: .35em; font-weight: 500; }
.chat-trace .chat-ar__step[data-status="running"] .chat-ar__verb { color: var(--ar-live); }
.chat-trace .chat-ar__step[data-status="done"] .chat-ar__verb { color: var(--ar-2); font-weight: 400; }
.chat-trace .chat-ar__target { color: var(--ar-2); }
.chat-trace .chat-ar__target::before { content: "· "; color: var(--ar-mute); }
.chat-trace .chat-ar__time {
  flex: none;
  min-width: 4.5ch;
  margin-top: 1px;
  color: var(--ar-mute);
  font-size: calc(12px * var(--ui-font-scale, 1));
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.chat-trace .chat-ar__time.is-live { color: var(--ar-2); }
.chat-trace .chat-ar__state {
  display: inline-flex;
  flex: none;
  width: 14px;
  height: 14px;
  margin-top: 3px;
  color: var(--ar-ok);
}
.chat-trace .chat-ar__check { width: 14px; height: 14px; }
.chat-trace .chat-ar__check path { stroke-dasharray: 1; stroke-dashoffset: 0; }
.chat-trace .chat-ar__check.is-draw path { animation: chat-ar-draw 200ms var(--ar-ease) both; }
.chat-trace .chat-ar__shimmer {
  background-image: linear-gradient(90deg,
    color-mix(in oklab, var(--ar-live) 78%, transparent) 0%,
    color-mix(in oklab, var(--ar-live) 78%, transparent) 38%,
    var(--ar-live) 50%,
    color-mix(in oklab, var(--ar-live) 78%, transparent) 62%,
    color-mix(in oklab, var(--ar-live) 78%, transparent) 100%);
  background-size: 300% 100%;
  background-position: 100% 0;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: chat-ar-shimmer 2.4s linear infinite;
}
.chat-trace .chat-ar__brief {
  margin: 2px 0 6px;
  color: var(--ar-2);
  line-height: 1.5;
}
.chat-trace .chat-ar__sources {
  margin: 4px 0 2px;
  color: var(--ar-2);
  font-size: calc(12px * var(--ui-font-scale, 1));
}
@keyframes chat-ar-shimmer { 0% { background-position: 100% 0; } 75%, 100% { background-position: 0% 0; } }
@keyframes chat-ar-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes chat-ar-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .chat-trace .chat-ar__collapse,
  .chat-trace .chat-ar__step,
  .chat-trace .chat-ar__chevron,
  .chat-trace .chat-ar__icon.is-spin,
  .chat-trace .chat-ar__check.is-draw path,
  .chat-trace .chat-ar__shimmer {
    transition: none;
    animation: none;
  }
  .chat-trace .chat-ar__shimmer {
    background: none;
    color: inherit;
  }
  html body #chat-drawer.mode-page > #chat-log > .chat-trace.is-rail.is-settled:not(.is-open) .chat-ar__fold:active,
  html body #chat-drawer.mode-page > .chat-run-rail.is-on .chat-trace.is-settled:not(.is-open) .chat-ar__fold:active {
    transform: none;
  }
}

/* Full page, wide enough for a gutter: the latest Agent run sits in the
   blank left of the centered column. When the answer finishes it is a
   32px icon. Older runs stay folded in the thread. Float and dock keep
   the in-log fold. */
@media (min-width: 1280px) {
  html body #chat-drawer.mode-page > #chat-log > .chat-trace.is-rail {
    position: fixed;
    z-index: 4;
    left: calc(var(--chat-page-rail, 272px) + 12px);
    top: calc(var(--topbar-height, 49px) + 12px);
    bottom: 16px;
    width: max(96px, min(260px, calc((100vw - var(--chat-page-rail, 272px) - min(var(--chat-page-col, 48rem), 100vw - var(--chat-page-rail, 272px))) / 2 - 24px))) !important;
    max-width: none !important;
    margin: 0 !important;
    padding: 0 2px;
    overflow: auto;
    background: transparent;
    box-sizing: border-box;
  }
  html body #chat-drawer.mode-page > #chat-log > .chat-trace.is-rail .chat-ar__label,
  html body #chat-drawer.mode-page > #chat-log > .chat-trace.is-rail .chat-ar__target {
    white-space: normal;
    overflow-wrap: anywhere;
  }
  html body #chat-drawer.mode-page > #chat-log > .chat-trace.is-rail.is-settled:not(.is-open) {
    bottom: auto;
    width: 32px !important;
    height: 32px;
    padding: 0;
    overflow: visible;
    border: 1px solid var(--border-default);
    border-radius: var(--r-md, 8px);
    background: var(--bg-elevated);
  }
  html body #chat-drawer.mode-page > #chat-log > .chat-trace.is-rail.is-settled:not(.is-open) .chat-ar__list,
  html body #chat-drawer.mode-page > #chat-log > .chat-trace.is-rail.is-settled:not(.is-open) .chat-ar__fold-text,
  html body #chat-drawer.mode-page > #chat-log > .chat-trace.is-rail.is-settled:not(.is-open) .chat-ar__chevron {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
  html body #chat-drawer.mode-page > #chat-log > .chat-trace.is-rail.is-settled:not(.is-open) .chat-ar__fold {
    width: 32px;
    height: 32px;
    min-height: 32px;
    padding: 0;
    justify-content: center;
    gap: 0;
  }
  html body #chat-drawer.mode-page > #chat-log > .chat-trace.is-rail.is-settled:not(.is-open) .chat-ar__fold:active {
    transform: scale(0.98);
  }
}

/* Full page: every turn's Agent run stacks in the left gutter. A live
   turn stays open inside a short section of the page. A finished turn
   is a 32px icon until it is opened. The section scrolls without a bar. */
.chat-run-rail { display: none; }
@media (min-width: 1280px) {
  html body #chat-drawer.mode-page > .chat-run-rail.is-on {
    display: block;
    position: fixed;
    z-index: 4;
    left: calc(var(--chat-page-rail, 272px) + 12px);
    top: calc(var(--topbar-height, 49px) + 12px);
    bottom: auto;
    width: max(96px, min(260px, calc((100vw - var(--chat-page-rail, 272px) - min(var(--chat-page-col, 48rem), 100vw - var(--chat-page-rail, 272px))) / 2 - 24px))) !important;
    height: auto;
    max-height: min(32rem, 46vh);
    max-width: none !important;
    margin: 0;
    padding: 0 2px 12px;
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: none;
    background: transparent;
    box-sizing: border-box;
  }
  html body #chat-drawer.mode-page > .chat-run-rail.is-on::-webkit-scrollbar {
    width: 0;
    height: 0;
    display: none;
  }
  html body #chat-drawer.mode-page > .chat-run-rail.is-on .chat-trace {
    position: static;
    width: auto !important;
    max-width: none !important;
    margin: 0 0 16px !important;
  }
  html body #chat-drawer.mode-page > .chat-run-rail.is-on .chat-trace.is-settled:not(.is-open) {
    width: 32px !important;
    height: 32px;
    max-height: 32px;
    margin: 0 0 8px !important;
    padding: 0;
    overflow: hidden;
    border: 1px solid var(--border-default);
    border-radius: var(--r-md, 8px);
    background: var(--bg-elevated);
  }
  html body #chat-drawer.mode-page > .chat-run-rail.is-on .chat-trace.is-settled:not(.is-open) .chat-ar__list,
  html body #chat-drawer.mode-page > .chat-run-rail.is-on .chat-trace.is-settled:not(.is-open) .chat-ar__fold-text,
  html body #chat-drawer.mode-page > .chat-run-rail.is-on .chat-trace.is-settled:not(.is-open) .chat-ar__chevron {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
  html body #chat-drawer.mode-page > .chat-run-rail.is-on .chat-trace.is-settled:not(.is-open) .chat-ar__fold {
    width: 32px;
    height: 32px;
    min-height: 32px;
    padding: 0;
    justify-content: center;
    gap: 0;
  }
  html body #chat-drawer.mode-page > .chat-run-rail.is-on .chat-trace.is-settled:not(.is-open) .chat-ar__fold:active {
    transform: scale(0.98);
  }
  html body #chat-drawer.mode-page > .chat-run-rail.is-on .chat-ar__label,
  html body #chat-drawer.mode-page > .chat-run-rail.is-on .chat-ar__target {
    white-space: normal;
    overflow-wrap: break-word;
  }
}

/* Full page: 3–5 points from the finished answer sit just to the right
   of the reading column, not against the screen edge. Hidden until the
   answer is done, and hidden in the float, the dock, and a narrow page. */
.chat-highlights { display: none; }
@media (min-width: 1280px) {
  html body #chat-drawer.mode-page > #chat-log > .chat-highlights.is-on {
    --hi-after: calc(var(--chat-page-rail, 272px) + (100vw - var(--chat-page-rail, 272px) + min(var(--chat-page-col, 48rem), 100vw - var(--chat-page-rail, 272px))) / 2 + 16px);
    display: block;
    position: fixed;
    z-index: 4;
    left: var(--hi-after);
    right: auto;
    top: calc(var(--topbar-height, 49px) + 12px);
    bottom: auto;
    max-height: calc(100vh - var(--topbar-height, 49px) - 96px);
    width: min(260px, calc(100vw - var(--hi-after) - 16px)) !important;
    max-width: none !important;
    margin: 0 !important;
    padding: 0;
    overflow: auto;
    background: transparent;
    box-sizing: border-box;
    color: var(--text-secondary);
    font-size: calc(13px * var(--ui-font-scale, 1));
    font-weight: 400;
    line-height: 1.4;
  }
  html body #chat-drawer.mode-page > #chat-log > .chat-highlights.is-on .chat-highlights-label {
    margin: 0 0 8px;
    color: var(--text-muted);
    font-size: var(--fs-xs, 12px);
    font-weight: 400;
    line-height: 1.4;
  }
  html body #chat-drawer.mode-page > #chat-log > .chat-highlights.is-on ul {
    margin: 0;
    padding: 0 0 0 1.05em;
  }
  html body #chat-drawer.mode-page > #chat-log > .chat-highlights.is-on li {
    margin: 0 0 8px;
    padding: 0;
    color: var(--text-secondary);
  }
  html body #chat-drawer.mode-page > #chat-log > .chat-highlights.is-on li::marker {
    color: var(--text-muted);
  }
  html body #chat-drawer.mode-page > #chat-log > .chat-highlights.is-on a.chat-highlights-link {
    color: inherit;
    text-decoration: none;
    cursor: pointer;
  }
  html body #chat-drawer.mode-page > #chat-log > .chat-highlights.is-on a.chat-highlights-link:hover,
  html body #chat-drawer.mode-page > #chat-log > .chat-highlights.is-on a.chat-highlights-link.is-current {
    color: var(--text-primary);
    text-decoration: none;
  }
  html body #chat-drawer.mode-page > #chat-log > .chat-highlights.is-on a.chat-highlights-link:active {
    opacity: 0.72;
  }
  html body #chat-drawer.mode-page > #chat-log > .chat-highlights.is-on a.chat-highlights-link:focus-visible {
    outline: 1px solid var(--accent);
    outline-offset: 2px;
    border-radius: 2px;
  }
}
#chat-log :is(p, li, h1, h2, h3, h4, blockquote).is-hi-mark {
  background: color-mix(in srgb, var(--text-primary) 7%, transparent);
  border-radius: 4px;
}
#chat-log :is(p, li, h1, h2, h3, h4, blockquote).is-hi-mark:focus {
  outline: none;
}
#chat-log :is(p, li, h1, h2, h3, h4, blockquote).is-hi-mark:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  html body #chat-drawer.mode-page > #chat-log > .chat-highlights.is-on a.chat-highlights-link:active {
    opacity: 1;
  }
}

/* ---------- Collapsed process blocks (tool_call / tool_response in prose) ---------- */
.chat-process {
  margin: 6px 0;
  border: 1px solid var(--border-muted, rgba(110,118,129,.25));
  border-radius: var(--r-sm, 4px);
  background: color-mix(in srgb, var(--bg-base, #0d1117) 92%, transparent);
  font-size: var(--fs-xs, 11px);
  color: var(--text-muted, #656d76);
  overflow: hidden;
}
.chat-process summary {
  padding: 4px 10px;
  cursor: pointer;
  font-family: var(--font-mono, monospace);
  font-size: 10px;
  letter-spacing: 0.02em;
  color: var(--text-secondary, #8b949e);
  user-select: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  list-style: none;             /* hide default marker */
}
.chat-process summary::before {
  content: "▸ ";
  font-size: 9px;
  opacity: .7;
}
.chat-process[open] summary::before { content: "▾ "; }
.chat-process summary:hover {
  color: var(--text-primary);
  background: color-mix(in srgb, var(--accent, #58a6ff) 8%, transparent);
}
.chat-process .proc-pre {
  margin: 0;
  padding: 6px 10px 8px;
  font-size: 10px;
  line-height: 1.4;
  max-height: 200px;
  overflow: auto;
  background: color-mix(in srgb, var(--bg-base, #0d1117) 80%, transparent);
  border-top: 1px solid var(--border-muted, rgba(110,118,129,.18));
  white-space: pre-wrap;
  word-break: break-all;
  color: var(--text-secondary, #8b949e);
}

/* ---------- Activity bar (sticky above input) ---------- */
.chat-activity-bar {
  flex-shrink: 0;
  display: none;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  background: var(--bg-elevated);
  border-top: none;
  border-bottom: none;
  font-family: var(--font-sans);
  font-size: 12px;
  line-height: 1.4;
  color: var(--text-muted);
  opacity: 0;
  transition: opacity var(--dur-ui) var(--ease-out);
  position: relative;
  overflow: hidden;
}
.chat-activity-bar::before {
  display: none;
}
.chat-activity-bar.active::before {
  animation: none;
}
@keyframes chat-act-shimmer {
  0%   { background-position:  200% 0; }
  100% { background-position: -200% 0; }
}
.chat-activity-bar > * { position: relative; z-index: 1; }
.chat-activity-bar.active {
  display: flex;
  opacity: 1;
}
/* Subtle fade gradient above the bar, mask-image on the bottom of chat-log. */
.chat-activity-bar.active ~ .chat-log,
.chat-log:has(~ .chat-activity-bar.active) {
  /* fallback: handled by JS adding class to chat-log */
}
.chat-log.has-activity {
  --log-fade-bot: 40px;
}

/* Fade out when done */
.chat-activity-bar.done {
  opacity: .3;
  transition: opacity 1.2s ease 0.4s;
}
.chat-activity-bar.done:hover { opacity: .65; }

/* Spinner — tri-color conic-gradient ring sweeping through the iridescent
   palette (#6c8cff → #b07cff → #5dd1ff). Ported from the ticker-page
   copilot so the main chat's "AI is working" state matches the rest of
   the AI surfaces. The radial mask carves out the centre so it reads as
   a ring, not a disc. */
.chat-activity-bar.has-sites .activity-spin { display: none; }
.chat-activity-bar .activity-spin {
  display: inline-block;
  width: 12px; height: 12px;
  border-radius: 50%;
  border: 1.5px solid var(--border-default);
  border-top-color: var(--text-muted);
  background: none;
  mask: none;
  -webkit-mask: none;
  animation: chat-act-spin 0.8s linear infinite;
  flex-shrink: 0;
}
@keyframes chat-act-spin { to { transform: rotate(360deg); } }

/* "Done" state: stop the spinner, drop in a check icon so the user
   has a clear "finished" signal instead of a frozen ring. */
.chat-activity-bar.done .activity-spin {
  animation: none;
  background: #3aa763;
  mask: none;
  -webkit-mask: none;
  position: relative;
}
.chat-activity-bar.done .activity-spin::after {
  content: "✓";
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 10px; color: #fff; font-weight: 700;
}

/* Label + count — iridescent gradient text while active, drops to muted
   grey when the bar enters the .done state. */
.chat-activity-bar .activity-label {
  font-family: var(--font-sans, system-ui, -apple-system, sans-serif);
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
  letter-spacing: 0.005em;
  display: inline-flex;
  align-items: baseline;
  background: none;
  color: var(--text-muted);
  -webkit-text-fill-color: var(--text-muted);
  flex: 1;
  min-width: 0;
  overflow: hidden;
}
.chat-activity-bar.done .activity-label {
  background: none;
  color: var(--text-muted);
  -webkit-text-fill-color: var(--text-muted);
}
.chat-activity-bar .activity-label .activity-text {
  display: inline-block;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
/* Animated "…" — three dots that fade in/out sequentially. Has its own
   fill color so it stays visible even though the parent .activity-label
   uses `background-clip:text` + transparent fill for the iridescent
   gradient effect. */
.chat-activity-bar .activity-label .activity-dots {
  display: inline-block;
  width: 1.1em;
  text-align: left;
  margin-left: 2px;
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
  -webkit-text-fill-color: var(--text-secondary);
  background: none;
}
.chat-activity-bar.active .activity-label .activity-dots::after {
  content: "";
  display: inline-block;
  animation: activity-dots 1.4s steps(1, end) infinite;
}
@keyframes activity-dots {
  0%   { content: ""; }
  25%  { content: "."; }
  50%  { content: ".."; }
  75%  { content: "..."; }
  100% { content: ""; }
}
/* Done state: no animated dots, just steady "Done". */
.chat-activity-bar.done .activity-label .activity-dots::after { content: ""; }

.chat-activity-bar .activity-count {
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  opacity: .55;
  white-space: nowrap;
}

/* Latest tool meta (timing/denied) — small, muted, right-aligned-ish. */
.chat-activity-bar .activity-latest {
  flex: 0 1 auto;
  max-width: 34%;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-muted, #656d76);
  font-size: 10px;
  font-family: var(--font-mono);
  opacity: 0.75;
}

/* Site marks that flip in while a web search is open. */
.activity-sites {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  height: 18px;
  perspective: 140px;
}
.activity-sites[hidden] { display: none !important; }
.activity-site {
  width: 16px;
  height: 16px;
  border-radius: 3px;
  margin-left: -5px;
  border: 1px solid var(--border-muted);
  background: var(--bg-elevated-2);
  object-fit: cover;
  flex-shrink: 0;
  box-sizing: border-box;
  opacity: 0;
  transform: rotateY(88deg) scale(0.72);
  animation: activity-site-flip 170ms cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
  backface-visibility: hidden;
}
.activity-site:first-child { margin-left: 0; }
/* One site, drawn in the sentence immediately left of the host. */
.activity-label .activity-site {
  width: 14px;
  height: 14px;
  margin-left: 0;
  margin-right: 4px;
  vertical-align: -2px;
  display: inline-block;
}
.activity-label .activity-site--letter {
  display: inline-flex;
  vertical-align: -2px;
}
.activity-site--letter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans, Inter, sans-serif);
  font-size: 9px;
  font-weight: 600;
  line-height: 1;
  color: var(--text-secondary);
}
@keyframes activity-site-flip {
  0%   { opacity: 0; transform: rotateY(88deg) scale(0.72); }
  45%  { opacity: 1; transform: rotateY(-16deg) scale(1.04); }
  100% { opacity: 1; transform: rotateY(0deg) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .activity-site {
    animation: none;
    opacity: 1;
    transform: none;
  }
}

/* ---- Stop button: round, Claude/ChatGPT style ---- */
.chat-activity-bar .activity-stop {
  appearance: none;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1.5px solid var(--border-default, #30363d);
  background: var(--bg-elevated-2, #161b22);
  color: var(--text-secondary, #8b949e);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  padding: 0;
  transition: background 150ms ease, border-color 150ms ease, color 150ms ease,
              transform 100ms ease;
}
.chat-activity-bar .activity-stop:hover {
  background: var(--danger, #f85149);
  border-color: var(--danger, #f85149);
  color: #fff;
  transform: scale(1.08);
}
.chat-activity-bar .activity-stop:active {
  transform: scale(0.95);
}
.chat-activity-bar .activity-stop svg {
  width: 12px;
  height: 12px;
  fill: currentColor;
}

/* Fade-in keyframe (used by JS when first shown) */
@keyframes activity-fadein {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.chat-activity-bar.entering {
  animation: activity-fadein 300ms ease forwards;
}

/* Legacy .chat-tool blocks (used by renderTranscript for replay) — keep
   them compact so old transcripts don't look out of place. */
.chat-tool { max-width: 100%; overflow: hidden; }

/* ··· tools toggle + tray-close: desktop hides them (inline actions). */
.chat-actions-toggle,
.chat-actions-close {
  display: none;
  flex-shrink: 0;
}

/* ---------- Mobile (phones / narrow tablets) — layout shell only.
   Sliding tools tray CSS lives in responsive.css next to the main
   top-bar tools tray so both share the same touch media query & style. */
@media (max-width: 768px) {
  .chat-drawer { width: 100vw; }
  .chat-fab,
  .chat-toggle-fab { bottom: var(--sp-3); right: var(--sp-3); }
  .chat-model-pop { min-width: 180px; }
  .chat-resizer { display: none; }
  .content-right.mode-float,
  .content-right.mode-mini {
    top: auto; bottom: 0; right: 0; left: 0;
    width: 100vw; height: 70vh;
    border-radius: 0;
  }
  .chat-layout-wrap,
  .chat-drag-grip { display: none !important; }

  .chat-panel-header {
    flex-wrap: nowrap;
    height: 48px;
    min-height: 48px;
    max-height: 48px;
    padding: 0 8px 0 12px;
    gap: 8px;
    align-items: center;
    position: relative;
    overflow: visible;
  }
  .chat-panel-title {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 15px;
    font-weight: 600;
  }
  .chat-panel-header > #chat-close {
    flex-shrink: 0;
  }

  /* ── Model / Tier / Sessions pickers on mobile ───────────────────────
     JS portals #chat-model-pop / #chat-tier-pop (and sessions) to
     document.body while open. Nested under the ··· overflow strip they
     were clipped by a 40px flex wrap + transform animation, so the list
     never painted. Once on <body> they are real bottom sheets. */
  body.chat-sheet-open {
    overflow: hidden !important;
  }
  /* Only the JS class — :has(.open) left a stuck dimmer on iOS when the
     drawer closed while a portaled pop still had .open. */
  body.chat-sheet-open::before {
    content: "";
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    /* Must beat open chat (27000) + ··· tools tray (30000). */
    z-index: 30500;
    pointer-events: auto;
    animation: chatBackdropIn 180ms ease-out;
  }
  @keyframes chatBackdropIn {
    from { opacity: 0; }
    to   { opacity: 1; }
  }
  /* Portaled or in-tree: always a full-viewport bottom sheet on mobile. */
  body > .chat-model-pop.open,
  body > .chat-tier-pop.open,
  body > .chat-sessions-pop.open,
  .chat-model-pop.open,
  .chat-tier-pop.open,
  .chat-sessions-pop.open {
    position: fixed !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    top: auto !important;
    width: 100vw !important;
    max-width: 100vw !important;
    min-width: 0 !important;
    height: auto !important;
    max-height: min(72dvh, 560px) !important;
    border-radius: 16px 16px 0 0 !important;
    border: 1px solid var(--border-default) !important;
    border-bottom: none !important;
    box-shadow: 0 -12px 40px rgba(0, 0, 0, 0.4) !important;
    background: var(--bg-elevated) !important;
    color: var(--text-primary) !important;
    opacity: 1 !important;
    filter: none !important;
    -webkit-filter: none !important;
    z-index: 31000 !important;
    overflow: hidden !important;
    padding: 0 0 calc(10px + env(safe-area-inset-bottom, 0)) 0 !important;
    margin: 0 !important;
    list-style: none !important;
    display: flex !important;
    flex-direction: column !important;
    visibility: visible !important;
    pointer-events: auto !important;
    /* No transform:none — that would freeze the sheet at the animation
       start (translateY(100%)) and hide every choice off-screen. */
    animation: chatSheetUp var(--dur-sheet, 440ms) var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)) both;
  }
  @keyframes chatSheetUp {
    from { transform: translateY(110%); }
    to   { transform: translateY(0); }
  }
  @keyframes chatSheetDown {
    from { transform: translateY(0); }
    to   { transform: translateY(110%); }
  }
  body > .chat-model-pop.open.is-leaving,
  body > .chat-tier-pop.open.is-leaving,
  body > .chat-sessions-pop.open.is-leaving,
  .chat-model-pop.open.is-leaving,
  .chat-tier-pop.open.is-leaving,
  .chat-sessions-pop.open.is-leaving {
    animation: chatSheetDown var(--dur-sheet, 440ms) var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)) both !important;
    pointer-events: none !important;
  }
  body.chat-sheet-open::before {
    animation: chatBackdropIn var(--dur-ui, 280ms) var(--ease-out, ease);
  }
  body > .chat-model-pop.open::before,
  body > .chat-tier-pop.open::before,
  body > .chat-sessions-pop.open::before,
  .chat-model-pop.open::before,
  .chat-tier-pop.open::before,
  .chat-sessions-pop.open::before {
    content: "";
    display: block;
    width: 40px;
    height: 4px;
    background: var(--border-default);
    border-radius: 999px;
    margin: 10px auto 12px auto;
    flex-shrink: 0;
  }
  /* Choice rows — full contrast, tappable */
  .chat-model-pop.open li,
  .chat-tier-pop.open li {
    display: flex !important;
    flex-direction: column;
    justify-content: center;
    min-height: 52px;
    padding: 12px 18px !important;
    color: var(--text-primary) !important;
    opacity: 1 !important;
    visibility: visible !important;
    background: transparent;
    border-bottom: 1px solid var(--border-soft, var(--border-default));
    pointer-events: auto !important;
  }
  .chat-model-pop.open li.grp {
    min-height: 0;
    padding: 10px 18px 4px !important;
    font-size: 11px !important;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted) !important;
    border-bottom: none;
    pointer-events: none;
  }
  .chat-model-pop.open li.mdl,
  .chat-tier-pop.open li.mdl {
    cursor: pointer;
  }
  .chat-model-pop.open li.mdl:active,
  .chat-tier-pop.open li.mdl:active {
    background: var(--bg-elevated-2, var(--bg-base));
  }
  .chat-model-pop.open li.mdl .m-label,
  .chat-tier-pop.open li.mdl .m-label {
    display: block !important;
    font-size: 16px !important;
    font-weight: 600;
    color: var(--text-primary) !important;
    opacity: 1 !important;
  }
  .chat-model-pop.open li.mdl .m-id,
  .chat-tier-pop.open li.mdl .m-id {
    display: block !important;
    font-size: 12px !important;
    color: var(--text-muted) !important;
    opacity: 1 !important;
  }
  .chat-model-pop.open li.mdl.active,
  .chat-tier-pop.open li.mdl.active {
    background: color-mix(in srgb, var(--text-primary) 10%, transparent);
    border-left: 0;
    box-shadow: none;
  }
  .chat-model-pop.open li.mdl.active .m-label,
  .chat-tier-pop.open li.mdl.active .m-label {
    color: var(--text-primary) !important;
  }
  .chat-model-pop.open li.mdl-foot,
  .chat-tier-pop.open li.mdl-foot {
    min-height: 0;
    font-size: 12px !important;
    color: var(--text-muted) !important;
    border-bottom: none;
    background: var(--bg-elevated) !important;
  }
  .chat-model-pop.open li.empty,
  .chat-tier-pop.open li.empty {
    color: var(--text-muted) !important;
    font-style: italic;
  }
  .chat-sessions-pop.open,
  .chat-sessions-pop.open .sess-chrome,
  .chat-sessions-pop.open .sess-head,
  .chat-sessions-pop.open .sess-foot {
    background: var(--bg-elevated) !important;
    color: var(--text-primary);
    opacity: 1;
  }
  .chat-sessions-pop.open li {
    color: var(--text-primary);
    opacity: 1;
  }

  /* Sessions mobile: chrome fixed, list scrolls, long help hidden */
  body > .chat-model-pop.open,
  body > .chat-tier-pop.open,
  .chat-model-pop.open,
  .chat-tier-pop.open {
    display: block !important;
    overflow-x: hidden !important;
    overflow-y: scroll !important;
    -webkit-overflow-scrolling: touch !important;
    overscroll-behavior: contain !important;
    touch-action: pan-y !important;
    max-height: min(70dvh, 560px) !important;
    animation: none !important;
    transform: none !important;
  }
  .chat-sessions-pop.open .sess-chrome {
    flex: 0 0 auto !important;
    position: relative !important;
    top: auto !important;
  }
  .chat-sessions-pop.open .sess-rail {
    display: none !important;
  }
  .chat-sessions-pop.open .sess-toolbar {
    flex: 0 0 auto !important;
  }
  .chat-sessions-pop.open .sess-list {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }
  .chat-sessions-pop.open .sess-more-wrap {
    flex: 0 0 auto !important;
  }
  .chat-sessions-pop.open .sess-foot {
    display: none !important;
  }
  .chat-sessions-pop.open .sess-nav,
  .chat-sessions-pop.open .sess-nav-btn,
  .chat-sessions-pop.open .sess-nav-pos {
    display: none !important;
  }
  .chat-sessions-pop.open .sess-search {
    min-height: 40px !important;
    font-size: 16px !important;
  }
  .chat-sessions-pop.open .s-label {
    display: block !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    white-space: nowrap !important;
    font-weight: 500 !important;
    font-size: 15px !important;
    line-height: 1.25 !important;
  }
  .chat-sessions-pop.open li.sess {
    display: flex !important;
    align-items: center !important;
    min-height: 52px !important;
    padding: 10px 12px !important;
    gap: 8px !important;
  }
  .chat-sessions-pop.open .s-trail {
    position: static !important;
    transform: none !important;
    opacity: 1 !important;
    pointer-events: auto !important;
    background: none !important;
    padding-left: 8px !important;
  }
  .chat-sessions-pop.open .s-del {
    opacity: 1 !important;
    min-width: 40px !important;
    min-height: 40px !important;
    width: 40px !important;
    height: 40px !important;
    flex: 0 0 auto !important;
  }
  .chat-model-pop.open li.mdl .m-label,
  .chat-tier-pop.open li.mdl .m-label,
  .chat-model-pop.open li.mdl .m-id,
  .chat-tier-pop.open li.mdl .m-id {
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    white-space: nowrap !important;
  }
  .chat-model-pop.open li.mdl-foot,
  .chat-tier-pop.open li.mdl-foot {
    max-height: 4.2em !important;
    overflow: hidden !important;
  }

  /* Hide power-user chrome that steals vertical space on phones */
  #chat-usage,
  .chat-usage { display: none !important; }
  .chat-fmt-toggle,
  .chat-toolbar,
  #chat-toolbar { display: none !important; }
  .chat-status-bar:empty { display: none !important; }
  .chat-status-bar {
    padding: 0;
    font-size: 10px;
    min-height: 0;
    max-width: min(42vw, 160px);
  }

  /* ── Composer — single shell with in-box tools + send ────────────────
     [ type a message…          ]
     [ 📎 🎤 🖼 …          ➤  ]
     Single-line floor (~1.5 lh). Grows only as the user types. */
  .chat-input-row {
    flex-wrap: nowrap;
    flex-direction: row;
    align-items: stretch;
    gap: 0;
    padding: 6px 10px;
    padding-bottom: calc(6px + env(safe-area-inset-bottom, 0));
    position: relative;
    border-top: none;
    background: transparent;
  }
  .chat-input-wrap {
    flex: 1 1 auto;
    min-width: 0;
    border-radius: 16px;
  }
  .chat-textarea-container {
    align-items: flex-start;
    min-height: 0;
  }
  #chat-input {
    /* 16px prevents iOS zoom-on-focus; 1.5× line-height floor */
    --chat-input-fs: 16px;
    --chat-input-lh: 1.4;
    min-height: calc(16px * 1.4 * 1.5 + 6px) !important;
    max-height: 140px;
    padding: 10px 12px 4px !important;
    font-size: 16px !important;
    line-height: 1.4 !important;
  }
  .chat-attachments-row:not(:empty) {
    padding: 2px 10px 4px;
  }
  .chat-composer-bar {
    padding: 2px 6px 6px 6px;
    min-height: 36px;
    border: none;
    border-top: none;
    background: transparent;
  }
  .chat-composer-bar .chat-action-buttons .chat-action-btn,
  .chat-input-wrap .chat-action-buttons .chat-action-btn {
    width: 34px;
    height: 34px;
  }
  .chat-composer-bar > button#chat-send,
  .chat-input-wrap #chat-send,
  #chat-send {
    width: 34px !important;
    height: 34px !important;
    min-width: 34px !important;
    min-height: 34px !important;
    max-width: 34px !important;
    max-height: 34px !important;
    border-radius: 50% !important;
    padding: 0 !important;
  }
  #chat-send .send-label { display: none; }
  #chat-send .send-ico   { display: inline-flex; }
  #chat-send .send-ico svg { width: 15px; height: 15px; }

  /* Empty-session: keep side padding modest on phones */
  .content-right.is-empty-session .chat-input-row {
    padding-left: 10px;
    padding-right: 10px;
  }
  .content-right.is-empty-session .chat-input-wrap {
    border-radius: var(--r-md);
  }
}

/* Legacy "+" attach toggle — removed; tools live in .chat-composer-bar. */
.chat-attach-toggle { display: none !important; }


/* =================================================================
 * Custom tooltip — JS-positioned floating card.
 * Triggered by [data-tip] on any element. Optional [data-tip-title]
 * adds a bold title row. Optional [data-tip-kbd] adds a keyboard chip.
 * Positioned via JS into <body> so it never gets clipped.
 * ================================================================= */
.oc-tip {
  position: fixed;
  z-index: 100000;
  max-width: 240px;
  min-width: 100px;
  padding: 5px 9px 6px 9px;
  background: var(--bg-elevated);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  color: var(--text-primary);
  border: 1px solid var(--border-default);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  font-family: var(--font-sans, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif);
  font-size: 11px;
  line-height: 1.4;
  letter-spacing: 0.01em;
  pointer-events: none;
  opacity: 0;
  transform: translateY(-1px);
  transition: opacity 110ms ease-out, transform 110ms ease-out;
  white-space: normal;
  word-wrap: break-word;
}
.oc-tip.visible {
  opacity: 1;
  transform: translateY(0);
}
.oc-tip-title {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 1px;
  font-size: 11px;
  font-weight: 700;
  color: var(--text-primary);
  letter-spacing: 0.015em;
}
.oc-tip-kbd {
  margin-left: auto;
  padding: 0 5px;
  background: rgba(0, 0, 0, 0.06);
  border: 1px solid rgba(0, 0, 0, 0.10);
  border-radius: 3px;
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Consolas, monospace);
  font-size: 9px;
  color: #2a3142;
}
.oc-tip-body {
  color: var(--text-secondary);
  font-weight: 500;
}
.oc-tip-body code {
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Consolas, monospace);
  font-size: 10px;
  padding: 0 4px;
  background: rgba(0, 0, 0, 0.06);
  border: 1px solid rgba(0, 0, 0, 0.10);
  border-radius: 3px;
  color: #7a4b00;
}
.oc-tip-arrow {
  position: absolute;
  width: 8px;
  height: 8px;
  background: rgba(255, 255, 255, 0.72);
  -webkit-backdrop-filter: blur(18px) saturate(180%);
  backdrop-filter: blur(18px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.55);
  transform: rotate(45deg);
  pointer-events: none;
}
.oc-tip[data-side="bottom"] .oc-tip-arrow {
  top: -5px;
  border-right: none;
  border-bottom: none;
}
.oc-tip[data-side="top"] .oc-tip-arrow {
  bottom: -5px;
  border-left: none;
  border-top: none;
}
/* Fallback for browsers without backdrop-filter — bump opacity so text reads. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .oc-tip { background: rgba(255, 255, 255, 0.95); }
  .oc-tip-arrow { background: rgba(255, 255, 255, 0.95); }
}
@media (prefers-reduced-motion: reduce) {
  .oc-tip { transition: opacity 0ms; transform: none; }
  .oc-tip.visible { transform: none; }
}

/* Dark + blue steel: bright title/body. Light keeps the default tokens. */
html:not([data-theme="light"]) .oc-tip {
  background: var(--bg-elevated);
  -webkit-backdrop-filter: none;
          backdrop-filter: none;
  color: var(--text-primary);
  border: 1px solid var(--border-default);
  box-shadow: var(--shadow-sm);
}
html:not([data-theme="light"]) .oc-tip-title { color: #ffffff; }
html:not([data-theme="light"]) .oc-tip-body  { color: var(--text-primary); }
html:not([data-theme="light"]) .oc-tip-kbd {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.12);
  color: var(--text-primary);
}
html:not([data-theme="light"]) .oc-tip-body code {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border-color: color-mix(in srgb, var(--accent) 28%, transparent);
  color: var(--text-primary);
}
html:not([data-theme="light"]) .oc-tip-arrow {
  background: var(--bg-elevated);
  border-color: var(--border-default);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  html:not([data-theme="light"]) .oc-tip { background: var(--bg-elevated); }
  html:not([data-theme="light"]) .oc-tip-arrow { background: var(--bg-elevated); }
}

/* ==========================================================================
   Rich render output (charts, widgets, tables) injected by generation tools
   ========================================================================== */
.chat-render {
  margin: 12px 0;
  border: 1px solid var(--border-default, #e2e8f0);
  border-radius: 8px;
  overflow: hidden;
  background: transparent;
}
.render-svg {
  padding: 4px 8px 8px;
}
.render-svg svg {
  display: block;
  width: 100%;
  height: auto;
}
.render-svg text {
  font-family: inherit;
}
.render-unit {
  padding: 0 12px;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 11px;
  color: var(--text-muted, #6b7079);
}

.render-title {
  padding: var(--sp-2, 8px) var(--sp-3, 12px);
  font-size: var(--fs-base, 13px);
  font-weight: var(--fw-semibold, 600);
  color: var(--text-primary, #1a202c);
  border-bottom: 1px solid var(--border-default, #e2e8f0);
  background: var(--bg-elevated, #f7fafc);
}

/* --- Chart --- */
.chat-render-chart canvas {
  display: block;
  max-width: 100%;
  margin: 0 auto;
  padding: var(--sp-3, 12px);
}

/* --- Widget (custom HTML) --- */
.render-widget-body {
  padding: var(--sp-3, 12px);
  font-size: var(--fs-base, 13px);
  color: var(--text-primary, #1a202c);
  line-height: 1.6;
  overflow-x: auto;
}
.render-widget-body table {
  width: 100%;
  border-collapse: collapse;
  margin: var(--sp-2, 8px) 0;
}
.render-widget-body th,
.render-widget-body td {
  padding: var(--sp-1, 4px) var(--sp-2, 8px);
  border: 1px solid var(--border-default, #e2e8f0);
  text-align: left;
  font-size: var(--fs-sm, 12px);
}
.render-widget-body th {
  background: var(--bg-elevated, #f7fafc);
  font-weight: var(--fw-semibold, 600);
}

/* --- Table --- */
.render-table-wrap {
  overflow-x: auto;
  padding: 0 var(--sp-2, 8px) var(--sp-2, 8px);
}
.render-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-sm, 12px);
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Consolas, monospace);
}
.render-table th {
  position: sticky;
  top: 0;
  background: var(--bg-elevated, #f7fafc);
  font-weight: var(--fw-semibold, 600);
  text-align: left;
  padding: var(--sp-2, 8px) var(--sp-2, 8px);
  border-bottom: 2px solid var(--border-default, #e2e8f0);
  white-space: nowrap;
}
.render-table td {
  padding: var(--sp-1, 4px) var(--sp-2, 8px);
  border-bottom: 1px solid var(--border-subtle, #edf2f7);
  white-space: nowrap;
}
.render-table tr:hover td {
  background: var(--accent-muted, rgba(66, 133, 244, 0.06));
}

/* --- Footer & error --- */
.render-footer {
  padding: var(--sp-1, 4px) var(--sp-3, 12px);
  font-size: var(--fs-xs, 11px);
  color: var(--text-muted, #a0aec0);
  border-top: 1px solid var(--border-default, #e2e8f0);
  text-align: right;
}
.render-error {
  padding: var(--sp-3, 12px);
  color: var(--danger, #e53e3e);
  font-size: var(--fs-sm, 12px);
  font-style: italic;
}

/* Dark mode adjustments for render output */
[data-theme="dark"] .chat-render {
  border-color: var(--border-default);
  background: var(--bg-elevated);
}
[data-theme="dark"] .render-title {
  background: var(--bg-elevated-2);
  border-color: var(--border-default);
}
[data-theme="dark"] .render-table th {
  background: var(--bg-elevated-2);
}
[data-theme="dark"] .render-table td {
  border-color: var(--border-subtle);
}

/* ==========================================================================
   Auto-collapse chatbox (inactive → narrow column, hover/active → expand)
   ----------------------------------------------------------------------------
   Activation:
     • .content-right.auto-collapsed   → narrow column (sidebar width)
     • .content-right.auto-collapsed:hover → expand back to full size
     • .content-right.pinned           → user pinned, disable auto-collapse
   The header bar slides completely to the right when collapsed.
   ========================================================================== */

/* Smooth width transition on the drawer itself (only in dock mode).
   Do NOT tween width while JS is transform-sliding open/close, or while
   collapsed — that stacked a second slide on top of the first. */
.content-right.mode-dock {
  transition: width 0.3s ease-in-out, min-width 0.3s ease-in-out;
}
/* Chrome can resolve this flex item's cyclic max-width:100% to 0 when
   the panel moves from position:fixed (float) into the row. min-width
   wins over that max-width, so the split cannot vanish. Collapsed
   (width:0) and the auto-collapse !important widths are unchanged. */
@media (min-width: 821px) {
  .content-right.mode-dock:not(.collapsed) {
    flex-shrink: 0;
    min-width: min(320px, 40vw);
  }
}
.content-right.mode-dock.closing,
.content-right.mode-dock.collapsed,
.content-right.mode-dock.chat-no-motion {
  transition: none !important;
}

/* Pin button visual state (active = pinned) */
.chat-pin-btn { font-size: var(--fs-sm); opacity: 0.55; }
.chat-pin-btn[aria-pressed="true"] {
  opacity: 1;
  background: var(--accent);
  color: var(--text-inverse);
  border-color: var(--accent);
}

/* Collapsed state: narrow column = expanded sidebar width (260px) */
.content-right.mode-dock.auto-collapsed {
  width: var(--sidebar-width, 260px) !important;
  min-width: var(--sidebar-width, 260px) !important;
  max-width: var(--sidebar-width, 260px) !important;
  overflow: hidden;
}

/* Collapsed dock: hide header with opacity/visibility — NOT transform.
   Permanent will-change:transform + translateX on the header made the
   Sessions/menu bar flicker whenever #chat-log scrolled (GPU layer). */
.content-right.mode-dock.auto-collapsed .chat-panel-header {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: none !important;
  will-change: auto;
  transition: opacity 0.2s ease, visibility 0.2s ease;
}
.content-right.mode-dock .chat-panel-header {
  /* Only transition opacity when collapsing — never keep will-change on. */
  transition: opacity 0.2s ease, visibility 0.2s ease;
  will-change: auto;
  transform: none;
}

/* Hover restores full size + shows the header again */
.content-right.mode-dock.auto-collapsed:hover {
  width: var(--chat-width-user, var(--chat-width)) !important;
  min-width: var(--chat-width-user, var(--chat-width)) !important;
  max-width: none !important;
}
.content-right.mode-dock.auto-collapsed:hover .chat-panel-header {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: none !important;
}

/* When pinned, disable any auto-collapse styling regardless of class state.
   IMPORTANT: use the real drawer-width variables (--chat-width-user with
   --chat-width fallback) so pinning keeps the drawer at its natural /
   user-resized width, NOT the legacy hardcoded 480px which actually made
   the drawer SHRINK from its larger natural size — looking like a collapse. */
.content-right.mode-dock.pinned,
.content-right.mode-dock.pinned:hover,
.content-right.mode-dock.pinned.auto-collapsed,
.content-right.mode-dock.pinned.auto-collapsed:hover {
  width: var(--chat-width-user, var(--chat-width)) !important;
  min-width: var(--chat-width-user, var(--chat-width)) !important;
  max-width: none !important;
  overflow: visible !important;
}
.content-right.mode-dock.pinned .chat-panel-header,
.content-right.mode-dock.pinned.auto-collapsed .chat-panel-header,
.content-right.mode-dock.pinned.auto-collapsed:hover .chat-panel-header {
  opacity: 1 !important;
  visibility: visible !important;
  transform: none !important;
  pointer-events: auto !important;
}

/* Mobile: completely disable auto-collapse (no width override, no hide) */
@media (max-width: 768px) {
  .content-right.mode-dock.auto-collapsed,
  .content-right.mode-dock.auto-collapsed:hover {
    width: auto !important;
    min-width: 0 !important;
    max-width: none !important;
  }
  .content-right.mode-dock.auto-collapsed .chat-panel-header {
    opacity: 1 !important;
    visibility: visible !important;
    transform: none !important;
    pointer-events: auto !important;
  }
}

/* =========================================================================
   Empty-session layout (ChatGPT / Claude / Grok style)
   When the chat log has no messages yet, lift the composer toward the
   centre of the panel and show a welcome block. The first message removes
   .is-empty-session and the composer slides smoothly back to the bottom.
   ========================================================================= */

/* Welcome block — only visible while the panel is in empty-session mode */
.chat-empty-welcome {
  display: none;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--sp-2);
  padding: var(--sp-4) var(--sp-5) var(--sp-3);
  color: var(--text-default);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.45s ease, transform 0.45s ease;
}
.content-right.is-empty-session .chat-empty-welcome {
  display: flex;
  opacity: 1;
  transform: translateY(0);
}
.chat-empty-welcome .cew-icon {
  font-size: 56px;
  line-height: 1;
  background: linear-gradient(135deg, #6c8cff, #b07cff 55%, #5dd1ff);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
  animation: oc-ai-sweep 8s linear infinite;
}
.chat-empty-welcome .cew-title {
  font-size: calc(22px * var(--ui-font-scale, 1));
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1.25;
}
.chat-empty-welcome .cew-sub {
  font-size: calc(14px * var(--ui-font-scale, 1));
  font-weight: 400;
  color: var(--text-secondary);
  max-width: 42ch;
  line-height: 1.6;
}
.chat-empty-welcome .cew-sub code {
  font-family: var(--font-mono);
  font-size: 11.5px;
  padding: 1px 5px;
  border-radius: 3px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--text-default);
}
.chat-empty-welcome .cew-actions {
  margin-top: 14px;
  display: flex;
  gap: 8px;
  justify-content: center;
  flex-wrap: wrap;
}
.chat-empty-welcome .cew-chip {
  font: inherit;
  font-size: calc(14px * var(--ui-font-scale, 1));
  font-weight: 500;
  line-height: 1.2;
  color: #fff;
  background: var(--accent, #58a6ff);
  border: 0;
  border-radius: 999px;
  padding: 8px 16px;
  min-height: 36px;
  cursor: pointer;
  transition: opacity var(--tr-fast, 0.15s);
}
.chat-empty-welcome .cew-chip:hover { opacity: 0.9; }
.chat-empty-welcome .cew-chip:active { opacity: 0.8; }

/* Hide the empty log so it doesn't reserve space; the composer is what
   the user should see. `!important` is required because base.html sets
   `flex: 1` on the log via inline style — inline always wins specificity
   without it, which kept the log eating the available vertical space and
   pinned the composer to the bottom even in empty-session mode. */
.content-right.is-empty-session .chat-log {
  flex: 0 0 auto !important;
  min-height: 0 !important;
  padding: 0 !important;
  overflow: hidden !important;
}

/* Hide the in-flight progress strip and todos area while no conversation
   exists yet — keeps the centred composer view clean.
   A live bar (.active / .is-working) is not part of that welcome view. */
.content-right.is-empty-session #chat-activity-bar:not(.active),
.content-right.is-empty-session #chat-todos,
.content-right.is-empty-session #chat-usage {
  display: none;
}

/* margin-top:auto pushes the welcome+composer down toward the centre;
   margin-bottom:auto pads below. In a flex column, the two `auto`s split
   the remaining space evenly, so the block sits in the middle. */
.content-right.is-empty-session .chat-empty-welcome { margin-top: auto; }
.content-right.is-empty-session .chat-input-row {
  margin-bottom: auto;
  transition: margin 0.45s ease;
}

/* When transitioning back (first message arrives), the auto margins
   collapse and the composer slides to the bottom naturally because of the
   sibling flex layout. */
.content-right:not(.is-empty-session) .chat-input-row {
  margin-top: 0;
  margin-bottom: 0;
  transition: margin 0.45s ease;
}

/* Thinking… / Responding… stay on the bottom edge, directly above the
   composer. Empty-session auto margins (including the shells.css
   !important ones) must not carry that line to the middle of the pane.
   One id beats those class rules. */
#chat-drawer.is-working > #chat-activity-bar.active {
  display: flex !important;
  flex: 0 0 auto !important;
  margin: 0 !important;
  opacity: 1;
}
#chat-drawer.is-working > .chat-input-row {
  margin-top: 0 !important;
  margin-bottom: 0 !important;
}
#chat-drawer.is-working > .chat-log {
  flex: 1 1 0 !important;
  min-height: 0 !important;
  overflow-x: hidden !important;
  overflow-y: auto !important;
}
#chat-drawer.is-working .chat-empty-welcome {
  display: none !important;
  margin: 0 !important;
}
/* The empty assistant bubble is the same status. In a short thread it
   sits mid-pane. The bar above the composer is the only indicator. */
#chat-drawer.is-working .chat-msg.assistant.is-thinking {
  display: none;
}

/* Floating / mini chat is a panel, not a modal. Do not grey the desk. */

/* =========================================================================
   Persona analyst (Phase 1)
   - Chip in the chat-panel header (avatar + name + framework tag)
   - Click → popover with bio
   - Today's-book strip above the chat input
   ========================================================================= */

.persona-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: 8px;
  padding: 2px 8px 2px 4px;
  background: var(--bg-elevated-2);
  border: 1px solid var(--border-default);
  border-radius: 999px;
  color: var(--text-primary);
  font-size: var(--fs-xs);
  font-family: var(--font-sans);
  cursor: pointer;
  line-height: 1;
  transition: background var(--tr-fast), border-color var(--tr-fast);
}
.persona-chip:hover { background: var(--bg-elevated); border-color: var(--accent); }
.persona-chip__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  background: var(--accent-muted, color-mix(in srgb, var(--accent) 14%, transparent));
  border-radius: 50%;
  font-size: 12px;
}
.persona-chip__name { font-weight: 600; }
.persona-chip__tag {
  font-size: 10px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding-left: 4px;
  border-left: 1px solid var(--border-default);
  margin-left: 2px;
}

.persona-popover {
  position: absolute;
  z-index: 1000;
  margin-top: 4px;
  max-width: 320px;
  padding: 12px;
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--r-md);
  box-shadow: 0 8px 28px rgba(0,0,0,.3);
  font-size: var(--fs-sm);
}
.persona-popover__head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}
.persona-popover__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  background: var(--accent-muted, color-mix(in srgb, var(--accent) 14%, transparent));
  border-radius: 50%;
  font-size: 20px;
}
.persona-popover__head-text { display: flex; flex-direction: column; gap: 2px; }
.persona-popover__tag {
  font-size: 10px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.persona-popover__bio {
  margin: 0;
  color: var(--text-secondary);
  white-space: pre-wrap;
  line-height: 1.4;
  font-size: var(--fs-xs);
}

/* Today's-book strip — thin one-liner above the chat input. */
.book-strip {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  margin: 0 8px 4px;
  background: var(--bg-elevated-2);
  border: 1px solid var(--border-muted);
  border-radius: var(--r-sm);
  font-size: var(--fs-xs);
  color: var(--text-secondary);
}
.book-strip__icon { opacity: 0.6; }
.book-strip__text { flex: 1; }

/* Assistant signature line — rendered at the bottom of each assistant
   bubble when a persona is active. chat.js inserts it as <em class="msg-sig">.
   Subtle italic so it feels signed-off, not foisted. */
.msg-sig {
  display: block;
  margin-top: 8px;
  font-style: italic;
  color: var(--text-muted);
  font-size: var(--fs-xs);
}

/* Inline confidence badge — rendered by chat.js' message post-processor.
   Replaces [conf:NN%] markers. Color gradient by band.
   --- High (≥70):  green  --- Medium (40-69): amber  --- Low (<40): red
*/
.conf-badge {
  --conf-ink: var(--text-secondary);
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin: 0 0.2em;
  padding: 0 7px 0 6px;
  border-radius: 6px;
  font-family: var(--font-sans);
  font-size: calc(12px * var(--ui-font-scale, 1));
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: 0;
  vertical-align: baseline;
  color: var(--text-secondary);
  background: color-mix(in srgb, var(--conf-ink) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--conf-ink) 32%, transparent);
  white-space: nowrap;
}
.conf-badge::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--conf-ink);
  flex: 0 0 auto;
}
.conf-badge__k { font-weight: 500; }
.conf-badge__n {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}
.conf-badge--high { --conf-ink: #3dbe55; }
.conf-badge--med { --conf-ink: #d39212; }
.conf-badge--low { --conf-ink: #e15b5b; }
html[data-theme="light"] .conf-badge--high { --conf-ink: #0d6b2c; }
html[data-theme="light"] .conf-badge--med { --conf-ink: #8a5a00; }
html[data-theme="light"] .conf-badge--low { --conf-ink: #9a2048; }

/* ---------- Persona switcher (in the chip popover) -----------------------
   One row per persona; active row muted. Click → PUTs /api/persona/current.
*/
.persona-switch {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border-muted);
}
.persona-switch__row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  background: transparent;
  border: 1px solid var(--border-muted);
  border-radius: var(--r-sm);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: var(--fs-xs);
  cursor: pointer;
  text-align: left;
  transition: background var(--tr-fast), border-color var(--tr-fast);
}
.persona-switch__row:hover { background: var(--bg-elevated-2); border-color: var(--accent); }
.persona-switch__row.is-active {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border-color: var(--accent);
  color: var(--text-primary);
  cursor: default;
}
.persona-switch__avatar { width: 18px; text-align: center; }
.persona-switch__name { flex: 1; font-weight: 600; }
.persona-switch__tag {
  font-size: 10px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.persona-popover__footer {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--border-muted);
  text-align: right;
}
.persona-popover__link {
  font-size: var(--fs-xs);
  color: var(--accent);
  text-decoration: none;
}
.persona-popover__link:hover { text-decoration: none; }

/* ---------- Council button (next to send) + modal ---------------------- */
#chat-council {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 0 10px;
  margin-right: 4px;
  background: var(--bg-elevated-2);
  color: var(--text-secondary);
  border: 1px solid var(--border-default);
  border-radius: var(--r-md);
  font-family: var(--font-sans);
  font-size: var(--fs-xs);
  cursor: pointer;
  transition: background var(--tr-fast), color var(--tr-fast);
}
#chat-council:hover {
  background: var(--accent-muted, color-mix(in srgb, var(--accent) 12%, transparent));
  color: var(--text-primary);
  border-color: var(--accent);
}

.council-modal { position: fixed; inset: 0; z-index: 1100; }
.council-modal__backdrop { position: absolute; inset: 0; background: rgba(0,0,0,.5); }
.council-modal__panel {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: min(1100px, 96vw);
  max-height: 88vh;
  display: flex;
  flex-direction: column;
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--r-md);
  box-shadow: 0 16px 48px rgba(0,0,0,.5);
  overflow: hidden;
}
.council-modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border-muted);
}
.council-modal__head h3 { margin: 0; font-size: var(--fs-md); }
.council-modal__close {
  background: transparent;
  border: none;
  color: var(--text-secondary);
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
}
.council-modal__close:hover { color: var(--text-primary); }
.council-modal__question {
  padding: 8px 16px;
  font-size: var(--fs-sm);
  color: var(--text-secondary);
  font-style: italic;
  border-bottom: 1px solid var(--border-muted);
  background: var(--bg-elevated-2);
}
.council-modal__grid {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 12px;
  padding: 16px;
  overflow-y: auto;
}
.council-modal__loading, .council-modal__err {
  grid-column: 1 / -1;
  padding: 24px;
  text-align: center;
  color: var(--text-muted);
  font-size: var(--fs-sm);
}
.council-modal__err { color: #ff7e7e; font-family: var(--font-mono); }
.council-card {
  display: flex;
  flex-direction: column;
  background: var(--bg-elevated-2);
  border: 1px solid var(--border-muted);
  border-radius: var(--r-md);
  overflow: hidden;
  min-height: 0;
}
.council-card__head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border-muted);
}
.council-card__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border-radius: 50%;
  font-size: 16px;
}
.council-card__meta { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.council-card__meta strong { font-size: var(--fs-sm); color: var(--text-primary); }
.council-card__tag {
  font-size: 10px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.council-card__lat {
  font-size: 10px;
  color: var(--text-muted);
  font-family: var(--font-mono);
}
.council-card__body {
  padding: 12px;
  font-size: var(--fs-sm);
  line-height: 1.5;
  color: var(--text-primary);
  word-wrap: break-word;
}
.council-card__body p { margin: 0 0 8px; }
.council-card__body p:last-child { margin-bottom: 0; }
.council-card__err {
  color: #ff7e7e;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
}

/* ==========================================================================
   Phase 3 — chat mobile hardening (ADDITIVE).
   ========================================================================== */

/* "↓ New messages" pill — shown by chat.js when the user has scrolled up while
   new content streams in. Floats above the composer, centered. */
.chat-jump-bottom {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 92px;                 /* clears the composer + activity bar */
  z-index: 40;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 12px;
  font-size: var(--fs-sm);
  font-family: inherit;
  color: #fff;
  background: var(--accent, #58a6ff);
  border: 0;
  border-radius: 999px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28);
  cursor: pointer;
  opacity: 0.96;
}
.chat-jump-bottom[hidden] { display: none; }
.chat-jump-bottom:hover { opacity: 1; }

/* Tighten transient/attachment chrome on very narrow phones so nothing
   pushes the bubble sideways (iPhone SE / mini ~320–375px). */
@media (max-width: 480px) {
  .chat-tool { max-width: 100%; }
  .chat-attachment-pill { max-width: min(200px, 72vw); }
}
@media (max-width: 360px) {
  .chat-attachment-pill { max-width: 64vw; }
}

/* Pathway C Stage 3 — chat header AI mark */
.chat-panel-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.chat-ai-mark {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--gradient-ai, linear-gradient(135deg, #8ab4ff, #c084fc));
  box-shadow: 0 0 8px -1px color-mix(in srgb, var(--accent-ai, #c084fc) 50%, transparent);
  flex-shrink: 0;
}
.chat-panel-header {
  /* Fully opaque — a base mix read translucent under the old glass layer. */
  background: var(--bg-elevated, #161b22) !important;
}


/* OC_MOBILE_COMPOSER_PIN — phone: keep composer at bottom (not mid-panel) */
@media (max-width: 820px), (hover: none) and (pointer: coarse) {
  .content-right.is-empty-session .chat-empty-welcome {
    margin-top: 0 !important;
    margin-bottom: 0 !important;
    flex: 1 1 auto !important;
    justify-content: center !important;
  }
  .content-right.is-empty-session .chat-input-row {
    margin-top: 0 !important;
    margin-bottom: 0 !important;
  }
}

/* ---- 5C voice recording + read-aloud ---- */
#chat-attach-voice.is-recording {
  color: var(--text-inverse, #fff) !important;
  background: var(--danger, #da3633) !important;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--danger, #da3633) 35%, transparent);
  animation: chat-voice-pulse 1.2s ease-in-out infinite;
}
#chat-attach-voice.is-busy {
  opacity: 0.7;
  pointer-events: none;
}
#chat-speak-toggle.is-on {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}
.chat-voice-live {
  font-size: var(--fs-xs);
  color: var(--danger, #da3633);
  white-space: nowrap;
  padding: 0 6px;
  letter-spacing: 0.01em;
}
@keyframes chat-voice-pulse {
  0%, 100% { box-shadow: 0 0 0 2px color-mix(in srgb, var(--danger, #da3633) 25%, transparent); }
  50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--danger, #da3633) 12%, transparent); }
}
@media (prefers-reduced-motion: reduce) {
  #chat-attach-voice.is-recording { animation: none; }
}


/* ==========================================================================
   Docked-drawer width reservation (Phase 3.4, 2026-09-12)
   The drawer's markup sits at the end of <body>. Before this rule the main
   column laid out at full width and the whole page reflowed by the dock width
   when the drawer parsed — CLS 0.454 on /markets, ~97% of the portal's total
   layout shift. base.html sets data-chat-dock before first paint; this
   reserves the space so the first layout is already the final one.
   ========================================================================== */
@media (min-width: 821px) {
  /* Reserve on the wrapper, and only while the drawer is genuinely absent
     from the DOM: :has() stops matching the moment #chat-drawer parses, so
     the padding is handed straight over to the real element with no net
     change. Styling the wrapper also avoids fighting the per-page
     `max-width: 100% !important` that some routes put on .content-left. */
  html[data-chat-dock="1"] .content-wrapper:not(:has(> #chat-drawer)) {
    padding-right: var(--chat-width-user, var(--chat-width));
    box-sizing: border-box;
  }
}


/* ==========================================================================
   Chat menus and popovers — folded out of quiet.css (Phase 1, css_fold.py)
   Moved verbatim, included, so the cascade result is unchanged;
   the CSSOM guard verifies that. The component owns these rules now.
   ========================================================================== */
/* ---------- Chatbox menus — x.ai / Grok: floating, padded, snappy ---------- */
.chat-pop,
.chat-sessions-pop,
.chat-model-pop,
.chat-tier-pop,
.chat-header-menu {
  --chat-menu-ease: cubic-bezier(0.16, 1, 0.3, 1);
  background: color-mix(in srgb, var(--bg-elevated) 82%, transparent);
  border: 1px solid color-mix(in srgb, var(--text-primary) 10%, transparent);
  border-radius: 14px;
  box-shadow:
    0 18px 50px -16px rgba(0, 0, 0, 0.55),
    0 0 0 1px color-mix(in srgb, var(--text-primary) 4%, transparent);
  backdrop-filter: blur(22px) saturate(1.25);
  -webkit-backdrop-filter: blur(22px) saturate(1.25);
  padding: 6px;
  overflow-x: hidden;
  overflow-y: auto;
}

[data-theme="light"] .chat-pop,
[data-theme="light"] .chat-sessions-pop,
[data-theme="light"] .chat-model-pop,
[data-theme="light"] .chat-tier-pop,
[data-theme="light"] .chat-header-menu {
  background: color-mix(in srgb, #ffffff 88%, transparent) !important;
  border-color: rgba(0, 0, 0, 0.08) !important;
  box-shadow:
    0 18px 50px -18px rgba(0, 0, 0, 0.18),
    0 0 0 1px rgba(0, 0, 0, 0.04) !important;
}

.chat-model-pop,
.chat-tier-pop,
.chat-header-menu,
.chat-sessions-pop {
  transform: translateY(-8px) scale(0.96);
  transform-origin: top right;
  transition:
    opacity 220ms var(--chat-menu-ease, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 220ms var(--chat-menu-ease, cubic-bezier(0.16, 1, 0.3, 1)),
    visibility 0s linear 220ms;
}

.chat-pop {
  transform: translateY(8px) scale(0.96);
  transform-origin: bottom center;
  transition:
    opacity 220ms var(--chat-menu-ease, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 220ms var(--chat-menu-ease, cubic-bezier(0.16, 1, 0.3, 1)),
    visibility 0s linear 220ms;
}

/* Chromium's default position-visibility is anchors-visible. These
   menus anchor to a button inside overflow:hidden #chat-drawer; Chrome
   then strongly-hides the menu when it decides that button is clipped. */
#chat-layout-pop[data-oc-anchored],
#chat-more-pop[data-oc-anchored],
#chat-sessions-pop[data-oc-anchored],
#chat-model-pop[data-oc-anchored],
#chat-tier-pop[data-oc-anchored] {
  position-visibility: always;
}

.chat-model-pop.open,
.chat-tier-pop.open,
.chat-header-menu.open,
.chat-sessions-pop.open,
.chat-pop.open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: none;
  transition:
    opacity 220ms var(--chat-menu-ease, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 220ms var(--chat-menu-ease, cubic-bezier(0.16, 1, 0.3, 1)),
    visibility 0s linear 0s;
}

.chat-model-pop li.grp,
.chat-pop li,
.chat-sessions-pop li.empty {
  border: none;
  border-radius: 8px;
  margin: 0;
  padding: 4px 8px;
  background: transparent;
  height: auto;
}

.chat-sessions-pop li.sess {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 6px;
  min-height: 0;
  height: 32px;
  padding: 0 8px;
  margin: 1px 0;
  border: none;
  border-radius: 8px;
  background: transparent;
  white-space: nowrap;
}

.chat-sessions-pop .s-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.2;
  font-size: 13px;
}

.chat-sessions-pop .s-rel { display: none; }

.chat-sessions-pop .s-del {
  width: 22px;
  height: 22px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.chat-model-pop li.mdl {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 8px;
  min-height: 0;
  height: 32px;
  padding: 0 10px;
  margin: 1px 0;
  border: none;
  border-radius: 8px;
  background: transparent;
  white-space: nowrap;
}

.chat-model-pop li.mdl .m-label {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13px;
  line-height: 1.2;
}

.chat-model-pop li.mdl .m-id {
  flex: 0 1 auto;
  max-width: 42%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 10px;
  line-height: 1.2;
  opacity: 0.55;
}

.chat-header-menu .chat-menu-item {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr);
  grid-template-rows: auto auto;
  column-gap: 8px;
  row-gap: 2px;
  align-items: start;
  width: 100%;
  height: auto;
  min-height: 0;
  white-space: normal;
  overflow: visible;
  border: none;
  border-radius: 10px;
  padding: 8px 10px;
  background: transparent;
}

.chat-more-pop .chat-menu-item {
  grid-template-columns: minmax(0, 1fr);
}

.chat-menu-ico {
  grid-column: 1;
  grid-row: 1 / span 2;
}

.chat-menu-label {
  grid-column: 2;
  grid-row: 1;
  display: block;
  min-width: 0;
  line-height: 1.3;
}

.chat-menu-hint {
  grid-column: 2;
  grid-row: 2;
  display: block;
  min-width: 0;
  white-space: normal;
  line-height: 1.35;
  color: var(--text-muted);
}
html:not([data-theme="light"]) .chat-menu-item:hover .chat-menu-hint,
html:not([data-theme="light"]) .chat-menu-item:focus-visible .chat-menu-hint {
  color: #ffffff;
}

.chat-more-pop .chat-menu-label,
.chat-more-pop .chat-menu-hint {
  grid-column: 1;
}

.chat-model-pop li.mdl-foot {
  display: block;
  position: relative;
  flex-direction: unset;
  white-space: normal;
  line-height: 1.45;
  padding: 10px;
  margin-top: 6px;
  border-top: 1px solid color-mix(in srgb, var(--text-primary) 8%, transparent);
  height: auto;
}

.chat-model-pop li.mdl:hover,
.chat-pop li:hover,
.chat-pop li.active,
.chat-sessions-pop li.sess:hover:not(.empty),
.chat-menu-item:hover {
  background: color-mix(in srgb, var(--text-primary) 7%, transparent);
  color: var(--text-primary);
  --sess-fade: color-mix(in srgb, var(--text-primary) 7%, var(--bg-elevated));
}

.chat-model-pop li.mdl.active,
.chat-sessions-pop li.sess.active,
.chat-menu-item[aria-checked="true"],
.chat-menu-item.is-active {
  /* Still load-bearing: desk.css loads after this sheet and accent-tints the
     active item. Reconcile when desk.css is folded. */
  background: color-mix(in srgb, var(--text-primary) 10%, transparent) !important;
  --sess-fade: color-mix(in srgb, var(--text-primary) 10%, var(--bg-elevated));
}

.chat-model-pop li.mdl.active .m-label,
.chat-model-pop li.mdl.active {
  color: var(--text-primary);
  border-left-color: transparent;
}

.chat-model-pop li.grp,
.chat-sessions-pop li.sess-group,
.chat-menu-section {
  text-transform: none;
  letter-spacing: -0.01em;
  font-size: 11px;
  font-weight: 500;
  color: var(--text-muted);
  background: transparent;
  border: none;
  padding: 8px 10px 4px;
}

.chat-sessions-pop .sess-chrome,
.chat-sessions-pop .sess-head,
.chat-sessions-pop .sess-toolbar,
.chat-sessions-pop .sess-foot,
.chat-model-pop li.mdl-foot {
  background: transparent;
  border-color: color-mix(in srgb, var(--text-primary) 8%, transparent);
}

.chat-sessions-pop .sess-search {
  border-radius: 10px;
  background: color-mix(in srgb, var(--bg-base) 70%, transparent);
  border-color: color-mix(in srgb, var(--text-primary) 10%, transparent);
  box-shadow: none;
}

.chat-sessions-pop .sess-search:focus {
  border-color: color-mix(in srgb, var(--text-primary) 22%, transparent);
  box-shadow: none;
}

.chat-sessions-pop .sess-head .sess-new {
  background: transparent;
  color: var(--text-primary);
  border: none;
  border-radius: 8px;
  padding: 8px 10px;
  filter: none;
}

.chat-sessions-pop .sess-new:hover { filter: none; background: color-mix(in srgb, var(--text-primary) 7%, transparent); }

.chat-sessions-pop .s-rename-input {
  box-shadow: none;
  border-radius: 8px;
}

/* Icon-only composer / header */
.chat-action-btn,
.chat-toolbar-btn,
.chat-actions-toggle,
.chat-actions-close {
  width: 32px;
  height: 32px;
  /* !important still load-bearing: a later sheet pads these icon buttons. */
  padding: 0 !important;
  min-width: 32px;
}

.chat-action-btn:hover,
.chat-toolbar-btn:hover {
  background: var(--btn-wash);
  border-color: transparent;
  color: var(--text-primary);
}


/* Session icons, the new-session mark, and close share one row with the
   menus. The title gives up width; nothing wraps under the close button. */
.chat-chips {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
}
.chat-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
}
.chat-icon-btn .oc-ico { width: 15px; height: 15px; }
.chat-icon-btn:hover,
.chat-icon-btn:focus-visible {
  background: var(--bg-elevated-2);
  color: var(--text-primary);
}
.chat-icon-btn[aria-pressed="true"],
.chat-icon-btn.is-active {
  background: var(--bg-elevated-2);
  color: var(--accent, var(--text-primary));
}
@media (min-width: 821px) {
  /* One row: title, menus, session icons, new session, close. */
  .content-right.mode-dock .chat-panel-header,
  .content-right.mode-float .chat-panel-header,
  .content-right.mode-mini .chat-panel-header {
    flex-wrap: nowrap;
    align-items: center;
    row-gap: 0;
    padding: 0 8px;
    gap: 2px;
  }
  .content-right.mode-dock .chat-panel-header > .chat-panel-title,
  .content-right.mode-float .chat-panel-header > .chat-panel-title,
  .content-right.mode-mini .chat-panel-header > .chat-panel-title {
    order: 0;
    flex: 1 1 auto !important;
    min-width: 0;
  }
  .content-right.mode-dock .chat-panel-header > #chat-panel-actions,
  .content-right.mode-float .chat-panel-header > #chat-panel-actions,
  .content-right.mode-mini .chat-panel-header > #chat-panel-actions {
    order: 1;
    flex: 0 1 auto !important;
    width: auto !important;
    min-width: 0;
    flex-wrap: nowrap;
    justify-content: flex-end;
    gap: 0 !important;
  }
  .content-right.mode-dock #chat-panel-actions .chat-panel-btn,
  .content-right.mode-float #chat-panel-actions .chat-panel-btn,
  .content-right.mode-mini #chat-panel-actions .chat-panel-btn {
    padding: 4px 6px !important;
  }
  .content-right.mode-dock .chat-model-wrap,
  .content-right.mode-float .chat-model-wrap,
  .content-right.mode-mini .chat-model-wrap {
    min-width: 0;
    flex-shrink: 1;
  }
  .content-right.mode-dock .chat-model-btn,
  .content-right.mode-float .chat-model-btn,
  .content-right.mode-mini .chat-model-btn {
    min-width: 0;
    max-width: 100%;
  }
  .content-right.mode-dock #chat-model-label,
  .content-right.mode-float #chat-model-label,
  .content-right.mode-mini #chat-model-label {
    display: inline-block;
    min-width: 0;
    max-width: 9ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
  }
  .content-right.mode-dock .chat-layout-btn .chat-layout-txt,
  .content-right.mode-float .chat-layout-btn .chat-layout-txt,
  .content-right.mode-mini .chat-layout-btn .chat-layout-txt {
    display: none;
  }
  .content-right.mode-dock .chat-panel-header > .chat-chips,
  .content-right.mode-float .chat-panel-header > .chat-chips {
    order: 2;
    margin-left: 2px;
    gap: 0;
    flex-shrink: 0;
  }
  .content-right.mode-dock .chat-chips .chat-icon-btn,
  .content-right.mode-float .chat-chips .chat-icon-btn { width: 24px; }
  .content-right.mode-dock .chat-panel-header > #chat-new-session,
  .content-right.mode-float .chat-panel-header > #chat-new-session,
  .content-right.mode-mini .chat-panel-header > #chat-new-session {
    order: 3;
    flex-shrink: 0;
    margin-left: 0;
  }
  .content-right.mode-dock .chat-panel-header > #chat-page,
  .content-right.mode-float .chat-panel-header > #chat-page {
    order: 4;
    flex-shrink: 0;
  }
  .content-right.mode-mini #chat-page { display: none; }
  .content-right.mode-dock .chat-panel-header > #chat-close,
  .content-right.mode-float .chat-panel-header > #chat-close,
  .content-right.mode-mini .chat-panel-header > #chat-close {
    order: 5;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 26px;
    height: 26px;
    padding: 0;
    margin-left: 0;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--text-secondary);
    font-size: 13px;
    line-height: 1;
  }
  .content-right.mode-dock .chat-panel-header > #chat-close:hover,
  .content-right.mode-float .chat-panel-header > #chat-close:hover,
  .content-right.mode-mini .chat-panel-header > #chat-close:hover {
    background: var(--bg-elevated-2);
    color: var(--text-primary);
  }
}

/* ---------- OceanusAI floating button: north-star mark, neon ring ----------
   The classic button keeps its accent fill; the flat button keeps its white
   card. Both carry the two-star mark and a thin neon ring so the AI surface
   is told apart from ordinary controls at a glance. */
.chat-toggle-fab .chat-fab-ico[data-ico="northstar"],
.chat-fab .chat-fab-ico[data-ico="northstar"] {
  width: 24px;
  height: 24px;
}
.chat-toggle-fab,
.chat-fab {
  box-shadow: var(--shadow-sm), 0 0 0 1px rgba(124, 58, 237, .45), 0 0 8px rgba(6, 182, 212, .25);
}
.chat-toggle-fab:hover,
.chat-fab:hover {
  box-shadow: var(--shadow-sm), 0 0 0 1px rgba(124, 58, 237, .7), 0 0 10px rgba(6, 182, 212, .45);
}
html[data-ui="flat"] body #chat-fab.chat-toggle-fab {
  box-shadow: var(--shadow-md), 0 0 0 1px rgba(124, 58, 237, .55), 0 0 8px rgba(6, 182, 212, .3) !important;
}
html[data-ui="flat"] body #chat-fab.chat-toggle-fab:hover {
  box-shadow: var(--shadow-md), 0 0 0 1px rgba(124, 58, 237, .8), 0 0 10px rgba(6, 182, 212, .5) !important;
}
html[data-ui="flat"] body #chat-fab.chat-toggle-fab .chat-fab-ico[data-ico="northstar"] {
  width: 22px !important;
  height: 22px !important;
}

/* ---------- OceanusAI composer: the same raised card as Helm and the analyst
   chat — no hairline, a lifted surface, a drop shadow that deepens on focus.
   The id in the selector outranks the desk and quiet layers' class rules. --- */
html body #chat-drawer .chat-input-wrap,
html body #chat-drawer.is-empty-session .chat-input-wrap,
html:not([data-theme="light"]) body #chat-drawer .chat-input-wrap {
  border: 1px solid transparent !important;
  background: var(--composer-bg, var(--bg-elevated)) !important;
  box-shadow: var(--composer-shadow, 0 10px 28px -10px rgba(0, 0, 0, .6)) !important;
  transition: box-shadow var(--dur-ui) var(--ease-out);
}
html body #chat-drawer .chat-input-wrap:hover,
html:not([data-theme="light"]) body #chat-drawer .chat-input-wrap:hover {
  border-color: transparent !important;
  box-shadow: var(--composer-shadow, 0 10px 28px -10px rgba(0, 0, 0, .6)) !important;
}
html body #chat-drawer .chat-input-wrap:focus-within,
html:not([data-theme="light"]) body #chat-drawer .chat-input-wrap:focus-within {
  border-color: transparent !important;
  box-shadow: var(--composer-shadow-focus, 0 14px 36px -10px rgba(0, 0, 0, .72)) !important;
}

/* Standing legal line. Inside the row so empty-session auto margins keep
   it with the field. Column beats the phone row lock (responsive.css). */
#chat-drawer > .chat-input-row {
  flex-direction: column !important;
  flex-wrap: nowrap !important;
  align-items: stretch !important;
}
#chat-drawer > .chat-input-row > .chat-input-wrap {
  flex: 0 1 auto !important;
  width: 100%;
  max-width: 100%;
}
.ai-notice {
  flex: 0 0 auto;
  margin: 8px 4px 2px;
  padding: 0 8px;
  font-family: var(--font-sans);
  font-size: calc(11px * var(--ui-font-scale, 1));
  font-weight: 400;
  line-height: 1.45;
  text-align: left;
  color: var(--text-muted);
}
.ai-notice a,
.ai-notice a:hover,
.ai-notice a:active {
  color: var(--text-muted);
  text-decoration: underline !important;
  text-underline-offset: 2px;
}
.ai-notice a:hover,
.ai-notice a:active {
  color: var(--text-primary);
}
.ai-notice a:focus-visible {
  outline: 1px solid var(--border-strong);
  outline-offset: 2px;
}
#th-chat-panel .th-copilot-body > .ai-notice {
  margin: 0 12px 10px;
}

/* Xueqiu-style numbered notices under each finished AI reply.
   Composer .ai-notice at the panel foot stays. Hidden while the
   answer is still arriving so the list does not flash under "…". */
.ai-legal {
  margin: 10px 0 0;
  padding: 8px 0 0;
  border-top: 1px solid var(--border-default);
  color: var(--text-muted);
  font-family: var(--font-sans);
  font-size: calc(11px * var(--ui-font-scale, 1));
  font-weight: 400;
  line-height: 1.45;
}
.ai-legal-title {
  margin: 0 0 4px;
  font-size: inherit;
  font-weight: 500;
  color: var(--text-muted);
}
.ai-legal ol {
  margin: 0;
  padding-left: 1.25em;
}
.ai-legal li + li {
  margin-top: 2px;
}
.ai-legal a,
.ai-legal a:hover,
.ai-legal a:active {
  color: var(--text-muted);
  text-decoration: underline !important;
  text-underline-offset: 2px;
}
.ai-legal a:hover,
.ai-legal a:active {
  color: var(--text-primary);
}
.ai-legal a:focus-visible {
  outline: 1px solid var(--border-strong);
  outline-offset: 2px;
}
.an-msg__bubble > .ai-legal p,
.th-chat-msg.assistant > .ai-legal p {
  margin: 0 0 4px;
}
.th-chat-msg.assistant > .ai-legal ol,
.th-chat-msg.assistant > .ai-legal li {
  margin: 0;
  padding-left: 0;
  color: var(--text-muted);
}
.th-chat-msg.assistant > .ai-legal ol {
  padding-left: 1.25em;
}
.th-chat-msg.assistant > .ai-legal li + li {
  margin-top: 2px;
}
.th-chat-msg.assistant > .ai-legal a {
  color: var(--text-muted);
}
.th-chat-body {
  min-width: 0;
}
.chat-msg.assistant.is-thinking .ai-legal,
.chat-msg.assistant.is-streaming .ai-legal,
.th-chat-msg.assistant.is-thinking .ai-legal,
.th-chat-msg.assistant.is-streaming .ai-legal,
.an-msg--thinking .ai-legal,
.an-msg--streaming .ai-legal {
  display: none;
}
