:root {
  /* Backgrounds */
  --bg-primary: #faf9f7;
  --bg-surface: #f0eeeb;

  /* Text */
  --text-primary: #1a1815;
  --text-secondary: #6b6560;
  --text-dim: #a8a29e;

  /* State colors */
  --color-recording: #c0392b;
  --color-recording-dark: #c0392b;
  --color-processing: #d4a017;
  --color-playing: #1D9E75;
  --color-playing-dark: #0F6E56;
  --color-accent: #1a1815;
  --color-accent-muted: #6b6560;

  /* Bubbles */
  --user-bubble: #1a1815;
  --assistant-bubble: #f0eeeb;
  --system-bubble: rgba(212, 160, 23, 0.06);

  /* Misc */
  --radius: 12px;

  /* Typography */
  --font-body: 'Outfit', sans-serif;
  --font-heading: 'Newsreader', serif;
  --font-mono: 'Space Mono', monospace;

  /* Borders & Shadows */
  --border-color: #dddad5;
  --card-bg: #fff;
  --shadow-sm: 0 1px 4px rgba(0, 0, 0, 0.04);
  --shadow-md: 0 2px 8px rgba(0, 0, 0, 0.06);

  /* Dynamic viewport. Starts at 100dvh; ViewportHeight.js overwrites with
     visualViewport.height in px so iOS keyboard/toolbar transitions track. */
  --app-height: 100dvh;
  --footer-height: 180px;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  background: var(--bg-primary);
  color: var(--text-primary);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  scrollbar-width: thin;
  scrollbar-color: var(--border-color) transparent;
}

/* Webkit scrollbar (Chrome, Safari, Edge) */
::-webkit-scrollbar {
  width: 6px;
}

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

::-webkit-scrollbar-thumb {
  background: var(--border-color);
  border-radius: 3px;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--text-dim);
}

#app {
  min-height: 100%;
}

/* Layout: sidebar + chat */
.app-layout {
  display: flex;
  height: var(--app-height);
  overflow: hidden;
}

.app {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  min-height: 0;
  padding: env(safe-area-inset-top, 0) 0 env(safe-area-inset-bottom, 0);
}

.app__main {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  scrollbar-width: thin;
  scrollbar-color: var(--border-color) transparent;
}

/* Status Bar */
.status-bar {
  z-index: 10;
  padding: 10px 20px;
  min-height: 56px;
  background: var(--bg-primary);
  border-bottom: 1px solid transparent;
  box-shadow: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 12px;
}

.status-bar--scrolled {
  border-bottom-color: var(--border-color);
  box-shadow: var(--shadow-sm);
}

.status-bar__menu,
.status-bar__back {
  background: none;
  border: none;
  color: var(--text-secondary);
  cursor: pointer;
  padding: 0;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  border-radius: 50%;
  -webkit-tap-highlight-color: transparent;
}

.status-bar__menu:hover,
.status-bar__back:hover {
  background: var(--bg-surface);
}

.status-bar__title-block {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow: hidden;
  user-select: none;
  -webkit-user-select: none;
  cursor: default;
}

.status-bar__title {
  font-family: var(--font-heading);
  font-size: 20px;
  font-weight: 500;
  color: var(--text-primary);
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.status-bar__subtitle {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 400;
  color: var(--text-dim);
  letter-spacing: 1px;
  text-transform: uppercase;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.session-end-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 24px 12px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-dim);
}

.session-end-divider__line {
  flex: 1 1 auto;
  height: 1px;
  background: var(--border-color);
}

.session-end-divider__label {
  flex: 0 0 auto;
  white-space: nowrap;
}

.status-bar__session-timer {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  margin-right: 8px;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(192, 57, 43, 0.15);
  color: var(--color-recording);
  font-family: var(--font-mono);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  flex: 0 0 auto;
}

.status-bar__model {
  position: relative;
  flex: 0 0 auto;
}

.status-bar__model-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 50px;
  border: 1.5px solid var(--border-color);
  background: var(--card-bg);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  -webkit-tap-highlight-color: transparent;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.status-bar__model-pill:hover {
  border-color: var(--text-dim);
}

.status-bar__model-pill[aria-expanded="true"] {
  border-color: var(--color-accent);
}

.status-bar__model-pill svg {
  color: var(--text-secondary);
}

.model-picker {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  min-width: 180px;
  background: var(--card-bg);
  border: 1px solid var(--border-color);
  border-radius: 12px;
  padding: 4px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  z-index: 11;
  box-shadow: var(--shadow-md);
}

.model-picker__option {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 8px 12px;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--text-secondary);
  cursor: pointer;
  text-transform: none;
  letter-spacing: 0;
  font-size: 13px;
  -webkit-tap-highlight-color: transparent;
}

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

.model-picker__option--active {
  background: var(--bg-primary);
  color: var(--text-primary);
}

.model-picker__label {
  font-weight: 600;
}

.model-picker__desc {
  font-weight: 400;
  font-size: 11px;
  color: var(--text-dim);
}

.status-bar__voice {
  position: relative;
  flex: 0 0 auto;
  margin-right: 6px;
}

.status-bar__voice-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 50px;
  border: 1.5px solid var(--border-color);
  background: var(--card-bg);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  -webkit-tap-highlight-color: transparent;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, opacity 0.15s ease;
  max-width: 140px;
}

.status-bar__voice-pill > span:first-child {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.status-bar__voice-pill:hover {
  border-color: var(--text-dim);
}

.status-bar__voice-pill[aria-expanded="true"] {
  border-color: var(--color-accent);
}

.status-bar__voice-pill--locked,
.status-bar__voice-pill[disabled] {
  opacity: 0.55;
  cursor: not-allowed;
}

.status-bar__voice-pill svg {
  color: var(--text-secondary);
}

.voice-picker {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  min-width: 260px;
  max-width: 320px;
  max-height: 60vh;
  overflow-y: auto;
  background: var(--card-bg);
  border: 1px solid var(--border-color);
  border-radius: 12px;
  padding: 4px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  z-index: 11;
  box-shadow: var(--shadow-md);
}

.voice-picker__option {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 12px;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--text-secondary);
  cursor: pointer;
  text-transform: none;
  letter-spacing: 0;
  font-size: 13px;
  text-align: left;
  -webkit-tap-highlight-color: transparent;
}

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

