@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap');

/* ═══════════════════════════════════════════════════════════════════════════
   Shotlist Pro — design system
   ───────────────────────────────────────────────────────────────────────────
   Rebuilt 2026-09-11, replacing ~46KB of accreted rules ("v60", "openserv
   redesign pilot", "passionfroot", …) with one documented token layer.

   The rules of this file:

     1. TOKENS ARE DECLARED ONCE, at the top, on bare :root. Every one of them
        is SEMANTIC ("--surface-raised", "--text-dim", "--status-danger"), not
        literal ("--grey-200"). A component never writes a hex code; it reads
        a token. That is what makes the dark palette below a 40-line override
        instead of a second stylesheet.

     2. DARK MODE redefines ONLY the token values, in two places:
            @media (prefers-color-scheme: dark) { :root:not([data-theme=light]) }
            :root[data-theme="dark"]
        The media query serves the "system" default; the attribute selector is
        what an explicit toggle sets, so a person on a dark OS can force light
        and a person on a light OS can force dark, and both win. No component
        rule anywhere is theme-aware.

     3. THE BRAND IS FIXED. White, near-black, and one yellow. The yellow has
        two jobs and therefore two tokens, because they are not
        interchangeable:
            --accent       #f5c400   solid fills only, always with --accent-ink
                                     (near-black) on top. White on this yellow
                                     is unreadable.
            --accent-text  #a67c00   the same hue as TEXT or as a thin BORDER
                                     on a light surface. Bright yellow text on
                                     white is invisible; this deeper amber is
                                     the same brand, legible. In dark mode the
                                     two converge, because yellow on near-black
                                     needs no help.

     4. EVERY SURFACE PAINTS ITSELF. No transparent backgrounds inheriting
        whatever is behind them — that is how a light card ends up unreadable
        on a dark viewport.
   ═══════════════════════════════════════════════════════════════════════════ */

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
/* Visibility is toggled with el.hidden in these templates; without this, a
   component rule like `.new-project-form { display:flex }` silently beats it. */
[hidden] { display: none !important; }

/* ───────────────────────────────────────────────────────────────────────────
   1. TOKENS — light (and every value that never changes between themes)
   ─────────────────────────────────────────────────────────────────────────── */
:root {
  color-scheme: light;

  /* ── Brand ───────────────────────────────────────────────────────────── */
  --accent:        #f5c400;   /* solid fill; pair with --accent-ink          */
  --accent-hover:  #e0b400;   /* the fill, pressed/hovered                   */
  --accent-ink:    #0a0a0a;   /* what goes ON the solid fill                 */
  --accent-text:   #a67c00;   /* the brand as text / hairline on a surface   */
  --accent-soft:   #fdf3d0;   /* tinted background for accent chips          */
  --accent-ring:   rgba(245, 196, 0, .30);  /* focus halo                    */

  /* ── Surfaces ────────────────────────────────────────────────────────── */
  --surface:         #ffffff;  /* the page                                   */
  --surface-raised:  #ffffff;  /* cards sitting above the page               */
  --surface-sunken:  #f6f6f5;  /* wells, table headers, inert rows           */
  --surface-mute:    #eeeeec;  /* chips, tracks, disabled fills              */
  --surface-inverse: #121214;  /* the sidebar, tooltips, the inverted rail   */
  --surface-overlay: rgba(12, 12, 14, .55);  /* modal scrim                  */

  /* ── Lines ───────────────────────────────────────────────────────────── */
  --border:        #e6e5e2;
  --border-strong: #d3d1cd;
  --border-inverse: rgba(255, 255, 255, .10);
  --border-inverse-strong: rgba(255, 255, 255, .20);

  /* Tokens that are deliberately the SAME in both themes. The navigation rail is dark in
     light mode and dark in dark mode — it is the app's one fixed dark surface, so the
     translucent whites layered on it, and the white ink on a saturated status fill, are
     constants rather than theme values. They are still tokens: a component must never
     reach for a literal. */
  --surface-inverse-soft:  rgba(255, 255, 255, .05);
  --surface-inverse-hover: rgba(255, 255, 255, .08);
  --surface-inverse-chip:  rgba(245, 196, 0, .16);
  --text-on-status: #ffffff;
  --media-bg: #000000;        /* letterbox behind a video or a 16:9 card preview */
  --sheen: rgba(255, 255, 255, .45);
  --scrim-strong: rgba(10, 10, 12, .78);
  --knob-shadow: 0 1px 2px rgba(0, 0, 0, .35);

  /* ── Text ────────────────────────────────────────────────────────────── */
  --text:           #3a3a38;  /* body                                        */
  --text-strong:    #0a0a0a;  /* headings, numbers that matter               */
  --text-dim:       #7d7c78;  /* hints, labels, secondary                    */
  --text-inverse:   #ffffff;  /* on --surface-inverse                        */
  --text-inverse-dim: rgba(255, 255, 255, .56);

  /* ── Status ──────────────────────────────────────────────────────────── */
  --status-success:      #157f4c;  --status-success-soft: #e6f6ee;
  --status-danger:       #b5342a;  --status-danger-soft:  #fbeae7;
  --status-warning:      #9c6612;  --status-warning-soft: #fbf1dc;
  --status-info:         #35648f;  --status-info-soft:    #e9f1f8;
  --status-neutral:      #6f6e6a;  --status-neutral-soft: #efeeec;
  --status-special:      #b8447f;  --status-special-soft: #fbe8f2;

  /* ── Type ────────────────────────────────────────────────────────────── */
  --font-sans: 'Space Grotesk', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --font-mono: 'IBM Plex Mono', 'SFMono-Regular', Consolas, monospace;
  --text-xs: 11px; --text-sm: 12.5px; --text-md: 13.5px; --text-lg: 16px;
  --text-xl: 21px; --text-2xl: 27px;

  /* ── Shape & depth ───────────────────────────────────────────────────── */
  --radius-sm: 8px; --radius: 12px; --radius-lg: 18px; --radius-pill: 999px;
  --shadow-sm: 0 1px 2px rgba(12, 12, 20, .05);
  --shadow:    0 1px 3px rgba(12, 12, 20, .07), 0 6px 16px -8px rgba(12, 12, 20, .10);
  --shadow-lg: 0 8px 28px -10px rgba(12, 12, 20, .22), 0 2px 6px rgba(12, 12, 20, .06);

  /* ── Rhythm ──────────────────────────────────────────────────────────── */
  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px;
  --space-5: 24px; --space-6: 32px; --space-7: 48px;
  --gutter: clamp(16px, 4vw, 40px);   /* never smaller than 16px, any width  */
  --sidebar-w: 232px;
  --content-max: 1120px;

  /* ── Motion ──────────────────────────────────────────────────────────── */
  --ease: cubic-bezier(.22, 1, .36, 1);
  --fast: .12s; --slow: .32s;

  /* ── Compatibility aliases ───────────────────────────────────────────────
     Inline template JS (editor.html's asset notes, admin.html's charts and
     badges, account.html's ledger) writes colours as var(--red), var(--bg3)
     and friends into generated markup. Those names predate this file and are
     spread across 150KB of templates, so they are kept — but as one-line
     aliases pointing at the semantic tokens above. Because var() resolves at
     use time, an alias declared here automatically follows whatever the dark
     blocks below redefine, so none of it needs to be theme-aware either. */
  --bg: var(--surface);            --bg2: var(--surface-sunken);
  --bg3: var(--surface-mute);      --bg4: var(--surface-mute);
  --fg: var(--text);               --fg-dim: var(--text-dim);
  --fg-bright: var(--text-strong); --ink: var(--accent-ink);
  --coral: var(--accent);          --coral-hover: var(--accent-text);
  --coral-bg: var(--accent-soft);  --mint: var(--accent);
  --red: var(--status-danger);     --red-bg: var(--status-danger-soft);
  --green: var(--status-success);  --green-bg: var(--status-success-soft);
  --amber: var(--status-warning);  --amber-bg: var(--status-warning-soft);
  --blue: var(--status-info);      --blue-bg: var(--status-info-soft);
  --pink: var(--status-special);   --pink-bg: var(--status-special-soft);
  --danger: var(--status-danger);
  --sans: var(--font-sans);        --mono: var(--font-mono);
  --radius-xl: var(--radius-lg);
}

/* ───────────────────────────────────────────────────────────────────────────
   2. TOKENS — dark
   Values only. The guard on the media query means an explicit "light" choice
   survives a dark OS; the [data-theme="dark"] block means an explicit "dark"
   choice survives a light OS. Same body twice, deliberately: there is no way
   to share one declaration block between a media query and an attribute
   selector without a preprocessor, and the alternative (one block, wrong
   specificity) is the bug this shape exists to avoid.
   ─────────────────────────────────────────────────────────────────────────── */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --accent: #f5c400; --accent-hover: #ffd429; --accent-ink: #0a0a0a;
    --accent-text: #ffd12e; --accent-soft: #3a2f05;
    --accent-ring: rgba(245, 196, 0, .34);

    --surface: #121316; --surface-raised: #191a1e; --surface-sunken: #1f2126;
    --surface-mute: #2a2c32; --surface-inverse: #0a0b0d;
    --surface-overlay: rgba(0, 0, 0, .66);

    --border: #2c2e34; --border-strong: #3c3f47;
    --border-inverse: rgba(255, 255, 255, .08);

    --text: #d7d6d2; --text-strong: #f7f6f3; --text-dim: #96958f;
    --text-inverse: #ffffff; --text-inverse-dim: rgba(255, 255, 255, .56);

    --status-success: #4bd08a; --status-success-soft: #102b1e;
    --status-danger:  #ff7a6b; --status-danger-soft:  #331613;
    --status-warning: #f0b849; --status-warning-soft: #30250f;
    --status-info:    #77b0e8; --status-info-soft:    #14232f;
    --status-neutral: #a3a29d; --status-neutral-soft: #26272b;
    --status-special: #f184bd; --status-special-soft: #2f1524;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .45);
    --shadow:    0 1px 3px rgba(0, 0, 0, .5), 0 6px 18px -8px rgba(0, 0, 0, .6);
    --shadow-lg: 0 10px 32px -12px rgba(0, 0, 0, .78), 0 2px 6px rgba(0, 0, 0, .5);
  }
}
/* The editor's own surface (templates/editor.html): always dark, whatever the theme —
   the picture is what the eye should be on. Same values in every theme, on purpose. */
:root, :root[data-theme="light"], :root[data-theme="dark"] {
  --e-bg: #141416; --e-panel: #1d1d21; --e-raised: #26262b; --e-hover: #2f2f35;
  --e-border: rgba(255, 255, 255, .09); --e-border-strong: rgba(255, 255, 255, .2);
  --e-text: #f2f2f4; --e-dim: rgba(255, 255, 255, .58); --e-faint: rgba(255, 255, 255, .36);
  --e-tick: rgba(255, 255, 255, .18); --e-scrim: rgba(0, 0, 0, .62); --e-black: #000000; --e-overlay: rgba(20, 20, 22, .82);
  --e-ok-soft: rgba(21, 127, 76, .25); --e-ok: #7fd6a4;
  --e-info-soft: rgba(53, 100, 143, .3); --e-info: #9cc4ec;
  --e-danger-soft: rgba(181, 52, 42, .25); --e-danger: #ff9d94;
  --e-warn-soft: rgba(156, 102, 18, .22); --e-warn: #f2c66d;
  --e-text-clip: #6d4fd6; --e-card-clip: #b8447f; --e-cutaway-clip: #35648f;
  --e-audio-a: #8f7bff; --e-audio-b: #6d4fd6; --e-audio-mark: rgba(255, 255, 255, .35);
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --accent: #f5c400; --accent-hover: #ffd429; --accent-ink: #0a0a0a;
  --accent-text: #ffd12e; --accent-soft: #3a2f05;
  --accent-ring: rgba(245, 196, 0, .34);

  --surface: #121316; --surface-raised: #191a1e; --surface-sunken: #1f2126;
  --surface-mute: #2a2c32; --surface-inverse: #0a0b0d;
  --surface-overlay: rgba(0, 0, 0, .66);

  --border: #2c2e34; --border-strong: #3c3f47;
  --border-inverse: rgba(255, 255, 255, .08);

  --text: #d7d6d2; --text-strong: #f7f6f3; --text-dim: #96958f;
  --text-inverse: #ffffff; --text-inverse-dim: rgba(255, 255, 255, .56);

  --status-success: #4bd08a; --status-success-soft: #102b1e;
  --status-danger:  #ff7a6b; --status-danger-soft:  #331613;
  --status-warning: #f0b849; --status-warning-soft: #30250f;
  --status-info:    #77b0e8; --status-info-soft:    #14232f;
  --status-neutral: #a3a29d; --status-neutral-soft: #26272b;
  --status-special: #f184bd; --status-special-soft: #2f1524;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .45);
  --shadow:    0 1px 3px rgba(0, 0, 0, .5), 0 6px 18px -8px rgba(0, 0, 0, .6);
  --shadow-lg: 0 10px 32px -12px rgba(0, 0, 0, .78), 0 2px 6px rgba(0, 0, 0, .5);
}

