/* CSS Reset and Base Styles */
* {
  box-sizing: border-box;
}

html {
  height: 100%;
  height: 100dvh;
  overflow: hidden;
}

body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  font-family: var(--font-sans);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  letter-spacing: -0.01em;
  color: var(--text-primary);
  background: var(--bg-secondary);
}

/* #root hosts the React tree. Make it a flex column so the top banner
   (when present) can sit at the top and push the app-container down. */
#root {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}

/* CSS Variables */
:root {
  --font-sans:
    -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, Roboto, "Helvetica Neue", Arial,
    sans-serif;
  --font-mono:
    /* Lead with the ui-monospace generic and the PostScript name
       SFMono-Regular. The bare "SF Mono" family name can resolve to a
       bold/heavy face in browsers (SF Mono isn't a normally-installed font; it
       lives inside Terminal.app), so inline code rendered as "SF Mono" looks
       heavy on macOS. ui-monospace / SFMono-Regular pick the proper regular
       weight. */
    ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, "Cascadia Code", "Roboto Mono",
    Consolas, "Courier New", monospace;
  --primary: #2563eb;
  --primary-dark: #1d4ed8;
  --bg-base: #ffffff;
  --bg-secondary: #f9fafb;
  --bg-tertiary: #f3f4f6;
  --bg-hover: #f3f4f6;
  --border: #e5e7eb;
  --code-bg: #eceef2;
  --user-message-text: #2563eb;
  --text-primary: #111827;
  --text-secondary: #6b7280;
  --text-tertiary: #9ca3af;
  --success-bg: #f0fdf4;
  --success-border: #bbf7d0;
  --success-text: #166534;
  --error-bg: #fef2f2;
  --error-border: #fecaca;
  --error-text: #991b1b;
  --warning-bg: #fffbeb;
  --warning-border: #fcd34d;
  --warning-text: #92400e;
  --blue-bg: #eff6ff;
  --blue-border: #bfdbfe;
  --blue-text: #1e40af;
  --link-color: #2563eb;
  --green-600: #16a34a;
  --green-700: #15803d;
  --gray-50: #f9fafb;
  --gray-100: #f3f4f6;
  --gray-200: #e5e7eb;
  --gray-300: #d1d5db;
  --gray-400: #9ca3af;
  --gray-500: #6b7280;
  --gray-600: #4b5563;
  --gray-700: #374151;
  --gray-800: #1f2937;
  --gray-900: #111827;
}

.dark {
  --bg-base: #1f2937;
  --bg-secondary: #111827;
  --bg-tertiary: #374151;
  --bg-hover: #374151;
  --border: #374151;
  --code-bg: #414a59;
  --user-message-text: #60a5fa;
  --text-primary: #f9fafb;
  --text-secondary: #9ca3af;
  --text-tertiary: #6b7280;
  --success-bg: rgba(34, 197, 94, 0.1);
  --success-border: rgba(34, 197, 94, 0.3);
  --success-text: #86efac;
  --error-bg: rgba(239, 68, 68, 0.1);
  --error-border: rgba(239, 68, 68, 0.3);
  --error-text: #fca5a5;
  --warning-bg: rgba(251, 191, 36, 0.15);
  --warning-border: #fbbf24;
  --warning-text: #fcd34d;
  --blue-bg: rgba(59, 130, 246, 0.1);
  --blue-border: rgba(59, 130, 246, 0.3);
  --blue-text: #93c5fd;
  --link-color: #60a5fa;
}

/* Layout */
.app-container {
  display: flex;
  flex: 1;
  min-height: 0;
  background: var(--bg-secondary);
  position: relative;
  overflow: hidden;
}

.main-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.screen-height {
  height: 100vh; /* Fallback for older browsers */
  height: 100dvh;
}

.full-height {
  height: 100%;
}

/* Flexbox utilities */
.flex {
  display: flex;
}

.flex-col {
  flex-direction: column;
}

.flex-1 {
  flex: 1;
}

.items-center {
  align-items: center;
}

.justify-center {
  justify-content: center;
}

.justify-between {
  justify-content: space-between;
}

.space-x-2 > * + * {
  margin-left: 0.5rem;
}

.space-x-3 > * + * {
  margin-left: 0.75rem;
}

.space-y-2 > * + * {
  margin-top: 0.5rem;
}

.space-y-3 > * + * {
  margin-top: 0.75rem;
}

.space-y-4 > * + * {
  margin-top: 1rem;
}

/* Text */
.text-center {
  text-align: center;
}

.text-sm {
  font-size: 0.875rem;
  line-height: 1.6;
}

.text-xs {
  font-size: 0.75rem;
  line-height: 1.4;
}

.text-lg {
  font-size: 1.25rem;
  line-height: 1.6;
}

.font-medium {
  font-weight: 500;
}

.font-semibold {
  font-weight: 600;
}

.italic {
  font-style: italic;
}

.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.break-words {
  word-break: break-word;
}

.break-all {
  word-break: break-all;
}

.whitespace-pre-wrap {
  white-space: pre-wrap;
}

/* Colors */
.text-primary {
  color: var(--text-primary);
}

.text-secondary {
  color: var(--text-secondary);
}

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

.text-white {
  color: white;
}

.text-error {
  color: var(--error-text);
}

.text-success {
  color: var(--success-text);
}

.text-blue {
  color: var(--blue-text);
}

.bg-primary {
  background: var(--primary);
}

.bg-base {
  background: var(--bg-base);
}

.bg-secondary {
  background: var(--bg-secondary);
}

/* Buttons */
/* Migrated PrimeVue <Button>s inherit the legacy .btn-* letter-spacing so text
   buttons match the un-migrated ones exactly. (PrimeVue has no letter-spacing
   token, so it lives here.) */
.p-button {
  letter-spacing: -0.01em;
}
/* Bare-element reset for legacy native <button>s. Wrapped in :where() so it has
   ZERO specificity: it still resets plain <button>s but loses to the .btn-*
   design-system classes (otherwise the reset would strip their chrome). The
   :not(.p-button) keeps it from touching PrimeVue <Button>s at all — styles.css
   is unlayered and would otherwise beat PrimeVue's layered .p-button rules. */
:where(button:not(.p-button)) {
  font-family: inherit;
  cursor: pointer;
  border: none;
  background: none;
  padding: 0;
  color: inherit;
}

.btn {
  padding: 0.5rem 0.75rem;
  border-radius: 0.25rem;
  /* The global button reset inherits font-family but not font-size, so
     unstyled buttons fall back to the browser default (13.33px). Pin the
     styled button classes to the app's standard 14px UI size. */
  font-size: 0.875rem;
  transition: background-color 0.2s;
}

.btn:hover {
  background: var(--bg-tertiary);
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-primary {
  padding: 0.5rem 1rem;
  background: var(--primary);
  color: white;
  border-radius: 0.25rem;
  font-size: 0.875rem;
  font-weight: 500;
  transition: background-color 0.2s;
  letter-spacing: -0.01em;
}

.btn-primary:hover:not(:disabled) {
  background: var(--primary-dark);
}

.btn-primary:disabled {
  background: var(--gray-300);
  cursor: not-allowed;
}

.dark .btn-primary:disabled {
  background: var(--gray-600);
}

.btn-secondary {
  padding: 0.5rem 1rem;
  background: var(--bg-secondary);
  color: var(--text-primary);
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  font-size: 0.875rem;
  font-weight: 500;
  transition: background-color 0.2s;
  letter-spacing: -0.01em;
}

.btn-secondary:hover:not(:disabled) {
  background: var(--bg-tertiary);
}

.btn-secondary:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-sm {
  padding: 0.375rem 0.75rem;
  font-size: 0.875rem;
}

.btn-icon {
  padding: 0.5rem;
  border-radius: 0.375rem;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.2s;
}

.btn-icon:hover {
  background: var(--bg-tertiary);
}

.btn-icon-sm {
  padding: 0.25rem;
  border-radius: 0.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    background-color 0.2s,
    opacity 0.2s;
  opacity: 0.4;
  color: var(--text-secondary);
}

.btn-icon-sm:hover {
  background: var(--gray-200);
  opacity: 1;
}

.dark .btn-icon-sm:hover {
  background: var(--gray-600);
}

.conversation-item:hover .btn-icon-sm {
  opacity: 0.7;
}

.conversation-item.active .btn-icon-sm {
  color: rgba(255, 255, 255, 0.8);
  opacity: 0.7;
}

.conversation-item.active .btn-icon-sm:hover {
  background: rgba(255, 255, 255, 0.2);
  color: white;
  opacity: 1;
}

.btn-icon-sm.btn-danger:hover {
  background: var(--red-600);
  color: white;
  opacity: 1;
}

.btn-new {
  width: 2rem;
  height: 2rem;
  background: var(--text-primary);
  color: var(--bg-base);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.2s;
}

.btn-new:hover {
  background: var(--text-secondary);
}

/* Header */
.app-bar-title {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 1rem;
  font-weight: 600;
  line-height: 2rem;
  letter-spacing: -0.02em;
}

.header {
  flex: 0 0 auto;
  background: var(--bg-base);
  border-bottom: 1px solid var(--border);
  padding: 0.5rem 1rem;
  padding-top: calc(0.5rem + env(safe-area-inset-top, 0px));
  padding-left: max(1rem, env(safe-area-inset-left));
  padding-right: max(1rem, env(safe-area-inset-right));
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-width: 0; /* Allow shrinking below content size */
  flex: 1 1 auto;
  overflow: hidden;
}

.header-title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0; /* Never shrink the actions */
}

/* Top-of-page banner. A full-width bar pinned to the very top of the
   viewport; the rest of the app sits below it (see #root flex column).
   Pairs with the `banner` field in init data. */
.top-banner {
  flex: 0 0 auto;
  background: #b45309; /* amber-700 */
  color: #fff;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  padding: 0.35rem 0.75rem;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Drawer/Sidebar */
.drawer {
  position: fixed;
  inset: 0 auto 0 0;
  z-index: 50;
  width: 20rem;
  max-width: calc(100vw - 3rem); /* Ensure drawer doesn't fill entire screen on mobile */
  background: var(--bg-base);
  border-right: 1px solid var(--border);
  color: var(--text-primary);
  display: flex;
  flex-direction: column;
  height: 100%;
  height: 100dvh;
  transform: translateX(-100%);
  transition: transform 0.3s ease;
  padding-top: env(safe-area-inset-top);
  padding-left: env(safe-area-inset-left);
  padding-bottom: env(safe-area-inset-bottom);
}

.drawer.open {
  transform: translateX(0);
}

.drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  border-bottom: 1px solid var(--border);
}

.drawer-header-actions {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  flex-shrink: 0;
}

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

.drawer-body {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
}

/* Drawer search bar (FTS over slug + message content). */
.drawer-search {
  position: relative;
  display: flex;
  align-items: center;
  padding: 0 1rem 0.5rem;
}

.drawer-search-icon {
  position: absolute;
  left: 1.625rem;
  color: var(--text-secondary);
  pointer-events: none;
}

.drawer-search-input {
  flex: 1;
  padding: 0.4rem 1.75rem 0.4rem 2.1rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  color: var(--text);
  font-size: 0.875rem;
  outline: none;
}

.drawer-search-input:focus {
  border-color: var(--accent, #4a90e2);
}

.drawer-search-clear {
  position: absolute;
  right: 1.4rem;
  background: none;
  border: none;
  color: var(--text-secondary);
  cursor: pointer;
  font-size: 0.875rem;
  padding: 0.15rem 0.35rem;
  line-height: 1;
}

.drawer-search-clear:hover {
  color: var(--text);
}

/* Snippet shown in place of the preview for FTS search results.
   Wraps to two lines (instead of the single-line preview) so the
   highlighted match has a real chance of staying on screen. */
.conversation-snippet {
  font-style: italic;
  opacity: 0.85;
  white-space: normal;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  word-break: break-word;
  overflow-wrap: anywhere;
}

.conversation-snippet-mark {
  background: #fff4a3;
  color: #000;
  padding: 0 1px;
  border-radius: 2px;
  font-style: normal;
  font-weight: 600;
}

.dark .conversation-snippet-mark {
  background: #b08400;
  color: #fff;
}

.drawer-section {
  padding: 1rem;
  border-bottom: 1px solid var(--border);
}

.drawer-footer {
  padding: 1rem;
}

/* Backdrop */
.backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 40;
}

/* Group By */
.group-by-wrapper {
  position: relative;
}

.btn-icon.group-by-active {
  color: var(--primary);
}

.btn-icon.search-toggle-active {
  color: var(--primary);
}

.group-by-menu {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 50;
  margin-top: 0.25rem;
  min-width: 8rem;
  padding: 0.25rem;
  border-radius: 0.375rem;
  border: 1px solid var(--border);
  background: var(--bg-secondary);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.group-by-menu-item {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  width: 100%;
  padding: 0.375rem 0.625rem;
  border: none;
  border-radius: 0.25rem;
  background: none;
  color: var(--text-primary);
  font-size: 0.875rem;
  text-align: left;
  cursor: pointer;
}

.group-by-menu-icon {
  width: 0.875rem;
  height: 0.875rem;
  flex-shrink: 0;
}

.group-by-menu-separator {
  height: 1px;
  margin: 0.25rem 0.25rem;
  background: var(--border);
}

@keyframes conversationItemEnter {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.conversation-item-enter {
  animation: conversationItemEnter 180ms ease-out;
}

.group-by-menu-item:hover {
  background: var(--bg-tertiary);
}

.group-by-menu-item.active {
  font-weight: 600;
  color: var(--primary);
}

/* Conversation Groups */
.conversation-group {
  margin-bottom: 0.25rem;
}

.conversation-group + .conversation-group {
  margin-top: 0.375rem;
}

.conversation-group-header {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  width: 100%;
  padding: 0.375rem 0.75rem;
  border: none;
  background: var(--bg-tertiary);
  border-radius: 0.375rem;
  color: var(--text-secondary);
  font-size: 0.75rem;
  font-weight: 600;
  cursor: pointer;
  text-align: left;
  letter-spacing: 0.02em;
}

.conversation-group-header:hover {
  background: var(--bg-secondary);
  color: var(--text-primary);
}

.conversation-group-chevron {
  width: 0.75rem;
  height: 0.75rem;
  flex-shrink: 0;
  transition: transform 0.15s ease;
}

.conversation-group-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.conversation-group-count {
  flex-shrink: 0;
  color: var(--text-tertiary);
  font-weight: 400;
}

/* Conversation List */
.conversation-list {
  padding: 0.5rem;
}

.conversation-item {
  width: 100%;
  text-align: left;
  padding: 0.75rem;
  border-radius: 0.5rem;
  margin-bottom: 0.25rem;
  transition: background-color 0.2s;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.25rem;
}

.conversation-item:hover {
  background: var(--bg-tertiary);
}

.conversation-item.active {
  background: var(--primary);
  color: white;
}

/* Pinned draft entry that represents the not-yet-created new conversation.
   Styled like a regular conversation item; the slug-like title is italicized
   to signal that it's a placeholder (no real slug yet). */
.conversation-title-draft {
  font-style: italic;
}

.conversation-item .conversation-title {
  font-weight: 500;
  font-size: 0.875rem;
  word-break: break-all;
}

.conversation-item .conversation-preview {
  font-size: 0.75rem;
  color: var(--text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  margin-top: 0.125rem;
}

.conversation-item.active .conversation-preview {
  color: rgba(255, 255, 255, 0.8);
}

.conversation-item .conversation-meta {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.75rem;
  color: var(--text-tertiary);
  min-width: 0;
}

.conversation-item .conversation-date {
  flex-shrink: 0;
}

.conversation-item.active .conversation-meta {
  color: rgba(255, 255, 255, 0.8);
}

.conversation-item .conversation-cwd {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  opacity: 0.8;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: left;
  min-width: 0;
}

.subagent-count-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.125rem;
  font-size: 0.75rem;
  padding: 0 0.25rem;
  border-radius: 0.25rem;
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  border: none;
  cursor: pointer;
  line-height: 1.4;
  transition: background-color 0.15s;
  margin-left: auto;
  flex-shrink: 0;
}

.subagent-count-badge:hover {
  background: var(--gray-200);
  color: var(--text-primary);
}

.dark .subagent-count-badge:hover {
  background: var(--gray-600);
}

.conversation-item.active .subagent-count-badge {
  background: rgba(255, 255, 255, 0.15);
  color: rgba(255, 255, 255, 0.8);
}

.conversation-item.active .subagent-count-badge:hover {
  background: rgba(255, 255, 255, 0.25);
  color: white;
}

/* Messages */
.messages-container {
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: 1rem;
  padding-left: max(1rem, env(safe-area-inset-left));
  padding-right: max(1rem, env(safe-area-inset-right));
}

.messages-list {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

/* Off-screen rendering containment. Applied per *chunk* of ~50 rendered rows
   (see chunkRenderNodes in ChatInterface.vue), not per row and not per
   generation section. Granularity is critical for WebKit typing performance
   in huge conversations: one giant content-visibility box (a whole generation
   section) is always partially visible, can never be skipped, and costs
   150-200ms of containment bookkeeping per composite; per-row boxes make every
   frame re-check thousands of viewport-relevancy candidates. Chunked, both
   costs collapse (~16ms/frame while typing). */
.messages-chunk {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  content-visibility: auto;
  /* ~50 rows x 80px estimate; `auto` remembers the real laid-out size after
     first paint so the estimate only matters for never-visited chunks. */
  contain-intrinsic-size: auto 4000px;
}

.messages-bottom-sentinel {
  height: 1px;
}

.message {
  display: flex;
  flex-direction: column;
}

.message-content {
  padding: 1rem;
  border-radius: 0.5rem;
  overflow-wrap: break-word;
  word-wrap: break-word;
  min-width: 0;
  font-size: 0.9375rem;
}

.message-user .message-content {
  margin-left: auto;
  max-width: 80%;
  color: var(--user-message-text);
}

/* Author email label, shown on user messages when multiple users have
   participated in the conversation. Right-aligned to match user bubbles. */
.message-author-email {
  font-size: 0.75rem;
  color: var(--text-secondary);
  opacity: 0.8;
  margin-bottom: 0.25rem;
  text-align: right;
  overflow-wrap: anywhere;
}

.message-agent .message-content,
.message-tool .message-content {
  margin-right: auto;
  max-width: 100%;
  color: var(--text-primary);
}

.thinking-indicator {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  color: var(--text-secondary);
  font-size: 0.875rem;
  margin: 0.25rem 0 0.75rem 0;
  padding-left: 0.5rem;
}

.thinking-dots {
  display: inline-flex;
  gap: 0.2rem;
  font-size: 1.25rem;
  letter-spacing: 0.15rem;
  color: var(--blue-text);
}

.thinking-dots span {
  animation: thinking-dot 1.2s infinite ease-in-out;
  opacity: 0.25;
}

.thinking-dots span:nth-child(2) {
  animation-delay: 0.2s;
}

.thinking-dots span:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes thinking-dot {
  0%,
  80%,
  100% {
    opacity: 0.25;
    transform: translateY(0);
  }
  40% {
    opacity: 1;
    transform: translateY(-0.2rem);
  }
}

.message-error .message-content {
  margin-right: auto;
  max-width: 100%;
  background: var(--error-bg);
  border: 2px solid var(--error-border);
  color: var(--error-text);
}

.error-retry-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 0.5rem;
}

.error-retry-button {
  background: var(--error-text, #b91c1c);
  color: white;
  border: none;
  border-radius: 4px;
  padding: 0.25rem 0.75rem;
  font-size: 0.875rem;
  cursor: pointer;
  font-weight: 500;
}

.error-retry-button:hover:not(:disabled) {
  opacity: 0.9;
}

.error-retry-button:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.error-retry-error {
  font-size: 0.8125rem;
  color: var(--error-text);
  opacity: 0.85;
}

.message-warning .message-content {
  margin-right: auto;
  max-width: 100%;
  background: var(--warning-bg);
  border: 1px solid var(--warning-border);
  color: var(--warning-text);
  padding: 0.5rem 0.75rem;
  font-size: 0.875rem;
}

.message-timestamp-row {
  display: flex;
  justify-content: center;
  padding: 0.375rem 0 0.125rem;
  pointer-events: none;
}

.message-timestamp {
  font-size: 0.6875rem;
  color: var(--text-secondary);
  opacity: 0.5;
  line-height: 1.2;
  user-select: none;
  pointer-events: none;
  transition: opacity 0.15s ease;
  letter-spacing: 0.02em;
}

.message-timestamp:hover {
  opacity: 0.95;
}

.message-day-separator {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0.75rem 0 0.25rem;
  color: var(--text-secondary);
  font-size: 0.75rem;
  opacity: 0.6;
  user-select: none;
}

.message-day-separator::before,
.message-day-separator::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--border-color, var(--text-secondary));
  opacity: 0.25;
}

.message-day-separator span {
  white-space: nowrap;
}

.context-token-marker {
  display: flex;
  justify-content: center;
  padding: 0.25rem 0 0.125rem;
  pointer-events: none;
}

.context-token-marker span {
  font-size: 0.625rem;
  color: var(--text-secondary);
  opacity: 0.45;
  line-height: 1.2;
  user-select: none;
  pointer-events: auto;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* Tool Display */
.tool-use {
  background: var(--blue-bg);
  border: 1px solid var(--blue-border);
  border-radius: 0.5rem;
  padding: 0.75rem;
  margin: 0.5rem 0;
}

.tool-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.tool-name {
  font-weight: 500;
  color: var(--blue-text);
}

.tool-input {
  font-size: 0.875rem;
  font-family: var(--font-mono);
  background: var(--gray-100);
  border-radius: 0.25rem;
  padding: 0.5rem;
  overflow-wrap: break-word;
  word-break: break-all;
  white-space: pre-wrap;
}

.dark .tool-input {
  background: var(--gray-800);
}

.tool-result-details {
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  margin: 0.5rem 0;
}

.tool-result-details.error {
  border-color: var(--error-border);
}

.tool-result-summary {
  cursor: pointer;
  padding: 0.5rem 0.75rem;
  border-radius: 0.5rem;
  transition: background-color 0.2s;
  background: var(--bg-tertiary);
}

.tool-result-summary:hover {
  background: var(--bg-secondary);
}

.tool-result-details.error .tool-result-summary {
  background: var(--error-bg);
  color: var(--error-text);
}

.tool-result-content {
  padding: 0.75rem;
  padding-top: 0;
}

.tool-result-section {
  background: var(--blue-bg);
  border: 1px solid var(--blue-border);
  border-radius: 0.25rem;
  padding: 0.5rem;
  margin-top: 0.75rem;
}

.tool-result-section.output {
  background: var(--success-bg);
  border-color: var(--success-border);
}

.tool-result-section.error.output {
  background: var(--error-bg);
  border-color: var(--error-border);
}

.tool-result-label {
  font-size: 0.75rem;
  font-weight: 500;
  margin-bottom: 0.25rem;
  color: var(--blue-text);
}

.tool-result-section.output .tool-result-label {
  color: var(--success-text);
}

.tool-result-section.error.output .tool-result-label {
  color: var(--error-text);
}

.tool-result-data {
  font-size: 0.875rem;
  font-family: var(--font-mono);
  overflow-wrap: break-word;
  word-break: break-all;
  white-space: pre-wrap;
}

.tool-result-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.tool-result-status {
  font-size: 0.75rem;
}

.tool-result-status.success {
  color: var(--success-text);
}

.tool-result-status.error {
  color: var(--error-text);
}

.tool-result-time {
  font-size: 0.75rem;
  color: var(--text-tertiary);
}

/* Tool running state */
.tool-running {
  background: var(--blue-bg);
  border: 1px solid var(--blue-border);
  border-radius: 0.5rem;
  padding: 0.75rem;
  margin: 0.5rem 0;
}

.tool-running-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.tool-status-running {
  font-size: 0.875rem;
  color: var(--text-secondary);
  font-style: italic;
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
}

/* Completed specialized tool cards mount only when they approach the viewport.
 * These blank shells preserve the approximate outer block geometry (including
 * the card's 0.5rem vertical margins) without mounting any tool interior. */
.tool-card-mount-placeholder {
  --tool-card-placeholder-outer-size: 76px;
  box-sizing: border-box;
  block-size: calc(var(--tool-card-placeholder-outer-size) - 1rem);
  margin: 0.5rem 0;
  width: 100%;
  border-radius: 0.5rem;
  background: var(--gray-100);
  contain: strict;
  contain-intrinsic-block-size: calc(var(--tool-card-placeholder-outer-size) - 1rem);
  pointer-events: none;
}

.dark .tool-card-mount-placeholder {
  background: var(--gray-800);
}

.tool-card-mount-placeholder--bash {
  --tool-card-placeholder-outer-size: 68px;
}

.tool-card-mount-placeholder--output-iframe {
  --tool-card-placeholder-outer-size: 84px;
}

.tool-card-mount-placeholder--patch,
.tool-card-mount-placeholder--media {
  --tool-card-placeholder-outer-size: 282px;
}

/* Tool Component (shared styles for all tools) */
.tool {
  background: var(--gray-100);
  border-radius: 0.5rem;
  margin: 0.5rem 0;
  width: 100%;
}

.dark .tool {
  background: var(--gray-800);
}

.tool-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  cursor: pointer;
  user-select: none;
}

.tool-header:hover {
  background: rgba(0, 0, 0, 0.02);
  border-radius: 0.5rem;
}

.dark .tool-header:hover {
  background: rgba(255, 255, 255, 0.02);
}

.tool-summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1;
  min-width: 0;
}

.tool-emoji {
  font-size: 1rem;
  flex-shrink: 0;
}

.tool-emoji.running {
}

