/* ==========================================================================
   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(--sp-5);
  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-lg);
  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; }
.chat-toggle-fab:hover,
.chat-fab:hover { background: var(--accent-hover); transform: translateY(-2px); }

/* ---------- 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) ---------- */
.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-shrink: 0;
  gap: var(--sp-2);
  min-width: 0;
  position: relative;
  z-index: 100;
}
.chat-panel-title {
  font-family: var(--font-sans);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-md);
  color: var(--text-primary);
  flex-shrink: 0;
  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(--accent);
}

/* 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);
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  line-height: var(--lh-normal);
  color: var(--text-secondary);
  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; }

/* 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: calc(100vh - var(--topbar-height));
  max-height: calc(100vh - var(--topbar-height));
  position: relative;
}

/* (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; }

/* 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: linear-gradient(135deg, var(--accent-muted), var(--bg-elevated-2));
  color: var(--accent);
  border-color: var(--accent-muted);
}

/* 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(--fs-base);
  line-height: var(--lh-normal);
  background: var(--bg-elevated-2);
  border: 1px solid var(--border-muted);
  border-radius: var(--r-md);
  padding: var(--sp-2) var(--sp-3);
}
.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(--fs-base);
  line-height: var(--lh-loose);
  white-space: normal;
}
.chat-msg.assistant .body p {
  margin: 0 0 var(--sp-3) 0;
  text-align: left;
}
.chat-msg.assistant .body p:last-child { margin-bottom: 0; }

/* 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: var(--sp-1);
  padding-left: var(--sp-1);
}
.chat-msg.assistant .body li::marker { color: var(--text-muted); }

/* Emphasis */
.chat-msg.assistant .body strong,
.chat-msg.assistant .body b {
  font-weight: var(--fw-semibold);
  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: var(--fs-sm);
  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: var(--lh-normal);
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  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: var(--fs-sm);
}

/* 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: var(--fw-semibold);
  color: var(--text-primary);
  margin: var(--sp-4) 0 var(--sp-2) 0;
  line-height: var(--lh-tight);
}
.chat-msg.assistant .body h1 { font-size: var(--fs-xl); }
.chat-msg.assistant .body h2 { font-size: var(--fs-lg); }
.chat-msg.assistant .body h3 { font-size: var(--fs-md); }
.chat-msg.assistant .body h4 { font-size: var(--fs-base); }
.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: 1px solid var(--accent-muted);
  transition: border-bottom-color var(--tr-fast), color var(--tr-fast);
}
.chat-msg.assistant .body a:hover,
.chat-msg.user .body a:hover {
  color: var(--accent-hover);
  border-bottom-color: var(--accent);
}

/* 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: var(--fs-sm);
  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: var(--fw-semibold);
  text-align: left;
}
.chat-msg .body tbody tr:nth-child(even) td { background: rgba(127,127,127,0.04); }

/* ---------- 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 ---------- */
.chat-input-row {
  border-top: 1px solid var(--border-default);
  padding: var(--sp-2);
  display: flex;
  align-items: stretch;           /* let #chat-send fill the row's full
                                     height so it occupies the previously-
                                     empty space next to the textarea */
  gap: var(--sp-2);
  background: var(--bg-elevated);
  flex-shrink: 0;
}
/* The little 36×36 action buttons should NOT stretch tall when the
   textarea grows — keep them bottom-aligned. */
.chat-input-row > .chat-action-buttons {
  align-self: flex-end;
}
.chat-input-wrap {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0;
  background: var(--bg-input);
  border: 1px solid var(--border-default);
  border-radius: var(--r-sm);
  transition: border-color var(--tr-fast), border-radius 0.35s ease;
}
.chat-input-wrap:focus-within {
  border-color: var(--accent);
}

/* 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: 24px;
  background: var(--bg-elevated, var(--bg-input));
  border-color: color-mix(in srgb, var(--accent, #5b8def) 18%, var(--border-default));
  box-shadow: 0 8px 24px -10px rgba(0, 0, 0, 0.25);
}
[data-theme="dark"] .content-right.is-empty-session .chat-input-wrap {
  box-shadow: 0 10px 28px -12px rgba(0, 0, 0, 0.55);
}
.content-right.is-empty-session .chat-input-wrap:focus-within {
  border-color: var(--accent);
  box-shadow: 0 12px 32px -10px color-mix(in srgb, var(--accent, #5b8def) 35%, transparent);
}
/* 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: 18px;
  padding-right: 18px;
}
/* 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 — modern AI-style minimalist pill with paper-plane icon.
   Palette: indigo → violet → magenta, the same vocabulary frontier-AI UIs
   (ChatGPT / Claude / Perplexity / Gemini) use. Scoped to #chat-send only
   so it doesn't disturb the rest of the theme's accent tokens. */