/* ───────────────────────────────────────────────────────────────────────────
   3. ELEMENT BASELINE
   ─────────────────────────────────────────────────────────────────────────── */
html { -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--font-sans);
  background: var(--surface);
  color: var(--text);
  font-size: var(--text-md);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
/* Deliberately NOT `overflow-x: hidden` on <body>: that turns the body into a scroll
   container, which breaks `position: sticky` for the sidebar rail and hides a real
   overflow bug instead of fixing it. Every element wider than a phone is inside its own
   .table-scroll / .shot-scroll instead, and every grid track that holds content sets
   min-width:0 so a long word can't push the column past the viewport. */
a { color: var(--accent-text); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3, h4 { color: var(--text-strong); letter-spacing: -.02em; font-weight: 700; }
h1 { font-size: var(--text-xl); line-height: 1.25; }
h2 { font-size: var(--text-lg); }
h3 { font-size: var(--text-md); }
code { font-family: var(--font-mono); font-size: .92em; }
img, video, svg, iframe { max-width: 100%; }
:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 2px; }
::selection { background: var(--accent); color: var(--accent-ink); }
.hint { font-size: var(--text-xs); color: var(--text-dim); line-height: 1.5;
        font-weight: 400; letter-spacing: 0; text-transform: none; }
.subtitle { color: var(--text-dim); font-size: var(--text-sm); margin-top: 2px; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden;
                   clip: rect(0 0 0 0); white-space: nowrap; }

/* ── Form controls, one recipe for every input on every page ──────────── */
input[type="text"], input[type="email"], input[type="password"], input[type="number"],
input[type="search"], input:not([type]), select, textarea {
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--text);
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  outline: none;
  max-width: 100%;
  transition: border-color var(--fast), box-shadow var(--fast);
}
select { cursor: pointer; }
textarea { line-height: 1.6; resize: vertical; min-height: 96px; width: 100%; }
input:focus, select:focus, textarea:focus {
  border-color: var(--accent-text);
  box-shadow: 0 0 0 3px var(--accent-ring);
}
input::placeholder, textarea::placeholder { color: var(--text-dim); }
input:disabled, select:disabled, textarea:disabled { opacity: .55; cursor: not-allowed; }
label { font-size: var(--text-xs); font-weight: 600; color: var(--text-dim); }
.field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.field > label { text-transform: uppercase; letter-spacing: .04em; }

/* Toggle switch, applied to every plain checkbox in the app. */
input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  width: 38px; height: 22px; min-width: 38px; border-radius: var(--radius-pill);
  background: var(--surface-mute); border: 1px solid var(--border-strong);
  position: relative; cursor: pointer; vertical-align: middle; flex-shrink: 0;
  transition: background-color var(--slow), border-color var(--slow);
}
input[type="checkbox"]::before {
  content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px;
  border-radius: 50%; background: var(--surface-raised);
  box-shadow: var(--knob-shadow);
  transition: transform var(--slow) var(--ease);
}
input[type="checkbox"]:checked { background: var(--accent); border-color: var(--accent-text); }
input[type="checkbox"]:checked::before { transform: translateX(16px); background: var(--accent-ink); }
input[type="checkbox"]:focus-visible { box-shadow: 0 0 0 3px var(--accent-ring); }
input[type="range"] { accent-color: var(--accent); }

/* ───────────────────────────────────────────────────────────────────────────
   4. BUTTONS
   ─────────────────────────────────────────────────────────────────────────── */
.btn-primary, .btn-ghost, .btn-success, .btn-danger, .btn-add {
  font-family: var(--font-sans); font-size: var(--text-sm); font-weight: 600;
  padding: 8px 16px; border: 1px solid transparent; border-radius: var(--radius-pill);
  cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
  justify-content: center; white-space: nowrap; line-height: 1.3;
  transition: background-color var(--fast), border-color var(--fast),
              color var(--fast), box-shadow var(--fast), transform var(--fast);
}
.btn-primary { background: var(--accent); color: var(--accent-ink); box-shadow: var(--shadow-sm); }
.btn-primary:hover { background: var(--accent-hover); text-decoration: none; }
.btn-ghost { background: var(--surface-raised); color: var(--text); border-color: var(--border-strong); }
.btn-ghost:hover { background: var(--surface-sunken); border-color: var(--text-dim);
                   color: var(--text-strong); text-decoration: none; }
.btn-ghost.active { border-color: var(--accent-text); color: var(--accent-text);
                    background: var(--accent-soft); }
.btn-success { background: var(--status-success); color: var(--text-on-status); }
.btn-success:hover { filter: brightness(1.08); text-decoration: none; }
.btn-danger { background: var(--status-danger-soft); color: var(--status-danger);
              border-color: var(--status-danger); }
.btn-primary:disabled, .btn-ghost:disabled, .btn-success:disabled, .btn-danger:disabled {
  background: var(--surface-mute); color: var(--text-dim); border-color: transparent;
  cursor: default; box-shadow: none; opacity: .8;
}
.btn-primary:active, .btn-ghost:active, .btn-success:active { transform: scale(.975); }
.btn-full { width: 100%; padding: 11px; font-size: var(--text-md); margin-top: var(--space-1); }
.btn-lg { font-size: var(--text-md); padding: 11px 22px; }
.btn-sm { font-size: var(--text-xs); padding: 5px 11px; }
.btn-add {
  background: var(--surface-raised); border: 1px dashed var(--border-strong);
  color: var(--text-dim); width: 100%; padding: 10px; margin-top: var(--space-2);
  border-radius: var(--radius);
}
.btn-add:hover { border-color: var(--accent-text); color: var(--accent-text); }
.actions { display: flex; gap: var(--space-2); margin-top: var(--space-5);
           align-items: center; flex-wrap: wrap; }

/* ───────────────────────────────────────────────────────────────────────────
   5. APP SHELL — sidebar rail, mobile drawer, content column
   ─────────────────────────────────────────────────────────────────────────── */
#app { display: grid; grid-template-columns: var(--sidebar-w) 1fr; min-height: 100vh; }

.sidebar {
  background: var(--surface-inverse);
  border-right: 1px solid var(--border-inverse);
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: 18px 0 14px;
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
  z-index: 40;
}
.logo {
  display: flex; align-items: center; gap: 9px;
  font-size: var(--text-lg); font-weight: 700; color: var(--text-inverse);
  padding: 2px 16px 10px; text-decoration: none; letter-spacing: -.02em;
}
.logo:hover { text-decoration: none; }
.logo-word { color: var(--accent); margin-left: 4px; }
.logo-mark {
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: var(--radius-sm);
  background: var(--accent); color: var(--accent-ink); flex-shrink: 0;
}
.sidebar-project {
  display: flex; align-items: center; gap: 8px; margin: 0 12px 6px;
  padding: 8px 10px; background: var(--surface-inverse-soft);
  border: 1px solid var(--border-inverse); border-radius: var(--radius);
  text-decoration: none; min-width: 0;
}
.sidebar-project:hover { border-color: var(--border-inverse-strong); text-decoration: none; }
.sidebar-project-dot { width: 7px; height: 7px; border-radius: 50%;
                       background: var(--accent); flex-shrink: 0; }
.sidebar-project-name { font-size: var(--text-xs); font-weight: 600; color: var(--text-inverse);
                        overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.steps { display: flex; flex-direction: column; gap: 2px; padding: 0 12px; }
.sidebar-heading {
  font-size: 9.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-inverse-dim); padding: 10px 14px 4px;
}
.step {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  border: none; background: transparent; color: var(--text-inverse-dim);
  font-family: var(--font-sans); font-size: var(--text-sm); font-weight: 500;
  text-align: left; cursor: pointer; border-radius: var(--radius-sm);
  text-decoration: none; width: 100%;
  transition: background-color var(--fast), color var(--fast);
}
.step:hover { background: var(--surface-inverse-hover); color: var(--text-inverse); text-decoration: none; }
.step.active { background: var(--accent); color: var(--accent-ink); font-weight: 600; }
.step.done { color: var(--status-success); }
.step-static { cursor: default; }
.step-static:hover { background: transparent; color: var(--text-inverse-dim); }
.step-num {
  width: 19px; height: 19px; display: flex; align-items: center; justify-content: center;
  background: var(--surface-inverse-hover); border-radius: 50%; font-size: 10px;
  font-weight: 700; color: var(--text-inverse-dim); flex-shrink: 0; font-family: var(--font-mono);
}
.step.active .step-num { background: var(--accent-ink); color: var(--accent); }
.step.done .step-num { background: var(--status-success); color: var(--accent-ink); }
.step-icon { width: 16px; height: 16px; display: flex; align-items: center;
             justify-content: center; flex-shrink: 0; color: inherit; }
.step-icon svg { display: block; }
.step-tail { margin-left: auto; font-size: 10px; font-weight: 700; letter-spacing: .04em;
             text-transform: uppercase; opacity: .8; }
.avatar {
  width: 21px; height: 21px; border-radius: 50%; background: var(--accent);
  color: var(--accent-ink); font-size: 10px; font-weight: 700; display: flex;
  align-items: center; justify-content: center; flex-shrink: 0;
}
.sidebar-bottom {
  margin-top: auto; padding: 12px 12px 0; border-top: 1px solid var(--border-inverse);
  display: flex; flex-direction: column; gap: 2px;
}
.token-pill {
  display: inline-flex; align-items: center; gap: 6px; align-self: flex-start;
  margin: 0 0 8px; padding: 4px 11px; background: var(--surface-inverse-chip);
  color: var(--accent); font-size: var(--text-xs); font-weight: 700;
  border-radius: var(--radius-pill); text-decoration: none;
}
.token-pill:hover { text-decoration: none; filter: brightness(1.12); }

/* Theme toggle — three explicit states so "follow my system" stays reachable. */
.theme-switch { display: flex; gap: 3px; margin: 4px 0 8px; padding: 3px;
                background: var(--surface-inverse-soft); border-radius: var(--radius-pill); }
.theme-switch button {
  flex: 1; border: none; background: transparent; cursor: pointer;
  font-family: var(--font-sans); font-size: 10.5px; font-weight: 600;
  color: var(--text-inverse-dim); padding: 5px 4px; border-radius: var(--radius-pill);
  transition: background-color var(--fast), color var(--fast);
}
.theme-switch button:hover { color: var(--text-inverse); }
.theme-switch button[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }

/* Mobile top bar + drawer. Hidden entirely on desktop. */
.appbar { display: none; }
.drawer-scrim { display: none; }

.main {
  min-width: 0;
  padding-block: var(--space-6);
  padding-inline: var(--gutter);
  background: var(--surface);
  animation: riseIn .3s var(--ease);
}
.dashboard-content, .dashboard-main { max-width: var(--content-max); margin: 0 auto; }
.dashboard-content.narrow { max-width: 780px; }
.dashboard-content.wide { max-width: 1600px; }   /* admin: tables want the room (2026-09-13) */
.dashboard-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-5);
}
.page-head { margin-bottom: var(--space-5); }

/* ───────────────────────────────────────────────────────────────────────────
   6. SURFACES — one card recipe, reused everywhere
   ─────────────────────────────────────────────────────────────────────────── */
.card, .editor-card, .admin-section, .admin-stat, .new-project-form {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.card, .editor-card { padding: 18px 20px; margin-top: var(--space-4); }
.card > h2:first-child, .editor-card > h2:first-child { margin-top: 0; }
.card-head { display: flex; align-items: center; gap: 10px; justify-content: space-between;
             flex-wrap: wrap; margin-bottom: var(--space-3); }
.card-title { display: flex; align-items: center; gap: 8px; font-size: var(--text-md);
              font-weight: 700; color: var(--text-strong); }
.card-icon { display: inline-flex; align-items: center; justify-content: center;
             width: 24px; height: 24px; border-radius: 7px;
             background: var(--accent-soft); color: var(--accent-text); flex-shrink: 0; }
.well { background: var(--surface-sunken); border: 1px solid var(--border);
        border-radius: var(--radius); padding: 12px 14px; }

/* Generic scroll container for anything wider than a phone. Tables, diagrams
   and code live inside one of these so the PAGE never scrolls sideways. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch;
                border-radius: var(--radius); }
.table-scroll > table { min-width: 640px; }

/* ───────────────────────────────────────────────────────────────────────────
   7. BADGES, PILLS, BANNERS
   ─────────────────────────────────────────────────────────────────────────── */
.badge, .status-badge, .stat-badge, .type-pill, .admin-error-bucket, .admin-test-badge, .chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 10.5px; font-weight: 700; padding: 3px 9px;
  border-radius: var(--radius-pill); letter-spacing: .02em; white-space: nowrap;
  background: var(--status-neutral-soft); color: var(--status-neutral);
}
.status-badge { text-transform: uppercase; letter-spacing: .04em; }
.status-draft        { background: var(--status-neutral-soft); color: var(--status-neutral); }
.status-transcribing, .status-analyzing, .status-generating, .status-assembling {
  background: var(--status-warning-soft); color: var(--status-warning); }