.voice-picker__option--active {
  background: var(--bg-primary);
  color: var(--text-primary);
}

.voice-picker__label {
  flex: 1 1 auto;
  min-width: 0;
  font-weight: 600;
  line-height: 1.3;
  word-break: break-word;
}

.voice-picker__desc {
  flex: 0 0 auto;
  font-weight: 400;
  font-size: 11px;
  color: var(--text-dim);
  white-space: nowrap;
  padding-top: 2px;
}


/* Chat Log */
.chat-log {
  flex: 1;
  padding: 16px 32px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 600px;
  width: 100%;
  margin: 0 auto;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

.chat-log__empty {
  margin: auto;
  color: var(--text-secondary);
  font-size: 15px;
}

.chat-log__spacer {
  flex: 1;
}

/* Message Bubbles */
.message-bubble {
  max-width: 82%;
  padding: 10px 14px;
  border-radius: var(--radius);
  font-size: 15px;
  line-height: 1.5;
  overflow-wrap: break-word;
  word-break: break-word;
  white-space: pre-wrap;
}

.message-user {
  align-self: flex-end;
  background: var(--user-bubble);
  color: #faf9f7;
  border-top-right-radius: 3px;
}

.message-assistant {
  align-self: flex-start;
  background: var(--assistant-bubble);
  color: var(--text-primary);
  border-bottom-left-radius: 3px;
  transition: box-shadow 0.3s;
}

.message-assistant--speaking {
  box-shadow: 0 0 0 1.5px var(--color-playing);
  animation: speaking-pulse 1.5s ease-in-out infinite;
}

.message-assistant--interrupted {
  background: transparent;
  border: 1px dashed rgba(26, 24, 21, 0.2);
  color: var(--text-dim);
  padding: 6px 10px;
}

.message-bubble__interrupted-label {
  font-size: 12px;
  font-style: italic;
  letter-spacing: 0.02em;
}

/* Partial-stream interrupt: the bubble keeps its delivered text but
   reads as "did not complete" — slight desaturation + an inline tail
   marker. Less visually loud than the placeholder so the text is
   still primary. */
.message-assistant--interrupted-partial {
  opacity: 0.85;
}

.message-bubble__interrupted-tail {
  color: var(--text-dim);
  font-size: 11px;
  font-style: italic;
  letter-spacing: 0.02em;
}

@keyframes speaking-pulse {
  0%, 100% { box-shadow: 0 0 0 1.5px var(--color-playing); }
  50% { box-shadow: 0 0 0 1.5px rgba(29, 158, 117, 0.15); }
}

.message-time {
  display: block;
  font-size: 11px;
  color: rgba(26, 24, 21, 0.35);
  margin-top: 4px;
  text-align: right;
}

.message-assistant .message-time {
  color: var(--text-dim);
}

.message-timing-icon {
  background: none;
  border: none;
  color: inherit;
  opacity: 0.5;
  cursor: pointer;
  padding: 2px 4px;
  margin-right: 2px;
  display: inline-flex;
  align-items: center;
  vertical-align: middle;
  -webkit-tap-highlight-color: transparent;
  min-width: 24px;
  min-height: 24px;
  justify-content: center;
}

.message-timing-icon:hover,
.message-timing-icon:active {
  opacity: 0.8;
}

.message-timing-details {
  font-size: 11px;
  color: var(--text-dim);
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--border-color);
  line-height: 1.6;
}

.message-timing-pipeline {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.02em;
}

.message-timing-totals {
  margin-top: 2px;
}

.message-system {
  align-self: center;
  background: var(--system-bubble);
  border: 1px solid rgba(212, 160, 23, 0.15);
  color: var(--color-processing);
  font-size: 13px;
  font-family: var(--font-mono);
  text-align: center;
}

.message-error {
  align-self: center;
  background: rgba(192, 57, 43, 0.06);
  border: 1px solid rgba(192, 57, 43, 0.15);
  color: var(--color-recording);
  font-size: 13px;
  font-family: var(--font-mono);
  text-align: center;
}

/* Control Bar */
.app-footer {
  position: sticky;
  bottom: 0;
  z-index: 10;
  flex-shrink: 0;
  padding: 0 12px env(safe-area-inset-bottom, 0);
  max-width: 600px;
  width: 100%;
  margin: auto auto 0;
  background: linear-gradient(to top, var(--bg-primary) 16px, transparent);
}

.control-bar {
  background: var(--card-bg);
  border: 1px solid var(--border-color);
  border-radius: 16px;
  padding: 12px 16px 16px;
  box-shadow: var(--shadow-md);
  user-select: none;
}

.button-area {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 18px;
  /* Top room for the "↑ LOCK" swipe hint, which is positioned above the
     mic-wrap and would otherwise crowd the composer. */
  padding: 18px 16px 0;
}

/* On touch devices, hide the action button while the composer has
   focus — the soft keyboard is up and any press would race the IME
   collapse. Scoped to textarea focus so the button itself doesn't
   trip the rule when tapped (Android Chrome focuses buttons on tap,
   which would otherwise hide the TalkButton mid-gesture and swallow
   the click). */
@media (pointer: coarse) {
  .control-bar:has(textarea:focus) .button-area { display: none; }
}

/* In-button status label — single home for swipe/state cues. Sits in the
   PTT's own footprint, not a separate box. */
.mic-label {
  text-align: center;
  font-size: 11px;
  min-height: 16px;
  font-family: var(--font-mono);
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-dim);
  transition: color 180ms ease, opacity 180ms ease;
}
.mic-label--held       { color: var(--color-recording); }
.mic-label--locked     { color: var(--color-recording-dark); font-weight: 600; }
.mic-label--up         { color: var(--color-processing); }
.mic-label--left       { color: var(--color-recording); }
.mic-label--right      { color: var(--color-playing); }
.mic-label--confirming { color: var(--color-processing); font-weight: 600; }