:root {
  --send-c1: #6366f1; /* indigo-500 */
  --send-c2: #8b5cf6; /* violet-500 */
  --send-c3: #ec4899; /* pink-500   */
  --send-glow: rgba(139, 92, 246, 0.45);
}
[data-theme="dark"] {
  --send-c1: #818cf8; /* indigo-400 */
  --send-c2: #a78bfa; /* violet-400 */
  --send-c3: #f472b6; /* pink-400   */
  --send-glow: rgba(167, 139, 250, 0.55);
}
.chat-input-row > button#chat-send,
#chat-send {
  /* Sibling of .chat-input-wrap inside the row's flex container.
     align-self: stretch + min-height: 36px makes the button fill the full
     row height — when the textarea grows to 88px+, the button grows with
     it (a bit tall, but no whitespace). */
  align-self: stretch;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: linear-gradient(
    135deg,
    var(--send-c1) 0%,
    var(--send-c2) 55%,
    var(--send-c3) 100%
  );
  background-size: 180% 180%;
  background-position: 0% 50%;
  color: #ffffff;
  border: none;
  border-radius: 8px;
  padding: 0 14px;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  min-height: 36px;              /* floor: never smaller than action btns */
  min-width: 56px;
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.08),
    0 3px 10px -4px var(--send-glow);
  transition:
    transform var(--tr-fast),
    box-shadow var(--tr-fast),
    background-position 0.6s ease,
    filter var(--tr-fast);
}
#chat-send .send-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transform: translateX(0) rotate(0deg);
  transition: transform var(--tr-fast);
  /* Soft white halo so the icon pops on the colored gradient. */
  filter: drop-shadow(0 0 1px rgba(255, 255, 255, 0.5));
}
#chat-send .send-label {
  font-family: var(--font-sans);
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
}
#chat-send:hover:not(:disabled) {
  background-position: 100% 50%;
  filter: brightness(1.05);
  box-shadow:
    0 2px 6px rgba(0, 0, 0, 0.14),
    0 6px 18px -4px var(--send-glow),
    0 0 0 3px color-mix(in srgb, var(--send-c2) 28%, transparent);
}
#chat-send:hover:not(:disabled) .send-ico {
  transform: translateX(2px) rotate(-6deg);
}
#chat-send:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 3px color-mix(in srgb, var(--send-c2) 40%, transparent),
    0 4px 12px -4px var(--send-glow);
}
#chat-send:active:not(:disabled) {
  transform: scale(0.97);
  filter: brightness(0.94);
}
#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: chat-send-shimmer 2.4s linear infinite;
}
#chat-send.is-busy .send-ico {
  animation: chat-send-pulse 1s ease-in-out infinite;
}
@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 ---------- */
/* Rich-text toolbar — modern flat style. Buttons are borderless ghost
   tiles that pick up a subtle accent tint on hover. Toolbar surface
   uses the theme's --bg-elevated so it blends with the composer in both
   light and dark. */
.chat-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  padding: 6px 8px;
  background: color-mix(in srgb, var(--bg-elevated) 70%, transparent);
  border-bottom: 1px solid var(--border-subtle, var(--border-default));
  border-radius: var(--r-sm) var(--r-sm) 0 0;
  align-items: center;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.chat-toolbar.hidden {
  display: none;
}
.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 ---------- */
/* Lives inside `.chat-input-wrap` (column flex). Stretches its children
   vertically so the textarea visually fills the wrap — otherwise the
   textarea (sized by JS to its content) sits anchored at the top and a
   gap appears below. The fmt-toggle pins itself with `align-self:
   flex-start` so it doesn't stretch tall. */
.chat-textarea-container {
  position: relative;
  display: flex;
  align-items: stretch;
  gap: 0;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 0;
  flex: 1;
  min-height: 0;
}