.status-transcribed, .status-done, .status-generated {
  background: var(--status-info-soft); color: var(--status-info); }
.status-assembled    { background: var(--status-success-soft); color: var(--status-success); }
.status-error        { background: var(--status-danger-soft); color: var(--status-danger); }

.type-talking_head, .type-talking_head_closeup { background: var(--status-special-soft); color: var(--status-special); }
.type-broll, .type-broll_pip { background: var(--status-success-soft); color: var(--status-success); }
.type-activity       { background: var(--status-warning-soft); color: var(--status-warning); }
.type-pov_shot       { background: var(--status-info-soft); color: var(--status-info); }
.type-photo          { background: var(--status-neutral-soft); color: var(--status-neutral); }
/* A photo with the presenter in it is a photo — same price, same share, same Ken Burns —
   so it reads as one, with the accent marking the half-dozen shots per video she is in. */
.type-photo_edited   { background: var(--accent-soft); color: var(--accent-text); }
.type-animation      { background: var(--status-danger-soft); color: var(--status-danger); }

.chip-accent  { background: var(--accent-soft); color: var(--accent-text); }
.chip-danger  { background: var(--status-danger-soft); color: var(--status-danger); }
.chip-success { background: var(--status-success-soft); color: var(--status-success); }
.chip-info    { background: var(--status-info-soft); color: var(--status-info); }

.banner, .status-msg, .verify-banner {
  display: flex; align-items: flex-start; gap: 8px; flex-wrap: wrap;
  padding: 10px 14px; border-radius: var(--radius); font-size: var(--text-sm);
  border: 1px solid var(--border); background: var(--surface-sunken);
  color: var(--text); margin-top: var(--space-3);
}
.banner-ok, .verify-ok       { background: var(--status-success-soft); color: var(--status-success);
                               border-color: color-mix(in srgb, var(--status-success) 34%, transparent); }
.banner-warn, .verify-warn   { background: var(--status-warning-soft); color: var(--status-warning);
                               border-color: color-mix(in srgb, var(--status-warning) 34%, transparent); }
.banner-error, .status-msg.error { background: var(--status-danger-soft); color: var(--status-danger);
                               border-color: color-mix(in srgb, var(--status-danger) 34%, transparent); }
.banner-info                 { background: var(--status-info-soft); color: var(--status-info);
                               border-color: color-mix(in srgb, var(--status-info) 34%, transparent); }

/* ───────────────────────────────────────────────────────────────────────────
   8. AUTH
   ─────────────────────────────────────────────────────────────────────────── */
.auth-page {
  display: flex; align-items: center; justify-content: center; min-height: 100vh;
  background: var(--surface-sunken);
  padding-block: var(--space-5); padding-inline: var(--gutter);
  position: relative; overflow: hidden;
}
.auth-page::before, .auth-page::after {
  content: ""; position: absolute; width: 520px; height: 520px; border-radius: 50%;
  background: radial-gradient(circle, var(--accent-soft) 0%, transparent 70%);
  pointer-events: none; z-index: 0; opacity: .9;
}
.auth-page::before { top: -220px; left: -160px; }
.auth-page::after { bottom: -240px; right: -160px; }
.auth-card {
  position: relative; z-index: 1; width: min(380px, 100%);
  background: var(--surface-raised); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: clamp(22px, 5vw, 34px);
  box-shadow: var(--shadow-lg); animation: riseIn .4s var(--ease);
}
.auth-logo { display: flex; align-items: center; gap: 8px; font-size: var(--text-xl);
             font-weight: 700; color: var(--text-strong); margin-bottom: var(--space-5); }
.auth-logo .logo-word { color: var(--accent-text); margin-left: 4px; }
.auth-card h2 { font-size: var(--text-lg); margin-bottom: var(--space-4); }
.auth-card input { width: 100%; margin-bottom: 9px; padding: 10px 12px; }
.auth-error { color: var(--status-danger); font-size: var(--text-sm);
              margin-top: 6px; min-height: 18px; }
.auth-switch { font-size: var(--text-sm); color: var(--text-dim);
               margin-top: var(--space-4); text-align: center; }
.auth-switch a { color: var(--text-strong); font-weight: 600; }

/* ───────────────────────────────────────────────────────────────────────────
   9. PROJECTS
   ─────────────────────────────────────────────────────────────────────────── */
.new-project-form { display: flex; gap: var(--space-2); margin-bottom: var(--space-5);
                    align-items: center; padding: 14px; flex-wrap: wrap; }
.new-project-form input { flex: 1; min-width: 160px; }
.project-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
                gap: var(--space-3); }
.project-card {
  display: block; padding: 16px; background: var(--surface-raised);
  border: 1px solid var(--border); border-radius: var(--radius);
  text-decoration: none; color: var(--text); position: relative;
  box-shadow: var(--shadow-sm);
  transition: border-color var(--fast), box-shadow var(--fast), transform var(--fast);
}
.project-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-lg);
                      text-decoration: none; transform: translateY(-2px); }
.project-icon {
  width: 36px; height: 36px; border-radius: var(--radius-sm);
  background: var(--accent-soft); color: var(--accent-text);
  display: flex; align-items: center; justify-content: center; margin-bottom: 14px;
}
.project-name { font-size: var(--text-md); font-weight: 600; color: var(--text-strong);
                margin-bottom: 6px; overflow-wrap: anywhere; }
.project-meta { margin-top: 4px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.project-delete {
  position: absolute; top: 10px; right: 10px; background: none; border: none;
  color: var(--text-dim); font-size: 17px; cursor: pointer; opacity: 0;
  line-height: 1; transition: opacity var(--fast), color var(--fast);
}
.project-card:hover .project-delete, .project-delete:focus-visible { opacity: .7; }
.project-delete:hover { opacity: 1 !important; color: var(--status-danger); }
button.project-card { font-family: var(--font-sans); text-align: left; width: 100%; }
.project-card-add { display: flex; flex-direction: column; align-items: flex-start;
                    justify-content: center; border-style: dashed;
                    border-color: var(--border-strong); box-shadow: none;
                    background: var(--surface); color: var(--text-dim); }
.project-card-add:hover { border-color: var(--accent-text); color: var(--accent-text); box-shadow: none; }
.project-icon-add { background: var(--surface-mute); color: var(--text-dim); }
.project-card-add:hover .project-icon-add { background: var(--accent-soft); color: var(--accent-text); }
.project-card-add .project-name { color: inherit; margin-bottom: 0; }
.empty-state { text-align: center; padding: 56px 20px; color: var(--text-dim);
               font-size: var(--text-sm); border: 1px dashed var(--border);
               border-radius: var(--radius-lg); background: var(--surface-raised); }
.empty-icon { width: 56px; height: 56px; border-radius: 50%; background: var(--accent-soft);
              color: var(--accent-text); display: flex; align-items: center;
              justify-content: center; margin: 0 auto var(--space-4); }
.empty-hint { font-size: var(--text-sm); color: var(--text-dim); padding: 8px 0; }

/* ───────────────────────────────────────────────────────────────────────────
   10. THE EDITOR — step rail, run panel, shot list, assets
   ─────────────────────────────────────────────────────────────────────────── */
.flow { display: flex; flex-direction: column; }
.flow-section { position: relative; padding: var(--space-6) 0 var(--space-7);
                border-top: 1px solid var(--border);
                transition: opacity var(--slow) ease, filter var(--slow) ease; }
.flow-section:first-of-type { border-top: none; padding-top: 0; }
/* A section can be simultaneously revealed by the scroll observer and locked
   (not reached yet). Locked must win over the reveal's opacity:1. */
.flow-section.locked { opacity: .42 !important; filter: grayscale(.4); pointer-events: none; }
.flow-head { display: flex; align-items: flex-start; gap: 14px; margin-bottom: var(--space-4); }
.flow-num {
  flex-shrink: 0; width: 30px; height: 30px; border-radius: 50%;
  background: var(--surface-mute); color: var(--text-dim);
  font-weight: 700; font-size: var(--text-sm);
  display: flex; align-items: center; justify-content: center; margin-top: 2px;
  transition: background-color var(--slow), color var(--slow);
}
.flow-section:not(.locked) .flow-num { background: var(--accent); color: var(--accent-ink); }
.flow-head h1 { margin-bottom: 2px; }

/* Step indicator with real state. One row of segments, each one carrying its
   own status so "running", "blocked" and "failed" are distinguishable at a
   glance rather than all reading as "not done". */
.steptrack { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: var(--space-5); }
.steptrack-item {
  flex: 1 1 160px; min-width: 0; display: flex; align-items: center; gap: 9px;
  padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface-raised); text-align: left;
  transition: border-color var(--fast), background-color var(--fast);
}
.steptrack-dot {
  width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 10.5px; font-weight: 700; font-family: var(--font-mono);
  background: var(--surface-mute); color: var(--text-dim);
}
.steptrack-name { font-size: var(--text-sm); font-weight: 600; color: var(--text-strong);
                  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.steptrack-state { font-size: 10px; font-weight: 700; text-transform: uppercase;
                   letter-spacing: .06em; color: var(--text-dim); }
.steptrack-item[data-state="done"]    { border-color: color-mix(in srgb, var(--status-success) 40%, transparent); }
.steptrack-item[data-state="done"]    .steptrack-dot { background: var(--status-success-soft); color: var(--status-success); }
.steptrack-item[data-state="done"]    .steptrack-state { color: var(--status-success); }
.steptrack-item[data-state="running"] { border-color: var(--accent-text); background: var(--accent-soft); }
.steptrack-item[data-state="running"] .steptrack-dot { background: var(--accent); color: var(--accent-ink); }
.steptrack-item[data-state="running"] .steptrack-state { color: var(--accent-text); }
.steptrack-item[data-state="failed"]  { border-color: color-mix(in srgb, var(--status-danger) 45%, transparent); }
.steptrack-item[data-state="failed"]  .steptrack-dot { background: var(--status-danger-soft); color: var(--status-danger); }
.steptrack-item[data-state="failed"]  .steptrack-state { color: var(--status-danger); }
.steptrack-item[data-state="blocked"] .steptrack-dot { background: var(--surface-mute); color: var(--text-dim); }
.steptrack-item[data-state="blocked"] { opacity: .62; }

/* Cost preview — the number a customer reads before committing real money. */
.cost-preview { display: flex; flex-wrap: wrap; gap: 10px; width: 100%;
                margin-top: var(--space-3); padding: 14px;
                background: var(--surface-sunken); border: 1px solid var(--border);
                border-radius: var(--radius); }
.cost-item { display: flex; flex-direction: column; gap: 1px; flex: 1 1 140px;
             font-size: var(--text-xs); color: var(--text-dim); }
.cost-item b { color: var(--text-strong); font-size: var(--text-lg); font-weight: 700;
               font-variant-numeric: tabular-nums; }
.cost-item.cost-total { flex: 1 1 160px; padding-left: 14px;
                        border-left: 2px solid var(--accent); }
.cost-item.cost-total b { color: var(--accent-text); }

.progress-container { margin-top: var(--space-4); padding: 14px 16px;
                      background: var(--surface-sunken); border-radius: var(--radius);
                      border: 1px solid var(--border); }
.progress-header { display: flex; justify-content: space-between; gap: 10px;
                   flex-wrap: wrap; margin-bottom: 8px; font-size: var(--text-sm); }
.progress-header > span:last-child { color: var(--text-dim); font-family: var(--font-mono);
                                     display: flex; align-items: center; gap: 10px; }
.progress-bar { height: 6px; background: var(--surface-mute);
                border-radius: var(--radius-pill); overflow: hidden; }
.progress-fill { height: 100%; background: var(--accent); border-radius: var(--radius-pill);
                 transition: width .4s ease; width: 0%; position: relative; overflow: hidden; }
.progress-fill::after {
  content: ""; position: absolute; inset: 0;
  background-image: linear-gradient(90deg, transparent, var(--sheen), transparent);
  background-size: 70px 100%; background-repeat: no-repeat; background-position: -70px 0;
  animation: shimmer 1.3s linear infinite;
}
.flow-inline-progress {
  /* Shown/hidden with el.hidden, so the resting state here is the LAID-OUT one —
     [hidden]{display:none!important} does the hiding. A display:none here would make
     `hidden = false` a no-op. */
  display: flex; align-items: center; gap: 14px; margin: var(--space-2) 0 var(--space-5);
  padding: 16px 18px; background: var(--surface-sunken); border: 1px solid var(--border);
  border-radius: var(--radius); animation: dropIn .35s var(--ease);
}
.flow-inline-progress-body { flex: 1; min-width: 0; }
.spinner, .flow-inline-progress .spinner {
  display: block; width: 22px; height: 22px; border-radius: 50%;
  border: 3px solid var(--border-strong); border-top-color: var(--accent);
  animation: spin .8s linear infinite; flex-shrink: 0;
}

/* Voiceover upload */
.vo-panel { margin-bottom: var(--space-3); }
.upload-zone { border: 1px dashed var(--border-strong); border-radius: var(--radius);
               padding: 34px 20px; text-align: center; cursor: pointer;
               background: var(--surface-sunken);
               transition: border-color var(--fast), background-color var(--fast); }
.upload-zone:hover { border-color: var(--accent-text); background: var(--accent-soft); }
.upload-icon { margin-bottom: 8px; color: var(--text-dim); display: flex; justify-content: center; }
.upload-text { font-size: var(--text-md); color: var(--text-strong); font-weight: 600; }
.upload-hint { font-size: var(--text-xs); color: var(--text-dim); margin-top: 4px; }
.audio-preview { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
                 padding: 12px 14px; background: var(--surface-sunken);
                 border-radius: var(--radius); margin-top: 14px; border: 1px solid var(--border); }
.audio-preview span { font-size: var(--text-sm); color: var(--text-strong); font-weight: 600; }
.audio-preview audio { flex: 1; min-width: 200px; height: 34px; }

/* Shot list — its own scroll box, sticky header, per-row type colour. */
.shotlist-toolbar { display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center;
                    margin: var(--space-3) 0; }
.filter-group { display: flex; gap: 4px; flex-wrap: wrap; }
.filter-chip {
  font-family: var(--font-sans); font-size: var(--text-xs); font-weight: 600;
  padding: 4px 11px; border-radius: var(--radius-pill); cursor: pointer;
  border: 1px solid var(--border-strong); background: var(--surface-raised);
  color: var(--text-dim); transition: all var(--fast);
}
.filter-chip:hover { color: var(--text-strong); border-color: var(--text-dim); }
.filter-chip[aria-pressed="true"] { background: var(--accent); border-color: var(--accent);
                                    color: var(--accent-ink); }
.stat-badges { display: flex; gap: 6px; flex-wrap: wrap; align-items: center;
               margin-bottom: var(--space-2); }
.shot-scroll { max-height: 70vh; overflow: auto; border: 1px solid var(--border);
               border-radius: var(--radius); background: var(--surface-raised); }
.shot-table { width: 100%; border-collapse: separate; border-spacing: 0;
              font-size: var(--text-sm); min-width: 820px; }
.shot-table th {
  text-align: left; padding: 9px 10px; background: var(--surface-sunken);
  color: var(--text-dim); font-size: 10.5px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 5;
}
.shot-row td { padding: 7px 10px; vertical-align: middle; background: var(--surface-raised); }
.shot-row:hover td { background: var(--surface-sunken); }
.shot-text-row td { padding: 0 10px 9px; border-bottom: 1px solid var(--border);
                    font-size: var(--text-xs); color: var(--text-dim); line-height: 1.45;
                    background: var(--surface-raised); }
.shot-row td:first-child { border-left: 3px solid var(--status-neutral); }
.type-row-talking_head td:first-child { border-left-color: var(--status-special); }
.type-row-broll td:first-child, .type-row-broll_pip td:first-child { border-left-color: var(--status-success); }
.type-row-activity td:first-child { border-left-color: var(--status-warning); }
.type-row-pov_shot td:first-child { border-left-color: var(--status-info); }
.type-row-photo td:first-child { border-left-color: var(--status-neutral); }
.type-row-photo_edited td:first-child { border-left-color: var(--accent); }
.type-row-animation td:first-child { border-left-color: var(--status-danger); }
.cell-ts { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-dim);
           white-space: nowrap; }
