/* ── Relay Stream — Additional styles ──────────────────────── */

/* When the canvas pipeline owns the preview, the source <video> must
   stay in the render tree so the browser keeps decoding frames; if we
   hide it with display:none (Tailwind .hidden), Android Chrome (and
   sometimes iOS Safari) pause decoding and drawImage(video, ...) only
   produces black frames. Keep it laid out off-screen instead. */
#preview-video.preview-source {
  display: block !important;
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  opacity: 0 !important;
  pointer-events: none !important;
  top: 0;
  left: 0;
}

/* ── Private-message UI (dashboard chat) ──────────────────── */
.dash-pm-chip {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; padding: 4px 8px; margin-bottom: 6px;
  background: rgba(99, 102, 241, 0.18);
  border: 1px solid rgba(99, 102, 241, 0.5);
  border-radius: 6px;
  font-size: 11px; color: #c7d2fe;
}
.dash-pm-chip-label strong { color: #fff; }
.dash-pm-chip-close {
  background: transparent; border: none; color: #c7d2fe;
  font-size: 16px; line-height: 1; cursor: pointer; padding: 0 4px;
}
.dash-pm-chip-close:hover { color: #fff; }

.user-list-item {
  cursor: pointer;
  border-radius: 4px;
  transition: background 0.1s;
}
.user-list-item:hover { background: rgba(99, 102, 241, 0.15); }
.user-list-item.selected {
  background: rgba(99, 102, 241, 0.3);
  outline: 1px solid rgba(99, 102, 241, 0.6);
}

/* ── Mobile safe-area (notch, dynamic address bar) ─────────── */
#screen-dashboard > div:first-child {
  padding-top: env(safe-area-inset-top, 0px);
}
#screen-streaming {
  padding-top: env(safe-area-inset-top, 0px);
}

/* Smooth screen transitions */
.screen {
  transition: opacity 0.2s ease;
}

/* Chat message bubbles */
.chat-msg {
  padding: 0.5rem 0.75rem;
  border-radius: 0.5rem;
  max-width: 85%;
  word-break: break-word;
}
.chat-msg-incoming {
  background: #1e293b;
  align-self: flex-start;
}
.chat-msg-outgoing {
  background: #4f46e5;
  align-self: flex-end;
  margin-left: auto;
}
.chat-msg-system {
  background: #064e3b;
  align-self: center;
  text-align: center;
  font-size: 0.75rem;
  opacity: 0.8;
}

/* Platform card */
.platform-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  background: #1e293b;
  border: 1px solid #334155;
  border-radius: 0.5rem;
}

/* Pulsing live indicator */
@keyframes livePulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}
.animate-pulse {
  animation: livePulse 1.5s ease-in-out infinite;
}

/* Remove default focus rings on mobile */
input:focus, button:focus, select:focus {
  outline: none;
  box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.5);
}

/* Dashboard chat tabs */
.dash-tab {
  flex: 1;
  padding: 6px 0;
  cursor: pointer;
  text-align: center;
  color: #94a3b8;
  border-bottom: 2px solid transparent;
  background: none;
  border-top: none;
  border-left: none;
  border-right: none;
  font-size: 0.75rem;
  transition: color 0.15s, border-color 0.15s;
}
.dash-tab:hover {
  color: #cbd5e1;
}
.dash-tab.active {
  color: #fff;
  border-bottom-color: #6366f1;
}

/* Platform identification icons (favicons) */
.platform-icon {
  display: inline-block;
  width: 14px;
  height: 14px;
  margin-right: 3px;
  vertical-align: middle;
  flex-shrink: 0;
  border-radius: 2px;
  object-fit: contain;
}

/* Chat emoticons/GIFs inline */
.chat-emoticon {
  display: inline-block;
  vertical-align: middle;
  max-height: 60px;
  border-radius: 4px;
  margin: 1px 2px;
}

/* User list items */
.user-list-item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3px 6px;
  border-radius: 4px;
  font-size: 0.8rem;
}
.user-list-item:hover {
  background: rgba(255, 255, 255, 0.05);
}
/* CB renders user-list usernames at 12px bold (700). Match that
   exactly so the role tinting (red mod, orange broadcaster, etc.)
   reads the same density as CB's original sidebar. */
