/* Vortex Webapp — Control Panel Styles */

/* ---------------------------------------------------------------------------
   Theme variables — defaults match browser dark mode
   Teams mode overrides via .teams-dark / .teams-light on <body>
   --------------------------------------------------------------------------- */
:root {
  --bg-page: #0A0A0A;
  --bg-card: #1A1A1A;
  --bg-input: #111111;
  --bg-caption: #111111;
  --border-card: #262626;
  --border-input: #262626;
  --card-shadow: none;
  --input-shadow: none;
  --text-primary: #e5e5e5;
  --text-secondary: #a3a3a3;
  --text-tertiary: #737373;
  --text-hint: #525252;
  --accent: #ED1C24;
  --accent-hover: #DC2626;
  --accent-rgb: 237, 28, 36;
  --success: #10b981;
  --success-rgb: 16, 185, 129;
  --danger: #ef4444;
  --danger-rgb: 239, 68, 68;
}

.teams-dark {
  --bg-page: #1f1f1f;
  --bg-card: #292929;
  --bg-input: #1f1f1f;
  --bg-caption: #1f1f1f;
  --border-card: #3d3d3d;
  --border-input: #3d3d3d;
  --card-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  --input-shadow: none;
  --text-primary: #e5e5e5;
  --text-secondary: #adadad;
  --text-tertiary: #737373;
  --text-hint: #616161;
  --accent: #7B83EB;
  --accent-hover: #9299F7;
  --accent-rgb: 123, 131, 235;
  --success: #54B054;
  --success-rgb: 84, 176, 84;
  --danger: #DC626D;
  --danger-rgb: 220, 98, 109;
}

.teams-light {
  --bg-page: #ffffff;
  --bg-card: #f5f5f5;
  --bg-input: #ffffff;
  --bg-caption: #ffffff;
  --border-card: transparent;
  --border-input: #d1d1d1;
  --card-shadow: 0 2px 12px rgba(0, 0, 0, 0.08), 0 0 0 1px rgba(0, 0, 0, 0.04);
  --input-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.06);
  --text-primary: #242424;
  --text-secondary: #616161;
  --text-tertiary: #999999;
  --text-hint: #adadad;
  --accent: #5B5FC7;
  --accent-hover: #4F52B2;
  --accent-rgb: 91, 95, 199;
  --success: #107C10;
  --success-rgb: 16, 124, 16;
  --danger: #D13438;
  --danger-rgb: 209, 52, 56;
}

/* Base */
body {
  font-family: 'Segoe UI', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  background: var(--bg-page);
  color: var(--text-primary);
}

/* Language detect toggle switch */
.lang-detect-switch {
  position: relative;
  width: 36px;
  height: 20px;
}
.lang-detect-switch input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.lang-detect-track {
  width: 36px;
  height: 20px;
  border-radius: 9999px;
  background: var(--border-card);
  transition: background 0.2s;
}
.lang-detect-thumb {
  position: absolute;
  left: 2px;
  top: 2px;
  width: 16px;
  height: 16px;
  border-radius: 9999px;
  background: white;
  box-shadow: 0 1px 3px rgba(0,0,0,0.3);
  transition: transform 0.2s;
}
.lang-detect-switch input:checked + .lang-detect-track {
  background: var(--accent);
}
.lang-detect-switch input:checked + .lang-detect-track + .lang-detect-thumb {
  transform: translateX(16px);
}

/* Input field */
.input-field {
  width: 100%;
  padding: 0.6rem 0.75rem;
  background-color: var(--bg-input);
  border: 1px solid var(--border-input);
  border-radius: 0.5rem;
  font-size: 0.8rem;
  color: var(--text-primary);
  outline: none;
  box-shadow: var(--input-shadow);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.input-field::placeholder { color: var(--text-hint); }
.input-field:focus {
  border-color: rgba(var(--accent-rgb), 0.5);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.12);
}

/* Cards */
.card {
  background: var(--bg-card);
  border: 1px solid var(--border-card);
  border-radius: 8px;
  padding: 0.6rem 0.65rem;
  box-shadow: var(--card-shadow);
}

/* Advanced (optional) collapsible on the start form — keeps the optional CART
   field out of the way until needed. */