.cell-text { font-size: var(--text-xs); color: var(--text-dim); }
.cell-input { font-family: var(--font-sans); font-size: var(--text-sm); background: transparent;
              color: var(--text); border: 1px solid transparent; border-radius: var(--radius-sm);
              padding: 4px 6px; outline: none; width: 100%; }
.cell-input:hover { border-color: var(--border); }
.cell-input:focus { border-color: var(--accent-text); background: var(--surface-raised);
                    box-shadow: 0 0 0 3px var(--accent-ring); }
.type-select { font-family: var(--font-sans); font-size: var(--text-xs);
               padding: 4px 6px; border-radius: var(--radius-sm); width: 100%; }
.row-regen { background: none; border: 1px solid var(--border-strong); color: var(--text-dim);
             border-radius: var(--radius-sm); cursor: pointer; padding: 3px 8px;
             font-size: var(--text-xs); }
.row-regen:hover { color: var(--accent-text); border-color: var(--accent-text); }

/* Assets */
.assets-stats-bar { display: flex; gap: 4px; flex-wrap: wrap; margin-bottom: 14px;
                    padding: 12px 14px; background: var(--surface-sunken);
                    border-radius: var(--radius); border: 1px solid var(--border); }
.stat-item { display: flex; flex-direction: column; align-items: center;
             padding: 4px 14px; min-width: 76px; }
.stat-item.total { background: var(--surface-mute); border-radius: var(--radius-sm); padding: 4px 16px; }
.stat-val { font-size: var(--text-lg); font-weight: 700; color: var(--text-strong);
            font-variant-numeric: tabular-nums; }
.stat-item.total .stat-val { color: var(--status-success); }
.stat-label { font-size: 9.5px; color: var(--text-dim); margin-top: 2px;
              text-transform: uppercase; letter-spacing: .05em; text-align: center; }
.assets-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); min-width: 760px; }
.assets-table th { text-align: left; padding: 9px 10px; background: var(--surface-sunken);
                   color: var(--text-dim); font-size: 10.5px; font-weight: 700;
                   text-transform: uppercase; letter-spacing: .05em;
                   border-bottom: 1px solid var(--border); position: sticky; top: 0; z-index: 5; }
.assets-table td { padding: 9px 10px; border-bottom: 1px solid var(--border); vertical-align: top;
                   background: var(--surface-raised); }
.assets-table tr:hover td { background: var(--surface-sunken); }
.cell-prompt { font-size: var(--text-xs); color: var(--text); line-height: 1.5; max-width: 300px; }
.cell-asset { padding: 6px; }
.asset-preview { max-width: 230px; max-height: 140px; border-radius: var(--radius-sm);
                 cursor: pointer; display: block; border: 1px solid var(--border); }
.asset-empty { width: 100%; max-width: 230px; height: 74px; background: var(--surface-mute);
               border-radius: var(--radius-sm); display: flex; align-items: center;
               justify-content: center; font-size: var(--text-xs); color: var(--text-dim); }

/* ───────────────────────────────────────────────────────────────────────────
   11. SETTINGS & PRESENTER
   ─────────────────────────────────────────────────────────────────────────── */
.settings-section { margin-top: var(--space-6); }
.settings-section > h2 { font-size: var(--text-lg); margin-bottom: 4px; }
.settings-section > .hint { margin-bottom: var(--space-3); }
.setting-card { background: var(--surface-raised); border: 1px solid var(--border);
                border-radius: var(--radius); padding: 14px 16px; margin-top: var(--space-3); }
.setting-label { margin-bottom: 6px; }
.setting-label strong { font-size: var(--text-md); color: var(--text-strong); font-weight: 700; }
.setting-label .hint { display: inline; margin-left: 6px; }
.setting-input-row { display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; }
.setting-input-row > input[type="password"], .setting-input-row > input[type="text"] { flex: 1; min-width: 180px; }
.settings-grid { display: grid; gap: var(--space-3); }
.swatch-row { display: flex; flex-wrap: wrap; gap: 18px; align-items: center; }
.swatch-field { display: flex; align-items: center; gap: 8px; font-size: var(--text-xs);
                color: var(--text-dim); }
.hex-swatch { display: inline-block; width: 22px; height: 22px; border-radius: 6px;
              border: 1px solid var(--border-strong); flex-shrink: 0; }
.hex-input { width: 96px; font-family: var(--font-mono); }
.switch-row { display: flex; align-items: flex-start; gap: 9px; font-size: var(--text-xs);
              color: var(--text-dim); line-height: 1.5; cursor: pointer; }
.switch-row span { flex: 1; min-width: 0; }
.switch-row b { color: var(--text-strong); font-size: var(--text-sm); }

.character-list { display: flex; flex-direction: column; gap: var(--space-2); }
.char-card { padding: 12px 14px; background: var(--surface-raised); border: 1px solid var(--border);
             border-radius: var(--radius); cursor: pointer; position: relative;
             transition: border-color var(--fast), box-shadow var(--fast); }
.char-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow); }
.char-card.selected { border-color: var(--accent-text); box-shadow: 0 0 0 1.5px var(--accent-text);
                      background: var(--accent-soft); }
.char-card-inner { display: flex; gap: 12px; flex-wrap: wrap; }
.char-ref-thumb { width: 72px; height: 72px; border-radius: var(--radius-sm); object-fit: cover;
                  flex-shrink: 0; border: 1px solid var(--border); background: var(--surface-mute); }
.char-ref-empty { width: 72px; height: 72px; border-radius: var(--radius-sm);
                  background: var(--surface-mute); display: flex; align-items: center;
                  justify-content: center; font-size: 10.5px; color: var(--text-dim); flex-shrink: 0; }
.char-info { flex: 1; min-width: 160px; }
.char-name { font-size: var(--text-md); font-weight: 700; color: var(--text-strong); }
.char-meta { font-size: 10.5px; color: var(--text-dim); font-weight: 400; margin-left: 6px; }
.char-desc { font-size: var(--text-xs); color: var(--text-dim); margin-top: 2px; }
.char-warn { font-size: var(--text-xs); color: var(--status-warning); margin-top: 4px; }
.char-ok { font-size: var(--text-xs); color: var(--status-success); margin-top: 4px; }
.char-actions-row { display: flex; gap: var(--space-2); margin-top: var(--space-2);
                    align-items: center; flex-wrap: wrap; }
.char-delete { background: none; border: none; color: var(--text-dim);
               font-size: var(--text-xs); cursor: pointer; padding: 4px 7px; }
.char-delete:hover { color: var(--status-danger); }
.char-form-large { margin-top: var(--space-3); padding: 18px; background: var(--surface-sunken);
                   border-radius: var(--radius); border: 1px solid var(--border); }
.char-form-large h3 { margin-bottom: 14px; }
.char-row { display: flex; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }
.char-field { flex: 1; min-width: 140px; display: flex; flex-direction: column; gap: 5px; }
.char-field label { font-size: 10.5px; font-weight: 700; color: var(--text-dim);
                    text-transform: uppercase; letter-spacing: .04em; }
.char-field input, .char-field select, .char-field textarea { width: 100%; }
.form-actions { display: flex; gap: var(--space-2); margin-top: var(--space-3); flex-wrap: wrap; }
.gen-timer { color: var(--status-warning); animation: pulse 1.5s infinite; }
.pose-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
             gap: 8px; margin-top: 6px; }
.pose-slot { position: relative; width: 100%; aspect-ratio: 16/9; border-radius: 6px;
             overflow: hidden; background: var(--surface-mute); }
.pose-slot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pose-loading { position: absolute; inset: 0; background: var(--surface-overlay);
                display: flex; flex-direction: column; align-items: center; justify-content: center;
                gap: 6px; font-size: var(--text-xs); color: var(--text-inverse); }
.pose-loading::before { content: ""; width: 26px; height: 26px; border-radius: 50%;
                        border: 3px solid var(--border-inverse-strong); border-top-color: var(--accent);
                        animation: spin .9s linear infinite; }
.pose-placeholder { background: var(--surface-mute); color: var(--text-dim);
                    font-size: var(--text-xs); display: flex; align-items: center;
                    justify-content: center; width: 100%; aspect-ratio: 16/9;
                    border-radius: 6px; animation: pulse 1.6s ease-in-out infinite; }
.pose-rejected img { filter: grayscale(1); opacity: .45 !important; }
.pose-out { position: absolute; left: 0; right: 0; bottom: 0;
            background: var(--scrim-strong); color: var(--text-on-status); font-size: var(--text-xs);
            padding: 2px 0; text-align: center; }

/* ───────────────────────────────────────────────────────────────────────────
   12. ADMIN
   ─────────────────────────────────────────────────────────────────────────── */
.admin-layout { display: grid; grid-template-columns: 200px 1fr; gap: var(--space-5);
                align-items: start; }
.admin-nav { display: flex; flex-direction: column; gap: 2px; position: sticky; top: var(--space-5);
             background: var(--surface-raised); border: 1px solid var(--border);
             border-radius: var(--radius); padding: 8px; }
