/* Reserve scrollbar gutter so tabs with short content don't shift everything
   sideways when their scrollbar disappears vs taller tabs. */
html { scrollbar-gutter: stable; }


/* ── Show Works Radio — console theme (revamp 2026-11-01) ───────────────
   Modelled on Rental Rodeo: dark sidebar, light working area. The two
   halves get their own token sets because they are genuinely different
   surfaces — inverting one must never drag the other with it.

   Content tokens are the Show Works shop's own values, so the console and
   hire.show-works.co.uk read as one product:

       --sw-red #e23b2e   --ink #17181c   --muted #6f7680
       --line   #e8e6e2   --soft #f7f5f2  --warm  #faf8f5
       --ok     #1f9d55   --radius 14px

   NOTE on form inputs: the operator has twice asked that inputs match the
   theme rather than defaulting to browser white. On a LIGHT theme white is
   the matching answer, so the .tab-panel input baseline further down now
   resolves to a light field with a visible border — same intent, inverted
   surface. Don't "fix" it back to dark.

   One deliberate divergence from the shop: --danger is a deeper red than
   the brand --accent. The brand colour is red, and a Delete button must
   not read as a primary action. */
:root {
    /* Working area */
    --bg: #faf8f5;            /* page — the shop's --warm             */
    --surface: #ffffff;       /* cards                                */
    --surface2: #f7f5f2;      /* inputs, wells — the shop's --soft    */
    --border: #e8e6e2;        /* hairline — the shop's --line         */
    --text: #17181c;          /* the shop's --ink                     */
    --text-dim: #6f7680;      /* the shop's --muted                   */
    --accent: #e23b2e;        /* brand — the shop's --sw-red          */
    --accent-hover: #c7301f;
    --accent-soft: #fdf0ee;   /* tinted fill behind brand elements    */
    --accent-line: #f3ded8;
    --danger: #a32b1f;        /* heavier than --accent; see above     */
    --danger-hover: #8a241a;
    /* Both darkened again 2026-11-01. The light-theme flip darkened
       --warning once but neither token actually cleared WCAG AA on the
       white card: --success was 3.49:1 and --warning 4.24:1. Values here
       are chosen against the WORST composited background each is used on —
       their own 0.18-0.20 tint over white, not plain white — so a token
       used as text on a tinted chip still passes:
         --success  #1b7842  5.51:1 on white, 4.59:1 on its 0.18 tint
         --warning  #8a5200  6.39:1 on white, 5.47:1 on its 0.20 tint
       --danger (#a32b1f, 7.19:1 / 5.71:1) was already fine.
       Darkening the tokens is the lever that fixes the most call sites at
       once; the bare literals that bypassed them are converted separately.
       NOTE the token is --warning, not --warn. Four call sites wrote
       var(--warn, #d4a017), which resolves to nothing and falls through to
       the old dark-theme amber at 2.38:1. */
    --success: #1b7842;       /* the shop's --ok, darkened for AA     */
    --warning: #8a5200;       /* AA on white and on its own tints     */
    --radius: 14px;
    --shadow: 0 1px 3px rgba(23,24,28,.06);

    /* Sidebar — stays dark whatever the content area does */
    --sb-bg: #17181c;
    --sb-bg-2: #22232a;
    --sb-text: #e9e8e6;
    --sb-dim: #8e8f96;
    --sb-line: #2c2d34;
    --sb-w: 264px;
    --sb-w-collapsed: 72px;
}

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

body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    background: var(--bg);
    color: var(--text);
    min-height: 100vh;
}

/* Display type. The Show Works shop sets its headings in Space Grotesk;
   matching it here is the single strongest brand cue in the console. Body
   copy stays on the system stack — Space Grotesk at 0.8rem in a dense
   admin table is harder to scan, and the font is loaded from Google so a
   blocked/slow CDN must not take the whole UI's legibility with it. The
   fallback chain is the same system stack body uses. */
h1, h2, h3, .header h1, .tab-dropdown-toggle, .btn {
    font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont,
                 'Segoe UI', sans-serif;
}

.container {
    max-width: 900px;
    margin: 0 auto;
    padding: 2rem 1.5rem;
}

.container.wide { max-width: 1200px; }

/* ══ App shell — dark sidebar + light working area ═══════════════════════
   Replaces the old centred .container + dropdown-nav layout (2026-11-01).
   The sidebar is fixed; .main scrolls. Everything inside a .tab-panel is
   untouched by this — panels keep rendering exactly as before, they just
   now sit in a column rather than under a row of dropdowns. */

.app { display: flex; min-height: 100vh; }

/* ── Sidebar ── */
.sidebar {
    width: var(--sb-w);
    flex: 0 0 var(--sb-w);
    background: var(--sb-bg);
    color: var(--sb-text);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    transition: width .16s ease, flex-basis .16s ease;
}
.sidebar * { font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont,
                          'Segoe UI', sans-serif; }

.sb-brand {
    display: flex; align-items: center; justify-content: space-between;
    padding: 1.15rem 1.1rem .4rem;
}
.sb-brand .mark {
    font-size: 1.22rem; font-weight: 700; letter-spacing: -.02em;
    white-space: nowrap; overflow: hidden;
}
.sb-brand .mark .a { color: var(--accent); }
.sb-collapse {
    background: none; border: none; color: var(--sb-dim); cursor: pointer;
    font-size: 1rem; line-height: 1; padding: .3rem .35rem; border-radius: 6px;
    flex: 0 0 auto;
}
.sb-collapse:hover { background: var(--sb-bg-2); color: var(--sb-text); }

.sb-primary {
    margin: .85rem 1.1rem 1rem;
    background: var(--accent); color: #fff;
    border: none; border-radius: 10px;
    padding: .78rem 1rem;
    font-size: .95rem; font-weight: 600;
    display: flex; align-items: center; justify-content: center; gap: .5rem;
    text-decoration: none; cursor: pointer; white-space: nowrap;
}
.sb-primary:hover { background: var(--accent-hover); }

.sb-nav { flex: 1; overflow-y: auto; overflow-x: hidden; padding-bottom: .8rem; }
/* Thin scrollbar — a chunky default one eats into 264px badly. */
.sb-nav::-webkit-scrollbar { width: 6px; }
.sb-nav::-webkit-scrollbar-thumb { background: var(--sb-line); border-radius: 3px; }

.sb-group {
    font-size: .66rem; letter-spacing: .12em; text-transform: uppercase;
    color: var(--sb-dim); font-weight: 600;
    padding: .9rem 1.35rem .35rem;
    white-space: nowrap;
}

/* Scoped to .sidebar (2026-11-02). Every sidebar link is
   class="tab-link sb-item" so the tab switcher can find it, and .tab-link
   is defined LATER in this file with the same specificity — so it won and
   painted the nav --text-dim (#6f7680) on --sb-bg (#17181c): 3.87:1, below
   AA, on 19 of the 20 items. Its .active rule also quietly replaced the
   dark pill with var(--surface), which is where the white active pill in
   the dark sidebar came from.

   Note --text (#17181c) is the SAME colour as --sb-bg, so any rule leaking
   the light theme's body colour into the sidebar renders literally
   invisible. Keep sidebar rules scoped. */
.sidebar .sb-item {
    display: flex; align-items: center; gap: .72rem;
    padding: .62rem 1.1rem;
    margin: 0 .5rem .1rem;
    border-radius: 9px;
    color: var(--sb-text); text-decoration: none;
    font-size: .93rem; font-weight: 500;
    white-space: nowrap; overflow: hidden;
    border-left: 3px solid transparent;
    cursor: pointer;
}
.sidebar .sb-item:hover { background: var(--sb-bg-2); }

/* Focus rings (2026-11-01). Nothing but form inputs had a focus style, so
   every link and button fell through to Chrome's default blue ring — which
   on the dark sidebar rendered as a bright blue box around a white pill,
   the one jarringly off-brand thing in the nav.

   :focus-visible rather than :focus so the ring appears for keyboard
   users and not on every mouse click. Two colours: the light accent on
   the dark sidebar, the normal accent everywhere else. */
.sidebar .sb-item:focus { outline: none; }
.sidebar .sb-item:focus-visible {
    outline: 2px solid #ff6a5c;
    outline-offset: -2px;
    background: var(--sb-bg-2);
}
.sb-primary:focus-visible {
    outline: 2px solid #ff6a5c;
    outline-offset: 2px;
}
.sidebar .sb-item svg { flex: 0 0 20px; width: 20px; height: 20px; stroke-width: 1.6; }
.sidebar .sb-item.active {
    background: var(--sb-bg-2);
    border-left-color: var(--accent);
    color: #fff; font-weight: 600;
}
.sidebar .sb-item.active svg { color: var(--accent); }

.sb-user {
    border-top: 1px solid var(--sb-line);
    padding: .8rem 1.1rem;
    display: flex; align-items: center; gap: .6rem;
    font-size: .86rem; color: var(--sb-dim);
    white-space: nowrap; overflow: hidden;
}
.sb-user .who { flex: 1; min-width: 0; color: var(--sb-text);
                overflow: hidden; text-overflow: ellipsis; }