.advanced-options { border: 1px solid var(--border-card); border-radius: 8px; padding: 0.4rem 0.55rem; }
.advanced-summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--text-secondary);
  user-select: none;
}
.advanced-summary::-webkit-details-marker { display: none; }
.advanced-chevron { transition: transform 0.2s ease; opacity: 0.7; flex-shrink: 0; }
.advanced-options[open] .advanced-chevron { transform: rotate(90deg); }

/* ---------------------------------------------------------------------------
   Live session view — viewport-locked layout so ONLY the caption feed scrolls.
   Without this the whole panel grew past the viewport and produced a second,
   outer scrollbar; scrolling it pushed the Stop button + glossary card off the
   top. We lock the page to the viewport height and let the feed absorb the
   remaining space (see .utterance-feed). Applied only while the session view is
   active (body.session-active) so the start form and transcript panel keep their
   normal, naturally-scrolling document flow.
   --------------------------------------------------------------------------- */
body.session-active {
  height: 100dvh;
  overflow: hidden;               /* no outer page scroll — feed scrolls instead */
  display: flex;
  flex-direction: column;
}
/* The browser-mode header (hidden in Teams) stays a fixed-height row so `main`
   gets the remaining height. */
body.session-active > header { flex: 0 0 auto; }
body.session-active > main {
  flex: 1 1 auto;
  min-height: 0;                  /* allow the column to shrink so children scroll */
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
/* The visible session section fills the remaining height and lays its children
   (status row + Stop, glossary card, feed) out as a column; only the feed grows
   and scrolls. */
body.session-active > main > #session-section {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
/* The status/Stop row and glossary card stay fixed-height at the top. */
body.session-active > main > #session-section > .glossary-card,
body.session-active > main > #session-section > div:first-child {
  flex: 0 0 auto;
}

/* ---------------------------------------------------------------------------
   Session info bar
   --------------------------------------------------------------------------- */
.session-info-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1rem;
  align-items: center;
  padding: 0.6rem 0.75rem;
  background: var(--bg-input);
  border: 1px solid var(--border-card);
  border-radius: 8px;
  margin-bottom: 0.75rem;
}

.info-chip {
  display: flex;
  align-items: center;
  gap: 0.35rem;
}

.info-chip-label {
  font-size: 0.6rem;
  color: var(--text-hint);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 600;
}

.info-chip-value {
  font-size: 0.72rem;
  color: var(--text-secondary);
  font-weight: 500;
}

.info-chip-sep {
  color: var(--border-card);
  font-size: 0.9rem;
  line-height: 1;
  user-select: none;
}

/* ---------------------------------------------------------------------------
   Utterance feed + cards
   --------------------------------------------------------------------------- */
.utterance-feed {
  /* The feed is the ONLY scrolling region of the live session view. Its parent
     (#session-section) is a viewport-height flex column, so the feed simply
     takes whatever vertical space is left after the (fixed) status row + Stop
     button + glossary card, and scrolls internally. flex:1 + min-height:0 is the
     robust way to let a flex child shrink and scroll instead of pushing the page
     taller (which previously produced a second, outer scrollbar that hid the
     Stop button). A max-height fallback keeps it sane if the flex context is
     ever absent (e.g. an unexpected layout state). */
  flex: 1 1 auto;
  min-height: 0;
  max-height: calc(100dvh - 5rem);
  overflow-y: auto;
  padding-right: 2px;
  /* Bottom cushion so the auto-scroll lands the last card well above the bottom
     edge (more breathing room, easier to read the newest line). The padding is
     part of the scrollable area, so scrollTop=scrollHeight leaves this much empty
     space below the final card. */
  padding-bottom: 2.5rem;
  scroll-padding-bottom: 2.5rem;
  /* Disable browser-native scroll anchoring — without this the browser
     automatically scrolls the feed to the bottom whenever new cards are
     appended, even when the user has manually scrolled up to read history.
     Scroll behaviour is controlled exclusively by scrollFeedToBottom() in
     app.js, which checks the user's position first. */
  overflow-anchor: none;
}

.utterance-feed::-webkit-scrollbar {
  width: 4px;
}
.utterance-feed::-webkit-scrollbar-track {
  background: transparent;
}
.utterance-feed::-webkit-scrollbar-thumb {
  background: var(--border-card);
  border-radius: 9999px;
}