.tool-command {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tool-running {
  font-size: 0.75rem;
  color: var(--text-secondary);
  font-style: italic;
  flex-shrink: 0;
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

.tool-success {
  color: var(--success-text);
  font-size: 0.875rem;
  flex-shrink: 0;
}

.tool-error {
  color: var(--error-text);
  font-size: 0.875rem;
  flex-shrink: 0;
}

.tool-badge {
  font-size: 0.7rem;
  padding: 0.1rem 0.4rem;
  border-radius: 0.25rem;
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  font-weight: 500;
  white-space: nowrap;
}

.subagent-model-badge {
  background: var(--bg-tertiary);
  color: var(--text-tertiary);
  font-family: var(--font-mono);
  font-size: 0.65rem;
}

.tool-toggle {
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
  flex-shrink: 0;
}

.tool-toggle:hover {
  color: var(--text-primary);
}

.tool-details {
  padding: 0 1rem 0.75rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.tool-section {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* llm_one_shot image previews sit outside the collapsible .tool-details so
 * they are visible even when the card is collapsed. */
.llm-one-shot-images {
  padding: 0 1rem 0.75rem 1rem;
}

.tool-label {
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.tool-time {
  font-size: 0.75rem;
  color: var(--text-tertiary);
  font-weight: 400;
}

.tool-code {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  background: var(--bg-base);
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  padding: 0.75rem;
  margin: 0;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--text-primary);
}

/* Error output is signalled by the ✗ status icon in the header, not by
 * painting the whole output box red, so `.tool-code.error` carries no
 * styling (it intentionally renders like a normal code block). */

/* Bash Tool Component - uses shared tool styles */
.bash-tool {
  /* Alias for backwards compatibility */
  background: var(--gray-100);
  border-radius: 0.5rem;
  margin: 0.5rem 0;
  width: 100%;
}

.dark .bash-tool {
  background: var(--gray-800);
}

.bash-tool-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  cursor: pointer;
  user-select: none;
}

.bash-tool-header:hover {
  background: rgba(0, 0, 0, 0.02);
  border-radius: 0.5rem;
}

.dark .bash-tool-header:hover {
  background: rgba(255, 255, 255, 0.02);
}

.bash-tool-summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1;
  min-width: 0;
}

.bash-tool-emoji {
  font-size: 1rem;
  flex-shrink: 0;
}

.bash-tool-emoji.running {
}

.bash-tool-command {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex-shrink: 1;
  min-width: 0;
}

.bash-tool-cwd {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--text-tertiary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex-shrink: 0;
  max-width: 30%;
}

.bash-tool-running {
  font-size: 0.75rem;
  color: var(--text-secondary);
  font-style: italic;
  flex-shrink: 0;
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

.bash-tool-success {
  color: var(--success-text);
  font-size: 0.875rem;
  flex-shrink: 0;
}

.bash-tool-error {
  color: var(--error-text);
  font-size: 0.875rem;
  flex-shrink: 0;
}

.bash-tool-cancelled {
  color: var(--error-text);
  font-size: 0.875rem;
  flex-shrink: 0;
}

.bash-tool-toggle {
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
  flex-shrink: 0;
}

.bash-tool-toggle:hover {
  color: var(--text-primary);
}

.bash-tool-details {
  padding: 0 1rem 0.75rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.bash-tool-section {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.bash-tool-label {
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.bash-tool-time {
  font-size: 0.75rem;
  color: var(--text-tertiary);
  font-weight: 400;
}

.bash-tool-code {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  background: var(--bg-base);
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  padding: 0.75rem;
  margin: 0;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--text-primary);
}

/* See note on .tool-code.error: error output boxes get no red fill. */

.bash-tool-streaming {
  max-height: 300px;
  overflow-y: auto;
  border-color: var(--accent-primary);
  background: var(--bg-base);
}

/* Compact streaming preview shown below the header while a tool is running */
.bash-tool-preview {
  padding: 0 1rem 0.75rem;
}

.bash-tool-preview-code {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  line-height: 1.4;
  color: var(--text-secondary);
  background: var(--bg-base);
  border: 1px solid var(--accent-primary);
  border-radius: 0.25rem;
  padding: 0.5rem 0.75rem;
  margin: 0;
  max-height: 10rem;
  overflow-y: auto;
  white-space: pre-wrap;
  word-break: break-word;
}

.bash-tool-preview-more {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 0.75rem;
  color: var(--accent-primary);
  padding: 0.25rem 0 0;
  font-family: var(--font-mono);
}

.bash-tool-preview-more:hover {
  text-decoration: underline;
}

/* Streaming cursor animation */
.streaming-cursor {
  animation: blink 1s step-end infinite;
  color: var(--accent-primary);
}

@keyframes blink {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
}

/* Streaming message preview */
.streaming-message {
  opacity: 0.85;
}

.streaming-message .message-content {
  min-height: 1.5em;
}

/* Streamed markdown: blinking cursor follows the rendered content. */
.streaming-markdown .streaming-cursor {
  margin-left: 0.15em;
}

/* Patch Tool */
.patch-tool {
  background: var(--gray-100);
  border-radius: 0.5rem;
  margin: 0.5rem 0;
  width: 100%;
  /* Performance: isolate layout/paint for each patch tool */
  contain: layout style;
}

.dark .patch-tool {
  background: var(--gray-800);
}

.patch-tool-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  cursor: pointer;
  user-select: none;
}

.patch-tool-header:hover {
  background: rgba(0, 0, 0, 0.02);
  border-radius: 0.5rem;
}

.dark .patch-tool-header:hover {
  background: rgba(255, 255, 255, 0.02);
}

.patch-tool-summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1;
  min-width: 0;
}

.patch-tool-emoji {
  font-size: 1rem;
  flex-shrink: 0;
}

.patch-tool-emoji.running {
}

.patch-tool-filename {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
}

.patch-tool-running {
  font-size: 0.75rem;
  color: var(--text-secondary);
  font-style: italic;
  flex-shrink: 0;
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

.patch-tool-success {
  color: var(--success-text);
  font-size: 0.875rem;
  flex-shrink: 0;
}

.patch-tool-error {
  color: var(--text-secondary);
  font-size: 0.875rem;
  flex-shrink: 0;
}

.patch-tool-header-controls {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  flex-shrink: 0;
}

.patch-tool-toggle {
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
  flex-shrink: 0;
}

.patch-tool-toggle:hover {
  color: var(--text-primary);
}

.patch-tool-diff-mode-toggle {
  background: none;
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  cursor: pointer;
  padding: 0.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
  flex-shrink: 0;
  transition: all 0.15s ease;
}

.patch-tool-diff-mode-toggle:hover {
  color: var(--text-primary);
  background: var(--bg-secondary);
  border-color: var(--text-tertiary);
}

.patch-tool-details {
  padding: 0 1rem 0.75rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.patch-tool-section {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.patch-tool-label {
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.patch-tool-time {
  font-size: 0.75rem;
  color: var(--text-tertiary);
  font-weight: 400;
}

.patch-tool-error-message {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  background: var(--bg-tertiary);
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  padding: 0.75rem;
  margin: 0;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--text-secondary);
}

.patch-tool-raw-diff {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  line-height: 1.6;
  background: var(--bg-tertiary);
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  padding: 0.75rem;
  margin: 0;
  overflow-x: auto;
  white-space: pre;
  color: var(--text-secondary);
  max-height: 400px;
}

/* Patch Tool Simple Diff View */
.patch-tool-diff {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  background: var(--bg-base);
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  padding: 0.75rem;
  margin: 0;
  overflow-x: auto;
  line-height: 1.4;
}

.patch-diff-line {
  white-space: pre;
  display: block;
}

.patch-diff-addition {
  background: rgba(34, 197, 94, 0.1);
  color: #16a34a;
}

.dark .patch-diff-addition {
  background: rgba(34, 197, 94, 0.15);
  color: #86efac;
}

.patch-diff-deletion {
  background: rgba(239, 68, 68, 0.1);
  color: #dc2626;
}

.dark .patch-diff-deletion {
  background: rgba(239, 68, 68, 0.15);
  color: #fca5a5;
}

.patch-diff-hunk {
  color: var(--text-secondary);
  background: var(--bg-tertiary);
  font-weight: 500;
}

.patch-diff-header {
  color: var(--text-tertiary);
  font-style: italic;
}

/* Patch Tool Diffs Container */
.patch-tool-diffs-container {
  border-radius: 0.25rem;
  overflow: hidden;
  font-size: 0.875rem;
  /* Performance: allow browser to skip rendering off-screen diffs */
  content-visibility: auto;
  contain-intrinsic-size: auto 200px;
}

/* Target the diffs-container custom element from @pierre/diffs */
.patch-tool-diffs-container diffs-container {
  display: block;
  contain: content;
}

/* Screenshot Tool */
.screenshot-tool {
  background: var(--gray-100);
  border-radius: 0.5rem;
  margin: 0.5rem 0;
  width: 100%;
}

.dark .screenshot-tool {
  background: var(--gray-800);
}

.screenshot-tool-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  cursor: pointer;
  user-select: none;
}

.screenshot-tool-header:hover {
  background: rgba(0, 0, 0, 0.02);
  border-radius: 0.5rem;
}

.dark .screenshot-tool-header:hover {
  background: rgba(255, 255, 255, 0.02);
}

.screenshot-tool-summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1;
  min-width: 0;
}

.screenshot-tool-emoji {
  font-size: 1rem;
  flex-shrink: 0;
}

.screenshot-tool-emoji.running {
}

.screenshot-tool-filename {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
}

.screenshot-tool-running {
  font-size: 0.75rem;
  color: var(--text-secondary);
  font-style: italic;
  flex-shrink: 0;
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

.screenshot-tool-success {
  color: var(--success-text);
  font-size: 0.875rem;
  flex-shrink: 0;
}

.screenshot-tool-error {
  color: var(--error-text);
  font-size: 0.875rem;
  flex-shrink: 0;
}

.screenshot-tool-toggle {
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
  flex-shrink: 0;
}

.screenshot-tool-toggle:hover {
  color: var(--text-primary);
}

.screenshot-tool-details {
  padding: 0 1rem 0.75rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.screenshot-tool-section {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.screenshot-tool-label {
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.screenshot-tool-time {
  font-size: 0.75rem;
  color: var(--text-tertiary);
  font-weight: 400;
}

.screenshot-tool-image-container {
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  overflow: hidden;
  background: var(--bg-base);
  width: fit-content;
  max-width: 100%;
}

.screenshot-tool-image-container a {
  display: block;
}

.screenshot-tool-image-container img {
  display: block;
  border-radius: 0.25rem;
}

.screenshot-tool-error-message {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  background: var(--error-bg);
  border: 1px solid var(--error-border);
  border-radius: 0.25rem;
  padding: 0.75rem;
  margin: 0;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--error-text);
}

/* Screencast Tool */
.screencast-tool {
  background: var(--gray-100);
  border-radius: 0.5rem;
  margin: 0.5rem 0;
  overflow: hidden;
}

.screencast-tool-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 0.75rem;
  cursor: pointer;
  user-select: none;
}

.screencast-tool-header:hover {
  background: var(--gray-200);
}

.screencast-tool-summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
  flex: 1;
}

.screencast-tool-emoji {
  flex-shrink: 0;
  font-size: 1rem;
}

.screencast-tool-emoji.running {
  animation: pulse 1.5s ease-in-out infinite;
}

.screencast-tool-label {
  font-size: 0.875rem;
  color: var(--text-primary);
  font-weight: 500;
}

.screencast-tool-toggle {
  background: none;
  border: none;
  padding: 0.25rem;
  cursor: pointer;
  color: var(--text-secondary);
  display: flex;
  align-items: center;
}

.screencast-tool-success {
  color: var(--green-600);
  font-weight: bold;
  margin-left: 0.25rem;
}

.screencast-tool-error {
  color: var(--error-text);
  font-weight: bold;
  margin-left: 0.25rem;
}

.screencast-tool-details {
  padding: 0 0.75rem 0.75rem;
}

.screencast-tool-section {
  margin-top: 0.5rem;
}

.screencast-tool-meta {
  font-size: 0.75rem;
  color: var(--text-secondary);
  margin-bottom: 0.5rem;
}

.screencast-tool-status {
  font-size: 0.875rem;
  color: var(--text-secondary);
  font-style: italic;
}

.screencast-tool-video-container {
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  overflow: hidden;
  background: var(--bg-base);
  width: fit-content;
  max-width: 100%;
}

.screencast-tool-video {
  display: block;
  max-width: 100%;
  height: auto;
  border-radius: 0.25rem;
}

.screencast-tool-output {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  background: var(--gray-200);
  border-radius: 0.25rem;
  padding: 0.5rem 0.75rem;
  margin: 0;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
}

.screencast-tool-error-message {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  background: var(--error-bg);
  border: 1px solid var(--error-border);
  border-radius: 0.25rem;
  padding: 0.75rem;
  margin: 0;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--error-text);
}

/* Output Iframe Tool */
.output-iframe-tool {
  background: var(--gray-100);
  border-radius: 0.5rem;
  margin: 0.5rem 0;
  width: 100%;
}

.dark .output-iframe-tool {
  background: var(--gray-800);
}

.output-iframe-tool-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  cursor: pointer;
  user-select: none;
}

.output-iframe-tool-header:hover {
  background: rgba(0, 0, 0, 0.02);
  border-radius: 0.5rem;
}

.dark .output-iframe-tool-header:hover {
  background: rgba(255, 255, 255, 0.02);
}

.output-iframe-tool-summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1;
  min-width: 0;
}

.output-iframe-tool-emoji {
  font-size: 1rem;
  flex-shrink: 0;
}

.output-iframe-tool-emoji.running {
}

.output-iframe-tool-title {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
}

.output-iframe-tool-success {
  color: var(--success-text);
  font-weight: 600;
  margin-left: 0.5rem;
}

.output-iframe-tool-error {
  color: var(--error-text);
  font-weight: 600;
  margin-left: 0.5rem;
}

.output-iframe-tool-actions {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  flex-shrink: 0;
}

.output-iframe-tool-open-btn,
.output-iframe-tool-download-btn {
  background: none;
  border: none;
  padding: 0.25rem;
  cursor: pointer;
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
}

.output-iframe-tool-open-btn:hover,
.output-iframe-tool-download-btn:hover {
  color: var(--text-primary);
  background: var(--gray-200);
}

.dark .output-iframe-tool-open-btn:hover,
.dark .output-iframe-tool-download-btn:hover {
  background: var(--gray-700);
}

.output-iframe-tool-toggle {
  background: none;
  border: none;
  padding: 0.25rem;
  cursor: pointer;
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.output-iframe-tool-toggle:hover {
  color: var(--text-primary);
}

.output-iframe-tool-details {
  padding: 0 1rem 1rem 1rem;
}

.output-iframe-tool-section {
  margin-top: 0.5rem;
}

.output-iframe-tool-label {
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--text-secondary);
  margin-bottom: 0.5rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.output-iframe-tool-time {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--text-tertiary);
}

.output-iframe-container {
  width: 100%;
  overflow: hidden;
  border-radius: 0.25rem;
}

.output-iframe-container iframe {
  display: block;
}

.output-iframe-tool-error-message {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  background: var(--error-bg);
  border: 1px solid var(--error-border);
  border-radius: 0.25rem;
  padding: 0.75rem;
  margin: 0;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--error-text);
}

/* Message Input */
.message-input-container {
  flex: 0 0 auto;
  background: var(--bg-base);
  border-top: 1px solid var(--border);
  padding: 1rem;
  padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
  padding-left: max(1rem, env(safe-area-inset-left));
  padding-right: max(1rem, env(safe-area-inset-right));
}

.message-input-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.5rem;
  max-width: 800px;
  margin: 0 auto;
}

.message-input-container.slash-menu-open .message-input-form {
  position: relative;
  z-index: 130;
}

.message-textarea {
  display: block;
  width: 100%;
  box-sizing: border-box;
  min-height: 46px;
  max-height: 200px;
  field-sizing: content;
  overflow-y: auto;
  padding: 0.625rem 1rem;
  border: 1.5px solid var(--border);
  border-radius: 4px;
  resize: none;
  background: var(--bg-base);
  color: var(--text-primary);
  font-family: inherit;
  font-size: 1rem; /* Must be 16px+ to prevent iOS zoom on focus */
  line-height: 1.6;
  transition:
    border-color 0.2s,
    box-shadow 0.2s;
}

.message-textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.08);
}

.message-textarea:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.message-send-btn svg {
  transform: rotate(-90deg);
}

.message-textarea::placeholder {
  color: var(--text-tertiary);
}

.message-send-btn {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  margin-bottom: 0.25rem;
  padding: 0;
  background: var(--primary);
  color: white;
  border: none;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    background-color 0.2s,
    transform 0.1s;
  cursor: pointer;
}

.message-send-btn:hover:not(:disabled) {
  background: var(--primary-dark);
  transform: scale(1.05);
}

.message-send-btn:active:not(:disabled) {
  transform: scale(0.95);
}

.message-send-btn:disabled {
  background: var(--gray-300);
  cursor: not-allowed;
  opacity: 0.6;
}

.dark .message-send-btn:disabled {
  background: var(--gray-600);
}

/* Send button wrapper for queue menu positioning */
.message-send-wrapper {
  position: relative;
  display: flex;
  align-items: flex-end;
}

/* Slack-style split send button: [Send | ▾] */
.send-split-btn {
  display: flex;
  align-items: stretch;
  border-radius: 18px;
  overflow: hidden;
  margin-bottom: 0.25rem;
  background: var(--primary);
  transition: background-color 0.2s;
}

.send-split-btn-queue {
  background: var(--orange-500, #f97316);
}

.send-split-main {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: none;
  background: transparent;
  color: white;
  cursor: pointer;
  transition: background-color 0.15s;
}

.send-split-main:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.15);
}

.send-split-main:active:not(:disabled) {
  background: rgba(255, 255, 255, 0.25);
}

.send-split-main:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

.send-split-main svg {
  transform: rotate(-90deg);
}

.send-split-divider {
  width: 1px;
  background: rgba(255, 255, 255, 0.3);
  margin: 6px 0;
}

.send-split-chevron {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  padding: 0;
  border: none;
  background: transparent;
  color: white;
  cursor: pointer;
  transition: background-color 0.15s;
}

.send-split-chevron:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.15);
}

.send-split-chevron:active:not(:disabled) {
  background: rgba(255, 255, 255, 0.25);
}

.send-split-chevron:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

.send-split-chevron-inactive {
  opacity: 0.4;
  cursor: default;
}

/* Send split disabled state */
.send-split-btn:has(.send-split-main:disabled) {
  background: var(--gray-300);
  opacity: 0.6;
}

.dark .send-split-btn:has(.send-split-main:disabled) {
  background: var(--gray-600);
}

/* Queue dropdown menu */
.queue-menu {
  position: absolute;
  bottom: calc(100% + 4px);
  right: 0;
  background: var(--bg-base);
  border: 1px solid var(--border-color);
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  padding: 4px;
  z-index: 100;
  min-width: 220px;
  animation: queue-menu-in 0.15s ease-out;
}

@keyframes queue-menu-in {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.queue-menu-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 12px;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--text-primary);
  font-size: 0.85rem;
  cursor: pointer;
  white-space: nowrap;
}

.queue-menu-item:hover {
  background: var(--gray-100);
}

.dark .queue-menu-item:hover {
  background: var(--gray-700);
}

.queue-menu-item svg {
  flex-shrink: 0;
  color: var(--text-secondary);
}

/* Queued message badge (shown on queued user messages) */
.message-queued {
  opacity: 0.7;
}

/* Ghost queued messages render with a dashed border to read as "pending". */
.message-queued .message-content {
  border: 1px dashed rgba(249, 115, 22, 0.5);
}

.queued-cancel-all-row {
  display: flex;
  justify-content: flex-end;
  margin: 4px 0 8px;
}

.queued-message-badge {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  padding: 4px 10px;
  font-size: 0.75rem;
  color: var(--orange-600, #ea580c);
  background: rgba(249, 115, 22, 0.08);
  border-radius: 6px;
  width: fit-content;
}

.dark .queued-message-badge {
  color: var(--orange-400, #fb923c);
  background: rgba(249, 115, 22, 0.12);
}

.queued-message-badge-label {
  display: flex;
  align-items: center;
  font-weight: 600;
  letter-spacing: 0.03em;
}

.queued-message-badge-cancel {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 4px 10px;
  border: 1px solid currentColor;
  border-radius: 4px;
  background: transparent;
  color: inherit;
  cursor: pointer;
  font-size: 0.75rem;
  font-weight: 500;
  opacity: 0.7;
  transition:
    opacity 0.15s,
    background-color 0.15s;
  /* Ensure tappable on mobile */
  min-height: 28px;
  min-width: 44px;
}

.queued-message-badge-cancel:hover {
  opacity: 1;
  background: rgba(0, 0, 0, 0.08);
}

.dark .queued-message-badge-cancel:hover {
  background: rgba(255, 255, 255, 0.08);
}

/* Action row under textarea */
.message-controls-row {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.25rem;
}

/* Attach file button */
.message-attach-btn {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  margin-bottom: 0.25rem;
  padding: 0;
  background: transparent;
  color: var(--text-secondary);
  border: none;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    background-color 0.2s,
    color 0.2s,
    transform 0.1s;
  cursor: pointer;
}

.message-attach-btn:hover:not(:disabled) {
  background: var(--gray-100);
  color: var(--text-primary);
}

.dark .message-attach-btn:hover:not(:disabled) {
  background: var(--gray-700);
}

.message-attach-btn:active:not(:disabled) {
  transform: scale(0.95);
}

.message-attach-btn:disabled {
  cursor: not-allowed;
  opacity: 0.4;
}

/* Voice input button */
.message-voice-btn {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  margin-bottom: 0.25rem;
  padding: 0;
  background: transparent;
  color: var(--text-secondary);
  border: none;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    background-color 0.2s,
    color 0.2s,
    transform 0.1s;
  cursor: pointer;
}

.message-voice-btn:hover:not(:disabled):not(.listening) {
  background: var(--gray-100);
  color: var(--text-primary);
}

.dark .message-voice-btn:hover:not(:disabled):not(.listening) {
  background: var(--gray-700);
}

.message-voice-btn:active:not(:disabled):not(.listening) {
  transform: scale(0.95);
}

.message-voice-btn:disabled {
  cursor: not-allowed;
  opacity: 0.4;
}

.message-voice-btn.listening,
.message-voice-btn.listening:hover {
  background: #dc2626;
  color: white;
  animation: pulse-voice 1.5s ease-in-out infinite;
}

.dark .message-voice-btn.listening,
.dark .message-voice-btn.listening:hover {
  background: #ef4444;
  color: white;
}

@keyframes pulse-voice {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.1);
  }
}

/* Drag and drop styles */
.message-input-container {
  position: relative;
}

.message-input-container.drag-over {
  border-color: var(--primary);
}

.message-input-container.shell-mode .message-input-form {
  border-color: var(--warning-border);
  background: var(--warning-bg);
}

.message-input-container.shell-mode .message-textarea {
  font-family: var(--font-mono);
  background: transparent;
  padding-left: 36px;
  width: 100%;
}

.textarea-wrapper {
  position: relative;
  flex: 1;
  min-width: 0;
}

.slash-command-menu {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(100% + 6px);
  z-index: 120;
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: min(260px, 40vh);
  overflow-y: auto;
  padding: 4px;
  background: var(--bg-base);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 10px 28px rgba(15, 23, 42, 0.18);
}

.slash-command-item {
  display: grid;
  grid-template-columns: minmax(5.5rem, auto) minmax(0, 1fr);
  gap: 12px;
  align-items: center;
  width: 100%;
  min-height: 38px;
  padding: 8px 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-primary);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.slash-command-item:hover,
.slash-command-item.selected {
  background: var(--gray-100);
}

.dark .slash-command-item:hover,
.dark .slash-command-item.selected {
  background: var(--gray-700);
}

.slash-command-name {
  font-family: var(--font-mono);
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--primary);
  white-space: nowrap;
}

.slash-command-description {
  min-width: 0;
  overflow: hidden;
  color: var(--text-secondary);
  font-size: 0.85rem;
  line-height: 1.3;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.message-input-container.shell-mode .message-textarea::placeholder {
  font-family: inherit;
}

.shell-mode-indicator {
  position: absolute;
  left: 12px;
  top: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--warning-text);
  pointer-events: none;
  z-index: 1;
}

.drag-overlay {
  position: absolute;
  inset: 0;
  background: rgba(37, 99, 235, 0.1);
  border: 2px dashed var(--primary);
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
  pointer-events: none;
}

.drag-overlay-content {
  background: var(--primary);
  color: white;
  padding: 0.5rem 1rem;
  border-radius: 4px;
  font-size: 0.875rem;
  font-weight: 500;
}

/* Modal */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}

.modal {
  background: var(--bg-base);
  border-radius: 0.5rem;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
  max-width: 28rem;
  width: 100%;
  /* As a flex item, the default `min-width: auto` lets wide content (e.g. the
     models table) push the modal past the viewport. Allow it to shrink so
     `width: 100%` / `max-width` are honored and inner content scrolls. */
  min-width: 0;
  max-height: 80vh;
  overflow: hidden;
  /* Flex column so the header (and optional .modal-footer) stay pinned while
     .modal-body scrolls. */
  display: flex;
  flex-direction: column;
}

.modal.modal-wide {
  max-width: 40rem;
}

.modal.modal-xwide {
  max-width: 64rem;
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* No bottom border and a snug bottom padding: the title sits close to the
     body rather than being separated by whitespace + a divider line. */
  padding: 1rem 1rem 0.5rem;
  flex-shrink: 0;
}

.modal-title {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 600;
}

.modal-title-right {
  margin-left: auto;
  margin-right: 1rem;
}

.models-header-actions {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

/* Keep the Refresh / Add Model buttons on a single line each; on narrow
   viewports they were wrapping ("+ Add" / "Model") and inflating the header.
   These are PrimeVue <Button size="small"> (.p-button-sm); the .btn-sm selector
   is kept for any legacy small buttons. */
.models-header-actions .btn-sm,
.models-header-actions .p-button-sm {
  white-space: nowrap;
}

/* When the Manage Models list is showing, the table (a PrimeVue DataTable)
   renders its own header row and fills the modal, so the modal-body padding is
   just dead space above the column labels and a gap below the last row. Make
   the modal a flex column and let the table fill it edge-to-edge (also lets
   scroll-height="flex" work — it needs a definite-height flex ancestor).
   Scoped to .modal-xwide, which only this modal uses; the form/empty views
   keep their normal padding since they don't add .models-modal-list. */
.modal.modal-xwide {
  display: flex;
  flex-direction: column;
}

.modal-xwide .modal-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  /* max-height is handled by the flex parent (.modal, capped at 80vh). */
  max-height: none;
}

/* List state: drop wrapper padding so the table spans the modal fully. */
.modal-xwide .modal-body:has(.models-modal-list) {
  padding: 0;
}

.modal-xwide .models-modal-list {
  padding: 0;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

.modal-xwide .models-modal-list .models-datatable {
  margin: 0;
  flex: 1;
  min-height: 0;
}

/* On phones the title + both action buttons + close can't share one row, so
   the title wrapped ("Manage / Models") and ballooned the header. Stack it:
   title + close on the first row, the two actions full-width on the second. */
@media (max-width: 520px) {
  .modal-xwide .modal-header {
    flex-wrap: wrap;
    padding: 0.75rem 1rem;
  }

  .modal-xwide .modal-title {
    flex: 1;
    font-size: 1.125rem;
    white-space: nowrap;
  }

  .modal-xwide .modal-title-right {
    order: 1;
    flex-basis: 100%;
    margin: 0.5rem 0 0;
  }

  .modal-xwide .models-header-actions {
    width: 100%;
  }

  .modal-xwide .models-header-actions .btn-sm,
  .modal-xwide .models-header-actions .p-button-sm {
    flex: 1;
  }
}

.modal-body {
  /* Snug top padding since the header no longer has a bottom border/gap. */
  padding: 0.5rem 1rem 1rem;
  overflow-y: auto;
  flex: 1 1 auto;
  min-height: 0;
}

/* Optional pinned footer row (Modal.vue #footer slot). */
.modal-footer {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 1rem;
  border-top: 1px solid var(--border);
  flex-shrink: 0;
}

/* Form Elements */
label {
  display: block;
  font-size: 0.875rem;
  font-weight: 500;
  margin-bottom: 0.5rem;
}

select {
  width: 100%;
  background: var(--bg-tertiary);
  border: 1px solid var(--border);
  border-radius: 0.375rem;
  padding: 0.5rem 0.75rem;
  font-family: inherit;
  font-size: 1rem;
  color: var(--text-primary);
}

select:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.1);
}

select:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Loading Spinner */
.spinner {
  width: 2rem;
  height: 2rem;
  border: 2px solid transparent;
  border-top-color: var(--primary);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

.spinner-small {
  width: 1rem;
  height: 1rem;
  border-width: 2px;
  border-top-color: currentColor;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* Loading/Error States */
.loading-container,
.error-container {
  height: 100vh; /* Fallback for older browsers */
  height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.loading-content,
.error-content {
  text-align: center;
}

/* Unified Status Bar */
.status-bar {
  flex: 0 0 auto;
  background: var(--bg-base);
  border-top: 1px solid var(--border);
  padding: 0.5rem 1rem;
  padding-left: max(1rem, env(safe-area-inset-left));
  padding-right: max(1rem, env(safe-area-inset-right));
  min-height: 2.5rem;
  display: flex;
  align-items: center;
}

.status-bar-content {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  gap: 0.75rem;
}

.status-message {
  color: var(--text-secondary);
  font-size: 0.875rem;
  flex: 1;
  min-width: 0;
}

/* "Ready on <hostname>" is a readout like the cwd/tokens/model group on the
   other end of the bar, not prose — same mono type, so the bar reads as one
   thing. The other .status-message variants (error, disconnected, no-models)
   are sentences and stay in the default sans. */
.status-message.status-ready {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  line-height: 1.2;
  color: var(--text-tertiary);
}

.status-message.status-warning {
  color: var(--blue-text);
  font-weight: 500;
}

/* No models configured is a setup gap, not a failure: warning color, because
   red reads like something broke inside Shelley. */
.status-message.status-no-models {
  color: var(--warning-text);
  font-weight: 500;
}

.status-message.status-error {
  color: var(--error-text);
  font-weight: 500;
}

.status-message.status-reconnecting {
  color: var(--blue-text);
  font-weight: 500;
}

.reconnecting-dots {
  display: inline-block;
  animation: reconnecting-pulse 1.5s ease-in-out infinite;
}

@keyframes reconnecting-pulse {
  0%,
  100% {
    opacity: 0.3;
  }
  50% {
    opacity: 1;
  }
}

.animated-working {
  display: inline;
  font-family: var(--font-mono);
}

.animated-working .bold-letter {
  color: var(--text-primary);
}

.status-button {
  padding: 0.375rem 0.875rem;
  border-radius: 0.375rem;
  font-size: 0.875rem;
  font-weight: 500;
  transition: all 0.2s;
  display: flex;
  align-items: center;
  gap: 0.375rem;
  white-space: nowrap;
  border: none;
  cursor: pointer;
}

.status-button svg {
  width: 0.875rem;
  height: 0.875rem;
}

.status-button-primary {
  background: var(--primary);
  color: white;
}

.status-button-primary:hover {
  background: var(--primary-dark);
}

.status-button-cancel {
  background: var(--error-bg);
  color: var(--error-text);
  border: 1px solid var(--error-border);
}

.status-button-cancel:hover:not(:disabled) {
  background: var(--error-text);
  color: white;
}

.status-button-cancel:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.status-button-text {
  background: transparent;
  color: var(--text-secondary);
  padding: 0.25rem;
}

.status-button-text:hover {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

/* Legacy disconnect/error banner classes (kept for compatibility but unused) */
.disconnect-banner {
  background: var(--gray-100);
  border-top: 1px solid var(--border);
  padding: 0.5rem 1rem;
}

.dark .disconnect-banner {
  background: var(--gray-800);
}

.disconnect-banner-content {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
}

.disconnect-message {
  color: var(--text-secondary);
  font-size: 0.875rem;
  margin: 0;
}

.btn-reconnect {
  padding: 0.25rem 0.75rem;
  background: var(--primary);
  color: white;
  border-radius: 0.375rem;
  font-size: 0.875rem;
  font-weight: 500;
  transition: background-color 0.2s;
}

.btn-reconnect:hover {
  background: var(--primary-dark);
}

.error-banner {
  background: var(--error-bg);
  border-top: 1px solid var(--error-border);
  padding: 0.75rem 1rem;
}

.error-banner-content {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.error-message {
  color: var(--error-text);
  font-size: 0.875rem;
}

/* Empty State */
.empty-state {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: var(--text-secondary);
}

.empty-state-content {
  text-align: center;
}

/* Scrollbar */
.scrollable {
  scrollbar-width: thin;
  scrollbar-color: rgba(156, 163, 175, 0.5) transparent;
}

.scrollable::-webkit-scrollbar {
  width: 6px;
}

.scrollable::-webkit-scrollbar-track {
  background: transparent;
}

.scrollable::-webkit-scrollbar-thumb {
  background-color: rgba(156, 163, 175, 0.5);
  border-radius: 3px;
}

.scrollable::-webkit-scrollbar-thumb:hover {
  background-color: rgba(156, 163, 175, 0.8);
}

/* SVG Icons */
svg {
  width: 1.25rem;
  height: 1.25rem;
  display: block;
}

.icon-sm svg {
  width: 1rem;
  height: 1rem;
}

/* Utility Classes */
.relative {
  position: relative;
}

.overflow-auto {
  overflow: auto;
}

.overflow-hidden {
  overflow: hidden;
}

.rounded {
  border-radius: 0.25rem;
}

.rounded-lg {
  border-radius: 0.5rem;
}

.border {
  border: 1px solid var(--border);
}

.min-h-0 {
  min-height: 0;
}

/* Overflow Menu */
.overflow-menu {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  box-shadow:
    0 4px 6px -1px rgba(0, 0, 0, 0.1),
    0 2px 4px -1px rgba(0, 0, 0, 0.06);
  min-width: 16rem;
  z-index: 50;
}

.overflow-menu-item {
  display: flex;
  align-items: center;
  width: 100%;
  padding: 0.75rem 1rem;
  text-align: left;
  background: transparent;
  border: none;
  color: var(--text-primary);
  font-size: 0.875rem;
  cursor: pointer;
  transition: background-color 0.2s;
  white-space: nowrap;
}

.overflow-menu-item:hover {
  background: var(--bg-hover);
}

.overflow-menu-item:first-child {
  border-top-left-radius: 0.5rem;
  border-top-right-radius: 0.5rem;
}

.overflow-menu-item:last-child {
  border-bottom-left-radius: 0.5rem;
  border-bottom-right-radius: 0.5rem;
}

.overflow-menu-divider {
  height: 1px;
  background: var(--border);
  margin: 0.5rem 0;
}

.theme-toggle-row {
  display: flex;
  gap: 0.25rem;
  padding: 0.5rem;
}

.theme-toggle-btn {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.5rem;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 0.375rem;
  color: var(--text-secondary);
  cursor: pointer;
  transition: all 0.15s;
}

.theme-toggle-btn svg {
  width: 1.125rem;
  height: 1.125rem;
}

.theme-toggle-btn:hover {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

.theme-toggle-btn-selected {
  background: var(--primary);
  border-color: var(--primary);
  color: white;
}

.theme-toggle-btn-selected:hover {
  background: var(--primary-dark);
  border-color: var(--primary-dark);
  color: white;
}

/* Markdown mode toggle */
.md-toggle-row {
  padding: 0.5rem;
}

.md-toggle-label {
  font-size: 0.75rem;
  color: var(--text-secondary);
  margin-bottom: 0.375rem;
  font-weight: 500;
}

.md-toggle-buttons {
  display: flex;
  background: var(--bg-tertiary);
  border-radius: 0.375rem;
  padding: 2px;
  gap: 2px;
}

.md-toggle-btn {
  flex: 1;
  padding: 0.25rem 0.375rem;
  background: transparent;
  border: none;
  border-radius: 0.25rem;
  color: var(--text-secondary);
  cursor: pointer;
  font-size: 0.75rem;
  font-weight: 500;
  transition: all 0.15s;
}

.md-toggle-btn:hover {
  color: var(--text-primary);
  background: var(--bg-secondary);
}

.md-toggle-btn-selected {
  background: var(--primary);
  color: white;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

.md-toggle-btn-selected:hover {
  background: var(--primary-dark);
  color: white;
}

/* Language dropdown */
.language-selector-row {
  padding: 0.5rem;
}

.language-dropdown {
  position: relative;
  margin-top: 0.375rem;
}

.language-dropdown-trigger {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.375rem 0.5rem;
  background: var(--bg-tertiary);
  border: 1px solid var(--border);
  border-radius: 0.375rem;
  color: var(--text-primary);
  font-size: 0.875rem;
  cursor: pointer;
  transition: all 0.15s;
}

.language-dropdown-trigger:hover {
  background: var(--bg-hover);
  border-color: var(--text-secondary);
}

.language-dropdown-flag {
  font-size: 1rem;
  line-height: 1;
}

.language-dropdown-text {
  flex: 1;
  text-align: left;
}

.language-dropdown-chevron {
  color: var(--text-secondary);
  transition: transform 0.15s;
  flex-shrink: 0;
}

.language-dropdown-chevron-open {
  transform: rotate(180deg);
}

.language-dropdown-menu {
  position: absolute;
  bottom: calc(100% + 4px);
  left: 0;
  right: 0;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: 0.375rem;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  z-index: 100;
  overflow: hidden;
}

.language-dropdown-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.375rem 0.5rem;
  background: transparent;
  border: none;
  color: var(--text-primary);
  font-size: 0.875rem;
  cursor: pointer;
  transition: background 0.1s;
  text-align: left;
}

.language-dropdown-item:hover {
  background: var(--bg-hover);
}

.language-dropdown-item-selected {
  color: var(--primary);
  font-weight: 500;
}

.language-dropdown-check {
  margin-left: auto;
  color: var(--primary);
  flex-shrink: 0;
}

/* Diff display styling */
.diff-display {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  line-height: 1.6;
  background: var(--bg-base);
  padding: 1rem;
  border-radius: 0.25rem;
  overflow-x: auto;
  white-space: pre;
  color: var(--text-primary);
}

/* Responsive adjustments */
@media (min-width: 768px) {
  .drawer {
    position: static;
    transform: translateX(0) !important;
    /* When static, fill the flex parent rather than the full viewport, so
       the drawer doesn't overflow when a top banner is present. */
    height: 100%;
  }

  .drawer.collapsed {
    display: none;
  }

  .hide-on-desktop {
    display: none !important;
  }

  .show-on-desktop-only {
    display: flex !important;
  }

  .backdrop {
    display: none !important;
  }
}

/* Hide desktop-only elements on mobile */
@media (max-width: 767px) {
  .show-on-desktop-only {
    display: none !important;
  }
}

/* Scroll to bottom button */
.scroll-to-bottom-button {
  position: absolute;
  bottom: 1rem;
  left: 50%;
  transform: translateX(-50%);
  background: var(--bg-base);
  border: 1px solid var(--border);
  border-radius: 2rem;
  padding: 0.5rem 1rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  transition: all 0.2s ease;
  color: var(--text-primary);
  font-size: 0.875rem;
  z-index: 10;
}

.scroll-to-bottom-button:hover {
  background: var(--bg-hover);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.scroll-to-bottom-button:active {
  transform: translateX(-50%) scale(0.95);
}

/* Floating nav cluster — bottom of messages area. Contains TOC button
   (always visible) and an optional scroll-to-bottom button. Replaces the
   centered scroll-to-bottom button so the TOC is a first-class control. */
.chat-nav-cluster {
  position: absolute;
  bottom: 1rem;
  right: 1rem;
  display: flex;
  flex-direction: column-reverse;
  align-items: flex-end;
  gap: 0.5rem;
  z-index: 10;
  pointer-events: none;
}
.chat-nav-cluster > * {
  pointer-events: auto;
}
/* Override centered positioning when inside the cluster; match TOC button size */
.chat-nav-cluster .scroll-to-bottom-button {
  position: static;
  transform: none;
  padding: 0;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 999px;
  justify-content: center;
}
.chat-nav-cluster .scroll-to-bottom-button:active {
  transform: scale(0.95);
}
.chat-nav-cluster .chat-scroll-icon {
  width: 1.125rem;
  height: 1.125rem;
}

/* TOC trigger button */
.toc-button {
  background: var(--bg-base);
  border: 1px solid var(--border);
  border-radius: 999px;
  width: 2.5rem;
  height: 2.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--text-primary);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
  transition:
    background 0.15s ease,
    box-shadow 0.15s ease,
    transform 0.1s ease;
}
.toc-button:hover {
  background: var(--bg-hover);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
}
.toc-button:active {
  transform: scale(0.95);
}
.toc-button-open {
  background: var(--bg-hover);
}
.toc-button-icon {
  width: 1.125rem;
  height: 1.125rem;
}

/* TOC popover — PrimeVue Popover surface. PrimeVue owns positioning (absolute
   + inline top/left, flipped to fit the viewport), so unlike the old
   hand-rolled version we must NOT set position/bottom/right here. */
.toc-popover.p-popover {
  width: min(28rem, calc(100vw - 2rem));
  background: var(--bg-base);
  border: 1px solid var(--border);
  border-radius: 0.75rem;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
  overflow: hidden;
}
/* Popover has no placement prop: it always aligns below the target unless it
   would overflow the viewport (then it adds .p-popover-flipped and positions
   above). The TOC button floats just above the message input, so "below"
   covers the input; shift the panel above the button (own height + the
   2.5rem button + gap). When PrimeVue flipped it is already above. This also
   suppresses the p-popover scaleY enter transform, which is fine. */
.toc-popover.p-popover:not(.p-popover-flipped) {
  transform: translateY(calc(-100% - 3rem));
}
/* No arrow for this panel; PrimeVue draws one via :before/:after. */
.toc-popover.p-popover:before,
.toc-popover.p-popover:after {
  display: none;
}
.toc-popover .toc-popover-content {
  display: flex;
  flex-direction: column;
  max-height: min(60vh, 32rem);
  padding: 0;
}
.toc-popover-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 0.625rem 0.875rem;
  border-bottom: 1px solid var(--border);
  font-size: 0.8125rem;
}
.toc-popover-title {
  font-weight: 600;
  color: var(--text-primary);
}
.toc-popover-list {
  width: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  max-height: min(448px, 52vh);
  overscroll-behavior: contain;
}
.toc-entry {
  box-sizing: border-box;
  height: 30px;
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  width: 100%;
  padding: 0.375rem 0.875rem;
  background: transparent;
  border: none;
  text-align: left;
  cursor: pointer;
  color: var(--text-primary);
  font-size: 0.8125rem;
  line-height: 1.35;
  font-family: inherit;
}
.toc-entry:hover {
  background: var(--bg-hover);
}
.toc-entry-with-thumbnail {
  height: 38px;
  align-items: center;
  padding-top: 0.25rem;
  padding-bottom: 0.25rem;
}
.toc-entry-thumbnail-wrap {
  position: relative;
  flex: 0 0 2.5rem;
  width: 2.5rem;
  height: 1.75rem;
}
.toc-entry-thumbnail {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  background: var(--bg-secondary);
}
.toc-entry-thumbnail-count {
  position: absolute;
  right: -0.25rem;
  bottom: -0.2rem;
  min-width: 1rem;
  padding: 0 0.2rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-base);
  color: var(--text-secondary);
  font-size: 0.625rem;
  line-height: 0.875rem;
  text-align: center;
}
.toc-entry:hover .toc-entry-thumbnail,
.toc-entry-active .toc-entry-thumbnail {
  border-color: var(--blue-text, #3b82f6);
}
.toc-entry-active {
  background: var(--bg-hover);
}
.toc-entry-active .toc-entry-icon {
  color: var(--blue-text, #3b82f6);
}
.toc-entry-icon {
  flex: 0 0 1.25rem;
  text-align: center;
  color: var(--text-secondary);
  font-size: 0.875rem;
  line-height: 1.2;
  padding-top: 0.0625rem;
}
.toc-entry-label {
  flex: 1 1 auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.toc-entry-top .toc-entry-label,
.toc-entry-bottom .toc-entry-label {
  color: var(--text-secondary);
  font-style: italic;
}
.toc-entry-gen {
  align-items: center;
  gap: 0.5rem;
  color: var(--text-secondary);
}
.toc-entry-gen .toc-entry-label {
  flex: 0 0 auto;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.toc-entry-gen::before,
.toc-entry-gen::after {
  content: "";
  flex: 1 1 auto;
  border-top: 1px solid var(--border);
}
.toc-entry-user .toc-entry-label {
  font-weight: 500;
}

/* Mobile: near-full-width popover */
@media (max-width: 640px) {
  .toc-popover.p-popover {
    width: calc(100vw - 1rem);
  }
  .toc-popover .toc-popover-content {
    max-height: 70vh;
  }
}

/* Wrapper for messages area to position scroll-to-bottom button */
.messages-area-wrapper {
  position: relative;
  flex: 1 1 auto;
  min-height: 0; /* Important for flex children to shrink properly */
  overflow: hidden;
}

.messages-container {
  height: 100%;
}

/* Status bar configuration controls for empty conversations */
.status-bar-config {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
}

.status-bar-new-conversation {
  display: flex;
  align-items: center;
  width: 100%;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.status-bar-controls {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* Flexible containers for status fields that adapt to content */
.status-field {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  min-width: 0; /* Allow flex items to shrink below content size */
}

.status-field-label {
  font-size: 0.75rem;
  color: var(--text-secondary);
  flex-shrink: 0;
}

.status-field-model {
  flex: 1 1 auto;
  min-width: 170px;
  max-width: 320px;
}

.status-field-cwd {
  flex: 1 1 auto;
  min-width: 180px;
  max-width: 400px;
}

/* Compact clickable chips for model and cwd */
.status-chip {
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-size: 0.75rem;
  cursor: pointer;
  transition: all 0.2s;
  white-space: normal; /* Allow text to wrap */
  word-break: break-word; /* Break long words if needed */
  overflow-wrap: break-word;
  width: 100%;
  text-align: left;
  box-sizing: border-box;
  line-height: 1.4; /* Better line height for multi-line text */
  min-height: 1.75rem; /* Minimum height to accommodate wrapped text */
}

.status-chip:hover:not(:disabled) {
  background: var(--bg-secondary);
  border-color: var(--blue-text);
}

.status-chip:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.status-chip-error {
  border-color: var(--red-text, #dc2626);
  background: rgba(220, 38, 38, 0.1);
}

.status-field-error {
  position: relative;
}

/* Advanced settings gear button + popover */
.advanced-settings-wrapper {
  position: relative;
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.advanced-settings-trigger {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  cursor: pointer;
  transition: all 0.2s;
  padding: 0;
}

.advanced-settings-trigger:hover:not(:disabled) {
  background: var(--bg-secondary);
  color: var(--text-primary);
  border-color: var(--blue-text);
}

.advanced-settings-trigger:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.advanced-settings-trigger.active {
  color: var(--blue-text, #3b82f6);
  border-color: var(--blue-text, #3b82f6);
}

.advanced-settings-popover {
  position: absolute;
  bottom: 100%;
  /* Gear trigger sits on the left of the status bar, so open the popover
     rightward from its left edge. Anchoring to the right overflowed off the
     left viewport edge and got clipped. */
  left: 0;
  margin-bottom: 4px;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: 0.375rem;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  z-index: 1000;
  padding: 0.5rem 0.75rem;
  min-width: min(520px, calc(100vw - 1rem));
  max-width: min(680px, calc(100vw - 1rem));
  max-height: 70vh;
  overflow-y: auto;
  overflow-x: hidden;
}

@media (max-width: 640px) {
  .advanced-settings-popover {
    position: fixed;
    inset: 3rem 0.5rem auto 0.5rem;
    margin: 0;
    min-width: 0;
    max-width: none;
    max-height: calc(100vh - 4rem);
  }
  .tool-override-summary {
    display: none;
  }
  .tool-override-row {
    padding: 0.35rem 0;
  }
  .tool-override-choice {
    padding: 0.35rem 0.55rem;
    font-size: 0.75rem;
  }
}

.tool-override-list {
  display: flex;
  flex-direction: column;
}

.tool-override-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.2rem 0;
  border-bottom: 1px dashed var(--border);
  flex-wrap: wrap;
}

.tool-override-row:last-child {
  border-bottom: none;
}

.tool-override-info {
  display: flex;
  flex-direction: row;
  align-items: baseline;
  gap: 0.4rem;
  min-width: 0;
  flex: 1;
  overflow: hidden;
}

.tool-override-name {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--text-primary);
  font-weight: 600;
  flex-shrink: 0;
}

.tool-override-summary {
  font-size: 0.6875rem;
  color: var(--text-tertiary);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  flex: 1;
}

.tool-override-choices {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  overflow: hidden;
  flex-shrink: 0;
}

.tool-override-choice {
  border: none;
  background: var(--bg-base);
  color: var(--text-secondary);
  font-size: 0.6875rem;
  padding: 0.2rem 0.45rem;
  cursor: pointer;
  border-right: 1px solid var(--border);
  white-space: nowrap;
}

.tool-override-choice:last-child {
  border-right: none;
}

.tool-override-choice:not(.active):hover:not(:disabled) {
  background: var(--bg-hover, rgba(255, 255, 255, 0.05));
}

.tool-override-choice.active,
.tool-override-choice.active:hover:not(:disabled) {
  background: var(--blue-text, #3b82f6);
  color: white;
}

.tool-override-choice:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.advanced-settings-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 0.5rem;
  padding-bottom: 0.375rem;
  border-bottom: 1px solid var(--border);
}

.advanced-settings-reset {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  padding: 0.15rem 0.5rem;
  font-size: 0.625rem;
  font-weight: 500;
  text-transform: none;
  letter-spacing: normal;
  color: var(--text-secondary);
  cursor: pointer;
}

.advanced-settings-reset:hover:not(:disabled) {
  background: var(--bg-hover);
  color: var(--text-primary);
}

.advanced-settings-reset:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.status-input-error {
  border-color: var(--red-text, #dc2626);
}

.status-input {
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--blue-text);
  border-radius: 0.25rem;
  background: var(--bg-base);
  color: var(--text-primary);
  font-size: 0.75rem;
  transition: border-color 0.2s;
  width: 100%;
  box-sizing: border-box;
}

.status-input::placeholder {
  color: var(--text-secondary);
  opacity: 0.6;
}

.status-input:hover:not(:disabled) {
  border-color: var(--blue-text);
}

.status-input:focus {
  outline: none;
  border-color: var(--blue-text);
  box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
}

.status-input:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Responsive adjustments for status bar controls */
@media (max-width: 768px) {
  .status-bar-config {
    flex-wrap: wrap;
    gap: 0.5rem;
  }

  .status-bar-controls {
    flex-wrap: wrap;
    gap: 0.5rem;
  }

  .status-field-model {
    min-width: 140px;
    max-width: none;
  }

  .status-field-cwd {
    min-width: 140px;
    max-width: none;
  }
}

/* Directory Picker Modal */
.directory-picker-modal {
  max-width: 32rem;
  height: 70vh;
}

/* The list scrolls internally; make the modal body a non-scrolling flex
   column so .directory-picker-body can fill it. */
.directory-picker-modal .modal-body {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.directory-picker-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

.directory-picker-input-container {
  margin-bottom: 0.75rem;
}

.directory-picker-input {
  width: 100%;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  background: var(--bg-base);
  color: var(--text-primary);
  font-family: var(--font-mono);
  font-size: 0.875rem;
}

.directory-picker-input:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.1);
}

.directory-picker-current {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.75rem;
  color: var(--text-secondary);
  font-family: var(--font-mono);
  margin-bottom: 0.5rem;
  padding: 0.25rem 0;
}

.directory-picker-current-path {
  flex-shrink: 0;
}

.directory-picker-current-git .directory-picker-current-path {
  color: var(--accent-color, #f97316);
}

.directory-picker-current-subject {
  flex: 1;
  min-width: 0;
  color: var(--text-tertiary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: right;
}

.directory-picker-filter {
  color: var(--primary);
  font-weight: 500;
}

.directory-picker-git-root-row {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  margin-bottom: 0.5rem;
}

.directory-picker-git-root-btn {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.375rem 0.75rem;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 0.375rem;
  color: var(--accent-color, #f97316);
  font-size: 0.875rem;
  cursor: pointer;
  text-align: left;
}

.directory-picker-git-root-btn:hover {
  background: var(--bg-tertiary);
  border-color: var(--accent-color, #f97316);
}

.directory-picker-git-root-btn .directory-picker-icon {
  flex-shrink: 0;
}

.directory-picker-git-root-path {
  color: var(--text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  margin-left: auto;
}

.directory-picker-error {
  padding: 0.5rem 0.75rem;
  background: var(--error-bg);
  border: 1px solid var(--error-border);
  border-radius: 0.25rem;
  color: var(--error-text);
  font-size: 0.875rem;
  margin-bottom: 0.75rem;
}

.directory-picker-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  flex: 1;
  color: var(--text-secondary);
  font-size: 0.875rem;
}

.directory-picker-list {
  flex: 1;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  min-height: 0;
}

.directory-picker-entry {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.5rem 0.75rem;
  text-align: left;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--border);
  color: var(--text-primary);
  font-size: 0.875rem;
  font-family: var(--font-mono);
  cursor: pointer;
  transition: background-color 0.15s;
}

.directory-picker-entry:last-child {
  border-bottom: none;
}

.directory-picker-entry:hover {
  background: var(--bg-tertiary);
}

.directory-picker-entry-parent {
  color: var(--text-secondary);
  font-weight: 500;
}

.directory-picker-icon {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
  color: var(--text-secondary);
}

.directory-picker-entry-name {
  flex-shrink: 0;
}

.directory-picker-entry-git .directory-picker-icon {
  color: var(--accent-color, #f97316);
}

.directory-picker-git-subject {
  flex: 1;
  min-width: 0;
  color: var(--text-tertiary);
  font-size: 0.75rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: right;
}

.directory-picker-empty,
.directory-picker-truncated {
  padding: 2rem;
  text-align: center;
  color: var(--text-tertiary);
  font-size: 0.875rem;
}

/* The truncation hint sits under 500 rows; keep it compact. */
.directory-picker-truncated {
  padding: 0.75rem 2rem;
}

.directory-picker-footer-spacer {
  flex: 1;
}

.directory-picker-new-btn {
  display: flex;
  align-items: center;
  gap: 0.375rem;
}

.directory-picker-new-icon {
  width: 1rem;
  height: 1rem;
}

/* Create directory form inside the list */
.directory-picker-create-form {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  background: var(--bg-tertiary);
  border-bottom: 1px solid var(--border);
}

.directory-picker-create-input {
  flex: 1;
  padding: 0.375rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  background: var(--bg-base);
  color: var(--text-primary);
  font-family: var(--font-mono);
  font-size: 0.875rem;
}

.directory-picker-create-input:focus {
  outline: none;
  border-color: var(--primary);
}

.directory-picker-create-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  padding: 0;
  border: none;
  border-radius: 0.25rem;
  background: var(--primary);
  color: white;
  cursor: pointer;
  transition: background-color 0.15s;
}

.directory-picker-create-btn:hover:not(:disabled) {
  background: var(--primary-hover);
}

.directory-picker-create-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.directory-picker-create-btn svg {
  width: 1rem;
  height: 1rem;
}

.directory-picker-cancel-btn {
  background: var(--bg-secondary);
  color: var(--text-secondary);
}

.directory-picker-cancel-btn:hover:not(:disabled) {
  background: var(--bg-tertiary);
}

.directory-picker-create-error {
  padding: 0.375rem 0.75rem;
  background: var(--error-bg);
  color: var(--error-text);
  font-size: 0.75rem;
  border-bottom: 1px solid var(--error-border);
}

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

/* Context Usage Bar */
/* Status bar for active conversation */
.status-bar-active {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  width: 100%;
  min-width: 0;
}

.status-working-group {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* Right-hand status readout: "~/dir · 15k · model-name", dot-separated. One
   type style for every segment (the cwd used to be mono at a different size,
   which read as three unrelated widgets sitting next to each other) — set
   here on the container and inherited, so the segments can't drift apart.

   min-width: 0 here and on every descendant down to the model name is what
   lets the readout shrink by ellipsizing instead of overflowing the bar; a
   single default min-width: auto anywhere in that chain floors the whole
   subtree at its content width. This holds on mobile too (where the cwd
   segment is hidden), so the media query needs no override. */
.status-readout {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  margin-left: auto;
  min-width: 0;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  line-height: 1.2;
  color: var(--text-secondary);
}

/* Shrink order under pressure is cwd first, then the model name; the token
   count never gives (a clipped "1" reads as a different number, so it stays
   flex-shrink: 0). flex-shrink is weighted by base size, so the long cwd
   already absorbs most of any deficit — the explicit 3 states the intent
   rather than leaving it emergent, and keeps the model name legible longer.
   direction: rtl ellipsizes the root, keeping the leaf directory visible. */
.status-readout-cwd {
  flex-shrink: 3;
  min-width: 0;
  max-width: 60ch;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  direction: rtl;
  text-align: left;
  unicode-bidi: plaintext;
}

.status-readout-sep {
  flex-shrink: 0;
  opacity: 0.5;
}

/* The model segment wraps the inline ModelPicker so a tooltip has something to
   attach to while the picker itself is disabled (a disabled control emits no
   pointer events, so v-tooltip on it would never fire). */
.status-readout-model {
  display: flex;
  min-width: 0;
}

.status-stop-button {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.25rem 0.5rem;
  border: none;
  border-radius: 0.25rem;
  background: var(--error-bg);
  color: var(--error-text);
  cursor: pointer;
  transition: all 0.15s ease;
  font-size: 0.75rem;
  font-weight: 500;
}

.status-stop-button:hover:not(:disabled) {
  background: var(--error-text);
  color: white;
}

.status-stop-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.status-stop-button svg {
  width: 0.75rem;
  height: 0.75rem;
  flex-shrink: 0;
}

.status-stop-label {
  white-space: nowrap;
}

/* Hide stop label on small screens */
@media (max-width: 500px) {
  .status-stop-label {
    display: none;
  }
  .status-stop-button {
    padding: 0.25rem;
  }
}

/* Wrapper holding the popover and its anchor. min-width: 0 because a block-level
   flex item defaults to min-width: auto, which floors it at its content width;
   the token count itself never shrinks (see .context-usage-label-tokens), but a
   floored segment steals width the model name beside it needs to ellipsize. */
.context-usage-root {
  min-width: 0;
}

.context-usage-container {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  min-width: 0;
}

.context-warning-icon {
  flex-shrink: 0;
  font-size: 0.875rem;
  line-height: 1;
  cursor: help;
}

/* Context usage readout: "132k · model-name", opens the context usage popup.
   Type is inherited from .status-readout so this matches the cwd segment. */
.context-usage-label {
  display: flex;
  /* center, not baseline: the model-name span has overflow:hidden for its
     ellipsis, and baseline synthesis for a non-visible-overflow box varies
     across engines. Visually identical here — one line, one font size. */
  align-items: center;
  gap: 0.375rem;
  min-width: 0;
  /* Vertical padding cancelled by an equal negative margin: the 14px-tall text
     alone is under the 24px minimum touch target, and on mobile this is the
     only way to open the popup. The hit area grows; the layout doesn't move.
     Vertical only — negative horizontal margin would eat into the flex gap
     that separates this from the cwd/hostname readouts. */
  padding: 5px 0;
  margin: -5px 0;
  border: none;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

.context-usage-label:hover {
  color: var(--text-primary);
}

.context-usage-label:focus-visible {
  outline: 2px solid var(--blue-text);
  outline-offset: 1px;
  border-radius: 3px;
}

.context-usage-label-tokens {
  flex-shrink: 0;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  transition: color 0.3s ease;
}

.context-usage-label-tokens-warn {
  color: var(--warning-text, #f59e0b);
}

.context-usage-label-tokens-error {
  color: var(--error-text);
}

/* Inline status slot in message controls — hidden on desktop, shown on mobile */
.message-controls-status-slot {
  display: none;
}

/* Mobile optimizations for tighter spacing */
@media (max-width: 767px) {
  .header {
    padding: 0.375rem 0.75rem;
    padding-top: calc(0.375rem + env(safe-area-inset-top, 0px));
  }

  /* Hide standalone status bar on mobile — content is shown inline in controls row.
     Exception: keep visible for archived conversations (no MessageInput rendered)
     and new conversations (status slot is not used). */
  .status-bar:not(.status-bar-archived):not(.status-bar-new) {
    display: none;
  }

  .hide-on-mobile {
    display: none;
  }

  /* Show inline status slot on mobile */
  .message-controls-status-slot {
    display: flex;
    align-items: center;
    flex: 1;
    min-width: 0;
    overflow: hidden;
    font-size: 0.875rem;
  }

  /* Compact the status bar active layout when inline */
  .message-controls-status-slot .status-bar-active {
    gap: 0.375rem;
  }

  /* The hostname readout yields room to the context usage label rather than
     wrapping to a second line. Scoped to .status-ready: error and
     no-models messages are the whole point of the status bar when they
     appear, and must keep wrapping rather than be clipped. */
  .message-controls-status-slot .status-message.status-ready {
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* Let new-conversation fields share a row when they fit and wrap naturally
     when the available width is too narrow. */
  .message-controls-status-slot .status-bar-new-conversation {
    width: 100%;
    gap: 0.375rem;
  }

  .message-controls-status-slot .status-field {
    min-width: 0;
  }

  .message-controls-status-slot .status-chip {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .message-input-container {
    padding: 0.5rem 0.75rem;
    padding-bottom: calc(0.5rem + env(safe-area-inset-bottom, 0px));
    border-top: 1px solid var(--border);
  }

  .message-input-form {
    flex-direction: column-reverse;
    align-items: stretch;
    gap: 0.375rem;
  }

  .message-controls-row {
    width: 100%;
  }

  .message-attach-btn,
  .message-voice-btn,
  .message-send-btn {
    margin-bottom: 0;
  }

  .send-split-btn {
    margin-bottom: 0;
  }
}

/* Print styles - looks like the chat window, just without chrome */
@media print {
  /* Reset page layout */
  html,
  body {
    height: auto !important;
    overflow: visible !important;
    background: white !important;
  }

  /* Hide interactive chrome but keep the header title */
  .status-bar,
  .message-input-container,
  .drawer,
  .backdrop,
  .scroll-to-bottom-button,
  .overflow-menu,
  .chat-overflow-popover,
  .context-menu,
  .modal-overlay {
    display: none !important;
  }

  /* Hide header buttons but keep the title */
  .header-actions,
  .header .btn-icon {
    display: none !important;
  }

  /* Simplify header for print */
  .header {
    background: white !important;
    border-bottom: 1px solid #e5e7eb !important;
    padding: 0.75rem 1rem !important;
  }

  .header-title {
    font-size: 1rem !important;
  }

  /* Reset app container for print */
  .app-container {
    display: block !important;
    height: auto !important;
    background: white !important;
  }

  .main-content {
    display: block !important;
    height: auto !important;
  }

  /* Reset messages area to flow naturally */
  .messages-area-wrapper {
    height: auto !important;
    overflow: visible !important;
    position: static !important;
    background: white !important;
  }

  .messages-container {
    height: auto !important;
    overflow: visible !important;
    position: static !important;
    background: white !important;
  }

  .messages-list {
    background: white !important;
  }

  /* Hide empty state in print */
  .empty-state {
    display: none !important;
  }

  /* Keep message styling, just add page break hints */
  .message {
    page-break-inside: avoid;
  }

  /* Tool results */
  .tool-result-details {
    page-break-inside: avoid;
  }

  /* Code blocks */
  pre,
  code {
    page-break-inside: avoid;
  }

  /* Screenshots and images - ensure they fit */
  .screenshot-preview,
  .screenshot-image,
  .read-image-preview {
    max-width: 100% !important;
    height: auto !important;
    page-break-inside: avoid;
  }
}

/* AGENTS.md Editor Modal */
.agents-md-header-path {
  flex: 1;
  min-width: 0;
  font-size: 0.8rem;
  color: var(--text-secondary);
  font-family: var(--font-mono);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.agents-md-save-status {
  font-size: 0.75rem;
  white-space: nowrap;
  flex-shrink: 0;
}

.agents-md-save-saving {
  color: var(--text-secondary);
}

.agents-md-save-saved {
  color: var(--success-text, #16a34a);
}

.agents-md-save-error {
  color: var(--error-text, #dc2626);
}

/* Diff Viewer Overlay */
.diff-viewer-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  padding-top: max(1rem, env(safe-area-inset-top, 0px));
  padding-bottom: max(1rem, env(safe-area-inset-bottom, 0px));
}

.diff-viewer-container {
  background: var(--bg-base);
  border-radius: 0.5rem;
  width: calc(100% - 2rem);
  max-width: none;
  height: calc(100% - 2rem);
  max-height: none;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.3);
}

.diff-viewer-header {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.375rem 0.75rem;
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border-color);
}

.diff-viewer-header-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
}

/* Header title shown in desktop sidebar layout in place of the
   selectors row — the open file path or commit-message subject. */
.diff-viewer-header-title {
  flex: 1 1 0;
  min-width: 0;
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 0 0.25rem;
}

.diff-viewer-selectors-row {
  display: flex;
  flex: 1;
  gap: 0.5rem;
  min-width: 0;
  /* align bottoms so the two inputs sit on the same baseline without
   * stretching the column and wasting vertical space between the label
   * and the input. */
  align-items: flex-end;
}

.diff-viewer-selectors-row .diff-viewer-select {
  flex: 1;
  min-width: 0;
  max-width: none;
}

.diff-viewer-selector-group {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  gap: 0;
}

.diff-viewer-selector-label {
  font-size: 0.65rem;
  line-height: 1.1;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-secondary);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 0.125rem;
  display: flex;
  align-items: center;
  gap: 0.25rem;
  min-height: 1.25rem;
}

/* Combined commit picker (replaces the prior pair of <select>s). */
.commit-picker {
  position: relative;
  display: flex;
  flex: 1;
  min-width: 0;
}

.commit-picker-trigger {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1;
  min-width: 0;
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--border-color);
  border-radius: 0.25rem;
  background: var(--bg-base);
  color: var(--text-primary);
  font-size: 0.875rem;
  cursor: pointer;
  text-align: left;
}

.commit-picker-trigger:hover {
  background: var(--bg-tertiary);
}

.commit-picker-trigger-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  line-height: 1.2;
}

.commit-picker-trigger-primary {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.commit-picker-trigger-chevron {
  flex-shrink: 0;
  color: var(--text-secondary);
  font-size: 0.875rem;
}

/* Desktop popover */
.commit-picker-popover {
  position: absolute;
  z-index: 1500;
  margin-top: 0.25rem;
  width: min(560px, calc(100vw - 2rem));
  max-height: 70vh;
  background: var(--bg-base);
  border: 1px solid var(--border-color);
  border-radius: 0.375rem;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Mobile modal */
.commit-picker-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 1500;
  display: flex;
  align-items: stretch;
  justify-content: stretch;
}

.commit-picker-modal {
  background: var(--bg-base);
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.commit-picker-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border-color);
  font-weight: 600;
}

.commit-picker-modal-close {
  width: 2rem;
  height: 2rem;
  border: none;
  background: transparent;
  font-size: 1.25rem;
  cursor: pointer;
  color: var(--text-secondary);
  border-radius: 0.25rem;
}

.commit-picker-modal-close:hover {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

.commit-picker-help {
  padding: 0.5rem 0.75rem;
  font-size: 0.75rem;
  color: var(--text-secondary);
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border-color);
  line-height: 1.4;
}

.commit-picker-status {
  padding: 0.5rem 0.75rem;
  font-size: 0.75rem;
  color: var(--text-secondary);
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border-color);
  line-height: 1.4;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* Range toggle: rendered as a pair of side-by-side cards so the
   either/or nature of the choice is obvious at a glance. */
.commit-picker-range-toggle {
  display: grid;
  /* `minmax(0, 1fr)` keeps both cards exactly half-width even when their
     labels would otherwise blow out the second column. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 0.375rem;
  flex-shrink: 0;
}

.commit-picker-range-btn {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  min-width: 0;
  background: var(--bg-base);
  border: 1px solid var(--border-color);
  border-radius: 0.375rem;
  padding: 0.375rem 0.5rem;
  font-size: 0.75rem;
  color: var(--text-secondary);
  cursor: pointer;
  font-family: inherit;
  line-height: 1.25;
  text-align: left;
  transition:
    background 0.1s ease,
    border-color 0.1s ease;
}

.commit-picker-range-btn:hover:not(:disabled) {
  background: var(--bg-tertiary);
  border-color: var(--text-secondary);
  color: var(--text-primary);
}

.commit-picker-range-btn.active {
  background: var(--accent-bg, rgba(37, 99, 235, 0.18));
  border-color: var(--accent-text, var(--accent, #2563eb));
  color: var(--accent-text, var(--text-primary));
}

.commit-picker-range-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.commit-picker-range-btn-radio {
  flex-shrink: 0;
  width: 0.8rem;
  height: 0.8rem;
  margin-top: 0.1rem;
  border-radius: 50%;
  border: 1.5px solid var(--text-secondary);
  background: transparent;
  position: relative;
}

.commit-picker-range-btn.active .commit-picker-range-btn-radio {
  border-color: var(--accent-text, var(--accent, #2563eb));
}

.commit-picker-range-btn.active .commit-picker-range-btn-radio::after {
  content: "";
  position: absolute;
  inset: 2px;
  border-radius: 50%;
  background: var(--accent-text, var(--accent, #2563eb));
}

.commit-picker-range-btn-label {
  font-weight: 600;
  font-size: 0.75rem;
  color: var(--text-primary);
  flex: 1 1 0;
  min-width: 0;
  /* Multi-word labels (e.g. "Through working tree") should wrap, not
     get clipped in narrow sidebars. */
  overflow-wrap: break-word;
  word-break: normal;
  white-space: normal;
  line-height: 1.15;
}

.commit-picker-range-btn.active .commit-picker-range-btn-label {
  color: var(--accent-text, var(--text-primary));
}

.commit-picker-status code {
  font-family: monospace;
  color: var(--text-primary);
  background: var(--bg-base);
  padding: 0.05rem 0.3rem;
  border-radius: 0.2rem;
  border: 1px solid var(--border-color);
}

.commit-picker-status-pending {
  background: rgba(99, 102, 241, 0.12);
  color: var(--text-primary);
  border-bottom-color: rgba(99, 102, 241, 0.4);
}

.commit-picker-action-primary {
  background: rgba(99, 102, 241, 0.15) !important;
  border-color: rgba(99, 102, 241, 0.5) !important;
  color: rgb(165, 180, 252) !important;
  font-weight: 600;
}

.commit-picker-trigger-primary code {
  font-family: monospace;
}

.commit-picker-list {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

.commit-picker-empty {
  padding: 1.5rem;
  text-align: center;
  color: var(--text-secondary);
  font-size: 0.875rem;
}

.commit-picker-row {
  display: flex;
  align-items: stretch;
  border-bottom: 1px solid var(--border-color);
  position: relative;
}

.commit-picker-row:last-child {
  border-bottom: none;
}

.commit-picker-row-from {
  background: var(--blue-bg, rgba(59, 130, 246, 0.12));
}

.commit-picker-row-to {
  background: var(--green-bg, rgba(16, 185, 129, 0.12));
}

.commit-picker-row-in-range {
  background: rgba(59, 130, 246, 0.05);
}

.commit-picker-row-main {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  border: none;
  background: transparent;
  cursor: pointer;
  text-align: left;
  color: inherit;
  min-width: 0;
}

.commit-picker-row-main:hover {
  background: var(--bg-tertiary);
}

.commit-picker-row-marker {
  width: 1rem;
  flex-shrink: 0;
  text-align: center;
  color: var(--text-secondary);
  font-family: monospace;
}

.commit-picker-row-from .commit-picker-row-marker {
  color: var(--blue-text, #2563eb);
}

.commit-picker-row-to .commit-picker-row-marker {
  color: var(--green-text, #059669);
}

.commit-picker-row-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}

.commit-picker-row-subject {
  font-size: 0.875rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: flex;
  align-items: center;
  gap: 0.25rem;
  min-width: 0;
}

.commit-picker-row-message {
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.commit-picker-refs {
  display: inline-flex;
  gap: 0.25rem;
  flex-shrink: 0;
}

.commit-picker-ref {
  display: inline-block;
  font-size: 0.7rem;
  font-family: monospace;
  line-height: 1;
  padding: 0.15rem 0.35rem;
  border-radius: 0.25rem;
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  border: 1px solid var(--border-color);
  white-space: nowrap;
}

.commit-picker-ref-head {
  background: rgba(99, 102, 241, 0.15);
  color: rgb(129, 140, 248);
  border-color: rgba(99, 102, 241, 0.4);
  font-weight: 600;
}

.commit-picker-ref-remote {
  background: rgba(244, 114, 182, 0.12);
  color: rgb(244, 114, 182);
  border-color: rgba(244, 114, 182, 0.35);
}

.commit-picker-ref-mergebase {
  background: rgba(245, 158, 11, 0.15);
  color: rgb(251, 191, 36);
  border-color: rgba(245, 158, 11, 0.4);
  font-style: italic;
}

.commit-picker-row-pending {
  outline: 2px dashed rgba(99, 102, 241, 0.5);
  outline-offset: -2px;
  border-radius: 0.25rem;
}

.commit-picker-row-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  font-size: 0.7rem;
  color: var(--text-secondary);
}

.commit-picker-row-hash {
  font-family: monospace;
}

.commit-picker-row-actions {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  padding-right: 0.5rem;
  flex-shrink: 0;
}

.commit-picker-action {
  padding: 0.25rem 0.5rem;
  font-size: 0.7rem;
  border: 1px solid var(--border-color);
  border-radius: 0.25rem;
  background: var(--bg-base);
  color: var(--text-primary);
  cursor: pointer;
  white-space: nowrap;
}

.commit-picker-action:hover {
  background: var(--bg-tertiary);
}

.diff-viewer-file-selector-wrapper {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1;
  min-width: 0;
}

.diff-viewer-file-selector-wrapper .diff-viewer-select {
  flex: 1;
  min-width: 0;
}

.diff-viewer-file-index {
  font-size: 0.75rem;
  color: var(--text-secondary);
  white-space: nowrap;
  flex-shrink: 0;
}

.diff-viewer-controls-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}

.diff-viewer-header-mobile {
  flex-direction: row;
  align-items: center;
  gap: 0.5rem;
  padding: 0.375rem 0.5rem;
}

.diff-viewer-mobile-selectors {
  display: flex;
  flex: 1;
  gap: 0.375rem;
  min-width: 0;
}

.diff-viewer-mobile-selectors .diff-viewer-select {
  flex: 1;
  min-width: 0;
  font-size: 0.75rem;
  padding: 0.375rem;
}

.diff-viewer-mode-toggle {
  display: flex;
  border: 1px solid var(--border-color);
  border-radius: 0.25rem;
  overflow: hidden;
}

.diff-viewer-mode-btn {
  padding: 0.25rem 0.5rem;
  border: none;
  background: var(--bg-base);
  color: var(--text-secondary);
  cursor: pointer;
  font-size: 0.875rem;
}

.diff-viewer-mode-btn:first-child {
  border-right: 1px solid var(--border-color);
}

.diff-viewer-mode-btn.active {
  background: var(--blue-bg);
  color: var(--blue-text);
}

.diff-viewer-mode-btn:hover:not(.active) {
  background: var(--bg-tertiary);
}

.diff-viewer-nav-buttons {
  display: flex;
  gap: 0.125rem;
}

.diff-viewer-nav-btn {
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--border-color);
  background: var(--bg-base);
  color: var(--text-primary);
  cursor: pointer;
  border-radius: 0.25rem;
  font-size: 0.875rem;
}

.diff-viewer-nav-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.diff-viewer-nav-btn:hover:not(:disabled) {
  background: var(--bg-tertiary);
}

.diff-viewer-select {
  flex: 1;
  min-width: 120px;
  max-width: 300px;
  padding: 0.5rem;
  border: 1px solid var(--border-color);
  border-radius: 0.25rem;
  background: var(--bg-base);
  color: var(--text-primary);
  font-size: 0.875rem;
}

.diff-viewer-dir-btn {
  width: 2rem;
  height: 2rem;
  border: none;
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  border-radius: 0.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  padding: 0;
}

.diff-viewer-dir-btn:hover {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

.diff-viewer-close {
  width: 2rem;
  height: 2rem;
  border: none;
  background: transparent;
  color: var(--text-secondary);
  font-size: 1.5rem;
  cursor: pointer;
  border-radius: 0.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.diff-viewer-close:hover {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

.diff-viewer-error {
  padding: 0.5rem 1rem;
  background: var(--error-bg);
  color: var(--error-text);
  font-size: 0.875rem;
}

.diff-viewer-toast {
  position: fixed;
  bottom: 24px;
  right: 24px;
  padding: 12px 16px;
  border-radius: 8px;
  font-size: 0.875rem;
  font-weight: 500;
  z-index: 9999;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  animation: toast-fade-in 0.2s ease;
  color: #ffffff;
}

.diff-viewer-toast-saving {
  background: #1976d2;
}

.diff-viewer-toast-saved {
  background: #2e7d32;
}

.diff-viewer-toast-error {
  background: #d32f2f;
}

.diff-viewer-toast-hint {
  background: var(--bg-tertiary);
  color: var(--text-primary);
  border: 1px solid var(--border-color);
}

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

.diff-viewer-content {
  flex: 1;
  overflow: hidden;
  position: relative;
}

/* Sidebar layout: split content into a left column (commit picker + file
 * list) and the main editor area. Desktop only. */
.diff-viewer-content-sidebar {
  display: flex;
  flex-direction: row;
  align-items: stretch;
}

.diff-viewer-content-sidebar > .diff-viewer-main {
  flex: 1;
  min-width: 0;
  position: relative;
  overflow: hidden;
}

.diff-viewer-content:not(.diff-viewer-content-sidebar) > .diff-viewer-main {
  height: 100%;
  width: 100%;
  /* Make .diff-viewer-main the offset parent in both layouts so the floating
     comment prompt's getBoundingClientRect math matches its positioning. */
  position: relative;
}

.diff-viewer-sidebar {
  width: 280px;
  flex-shrink: 0;
  border-right: 1px solid var(--border-color);
  background: var(--bg-secondary);
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

.diff-viewer-sidebar-section {
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: 0.375rem 0.5rem;
}

.diff-viewer-sidebar-commits {
  border-bottom: 1px solid var(--border-color);
  /* Size to content when the commit list is short so the file list
   * gets the leftover real estate; cap at half the sidebar when the
   * history is long enough to scroll. */
  flex: 0 1 auto;
  max-height: 50%;
}

.diff-viewer-sidebar-commits-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  margin: 0 -0.25rem;
}

.diff-viewer-sidebar-range {
  margin-bottom: 0.375rem;
}

.diff-viewer-sidebar-range .commit-picker-range-toggle {
  width: 100%;
}

.diff-viewer-sidebar-range .commit-picker-range-btn {
  flex: 1;
  white-space: nowrap;
}

.diff-viewer-sidebar-files {
  /* Take all remaining vertical space below the commit section. */
  flex: 1 1 0;
  min-height: 0;
  padding-bottom: 0.25rem;
}

.diff-viewer-sidebar-label {
  font-size: 0.65rem;
  line-height: 1.1;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-secondary);
  font-weight: 600;
  margin-bottom: 0.25rem;
  display: flex;
  align-items: center;
  gap: 0.375rem;
  min-height: 1.5rem;
}

/* Sidebar commit list (above the picker shows a few recent commits +
 * working changes to make orientation quick). */
.diff-viewer-commit-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.diff-viewer-commit-list-item {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.125rem;
  padding: 0.25rem 0.5rem;
  background: transparent;
  border: none;
  border-radius: 0.25rem;
  color: var(--text-primary);
  font-size: 0.8125rem;
  text-align: left;
  cursor: pointer;
  font-family: inherit;
}

.diff-viewer-commit-list-item:hover {
  background: var(--bg-tertiary);
}

/* Highlight commits inside the active diff range (only the selected
 * commit, or every commit between it and the working tree). The
 * selected row gets a stronger tint than the in-range siblings so the
 * "from" endpoint is still distinguishable in through-working mode. */
.diff-viewer-commit-list-item.in-range {
  background: var(--accent-bg, rgba(37, 99, 235, 0.1));
}

.diff-viewer-commit-list-item.selected {
  background: var(--accent-bg, rgba(37, 99, 235, 0.22));
  font-weight: 500;
}

.diff-viewer-commit-list-item.working {
  font-style: italic;
}

.diff-viewer-commit-list-line1 {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  min-width: 0;
}

.diff-viewer-commit-list-subject {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.diff-viewer-commit-list-range {
  flex-shrink: 0;
  font-size: 0.6875rem;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

.diff-viewer-commit-list-refs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-left: 0.125rem;
}

.diff-viewer-commit-list-ref {
  display: inline-block;
  font-size: 0.6875rem;
  line-height: 1.1;
  padding: 0.0625rem 0.3125rem;
  border-radius: 0.625rem;
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  white-space: nowrap;
}

.diff-viewer-commit-list-ref.head {
  background: var(--accent-bg, rgba(37, 99, 235, 0.15));
  color: var(--accent-text, #2563eb);
  font-weight: 600;
}

.diff-viewer-commit-list-ref.remote {
  background: var(--green-bg, rgba(22, 163, 74, 0.12));
  color: var(--green-text, #16a34a);
}

.diff-viewer-commit-list-ref.mergebase {
  background: transparent;
  color: var(--text-secondary);
  border: 1px dashed var(--border-color);
}

.diff-viewer-sidebar-files-scroll {
  flex: 1;
  min-height: 0;
  /* The inner tree owns its scrollbar; we only keep overflow:hidden so
     a stray commit-message overflow doesn't break layout. */
  overflow: hidden;
  display: flex;
  flex-direction: column;
  margin: 0 -0.25rem;
}

.diff-viewer-file-list {
  display: flex;
  flex-direction: column;
  min-height: 0;
  height: 100%;
  gap: 0.25rem;
}

/* Wrapper that lets the file tree fill the sidebar's remaining space. */
.diff-viewer-file-tree-wrap {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* Home-grown file tree (replaces @pierre/trees: their middle-truncate
   and shadow-root theming fought our narrow sidebar). Style matches
   the rest of the diff-viewer sidebar so it blends in. */
.diff-tree {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.diff-tree-search {
  flex-shrink: 0;
  padding: 0 0.25rem;
}

.diff-tree-search-input {
  width: 100%;
  box-sizing: border-box;
  padding: 0.25rem 0.5rem;
  font-size: 0.8125rem;
  font-family: inherit;
  background: var(--bg-base);
  border: 1px solid var(--border-color);
  border-radius: 0.25rem;
  color: var(--text-primary);
}

.diff-tree-search-input:focus {
  outline: none;
  border-color: var(--accent-text, var(--text-secondary));
  box-shadow: 0 0 0 2px var(--accent-bg, rgba(37, 99, 235, 0.2));
}

.diff-tree-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 0 0.25rem 0.25rem;
}

.diff-tree-row {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.2rem 0.4rem;
  background: transparent;
  border: none;
  border-radius: 0.25rem;
  color: var(--text-primary);
  font-size: 0.8125rem;
  text-align: left;
  cursor: pointer;
  font-family: inherit;
  min-width: 0;
}

.diff-tree-row:hover {
  background: var(--bg-tertiary);
}

.diff-tree-row.active {
  background: var(--accent-bg, rgba(37, 99, 235, 0.15));
  color: var(--accent-text, var(--text-primary));
  font-weight: 500;
}

.diff-tree-icon {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 0.85rem;
  height: 0.85rem;
  color: var(--text-secondary);
}

.diff-tree-row.active .diff-tree-icon {
  color: inherit;
}

.diff-tree-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.diff-tree-decoration {
  flex-shrink: 0;
  font-size: 0.625rem;
  font-family: var(--font-mono, monospace);
  color: var(--text-secondary);
  padding: 0.05rem 0.25rem;
  border-radius: 0.2rem;
  background: var(--bg-tertiary);
}

.diff-tree-row.active .diff-tree-decoration {
  background: rgba(255, 255, 255, 0.25);
  color: inherit;
}

.diff-tree-status {
  flex-shrink: 0;
  width: 0.75rem;
  text-align: center;
  font-family: var(--font-mono, monospace);
  font-size: 0.6875rem;
  font-weight: 600;
  opacity: 0.85;
}

.diff-tree-changes {
  flex-shrink: 0;
  display: inline-flex;
  gap: 0.3rem;
  font-family: var(--font-mono, monospace);
  font-size: 0.625rem;
  font-weight: 600;
  opacity: 0.85;
}

.diff-tree-changes-added {
  color: var(--green-text, #16a34a);
}
.diff-tree-changes-deleted {
  color: var(--red-text, #dc2626);
}
.diff-tree-row.active .diff-tree-changes-added,
.diff-tree-row.active .diff-tree-changes-deleted {
  color: inherit;
}

.diff-tree-status-added {
  color: var(--green-text, #16a34a);
}
.diff-tree-status-deleted {
  color: var(--red-text, #dc2626);
}
.diff-tree-status-modified {
  color: var(--text-secondary);
}
.diff-tree-row.active .diff-tree-status {
  color: inherit;
}

.diff-viewer-file-list-empty {
  padding: 0.5rem 0.75rem;
  color: var(--text-secondary);
  font-size: 0.8125rem;
}

.diff-viewer-file-list-item {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.25rem 0.5rem;
  background: transparent;
  border: none;
  border-radius: 0.25rem;
  color: var(--text-primary);
  font-size: 0.8125rem;
  text-align: left;
  cursor: pointer;
  font-family: inherit;
}

.diff-viewer-file-list-item:hover {
  background: var(--bg-tertiary);
}

.diff-viewer-file-list-item.active {
  background: var(--accent-bg, rgba(37, 99, 235, 0.15));
  color: var(--accent-text, var(--text-primary));
  font-weight: 500;
}

.diff-viewer-file-list-status {
  flex-shrink: 0;
  font-family: var(--font-mono, monospace);
  width: 0.75rem;
  text-align: center;
  opacity: 0.75;
}

.diff-viewer-file-list-status.status-added {
  color: var(--green-text, #16a34a);
}
.diff-viewer-file-list-status.status-deleted {
  color: var(--red-text, #dc2626);
}
.diff-viewer-file-list-status.status-modified {
  color: var(--text-secondary);
}

.diff-viewer-file-list-icon {
  flex-shrink: 0;
}

.diff-viewer-file-list-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.diff-viewer-file-list-stats {
  flex-shrink: 0;
  display: flex;
  gap: 0.25rem;
  font-size: 0.6875rem;
  font-variant-numeric: tabular-nums;
  opacity: 0.8;
}

.diff-viewer-file-list-stats .add {
  color: var(--green-text, #16a34a);
}
.diff-viewer-file-list-stats .del {
  color: var(--red-text, #dc2626);
}
.diff-viewer-file-list-stats .gen {
  color: var(--text-secondary);
}

/* Chevron-double sidebar expand/collapse, styled like the conversations
 * drawer's collapse button. */
.diff-viewer-expand-btn,
.diff-viewer-collapse-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: var(--text-secondary);
  border: none;
  padding: 0.25rem;
  border-radius: 0.25rem;
  cursor: pointer;
}

.diff-viewer-expand-btn:hover,
.diff-viewer-collapse-btn:hover {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

.diff-viewer-collapse-btn {
  flex-shrink: 0;
}

.diff-viewer-loading,
.diff-viewer-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: var(--text-secondary);
  gap: 0.5rem;
}

.diff-viewer-hint {
  font-size: 0.875rem;
  opacity: 0.7;
}

.diff-viewer-editor {
  height: 100%;
  width: 100%;
}

/* Diff viewer line hover highlighting (via decoration API) */
.diff-viewer-editor .monaco-editor .diff-viewer-line-hover {
  background-color: rgba(37, 99, 235, 0.08) !important;
}

.dark .diff-viewer-editor .monaco-editor .diff-viewer-line-hover {
  background-color: rgba(96, 165, 250, 0.12) !important;
}

/* Comment indicator glyph in margin for diff viewer */
.diff-viewer-editor .monaco-editor .diff-viewer-comment-glyph {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z'%3E%3C/path%3E%3Cline x1='9' y1='10' x2='15' y2='10'%3E%3C/line%3E%3C/svg%3E");
  background-size: 14px 14px;
  background-repeat: no-repeat;
  background-position: center;
  opacity: 0.6;
  cursor: pointer;
}

.diff-viewer-editor .monaco-editor .diff-viewer-comment-glyph:hover {
  opacity: 1;
}

.dark .diff-viewer-editor .monaco-editor .diff-viewer-comment-glyph {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z'%3E%3C/path%3E%3Cline x1='9' y1='10' x2='15' y2='10'%3E%3C/line%3E%3C/svg%3E");
}

/* Make diff viewer Monaco lines clickable with pointer cursor */
.diff-viewer-editor .monaco-editor .view-lines {
  cursor: pointer;
}

.diff-viewer-comment-badge {
  position: absolute;
  bottom: 1rem;
  left: 1rem;
  padding: 0.5rem 1rem;
  background: var(--blue-bg);
  color: var(--blue-text);
  border-radius: 1rem;
  font-size: 0.875rem;
  font-weight: 500;
}

/* Floating "add comment" prompt next to a text selection in comment mode */
.diff-viewer-comment-prompt {
  position: absolute;
  z-index: 1002;
  padding: 0.25rem 0.6rem;
  background: var(--blue-bg);
  color: var(--blue-text);
  border: 1px solid var(--border-color);
  border-radius: 1rem;
  font-size: 0.8125rem;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
}

.diff-viewer-comment-prompt:hover {
  filter: brightness(0.96);
}

/* Comment dialog */
.diff-viewer-comment-dialog {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* Grow to fit the quoted line, within reason; the pre scrolls beyond that. */
  width: max-content;
  min-width: min(500px, 90%);
  max-width: 90%;
  background: var(--bg-base);
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
  padding: 1rem;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  z-index: 1001;
}

/* Once dragged, the dialog uses explicit top/left, so drop the centering transform. */
.diff-viewer-comment-dialog.is-dragged {
  transform: none;
}

.diff-viewer-comment-dialog h4 {
  margin: 0 0 0.75rem 0;
  color: var(--text-primary);
}

/* Draggable header for the comment dialog. */
.diff-viewer-comment-dialog-handle {
  cursor: move;
  user-select: none;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.diff-viewer-comment-dialog-handle::before {
  content: "\2630";
  opacity: 0.4;
  font-size: 0.85em;
}

.diff-viewer-selected-text {
  margin: 0 0 0.75rem 0;
  padding: 0.5rem;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  border-radius: 0.25rem;
  font-size: 0.75rem;
  font-family: var(--font-mono);
  max-height: 150px;
  overflow: auto;
  white-space: pre;
}

.diff-viewer-comment-input {
  width: 100%;
  min-height: 100px;
  padding: 0.5rem;
  border: 1px solid var(--border-color);
  border-radius: 0.25rem;
  background: var(--bg-base);
  color: var(--text-primary);
  font-size: 0.875rem;
  resize: vertical;
}

.diff-viewer-comment-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 0.75rem;
}

.diff-viewer-btn {
  padding: 0.5rem 1rem;
  border: none;
  border-radius: 0.25rem;
  font-size: 0.875rem;
  cursor: pointer;
}

.diff-viewer-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.diff-viewer-btn-primary {
  background: var(--blue-bg);
  color: var(--blue-text);
}

.diff-viewer-btn-primary:hover:not(:disabled) {
  filter: brightness(0.95);
}

.diff-viewer-btn-secondary {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

.diff-viewer-btn-secondary:hover:not(:disabled) {
  background: var(--bg-secondary);
}

/* Image annotation view (ImageCommentModal): drag a box on the image, comment on
 * it in the diff viewer's CommentDialog, and the comment goes straight into the
 * message input. Layered over the conversation on a backdrop, matching the diff
 * viewer, whose .diff-viewer-btn buttons and comment dialog it reuses. Regions
 * are positioned in percentages of the image box so they track any resize. */
.image-comment-overlay {
  position: fixed;
  inset: 0;
  z-index: 1500;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.5);
  padding: 1rem;
  padding-top: max(1rem, env(safe-area-inset-top, 0px));
  padding-bottom: max(1rem, env(safe-area-inset-bottom, 0px));
}

.image-comment-container {
  display: flex;
  flex-direction: column;
  width: calc(100% - 2rem);
  height: calc(100% - 2rem);
  overflow: hidden;
  border-radius: 0.5rem;
  background: var(--bg-secondary);
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.3);
}

.image-comment-bar {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--border);
  background: var(--bg-base);
}

.image-comment-title {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 40%;
}

.image-comment-hint {
  flex: 1;
  min-width: 0;
  font-size: 0.8125rem;
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.image-comment-bar-link {
  flex-shrink: 0;
  font-size: 0.8125rem;
  color: var(--link-color);
}

.image-comment-close {
  flex-shrink: 0;
  width: 2rem;
  height: 2rem;
  border: none;
  border-radius: 0.25rem;
  background: transparent;
  color: var(--text-secondary);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}

.image-comment-close:hover {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

.image-comment-stage {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  overflow: auto;
}

/* Shrink-wraps the image so region percentages resolve against the pixels the
 * user actually sees. Deliberately unconstrained: the image below carries the
 * size limit, and a max-height here would clamp the frame while the image
 * overflowed it, leaving the overflowing part unmappable. */
.image-comment-frame {
  position: relative;
  display: inline-block;
  max-width: 100%;
  line-height: 0;
  cursor: crosshair;
  touch-action: none;
}

.image-comment-frame.is-drawing {
  user-select: none;
}

.image-comment-img {
  display: block;
  max-width: 100%;
  /* Against the viewport, not the frame: a percentage max-height would resolve
   * against the frame's auto height, i.e. not at all, and a tall image would
   * render full size and scroll out of reach. The subtrahend is this panel's
   * chrome -- overlay padding, container inset, title bar, stage padding. */
  max-height: calc(100dvh - 9rem);
  width: auto;
  height: auto;
  background: var(--bg-tertiary);
}

/* A drawn region. Transparent to pointers so a new drag can start anywhere,
 * including over an existing region -- on a busy screenshot the regions would
 * otherwise cover most of the image, and there is nothing to click them for now
 * that their comment is already in the message input. */
.image-comment-region,
.image-comment-draft {
  position: absolute;
  border: 2px solid var(--primary);
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  padding: 0;
  pointer-events: none;
}

/* The box awaiting its comment, so it is clear which region the open dialog
 * belongs to. */
.image-comment-region.active {
  border-color: var(--warning-border);
  background: color-mix(in srgb, var(--warning-border) 20%, transparent);
}

.image-comment-draft {
  border-style: dashed;
}

.image-comment-region-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 0.25rem;
  border-radius: 999px;
  background: var(--primary);
  color: #fff;
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1;
}

/* Numbers a commented region from just outside its top-left corner, so it never
 * hides what it marks. */
.image-comment-region-badge {
  position: absolute;
  top: -0.75rem;
  left: -0.25rem;
}

/* Confirms comments reached the composer, which is otherwise off-screen behind
 * this view. */
.image-comment-sent {
  font-size: 0.8125rem;
  color: var(--success-text, var(--text-secondary));
}

/* Terminal state: an image we could not load has nothing to annotate, so the
 * stage says so and offers the only two useful actions. */
.image-comment-failed {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  padding: 2rem 1rem;
  color: var(--text-secondary);
  font-size: 0.875rem;
  text-align: center;
}

.image-comment-foot {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem;
  border-top: 1px solid var(--border);
  background: var(--bg-base);
}

/* Images that open the annotation view on click. Markdown images get the same
 * class and wrapper from MarkdownContent.vue; images inside a link keep their
 * navigation and are excluded. */
.commentable-image {
  cursor: pointer;
}

/* The wrapping link exists only for modifier-click (open in new tab), so it
 * should not look or lay out like body-text link. Positioned to anchor the
 * hover badge. */
.commentable-image-link {
  position: relative;
  display: inline-block;
  line-height: 0;
  text-decoration: none;
  color: inherit;
}

/* "Comment" badge over the corner of a commentable image. Hidden until hover or
 * keyboard focus: on a page of screenshots, permanent badges are noise. Shown
 * unconditionally on touch, where there is no hover to reveal it. */
.commentable-image-badge {
  position: absolute;
  top: 0.375rem;
  right: 0.375rem;
  display: flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.25rem 0.5rem;
  border-radius: 0.25rem;
  background: rgba(0, 0, 0, 0.72);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.2;
  opacity: 0;
  transition: opacity 0.12s ease-in-out;
  pointer-events: none;
}

.commentable-image-link:hover .commentable-image-badge,
.commentable-image-link:focus-visible .commentable-image-badge,
/* Markdown images are wrapped in a plain <span>, so focus lands on the image. */
.commentable-image:focus-visible + .commentable-image-badge {
  opacity: 1;
}

@media (hover: none) {
  .commentable-image-badge {
    opacity: 1;
  }
}

@media (max-width: 768px) {
  /* Nearly the whole screen: the padded, rounded panel wastes room a phone
   * does not have. */
  .image-comment-overlay {
    padding: 0;
  }

  .image-comment-container {
    width: 100%;
    height: 100%;
    border-radius: 0;
  }

  .image-comment-stage {
    padding: 0.5rem;
  }

  /* The bar has no room for the instruction at this width; the footer button
   * and the crosshair cursor carry it. */
  .image-comment-hint {
    display: none;
  }
}

/* Mobile floating nav buttons */
.diff-viewer-mobile-nav {
  position: absolute;
  bottom: 1.5rem;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 0.5rem;
  z-index: 100;
}

.diff-viewer-mobile-nav-btn {
  width: 3rem;
  height: 3rem;
  border: none;
  border-radius: 50%;
  background: var(--bg-base);
  color: var(--text-primary);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}

.diff-viewer-mobile-nav-btn svg {
  width: 24px;
  height: 24px;
}

.diff-viewer-mobile-nav-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.diff-viewer-mobile-nav-btn:active:not(:disabled) {
  background: var(--bg-tertiary);
  transform: scale(0.95);
}

.diff-viewer-mobile-mode-btn {
  font-size: 1.25rem;
}

.diff-viewer-mobile-mode-btn.active {
  background: var(--blue-bg);
  color: var(--blue-text);
}

/* Monaco comment glyph decoration */
/* Mobile optimizations for diff viewer */
@media (max-width: 767px) {
  .diff-viewer-overlay {
    align-items: stretch;
    justify-content: stretch;
    padding-top: env(safe-area-inset-top, 0px);
    padding-right: env(safe-area-inset-right, 0px);
    padding-bottom: env(safe-area-inset-bottom, 0px);
    padding-left: env(safe-area-inset-left, 0px);
  }

  .diff-viewer-container {
    border-radius: 0;
    width: 100%;
    max-width: 100%;
    height: 100dvh;
    max-height: 100dvh;
  }

  .diff-viewer-close {
    width: 1.75rem;
    height: 1.75rem;
    font-size: 1.25rem;
    flex-shrink: 0;
  }

  /* Monaco editor mobile styles - keep a small left inset so text and
   * selection handles do not sit flush against the viewport edge. */
  .diff-viewer-editor .monaco-editor .margin {
    width: 8px !important;
  }

  .diff-viewer-editor .monaco-editor .margin-view-overlays {
    width: 8px !important;
  }

  .diff-viewer-editor .monaco-editor .editor-scrollable {
    left: 8px !important;
  }

  .diff-viewer-editor .monaco-editor .lines-content {
    margin-left: 0 !important;
  }

  /* The inline diff gutters are just change markers on mobile. Keep them
   * narrow so red/green columns don't consume code space. */
  .diff-viewer-editor .monaco-diff-editor .line-delete,
  .diff-viewer-editor .monaco-diff-editor .line-insert,
  .diff-viewer-editor .monaco-diff-editor .char-delete,
  .diff-viewer-editor .monaco-diff-editor .char-insert {
    border-left-width: 2px !important;
  }

  /* Ensure diff editor uses full width */
  .diff-viewer-editor .monaco-diff-editor {
    width: 100% !important;
  }

  .diff-viewer-editor .monaco-diff-editor .editor.modified {
    width: 100% !important;
    left: 0 !important;
  }

  /* Comment dialog on top half of screen for mobile (keyboard space) */
  .diff-viewer-comment-dialog {
    top: 10%;
    transform: translate(-50%, 0);
    max-height: 40vh;
    overflow-y: auto;
  }

  .diff-viewer-comment-input {
    min-height: 60px;
  }
}

/* Injected text indicator (for diff comments) */
.injected-text-indicator {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 0.75rem;
  background: var(--blue-bg);
  border-bottom: 1px solid var(--border-color);
  gap: 0.5rem;
}

.injected-text-label {
  font-size: 0.875rem;
  color: var(--blue-text);
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.injected-text-insert-btn {
  padding: 0.375rem 0.75rem;
  background: var(--blue-text);
  color: white;
  border: none;
  border-radius: 0.25rem;
  font-size: 0.75rem;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
}

.injected-text-insert-btn:hover {
  filter: brightness(1.1);
}

/* Links in message text */
.text-link {
  color: var(--blue-text);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-color: var(--blue-border);
}

.text-link:hover {
  text-decoration-color: var(--blue-text);
}

/* Command Palette */
.command-palette-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 100;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding-top: 15vh;
}

.command-palette {
  background: var(--bg-base);
  border: 1px solid var(--border-color);
  border-radius: 0.75rem;
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
  width: 100%;
  max-width: 32rem;
  max-height: 60vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.command-palette-input-wrapper {
  display: flex;
  align-items: center;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border-color);
  gap: 0.75rem;
}

.command-palette-search-icon {
  color: var(--text-secondary);
  flex-shrink: 0;
}

.command-palette-input {
  flex: 1;
  border: none;
  background: transparent;
  font-size: 1rem;
  color: var(--text-primary);
  outline: none;
}

.command-palette-input::placeholder {
  color: var(--text-secondary);
}

.command-palette-shortcut {
  flex-shrink: 0;
}

.command-palette-spinner {
  width: 16px;
  height: 16px;
  border: 2px solid var(--border-color);
  border-top-color: var(--primary);
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
  flex-shrink: 0;
}

.command-palette-list {
  flex: 1;
  overflow-y: auto;
  padding: 0.5rem;
}

.command-palette-empty {
  padding: 2rem 1rem;
  text-align: center;
  color: var(--text-secondary);
}

.command-palette-item {
  display: flex;
  align-items: center;
  padding: 0.625rem 0.75rem;
  border-radius: 0.5rem;
  cursor: pointer;
  gap: 0.75rem;
}

.command-palette-item:hover,
.command-palette-item.selected {
  background: var(--bg-secondary);
}

.command-palette-item-icon {
  flex-shrink: 0;
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
}

.command-palette-item.selected .command-palette-item-icon {
  color: var(--primary);
}

.command-palette-item-content {
  flex: 1;
  min-width: 0;
}

.command-palette-item-title {
  font-size: 0.875rem;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.command-palette-item-subtitle {
  font-size: 0.75rem;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 0.125rem;
}

.command-palette-item-badge {
  flex-shrink: 0;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 0.125rem 0.375rem;
  background: var(--bg-tertiary);
  border-radius: 0.25rem;
  color: var(--text-secondary);
}

.command-palette-item-shortcut {
  flex-shrink: 0;
  margin-left: auto;
}

.command-palette-item-shortcut kbd {
  font-size: 0.75rem;
  font-family: inherit;
  padding: 0.125rem 0.375rem;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  border-radius: 0.25rem;
  color: var(--text-secondary);
}

/* Right-aligned keyboard hint on overflow-menu action rows. */
.overflow-menu-shortcut {
  flex-shrink: 0;
  margin-left: auto;
  padding-left: 1rem;
}

.overflow-menu-shortcut kbd {
  font-size: 0.75rem;
  font-family: inherit;
  padding: 0.125rem 0.375rem;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  border-radius: 0.25rem;
  color: var(--text-secondary);
  white-space: nowrap;
}

/* Edit File's shortcut is inert in Firefox (reserved for private window). */
.overflow-menu-shortcut-inert kbd {
  opacity: 0.5;
  text-decoration: line-through;
}

.command-palette-footer {
  display: flex;
  gap: 1rem;
  padding: 0.5rem 1rem;
  border-top: 1px solid var(--border-color);
  font-size: 0.75rem;
  color: var(--text-secondary);
}

.command-palette-footer span {
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

@media (max-width: 640px) {
  .command-palette-overlay {
    padding: 1rem;
    padding-top: 5vh;
  }

  .command-palette {
    max-height: 80vh;
  }

  .command-palette-footer {
    display: none;
  }
}

/* Models Modal Styles */
.models-modal {
  padding: 0.5rem;
}

.models-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 2rem;
  color: var(--text-secondary);
}

.models-error {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  background: var(--error-bg);
  border: 1px solid var(--error-border);
  border-radius: 0.375rem;
  color: var(--error-text);
  margin-bottom: 1rem;
}

.models-error-dismiss {
  background: none;
  border: none;
  font-size: 1.25rem;
  cursor: pointer;
  color: inherit;
  padding: 0;
  line-height: 1;
}

.oauth-panel {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin: 0 0 1rem;
  padding: 0.875rem 1rem;
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  background: var(--bg-secondary);
}

.models-modal-list .oauth-panel {
  margin: 0.5rem 1rem 1rem;
}

.oauth-panel-copy {
  min-width: 0;
}

.oauth-panel-title-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.oauth-panel-copy p {
  margin: 0.25rem 0 0 1rem;
  color: var(--text-secondary);
  font-size: 0.8125rem;
}

.oauth-status-dot {
  width: 0.5rem;
  height: 0.5rem;
  flex: 0 0 auto;
  border-radius: 9999px;
  background: var(--text-tertiary);
}

.oauth-status-complete {
  background: var(--green-text, #16a34a);
}

.oauth-status-pending {
  background: var(--accent);
  box-shadow: 0 0 0 0.2rem color-mix(in srgb, var(--accent) 18%, transparent);
}

.oauth-status-failed {
  background: var(--error-text);
}

.oauth-panel-copy .oauth-panel-error {
  color: var(--error-text);
}

.oauth-panel-link {
  display: inline-block;
  margin: 0.375rem 0 0 1rem;
  font-size: 0.8125rem;
}

.oauth-panel-actions {
  flex: 0 0 auto;
}

@media (max-width: 640px) {
  .oauth-panel {
    align-items: stretch;
    flex-direction: column;
  }

  .oauth-panel-actions .p-button {
    width: 100%;
  }
}

.models-info {
  padding: 0.75rem 1rem;
  background: var(--bg-tertiary);
  border-radius: 0.375rem;
  margin-bottom: 1rem;
}

.models-info p {
  margin: 0 0 0.5rem 0;
  color: var(--text-secondary);
}

.builtin-list {
  margin: 0;
  padding-left: 1.25rem;
  color: var(--text-primary);
}

.builtin-list li {
  margin: 0.25rem 0;
}

/* Manage Models list is a PrimeVue DataTable (see ModelsModal.vue); most of
   its look comes from modelsTableDt design tokens. These rules pull the modal
   body padding to the edges, keep the header row sticky, and style the cell
   content wrappers for a compact, data-dense layout. */
.models-datatable {
  /* Pull to the modal-body edges so the table spans the full width. */
  margin: 0 -1rem;
  font-size: 0.8125rem;
}

/* Keep the header visible while the body scrolls. size="small" + tokens set
   padding; this just makes the labels compact and uppercase like before. */
.models-datatable .p-datatable-column-title {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
}

/* Keep every row a single line tall. Without this, cells like the API-shape
   label ("OpenAI (Responses API)") wrap and blow up row height, wasting
   vertical space; the table scrolls horizontally to reveal the full text. */
.models-datatable .p-datatable-tbody > tr > td,
.models-datatable .p-datatable-thead > tr > th {
  white-space: nowrap;
}

.models-cell-name {
  font-weight: 500;
  white-space: nowrap;
}

/* Tag chips shown inline after a custom model's name. */
.models-cell-tag {
  display: inline-block;
  margin-left: 0.375rem;
  padding: 0.0625rem 0.375rem;
  border-radius: 9999px;
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  font-size: 0.6875rem;
  font-weight: 400;
  vertical-align: middle;
}

/* Source group subheader: source name, model count, common endpoint. */
.models-datatable .p-datatable-row-group-header {
  background: var(--bg-secondary);
}
.models-group-name {
  font-weight: 600;
  font-size: 0.75rem;
}
.models-group-count {
  margin-left: 0.375rem;
  color: var(--text-tertiary);
  font-size: 0.75rem;
}
.models-group-endpoint {
  margin-left: 0.75rem;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  color: var(--text-tertiary);
}

.models-cell-mono {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--text-secondary);
  white-space: nowrap;
}

.models-cell-muted {
  color: var(--text-tertiary);
}

/* Per-row endpoint (only when it differs from the group's common endpoint,
   plus custom models' user-configured endpoints), shown under the model id. */
.models-cell-endpoint {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  color: var(--text-tertiary);
  max-width: 20rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Right-align the images + actions columns and keep them from growing. */
.models-col-images,
.models-col-actions {
  width: 1%;
  white-space: nowrap;
}

.models-col-images {
  text-align: center;
}

.models-cell-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.125rem;
}

.models-table-image-yes {
  color: var(--green-text, #16a34a);
  font-weight: 600;
}

.models-table-image-no {
  color: var(--red-text, #b91c1c);
}

/* Small "auto" tag shown next to the resolved ✓/✕ for custom models whose
   image support is set to Auto. */
.models-table-image-auto-tag {
  margin-left: 0.25rem;
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-tertiary);
  vertical-align: middle;
}

.model-card {
  padding: 0.75rem 1rem;
  background: var(--bg-base);
  border: 1px solid var(--border);
  border-radius: 0.375rem;
}

.models-empty {
  padding: 2rem;
  text-align: center;
  color: var(--text-secondary);
}

.models-empty-hint {
  font-size: 0.875rem;
  margin-top: 0.5rem;
  color: var(--text-tertiary);
}

.btn-icon {
  padding: 0.25rem;
  border-radius: 0.25rem;
  color: var(--text-secondary);
  background: transparent;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.btn-icon:hover {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

/* Version Checker Styles */
.version-update-dot {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 8px;
  height: 8px;
  background: #ef4444;
  border-radius: 50%;
  border: 2px solid var(--bg-base);
}

.version-menu-dot {
  width: 8px;
  height: 8px;
  background: #ef4444;
  border-radius: 50%;
  margin-left: auto;
  flex-shrink: 0;
}

/* Version modal: chrome comes from the shared Modal (PrimeVue Dialog);
   these classes only size it and lay out the body/footer content. Sized like
   .modal-xwide (that class also carries Manage-Models-specific layout, so only
   the width is borrowed) so most changelog commit subjects fit on one line. */
.modal.version-modal {
  max-width: 64rem;
}

.version-modal .modal-body {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.version-info-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.875rem;
}

.version-label {
  color: var(--text-secondary);
}

.version-value {
  font-weight: 500;
  color: var(--text-primary);
  font-family: var(--font-mono);
}

.version-loading {
  color: var(--text-secondary);
  font-size: 0.875rem;
  padding: 0.5rem 0;
}

@media (max-width: 600px) {
  /* Full-screen on phones: drop the mask padding so 100dvh fits. */
  .modal-overlay:has(.version-modal) {
    padding: 0;
  }

  .modal.version-modal {
    max-height: 100dvh;
    max-width: 100%;
    border-radius: 0;
    height: 100dvh;
  }
}

.btn-icon.btn-danger:hover {
  background: var(--error-bg);
  color: var(--error-text);
}

.add-model-btn {
  width: 100%;
}

/* Model Form (rendered inside ModelFormModal's stacked dialog; the dialog
   title replaces the old inline <h3>). */
.form-group {
  margin-bottom: 0.75rem;
}

.form-group label {
  display: block;
  font-size: 0.875rem;
  font-weight: 500;
  margin-bottom: 0.25rem;
  color: var(--text-primary);
}

.form-group label .optional {
  font-weight: 400;
  color: var(--text-secondary);
}

.form-checkbox {
  display: flex;
  align-items: center;
}

.form-checkbox label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
  margin: 0;
}

.form-checkbox input[type="checkbox"] {
  width: 1rem;
  height: 1rem;
  cursor: pointer;
}

.info-icon-wrapper {
  position: relative;
  display: inline-flex;
  align-items: center;
  margin-left: 0.25rem;
}

.info-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text-tertiary);
  cursor: pointer;
}

.info-icon:hover {
  color: var(--text-secondary);
}

/* PrimeVue Tooltip (v-tooltip directive) — shared theme for the title=→tooltip
   sweep. Matches the app chrome (bg-tertiary panel, small text) instead of
   Aura's dark defaults. The arrow is hidden: at this size it adds noise. */
.p-tooltip .p-tooltip-text {
  background: var(--bg-tertiary);
  border: 1px solid var(--border);
  border-radius: 0.375rem;
  padding: 0.375rem 0.625rem;
  font-size: 0.75rem;
  font-weight: 400;
  color: var(--text-primary);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  white-space: pre-line; /* multiline titles (e.g. "Git directory: …\nClick to change") */
  max-width: 20rem;
}
.p-tooltip .p-tooltip-arrow {
  display: none;
}

.provider-buttons {
  display: flex;
  gap: 0.5rem;
}

.provider-btn {
  flex: 1;
  padding: 0.5rem;
  background: var(--bg-base);
  border: 1px solid var(--border);
  border-radius: 0.375rem;
  color: var(--text-primary);
  font-size: 0.875rem;
  cursor: pointer;
  transition: all 0.15s;
}

.provider-btn:hover {
  background: var(--bg-tertiary);
}

.provider-btn.selected {
  background: var(--primary);
  border-color: var(--primary);
  color: white;
}

.endpoint-toggle {
  display: flex;
  gap: 0;
  margin-bottom: 0.5rem;
}

.toggle-btn {
  flex: 1;
  padding: 0.375rem 0.75rem;
  background: var(--bg-base);
  border: 1px solid var(--border);
  color: var(--text-secondary);
  font-size: 0.75rem;
  cursor: pointer;
  transition: all 0.15s;
}

.toggle-btn:first-child {
  border-radius: 0.375rem 0 0 0.375rem;
}

.toggle-btn:last-child {
  border-radius: 0 0.375rem 0.375rem 0;
  border-left: none;
}

.toggle-btn.selected {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

.endpoint-display {
  padding: 0.5rem 0.75rem;
  background: var(--bg-tertiary);
  border-radius: 0.375rem;
  font-size: 0.75rem;
  color: var(--text-secondary);
  word-break: break-all;
}

.form-hint {
  margin-top: 0.375rem;
  color: var(--text-secondary);
  font-size: 0.75rem;
  line-height: 1.3;
}

.form-hint code {
  font-family: var(--font-mono, monospace);
  font-size: 0.7rem;
  word-break: break-all;
  color: var(--text-primary);
}

.test-result {
  padding: 0.75rem 1rem;
  border-radius: 0.375rem;
  margin-bottom: 1rem;
  font-size: 0.875rem;
}

.test-result.success {
  background: var(--success-bg);
  border: 1px solid var(--success-border);
  color: var(--success-text);
}

.test-result.error {
  background: var(--error-bg);
  border: 1px solid var(--error-border);
  color: var(--error-text);
}

.form-actions {
  display: flex;
  gap: 0.5rem;
  justify-content: flex-end;
  margin-top: 1rem;
  padding-bottom: 0.5rem;
}

kbd {
  display: inline-block;
  padding: 0.125rem 0.375rem;
  font-size: 0.75rem;
  font-family: inherit;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  border-radius: 0.25rem;
  color: var(--text-secondary);
}

/* System Prompt View */
.system-prompt-view {
  background: var(--gray-100);
  border-radius: 0.5rem;
  margin: 0.5rem 0;
  width: 100%;
  border: 1px dashed var(--border);
}

.dark .system-prompt-view {
  background: var(--gray-800);
}

.system-prompt-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  cursor: pointer;
  user-select: none;
}

.system-prompt-header:hover {
  background: rgba(0, 0, 0, 0.02);
  border-radius: 0.5rem;
}

.dark .system-prompt-header:hover {
  background: rgba(255, 255, 255, 0.02);
}

.system-prompt-summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1;
  min-width: 0;
}

.system-prompt-icon {
  font-size: 1rem;
  flex-shrink: 0;
}

.system-prompt-label {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  color: var(--text-primary);
  font-weight: 500;
}

.system-prompt-meta {
  font-size: 0.75rem;
  color: var(--text-secondary);
  flex-shrink: 0;
}

.system-prompt-content {
  padding: 0 1rem 1rem 1rem;
}

.system-prompt-text {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  line-height: 1.6;
  color: var(--text-secondary);
  background: var(--bg-base);
  border: 1px solid var(--border);
  border-radius: 0.375rem;
  padding: 1rem;
  margin: 0;
  max-height: 400px;
  overflow: auto;
  white-space: pre-wrap;
  word-wrap: break-word;
}

.dark .system-prompt-text {
  background: var(--gray-900);
}

/* ===== Terminal Panel ===== */
.terminal-panel {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--border);
  background: var(--bg-secondary);
  min-height: 80px;
  max-height: 800px;
  overflow: hidden;
}

.terminal-panel-minimized {
  min-height: unset;
  max-height: unset;
  height: auto;
  flex-shrink: 0;
}

.terminal-panel-minimized .terminal-panel-header {
  border-bottom: none;
}

.terminal-panel-resize-handle {
  height: 6px;
  cursor: ns-resize;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border);
  user-select: none;
}

.terminal-panel-resize-handle:hover {
  background: var(--bg-tertiary);
}

.terminal-panel-resize-grip {
  width: 40px;
  height: 3px;
  background: var(--text-tertiary);
  border-radius: 2px;
}

.terminal-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 8px;
  height: 34px;
  flex-shrink: 0;
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border);
  gap: 8px;
}

.terminal-panel-tabs {
  display: flex;
  align-items: center;
  gap: 2px;
  overflow-x: auto;
  flex: 1;
  min-width: 0;
  scrollbar-width: none;
}

.terminal-panel-tabs::-webkit-scrollbar {
  display: none;
}

.terminal-panel-tab {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 0.75rem;
  font-family: var(--font-mono);
  color: var(--text-secondary);
  white-space: nowrap;
  user-select: none;
  border: 1px solid transparent;
  transition:
    background-color 0.1s,
    color 0.1s;
}

.terminal-panel-tab:hover {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

.terminal-panel-tab-active {
  background: var(--bg-base);
  color: var(--text-primary);
  border-color: var(--border);
}

.terminal-panel-tab-indicator {
  font-size: 0.75rem;
  line-height: 1;
}

.terminal-panel-tab-running {
  color: var(--success-text);
}

.terminal-panel-tab-success {
  color: var(--success-text);
}

.terminal-panel-tab-error {
  color: var(--error-text);
}

.terminal-panel-tab-label {
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
}

.terminal-panel-tab-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border: none;
  background: none;
  cursor: pointer;
  color: var(--text-tertiary);
  font-size: 0.875rem;
  line-height: 1;
  border-radius: 3px;
  padding: 0;
}

.terminal-panel-tab-close:hover {
  background: var(--bg-tertiary);
  color: var(--error-text);
}

.terminal-panel-actions {
  display: flex;
  align-items: center;
  gap: 2px;
  background: var(--bg-base);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 2px;
  flex-shrink: 0;
}

.terminal-panel-actions-divider {
  width: 1px;
  height: 16px;
  background: var(--border);
  margin: 0 2px;
}

.terminal-panel-action-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 4px;
  border: none;
  background: transparent;
  cursor: pointer;
  color: var(--text-secondary);
  transition:
    background-color 0.15s,
    color 0.15s;
}

.terminal-panel-action-btn:hover {
  background: var(--bg-tertiary);
}

.terminal-panel-action-btn-feedback {
  background: var(--success-bg);
  color: var(--success-text);
}

.terminal-panel-content {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  position: relative;
}

.terminal-panel-content > div {
  position: absolute;
  inset: 4px;
}

@media (pointer: coarse) {
  /* xterm.js positions its helper textarea off-screen with zero dimensions
     (left: -9999em; width/height: 0), so on iOS/Android focus() doesn't open
     the soft keyboard. Pull it back on-screen and give it real dimensions so
     focus() inside a touch gesture (see TerminalPanel's pointerdown handler)
     reliably opens the keyboard. pointer-events: none keeps touches passing
     through to the terminal for native scrolling. */
  .terminal-panel .xterm .xterm-helpers {
    position: absolute !important;
    left: 0 !important;
    top: 0 !important;
    width: 100% !important;
    height: 100% !important;
    pointer-events: none !important;
  }
  .terminal-panel .xterm .xterm-helper-textarea {
    left: 0 !important;
    top: 0 !important;
    width: 100% !important;
    height: 100% !important;
    pointer-events: none !important;
    /* Stay invisible while still being focusable. */
    opacity: 0 !important;
    /* iOS auto-zooms inputs whose font-size is < 16px; prevent that. */
    font-size: 16px !important;
  }
}

/* Highlight animation for navigated user messages */
@keyframes message-nav-highlight {
  0% {
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.3);
    background-color: rgba(37, 99, 235, 0.08);
  }
  100% {
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0);
    background-color: transparent;
  }
}

@keyframes message-nav-highlight-dark {
  0% {
    box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.3);
    background-color: rgba(96, 165, 250, 0.08);
  }
  100% {
    box-shadow: 0 0 0 3px rgba(96, 165, 250, 0);
    background-color: transparent;
  }
}

.message-highlight {
  animation: message-nav-highlight 1.5s ease-out;
  border-radius: 8px;
}

.dark .message-highlight {
  animation: message-nav-highlight-dark 1.5s ease-out;
}

/* Markdown content rendering */
.markdown-content {
  line-height: 1.6;
}

.markdown-content p {
  margin: 0.5em 0;
}

.markdown-content p:first-child {
  margin-top: 0;
}

.markdown-content p:last-child {
  margin-bottom: 0;
}

.markdown-content h1,
.markdown-content h2,
.markdown-content h3,
.markdown-content h4,
.markdown-content h5,
.markdown-content h6 {
  margin: 1em 0 0.5em;
  font-weight: 600;
  line-height: 1.4;
}

.markdown-content h1:first-child,
.markdown-content h2:first-child,
.markdown-content h3:first-child {
  margin-top: 0;
}

.markdown-content h1 {
  font-size: 1.25rem;
}
.markdown-content h2 {
  font-size: 1.25rem;
}
.markdown-content h3 {
  font-size: 1.25rem;
}

.markdown-content code {
  /* display:inline is asserted defensively: the @pierre/diffs stylesheet ships
     a global reset (pre, code, [data-error-wrapper] { display: block }) in
     @layer base. Inline code spans must stay inline, so beat that reset by
     specificity rather than relying on the UA default. */
  display: inline;
  font-family: var(--font-mono);
  font-size: 0.875rem;
  background: var(--code-bg);
  padding: 0.15em 0.35em;
  border-radius: 4px;
}

.markdown-content pre {
  margin: 0.75em 0;
  padding: 0.75em 1em;
  background: var(--code-bg);
  border-radius: 6px;
  overflow-x: auto;
}

.markdown-content pre code {
  /* Code inside a fenced block fills the <pre>; keep it block-level (the diffs
     reset already makes it block, but assert it so it survives the rule above). */
  display: block;
  background: none;
  padding: 0;
  font-size: 0.875rem;
}

.inline-code {
  /* Same reasoning as .markdown-content code: stay inline despite the diffs
     global pre/code reset to display:block. */
  display: inline;
  font-family: var(--font-mono);
  font-size: 0.875em;
  background: var(--code-bg);
  padding: 0.15em 0.35em;
  border-radius: 4px;
}

.inline-code-block {
  margin: 0.5em 0;
  padding: 0.75em 1em;
  background: var(--code-bg);
  border-radius: 6px;
  overflow-x: auto;
  white-space: pre;
}

.inline-code-block code {
  font-family: var(--font-mono);
  font-size: 0.875em;
  background: none;
  padding: 0;
}

.markdown-content blockquote {
  margin: 0.75em 0;
  padding: 0.25em 1em;
  border-left: 3px solid var(--border);
  color: var(--text-secondary);
}

.markdown-content ul,
.markdown-content ol {
  margin: 0.5em 0;
  padding-left: 1.5em;
}

.markdown-content li {
  margin: 0.25em 0;
}

.markdown-content hr {
  margin: 1em 0;
  border: none;
  border-top: 1px solid var(--border);
}

.markdown-content table {
  border-collapse: collapse;
  margin: 0.75em 0;
  word-break: normal;
  display: block;
  overflow-x: auto;
}

.markdown-content th,
.markdown-content td {
  border: 1px solid var(--border);
  padding: 0.4em 0.75em;
  text-align: left;
}

.markdown-content th {
  background: var(--bg-tertiary);
  font-weight: 600;
  white-space: nowrap;
}

.markdown-content a {
  color: var(--link-color);
  text-decoration: underline;
}

.markdown-content a:hover {
  text-decoration: none;
}

.markdown-content del {
  text-decoration: line-through;
  color: var(--text-secondary);
}

.system-prompt-tools {
  margin-bottom: 0.75rem;
  border: 1px solid var(--border);
  border-radius: 0.375rem;
  overflow: hidden;
}

.system-prompt-tools-label {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  color: var(--text-primary);
  font-weight: 500;
  padding: 0.5rem 0.75rem 0.25rem;
}

.system-prompt-tools-list {
  padding: 0.25rem 0.75rem 0.5rem;
}

.system-prompt-tool-item {
  border-top: 1px solid var(--border);
  padding: 0;
}

.system-prompt-tool-item:first-child {
  border-top: none;
}

.system-prompt-tool-header {
  display: flex;
  align-items: baseline;
  gap: 0.375rem;
  padding: 0.3rem 0;
}

.system-prompt-tool-header--clickable {
  cursor: pointer;
  user-select: none;
  min-width: 0;
}

.system-prompt-tool-header--clickable:focus-visible {
  outline: 2px solid var(--text-accent);
  outline-offset: 2px;
  border-radius: 2px;
}

.system-prompt-tool-header--clickable:hover .system-prompt-tool-name {
  color: var(--text-accent);
  text-decoration: underline;
}

.tool-item-chevron {
  flex-shrink: 0;
  color: var(--text-muted, var(--text-secondary));
  transition: transform 0.15s ease;
  align-self: center;
}

.tool-item-chevron--expanded {
  transform: rotate(90deg);
}

.tool-item-chevron-spacer {
  display: inline-block;
  width: 10px;
  flex-shrink: 0;
}

.system-prompt-tool-name {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--text-accent);
  white-space: nowrap;
  flex-shrink: 0;
}

.system-prompt-tool-desc {
  font-size: 0.75rem;
  color: var(--text-secondary);
  line-height: 1.4;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.system-prompt-tool-detail {
  padding: 0.375rem 0 0.5rem 1.375rem;
}

.system-prompt-tool-full-desc {
  font-size: 0.75rem;
  color: var(--text-secondary);
  line-height: 1.5;
  white-space: pre-wrap;
  margin: 0 0 0.5rem;
}

.system-prompt-tool-params {
  margin-top: 0.25rem;
}

.system-prompt-tool-params-label {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-secondary);
  margin-bottom: 0.25rem;
}

.system-prompt-tool-params-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.75rem;
}

.system-prompt-tool-param-row td {
  padding: 0.2rem 0.5rem 0.2rem 0;
  vertical-align: top;
  border-bottom: 1px solid var(--border);
}

.system-prompt-tool-param-row:last-child td {
  border-bottom: none;
}

.system-prompt-tool-param-name {
  white-space: nowrap;
  font-family: var(--font-mono);
  color: var(--text-primary);
}

.system-prompt-tool-param-name code {
  font-family: var(--font-mono);
  font-size: 0.75rem;
}

.system-prompt-tool-param-required {
  color: var(--text-accent);
  margin-left: 0.15rem;
  font-weight: 700;
}

.system-prompt-tool-param-row td.system-prompt-tool-param-type {
  white-space: nowrap;
  padding-right: 0.75rem;
}

.system-prompt-tool-param-type code {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--text-secondary);
}

.system-prompt-tool-param-desc {
  color: var(--text-secondary);
  line-height: 1.4;
}

.system-prompt-tool-param-enum {
  color: var(--text-secondary);
  font-size: 0.7rem;
}

.system-prompt-tool-param-enum code {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--text-primary);
}

.conversation-loading-overlay {
  position: absolute;
  inset: 0;
  z-index: 20;
  background: var(--bg-base);
}

.conversation-loading {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 1rem;
}

.conversation-loading-title {
  font-size: 1rem;
  color: var(--text-primary);
  font-weight: 500;
}

.conversation-loading-subtitle {
  font-size: 0.875rem;
  color: var(--text-secondary);
}

.conversation-loading-bar {
  width: min(22rem, 70vw);
  height: 0.4rem;
  background: var(--bg-tertiary);
  border: 1px solid var(--border);
  border-radius: 999px;
  overflow: hidden;
}

.conversation-loading-bar-fill {
  height: 100%;
  background: var(--primary);
  transition: width 120ms linear;
}

.conversation-loading-bar-fill.indeterminate {
  width: 35%;
  animation: loading-slide 1.1s ease-in-out infinite;
}

.conversation-loading-bar-fill.parsing {
  width: 100%;
  animation: pulse-loading 1.1s ease-in-out infinite;
}

@keyframes pulse-loading {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.55;
  }
}

@keyframes loading-slide {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(300%);
  }
}

/* Usage Detail Modal */
/* Usage / message details: chrome comes from the shared Modal (PrimeVue
   Dialog); only size it and lay out the details grid. */
.modal.usage-detail-modal {
  max-width: 31.25rem;
}

.usage-detail-grid {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.75rem 1.25rem;
  font-size: 0.875rem;
}

.usage-detail-label {
  color: var(--text-secondary);
  font-weight: 500;
}

.usage-detail-value {
  color: var(--text-primary);
}

/* NotificationsModal styles */
.notifications-error-message {
  margin-bottom: 1rem;
}

.notifications-type-selector {
  display: flex;
  gap: 0.5rem;
}

.notifications-section {
  margin-bottom: 1rem;
}

.notifications-section-label {
  margin-bottom: 0.5rem;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-secondary);
}

.notifications-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  margin-bottom: 0.5rem;
}

.notifications-card-title {
  font-weight: 500;
}

.notifications-card-description {
  font-size: 0.75rem;
  color: var(--text-secondary);
}

.notifications-card-actions {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.notifications-denied-text {
  font-size: 0.75rem;
  color: var(--text-secondary);
}

.notifications-loading {
  padding: 1rem;
  color: var(--text-secondary);
}

.notifications-empty-state {
  padding: 1rem;
  color: var(--text-secondary);
  text-align: center;
}

.notifications-link-button {
  color: var(--primary);
  background: none;
  border: none;
  cursor: pointer;
  text-decoration: underline;
  font: inherit;
}

.notifications-channel-content {
  flex: 1;
  min-width: 0;
}

.notifications-channel-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.notifications-channel-name {
  font-weight: 500;
}

.notifications-channel-type-badge {
  font-size: 0.75rem;
  padding: 0.125rem 0.375rem;
  border-radius: 0.25rem;
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.notifications-channel-actions {
  display: flex;
  gap: 0.375rem;
  align-items: center;
  flex-shrink: 0;
}

/* Message component styles */
.msg-icon-middle {
  vertical-align: middle;
}

.msg-gitinfo-container {
  padding: 0.4rem 1rem;
  font-size: 0.875rem;
  color: var(--text-secondary);
  text-align: center;
  font-style: italic;
}

.msg-modelchange-container {
  gap: 0.4em;
  font-style: normal;
  white-space: pre-wrap;
}

.msg-modelchange-icon {
  margin-right: 0.25em;
}

/* Customized pill for an actual model/reasoning switch. Override the base
   .message column flex so the chips lay out inline. */
.message.msg-modelchange-switch {
  flex-flow: row wrap;
  align-items: center;
  justify-content: center;
  gap: 0.4em;
  white-space: normal;
}

.msg-modelchange-chip {
  display: inline-flex;
  align-items: center;
  padding: 0.1em 0.5em;
  border-radius: 999px;
  background: var(--bg-tertiary, rgba(127, 127, 127, 0.14));
  border: 1px solid var(--border-subtle, rgba(127, 127, 127, 0.22));
  color: var(--text-primary);
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.4;
}

.msg-modelchange-from {
  color: var(--text-secondary);
  background: transparent;
}

.msg-modelchange-to {
  border-color: var(--accent, #6366f1);
  color: var(--accent, #6366f1);
}

.msg-modelchange-arrow {
  color: var(--text-secondary);
  font-size: 0.9rem;
}

.msg-modelchange-reasoning {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
}

.msg-modelchange-reasoning-label {
  color: var(--text-secondary);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.msg-worktree {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  margin-right: 0.5em;
}

.msg-branch {
  font-weight: 500;
  font-style: normal;
}

.msg-commit-hash {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  background: var(--bg-tertiary);
  padding: 0.1em 0.3em;
  border-radius: 3px;
  cursor: pointer;
}

.msg-copy-button {
  background: none;
  border: none;
  padding: 0.1em 0.3em;
  cursor: pointer;
  vertical-align: middle;
  margin-left: 0.2em;
}

.msg-copy-button:not(.copied) {
  color: var(--text-tertiary);
}

.msg-copy-button.copied {
  color: var(--success-text);
}

.msg-subject {
  margin-left: 0.3em;
}

.msg-diff-link {
  color: var(--blue-text);
  text-decoration: underline;
}

.msg-distill-container {
  padding: 0.5rem 1rem;
  font-size: 0.875rem;
  color: var(--text-secondary);
  text-align: center;
  font-style: italic;
}

.msg-distill-container.error {
  color: var(--error-text);
}

.msg-spinner-inline {
  display: inline-block;
  margin-right: 6px;
  vertical-align: middle;
}

.msg-unexpected-role {
  background: var(--warning-bg);
  border: 1px solid var(--warning-border);
  border-radius: 0.25rem;
  padding: 0.5rem;
  font-size: 0.875rem;
}

.msg-unexpected-role-text {
  color: var(--warning-text);
}

.msg-unexpected-content {
  margin-top: 0.25rem;
}

.msg-unknown-content {
  background: var(--bg-tertiary);
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  padding: 0.75rem;
}

.msg-unknown-content-label {
  margin-bottom: 0.5rem;
}

.msg-media-section {
  margin-bottom: 0.5rem;
}

.msg-media-type-label {
  margin-bottom: 0.25rem;
}

.msg-media-image {
  max-width: 100%;
  height: auto;
  max-height: 300px;
}

.msg-raw-content-summary {
  cursor: pointer;
}

.msg-raw-content-pre {
  margin-top: 0.5rem;
  padding: 0.5rem;
  background: var(--bg-base);
  border-radius: 0.25rem;
  font-size: 0.75rem;
  overflow: auto;
}

.msg-container-relative {
  position: relative;
}

/* ChatInterface styles */

/* Context usage popup — PrimeVue Popover surface. PrimeVue owns positioning
   (absolute + inline top/left), so no position/bottom/right here. */
.chat-context-popup.p-popover {
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 4px;
  font-size: 0.75rem;
  color: var(--text-secondary);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  max-width: calc(100vw - 1rem);
}
.chat-context-popup.p-popover:before,
.chat-context-popup.p-popover:after {
  display: none;
}
/* Same flip caveat as .toc-popover: Popover defaults to "below the target",
   which for the status-bar usage bar means covering the message input. Shift
   it above the 6px bar (+4px gap) unless PrimeVue already flipped it. */
.chat-context-popup.p-popover:not(.p-popover-flipped) {
  transform: translateY(calc(-100% - 10px));
}
.chat-context-popup .chat-context-popup-content {
  padding: 6px 10px;
}

.chat-popup-warning {
  margin-top: 6px;
  color: var(--warning-text, #f59e0b);
}

/* Token cost graph in the context usage popup */
.token-cost-graph {
  margin-top: 8px;
  width: 280px;
  max-width: 100%;
}

.token-cost-controls {
  display: flex;
  gap: 4px;
  margin-bottom: 4px;
}

.token-cost-toggle {
  font-size: 0.65rem;
  line-height: 1.4;
  padding: 1px 8px;
  border: 1px solid var(--border-color);
  border-radius: 10px;
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
}

.token-cost-toggle-active {
  background: var(--bg-tertiary);
  color: var(--text-primary);
  border-color: var(--text-secondary);
}

.token-cost-graph-svg {
  display: block;
  width: 100%;
  height: auto;
  background: var(--bg-tertiary);
  border-radius: 4px;
}

.token-cost-axis {
  stroke: var(--border-color);
  stroke-width: 1;
}

.token-cost-gridline {
  stroke: var(--border-color);
  stroke-width: 0.5;
  opacity: 0.6;
}

.token-cost-hover-line {
  stroke: var(--text-secondary);
  stroke-width: 1;
  stroke-dasharray: 2 2;
  pointer-events: none;
}

.token-cost-gen-line {
  stroke: var(--text-primary);
  stroke-width: 1;
  stroke-dasharray: 4 3;
  opacity: 0.45;
  pointer-events: none;
}

.token-cost-label {
  font-size: 9px;
  fill: var(--text-secondary);
}

.token-cost-hover-readout {
  margin-top: 2px;
  font-size: 0.7rem;
  line-height: 1.35;
  color: var(--text-secondary);
  min-height: 2.7em;
}

.token-cost-hover-snippet {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-style: italic;
}

.token-cost-legend {
  margin-top: 4px;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.token-cost-model-row {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 0.7rem;
  font-weight: 600;
  margin-top: 3px;
}

.token-cost-model-name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.token-cost-legend-row {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.7rem;
}

.token-cost-chip {
  width: 8px;
  height: 8px;
  border-radius: 2px;
  flex-shrink: 0;
}

.token-cost-legend-label {
  flex: 1;
}

.token-cost-legend-tokens {
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

.token-cost-legend-unit {
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  min-width: 58px;
  text-align: right;
}

.token-cost-legend-cost {
  min-width: 52px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.token-cost-graph-note {
  margin-top: 4px;
  font-size: 0.68rem;
  color: var(--text-secondary);
}

.chat-distill-container {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
}

.chat-distill-button {
  padding: 4px 8px;
  background-color: var(--blue-text);
  color: white;
  border: none;
  border-radius: 4px;
  font-size: 0.75rem;
}

.chat-distill-button:not(:disabled) {
  cursor: pointer;
}

.chat-distill-button:disabled {
  cursor: not-allowed;
  opacity: 0.7;
}

.chat-distill-generation-button {
  background-color: var(--bg-secondary, #2a2a2a);
  border: 1px solid var(--blue-text);
  color: var(--blue-text);
}

.generation-section {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.generation-section-previous {
  background: color-mix(in srgb, var(--bg-tertiary) 72%, transparent);
  border-radius: 0.75rem;
  margin: 0 -0.5rem;
  padding: 0.5rem;
  opacity: 0.9;
}

.carried-band {
  margin: 0.5rem 0;
}

.carried-band-toggle {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  width: 100%;
  background: transparent;
  border: 1px dashed var(--border);
  border-radius: 8px;
  padding: 0.35rem 0.65rem;
  color: var(--text-secondary);
  font-size: 0.75rem;
  cursor: pointer;
  text-align: left;
}

.carried-band-toggle:hover {
  background: var(--bg-secondary);
}

.carried-band-chevron {
  font-size: 0.7rem;
  opacity: 0.7;
}

.carried-band-label {
  opacity: 0.85;
}

.carried-band-body {
  margin-top: 0.35rem;
  padding-left: 0.5rem;
  border-left: 2px solid var(--border);
  opacity: 0.85;
}

.generation-divider {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  color: var(--text-secondary);
  font-size: 0.75rem;
  margin: 0.75rem 0;
  text-align: center;
}

.generation-divider::before,
.generation-divider::after {
  content: "";
  flex: 1;
  border-top: 1px solid var(--border);
}

.generation-divider span {
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.25rem 0.75rem;
}

.chat-tool-icon {
  width: 1rem;
  height: 1rem;
  color: var(--blue-text);
}

.chat-welcome-text {
  margin-bottom: 1rem;
  line-height: 1.6;
}

.chat-welcome-link {
  color: var(--blue-text);
  text-decoration: underline;
}

.chat-secondary-text {
  color: var(--text-secondary);
}

/* Empty-model-list warning. Shown in the welcome panel when the server
   serves no models. Warning-colored (not plain secondary text) because the
   composer is unusable until it's resolved — this is a blocking condition,
   not an informational note. Constrained width and left alignment keep it
   readable on mobile, where the surrounding welcome copy is centered. */
/* PrimeVue's Message (severity="warn") supplies the warning palette and
   chrome; only layout and the command list belong here. */
.no-models-message {
  max-width: 34rem;
  margin: 0.75rem auto 0;
  text-align: left;
  line-height: 1.5;
}

.no-models-title {
  margin: 0;
  font-weight: 600;
}

.no-models-message p + p,
.no-models-message .no-models-commands + p {
  margin: 0.375rem 0 0;
}

/* One command per line, each a click-to-apply suggest link. */
.no-models-commands {
  margin: 0.5rem 0 0;
  padding: 0;
  list-style: none;
}

.no-models-commands li + li {
  margin-top: 0.25rem;
}

/* Links inherit the Message's warning color: default link blue fights the
   amber panel, and the underline alone already marks them clickable. */
.no-models-commands a {
  color: inherit;
  text-decoration-color: color-mix(in srgb, currentcolor 45%, transparent);
  text-underline-offset: 2px;
}

.no-models-commands a:hover {
  text-decoration-color: currentcolor;
}

.no-models-commands code {
  font-size: 0.8125rem;
  /* Long commands wrap instead of overflowing on narrow viewports. */
  overflow-wrap: anywhere;
}

.chat-icon-1rem {
  width: 1rem;
  height: 1rem;
}

.chat-overflow-menu-wrapper {
  position: relative;
}

.chat-menu-icon {
  width: 1.25rem;
  height: 1.25rem;
  margin-right: 0.75rem;
}

.chat-scroll-icon {
  width: 1.25rem;
  height: 1.25rem;
}

/* Tool chevron animation */
.tool-chevron {
  transition: transform 0.2s;
}

.tool-chevron-expanded {
  transform: rotate(90deg);
}

/* ThinkingContent styles */
.thinking-content-wrapper {
  margin-bottom: 0.5rem;
}

.thinking-clickable-area {
  cursor: pointer;
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin-left: 0;
}

.thinking-emoji {
  flex-shrink: 0;
}

.thinking-text {
  flex: 1;
  font-style: italic;
  color: var(--text-secondary);
  white-space: pre-wrap;
  word-break: break-word;
}

/* Collapsed preview: single line, ellipsis at the edge instead of a
   mid-line "..." cutoff. min-width lets the flex item shrink. */
.thinking-text-collapsed {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.thinking-toggle-button {
  background: none;
  border: none;
  padding: 0.25rem;
  cursor: pointer;
  color: var(--text-tertiary);
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

/* BrowserProfileTool styles */
.profile-file-wrapper {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.profile-file-path {
  background: var(--bg-tertiary);
  padding: 0.25rem 0.5rem;
  border-radius: 0.25rem;
  font-size: 0.875rem;
  word-break: break-all;
}

.profile-copy-button {
  padding: 0.25rem 0.5rem;
  font-size: 0.75rem;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  cursor: pointer;
  color: var(--text-primary);
}

.profile-speedscope-link {
  padding: 0.25rem 0.75rem;
  font-size: 0.75rem;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: 0.25rem;
  cursor: pointer;
  color: var(--text-primary);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}

/* MessageActionBar styles */
.message-action-bar-wrapper {
  position: absolute;
  top: -16px;
  right: 8px;
  display: flex;
  gap: 2px;
  background: var(--bg-base);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 2px;
  z-index: 10;
}

.message-action-button {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 4px;
  border: none;
  background: transparent;
  cursor: pointer;
  color: var(--text-secondary);
  transition:
    background-color 0.15s,
    color 0.15s;
}

.message-action-button:hover {
  background: var(--bg-tertiary);
}

.message-action-button::after {
  content: attr(data-tooltip);
  position: absolute;
  left: 50%;
  bottom: calc(100% + 0.4rem);
  transform: translateX(-50%);
  z-index: 20;
  padding: 0.25rem 0.45rem;
  border-radius: 0.25rem;
  background: var(--text-primary);
  color: var(--bg-base);
  font-size: 0.75rem;
  line-height: 1.2;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.1s ease;
}

.message-action-button:hover::after,
.message-action-button:focus-visible::after {
  opacity: 1;
  visibility: visible;
}

.message-action-button-success {
  background: var(--success-bg);
  color: var(--success-text);
}

/* MessageInput styles */
.message-input-hidden {
  display: none;
}

.message-send-spinner-white {
  border-top-color: white;
}

/* OutputIframeTool styles */
.output-iframe-wrapper {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: 4px;
  background-color: var(--bg-base);
}

/* ReadImageTool and ScreenshotTool styles */
.tool-image-responsive {
  max-width: 100%;
  height: auto;
}

/* SubagentTool styles */
.subagent-link {
  color: var(--link-color);
  text-decoration: underline;
}

/* Strip under the SubagentTool card header while the subagent is working.
 * Full-width click target that opens the subagent conversation. */
.subagent-live {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.25rem 0.75rem;
  border: none;
  border-top: 1px solid var(--border-color);
  background: transparent;
  color: var(--text-secondary);
  font: inherit;
  font-size: 0.75rem;
  text-align: left;
  cursor: pointer;
  min-width: 0;
}

.subagent-live:hover {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

.subagent-live-slug {
  color: var(--link-color);
  font-weight: 600;
  flex-shrink: 0;
}

.subagent-live:hover .subagent-live-slug {
  text-decoration: underline;
}

.subagent-live-activity {
  font-family: var(--font-mono);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
  flex: 1;
}

/* Live segment attached to a subagent tool pill: its own small chip to
 * the right of the pill (a button can't nest interactive content). */
.subagent-pill-live {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  min-height: 26px;
  padding: 2px 10px;
  border-radius: 999px;
  border: 1px dashed var(--tp-border, var(--border));
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  white-space: nowrap;
}

.subagent-pill-live:hover {
  color: var(--link-color);
  border-color: var(--link-color);
}

.subagent-pill-live:focus-visible {
  outline: 2px solid var(--link-color);
  outline-offset: 1px;
}

.subagent-pill-activity {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 600px) {
  .subagent-pill-activity {
    max-width: 110px;
  }
}

/* ConfigFieldInput styles */
.config-field-description {
  font-size: 0.75rem;
  color: var(--text-secondary);
  margin-top: 0.25rem;
  display: block;
}

/* ConversationDrawer styles */
.drawer-conversation-item-flex-container {
  flex: 1;
  min-width: 0;
}

.drawer-conversation-header-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.drawer-rename-input {
  width: 100%;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--text-secondary);
  outline: none;
  padding: 0;
  font: inherit;
  color: inherit;
}

/* "Working" mark shared by the drawer rows, subagent badges, and the live
   subagent strips/chips: a subtle, non-animated hollow ring in the current
   text color. Tracks the foreground so it stays legible on both the default
   and selected (var(--primary)) backgrounds without re-using the same hue as
   the row fill. */
.working-indicator {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  border: 1.5px solid currentColor;
  background-color: transparent;
  box-sizing: border-box;
  opacity: 0.75;
  flex-shrink: 0;
}

.drawer-working-indicator {
  width: 8px;
  height: 8px;
}

.drawer-subagent-count-badge-text {
  font-weight: 500;
}

.drawer-subagent-chevron {
  width: 0.625rem;
  height: 0.625rem;
  transition: transform 0.15s ease;
}

.drawer-subagent-chevron-expanded {
  transform: rotate(90deg);
}

.drawer-subagent-chevron-collapsed {
  transform: rotate(0deg);
}

.drawer-actions-row {
  display: flex;
  gap: 0.25rem;
  margin-left: auto;
}

.drawer-actions-row-offset {
  display: flex;
  gap: 0.25rem;
  margin-left: 0.5rem;
}

.drawer-icon-size {
  width: 1rem;
  height: 1rem;
}

/* Inline delete confirmation rendered in place of the trash icon. */
.drawer-delete-confirm {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.125rem 0.25rem;
  border-radius: 0.25rem;
  background: var(--gray-200);
}

.dark .drawer-delete-confirm {
  background: var(--gray-700);
}

.conversation-item.active .drawer-delete-confirm {
  background: rgba(255, 255, 255, 0.15);
}

.drawer-delete-confirm-label {
  font-size: 0.75rem;
  color: var(--text-secondary);
  white-space: nowrap;
}

.conversation-item.active .drawer-delete-confirm-label {
  color: rgba(255, 255, 255, 0.9);
}

.drawer-delete-confirm .btn-icon-sm {
  opacity: 1;
}

.drawer-delete-confirm-yes {
  color: var(--red-600);
}

.dark .drawer-delete-confirm-yes {
  color: var(--red-400, #f87171);
}

.drawer-git-info {
  display: flex;
  align-items: center;
  gap: 0.3em;
  font-size: 0.75rem;
  color: var(--text-secondary);
}

.drawer-git-info-active {
  color: rgba(255, 255, 255, 0.7);
}

.drawer-git-hash {
  font-family: var(--font-mono);
  cursor: pointer;
}

.drawer-git-hash-copied {
  color: var(--success-text);
}

.drawer-git-subject {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.drawer-subagent-list {
  margin-left: 1.5rem;
}

.drawer-subagent-item-style {
  cursor: pointer;
  font-size: 0.875rem;
  padding-left: 0.5rem;
  border-left: 2px solid var(--border-color);
}

.drawer-subagent-date {
  font-size: 0.875rem;
}

.drawer-empty-state {
  padding: 1rem;
  text-align: center;
}

.drawer-empty-state-hint {
  margin-top: 0.25rem;
}

.drawer-footer-button {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}

.model-bar {
  background: var(--gray-100);
  border-radius: 0.5rem;
  margin: 0.5rem 0 0.25rem 0;
  width: 100%;
  border: 1px solid var(--border);
}

.dark .model-bar {
  background: var(--gray-800);
}

.model-bar-summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem 1rem;
  user-select: none;
}

.model-bar-icon {
  font-size: 1rem;
  flex-shrink: 0;
}

.model-bar-label {
  color: var(--text-primary);
  font-size: 0.875rem;
  font-weight: 500;
}

.model-bar-name {
  color: var(--text-secondary);
  font-size: 0.875rem;
  font-family: var(--font-mono);
}

/* Floating toolbar shown above/below a text selection inside a commentable
 * message. Portaled to document.body so it sits above everything in the chat
 * view (but below PrimeVue dialog masks, ~1100+, so an open modal covers it)
 * and doesn't participate in the selection itself. */
.message-selection-toolbar {
  position: fixed;
  z-index: 900;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-base);
  color: var(--text-primary);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
  cursor: pointer;
  /* Avoid participating in selection or capturing the selection accidentally. */
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
}
.message-selection-toolbar:hover {
  background: var(--bg-tertiary);
}

/* Git Graph Viewer */
.git-graph-container {
  font-size: 0.82rem;
  position: relative;
}

.git-graph-close {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  z-index: 5;
  width: 1.75rem;
  height: 1.75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-base);
  border: 1px solid var(--border-color);
  color: var(--text-primary);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  border-radius: 999px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
}

.git-graph-close:hover {
  background: var(--bg-secondary);
  color: var(--text-primary);
  border-color: var(--text-secondary);
}

.git-graph-close:focus-visible {
  outline: 2px solid var(--accent, #3b82f6);
  outline-offset: 2px;
}

.git-graph-body {
  flex: 1;
  display: flex;
  min-height: 0;
  overflow: hidden;
}

.git-graph-list {
  flex: 1;
  min-width: 0;
  overflow: auto;
  background: var(--bg-base);
  font-family: var(--font-mono);
  padding: 0.25rem 0 0.5rem;
}

.git-graph-status {
  padding: 1rem;
  color: var(--text-secondary);
}

.git-graph-error {
  color: var(--error-text, #dc2626);
}

.git-graph-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0 0.5rem;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  font-size: 0.8rem;
}

.git-graph-row:hover {
  background: var(--bg-secondary);
}

.git-graph-row-selected,
.git-graph-row-selected:hover {
  background: var(--accent-bg, rgba(59, 130, 246, 0.18));
}

.git-graph-hash {
  flex: 0 0 auto;
  color: var(--text-secondary);
  font-size: 0.78rem;
  width: 7ch;
}

/* Override the global svg sizing so each row's graph cell uses the
   width/height we compute inline. */
.git-graph-svg {
  flex: 0 0 auto;
  pointer-events: none;
  display: block;
  width: auto !important;
  height: auto !important;
}

.git-graph-main {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  display: inline-flex;
  gap: 0.35rem;
  align-items: center;
  font-family: var(--font-sans, inherit);
  color: var(--text-primary);
}

.git-graph-refs {
  display: inline-flex;
  gap: 0.2rem;
  flex: 0 0 auto;
}

.git-graph-subject {
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.git-graph-ref {
  display: inline-block;
  padding: 0 0.35rem;
  border-radius: 0.25rem;
  font-size: 0.68rem;
  line-height: 1.4;
  border: 1px solid transparent;
}

.git-graph-ref-head {
  background: #fde68a;
  color: #78350f;
}

.git-graph-ref-local {
  background: #bbf7d0;
  color: #064e3b;
}

.git-graph-ref-remote {
  background: #bfdbfe;
  color: #1e3a8a;
}

.git-graph-ref-mergebase {
  background: transparent;
  color: var(--text-secondary);
  border: 1px dashed var(--border-color);
  font-style: italic;
}

.git-graph-ref-tag {
  background: #e9d5ff;
  color: #581c87;
}

.git-graph-author {
  flex: 0 0 auto;
  color: var(--text-secondary);
  font-size: 0.74rem;
  max-width: 14ch;
  overflow: hidden;
  text-overflow: ellipsis;
  font-family: var(--font-sans, inherit);
}

.git-graph-time {
  flex: 0 0 auto;
  color: var(--text-secondary);
  font-size: 0.74rem;
  min-width: 5rem;
  text-align: right;
  font-family: var(--font-sans, inherit);
}

.git-graph-loadmore {
  padding: 0.75rem 1rem;
  text-align: center;
  color: var(--text-secondary);
  font-size: 0.82rem;
  font-family: var(--font-sans, inherit);
}

.git-graph-loadmore-end {
  font-style: italic;
  opacity: 0.7;
}

.git-graph-loadmore-link {
  color: var(--accent, #3b82f6);
  text-decoration: none;
}

.git-graph-loadmore-link:hover {
  text-decoration: underline;
}

.git-graph-detail {
  width: 22rem;
  flex: 0 0 auto;
  padding: 0.75rem 1rem;
  border-left: 1px solid var(--border-color);
  background: var(--bg-secondary);
  overflow: auto;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* Draggable divider between the commit list and the detail pane.
   Hidden on mobile (where the detail pane is a bottom sheet). */
.git-graph-divider {
  flex: 0 0 6px;
  width: 6px;
  cursor: col-resize;
  background: transparent;
  position: relative;
  user-select: none;
  touch-action: none;
  display: flex;
  align-items: center;
  justify-content: center;
}

.git-graph-divider:hover,
.git-graph-divider:active {
  background: var(--bg-tertiary, rgba(127, 127, 127, 0.18));
}

.git-graph-divider-grip {
  width: 2px;
  height: 32px;
  background: var(--text-tertiary, var(--text-secondary));
  border-radius: 1px;
  opacity: 0.5;
}

.git-graph-divider:hover .git-graph-divider-grip {
  opacity: 0.9;
}

.git-graph-detail-top {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  /* Leave room for the floating top-right toolbar (scope toggle + buttons),
     which sits above the title at small widths. */
  padding-top: 2.25rem;
  padding-right: 2.25rem;
}

.git-graph-gravatar {
  width: 3rem;
  height: 3rem;
  border-radius: 0.35rem;
  flex-shrink: 0;
  background: var(--bg-base);
  object-fit: cover;
}

.git-graph-detail-hash {
  font-size: 0.72rem;
  word-break: break-all;
  color: var(--text-secondary);
}

.git-graph-detail-sha-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
}

.git-graph-copy-group {
  display: inline-flex;
  gap: 0.2rem;
  margin-left: auto;
}

.git-graph-copy-btn {
  background: var(--bg-base);
  color: var(--text-primary);
  border: 1px solid var(--border-color);
  border-radius: 0.25rem;
  padding: 0.1rem 0.4rem;
  font-size: 0.7rem;
  font-family: var(--font-mono);
  cursor: pointer;
  line-height: 1.4;
}

.git-graph-copy-btn:hover {
  background: var(--bg-secondary);
  border-color: var(--text-secondary);
}

.git-graph-detail-actions {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.git-graph-open-diff {
  background: var(--accent, #3b82f6);
  color: white;
  border: none;
  border-radius: 0.25rem;
  padding: 0.3rem 0.7rem;
  font-size: 0.78rem;
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
}

.git-graph-open-diff:disabled,
.git-graph-open-diff-disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

.git-graph-github-link {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.25rem 0.55rem;
  font-size: 0.75rem;
  color: var(--text-primary);
  background: var(--bg-base);
  border: 1px solid var(--border-color);
  border-radius: 0.25rem;
  text-decoration: none;
}

.git-graph-github-link:hover {
  background: var(--bg-secondary);
  border-color: var(--text-secondary);
}

.git-graph-github-link svg {
  width: 0.95rem !important;
  height: 0.95rem !important;
}

.git-graph-detail-subject {
  font-weight: 600;
  color: var(--text-primary);
  white-space: pre-wrap;
}

.git-graph-detail-meta {
  font-size: 0.78rem;
  color: var(--text-secondary);
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.git-graph-detail-refs {
  display: flex;
  gap: 0.25rem;
  flex-wrap: wrap;
  margin-top: 0.25rem;
}

.git-graph-detail-root {
  margin-top: 0.5rem;
  font-size: 0.72rem;
  word-break: break-all;
}

/* The body and diffstat list deliberately have no inner scroll. The
   sidebar (or, on mobile, the bottom sheet) is the single scrollable
   surface. Nested scrollers led to tiny, awkward read-areas for long
   commit messages. */
.git-graph-detail-body {
  margin: 0;
  padding: 0.55rem 0.7rem;
  background: var(--bg-base);
  border: 1px solid var(--border-color);
  border-radius: 0.3rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  line-height: 1.4;
  color: var(--text-primary);
  white-space: pre-wrap;
  word-break: break-word;
}

.git-graph-detail-loading {
  font-size: 0.75rem;
  color: var(--text-secondary);
  font-style: italic;
}

.git-graph-diffstat {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.72rem;
}

.git-graph-diffstat-summary {
  color: var(--text-secondary);
  font-size: 0.72rem;
}

.git-graph-diffstat-ins {
  color: #16a34a;
}

.git-graph-diffstat-del {
  color: #dc2626;
}

.dark .git-graph-diffstat-ins {
  color: #4ade80;
}

.dark .git-graph-diffstat-del {
  color: #f87171;
}

.git-graph-diffstat-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 0.1rem 0.5rem;
  align-items: baseline;
  font-family: var(--font-mono);
}

.git-graph-diffstat-row {
  display: contents;
}

.git-graph-diffstat-path {
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.git-graph-diffstat-counts {
  display: inline-flex;
  gap: 0.3rem;
  justify-self: end;
  white-space: nowrap;
}

.git-graph-diffstat-binary {
  color: var(--text-secondary);
  font-style: italic;
}

.git-graph-diffstat-bar {
  font-family: var(--font-mono);
  letter-spacing: -0.05em;
  white-space: nowrap;
  color: #16a34a; /* + */
}

.dark .git-graph-diffstat-bar {
  color: #4ade80;
}

/* Deletions in the bar rendered via ::first-line trick won't work — we
   mix + and − in one span and color the −s via a pseudo approach isn't
   easy without splitting. Keep simple: split colors by using two spans. */

.git-graph-parent-link {
  color: var(--accent, #3b82f6);
  text-decoration: none;
  font-family: var(--font-mono);
}

.git-graph-parent-link:hover {
  text-decoration: underline;
}

/* Desktop: the sheet decorations are invisible. */
.git-graph-sheet-backdrop,
.git-graph-sheet-topbar {
  display: none;
}

@media (max-width: 768px) {
  .git-graph-author {
    display: none;
  }
  /* Hide SHAs on mobile to save horizontal space; the detail sheet
     surfaces the full hash when a row is tapped. */
  .git-graph-hash {
    display: none;
  }

  /* Hide the desktop divider on mobile — the detail pane becomes a
     bottom sheet there, so there's nothing to drag. */
  .git-graph-divider {
    display: none;
  }

  /* Mobile: the detail pane becomes a bottom sheet that only shows
     when the user taps a row. It slides up from the bottom and sits
     above a dimmed backdrop. */
  .git-graph-detail {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    max-width: none;
    height: 75vh;
    max-height: 85%;
    border-left: none;
    border-top: 1px solid var(--border-color);
    border-top-left-radius: 0.75rem;
    border-top-right-radius: 0.75rem;
    box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.25);
    padding-top: 0.25rem;
    transform: translateY(100%);
    transition: transform 0.22s ease;
    z-index: 4;
  }

  .git-graph-detail.git-graph-detail-sheet-open {
    transform: translateY(0);
  }

  /* Sticky zero-height topbar so the close button floats at the
     top-right of the visible sheet area instead of pushing the
     commit subject down onto a second row. */
  .git-graph-sheet-topbar {
    display: block;
    position: sticky;
    top: 0;
    height: 0;
    margin: 0;
    z-index: 2;
    pointer-events: none;
    flex-shrink: 0;
  }

  .git-graph-sheet-grip {
    display: none;
  }

  .git-graph-sheet-close {
    pointer-events: auto;
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    width: 1.75rem;
    height: 1.75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-base);
    border: 1px solid var(--border-color);
    color: var(--text-primary);
    font-size: 1.1rem;
    line-height: 1;
    padding: 0;
    border-radius: 999px;
    cursor: pointer;
  }

  /* Backdrop sits behind the sheet, above everything else in the
     graph container. Sibling of the sheet so it doesn't get stuck in
     the sheet's stacking context. */
  .git-graph-sheet-backdrop {
    display: block;
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.35);
    z-index: 5;
    animation: git-graph-fade-in 0.18s ease;
  }

  @keyframes git-graph-fade-in {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }

  .git-graph-detail.git-graph-detail-sheet-open {
    z-index: 6;
  }

  /* When the sheet is closed on mobile, don't reserve any layout space. */
  .git-graph-detail:not(.git-graph-detail-sheet-open) {
    pointer-events: none;
  }
}

/* Vim mode toggle (Monaco editors) */
.vim-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 28px;
  padding: 0 10px;
  font-size: 12px;
  font-weight: 600;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
  letter-spacing: 0.04em;
  background: var(--bg-secondary, #f0f0f0);
  color: var(--text-secondary, #555);
  border: 1px solid var(--border-color, #d0d0d0);
  border-radius: 4px;
  cursor: pointer;
  user-select: none;
}
.vim-toggle:hover {
  background: var(--bg-hover, #e5e5e5);
}
.vim-toggle.active {
  background: #019833;
  color: #fff;
  border-color: #019833;
}

/* monaco-vim status bar (mode indicator + ex command line). Anchored to the
   bottom of its positioned ancestor so we don't have to restructure the
   Monaco editor's flex layout. */
.monaco-vim-status {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 5;
  padding: 2px 8px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
  font-size: 12px;
  background: var(--bg-secondary, #f0f0f0);
  color: var(--text-primary, #222);
  border-top: 1px solid var(--border-color, #d0d0d0);
  min-height: 20px;
  white-space: nowrap;
  overflow: hidden;
}
.monaco-vim-status input {
  background: transparent;
  border: none;
  outline: none;
  color: inherit;
  font: inherit;
  width: 100%;
}
.dark .monaco-vim-status {
  background: #1e1e1e;
  color: #ccc;
  border-top-color: #333;
}

.distillation-file-box {
  border: 1px solid var(--blue-border);
  border-radius: 0.75rem;
  background: var(--blue-bg);
  overflow: hidden;
  box-shadow: 0 2px 8px rgb(37 99 235 / 0.1);
}

.distillation-file-box-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.75rem 0.875rem 0.25rem;
}

.distillation-file-box-title {
  color: var(--text-primary);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.01em;
}

.distillation-edit-button {
  border: 1px solid var(--border-color);
  border-radius: 999px;
  background: var(--bg-base);
  color: var(--blue-text);
  cursor: pointer;
  font-size: 0.75rem;
  font-weight: 600;
  padding: 0.25rem 0.625rem;
}

.distillation-edit-button:hover {
  background: var(--bg-hover);
}

.distillation-file-box-meta {
  padding: 0 0.875rem 0.75rem;
  color: var(--text-secondary);
  font-size: 0.75rem;
}

.distillation-file-box-meta code {
  color: var(--text-primary);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  overflow-wrap: anywhere;
}

.distillation-file-box-content {
  max-height: 50vh;
  overflow: auto;
  border-top: 1px solid var(--blue-border);
  background: var(--bg-base);
  color: var(--text-primary);
  padding: 0.875rem 1rem;
}

.distillation-file-box-content .markdown-content > :first-child {
  margin-top: 0;
}

.distillation-file-box-content .markdown-content > :last-child {
  margin-bottom: 0;
}

.distillation-empty {
  color: var(--text-secondary);
  font-style: italic;
}

.agents-md-header-title {
  color: var(--text-primary);
  font-weight: 600;
  margin-right: 0.5rem;
}

@media (max-width: 767px) {
  .distillation-file-box {
    border-width: 2px;
    box-shadow: 0 2px 10px rgb(37 99 235 / 0.14);
  }

  .distillation-file-box-header {
    padding: 0.875rem 0.875rem 0.375rem;
  }

  .distillation-file-box-title {
    font-size: 0.875rem;
  }

  .distillation-edit-button {
    font-size: 0.8125rem;
    padding: 0.35rem 0.8rem;
  }

  .distillation-file-box-meta,
  .distillation-file-box-meta code {
    font-size: 0.8125rem;
  }
}

/* Tree Directory Picker */
.tdp-modal {
  max-width: 36rem;
  display: flex;
  flex-direction: column;
  max-height: 80vh;
}
.tdp-body {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-height: 0;
  flex: 1;
}
.tdp-selection {
  width: 100%;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.875rem;
  padding: 0.4rem 0.55rem;
  background: var(--bg-secondary);
  color: var(--text-primary);
  border: 1px solid var(--border-color);
  border-radius: 0.375rem;
}
.tdp-shortcuts {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
.tdp-shortcut {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.95rem;
  width: 2rem;
  height: 2rem;
  border-radius: 0.375rem;
  border: 1px solid var(--border-color);
  background: var(--bg-base);
  color: var(--text-primary);
  cursor: pointer;
}
.tdp-shortcut:hover:not(:disabled) {
  background: var(--bg-secondary);
}
.tdp-shortcut-active {
  background: var(--bg-tertiary);
  border-color: var(--text-secondary);
}
.tdp-shortcut:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.tdp-filter {
  flex: 1;
  font-size: 0.875rem;
  padding: 0.4rem 0.55rem;
  background: var(--bg-base);
  color: var(--text-primary);
  border: 1px solid var(--border-color);
  border-radius: 0.375rem;
}
.tdp-tree {
  flex: 1;
  min-height: 12rem;
  max-height: 50vh;
  overflow-y: auto;
  border: 1px solid var(--border-color);
  border-radius: 0.375rem;
  background: var(--bg-base);
  padding: 0.25rem 0;
  font-size: 0.875rem;
}
.tdp-row {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.2rem 0.5rem 0.2rem 0.25rem;
  cursor: pointer;
  user-select: none;
  color: var(--text-primary);
  white-space: nowrap;
}
.tdp-row:hover {
  background: var(--bg-secondary);
}
.tdp-row-selected,
.tdp-row-selected:hover {
  background: var(--accent, #3b82f6);
  color: white;
}
.tdp-row-empty {
  color: var(--text-secondary);
  font-style: italic;
  cursor: default;
}
.tdp-row-empty:hover {
  background: transparent;
}
.tdp-twisty {
  width: 1rem;
  height: 1rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: var(--text-secondary);
  transition: transform 0.1s ease;
}
.tdp-row-selected .tdp-twisty {
  color: white;
}
.tdp-twisty-open {
  transform: rotate(90deg);
}
.tdp-icon {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
  color: var(--text-secondary);
}
.tdp-row-selected .tdp-icon {
  color: white;
}
.tdp-name {
  overflow: hidden;
  text-overflow: ellipsis;
  font-family: var(--font-mono, ui-monospace, monospace);
}
.tdp-hint {
  font-size: 0.75rem;
  color: var(--text-secondary);
  margin-left: 0.25rem;
}
.tdp-error {
  color: #ef4444;
}

/* Git graph mini-toolbar (top-right) */
.git-graph-toolbar {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.2rem;
  background: var(--bg-base);
  border: 1px solid var(--border-color);
  border-radius: 999px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
}
.git-graph-tool {
  width: 1.5rem;
  height: 1.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  color: var(--text-primary);
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  border-radius: 999px;
}
.git-graph-tool svg {
  width: 0.95rem;
  height: 0.95rem;
  color: var(--text-secondary);
}
.git-graph-tool:hover {
  background: var(--bg-secondary);
}
.git-graph-tool:hover svg {
  color: var(--text-primary);
}
.git-graph-tool:focus-visible {
  outline: 2px solid var(--accent, #3b82f6);
  outline-offset: 2px;
}

/* Branch-scope segmented toggle (All branches / Current branch). */
.git-graph-scope {
  display: inline-flex;
  align-items: center;
  gap: 0;
  background: var(--bg-secondary);
  border-radius: 999px;
  padding: 0.1rem;
  margin-right: 0.15rem;
}
.git-graph-scope-btn {
  appearance: none;
  background: transparent;
  color: var(--text-secondary);
  border: 0;
  padding: 0.15rem 0.55rem;
  font: inherit;
  font-size: 0.72rem;
  line-height: 1.1;
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
}
.git-graph-scope-btn:hover {
  color: var(--text-primary);
}
.git-graph-scope-btn-active {
  background: var(--bg-base);
  color: var(--text-primary);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
.git-graph-scope-btn:focus-visible {
  outline: 2px solid var(--accent, #3b82f6);
  outline-offset: 1px;
}

/* Git repo picker. Height is locked so the modal doesn't bounce around
   as the filter shrinks the list. */
.grp-modal {
  max-width: 36rem;
  width: 100%;
  height: 80vh;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
}
.grp-modal .modal-header {
  padding: 0.5rem 0.75rem;
  flex-shrink: 0;
}
.grp-modal .modal-title {
  font-size: 1rem;
}
.grp-modal .modal-body {
  /* .grp-list scrolls internally; make the body a non-scrolling flex column. */
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 0.5rem 0.75rem 0.75rem;
}
.grp-body {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-height: 0;
  flex: 1;
  height: 100%;
}
.grp-filter {
  width: 100%;
  font-size: 0.95rem;
  padding: 0.5rem 0.65rem;
  background: var(--bg-base);
  color: var(--text-primary);
  border: 1px solid var(--border-color);
  border-radius: 0.375rem;
  flex-shrink: 0;
}
.grp-list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  border: 1px solid var(--border-color);
  border-radius: 0.375rem;
  background: var(--bg-base);
  padding: 0.25rem 0;
}
.grp-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.4rem 0.6rem;
  background: transparent;
  border: 0;
  text-align: left;
  cursor: pointer;
  font-size: 0.875rem;
  color: var(--text-primary);
}
.grp-row-active {
  background: var(--bg-secondary);
}
.grp-row-current .grp-path {
  font-weight: 600;
}
.grp-icon {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
  color: var(--text-secondary);
}
.grp-main {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.grp-path {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--font-mono, ui-monospace, monospace);
}
.grp-hit {
  background: transparent;
  color: var(--accent, #3b82f6);
  font-weight: 700;
  padding: 0;
}
.grp-meta {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  flex-shrink: 0;
}
.grp-branch {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.75rem;
  color: var(--text-secondary);
  background: var(--bg-secondary);
  padding: 0.05rem 0.4rem;
  border-radius: 0.25rem;
  max-width: 12rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.grp-when {
  font-size: 0.75rem;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  margin-left: auto;
}
.grp-empty {
  padding: 1rem;
  color: var(--text-secondary);
  text-align: center;
  font-style: italic;
}
.grp-error {
  color: #ef4444;
  padding: 0.4rem 0.5rem;
  border: 1px solid #ef4444;
  border-radius: 0.375rem;
  font-size: 0.875rem;
  flex-shrink: 0;
}
.grp-truncated {
  font-size: 0.75rem;
  color: var(--text-secondary);
  text-align: center;
  flex-shrink: 0;
}

/* Fuzzy file finder: the directory chip lives in the modal title-right slot
   and re-roots the search when clicked. Reuses .grp-* for the list body. */
.ff-dir-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  max-width: 22rem;
  padding: 0.25rem 0.6rem;
  background: var(--bg-secondary);
  color: var(--text-secondary);
  border: 1px solid var(--border);
  border-radius: 0.375rem;
  cursor: pointer;
  font-size: 0.8rem;
  transition:
    border-color 0.12s ease,
    background 0.12s ease,
    color 0.12s ease;
}
.ff-dir-btn:hover {
  color: var(--text-primary);
  background: var(--bg-hover);
  border-color: var(--primary);
}
.ff-dir-btn:active {
  transform: translateY(0.5px);
}
.ff-dir-btn:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}
.ff-dir-btn .grp-icon {
  width: 0.9rem;
  height: 0.9rem;
  color: var(--primary);
  flex-shrink: 0;
}
.ff-dir-path {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--font-mono, ui-monospace, monospace);
}

/* Mobile: keep the finder title compact so the directory chip fits on the
   same row instead of wrapping the title across three lines. */
@media (max-width: 768px) {
  .ff-modal .modal-title {
    font-size: 0.95rem;
    white-space: nowrap;
  }
  .ff-modal .modal-title-right {
    margin-right: 0.5rem;
    min-width: 0;
  }
  .ff-dir-btn {
    max-width: 48vw;
  }
}

/* Mobile: use the full screen, slim header, and stack branch/worktree
   onto a second line so the repo path always gets full width. */
@media (max-width: 768px) {
  /* Full-screen on phones: drop the mask padding so 100dvh fits. */
  .modal-overlay:has(.grp-modal) {
    padding: 0;
  }
  .grp-modal {
    height: 100vh;
    height: 100dvh;
    max-height: 100dvh;
    max-width: 100vw;
    border-radius: 0;
  }
  .grp-modal .modal-header {
    padding: 0.4rem 0.6rem;
  }
  .grp-modal .modal-title {
    font-size: 0.95rem;
  }
  .grp-modal .modal-body {
    padding: 0.5rem 0.6rem 0.6rem;
  }
  .grp-main {
    flex-direction: column;
    align-items: stretch;
    gap: 0.1rem;
  }
  .grp-row {
    align-items: flex-start;
    padding-top: 0.55rem;
    padding-bottom: 0.55rem;
  }
  .grp-icon {
    margin-top: 0.15rem;
  }
  .grp-meta {
    flex-wrap: wrap;
    font-size: 0.75rem;
  }
  .grp-branch {
    max-width: none;
  }
}

/* Attachment thumbnails strip above the textarea. Mirrors the iOS app: when
   a user pastes/drops an image we show a thumbnail; the [path] token is only
   injected into the message at send time. */
.message-attachments {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0.25rem 0 0.5rem;
  flex: 0 0 100%;
  order: -1;
}

.message-attachment {
  position: relative;
  width: 64px;
  height: 64px;
  border-radius: 0.375rem;
  overflow: hidden;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  flex-shrink: 0;
}

.message-attachment-thumb {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.message-attachment-file {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.125rem;
  padding: 0.25rem;
  color: var(--text-secondary);
  font-size: 0.65rem;
  text-align: center;
}

.message-attachment-name {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.message-attachment-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
}

.message-attachment-error-badge {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(220, 38, 38, 0.7);
  color: white;
  font-weight: 700;
  font-size: 1.25rem;
}

.message-attachment-remove {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: none;
  background: rgba(0, 0, 0, 0.6);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 2px;
  opacity: 0.85;
}

.message-attachment-remove:hover {
  opacity: 1;
  background: rgba(0, 0, 0, 0.8);
}

.message-attachment-remove svg {
  width: 100%;
  height: 100%;
}

/* Web Search Tool */
.web-search-results {
  padding: 0.5rem 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.web-search-result {
  padding: 0.375rem 0;
  border-bottom: 1px solid var(--border);
}

.web-search-result:last-child {
  border-bottom: none;
}

.web-search-result-title {
  color: var(--link-color);
  text-decoration: none;
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.3;
  display: block;
}

.web-search-result-title:hover {
  text-decoration: underline;
}

.web-search-result-meta {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.125rem;
  font-size: 0.75rem;
  color: var(--text-secondary);
  line-height: 1.3;
}

.web-search-result-url {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 400px;
}

.web-search-result-age {
  flex-shrink: 0;
  color: var(--text-tertiary);
}

.web-search-query {
  font-style: italic;
  color: var(--text-secondary);
}

/* Inline web-search citations (coalesced text runs) */
.citation-refs {
  /* keep markers on the text baseline as small superscripts */
  font-size: 0.7em;
  line-height: 0;
  white-space: nowrap;
}

.citation-ref {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.05em;
  height: 1.05em;
  padding: 0 0.25em;
  margin: 0 0.1em;
  border-radius: 0.5em;
  background: var(--bg-secondary, rgba(127, 127, 127, 0.15));
  color: var(--link-color);
  font-weight: 600;
  text-decoration: none;
  vertical-align: super;
}

.citation-ref:hover {
  background: var(--link-color);
  color: var(--bg-base, #fff);
}

.citation-sources {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0.5rem 0 0;
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.citation-source {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  font-size: 0.75rem;
  line-height: 1.3;
}

/* The number is rendered explicitly (.citation-source-num) so it always
   matches the inline marker, even across multiple text runs in a message. */
.citation-source-num {
  flex-shrink: 0;
  min-width: 1.1em;
  text-align: center;
  color: var(--text-secondary);
  font-weight: 600;
}

.citation-source-link {
  color: var(--link-color);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.citation-source-link:hover {
  text-decoration: underline;
}

/* Feature flags modal */
.feature-flag-empty {
  color: var(--text-secondary);
  font-size: 0.9rem;
  padding: 1rem 0;
}
.feature-flag-list {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}
.feature-flag-row {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--border);
}
.feature-flag-row:last-child {
  border-bottom: none;
}
.feature-flag-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.feature-flag-name {
  font-weight: 600;
  font-size: 0.95rem;
}
.feature-flag-badge {
  font-size: 0.7rem;
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
  background: var(--accent, #4f46e5);
  color: white;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.feature-flag-desc {
  color: var(--text-secondary);
  font-size: 0.875rem;
}
.feature-flag-bool {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
  user-select: none;
}
.feature-flag-json {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.85rem;
  resize: vertical;
  min-height: 2.5rem;
}
.feature-flag-actions {
  display: flex;
  justify-content: flex-end;
}
.feature-flag-meta {
  display: flex;
  align-items: center;
  gap: 1rem;
  font-size: 0.8rem;
  color: var(--text-secondary);
}
.feature-flag-meta code {
  font-size: 0.8rem;
}
.feature-flag-clear {
  margin-left: auto;
  padding: 0.25rem 0.6rem;
  font-size: 0.8rem;
}
.feature-flag-error {
  color: #dc2626;
  font-size: 0.85rem;
  white-space: pre-wrap;
}

/* Conversation tags */
.conversation-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.2rem;
  align-items: center;
}

.conversation-tag {
  display: inline-flex;
  align-items: center;
  font-size: 0.75rem;
  line-height: 1.2;
  color: var(--accent-text, var(--primary));
  max-width: 12rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.conversation-item.active .conversation-tag {
  color: rgba(255, 255, 255, 0.85);
}

.conversation-tag-hash {
  opacity: 0.6;
  margin-right: 0.05rem;
}

.conversation-tag-remove {
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
  font-size: 0.85rem;
  line-height: 1;
  padding: 0 0.15rem;
  margin-left: 0.1rem;
  opacity: 0;
  transition: opacity 0.1s ease;
}

.conversation-tag-removable:hover .conversation-tag-remove,
.conversation-tag-remove:focus {
  opacity: 0.7;
}

.conversation-tag-remove:hover {
  opacity: 1 !important;
}

/* While editing, chips and the inline text input share one flex row, so
   the experience is "the tag list grows another chip" rather than a
   separate popover under the row. */
.conversation-tag-inline-form {
  display: inline-flex;
  flex: 1;
  min-width: 4rem;
}

.conversation-tag-inline-input {
  flex: 1;
  min-width: 4rem;
  padding: 0 0.15rem;
  font-size: 0.75rem;
  line-height: 1.4;
  border: none;
  border-radius: 0;
  background-color: transparent;
  color: inherit;
}

.conversation-tag-inline-input:focus {
  outline: none;
}

.conversation-tag-inline-input::placeholder {
  opacity: 0.5;
}

/* ============================================================
 * Tool pills (iOS-style)
 *
 * A burst of tool calls is rendered as a single wrapped row of
 * tightly-packed pills. Tapping a pill opens the full
 * CoalescedToolCall view in a modal. Diffs, screenshots, image
 * reads and output_iframe results continue to render inline.
 * Mirrors mobile/ToolPillsRow.swift.
 * ============================================================ */

.tool-pills-row-wrap .message-content {
  padding: 0;
  background: none;
  border: none;
}

.tool-pills-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 4px 0;
  margin: 0;
  list-style: none;
  align-items: center;
}

.tool-pill-item {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.tool-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  min-height: 26px;
  padding: 2px 10px;
  border-radius: 999px;
  border: 1px solid var(--tp-border, var(--border));
  background: var(--tp-bg, var(--bg-tertiary));
  color: var(--text-primary);
  font: inherit;
  font-size: 0.8125rem;
  line-height: 1.2;
  cursor: pointer;
  white-space: nowrap;
  transition:
    filter 0.12s ease,
    transform 0.06s ease;
}

.tool-pill:hover {
  filter: brightness(1.04);
}

.tool-pill:active {
  transform: translateY(0.5px);
}

.tool-pill:focus-visible {
  outline: 2px solid var(--link-color);
  outline-offset: 1px;
}

.tool-pill-emoji {
  font-size: 0.8125rem;
  line-height: 1;
  flex-shrink: 0;
}

.tool-pill-text {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  /* Desktop affords wider pills; the headline budget in toolMeta.ts
   * already picks how much text to surface, this is the visual guard. */
  max-width: 360px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tool-pill-spinner {
  width: 10px;
  height: 10px;
  border: 1.5px solid var(--tp-border, var(--text-secondary));
  border-top-color: transparent;
  border-radius: 50%;
  animation: tool-pill-spin 0.8s linear infinite;
  flex-shrink: 0;
}

@keyframes tool-pill-spin {
  to {
    transform: rotate(360deg);
  }
}

.tool-pill-err {
  /* Exit-code/error is a low-priority signal: a small muted glyph, not a
   * red chip. The pill keeps its neutral background (see .tool-pill--error). */
  color: var(--text-secondary);
  font-size: 0.75rem;
  font-weight: 600;
  flex-shrink: 0;
}

/* Errored pills keep the normal neutral chip styling; the small muted
 * ✗ glyph is the only differentiator. No red overrides here. */

/* No per-tool tint on the web. Web's tool widgets are monochrome
 * with a single blue accent, and a rainbow row of pills clashes
 * with the rest of the conversation surface. The emoji already
 * encodes tool identity at-a-glance; the pill itself just needs to
 * look like a tappable chip. (iOS uses color because its native
 * surfaces are richer, see ToolPillsRow.swift.) */

/* Pill in the expanded state: keep it visually anchored to the
 * card that opened below it. */
.tool-pill--expanded {
  background: var(--bg-secondary, var(--bg-tertiary));
  border-color: var(--link-color);
}

/* Inline-expanded tool cards live directly under the pill row
 * inside the same .message-content wrapper. */
.tool-pill-expanded-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 8px;
}

.tool-pill-expanded > .message-tool {
  margin: 0;
}

@media (max-width: 600px) {
  .tool-pill-text {
    max-width: 150px;
  }
}

/* ============================================================
 * Tool detail modal: a WIDE, FLAT detail view for the
 * CoalescedToolCall card shown in a dialog when a pill is clicked.
 *
 * The inline (non-modal) tool cards are a gray rounded card with their
 * own clickable header. Inside the modal that produces ugly
 * double-boxing and shows the command up to three times. Everything
 * below is scoped to .tool-detail-modal so the inline cards are
 * untouched: we flatten the card, hide its header (the modal title
 * + status strip name the tool and its result), and let the boxed
 * sections sit directly on the flat modal background.
 * ============================================================ */
.tool-detail-modal {
  width: min(960px, 94vw);
  max-width: 94vw;
}

.tool-detail-modal .tool-pill-expanded > .message-tool {
  margin: 0;
}

/* Flatten the outer card: no gray card-within-card. */
.tool-detail-modal .bash-tool,
.tool-detail-modal .tool {
  background: none;
  margin: 0;
}

.dark .tool-detail-modal .bash-tool,
.dark .tool-detail-modal .tool {
  background: none;
}

/* Hide the card's own header entirely: the modal title names the tool
 * and the titleRight status strip carries result + duration, so the
 * card header (command line, cwd, duplicate status, chevron) is
 * redundant. */
.tool-detail-modal .bash-tool-header,
.tool-detail-modal .tool-header {
  display: none;
}

/* Align the body to the modal padding (the modal-body already pads). */
.tool-detail-modal .bash-tool-details,
.tool-detail-modal .llm-one-shot-images,
.tool-detail-modal .tool-details {
  padding: 0;
  gap: 1rem;
}

/* Polish the code/pre boxes so they look intentional on the flat
 * background: comfortable padding, subtle rounded border, readable
 * line-height, and scroll when content is large. */
.tool-detail-modal .bash-tool-code,
.tool-detail-modal .tool-code {
  padding: 0.875rem 1rem;
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  line-height: 1.55;
  /* The modal body is the single scroll container — don't cap the box
   * height or add a nested overflow, otherwise long output produces two
   * scrollbars (inner box + modal body). Let it grow and scroll the body. */
  max-height: none;
  overflow-x: auto;
  overflow-y: visible;
}

/* Fallback render path: unmapped tools (no entry in TOOL_COMPONENTS) use
 * the generic .tool-result-details card. Flatten it the same way and
 * strip the red error tint so it matches the specialised tool cards. */
.tool-detail-modal .tool-result-details,
.tool-detail-modal .tool-result-details.error {
  border: none;
  margin: 0;
}

.tool-detail-modal .tool-result-summary {
  display: none;
}

.tool-detail-modal .tool-result-content {
  padding: 0;
}

.tool-detail-modal .tool-result-section.error.output,
.tool-detail-modal .tool-result-section.output,
.tool-detail-modal .tool-result-section {
  background: var(--bg-base);
  border: 1px solid var(--border);
}

.tool-detail-modal .tool-result-section.error.output .tool-result-label {
  color: var(--text-secondary);
}

/* Specialised tool error messages (screenshot/screencast/output-iframe)
 * paint a red box inline; inside the detail modal we keep the rest of the
 * surface neutral, so render these as ordinary code blocks too. */
.tool-detail-modal .screenshot-tool-error-message,
.tool-detail-modal .screencast-tool-error-message,
.tool-detail-modal .output-iframe-tool-error-message {
  background: var(--bg-base);
  border-color: var(--border);
  color: var(--text-primary);
}

/* ------------------------------------------------------------
 * Status strip (Modal titleRight): a small, muted badge with the
 * run state and execution duration. Tasteful and monochrome — even
 * a failure is just a soft ✗, never a red banner.
 * ------------------------------------------------------------ */
.tool-detail-status {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.8125rem;
  color: var(--text-secondary);
}

.tool-detail-status-label {
  font-weight: 500;
}

.tool-detail-status-glyph {
  font-weight: 600;
}

.tool-detail-status--success .tool-detail-status-glyph {
  color: var(--success-text);
}

/* Failure and cancellation stay muted — the ✗ reads as secondary text,
 * not an alarm. */
.tool-detail-status--failed .tool-detail-status-glyph,
.tool-detail-status--failed .tool-detail-status-label,
.tool-detail-status--cancelled .tool-detail-status-glyph,
.tool-detail-status--cancelled .tool-detail-status-label {
  color: var(--text-secondary);
}

.tool-detail-status-time {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--text-tertiary);
}

.tool-detail-status-spinner {
  width: 11px;
  height: 11px;
  border: 1.5px solid var(--text-secondary);
  border-top-color: transparent;
  border-radius: 50%;
  animation: tool-pill-spin 0.8s linear infinite;
  flex-shrink: 0;
}

/* ---------------------------------------------------------------------------
 * Conversation export page (/export/<id>)
 * A focused split-pane editor: editable Markdown left, rendered preview right.
 * Reuses the app theme variables and .markdown-content typography.
 * ------------------------------------------------------------------------- */
.export-page {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background: var(--bg-base);
  color: var(--text-primary);
}
.export-centered {
  align-items: center;
  justify-content: center;
}
.export-error {
  color: var(--text-secondary);
  padding: 24px;
  text-align: center;
}
.export-spinner {
  width: 32px;
  height: 32px;
  border: 3px solid var(--border);
  border-top-color: var(--primary);
  border-radius: 50%;
  animation: export-spin 0.8s linear infinite;
}
@keyframes export-spin {
  to {
    transform: rotate(360deg);
  }
}
.export-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 14px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-secondary);
  flex: 0 0 auto;
}
.export-title {
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1 1 auto;
  min-width: 0;
}
.export-opt {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--text-secondary);
  white-space: nowrap;
  cursor: pointer;
}
.export-opt input {
  cursor: pointer;
}
.export-tabs {
  display: none;
  gap: 4px;
}
.export-tab {
  border: 1px solid var(--border);
  background: var(--bg-base);
  color: var(--text-primary);
  padding: 6px 12px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 13px;
}
.export-tab-active {
  background: var(--primary);
  color: #fff;
  border-color: var(--primary);
}
.export-panes {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
}
.export-pane {
  display: flex;
  flex-direction: column;
  flex: 1 1 50%;
  min-width: 0;
  min-height: 0;
}
.export-pane-edit {
  border-right: 1px solid var(--border);
}
.export-pane-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-secondary);
  flex: 0 0 auto;
}
.export-pane-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.export-pane-actions {
  display: flex;
  gap: 6px;
}
.export-btn {
  border: 1px solid var(--border);
  background: var(--bg-base);
  color: var(--text-primary);
  padding: 5px 11px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 13px;
  white-space: nowrap;
}
.export-btn:hover {
  border-color: var(--primary);
}
.export-btn-primary {
  background: var(--primary);
  color: #fff;
  border-color: var(--primary);
}
.export-src {
  flex: 1 1 auto;
  width: 100%;
  border: 0;
  resize: none;
  padding: 16px;
  font:
    13px/1.55 ui-monospace,
    SFMono-Regular,
    Menlo,
    Consolas,
    monospace;
  background: var(--bg-base);
  color: var(--text-primary);
  outline: none;
  tab-size: 2;
}
.export-preview {
  flex: 1 1 auto;
  overflow: auto;
  padding: 16px 22px;
}
.export-toast {
  position: fixed;
  bottom: 18px;
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  background: var(--text-primary);
  color: var(--bg-base);
  padding: 8px 16px;
  border-radius: 8px;
  font-size: 13px;
  opacity: 0;
  pointer-events: none;
  transition:
    opacity 0.2s,
    transform 0.2s;
  z-index: 50;
}
.export-toast-show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
@media (max-width: 720px) {
  .export-tabs {
    display: flex;
  }
  .export-pane {
    flex-basis: 100%;
  }
  .export-pane-edit {
    border-right: 0;
  }
  .export-panes .export-pane {
    display: none;
  }
  .export-panes .export-pane.export-pane-shown {
    display: flex;
  }
}

/* =========================================================================
   ChatOverflowMenu.vue — the top-right kebab menu rebuilt on PrimeVue
   (Popover + SelectButton + Select). Scoped under .overflow-menu-panel so it
   never touches the legacy React menu, which still uses .overflow-menu and the
   hand-rolled .theme-toggle-* / .md-toggle-* / .language-dropdown-* classes.
   ========================================================================= */

/* The PrimeVue Popover surface. PrimeVue positions the root itself (fixed +
   inline top/left), so we only theme it; we must NOT set position/top/right
   like the legacy .overflow-menu does. */
.chat-overflow-popover.p-popover {
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  box-shadow:
    0 4px 6px -1px rgba(0, 0, 0, 0.1),
    0 2px 4px -1px rgba(0, 0, 0, 0.06);
  min-width: 16rem;
}

/* PrimeVue draws a little arrow via :before/:after; we don't want it for a
   menu, so hide it and remove the default content padding (our items own it). */
.chat-overflow-popover.p-popover:before,
.chat-overflow-popover.p-popover:after {
  display: none;
}
.chat-overflow-popover .overflow-menu-panel {
  padding: 0.25rem 0;
}

/* Action rows inside the popover reuse .overflow-menu-item, but that class'
   first/last-child radius rules assumed the row was flush with the panel edge.
   Re-assert the icon spacing and hover for items rendered here. */
.overflow-menu-panel .overflow-menu-item {
  display: flex;
  align-items: center;
  width: 100%;
  padding: 0.625rem 1rem;
  text-align: left;
  background: transparent;
  border: none;
  color: var(--text-primary);
  font-size: 0.875rem;
  cursor: pointer;
  transition: background-color 0.15s;
  white-space: nowrap;
}
.overflow-menu-panel .overflow-menu-item:hover {
  background: var(--bg-hover);
}
.overflow-menu-panel .chat-menu-icon {
  margin-right: 0.75rem;
  font-size: 1rem;
  width: 1.25rem;
  text-align: center;
  color: var(--text-secondary);
  flex-shrink: 0;
}
/* SVG-path icons (custom server links) keep their box sizing. */
.overflow-menu-panel svg.chat-menu-icon {
  width: 1.25rem;
  height: 1.25rem;
}

.overflow-menu-panel .overflow-menu-divider {
  height: 1px;
  background: var(--border);
  margin: 0.25rem 0;
}

/* Rows that hold a SelectButton / Select control. */
.overflow-menu-control {
  padding: 0.5rem;
}
.overflow-menu-control .md-toggle-label {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 0.75rem;
  color: var(--text-secondary);
  margin-bottom: 0.375rem;
  font-weight: 500;
}

/* Make the SelectButton fill the row and behave like a segmented control. */
.overflow-menu-control .p-selectbutton {
  display: flex;
  width: 100%;
}
.overflow-menu-control .p-selectbutton .p-togglebutton {
  flex: 1;
}

/* The language Select fills the row. */
.overflow-menu-control .overflow-language-select.p-select {
  width: 100%;
}
.overflow-menu-control .language-dropdown-flag {
  font-size: 1rem;
  line-height: 1;
  margin-right: 0.4rem;
}

/* Visually-hidden label kept for screen readers on icon-only toggle options. */
.overflow-menu-panel .sr-only-label {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* =========================================================================
   Status-bar model picker (ModelPicker.vue) — one PrimeVue <Select> that
   carries both the model choice and the reasoning-effort pill row. PrimeVue
   owns open/close, outside-click, Escape, viewport-aware flip placement AND
   all of the trigger/label/overlay/option theming: the component passes
   size="small" plus a :dt token map (statusPickerDt.ts) that feeds our CSS
   vars into PrimeVue's own token system. The only things hand-written here
   are the overlay's content-width behaviour and the bespoke option/footer
   markup. Scoped to the picker classes so nothing leaks to other PrimeVue
   Selects (e.g. the overflow-menu language picker).
   ========================================================================= */

/* Trigger label: model name + quiet "· effort" suffix. */
.model-picker .model-picker-value {
  display: flex;
  align-items: baseline;
  gap: 0.375rem;
  min-width: 0;
}
.model-picker .model-picker-value-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.model-picker .model-picker-value-effort {
  flex-shrink: 0;
  color: var(--text-secondary);
}

/* Inline variant: the status-bar readout renders the model as one dot-separated
   segment beside the cwd and token count, so the trigger has to be bare text —
   no box, no chevron, inheriting the readout's type. PrimeVue's chrome lives on
   .p-select/.p-select-label, hence the !important-free but specific overrides
   below (the :dt tokens set background/border as inline custom properties on
   the root, which a plain class can't outrank without matching specificity). */

/* No chevron: the segment reads as text, and the dot separators already imply
   the readout is a row of distinct things. Hidden in CSS with the rest of the
   inline chrome rather than via a pt style, so it's all in one place. */
.p-select.model-picker-inline .p-select-dropdown {
  display: none;
}

.p-select.model-picker-inline {
  background: none;
  border: none;
  border-radius: 3px;
  box-shadow: none;
  font: inherit;
  color: inherit;
  /* PrimeVue's Select is width:100% via fluid; inline it should be exactly as
     wide as the model name, and shrinkable to less (min-width: 0) so the name
     ellipsizes instead of pushing the readout past the edge of the bar. */
  width: auto;
  min-width: 0;
}

/* Padding/margin make the whole segment a 24px-tall hit target like the sibling
   usage label. Vertical only: horizontal padding would widen the segment (and a
   negative margin to cancel it would make the box wider than its flex parent,
   overflowing the status bar under width pressure). The focus ring gets its
   clearance from outline-offset below, which costs no layout. */
.p-select.model-picker-inline .p-select-label {
  padding: 5px 0;
  margin: -5px 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

.p-select.model-picker-inline:hover:not(.p-disabled),
.p-select.model-picker-inline.p-focus {
  background: none;
  border: none;
  box-shadow: none;
  color: var(--text-primary);
}

/* Disabled while the agent works (switching model would cancel the turn). The
   segment still has to read as the model name — it's the readout, not just a
   control — so dim it slightly rather than greying it out, and drop the pointer
   cursor so it doesn't invite a click that does nothing. The wrapper carries a
   tooltip explaining why (a .p-disabled element gets pointer-events: none, so
   the tooltip can't live here). */
.p-select.model-picker-inline.p-disabled {
  background: none;
  border: none;
  box-shadow: none;
  opacity: 0.65;
}

.p-select.model-picker-inline.p-disabled .p-select-label {
  cursor: default;
}

/* PrimeVue's .p-select-label is the focusable combobox. Its box is 5px taller
   than the text (the hit-target padding above) but flush with it horizontally,
   so a single outline-offset can't clear the glyphs on both axes: negative
   values cut into the first and last character, and positive ones push the ring
   well outside the segment vertically. Draw the ring with an inset box-shadow
   sized per-axis instead — 0 vertical (the padding already provides the gap),
   2px horizontal — which costs no layout and so can't widen the segment. */
.p-select.model-picker-inline .p-select-label:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--blue-text);
  border-radius: 3px;
}

/* box-shadow is dropped in forced-colors mode, which would leave this control
   with no focus indicator at all; fall back to a plain outline there. Cutting a
   few pixels into the glyphs is a fine trade for having a ring. */
@media (forced-colors: active) {
  .p-select.model-picker-inline .p-select-label:focus-visible {
    outline: 2px solid;
    outline-offset: -2px;
  }
}

/* Let the overlay grow to its widest option (PrimeVue only guarantees
   min-width:100% of the trigger) so long model names aren't clipped, while
   staying within the viewport. */
.p-select-overlay.model-picker-panel {
  width: max-content;
  /* min-width has to yield to the viewport too, not just max-width: it wins over
     max-width in CSS, so a flat 16rem floor overflows a narrow screen however
     tight the cap is. */
  min-width: min(16rem, 92vw);
  max-width: min(22rem, 92vw);
  /* size="small" only shrinks the trigger label; PrimeVue has no overlay
     font-size token, so match the compact status-bar scale here (options
     inherit). */
  font-size: 0.8125rem;
}

/* Option markup: name (+ source sub-label only in multi-source installs),
   a check mark on the current selection, and a "not ready" badge. */
.p-select-overlay.model-picker-panel .model-picker-option-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  min-width: 0;
}
.p-select-overlay.model-picker-panel .model-picker-option-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.p-select-overlay.model-picker-panel .model-picker-option-source {
  font-size: 0.6875rem;
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.p-select-overlay.model-picker-panel .model-picker-option-badge {
  flex: 0 0 auto;
  font-size: 0.6875rem;
  color: var(--text-secondary);
  background: var(--bg-base);
  padding: 0.125rem 0.375rem;
  border-radius: 0.25rem;
}
.p-select-overlay.model-picker-panel .model-picker-option-check {
  flex: 0 0 auto;
  color: var(--blue-text);
  margin-left: 0.5rem;
}

.p-select-overlay.model-picker-panel .model-picker-divider {
  height: 1px;
  background: var(--border);
}

/* "All models (N)" toggle: a quiet list-end row, not a call to action. */
.p-select-overlay.model-picker-panel .model-picker-more {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  width: 100%;
  padding: 0.375rem 0.75rem;
  border: none;
  background: var(--bg-secondary);
  color: var(--text-secondary);
  font-size: 0.75rem;
  text-align: left;
  cursor: pointer;
}
.p-select-overlay.model-picker-panel .model-picker-more:hover {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}
.p-select-overlay.model-picker-panel .model-picker-more-icon {
  flex-shrink: 0;
  transition: transform 0.15s ease;
}
.p-select-overlay.model-picker-panel .model-picker-more-icon.expanded {
  transform: rotate(180deg);
}

/* Inline reasoning-effort row: label + pill radiogroup. Selecting a pill
   keeps the popover open (it's a secondary adjustment, not a commit). */
.p-select-overlay.model-picker-panel .model-picker-effort {
  padding: 0.5rem 0.75rem;
  background: var(--bg-secondary);
}
.p-select-overlay.model-picker-panel .model-picker-effort-label {
  display: block;
  font-size: 0.6875rem;
  color: var(--text-secondary);
  margin-bottom: 0.375rem;
}
.p-select-overlay.model-picker-panel .model-picker-effort-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}
.p-select-overlay.model-picker-panel .model-picker-effort-pill {
  padding: 0.1875rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 9999px;
  background: transparent;
  color: var(--text-secondary);
  font-size: 0.6875rem;
  line-height: 1.2;
  cursor: pointer;
  transition:
    color 0.12s ease,
    border-color 0.12s ease,
    background 0.12s ease;
}
.p-select-overlay.model-picker-panel .model-picker-effort-pill:hover {
  color: var(--text-primary);
  border-color: var(--text-secondary);
}
.p-select-overlay.model-picker-panel .model-picker-effort-pill.active {
  color: var(--blue-text);
  border-color: var(--blue-text);
  background: color-mix(in srgb, var(--blue-text) 10%, transparent);
}

/* Footer: "Manage models…" text action + icon-only refresh. */
.p-select-overlay.model-picker-panel .model-picker-footer-row {
  display: flex;
  align-items: stretch;
  background: var(--bg-secondary);
}
.p-select-overlay.model-picker-panel .model-picker-manage {
  flex: 1;
  padding: 0.5rem 0.75rem;
  border: none;
  background: transparent;
  color: var(--blue-text);
  font-size: 0.75rem;
  text-align: left;
  cursor: pointer;
}
.p-select-overlay.model-picker-panel .model-picker-manage:hover {
  background: var(--bg-tertiary);
}
.p-select-overlay.model-picker-panel .model-picker-refresh {
  display: flex;
  align-items: center;
  padding: 0 0.75rem;
  border: none;
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
}
.p-select-overlay.model-picker-panel .model-picker-refresh:hover:not(:disabled) {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}
.p-select-overlay.model-picker-panel .model-picker-refresh:disabled {
  opacity: 0.6;
  cursor: default;
}
.p-select-overlay.model-picker-panel .model-picker-refresh-icon.spinning {
  animation: spin 1s linear infinite;
}

/* Filter/search box at the top of the model overlay. Match the compact
   status-bar scale and theme tokens; ensure it stays comfortably tappable on
   mobile. */
.p-select-overlay.model-picker-panel .p-select-header {
  padding: 0.5rem;
  border-bottom: 1px solid var(--border);
}
.p-select-overlay.model-picker-panel .p-select-filter {
  width: 100%;
  font-size: 0.875rem;
  /* Extra right padding leaves room for PrimeVue's trailing search icon. */
  padding: 0.5rem 2rem 0.5rem 0.625rem;
  color: var(--text-primary);
  background: var(--bg-base);
  border: 1px solid var(--border);
  border-radius: 0.375rem;
}
.p-select-overlay.model-picker-panel .p-select-filter:focus {
  outline: none;
  border-color: var(--blue-text);
}

/* =========================================================================
   Modal.vue — the base modal rebuilt on PrimeVue Dialog. The #container slot
   reproduces the legacy .modal markup, so the only PrimeVue-specific styling
   needed is for the dialog scaffolding it wraps that markup in. Scoped under
   PrimeVue's own classes so the legacy React modal (plain .modal-overlay div)
   is untouched.
   ========================================================================= */

/* PrimeVue's mask already carries our .modal-overlay class (via pt), which owns
   the backdrop, centering, and z-index. Neutralize the p-dialog root wrapper so
   it doesn't add its own background/border/shadow around our .modal panel.
   Scoped to .modal-dialog-root (set via pt) so it can't leak to any future
   PrimeVue Dialog/ConfirmDialog/useDialog overlay, which share the .p-dialog
   class. */
.p-dialog.modal-dialog-root {
  background: transparent;
  border: none;
  box-shadow: none;
  max-width: none;
  max-height: none;
  /* As a flex item in the centering mask, the default `min-width: auto` lets
     wide inner content (e.g. the models table) push this wrapper past the
     viewport. Allow it to shrink so the inner .modal can scroll instead. */
  min-width: 0;
  /* Span the mask (minus its padding) and center the .modal panel inside.
     Without this the wrapper shrink-wraps to its content's preferred width,
     so the panel's `width: 100%` can't reach the mask edges — visible on
     phones where full-width content (e.g. the repo picker list) got an
     arbitrary content-sized width instead of the viewport's. */
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* The wrapper is invisible but, spanning the mask, it would swallow
     backdrop clicks beside the panel (PrimeVue's dismissable-mask only fires
     when the click target IS the mask). Let clicks fall through to the mask;
     the real panel re-enables hit testing below. !important beats PrimeVue's
     inline pointer-events on the dialog root. */
  pointer-events: none !important;
}

.modal-dialog-root > .modal {
  pointer-events: auto;
}

/* We move focus to the .modal panel on open so PrimeVue's focus trap engages,
   but the panel is a focus container, not an interactive control: hide the
   browser focus ring on it (real controls inside keep their own outlines). */
.modal-dialog-root > .modal:focus,
.modal-dialog-root > .modal:focus-visible {
  outline: none;
}

.reasoning-map-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.5rem 0.75rem;
  margin-top: 0.25rem;
}

.reasoning-map-grid .reasoning-map-row {
  display: grid;
  grid-template-columns: 3.5rem auto minmax(0, 1fr);
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  font-size: 0.8125rem;
}

.reasoning-map-arrow {
  color: var(--text-muted);
}

.reasoning-map-input {
  min-width: 0;
  height: 2rem;
  padding: 0.25rem 0.5rem;
  font-size: 0.8125rem;
}

@media (max-width: 900px) {
  .reasoning-map-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 520px) {
  .reasoning-map-grid {
    grid-template-columns: 1fr;
  }
}

/* Performance HUD (performance-hud feature flag) */
.perf-hud {
  position: fixed;
  bottom: 8px;
  left: 8px;
  z-index: 10000;
  min-width: 240px;
  max-width: 340px;
  max-height: 60vh;
  overflow-y: auto;
  background: rgba(15, 17, 21, 0.92);
  color: #d0d6e0;
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 6px;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 10.5px;
  line-height: 1.35;
  pointer-events: auto;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.4);
}

.perf-hud.collapsed {
  min-width: 0;
}

.perf-hud-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 3px 8px;
  cursor: pointer;
  user-select: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  position: sticky;
  top: 0;
  background: rgba(15, 17, 21, 0.97);
  pointer-events: auto;
}

.perf-hud.collapsed .perf-hud-header {
  border-bottom: none;
}

.perf-hud-title {
  font-weight: 700;
  color: #7dd3fc;
}

.perf-hud-mini {
  color: #9aa3b2;
}

.perf-hud-actions {
  margin-left: auto;
  display: flex;
  gap: 4px;
}

.perf-hud-btn {
  background: rgba(255, 255, 255, 0.08);
  color: inherit;
  border: none;
  border-radius: 3px;
  font: inherit;
  padding: 0 5px;
  cursor: pointer;
}

.perf-hud-btn:hover {
  background: rgba(255, 255, 255, 0.18);
}

.perf-hud-table {
  width: 100%;
  border-collapse: collapse;
}

.perf-hud-table th,
.perf-hud-table td {
  padding: 1px 8px;
  text-align: right;
  white-space: nowrap;
}

.perf-hud-table th {
  color: #9aa3b2;
  font-weight: 400;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.perf-hud-name {
  text-align: left !important;
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
}

.perf-hud-hot td {
  color: #fbbf24;
}

.perf-hud-empty {
  text-align: center !important;
  color: #9aa3b2;
  padding: 8px !important;
}

.perf-hud-section {
  padding: 4px 8px 1px;
  color: #fbbf24;
  font-weight: 700;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.perf-hud-section-hint {
  color: #6b7280;
  font-weight: 400;
  margin-left: 4px;
}

.perf-hud-load td {
  text-align: left;
}

.perf-hud-load-when {
  color: #6b7280;
}

.perf-hud-load-source {
  color: #7dd3fc;
}

.perf-hud-load-total {
  color: #a7f3d0;
}

.perf-hud-longtask td {
  text-align: left;
}

.perf-hud-longtask-when {
  color: #6b7280;
}

.perf-hud-longtask-dur {
  color: #fbbf24;
}

.perf-hud-longtask-suspects {
  max-width: 200px;
  white-space: normal !important;
  overflow-wrap: anywhere;
  text-overflow: clip;
  color: #d0d6e0;
}

.perf-hud-footer {
  padding: 2px 8px 4px;
  color: #6b7280;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

@media (max-width: 768px) {
  .perf-hud {
    max-width: 60vw;
    max-height: 40vh;
    font-size: 10px;
  }
}

/* Reduced motion.
 *
 * Users who ask for less motion should get it. This is also what makes the e2e
 * suite quick: PrimeVue's Dialog animates in and out over 0.3s, and Playwright
 * waits for an element to stop moving before clicking it, so every open/close
 * of a tool-detail modal cost ~0.6s of pure waiting. The universal rule below
 * covers PrimeVue's runtime-injected theme too -- !important outranks
 * specificity, so `*` beats its single-class .p-dialog-enter-active rule.
 *
 * The blanket rule collapses one-shot entrances, exits and transitions. But
 * indefinite animations (spinners, pulsing "running" badges, the streaming
 * caret) are the UI saying it is still working: freezing those would make a
 * busy app look hung, which is worse than the motion. They are restored below.
 *
 * That restore list is hand-maintained, so `reduced-motion.spec.ts` derives the
 * set of infinite animations from every stylesheet the server ships -- including
 * dependency CSS, which the rule above reaches too -- and fails if any of them
 * stops animating under reduce, whether by duration or iteration count. Add a
 * spinner, and the test tells you to add it here.
 *
 * Killing transitions is safe: nothing keys behaviour off transitionend, and
 * the one animationend listener (message highlight, ChatInterface) has a 2s
 * timeout fallback -- and a near-zero animation still fires the event, so it
 * cannot latch. JS scrolls pass `behavior: "smooth"` explicitly, which wins
 * over the scroll-behavior below; that is deliberate, since those are direct
 * responses to a user action rather than ambient motion.
 */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-delay: 0ms !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }

  /* Looping progress indicators keep looping. iteration-count is untouched by
     the rule above, so only the duration needs restoring. */
  .bash-tool-running,
  .command-palette-spinner,
  .conversation-loading-bar-fill,
  .export-spinner,
  .message-voice-btn.listening,
  .patch-tool-running,
  .reconnecting-dots,
  .screencast-tool-emoji,
  .screenshot-tool-running,
  .spinner,
  .status-message.status-reconnecting,
  .streaming-cursor,
  .thinking-dots,
  .thinking-dots span,
  .tool-detail-status-spinner,
  .tool-detail-status-time,
  .tool-pill-spinner,
  .tool-running,
  .tool-running-header,
  .tool-status-running,
  .p-select-overlay.model-picker-panel .model-picker-refresh-icon.spinning {
    animation-duration: 1.5s !important;
  }

  /* PrimeIcons ships its own reduce rule that freezes .pi-spin by setting
     animation-iteration-count to 1, so restoring the duration alone would leave
     it stopped after a single turn. Nothing in our source uses .pi-spin today;
     this keeps it usable. */
  .pi-spin {
    animation-duration: 2s !important;
    animation-iteration-count: infinite !important;
  }

  /* Monaco's own looping indicators. The universal rule above reaches into
     lazily-loaded dependency CSS too, and a frozen indeterminate progress bar or
     "syncing" icon is exactly the hung-looking UI this exemption exists to
     avoid. Durations match monaco-editor.css. */
  .monaco-progress-container.infinite .progress-bit {
    animation-duration: 4s !important;
  }

  .codicon-sync.codicon-modifier-spin,
  .codicon-loading.codicon-modifier-spin,
  .codicon-gear.codicon-modifier-spin,
  .codicon-notebook-state-executing.codicon-modifier-spin {
    animation-duration: 1.5s !important;
  }
}