.sb-user a { color: var(--sb-dim); text-decoration: none; flex: 0 0 auto;
             padding: .25rem; border-radius: 5px; display: flex; }
.sb-user a:hover { color: var(--accent); background: var(--sb-bg-2); }

/* Collapsed: icons only. Labels are hidden rather than removed so the
   active state and click targets stay identical. */
.sidebar.collapsed { width: var(--sb-w-collapsed); flex-basis: var(--sb-w-collapsed); }
.sidebar.collapsed .sb-brand .mark,
.sidebar.collapsed .sb-group,
.sidebar.collapsed .sb-item .label,
.sidebar.collapsed .sb-user .who,
.sidebar.collapsed .sb-primary .label { display: none; }
.sidebar.collapsed .sb-item { justify-content: center; padding-inline: 0; }
.sidebar.collapsed .sb-primary { margin-inline: .7rem; padding-inline: 0; }
.sidebar.collapsed .sb-brand { justify-content: center; padding-inline: .4rem; }
.sidebar.collapsed .sb-user { justify-content: center; }

/* ── Main column ── */
.main { flex: 1; min-width: 0; display: flex; flex-direction: column;
        background: var(--bg); }

.topbar {
    display: flex; align-items: center; justify-content: space-between;
    gap: 1rem;
    padding: 1.4rem 2rem 1.1rem;
    background: var(--bg);
    position: sticky; top: 0; z-index: 20;
    border-bottom: 1px solid var(--border);
}
.topbar h1 {
    font-size: 1.65rem; font-weight: 700; letter-spacing: -.02em;
    font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont,
                 'Segoe UI', sans-serif;
}
.topbar .crumb { font-size: .78rem; color: var(--text-dim);
                 letter-spacing: .06em; text-transform: uppercase;
                 font-weight: 600; margin-bottom: .15rem; }
.topbar-actions { display: flex; gap: .6rem; align-items: center;
                  flex: 0 0 auto; }

.content { padding: 1.5rem 2rem 3rem; flex: 1; }

/* Narrow screens: the sidebar collapses to the icon rail rather than
   disappearing, so navigation is always reachable on a laptop. */
@media (max-width: 1100px) {
    .sidebar { width: var(--sb-w-collapsed); flex-basis: var(--sb-w-collapsed); }
    .sidebar .sb-brand .mark, .sidebar .sb-group, .sidebar .sb-item .label,
    .sidebar .sb-user .who, .sidebar .sb-primary .label { display: none; }
    .sidebar .sb-item { justify-content: center; padding-inline: 0; }
    .sidebar .sb-primary { margin-inline: .7rem; padding-inline: 0; }
    .sidebar .sb-brand { justify-content: center; }
    .sidebar .sb-collapse { display: none; }
    .content, .topbar { padding-inline: 1.1rem; }
}

/* Header */
.header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 2rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--border);
}

.header h1 {
    font-size: 1.4rem;
    font-weight: 600;
    letter-spacing: -0.015em;   /* Space Grotesk sets a touch wide at size */
}
/* Wordmark accent — the station name's first word carries the brand red,
   the rest stays in --text. Mirrors the shop's two-tone logo lockup. */
/* The only place this class is used is the login card. It was scoped to
   `.header h1`, which that card is not inside, so the accent never
   applied and the login wordmark rendered flat black while the sidebar
   showed it in brand red. */
.wordmark-accent { color: var(--accent); }

.header-links { display: flex; gap: 1rem; align-items: center; }
.header-links a {
    color: var(--text-dim);
    text-decoration: none;
    font-size: 0.85rem;
}
.header-links a:hover { color: var(--text); }

/* Cards */
.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 1.5rem;
    margin-bottom: 1.5rem;
    /* On the old dark theme a card read as "raised" purely because it was
       lighter than the page. On a light page it needs the shop's shadow
       to separate from --bg, which is only a shade away. */
    box-shadow: var(--shadow);
}

.card h2 {
    font-size: 1.1rem;
    margin-bottom: 1rem;
    font-weight: 600;
}

/* Forms */
.form-group {
    margin-bottom: 1rem;
}

.form-group label {
    display: block;
    font-size: 0.85rem;
    color: var(--text-dim);
    margin-bottom: 0.35rem;
    font-weight: 500;
}

.form-group input,
.form-group select,
.form-group textarea {
    width: 100%;
    padding: 0.6rem 0.8rem;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text);
    font-size: 0.95rem;
    font-family: inherit;
    transition: border-color 0.2s;
    box-sizing: border-box;
}
.form-group textarea { line-height: 1.5; resize: vertical; }

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
    outline: none;
    border-color: var(--accent);
}

.form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
}

/* Buttons */
.btn {
    display: inline-block;
    padding: 0.6rem 1.2rem;
    border: none;
    border-radius: 6px;
    font-size: 0.9rem;
    font-weight: 500;
    line-height: 1.2;
    cursor: pointer;
    transition: background 0.2s;
    text-decoration: none;
    /* Neutral by default. .btn-primary / .btn-danger paint over both of
       these; a bare .btn is a secondary button, not an invisible one —
       which is what white-on-nothing became when the theme went light. */
    background: var(--surface2);
    color: var(--text);
    border: 1px solid var(--border);
    vertical-align: middle;
}
.btn:hover { background: var(--border); }
.btn-primary, .btn-danger { color: #fff; border-color: transparent; }
.pending-actions { align-items: center; }

.btn-primary { background: var(--accent); }
.btn-primary:hover { background: var(--accent-hover); }
.btn-danger { background: var(--danger); font-size: 0.8rem; padding: 0.4rem 0.8rem; }
.btn-danger:hover { background: var(--danger-hover); }
.btn-secondary {
    background: var(--surface2);
    color: var(--text);
    font-size: 0.8rem;
    padding: 0.35rem 0.7rem;
}
.btn-secondary:hover { background: var(--border); }
.btn-sm { font-size: 0.8rem; padding: 0.35rem 0.7rem; }
.btn-block { width: 100%; text-align: center; }

/* Flash messages */
.flash {
    padding: 0.7rem 1rem;
    border-radius: 6px;
    margin-bottom: 1rem;
    font-size: 0.9rem;
}
.flash.error   { background: rgba(231, 76, 60, 0.15);  border: 1px solid var(--danger);  color: #c52818; }
.flash.success { background: rgba(39, 174, 96, 0.15);  border: 1px solid var(--success); color: #1b7842; }
.flash.warning { background: rgba(243, 156, 18, 0.15); border: 1px solid var(--warning); color: #986008; }

/* File input */
.file-input-wrap {
    position: relative;
    border: 2px dashed var(--border);
    border-radius: 8px;
    padding: 2rem;
    text-align: center;
    cursor: pointer;
    transition: border-color 0.2s;
}

.file-input-wrap:hover { border-color: var(--accent); }

.file-input-wrap input[type="file"] {
    position: absolute;
    inset: 0;
    opacity: 0;
    cursor: pointer;
}

.file-input-wrap .file-label {
    color: var(--text-dim);
    font-size: 0.9rem;
}

.file-input-wrap .file-name {
    color: var(--accent);
    font-weight: 500;
    margin-top: 0.3rem;
    display: none;
}

.file-list {
    text-align: left;
    width: 100%;
    margin-top: 0.5rem;
}

.file-list-item {
    font-size: 0.85rem;
    color: var(--accent);
    padding: 0.15rem 0;
}

.file-size {
    color: var(--text-dim);
    font-size: 0.8rem;
}

/* Users table */
.user-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
    table-layout: auto;
}

.user-table th {
    font-size: 0.72rem;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--text-dim);
    text-align: left;
    padding: 0.5rem 0.75rem;
    color: var(--text-dim);
    border-bottom: 1px solid var(--border);
    font-weight: 500;
}

.user-table td {
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
}

.user-table tr:last-child td { border-bottom: none; }

.user-actions { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.scripts-table .user-actions { flex-wrap: nowrap; }
.scripts-table .user-actions .btn { white-space: nowrap; }

/* Login page centering */
.login-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
}

.login-card {
    width: 100%;
    max-width: 380px;
    padding: 2rem;
}

.login-card h1 {
    text-align: center;
    margin-bottom: 0.3rem;
    font-size: 1.5rem;
}

.login-card .subtitle {
    text-align: center;
    color: var(--text-dim);
    font-size: 0.85rem;
    margin-bottom: 1.5rem;
}

/* Progress bar */
.upload-progress {
    display: none;
    margin-top: 1rem;
}

.progress-bar {
    width: 100%;
    height: 6px;
    background: var(--surface2);
    border-radius: 3px;
    overflow: hidden;
}

.progress-fill {
    height: 100%;
    background: var(--accent);
    width: 0%;
    transition: width 0.3s;
    border-radius: 3px;
}

.progress-text {
    font-size: 0.8rem;
    color: var(--text-dim);
    margin-top: 0.4rem;
    text-align: center;
}

/* Edit modal */
.modal-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.6);
    z-index: 100;
    align-items: center;
    justify-content: center;
}

.modal-overlay.active { display: flex; }