.user-list-item .chat-username-btn {
  font-weight: 700;
  font-size: 12px;
}
.user-list-item .user-role-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.user-list-item .user-gender {
  font-size: 0.7rem;
  opacity: 0.6;
}
.user-list-item .username {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Chaturbate role colors */
.role-broadcaster  { color: #f47321; }
.role-mod          { color: #dc0000; }
.role-inFanclub    { color: #009900; }
.role-tippedTonsRecently { color: #804baa; }
.role-tippedALotRecently { color: #be6aff; }
.role-tippedRecently     { color: #1e5cfb; }
.role-hasTokens    { color: #6699aa; }
.role-default      { color: #94a3b8; }
/* Role dot colors (matching username colors) */
.dot-broadcaster  { background: #f47321; }
.dot-mod          { background: #dc0000; }
.dot-inFanclub    { background: #009900; }
.dot-tippedTonsRecently { background: #804baa; }
.dot-tippedALotRecently { background: #be6aff; }
.dot-tippedRecently     { background: #1e5cfb; }
.dot-hasTokens    { background: #6699aa; }
.dot-default      { background: #64748b; }

/* User list summary bar */
.user-list-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 6px 8px;
  font-size: 0.7rem;
  color: #94a3b8;
  border-bottom: 1px solid #334155;
}
.user-list-summary .stat {
  display: flex;
  align-items: center;
  gap: 3px;
}

/* Settings panel slide animation */
.settings-panel {
  max-height: 0;
  overflow: hidden;
  overflow-y: auto;
  transition: max-height 0.3s ease;
  background: rgba(15, 23, 42, 0.95);
  border-bottom: 1px solid transparent;
}
.settings-panel.open {
  max-height: 80vh;
  border-bottom-color: #334155;
}

/* ── Settings accordion system ─────────────────────────────── */
.settings-accordion-list {
  padding: 5px 8px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.settings-accordion {
  background: #1e293b;
  border: 1px solid #334155;
  border-radius: 6px;
  overflow: hidden;
}

.settings-accordion-header {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  background: none;
  border: none;
  color: #e2e8f0;
  font-size: 0.75rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s;
  text-align: left;
}
.settings-accordion-header:hover {
  background: rgba(51, 65, 85, 0.4);
}

.acc-icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  color: #94a3b8;
}
.settings-accordion.open .acc-icon {
  color: #818cf8;
}

.acc-title {
  flex: 1;
  min-width: 0;
}

.acc-chevron {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  color: #64748b;
  transition: transform 0.2s ease;
}
.settings-accordion.open .acc-chevron {
  transform: rotate(180deg);
  color: #94a3b8;
}

/* Action button inside accordion header */
.acc-action-btn {
  padding: 1px 8px;
  border-radius: 4px;
  font-size: 0.625rem;
  font-weight: 600;
  background: #4f46e5;
  color: #fff;
  border: none;
  cursor: pointer;
  transition: background 0.15s;
  white-space: nowrap;
}
.acc-action-btn:hover {
  background: #4338ca;
}

/* Navigation-style accordion (no body, just arrow) */
.settings-accordion-nav .acc-nav-arrow {
  width: 14px;
  height: 14px;
  margin-left: auto;
  flex-shrink: 0;
  color: #64748b;
  transition: color 0.15s;
}
.settings-accordion-nav:hover .acc-nav-arrow {
  color: #94a3b8;
}

/* Accordion body animation */
.settings-accordion-body {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.25s ease;
}
.settings-accordion.open .settings-accordion-body {
  max-height: 500px;
}

.settings-accordion-inner {
  padding: 0 10px 8px;
}

/* ── Horizontal row: Video | Plataformas | Chat ─────────────── */
.acc-row {
  display: flex;
  gap: 4px;
}
.acc-row-btn {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 6px 4px;
  border-radius: 6px;
  border: 1px solid #334155;
  background: #1e293b;
  color: #94a3b8;
  font-size: 0.6875rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
  white-space: nowrap;
}
.acc-row-btn svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}
.acc-row-btn:hover {
  background: #334155;
  color: #e2e8f0;
}
.acc-row-btn.active {
  background: #312e81;
  border-color: #6366f1;
  color: #c7d2fe;
}

.acc-row-expand {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.25s ease;
  background: #1e293b;
  border: 1px solid transparent;
  border-radius: 6px;
}
.acc-row-expand.open {
  max-height: 500px;
  border-color: #334155;
}

.acc-row-panel {
  padding: 8px 10px;
}

/* Add platform form (floating between accordions) */
.settings-accordion-form {
  padding: 10px;
  background: #1e293b;
  border: 1px solid #4f46e5;
  border-radius: 6px;
}

/* Video settings row layout */
.vs-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.vs-label {
  font-size: 0.625rem;
  color: #94a3b8;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  width: 55px;
  flex-shrink: 0;
}

.settings-section-title {
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #94a3b8;
  margin-bottom: 0.5rem;
}

/* Platform dropdown */
.platform-dropdown {
  position: relative;
}

/* Trigger button */
.platform-trigger {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 5px 10px;
  border-radius: 6px;
  border: 1px solid #475569;
  background: #334155;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
  color: #94a3b8;
}
.platform-trigger:hover {
  background: #475569;
  border-color: #64748b;
}
.platform-trigger.open {
  background: #475569;
  border-color: #6366f1;
}
.platform-trigger.has-live {
  border-color: #059669;
}
.platform-trigger.has-live.open {
  border-color: #6366f1;
}

.platform-trigger-icons {
  display: flex;
  align-items: center;
  gap: 3px;
}
.platform-trigger-icon {
  width: 16px;
  height: 16px;
  border-radius: 2px;
  object-fit: contain;
  opacity: 0.5;
  transition: opacity 0.15s;
}
.platform-trigger-icon.live {
  opacity: 1;
  filter: drop-shadow(0 0 3px rgba(52, 211, 153, 0.6));
}

.platform-trigger-arrow {
  transition: transform 0.2s;
}
.platform-trigger.open .platform-trigger-arrow {
  transform: rotate(180deg);
}

/* Dropdown menu */
.platform-dropdown-menu {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 220px;
  background: #1e293b;
  border: 1px solid #334155;
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
  z-index: 50;
  padding: 4px;
  flex-direction: column;
  gap: 2px;
}
.platform-dropdown-menu.open {
  display: flex;
}

/* Dropdown item */
.platform-dropdown-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 6px;
  border: none;
  background: none;
  cursor: pointer;
  width: 100%;
  text-align: left;
  color: #e2e8f0;
  transition: background 0.12s;
}
.platform-dropdown-item:hover {
  background: #334155;
}

.pdi-left {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.pdi-icon {
  width: 28px;
  height: 28px;
  border-radius: 4px;
  object-fit: contain;
  flex-shrink: 0;
}
.pdi-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.pdi-name {
  font-size: 0.85rem;
  font-weight: 600;
  text-transform: capitalize;
  white-space: nowrap;
}
.pdi-bridge {
  display: flex;
  align-items: center;
  gap: 4px;
}
.pdi-bridge-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
}
.pdi-bridge-label {
  font-size: 0.7rem;
  color: #94a3b8;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Status badge */
.pdi-status {
  font-size: 0.7rem;
  font-weight: 600;
  padding: 3px 8px;
  border-radius: 9999px;
  white-space: nowrap;
  flex-shrink: 0;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.pdi-status.offline {
  background: #334155;
  color: #94a3b8;
}
.pdi-status.streaming {
  background: #064e3b;
  color: #34d399;
}
.pdi-status.starting {
  background: #422006;
  color: #fbbf24;
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.pdi-status.recovering {
  background: #422006;
  color: #fb923c;
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.pdi-status.error {
  background: #450a0a;
  color: #f87171;
}

/* Right column: status badge + live bitrate stacked */
.pdi-right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  flex-shrink: 0;
}

/* Live bitrate badge — only shown while ffmpeg is forwarding.
   Tier colors mirror what Chaturbate flags as low (<3000 kbps for HD). */
.pdi-bitrate {
  font-size: 0.65rem;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 4px;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}
.pdi-bitrate-low {
  background: #450a0a;
  color: #fca5a5;
}
.pdi-bitrate-mid {
  background: #422006;
  color: #fbbf24;
}
.pdi-bitrate-good {
  background: #064e3b;
  color: #6ee7b7;
}

/* Manual "Iniciar show" button — Stripchat-only secondary action.
   Lives inside the platform dropdown item next to status; click is
   isolated from the parent toggleStream via stopPropagation in JS. */
.pdi-start-show {
  font-size: 0.65rem;
  font-weight: 700;
  padding: 4px 8px;
  border-radius: 6px;
  background: #7c2d12;
  color: #fed7aa;
  border: 1px solid #c2410c;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s ease, color 0.15s ease;
}
.pdi-start-show:hover {
  background: #c2410c;
  color: #fff7ed;
}
.pdi-start-show:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* ── Chat: PM bubble + clickable username button ─────────────── */
.chat-msg-pm {
  background: rgba(124, 58, 237, 0.12);   /* violet-600 / 12% */
  border-left: 3px solid #a78bfa;          /* violet-400 */
  padding: 4px 8px;
  margin: 2px 0;
  border-radius: 4px;
}
.chat-pm-tag {
  display: inline-block;
  font-size: 0.65rem;
  font-weight: 700;
  padding: 1px 5px;
  border-radius: 3px;
  background: #6d28d9;
  color: #ddd6fe;
  letter-spacing: 0.04em;
  margin-right: 4px;
  vertical-align: middle;
}
.chat-username-btn {
  display: inline;
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: #818cf8;            /* indigo-400 */
  font-weight: 600;
  font-size: 0.75rem;
  cursor: pointer;
  text-decoration: none;
}
.chat-username-btn:hover {
  color: #c7d2fe;             /* indigo-200 */
  text-decoration: underline;
}

/* ── User-action floating menu (Chaturbate per-user actions) ── */
.chat-user-action-menu {
  position: fixed;
  z-index: 10000;
  min-width: 200px;
  background: #1e293b;        /* slate-800 */
  border: 1px solid #475569;  /* slate-600 */
  border-radius: 8px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
  padding: 4px;
  font-size: 0.8rem;
}
.chat-user-action-menu.hidden { display: none; }
.cuam-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 8px;
  border-bottom: 1px solid #334155;
  margin-bottom: 4px;
}
.cuam-username {
  font-weight: 700;
  color: #e2e8f0;
}
.cuam-platform {
  font-size: 0.65rem;
  color: #94a3b8;
  text-transform: capitalize;
  background: #334155;
  padding: 2px 6px;
  border-radius: 4px;
}
.cuam-info {
  padding: 6px 8px;
  margin-bottom: 4px;
  border-bottom: 1px solid #334155;
  font-size: 0.72rem;
  color: #cbd5e1;
}
.cuam-info-loading,
.cuam-info-error {
  color: #94a3b8;
  font-style: italic;
}
.cuam-info-error { color: #fda4af; }
.cuam-info-role {
  font-weight: 600;
  color: #f0abfc;
  margin-bottom: 3px;
}
.cuam-info-sub {
  font-weight: 400;
  color: #94a3b8;
  font-size: 0.7rem;
}
.cuam-info-tips {
  display: flex;
  gap: 8px;
  font-variant-numeric: tabular-nums;
  color: #fbbf24;
}
.cuam-info-note {
  margin-top: 4px;
  padding: 3px 6px;
  background: rgba(124, 58, 237, 0.18);
  border-left: 2px solid #a78bfa;
  border-radius: 3px;
  color: #ddd6fe;
  font-size: 0.7rem;
}

.cuam-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 6px 10px;
  background: transparent;
  border: none;
  border-radius: 4px;
  color: #cbd5e1;
  cursor: pointer;
  font-size: 0.8rem;
  transition: background 0.1s ease, color 0.1s ease;
}
.cuam-item:hover {
  background: #334155;
  color: #f1f5f9;
}
.cuam-item-danger {
  color: #fda4af;             /* rose-300 */
}
.cuam-item-danger:hover {
  background: #7f1d1d;
  color: #fee2e2;
}
.cuam-item-disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.cuam-item-disabled:hover {
  background: transparent;
  color: #cbd5e1;
}

/* ── User-action text prompt (DM/PM/Note) ───────────────────── */
.cuam-prompt-overlay {
  position: fixed;
  inset: 0;
  z-index: 10001;
  background: rgba(15, 23, 42, 0.75);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}
.cuam-prompt-card {
  background: #1e293b;
  border: 1px solid #475569;
  border-radius: 10px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.6);
  padding: 16px;
  width: min(420px, 100%);
}
.cuam-prompt-title {
  font-size: 0.85rem;
  font-weight: 600;
  color: #e2e8f0;
  margin-bottom: 10px;
}
.cuam-prompt-textarea {
  width: 100%;
  padding: 8px 10px;
  border-radius: 6px;
  background: #0f172a;
  border: 1px solid #475569;
  color: #f1f5f9;
  font-size: 0.85rem;
  font-family: inherit;
  resize: vertical;
  outline: none;
}
.cuam-prompt-textarea:focus {
  border-color: #818cf8;
}
.cuam-prompt-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 12px;
}
.cuam-prompt-cancel,
.cuam-prompt-send {
  padding: 6px 14px;
  border-radius: 6px;
  border: none;
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
}
.cuam-prompt-cancel {
  background: #334155;
  color: #cbd5e1;
}
.cuam-prompt-cancel:hover { background: #475569; }
.cuam-prompt-send {
  background: #4f46e5;
  color: #fff;
}
.cuam-prompt-send:hover { background: #6366f1; }

/* ── Private show request banner ─────────────────────────────── */
.private-show-banner {
  position: fixed;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10005;
  width: min(560px, 92vw);
  background: linear-gradient(135deg, #7c2d12 0%, #be123c 60%, #db2777 100%);
  border: 2px solid #fbbf24;
  border-radius: 12px;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.7), 0 0 0 4px rgba(251, 191, 36, 0.18);
  padding: 12px 16px;
  animation: privateShowPulse 2s ease-in-out infinite;
}
@keyframes privateShowPulse {
  0%, 100% { box-shadow: 0 16px 40px rgba(0, 0, 0, 0.7), 0 0 0 4px rgba(251, 191, 36, 0.18); }
  50%      { box-shadow: 0 16px 40px rgba(0, 0, 0, 0.7), 0 0 0 8px rgba(251, 191, 36, 0.30); }
}
.private-show-banner-content {
  display: flex;
  align-items: center;
  gap: 12px;
}
.private-show-banner-icon {
  font-size: 2rem;
  filter: drop-shadow(0 0 6px rgba(251, 191, 36, 0.8));
}
.private-show-banner-body { flex: 1; min-width: 0; }
.private-show-banner-title {
  font-size: 0.95rem;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}
.private-show-banner-sub {
  font-size: 0.75rem;
  color: #fde68a;
  margin-top: 2px;
}
.private-show-banner-countdown {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.private-show-banner-actions {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}
.private-show-banner-accept,
.private-show-banner-decline {
  padding: 8px 18px;
  border-radius: 6px;
  border: none;
  font-weight: 700;
  font-size: 0.85rem;
  cursor: pointer;
}
.private-show-banner-accept {
  background: #16a34a;
  color: #fff;
}
.private-show-banner-accept:hover { background: #22c55e; }
.private-show-banner-decline {
  background: rgba(0, 0, 0, 0.4);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.3);
}
.private-show-banner-decline:hover { background: rgba(0, 0, 0, 0.6); }

/* ── Chaturbate emoticons picker ─────────────────────────────── */
.cb-emoticon-panel {
  position: fixed;
  z-index: 10001;
  width: 300px;
  max-height: 320px;
  overflow-y: auto;
  background: #1e293b;
  border: 1px solid #475569;
  border-radius: 8px;
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.6);
  padding: 6px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
}
.cb-emoticon-panel.hidden { display: none; }
.cb-emoticon-btn {
  padding: 6px 4px;
  border-radius: 4px;
  border: 1px solid #334155;
  background: #0f172a;
  color: #cbd5e1;
  font-size: 0.7rem;
  cursor: pointer;
  text-align: center;
  transition: background 0.1s ease, color 0.1s ease;
}
.cb-emoticon-btn:hover {
  background: #f97316;
  color: #fff;
  border-color: #ea580c;
}

/* ── User-list role badges (M / T / FC / B) ──────────────────── */
.ul-badge {
  display: inline-block;
  font-size: 0.6rem;
  font-weight: 800;
  padding: 1px 5px;
  margin-left: 4px;
  border-radius: 4px;
  letter-spacing: 0.04em;
  vertical-align: middle;
}
/* Badge colors match CB's role tinting exactly (live-probed). The
   previous palette was Tailwind defaults that conflicted with the
   role-* font colors (mod was BLUE on the badge but RED in CB). */
.ul-badge-mod {
  background: #dc0000;       /* CB mod red */
  color: #ffffff;
}
.ul-badge-trusted {
  background: #11a3a3;       /* CB trusted viewer teal */
  color: #cffafe;
}
.ul-badge-fanclub {
  background: #b40e7a;       /* CB fan club magenta */
  color: #fce7f3;
}
.ul-badge-broadcaster {
  background: #f47321;       /* CB orange */
  color: #ffffff;
}
/* viewer is currently sharing their cam2cam — clickable to open */
.ul-badge-cam {
  background: #4c1d95;       /* violet-900 */
  color: #ede9fe;
  cursor: pointer;
  animation: ulBadgeCamPulse 2.4s ease-in-out infinite;
}
@keyframes ulBadgeCamPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(139, 92, 246, 0.6); }
  50%      { box-shadow: 0 0 0 4px rgba(139, 92, 246, 0); }
}

/* ── Chat join/leave notice — mirrors CB's inline row ────────────── */
.chat-msg-join-leave {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  padding: 2px 6px;
  border-radius: 6px;
  background: rgba(30, 41, 59, 0.4);    /* slate-800/40 */
  color: #94a3b8;                       /* slate-400 */
}
.cjl-role-prefix {
  font-weight: 600;
  font-size: 11px;
  padding: 1px 5px;
  border-radius: 3px;
  letter-spacing: 0.03em;
}
.cjl-role-broadcaster { background: #f47321; color: #ffffff; }   /* CB orange */
.cjl-role-mod         { background: #dc0000; color: #ffffff; }   /* CB mod red */
.cjl-role-inFanclub   { background: #b40e7a; color: #fce7f3; }   /* CB FC pink */
.chat-msg-join-leave .chat-username-btn {
  background: none;
  border: none;
  font-weight: 700;            /* CB renders user-list usernames bold */
  cursor: pointer;
  padding: 0;
}
.chat-msg-join-leave .chat-username-btn.role-broadcaster { color: #f47321; }
.chat-msg-join-leave .chat-username-btn.role-mod         { color: #dc0000; }
.chat-msg-join-leave .chat-username-btn.role-inFanclub   { color: #009900; }
.chat-msg-join-leave .chat-username-btn.role-default     { color: #e2e8f0; }
.chat-msg-join-leave .chat-username-btn:hover { text-decoration: underline; }
.cjl-cam {
  font-size: 13px;
  animation: ulBadgeCamPulse 2.4s ease-in-out infinite;
  border-radius: 50%;
  padding: 0 2px;
}
.cjl-trusted {
  color: #67e8f9;          /* cyan-300 */
  font-size: 12px;
}
.cjl-action {
  color: #cbd5e1;          /* slate-300 */
  margin-left: 2px;
}

/* ── Dashboard tab with unread badge ─────────────────────────── */
.dash-tab.dash-tab-has-unread {
  color: #f0abfc;
  font-weight: 700;
}
.dash-tab.dash-tab-has-unread::after {
  content: " ●";
  color: #d946ef;
  font-size: 0.7rem;
  margin-left: 1px;
}
.dash-tab.dash-tab-has-unread.active {
  /* Active tab clears the unread style — the operator is reading it now */
  color: inherit;
  font-weight: inherit;
}
.dash-tab.dash-tab-has-unread.active::after {
  content: "";
}

/* Bitrate override row inside the Calidad accordion */
.bitrate-row {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
}
.bitrate-label {
  font-size: 0.7rem;
  color: #94a3b8;
  font-weight: 600;
  flex-shrink: 0;
}
.bitrate-input {
  flex: 1;
  background: rgba(51, 65, 85, 0.8);
  border: 1px solid #475569;
  color: #e2e8f0;
  font-size: 0.75rem;
  padding: 4px 8px;
  border-radius: 4px;
  outline: none;
  font-variant-numeric: tabular-nums;
  min-width: 0;
}
.bitrate-input:focus {
  border-color: #6366f1;
}
.bitrate-unit {
  font-size: 0.65rem;
  color: #64748b;
}
.bitrate-reset {
  background: rgba(51, 65, 85, 0.6);
  color: #cbd5e1;
  border: 1px solid #475569;
  border-radius: 4px;
  padding: 2px 8px;
  font-size: 0.85rem;
  cursor: pointer;
  flex-shrink: 0;
}
.bitrate-reset:hover {
  background: rgba(71, 85, 105, 0.8);
  color: #fff;
}
.bitrate-hint {
  font-size: 0.65rem;
  color: #64748b;
  margin-top: 4px;
  margin-bottom: 0;
}
.bitrate-hint-override {
  color: #fbbf24;
}

/* Stats panel */
.stats-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 4px;
}
.stats-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 4px 8px;
  background: rgba(51, 65, 85, 0.4);
  border-radius: 4px;
  font-size: 0.75rem;
}
.stats-label {
  color: #94a3b8;
  font-weight: 500;
}
.stats-value {
  color: #e2e8f0;
  font-variant-numeric: tabular-nums;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.7rem;
}
.stats-value-good {
  color: #34d399;
}
.stats-value-warn {
  color: #fbbf24;
}
.stats-value-bad {
  color: #f87171;
}

/* Quality selector */
.quality-btn {
  flex: 1;
  padding: 4px 0;
  border: 1px solid #334155;
  border-radius: 5px;
  background: #1e293b;
  color: #94a3b8;
  font-size: 0.6875rem;
  font-weight: 500;
  cursor: pointer;
  text-align: center;
  transition: all 0.15s;
}
.quality-btn:hover {
  border-color: #475569;
  color: #e2e8f0;
}
.quality-btn.active {
  background: #1d4ed8;
  border-color: #3b82f6;
  color: #fff;
  font-weight: 600;
}

/* Video preview */
#video-preview-section video:not(.hidden) {
  display: block;
}

/* ── Video settings ────────────────────────────────────────── */
.video-settings-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 4px;
  border-radius: 6px;
  color: #94a3b8;
  transition: color 0.2s, background 0.2s;
}
.video-settings-btn:hover {
  color: #fff;
  background: #334155;
}
.video-settings-btn.active {
  color: #818cf8;
  background: #334155;
}

.video-settings-panel {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease;
  background: rgba(15, 23, 42, 0.95);
  border-bottom: 1px solid transparent;
}
.video-settings-panel.open {
  max-height: 360px;
  border-bottom-color: #334155;
}

.vs-chip {
  padding: 3px 8px;
  border-radius: 9999px;
  font-size: 0.6875rem;
  font-weight: 600;
  background: #334155;
  border: 1px solid #475569;
  color: #94a3b8;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
  white-space: nowrap;
}
.vs-chip:hover {
  background: #475569;
  color: #e2e8f0;
}
.vs-chip.active {
  background: #4f46e5;
  border-color: #6366f1;
  color: #fff;
}

/* Zoom slider */
.vs-slider {
  -webkit-appearance: none;
  appearance: none;
  height: 4px;
  background: #334155;
  border-radius: 2px;
  outline: none;
  cursor: pointer;
}
.vs-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #6366f1;
  border: 2px solid #818cf8;
  cursor: pointer;
  transition: background 0.15s;
}
.vs-slider::-webkit-slider-thumb:hover {
  background: #4f46e5;
}
.vs-slider::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #6366f1;
  border: 2px solid #818cf8;
  cursor: pointer;
}
.vs-slider::-moz-range-track {
  height: 4px;
  background: #334155;
  border-radius: 2px;
}

/* Canvas preview for processed video */
#preview-canvas:not(.hidden) {
  display: block;
}

/* Scrollbar styling */
#chat-messages::-webkit-scrollbar,
.dash-panel::-webkit-scrollbar {
  width: 4px;
}
#chat-messages::-webkit-scrollbar-thumb,
.dash-panel::-webkit-scrollbar-thumb {
  background: #475569;
  border-radius: 2px;
}

/* ── Emoji Picker ──────────────────────────────────────────── */
.emoji-picker {
  display: none;
  position: absolute;
  bottom: calc(100% + 6px);
  right: 0;
  width: 320px;
  max-height: 360px;
  background: #1e293b;
  border: 1px solid #334155;
  border-radius: 10px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
  z-index: 100;
  flex-direction: column;
  overflow: hidden;
}
.emoji-picker[data-position="below"] {
  bottom: auto;
  top: calc(100% + 6px);
}
.emoji-picker.open {
  display: flex;
}

.emoji-picker-search {
  padding: 8px;
  border-bottom: 1px solid #334155;
}
.emoji-picker-search-input {
  width: 100%;
  padding: 6px 10px;
  border-radius: 6px;
  border: 1px solid #475569;
  background: #0f172a;
  color: #e2e8f0;
  font-size: 0.8rem;
  outline: none;
  box-sizing: border-box;
}
.emoji-picker-search-input:focus {
  border-color: #6366f1;
}
.emoji-picker-search-input::placeholder {
  color: #64748b;
}

.emoji-picker-tabs {
  display: flex;
  border-bottom: 1px solid #334155;
  background: #0f172a;
  overflow-x: auto;
  scrollbar-width: none;
}
.emoji-picker-tabs::-webkit-scrollbar {
  display: none;
}
.emoji-picker-tab {
  flex-shrink: 0;
  padding: 6px 8px;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  font-size: 1rem;
  opacity: 0.5;
  transition: opacity 0.15s, border-color 0.15s;
}
.emoji-picker-tab:hover {
  opacity: 0.8;
}
.emoji-picker-tab.active {
  opacity: 1;
  border-bottom-color: #6366f1;
}

.emoji-picker-grid-wrap {
  flex: 1;
  overflow-y: auto;
  padding: 6px;
  scrollbar-width: thin;
  scrollbar-color: #334155 transparent;
}
.emoji-picker-grid-wrap::-webkit-scrollbar {
  width: 4px;
}
.emoji-picker-grid-wrap::-webkit-scrollbar-thumb {
  background: #475569;
  border-radius: 2px;
}

.emoji-picker-cat-label {
  font-size: 0.7rem;
  color: #64748b;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 4px 4px 6px;
  font-weight: 600;
}

.emoji-picker-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 2px;
}

.emoji-picker-emoji {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  aspect-ratio: 1;
  font-size: 1.3rem;
  background: none;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.1s;
  padding: 0;
  line-height: 1;
}
.emoji-picker-emoji:hover {
  background: #334155;
}

.emoji-picker-empty {
  grid-column: 1 / -1;
  text-align: center;
  padding: 20px;
  color: #64748b;
  font-size: 0.8rem;
}

/* Emoji trigger button */
.emoji-trigger {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 8px;
  border: 1px solid #475569;
  background: #334155;
  cursor: pointer;
  font-size: 1.1rem;
  transition: background 0.15s, border-color 0.15s;
  flex-shrink: 0;
  padding: 0;
  line-height: 1;
}
.emoji-trigger:hover {
  background: #475569;
  border-color: #64748b;
}

/* Up/down arrows next to "Enviar" — resize the dashboard chat container.
   Stacked vertically (▲ over ▼) in a 22px-wide column matching the
   "Enviar" button height. Each half is ~half the input row height. */
.dash-chat-resize-stack {
  display: flex;
  flex-direction: column;
  width: 22px;
  min-width: 22px;
  gap: 2px;
  flex-shrink: 0;
}
.dash-chat-resize {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  width: 100%;
  min-height: 0;
  border-radius: 4px;
  border: 1px solid #475569;
  background: #334155;
  color: #cbd5e1;
  cursor: pointer;
  font-size: 0.65rem;
  padding: 0;
  line-height: 1;
}
.dash-chat-resize:hover {
  background: #475569;
  border-color: #64748b;
  color: #fff;
}
.dash-chat-resize:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* "Enviar a:" platform selector — operator needs to read it at a
   glance + tap it on mobile. Bumped from 10px (too small to read)
   to 13px and the select to 32px tall for easier tapping. */
.dash-platform-row {
  line-height: 1.25;
  font-size: 13px !important;       /* override the text-[10px] on the parent */
}
.dash-platform-row > span {
  font-size: 13px;
  font-weight: 500;
}
.dash-platform-row select {
  height: 32px;
  min-height: 32px;
  width: auto;
  font-size: 14px !important;       /* readable on mobile */
  padding: 0 0.5rem !important;
}

/* ── Chat font-size buttons (top-right of dashboard chat header) ─ */
.dash-fontsize-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 18px;
  padding: 0;
  border-radius: 4px;
  border: 1px solid #475569;
  background: #334155;
  color: #cbd5e1;
  cursor: pointer;
  font-size: 10px;
  font-weight: 600;
  line-height: 1;
}
.dash-fontsize-btn:hover {
  background: #475569;
  border-color: #64748b;
  color: #fff;
}
.dash-fontsize-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Font-size is applied as an inline style to #dash-chat-wrapper, then
   cascades to all dash-panel children. We override Tailwind's
   text-sm baseline by upping specificity from the wrapper. */
#dash-chat-wrapper[data-fontsize] .dash-panel,
#dash-chat-wrapper[data-fontsize] .dash-panel .text-sm {
  font-size: var(--dash-chat-fs, 0.875rem);
}

/* ── PM thread sidebar (vertical list, mirrors CB's PM panel) ── */
.dash-pm-thread-chip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  width: 100%;
  padding: 5px 8px;
  border-radius: 0;
  border: none;
  border-left: 3px solid transparent;
  background: transparent;
  color: #cbd5e1;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: background 0.1s, border-left-color 0.1s;
}
.dash-pm-thread-chip:hover {
  background: #334155;
}
.dash-pm-thread-chip.active {
  background: #4c1d95;             /* violet-900 */
  border-left-color: #a78bfa;      /* violet-400 */
  color: #ede9fe;
}
.dash-pm-thread-chip.has-unread:not(.active) {
  color: #f0abfc;                  /* fuchsia-300 */
  font-weight: 600;
}
.dash-pm-thread-badge {
  display: inline-block;
  min-width: 16px;
  padding: 0 4px;
  border-radius: 8px;
  background: #db2777;             /* pink-600 */
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  text-align: center;
  line-height: 14px;
  flex-shrink: 0;
}
.dash-pm-thread-chip.active .dash-pm-thread-badge {
  background: #ec4899;             /* pink-500 */
}

/* ── Translation toggle + per-message translation hint ─────────── */
/* Bumped from 10px → 14px: operator uses this toggle constantly to
   switch ES↔EN translation; it has to be readable + tappable. */
.dash-translate-toggle {
  font-size: 14px !important;
  color: #cbd5e1;
  gap: 0.4rem !important;
  padding: 0.2rem 0.35rem;
}
.dash-translate-toggle span {
  font-weight: 600;
}
.dash-translate-checkbox {
  width: 20px;
  height: 20px;
  accent-color: #6366f1;        /* indigo-500 */
  cursor: pointer;
  flex-shrink: 0;
}
/* Translation line appended below an incoming message bubble — same
   slot height as the original text, slightly dimmer + italic so the
   operator can scan original vs translation at a glance.
   font-size is relative (em) so it scales with the chat font-size
   buttons (A− / A+ in the header). 0.85em ≈ 12px when chat is at 14px,
   and grows proportionally to ~27px when chat is at 32px. */
.chat-msg-translation {
  margin-top: 1px;
  padding-left: 18px;            /* approx aligns under the username text */
  font-size: 0.85em;
  font-style: italic;
  color: #67e8f9;                /* cyan-300 */
  opacity: 0.85;
  line-height: 1.3;
}
.chat-msg-translation::before {
  content: '↳ ';
  opacity: 0.6;
}
/* Outgoing-translation chip: shows the English we actually sent under
   the Spanish bubble the operator typed. Same em-relative sizing. */
.chat-msg-translation-out {
  margin-top: 1px;
  padding-right: 4px;
  font-size: 0.85em;
  font-style: italic;
  color: #fcd34d;                /* amber-300 */
  opacity: 0.9;
}
.chat-msg-translation-out::before {
  content: '→ EN: ';
  opacity: 0.7;
}

/* ── RouteMaster ──────────────────────────────────────────── */

/* Top bar tabs */
.topbar-tab {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  border-radius: 6px;
  font-size: 0.85rem;
  font-weight: 600;
  color: #94a3b8;
  background: none;
  border: none;
  cursor: pointer;
  transition: color 0.15s, background 0.15s;
  white-space: nowrap;
}
.topbar-tab:hover {
  color: #e2e8f0;
  background: rgba(51, 65, 85, 0.5);
}
.topbar-tab.active {
  color: #fff;
  background: #334155;
}

/* Platform filter chips */
.rm-plat-chip {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 5px 10px;
  border-radius: 9999px;
  font-size: 0.75rem;
  font-weight: 600;
  background: #334155;
  border: 1px solid #475569;
  color: #94a3b8;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.rm-plat-chip:hover {
  background: #475569;
  color: #e2e8f0;
}
.rm-plat-chip.active {
  background: #4f46e5;
  border-color: #6366f1;
  color: #fff;
}

/* Traffic light indicator */
.rm-traffic-light {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.rm-light-green  { background: #22c55e; box-shadow: 0 0 6px rgba(34,197,94,0.4); }
.rm-light-yellow { background: #eab308; box-shadow: 0 0 6px rgba(234,179,8,0.4); }
.rm-light-red    { background: #ef4444; box-shadow: 0 0 6px rgba(239,68,68,0.4); }

/* Recommendation cards */
.rm-rec-card {
  padding: 12px;
  border-radius: 10px;
  background: #1e293b;
  border: 1px solid #334155;
  transition: border-color 0.2s;
}
.rm-rec-green  { border-color: rgba(34,197,94,0.3); }
.rm-rec-yellow { border-color: rgba(234,179,8,0.3); }
.rm-rec-red    { border-color: rgba(239,68,68,0.3); }

.rm-rank {
  font-size: 0.7rem;
  font-weight: 700;
  color: #64748b;
  background: #0f172a;
  padding: 2px 6px;
  border-radius: 4px;
}

/* Score gauge bar */
.rm-score-gauge {
  height: 4px;
  background: #0f172a;
  border-radius: 2px;
  overflow: hidden;
}
.rm-score-fill {
  height: 100%;
  border-radius: 2px;
  transition: width 0.5s ease;
}
.rm-fill-green  { background: #22c55e; }
.rm-fill-yellow { background: #eab308; }
.rm-fill-red    { background: #ef4444; }

/* Server list cards */
.rm-server-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 12px;
  background: #1e293b;
  border: 1px solid #334155;
  border-radius: 8px;
}

/* Metrics grid */
.rm-metrics {
  display: flex;
  gap: 12px;
  flex-shrink: 0;
}
.rm-metric {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 44px;
}
.rm-metric-label {
  font-size: 0.6rem;
  color: #64748b;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.rm-metric-value {
  font-size: 0.8rem;
  color: #e2e8f0;
  font-variant-numeric: tabular-nums;
}

/* Mobile: stack server card vertically */
@media (max-width: 640px) {
  .rm-server-card {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }
  .rm-metrics {
    justify-content: space-between;
    padding-top: 8px;
    border-top: 1px solid #334155;
  }
}

/* ── RouteMaster v2 — Visual Enhancements ─────────────────── */

/* Active probe pills (pulsing hostnames during scan) */
.rm-active-probe {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 9999px;
  font-size: 0.65rem;
  font-weight: 600;
  background: rgba(79, 70, 229, 0.2);
  border: 1px solid rgba(99, 102, 241, 0.3);
  color: #a5b4fc;
  animation: rm-probe-pulse 1.5s ease-in-out infinite;
}
.rm-active-probe::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #818cf8;
  animation: rm-dot-blink 1s ease-in-out infinite;
}
@keyframes rm-probe-pulse {
  0%, 100% { opacity: 0.7; }
  50% { opacity: 1; }
}
@keyframes rm-dot-blink {
  0%, 100% { opacity: 0.4; }
  50% { opacity: 1; }
}

/* Card enter animation (live results) */
.rm-card-enter {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.35s ease, transform 0.35s ease;
}
.rm-card-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Probe dots (5 colored circles per server) */
.rm-probe-dots {
  display: inline-flex;
  gap: 3px;
  align-items: center;
}
.rm-probe-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
}
.rm-probe-dot.ok  { background: #22c55e; }
.rm-probe-dot.fail { background: #ef4444; }

/* Latency range bar (min→avg→max) */
.rm-range-bar {
  position: relative;
  width: 100%;
  height: 3px;
  background: #334155;
  border-radius: 2px;
  margin-top: 4px;
}
.rm-range-fill {
  position: absolute;
  height: 100%;
  border-radius: 2px;
  background: rgba(99, 102, 241, 0.4);
}
.rm-range-avg {
  position: absolute;
  top: -2px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #818cf8;
  border: 1px solid #1e293b;
  transform: translateX(-50%);
}

/* Server card — now column layout for expandable */
.rm-server-card {
  flex-direction: column;
  cursor: pointer;
  transition: border-color 0.2s, background 0.2s;
}
.rm-server-card:hover {
  border-color: #475569;
}
.rm-server-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
}

/* Expand arrow */
.rm-expand-arrow {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  color: #64748b;
  transition: transform 0.25s ease, color 0.2s;
}
.rm-server-card.rm-expanded .rm-expand-arrow {
  transform: rotate(180deg);
  color: #94a3b8;
}

/* Card detail panel (expanded) */
.rm-card-detail {
  display: none;
  padding-top: 10px;
  margin-top: 10px;
  border-top: 1px solid #334155;
  animation: rm-detail-in 0.25s ease;
}
.rm-server-card.rm-expanded .rm-card-detail {
  display: block;
}
@keyframes rm-detail-in {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Mini probe latency bars (vertical) */
.rm-probe-bars {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 40px;
}
.rm-probe-bar {
  width: 18px;
  min-height: 2px;
  border-radius: 2px 2px 0 0;
  background: #818cf8;
  transition: height 0.3s ease;
  position: relative;
}
.rm-probe-bar.fail {
  background: #ef4444;
}
.rm-probe-bar-label {
  position: absolute;
  bottom: calc(100% + 2px);
  left: 50%;
  transform: translateX(-50%);
  font-size: 0.55rem;
  color: #94a3b8;
  white-space: nowrap;
}

/* Score breakdown bars */
.rm-score-breakdown {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.rm-breakdown-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.rm-breakdown-label {
  font-size: 0.65rem;
  color: #94a3b8;
  width: 52px;
  text-align: right;
  flex-shrink: 0;
}
.rm-breakdown-track {
  flex: 1;
  height: 6px;
  background: #0f172a;
  border-radius: 3px;
  overflow: hidden;
}
.rm-breakdown-fill {
  height: 100%;
  border-radius: 3px;
  transition: width 0.5s ease;
}
.rm-breakdown-fill.loss    { background: #f97316; }
.rm-breakdown-fill.latency { background: #818cf8; }
.rm-breakdown-fill.jitter  { background: #22d3ee; }
.rm-breakdown-value {
  font-size: 0.65rem;
  color: #64748b;
  width: 38px;
  font-variant-numeric: tabular-nums;
}

/* RTMP URL block */
.rm-rtmp-url {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  background: #0f172a;
  border: 1px solid #334155;
  border-radius: 6px;
  font-family: 'Courier New', monospace;
  font-size: 0.7rem;
  color: #94a3b8;
  word-break: break-all;
  cursor: pointer;
  transition: border-color 0.2s;
}
.rm-rtmp-url:hover {
  border-color: #6366f1;
}
.rm-rtmp-url .rm-copy-icon {
  flex-shrink: 0;
  width: 14px;
  height: 14px;
  color: #64748b;
}

/* Recommendation pills */
.rm-rec-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 6px;
}
.rm-pill {
  padding: 1px 6px;
  border-radius: 9999px;
  font-size: 0.6rem;
  font-weight: 600;
  background: rgba(15, 23, 42, 0.8);
  color: #94a3b8;
  border: 1px solid #334155;
}

/* Score gauge animation */
.rm-score-animate .rm-score-fill {
  transition: width 1s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Best server pulse (#1) */
.rm-best-pulse {
  animation: rm-best-glow 2s ease-in-out infinite;
}
@keyframes rm-best-glow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0); }
  50% { box-shadow: 0 0 12px 2px rgba(34, 197, 94, 0.2); }
}

/* Scan summary banner */
.rm-summary-inner {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: #1e293b;
  border: 1px solid #334155;
  border-radius: 8px;
  font-size: 0.75rem;
  color: #94a3b8;
}
.rm-summary-inner svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: #22c55e;
}
.rm-summary-inner .rm-cache-age {
  margin-left: auto;
  color: #64748b;
  font-size: 0.65rem;
}

/* Mobile adjustments for v2 */
@media (max-width: 640px) {
  .rm-server-summary {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }
  .rm-probe-bars {
    height: 32px;
  }
  .rm-breakdown-label {
    width: 44px;
  }
}

/* ── Voice changer modal ─────────────────────────────────────
   Fullscreen overlay anchored INSIDE #screen-dashboard so it
   inherits the dashboard's z-context. Backdrop closes on click;
   inner panel stops propagation so clicks inside don't dismiss. */
.vc-modal {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
.vc-modal.hidden { display: none; }
.vc-modal-backdrop {
  position: absolute;
  inset: 0;
  /* Use a higher-opacity solid color INSTEAD of backdrop-filter:blur.
     On mobile Chrome / Safari the blur forces GPU re-composition of
     every element behind the modal — including the <video> preview
     of the active camera, which pauses or freezes mid-frame while
     the blur is computed. That's the very stream we need flowing
     into the WHIP source, so freezing it kills the voice-monitor
     pipeline upstream. The flat overlay covers the dashboard fine
     without any compositing cost. */
  background: rgba(15, 23, 42, 0.92);
}
.vc-modal-panel {
  position: relative;
  background: #1e293b;
  border: 1px solid #334155;
  border-radius: 0.75rem;
  width: 100%;
  max-width: 26rem;
  max-height: 90vh;
  overflow-y: auto;
  padding: 1.25rem;
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
}
.vc-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1rem;
}
.vc-modal-head h3 {
  font-size: 1rem;
  font-weight: 600;
  color: #f8fafc;
}
.vc-modal-close {
  background: none;
  border: none;
  color: #94a3b8;
  font-size: 1.5rem;
  line-height: 1;
  padding: 0 0.25rem;
  cursor: pointer;
}
.vc-modal-close:hover { color: #f8fafc; }

.vc-toggle-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 0;
  border-bottom: 1px solid #334155;
  margin-bottom: 0.75rem;
}
.vc-toggle-label {
  font-size: 0.875rem;
  color: #e2e8f0;
  font-weight: 500;
}
/* Toggle switch — pure CSS, no external library */
.vc-switch {
  position: relative;
  display: inline-block;
  width: 44px;
  height: 24px;
  cursor: pointer;
}
.vc-switch input { display: none; }
.vc-switch-track {
  position: absolute;
  inset: 0;
  background: #475569;
  border-radius: 9999px;
  transition: background 0.15s ease;
}
.vc-switch-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 20px;
  height: 20px;
  background: #f8fafc;
  border-radius: 9999px;
  transition: transform 0.15s ease;
}
.vc-switch input:checked + .vc-switch-track {
  background: #10b981;
}
.vc-switch input:checked + .vc-switch-track .vc-switch-thumb {
  transform: translateX(20px);
}

.vc-hint {
  font-size: 0.75rem;
  color: #94a3b8;
  margin-bottom: 0.75rem;
  line-height: 1.4;
}

.vc-speaker-group {
  margin-bottom: 0.875rem;
}
.vc-speaker-group-title {
  font-size: 0.75rem;
  color: #64748b;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
  margin-bottom: 0.4rem;
}
.vc-speaker-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.4rem;
}
.vc-speaker {
  padding: 0.5rem 0.6rem;
  border-radius: 0.5rem;
  border: 1px solid #334155;
  background: #0f172a;
  color: #e2e8f0;
  font-size: 0.8rem;
  font-weight: 500;
  cursor: pointer;
  transition: border-color 0.1s, background 0.1s;
}
.vc-speaker:hover {
  background: #1e293b;
  border-color: #475569;
}
.vc-speaker.active {
  background: #064e3b;
  border-color: #10b981;
  color: #ecfdf5;
}
.vc-speaker:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Status line below the speaker grid. Color shifts based on
   whether voice-changer is live, queued for next stream, or off. */
.vc-status {
  font-size: 0.75rem;
  color: #94a3b8;
  padding: 0.6rem 0.75rem;
  border-radius: 0.5rem;
  background: #0f172a;
  border: 1px solid #1e293b;
  margin-top: 0.5rem;
}
.vc-status.vc-status-live {
  color: #ecfdf5;
  background: #064e3b;
  border-color: #10b981;
}
.vc-status.vc-status-queued {
  color: #fef3c7;
  background: #422006;
  border-color: #d97706;
}

/* ── Voice-monitor (local preview) inside the modal ─────────── */
.vc-monitor-section {
  margin-top: 0.875rem;
  padding-top: 0.875rem;
  border-top: 1px solid #334155;
}
.vc-monitor-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 0.85rem;
  border-radius: 0.5rem;
  border: 1px solid #475569;
  background: #1e293b;
  color: #e2e8f0;
  font-size: 0.8rem;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.1s, border-color 0.1s;
}
.vc-monitor-btn:hover { background: #334155; border-color: #64748b; }
.vc-monitor-btn.active {
  background: #064e3b;
  border-color: #10b981;
  color: #ecfdf5;
}
.vc-monitor-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.vc-monitor-hint {
  font-size: 0.7rem;
  color: #94a3b8;
  margin-top: 0.4rem;
  line-height: 1.4;
}

/* ── Live dictation overlay (Phase C streaming feedback) ────
   Body-level FIXED overlay so it floats above all page content
   (video frame, chat panel, modals) and never gets clipped by a
   parent's overflow:hidden. The transcript sits just below the
   FAB so the operator always knows where the live text appears.
   ALWAYS present in the DOM with reserved height so the layout
   never jumps when text comes/goes. */
.vc-live-transcript {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  /* Width sized to be visible on phone (anchor near FAB) and
     desktop (no need to span full viewport). */
  width: calc(min(28rem, 92vw));
  /* Reserved height: 2 lines worth (~52px) so empty/full take same room. */
  min-height: 2.4em;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: rgba(15, 23, 42, 0.92);
  color: #e2e8f0;
  padding: 0.5rem 0.8rem;
  border-radius: 0.55rem;
  font-size: 0.9rem;
  line-height: 1.3;
  pointer-events: none;
  border: 1px solid rgba(99, 102, 241, 0.45);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: border-color 0.25s ease-out, background 0.25s ease-out;
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.42);
  z-index: 9990;     /* below FAB (9999) but above everything else */
}
.vc-live-transcript.dictating {
  border-color: rgba(239, 68, 68, 0.6);
  background: rgba(15, 23, 42, 0.88);
}
.vc-live-text {
  flex: 1 1 auto;
  min-width: 0;
  /* Truncate to 2 lines max so very long phrases stay contained. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: 500;
  transition: opacity 0.25s ease-out;
}
.vc-live-text.fading {
  opacity: 0;
}
.vc-live-text:empty::before {
  content: 'Tocá el micrófono y hablá…';
  color: #64748b;
  font-style: italic;
  font-weight: 400;
}
.vc-live-counter {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  color: #94a3b8;
  font-size: 0.72rem;
  white-space: nowrap;
  font-weight: 600;
  padding: 0.15rem 0.45rem;
  border-radius: 0.35rem;
  background: rgba(30, 41, 59, 0.7);
}
.vc-live-transcript.dictating .vc-live-counter {
  color: #fca5a5;
  background: rgba(127, 29, 29, 0.6);
}

/* ── Quick-mic FAB ────────────────────────────────────────────
   Body-level FIXED so it floats above everything on the page,
   never gets clipped, and always reachable for taps. Sits at
   bottom-right of the viewport, ABOVE the live transcript bar
   (which is at bottom:1rem). Pulses indigo when idle; red/amber
   while dictating. Big enough for thumb on mobile. */
.vc-quickmic-btn {
  position: fixed;
  bottom: 4.5rem;     /* above transcript (1rem + 2.4em + gap) */
  right: 1rem;
  width: 3.6rem;
  height: 3.6rem;
  border-radius: 50%;
  background: rgba(79, 70, 229, 0.95);
  color: #fff;
  border: 2px solid rgba(255, 255, 255, 0.3);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.55),
              0 0 0 0 rgba(99, 102, 241, 0.6);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  animation: vc-quickmic-idle 2.4s ease-in-out infinite;
  transition: background 0.18s, transform 0.12s;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;   /* removes 300ms tap delay on mobile */
  padding: 0;                   /* avoid native button padding */
}
.vc-quickmic-btn:hover { background: rgba(99, 102, 241, 1); }
.vc-quickmic-btn:active { transform: scale(0.93); }
.vc-quickmic-icon {
  width: 1.6rem;
  height: 1.6rem;
}
/* Idle: gentle indigo halo to draw attention. */
@keyframes vc-quickmic-idle {
  0%, 100% { box-shadow: 0 8px 22px rgba(0,0,0,0.45), 0 0 0  0px rgba(99,102,241,0.55); }
  50%      { box-shadow: 0 8px 22px rgba(0,0,0,0.45), 0 0 0 12px rgba(99,102,241,0.00); }
}
/* Active = dictating. Two flavours depending on what happens with
   each final phrase:
   - .mode-send  → red, fast pulse: each phrase auto-sends to chat/PM.
   - .mode-append → amber, slower pulse: each phrase appends to the
                    input, operator hits Send manually. */
.vc-quickmic-btn.active.mode-send {
  background: rgba(220, 38, 38, 0.95);
  animation: vc-quickmic-active 1s ease-in-out infinite;
}
.vc-quickmic-btn.active.mode-send:hover { background: rgba(239, 68, 68, 1); }
.vc-quickmic-btn.active.mode-append {
  background: rgba(217, 119, 6, 0.95);
  animation: vc-quickmic-active-amber 1.4s ease-in-out infinite;
}
.vc-quickmic-btn.active.mode-append:hover { background: rgba(245, 158, 11, 1); }
/* Plain .active fallback (shouldn't normally fire — bindQuickMicButton
   always sets either mode-send or mode-append). Stays red as safety. */
.vc-quickmic-btn.active:not(.mode-send):not(.mode-append) {
  background: rgba(220, 38, 38, 0.95);
  animation: vc-quickmic-active 1s ease-in-out infinite;
}
@keyframes vc-quickmic-active {
  0%, 100% { box-shadow: 0 8px 22px rgba(0,0,0,0.45), 0 0 0  0px rgba(239,68,68,0.7); }
  50%      { box-shadow: 0 8px 22px rgba(0,0,0,0.45), 0 0 0 14px rgba(239,68,68,0.00); }
}
@keyframes vc-quickmic-active-amber {
  0%, 100% { box-shadow: 0 8px 22px rgba(0,0,0,0.45), 0 0 0  0px rgba(245,158,11,0.7); }
  50%      { box-shadow: 0 8px 22px rgba(0,0,0,0.45), 0 0 0 14px rgba(245,158,11,0.00); }
}
/* Disabled state (no SpeechRecognition support, etc). */
.vc-quickmic-btn.disabled {
  background: rgba(71, 85, 105, 0.6);
  animation: none;
  cursor: not-allowed;
  opacity: 0.6;
}

/* When the iOS frozen-camera overlay is up, hide the FAB / transcript
   / menu so they don't cover the "Reanudar cámara" button. Body class
   is toggled by show/hideFrozenOverlay in app.js. */
body.frozen-active .vc-quickmic-btn,
body.frozen-active .vc-live-transcript,
body.frozen-active .vc-quickmic-menu {
  display: none !important;
}

/* ── Quick-mic popover menu ──────────────────────────────────
   Body-level FIXED so it floats above all page content. Anchored
   above the FAB (FAB at bottom: 4.5rem + 3.6rem tall = top at
   8.1rem). Menu sits at bottom: 8.7rem (small gap). */
.vc-quickmic-menu {
  position: fixed;
  right: 1rem;
  bottom: 8.7rem;
  min-width: 17rem;
  max-width: calc(100vw - 2rem);
  background: rgba(15, 23, 42, 0.98);
  border: 1px solid rgba(99, 102, 241, 0.55);
  border-radius: 0.65rem;
  padding: 0.4rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  z-index: 10000;     /* above FAB */
  box-shadow: 0 14px 38px rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transform-origin: bottom right;
  transition: opacity 0.16s ease-out, transform 0.16s ease-out;
}
.vc-quickmic-menu.hidden {
  display: none;
}
.vc-qm-item {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.55rem 0.7rem;
  background: transparent;
  border: none;
  border-radius: 0.45rem;
  color: #e2e8f0;
  text-align: left;
  cursor: pointer;
  width: 100%;
  font: inherit;
  transition: background 0.12s;
  -webkit-tap-highlight-color: transparent;
}
.vc-qm-item:hover,
.vc-qm-item:focus-visible {
  background: rgba(99, 102, 241, 0.18);
  outline: none;
}
.vc-qm-item:active {
  background: rgba(99, 102, 241, 0.32);
}
.vc-qm-emoji {
  font-size: 1.25rem;
  flex: 0 0 auto;
  width: 1.6rem;
  text-align: center;
}
.vc-qm-body {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}
.vc-qm-title {
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.15;
}
.vc-qm-sub {
  font-size: 0.72rem;
  color: #94a3b8;
  line-height: 1.25;
}
.vc-qm-cancel {
  margin-top: 0.15rem;
  border-top: 1px solid rgba(99, 102, 241, 0.18);
  padding-top: 0.55rem;
  border-radius: 0 0 0.45rem 0.45rem;
}
.vc-qm-cancel .vc-qm-title { color: #94a3b8; font-weight: 500; }
.vc-qm-cancel:hover { background: rgba(248, 113, 113, 0.12); }

/* Click-to-copy VLC URL pill inside the voice-monitor status. */
.vc-status code.vc-vlc-url {
  display: inline-block;
  padding: 2px 6px;
  margin-top: 4px;
  border-radius: 4px;
  background: #1e293b;
  color: #fbbf24;
  font-family: monospace;
  font-size: 0.7rem;
  word-break: break-all;
  border: 1px dashed #475569;
}
.vc-status code.vc-vlc-url:hover {
  background: #334155;
  border-color: #fbbf24;
}

/* Voice-changer live transcript panel inside the 🎤 modal. */
.vc-transcript-section {
  margin-top: 0.875rem;
  padding-top: 0.875rem;
  border-top: 1px solid #334155;
}
.vc-transcript-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #64748b;
  font-weight: 600;
  margin-bottom: 0.4rem;
}
.vc-transcript-hint {
  font-size: 0.65rem;
  color: #475569;
  text-transform: none;
  letter-spacing: 0;
}
.vc-transcript-panel {
  max-height: 200px;
  overflow-y: auto;
  background: #0f172a;
  border: 1px solid #1e293b;
  border-radius: 0.4rem;
  padding: 0.4rem 0.5rem;
  font-family: ui-monospace, "SF Mono", monospace;
  font-size: 0.7rem;
  line-height: 1.5;
}
.vc-transcript-panel:empty::before {
  content: "Esperando audio... habla con voice-changer ON.";
  color: #475569;
  font-style: italic;
}
.vc-transcript-line {
  color: #e2e8f0;
  padding: 1px 0;
  word-break: break-word;
}
.vc-transcript-line .vc-tr-time {
  color: #64748b;
  margin-right: 0.3rem;
}
.vc-transcript-line .vc-tr-text {
  color: #fbbf24;
}
.vc-transcript-line .vc-tr-ms {
  color: #475569;
  font-size: 0.65rem;
  margin-left: 0.3rem;
}
.vc-transcript-line .vc-tr-skip {
  color: #475569;
  font-style: italic;
}
.vc-transcript-line.vc-transcript-halluc {
  color: #fecaca;
}
.vc-transcript-line.vc-transcript-halluc .vc-tr-text {
  color: #fca5a5;
  text-decoration: line-through;
  text-decoration-color: #ef4444;
}
.vc-transcript-line.vc-transcript-skipped {
  opacity: 0.5;
}
.vc-transcript-line.vc-transcript-trace {
  background: rgba(251, 191, 36, 0.06);
  border-left: 2px solid #f59e0b;
  padding-left: 6px;
}
.vc-transcript-line.vc-transcript-trace .vc-tr-time {
  color: #fbbf24;
  font-weight: 600;
}
.vc-transcript-line.vc-transcript-trace .vc-tr-ms {
  color: #94a3b8;
  font-size: 0.78rem;
}

/* Voice-changer engine selector (Local/Browser/Auto). */
.vc-engine-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid #334155;
}
.vc-engine-label {
  font-size: 0.75rem;
  color: #e2e8f0;
  font-weight: 600;
}
.vc-engine-select {
  background: #1e293b;
  border: 1px solid #475569;
  color: #e2e8f0;
  font-size: 0.75rem;
  padding: 0.35rem 0.5rem;
  border-radius: 0.4rem;
  outline: none;
}
.vc-engine-select:focus {
  border-color: #10b981;
}
.vc-engine-hint {
  font-size: 0.65rem;
  color: #94a3b8;
  margin-top: 0.3rem;
  line-height: 1.4;
  min-height: 1.2em;
}
.vc-engine-hint.vc-engine-hint-warn {
  color: #fbbf24;
}
.vc-engine-hint.vc-engine-hint-ok {
  color: #10b981;
}

/* ── iOS camera-freeze overlay (Phase A) ───────────────────── */
#capture-frozen-overlay {
  /* Layout already on the element via Tailwind classes; we add visual
     polish + an indeterminate spinner. Visible only when JS removes
     the .hidden class; otherwise display:none from Tailwind. */
  backdrop-filter: blur(2px);
}
#capture-frozen-overlay.capture-frozen-hard {
  background: rgba(120, 53, 15, 0.85);
}
.frozen-spinner {
  width: 2rem;
  height: 2rem;
  border: 3px solid rgba(248, 250, 252, 0.25);
  border-top-color: #f8fafc;
  border-radius: 50%;
  animation: frozen-spin 0.9s linear infinite;
}
@keyframes frozen-spin {
  to { transform: rotate(360deg); }
}

/* ── Standalone (Add-to-Home-Screen) nudge modal (Phase B) ── */
.standalone-nudge-body p {
  color: #cbd5e1;
  font-size: 0.9rem;
  margin: 0 0 0.75rem 0;
  line-height: 1.5;
}
.standalone-nudge-body strong { color: #f8fafc; }
.standalone-nudge-steps {
  list-style: decimal;
  padding-left: 1.25rem;
  margin: 0 0 0.75rem 0;
  color: #e2e8f0;
  font-size: 0.9rem;
  line-height: 1.6;
}
.standalone-nudge-note {
  color: #94a3b8;
  font-size: 0.8rem;
  font-style: italic;
}
.standalone-nudge-remember {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.75rem;
  font-size: 0.85rem;
  color: #cbd5e1;
  cursor: pointer;
}
.standalone-nudge-foot {
  display: flex;
  justify-content: flex-end;
  margin-top: 1rem;
}
.standalone-nudge-btn {
  background: #4f46e5;
  color: #fff;
  border: none;
  border-radius: 0.375rem;
  padding: 0.5rem 1rem;
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
}
.standalone-nudge-btn:hover { background: #4338ca; }

/* ── Navegadores ON/OFF panel (inside modal) ──────────────── */
.browsers-panel {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
/* When mounted inside the modal panel we drop the surrounding
   border/background — the modal already has them. */
.browsers-panel-modal {
  background: transparent;
  border: none;
  padding: 0;
}
.browsers-bulk-actions {
  display: flex;
  gap: 0.5rem;
  justify-content: flex-end;
}
.btn-bulk {
  background: rgba(16, 185, 129, 0.18);
  color: #6ee7b7;
  border: 1px solid rgba(16, 185, 129, 0.35);
  border-radius: 0.375rem;
  padding: 0.3rem 0.65rem;
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.btn-bulk:hover { background: rgba(16, 185, 129, 0.28); }
.btn-bulk[disabled] { opacity: 0.5; cursor: not-allowed; }
.btn-bulk-danger {
  background: rgba(239, 68, 68, 0.18);
  color: #fca5a5;
  border-color: rgba(239, 68, 68, 0.35);
}
.btn-bulk-danger:hover { background: rgba(239, 68, 68, 0.28); }
.browsers-offline {
  background: rgba(245, 158, 11, 0.12);
  border: 1px solid rgba(245, 158, 11, 0.4);
  color: #fcd34d;
  border-radius: 0.375rem;
  padding: 0.5rem 0.7rem;
  font-size: 0.8rem;
  margin-bottom: 0.5rem;
}
.browsers-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 0.5rem;
}
.browser-card {
  background: rgba(15, 23, 42, 0.75);
  border: 1px solid rgba(71, 85, 105, 0.5);
  border-radius: 0.45rem;
  padding: 0.55rem 0.65rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.browser-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
}
.browser-platform {
  font-weight: 600;
  color: #e2e8f0;
  font-size: 0.88rem;
  text-transform: capitalize;
}
.browser-username {
  font-size: 0.72rem;
  color: #94a3b8;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 50%;
}
.browser-card-status {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.78rem;
}
.status-dot {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: #64748b;
  flex-shrink: 0;
}
.browser-card-status[data-status="off"]            { color: #94a3b8; }
.browser-card-status[data-status="off"]    .status-dot { background: #64748b; }
.browser-card-status[data-status="stopped"]        { color: #94a3b8; }
.browser-card-status[data-status="stopped"] .status-dot { background: #64748b; }
.browser-card-status[data-status="launching"]      { color: #fcd34d; }
.browser-card-status[data-status="launching"] .status-dot,
.browser-card-status[data-status="navigating_home"] .status-dot,
.browser-card-status[data-status="navigating_chat"] .status-dot {
  background: #facc15;
  animation: browser-pulse 1.1s ease-in-out infinite;
}
.browser-card-status[data-status="navigating_home"] { color: #fcd34d; }
.browser-card-status[data-status="navigating_chat"] { color: #fcd34d; }
.browser-card-status[data-status="awaiting_login"]  { color: #fdba74; }
.browser-card-status[data-status="awaiting_login"] .status-dot {
  background: #fb923c;
  animation: browser-pulse 1.4s ease-in-out infinite;
}
.browser-card-status[data-status="connected"],
.browser-card-status[data-status="running"]        { color: #6ee7b7; }
.browser-card-status[data-status="connected"] .status-dot,
.browser-card-status[data-status="running"]   .status-dot { background: #10b981; }
.browser-card-status[data-status="error"]          { color: #fca5a5; }
.browser-card-status[data-status="error"] .status-dot { background: #ef4444; }
.browser-card-status[data-status="offline"]        { color: #94a3b8; }
.browser-card-status[data-status="offline"] .status-dot { background: #475569; }
@keyframes browser-pulse {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 currentColor; }
  50%      { opacity: 0.55; box-shadow: 0 0 0 4px transparent; }
}
.browser-card-actions {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  justify-content: space-between;
}
.browser-toggle {
  background: rgba(16, 185, 129, 0.18);
  color: #6ee7b7;
  border: 1px solid rgba(16, 185, 129, 0.4);
  border-radius: 0.35rem;
  padding: 0.3rem 0.65rem;
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
}
.browser-toggle:hover { background: rgba(16, 185, 129, 0.28); }
.browser-toggle[data-action="stop"] {
  background: rgba(239, 68, 68, 0.18);
  color: #fca5a5;
  border-color: rgba(239, 68, 68, 0.4);
}
.browser-toggle[data-action="stop"]:hover { background: rgba(239, 68, 68, 0.28); }
.browser-toggle[disabled] { opacity: 0.5; cursor: not-allowed; }
.browser-card-flags {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  flex-wrap: wrap;
}
.browser-always-on {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.72rem;
  color: #cbd5e1;
  cursor: pointer;
  user-select: none;
}
.browser-always-on input[type="checkbox"] {
  width: 14px;
  height: 14px;
  accent-color: #6366f1;
  cursor: pointer;
}

/* Always-visible banner that surfaces external-camera state on the
   dashboard. Color-coded via data-state so the operator can tell at
   a glance whether the paired phone is alive + sending frames. */
.ext-cam-banner {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.55rem 0.8rem;
  border-radius: 0.5rem;
  border: 1px solid rgba(71, 85, 105, 0.5);
  background: rgba(15, 23, 42, 0.85);
  margin-bottom: 0.6rem;
  font-size: 0.85rem;
}
.ext-cam-banner-dot {
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 50%;
  background: #64748b;
  flex-shrink: 0;
}
.ext-cam-banner[data-state="ok"]      { border-color: rgba(16, 185, 129, 0.4); }
.ext-cam-banner[data-state="ok"]      .ext-cam-banner-dot { background: #10b981; }
.ext-cam-banner[data-state="silent"]  { border-color: rgba(217, 119, 6, 0.45); }
.ext-cam-banner[data-state="silent"]  .ext-cam-banner-dot { background: #d97706; animation: ext-cam-pulse 1.4s infinite; }
.ext-cam-banner[data-state="offline"] { border-color: rgba(239, 68, 68, 0.45); }
.ext-cam-banner[data-state="offline"] .ext-cam-banner-dot { background: #ef4444; }
@keyframes ext-cam-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.4; }
}
.ext-cam-banner-text {
  flex: 1;
  display: flex;
  flex-direction: column;
  line-height: 1.25;
}
.ext-cam-banner-text strong { color: #f1f5f9; font-weight: 600; }
.ext-cam-banner-sub { color: #94a3b8; font-size: 0.72rem; }
.ext-cam-banner-btn {
  background: transparent;
  border: 1px solid transparent;
  color: #94a3b8;
  border-radius: 0.4rem;
  padding: 0.25rem 0.5rem;
  cursor: pointer;
  font-size: 1rem;
}
.ext-cam-banner-btn:hover { color: #f1f5f9; background: rgba(71, 85, 105, 0.4); }

/* Slot that replaces #preview-video / #preview-canvas when ext-cam is on. */
.ext-cam-preview-wrap {
  position: relative;
  width: 100%;
  max-height: 30vh;
  min-height: 180px;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ext-cam-preview-wrap img {
  width: 100%;
  max-height: 30vh;
  object-fit: contain;
  display: none;          /* unhidden by JS when first frame arrives */
}
.ext-cam-preview-wrap.has-frame img { display: block; }
.ext-cam-preview-wrap.has-frame .ext-cam-preview-placeholder { display: none; }
.ext-cam-preview-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  text-align: center;
}

/* Banner at the top of the Video panel announcing that the chips
   below currently target the remote (paired-phone) camera. Toggled
   by the JS whenever _extCamPref flips. */
.video-panel-mode-hint {
  background: rgba(99, 102, 241, 0.14);
  border: 1px solid rgba(99, 102, 241, 0.4);
  color: #c7d2fe;
  border-radius: 0.4rem;
  padding: 0.45rem 0.65rem;
  font-size: 0.78rem;
  margin-bottom: 0.5rem;
}

/* Marker on the platform-trigger button — small 📷 to the right of
   the favicon row whenever ext-cam mode is on. Stays visible
   regardless of stream state so the operator sees at a glance
   "video source = external phone". */
.platform-trigger.ext-camera-active::after {
  content: "📷";
  font-size: 0.9rem;
  margin-left: 0.25rem;
  vertical-align: middle;
}

/* External-camera pair modal: QR + URL + 6-char code. The QR is the
   primary entry point ("aim the other phone at this"); URL and code
   are the fallbacks for when QR scanning isn't possible (older
   Androids without a system QR scanner, etc.). */
.ext-cam-pair-body { color: #cbd5e1; }
.ext-cam-pair-qr {
  background: #f8fafc;
  border-radius: 0.5rem;
  padding: 0.6rem;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 220px;
  margin-bottom: 0.5rem;
}
.ext-cam-pair-qr svg { display: block; width: 220px; height: 220px; }
.ext-cam-pair-qr-loading {
  font-size: 0.85rem;
  color: #64748b;
}
.ext-cam-pair-divider {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: #64748b;
  font-size: 0.75rem;
  margin: 0.8rem 0;
}
.ext-cam-pair-divider::before,
.ext-cam-pair-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: #334155;
}
.ext-cam-pair-url {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  background: #0f172a;
  border: 1px solid #334155;
  padding: 0.5rem 0.7rem;
  border-radius: 0.4rem;
  font-size: 0.8rem;
  color: #93c5fd;
  word-break: break-all;
}
.ext-cam-pair-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 2.4rem;
  text-align: center;
  letter-spacing: 0.3em;
  background: #1e293b;
  border: 1px solid #334155;
  padding: 1rem;
  border-radius: 0.5rem;
  color: #f8fafc;
  margin: 0.5rem 0 0.2rem;
}

/* Global "Invisible" toggle in the modal head — process-wide flag
   that applies to every platform of the operator at once, since
   Chrome's headless mode can't be split per-tab. */
.browsers-global-headless {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.8rem;
  color: #cbd5e1;
  cursor: pointer;
  user-select: none;
  margin-right: 0.5rem;
}
.browsers-global-headless input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: #6366f1;
  cursor: pointer;
}