/* Empty state */
.feed-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 2.5rem 1rem;
  text-align: center;
  gap: 0.5rem;
}

.feed-placeholder-icon {
  width: 3rem;
  height: 3rem;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(var(--accent-rgb), 0.06);
  border: 1px solid rgba(var(--accent-rgb), 0.12);
  margin-bottom: 0.25rem;
}

.feed-placeholder-text {
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--text-tertiary);
}

.feed-placeholder-hint {
  font-size: 0.7rem;
  color: var(--text-hint);
  max-width: 22rem;
  line-height: 1.5;
}

/* Utterance card */
.utterance-card {
  border: 1px solid var(--border-card);
  border-radius: 8px;
  padding: 0.4rem 0.6rem;
  background: var(--bg-input);
  margin-bottom: 0.3rem;
  transition: border-color 0.25s, box-shadow 0.25s;
  animation: slide-up 0.18s ease;
}

.utterance-card[data-state="live"] {
  border-color: rgba(var(--accent-rgb), 0.55);
  box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.12);
  animation: slide-up 0.18s ease, live-pulse 2s ease-in-out infinite;
}

.utterance-card[data-state="partial"] {
  border-color: rgba(var(--accent-rgb), 0.35);
  box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.08);
}

.utterance-card[data-state="complete"] {
  border-color: var(--border-card);
  box-shadow: none;
}

/* Card header */
.utterance-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.3rem;
}

.utterance-meta-left {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.speaker-name {
  font-size: 0.62rem;
  font-weight: 600;
  color: var(--text-secondary);
}

.lang-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--accent);
  background: rgba(var(--accent-rgb), 0.1);
  border: 1px solid rgba(var(--accent-rgb), 0.2);
  padding: 0.1rem 0.45rem;
  border-radius: 9999px;
}

.live-dot {
  display: inline-block;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
  animation: pulse-dot 1s ease-in-out infinite;
  flex-shrink: 0;
}

.utterance-time {
  font-size: 0.62rem;
  color: var(--text-hint);
  font-variant-numeric: tabular-nums;
}

/* Original text block — dimmer, smaller; no explicit label needed */
.utterance-original {
  margin-bottom: 0.25rem;
}

.original-text {
  font-size: 0.75rem;
  color: var(--text-secondary);
  line-height: 1.45;
  word-break: break-word;
}

/* Translation block — brighter, slightly larger; visually dominant */
.utterance-translation {
  border-top: 1px solid var(--border-card);
  padding-top: 0.25rem;
  margin-top: 0.25rem;
}

/* Per-language translation slot: one clean line per translation. The per-language
   badge is intentionally hidden (see .lang-badge-sm below) — the card header
   already shows the full "SRC → TGT1 · TGT2" set and a reader of a given language
   recognises it on sight — so the translated text uses the full row width.
   Consecutive slots get a light divider instead of the block border. */
.utterance-translation[data-lang] {
  display: flex;
  align-items: baseline;
  gap: 0;
  padding-top: 0.25rem;
  margin-top: 0.25rem;
  border-top: 1px solid var(--border-card);
}
/* Only the FIRST language slot carries the separator from the original block;
   subsequent slots sit tight under it as rows. */
.utterance-translation[data-lang] + .utterance-translation[data-lang] {
  border-top: none;
  padding-top: 0.1rem;
  margin-top: 0.1rem;
}
/* Redundant per-language badge — hidden in all cases (see comment above). */
.utterance-translation[data-lang] > .lang-badge-sm {
  display: none;
}
/* The body (text / hint / error / spinner) takes the full width of the row. */
.utterance-translation[data-lang] > .translation-text,
.utterance-translation[data-lang] > .translation-hint,
.utterance-translation[data-lang] > .translation-error,
.utterance-translation[data-lang] > .translation-pending {
  flex: 1 1 auto;
  min-width: 0;
}

/* Smaller badge used inside per-language slots so it reads as a label, not a
   duplicate of the card's source→targets header badge. Pill-styled to match the
   transcript lang tag for visual consistency across the two views. */
.lang-badge-sm {
  font-size: 0.55rem;
  padding: 0.05rem 0.35rem;
  letter-spacing: 0.06em;
  line-height: 1.6;
}