.modal {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 1.5rem;
    width: 90%;
    max-width: 420px;
}

.modal h3 { margin-bottom: 1rem; }
.modal .btn-row { display: flex; gap: 0.5rem; margin-top: 1rem; }

/* ── Tabs ──────────────────────────────────────────────────────── */
.tab-nav {
    display: flex;
    gap: 0.25rem;
    margin-bottom: 1.5rem;
    border-bottom: 1px solid var(--border);
    padding-bottom: 0;
}

.tab-link {
    padding: 0.5rem 1rem;
    border-radius: 6px 6px 0 0;
    text-decoration: none;
    color: var(--text-dim);
    font-size: 0.9rem;
    font-weight: 500;
    border: 1px solid transparent;
    border-bottom: none;
    margin-bottom: -1px;
    transition: color 0.15s;
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.tab-link:hover { color: var(--text); }

.tab-link.active {
    color: var(--text);
    background: var(--surface);
    border-color: var(--border);
    border-bottom-color: var(--surface);
}

.tab-panel { display: none; }
.tab-panel.active { display: block; }

.badge {
    background: var(--danger);
    color: #fff;
    border-radius: 999px;
    font-size: 0.7rem;
    padding: 0.1rem 0.45rem;
    font-weight: 700;
}

/* ── Pending items ─────────────────────────────────────────────── */
.pending-item { padding: 1rem 0; }
.pending-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1rem;
    margin-bottom: 0.5rem;
}

.pending-meta {
    display: block;
    font-size: 0.8rem;
    color: var(--text-dim);
    margin-top: 0.15rem;
}

.pending-status-badge {
    font-size: 0.8rem;
    padding: 0.25rem 0.6rem;
    border-radius: 4px;
    white-space: nowrap;
    font-weight: 500;
    flex-shrink: 0;
    display: inline-block;
}

/* Wrapper that puts the status badge directly above the lyrics block so the
   "Clean / Flagged" verdict reads with the lyrics rather than floating in the
   top-right of the card. */
.pending-lyrics-header {
    margin: 0.6rem 0 0.3rem;
}

.status-danger  { background: var(--accent-soft); color: var(--danger); border: 1px solid var(--accent-line); }
.status-warn    { background: rgba(178,106,0,0.10); color: var(--warning); border: 1px solid rgba(178,106,0,0.30); }
.status-success { background: rgba(39,174,96,0.18); color: #1b7842; border: 1px solid rgba(39,174,96,0.5); }

/* ── Pending-uploads card: audio stats row + intro preview button ─────────── */
.pending-audio-stats {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    margin: 0.5rem 0;
    font-size: 0.82rem;
    color: var(--text-dim);
}
.pending-stat strong { color: var(--text); font-weight: 600; }

.pending-audio-player {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin: 0.3rem 0 0.6rem;
}
.pending-audio-el {
    height: 36px;
    flex: 1;
    min-width: 260px;
    max-width: 480px;
    /* Light scheme (2026-11-02): the working area went light in the
       rebrand, so a dark scheme painted the native controls near-white on
       the near-white panel below and the player vanished. */
    color-scheme: light;
    border-radius: 6px;
}
.pending-audio-el::-webkit-media-controls-panel {
    background: var(--surface2);   /* matches the light scheme above */
}
.btn-jump-intro,
.btn-set-intro-here {
    font-size: 0.78rem;
    padding: 0.35rem 0.7rem;
    white-space: nowrap;
}
.btn-jump-intro:disabled,
.btn-set-intro-here:disabled { opacity: 0.5; cursor: not-allowed; }
.intro-edit-stat {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}
.intro-input {
    width: 4.5rem;
    padding: 0.2rem 0.4rem;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 5px;
    color: var(--text);
    font-size: 0.85rem;
    font-family: inherit;
    transition: border-color 0.15s;
    /* hide spinner buttons on Firefox; keep on Webkit for usability */
    -moz-appearance: textfield;
}
.intro-input:focus { outline: none; border-color: var(--accent); }
.intro-unit { color: var(--text-dim); font-size: 0.82rem; }
.intro-save-status {
    font-size: 0.72rem;
    color: var(--text-dim);
    min-width: 4rem;
    transition: opacity 0.3s;
}
.intro-save-status.saved { color: #1b7842; }
.intro-save-status.error { color: var(--danger); }
/* While the audio element is actively playing, highlight the player edge */
.pending-audio-player.playing .pending-audio-el {
    box-shadow: 0 0 0 2px rgba(226,59,46,0.35);
}

/* ── Pending-uploads card: AI track-group selector ────────────────────────── */
.track-group-pick {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin: 0.5rem 0 0.7rem;
    font-size: 0.85rem;
}
.track-group-pick label { color: var(--text-dim); }
.group-select {
    min-width: 12rem;
    padding: 0.4rem 0.6rem;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text);
    font-size: 0.85rem;
    font-family: inherit;
    transition: border-color 0.15s;
}
.group-select:focus { outline: none; border-color: var(--accent); }
.group-select:hover { border-color: var(--accent); }
.ai-pill {
    font-size: 0.72rem;
    padding: 0.18rem 0.55rem;
    border-radius: 999px;
    letter-spacing: 0.02em;
}
.ai-pill-thinking {
    background: rgba(23,24,28,0.05);
    color: var(--text-dim);
    border: 1px solid var(--border);
}

.flagged-words { margin: 0.4rem 0; font-size: 0.85rem; }
.flagged-chip {
    display: inline-block;
    background: rgba(231,76,60,0.15);
    color: var(--danger);
    border: 1px solid rgba(231,76,60,0.4);
    border-radius: 4px;
    padding: 0.1rem 0.45rem;
    font-size: 0.8rem;
    margin: 0.1rem;
}

.lyrics-details { margin: 0.5rem 0; font-size: 0.85rem; color: var(--text-dim); }
.lyrics-details summary { cursor: pointer; }
.lyric-hit { background: rgba(226,59,46,0.20); color: var(--danger); border-radius: 3px; padding: 0 2px; font-style: normal; font-weight: 700; }
.lyrics-pre {
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.75rem;
    margin-top: 0.5rem;
    font-size: 0.8rem;
    white-space: pre-wrap;
    word-break: break-word;
    color: var(--text);
    max-height: 200px;
    overflow-y: auto;
}

.pending-actions { display: flex; gap: 0.5rem; margin-top: 0.75rem; }
.divider { border: none; border-top: 1px solid var(--border); margin: 0; }

/* ── Chips (strip words / banned words) ────────────────────────── */
.inline-add-form {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.inline-add-form input {
    flex: 1;
    max-width: 320px;
    padding: 0.5rem 0.75rem;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text);
    font-size: 0.9rem;
}

.inline-add-form input:focus { outline: none; border-color: var(--accent); }

.chip-list { display: flex; flex-wrap: wrap; gap: 0.4rem; }

.chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 0.2rem 0.6rem 0.2rem 0.75rem;
    font-size: 0.82rem;
    color: var(--text);
}

.chip-danger {
    background: rgba(231,76,60,0.1);
    border-color: rgba(231,76,60,0.35);
    color: #d22b1a;
}

.chip-del {
    background: none;
    border: none;
    color: var(--text-dim);
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    padding: 0;
    display: flex;
    align-items: center;
}

.chip-del:hover { color: var(--danger); }

.empty-note { color: var(--text-dim); font-size: 0.9rem; }

/* ── Upload result items ────────────────────────────────────────── */
.result-item {
    display: flex;
    gap: 0.75rem;
    align-items: flex-start;
    padding: 0.75rem 0;
}

.result-icon {
    width: 1.6rem;
    height: 1.6rem;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.85rem;
    font-weight: 700;
    flex-shrink: 0;
    margin-top: 0.1rem;
}

.result-success .result-icon { background: rgba(39,174,96,0.2);  color: var(--success); }
.result-flagged .result-icon  { background: rgba(231,76,60,0.2);  color: var(--danger);  }
.result-warn    .result-icon  { background: rgba(243,156,18,0.2); color: var(--warning); }
.result-error   .result-icon  { background: rgba(231,76,60,0.15); color: var(--danger);  }

.result-body { flex: 1; min-width: 0; }

.result-filenames {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-bottom: 0.3rem;
    font-size: 0.88rem;
}

.result-original { color: var(--text-dim); }
.result-arrow    { color: var(--text-dim); }
.result-new      { color: var(--text); font-size: 0.85rem; }

.result-detail {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem;
    font-size: 0.83rem;
}

/* ── Lyrics status labels ───────────────────────────────────────── */
.lyrics-ok      { color: var(--success); }
.lyrics-bad     { color: var(--danger);  }
.lyrics-unknown { color: var(--warning); }

/* ── Status pills ───────────────────────────────────────────────── */
/* Every colour below is measured against its own tint COMPOSITED over the
   white card, not against plain white (2026-11-01). Only .pill-danger was
   touched in the first light-theme pass; its three neighbours kept
   dark-theme values and sat at 2.49:1 (.pill-warn) and 3.55:1
   (.pill-import). These are status words an operator SCANS rather than
   reads, so sub-AA on a white surface makes a disabled script hard to spot
   in a 50-row table. .pill-success now resolves var(--success), which the
   token darkening already brought to 4.81:1 on this tint. */