/* Mic Area & Lock Track */
.mic-area {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

/* Mic Button */
.mic-wrap {
  position: relative;
  width: 80px;
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  touch-action: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  cursor: pointer;
  margin: 8px 0;
}

.mic-glow {
  position: absolute;
  width: 130px;
  height: 130px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(192, 57, 43, 0.25) 0%, transparent 70%);
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.8);
  opacity: 0;
  transition: opacity 0.3s, transform 0.3s;
  pointer-events: none;
}

.mic-glow--active {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
  animation: glow-pulse 2s ease-in-out infinite;
}

@keyframes glow-pulse {
  0%, 100% { opacity: 0.6; transform: translate(-50%, -50%) scale(1); }
  50% { opacity: 1; transform: translate(-50%, -50%) scale(1.1); }
}

.mic-glow--warning {
  animation: glow-warning 0.8s ease-in-out infinite;
}

@keyframes glow-warning {
  0%, 100% { opacity: 0.8; transform: translate(-50%, -50%) scale(1); }
  50% { opacity: 0.2; transform: translate(-50%, -50%) scale(0.95); }
}

.mic-ring {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
}

.mic-ring__progress {
  transition: stroke-dashoffset 0.1s linear;
}

.mic-ring__progress--warning {
  animation: ring-warning 0.8s ease-in-out infinite;
}

@keyframes ring-warning {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.25; }
}

.mic-button {
  position: relative;
  z-index: 1;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.25s, transform 0.15s, color 0.25s, box-shadow 0.25s;
}

.mic-button--idle {
  background: var(--color-accent);
  color: #faf9f7;
  box-shadow: 0 2px 10px rgba(26, 24, 21, 0.15);
}

.mic-button--recording {
  background: var(--color-recording);
  color: #faf9f7;
  transform: scale(1.08);
  box-shadow: 0 2px 12px rgba(192, 57, 43, 0.35);
}

.mic-button--locked {
  background: var(--color-recording-dark);
  color: #faf9f7;
  box-shadow: 0 2px 12px rgba(192, 57, 43, 0.35);
}

.mic-button--processing {
  background: var(--color-accent-muted);
  color: rgba(250, 249, 247, 0.7);
  opacity: 0.7;
  cursor: default;
  pointer-events: none;
}

.mic-button--playing {
  background: var(--color-playing-dark);
  color: #faf9f7;
  box-shadow: 0 2px 10px rgba(15, 110, 86, 0.25);
}

/* Hold-to-erase confirmation: distinct amber state so it reads as
   "warning, you're about to clear the composer", not as recording. */
.mic-button--confirming {
  background: var(--color-processing);
  color: #faf9f7;
  transform: scale(1.05);
  box-shadow: 0 2px 12px rgba(212, 160, 23, 0.35);
}

/* At-rest hint that pressing will clear the composer. Subtle amber ring
   on the existing idle/playing background — the icon is already X, so
   the ring is the secondary cue, not the primary one. */
.mic-button--has-clear-hint {
  box-shadow: 0 2px 10px rgba(26, 24, 21, 0.15),
              inset 0 0 0 1.5px var(--color-processing);
}

/* Confirm-progress ring — second <circle> inside .mic-ring, only visible
   while the parent has the --running modifier. pathLength="100" lets us
   express the fill independently of RING_RADIUS. */
.mic-ring__confirm {
  opacity: 0;
  transition: opacity 120ms ease;
}
.mic-ring__confirm--running {
  opacity: 1;
  animation: mic-ring-confirm-fill 500ms linear forwards;
}
@keyframes mic-ring-confirm-fill {
  from { stroke-dashoffset: 100; }
  to   { stroke-dashoffset: 0; }
}

/* Auto-send grace ring — drains from full to empty over the configured
   hold window (animationDuration set inline). The element is remounted
   on every re-arm via a React `key`, which restarts the animation. */
.mic-ring__autosend {
  opacity: 1;
  animation-name: mic-ring-autosend-drain;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}
@keyframes mic-ring-autosend-drain {
  from { stroke-dashoffset: 0; }
  to   { stroke-dashoffset: 100; }
}

.mic-spinner {
  animation: spin 0.8s linear infinite;
}

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

/* Talk Button (Active Listening) — phase-driven, single-tap toggle. Sits
   in the same footer slot as the PTT mic button, sized identically so the
   layout doesn't shift when the user switches between PTT and session
   presets. Five phase variants below. */

