/* voice_modal.css — styles for the shared voice-creation modal.
 *
 * Loaded by both the main app page and the admin global-voices page so
 * the modal renders correctly on either. Only depends on base.css
 * (.btn, .form-row).
 */

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.5);
  z-index: 60;
  display: none;
  align-items: center;
  justify-content: center;
}
.modal-backdrop[data-open="true"] { display: flex; }

.modal {
  background: #ffffff;
  border-radius: 12px;
  width: min(520px, 92vw);
  max-height: 90vh;
  overflow-y: auto;
  padding: 20px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.2);
}

/* Widen when the shared step-2 editor is visible (both upload + YouTube
 * paths land in it and need horizontal room for the waveform). */
.modal:has(.vc-step--editor:not([hidden])) {
  width: min(960px, 96vw);
}

.modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}
.modal__close {
  background: transparent;
  border: none;
  font-size: 18px;
  cursor: pointer;
  color: #6b7280;
}
.modal__tabs {
  display: flex;
  /* Wrap whole tabs onto a second row rather than letting flex-shrink
   * compress each button below its label's natural width — that used
   * to force mid-word wraps ("From" / "YouTube" on separate lines)
   * while short labels like "Record" stayed one line, leaving each
   * tab's underline at a different height. */
  flex-wrap: wrap;
  gap: 6px 10px;
  border-bottom: 1px solid #e5e7eb;
  margin-bottom: 14px;
}
.modal__tab {
  padding: 8px 14px;
  border: none;
  background: transparent;
  font-weight: 500;
  color: #6b7280;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  font-size: 14px;
  white-space: nowrap;
}
.modal__tab[data-active="true"] {
  color: #1e40af;
  border-bottom-color: #1e40af;
}
.modal__panel { display: none; }
.modal__panel[data-active="true"] { display: block; }
.modal__footer {
  margin-top: 16px;
  display: flex;
  gap: 10px;
  justify-content: flex-end;
}