.chat-fmt-toggle {
  background: transparent;
  border: none;
  /* Faded almost into the background — the rich-text editor is a hidden
     option; we don't want the T glyph competing with the textarea cursor
     or the send button for attention. Hover/active states still reveal
     full contrast so it's discoverable. */
  color: var(--text-muted);
  opacity: 0.4;
  font-size: var(--fs-base);
  cursor: pointer;
  padding: var(--sp-1) var(--sp-1) var(--sp-1) var(--sp-2);
  transition: color var(--tr-fast), background var(--tr-fast), opacity var(--tr-fast);
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  height: 32px;
  align-self: flex-start;    /* don't stretch when container grows tall */
  border-radius: 4px;
}
.chat-fmt-toggle:hover {
  color: var(--text-default);
  opacity: 1;
  background: color-mix(in srgb, var(--accent, #5b8def) 10%, transparent);
}
/* When the toolbar is open, the T button reads as "active" so the user
   can see at a glance which state they're in. Restore full opacity here
   too — when the toolbar is open the T is no longer "hidden". */
.chat-input-wrap:has(.chat-toolbar:not(.hidden)) .chat-fmt-toggle {
  color: var(--accent);
  opacity: 1;
  background: color-mix(in srgb, var(--accent, #5b8def) 14%, transparent);
}

#chat-input {
  flex: 1;
  resize: none;
  background: transparent;
  color: var(--text-primary);
  border: none;
  outline: none;
  /* More breathing room at the top — caret was sitting flush against
     the wrap's top edge. Roughly matches the IM/co-pilot composer. */
  padding: var(--sp-2) var(--sp-2) var(--sp-1) var(--sp-2);
  /* Parity with the IM/co-pilot composer textarea: sans, not mono. */
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  line-height: var(--lh-normal);
  min-height: 88px;       /* default (no toolbar): fill compose box */
  max-height: 300px;
  overflow-y: auto;
  overflow-x: hidden;
  word-wrap: break-word;
}
/* When the rich-text toolbar is visible (NOT hidden), shrink the textarea
   floor back down so toolbar+textarea together don't oversize the row. */
.chat-input-wrap:has(.chat-toolbar:not(.hidden)) #chat-input {
  min-height: 44px;
}
#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 ---------- */
.chat-action-buttons {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}
.chat-input-row .chat-action-buttons .chat-action-btn,
button.chat-action-btn {
  background: #f5f5f5;
  color: #1a1a1a;
  border: 1px solid #e0e0e0;
  border-radius: var(--r-xs);
  width: 36px;
  height: 36px;
  padding: 0;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all var(--tr-fast);
  flex-shrink: 0;
}
.chat-input-row .chat-action-buttons .chat-action-btn:hover,
button.chat-action-btn:hover {
  background: #e8e8e8;
  color: #000;
  border-color: #c8c8c8;
  transform: scale(1.05);
}
.chat-input-row .chat-action-buttons .chat-action-btn:active,
button.chat-action-btn:active {
  transform: scale(0.95);
  background: #d8d8d8;
}
/* Dark-theme support. The light-mode rule above uses a 3-class selector
   `.chat-input-row .chat-action-buttons .chat-action-btn` (specificity
   0,3,1), so the previous `[data-theme="dark"] .chat-action-btn` rule
   (specificity 0,2,1) was losing the cascade and the buttons stayed
   light in dark mode. Match the same nesting so the dark rule actually
   takes effect. */
[data-theme="dark"] .chat-input-row .chat-action-buttons .chat-action-btn,
[data-theme="dark"] button.chat-action-btn {
  background: var(--bg-elevated, #1a1f29);
  color: var(--text-default, #e6eaf0);
  border-color: var(--border-default, #2a2f3a);
}
[data-theme="dark"] .chat-input-row .chat-action-buttons .chat-action-btn:hover,
[data-theme="dark"] button.chat-action-btn:hover {
  background: color-mix(in srgb, var(--accent, #4a90e2) 15%, var(--bg-elevated, #1a1f29));
  color: var(--text-default, #fff);
  border-color: color-mix(in srgb, var(--accent, #4a90e2) 50%, var(--border-default, #2a2f3a));
}
[data-theme="dark"] .chat-input-row .chat-action-buttons .chat-action-btn:active,
[data-theme="dark"] button.chat-action-btn:active {
  background: color-mix(in srgb, var(--accent, #4a90e2) 25%, var(--bg-elevated, #1a1f29));
}

/* ---------- Status bar ---------- */
.chat-status-bar {
  padding: var(--sp-1) var(--sp-3);
  font-family: var(--font-sans);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  border-top: 1px solid var(--border-default);
  background: var(--bg-elevated);
  flex-shrink: 0;
}
.chat-status-bar .err { color: var(--danger); }

/* ---------- 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: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  padding: var(--sp-2) var(--sp-3) var(--sp-1);
  font-weight: var(--fw-semibold);
}
.chat-todo-list {
  list-style: none;
  margin: 0;
  padding: 0 var(--sp-3) var(--sp-2);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  line-height: var(--lh-normal);
}
.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-block; }
#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: none;
  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-md);
}
.chat-pop.open { display: block; }
.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 ---------- */
.chat-banner {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  padding: var(--sp-1) var(--sp-2);
  margin: var(--sp-1) 0;
  border-radius: var(--r-sm);
  background: var(--bg-elevated-2);
  border-left: 3px solid var(--text-muted);
  color: var(--text-secondary);
}
.chat-banner.info { border-left-color: var(--accent); color: var(--accent); }
.chat-banner.warn { border-left-color: var(--warning); color: var(--warning); }
.chat-banner.err  { border-left-color: var(--danger);  color: var(--danger); }
.chat-banner.ok   { border-left-color: var(--success); color: var(--success); }

/* ---------- 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: var(--fs-base);
  margin-bottom: var(--sp-2);
  line-height: var(--lh-normal);
}
.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: var(--fs-sm);
  font-weight: var(--fw-semibold);
}
.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-lg);
  z-index: var(--z-dropdown);
  display: none;
  padding: 0;                 /* header / footer handle their own padding */
  margin: 0;
  list-style: none;
  font-family: var(--font-sans);
}
.chat-sessions-pop.open { display: block; }

/* 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: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--border-default);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.chat-sessions-pop .sess-head .sess-new {
  background: var(--accent-muted);
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--r-sm);
  padding: 2px var(--sp-2);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  cursor: pointer;
  letter-spacing: 0;
  text-transform: none;
  font-family: var(--font-sans);
}
.chat-sessions-pop .sess-head .sess-new:hover { filter: brightness(1.1); }

/* Search + prev/next toolbar (parity with /analysts threads panel). */
.chat-sessions-pop .sess-toolbar {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px var(--sp-3);
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--border-muted);
}
.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-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.chat-sessions-pop .sess-nav-btn {
  background: var(--bg-elevated-2, var(--bg-elevated));
  border: 1px solid var(--border-muted);
  color: var(--text-primary);
  border-radius: var(--r-sm);
  width: 28px;
  height: 24px;
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  padding: 0;
}
.chat-sessions-pop .sess-nav-btn:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
}
.chat-sessions-pop .sess-nav-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}
.chat-sessions-pop .sess-nav-pos {
  font-size: 11px;
  font-family: var(--font-mono);
  color: var(--text-muted);
  min-width: 3.5em;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* 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-more-wrap {
  padding: var(--sp-2) var(--sp-3);
  border-top: 1px solid var(--border-muted);
}
.chat-sessions-pop .sess-more {
  width: 100%;
  background: var(--bg-elevated-2, var(--bg-elevated));
  color: var(--accent);
  border: 1px solid var(--border-default);
  border-radius: var(--r-sm);
  padding: var(--sp-2) var(--sp-3);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  cursor: pointer;
  font-family: var(--font-sans);
}
.chat-sessions-pop .sess-more:hover:not(:disabled) {
  border-color: var(--accent);
  filter: brightness(1.05);
}
.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: 1px solid var(--border-muted);
}
.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 .s-main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.chat-sessions-pop .s-meta {
  display: flex;
  gap: 8px;
  align-items: center;
  font-size: 10px;
  color: var(--text-muted);
  font-family: var(--font-mono);
}
.chat-sessions-pop .s-when {
  flex: 0 0 auto;
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 10px;
}
.chat-sessions-pop .s-rel {
  opacity: 0.85;
}
.chat-sessions-pop .s-label {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.3;
}
.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 var(--sp-1);
  font-size: var(--fs-md);
  line-height: 1;
  opacity: 0.55;
  transition: color var(--tr-fast), opacity var(--tr-fast), background var(--tr-fast);
  border-radius: var(--r-sm);
}
.chat-sessions-pop li.sess:hover .s-rename,
.chat-sessions-pop li.sess:hover .s-del { opacity: 1; }
.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); }

/* 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);
}
/* Hide the rename pencil while the row is in edit mode (the input owns the row). */
.chat-sessions-pop li.sess.editing .s-rename,
.chat-sessions-pop li.sess.editing .s-del { 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 0.12s ease-out;
}
@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:hover .msg-actions,
.chat-msg:focus-within .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);
}

/* ---------- 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: 0 8px 24px rgba(0, 0, 0, 0.35);
  padding: var(--sp-1) 0;
  margin: 0;
  list-style: none;
  z-index: 10000;
  display: none;
}
.chat-model-pop.open { display: block; }
.chat-model-pop li.grp {
  padding: 4px var(--sp-3) 2px;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  font-weight: 600;
}
.chat-model-pop li.mdl {
  display: flex;
  flex-direction: column;
  padding: 6px var(--sp-3);
  cursor: pointer;
  gap: 1px;
  border-left: 2px solid transparent;
}
.chat-model-pop li.mdl:hover {
  background: var(--bg-elevated-2);
}
.chat-model-pop li.mdl.active {
  border-left-color: var(--accent);
  background: var(--bg-elevated-2);
}
.chat-model-pop li.mdl .m-label {
  font-size: var(--fs-sm);
  color: var(--text-primary);
  font-weight: 500;
}
.chat-model-pop li.mdl.active .m-label { color: var(--accent); }
.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: var(--border-default);
  transform: translateY(-50%);
  opacity: 0;
  transition: opacity 120ms ease;
}
.chat-resizer:hover { background: rgba(127, 127, 127, 0.08); }
.chat-resizer:hover::after { opacity: 0.7; }
body.chat-resizing .chat-resizer { background: rgba(127, 127, 127, 0.16); }
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. */

/* ---------- Window-mode controls (right side of header) ---------- */
.chat-window-controls {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  margin: 0 var(--sp-1);
  padding: 0 var(--sp-1);
  border-left: 1px solid var(--border-muted);
  border-right: 1px solid var(--border-muted);
}
.chat-win-btn {
  appearance: none;
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-muted);
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  line-height: 1;
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.chat-win-btn:hover {
  background: var(--bg-elevated-2);
  color: var(--text-primary);
  border-color: var(--border-default);
}
/* Active mode indicator: highlight whichever mode button matches. */
.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 {
  color: var(--accent);
  border-color: var(--accent-muted);
  background: var(--bg-elevated-2);
}

/* 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) ---------- */
.content-right.mode-float {
  position: fixed;
  top: var(--chat-fy, 80px);
  right: var(--chat-fx, 24px);
  bottom: 24px;
  width: var(--chat-width-user, var(--chat-width));
  height: auto;
  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);
}

/* 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;
  border-radius: var(--r-lg, 12px);
}

/* ---------- 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;
  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 the heavy header buttons to keep the chrome small. */
.content-right.mode-mini #chat-sessions,
.content-right.mode-mini #chat-memory,
.content-right.mode-mini #chat-plan,
.content-right.mode-mini #chat-export,
.content-right.mode-mini .chat-model-wrap,
.content-right.mode-mini #chat-reset {
  display: none;
}
.content-right.mode-mini .chat-panel-title { font-size: var(--fs-sm); }

/* ---------- 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;
}
@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 {
  height: var(--topbar-height);
  max-height: var(--topbar-height);
  min-height: 0;
}
.content-right.shaded.mode-float,
.content-right.shaded.mode-mini {
  height: auto;
}
.content-right.shaded #chat-win-min { background: var(--accent-muted); color: var(--accent); }

/* ---------- 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%; }

/* ---------- Fade-in/out edges on chat-log scroll ---------- */
.chat-log { position: relative; }
.chat-log::before,
.chat-log::after {
  content: "";
  position: sticky;
  left: 0;
  right: 0;
  display: block;
  height: 32px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 240ms ease;
  z-index: 5;
}
.chat-log::before {
  /* Sticky offsets are relative to the scrollport PADDING box, so top:0 would
     sit one top-padding (--sp-4) below the chat-log's border. Pull it up by
     that padding so the fade starts exactly at the top content border. */
  top: calc(-1 * var(--sp-4));
  margin-bottom: -32px;
  background: linear-gradient(to bottom,
    var(--bg-elevated) 0%,
    rgba(0, 0, 0, 0) 100%);
}
.chat-log::after {
  bottom: calc(-1 * var(--sp-3));
  margin-top: -32px;
  background: linear-gradient(to top,
    var(--bg-elevated) 0%,
    rgba(0, 0, 0, 0) 100%);
}
.chat-log.faded-top::before    { opacity: 1; }
.chat-log.faded-bottom::after  { 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, Claude/ChatGPT style) ---------- */
/* Sits as a flex sibling between #chat-log and #chat-usage.
   Fixed height, does not scroll.  Fade-gradient blends into chat log above.
   Iridescent palette + slow shimmer ported from the ticker-page copilot
   so all "AI is working" surfaces share the same visual vocabulary
   (#6c8cff blue → #b07cff purple → #5dd1ff cyan). */
.chat-activity-bar {
  flex-shrink: 0;
  display: none;                          /* hidden until JS adds .active */
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  background:
    linear-gradient(90deg,
      color-mix(in srgb, #6c8cff 10%, transparent) 0%,
      color-mix(in srgb, #b07cff  8%, transparent) 50%,
      color-mix(in srgb, #5dd1ff  8%, transparent) 100%),
    var(--bg-elevated);
  border-top: 1px solid color-mix(in srgb, #6c8cff 22%, transparent);
  border-bottom: 1px solid color-mix(in srgb, #6c8cff 18%, transparent);
  font-family: var(--font-sans, system-ui, -apple-system, sans-serif);
  font-size: 12px;
  line-height: 1.4;
  color: var(--text-default);
  opacity: 0;
  transition: opacity 400ms ease;
  position: relative;
  overflow: hidden;
}
.chat-activity-bar::before {
  /* Slow shimmer sweep — same effect as ticker copilot. */
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(105deg,
    transparent 0%,
    color-mix(in srgb, #b07cff 18%, transparent) 50%,
    transparent 100%);
  background-size: 200% 100%;
  background-position: 200% 0;
  pointer-events: none;
  z-index: 0;
}
.chat-activity-bar.active::before {
  animation: chat-act-shimmer 3.6s ease-in-out infinite;
}
@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 {
  mask-image: linear-gradient(to bottom, black 0%, black 92%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, black 0%, black 92%, transparent 100%);
}

/* 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 .activity-spin {
  display: inline-block;
  width: 14px; height: 14px;
  border-radius: 50%;
  border: none;
  background: conic-gradient(from 0deg,
    #6c8cff, #b07cff, #5dd1ff, #6c8cff);
  mask: radial-gradient(circle, transparent 4px, black 5px);
  -webkit-mask: radial-gradient(circle, transparent 4px, black 5px);
  animation: chat-act-spin 1.1s 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: linear-gradient(135deg, #6c8cff, #b07cff 55%, #5dd1ff);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}
.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;
}
/* 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: 1;
  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;
}

/* ---- 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; }

/* The mobile-only ☰ overflow toggle. Hidden on desktop where every action
 * button fits in the header; shown on phones where the 13+ buttons would
 * wrap onto multiple lines. */
.chat-actions-toggle {
  display: none;
  font-size: 16px;
  line-height: 1;
  padding: 4px 8px;
  flex-shrink: 0;
}

/* ---------- Mobile ---------- */
@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-window-controls { display: none; }
  /* The "≡" drag grip is for float-mode repositioning. Useless on mobile. */
  .chat-drag-grip { display: none; }

  /* Tighten the header to a single fixed-height row — no wrap.
     The action buttons are hidden behind a ☰ toggle so the bar stays
     compact while the chat is in use. */
  .chat-panel-header {
    flex-wrap: nowrap;
    height: var(--topbar-height);
    min-height: var(--topbar-height);
    padding: 4px 10px;
    gap: 6px;
  }
  .chat-panel-title {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: var(--fs-sm);
  }
  /* Show the toggle on mobile. */
  .chat-actions-toggle { display: inline-flex; align-items: center; justify-content: center; }

  /* By default on mobile, hide every action button EXCEPT the always-visible
     close (✕). The toggle button itself is a sibling of .chat-panel-actions
     and isn't affected by this rule. */
  .chat-panel-actions > :not(#chat-close) {
    display: none;
  }
  .chat-panel-actions {
    flex: 0 0 auto;
    gap: 4px;
  }

  /* When the user opens the overflow menu, slide the full action list down
     as a dropdown panel beneath the header. It uses normal wrap so the
     buttons lay out as a grid, not as a horizontal scroll.
     The slide-down animation mirrors the bottom "+" popover so the two
     toggles feel like one cohesive interaction language. */
  .content-right.actions-open .chat-panel-actions {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--bg-elevated);
    border-bottom: 1px solid var(--border-default);
    border-bottom-left-radius: 12px;
    border-bottom-right-radius: 12px;
    padding: 10px;
    flex-wrap: wrap;
    gap: 6px;
    max-height: 60vh;
    overflow-y: auto;
    z-index: 110;
    box-shadow: 0 8px 22px rgba(0,0,0,0.20);
    transform-origin: top center;
    animation: chat-actions-slide-down 0.20s cubic-bezier(0.2, 0.8, 0.25, 1);
  }
  @keyframes chat-actions-slide-down {
    from {
      opacity: 0;
      transform: translateY(-10px) scaleY(0.92);
    }
    to {
      opacity: 1;
      transform: translateY(0) scaleY(1);
    }
  }
  .content-right.actions-open .chat-panel-actions > :not(#chat-close) {
    display: inline-flex;
  }
  /* When dropped down, the close button slides into the panel too instead
     of staying alone in the collapsed header — feels more cohesive. */
  .content-right.actions-open .chat-panel-actions > #chat-close {
    margin-left: auto;
  }
  /* Touch targets: chunky enough to tap reliably on a phone. */
  .chat-panel-actions .chat-panel-btn,
  .chat-panel-actions .chat-win-btn {
    min-height: 36px;
    padding: 6px 10px;
    font-size: var(--fs-sm);
  }
  /* Rotate the toggle when open so the icon reflects state. */
  .content-right.actions-open .chat-actions-toggle {
    transform: rotate(90deg);
    color: var(--accent);
    border-color: var(--accent);
  }
  .chat-actions-toggle { transition: transform 0.18s ease, color 0.18s ease; }

  /* ── Bottom input row — WhatsApp / ChatGPT mobile pattern ─────────────
     Single row: [+] [textarea ──────────] [→]
     The three attach options (file / voice / image) live behind the "+"
     popover so the row stays clean. */
  .chat-input-row {
    flex-wrap: nowrap;
    padding: 8px;
    gap: 6px;
    align-items: flex-end;          /* baseline = textarea bottom */
    position: relative;             /* anchor for the popover */
  }
  .chat-input-wrap {
    flex: 1 1 auto;
    min-width: 0;
  }
  /* Show the "+" toggle on mobile (hidden by default — see desktop rule
     before the media query). Round, 36px, bottom-aligned with the others. */
  .chat-attach-toggle {
    display: inline-flex !important;
    align-self: flex-end;
    flex: 0 0 auto;
    width: 36px;
    height: 36px;
    padding: 0;
    border-radius: 50%;
    background: transparent;
    border: 1px solid var(--border-default);
    color: var(--text-secondary);
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background var(--tr-fast), color var(--tr-fast),
                border-color var(--tr-fast), transform 0.18s ease;
  }
  .chat-attach-toggle:hover {
    background: var(--bg-elevated-2);
    color: var(--text-primary);
    border-color: var(--accent);
  }
  .content-right.attach-open .chat-attach-toggle {
    transform: rotate(45deg);       /* "+" becomes "×" visually */
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
  }

  /* On mobile, hide the inline action-buttons row by default and convert
     it into a popover anchored above the "+" toggle when .attach-open. */
  .chat-input-row > .chat-action-buttons {
    display: none;
  }
  .content-right.attach-open .chat-input-row > .chat-action-buttons {
    display: flex;
    flex-direction: column;
    gap: 4px;
    position: absolute;
    left: 8px;
    bottom: calc(100% + 6px);       /* sit just above the input row */
    background: var(--bg-elevated);
    border: 1px solid var(--border-default);
    border-radius: 12px;
    padding: 6px;
    box-shadow: 0 8px 22px rgba(0,0,0,0.18);
    z-index: 120;
    animation: chat-attach-pop-in 0.14s ease-out;
  }
  @keyframes chat-attach-pop-in {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0); }
  }
  /* Compact icon buttons inside the popover. */
  .content-right.attach-open .chat-input-row .chat-action-buttons .chat-action-btn,
  .content-right.attach-open .chat-input-row button.chat-action-btn {
    width: 40px;
    height: 40px;
    padding: 0;
    border-radius: 10px;
  }
  .content-right.attach-open .chat-input-row .chat-action-buttons .chat-action-btn svg,
  .content-right.attach-open .chat-input-row button.chat-action-btn svg {
    width: 18px;
    height: 18px;
  }

  /* Send: compact 36×36 circular icon-only button, inline. */
  .chat-input-row > button#chat-send,
  #chat-send {
    flex: 0 0 auto;
    align-self: flex-end;
    width: 36px;
    height: 36px;
    min-width: 36px;
    min-height: 36px;
    max-height: 36px;
    padding: 0;
    border-radius: 50%;
    gap: 0;
  }
  #chat-send .send-label { display: none; }
  #chat-send .send-ico   { display: inline-flex; }
  #chat-send .send-ico svg { width: 16px; height: 16px; }

  /* Empty-session pill mode — reduce its huge horizontal padding so the
     phone row doesn't get crushed. */
  .content-right.is-empty-session .chat-input-row {
    padding-left: 12px;
    padding-right: 12px;
  }

  /* Single-line textarea floor on mobile. Desktop ships an 88px floor
     because there's room for multi-line drafting; on a phone that
     mismatches the 36px [+] and [→] buttons and makes them look like
     they're floating at the bottom of an oversized box.
     Setting the floor to 40px makes the textarea start the same height
     as the buttons so everything lines up cleanly. The textarea still
     auto-grows up to max-height as the user types. */
  #chat-input {
    min-height: 40px;
    padding: 9px 10px;
    line-height: 1.3;
  }
  .chat-input-wrap:has(.chat-toolbar:not(.hidden)) #chat-input {
    min-height: 36px;
  }
  /* Make sure the wrap itself doesn't impose extra height. */
  .chat-input-wrap {
    min-height: 40px;
  }
}