.translation-text {
  font-size: 0.85rem;
  color: var(--text-primary);
  font-weight: 500;
  line-height: 1.5;
  word-break: break-word;
}

.translation-hint {
  font-size: 0.72rem;
  color: var(--text-hint);
  font-style: italic;
  line-height: 1.4;
  word-break: break-word;
}

/* Card-level status note — shown when an utterance has no translation slots
   (unsupported source language, no configured target, etc.). Neutral/dim by
   default so it reads as an explanation, not a failure; .is-error tints it red
   for genuine failures (all-failed). Separated from the original text with the
   same light divider used by translation rows. */
.utterance-status-note {
  border-top: 1px solid var(--border-card);
  padding-top: 0.25rem;
  margin-top: 0.25rem;
  font-size: 0.72rem;
  font-style: italic;
  color: var(--text-hint);
  line-height: 1.4;
  word-break: break-word;
}
.utterance-status-note.is-error {
  color: #f87171; /* red-400 — matches .translation-error */
  font-style: normal;
}

.translation-pending {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--text-hint);
  font-size: 0.72rem;
  font-style: italic;
}

/* Diagnostic error messages in the translation slot — visible during testing */
.translation-error {
  font-size: 0.72rem;
  color: #f87171; /* red-400 */
  font-style: italic;
  line-height: 1.5;
  word-break: break-word;
}

.translation-spinner {
  display: inline-block;
  width: 10px;
  height: 10px;
  border: 1.5px solid rgba(var(--accent-rgb), 0.25);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  flex-shrink: 0;
}