.talk-area {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

/* Wrap + SVG overlay for the multi-utterance commit-window countdown.
   The button sits centered inside; the ring drains its stroke while the
   user has finished an utterance and the backend is waiting on the
   commit_silence_ms window to see if more is coming. Visually mirrors
   PTT's autosend ring so the two modes share one affordance. The
   `margin: 8px 0` matches `.mic-wrap` so that, when TalkButton and
   PTTButton sit side-by-side in the new-chat ControlBar, their inner
   buttons (and labels below) align on the same baseline. */
.talk-button-container {
  position: relative;
  width: 80px;
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 8px 0;
}

.talk-ring {
  position: absolute;
  inset: 0;
  width: 80px;
  height: 80px;
  pointer-events: none;
}

.talk-ring__commit {
  opacity: 1;
  animation-name: mic-ring-autosend-drain;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}

.talk-button {
  position: relative;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.25s, transform 0.15s, color 0.25s, box-shadow 0.25s;
}

.talk-button:disabled {
  cursor: default;
}

.talk-button--idle {
  background: var(--color-accent);
  color: #faf9f7;
  box-shadow: 0 2px 10px rgba(26, 24, 21, 0.15);
}

.talk-button--connecting,
.talk-button--stopping {
  background: var(--color-accent-muted);
  color: rgba(250, 249, 247, 0.7);
  opacity: 0.8;
  pointer-events: none;
}

/* "Armed, waiting" — slow gentle pulse so it reads as "mic is open" without
   being as visually loud as PTT recording-red mid-press. */
.talk-button--listening {
  background: var(--color-recording-dark);
  color: #faf9f7;
  animation: talk-listening-pulse 2s ease-in-out infinite;
}
@keyframes talk-listening-pulse {
  0%, 100% { box-shadow: 0 2px 12px rgba(192, 57, 43, 0.35), 0 0 0 0 rgba(192, 57, 43, 0.45); }
  50%      { box-shadow: 0 2px 12px rgba(192, 57, 43, 0.35), 0 0 0 12px rgba(192, 57, 43, 0); }
}

/* Assistant speaking — same teal as PTT-mode playing so the user reads
   "the assistant is talking" cross-mode. */
.talk-button--answering {
  background: var(--color-playing-dark);
  color: #faf9f7;
  box-shadow: 0 2px 12px rgba(15, 110, 86, 0.35);
}

/* Visibility paused — muted, communicates "session is still alive, tap
   to resume." */
.talk-button--paused {
  background: var(--color-accent-muted);
  color: rgba(250, 249, 247, 0.85);
  box-shadow: 0 2px 10px rgba(26, 24, 21, 0.2);
  opacity: 0.85;
}

/* Vocative-mode awaiting trigger — same "mic is hot" red as `--listening`,
   but a slower, gentler pulse to read as "patiently waiting for a name"
   rather than "actively capturing." */
.talk-button--awaiting-trigger {
  background: var(--color-recording-dark);
  color: #faf9f7;
  animation: talk-awaiting-pulse 4s ease-in-out infinite;
}
@keyframes talk-awaiting-pulse {
  0%, 100% { box-shadow: 0 2px 12px rgba(192, 57, 43, 0.25), 0 0 0 0 rgba(192, 57, 43, 0.30); }
  50%      { box-shadow: 0 2px 12px rgba(192, 57, 43, 0.25), 0 0 0 16px rgba(192, 57, 43, 0); }
}

.talk-label {
  text-align: center;
  font-size: 11px;
  min-height: 16px;
  font-family: var(--font-mono);
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-dim);
  transition: color 180ms ease;
}
.talk-label--listening { color: var(--color-recording-dark); font-weight: 600; }
.talk-label--answering { color: var(--color-playing-dark); font-weight: 600; }
.talk-label--paused    { color: var(--text-dim); }

/* Disclaimer */
.app-disclaimer {
  text-align: center;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-dim);
  padding: 8px 16px 16px;
  user-select: none;
  -webkit-user-select: none;
  cursor: default;
}

/* Scroll to bottom */
.scroll-to-bottom {
  position: fixed;
  bottom: calc(var(--footer-height, 180px) + 16px);
  left: 50%;
  transform: translateX(-50%);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--border-color);
  background: var(--card-bg);
  color: var(--text-secondary);
  box-shadow: var(--shadow-md);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 15;
  -webkit-tap-highlight-color: transparent;
}

/* Auth loading */
.auth-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

.auth-spinner {
  width: 32px;
  height: 32px;
  border: 3px solid var(--text-dim);
  border-top-color: var(--color-accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

/* Login Screen */
.login-screen {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--app-height);
  max-width: 600px;
  margin: 0 auto;
  padding: 24px;
}

.login-card {
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: 100%;
  max-width: 320px;
  padding: 32px 24px;
  background: var(--card-bg);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
}

.login-title {
  font-family: var(--font-heading);
  font-size: 24px;
  font-weight: 600;
  text-align: center;
  color: var(--text-primary);
  letter-spacing: 0.05em;
}

.login-input {
  width: 100%;
  padding: 12px 14px;
  background: var(--bg-primary);
  border: 1px solid var(--border-color);
  border-radius: 8px;
  color: var(--text-primary);
  font-size: 16px;
  outline: none;
  transition: border-color 0.2s;
}

.login-input:focus {
  border-color: var(--color-accent);
}

.login-input::placeholder {
  color: var(--text-dim);
}

.login-button {
  width: 100%;
  padding: 12px;
  background: var(--color-accent);
  border: none;
  border-radius: 50px;
  color: #faf9f7;
  font-size: 16px;
  font-weight: 500;
  cursor: pointer;
  transition: opacity 0.2s;
}

.login-button:disabled {
  opacity: 0.5;
  cursor: default;
}

.login-error {
  color: var(--color-recording);
  font-size: 14px;
  text-align: center;
}

/* Not Found Page (standalone) */
.not-found-page {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--app-height);
  padding: 24px;
}

.not-found-page__content {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  max-width: 480px;
  width: 100%;
}

.not-found-page__title {
  font-family: var(--font-heading);
  font-size: 28px;
  font-weight: 500;
  color: var(--text-primary);
  margin-bottom: 12px;
}

.not-found-page__subtitle {
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--text-dim);
  line-height: 1.5;
  margin-bottom: 20px;
}

.not-found-page__url {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 4px;
  max-width: 100%;
  margin-bottom: 24px;
}

.not-found-page__label {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 400;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-dim);
  text-align: left;
}

.not-found-page__path {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-secondary);
  background: var(--bg-surface);
  border: 1px solid var(--border-color);
  border-radius: 6px;
  padding: 6px 10px;
  max-width: 100%;
  word-break: break-all;
  text-align: left;
}

.not-found-page--backend .not-found-page__label {
  color: var(--color-info);
}

.not-found-page--backend .not-found-page__path {
  border-color: rgba(41, 128, 185, 0.3);
}

.not-found-page__action {
  padding: 11px 22px;
  border-radius: 50px;
  border: none;
  background: var(--color-accent);
  color: #faf9f7;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: opacity 0.15s ease;
  -webkit-tap-highlight-color: transparent;
}

.not-found-page__action:hover {
  opacity: 0.9;
}

/* New Chat View */
.new-chat-view {
  display: flex;
  flex-direction: column;
  flex: 1;
}