.status-pill {
    display: inline-block;
    padding: 0.15rem 0.6rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    text-align: center;
    vertical-align: middle;
    line-height: 1.4;
    white-space: nowrap;
}

.pill-success { background: rgba(31,157,85,0.12); color: var(--success); border: 1px solid rgba(31,157,85,0.35); }
.pill-warn    { background: rgba(243,156,18,0.18); color: #945f07; border: 1px solid rgba(243,156,18,0.4); }
.pill-danger  { background: rgba(231,76,60,0.18);  color: #c52818; border: 1px solid rgba(231,76,60,0.4);  }
.pill-import  { background: rgba(52,152,219,0.18); color: #236e9f; border: 1px solid rgba(52,152,219,0.4); }

/* ── Meta source chip ───────────────────────────────────────────── */
.meta-source-chip {
    display: inline-block;
    background: rgba(226,59,46,0.15);
    color: var(--accent);
    border: 1px solid rgba(226,59,46,0.3);
    border-radius: 4px;
    font-size: 0.72rem;
    padding: 0.1rem 0.4rem;
}

@media (max-width: 600px) {
    .form-row { grid-template-columns: 1fr; }
    .container { padding: 1rem; }
    .tab-nav { overflow-x: auto; }
    .pending-header { flex-direction: column; }
}

/* ── Tab group dropdown nav ─────────────────────────────────────── */
.tab-dropdown-nav {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 1rem;
    padding-bottom: 0.75rem;
    border-bottom: 2px solid var(--surface2);
    flex-wrap: wrap;
}
.tab-dropdown { position: relative; }
.tab-dropdown-toggle {
    appearance: none;
    background: var(--surface2);
    color: var(--text-dim);
    border: 1px solid transparent;
    padding: 0.55rem 1rem;
    border-radius: 6px;
    font-weight: 600;
    font-size: 0.92rem;
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-family: inherit;
    /* Stable width regardless of which tab is selected — prevents reflow
       when switching tabs inside the same group. The min/max pair keeps
       the button a constant width; any active-tab label that overflows
       (e.g. 'Music Library · ⌫ Verify Track Names ▾') gets ellipsis-
       truncated via .tab-dropdown-current's text-overflow rule below.
       2026-06-12: was only min-width, so longer labels still pushed the
       button wider — fixed by also setting max-width.
       2026-07-02: shrunk from 18rem → 13rem so all four top-level tabs
       fit on one line (4 × 13rem + gaps ≈ 53rem, comfortably under any
       laptop viewport). Long labels still ellipsis-truncate; the caret
       and tab-name stay visible. */
    min-width: 13rem;
    max-width: 13rem;
    justify-content: flex-start;
}
.tab-dropdown-current {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}
.tab-dropdown-toggle:hover { background: rgba(23,24,28,0.06); color: var(--text); }
.tab-dropdown.active .tab-dropdown-toggle {
    background: var(--accent);
    color: white;
}
/* Inline current-tab indicator text inside the toggle */
.tab-dropdown-toggle .tab-dropdown-current {
    font-weight: 400;
    font-size: 0.85rem;
    opacity: 0.85;
}
.tab-dropdown-toggle .caret {
    font-size: 0.7rem;
    opacity: 0.8;
    margin-left: 0.15rem;
    transition: transform 0.15s;
}
.tab-dropdown.open .tab-dropdown-toggle .caret { transform: rotate(180deg); }

.tab-dropdown-menu {
    position: absolute;
    top: calc(100% + 0.4rem);
    left: 0;
    min-width: 14rem;
    padding: 0.35rem;
    background: var(--surface);
    border: 1px solid var(--surface2);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(23,24,28,0.16);
    z-index: 50;
    display: none;
    flex-direction: column;
    gap: 0.1rem;
}
.tab-dropdown.open .tab-dropdown-menu { display: flex; }
.tab-dropdown-menu .tab-link {
    display: block;
    padding: 0.5rem 0.75rem;
    color: var(--text-dim);
    text-decoration: none;
    border-radius: 4px;
    font-size: 0.9rem;
    font-weight: 500;
    transition: background 0.1s, color 0.1s;
}
.tab-dropdown-menu .tab-link:hover { background: var(--surface2); color: var(--text); }
.tab-dropdown-menu .tab-link.active {
    background: rgba(226,59,46,0.18);
    color: var(--accent);
}

/* ── Hour Exclusion grid (click-to-toggle) ──────────────────────── */
.hourex-grid {
    border-collapse: collapse;
    font-size: 0.78rem;
}
.hourex-grid th {
    padding: 0.3rem 0.4rem;
    color: var(--text-dim);
    font-weight: 600;
    font-size: 0.72rem;
}
.hourex-grid tbody th {
    text-align: right;
    padding-right: 0.6rem;
    color: var(--text);
}
.hourex-grid td { padding: 1px; }
.hourex-cell {
    width: 1.6rem;
    height: 1.6rem;
    background: var(--surface2);
    border-radius: 3px;
    cursor: pointer;
    transition: background 0.15s;
}
.hourex-cell:hover { background: rgba(23,24,28,0.08); }
.hourex-cell.hourex-on { background: rgba(231,76,60,0.5); }
.hourex-cell.hourex-on:hover { background: rgba(231,76,60,0.7); }

/* ── Clock exclusion list ───────────────────────────────────────── */
.clock-row {
    display: grid;
    grid-template-columns: 8rem 1fr;
    align-items: start;
    gap: 0.75rem;
    padding: 0.6rem 0.75rem;
    margin-bottom: 0.4rem;
    background: var(--surface2);
    border-radius: 6px;
    font-size: 0.85rem;
}
.clock-row.clock-excluded {
    background: rgba(231,76,60,0.1);
    border: 1px solid rgba(231,76,60,0.3);
    padding: calc(0.6rem - 1px) calc(0.75rem - 1px);
}
.clock-toggle {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    cursor: pointer;
    font-size: 0.8rem;
    color: var(--text-dim);
    user-select: none;
}
.clock-toggle input { accent-color: var(--accent); }
.clock-label {
    width: 100%;
    padding: 0.35rem 0.55rem;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text);
    font-size: 0.85rem;
    margin-bottom: 0.4rem;
}
.clock-label:focus { outline: none; border-color: var(--accent); }
.clock-meta { grid-column: 2; font-size: 0.78rem; color: var(--text-dim); }
.clock-titles { line-height: 1.4; }
.clock-titles em { opacity: 0.5; }
.clock-guid { font-size: 0.7rem; opacity: 0.6; margin-top: 0.2rem; }
.clock-guid code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

/* ── Rotation rules inputs ─────────────────────────────────────── */
.rot-input {
    padding: 0.5rem 0.7rem;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text);
    font-size: 0.9rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.rot-input:focus { outline: none; border-color: var(--accent); }

/* ── Exclusion grid (track-group checkbox list) ─────────────────── */
.exclusions-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 0.35rem;
}
.exclusion-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.6rem;
    background: var(--surface2);
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.85rem;
    user-select: none;
}
.exclusion-row:hover { background: rgba(23,24,28,0.04); }
.exclusion-row input[type="checkbox"] { accent-color: var(--accent); }
.exclusion-row:has(input:checked) {
    background: rgba(231,76,60,0.12);
    border: 1px solid rgba(231,76,60,0.35);
    padding: calc(0.4rem - 1px) calc(0.6rem - 1px);
}
.exclusion-name { flex: 1; }
.exclusion-count { color: var(--text-dim); font-size: 0.75rem; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

/* ── Schedule tab (target BPM grid) ─────────────────────────────── */
.schedule-grid {
    border-collapse: collapse;
    font-size: 0.85rem;
}
.schedule-grid th {
    padding: 0.4rem 0.5rem;
    color: var(--text-dim);
    font-weight: 600;
    font-size: 0.75rem;
    text-align: center;
}
.schedule-grid tbody th {
    text-align: right;
    padding-right: 0.7rem;
    color: var(--text);
}
.schedule-grid td {
    padding: 2px;
}
.schedule-grid input[type="number"] {
    width: 3.2rem;
    padding: 0.3rem 0.35rem;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text);
    font-size: 0.8rem;
    text-align: center;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    /* hide the number-input spinner — saves space and the grid is dense */
    -moz-appearance: textfield;
}
.schedule-grid input[type="number"]::-webkit-outer-spin-button,
.schedule-grid input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none; margin: 0;
}
.schedule-grid input[type="number"]:focus { outline: none; border-color: var(--accent); }

/* The Harmony tab's CSS (~120 lines, .hm-* / .harmony-*) was removed on
   2026-11-01. The Harmony project itself went on 2026-05-19 — code,
   routes, systemd units, DB tables and the nav dropdown — but the
   stylesheet was missed, so a dead .harmony-badge.stale rule was still
   being flagged by the light-theme contrast audit. Nothing in any
   template or .py referenced a single one of these selectors. */