/* System/error messages in the feed */
.system-message {
  padding: 0.4rem 0.6rem;
  border-radius: 6px;
  font-size: 0.72rem;
  margin-bottom: 0.4rem;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.system-message.state {
  background: rgba(var(--success-rgb), 0.06);
  color: var(--text-tertiary);
  border: 1px solid rgba(var(--success-rgb), 0.15);
}

.system-message.error {
  background: rgba(var(--danger-rgb), 0.08);
  color: var(--danger);
  border: 1px solid rgba(var(--danger-rgb), 0.2);
}

.system-message.cart {
  background: rgba(123, 131, 235, 0.06);
  color: var(--text-hint);
  border: 1px solid rgba(123, 131, 235, 0.15);
  font-size: 0.65rem;
}

/* ---------------------------------------------------------------------------
   Session status badges
   --------------------------------------------------------------------------- */
.badge-running {
  display: inline-flex; align-items: center; gap: 0.25rem;
  padding: 0.125rem 0.5rem;
  background: rgba(var(--success-rgb), 0.1);
  border: 1px solid rgba(var(--success-rgb), 0.3);
  border-radius: 9999px;
  font-size: 0.65rem; font-weight: 600;
  color: var(--success);
  text-transform: uppercase; letter-spacing: 0.05em;
}
.badge-running::before {
  content: '';
  width: 6px; height: 6px;
  background: var(--success);
  border-radius: 50%;
  animation: pulse-dot 1.5s ease-in-out infinite;
}
.badge-succeeded {
  display: inline-flex; align-items: center; gap: 0.25rem;
  padding: 0.125rem 0.5rem;
  background: rgba(82, 82, 82, 0.2);
  border: 1px solid var(--border-card);
  border-radius: 9999px;
  font-size: 0.65rem; font-weight: 600;
  color: var(--text-tertiary);
  text-transform: uppercase; letter-spacing: 0.05em;
}
.badge-failed {
  display: inline-flex; align-items: center; gap: 0.25rem;
  padding: 0.125rem 0.5rem;
  background: rgba(var(--danger-rgb), 0.1);
  border: 1px solid rgba(var(--danger-rgb), 0.3);
  border-radius: 9999px;
  font-size: 0.65rem; font-weight: 600;
  color: var(--danger);
  text-transform: uppercase; letter-spacing: 0.05em;
}

/* ---------------------------------------------------------------------------
   Corrector status dot
   --------------------------------------------------------------------------- */
.dot-online  { background: var(--success); box-shadow: 0 0 6px rgba(var(--success-rgb), 0.4); }
.dot-offline { background: var(--danger); }
.dot-unknown { background: var(--text-hint); }

/* ---------------------------------------------------------------------------
   Animations
   --------------------------------------------------------------------------- */
@keyframes pulse-dot {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

@keyframes spin { to { transform: rotate(360deg); } }

@keyframes slide-up {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Subtle border glow that pulses while a card is in live-streaming state */
@keyframes live-pulse {
  0%, 100% { box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.12); }
  50%       { box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.22); }
}

/* Listening spinner — slower, dimmer than the Translating spinner */
.live-spinner {
  border-color: rgba(var(--accent-rgb), 0.15);
  border-top-color: rgba(var(--accent-rgb), 0.5);
  animation: spin 1.4s linear infinite;
}

/* ---------------------------------------------------------------------------
   Spinner
   --------------------------------------------------------------------------- */
.spinner {
  width: 14px; height: 14px;
  border: 2px solid rgba(var(--accent-rgb), 0.2);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  display: inline-block;
  flex-shrink: 0;
}

.spinner-sm {
  width: 10px; height: 10px;
  border: 1.5px solid rgba(var(--accent-rgb), 0.2);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  display: inline-block;
  flex-shrink: 0;
}

/* ---------------------------------------------------------------------------
   Buttons
   --------------------------------------------------------------------------- */
.btn-accent {
  background: var(--accent);
  color: #ffffff;
  box-shadow: 0 1px 3px rgba(var(--accent-rgb), 0.3);
}
.btn-accent:hover {
  background: var(--accent-hover);
  box-shadow: 0 2px 6px rgba(var(--accent-rgb), 0.35);
}
.btn-accent:disabled { opacity: 0.5; cursor: not-allowed; box-shadow: none; }

.btn-danger-outline {
  color: var(--danger);
  background: transparent;
  border: 1px solid rgba(var(--danger-rgb), 0.3);
  border-radius: 8px;
}
.btn-danger-outline:hover {
  background: rgba(var(--danger-rgb), 0.08);
  border-color: rgba(var(--danger-rgb), 0.5);
}

/* ---------------------------------------------------------------------------
   Session row (sessions list)
   --------------------------------------------------------------------------- */
.session-row {
  padding: 0.75rem;
  background: var(--bg-input);
  border: 1px solid var(--border-card);
  border-radius: 8px;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
}
.session-row + .session-row { margin-top: 0.5rem; }

/* ---------------------------------------------------------------------------
   Hint text (hidden in Teams mode via JS)
   --------------------------------------------------------------------------- */
.field-hint {
  font-size: 0.65rem;
  color: var(--text-hint);
  margin-top: 0.25rem;
}

/* ---------------------------------------------------------------------------
   Text helpers
   --------------------------------------------------------------------------- */
.text-primary { color: var(--text-primary); }
.text-secondary { color: var(--text-secondary); }
.text-tertiary { color: var(--text-tertiary); }
.text-hint { color: var(--text-hint); }
.text-accent { color: var(--accent); }
.text-success { color: var(--success); }
.text-danger { color: var(--danger); }

/* ---------------------------------------------------------------------------
   Teams mode — hide elements not needed in the side panel
   --------------------------------------------------------------------------- */
.teams-mode .hide-in-teams { display: none !important; }

/* Active Sessions list retired — broad session enumeration was removed to
   prevent cross-meeting disclosure, so this panel has no data to show. The
   element stays in the DOM (app.js toggles its .hidden class and references it
   by id) but is never displayed, in browser or Teams. */
#sessions-section { display: none !important; }

/* ---------------------------------------------------------------------------
   Transcript review section
   --------------------------------------------------------------------------- */

/* Card header row */
.transcript-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-bottom: 0.75rem;
}

/* Download button row */
.transcript-download-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding: 0.5rem 0.65rem;
  background: var(--bg-input);
  border: 1px solid var(--border-card);
  border-radius: 8px;
  margin-bottom: 0.75rem;
}

.transcript-dl-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.7rem;
  font-weight: 600;
  padding: 0.3rem 0.65rem;
  border-radius: 6px;
  border: 1px solid rgba(var(--accent-rgb), 0.3);
  color: var(--accent);
  background: rgba(var(--accent-rgb), 0.06);
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.transcript-dl-btn:hover {
  background: rgba(var(--accent-rgb), 0.14);
  border-color: rgba(var(--accent-rgb), 0.55);
}