.new-chat-view__content {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 32px;
  max-width: 600px;
  width: 100%;
  margin: 0 auto;
}

.new-chat-view__greeting {
  font-family: var(--font-heading);
  font-size: 28px;
  font-weight: 500;
  color: var(--text-primary);
  margin-bottom: 12px;
}

.new-chat-view__subtitle {
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--text-dim);
  margin-bottom: 32px;
}

/* Chat Not Found */
.chat-not-found {
  display: flex;
  flex-direction: column;
  flex: 1;
}

.chat-not-found__content {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 32px;
  max-width: 480px;
  width: 100%;
  margin: 0 auto;
}

.chat-not-found__title {
  font-family: var(--font-heading);
  font-size: 28px;
  font-weight: 500;
  color: var(--text-primary);
  margin-bottom: 12px;
}

.chat-not-found__subtitle {
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--text-dim);
  line-height: 1.5;
  margin-bottom: 24px;
}

.chat-not-found__action {
  padding: 11px 22px;
  border-radius: 50px;
  border: none;
  background: var(--color-accent);
  color: #faf9f7;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: opacity 0.15s ease;
  -webkit-tap-highlight-color: transparent;
}

.chat-not-found__action:hover {
  opacity: 0.9;
}

/* Preset Bar */
.preset-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  padding: 8px 32px;
  flex-shrink: 0;
  max-width: 600px;
  width: 100%;
  margin: 0 auto;
}

.preset-bar::-webkit-scrollbar {
  display: none;
}

.preset-pill {
  padding: 8px 18px;
  border-radius: 50px;
  border: 1.5px solid var(--border-color);
  background: var(--card-bg);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: background 0.15s, border-color 0.15s;
  -webkit-tap-highlight-color: transparent;
}

.preset-pill:hover {
  background: var(--bg-surface);
}

.preset-pill__icon {
  display: inline-flex;
  align-items: center;
  color: var(--text-dim);
  top: 1px;
  position: relative;
}

.preset-pill--add {
  border-style: dashed;
  color: var(--text-dim);
  background: transparent;
}

.preset-pill--add:hover {
  background: var(--bg-surface);
}

.preset-pill--editing {
  border-style: dashed;
  opacity: 0.85;
}

.preset-bar__edit {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1.5px solid var(--border-color);
  background: var(--card-bg);
  color: var(--text-dim);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  -webkit-tap-highlight-color: transparent;
}

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

.preset-bar__edit--active {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: #faf9f7;
}

/* Preset Editor (Bottom Sheet) */
.preset-editor {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(8px);
  z-index: 100;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.preset-editor__panel {
  width: 100%;
  max-width: 440px;
  background: var(--card-bg);
  border-radius: 20px 20px 0 0;
  padding: 24px 20px 32px;
  max-height: 85vh;
  overflow-y: auto;
}

.preset-editor__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.preset-editor__title {
  font-family: var(--font-heading);
  font-size: 20px;
  font-weight: 500;
  color: var(--text-primary);
}

.preset-editor__close {
  background: none;
  border: none;
  color: var(--text-dim);
  cursor: pointer;
  padding: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.preset-editor__body {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-bottom: 24px;
}

.preset-editor__field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.preset-editor__label {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 1px;
}

.preset-editor__input {
  width: 100%;
  padding: 10px 14px;
  border-radius: 12px;
  border: 1.5px solid var(--border-color);
  background: var(--card-bg);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 14px;
  outline: none;
  box-sizing: border-box;
  transition: border-color 0.2s;
}

.preset-editor__input:focus {
  border-color: var(--color-accent);
}

.preset-editor__textarea {
  width: 100%;
  padding: 10px 14px;
  border-radius: 12px;
  border: 1.5px solid var(--border-color);
  background: var(--card-bg);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 14px;
  outline: none;
  box-sizing: border-box;
  resize: vertical;
  min-height: 88px;
  line-height: 1.5;
  transition: border-color 0.2s;
}

.preset-editor__textarea:focus {
  border-color: var(--color-accent);
}

.preset-editor__select {
  width: 100%;
  padding: 10px 14px;
  border-radius: 12px;
  border: 1.5px solid var(--border-color);
  background: var(--card-bg);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 14px;
  outline: none;
  box-sizing: border-box;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%236b6560'><path d='M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6z'/></svg>");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 14px;
  padding-right: 36px;
  transition: border-color 0.2s;
}

.preset-editor__select:focus {
  border-color: var(--color-accent);
}

.preset-editor__actions {
  display: flex;
  gap: 10px;
}

.preset-editor__delete {
  flex: 0 0 auto;
  padding: 12px 16px;
  border-radius: 50px;
  border: 1.5px solid var(--color-recording);
  background: transparent;
  color: var(--color-recording);
  font-family: var(--font-body);
  font-size: 14px;
  cursor: pointer;
}

.preset-editor__save {
  flex: 1;
  padding: 12px 16px;
  border-radius: 50px;
  border: none;
  background: var(--color-accent);
  color: #faf9f7;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

.preset-editor__save:disabled {
  opacity: 0.5;
  cursor: default;
}

.preset-editor__toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 24px;
  cursor: pointer;
}

.preset-editor__switch {
  width: 44px;
  height: 24px;
  border-radius: 12px;
  background: var(--border-color);
  position: relative;
  transition: background 0.2s;
  flex-shrink: 0;
}

.preset-editor__switch--on {
  background: var(--color-accent);
}

.preset-editor__thumb {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fff;
  position: absolute;
  top: 2px;
  left: 2px;
  transition: left 0.2s;
  box-shadow: var(--shadow-sm);
}

.preset-editor__switch--on .preset-editor__thumb {
  left: 22px;
}

.preset-editor__toggle-text {
  display: flex;
  flex-direction: column;
}

.preset-editor__toggle-label {
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--text-primary);
}

.preset-editor__toggle-desc {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-dim);
}