/* Desktop default: the "+" toggle is hidden because the three action
   buttons already live inline next to the textarea. The mobile rule
   above flips this with !important inside the @media block. */
.chat-attach-toggle { display: none; }


/* =================================================================
 * 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;
  /* Frosted-glass: bright translucent panel with dark text. */
  background: rgba(255, 255, 255, 0.72);
  -webkit-backdrop-filter: blur(18px) saturate(180%);
  backdrop-filter: blur(18px) saturate(180%);
  color: #1a1f2c;
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: 7px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.85),
    inset 0 0 0 1px rgba(255, 255, 255, 0.25),
    0 4px 14px rgba(0, 0, 0, 0.12),
    0 1px 2px rgba(0, 0, 0, 0.10);
  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: #0b1020;
  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: #2a3142;
  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-theme tooltip: deep ink panel with bright text + subtle accent ring.
 *    Replaces the white-frosted look that turned dull-gray under dark mode. -- */
[data-theme="dark"] .oc-tip {
  background:
    linear-gradient(180deg, rgba(35, 39, 55, 0.92) 0%, rgba(22, 25, 36, 0.92) 100%);
  -webkit-backdrop-filter: blur(18px) saturate(160%);
          backdrop-filter: blur(18px) saturate(160%);
  color: #e9ecf3;
  border: 1px solid rgba(138, 180, 255, 0.22);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.06),
    inset 0 0 0 1px rgba(255, 255, 255, 0.03),
    0 8px 24px rgba(0, 0, 0, 0.55),
    0 1px 2px rgba(0, 0, 0, 0.40);
}
[data-theme="dark"] .oc-tip-title { color: #f4f6fb; }
[data-theme="dark"] .oc-tip-body  { color: #c8ccd6; }
[data-theme="dark"] .oc-tip-kbd {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.12);
  color: #c8ccd6;
}
[data-theme="dark"] .oc-tip-body code {
  background: rgba(192, 132, 252, 0.10);
  border-color: rgba(192, 132, 252, 0.25);
  color: #d6b8ff;
}
[data-theme="dark"] .oc-tip-arrow {
  background: rgba(28, 32, 46, 0.92);
  border-color: rgba(138, 180, 255, 0.22);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  [data-theme="dark"] .oc-tip { background: rgba(28, 32, 46, 0.98); }
  [data-theme="dark"] .oc-tip-arrow { background: rgba(28, 32, 46, 0.98); }
}

/* ==========================================================================
   Rich render output (charts, widgets, tables) injected by generation tools
   ========================================================================== */
.chat-render {
  margin: var(--sp-3, 12px) 0;
  border: 1px solid var(--border-default, #e2e8f0);
  border-radius: var(--r-lg, 10px);
  overflow: hidden;
  background: var(--bg-base, #fff);
}

.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) */
.content-right.mode-dock {
  transition: width 0.3s ease-in-out, min-width 0.3s ease-in-out;
}

/* 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;
}

/* Slide header smoothly off to the right when collapsed */
.content-right.mode-dock.auto-collapsed .chat-panel-header {
  transform: translateX(100%);
  transition: transform 0.3s ease-in-out;
  pointer-events: none;
}
.content-right.mode-dock .chat-panel-header {
  transition: transform 0.3s ease-in-out;
  will-change: transform;
}

/* Hover restores full size + slides the header back smoothly */
.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 {
  transform: translateX(0);
  transition: transform 0.3s ease-in-out;
  pointer-events: auto;
}

/* 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 {
  transform: translateX(0) !important;
  pointer-events: auto !important;
}

/* Mobile: completely disable auto-collapse (no width override, no slide) */
@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 {
    transform: translateX(0) !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: 24px;
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.25;
}
.chat-empty-welcome .cew-sub {
  font-size: 13px;
  color: var(--text-secondary);
  max-width: 42ch;
  line-height: 1.55;
}
.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: 13px;
  font-weight: 500;
  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. */
.content-right.is-empty-session #chat-activity-bar,
.content-right.is-empty-session #chat-todos,
.content-right.is-empty-session #chat-usage,
.content-right.is-empty-session #chat-status {
  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;
}

/* ---------- Floating-mode backdrop ----------
 * When the chat is detached (float / mini, not collapsed), blur and dim the
 * rest of the app so attention lands on the floating panel. The backdrop is
 * a body-level pseudo-element that sits under the panel (z=9000) and over
 * everything else. Click-through preserved via pointer-events:none. */
body:has(.content-right.mode-float:not(.collapsed))::before,
body:has(.content-right.mode-mini:not(.collapsed))::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 8990;
  pointer-events: none;
  background: rgba(0, 0, 0, 0.28);
  -webkit-backdrop-filter: blur(6px) saturate(0.95);
          backdrop-filter: blur(6px) saturate(0.95);
  animation: oceanus-chat-backdrop-in 180ms ease forwards;
}
@keyframes oceanus-chat-backdrop-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* While the panel is mid-genie-close, fade the backdrop out in step. */
body:has(.content-right.mode-float.closing)::before,
body:has(.content-right.mode-mini.closing)::before {
  animation: oceanus-chat-backdrop-out 240ms ease forwards;
}
@keyframes oceanus-chat-backdrop-out {
  from { opacity: 1; }
  to   { opacity: 0; }
}
/* Respect reduced motion / no-blur preferences. */
@media (prefers-reduced-motion: reduce) {
  body:has(.content-right.mode-float:not(.collapsed))::before,
  body:has(.content-right.mode-mini:not(.collapsed))::before { animation: none; }
}

/* =========================================================================
   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 {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin: 0 2px;
  padding: 0 6px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  font-family: var(--font-sans);
  vertical-align: baseline;
  line-height: 16px;
  height: 16px;
  border: 1px solid transparent;
}
.conf-badge--high {
  background: color-mix(in srgb, #4caf50 18%, transparent);
  color: #58c267;
  border-color: color-mix(in srgb, #4caf50 40%, transparent);
}
.conf-badge--med {
  background: color-mix(in srgb, #f5a623 16%, transparent);
  color: #f0a924;
  border-color: color-mix(in srgb, #f5a623 40%, transparent);
}
.conf-badge--low {
  background: color-mix(in srgb, #ff6363 16%, transparent);
  color: #ff7e7e;
  border-color: color-mix(in srgb, #ff6363 40%, transparent);
}

/* ---------- 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: underline; }

/* ---------- 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 {
  background: color-mix(in srgb, var(--bg-elevated) 94%, var(--bg-base));
}