/* Scrollable transcript feed */
.transcript-feed {
  max-height: 34rem;
  overflow-y: auto;
  scroll-behavior: smooth;
  padding-right: 2px;
  margin-bottom: 0.75rem;
}
.transcript-feed::-webkit-scrollbar { width: 4px; }
.transcript-feed::-webkit-scrollbar-track { background: transparent; }
.transcript-feed::-webkit-scrollbar-thumb {
  background: var(--border-card);
  border-radius: 9999px;
}

/* Speaker block — groups all utterances from one contiguous speaker turn */
.transcript-speaker-block {
  margin-bottom: 0.75rem;
}

/* Speaker name + timestamp header */
.transcript-speaker-header {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin-bottom: 0.35rem;
  padding-bottom: 0.25rem;
  border-bottom: 1px solid var(--border-card);
}

.transcript-speaker-name {
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--text-secondary);
}

.transcript-speaker-time {
  font-size: 0.62rem;
  color: var(--text-hint);
  font-variant-numeric: tabular-nums;
}

/* Individual utterance within a speaker block */
.transcript-utterance {
  padding: 0.4rem 0 0.4rem 0.6rem;
  border-left: 2px solid var(--border-card);
  margin-bottom: 0.3rem;
}
.transcript-utterance:last-child { margin-bottom: 0; }

/* One line in the utterance (original or translation) */
.transcript-line {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
  line-height: 1.55;
}
.transcript-line + .transcript-line {
  margin-top: 0.2rem;
}

.transcript-lang-tag {
  flex-shrink: 0;
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--accent);
  background: rgba(var(--accent-rgb), 0.1);
  border: 1px solid rgba(var(--accent-rgb), 0.2);
  padding: 0.05rem 0.35rem;
  border-radius: 9999px;
  line-height: 1.6;
}

.transcript-line.original .transcript-line-text {
  font-size: 0.8rem;
  color: var(--text-secondary);
  word-break: break-word;
}

.transcript-line.translation .transcript-line-text {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text-primary);
  word-break: break-word;
}

/* Diagnostic error reason shown when translation failed — visible during testing */
.transcript-line.translation-error .transcript-line-text {
  font-size: 0.75rem;
  font-style: italic;
  color: #f87171; /* red-400 — matches .translation-error in live feed */
  word-break: break-word;
}



/* ---------------------------------------------------------------------------
   Teams side panel — narrow viewport adjustments
   --------------------------------------------------------------------------- */
@media (max-width: 400px) {
  main { padding: 0.25rem !important; }
  main > .card { padding: 0.5rem 0.55rem; }
  .input-field { font-size: 0.75rem; }
  .session-row { padding: 0.4rem; }
  .utterance-feed { max-height: calc(100dvh - 5rem); }
  .info-chip-sep { display: none; }
  .grid-cols-2 { grid-template-columns: 1fr !important; }

  /* Transcript — side panel adjustments */
  .transcript-feed { max-height: calc(100dvh - 10rem); }
  .transcript-download-row { gap: 0.3rem; padding: 0.35rem 0.5rem; }
  .transcript-dl-btn { font-size: 0.65rem; padding: 0.2rem 0.45rem; }
  .transcript-speaker-name { font-size: 0.68rem; }
  .transcript-line.original .transcript-line-text { font-size: 0.75rem; }
  .transcript-line.translation .transcript-line-text { font-size: 0.8rem; }
}

/* ---------------------------------------------------------------------------
   Glossary add-term — card style (collapsible)
   --------------------------------------------------------------------------- */
.glossary-card {
  border-radius: 0.7rem;
  /* Match the post-meeting feedback panel's soft accent-tinted look, but the
     surface MUST be OPAQUE: this card is sticky and floats over the caption feed
     while the panel scrolls, so a translucent tint let cards show through behind
     it. Layer the accent tint over the solid page background so it's the same
     colour AND fully occludes whatever scrolls underneath. */
  border: 1px solid rgba(var(--accent-rgb), 0.18);
  background:
    linear-gradient(rgba(var(--accent-rgb), 0.05), rgba(var(--accent-rgb), 0.05)),
    var(--bg-page);
  overflow: hidden;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
  /* Keep the glossary entry pinned at the top of the session panel so the user
     can add a term at any time while the caption feed below scrolls underneath.
     A small negative-margin/padding trick isn't needed — the opaque background
     + z-index ensures cards never bleed through. */
  position: sticky;
  top: 0;
  z-index: 20;
}
.glossary-card:hover { border-color: rgba(var(--accent-rgb), 0.28); }