.admin-nav button {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  font-family: var(--font-sans); font-size: var(--text-sm); font-weight: 600;
  padding: 8px 10px; border: none; border-radius: var(--radius-sm);
  background: transparent; color: var(--text-dim); cursor: pointer;
  transition: background-color var(--fast), color var(--fast);
}
.admin-nav button:hover { background: var(--surface-sunken); color: var(--text-strong); }
.admin-nav button[aria-current="true"] { background: var(--accent); color: var(--accent-ink); }
.admin-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
              gap: var(--space-3); margin-bottom: var(--space-4); }
.admin-grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
                gap: var(--space-4); }
.admin-stat { padding: 14px 16px; }
.admin-stat-label { font-size: 10.5px; color: var(--text-dim); text-transform: uppercase;
                    letter-spacing: .05em; margin-bottom: 5px; }
.admin-stat-value { font-size: var(--text-2xl); font-weight: 700; color: var(--text-strong);
                    font-variant-numeric: tabular-nums; line-height: 1.15; }
.admin-stat-sub { font-size: var(--text-xs); color: var(--text-dim); margin-top: 3px; }
.admin-section { padding: 18px 20px; margin-bottom: var(--space-4); }
.admin-section > h3 { font-size: var(--text-md); margin-bottom: 6px; display: flex;
                      align-items: center; gap: 8px; flex-wrap: wrap; }
.admin-section > h3 + .hint { margin-bottom: var(--space-3); }
.admin-test-badge { background: var(--status-warning-soft); color: var(--status-warning); }
.admin-error-bucket { background: var(--status-danger-soft); color: var(--status-danger);
                      margin-right: 5px; margin-bottom: 4px; }
.admin-bar-row { display: flex; align-items: center; gap: 10px; margin-bottom: 8px;
                 font-size: var(--text-sm); }
.admin-bar-label { width: 120px; flex-shrink: 0; color: var(--text); overflow: hidden;
                   text-overflow: ellipsis; white-space: nowrap; }
.admin-bar-track { flex: 1; height: 10px; background: var(--surface-mute);
                   border-radius: var(--radius-pill); overflow: hidden; }
.admin-bar-fill { height: 100%; border-radius: var(--radius-pill); }
.admin-bar-value { width: 84px; text-align: right; flex-shrink: 0; color: var(--text-dim);
                   font-variant-numeric: tabular-nums; }
.admin-health-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%;
                    background: var(--text-dim); }
.admin-health-dot.ok { background: var(--status-success); }
.admin-health-dot.warn { background: var(--status-danger); }
.admin-error-row { border-top: 1px solid var(--border); padding: 9px 0; font-size: var(--text-sm);
                   overflow-wrap: anywhere; }
.admin-error-row:first-of-type { border-top: none; }
.admin-table { width: 100%; font-size: var(--text-sm); border-collapse: collapse; min-width: 700px; }
.admin-table th { text-align: left; font-size: 10.5px; text-transform: uppercase;
                  letter-spacing: .05em; color: var(--text-dim); font-weight: 700;
                  padding: 8px 8px; border-bottom: 1px solid var(--border); }
.admin-table td { padding: 9px 8px; border-bottom: 1px solid var(--border); vertical-align: top; }
.admin-table tr:hover td { background: var(--surface-sunken); }
/* The engine table is five columns of prose, not numbers, so the browser's auto layout
   gives the widest cell the most room and squeezes the first column to one word per line —
   exactly backwards, since the first column is what an admin scans down. Fixed layout with
   explicit widths instead. 820px is chosen to FIT the section at an ordinary laptop width
   rather than to be generous: a first pass used 1000px, which pushed "Where to change it"
   off the right edge behind a scrollbar on a 1500px screen — the column an admin most
   needs was the one they had to go looking for (2026-09-11). Below 820px it scrolls. */
#engines-table { table-layout: fixed; min-width: 820px; }
#engines-table th:nth-child(1), #engines-table td:nth-child(1) { width: 25%; }
#engines-table th:nth-child(2), #engines-table td:nth-child(2) { width: 16%; }
#engines-table th:nth-child(3), #engines-table td:nth-child(3) { width: 19%; }
#engines-table th:nth-child(4), #engines-table td:nth-child(4) { width: 13%; }
#engines-table th:nth-child(5), #engines-table td:nth-child(5) { width: 27%; }
#engines-table td code { font-size: var(--text-xs); word-break: break-all; }
#engines-table td .hint { max-width: none; }
.ledger-table th { text-align: left; font-size: 10.5px; text-transform: uppercase;
                   letter-spacing: .05em; color: var(--text-dim); padding: 6px 4px; }
.ledger-table td { padding: 6px 4px; border-bottom: 1px solid var(--border); }
.curve-legend { display: flex; gap: 16px; margin-top: 8px; font-size: var(--text-xs);
                color: var(--text-dim); flex-wrap: wrap; }
.curve-legend span { display: flex; align-items: center; gap: 5px; }
.curve-legend i { width: 12px; height: 2px; border-radius: 1px; display: inline-block; }
.chart-svg .grid-line { stroke: var(--border); stroke-width: 1; }
.chart-svg .axis-tick { font-size: 9.5px; fill: var(--text-dim); font-family: var(--font-sans); }
.chart-svg .curve-line { fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* Quality tiers — the one quality lever a customer still has, so the editor
   explains what each level buys rather than just naming it. */
.tier-card { background: var(--surface-raised); border: 1px solid var(--border);
             border-radius: var(--radius); padding: 16px 18px; margin-bottom: 14px;
             box-shadow: var(--shadow-sm); }
.tier-head { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; flex-wrap: wrap; }
.tier-tag { font-size: var(--text-xs); font-weight: 700; letter-spacing: .09em;
            text-transform: uppercase; color: var(--text-dim); min-width: 60px; }
.tier-label { flex: 1; min-width: 160px; font-size: var(--text-md); font-weight: 600; }
.tier-price { display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.tier-price input { width: 96px; text-align: right; font-weight: 600; }
.tier-price span { font-size: var(--text-xs); color: var(--text-dim); }
.tier-desc { width: 100%; margin-bottom: 8px; }
.tier-cost { font-size: var(--text-xs); color: var(--text-dim); background: var(--surface-sunken);
             border-radius: var(--radius); padding: 8px 10px; margin-bottom: 12px; }
.tier-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
             gap: 10px 16px; margin-bottom: 14px; }
.tier-field { display: flex; flex-direction: column; gap: 4px; font-size: var(--text-xs);
              color: var(--text-dim); }
.tier-field select { width: 100%; }
.tier-pacing { border-top: 1px solid var(--border); padding-top: 12px; }
.tier-pacing-head { display: flex; gap: 10px; align-items: baseline; margin-bottom: 8px;
                    flex-wrap: wrap; font-size: var(--text-sm); }
.tier-table { border-collapse: collapse; font-size: var(--text-xs); margin-bottom: 8px; }
.tier-table th { font-weight: 700; color: var(--text-dim); text-align: left;
                 padding: 4px 8px 6px 0; }
.tier-table td { padding: 3px 8px 3px 0; }
.tier-table input { width: 84px; text-align: right; }
.tier-table tr.bad input[data-sec]:not([data-sec='start']):not([data-sec='end']) {
  border-color: var(--status-danger); }
/* The photo-quality explainer table (docs/ENGINES.md, in the UI). */
.explain-table { width: 100%; border-collapse: collapse; font-size: var(--text-xs);
                 min-width: 460px; }
.explain-table th { text-align: left; color: var(--text-dim); font-weight: 700;
                    text-transform: uppercase; letter-spacing: .05em; font-size: 10px;
                    padding: 6px 8px; border-bottom: 1px solid var(--border); }
.explain-table td { padding: 7px 8px; border-bottom: 1px solid var(--border);
                    vertical-align: top; color: var(--text); }
.explain-table td:first-child { font-family: var(--font-mono); color: var(--text-strong);
                                white-space: nowrap; }

/* Admin redesign (2026-09-13): grouped nav, status strip, attention list, tables ─── */
.admin-nav .admin-nav-group { font-size: 10px; text-transform: uppercase; letter-spacing: .08em; color: var(--text-dim);
                              padding: 10px 10px 4px; font-weight: 700; }
.admin-nav .admin-nav-group:first-child { padding-top: 4px; }
.admin-status-strip { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; font-size: var(--text-xs); color: var(--text-dim);
                      margin: 4px 0 var(--space-4); }
.admin-status-strip .chip { font-size: 11px; }
.chip-warning { background: var(--status-warning-soft); color: var(--status-warning); }
.attention-list { display: flex; flex-direction: column; gap: 6px; }
.attention-item { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-radius: var(--radius-sm);
                  border: 1px solid var(--border); background: var(--surface-raised); font-size: var(--text-sm); cursor: pointer; }
.attention-item:hover { background: var(--surface-sunken); }
.attention-item .dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; background: var(--text-dim); }
.attention-item.danger .dot { background: var(--status-danger); }
.attention-item.warning .dot { background: var(--status-warning); }
.attention-item.info .dot { background: var(--status-info); }
.attention-item .arrow { margin-left: auto; color: var(--text-dim); }
.attention-ok { color: var(--status-success); font-size: var(--text-sm); }
.atable { position: relative; }
.atable-bar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 8px; }
.atable-bar-right { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; }
.atable-search { max-width: 260px; }
.atable-count { white-space: nowrap; }
.atable-table { min-width: 900px; }
.atable-table th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
.atable-table th.sortable:hover { color: var(--text-strong); }
.atable-sort { color: var(--accent-text); }
.atable-filters th { padding: 2px 4px 8px; }
.atable-fin { width: 100%; min-width: 70px; font-size: 12px; padding: 4px 6px; height: 28px; }
.atable-range { display: flex; gap: 3px; }
.atable-range .atable-fin { min-width: 60px; width: 60px; font-size: 11px; padding: 4px 4px; }
.atable-range input[type=date].atable-fin { min-width: 122px; width: 122px; }
.atable-table { font-size: 12.5px; }
.atable-table td { padding: 6px 7px; }
.atable-table td { white-space: nowrap; max-width: 320px; overflow: hidden; text-overflow: ellipsis; }
.atable-table td.ta-right, .atable-table th.ta-right { text-align: right; font-variant-numeric: tabular-nums; }
.atable-row-click { cursor: pointer; }
.atable-empty { text-align: center; padding: 28px 8px !important; }
.atable-thumb { width: 72px; height: 40px; object-fit: cover; border-radius: 4px; background: var(--surface-mute); display: block; }
.atable-foot { display: flex; align-items: center; gap: 10px; margin-top: 8px; font-size: var(--text-sm); }
.atable-size { margin-left: auto; width: auto; font-size: 12px; height: 28px; padding: 2px 6px; }
.atable-loading .atable-table { opacity: .55; transition: opacity .15s; }
.atable-sub .atable-table { min-width: 0; }
.detail-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.live-jobs { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: var(--space-3); margin-bottom: var(--space-3); }
@media (max-width: 900px) { .admin-layout { grid-template-columns: 1fr; } .admin-nav { position: static; flex-direction: row; flex-wrap: wrap; } .admin-nav .admin-nav-group { width: 100%; } }

/* ───────────────────────────────────────────────────────────────────────────
   13. MODALS
   ─────────────────────────────────────────────────────────────────────────── */
.modal-scrim { position: fixed; inset: 0; background: var(--surface-overlay); z-index: 1000;
               display: flex; align-items: center; justify-content: center;
               padding: var(--gutter); }
.modal-panel { background: var(--surface-raised); color: var(--text);
               border: 1px solid var(--border); border-radius: var(--radius-lg);
               box-shadow: var(--shadow-lg); width: min(1100px, 100%);
               max-height: 88vh; display: flex; flex-direction: column; overflow: hidden; }