/* Delete Session Confirm (Bottom Sheet) */
.confirm-sheet {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(8px);
  z-index: 100;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.confirm-sheet__panel {
  width: 100%;
  max-width: 440px;
  background: var(--card-bg);
  border-radius: 20px 20px 0 0;
  padding: 24px 20px 32px;
  max-height: 85vh;
  overflow-y: auto;
}

.confirm-sheet__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.confirm-sheet__title {
  font-family: var(--font-heading);
  font-size: 20px;
  font-weight: 500;
  color: var(--text-primary);
}

.confirm-sheet__close {
  background: none;
  border: none;
  color: var(--text-dim);
  cursor: pointer;
  padding: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.confirm-sheet__body {
  margin-bottom: 24px;
}

.confirm-sheet__text {
  margin: 0;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--text-secondary);
  line-height: 1.5;
}

.confirm-sheet__name {
  color: var(--text-primary);
  font-weight: 500;
}

.confirm-sheet__actions {
  display: flex;
  gap: 10px;
}

.confirm-sheet__delete {
  flex: 0 0 auto;
  padding: 12px 16px;
  border-radius: 50px;
  border: 1.5px solid var(--color-recording);
  background: transparent;
  color: var(--color-recording);
  font-family: var(--font-body);
  font-size: 14px;
  cursor: pointer;
}

.confirm-sheet__cancel {
  flex: 1;
  padding: 12px 16px;
  border-radius: 50px;
  border: none;
  background: var(--color-accent);
  color: #faf9f7;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

/* Bug report — header trigger + bottom sheet */
.bug-report__trigger {
  position: relative;
  background: none;
  border: none;
  color: var(--text-secondary);
  cursor: pointer;
  padding: 0;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  border-radius: 50%;
  margin-left: 4px;
  -webkit-tap-highlight-color: transparent;
  transition: color 0.15s ease, background-color 0.15s ease;
}

.bug-report__trigger:hover {
  background: var(--bg-surface);
  color: var(--color-processing);
}

.bug-report__badge {
  position: absolute;
  top: 2px;
  right: 2px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 8px;
  background: var(--color-recording);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  line-height: 16px;
  text-align: center;
  pointer-events: none;
  box-shadow: 0 0 0 2px var(--bg-primary);
}

/* Inline variant — sits next to text in the "View local logs" link.
   Drops absolute positioning and the cream-ring outline, keeps the pill. */
.bug-report__badge--inline {
  position: static;
  display: inline-block;
  margin-left: 6px;
  vertical-align: middle;
  box-shadow: none;
}

.bug-report__backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(8px);
  z-index: 100;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.bug-report__sheet {
  width: 100%;
  max-width: 440px;
  background: var(--card-bg);
  border-radius: 20px 20px 0 0;
  padding: 12px 20px 32px;
  max-height: 85vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.bug-report__handle {
  align-self: center;
  width: 36px;
  height: 4px;
  background: var(--border-color);
  border-radius: 2px;
  margin-bottom: 4px;
}

.bug-report__title {
  font-family: var(--font-heading);
  font-size: 20px;
  font-weight: 500;
  color: var(--text-primary);
}

.bug-report__hint {
  font-family: var(--font-body);
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-secondary);
}

.bug-report__textarea {
  width: 100%;
  min-height: 96px;
  padding: 12px;
  border: 1.5px solid var(--border-color);
  border-radius: 12px;
  background: var(--bg-primary);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 14px;
  resize: vertical;
}

.bug-report__textarea:focus {
  outline: none;
  border-color: var(--color-accent);
}

.bug-report__ids {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 12px;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--bg-surface);
  font-family: var(--font-mono);
  font-size: 11px;
}

.bug-report__ids > div {
  display: contents;
}

.bug-report__ids span {
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 1px;
}

.bug-report__ids code {
  color: var(--text-primary);
  word-break: break-all;
}

.bug-report__report-id {
  font-family: var(--font-mono);
  font-size: 18px;
  font-weight: 500;
  color: var(--text-primary);
  padding: 12px;
  border-radius: 12px;
  background: var(--bg-surface);
  text-align: center;
  letter-spacing: 1px;
}

.bug-report__error {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--color-recording);
}

.bug-report__actions {
  display: flex;
  gap: 10px;
  margin-top: 4px;
}