/* ── Tracks tab — inline edit inputs ────────────────────────────── */
#tab-tracks input[type="number"],
#tab-tracks select.tracks-key-select {
    width: 5rem;
    padding: 0.4rem 0.6rem;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text);
    font-size: 0.9rem;
    font-family: inherit;
}
#tab-tracks select.tracks-key-select { width: 7rem; }
#tab-tracks input[type="number"]:focus,
#tab-tracks select.tracks-key-select:focus { outline: none; border-color: var(--accent); }
#tab-tracks table th { color: var(--text-dim); font-weight: 600; font-size: 0.85rem; }
#tab-tracks tbody tr:hover { background: rgba(23,24,28,0.02); }

/* ── AI Presenter (Phase E) ───────────────────────────────────────────── */
.ai-status-row {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin: 0.4rem 0 1rem;
}
.ai-status-row .status-pill { font-size: 0.78rem; padding: 0.2rem 0.55rem; }

/* ── NAS output-path box (shown for reels + AI presenter mp3 locations) ── */
.nas-path-box {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 0.8rem;
    font-size: 0.76rem;
    color: var(--text-dim);
    background: var(--surface2, rgba(23,24,28,0.04));
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.35rem 0.6rem;
}
.nas-path-box code {
    font-size: 0.74rem;
    background: transparent;
    color: var(--text);
    word-break: break-all;
}
.nas-path-label {
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: 0.66rem;
    opacity: 0.8;
}
.nas-path-win { opacity: 0.85; }