/* One-row entry: [ Term ][ Full form ........ ][+]. Stays on ONE line and
   resizes with the panel — the term is short (a few chars), the full form takes
   the remaining width, and the submit is a compact square icon button so it
   costs almost no horizontal space. Never wraps: nowrap keeps it a single row. */
.glossary-row {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: nowrap;
}
.glossary-row .glossary-term-input {
  flex: 0 1 5.5rem;   /* short — most terms are 5-6 chars; shrinks if needed */
  min-width: 3.5rem;
  width: auto;
}
.glossary-row .glossary-longform-input {
  flex: 1 1 auto;     /* takes all remaining width, shrinks with the panel */
  min-width: 3.5rem;
  width: auto;
}
/* Compact square icon submit — hugs a fixed small footprint regardless of panel width. */
.glossary-row .glossary-submit-icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border-radius: 0.45rem;
}
.glossary-row .glossary-submit-icon svg { width: 1rem; height: 1rem; }

/* Card header — the full-width clickable collapse/expand bar. */
.glossary-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 0.6rem 0.75rem;
  background: rgba(var(--accent-rgb), 0.06);
  border: none;
  cursor: pointer;
  transition: background 0.15s ease;
}
.glossary-card-header:hover { background: rgba(var(--accent-rgb), 0.11); }
.glossary-card-title {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--accent);
}
.glossary-chevron { transition: transform 0.2s ease; opacity: 0.7; flex-shrink: 0; }
.glossary-card-header[aria-expanded="true"] .glossary-chevron { transform: rotate(180deg); }
.glossary-card.is-collapsed { }

/* Card body — the actual form. Slightly tighter bottom padding so the compact
   one-row form doesn't leave a tall gap above the caption feed. */
.glossary-card-body {
  padding: 0.75rem 0.75rem 0.6rem;
  animation: glossary-slide 0.18s ease;
}
@keyframes glossary-slide {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.glossary-panel-hint {
  font-size: 0.68rem;
  color: var(--text-secondary);
  margin-bottom: 0.6rem;
  line-height: 1.4;
}
.glossary-field { margin-bottom: 0.5rem; }
.glossary-label {
  display: block;
  font-size: 0.65rem;
  font-weight: 600;
  color: var(--text-secondary);
  margin-bottom: 0.2rem;
  letter-spacing: 0.01em;
}
.glossary-req { color: var(--accent); }
.glossary-optional {
  font-weight: 400;
  font-size: 0.6rem;
  color: var(--text-hint);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-left: 0.15rem;
}
/* Inputs match the app's .input-field convention: --bg-input surface,
   --border-input, and the same accent focus ring. */
.glossary-input {
  width: 100%;
  font-size: 0.75rem;
  padding: 0.45rem 0.6rem;
  border-radius: 0.45rem;
  background: var(--bg-input);
  border: 1px solid var(--border-input);
  color: var(--text-primary);
  box-shadow: var(--input-shadow);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.glossary-input::placeholder { color: var(--text-hint); }
.glossary-input:focus {
  outline: none;
  border-color: rgba(var(--accent-rgb), 0.5);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.12);
}
.glossary-actions {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: 0.7rem;
}
.glossary-submit {
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.4rem 0.9rem;
  border-radius: 0.45rem;
}
/* Status line: only occupies vertical space when it actually has a message.
   Empty (the normal idle state) collapses to nothing so there's no dead gap at
   the bottom of the form before the caption feed. */
.glossary-status { font-size: 0.68rem; line-height: 1.3; display: block; margin-top: 0.4rem; }
.glossary-status:empty { display: none; margin: 0; }
.glossary-details-wrap { margin-top: 0.4rem; }

/* "Add description" sub-toggle inside the glossary card. Minimal bottom margin —
   the details panel (when open) supplies its own spacing. */
.glossary-details-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin: 0.15rem 0 0;
  padding: 0.15rem 0;
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--accent);
  background: none;
  border: none;
  cursor: pointer;
}
.glossary-details-toggle:hover { text-decoration: underline; }
.glossary-details-toggle[aria-expanded="true"] .glossary-chevron { transform: rotate(180deg); }
#glossary-details-panel { animation: glossary-slide 0.15s ease; }