.bug-report__btn {
  flex: 1;
  padding: 12px 16px;
  border-radius: 50px;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.bug-report__btn--primary {
  border: none;
  background: var(--color-accent);
  color: #faf9f7;
}

.bug-report__btn--primary:disabled {
  background: var(--color-accent-muted);
  cursor: not-allowed;
}

.bug-report__btn--secondary {
  border: 1.5px solid var(--border-color);
  background: var(--card-bg);
  color: var(--text-primary);
}

.bug-report__btn--secondary:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.bug-report__link {
  align-self: center;
  background: none;
  border: none;
  padding: 4px 8px;
  font-family: var(--font-body);
  font-size: 12px;
  color: var(--text-dim);
  text-decoration: underline;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

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

/* Sidebar */
.sidebar {
  width: 300px;
  flex-shrink: 0;
  background: var(--card-bg);
  border-right: 1px solid var(--border-color);
  display: flex;
  flex-direction: column;
  height: var(--app-height);
}

.sidebar__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 16px 12px;
}

.sidebar__title {
  font-family: var(--font-heading);
  font-size: 20px;
  font-weight: 500;
  color: var(--text-primary);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  text-align: left;
  transition: opacity 0.15s ease;
  -webkit-tap-highlight-color: transparent;
}

.sidebar__title:hover {
  opacity: 0.75;
}

.sidebar__close {
  background: none;
  border: none;
  color: var(--text-dim);
  cursor: pointer;
  padding: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  -webkit-tap-highlight-color: transparent;
}

.sidebar__actions {
  padding: 0 16px 12px;
}

.sidebar__presets {
  padding: 0 12px 12px;
}

.sidebar__presets .preset-bar {
  padding: 0;
  max-width: none;
  margin: 0;
  gap: 6px;
  justify-content: flex-start;
}

.sidebar__presets .preset-pill {
  padding: 6px 14px;
  font-size: 12px;
}

.sidebar__presets .preset-bar__edit {
  width: 28px;
  height: 28px;
}

.sidebar__new-chat {
  width: 100%;
  padding: 10px 16px;
  border-radius: 50px;
  border: none;
  background: var(--color-accent);
  color: #faf9f7;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  transition: opacity 0.15s;
}

.sidebar__new-chat:hover {
  opacity: 0.85;
}

.sidebar__list {
  flex: 1;
  overflow-y: auto;
  padding: 0 8px 16px;
  scrollbar-width: thin;
  scrollbar-color: var(--border-color) transparent;
}

.sidebar__group {
  margin-top: 16px;
}

.sidebar__group:first-child {
  margin-top: 0;
}

.sidebar__group-label {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 400;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 1px;
  padding: 8px 12px 4px;
  user-select: none;
  -webkit-user-select: none;
  cursor: default;
}

.sidebar__session-row {
  display: flex;
  align-items: stretch;
  border-radius: 12px;
  border: 1.5px solid transparent;
  transition: background 0.15s, border-color 0.15s;
}

.sidebar__session-row:hover {
  background: var(--bg-surface);
}

.sidebar__session-row--active {
  background: rgba(26, 24, 21, 0.04);
  border-color: var(--color-accent);
}

.sidebar__session {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 10px 4px 10px 12px;
  border: none;
  background: none;
  cursor: pointer;
  text-align: left;
  -webkit-tap-highlight-color: transparent;
}

.sidebar__session-title {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.sidebar__session-row--active .sidebar__session-title {
  font-weight: 600;
}

.sidebar__session-delete {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  padding: 0 8px;
  border: none;
  background: none;
  color: var(--text-dim);
  opacity: 0.55;
  cursor: pointer;
  border-radius: 0 12px 12px 0;
  transition: color 0.15s, opacity 0.15s, background 0.15s;
  -webkit-tap-highlight-color: transparent;
}

.sidebar__session-delete:hover,
.sidebar__session-delete:focus-visible {
  color: var(--color-recording);
  opacity: 1;
  outline: none;
}

.sidebar__session-date {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-dim);
}

.sidebar__empty {
  padding: 24px 12px;
  text-align: center;
  color: var(--text-dim);
  font-size: 13px;
}

.sidebar-backdrop {
  display: none;
}

/* Mobile: sidebar as overlay */
@media (max-width: 767px) {
  .sidebar {
    position: fixed;
    left: 0;
    top: 0;
    bottom: 0;
    z-index: 20;
    transform: translateX(-100%);
    transition: transform 0.25s ease;
    box-shadow: none;
    height: 100%;
  }

  .sidebar--open {
    transform: translateX(0);
    box-shadow: 4px 0 12px rgba(0, 0, 0, 0.1);
  }

  .sidebar-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.3);
    z-index: 19;
  }

  .status-bar {
    padding: 8px 12px;
    gap: 8px;
  }

  .status-bar__title {
    font-size: 15px;
  }
}

/* Desktop: hide mobile-only controls, adjust fixed elements */
@media (min-width: 768px) {
  .sidebar__close {
    display: none;
  }

  .status-bar__menu {
    display: none;
  }

  .scroll-to-bottom {
    left: calc(50% + 150px);
  }
}

/* Toast notification */
.toast {
  margin: 0 auto 12px;
  max-width: 340px;
  padding: 10px 16px;
  border-radius: 10px;
  background: var(--card-bg);
  border: 1px solid rgba(192, 57, 43, 0.25);
  color: var(--color-recording);
  font-size: 13px;
  font-family: var(--font-mono);
  text-align: center;
  box-shadow: var(--shadow-md);
  cursor: pointer;
  animation: toast-in 0.25s ease-out;
}

.toast--exit {
  animation: toast-out 0.25s ease-in forwards;
}

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

@keyframes toast-out {
  from { opacity: 1; transform: translateY(0); }
  to   { opacity: 0; transform: translateY(8px); }
}

/* ─── TextComposer ───────────────────────────────────────────── */
.text-composer {
  width: 100%;
  display: flex;
  align-items: flex-end;
  gap: 8px;
  padding: 8px 10px 8px 14px;
  background: var(--card-bg);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  margin-bottom: 12px;
  box-sizing: border-box;
  transition: border-color 150ms ease, opacity 150ms ease, background 150ms ease;
}
.text-composer:focus-within {
  border-color: var(--color-accent);
}

.text-composer__input {
  flex: 1;
  border: none;
  outline: none;
  resize: none;
  background: transparent;
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.4;
  padding: 6px 0;
  max-height: calc(1.4em * 5);
}
.text-composer__input::placeholder { color: var(--text-dim); }
.text-composer__input:disabled {
  color: var(--text-dim);
  cursor: not-allowed;
  -webkit-text-fill-color: var(--text-dim); /* iOS Safari override */
  opacity: 1; /* iOS Safari otherwise dims to ~0.4 */
}

.text-composer__send {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border: none;
  border-radius: 50%;
  background: var(--color-accent);
  color: var(--bg-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: opacity 150ms ease, background 150ms ease;
}
.text-composer__send:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

/* ─── Swipe direction hints (around PTT button) ──────────────── */
.swipe-hints {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 180ms ease;
}
.swipe-hints--visible { opacity: 1; }

.swipe-hint {
  position: absolute;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-dim);
  white-space: nowrap;
}
.swipe-hint--up    { bottom: 100%; left: 50%; transform: translate(-50%, -4px); }
.swipe-hint--left  { right: 100%; top: 50%;  transform: translate(-8px, -50%); }
.swipe-hint--right { left: 100%;  top: 50%;  transform: translate(8px, -50%); }

/* Active: gesture has crossed the threshold — release will fire the action.
   Bumps weight + color, plus a small scale that compounds with the existing
   translate so each hint stays anchored where it was. */