.modal-head { display: flex; justify-content: space-between; align-items: center; gap: 10px;
              padding: 14px 18px; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
.modal-body { margin: 0; padding: 18px; overflow: auto; white-space: pre-wrap;
              font-size: var(--text-sm); line-height: 1.5; flex: 1;
              font-family: var(--font-mono); }

/* Character wizard — first-run "no character, no project" gate (2026-09-15,
   Menno: "maak het verplicht om eerst een character aan te maken, met een leuke manier
   van een animation, met een stap. zonder character geen project.") ───────────────── */
.wizard-panel { max-width: 560px; padding: 26px 28px; }
.wizard-steps { display: flex; gap: 6px; margin-bottom: 18px; }
.wizard-step-dot { height: 4px; flex: 1; border-radius: 2px; background: var(--surface-mute);
                    transition: background .2s; }
.wizard-step-dot.active { background: var(--accent); }
.wizard-loading { text-align: center; padding: 34px 10px 18px; }
.wizard-spinner { font-size: 40px; display: inline-block; animation: wizardFloat 1.8s ease-in-out infinite; }
@keyframes wizardFloat { 0%, 100% { transform: translateY(0) scale(1); } 50% { transform: translateY(-8px) scale(1.08); } }
.wizard-loading h2 { margin: 14px 0 4px; font-size: var(--text-lg); }
.wizard-candidates .pose-slot { cursor: pointer; transition: outline-color .15s, transform .1s; outline: 2px solid transparent; }
.wizard-candidates .pose-slot:hover { outline-color: var(--accent); transform: translateY(-2px); }

/* Voice library picker (2026-09-13) ───────────────────────────────────────── */
.voice-card { display: flex; flex-direction: column; gap: 3px; text-align: left; padding: 10px 12px; border: 1px solid var(--border-strong);
              border-radius: var(--radius); background: var(--surface-raised); color: var(--text); cursor: pointer; font-family: var(--font-sans); font-size: var(--text-sm); }
.voice-card:hover { border-color: var(--text-dim); }
.voice-card.selected { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-ring); }
.voice-card.featured { background: var(--accent-soft); }
.voice-head { display: flex; align-items: center; gap: 6px; }
.voice-head .voice-play { margin-left: auto; width: 26px; height: 26px; border-radius: 50%; border: 1px solid var(--border-strong); display: inline-flex; align-items: center; justify-content: center; font-size: 11px; background: var(--surface-raised); }
.voice-head .voice-play:hover { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.voice-note { font-size: var(--text-xs); color: var(--text); }
.voice-picker { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 6px; }
.voice-picker .voice-current { min-width: 260px; max-width: 420px; cursor: default; }
.voice-modal { width: min(720px, 100%); max-height: 86vh; }
.voice-tools { padding: 10px 18px 6px; border-bottom: 1px solid var(--border); display: flex; flex-direction: column; gap: 8px; }
.voice-search { width: 100%; }
.voice-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.voice-chip { cursor: pointer; border: 1px solid var(--border-strong); background: var(--surface-raised); color: var(--text-dim); }
.voice-chip.on { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.voice-list { overflow: auto; flex: 1; padding: 6px 10px 10px; }
.voice-row { display: flex; align-items: center; gap: 12px; padding: 9px 8px; border-bottom: 1px solid var(--border); }
.voice-row:hover { background: var(--surface-sunken); }
.voice-row.selected { background: var(--accent-soft); }
.voice-row .voice-play { width: 30px; height: 30px; border-radius: 50%; border: 1px solid var(--border-strong); background: var(--surface-raised); cursor: pointer; flex-shrink: 0; }
.voice-row .voice-play:hover { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.voice-row-main { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; font-size: var(--text-sm); }
/* ElevenLabs-style dials on the settings page (2026-09-13) */
.voice-dial { display: grid; grid-template-columns: minmax(140px, 220px) 1fr 52px; gap: 12px; align-items: center; margin-top: 10px; font-size: var(--text-sm); }
.voice-dial label { display: flex; flex-direction: column; gap: 1px; }
.voice-dial label .hint { font-size: var(--text-xs, 11px); }
.voice-dial input[type=range] { width: 100%; accent-color: var(--accent); }
.voice-dial output { text-align: right; font-variant-numeric: tabular-nums; color: var(--text-dim); }
.link-btn { background: none; border: 0; padding: 0; color: var(--accent); cursor: pointer; font: inherit; text-decoration: underline; }
@media (max-width: 560px) { .voice-dial { grid-template-columns: 1fr 52px; } .voice-dial label { grid-column: 1 / -1; } }

/* Toasts + confirm/prompt dialogs (2026-09-13, static/app.js) ─────────────── */
.impersonation-bar { position: sticky; top: 0; z-index: 50; display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
                     background: var(--status-warning-soft); color: var(--status-warning); border-bottom: 1px solid var(--status-warning);
                     padding: 8px 16px; font-size: var(--text-sm); margin: 0 0 12px; }
.impersonation-bar .btn-ghost { margin-left: auto; }
.text-success { color: var(--status-success); }
.text-danger  { color: var(--status-danger); }
#sp-toasts { position: fixed; right: 16px; bottom: 16px; z-index: 1100; display: flex; flex-direction: column;
             gap: 8px; max-width: min(420px, calc(100vw - 32px)); pointer-events: none; }
.sp-toast { pointer-events: auto; display: flex; align-items: flex-start; gap: 10px;
            background: var(--surface-raised); color: var(--text); border: 1px solid var(--border-strong);
            border-left: 4px solid var(--text-dim); border-radius: var(--radius); box-shadow: var(--shadow-lg);
            padding: 10px 12px; font-size: var(--text-sm); line-height: 1.4; animation: riseIn .18s ease-out;
            white-space: pre-wrap; word-break: break-word; }
.sp-toast-success { border-left-color: var(--status-success); }
.sp-toast-error   { border-left-color: var(--status-danger); }
.sp-toast-out     { opacity: 0; transform: translateY(6px); transition: opacity .2s, transform .2s; }
.sp-toast-x { margin-left: auto; background: none; border: 0; color: var(--text-dim); font-size: 18px; line-height: 1;
              cursor: pointer; padding: 0 2px; }
.sp-toast-x:hover { color: var(--text); }
.sp-dialog { width: min(460px, 100%); animation: dropIn .15s ease-out; }
.sp-dialog-body { padding: 16px 18px; font-size: var(--text-sm); line-height: 1.5; white-space: pre-wrap; }
.sp-dialog-input { display: block; width: 100%; margin-top: 12px; }
.sp-dialog-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 18px; border-top: 1px solid var(--border); }
@media (prefers-reduced-motion: reduce) { .sp-toast, .sp-dialog { animation: none; } }

/* ───────────────────────────────────────────────────────────────────────────
   14. MOTION
   ─────────────────────────────────────────────────────────────────────────── */
@keyframes spin      { to { transform: rotate(360deg); } }
@keyframes pulse     { 0%, 100% { opacity: 1 } 50% { opacity: .5 } }
@keyframes shimmer   { 0% { background-position: -70px 0 } 100% { background-position: 140px 0 } }
@keyframes riseIn    { from { opacity: 0; transform: translateY(12px) } to { opacity: 1; transform: none } }
@keyframes dropIn    { from { opacity: 0; transform: translateY(-6px) } to { opacity: 1; transform: none } }
@keyframes slideInLeft { from { transform: translateX(-100%) } to { transform: none } }

[data-reveal] { opacity: 0; transform: translateY(12px);
                transition: opacity .45s ease, transform .45s var(--ease);
                transition-delay: calc(var(--reveal-i, 0) * 45ms); }
[data-reveal].in-view { opacity: 1; transform: none; }

.editor-card, .admin-stat, .admin-section, .setting-card, .char-card, .project-card {
  transition: transform var(--fast), box-shadow var(--fast), border-color var(--fast);
}
.editor-card:hover, .admin-section:hover, .setting-card:hover {
  box-shadow: var(--shadow); border-color: var(--border-strong);
}
.admin-stat:hover { box-shadow: var(--shadow); }

/* ───────────────────────────────────────────────────────────────────────────
   15. RESPONSIVE
   The rail becomes a top bar plus a slide-in drawer; every dense grid
   collapses to one column; every wide table is already inside its own
   .table-scroll / .shot-scroll, so the page body itself never scrolls
   sideways at any width down to 320px.
   ─────────────────────────────────────────────────────────────────────────── */
@media (max-width: 1040px) {
  .admin-layout { grid-template-columns: 1fr; }
  .admin-nav { position: static; flex-direction: row; overflow-x: auto; gap: 4px; }
  .admin-nav button { width: auto; white-space: nowrap; }
}

@media (max-width: 860px) {
  :root { --sidebar-w: 0px; }
  #app { grid-template-columns: 1fr; }

  .appbar {
    display: flex; align-items: center; gap: 10px;
    position: sticky; top: 0; z-index: 45;
    padding: 10px var(--gutter);
    background: var(--surface-inverse); color: var(--text-inverse);
    border-bottom: 1px solid var(--border-inverse);
  }
  .appbar .logo { padding: 0; font-size: var(--text-md); }
  .appbar-spacer { flex: 1; }
  .appbar-btn {
    display: flex; align-items: center; justify-content: center;
    width: 36px; height: 36px; border-radius: var(--radius-sm);
    background: var(--surface-inverse-hover); border: 1px solid var(--border-inverse);
    color: var(--text-inverse); cursor: pointer; flex-shrink: 0;
  }
  .appbar-btn:hover { background: var(--border-inverse-strong); }

  .sidebar {
    position: fixed; inset: 0 auto 0 0; width: min(280px, 84vw);
    transform: translateX(-100%); transition: transform var(--slow) var(--ease);
    box-shadow: var(--shadow-lg); height: 100dvh;
  }
  #app.drawer-open .sidebar { transform: none; }
  #app.drawer-open .drawer-scrim {
    display: block; position: fixed; inset: 0; z-index: 39;
    background: var(--surface-overlay); border: none;
  }
  .main { padding-block: var(--space-5); }
  .flow-head { gap: 10px; }
  .steptrack-item { flex-basis: 100%; }
  .admin-grid { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
  .tier-grid { grid-template-columns: 1fr; }
  .assets-stats-bar { justify-content: space-between; }
  .stat-item { min-width: 64px; padding: 4px 8px; }
}

@media (max-width: 560px) {
  :root { --text-xl: 19px; --text-2xl: 23px; }
  .dashboard-header { align-items: flex-start; flex-direction: column; }
  .project-grid { grid-template-columns: 1fr; }
  .cost-item { flex-basis: 100%; }
  .cost-item.cost-total { border-left: none; padding-left: 0; border-top: 2px solid var(--accent);
                          padding-top: 10px; }
  .setting-input-row > * { flex: 1 1 100%; }
  .setting-input-row > button, .setting-input-row > .btn-ghost { flex: 0 0 auto; }
  .admin-bar-label { width: 88px; }
  .admin-bar-value { width: 70px; }
  .shot-scroll { max-height: none; }
  .modal-panel { max-height: 92vh; }
}

@media print {
  .sidebar, .appbar, .actions { display: none !important; }
  #app { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important;
                           transition-duration: .001ms !important; }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
}

/* ── Animation template gallery (/animations/preview) ───────────────────── */
.anim-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(420px, 100%), 1fr));
             gap: 20px; margin-top: var(--space-5); }
.anim-card { background: var(--surface-raised); border: 1px solid var(--border);
             border-radius: var(--radius); overflow: hidden; }
.anim-stage { position: relative; width: 100%; aspect-ratio: 16/9; background: var(--media-bg);
              cursor: pointer; overflow: hidden; }
.anim-meta { padding: 12px 14px; }

/* Live brand preview — the card is authored on a fixed 1920x1080 canvas, so the
   iframe renders at that size and is scaled by JS to the box's real width. */
.brand-preview { margin-top: 16px; border-radius: var(--radius); overflow: hidden;
                 border: 1px solid var(--border-strong); background: var(--media-bg);
                 width: 100%; max-width: 480px; height: 270px; position: relative; }
.brand-preview iframe { border: 0; position: absolute; top: 0; left: 0;
                        transform-origin: 0 0; transform: scale(.25); }

/* Step indicator is an <ol>: drop the markers, keep the semantics. */
.steptrack { list-style: none; }

/* Presenter status card — warm while blocked (no presenter, or no reference image
   yet), calm once it is ready, instead of one flat neutral box for both. */
#presenter-box.presenter-warn { background: var(--accent-soft); border-color: var(--accent); }
#presenter-box.presenter-ready { background: var(--status-success-soft);
                                 border-color: color-mix(in srgb, var(--status-success) 30%, transparent); }
.token-est { font-variant-numeric: tabular-nums; }
.admin-panes { min-width: 0; }

/* ── Admin → Engines: the per-component editor ──────────────────────────────
   2026-09-11 (Menno: "ik wil deze allemaal op de engines pagina kunnen aanpassen").
   The table stays the overview — an admin scanning "what runs what" should not have to
   open anything — and a row expands into the form below it. Every control is built from
   field metadata, so this styles TYPES (a grid of fields, an error under one of them),
   never a named setting. */
.engine-editor-row > td { background: var(--surface-sunken); padding: 0 8px 14px; }
/* The overview table is wider than a phone and scrolls sideways inside .table-scroll. The
   form must not go with it: sticky-left keeps the open editor in view while the columns
   above it scroll, so a 400px screen gets a usable form instead of one 700px wide. */
.engine-editor { padding: 14px 2px 2px; position: sticky; left: 0;
                 max-width: min(900px, calc(100vw - 40px)); }
.engine-editor-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.engine-editor-head > label { font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em;
                              color: var(--text-dim); font-weight: 700; }