.upload-status {
  font-size: 13px;
  color: #6b7280;
  margin-top: 10px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

/* Inline spinner used inside upload-status while a download/transcode
 * is in progress. The .vc-spinner element is added by JS via setStatus
 * with kind="busy"; CSS keyframe is local so the modal partial doesn't
 * depend on main.css. */
.vc-spinner {
  display: inline-block;
  width: 12px;
  height: 12px;
  border: 2px solid rgba(79, 70, 229, 0.25);
  border-top-color: #1e40af;
  border-radius: 50%;
  animation: vc-spin 0.9s linear infinite;
  flex-shrink: 0;
}
@keyframes vc-spin { to { transform: rotate(360deg); } }

/* Elapsed-time counter shown next to the spinner. */
.vc-elapsed {
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 12px;
  color: #1e3a8a;
  font-weight: 600;
}

/* --- Voice modal: file upload drop-zone ----------------------------- */
.vc-drop {
  position: relative;
  padding: 28px 20px;
  border: 2px dashed #bfdbfe;
  border-radius: 12px;
  background: #f5f7ff;
  text-align: center;
  transition: background 120ms ease, border-color 120ms ease;
  cursor: pointer;
}
.vc-drop:hover { background: #eff6ff; border-color: #93c5fd; }
.vc-drop[data-busy="true"] { opacity: 0.6; pointer-events: none; }
.vc-drop input[type="file"] {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  opacity: 0; cursor: pointer;
  z-index: 1;
}
.vc-drop__label {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  pointer-events: none;
}
.vc-drop__icon { font-size: 28px; color: #2563eb; line-height: 1; }
.vc-drop__title { font-size: 15px; font-weight: 600; color: #1f2937; }
.vc-drop__hint { font-size: 12px; color: #6b7280; }
.vc-drop__filename {
  margin-top: 8px; font-size: 12px; color: #1e3a8a;
  font-family: ui-monospace, SFMono-Regular, monospace;
}

/* --- Voice modal: YouTube URL input --------------------------------- */
.vc-url-input {
  width: 100%;
  padding: 10px 12px;
  font-size: 14px;
  font-family: inherit;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  background: #ffffff;
  color: #1f2937;
  box-sizing: border-box;
}
.vc-url-input::placeholder { color: #9ca3af; font-family: inherit; }
.vc-url-input:focus { outline: 2px solid #bfdbfe; border-color: #1e40af; }

.vc-entry-actions {
  display: flex; align-items: center; gap: 12px;
  margin: 12px 0 8px;
}
.vc-step--editor[hidden] { display: none; }

/* --- Terms-of-service acceptance checkbox --------------------------- */
.vc-tos {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  padding: 10px 12px;
  margin: 8px 0 0;
  font-size: 13px;
  line-height: 1.5;
  color: #374151;
  background: #fef3c7;
  border: 1px solid #fde68a;
  border-radius: 8px;
  cursor: pointer;
  user-select: none;
}
.vc-tos input[type="checkbox"] {
  margin-top: 3px;
  width: 16px; height: 16px;
  accent-color: #1e40af;
  flex-shrink: 0;
}
.vc-tos__link {
  color: #1e3a8a;
  font-weight: 600;
  text-decoration: underline;
}
.vc-tos__link:hover { color: #1e3a8a; }

/* Transient attention flash applied by voice_modal.js when the user
   tries to finish without ticking the box. Pure CSS animation so it
   self-clears; JS just toggles the class and removes it on
   animationend. Red ring + amber pulse reads as "look here" without
   being a permanent error state. */
@keyframes vc-tos-flash {
  0%, 100% { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0); }
  20%      { box-shadow: 0 0 0 4px rgba(220, 38, 38, 0.45); }
  60%      { box-shadow: 0 0 0 4px rgba(220, 38, 38, 0.25); }
}
.vc-tos--flash {
  animation: vc-tos-flash 1s ease-in-out 2;
  border-color: #dc2626;
}

/* --- Terms-of-service modal ----------------------------------------- */
.tos-modal-backdrop { z-index: 70; }
.modal.tos-modal { width: min(720px, 94vw); }

.tos-body {
  max-height: 60vh;
  overflow-y: auto;
  padding: 4px 4px 8px;
  font-size: 13.5px;
  line-height: 1.6;
  color: #1f2937;
}
.tos-updated {
  font-size: 12px;
  color: #6b7280;
  margin: 0 0 12px;
}
.tos-body h3 {
  font-size: 14px;
  margin: 18px 0 6px;
  color: #111827;
}
.tos-body h3:first-of-type { margin-top: 8px; }
.tos-body p { margin: 0 0 8px; }
.tos-body ul {
  margin: 0 0 10px;
  padding-left: 20px;
}
.tos-body li { margin-bottom: 4px; }
.tos-footer {
  margin-top: 16px !important;
  padding: 10px 12px;
  background: #eff6ff;
  border: 1px solid #1e40af;
  border-radius: 4px;
  font-size: 13px;
}

/* --- Record tab ----------------------------------------------------- */
/* The .vc-rec-step container carries data-rec-state so child elements
 * (tips / timer) can show or hide without the JS having to touch them
 * individually. States: idle | recording | review | done. */
.vc-rec-step { display: flex; flex-direction: column; gap: 12px; }

.vc-rec {
  display: flex; flex-direction: column; align-items: center;
  gap: 8px;
  padding: 12px 16px;
  background: #f9fafb;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  text-align: center;
}
.vc-rec__status {
  font-size: 13px;
  color: #6b7280;
}
.vc-rec__status[data-state="recording"] { color: #b91c1c; font-weight: 600; }
.vc-rec__status[data-state="done"] { color: #065f46; font-weight: 600; }
.vc-rec__status[data-state="review"] { color: #1e3a8a; font-weight: 600; }
.vc-rec__timer {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 32px;
  font-weight: 600;
  color: #1f2937;
  font-variant-numeric: tabular-nums;
}
.vc-rec__timer[hidden] { display: none; }

/* Collapse the whole status/timer box when it has nothing to show
 * (idle: empty status + hidden timer). Without this it renders as an
 * empty grey bar wedged between the sample sentence and the record
 * button. Content-driven via :has() rather than data-rec-state
 * because recStatus() writes the "Đang xin quyền…" message while
 * state is still effectively idle (state || 'idle' fallback) — a
 * state-based hide would swallow that message. The box reappears the
 * instant status gets text or the timer unhides. */
.vc-rec:has(.vc-rec__status:empty):has(.vc-rec__timer[hidden]) {
  display: none;
}

/* When recording, drop the tips and pump up the sample text + timer so
 * the reader can focus on what to say. */
.vc-rec-step[data-rec-state="recording"] .vc-rec__tips { display: none; }
.vc-rec-step[data-rec-state="recording"] .vc-rec__sample-text {
  font-size: 17px;
  line-height: 1.7;
}
.vc-rec-step[data-rec-state="recording"] .vc-rec__sample-refresh { display: none; }

/* Review step: hide the sample sentence, tips and record button — only
 * the playback + Ghi lại / Dùng đoạn này actions make sense here. */
.vc-rec-step[data-rec-state="review"] .vc-rec__tips,
.vc-rec-step[data-rec-state="review"] .vc-rec__sample,
.vc-rec-step[data-rec-state="review"] .vc-rec__controls {
  display: none;
}
.vc-rec__review {
  display: none;
  flex-direction: column;
  gap: 10px;
  padding: 12px 16px;
  background: #eff6ff;
  border: 1px solid #bfdbfe;
  border-radius: 12px;
}
.vc-rec-step[data-rec-state="review"] .vc-rec__review { display: flex; }
.vc-rec__review-actions {
  display: flex; gap: 10px; justify-content: center;
}
.vc-rec__review-actions .btn { flex: 1 1 0; max-width: 220px; }

.vc-rec__controls { display: flex; gap: 10px; justify-content: center; }
/* Sticky controls — primarily for mobile so the record button never
 * disappears below the fold. Sits at the bottom of the modal scroll
 * area with a soft fade so content scrolling underneath stays legible. */
.vc-rec__controls--sticky {
  position: sticky;
  bottom: -20px;          /* cancels modal's 20px bottom padding */
  margin: 4px -20px -20px;
  padding: 12px 16px 16px;
  background: linear-gradient(to top, #ffffff 70%, rgba(255, 255, 255, 0));
  z-index: 5;
}
.vc-rec__btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 18px;
  font-size: 14px;
  font-weight: 600;
  font-family: inherit;
  border-radius: 999px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 100ms ease, transform 60ms ease;
}
.vc-rec__btn--record {
  background: #dc2626; color: #ffffff; border-color: #b91c1c;
}
.vc-rec__btn--record:hover { background: #b91c1c; }
.vc-rec__btn--record:active { transform: scale(0.96); }
.vc-rec__btn--record:disabled { background: #fca5a5; cursor: not-allowed; }
.vc-rec__btn--stop {
  background: #1f2937; color: #ffffff; border-color: #111827;
}
.vc-rec__btn--stop:hover { background: #111827; }
.vc-rec__icon {
  width: 10px; height: 10px; display: inline-block;
}
.vc-rec__icon--dot {
  border-radius: 50%;
  background: #ffffff;
  animation: vc-rec-pulse 1.2s ease-in-out infinite;
}
.vc-rec__btn:disabled .vc-rec__icon--dot { animation: none; }
.vc-rec__icon--square {
  background: #ffffff; border-radius: 2px;
}
@keyframes vc-rec-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.5; transform: scale(0.8); }
}

/* Sample text for recording */
.vc-rec__sample {
  width: 100%;
  background: #f9fafb;
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  padding: 12px 14px;
  text-align: left;
}

.vc-rec__sample-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
}

.vc-rec__sample-label {
  font-size: 12px;
  font-weight: 600;
  color: #6b7280;
  text-transform: uppercase;
  letter-spacing: 0.3px;
}

.vc-rec__sample-text {
  margin: 0;
  font-size: 15px;
  line-height: 1.6;
  color: #1f2937;
  font-style: italic;
  border: 1px solid #1e40af;
  padding: 10px 12px;
  background: #ffffff;
  border-radius: 6px;
}

.vc-rec__sample-refresh {
  padding: 4px 10px;
  font-size: 12px;
  color: #1e40af;
  background: transparent;
  border: 1px solid #bfdbfe;
  border-radius: 6px;
  cursor: pointer;
  transition: all 120ms ease;
  white-space: nowrap;
}

.vc-rec__sample-refresh:hover {
  background: #eff6ff;
  border-color: #1e40af;
}

/* --- Shared step-2 editor (waveform + range + STT) ------------------- */

.yt-hint {
  font-size: 12px;
  color: #6b7280;
  margin: 8px 0 0;
  line-height: 1.5;
}

.yt-title {
  font-size: 13px;
  font-weight: 600;
  color: #374151;
  margin-bottom: 6px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.yt-wave-wrap {
  position: relative;
  background: #f3f4f6;
  border-radius: 6px;
  margin-bottom: 8px;
  overflow-x: auto;
  overflow-y: hidden;
}

.yt-wave {
  position: relative;
  height: 100px;
  /* width set inline by JS = duration * pxPerSec */
}

.yt-wave canvas { display: block; }

/* Mobile-only scroll aid — see the aria-hidden div in _voice_modal.html
 * for why this exists. Hidden by default (and whenever there's nothing
 * to scroll, via data-active); the max-width:600px block below reveals
 * it. Thick + high-contrast on purpose: it has to be an easy touch
 * target, not a subtle native scrollbar sliver. */
.yt-wave-scrollbar {
  display: none;
  position: relative;
  height: 22px;
  margin: 2px 0 8px;
  background: #e5e7eb;
  border-radius: 999px;
  touch-action: none;
}
.yt-wave-scrollbar[data-active="false"] { display: none; }
.yt-wave-scrollbar__thumb {
  position: absolute;
  top: 3px;
  left: 0;
  height: 16px;
  min-width: 32px;
  background: #2563eb;
  border-radius: 999px;
}

.yt-zoom {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
  font-size: 12px;
  color: #6b7280;
  flex-wrap: wrap;
}
/* [−] [Nx] [+] grouped as one visual control. The level pill in the
 * middle is read-only — it tracks state.pxPerSec and updates via
 * `_pxToNearestLevel` so pinch-zoom and step-buttons stay in sync. */
.yt-zoom__group {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid #d1d5db;
  border-radius: 6px;
  overflow: hidden;
  background: #ffffff;
}
.yt-zoom__group .yt-zoom__btn--step {
  border: none;
  border-radius: 0;
  padding: 4px 12px;
  min-width: 32px;
  font-size: 16px;
  line-height: 1;
  font-weight: 600;
  color: #374151;
}
.yt-zoom__group .yt-zoom__btn--step:hover { background: #f3f4f6; }
.yt-zoom__level {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  padding: 0 8px;
  font-size: 13px;
  font-weight: 600;
  color: #1f2937;
  background: #f9fafb;
  border-left: 1px solid #d1d5db;
  border-right: 1px solid #d1d5db;
  /* Tabular numerals so "1x" and "12x" don't shift the [+] button
   * sideways as the level changes. */
  font-variant-numeric: tabular-nums;
}
.yt-zoom__btn {
  padding: 4px 10px;
  border: 1px solid #d1d5db;
  background: #ffffff;
  border-radius: 6px;
  cursor: pointer;
  font-family: inherit;
  font-size: 12px;
  color: #4b5563;
}
.yt-zoom__btn:hover { background: #f3f4f6; }
/* AI auto-pick button — gradient + sparkle accent so the operator
 * sees it as a distinct AI-powered action vs the plain zoom buttons.
 * Same shape as .yt-zoom__btn so it lays out cleanly inside the bar. */
.yt-zoom__btn--ai {
  background: linear-gradient(135deg, #eef2ff 0%, #ede9fe 100%);
  border-color: #c4b5fd;
  color: #5b21b6;
  font-weight: 500;
}
.yt-zoom__btn--ai:hover {
  background: linear-gradient(135deg, #e0e7ff 0%, #ddd6fe 100%);
  border-color: #a78bfa;
}
.yt-zoom__btn--ai:disabled {
  opacity: 0.6;
  cursor: progress;
}

.yt-wave__selection {
  position: absolute;
  top: 0;
  bottom: 0;
  background: rgba(79, 70, 229, 0.15);
  /* Thin 2px edge lines — precise selection boundaries. */
  border: 1px solid #1e40af;
  border-right: 2px solid #1e40af;
  cursor: grab;
  touch-action: none;
  user-select: none;
}
.yt-wave__selection:active { cursor: grabbing; }

/* Handles: visually thin (2px) but with a wider invisible hit-zone
 * (12px on each side) so the user can still grab them comfortably. */
.yt-wave__handle {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  background: #1e40af;
  cursor: ew-resize;
  touch-action: none;
}
.yt-wave__handle::before {
  /* Invisible pointer-capture pad extending 12px either side. */
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  left: -12px; right: -12px;
}
.yt-wave__handle::after {
  /* Small visible grip dot at the vertical center — helps users
   * see where the handle is without thickening the line itself. */
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 8px;
  height: 8px;
  margin: -4px 0 0 -4px;
  background: #1e40af;
  border: 2px solid #ffffff;
  border-radius: 50%;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
.yt-wave__handle--left  { left:  -1px; }
.yt-wave__handle--right { right: -1px; }

.yt-wave__playhead {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  background: #dc2626;
  pointer-events: none;
  z-index: 3;
  box-shadow: 0 0 4px rgba(220, 38, 38, 0.5);
}
.yt-wave__playhead[hidden] { display: none; }

.yt-duration {
  font-size: 13px;
  font-weight: 600;
  color: #1e3a8a;
  margin-bottom: 6px;
}

.yt-range__row {
  display: grid;
  grid-template-columns: 60px auto 1fr auto 90px;
  align-items: center;
  gap: 6px;
  margin-bottom: 8px;
  font-size: 13px;
  color: #374151;
}
.yt-range__row input[type="range"] { width: 100%; }

.yt-range__val {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  color: #4b5563;
  text-align: right;
}
.yt-range__step-group { display: flex; gap: 4px; }
.yt-range__step {
  padding: 4px 10px;
  font-size: 11px;
  font-weight: 600;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  border: 1px solid #bfdbfe;
  background: #eff6ff;
  color: #1e3a8a;
  border-radius: 999px;
  cursor: pointer;
  min-width: 38px;
  line-height: 1.2;
  transition: background 100ms ease, transform 60ms ease;
}
.yt-range__step:hover {
  background: #bfdbfe;
  color: #1e3a8a;
  border-color: #93c5fd;
}
.yt-range__step:active {
  background: #93c5fd;
  transform: scale(0.95);
}

.yt-range__actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 10px 0 14px;
}

/* ============================================================
 * Voice-creation wizard (step indicator, tips, panes, footer).
 * Wraps the shared editor in a 4-step linear flow so non-tech-
 * savvy users see one decision at a time instead of a wall of
 * controls.
 * ============================================================ */

.vc-tips {
  background: #eff6ff;
  border: 1px solid #bfdbfe;
  border-radius: 10px;
  padding: 12px 14px;
  margin: 0 0 16px;
}
.vc-tips--compact { padding: 10px 12px; margin-bottom: 12px; }
.vc-tips__title {
  font-weight: 600;
  font-size: 13px;
  color: #1e40af;
  margin-bottom: 6px;
}
.vc-tips__list {
  margin: 0;
  padding-left: 18px;
  font-size: 13px;
  color: #1f2937;
  line-height: 1.5;
}
.vc-tips__list li { margin-bottom: 2px; }
.vc-tips__body {
  margin: 0 0 8px;
  font-size: 13px;
  color: #1f2937;
  line-height: 1.5;
}
.vc-tips__body:last-child { margin-bottom: 0; }

/* Numbered "how-to" block — concrete action steps so the user knows
 * exactly what to click. Used in step 1 + step 2. */
.vc-tips__howto {
  margin-top: 8px;
  padding: 8px 10px;
  background: #ffffff;
  border: 1px solid #dbeafe;
  border-radius: 6px;
  font-size: 13px;
  color: #1f2937;
}
.vc-tips__steps {
  margin: 4px 0 0 18px;
  padding: 0;
  line-height: 1.65;
}
.vc-tips__pill {
  display: inline-block;
  padding: 1px 8px;
  background: #eef2ff;
  border-radius: 999px;
  color: #3730a3;
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
}
.vc-tips__hint {
  margin: 6px 0 0;
  font-size: 12px;
  color: #6b7280;
  font-style: italic;
}

/* 2-column "TỐT vs Tránh" block in step 1 — quick visual signal of
 * what's good (green tint) vs bad (red tint) so the user can scan
 * without parsing prose. Falls back to single column on narrow modals. */
.vc-tips__cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-top: 8px;
}
@media (max-width: 540px) {
  .vc-tips__cols { grid-template-columns: 1fr; }
}
.vc-tips__col {
  padding: 8px 10px;
  border-radius: 6px;
  font-size: 12px;
  line-height: 1.5;
}
.vc-tips__col--good {
  background: #f0fdf4;
  border: 1px solid #bbf7d0;
}
.vc-tips__col--bad {
  background: #fef2f2;
  border: 1px solid #fecaca;
}
.vc-tips__col-title {
  font-weight: 600;
  margin-bottom: 4px;
  color: #14532d;
}
.vc-tips__col--bad .vc-tips__col-title { color: #991b1b; }
.vc-tips__col .vc-tips__list { font-size: 12px; }
.vc-tips__col .vc-tips__list li { margin-bottom: 1px; }

/* Inline (compact) tip used in step 1 — replaces the prior heavy multi-
 * card layout. One sentence + "Xem thêm" link that opens the help
 * modal for first-time users who want depth. */
.vc-tips--inline {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 10px 12px;
  background: #eff6ff;
  border: 1px solid #bfdbfe;
  border-radius: 8px;
  margin-bottom: 10px;
  font-size: 13px;
  line-height: 1.5;
}
.vc-tips__inline-text { flex: 1 1 auto; color: #1f2937; }
.vc-tips__more {
  flex: 0 0 auto;
  background: transparent;
  border: 0;
  color: #1e40af;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  text-decoration: underline;
  padding: 0;
}
.vc-tips__more:hover { color: #1e3a8a; }

/* Detailed step-1 help popup — TOS-modal sibling. Wider body for the
 * how-to content and image figures. */
.vc-help-modal { max-width: 720px; width: calc(100vw - 24px); }
.vc-help-body { padding: 16px 20px; max-height: 70vh; overflow-y: auto; font-size: 14px; line-height: 1.6; color: #1f2937; }
.vc-help-body h3 { font-size: 14px; font-weight: 600; color: #1e3a8a; margin: 18px 0 8px; }
.vc-help-body p { margin: 0 0 12px; }
.vc-help-list { margin: 0 0 12px; padding-left: 20px; }
.vc-help-list li { margin-bottom: 4px; }
.vc-help-list--good li::marker { color: #16a34a; }
.vc-help-list--bad li::marker { color: #dc2626; }
.vc-help-figure {
  margin: 8px 0 16px;
  padding: 12px;
  background: #f9fafb;
  border: 1px dashed #d1d5db;
  border-radius: 8px;
  text-align: center;
}
.vc-help-figure img { max-width: 100%; height: auto; border-radius: 6px; }
.vc-help-figure__placeholder {
  color: #6b7280;
  font-style: italic;
  font-size: 13px;
  padding: 24px 0;
}

/* Banner shown when the modal is opened in edit mode (✏ Sửa giọng).
 * Sits above the wizard so the operator can't miss they're updating
 * an existing voice rather than creating a new one. */
.vc-edit-banner {
  background: #fef3c7;
  border: 1px solid #fde68a;
  color: #92400e;
  border-radius: 10px;
  padding: 10px 14px;
  margin: 0 0 14px;
  font-size: 13px;
  line-height: 1.5;
}

/* Edit mode: pre-fill the existing voice's metadata so the operator
 * has full context, but keep every field editable — onReplace sends
 * the latest values back to the server. Hide only the ToS (already
 * accepted at create time) and the create-only tip blurbs. The
 * "💾 Lưu giọng" button label + onReplace dispatch carry the actual
 * semantics; everything else behaves like the create flow. */
/* In Sửa giọng mode, hide ONLY the ToS — instructions in steps 3+4
 * stay visible so the operator gets the same onboarding hints they
 * see during create. (Earlier we hid the tips entirely in edit mode;
 * operator feedback was that the empty step 3+4 felt unguided.) */
#voice-modal[data-edit-mode="true"] .vc-wizard-pane[data-wpane="4"] .vc-tos {
  display: none;
}
#voice-modal[data-edit-mode="true"] .vc-required { display: none; }

.vc-wizard-steps {
  display: flex;
  gap: 0;
  list-style: none;
  margin: 0 0 16px;
  padding: 8px 0;
  border-bottom: 1px solid #e5e7eb;
  overflow-x: auto;
}
.vc-wizard-steps li {
  flex: 1 1 auto;
  min-width: 110px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  font-size: 13px;
  color: #9ca3af;
  white-space: nowrap;
  position: relative;
}
.vc-wizard-steps li[data-active="true"] {
  color: #1e40af;
  font-weight: 600;
}
.vc-wizard-steps li[data-done="true"] { color: #047857; }
.vc-wizard-step__num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  background: #f3f4f6;
  color: inherit;
  font-size: 12px;
  font-weight: 700;
  border: 1px solid #e5e7eb;
}
.vc-wizard-steps li[data-active="true"] .vc-wizard-step__num {
  background: #1e40af;
  color: #fff;
  border-color: #1e40af;
}
.vc-wizard-steps li[data-done="true"] .vc-wizard-step__num {
  background: #d1fae5;
  color: #065f46;
  border-color: #a7f3d0;
}

.vc-quick-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 8px 0 4px;
}

/* Step 4 admin-only "Đổi giọng" row — the dropdown + preview button
 * sit on one line so the existing form-row layout stays compact.
 * On mobile they wrap onto two lines naturally via flex-wrap. */
.vc-anon-controls {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.vc-anon-select {
  flex: 1 1 auto;
  min-width: 180px;
  padding: 8px 10px;
  font-size: 14px;
  font-family: inherit;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  background: #ffffff;
  color: #1f2937;
}
.vc-anon-select:focus {
  outline: 2px solid #bfdbfe;
  border-color: #1e40af;
}

/* "Áp dụng bộ lọc" checkbox sitting alongside the preview button. */
.vc-filter-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: #4b5563;
  cursor: pointer;
  user-select: none;
}
.vc-filter-toggle input[type="checkbox"] {
  margin: 0;
  cursor: pointer;
}

.vc-advanced {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px dashed #e5e7eb;
}
[data-action="vc-toggle-advanced"][aria-expanded="true"] {
  background: #eff6ff;
  color: #1e3a8a;
  border-color: #bfdbfe;
}

.vc-wizard-footer {
  margin-top: 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.vc-wizard-footer__nav {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
/* HTML's `hidden` attribute defaults to display:none but the .btn
   utility class's display:inline-flex / inline-block overrides it.
   The wizard footer toggles button visibility via .hidden, so
   re-assert none with !important on these specific buttons. */
.vc-wizard-footer__nav .btn[hidden] { display: none !important; }

/* Pill-button toggle group (Step 3 gender + region). One row of
 * mutually-exclusive choices; the active button gets the indigo fill. */
.vc-choice {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 4px;
}
.vc-choice__btn {
  padding: 8px 14px;
  border: 1px solid #d1d5db;
  background: #ffffff;
  color: #374151;
  border-radius: 999px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
}
.vc-choice__btn:hover {
  border-color: #1e40af;
  color: #1e40af;
}
.vc-choice__btn[data-active="true"] {
  background: #1e40af;
  color: #ffffff;
  border-color: #1e40af;
}

/* Red-star marker for required fields (name + ToS in Step 4). */
.vc-required {
  color: #dc2626;
  font-weight: 700;
  margin-left: 2px;
}

@media (max-width: 600px) {
  /* Modal becomes near-fullscreen on phones — no point wasting margin
   * on a 360px viewport. Less padding lets the waveform breathe.
   * Bottom padding is zero so the sticky wizard footer below sits
   * flush with the modal's edge (the footer carries its own padding). */
  .modal { width: calc(100vw - 12px); padding: 12px 12px 0; border-radius: 10px; }
  .modal:has(.vc-step--editor:not([hidden])) { width: calc(100vw - 12px); }

  .vc-wizard-steps li { min-width: 0; padding: 4px 6px; font-size: 11px; }
  .vc-wizard-step__num { width: 20px; height: 20px; font-size: 11px; }
  .vc-tips { padding: 10px 12px; margin-bottom: 10px; }

  /* Wizard footer becomes a 2-row stack on narrow viewports: "← Chọn
   * nguồn khác" gets its own row above the back/next/finish nav so
   * the primary "Tiếp theo →" never has to share width.
   *
   * Sticky-pinned to the bottom of the modal's scroll viewport so the
   * Next / Finish buttons are always reachable without scrolling past
   * the step's instructions on mobile. The modal itself is the
   * scrolling container (overflow-y: auto, max-height: 90vh), so
   * `position: sticky; bottom: 0` works without extra wrapping.
   * Negative side-margins + matching padding extend the sticky bar
   * to the modal's edge so the white background covers any
   * underlying step content as it scrolls under the footer. */
  .vc-wizard-footer {
    flex-wrap: wrap;
    gap: 8px;
    padding: 10px 12px;
    position: sticky;
    bottom: 0;
    background: #ffffff;
    border-top: 1px solid #e5e7eb;
    box-shadow: 0 -4px 12px rgba(15, 23, 42, 0.08);
    margin-left: -12px;
    margin-right: -12px;
    padding-bottom: max(10px, env(safe-area-inset-bottom));
    z-index: 5;
  }
  .vc-wizard-footer > [data-action="vc-reset"] { flex: 1 1 100%; order: 2; }
  .vc-wizard-footer__nav { flex: 1 1 100%; gap: 8px; order: 1; }
  .vc-wizard-footer__nav button { flex: 1 1 auto; min-height: 40px; }

  /* Quick-actions row (filter checkbox + preview + advanced) can
   * overflow horizontally; allow wrap and even-out tap targets. */
  .vc-quick-actions { flex-wrap: wrap; gap: 6px 8px; }
  .vc-quick-actions .btn { min-height: 36px; }
  .vc-filter-toggle { font-size: 12px; }

  /* Zoom bar on mobile: same [−][4x][+] widget as desktop, but with
   * larger tap targets and the AI-pick button pushed to its own row
   * via flex-wrap when it can't fit alongside. */
  .yt-zoom { gap: 6px 8px; }
  .yt-zoom__btn { padding: 6px 10px; font-size: 12px; min-height: 36px; }
  .yt-zoom__group .yt-zoom__btn--step {
    padding: 6px 14px; min-height: 36px; font-size: 18px;
  }
  .yt-zoom__level { min-width: 44px; font-size: 14px; }

  /* Waveform: shorter on mobile so the wizard tips + footer stay in
   * view without scrolling. Touch-drag still works. */
  .yt-wave-wrap { height: 100px; }
  .yt-wave-wrap__handle { width: 16px; }   /* larger tap target for handle */

  /* Reveal the dedicated scroll bar below the waveform — see
   * .yt-wave-scrollbar's own comment for why desktop doesn't need it. */
  .yt-wave-scrollbar { display: block; }

  /* Step 1 inline tip wraps cleanly on small screens. */
  .vc-tips--inline { flex-wrap: wrap; }
  .vc-tips__more { margin-left: auto; }

  /* Tighter spacing on mobile so the sample sentence is reachable
   * without scrolling, and the record button stays anchored bottom. */
  .vc-rec-step { gap: 8px; }
  .vc-rec__tips { padding: 8px 10px; }
  .vc-rec__tips .vc-tips__list { font-size: 12px; line-height: 1.45; }
  .vc-rec__sample { padding: 10px 12px; }
  .vc-rec__sample-text { font-size: 14px; padding: 8px 10px; }
  .vc-rec { padding: 8px 12px; }
  .vc-rec__timer { font-size: 28px; }
  .vc-rec__btn { padding: 12px 22px; font-size: 15px; }

  /* Desktop sticky offsets (bottom:-20px; margin:4px -20px -20px)
   * cancel the desktop modal's 20px padding. The mobile modal is
   * padding: 12px 12px 0 — no bottom padding to cancel and only 12px
   * sides — so reuse of the desktop negatives left the record button
   * jammed flush against the modal's bottom edge with no breathing
   * room. Re-derive the offsets for the mobile modal box: bleed the
   * side gradient to the 12px edges, give the button real bottom
   * spacing (clears the iOS home indicator via safe-area-inset). */
  .vc-rec__controls--sticky {
    bottom: 0;
    margin: 4px -12px 0;
    padding: 14px 12px max(18px, env(safe-area-inset-bottom));
  }

  /* Help popup: full-screen-ish on mobile so the long instruction is
   * scrollable inside the modal rather than the whole page. */
  .vc-help-modal { width: calc(100vw - 12px); max-height: 92vh; }
  .vc-help-body { padding: 12px 14px; max-height: 75vh; }
}