.swipe-hint {
  font-weight: 500;
  transition: color 120ms ease, font-weight 120ms ease, transform 120ms ease;
}
.swipe-hint--active { font-weight: 700; }
.swipe-hint--up.swipe-hint--active    { color: var(--color-processing); transform: translate(-50%, -4px) scale(1.18); }
.swipe-hint--left.swipe-hint--active  { color: var(--color-recording);  transform: translate(-8px, -50%) scale(1.18); }
.swipe-hint--right.swipe-hint--active { color: var(--color-playing);    transform: translate(8px, -50%) scale(1.18); }

/* --- Personas (Phase 3) --- */

/* Persona attribution at the top of an assistant bubble — WhatsApp-style.
   Shown only on the first bubble in a run from that persona. Default Vox
   (no persona) and user bubbles get no name label. Per DESIGN_SYSTEM.md
   "Labels (uppercase)": --font-mono, 10px, --text-dim, letter-spacing 1px,
   uppercase. Sits inside the bubble at the top so the bubble's own
   left-bottom corner-clip still anchors the speaker side. */
.message-bubble__persona-name {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 4px;
}

/* Bold the trigger phrase inside the user bubble that fired it */
.message-trigger {
  font-weight: 700;
}

/* PresetEditor binding rows */
.preset-editor__hint {
  font-size: 12px;
  color: var(--text-dim);
  margin-bottom: 6px;
}

/* Inline checkbox row (used by PersonaEditor's memory-enabled toggle). */
.preset-editor__label--checkbox {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}
.preset-editor__label--checkbox input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--accent-color, #5af);
}

/* Per-persona memory list inside the editor. */
.persona-memory-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 200px;
  overflow-y: auto;
}
.persona-memory-list__row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 6px;
  background: var(--surface-2, rgba(255, 255, 255, 0.04));
  font-size: 13px;
}
.persona-memory-list__content {
  flex: 1 1 auto;
  word-break: break-word;
}
.persona-memory-list__delete {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  border: none;
  border-radius: 4px;
  background: transparent;
  color: var(--text-dim);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}
.persona-memory-list__delete:hover {
  color: var(--text-color);
  background: var(--surface-3, rgba(255, 255, 255, 0.08));
}

/* Mode-pill row (Voice input / Auto-send / Active Listening). Three full-width
   pills laid out horizontally, with the active one filled. Mirrors
   docs/active-listening-brief mockup. */
.preset-editor__mode-row {
  display: flex;
  gap: 6px;
  margin-bottom: 6px;
}
.preset-editor__mode-pill {
  flex: 1 1 0;
  padding: 8px 10px;
  border-radius: 999px;
  border: 1.5px solid var(--border-color);
  background: var(--card-bg);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
}
.preset-editor__mode-pill:hover {
  border-color: var(--text-primary);
}
.preset-editor__mode-pill--on {
  background: var(--text-primary);
  border-color: var(--text-primary);
  color: var(--card-bg);
}

/* Generic small-pill row used for session timeout choices. */
.preset-editor__pill-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.preset-editor__pill {
  padding: 6px 12px;
  border-radius: 999px;
  border: 1.5px solid var(--border-color);
  background: var(--card-bg);
  color: var(--text-primary);
  font-family: var(--font-mono);
  font-size: 12px;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
}
.preset-editor__pill:hover {
  border-color: var(--text-primary);
}
.preset-editor__pill--on {
  background: var(--text-primary);
  border-color: var(--text-primary);
  color: var(--card-bg);
}
.preset-editor__binding {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 6px;
}
.preset-editor__binding-phrase {
  flex: 1 1 auto;
  min-width: 0;
}
.preset-editor__binding-persona {
  flex: 0 1 40%;
  min-width: 120px;
}
.preset-editor__binding-remove {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border: 1px solid var(--border-color);
  background: transparent;
  color: var(--text-dim);
  font-size: 18px;
  cursor: pointer;
  border-radius: 4px;
}
.preset-editor__binding-remove:hover {
  color: inherit;
  border-color: var(--text-dim);
}
.preset-editor__binding-add {
  margin-top: 4px;
  padding: 6px 10px;
  font-size: 13px;
  background: transparent;
  border: 1px dashed var(--border-color);
  color: var(--text-dim);
  cursor: pointer;
  border-radius: 4px;
}
.preset-editor__binding-add:hover {
  color: inherit;
  border-color: var(--text-dim);
}

/* Personas screen — uses the shared app-layout shell. The body below the
   StatusBar is a single padded scroll area holding a list of List Items
   per DESIGN_SYSTEM.md §Components.9. */
.screen-pad {
  padding: 20px;
  max-width: 640px;
  margin: 0 auto;
  width: 100%;
  box-sizing: border-box;
}
.screen-empty {
  color: var(--text-dim);
  font-family: var(--font-body);
  font-size: 14px;
  text-align: center;
  padding: 32px 8px;
}

.personas-list {
  display: flex;
  flex-direction: column;
  gap: 6px;  /* List Item composition: 4-6px gap between items */
}

/* Pill Button — ghost (dashed) variant per DESIGN_SYSTEM.md §1 */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 11px 22px;
  border-radius: 50px;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
  background: var(--card-bg);
  color: var(--text-primary);
  border: 1.5px solid var(--border-color);
  box-shadow: var(--shadow-sm);
}
.pill--ghost {
  background: transparent;
  color: var(--text-dim);
  border: 2px dashed var(--border-color);
  box-shadow: none;
}
.pill--ghost:hover {
  color: var(--text-primary);
  border-color: var(--text-secondary);
}

/* List Item — DESIGN_SYSTEM.md §Components.9 */
.list-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 14px;
  border-radius: 12px;
  border: 1.5px solid var(--border-color);
  background: var(--card-bg);
  color: var(--text-primary);
  text-align: left;
  cursor: pointer;
  font-family: var(--font-body);
  width: 100%;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.list-item:hover {
  border-color: var(--text-dim);
  background: rgba(26, 24, 21, 0.02);
}
.list-item__main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1 1 auto;
}
.list-item__label {
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  color: var(--text-primary);
}
.list-item__desc {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-dim);
}