/* ── AI Presenter dashboard ───────────────────────────────────────────── */
.aidash-chip {
    display: inline-block; padding: 0.05rem 0.4rem; border-radius: 4px;
    font-size: 0.7rem; font-weight: 600; margin: 0 0.1rem;
}
.aidash-chip.aidash-music    { background: rgba(39,174,96,0.25);  color: #1a733f; }
.aidash-chip.aidash-sweeper  { background: rgba(243,156,18,0.25); color: #935d07; }
.aidash-chip.aidash-announce { background: rgba(52,152,219,0.30); color: #1a6495; }
.aidash-chip.aidash-clock    { background: rgba(155,155,155,0.20); color: #696969; }
.aidash-list { display: flex; flex-direction: column; gap: 2px; }
.aidash-hour-header {
    margin: 0.7rem 0 0.3rem; padding: 0.25rem 0.5rem;
    font-weight: 700; font-size: 0.82rem; letter-spacing: 0.03em;
    background: var(--surface2, rgba(23,24,28,0.06));
    border-radius: 5px; border-left: 4px solid var(--accent, #3498db);
}
.aidash-hour-header:first-child { margin-top: 0; }
.aidash-split {
    text-align: center; font-size: 0.66rem; color: var(--text-dim);
    opacity: 0.5; letter-spacing: 0.1em; padding: 0.1rem 0;
}
.aidash-row {
    display: flex; align-items: center; gap: 0.6rem;
    padding: 0.3rem 0.5rem; border-radius: 5px; font-size: 0.84rem;
    background: var(--surface2, rgba(23,24,28,0.03));
    border-left: 3px solid transparent;
}
.aidash-row.aidash-music    { border-left-color: #1b7842; }
.aidash-row.aidash-sweeper  { border-left-color: #986008; }
.aidash-row.aidash-announce { border-left-color: #1d6da3; }
.aidash-row.aidash-clock    { border-left-color: #777; opacity: 0.7; font-size: 0.78rem; }
.aidash-row.aidash-current  { background: rgba(52,152,219,0.12); font-weight: 600; }
.aidash-row.aidash-pastrow  { opacity: 0.4; }
.aidash-row.aidash-willdelete { background: rgba(231,76,60,0.10); }
.aidash-time { font-variant-numeric: tabular-nums; color: var(--text-dim);
               font-size: 0.74rem; min-width: 4.2rem; }
.aidash-kind-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; background: currentColor; opacity: 0.5; }
.aidash-title { flex: 1; }
.aidash-flag { font-size: 0.68rem; color: var(--accent); font-weight: 600; }
.aidash-row .btn { padding: 0.1rem 0.45rem; font-size: 0.72rem; }
.aidash-modal {
    position: fixed; inset: 0; background: rgba(0,0,0,0.55);
    display: flex; align-items: center; justify-content: center; z-index: 1000;
}
.aidash-modal-box {
    background: var(--surface, #1e1e1e); border: 1px solid var(--border);
    border-radius: 8px; padding: 1.2rem; width: 520px; max-width: 92vw;
}
.aidash-modal-box textarea {
    background: var(--surface2, #111); color: var(--text); border: 1px solid var(--border);
    border-radius: 5px; padding: 0.5rem; font-size: 0.85rem;
}

/* Highlight the currently-active presenter row */
.user-table tr.active-row { background: rgba(226,59,46,0.08); }
.user-table tr.active-row td:first-child { color: var(--accent); font-weight: 700; }

/* Small icon-only button (used for the active-radio in the presenters table) */
.btn-icon {
    background: transparent;
    border: 1px solid transparent;
    color: var(--text-dim);
    font-size: 1rem;
    cursor: pointer;
    padding: 0.1rem 0.4rem;
    border-radius: 4px;
    transition: color 0.15s, border-color 0.15s;
}
.btn-icon:hover { color: var(--accent); border-color: var(--border); }

.ai-presenter-add-form .form-row { margin-bottom: 0.7rem; }

/* ── AI Script editor (Phase E.2) ──────────────────────────────────────── */
.script-editor-grid {
    display: grid;
    grid-template-columns: 1.4fr 1fr;
    gap: 1.5rem;
}
@media (max-width: 900px) {
    .script-editor-grid { grid-template-columns: 1fr; }
}
.sticky-preview { position: sticky; top: 1rem; }

.se-block-row {
    display: flex;
    gap: 0.4rem;
    align-items: center;
    padding: 0.4rem;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 6px;
    margin-bottom: 0.4rem;
}
.se-block-idx {
    color: var(--text-dim);
    font-size: 0.8rem;
    min-width: 1.5rem;
    text-align: right;
}
.se-block-row select,
.se-block-row input[type="text"] {
    padding: 0.35rem 0.55rem;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text);
    font-size: 0.85rem;
}
.se-block-row select { min-width: 11rem; }
.se-block-row input[type="text"] { flex: 1; min-width: 8rem; }
.se-block-row input[type="text"]:focus,
.se-block-row select:focus { outline: none; border-color: var(--accent); }
.se-block-row .btn-icon { padding: 0.15rem 0.4rem; font-size: 0.85rem; }

.se-add-row {
    display: flex;
    gap: 0.4rem;
    align-items: center;
    margin-top: 0.7rem;
}
.se-add-row select {
    flex: 1;
    padding: 0.4rem 0.55rem;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text);
    font-size: 0.85rem;
}

.inline-add-form { display: flex; gap: 0.4rem; flex-wrap: wrap; align-items: center; }
.inline-add-form input[type="text"] {
    padding: 0.35rem 0.55rem;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text);
    font-size: 0.85rem;
}

/* ── AI Script editor (Phase E.2 — shoutouts-style block editor) ──────── */
.block-editor {
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1rem;
    min-height: 200px;
}
.block-list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: stretch;
    min-height: 60px;
}
.block-item {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.6rem 0.85rem;
    border-radius: 6px;
    font-size: 0.85rem;
    cursor: grab;
    border: 1px solid;
    max-width: 100%;
    height: 40px;
    box-sizing: border-box;
}
.block-item .drag-handle { cursor: grab; opacity: 0.4; margin-right: 0.2rem; font-size: 0.9rem; }
.block-item .remove-block {
    cursor: pointer;
    opacity: 0.5;
    font-size: 0.95rem;
    margin-left: 0.3rem;
    line-height: 1;
}
.block-item .remove-block:hover { opacity: 1; }
.block-item-ghost {
    opacity: 0.4;
    border-color: var(--accent) !important;
    box-shadow: 0 0 0 2px var(--accent);
}
.block-palette {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border);
}
.block-palette .block-btn {
    padding: 0.35rem 0.75rem;
    border-radius: 6px;
    font-size: 0.8rem;
    cursor: pointer;
    border: 1px dashed;
    transition: opacity 0.15s, transform 0.15s;
    background: transparent;
}
.block-palette .block-btn:hover { opacity: 0.8; transform: translateY(-1px); }

.block-item input.block-text-input {
    background: transparent;
    border: none;
    color: inherit;
    font-size: inherit;
    font-family: inherit;
    padding: 0;
    min-width: 60px;
    width: auto;
}
.block-item input.block-text-input:focus { outline: none; }
.block-item select.block-text-input {
    background: transparent; border: none; color: inherit;
    font: inherit; padding: 0 0.2rem; cursor: pointer; outline: none;
}
.block-item select.block-text-input option { background: var(--surface2); color: var(--text); }
.block-item textarea.block-text-input {
    background: transparent; border: none; color: inherit; font: inherit;
    padding: 0; resize: vertical; outline: none;
}

.preview-pane {
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1rem;
    font-style: italic;
    color: var(--text-dim);
    min-height: 60px;
    margin-top: 0;
    line-height: 1.5;
}
.preview-pane.has-text { color: var(--text); font-style: normal; }

.back-link {
    display: inline-block;
    color: var(--text-dim);
    font-size: 0.9rem;
    text-decoration: none;
    margin-bottom: 1rem;
}
.back-link:hover { color: var(--text); }

.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
    gap: 1rem;
    flex-wrap: wrap;
}
.card-header h2, .card-header h3 { margin: 0; }
.btn-group { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.btn-outline {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text);
}
.btn-outline:hover { border-color: var(--accent); color: var(--accent); }
.text-dim { color: var(--text-dim); }
.text-sm   { font-size: 0.85rem; }
.mt-1 { margin-top: 0.5rem; }
.mt-2 { margin-top: 1rem; }

/* ── AI Scripts list: category chips + tighter rows ───────────────────── */
/* The Scripts tab renders one <table> per section (Standard / Hook
   sequences) via the render_section macro. With the default auto layout
   each table sizes its columns from its own content, so the two sat on
   screen with their columns visibly out of step. `fixed` makes the <th>
   widths authoritative and identical for both. Any column that would
   overflow now wraps instead, which is why Firing rules gets the
   normal-whitespace rule below. */
.scripts-table { table-layout: fixed; }
.scripts-table th,
.scripts-table td { overflow-wrap: anywhere; }

/* Below ~1150px the five declared column widths need more room than the
   card gives them. Scroll the table instead of letting the fixed layout
   squeeze a column to nothing — min-width is the sum of the two rem
   columns plus the 19rem of action buttons plus enough for the three text
   columns to stay legible. Both tables get the same wrapper, so they still
   line up with each other, which is the whole reason for fixed layout. */
.scripts-table-wrap { overflow-x: auto; }
.scripts-table { min-width: 52rem; }

/* Firing-rule pills must be able to shrink inside the fixed column.
   `.status-pill` is `white-space: nowrap` globally, which is right for a
   short "ON" badge but not for a 42-character gate label like
   "gated: playlist debut, last 14 days (just-played)" — under the fixed
   table layout that pill could not shrink and bled sideways across the
   Blocks and Status cells (2026-11-01 regression from adding
   table-layout: fixed to line the two tables up).

   Scoped to this table so the pills everywhere else keep their single
   line. min-width:0 on the flex row is the part that actually lets a
   flex item narrow below its content width. */
.scripts-table td > div { min-width: 0; }
.scripts-table .status-pill {
    white-space: normal;
    max-width: 100%;
    text-align: left;
    overflow-wrap: anywhere;
}
.scripts-table td { vertical-align: middle; padding: 0.55rem 0.75rem; }
.scripts-table .script-link { color: var(--text); text-decoration: none; }
.scripts-table .script-link:hover { color: var(--accent); }

.cat-chip {
    display: inline-block;
    padding: 0.18rem 0.55rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.02em;
    border: 1px solid;
    white-space: nowrap;
}
.cat-forward_intro { background: rgba(226,59,46,0.12);  border-color: rgba(226,59,46,0.4);  color: #c23328; }
.cat-back_intro    { background: rgba(52,152,219,0.12);  border-color: rgba(52,152,219,0.4);  color: #1d6da3; }
.cat-station_id    { background: rgba(243,156,18,0.12);  border-color: rgba(243,156,18,0.4);  color: #986008; }
.cat-show_promo    { background: rgba(39,174,96,0.12);   border-color: rgba(39,174,96,0.4);   color: #1b7842; }
.cat-weather       { background: rgba(26,188,156,0.12);  border-color: rgba(26,188,156,0.4);  color: #117864; }
.cat-freeform      { background: rgba(155,89,182,0.12);  border-color: rgba(155,89,182,0.4);  color: #8c4aa8; }

/* ── AI Presenter: Run now + Schedule grid ─────────────────────────────── */
.run-now-status {
    margin-top: 1rem;
    padding: 0.7rem 1rem;
    border-radius: 6px;
    font-size: 0.9rem;
    line-height: 1.4;
}

/* ── AI Presenter: Schedule by day-of-week (tab row + per-day panel) ────── */
.schedule-day-tabs {
    display: flex;
    gap: 0.3rem;
    margin: 1rem 0 1rem;
    border-bottom: 1px solid var(--border);
    padding-bottom: 0;
    overflow-x: auto;
}
.schedule-day-tab {
    background: transparent;
    border: 1px solid transparent;
    border-bottom: none;
    color: var(--text-dim);
    font-size: 0.9rem;
    font-weight: 500;
    padding: 0.6rem 1.1rem;
    margin-bottom: -1px;
    border-radius: 6px 6px 0 0;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    white-space: nowrap;
    transition: color 0.15s;
}
.schedule-day-tab:hover { color: var(--text); }
.schedule-day-tab.active {
    color: var(--text);
    background: var(--surface);
    border-color: var(--border);
}
.schedule-day-tab .day-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.3rem;
    height: 1.3rem;
    padding: 0 0.4rem;
    background: var(--accent);
    color: #fff;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 600;
    line-height: 1;
}
.schedule-day-card { padding: 1.2rem 1.4rem; }
.schedule-items { margin: 0.3rem 0 0.8rem; }
.schedule-item {
    display: grid;
    grid-template-columns: 4rem 1fr auto auto;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.55rem;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 6px;
    margin-bottom: 0.3rem;
}
.schedule-time {
    font-family: 'SF Mono', 'Menlo', monospace;
    color: var(--accent);
    font-weight: 600;
    font-size: 0.95rem;
}
.schedule-script { color: var(--text); font-size: 0.85rem; overflow: hidden; text-overflow: ellipsis; }
.schedule-script strong { font-weight: 500; }
.schedule-add-row {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: 0.5rem;
    align-items: center;
    margin-top: 0.4rem;
    padding-top: 0.7rem;
    border-top: 1px dashed var(--border);
}
.schedule-add-row input[type="time"],
.schedule-add-row select {
    padding: 0.35rem 0.5rem;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 5px;
    color: var(--text);
    font-size: 0.82rem;
    color-scheme: light;   /* light working area — see .pending-audio-el */
}
.schedule-add-row input[type="time"] { width: 6rem; font-family: 'SF Mono', monospace; }
.schedule-add-row input:focus, .schedule-add-row select:focus { outline: none; border-color: var(--accent); }

/* ── Reels: Shows tab (per-show config cards) ──────────────────────────── */
.reel-show-card { padding: 1.2rem 1.4rem; }
.reel-show-card .card-header { gap: 1rem; }
.reel-show-card h3 { font-weight: 600; }
.reel-show-card .reel-show-form .form-row { grid-template-columns: 1fr auto; }
.reel-show-card select,
.reel-show-card input[type="file"] {
    padding: 0.4rem 0.55rem;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 5px;
    color: var(--text);
    font-size: 0.85rem;
    font-family: inherit;
}
.reel-show-card select:focus { outline: none; border-color: var(--accent); }
.reel-show-card audio { border-radius: 4px; }

.reel-generate-status {
    padding: 0.6rem 0.9rem;
    border-radius: 6px;
    font-size: 0.85rem;
    line-height: 1.45;
}

/* ── Styled file input (replaces ugly browser default in Reels bed upload) ─ */
.file-input-styled {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0.8rem;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 5px;
    color: var(--text);
    font-size: 0.82rem;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
}
.file-input-styled:hover { border-color: var(--accent); background: rgba(226,59,46,0.08); }
.file-input-styled input[type="file"] { display: none; }
.file-input-styled .file-name {
    color: var(--text-dim);
    font-size: 0.78rem;
    margin-left: 0.3rem;
    max-width: 18rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.file-input-styled .file-name.empty::before { content: "no file chosen"; font-style: italic; }

/* ── Reels: assigned-script pills on the Shows tab ──────────────────────── */
.script-pill {
    display: inline-flex;
    align-items: center;
    padding: 0.25rem 0.65rem;
    background: rgba(226,59,46,0.12);
    border: 1px solid rgba(226,59,46,0.35);
    border-radius: 999px;
    color: var(--text);
    font-size: 0.78rem;
    text-decoration: none;
    transition: background 0.15s, border-color 0.15s;
}
.script-pill:hover { background: rgba(226,59,46,0.22); border-color: var(--accent); }
.script-pill-off {
    background: rgba(139,143,163,0.08);
    border-color: rgba(139,143,163,0.3);
    color: var(--text-dim);
}
.script-pill-add {
    background: transparent;
    border-style: dashed;
    color: var(--text-dim);
}
.script-pill-add:hover { color: var(--accent); }

/* Reels: per-show SFX slot grid (top + tail stinger, clip in + clip out).
   Four cards in a responsive grid — 4 across on wide screens, 2 across at
   medium widths, single column on narrow. */
.reel-sfx-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 0.6rem;
}
.reel-sfx-slot {
    background: rgba(226,59,46,0.04);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.55rem 0.7rem;
    min-width: 0;   /* let flex/grid children shrink */
}
.reel-sfx-slot-label {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text);
    margin-bottom: 0.35rem;
    letter-spacing: 0.02em;
}
.reel-sfx-slot audio { border-radius: 3px; }

/* The music-bed pill is wider than the SFX slots (it has a level slider) so
   it spans two grid cells on screens where there's room for it. */
.reel-sfx-slot-bed {
    grid-column: span 2;
    background: rgba(39,174,96,0.06);
    border-color: rgba(39,174,96,0.3);
}
@media (max-width: 720px) { .reel-sfx-slot-bed { grid-column: span 1; } }

/* Show Clip pill — green tint matches the clip rectangle on the timeline
   so the colour-coding stays consistent. No upload (clip comes from the
   recording dynamically), just a level slider. */
.reel-sfx-slot-clip {
    background: rgba(39,174,96,0.10);
    border-color: rgba(39,174,96,0.45);
}

/* Shared row layout inside a pill (e.g. filename + remove-X). */
.reel-sfx-row {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}
.reel-sfx-filename {
    font-size: 0.72rem;
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text-dim);
}
.reel-sfx-remove-btn {
    padding: 0.15rem 0.5rem !important;
    font-size: 0.72rem !important;
    line-height: 1 !important;
    flex-shrink: 0;
}
.reel-sfx-empty {
    color: var(--text-dim);
    font-size: 0.75rem;
    font-style: italic;
    margin: 0 0 0.35rem;
}
.reel-sfx-audio {
    height: 28px;
    width: 100%;
    color-scheme: light;   /* light working area — see .pending-audio-el */
    border-radius: 3px;
}

/* Upload row: file-chooser pill ON THE LEFT, Upload button on the right,
   BOTH inside the parent .reel-sfx-slot so the button doesn't fall outside.
   The file input itself is hidden — clicks bubble from the wrapping label. */
.reel-sfx-upload-form {
    display: flex;
    gap: 0.35rem;
    align-items: stretch;
    margin-top: 0.4rem;
    width: 100%;
    min-width: 0;
}
.reel-sfx-file-pill {
    flex: 1;
    min-width: 0;          /* lets the flex item shrink below intrinsic */
    background: var(--surface, #1a1e29);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 0.3rem 0.55rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    font-size: 0.72rem;
    color: var(--text-dim);
    overflow: hidden;
    transition: border-color 0.15s, background 0.15s;
}
.reel-sfx-file-pill:hover { border-color: var(--accent); background: rgba(226,59,46,0.08); }
.reel-sfx-file-pill input[type="file"] { display: none; }
.reel-sfx-file-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    width: 100%;
}
.reel-sfx-upload-btn {
    padding: 0.3rem 0.7rem !important;
    font-size: 0.72rem !important;
    flex-shrink: 0;        /* keep the button visible no matter the filename */
}

/* The per-show bed level slider — thin range input, dB readout on the right. */
.reel-bed-db-slider {
    -webkit-appearance: none;
    appearance: none;
    background: var(--surface, #2a2e3a);
    height: 4px;
    border-radius: 2px;
    outline: none;
}
.reel-bed-db-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--accent);
    cursor: pointer;
}
.reel-bed-db-slider::-moz-range-thumb {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--accent);
    cursor: pointer;
    border: none;
}
.reel-bed-db-val { color: var(--text-dim); font-variant-numeric: tabular-nums; }

/* Per-SFX level slider — same look as the bed slider. */
.reel-sfx-db-slider {
    -webkit-appearance: none;
    appearance: none;
    background: var(--surface, #2a2e3a);
    height: 4px;
    border-radius: 2px;
    outline: none;
}
.reel-sfx-db-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 12px; height: 12px; border-radius: 50%;
    background: var(--accent); cursor: pointer;
}
.reel-sfx-db-slider::-moz-range-thumb {
    width: 12px; height: 12px; border-radius: 50%;
    background: var(--accent); cursor: pointer; border: none;
}
.reel-sfx-db-val { color: var(--text-dim); font-variant-numeric: tabular-nums; }

/* Show-clip level slider — same look as bed/SFX sliders. */
.reel-clip-db-slider {
    -webkit-appearance: none;
    appearance: none;
    background: var(--surface, #2a2e3a);
    height: 4px;
    border-radius: 2px;
    outline: none;
}
.reel-clip-db-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 12px; height: 12px; border-radius: 50%;
    background: var(--accent); cursor: pointer;
}
.reel-clip-db-slider::-moz-range-thumb {
    width: 12px; height: 12px; border-radius: 50%;
    background: var(--accent); cursor: pointer; border: none;
}
.reel-clip-db-val { color: var(--text-dim); font-variant-numeric: tabular-nums; }

/* Reels → History tab. Summary stat-card row + table with failed-run
   error rows expanded inline. */
.reel-history-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 0.6rem;
}
.reel-stat {
    background: rgba(226,59,46,0.05);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.7rem 0.9rem;
}
.reel-stat-val {
    font-size: 1.4rem;
    font-weight: 600;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}
.reel-stat-label {
    font-size: 0.75rem;
    color: var(--text-dim);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-top: 0.25rem;
}
.reel-stat-danger { background: rgba(231,76,60,0.08); border-color: rgba(231,76,60,0.4); }
.reel-stat-danger .reel-stat-val { color: var(--danger); }

.reel-history-table { width: 100%; }
.reel-history-table th { text-align: left; font-weight: 600; font-size: 0.8rem; color: var(--text-dim); padding: 0.5rem 0.6rem; border-bottom: 1px solid var(--border); }
.reel-history-table td { padding: 0.55rem 0.6rem; border-bottom: 1px solid var(--border); vertical-align: top; }
.reel-history-row:hover { background: rgba(226,59,46,0.04); }
.reel-history-row-failed { background: rgba(231,76,60,0.05); }
.reel-history-row-failed:hover { background: rgba(231,76,60,0.10); }
.reel-history-when { font-variant-numeric: tabular-nums; }

/* Inline error row beneath a failed render */
.reel-history-error-row td {
    background: rgba(231,76,60,0.07);
    border-bottom: 1px solid var(--border);
    padding: 0.4rem 0.8rem;
}
.reel-history-error {
    color: var(--danger);
    font-size: 0.8rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    word-break: break-word;
}

/* Reels v2: crossfade settings grid on the per-show editor. */
.reel-xf-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 0.4rem 1rem;
}
.reel-xf-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    padding: 0.3rem 0.55rem;
    border-radius: 4px;
    background: rgba(226,59,46,0.04);
}
.reel-xf-row:hover { background: rgba(226,59,46,0.10); }
.reel-xf-label { font-size: 0.82rem; color: var(--text); }
.reel-xf-row input[type="number"] {
    width: 5rem;
    text-align: right;
    padding: 0.2rem 0.4rem;
    font-size: 0.85rem;
}

/* Reels v2 Pass B: block-based timeline editor.
   - .reel-timeline wraps the scrollable horizontal track
   - .reel-timeline-track is the inner positioned-children container
   - .reel-tl-block is one segment rectangle
   - .reel-tl-handle is a draggable crossfade marker positioned in the
     overlap region between two adjacent blocks
*/
.reel-timeline {
    background: rgba(226,59,46,0.04);
    border: 1px solid var(--border);
    border-radius: 6px;
    /* Extra top padding leaves room for the overlap-badge that floats
       above the track (positioned at top:-22px on each badge). */
    padding: 2rem 0.7rem 0.7rem;
    /* Track auto-scales to fit the container width — hide any minor
       overflow from rounding (1-2px) rather than producing a scrollbar. */
    overflow-x: hidden;
    overflow-y: visible;
    min-height: 100px;
}
.reel-timeline-empty {
    color: var(--text-dim);
    font-size: 0.85rem;
    font-style: italic;
    padding: 1rem 0.4rem;
}
.reel-timeline-total {
    color: var(--text-dim);
    font-size: 0.78rem;
    margin-top: 0.6rem;
}
/* Drag-the-clip interaction (2026-05-17): segments after the first can be
   dragged left/right to set the overlap with the previous segment. The
   first segment is non-draggable (nothing to overlap with on its left). */
.reel-tl-block.is-draggable { cursor: ew-resize; }
.reel-tl-block.is-draggable:hover {
    outline: 2px solid rgba(23,24,28,0.25);
    outline-offset: -2px;
}
.reel-tl-block.is-dragging {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
    z-index: 5;
}

/* Single badge centred in each overlap region showing the current overlap
   in seconds. Sits ABOVE the timeline track so it stays readable even when
   the overlap is small and the badge crowds the segment edges. */
.reel-tl-overlap-badge {
    position: absolute;
    top: -22px;
    transform: translateX(-50%);
    background: var(--accent);
    color: #fff;
    font-size: 0.7rem;
    font-weight: 600;
    padding: 2px 7px;
    border-radius: 10px;
    pointer-events: none;       /* clicks pass through to the segment underneath */
    white-space: nowrap;
    box-shadow: 0 1px 3px rgba(23,24,28,0.18);
    z-index: 4;
}
.reel-timeline-track {
    position: relative;
    height: 70px;
    /* width set inline by JS */
}
.reel-tl-block {
    position: absolute;
    top: 0;
    height: 70px;
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 0.35rem 0.5rem;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    overflow: hidden;
    user-select: none;
    /* Make overlaps blend with each other through transparency. */
    mix-blend-mode: normal;
}
.reel-tl-block-label {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text);
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
}
.reel-tl-block-dur {
    font-size: 0.7rem;
    color: var(--text-dim);
    align-self: flex-end;
}
.reel-tl-handle {
    position: absolute;
    top: -6px;
    height: 82px;
    width: 18px;
    transform: translateX(-9px);
    cursor: ew-resize;
    z-index: 10;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    user-select: none;
}
.reel-tl-handle-bar {
    width: 4px;
    height: 70px;
    background: var(--accent);
    border-radius: 2px;
    box-shadow: 0 0 0 1px rgba(0,0,0,0.4);
}
.reel-tl-handle:hover .reel-tl-handle-bar {
    width: 6px;
    background: var(--accent);
    box-shadow: 0 0 8px var(--accent);
}
.reel-tl-handle-label {
    position: absolute;
    top: -6px;
    background: var(--accent);
    color: #fff;
    font-size: 0.65rem;
    font-weight: 600;
    padding: 1px 5px;
    border-radius: 3px;
    pointer-events: none;
    white-space: nowrap;
}

/* ── AI Presenter → Schedule calendar grid ─────────────────────────────── */
.aisched-scroll { max-height: 620px; overflow: auto; border: 1px solid var(--border); border-radius: 8px; background: var(--surface2); }
.aisched-head, .aisched-body { display: grid; grid-template-columns: 54px repeat(7, minmax(0, 1fr)); }
.aisched-body { position: relative; }   /* positioning context for the 'now' line */
.aisched-head { position: sticky; top: 0; z-index: 3; background: var(--surface2, #1a1d27); }
.aisched-corner { border-right: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.aisched-dayhead { padding: 0.4rem 0.3rem; text-align: center; font-size: 0.78rem; font-weight: 600;
    color: var(--text); border-right: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.aisched-dayhead.is-today { color: var(--accent-hover); background: rgba(226,59,46, 0.06);
    box-shadow: inset 0 -2px 0 var(--accent); font-weight: 700; }
.aisched-gutter { position: relative; border-right: 1px solid var(--border); }
.aisched-hour { height: 44px; box-sizing: border-box; font-size: 0.65rem; color: var(--text-dim);
    text-align: right; padding: 1px 4px 0 0; border-bottom: 1px solid rgba(23,24,28,0.04); }
.aisched-col { position: relative; border-right: 1px solid var(--border); cursor: copy;
    background-image: repeating-linear-gradient(to bottom, rgba(23,24,28,0.07) 0 1px, transparent 1px 44px); }
/* Relaid for the light theme, 2026-11-01. This was
   `background: rgba(39,43,56,0.55)` — a dark slate at 55%, which read as a
   subtle lift on the old all-dark admin and as flat mud on white, with
   dark body text sat on top of it. Now a near-white card: the category
   colour on the left border does the identifying, not the fill. Still
   semi-transparent so the clock-name watermark behind stays readable. */
.aisched-block { position: absolute; left: 3px; right: 3px; min-height: 30px; box-sizing: border-box;
    border-radius: 6px; padding: 2px 16px 2px 6px; font-size: 0.7rem; line-height: 1.2; overflow: hidden;
    cursor: grab; color: var(--text);
    background: rgba(255, 255, 255, 0.88);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
    box-shadow: 0 1px 2px rgba(23, 24, 28, 0.07); z-index: 1; touch-action: none; }
.aisched-block:hover { background: #fff; border-color: var(--accent);
    box-shadow: 0 2px 8px rgba(23, 24, 28, 0.13); z-index: 3; }
.aisched-block.dragging { opacity: 0.85; cursor: grabbing; z-index: 5; }
.aisched-block.is-disabled { opacity: 0.45; border-left-style: dashed; }
.aisched-block .t { font-weight: 700; }
.aisched-block .p { display: block; font-size: 0.62rem; color: var(--text-dim); }
.aisched-block .x { position: absolute; top: 0; right: 3px; display: none; cursor: pointer;
    color: var(--text-dim); font-size: 0.72rem; }
.aisched-block:hover .x { display: block; }
.aisched-block.cat-station_id { border-left-color: #e67e22; }
.aisched-block.cat-show_promo { border-left-color: #1b7842; }
.aisched-block.cat-weather { border-left-color: #1d6da3; }
.aisched-block.cat-back_intro, .aisched-block.cat-forward_intro { border-left-color: #8c4aa8; }
/* The clock-name watermark behind the blocks. The black text-shadow was
   a glow for light-on-dark; on white it just smudged the letters. */
.aisched-clock { position: absolute; left: 4px; right: 4px; height: 44px; box-sizing: border-box;
    font-size: 0.62rem; line-height: 1.05; color: var(--text-dim); opacity: 0.85; pointer-events: none;
    overflow: hidden; white-space: nowrap; padding-top: 1px; z-index: 0; font-weight: 600; }
.aisched-clock-protected { background: rgba(231, 76, 60, 0.12); color: #c52818; opacity: 0.75;
    border-top: 1px solid rgba(231, 76, 60, 0.4); }

/* RECURRING-PREFERENCE BASELINE: all form inputs inside admin .tab-panel
   match the dark theme by default. Default browser white reads as "out of
   place" — flagged twice by the operator. Override with a higher-specificity
   class selector (e.g. .block-text-input) when a chip / transparent look is
   wanted. Checkboxes/radios/range/file keep their native styling. */
.tab-panel input[type="text"],
.tab-panel input[type="time"],
.tab-panel input[type="number"],
.tab-panel input[type="search"],
.tab-panel input[type="email"],
.tab-panel input[type="url"],
.tab-panel input[type="password"],
.tab-panel input:not([type]),
.tab-panel textarea,
.tab-panel select {
    background: var(--surface2);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 5px;
    padding: 0.4rem 0.55rem;
    font-family: inherit;
    font-size: 0.95rem;          /* match .form-group input convention */
    box-sizing: border-box;
}
.tab-panel textarea { resize: vertical; line-height: 1.35; }
/* Everything focusable in the light working area. Buttons, links and
   summary elements included — they all inherited the browser blue. */
.main a:focus-visible,
.main button:focus-visible,
.main summary:focus-visible,
.main [tabindex]:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 4px;
}

.tab-panel input:focus, .tab-panel textarea:focus, .tab-panel select:focus {
    outline: none; border-color: var(--accent);
}

/* Same baseline for inputs sitting directly inside an admin .card on a
   standalone page (script editor, topic editor, etc.) — bare <input> elements
   that aren't wrapped in .form-group don't pick up the .form-group rule. We
   intentionally MATCH .form-group's padding/font-size so where they overlap
   (a .form-group inside a .card) the visual output is identical regardless
   of which rule wins the cascade. Flagged 2026-05-23 (bed-timing inputs on
   the script editor). */
/* `:not(.block-text-input)` excludes chip-style inputs used inside script-
   editor blocks (e.g. audio_tag pill input). Those have their own transparent
   styling at `.block-item input.block-text-input` and must NOT pick up the
   dark surface2 background here — otherwise the chip's tint background is
   obscured by a black input rectangle (flagged 2026-05-23 on new Accents/
   Dialogue tags). Same specificity as the chip rule but :not() keeps us out
   of its way structurally. */
.card input[type="text"]:not(.block-text-input),
.card input[type="time"]:not(.block-text-input),
.card input[type="number"]:not(.block-text-input),
.card input[type="search"]:not(.block-text-input),
.card input[type="email"]:not(.block-text-input),
.card input[type="url"]:not(.block-text-input),
.card input[type="password"]:not(.block-text-input),
.card input:not([type]):not(.block-text-input),
.card textarea:not(.block-text-input),
.card select:not(.block-text-input) {
    background: var(--surface2);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.6rem 0.8rem;
    font-family: inherit;
    font-size: 0.95rem;
    box-sizing: border-box;
}
.card textarea:not(.block-text-input) { resize: vertical; line-height: 1.5; }
.card input:not(.block-text-input):focus,
.card textarea:not(.block-text-input):focus,
.card select:not(.block-text-input):focus {
    outline: none; border-color: var(--accent);
}
.aisched-now-line { position: absolute; left: 54px; right: 0; height: 2px; background: rgba(231, 76, 60, 0.7); z-index: 4; pointer-events: none; }
.aisched-now-line::before { content: ''; position: absolute; left: -4px; top: -3px; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
/* Add/edit modal (shared look with the dashboard modal) */
.aisched-modal { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.55); display: flex;
    align-items: center; justify-content: center; z-index: 1000; }
.aisched-modal-box { background: var(--surface, #1a1d27); border: 1px solid var(--border); border-radius: 10px;
    padding: 1.1rem 1.2rem; width: 360px; max-width: 92vw; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5); }
.aisched-lbl { display: block; font-size: 0.78rem; color: var(--text-dim); margin-bottom: 0.2rem; }
.aisched-modal-box select, .aisched-modal-box input[type="time"] { width: 100%; box-sizing: border-box;
    background: var(--surface2); color: var(--text); border: 1px solid var(--border); border-radius: 5px; padding: 0.4rem; }