.engine-editor-head select { min-width: min(360px, 100%); }
.engine-notes { margin: 8px 0 0; max-width: 70ch; }
.engine-price { margin: var(--space-3) 0 0; font-size: var(--text-xs); color: var(--accent-text);
                font-weight: 600; }
.engine-keymissing { color: var(--status-danger); }
/* A price the admin is looking at but has not saved yet must not read as the live rate. */
.engine-unsaved { color: var(--accent-text); font-weight: 600;
                  border-left: 2px solid var(--accent); padding-left: 6px; }

/* ── The typed-field form, shared by Engines and Prompting ──────────────────
   2026-09-11. Both pages are rendered from the same field metadata by the same functions
   in admin.html, so they are styled once here. Everything below is named for a field TYPE
   or a form PART — never for a setting, a driver or a rule — which is what lets a new
   field appear on either page without a line of CSS. */
.form-fields { display: grid; gap: var(--space-3); margin-top: var(--space-3);
               grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.form-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.form-field-wide { grid-column: 1 / -1; }
.form-field > label { font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em;
                      color: var(--text-dim); font-weight: 700; }
.form-field input[type="checkbox"] { width: 18px; height: 18px; }
.form-field textarea { font-family: var(--font-mono); font-size: var(--text-xs); }
.field-tag { text-transform: none; letter-spacing: 0; font-weight: 600;
             color: var(--accent-text); }
/* The placeholders a template supports, and what it costs to drop one. The warning is a
   warning and not an error colour: removing {text} is a legitimate rewrite, it is just
   never an accident worth leaving unsaid. */
.field-placeholders { font-family: var(--font-mono); }
.field-warn { font-size: var(--text-xs); color: var(--status-warning); font-weight: 600; }
/* The server validates every value before it writes any of them, so a rejection is one
   sentence about one field. It belongs under that field: an alert at the top of a form with
   eight inputs makes the admin work out which box it meant. */
.form-error { font-size: var(--text-xs); color: var(--status-danger); font-weight: 600; }
.form-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center;
                margin-top: var(--space-4); }
.form-actions .form-reset { margin-left: auto; }
.form-msg { margin: var(--space-2) 0 0; font-size: var(--text-xs); font-weight: 600; }
.form-msg-ok  { color: var(--status-success); }
.form-msg-bad { color: var(--status-danger); }

/* ── A json rule, edited as rows or chips ───────────────────────────────────
   A material library and a verb list are lookups an operator maintains, not documents they
   author, so the friendly editor is the default and the raw box is one click away for
   anything it cannot express. */
.json-editor { display: flex; flex-direction: column; gap: var(--space-2);
               border: 1px solid var(--border); border-radius: var(--radius-sm);
               background: var(--surface-raised); padding: var(--space-2); min-width: 0; }
.json-rows { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
/* key | value | remove. The key column is fixed so the clauses line up and can be read down
   the page; below 560px the row stacks, because two side-by-side boxes on a phone are two
   boxes too narrow to read either. */
.json-row { display: grid; grid-template-columns: minmax(90px, 160px) 1fr auto;
            gap: 6px; align-items: start; min-width: 0; }
.json-row .json-key { font-family: var(--font-mono); font-size: var(--text-xs); min-width: 0; }
.json-row .json-val { font-family: var(--font-mono); font-size: var(--text-xs);
                      min-width: 0; resize: vertical; }
.json-del { color: var(--text-dim); line-height: 1; padding: 4px 8px; }
.json-rows:has(.json-chip) { flex-direction: row; flex-wrap: wrap; gap: 6px; }
.json-chip { display: inline-flex; align-items: center; gap: 4px;
             background: var(--surface-mute); border: 1px solid var(--border);
             border-radius: var(--radius-pill); padding: 2px 4px 2px 10px;
             font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text); }
.json-chip-del { border: 0; background: none; cursor: pointer; color: var(--text-dim);
                 font-size: var(--text-sm); line-height: 1; padding: 0 4px; }
.json-chip-del:hover { color: var(--status-danger); }
.json-chip-input { font-family: var(--font-mono); font-size: var(--text-xs);
                   max-width: min(280px, 100%); }
.json-raw { font-family: var(--font-mono); font-size: var(--text-xs); width: 100%; }
.json-toggle { align-self: flex-start; }
.json-note { color: var(--status-warning); font-weight: 600; }

/* ── Admin → Prompting ──────────────────────────────────────────────────────
   One card per shot type, each its own block with its own Save, because the rules are
   validated and written per group: a shared save button would suggest one atomic change
   the server does not make. The shot types come first and the rules they share follow, so
   the page reads in the order the work is done. */
.prompting-jump { display: flex; flex-wrap: wrap; gap: var(--space-2);
                  margin-top: var(--space-3); }
.prompting-jump-link { font-size: var(--text-xs); font-weight: 600;
                       border: 1px solid var(--border); border-radius: var(--radius-pill);
                       padding: 3px 10px; text-decoration: none; color: var(--text); }
.prompting-jump-link:hover { border-color: var(--accent); color: var(--accent-text); }
.prompting-kind { margin-top: var(--space-5); font-size: 10.5px; text-transform: uppercase;
                  letter-spacing: .06em; color: var(--text-dim); }
.prompting-group { margin-top: var(--space-4); padding-top: var(--space-4);
                   border-top: 1px solid var(--border); max-width: 90ch;
                   scroll-margin-top: var(--space-5); }
.prompting-group > h4 { font-size: var(--text-md); margin-bottom: 4px; }
/* Which engines make this kind of shot. It is the first thing anyone wants to know when a
   shot type looks wrong, and it used to be on another tab. */
.prompting-engines { display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
                     margin-bottom: 4px; }
.prompting-arrow { color: var(--text-dim); }
.prompting-handed-label { font-weight: 600; margin-top: var(--space-3); }
/* The example is a prompt, so it is shown as one: monospace, wrapped, never a scrollbar an
   admin has to drag sideways to read the end of a sentence. */
.prompting-example { margin-top: var(--space-3); background: var(--surface-sunken);
                     border: 1px solid var(--border); border-radius: var(--radius-sm);
                     padding: var(--space-3); }
.prompting-example pre { font-family: var(--font-mono); font-size: var(--text-xs);
                         white-space: pre-wrap; overflow-wrap: anywhere; margin: 0;
                         color: var(--text-strong); }
.prompting-example p { margin-top: 6px; }

@media (max-width: 560px) {
  .form-actions .form-reset { margin-left: 0; }
  .engine-editor-head select { min-width: 100%; }
  .json-row { grid-template-columns: 1fr auto; }
  .json-row .json-val { grid-column: 1 / -1; }
}

/* ═══ The project page in three states (2026-09-12) ═══════════════════════════
   setup / loading / editor — see templates/editor.html. The editor is a CapCut-shaped
   layout: preview + inspector on top, one horizontal timeline of clips below. */
.ed-view { animation: dropIn .3s var(--ease); }
.ed-channel-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 12px; }
#voice-box.presenter-warn, #presenter-box.presenter-warn { background: var(--accent-soft); border-color: var(--accent); }

/* loading: nothing else on the page */
.ed-loading { max-width: 520px; margin: 12vh auto 0; text-align: center; padding: 36px 28px;
              background: var(--surface-raised); border: 1px solid var(--border); border-radius: var(--radius-lg);
              box-shadow: var(--shadow); }
