  /* ──────────────────────────────────────────────────────────────────────
     Theme tokens. Default is dark. The shared <clipflow-header> web
     component toggles <html class="dark"> based on localStorage.theme,
     so `html:not(.dark)` is light. CSS-only switch — no JS needed in
     this file. Tokens cover surfaces, text, borders, accent, and
     semantic colors. Low-impact / niche literals (terminal-style log
     drawer, isolated decorative hexes) intentionally stay hardcoded so
     the diff stays focused on the high-frequency, theme-bearing ones.
     ──────────────────────────────────────────────────────────────── */
  :root {
    /* Surfaces */
    --bg:           #1a1a1f;
    --surface:      #14141a;
    --surface-2:    #25252c;
    --hover:        #1f1f26;
    --input-bg:     #2a2a2a;
    /* Text */
    --text:         #e8e8e8;
    --text-1:       #e8e8e8;   /* alias of --text; keeps emphasis-picker legible */
    --text-2:       #9ca3af;
    --text-3:       #d1d5db;
    --text-muted:   #6b7280;
    --text-quiet:   #5a6168;
    /* Borders */
    --border:       #3a3a44;
    --border-2:     #4b5563;
    /* Accent */
    --accent:       #6366f1;
    --accent-2:     #a5b4fc;
    --accent-soft:  #c7d2fe;
    --accent-pale:  #e0e7ff;
    --accent-bg:    rgba(99,102,241,0.18);  /* subtle tint for active/selected items (dark) */
    /* Aliases used by popover components (emph-picker, etc.) */
    --bg-2:         #25252c;   /* = --surface-2: floating panel background */
    --bg-3:         rgba(255,255,255,0.06); /* hover tint on panel surface */
    /* Semantic */
    --warning:      #fbbf24;
    --danger:       #ef4444;
    --danger-2:     #f87171;
    --success:      #22c55e;
    --success-2:    #4ade80;
    --info:         #3b82f6;
    --info-2:       #60a5fa;
  }
  html:not(.dark) {
    --bg:           #ffffff;
    --surface:      #f7f7fa;
    --surface-2:    #ececf2;
    --hover:        #e8e8f0;
    --input-bg:     #ffffff;
    --text:         #1a1a23;
    --text-1:       #1a1a23;   /* = --text (light mode) */
    --text-2:       #4b5563;
    --text-3:       #374151;
    --text-muted:   #6b7280;
    --text-quiet:   #8b8ba0;
    --border:       #d8d8e0;
    --border-2:     #c0c0cc;
    --accent:       #6366f1;
    --accent-2:     #4f52d6;
    --accent-soft:  #4f46e5;
    --accent-pale:  #eef2ff;
    --accent-bg:    #eef2ff;   /* = --accent-pale: selected item bg (light) */
    --bg-2:         #ececf2;   /* = --surface-2 (light mode) */
    --bg-3:         #e8e8f0;   /* = --hover: item hover in light mode */
    --warning:      #d97706;
    --danger:       #dc2626;
    --danger-2:     #ef4444;
    --success:      #16a34a;
    --success-2:    #22c55e;
    --info:         #2563eb;
    --info-2:       #3b82f6;
  }

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

  body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    background: var(--bg);
    color: var(--text);
    /* iOS Safari's 100vh extends BELOW the address bar, hiding the top of
       the page under the status bar. 100dvh tracks the dynamic visible
       area, falling back to 100vh on browsers that don't support it. */
    height: 100vh;
    height: 100dvh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    font-feature-settings: "tnum" 0;
  }

  /* ── Header ── */
  header {
    display: flex;
    align-items: center;
    gap: 10px;
    /* env(safe-area-inset-top) pushes content below the iOS notch /
       Dynamic Island when the page is added to Home Screen as a PWA.
       In Safari with the address bar visible it's 0, so no effect. */
    padding: env(safe-area-inset-top) 20px 0;
    padding-left:  max(20px, env(safe-area-inset-left));
    padding-right: max(20px, env(safe-area-inset-right));
    /* Header gets at least 52px CONTENT height; total grows by the
       safe-area inset so the buttons stay below the notch. */
    min-height: 52px;
    background: var(--surface);
    border-bottom: 1px solid var(--surface-2);
    flex-shrink: 0;
  }
  header h1 {
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
    white-space: nowrap;
    letter-spacing: 0.01em;
  }
  header .spacer { flex: 1; }

  .save-status {
    font-size: 11px;
    font-weight: 500;
    padding: 3px 8px;
    border-radius: 4px;
    transition: opacity 0.4s;
    white-space: nowrap;
    opacity: 0;
    letter-spacing: 0.01em;
  }
  .save-status.dirty   { opacity: 1; color: var(--warning); }
  .save-status.saving  { opacity: 1; color: var(--text-muted); }
  .save-status.saved   { opacity: 1; color: var(--success); }

  button#renderBtn {
    background: #16a34a;
    color: #fff;
    border: none;
    border-radius: 6px;
    padding: 8px 18px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s;
    white-space: nowrap;
    display: inline-flex; align-items: center; gap: 7px;
    line-height: 1;
  }
  button#renderBtn:hover    { background: #15803d; }
  button#renderBtn:active   { background: var(--success); }
  button#renderBtn:disabled { background: var(--surface-2); color: var(--text-muted); cursor: not-allowed; }
  button#renderBtn svg { display: block; }

  /* ── Log drawer ── */
  #logDrawer {
    position: fixed;
    bottom: 0; left: 0; right: 0;
    height: 220px;
    background: var(--surface);
    border-top: 1px solid var(--surface-2);
    display: flex;
    flex-direction: column;
    transform: translateY(100%);
    transition: transform 0.25s ease;
    z-index: 100;
    box-shadow: 0 -8px 24px rgba(0,0,0,0.4);
  }
  #logDrawer.open { transform: translateY(0); }

  #logDrawerHeader {
    display: flex;
    align-items: center;
    padding: 9px 14px;
    border-bottom: 1px solid var(--surface-2);
    flex-shrink: 0;
    gap: 10px;
    background: var(--bg);
  }
  #logDrawerTitle {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: var(--text-2);
    flex: 1;
  }
  #logDrawerClose {
    background: none;
    border: 1px solid var(--surface-2);
    color: var(--text-muted);
    cursor: pointer;
    padding: 4px;
    line-height: 0;
    border-radius: 4px;
    transition: color 0.12s, border-color 0.12s, background 0.12s;
    display: inline-flex; align-items: center; justify-content: center;
  }
  #logDrawerClose:hover { color: var(--text); border-color: var(--border); background: rgba(255,255,255,0.04); }
  #logDrawerClose svg { display: block; }

  #logOutput {
    flex: 1;
    overflow-y: auto;
    padding: 10px 14px;
    font-family: "SF Mono", "Fira Code", monospace;
    font-size: 12px;
    line-height: 1.6;
    color: var(--text-2);
  }
  #logOutput::-webkit-scrollbar { width: 5px; }
  #logOutput::-webkit-scrollbar-thumb { background: var(--input-bg); border-radius: 3px; }
  #logOutput .log-done  { color: var(--success-2); }
  #logOutput .log-error { color: var(--danger-2); }
  #logOutput .log-sep   { color: #374151; }
  #logRevealBtn {
    display: none; background: #14532d; color: var(--success-2); border: 1px solid var(--success);
    border-radius: 5px; padding: 3px 12px; font-size: 11px; font-weight: 700;
    cursor: pointer; font-family: inherit; white-space: nowrap;
    transition: background 0.1s;
  }
  #logRevealBtn:hover { background: var(--success); }

  /* ── Body ── */
  .body {
    display: flex;
    flex: 1;
    overflow: hidden;
    position: relative;   /* anchor for #editorEmptyState overlay */
  }

  /* ── Left panel ── */
  .panel-left {
    width: 54%;
    display: flex;
    flex-direction: column;
    border-right: 1px solid var(--input-bg);
    overflow: hidden;
  }

  /* ── Tab bar ── */
  .tab-bar {
    display: flex;
    border-bottom: 1px solid var(--surface-2);
    flex-shrink: 0;
    background: var(--surface);
  }
  .tab-btn {
    flex: 1;
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    /* --text-2 (#9ca3af), not --text-muted (#6b7280): the muted token gives
       only 3.79:1 on the tab bar, below WCAG AA (4.5:1) for this 11px label.
       Tabs only lighten on :hover, which touch devices never fire, so on
       mobile the inactive tabs are permanently stuck at the failing ratio.
       --text-2 lands ~7.3:1 while staying clearly dimmer than the active tab
       (--text #e8e8e8 + accent underline), preserving the hierarchy. */
    color: var(--text-2);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 11px 0 10px;
    cursor: pointer;
    transition: color 0.12s, border-color 0.12s, background 0.12s;
    font-family: inherit;
  }
  .tab-btn:hover { color: var(--text-3); background: rgba(255,255,255,0.02); }
  .tab-btn.active { color: var(--text); border-bottom-color: var(--accent); }

  /* ── Tab panels ── */
  .tab-panel {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;
  }

  .captions-list {
    flex: 1;
    overflow-y: auto;
    padding: 10px 14px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-height: 0;
  }
  .captions-list::-webkit-scrollbar { width: 6px; }
  .captions-list::-webkit-scrollbar-track { background: transparent; }
  .captions-list::-webkit-scrollbar-thumb { background: #3a3a3a; border-radius: 3px; }
  #captionsWrap {
    position: relative; flex: 1; min-height: 0;
    display: flex; flex-direction: column; overflow: hidden;
  }
  #captionsGutter {
    position: absolute; right: 0; top: 0; bottom: 0;
    width: 6px; pointer-events: none; z-index: 5;
  }
  .ctg-tick {
    position: absolute; left: 0; right: 0;
    height: 4px; border-radius: 2px;
    transform: translateY(-50%);
    display: none;
    transition: top 0.12s ease;
  }
  #ctgIn  { background: var(--success); box-shadow: 0 0 4px rgba(34,197,94,0.6); }
  #ctgOut { background: var(--danger); box-shadow: 0 0 4px rgba(239,68,68,0.6); }
  .captions-status {
    flex-shrink: 0;
    border-top: 1px solid #1f1f1f;
    padding: 5px 14px;
    font-size: 10px;
    color: var(--border-2);
    display: flex;
    gap: 10px;
    min-height: 24px;
    align-items: center;
  }
  .captions-status span { white-space: nowrap; }
  #captionsStats { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
  .captions-status .cs-cuts   { color: #a16207; }
  .captions-status .cs-out    { color: var(--success-2); }
  .captions-status .cs-hidden { color: var(--text-muted); }
  #jumpToCurrentBtn {
    margin-left: auto; background: #1e2d3a; border: 1px solid var(--info);
    color: var(--info-2); border-radius: 4px; padding: 3px 9px;
    font-size: 10px; cursor: pointer; white-space: nowrap; flex-shrink: 0;
    transition: background 0.1s, color 0.1s;
    display: inline-flex; align-items: center; gap: 5px;
  }
  #jumpToCurrentBtn:hover { background: #2a3f5a; color: #93c5fd; }
  #jumpToCurrentBtn.hidden { display: none; }
  #jumpToCurrentBtn svg { display: block; }

  .empty-state {
    /* --text-2, not --border-2: a border-color token rendered this placeholder
       text at 2.29:1, far below WCAG AA. --text-2 is ~6.8:1 and correct. */
    color: var(--text-2);
    font-size: 14px;
    padding: 40px 18px;
    text-align: center;
  }

  /* ── No-clip-selected overlay ────────────────────────────────────────────
     Covers the .body area after loadClips() finishes if there's no clip to
     show. Two flavors:
       1. clipsList non-empty → "Pick a clip" + Library CTA + recent-clip
          quick picks
       2. clipsList empty     → "Create your first clip" + Browse CTA
     The overlay sits absolutely inside the .body flex row; absolute root
     positioning needs .body to be position:relative (added below). */
  #editorEmptyState {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, var(--bg) 0%, var(--surface) 100%);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 18px;
    padding: 24px;
    z-index: 100;
    text-align: center;
  }
  #editorEmptyState.hidden { display: none; }

  .ees-icon {
    width: 96px;
    height: 96px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 24px;
    background: linear-gradient(135deg, rgba(99,102,241,0.18), rgba(236,72,153,0.12));
    border: 1px solid rgba(99,102,241,0.30);
    color: var(--accent-2);
    animation: ees-float 3.6s ease-in-out infinite;
  }
  .ees-icon svg { width: 48px; height: 48px; }
  @keyframes ees-float {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-6px); }
  }

  .ees-title {
    font-size: 22px;
    font-weight: 600;
    color: var(--text);
    letter-spacing: 0.01em;
  }
  .ees-subtitle {
    font-size: 14px;
    /* --text-2, not --text-muted: muted gives only 3.59:1 here, below WCAG
       AA (4.5:1) for this instructional copy. --text-2 lands ~6.8:1. */
    color: var(--text-2);
    max-width: 420px;
    line-height: 1.5;
  }
  .ees-cta {
    padding: 12px 28px;
    background: var(--accent);
    color: #fff;
    border: 0;
    border-radius: 8px;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    text-decoration: none;
    transition: background 0.12s, transform 0.06s;
  }
  .ees-cta:hover  { background: #5558e3; }
  .ees-cta:active { transform: scale(0.97); }

  .ees-recents {
    margin-top: 14px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
  }
  .ees-recents-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    /* --text-2 (a text token), not --border-2 (a border-color token): using a
       border color for this label rendered it at 2.29:1, far below WCAG AA.
       --text-2 is both semantically correct and AA-passing (~6.8:1). */
    color: var(--text-2);
    font-weight: 600;
  }
  .ees-recents-list {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    justify-content: center;
    max-width: 600px;
  }
  .ees-recent {
    padding: 6px 12px;
    background: var(--bg);
    color: var(--text-3);
    border: 1px solid var(--surface-2);
    border-radius: 999px;
    font-size: 12px;
    font-family: inherit;
    cursor: pointer;
    transition: background 0.12s, border-color 0.12s, color 0.12s;
  }
  .ees-recent:hover {
    background: var(--hover);
    border-color: var(--accent);
    color: var(--text);
  }
  .ees-stage {
    font-size: 10px;
    color: var(--text-muted);
    margin-left: 6px;
  }

  @media (max-width: 480px) {
    #editorEmptyState { gap: 14px; padding: 16px; }
    .ees-title    { font-size: 18px; }
    .ees-subtitle { font-size: 13px; }
    .ees-icon     { width: 72px; height: 72px; }
    .ees-icon svg { width: 36px; height: 36px; }
    /* Apple HIG: 44pt minimum touch target. Default chip is 29px tall. */
    .ees-recent { min-height: 44px; display: inline-flex; align-items: center; padding: 8px 14px; }
    /* Default CTA is 42px tall — just under the HIG floor. */
    .ees-cta { min-height: 44px; }
  }

  /* ── Position sliders (caption + title) ── */
  .position-panel {
    flex-shrink: 0;
    border-top: 1px solid var(--input-bg);
    padding: 10px 14px;
    background: #111;
    display: flex;
    flex-direction: column;
    gap: 7px;
  }
  .position-panel-label {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--border-2);
    margin-bottom: 2px;
  }
  .pos-row {
    display: flex;
    align-items: center;
    gap: 10px;
  }
  .pos-label {
    font-size: 10px;
    font-weight: 600;
    color: var(--text-muted);
    min-width: 60px;
    letter-spacing: 0.02em;
  }
  .pos-slider {
    flex: 1;
    -webkit-appearance: none;
    appearance: none;
    height: 3px;
    border-radius: 2px;
    background: linear-gradient(to right, var(--accent) var(--fill, 50%), var(--surface-2) var(--fill, 50%));
    cursor: pointer;
    outline: none;
    min-width: 60px;
  }
  .pos-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 11px; height: 11px;
    border-radius: 50%;
    background: var(--accent-2);
    cursor: pointer;
    box-shadow: 0 1px 2px rgba(0,0,0,0.4);
    transition: transform 0.12s, background 0.12s;
  }
  .pos-slider:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
  .pos-slider:hover::-webkit-slider-thumb {
    background: var(--accent-soft);
    transform: scale(1.15);
  }
  .pos-slider::-moz-range-thumb {
    width: 11px; height: 11px; border-radius: 50%;
    background: var(--accent-2); cursor: pointer; border: none;
    box-shadow: 0 1px 2px rgba(0,0,0,0.4);
  }
  .pos-slider::-moz-range-track {
    height: 3px; border-radius: 2px;
    background: linear-gradient(to right, var(--accent) var(--fill, 50%), var(--surface-2) var(--fill, 50%));
  }
  .pos-value {
    font-size: 10px;
    font-weight: 500;
    color: #8b8e95;
    min-width: 38px;
    text-align: right;
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum";
    background: transparent;
    border: 1px solid transparent;
    border-radius: 4px;
    padding: 2px 5px;
    cursor: text;                /* click-to-edit affordance */
    transition: background 0.12s, color 0.12s;
  }
  .pos-value:hover  { color: var(--accent-soft); background: rgba(99,102,241,0.10); }
  .pos-value.editing {
    color: var(--text); background: rgba(99,102,241,0.10);
    border-color: rgba(99,102,241,0.50);
    outline: none; padding: 1px 5px;
    font: inherit; font-size: 10px; font-variant-numeric: tabular-nums;
  }

  /* ── Overlay / Layout tabs ── */
  #tabOverlay {
    overflow-y: auto;
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 10px;
  }
  #tabOverlay::-webkit-scrollbar { width: 5px; }
  #tabOverlay::-webkit-scrollbar-thumb { background: var(--surface-2); border-radius: 3px; }
  .overlay-section {
    display: flex;
    flex-direction: column;
    gap: 10px;
    background: var(--bg);          /* match captions tab */
    border: 1px solid var(--surface-2);    /* match captions tab */
    border-radius: 6px;
    padding: 12px 14px;
  }
  .overlay-section-label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.01em;
    text-transform: none;          /* dropped uppercase */
    color: var(--text-2);
    padding-bottom: 4px;
    display: flex;
    align-items: center;
    gap: 7px;
  }
  .overlay-section-label svg { display: block; color: var(--text-muted); }

  /* Toggle switch — smaller, calmer */
  .toggle-chk {
    appearance: none; -webkit-appearance: none;
    width: 26px; height: 14px;
    background: var(--surface-2); border-radius: 7px;
    position: relative; cursor: pointer;
    transition: background 0.18s; flex-shrink: 0;
    vertical-align: middle;
  }
  .toggle-chk:checked { background: rgba(99,102,241,0.70); }
  .toggle-chk::after {
    content: ''; position: absolute;
    width: 10px; height: 10px;
    background: var(--text-3); border-radius: 50%;
    top: 2px; left: 2px;
    transition: left 0.18s, background 0.18s;
    box-shadow: 0 1px 2px rgba(0,0,0,0.4);
  }
  .toggle-chk:checked::after { left: 14px; background: #fff; }
  .toggle-row {
    display: flex; align-items: center; gap: 8px;
    font-size: 11px; color: var(--text-2); cursor: pointer; user-select: none;
  }

  /* Pill radio buttons */
  .backend-pills { display: flex; gap: 6px; flex-wrap: wrap; }
  .backend-pill {
    display: inline-flex; align-items: center;
    padding: 5px 14px; border: 1px solid var(--surface-2);
    border-radius: 20px; font-size: 12px; color: var(--border-2);
    cursor: pointer; transition: all 0.15s;
    background: #060d16; font-family: inherit; font-weight: 600;
    user-select: none;
  }
  .backend-pill:hover { border-color: #374151; color: var(--text-muted); }
  .backend-pill:has(input:checked) {
    border-color: var(--accent); color: var(--accent-2);
    background: rgba(99,102,241,0.1);
  }
  .backend-pill input[type=radio] { display: none; }

  /* Inline select control */
  .ov-select {
    flex: 1; background: var(--surface); color: var(--text-3);
    border: 1px solid var(--surface-2); border-radius: 5px;
    padding: 6px 10px; font-size: 11px; font-family: inherit; cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
  }
  .ov-select:hover  { border-color: var(--border); }
  .ov-select:focus  { outline: none; border-color: var(--accent); background: var(--bg); }
  .ov-select option { background: var(--bg); color: var(--text-3); }

  /* Layout tab hint text */
  .layout-hint {
    font-size: 10px; color: var(--text-muted); text-align: center;
    line-height: 1.5; padding: 2px 4px;
  }

  /* Layout tab preview mode row — compact icon-forward buttons with a tiny
     9:16 aspect diagram so users learn the layouts by sight. */
  .lt-preview-modes {
    display: flex; gap: 4px;
  }
  .lt-preview-modes .lp-mode-btn {
    font-size: 9px; padding: 7px 2px 5px; gap: 4px;
    min-height: 56px; justify-content: space-between;
  }
  .lt-preview-modes .lp-mode-diagram {
    width: 14px; height: 24px;
    border-radius: 2px; overflow: hidden;
    display: flex; flex-direction: column;
    background: #0a0a0d;
  }
  .lt-preview-modes .lp-mode-diagram > * { display: block; }
  .lt-preview-modes .lp-mode-label { font-size: 8.5px; letter-spacing: 0.04em; }

  /* Streamer Cam + Gameplay mirrored side-by-side. On narrow panels the
     grid collapses back to a stack. */
  .lt-pane-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
  }
  @media (max-width: 720px) {
    .lt-pane-grid { grid-template-columns: 1fr; }
  }
  .lt-pane-grid .overlay-section[data-pane-dim="1"] {
    opacity: 0.55;
    transition: opacity 0.18s;
  }

  /* 2D pan pad — direct-manipulation alternative to Pan X / Pan Y sliders.
     Drag the dot anywhere inside the square to set both axes at once. */
  .pan-pad {
    position: relative;
    width: 100%; max-width: 140px; aspect-ratio: 1 / 1;
    margin: 4px auto 2px;
    background:
      radial-gradient(circle at center, rgba(99,102,241,0.06) 0%, transparent 60%),
      var(--surface);
    border: 1px solid var(--surface-2);
    border-radius: 6px;
    cursor: crosshair;
    user-select: none;
    touch-action: none;
    overflow: hidden;
  }
  .pan-pad::before, .pan-pad::after {
    content: "";
    position: absolute;
    background: rgba(255,255,255,0.06);
    pointer-events: none;
  }
  .pan-pad::before { left: 50%; top: 8%; bottom: 8%; width: 1px; transform: translateX(-50%); }
  .pan-pad::after  { top: 50%; left: 8%; right: 8%; height: 1px; transform: translateY(-50%); }
  .pan-pad-dot {
    position: absolute;
    width: 12px; height: 12px;
    border-radius: 50%;
    background: var(--accent-2);
    box-shadow: 0 0 0 2px rgba(99,102,241,0.25), 0 1px 3px rgba(0,0,0,0.5);
    transform: translate(-50%, -50%);
    pointer-events: none;
    transition: background 0.12s, box-shadow 0.12s;
  }
  .pan-pad:hover .pan-pad-dot,
  .pan-pad.dragging .pan-pad-dot {
    background: var(--accent-soft);
    box-shadow: 0 0 0 3px rgba(99,102,241,0.40), 0 1px 4px rgba(0,0,0,0.6);
  }
  .pan-pad-label {
    position: absolute; bottom: 4px; left: 6px;
    font-size: 9px; color: var(--border-2);
    font-variant-numeric: tabular-nums; pointer-events: none;
    letter-spacing: 0.02em;
  }

  /* The head-tracking row gets promoted: pulled out of the slider stack and
     given a calm card-within-a-card treatment so it reads as a major option. */
  .head-track-row {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 8px 10px;
    background: rgba(99,102,241,0.05);
    border: 1px solid rgba(99,102,241,0.15);
    border-radius: 5px;
    cursor: pointer; user-select: none;
  }
  .head-track-row:hover { background: rgba(99,102,241,0.08); border-color: rgba(99,102,241,0.25); }
  .head-track-row .toggle-chk { margin-top: 2px; }
  .head-track-row-text { display: flex; flex-direction: column; gap: 2px; }
  .head-track-row-title { font-size: 11px; font-weight: 600; color: var(--text-3); }
  .head-track-row-hint  { font-size: 10px; color: var(--text-muted); line-height: 1.4; }

  /* Two-column slider grid — pair related controls into one row to halve
     the panel's vertical sprawl. Each column behaves like a self-contained
     .pos-row but flexes to fit half the available width. */
  .pair-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
  }
  .pair-row .pos-row { min-width: 0; }
  .pair-row .pos-label { min-width: 50px; }

  /* Color control — swatch + label + reset packaged as one component. */
  .color-control {
    display: inline-flex; align-items: center; gap: 8px;
    background: var(--surface); border: 1px solid var(--surface-2);
    border-radius: 5px; padding: 4px 8px 4px 4px;
    transition: border-color 0.12s;
  }
  .color-control:hover { border-color: var(--border); }
  .color-control input[type=color] {
    -webkit-appearance: none; appearance: none;
    width: 22px; height: 22px;
    background: none; border: 1px solid var(--surface-2); border-radius: 4px;
    padding: 0; cursor: pointer; overflow: hidden;
  }
  .color-control input[type=color]::-webkit-color-swatch-wrapper { padding: 0; }
  .color-control input[type=color]::-webkit-color-swatch { border: none; border-radius: 3px; }
  .color-control input[type=color]::-moz-color-swatch { border: none; border-radius: 3px; }
  .color-control-hex {
    font-size: 10px; font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum"; color: var(--text-muted);
    letter-spacing: 0.02em;
  }
  .color-control-reset {
    background: none; border: none; padding: 3px;
    color: var(--text-quiet); cursor: pointer; line-height: 0;
    border-radius: 3px; opacity: 0.5;
    transition: opacity 0.12s, color 0.12s, background 0.12s;
    display: inline-flex; align-items: center; justify-content: center;
  }
  .color-control:hover .color-control-reset { opacity: 1; }
  .color-control-reset:hover { color: var(--accent-soft); background: rgba(255,255,255,0.05); }
  .color-control-reset svg { display: block; }

  /* Segmented control — two or more pill buttons that act like a radio group.
     Used for Words/Line (1–4) where a dropdown was overkill. */
  .seg-control {
    display: inline-flex; background: var(--surface);
    border: 1px solid var(--surface-2); border-radius: 5px;
    padding: 2px; gap: 2px;
  }
  .seg-control-btn {
    background: none; border: none; color: var(--text-muted);
    font-size: 11px; font-weight: 600; font-family: inherit;
    padding: 4px 10px; border-radius: 3px; cursor: pointer;
    transition: background 0.12s, color 0.12s;
    min-width: 22px;
  }
  .seg-control-btn:hover { color: var(--text-3); background: rgba(255,255,255,0.04); }
  .seg-control-btn.seg-active {
    background: rgba(99,102,241,0.18); color: var(--accent-soft);
  }

  /* Clip-name bar — promotes the single-input "Clip Name" section into a
     slim header strip at the top of the tab so it doesn't take a whole card. */
  .clip-name-bar {
    display: flex; align-items: center; gap: 10px;
    padding: 4px 6px 6px;
  }
  .clip-name-bar svg { color: var(--text-muted); flex-shrink: 0; }
  .clip-name-bar .config-input { flex: 1; }

  /* Music section: single-row on desktop, wraps on narrow widths so the
     volume + start-offset controls each get their own line on phones. */
  .music-row {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  }
  .music-row .config-input { flex: 1 1 220px; min-width: 0; }
  .music-row .music-vol {
    display: flex; align-items: center; gap: 8px;
    min-width: 140px;
    flex: 1 1 auto;
  }
  .music-row .music-vol .pos-slider { width: 80px; flex: 1 1 auto; min-width: 60px; }

  .title-theme-btns { display: flex; gap: 4px; flex-wrap: wrap; }
  .title-theme-btn {
    background: var(--surface); color: var(--text-muted); border: 1px solid var(--surface-2);
    border-radius: 5px; padding: 5px 12px; font-size: 11px; font-weight: 600;
    cursor: pointer; font-family: inherit; transition: all 0.12s;
  }
  .title-theme-btn:hover { border-color: var(--border); color: var(--text-2); }
  .title-theme-btn.ttheme-active {
    background: rgba(139,92,246,0.12); border-color: rgba(139,92,246,0.55); color: #c4b5fd;
  }

  /* ──────────────────────────────────────────────────────────────────────
     Reduce Motion (WCAG 2.3.3 / Apple HIG). No reduced-motion handling
     existed, so every UI transition (~76 across the stylesheets) and every
     keyframe animation (spinner, loop/badge pulses, timing-panel shake,
     empty-state float, ping-pong flash) played even when the OS "Reduce
     Motion" accessibility setting is on. Near-zero durations (not `none`)
     keep any transitionend/animationend listeners firing — though none
     exist today, this stays safe if some are added later. The karaoke
     captions are essential content drawn on <canvas> in JS, so they are
     deliberately unaffected; this only tames decorative chrome motion. */
  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      scroll-behavior: auto !important;
    }
  }