/* ---------------------------------------------------------------------------
   Target-language ("Translate into") — modern pill/chip selection
   --------------------------------------------------------------------------- */
.target-lang-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.target-lang-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.3rem 0.7rem;
  border-radius: 9999px;
  border: 1px solid var(--border-card);
  background: var(--bg-card);
  color: var(--text-secondary);
  font-size: 0.72rem;
  font-weight: 500;
  cursor: pointer;
  user-select: none;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.target-lang-pill:hover { border-color: rgba(var(--accent-rgb), 0.45); }
/* Hide the native checkbox — the pill itself is the control. */
.target-lang-cb {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  pointer-events: none;
}
/* The checkmark is collapsed (zero width) until selected, then slides in. */
.target-lang-check {
  width: 0;
  height: 0.85rem;
  flex-shrink: 0;
  opacity: 0;
  color: #fff;
  transition: width 0.15s ease, opacity 0.15s ease;
}
.target-lang-name { white-space: nowrap; }

/* Selected state — filled accent pill with visible checkmark. */
.target-lang-pill:has(.target-lang-cb:checked) {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.target-lang-pill:has(.target-lang-cb:checked) .target-lang-check {
  width: 0.85rem;
  opacity: 1;
}
/* Keyboard focus ring for accessibility. */
.target-lang-pill:has(.target-lang-cb:focus-visible) {
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.25);
}
/* Disabled (source in manual mode) — dimmed, not clickable. */
.target-lang-pill.is-disabled {
  opacity: 0.35;
  cursor: not-allowed;
  pointer-events: none;
}

/* ---------------------------------------------------------------------------
   Post-meeting feedback panel
   --------------------------------------------------------------------------- */
.feedback-panel {
  padding: 0.85rem;
  border-radius: 0.6rem;
  background: rgba(var(--accent-rgb), 0.05);
  border: 1px solid rgba(var(--accent-rgb), 0.18);
}
.feedback-title {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 0.5rem;
}
.feedback-stars {
  display: flex;
  align-items: center;
  gap: 0.15rem;
  margin-bottom: 0.6rem;
}
.feedback-star {
  font-size: 1.4rem;
  line-height: 1;
  color: var(--text-hint);
  cursor: pointer;
  transition: color 0.12s ease, transform 0.12s ease;
  background: none;
  border: none;
  padding: 0 0.05rem;
}
.feedback-star:hover { transform: scale(1.15); }
.feedback-star.is-active { color: #f5a623; }
.feedback-rating-label {
  font-size: 0.68rem;
  color: var(--text-secondary);
  margin-left: 0.5rem;
  min-width: 4rem;
}
.feedback-comment {
  width: 100%;
  font-size: 0.75rem;
  padding: 0.45rem 0.6rem;
  border-radius: 0.45rem;
  background: var(--bg-input);
  border: 1px solid var(--border-input);
  color: var(--text-primary);
  box-shadow: var(--input-shadow);
  resize: vertical;
  margin-bottom: 0.6rem;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.feedback-comment::placeholder { color: var(--text-hint); }
.feedback-comment:focus {
  outline: none;
  border-color: rgba(var(--accent-rgb), 0.5);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.12);
}
.feedback-actions { display: flex; align-items: center; gap: 0.6rem; }
.feedback-submit { font-size: 0.72rem; font-weight: 600; padding: 0.4rem 1rem; border-radius: 0.45rem; }
.feedback-skip {
  font-size: 0.7rem;
  color: var(--text-hint);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.35rem 0.4rem;
}
.feedback-skip:hover { color: var(--text-secondary); }
.feedback-status { font-size: 0.68rem; line-height: 1.3; }
.feedback-thanks {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--success);
}
.feedback-thanks .feedback-another {
  margin-left: auto;
  font-size: 0.68rem;
  font-weight: 500;
  color: var(--accent);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.25rem 0.4rem;
}
.feedback-thanks .feedback-another:hover { text-decoration: underline; }