.ed-loading-spinner { display: flex; justify-content: center; margin-bottom: 18px; }
.ed-loading-spinner .spinner { width: 34px; height: 34px; border-width: 4px; }
.ed-loading h1 { margin-bottom: 6px; }
.ed-loading-bar { margin-top: 22px; height: 8px; }
.ed-loading-meta { margin-top: 8px; font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-dim);
                   display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.ed-loading-msg { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* editor — the whole window, laid out like a video editor. Always dark: the stage is
   what the eye should be on, whatever the app theme. Everything below uses --e-* tokens. */
#main.main-editor { padding: 0; animation: none; }
#main.main-editor .dashboard-content { max-width: none; margin: 0; }
.ed-app { display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto minmax(0, 1fr) auto; height: 100vh; min-height: 560px; width: 100%; overflow: hidden;
          background: var(--e-bg); color: var(--e-text); color-scheme: dark; }
.ed-app .hint { color: var(--e-dim); }
.ed-app h1 { color: var(--e-text); }
.ed-app select, .ed-app input[type=search], .ed-app textarea { background: var(--e-raised); color: var(--e-text); border-color: var(--e-border); }
.ed-app .btn-ghost.ed-dark-btn, .ed-app .btn-ghost { background: var(--e-raised); color: var(--e-text); border-color: var(--e-border); }
.ed-app .btn-ghost:hover { background: var(--e-hover); border-color: var(--e-border-strong); }
.ed-app .banner-error { background: var(--e-danger-soft); color: var(--e-danger); }
.ed-app .banner-warn { background: var(--e-warn-soft); color: var(--e-warn); }
.ed-app .banner-ok { background: var(--e-ok-soft); color: var(--e-ok); }
.ed-app a { color: var(--accent-text); }

.ed-top { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 8px 14px 8px 12px;
          border-bottom: 1px solid var(--e-border); background: var(--e-panel); }
.ed-top-title { display: flex; align-items: center; gap: 10px; min-width: 0; }
.ed-top-mark { width: 26px; height: 26px; border-radius: 7px; background: var(--accent); color: var(--accent-ink); display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.ed-top-title h1 { margin: 0; font-size: var(--text-lg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 36vw; }
.ed-status { font-size: var(--text-xs); font-weight: 700; padding: 3px 10px; border-radius: var(--radius-pill); white-space: nowrap; }
.ed-status.is-ready { background: var(--e-ok-soft); color: var(--e-ok); }
.ed-status.is-partial { background: var(--e-info-soft); color: var(--e-info); }
.ed-status.is-error { background: var(--e-danger-soft); color: var(--e-danger); }
.ed-top-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.ed-banners { padding: 0 14px; }
.ed-banners .banner { margin: 8px 0 0; }

/* body: rail · panel · stage · inspector · rail */
.ed-body { display: grid; grid-template-columns: 64px auto minmax(0, 1fr) auto 64px; min-height: 0; }
.ed-rail { display: flex; flex-direction: column; gap: 2px; padding: 8px 6px; background: var(--e-panel); overflow-y: auto; }
.ed-rail-left { border-right: 1px solid var(--e-border); }
.ed-rail-right { border-left: 1px solid var(--e-border); }
.ed-rail-btn { display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 9px 2px 7px; border-radius: 8px;
               background: transparent; border: none; color: var(--e-dim); font-size: 10px; font-weight: 600; cursor: pointer; line-height: 1.1; text-align: center; }
.ed-rail-btn:hover { background: var(--e-hover); color: var(--e-text); }
.ed-rail-btn.active { background: var(--e-raised); color: var(--accent-text); box-shadow: inset 3px 0 0 var(--accent); }
.ed-rail-ico { font-size: 17px; line-height: 1; height: 20px; display: flex; align-items: center; }
.ed-panel { width: 300px; border-right: 1px solid var(--e-border); background: var(--e-panel); display: flex; flex-direction: column; min-height: 0; }
.ed-panel[hidden] { display: none !important; }
.ed-panel-head { display: flex; align-items: center; gap: 8px; padding: 10px 10px 10px 14px; border-bottom: 1px solid var(--e-border); }
.ed-panel-head b { font-size: var(--text-sm); white-space: nowrap; }
.ed-panel-head input { flex: 1; min-width: 0; font-size: var(--text-xs); padding: 5px 8px; border-radius: 6px; border: 1px solid var(--e-border); }
.ed-panel-close { height: 26px; min-width: 26px; padding: 0; }
.ed-panel-body { flex: 1; min-height: 0; overflow-y: auto; padding: 10px 12px 20px; scrollbar-width: thin; }
.ed-chips { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 10px; }
.ed-cliplist { display: flex; flex-direction: column; gap: 4px; }
.ed-clipitem { display: grid; grid-template-columns: 84px minmax(0, 1fr); gap: 8px; padding: 5px; border-radius: 8px; cursor: pointer;
               border-left: 3px solid transparent; }
.ed-clipitem:hover { background: var(--e-hover); }
.ed-clipitem.sel { background: var(--e-raised); box-shadow: 0 0 0 1px var(--accent); }
.ed-clipitem-thumb { width: 84px; height: 48px; border-radius: 5px; background: var(--e-raised) center/cover no-repeat; }
.ed-clipitem-empty { background: repeating-linear-gradient(45deg, var(--e-raised), var(--e-raised) 6px, var(--e-panel) 6px, var(--e-panel) 12px); }
.ed-clipitem-head { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; font-size: var(--text-xs); }
.ed-clipitem-narr { font-size: 11.5px; color: var(--e-dim); line-height: 1.35; margin-top: 2px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.ed-clipitem.type-row-talking_head { border-left-color: var(--status-special); }
.ed-clipitem.type-row-broll, .ed-clipitem.type-row-broll_pip { border-left-color: var(--status-success); }
.ed-clipitem.type-row-activity { border-left-color: var(--status-warning); }
.ed-clipitem.type-row-pov_shot { border-left-color: var(--status-info); }
.ed-clipitem.type-row-photo { border-left-color: var(--status-neutral); }
.ed-clipitem.type-row-photo_edited { border-left-color: var(--accent); }
.ed-clipitem.type-row-animation { border-left-color: var(--status-danger); }
.ed-script { font-size: var(--text-md); line-height: 1.75; color: var(--e-dim); }
.ed-sentence { cursor: pointer; border-radius: 4px; padding: 1px 2px; }
.ed-sentence:hover { background: var(--e-hover); color: var(--e-text); }
.ed-sentence.sel { background: var(--accent); color: var(--accent-ink); }
.ed-cardlist { display: flex; flex-direction: column; gap: 8px; }
.ed-cardbox { background: var(--e-raised); border: 1px solid var(--e-border); border-radius: var(--radius-sm); padding: 10px 12px; cursor: pointer; }
.ed-cardbox:hover { border-color: var(--e-border-strong); }

.ed-preview { display: flex; flex-direction: column; min-width: 0; min-height: 0; background: var(--e-bg); }
.ed-preview-frame { position: relative; flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; margin: 14px 18px 0;
                    background: var(--e-black); border-radius: 10px; overflow: hidden; }
.ed-preview-frame video, .ed-preview-frame img { width: 100%; height: 100%; max-height: 100%; object-fit: contain; display: block; cursor: pointer; }
.ed-preview-empty { color: var(--e-faint); font-size: var(--text-sm); }
.ed-transport { display: flex; align-items: center; gap: 6px; padding: 10px 18px; flex-wrap: wrap; }
.ed-tbtn { background: var(--e-raised); border: 1px solid var(--e-border); color: var(--e-text);
           border-radius: 7px; min-width: 32px; height: 30px; padding: 0 8px; cursor: pointer; font-size: 13px;
           display: inline-flex; align-items: center; justify-content: center; }
.ed-tbtn:hover { background: var(--e-hover); }
.ed-tbtn:disabled { opacity: .35; cursor: default; }
.ed-tbtn-play { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); min-width: 42px; font-size: 15px; }
.ed-tbtn-play:hover { background: var(--accent-hover); }
.ed-time { font-family: var(--font-mono); font-size: var(--text-sm); margin: 0 8px; white-space: nowrap; }
.ed-caption { font-size: var(--text-xs); color: var(--e-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }

.ed-inspector { width: 320px; border-left: 1px solid var(--e-border); background: var(--e-panel); padding: 14px 16px 24px; overflow-y: auto; min-height: 0; scrollbar-width: thin; }
.ed-inspector[hidden] { display: none !important; }
.ed-inspector-empty { color: var(--e-dim); font-size: var(--text-sm); padding: 24px 0; text-align: center; }
.ed-ins-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.ed-ins-asset img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: var(--radius-sm); display: block; margin-bottom: 4px; }
.ed-ins-section { margin-top: 14px; }
.ed-ins-label { font-size: var(--text-xs); color: var(--e-dim); text-transform: uppercase; letter-spacing: .06em; font-weight: 700; margin-bottom: 4px; }
.ed-ins-text { font-size: var(--text-md); color: var(--e-text); line-height: 1.55; }
.ed-ins-card-title { font-weight: 700; color: var(--e-text); font-size: var(--text-lg); }
.ed-ins-card-figure { font-family: var(--font-mono); font-size: var(--text-xl); color: var(--accent-text); font-weight: 700; margin-top: 2px; }
.ed-ins-card-lines { margin: 6px 0 0 18px; padding: 0; font-size: var(--text-sm); color: var(--e-dim); }
.ed-ins-card-lines li { margin: 2px 0; }
.ed-ins-cut { display: flex; gap: 10px; align-items: center; margin-top: 6px; font-size: var(--text-sm); }
.ed-ins-cut img { width: 72px; height: 40px; object-fit: cover; border-radius: 6px; }
.ed-ins-cut-empty { width: 72px; height: 40px; border-radius: 6px; background: var(--e-raised); font-size: var(--text-xs);
                    color: var(--e-dim); display: flex; align-items: center; justify-content: center; }
.ed-ins-buttons { display: flex; gap: 6px; flex-wrap: wrap; }
.ed-ins-ai { width: 100%; min-height: 80px; margin-top: 4px; border-radius: 8px; }
.ed-choice { display: flex; flex-direction: column; gap: 4px; }
.ed-choice-btn { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; text-align: left; padding: 8px 10px; border-radius: 8px;
                 background: var(--e-raised); border: 1px solid var(--e-border); color: var(--e-text); cursor: pointer; font-size: var(--text-sm); }
.ed-choice-btn:hover { background: var(--e-hover); }
.ed-choice-btn.sel { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.ed-soon { font-size: 10px; background: var(--e-raised); color: var(--e-dim); border-radius: var(--radius-pill);
           padding: 1px 7px; margin-left: 6px; text-transform: none; letter-spacing: 0; font-weight: 600; }
.ed-admin-grid { display: grid; grid-template-columns: 90px minmax(0, 1fr); gap: 5px 10px; margin-top: 8px; font-size: var(--text-sm); word-break: break-word; }
.ed-admin-grid .ed-ins-label { margin: 0; padding-top: 2px; }
/* admin: distribution vs settings (editor project panel, 2026-09-14) */
.ed-dist-table { border-collapse: collapse; font-size: var(--text-sm); width: 100%; }
.ed-dist-table th, .ed-dist-table td { text-align: left; padding: 4px 8px 4px 0; border-bottom: 1px solid var(--e-border); white-space: nowrap; vertical-align: top; }
.ed-dist-table th { font-weight: 600; }
.ed-dist-ok { color: var(--e-ok); }
.ed-dist-bad { color: var(--e-warn); font-weight: 600; }
.ed-admin-block { margin-top: 10px; }
.ed-admin-mono { font-family: var(--font-mono); font-size: var(--text-xs); white-space: pre-wrap; word-break: break-word;
                 background: var(--e-raised); border-radius: 6px; padding: 8px 10px; line-height: 1.5; }
.ed-more summary { list-style: none; cursor: pointer; font-family: var(--font-mono); font-size: var(--text-xs); color: var(--e-text);
                   background: var(--e-raised); border-radius: 6px; padding: 8px 10px; line-height: 1.5; word-break: break-word; }
.ed-more summary::-webkit-details-marker { display: none; }
.ed-more[open] summary { display: none; }
.ed-more-btn { color: var(--accent-text); font-weight: 700; white-space: nowrap; }

/* the loading overlay */
.ed-overlay { position: absolute; inset: 0; z-index: 20; background: var(--e-overlay); display: flex; align-items: center; justify-content: center; }
.ed-overlay[hidden] { display: none !important; }
.ed-overlay-card { display: flex; align-items: center; gap: 14px; background: var(--e-panel); border: 1px solid var(--e-border);
                   border-radius: var(--radius); padding: 18px 22px; box-shadow: var(--shadow-lg); color: var(--e-text); }
.ed-overlay-card .spinner { width: 26px; height: 26px; }
.ed-app { position: relative; }

/* timeline: ruler + text track + video track + audio track */
.ed-timeline-wrap { border-top: 1px solid var(--e-border); background: var(--e-panel); padding: 6px 14px 10px; }
.ed-timeline-tools { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
.ed-timeline-tools input[type=range] { width: 120px; accent-color: var(--accent); }
.ed-timeline { position: relative; overflow-x: auto; overflow-y: hidden; padding-bottom: 4px; outline: none; scrollbar-width: thin; }
.ed-timeline:focus-visible { box-shadow: 0 0 0 2px var(--accent-ring); border-radius: 6px; }
.ed-tl-inner { position: relative; min-width: 100%; }
.ed-ruler { position: relative; height: 18px; font-family: var(--font-mono); font-size: 10px; color: var(--e-dim); cursor: pointer; border-bottom: 1px solid var(--e-border); }
.ed-tick { position: absolute; top: 0; border-left: 1px solid var(--e-tick); padding-left: 4px; line-height: 18px; white-space: nowrap; }
.ed-track { position: relative; margin-top: 4px; }
.ed-track-text { height: 24px; }
.ed-track-video { height: 74px; }
.ed-track-audio { height: 26px; }
.ed-clip { position: absolute; top: 0; bottom: 0; border-radius: 6px; overflow: hidden; cursor: pointer; background: var(--e-raised);
           border: 2px solid transparent; border-left-width: 4px; transition: box-shadow var(--fast), filter var(--fast); }
.ed-clip:hover { filter: brightness(1.08); }
.ed-clip.sel { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); z-index: 1; }
.ed-clip.playing .ed-clip-label { background: var(--accent); color: var(--accent-ink); }
.ed-clip-missing { background: repeating-linear-gradient(45deg, var(--e-raised), var(--e-raised) 6px, var(--e-panel) 6px, var(--e-panel) 12px); }
.ed-clip-thumb { position: absolute; inset: 0; background-size: cover; background-position: center; }
.ed-clip-label { position: absolute; left: 0; right: 0; bottom: 0; font-size: 10px; font-weight: 700; padding: 3px 6px;
                 white-space: nowrap; overflow: hidden; text-overflow: ellipsis; background: var(--e-scrim); color: var(--e-text); }
.ed-clip.type-row-talking_head { border-left-color: var(--status-special); }
.ed-clip.type-row-broll, .ed-clip.type-row-broll_pip { border-left-color: var(--status-success); }
.ed-clip.type-row-activity { border-left-color: var(--status-warning); }
.ed-clip.type-row-pov_shot { border-left-color: var(--status-info); }
.ed-clip.type-row-photo { border-left-color: var(--status-neutral); }
.ed-clip.type-row-photo_edited { border-left-color: var(--accent); }
.ed-clip.type-row-animation { border-left-color: var(--status-danger); }
.ed-textclip { position: absolute; top: 0; bottom: 0; border-radius: 5px; background: var(--e-text-clip); color: var(--e-text); font-size: 10px; font-weight: 700;
               padding: 0 6px; line-height: 24px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; }
.ed-textclip.is-card { background: var(--e-card-clip); }
.ed-textclip.is-cutaway { background: var(--e-cutaway-clip); }
.ed-textclip:hover { filter: brightness(1.15); }
.ed-audioclip { position: absolute; top: 0; bottom: 0; border-radius: 5px; background: linear-gradient(180deg, var(--e-audio-a), var(--e-audio-b)); cursor: pointer; overflow: hidden; }
.ed-audioclip i { position: absolute; top: 4px; bottom: 4px; width: 1px; background: var(--e-audio-mark); }
.ed-audioclip-label { position: sticky; left: 8px; font-size: 10px; font-weight: 700; color: var(--e-text); line-height: 26px; padding-left: 8px; }
/* 2026-09-13: the playhead is draggable — a 2px line with an 18px grab zone and a bigger
   head, and the ruler scrubs too (editor.html). */
.ed-playhead { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--accent); z-index: 3; cursor: ew-resize; touch-action: none; }
.ed-playhead::before { content: ""; position: absolute; top: 0; left: -7px; border: 8px solid transparent; border-top: 11px solid var(--accent); }
.ed-playhead::after { content: ""; position: absolute; top: 0; bottom: 0; left: -9px; width: 20px; }
.ed-playhead:hover, .ed-playhead.dragging { width: 3px; }
.ed-ruler { touch-action: none; }
.ed-scrubbing, .ed-scrubbing * { cursor: ew-resize !important; user-select: none; }
@media (max-width: 1200px) { .ed-panel { width: 250px; } .ed-inspector { width: 280px; } }
@media (max-width: 860px) {
  .ed-app { height: auto; min-height: 0; display: block; }
  .ed-body { display: flex; flex-direction: column; }
  .ed-rail { flex-direction: row; overflow-x: auto; }
  .ed-rail-left, .ed-rail-right { border: none; border-bottom: 1px solid var(--e-border); }
  .ed-panel { width: auto; max-height: 40vh; border-right: none; border-bottom: 1px solid var(--e-border); }
  .ed-preview-frame { aspect-ratio: 16 / 9; flex: none; margin: 10px; }
  .ed-inspector { width: auto; border-left: none; border-top: 1px solid var(--e-border); max-height: 50vh; }
  .ed-track-video { height: 60px; }
}
/* admin: video cost panel (2026-09-15) */
.cb-table td, .cb-table th { vertical-align: top; padding: 5px 8px 5px 0; }
.cb-table tr.cb-prov td { border-top: 1px solid var(--border-strong); padding-top: 9px; }
.cb-table tr.cb-line td { border-bottom: none; font-size: var(--text-sm); }
.cb-table tr.cb-total td { border-top: 2px solid var(--border-strong); padding-top: 8px; }
