/* =====================================================================
 * chroma-setup-tuner.css — page-specific layer for chroma-setup-tuner.html
 *
 * Loaded AFTER product-theme.css (the unmodified canonical copy), per the
 * two-file rule in nanocosmos-brand-guidelines: the theme owns tokens,
 * header, footer, form controls, buttons and the workbench layout; this
 * file only holds what the theme has no component for (switcher, source
 * cards, stream cards, combo boxes, despill/EQ, transcode chips, RGB
 * picker…) plus a few mappings of this page's class names onto theme
 * components (see "Product Theme alignment" at the bottom).
 *
 * Every colour is a product-theme.css token. The only literal colours are
 * colour-as-DATA (key-colour swatches #00FF00 / #0057FF, RGB channel
 * labels and slider thumbs) and the near-black video frame, which the
 * theme's own .monitor also keeps literal.
 *
 * Built 2026-10-29 from setup-brand.css + the page's former inline
 * <style> block. setup-brand.css itself is unchanged and still serves
 * multi-chroma-key-player.html.
 * ===================================================================== */

/* Legacy token NAMES this page's rules still use, aliased onto the theme.
   Kept so the ~hundreds of call sites didn't all need renaming; new rules
   should use the theme's own token names directly. */
:root {
    --orange: var(--accent-orange);
    --orange-dark: var(--accent-orange-hover);
    --blue: var(--accent-blue);
    --blue-dark: var(--accent-blue-hover);
    --navy: var(--text-primary);
    --hero-navy: var(--text-primary);
    --platform-navy: var(--panel);
    --bg-soft: var(--panel-soft);
    --bg-sunken: var(--panel-inset);
    --bg-card: var(--panel);
    --bg-dark: var(--panel);
    --surface-2: var(--panel-soft);
    --ink: var(--text-primary);
    --text: var(--text-primary);
    --muted: var(--text-primary);
    --grey: var(--text-primary);
    --text-on-dark: var(--text-on-accent);
    --text-on-dark-soft: var(--text-primary);
    --line: var(--border);
    --line-strong: var(--border-strong);
    --line-faint: var(--border);
    --ok: var(--accent-blue);
    --ok-soft: var(--bg);
    --err: var(--accent-orange);
    --err-soft: var(--bg);
    --warn: var(--accent-orange);
    --warn-soft: var(--bg);
    --accent-green: var(--accent-blue);
    --font-display: var(--font-heading);
    --container: var(--page-max-width);
    --radius: 4px;
    --radius-sm: 4px;
    --radius-lg: 4px;
}

/* =====================================================================
 * setup-brand.css — fresh brand-aligned stylesheet for setup-brand.html
 *
 * Tier:  Demo page (web.pages.gitlab.nanocosmos.cloud)
 * Fonts: Lexend Deca (display, Google Fonts) + Source Sans 3 (body, Google Fonts)
 *        Cocogoose is reserved for marketing surfaces and is never loaded here.
 * Tokens: see :root below — canonical brand tokens from
 *        nanocosmos-brand-guidelines/references/web-css-shared.md.
 *
 * Built from scratch — no rules borrowed from styles.css. Only the layout
 * primitives (workbench grid, upload grid, sections, sticky preview,
 * sliders + value-input shape) are preserved by intent.
 * ===================================================================== */

/* ---------- Brand tokens (light demo theme) ---------- */

/* ---------- Reset / base ---------- */

h1,
h2,
h3,
h4,
h5 {
    font-family: var(--font-display);
    font-weight: 700;
    line-height: 1.2;
    color: var(--navy);
    margin: 0 0 12px;
    letter-spacing: 0;
    text-transform: none;
}
h1 { font-size: clamp(24px, 3.2vw, 32px); line-height: 1.15; }
h3 { font-size: 18px; }
h4 { font-size: 14px; }

p { margin: 0 0 12px; }

a { color: var(--blue); text-decoration: none; }
a:hover { color: var(--blue-dark); text-decoration: underline; }

code,
pre { font-family: var(--font-mono); font-size: 0.9em; }
code { background: var(--bg-sunken); padding: 1px 6px; border-radius: 4px; color: var(--navy); }

.hidden { display: none !important; }

/* ---------- Demo header (brand: navy bg, logo + title) ---------- */

/* ---------- Page layout ---------- */
.workbench > details,
.workbench > #configurationSection,
.workbench > script + footer { /* sections live directly under body */ }

/* Outer page padding wrapper using direct child rules */
.workbench > details.section,
.workbench > #configurationSection {
    width: min(calc(100% - 48px), var(--container));
    margin: 16px auto;
}

/* ---------- Section card ---------- */
.section,
details.section {
    background: var(--bg-card);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: 18px 22px;
    margin: 0 0 16px;
}

.section h3 { margin: 0 0 16px; }

/* Collapsible <details>/<summary> as section header */
details.collapsible > summary {
    list-style: none;
    cursor: pointer;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 16px;
    color: var(--text-primary);
    background: var(--blue);
    width: fit-content;
    padding: 8px 16px 8px 34px;
    margin: 0 0 14px;
    border-radius: var(--radius-sm);
    position: relative;
    user-select: none;
    display: inline-flex;
    align-items: center;
    gap: 12px;
}
details.collapsible > summary > select {
    width: auto;
    margin: 0;
    padding: 4px 8px;
    font-size: 13px;
    background: var(--bg);
    color: var(--ink);
    border: 1px solid var(--line-strong);
    border-left: 3px solid var(--border-strong);
    cursor: pointer;
}
details.collapsible:not([open]) > summary { margin-bottom: 0; }
details.collapsible { padding-top: 12px; padding-bottom: 12px; }
details.collapsible > summary::-webkit-details-marker { display: none; }
details.collapsible > summary::before {
    content: '';
    position: absolute;
    left: 12px;
    top: 50%;
    width: 8px;
    height: 8px;
    border-right: 2px solid var(--border-strong);
    border-bottom: 2px solid var(--border-strong);
    transform: translateY(-65%) rotate(-45deg);
    transition: transform 0.18s ease;
}
details.collapsible[open] > summary::before {
    transform: translateY(-50%) rotate(45deg);
}

.section-subhead {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 13px;
    color: var(--navy);
    margin: 20px 0 10px;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.section-actions { margin-top: 20px; }

/* ---------- Forms ---------- */
label {
    display: block;
    margin: 0 0 6px;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 13px;
    color: var(--navy);
    letter-spacing: 0.01em;
}

/* Range sliders */

input[type="range"].red::-webkit-slider-thumb,
input[type="range"].red::-moz-range-thumb { background: #E53935; }
input[type="range"].green::-webkit-slider-thumb,
input[type="range"].green::-moz-range-thumb { background: #2E8B57; }
input[type="range"].blue::-webkit-slider-thumb,
input[type="range"].blue::-moz-range-thumb { background: var(--blue); }

/* ---------- Buttons ---------- */

/* Secondary — blue */

/* Tertiary — outline navy (low emphasis utility actions) */
.btn-xs {
    background: var(--orange);
    color: var(--text-primary);
    border: 1px solid var(--border-strong);
}
.btn-xs:hover {
    background: var(--orange-dark);
    border-color: var(--orange-dark);
}
.btn-outline {
    background: var(--bg);
    color: var(--text-primary);
    border: 1px solid var(--border-strong);
}
.btn-outline:hover {
    color: var(--text-primary);
    border-color: var(--blue-dark);
    background: var(--blue);
}

/* Size variants */
.btn-sm { padding: 8px 14px; font-size: 13px; margin: 0; white-space: nowrap; }
.btn-xs { padding: 5px 10px; font-size: 12px; margin: 0; }
.btn-glyph { color: var(--text-primary); font-size: 12px; line-height: 1; }

/* Hidden native color-picker — keeps label clickable */
.native-picker-hidden {
    width: 0; height: 0;
    padding: 0;
    border: 0;
    opacity: 0;
    position: absolute;
    pointer-events: none;
}

/* ---------- Layout helpers ---------- */
.form-row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 12px;
}
.form-row.tight { gap: 6px; }
.form-row.wrap { flex-wrap: wrap; }
.form-row > label { margin: 0; white-space: nowrap; flex-shrink: 0; }
.form-row > .grow { flex: 1; min-width: 0; }
.form-row > input,
.form-row > select { margin: 0; }

.action-row {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 12px;
}
.action-row > .grow { flex: 1; min-width: 0; }

.adj-status-row { margin-top: 10px; min-height: 0; }
.adj-status-row:empty { display: none; }

.grid-2col {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
}

.overlay-center {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* ---------- Info / banner / result ---------- */
.info {
    background: var(--bg-soft);
    border: 1px solid var(--line);
    border-left: 3px solid var(--line-strong);
    border-radius: var(--radius);
    padding: 10px 14px;
    margin: 8px 0;
    font-size: 13px;
    color: var(--ink);
}
.info.sm { font-size: 12px; padding: 8px 12px; margin-bottom: 12px; }
.info code { background: var(--bg); color: var(--navy); padding: 1px 6px; border-radius: 4px; }

.result {
    background: var(--bg-sunken);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 12px 14px;
    margin-top: 10px;
    font-family: var(--font-mono);
    font-size: 12.5px;
    color: var(--ink);
    white-space: pre-wrap;
    word-break: break-all;
    max-height: 320px;
    overflow-y: auto;
}
.success { background: var(--bg-sunken); border-left: 3px solid var(--line-strong); color: var(--ink); }
.error { background: var(--err-soft); border-left: 3px solid var(--err); color: var(--text-primary); }

/* ---------- Mode tabs (Create / Reuse) ---------- */
.mode-tabs-row {
    display: flex;
    gap: 10px;
    margin: 4px 0 18px;
}
.mode-tab {
    flex: 1;
    padding: 6px 16px;
    margin: 0;
    border-radius: var(--radius);
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 14px;
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s, opacity 0.15s;
}
.mode-tab.left {
    background: var(--bg);
    color: var(--text-primary);
    border: 1px solid var(--border-strong);
}
.mode-tab.left:hover,
.mode-tab.left.active {
    background: var(--orange);
    color: var(--text-primary);
    border-color: var(--orange);
}
.mode-tab.left.active:hover { background: var(--orange-dark); border-color: var(--orange-dark); }
.mode-tab.right {
    background: var(--bg);
    color: var(--text-primary);
    border: 1px solid var(--border-strong);
}
.mode-tab.right:hover,
.mode-tab.right.active {
    background: var(--blue);
    color: var(--text-primary);
    border-color: var(--blue);
}
.mode-tab.right.active:hover { background: var(--blue-dark); border-color: var(--blue-dark); }

/* ---------- Auth tabs (API Key | Email & Password) — pill/segmented ---------- */
.auth-tabs-row {
    display: inline-flex;
    gap: 0;
    margin: 4px 0 10px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    overflow: hidden;
}
.auth-tab {
    padding: 5px 16px;
    margin: 0;
    border-radius: 0;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 13px;
    cursor: pointer;
    background: var(--bg);
    color: var(--text-primary);
    border: 0;
    transition: background 0.15s, color 0.15s;
}
.auth-tab + .auth-tab { border-left: 1px solid var(--border-strong); }
.auth-tab:hover { background: var(--bg); }
.auth-tab.active { background: var(--blue); color: var(--text-primary); }
.auth-tab.active:hover { background: var(--blue-dark); }
.auth-pane { /* shown/hidden by JS */ }

/* ---------- Chroma section (light card inside a section) ---------- */
.chroma-section {
    background: var(--bg-sunken);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 16px;
    margin: 0 0 14px;
}
.chroma-section h4 {
    margin: 0 0 12px;
    color: var(--navy);
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.slider-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    margin-bottom: 8px;
}
.slider-header label { margin: 0; }

.value-badge,
.value-input {
    display: inline-block;
    min-width: 56px;
    padding: 3px 10px;
    background: var(--orange);
    color: var(--text-primary);
    border: 1px solid var(--border-strong);
    border-radius: 999px;
    text-align: center;
    font-family: var(--font-body);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.01em;
}
.value-input {
    width: 76px;
    margin: 0;
    -moz-appearance: textfield;
}
.value-input::-webkit-outer-spin-button,
.value-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.value-input:focus { outline: 2px solid var(--border-strong); outline-offset: -3px; }

.param-slider { width: 100%; margin: 0 0 6px; }

.help-text {
    font-size: 12.5px;
    color: var(--muted);
    margin: 8px 0 0;
    line-height: 1.45;
}

/* ---------- Key Color picker ---------- */
.color-indicator {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 12px;
    font-size: 14px;
    color: var(--ink);
}
.color-indicator .swatch-box {
    width: 22px; height: 22px;
    border-radius: 4px;
    background: #00FF00;
    border: 2px solid var(--line);
    box-shadow: var(--shadow-sm);
}

.preset-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px;
    margin: 0;
    background: var(--bg);
    color: var(--navy);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 13px;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.preset-btn:hover:not(.active) {
    border-color: var(--navy);
    background: var(--bg-sunken);
}
.preset-btn.active {
    background: var(--orange);
    border-color: var(--orange);
    color: var(--text-primary);
}
.preset-btn .swatch {
    width: 16px; height: 16px;
    border-radius: 50%;
    border: 2px solid var(--border-strong);
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.18);
    display: inline-block;
}
.preset-btn .swatch.green { background: #00FF00; }
.preset-btn .swatch.blue { background: #0057FF; }
.preset-btn.picker-label { cursor: pointer; }

.color-compact {
    display: grid;
    grid-template-columns: 88px 1fr;
    gap: 16px;
    align-items: start;
}
.color-left { display: flex; flex-direction: column; gap: 8px; align-items: center; }
.color-right { display: flex; flex-direction: column; gap: 10px; }
.color-preview-compact {
    width: 76px; height: 76px;
    border-radius: 4px;
    background: #00FF00;
    border: 2px solid var(--line);
    box-shadow: var(--shadow-sm);
}

.rgb-inline { display: flex; gap: 12px; align-items: center; }
.rgb-channel { display: flex; gap: 8px; align-items: center; flex: 1; min-width: 0; }
.rgb-label { font-size: 12px; font-weight: 700; width: 14px; text-align: center; }
.rgb-label.red { color: #E53935; }
.rgb-label.green { color: #2E8B57; }
.rgb-label.blue { color: var(--blue); }
.rgb-slider { flex: 1; margin: 0; min-width: 0; }
.rgb-value {
    width: 52px;
    margin: 0;
    padding: 4px 6px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    text-align: center;
    font-size: 12px;
    color: var(--ink);
}

.hex-row-compact {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 4px;
    padding-top: 10px;
    border-top: 1px solid var(--line);
}
.hex-row-compact .hex-prefix { font-size: 14px; color: var(--muted); font-weight: 700; }
.hex-row-compact input {
    flex: 1;
    margin: 0;
    padding: 6px 10px;
    font-family: var(--font-mono);
    font-size: 13px;
    letter-spacing: 1px;
    text-transform: uppercase;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
}

/* ---------- Despill control row ---------- */
.despill-fields {
    display: grid;
    grid-template-columns: auto auto minmax(240px, 1fr);
    align-items: center;
    gap: 12px;
}
.despill-enable { display: inline-flex; align-items: center; gap: 8px; margin: 0; font-size: 13px; }
.despill-type { display: inline-flex; align-items: center; gap: 8px; }
.despill-mix { display: flex; align-items: center; gap: 10px; min-width: 0; }
.despill-mix label { margin: 0; font-size: 12px; color: var(--muted); }
.despill-mix .param-slider { flex: 1 1 auto; min-width: 90px; margin: 0; }
.despill-mix .value-input { width: 76px; }

/* Hide sub-options when Despill/EQ checkboxes are unchecked. Keeps the
   checkbox + its label visible so users can still toggle. !important
   is required because #despillAdvanced / #eqFields use inline display:grid. */
.chroma-section:has(#despillEnabled:not(:checked)) .despill-type,
.chroma-section:has(#despillEnabled:not(:checked)) .despill-mix,
.chroma-section:has(#despillEnabled:not(:checked)) .despill-fields > button,
.chroma-section:has(#despillEnabled:not(:checked)) #despillAdvanced,
.chroma-section:has(#despillEnabled:not(:checked)) #despillPreview {
    display: none !important;
}
.chroma-section:has(#eqEnabled:not(:checked)) #eqFields,
.chroma-section:has(#eqEnabled:not(:checked)) #eqPreview {
    display: none !important;
}

.color-radio {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    padding: 7px 12px;
    background: var(--bg);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    color: var(--ink);
    cursor: pointer;
    font-size: 13px;
    font-weight: 600;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.color-radio input { position: absolute; opacity: 0; pointer-events: none; }
.color-radio-square {
    width: 20px; height: 20px;
    border: 2px solid var(--border-strong);
    border-radius: 4px;
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.18);
}
.color-radio-green .color-radio-square { background: #00FF00; }
.color-radio-blue .color-radio-square { background: #0057FF; }
.color-radio:has(input:checked) {
    border-color: var(--orange);
    box-shadow: none;
    color: var(--navy);
}

/* ---------- Stream info table ---------- */
#streamInfo { margin: 6px 0 18px; }

.stream-table-wrap {
    overflow-x: auto;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--bg);
    margin-bottom: 12px;
}
.stream-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}
.stream-table th,
.stream-table td {
    text-align: left;
    padding: 12px 14px;
    border-bottom: 1px solid var(--line);
    vertical-align: middle;
    white-space: nowrap;
}
.stream-table th {
    font-family: var(--font-display);
    font-size: 12px;
    font-weight: 700;
    color: var(--navy);
    background: var(--bg-sunken);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.stream-table tr:last-child td { border-bottom: 0; }
.stream-table tr:hover td { background: var(--bg); }
.stream-table .mono {
    display: inline-block;
    font-family: var(--font-mono);
    font-size: 12.5px;
    padding: 2px 8px;
    background: var(--bg-sunken);
    color: var(--navy);
    border-radius: 4px;
    -webkit-user-select: all;
    user-select: all;
}
.stream-table a.mono { color: var(--blue); background: var(--bg-sunken); }
.stream-table a.mono:hover { color: var(--blue-dark); text-decoration: underline; }
.stream-table .stream-bg-select,
.stream-table .stream-bg-input {
    font-size: 12px;
    padding: 3px 6px;
    border-radius: 4px;
    border: 1px solid var(--line);
    background: var(--bg);
    color: var(--text);
    max-width: 260px;
    width: 100%;
}
.stream-table .copyable { cursor: pointer; color: var(--navy); }
.stream-table .copyable:hover { color: var(--text-primary); }
.stream-table .muted { color: var(--grey); }
.stream-table .copy-btn {
    background: transparent;
    color: var(--muted);
    border: 0;
    padding: 0 6px;
    margin: 0 0 0 4px;
    font-size: 13px;
    cursor: pointer;
    transition: color 0.15s;
}
.stream-table .copy-btn:hover { color: var(--text-primary); }

.stream-meta {
    font-size: 12.5px;
    color: var(--muted);
    margin: 4px 0 12px;
}
.stream-meta code { background: var(--bg-sunken); color: var(--navy); padding: 1px 6px; border-radius: 4px; }

.stream-type-badge {
    display: inline-block;
    font-family: var(--font-display);
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 2px 8px;
    border-radius: 4px;
    white-space: nowrap;
}
.ingest-badge {
    background: var(--bg);
    color: var(--navy);
}
.target-badge {
    background: var(--bg);
    color: var(--text-primary);
}

/* Ingest row — the input source, visually set apart from the target outputs */
.stream-table tr.ingest-row td {
    background: var(--bg);
    border-bottom: 2px solid var(--navy);
}
.stream-table tr.ingest-row:hover td {
    background: var(--bg);
}
.stream-table tr.ingest-row td:first-child {
    box-shadow: inset 3px 0 0 var(--navy);
}

/* Per-target delete button */
.stream-table .col-actions { width: 1%; white-space: nowrap; text-align: right; }
.target-del-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin: 0;
    padding: 4px 10px;
    font-family: var(--font-body);
    font-size: 12px;
    font-weight: 600;
    color: var(--muted);
    background: transparent;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: color .15s, background .15s, border-color .15s;
}
.target-del-btn:hover {
    color: var(--text-primary);
    background: var(--err);
    border-color: var(--err);
}
/* Open the stream overview in the dashboard (per-stream icon link) */
.stream-table .dash-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    margin-right: 6px;
    font-size: 14px;
    line-height: 1;
    text-decoration: none;
    color: var(--muted);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    vertical-align: middle;
    transition: color .15s, background .15s, border-color .15s;
}
.stream-table .dash-link:hover {
    color: var(--orange);
    border-color: var(--orange);
    background: var(--bg);
}

/* Auth status + org hash live inside the <summary> so they stay visible when
   the panel is collapsed. Override the summary's uppercase styling — the org
   hash is case-sensitive. Compact the status chip so it sits inline in the
   summary pill (the setup page wraps status text in a .result element). */
.auth-summary-status,
.auth-summary-org {
    font-size: 12px; font-weight: 600;
    text-transform: none; letter-spacing: 0;
    color: var(--text-primary); white-space: nowrap;
}
.auth-summary-org code { font-family: var(--font-mono); text-transform: none; letter-spacing: 0; }
.auth-summary-org.hidden { display: none; }
.auth-summary-status:empty { display: none; }
.auth-summary-status .result {
    display: inline; margin: 0; padding: 0;
    background: none; border: 0; border-radius: 0;
    max-height: none; overflow: visible;
    font-family: var(--font-body); font-size: 12px; white-space: nowrap;
}
.auth-summary-status .success { color: var(--text-primary); }
.auth-summary-status .error { color: var(--text-primary); background: none; }

.bg-select {
    width: 100%;
    margin: 0;
    padding: 6px 8px;
    font-size: 13px;
}

/* ---------- Upload area + file list + preview ---------- */
.upload-grid {
    display: grid;
    grid-template-columns: minmax(220px, 1fr) minmax(240px, 1.1fr) minmax(280px, 1.4fr);
    gap: 16px;
    margin-top: 10px;
}
@media (max-width: 900px) { .upload-grid { grid-template-columns: 1fr; } }
.upload-grid > div { min-width: 0; }

.upload-col-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin: 0 0 8px;
    font-size: 13px;
}
.upload-col-title strong {
    color: var(--navy);
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 13px;
}

.upload-area {
    border: 2px dashed var(--line-strong);
    border-radius: var(--radius);
    background: var(--bg-sunken);
    color: var(--muted);
    text-align: center;
    cursor: pointer;
    padding: 24px 12px;
    min-height: 130px;
    display: grid;
    place-content: center;
    gap: 4px;
    transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.upload-area:hover,
.upload-area.drag-over {
    border-color: var(--orange);
    background: var(--panel);
    color: var(--navy);
}
.upload-area.compact { padding: 18px 10px; font-size: 13px; }
.upload-area .drop-icon {
    width: 36px;
    height: 28px;
    margin: 0 auto 6px;
    border: 2px solid var(--border-strong);
    border-top-width: 8px;
    border-radius: 4px 4px 4px 4px;
    opacity: 0.95;
}

.upload-card-heading {
    background: var(--bg-soft);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 10px 12px;
    margin: 10px 0 8px;
    font-size: 12.5px;
}
.upload-card-heading ul {
    margin: 6px 0 0;
    padding-left: 18px;
    color: var(--muted);
    font-size: 12px;
}

.upload-progress {
    margin-top: 10px;
    padding: 10px 12px;
    background: var(--bg-sunken);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    font-size: 12.5px;
    color: var(--muted);
}
.upload-progress .bar {
    height: 6px;
    margin-top: 6px;
    background: var(--line);
    border-radius: 999px;
    overflow: hidden;
}
.upload-progress .fill {
    height: 100%;
    width: 0%;
    background: var(--orange);
    transition: width 0.3s;
}

.file-list-empty {
    color: var(--grey);
    font-size: 12.5px;
    padding: 18px 8px;
    text-align: center;
}
.file-list-box {
    background: var(--bg-soft);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 4px;
    max-height: 280px;
    overflow-y: auto;
}
.file-list-item {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    padding: 3px 10px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: 12.5px;
    color: var(--ink);
    border: 1px solid transparent;
    transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.file-list-item:hover { background: var(--bg-sunken); color: var(--navy); }
.file-list-item.selected {
    background: var(--bg);
    border-color: var(--blue);
    color: var(--navy);
}
.file-list-item .fname {
    font-family: var(--font-mono);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
    min-width: 0;
}
.file-list-item .fmeta {
    color: var(--muted);
    font-size: 12px;
    white-space: nowrap;
    flex-shrink: 0;
}
/* Average-bitrate flag on uploaded MP4 backgrounds (warn > 8, err > 15 Mbps). */
.bitrate-badge {
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
    flex-shrink: 0;
    padding: 0 6px;
    border-radius: var(--radius-sm);
    cursor: help;
}
.bitrate-badge.warn { color: var(--text-primary); background: var(--warn-soft); }
.bitrate-badge.err { color: var(--text-primary);  background: var(--err-soft); }
.bitrate-badge.unknown { color: var(--muted); border: 1px dashed var(--line); }
.bitrate-note { color: var(--text-primary); }
.bitrate-note.err { color: var(--text-primary); }

.preview-box {
    background: var(--bg-soft);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 12px;
    margin-bottom: 20px;
    min-height: 200px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 8px;
}
.preview-box img,
.preview-box video {
    max-width: 100%;
    max-height: 260px;
    border-radius: var(--radius-sm);
    background: #000;
}
.preview-box .placeholder {
    color: var(--grey);
    font-size: 12.5px;
    text-align: center;
}
.preview-box .fname-line {
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--muted);
    word-break: break-all;
    text-align: center;
    margin: 0;
}

/* ---------- Validation list (rendered by JS) ---------- */
.validation-item {
    list-style: none;
    padding: 7px 0;
    border-bottom: 1px solid var(--line-faint);
}
.validation-item .title { font-weight: 600; }
.validation-item .meta { font-size: 12px; color: var(--muted); margin-top: 2px; }
.validation-item.ok { color: var(--text-primary); }
.validation-item.warn { color: var(--text-primary); }
.validation-item.err { color: var(--text-primary); }
.validation-item.warn .meta.accent { color: var(--text-primary); }
.validation-item.err  .meta.accent { color: var(--text-primary); }
.validation-loading { color: var(--muted); list-style: none; padding: 6px 0; }

/* ---------- Switch (inline checkbox + label) ---------- */
.switch-label {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    padding: 0;
    color: var(--ink);
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 13px;
    cursor: pointer;
    white-space: nowrap;
}
.switch-label input[type="checkbox"] { cursor: pointer; }

/* ---------- Workbench layout (preview on left, controls on right) ---------- */
.workbench-header {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
    max-width: var(--container);
    margin: 22px auto 14px;
    padding: 16px 20px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}
.workbench-header .eyebrow {
    margin: 0 0 4px;
    font-family: var(--font-body);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-primary);
}
.workbench-header h3 {
    margin: 0;
    color: var(--navy);
    font-size: 20px;
}
.workbench-status {
    font-size: 12.5px;
    color: var(--muted);
    padding: 6px 12px;
    background: var(--bg-sunken);
    border: 1px solid var(--line);
    border-radius: 999px;
    white-space: nowrap;
}

.workbench-layout {
    display: grid;
    grid-template-columns: minmax(720px, 1fr) minmax(440px, 520px);
    gap: 24px;
    align-items: start;
    max-width: var(--container);
    margin: 0 auto 24px;
}
.workbench-preview,
.workbench-controls { min-width: 0; }

.workbench-preview {
    position: sticky;
    top: 96px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: 16px;
}

.workbench-controls {
    display: flex;
    flex-direction: column;
    gap: 14px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: 18px;
}
.workbench-controls .chroma-section { margin-bottom: 0; }
.workbench-controls > .grid-2col { grid-template-columns: 1fr; }
.workbench-controls #despillAdvanced,
.workbench-controls #eqFields { grid-template-columns: 1fr 1fr !important; gap: 12px; }
.workbench-controls .despill-fields { grid-template-columns: auto 1fr; gap: 14px; }
.workbench-controls .despill-mix {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: auto minmax(180px, 1fr) 76px;
    gap: 10px;
}
.workbench-controls .despill-fields > button {
    grid-column: 1 / -1;
    justify-self: start;
}
.workbench-controls > .action-row {
    position: sticky;
    bottom: 0;
    z-index: 2;
    margin: 4px 0 0;
    padding: 12px 14px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: none;
}

#configurationSection {
    background: transparent;
    border: 0;
    box-shadow: none;
    padding: 0;
    margin: 16px auto;
}
#configurationSection > .section,
#configurationSection > .mode-tabs-row,
#configurationSection > h3,
#configurationSection > h4,
#configurationSection > .section-subhead,
#configurationSection > #targetCountRow,
#configurationSection > #streamInfo,
#configurationSection > #createPane,
#configurationSection > #reusePane {
    max-width: var(--container);
    margin-left: auto;
    margin-right: auto;
}
#configurationSection > h3 {
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: 18px 22px;
    margin: 0 0 16px;
}
#configurationSection > h4,
#configurationSection > .section-subhead,
#configurationSection > #targetCountRow,
#configurationSection > #streamInfo,
#configurationSection > #createPane,
#configurationSection > #reusePane,
#configurationSection > .mode-tabs-row {
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: 18px 22px;
    margin: 0 0 16px;
}
#configurationSection > .mode-tabs-row { padding: 8px 22px; }

/* Adjust-panel (legacy; kept hidden by JS but styled for completeness) */
.adjust-panel {
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: 18px;
    margin: 14px 0;
}
.adjust-panel > h4 { color: var(--navy); font-size: 14px; margin: 0 0 12px; }
.adj-mode {
    padding: 6px 14px;
    background: var(--bg);
    color: var(--navy);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    font-size: 12px;
    cursor: pointer;
}
.adj-mode.active { background: var(--orange); border-color: var(--orange); color: var(--text-primary); }

/* ---------- Player section ---------- */
.player-section { margin: 0; }
.player-header {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 10px;
}
.player-header h4 {
    margin: 0;
    color: var(--navy);
    font-family: var(--font-display);
    font-size: 14px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.player-header-actions {
    margin-left: auto;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.player-tabs-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 12px;
    min-height: 36px;
}
.player-tab {
    padding: 7px 14px;
    margin: 0;
    background: var(--bg);
    color: var(--navy);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 13px;
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.player-tab:hover {
    border-color: var(--navy);
    background: var(--bg-sunken);
}
.player-tab.active {
    background: var(--orange);
    border-color: var(--orange);
    color: var(--text-primary);
}

.player-stage {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    background: #000;
    border-radius: var(--radius);
    overflow: hidden;
    border: 1px solid var(--line);
}
#playerDiv { width: 100%; height: 100%; }
#playerDiv > * { max-width: 100%; }
.player-placeholder {
    color: rgba(255, 255, 255, 0.55);
    font-size: 13px;
    text-align: center;
}

/* ---------- Text helpers ---------- */
.text-muted { color: var(--muted); font-size: 12.5px; }
.text-muted-sm { color: var(--muted); font-size: 12px; }

/* ---------- Demo footer ---------- */

.page-version {
    display: flex;
    gap: 8px;
    font-family: var(--font-body);
    font-size: 12px;
    color: var(--text-primary);
    letter-spacing: 0.02em;
}

/* ---------- Responsive ---------- */
@media (max-width: 1180px) {
    .workbench-layout { grid-template-columns: 1fr; }
    .workbench-preview { position: static; }
    .player-stage { min-height: 0; }
}

@media (max-width: 760px) {
    
    
    
    .section,
details.section,
#configurationSection > h3,
#configurationSection > h4,
#configurationSection > .section-subhead,
#configurationSection > #targetCountRow,
#configurationSection > #streamInfo,
#configurationSection > #createPane,
#configurationSection > #reusePane,
#configurationSection > .mode-tabs-row,
.workbench-header,
.workbench-preview,
.workbench-controls { padding: 14px; }
    .grid-2col,
.workbench-controls #despillAdvanced,
.workbench-controls #eqFields,
.despill-fields { grid-template-columns: 1fr !important; }
    .color-compact { grid-template-columns: 1fr; }
    .mode-tabs-row { flex-direction: column; }
    .mode-tab.left,
.mode-tab.right { margin: 0 0 4px; }
    .btn-sm,
.btn-xs { width: 100%; margin-right: 0; }
}

/* ---------- Dark grey workspace theme ---------- */

h1,
h2,
h3,
h4,
h5,
label,
.section-subhead,
.upload-col-title strong {
    color: var(--navy);
}

a:hover { color: var(--text-primary); }

code {
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-primary);
    border: 1px solid rgba(255, 255, 255, 0.06);
}

.workbench > details.section,
.workbench > #configurationSection {
    width: min(calc(100% - 48px), var(--container));
    margin: 18px auto;
}

.section,
details.section {
    position: relative;
    overflow: hidden;
    background: var(--panel);
    border-color: var(--border);
    border-radius: var(--radius-lg);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.055),
        inset 0 -1px 0 rgba(0, 0, 0, 0.28),
        0 14px 42px rgba(0, 0, 0, 0.30);
}

details.collapsible > summary {
    color: var(--text-primary);
    background: transparent;
    border: 1px solid var(--line);
    border-left: 3px solid var(--border-strong);
    border-radius: var(--radius);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 8px 14px 8px 32px;
}

details.collapsible > summary:hover {
    border-color: var(--line-strong);
    background: rgba(255, 255, 255, 0.03);
}

details.collapsible > summary > select,
.value-input,
.rgb-value,
.hex-row-compact input,
.stream-table .stream-bg-select,
.stream-table .stream-bg-input,
.bg-select {
    color: var(--ink);
    background: var(--panel-soft);
    border-color: var(--line);
    border-left-color: var(--border-strong);
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.34),
        inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

.btn-xs {
    background: var(--accent-orange);
    border-color: var(--border-strong);
    color: var(--text-primary);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22),
        0 8px 18px rgba(0, 0, 0, 0.18);
}

.btn-xs:hover {
    background: var(--accent-orange);
    border-color: var(--orange-dark);
}

.btn-outline {
    color: var(--text-primary);
    background: var(--panel);
    border-color: var(--line-strong);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08),
        0 6px 14px rgba(0, 0, 0, 0.12);
}

.btn-outline:hover {
    color: var(--text-primary);
    background: var(--panel);
    border-color: var(--orange);
}

.info,
.result,
.upload-card-heading,
.upload-progress,
.file-list-box,
.preview-box {
    color: var(--ink);
    background: var(--panel);
    border-color: var(--border);
}

.info {
    border-left-color: var(--border-strong);
}

.success {
    background: var(--ok-soft);
    border-left-color: var(--border-strong);
    color: var(--text-primary);
}

.error {
    background: var(--err-soft);
    border-left-color: var(--err);
    color: var(--text-primary);
}

.mode-tabs-row,
.auth-tabs-row {
    border-color: var(--line);
}

.mode-tab.left,
.mode-tab.right,
.auth-tab,
.preset-btn,
.color-radio,
.player-tab {
    color: var(--ink);
    background: var(--panel);
    border-color: var(--line);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
}

.mode-tab.left:hover,
.mode-tab.right:hover,
.auth-tab:hover,
.preset-btn:hover:not(.active),
.player-tab:hover {
    color: var(--text-primary);
    background: var(--panel);
    border-color: var(--line-strong);
}

.mode-tab.left.active,
.mode-tab.right.active,
.auth-tab.active,
.preset-btn.active,
.player-tab.active,
.adj-mode.active {
    color: var(--text-primary);
    background: var(--accent-orange);
    border-color: var(--orange);
}

.auth-tabs-row {
    background: var(--bg-sunken);
    overflow: hidden;
}

.auth-tab + .auth-tab {
    border-left-color: var(--line);
}

.chroma-section {
    background: var(--bg-soft);
    border-color: var(--line);
}

.chroma-section h4,
.player-header h4 {
    color: var(--text-primary);
    letter-spacing: 0.12em;
}

.help-text,
.text-muted,
.text-muted-sm,
.stream-meta,
.file-list-item .fmeta,
.preview-box .placeholder,
.preview-box .fname-line {
    color: var(--muted);
}

.color-indicator {
    color: var(--ink);
}

.color-indicator .swatch-box,
.color-preview-compact {
    border-color: #111418;
    box-shadow: 0 0 0 1px var(--line);
}

.hex-row-compact {
    border-top-color: var(--line);
}

.color-radio:has(input:checked) {
    color: #fff;
    border-color: var(--orange);
    box-shadow: none;
}

.stream-table-wrap {
    background: var(--bg-sunken);
    border-color: var(--line);
}

.stream-table th {
    color: var(--text-primary);
    background: var(--panel);
}

.stream-table td {
    border-bottom-color: var(--line-faint);
}

.stream-table tr:hover td {
    background: rgba(255, 255, 255, 0.03);
}

.stream-table .mono,
.stream-meta code,
.stream-table a.mono {
    color: var(--text-primary);
    background: rgba(255, 255, 255, 0.06);
}

.stream-table .copyable {
    color: var(--text-primary);
}

.stream-table .copyable:hover,
.stream-table .copy-btn:hover {
    color: var(--text-primary);
}

.ingest-badge {
    background: var(--bg);
    color: var(--text-primary);
}

.target-badge {
    background: var(--bg);
    color: var(--text-primary);
}

/* The ingest card is the one thing the whole page depends on — operators were
   reading it as just another row and not realising it is the source they have to
   publish to. Give it a heavier accent, a soft ring, and a plain-language note. */
.stream-card.ingest {
    border-color: var(--border-strong);
    box-shadow: none;
}
.stream-card.ingest::before { width: 6px; }
.stream-card.ingest .stream-type-badge.ingest-badge {
    font-size: 12px;
    padding: 4px 11px;
    background: var(--bg);
    color: var(--text-primary);
    box-shadow: none;
}
.sc-ingest-note {
    font-size: 12px;
    line-height: 1.5;
    color: var(--text-primary);
}
.sc-ingest-note strong { color: var(--text-primary); font-weight: 700; }

/* "Point your encoder here" — Server + Stream Key as the card's main content.
   Full values (never ellipsised), big Copy buttons, OBS field names. While the
   ingest isn't live the panel stays highlighted; once Bintu reports it live it
   calms down to the normal card tint. */
.sc-publish {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 14px 18px 14px 22px;
    background: transparent;
    transition: background 0.3s;
}
.stream-card.ingest.is-live .sc-publish { background: var(--bg); }
.sc-publish-head {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}
.sc-publish-step {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--blue);
    color: var(--text-primary);
    font-weight: 700;
    font-size: 14px;
}
.sc-publish-title { font-size: 16px; font-weight: 700; color: var(--text); }
.sc-publish-sub { font-size: 12px; color: var(--text-primary); margin-top: 2px; }
.sc-publish-sub strong { color: var(--text); font-weight: 600; }
.sc-env-tag {
    margin-left: auto;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-primary);
    background: var(--bg);
    box-shadow: none;
    white-space: nowrap;
}
.sc-publish-fields {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
    gap: 12px;
}
.sc-publish-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.sc-publish-label {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-primary);
}
.sc-publish-hint {
    margin-left: 6px;
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
    color: var(--text-primary);
}
.sc-publish-box {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 42px;
    padding: 6px 6px 6px 12px;
    border-radius: var(--radius-lg);
    background: var(--bg-sunken);
    border: 1px solid var(--border-strong);
}
.sc-publish-box .mono {
    flex: 1;
    min-width: 0;
    font-family: var(--font-mono);
    font-size: 14px;
    color: var(--text);
    word-break: break-all;
    -webkit-user-select: all;
    user-select: all;
}
.sc-copy-btn,
.sc-copy-full {
    flex-shrink: 0;
    width: auto;
    margin: 0;
    padding: 7px 12px;
    font-size: 12.5px;
    font-weight: 600;
    white-space: nowrap;
    color: var(--text-primary);
    background: var(--blue);
    border: 1px solid var(--border-strong);
}
.sc-copy-btn:hover,
.sc-copy-full:hover { background: var(--blue-dark); border-color: var(--blue-dark); }
.sc-copy-btn.copied,
.sc-copy-full.copied { background: var(--ok); border-color: var(--border-strong); color: var(--bg); }
.sc-copy-full { padding: 5px 10px; font-size: 12px; background: transparent; color: var(--text-primary); }
.sc-copy-full:hover { color: var(--text-primary); }
.sc-publish-foot { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.sc-publish-foot:empty { display: none; }
.sc-publish-foot-hint { font-size: 12px; color: var(--text-primary); }

/* Setup toolbar (create time only): Targets · Add timecode · Ingest tags on one
   compact row. Hidden once a setup is loaded. */
#configurationSection > #targetCountRow.setup-toolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px 16px;
    padding: 12px 22px;
}
.setup-toolbar .tb-group { display: inline-flex; align-items: center; gap: 8px; }
.setup-toolbar .tb-group > label { margin: 0; white-space: nowrap; }
.setup-toolbar .switch-label { display: inline-flex; align-items: center; gap: 8px; margin: 0; white-space: nowrap; }
.setup-toolbar .tb-sep { width: 1px; height: 22px; background: var(--line-strong); }
#configurationSection > #targetCountRow.setup-toolbar.is-loaded { display: none; }
.setup-toolbar .tb-grow { flex: 1 1 260px; min-width: 0; }
.setup-toolbar .tb-grow > input { flex: 1; min-width: 0; max-width: 460px; margin: 0; }

/* "+ Add output" and its status on the right of the Keyed outputs heading. */
.sc-section-actions { margin-left: auto; display: flex; align-items: center; gap: 12px; }
.sc-section-actions #addTargetStatus { font-size: 12px; }
.sc-section-actions .btn-sm { width: auto; white-space: nowrap; }

/* Non-production environment badge in the page header (hidden on Production). */
.env-badge {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 5px 12px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--bg);
    background: var(--warn);
    box-shadow: none;
    cursor: help;
}
.env-badge::before {
    content: "";
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: currentColor;
}
.env-badge[hidden] { display: none; }
.env-badge.env-dev { background: var(--accent-blue); box-shadow: none; }
.env-badge.env-custom { color: var(--text-primary); background: var(--blue); box-shadow: none; }

/* "Copy setup link" on the ingest card header. */
.sc-link-btn {
    width: auto;
    margin: 0;
    padding: 5px 10px;
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
    color: var(--text-primary);
    background: transparent;
    border: 1px solid var(--border-strong);
}
.sc-link-btn:hover { color: var(--text-primary); background: var(--blue); border-color: var(--blue); }
.sc-link-btn.copied { color: var(--bg); background: var(--ok); border-color: var(--border-strong); }

/* Ingest signal strip — full width under the card header. Green + moving bars
   while receiving, amber pulse while waiting, red-ish when the check fails. */
.sc-signal {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 10px 18px 10px 22px;
    font-size: 13px;
    color: var(--text-primary);
    background: rgba(255, 255, 255, 0.03);
    border-bottom: 1px solid var(--line);
    border-left: 4px solid var(--grey);
    transition: background 0.3s, border-color 0.3s;
}
.sc-signal strong {
    font-size: 13.5px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text);
}
.sc-signal-sub { color: var(--text-primary); }
.sc-signal-age { margin-left: auto; font-size: 12px; color: var(--grey); white-space: nowrap; }

.sc-signal.live {
    background: transparent;
    border-left-color: var(--ok);
    border-bottom-color: var(--accent-blue);
}
.sc-signal.live strong { color: var(--text-primary); }
.sc-signal.idle {
    background: transparent;
    border-left-color: var(--border-strong);
    border-bottom-color: var(--border-strong);
}
.sc-signal.idle strong { color: var(--text-primary); }
/* Check failed: neutral, so it isn't confused with "no signal" (red). */
.sc-signal.error { border-left-color: var(--grey); }
.sc-signal.error strong { color: var(--text-primary); }

/* Moving signal bars (receiving). */
.sc-bars { display: inline-flex; align-items: flex-end; gap: 3px; height: 18px; }
.sc-bars i {
    display: block;
    width: 4px;
    border-radius: 1px;
    background: var(--ok);
    box-shadow: none;
    
}
.sc-bars i:nth-child(1) { height: 40%; animation-delay: -0.9s; }
.sc-bars i:nth-child(2) { height: 70%; animation-delay: -0.6s; }
.sc-bars i:nth-child(3) { height: 100%; animation-delay: -0.3s; }
.sc-bars i:nth-child(4) { height: 60%; animation-delay: 0s; }
@keyframes sc-bar { 0%, 100% { transform: scaleY(0.45); } 50% { transform: scaleY(1); } }
.sc-bars i { transform-origin: bottom; }

/* Pulsing dot (waiting / checking / error). */
.sc-wait-dot {
    position: relative;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--grey);
    flex-shrink: 0;
}
.sc-signal.idle .sc-wait-dot { background: var(--err); }
.sc-signal.error .sc-wait-dot { background: var(--grey); }
.sc-signal.idle .sc-wait-dot::after {
    content: "";
    position: absolute;
    inset: -5px;
    border-radius: 50%;
    border: 2px solid var(--border-strong);
    
}
@keyframes sc-ping { 0% { transform: scale(0.5); opacity: 0.9; } 100% { transform: scale(1.6); opacity: 0; } }

/* The whole card picks up the signal state on its accent bar. */
.stream-card.ingest.is-live { border-color: var(--accent-blue); }
.stream-card.ingest.is-live::before { background: var(--ok); }

@media (prefers-reduced-motion: reduce) {
    .sc-bars i,
.sc-signal.idle .sc-wait-dot::after { animation: none; }
}
@media (max-width: 760px) {
    .sc-signal { padding: 10px 14px 10px 18px; }
    .sc-signal-age { margin-left: 0; width: 100%; }
}

/* One-shot "look here" pulse after a setup is created/loaded. */
.stream-card.ingest.attention { animation: sc-attention 0.9s ease-out 3; }
@keyframes sc-attention {
    0% { box-shadow: none; }
    100% { box-shadow: none; }
}
@media (prefers-reduced-motion: reduce) {
    .stream-card.ingest.attention { animation: none; border-color: var(--blue); }
}

/* ── Target cards ──
   Step 2 heading (mirrors the ingest card's step 1), a background thumbnail so
   outputs can be told apart at a glance, a highlight on whichever card is the
   active switcher source, and quieter secondary actions. */
.sc-section-head {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin: 10px 0 2px;
    padding: 0 4px;
}
.sc-publish-step.out { background: var(--orange); }

.sc-thumb {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 64px;
    height: 36px;
    overflow: hidden;
    border-radius: 4px;
    background: var(--bg-sunken);
    box-shadow: inset 0 0 0 1px var(--line);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.06em;
    color: var(--grey);
}
.sc-thumb img,
.sc-thumb video { width: 100%; height: 100%; object-fit: cover; display: block; }
.sc-thumb.stream {
    color: var(--text-primary);
    background: transparent;
    box-shadow: none;
}

/* Active switcher source: amber while previewing, red on air (same colours as
   the Preview | Live switch). */
.sc-active-tag:empty { display: none; }
.sc-active-tag {
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--text-primary);
    background: var(--warn-soft);
}
.stream-card.is-active { border-color: var(--accent-orange); }
.stream-card.target.is-active::before { background: var(--warn); }
.stream-card.is-onair { border-color: var(--accent-orange); }
.stream-card.target.is-onair::before { background: var(--accent-orange); }
.stream-card.is-onair .sc-active-tag { color: var(--text-primary); background: var(--bg); }

.sc-preview-btn {
    width: auto;
    margin: 0;
    padding: 5px 10px;
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
    color: var(--text-primary);
    background: transparent;
    border: 1px solid var(--line-strong);
}
.sc-preview-btn:hover { color: var(--text-primary); border-color: var(--warn); background: var(--warn-soft); }
.stream-card.is-active .sc-preview-btn { display: none; }

/* Tags Save: ghost until the field is edited, then the normal orange action. */
.stream-cards .tag-save-btn:not(.dirty) {
    color: var(--text-primary);
    background: transparent;
    border-color: var(--line-strong);
}
.stream-cards .tag-save-btn:not(.dirty):hover { color: var(--text); border-color: var(--grey); background: transparent; }

.stream-cards .target-del-btn.icon-only { width: 30px; height: 30px; font-size: 13px; }

/* ── Target cards: Dark Neutral Studio pass ──
   Graphite card, neutral structure, orange only for the active card and for
   actions (hover / dirty Save / input edge), green only for running status. */
.stream-cards .stream-card.target {
    background: var(--panel);
    border-color: var(--line);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.045), 0 10px 28px rgba(0, 0, 0, 0.22);
}
.stream-cards .stream-card.target::before { width: 3px; background: var(--line-strong); }
.stream-cards .stream-card.target .sc-head {
    background: rgba(255, 255, 255, 0.02);
    border-bottom-color: var(--line);
}
.stream-cards .target-badge {
    font-size: 12px;
    padding: 4px 10px;
    color: var(--text);
    background: rgba(255, 255, 255, 0.06);
    box-shadow: inset 0 0 0 1px var(--line-strong);
}

/* Active source = the selected mode (orange in Preview, red On air), matching
   the Preview | Live switcher. */
.stream-cards .stream-card.target.is-active { border-color: var(--accent-orange); }
.stream-cards .stream-card.target.is-active::before { background: var(--orange); }
.stream-cards .stream-card.is-active .sc-active-tag { color: var(--text-primary); background: var(--bg); }
.stream-cards .stream-card.target.is-onair { border-color: var(--accent-orange); }
.stream-cards .stream-card.target.is-onair::before { background: var(--accent-orange); }
.stream-cards .stream-card.is-onair .sc-active-tag { color: var(--text-primary); background: var(--bg); }
/* "Needs Apply": background/overlay edited but not yet sent to the output.
   Small orange dot + label (guideline dirty marker), and an orange edge. */
.sc-dirty-tag { display: none; }
.stream-card.needs-apply .sc-dirty-tag {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--text-primary);
    background: var(--bg);
    box-shadow: none;
}
.stream-card.needs-apply .sc-dirty-tag::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--orange);
}
.stream-cards .stream-card.target.needs-apply:not(.is-active):not(.is-onair)::before { background: var(--orange); }

/* Keep the destructive ✕ apart from the dashboard link. */
.sc-actions-sep { width: 1px; height: 20px; margin: 0 4px; background: var(--line-strong); }

.stream-cards .sc-preview-btn:hover { color: var(--text-primary); border-color: var(--orange); background: var(--bg); }

/* Body: thin divider rhythm, labels muted + precise, hints as plain text. */
.stream-cards .sc-body {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr) minmax(0, 0.85fr) minmax(0, 1.3fr);
    gap: 10px 22px;
    padding: 12px 18px 14px;
}
.stream-cards .asset-label { font-size: 12px; letter-spacing: 0.1em; color: var(--muted); }
.stream-cards .asset-hint {
    margin-left: 6px;
    padding: 0;
    border: 0;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: var(--grey);
    opacity: 0.8;
}

/* Inputs: recessed, neutral border, orange left edge (the guideline input). */
.stream-cards .bg-combo-field,
.stream-cards .bg-combo.ov-combo .bg-combo-field,
.stream-cards .sc-body .tag-edit-row .per-tag-input {
    background: var(--panel-soft);
    border: 1px solid var(--line);
    border-left: 3px solid var(--border-strong);
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.34);
}
.stream-cards .bg-combo.ov-combo .bg-combo-field { border-left-color: var(--line-strong); }
.stream-cards .bg-combo-field:focus-within,
.stream-cards .sc-body .tag-edit-row .per-tag-input:focus {
    border-color: var(--orange);
    box-shadow: none;
    outline: none;
}

/* Transcodes: one row. Running renditions are ticked in orange (a selected /
   active toggle, same as the create-mode chips) with a ✕ in the corner to
   remove; the rest are neutral tap-to-add actions. Green stays reserved for
   operational status (the ingest signal strip). */
.stream-cards .tc-chip-box { gap: 8px; padding-top: 4px; }
.stream-cards .tc-chip,
.stream-cards .tc-chip.on {
    position: relative;
    color: var(--text-primary);
    background: var(--panel);
    border-color: var(--line-strong);
    box-shadow: none;
}
.stream-cards .tc-chip:hover { color: var(--text-primary); border-color: var(--orange); }
.stream-cards .tc-chip.on.running {
    color: var(--text);
    background: var(--bg);
    border-color: var(--orange);
    box-shadow: none;
    cursor: default;
}
.stream-cards .tc-chip.on.running .tc-chip-res { color: var(--text-primary); }
.stream-cards .tc-chip.on.running:hover { border-color: var(--orange-dark); }
.tc-chip-x {
    position: absolute;
    top: -7px;
    right: -7px;
    width: 18px;
    height: 18px;
    margin: 0;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    line-height: 1;
    color: var(--text-primary);
    background: var(--panel);
    border: 1px solid var(--line-strong);
    border-radius: 50%;
    cursor: pointer;
}
.tc-chip-x:hover { color: var(--text-primary); background: var(--err); border-color: var(--err); }
.stream-cards .tc-chip.on.running.removing {
    opacity: 0.6;
    border-style: dashed;
    cursor: progress;
}
.stream-cards .tc-chip.on.running.removing .tc-chip-res { color: var(--text-primary); text-decoration: line-through; }
.tc-status:empty { display: none; }
.tc-status { font-size: 12px; line-height: 1.4; color: var(--text-primary); }
.tc-status.ok { color: var(--text-primary); }
.tc-status.warn { color: var(--text-primary); }
.tc-status.error { color: var(--text-primary); }
.stream-cards .tc-more { border: 0; padding: 2px 0; color: var(--muted); }
.stream-cards .tc-more:hover { color: var(--text-primary); }

@media (max-width: 1180px) {
    .stream-cards .sc-body { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 680px) {
    .stream-cards .sc-body { grid-template-columns: 1fr; }
}

/* Target stream names: present but deliberately quiet, so they don't read as a
   second place to publish. */
.sc-chip.sc-chip-output { opacity: 0.75; }

/* "Where do I publish? →" — jumps to the ingest card from encoder hints. */
.ingest-jump {
    width: auto;
    margin: 6px 0 0;
    padding: 0;
    background: none;
    border: 0;
    color: var(--text-primary);
    font-size: 12.5px;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.ingest-jump:hover { background: none; color: var(--text-primary); }
.source-status .ingest-jump { margin: 0 0 0 4px; font-size: inherit; }

@media (max-width: 760px) {
    .sc-publish { padding: 12px 14px 12px 18px; }
    .sc-publish-fields { grid-template-columns: 1fr; }
    .sc-env-tag { margin-left: 0; }
    .sc-copy-btn,
.sc-copy-full,
.ingest-jump,
.sc-preview-btn,
.sc-link-btn { width: auto; }
    .tc-chip-x { width: 18px; }
}

/* Ingest row — blue is the structural/source cue in the dark workbench theme */
.stream-table tr.ingest-row td {
    background: var(--bg);
    border-bottom: 2px solid var(--border-strong);
}
.stream-table tr.ingest-row:hover td {
    background: var(--bg);
}
.stream-table tr.ingest-row td:first-child {
    box-shadow: inset 3px 0 0 var(--blue);
}
.target-del-btn {
    color: var(--muted);
    border-color: var(--line-strong);
}
.target-del-btn:hover {
    color: var(--text-primary);
    background: var(--err);
    border-color: var(--err);
}

.upload-area {
    color: var(--muted);
    background: var(--bg-sunken);
    border-color: var(--line-strong);
}

.upload-area:hover,
.upload-area.drag-over {
    color: var(--text-primary);
    background: var(--panel);
    border-color: var(--orange);
}

.file-list-item {
    color: var(--ink);
}

.file-list-item:hover,
.file-list-item.selected {
    color: var(--text-primary);
    background: rgba(255, 255, 255, 0.05);
    border-color: var(--orange);
}

#configurationSection {
    background: transparent;
}

#configurationSection > h3,
#configurationSection > h4,
#configurationSection > .section-subhead,
#configurationSection > #targetCountRow,
#configurationSection > #streamInfo,
#configurationSection > #createPane,
#configurationSection > #reusePane,
#configurationSection > .mode-tabs-row {
    background: var(--panel);
    border-color: var(--border);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.055),
        inset 0 -1px 0 rgba(0, 0, 0, 0.28),
        0 14px 42px rgba(0, 0, 0, 0.30);
}

#configurationSection > h3 {
    border-left: 3px solid var(--border-strong);
}

#workbenchBlock {
    width: min(calc(100% - 96px), var(--container));
    margin: 18px auto 30px;
}

.workbench-header {
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: 0 2px;
    margin: 0 0 8px;
    max-width: none;
    width: 100%;
}

.workbench-header .eyebrow {
    color: var(--text-primary);
    letter-spacing: 0.16em;
}

.workbench-header h3 {
    color: var(--text-primary);
    font-size: 21px;
}

.workbench-status {
    flex: 0 1 560px;
    min-width: 220px;
    max-width: 100%;
    color: var(--text-primary);
    background: var(--bg);
    border-color: var(--border-strong);
    border-left: 3px solid var(--border-strong);
    border-radius: var(--radius);
    overflow-wrap: anywhere;
    text-align: right;
    white-space: normal;
}

.workbench-layout {
    grid-template-columns: minmax(720px, 1fr) minmax(390px, 440px);
    gap: 18px;
    max-width: none;
    width: 100%;
    margin: 0;
}

.workbench-preview,
.workbench-controls {
    position: relative;
    overflow: hidden;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.055),
        inset 0 -1px 0 rgba(0, 0, 0, 0.36),
        0 22px 64px rgba(0, 0, 0, 0.36);
}

.workbench-preview {
    position: static;
    border-top: 2px solid var(--border-strong);
    padding: 16px;
}

.workbench-controls {
    border-top: 2px solid var(--border-strong);
    position: sticky;
    top: 92px;
    max-height: calc(100vh - 116px);
    overflow: auto;
    padding: 18px;
    scrollbar-color: var(--border-strong) var(--border);
}

.workbench-controls .chroma-section {
    background: transparent;
    border: 0;
    border-top: 1px solid var(--border);
    border-radius: 0;
    box-shadow: none;
    margin: 0;
    padding: 16px 0 0;
}

.workbench-controls .chroma-section:first-child {
    border-top: 0;
    padding-top: 0;
}

.workbench-controls > .grid-2col {
    gap: 0;
}

.workbench-controls > .grid-2col .chroma-section + .chroma-section {
    margin-top: 16px;
}

.workbench-controls > .action-row {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 -12px 26px rgba(0, 0, 0, 0.18);
}

.player-tabs-row {
    gap: 8px;
}

.player-tab {
    min-height: 34px;
    background: var(--panel-soft);
    border-color: var(--border-strong);
}

.player-stage {
    background: #050607 !important;
    border-color: var(--border);
    border-radius: var(--radius);
    box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.62),
        inset 0 0 0 1px rgba(255, 255, 255, 0.04),
        0 1px 0 rgba(255, 255, 255, 0.04),
        0 12px 30px rgba(0, 0, 0, 0.24);
    transition: border-color 0.15s, box-shadow 0.15s;
}

/* Tally border on the stage itself — amber while previewing, red while
   on-air — so mode is readable from the video box, not just the switch. */
#workbenchPreview.tally-preview .player-stage {
    border-color: var(--border-strong);
    box-shadow: none;
}
/* Caption strip pinned to the top of the canvas stage — reminds you this is
   the local preview, not the real on-air output. Preview-only: canvasPane is
   hidden entirely while Live is active, so no extra JS toggle is needed. */
.preview-mode-hint {
    position: absolute;
    top: 0; left: 0; right: 0;
    z-index: 2;
    padding: 6px 12px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-align: center;
    color: var(--text-primary);
    background: var(--bg);
    border-bottom: 1px solid var(--border-strong);
}
.preview-mode-hint strong { color: var(--text-primary); }

#workbenchPreview.tally-live .player-stage {
    border-color: var(--border-strong);
    box-shadow: none;
}

#previewCanvas {
    background: #050607;
}

.player-placeholder {
    color: rgba(255, 255, 255, 0.62);
}

.source-inputs {
    margin-top: 12px;
}

.source-row-label {
    color: var(--muted) !important;
}

.source-upload,
.stream-group {
    color: var(--ink) !important;
    background: var(--panel-soft) !important;
    border-color: var(--border-strong) !important;
}

.source-upload:hover {
    color: var(--text-primary) !important;
    border-color: var(--orange) !important;
    background: var(--panel) !important;
}

.stream-group input {
    color: var(--ink) !important;
    background: transparent !important;
}

.stream-group input::placeholder {
    color: var(--text-muted) !important;
}

.stream-group-btn {
    color: var(--text-primary) !important;
    background: var(--panel) !important;
    border-left-color: var(--line) !important;
}

.stream-group-btn:hover {
    background: var(--orange) !important;
}

.source-status,
.scrub-time {
    color: var(--muted) !important;
}

#fgMiniPlayer {
    border-color: var(--line) !important;
}

#despillPreview,
#eqPreview,
.ffmpeg-cmd {
    color: var(--text-primary) !important;
    background: var(--panel-soft) !important;
    border-color: var(--border-strong) !important;
}

#applyModeHint {
    color: var(--muted) !important;
}

.switch-label {
    color: var(--ink);
}

.adj-status-row {
    color: var(--muted);
}

.page-version {
    color: var(--text-primary);
}

@media (max-width: 1180px) {
    .workbench-controls {
        position: static;
        max-height: none;
        overflow: visible;
    }
}

@media (max-width: 760px) {
    .workbench > details.section,
.workbench > #configurationSection,
#workbenchBlock {
        width: min(calc(100% - 24px), var(--container));
    }

    

    .workbench-header {
        display: block;
    }

    .workbench-status {
        display: inline-block;
        margin-top: 10px;
        text-align: left;
        white-space: normal;
    }
}

/* ======== moved from chroma-setup-tuner.html inline <style> ======== */
.ingest-info-grid {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 4px 16px;
    align-items: baseline;
    font-size: 12px;
}
.ingest-info-grid .lbl { color: var(--text-primary); white-space: nowrap; }
.ingest-info-grid code { font-size: 12px; word-break: break-all; }
.ffmpeg-cmd {
    background: rgba(0,0,0,0.04);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 10px 12px;
    font: 12px var(--font-mono);
    white-space: pre-wrap;
    word-break: break-all;
    color: var(--text);
    line-height: 1.6;
    margin: 0;
}
.bg-selector-grid {
    display: grid;
    grid-template-columns: 70px 1fr;
    gap: 6px 10px;
    align-items: center;
    margin-top: 8px;
}
.bg-selector-grid .lbl { font-size: 12px; color: var(--text-primary); }

/* ── Source inputs (FG / BG) ── */
/* Source pickers as small cards (FG / BG / OV) in a 3-column grid — equal
   width (1fr each) and equal height (stretch), using the full preview
   width. Each card groups its controls + status (+ frame scrubber). */
.source-inputs {
    display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px;
    margin-top: 8px; padding: 0 2px; align-items: stretch;
}
.source-card {
    background: var(--surface-2); border: 1px solid var(--border);
    border-radius: 8px; padding: 7px 11px; transition: border-color .14s; min-width: 0;
}
.source-card:hover { border-color: var(--border-strong); }
.source-card .source-row { gap: 2px 10px; }
.source-card .source-row + .source-row { margin-top: 5px; }
@media (max-width: 900px) { .source-inputs { grid-template-columns: 1fr; } }
.source-row { display: grid; grid-template-columns: 28px 1fr; gap: 3px 8px; }
.source-row-label {
    font-size: 12px; font-weight: 700; color: var(--text-primary);
    text-transform: uppercase; letter-spacing: .07em;
    padding-top: 6px; line-height: 1; white-space: nowrap;
}
.source-controls { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.source-upload {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 4px 10px; border: 1px solid var(--border);
    border-radius: 4px; font-size: 12px; font-weight: 600;
    color: var(--navy); cursor: pointer; white-space: nowrap;
    background: var(--panel); transition: background .15s,border-color .15s; line-height: 1.4;
}
.source-upload:hover { background: var(--surface-2); border-color: var(--blue); }
/* Primary FG source: the ingest stream */
.source-pill {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px 11px; border: 1px solid var(--border-strong);
    border-radius: 4px; font-size: 12px; font-weight: 700;
    color: var(--text-primary); cursor: pointer; white-space: nowrap;
    background: transparent; line-height: 1.4; font-family: var(--font-body);
    transition: background .15s,color .15s,border-color .15s;
}
.source-pill:hover { background: var(--orange); color: var(--text-primary); }
.stream-group {
    display: flex; align-items: stretch;
    border: 1px solid var(--border); border-radius: 4px;
    overflow: hidden; flex: 1; min-width: 120px; max-width: 260px; background: var(--panel);
}
.stream-group input {
    border: none; outline: none; padding: 4px 8px; font-size: 12px;
    flex: 1; min-width: 0; color: var(--text); background: transparent;
}
.stream-group input::placeholder { color: var(--text-muted); font-style: italic; }
.stream-group-btn {
    border: none; border-left: 1px solid var(--border);
    background: var(--navy); color: var(--text-primary);
    padding: 0 10px; cursor: pointer; font-size: 12px; line-height: 1;
    transition: background .15s; white-space: nowrap;
}
.stream-group-btn:hover { background: var(--blue); }
.source-select {
    border: 1px solid var(--border); border-radius: 4px;
    padding: 4px 6px; font-size: 12px; color: var(--text);
    max-width: 150px; flex: 1;
}
.source-status { grid-column: 2; font-size: 12px; color: var(--text-primary); margin-top: 1px; min-height: 0; }
.scrub-row { display: flex; align-items: center; gap: 6px; margin-top: 2px; }
.scrub-row input[type=range] { flex: 1; }
.scrub-time { font-size: 12px; color: var(--text-primary); white-space: nowrap; min-width: 38px; }

/* Force NanoPlayer video to fill container */
#playerDiv,
#playerDiv > div,
#playerDiv > div > div { width: 100% !important; height: 100% !important; }
#playerDiv video { width: 100% !important; height: 100% !important; object-fit: contain; }
#fgMiniPlayer,
#fgMiniPlayer > div,
#fgMiniPlayer > div > div { width: 100% !important; height: 100% !important; }
#fgMiniPlayer video { width: 100% !important; height: 100% !important; object-fit: contain; }

/* Sync badge on Live bus label */
.tab-sync-dot {
    display: inline-block; width: 7px; height: 7px; border-radius: 50%;
    background: var(--accent-green); margin-left: 5px; vertical-align: middle;
    box-shadow: none;
}
.tab-sync-dot.dirty { background: var(--orange); box-shadow: none; }

/* ── Broadcast switcher, single row: a Preview|Live mode switch + ONE
      shared strip of source tabs. Active source is amber while
      previewing, red when on-air — vision-mixer tally colours. ── */
.switcher {
    display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px;
    padding: 8px; border-radius: 4px;
    background: var(--surface-2); border: 1px solid var(--border);
}
.switcher-bus {
    display: flex; align-items: center; gap: 10px; min-width: 0; flex-wrap: wrap;
    padding: 5px 8px; border-radius: 4px; background: rgba(0,0,0,0.18);
}
/* Preview | Live segmented mode switch */
.mode-toggle {
    display: flex; flex-shrink: 0; border: 1px solid var(--border);
    border-radius: 4px; overflow: hidden; background: var(--surface-3);
}
.mode-seg {
    display: inline-flex; align-items: center; gap: 6px;
    font-family: var(--font-display); font-size: 12px; font-weight: 700;
    text-transform: uppercase; letter-spacing: .06em; white-space: nowrap;
    padding: 7px 14px; border: 0; margin: 0; cursor: pointer; line-height: 1.2;
    background: transparent; color: var(--text-primary);
    transition: background .14s, color .14s;
}
.mode-seg + .mode-seg { border-left: 1px solid var(--border); }
.mode-seg .seg-dot {
    width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
    background: var(--surface-3); transition: background .15s, box-shadow .15s;
}
/* Amber = previewing, red = on-air */
#tabPreview.active { background: var(--bg); color: var(--text-primary); }
#tabPreview.active .seg-dot { background: var(--orange); box-shadow: none; }
#tabLive.active { background: var(--bg); color: var(--text-primary); }
#tabLive.active .seg-dot { background: var(--accent-orange); box-shadow: none; }

.bus-btns { display: flex; gap: 6px; flex-wrap: wrap; flex: 1; min-width: 0; }
.src-btn {
    font-family: var(--font-body); font-size: 12px; font-weight: 600;
    padding: 6px 13px; border-radius: 4px; cursor: pointer; white-space: nowrap;
    border: 1px solid var(--border); background: var(--surface-3);
    color: var(--text-primary); line-height: 1.2;
    transition: background .14s, color .14s, border-color .14s, box-shadow .14s;
}
.src-btn:hover { color: var(--text); border-color: var(--border-strong); }
/* The one active source, coloured by the current mode. */
.switcher.mode-preview .src-btn.active {
    background: var(--bg); border-color: var(--orange);
    color: var(--text-primary); box-shadow: none;
}
.switcher.mode-live .src-btn.active {
    background: var(--bg); border-color: var(--accent-orange);
    color: var(--text-primary); box-shadow: none;
}
/* Output links at the right end of the row */
.switcher-outputs { display: flex; gap: 6px; flex-shrink: 0; margin-left: auto; }
.switcher-outputs .bus-output { white-space: nowrap; }

/* ── Per-target overlay control (enable switch · file · adjust) ── */
.ov-cell { display: flex; align-items: center; gap: 8px 10px; flex-wrap: wrap; }
.ov-cell .ov-enable { font-size: 12px; gap: 6px; }
.ov-cell .ov-enable span { color: var(--text-primary); }
.ov-cell.ov-off .ov-enable span { color: var(--text-primary); }
.ov-cell .ov-file-select { width: 100%; max-width: 190px; flex: 1 1 150px; transition: opacity .15s; }
.ov-cell.ov-off .ov-file-select { opacity: .5; }
.ov-adjust-btn {
    display: inline-flex; align-items: center; gap: 7px; width: fit-content; flex: 0 0 auto;
    font-size: 12px; padding: 5px 13px; border-radius: 4px; cursor: pointer;
    border: 1px solid var(--border); background: transparent;
    color: var(--text-primary); white-space: nowrap; font-weight: 600;
    transition: background .15s,color .15s,border-color .15s,box-shadow .15s;
}
.ov-adjust-btn:hover {
    border-color: var(--orange); color: var(--text-primary);
    background: var(--bg);
}
.ov-adjust-btn .chev { font-size: 12px; opacity: .75; transition: transform .2s; }
.ov-adjust-btn[aria-expanded="true"] .chev { transform: rotate(180deg); }
/* ── Post-create (loaded) stream cards ──
   One card per stream (ingest + each target) replaces the old wide
   table. A compact header carries identity (badge + copyable ID/key/RTMP
   chips + actions); the editable assets sit in a 2-col grid below. An
   accent bar on the left marks the type (blue = ingest, orange = target). */
.stream-cards { display: flex; flex-direction: column; gap: 10px; margin-bottom: 12px; max-width: 1460px; }
.stream-card {
    position: relative; border: 1px solid var(--border);
    border-radius: 4px; background: var(--surface-2);
    overflow: hidden; transition: border-color .15s, box-shadow .15s;
}
.stream-card::before {
    content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
    background: var(--orange);
}
.stream-card.ingest::before { background: var(--blue); }
.stream-card:hover { border-color: var(--border-strong); box-shadow: 0 6px 22px rgba(0,0,0,0.28); }

.sc-head {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 7px 14px 7px 18px; border-bottom: 1px solid var(--border);
}
.stream-card.ingest .sc-head { background: transparent; }
.stream-card.target .sc-head { background: transparent; }

.sc-ids { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; flex: 0 1 auto; min-width: 0; }
.sc-chip {
    display: inline-flex; align-items: center; gap: 6px; min-width: 0; max-width: 100%;
    padding: 3px 5px 3px 9px; border-radius: 8px;
    background: var(--surface-3); border: 1px solid var(--border);
}
.sc-chip-label {
    font-size: 12px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
    color: var(--text-primary); flex-shrink: 0;
}
.sc-chip .mono {
    font-family: var(--font-mono); font-size: 12px;
    color: var(--text); background: transparent; padding: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
    -webkit-user-select: all; user-select: all;
}
.sc-chip .muted { color: var(--text-primary); font-size: 12px; }
/* Inline ingest tags — styled as a chip box so it lines up with the
   ID/Key/RTMP chips: bordered container, label inside, transparent input,
   Save at the right (like the chips' copy button). */
.sc-head-tags {
    display: flex; align-items: center; gap: 7px; flex: 1 1 240px; min-width: 170px;
    padding: 2px 4px 2px 9px; border-radius: 8px;
    background: var(--surface-3); border: 1px solid var(--border);
}
.sc-head-tags:focus-within { border-color: var(--orange); }
.sc-head-tags .asset-label { flex-shrink: 0; }
.sc-head-tags .per-tag-input {
    flex: 1; min-width: 0; height: auto; margin: 0; padding: 2px 0;
    background: transparent; border: 0; color: var(--text); font-size: 12px;
}
.sc-head-tags .per-tag-input:focus { outline: none; box-shadow: none; }
.sc-head-tags .tag-save-btn { flex-shrink: 0; }
.sc-head-tags .tag-save-status:empty { display: none; }
.sc-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-shrink: 0; }
/* copy + dashboard buttons were scoped to .stream-table — restyle for cards */
.stream-cards .copy-btn {
    background: transparent; color: var(--text-primary); border: 0;
    padding: 0 4px; margin: 0; font-size: 13px; cursor: pointer; line-height: 1;
    flex-shrink: 0; transition: color .15s;
}
.stream-cards .copy-btn:hover { color: var(--text-primary); }
.stream-cards .dash-link {
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; font-size: 14px; line-height: 1; text-decoration: none;
    color: var(--text-primary); border: 1px solid var(--border);
    border-radius: 4px; transition: color .15s, background .15s, border-color .15s;
}
.stream-cards .dash-link:hover {
    color: var(--orange); border-color: var(--orange);
    background: var(--bg);
}

/* All four asset fields on one row, equal-width columns, uniform sizing.
   The overlay Position & size panel spans the full row on its own line. */
.sc-body {
    display: grid; grid-template-columns: repeat(4, minmax(0,1fr));
    gap: 8px 20px; padding: 9px 18px 11px; align-items: start;
}
.sc-body-ingest { grid-template-columns: 1fr; max-width: 560px; }
.sc-body .asset-field {
    display: flex; flex-direction: column; gap: 3px; align-items: stretch; min-width: 0;
}
.sc-body .asset-field > select,
.sc-body .asset-field > input { width: 100%; margin: 0; }
/* One consistent control height across Background / Overlay / Tags. */
.sc-body .asset-field > input,
.sc-body .asset-field > select,
.sc-body .tag-edit-row .per-tag-input {
    height: 34px; box-sizing: border-box; font-size: 12px;
}
.sc-body .asset-field > .tc-chips { margin-top: 1px; }

/* ── Combobox (Background + Overlay): one field (type any value) + a ▾ that
      opens a searchable, non-clipping asset menu. Input and toggle live in
      a flex "field" so the arrow can never escape the box. ── */
.bg-combo { position: relative; width: 100%; }
.sc-body .asset-field > .bg-combo { width: 100%; }
.bg-combo-field {
    display: flex; align-items: stretch; width: 100%; height: 34px; box-sizing: border-box;
    border: 1px solid var(--border-strong); border-radius: 4px; overflow: hidden;
    background: var(--surface-2); transition: box-shadow .14s, border-color .14s;
}
/* Overlay combo is secondary → neutral border (background stays orange/primary). */
.bg-combo.ov-combo .bg-combo-field { border-color: var(--border); }
.bg-combo-field:focus-within { border-color: var(--orange); box-shadow: none; }
/* Hard resets so the global input{} / button{} base styles in
   setup-brand.css don't turn these into separate bordered boxes. */
.bg-combo-input {
    flex: 1 1 auto; width: auto !important; min-width: 0; height: 100%;
    border: 0 !important; border-radius: 0 !important; outline: none;
    margin: 0 !important; padding: 0 8px !important; background: transparent !important;
    font-size: 12px; color: var(--text);
}
.bg-combo-input::placeholder { color: var(--text-muted); }
.bg-combo-toggle {
    flex: 0 0 30px; width: 30px; height: 100%; margin: 0 !important; padding: 0 !important;
    border: 0 !important; border-left: 1px solid var(--border) !important;
    border-radius: 0 !important; background: transparent !important; box-shadow: none !important;
    color: var(--text-primary); cursor: pointer; font-size: 12px; line-height: 1;
    transition: color .14s, background .14s;
}
.bg-combo-toggle:hover { color: var(--text-primary) !important; background: var(--bg) !important; }
/* position:fixed → not clipped by the card's overflow:hidden. JS sets left/top/width. */
.bg-combo-menu {
    position: fixed; z-index: 120; margin: 0; padding: 4px; list-style: none;
    max-height: 240px; overflow-y: auto;
    background: var(--surface-2); border: 1px solid var(--border);
    border-radius: 8px; box-shadow: 0 10px 28px rgba(0,0,0,0.45);
}
.bg-combo-item {
    padding: 6px 9px; border-radius: 4px; font-size: 12px; color: var(--text);
    cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bg-combo-item:hover,
.bg-combo-item.active { background: var(--bg); color: var(--text-primary); }
.bg-combo-item.bg-combo-none { color: var(--text-primary); font-style: italic; }
.bg-combo-empty { padding: 7px 9px; font-size: 12px; color: var(--text-primary); line-height: 1.4; }
/* In the create table the combo lives in a td — keep the field at row height. */
.stream-table .bg-combo-field { height: 33px; }
/* Preview source rows: the injected combobox fills the row (aligns its
   width with the FG stream input) rather than capping short. */
.preview-combo-slot { display: flex; flex: 1 1 auto; min-width: 140px; }
.preview-combo-slot .bg-combo { width: 100%; }
.source-controls .bg-combo-field { height: 32px; }

/* Overlay section: X and Y side by side (2 columns), Scale spans the full
   width on its own row. Compact label/value so the slider stays wide. */
#overlaySection .overlay-controls-grid { grid-template-columns: 1fr 1fr !important; max-width: none; gap: 10px 22px; }
#overlaySection .overlay-controls-grid .ov-ctrl { grid-template-columns: 42px 56px 1fr !important; gap: 0 10px; align-items: center; }
#overlaySection .overlay-controls-grid .ov-ctrl .param-slider { min-width: 0; width: 100%; }
/* Collapse to 2 columns, then 1, as the viewport narrows. */
@media (max-width: 1180px) { .sc-body { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 680px) { .sc-body { grid-template-columns: 1fr; } }
.asset-label {
    font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .08em;
    color: var(--text-primary);
}
.asset-hint {
    font-size: 12px; font-weight: 700; letter-spacing: .05em;
    color: var(--text-primary); border: 1px solid var(--border-strong);
    border-radius: 4px; padding: 0 3px; margin-left: 4px;
}
.overlay-panel-row td { padding-top: 0; padding-bottom: 0; white-space: normal; }
.overlay-panel {
    margin: 6px 0 10px;
    padding: 14px 16px 12px;
    background: transparent;
    border: 1px solid var(--border-strong);
    border-top: 2px solid var(--border-strong);
    border-radius: 8px;
}
.overlay-header-row {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    margin-bottom: 12px; padding-bottom: 11px;
    border-bottom: 1px solid var(--border-strong);
}
.overlay-controls-grid {
    display: grid; grid-template-columns: repeat(3,1fr); gap: 8px 16px; margin-bottom: 8px;
}
.ov-ctrl { display: flex; flex-direction: column; gap: 1px; }
.ov-ctrl .slider-header { margin-bottom: 1px; }
.ov-ctrl .param-slider { margin-top: 1px; }
.ov-flip-row {
    display: flex; flex-direction: row; gap: 14px; align-items: center;
    padding-top: 18px;
}
.overlay-presets-row {
    display: flex; gap: 5px; align-items: center; flex-wrap: wrap;
}

/* ── Preview overlay position/size: compact single-line control rows ── */
#ovControlsRow .ov-grid {
    display: grid; grid-template-columns: 1fr 1fr; gap: 8px 18px; padding-top: 2px;
}
#ovControlsRow .ov-ctrl {
    display: grid; grid-template-columns: 34px minmax(64px,auto) 1fr;
    align-items: center; gap: 0 9px;
}
#ovControlsRow .ov-ctrl .slider-header { display: contents; }
#ovControlsRow .ov-ctrl .slider-header label {
    font-size: 12px; font-weight: 600; color: var(--text-primary); white-space: nowrap;
}
#ovControlsRow .ov-ctrl .value-input { width: 64px; min-width: 0; padding: 3px 6px; }
#ovControlsRow .ov-ctrl .param-slider { margin: 0; flex: 1; min-width: 0; }
#ovControlsRow .ov-ctrl > div:last-child { display: flex; align-items: center; gap: 6px; min-width: 0; }
#ovPresetsRow .overlay-presets-row { padding-top: 2px; }

/* ── Source rows (FG/BG/OV): one consistent control height, aligned ── */
.source-controls { gap: 6px; }
.source-controls input,
.source-controls select { margin-bottom: 0; }
.source-controls .source-pill,
.source-controls .source-upload,
.source-controls .source-select,
.source-controls .stream-group,
.source-controls .btn-sm {
    height: 32px; box-sizing: border-box; margin: 0; font-size: 12px;
}
.source-controls .source-pill,
.source-controls .source-upload { display: inline-flex; align-items: center; justify-content: center; padding: 0 14px; }
.source-controls .source-select { padding: 0 10px; max-width: 210px; flex: 0 0 210px; }
.source-controls .stream-group { max-width: none; flex: 1 1 auto; min-width: 140px; }
.source-controls .stream-group input { height: 100%; margin: 0; padding: 0 10px; font-size: 12px; }
.source-controls .stream-group-btn { padding: 0 13px; font-size: 13px; }
.source-controls .btn-sm { padding: 0 10px; display: inline-flex; align-items: center; }

/* ── Bottom action row: align select height with buttons ── */
.action-row #previewEngineSelect { height: 34px; padding: 0 8px; }

/* ── Per-target overlay panel: X|Y and W|H side by side, compact rows ── */
/* Cap width so the full-width reuse/dashboard panel stays as contained as
   the creation panel (which lives in a narrower column). */
.overlay-controls-grid {
    grid-template-columns: 1fr 1fr !important; gap: 8px 20px !important;
    max-width: 860px;
}
.overlay-header-row { max-width: 860px; }
.overlay-controls-grid .ov-ctrl {
    display: grid !important; flex-direction: row;
    grid-template-columns: 74px minmax(54px,auto) 1fr;
    align-items: center; gap: 0 8px;
}
.overlay-controls-grid .ov-ctrl .slider-header { display: contents; }
.overlay-controls-grid .ov-ctrl .slider-header label {
    font-size: 12px; font-weight: 600; text-align: left;
    color: var(--text-primary); white-space: nowrap; min-width: 0;
}
.overlay-controls-grid .ov-ctrl .value-input { width: 54px; min-width: 0; padding: 3px 6px; }
.overlay-controls-grid .ov-ctrl .param-slider { margin: 0; flex: 1; min-width: 0; }
.overlay-controls-grid .ov-ctrl > div:last-child {
    display: flex; align-items: center; gap: 6px; min-width: 0;
}

/* ── Per-target tags + transcoding in the output target cards ── */
.per-tag-input {
    width: 100%; box-sizing: border-box; padding: 5px 8px; font-size: 12px;
    border: 1px solid var(--border); border-radius: 4px;
    background: var(--surface-2); color: var(--text);
}
.per-tag-input:focus { outline: none; border-color: var(--orange); }

/* Editable tags row (loaded ingest/target list): input + Save button. */
.tag-edit-row { display: flex; gap: 6px; align-items: center; }
.tag-edit-row .per-tag-input { flex: 1; min-width: 0; }
.tag-save-btn { flex-shrink: 0; white-space: nowrap; }
.tag-save-status { font-size: 12px; color: var(--text-primary); }

/* Transcoding profiles as toggle chips (resolution + bitrate). */
.tc-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.tc-chip {
    display: inline-flex; flex-direction: column; align-items: center; line-height: 1.12;
    padding: 4px 11px; border-radius: 4px; cursor: pointer; font-family: inherit;
    border: 1px solid var(--border); background: var(--surface-2);
    color: var(--text-primary); transition: background .14s,color .14s,border-color .14s,box-shadow .14s;
}
.tc-chip:hover { border-color: var(--orange); color: var(--text); }
.tc-chip .tc-chip-res { font-size: 12px; font-weight: 700; }
.tc-chip .tc-chip-br { font-size: 12px; font-weight: 600; opacity: .8; letter-spacing: .02em; }
.tc-chip.on {
    border-color: var(--orange); background: var(--bg);
    color: var(--text-primary); box-shadow: none;
}
/* Live transcode add/remove in flight (loaded target rows). */
.tc-chip.on-pending { opacity: .55; cursor: progress; }
/* × to remove a live rendition, shown inside the read-only "live:" badge. */
.tc-rend-del {
    margin-left: 5px; padding: 0 2px; border: 0; background: none; cursor: pointer;
    color: var(--text-primary); font-size: 12px; line-height: 1; opacity: .7;
}
.tc-rend-del:hover { opacity: 1; color: var(--accent-red); }
/* Add-output form lives outside the table, so mirror the compact table
   sizing (chips + controls) so it matches the per-target rows. */
#addTargetRow .tc-chip-box,
#addTargetRow .tc-chips { gap: 5px; }
#addTargetRow .tc-chip { padding: 3px 9px; }
#addTargetRow .stream-bg-select,
#addTargetRow .stream-bg-input,
#addTargetRow .per-tag-input {
    height: 33px; box-sizing: border-box; padding: 0 9px; font-size: 12px; line-height: normal;
}
#addTargetRow .per-tag-input { font-size: 12px; }
/* Transcode chip box: curated subset by default, scrollable when "Show
   all" expands it so a 60-profile list never blows out the row. */
.tc-chip-box { display: flex; gap: 5px; flex-wrap: wrap; }
.tc-chip-box.expanded {
    max-height: 170px; overflow-y: auto; padding: 6px;
    border: 1px solid var(--border); border-radius: 4px;
    background: rgba(0,0,0,0.15); margin-bottom: 5px;
}
.tc-more {
    margin-top: 5px; font-size: 12px; font-weight: 600; cursor: pointer;
    padding: 2px 8px; border-radius: 4px; white-space: nowrap;
    border: 1px solid var(--border); background: transparent;
    color: var(--text-primary); transition: color .14s,border-color .14s;
}
.tc-more:hover { color: var(--text-primary); border-color: var(--orange); }
/* Transcodes label line: "Transcodes tap to add" left, "Show all" right —
   keeps the toggle off its own row so the card stays shorter. */
.tc-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.tc-head .tc-more { margin-top: 0; }
/* Read-only renditions/tags in the reuse section (set at creation). */
.tc-chips.ro { gap: 5px; }
.tc-chip.ro { cursor: default; }
.tc-chip.ro:hover { border-color: var(--orange); color: var(--text-primary); }
.ro-value { font-size: 12px; color: var(--text); word-break: break-word; }
.ro-value.muted { color: var(--text-primary); }
.ro-hint {
    font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
    color: var(--text-primary); opacity: .7; margin-left: 4px;
}

/* ── Create-mode output table (compact multi-column) ── */
.create-table td { white-space: normal; vertical-align: middle; padding: 9px 12px; }
.create-table td.cnum { color: var(--text-primary); font-weight: 700; text-align: center; }
.create-table th .th-opt {
    font-weight: 400; text-transform: none; letter-spacing: 0; opacity: .55; font-size: 12px;
}
.create-table .per-tag-input { font-size: 12px; }
.create-table .tc-chips { gap: 5px; }
.create-table .tc-chip { padding: 3px 9px; }
/* Overlay cell: enable checkbox · file select · gear, on one line. */
.create-table .ov-cell { display: flex; align-items: center; gap: 7px; flex-wrap: nowrap; }
.create-table .ov-cell .ov-enable { margin: 0; flex-shrink: 0; }
.create-table .ov-cell .ov-file-select { flex: 1 1 auto; min-width: 0; max-width: none; }
.create-table .ov-cell.ov-off .ov-file-select { opacity: .55; }
/* Square icon-only buttons (gear toggle, remove ✕). */
.ov-adjust-btn.icon-only { padding: 0; width: 30px; height: 30px; justify-content: center; gap: 2px; flex-shrink: 0; }
.ov-adjust-btn.icon-only .chev { font-size: 12px; }
.target-del-btn.icon-only {
    padding: 0; width: 26px; height: 26px; line-height: 1; border-radius: 4px;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid transparent; background: transparent; cursor: pointer;
    color: var(--text-primary); font-size: 12px; transition: background .14s,color .14s;
}
.target-del-btn.icon-only:hover { background: var(--bg); color: var(--text-primary); }
/* The collapsible position/size sub-row sits flush under its target. */
.create-table .overlay-panel-row td { padding-top: 0; padding-bottom: 6px; }
.create-table .overlay-panel-row:hover td { background: transparent; }
/* Uniform control height so Background / Tags / Overlay fields line up
   (selects and inputs otherwise render at different heights). */
.stream-table .stream-bg-select,
.stream-table .stream-bg-input,
.stream-table .per-tag-input {
    height: 33px; box-sizing: border-box; padding: 0 9px; font-size: 12px; line-height: normal;
}

/* ── Info icon: hover/focus affordance carrying a filter's parameter
   help text as a native tooltip (title attr) — replaces scattered
   always-on help-text paragraphs under sliders. ── */
.info-icon {
    display: inline-flex; align-items: center; justify-content: center;
    cursor: help; font-size: 12px; line-height: 1; margin-left: 4px;
    color: var(--text-primary); opacity: .7; vertical-align: middle;
    transition: color .15s,opacity .15s;
}
.info-icon:hover,
.info-icon:focus-visible,
.info-icon[aria-expanded="true"] { color: var(--text-primary); opacity: 1; }
.info-icon:focus-visible { outline: 2px solid var(--accent-orange); outline-offset: 2px; border-radius: 50%; }
/* Shared tooltip for the ⓘ icons (positioned by initInfoTips). */
.info-pop {
    position: fixed; z-index: 1000; max-width: 260px; padding: 8px 11px;
    font-size: 12px; line-height: 1.45; font-weight: 500; letter-spacing: 0; text-transform: none;
    color: var(--text); background: var(--panel-soft);
    border: 1px solid var(--line-strong); border-radius: 4px;
    box-shadow: 0 10px 28px rgba(0,0,0,0.45);
    opacity: 0; visibility: hidden; transform: translateY(2px);
    transition: opacity .12s, transform .12s, visibility 0s linear .12s;
    pointer-events: none;
}
.info-pop.open { opacity: 1; visibility: visible; transform: none; transition: opacity .12s, transform .12s; }
.info-pop::after {
    content: ""; position: absolute; left: var(--arrow-x); top: 100%;
    width: 8px; height: 8px; margin-left: -4px; margin-top: -4px;
    background: var(--panel-soft); border-right: 1px solid var(--line-strong); border-bottom: 1px solid var(--line-strong);
    transform: rotate(45deg);
}
.info-pop.below::after { top: 0; transform: rotate(225deg); }

/* ── Embed mode (?embed=1) — workbench-only, for hosting inside the
   Production Console in an <iframe>. Hides the page chrome and the
   create/reuse setup flow; auth + stream load come from the URL handoff
   (?apikey=&env=&stream=). The live composite + all tuning controls
   (autotune, despill, EQ, colour picker, engines, backgrounds, and the
   per-target table) stay, so the console gets the identical tuner. */
html.embed-wb body { background: transparent; }
html.embed-wb #authSection { display: none !important; }
/* ?setup=1 keeps the create/reuse flow: the Builder Hub's "Set up chroma
   key" is the whole tool, not just the workbench. (main, Tuner 3.55.0) */
html.embed-wb:not(.embed-setup) #configurationSection .mode-tabs-row,
html.embed-wb:not(.embed-setup) #reusePane { display: none !important; }
html.embed-wb body { padding-top: 6px; }
/* ?view=workbench (with embed=1): only the workbench, no Backgrounds or
   Stream Setup card above it. For a frame that shows a demo setup (the
   Builder Hub's chroma key sample): the ingest id and stream key stay out
   of view without the host cropping at a measured offset. (main, 3.56.0) */
html.embed-wb.embed-workbench #uploadSection,
html.embed-wb.embed-workbench #configurationSection { display: none !important; }
/* In the Builder Hub's views the frame is as tall as the page, so 100vh is
   the page's own height: the rail's sticky max-height (calc(100vh - 116px),
   .workbench-controls above) would clip it and scroll it inside, and the
   height reported to the hub would leave its end out. There the rail flows
   with the page. (main, 3.56.0) */
html.embed-wb.embed-workbench .workbench-controls,
html.embed-wb.embed-setup .workbench-controls { position: static; max-height: none; overflow: visible; }

/* =====================================================================
   Product Theme alignment (nanoStudio) — 2026-10-29
   ---------------------------------------------------------------------
   Maps this page's own class names onto product-theme.css components,
   so it reads like tests/archetype-workbench.html (the approved
   nanoStudio reference) without renaming classes the JS builds or
   queries. Last in the file on purpose: it settles the cascade the
   older rules above leave behind. Tokens only — no literal colours.
   ===================================================================== */

/* ---- Page column ---------------------------------------------------
   .workbench (theme) owns width + outer margins: 1520px cap, 48px min
   gutter, aligned with .header-inner / .footer-inner. Blocks inside it
   are full-width and stacked on the theme's 20px rhythm. */
.workbench > details.section,
.workbench > .section,
.workbench > #workbenchBlock {
    width: 100%;
    max-width: none;
    margin: 0 0 20px;
}
.workbench > #workbenchBlock { margin-bottom: 0; }

/* ---- Sections = .panel --------------------------------------------- */
.workbench > .section {
    overflow: visible;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 4px;
    box-shadow: var(--shadow);
    padding: 20px;
    color: var(--text-primary);
}
details.collapsible > summary {
    width: auto;
    margin: 0 0 16px;
    padding: 0 0 0 22px;
    background: transparent;
    border: 0;
    border-radius: 0;
    font-family: var(--font-heading);
    font-size: 16px;
    font-weight: 700;
    letter-spacing: 0;
    text-transform: none;
    color: var(--text-primary);
}
details.collapsible > summary:hover { background: transparent; }
details.collapsible > summary::before {
    left: 2px;
    border-color: var(--text-primary);
}
.section h3,
.section-subhead,
#configurationSection > h3 {
    border: 0;
    padding-left: 0;
    color: var(--text-primary);
}

/* ---- Text: white everywhere, --text-muted only for placeholder and
   disabled (theme :root). Helper/status copy is white Source Sans 3. */
.text-muted,
.text-muted-sm,
.help-text,
.source-status,
.scrub-time,
.adj-status-row,
#applyModeHint,
#overlayActiveLabel,
.switch-label,
.form-row > label {
    color: var(--text-primary) !important;
}
.text-muted, .help-text, .source-status, .adj-status-row,
#previewStatus, #autotuneStatus, #overlayActiveLabel, #ovFrameHint {
    font-size: 13px;
}
/* Error messages: orange attention dot (theme .status-strip--attn), set
   by show(..., true) in nano-chroma-tuner.js — never a red text colour. */
.is-error::before {
    content: '';
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-right: 8px;
    border-radius: 50%;
    background: var(--accent-orange);
    vertical-align: middle;
}

/* ---- Workbench heading ------------------------------------------- */
.workbench-header { margin: 0 0 12px; padding: 0; }
.workbench-header .eyebrow {
    margin: 0 0 4px;
    font-family: var(--font-heading);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--text-primary);
}
.workbench-header h3 { margin: 0; font-size: 21px; }

/* ---- Workbench columns: theme .workbench-main + .control-rail ------
   The preview column is not a panel in the reference — the monitor
   stands on the page, with source cards as panels beneath it. */
.workbench-layout { margin: 0; }
.workbench-preview {
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: 0;
    overflow: visible;
}
#canvasPane, #livePane { display: flex; flex-direction: column; gap: 12px; }
.workbench-controls {
    background: var(--panel);
    border: 1px solid var(--border);
    border-top: 2px solid var(--border-strong);
    border-radius: 4px;
    box-shadow: var(--shadow);
    padding: 18px;
    scrollbar-color: var(--border-strong) var(--panel);
}
/* Each group in the rail = .control-section: a divider, no box. */
.workbench-controls .chroma-section {
    background: transparent;
    border: 0;
    border-top: 1px solid var(--border);
    border-radius: 0;
    box-shadow: none;
    margin: 16px 0 0;
    padding: 16px 0 0;
}
.workbench-controls > .chroma-section:first-child {
    border-top: 0;
    margin-top: 0;
    padding-top: 0;
}
.workbench-controls .chroma-section h4,
.workbench-controls details > summary strong {
    font-family: var(--font-heading);
    font-size: 14px;
    font-weight: 700;
    letter-spacing: 0;
    text-transform: none;
    color: var(--text-primary);
}

/* ---- Switcher: Preview / Live and source tokens = .btn-chip --------- */
.switcher,
.switcher-bus {
    background: transparent;
    border: 0;
    box-shadow: none;
    padding: 0;
}
.mode-toggle {
    display: inline-flex;
    gap: 8px;
    background: transparent;
    border: 0;
    padding: 0;
}
.btn-chip.mode-seg,
.btn-chip.auth-tab,
.btn-chip.mode-tab {
    gap: 8px;
    margin: 0;
    padding: 6px 14px;
    background: var(--panel-soft);
    border: 1px solid var(--border);
    border-radius: 999px;
    font-family: var(--font-body);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0;
    text-transform: none;
    color: var(--text-primary);
}
/* State stays the .active class the JS toggles; it renders exactly like
   the theme's selected chip ([aria-pressed="true"]), which inside
   data-color-critical is fill + neutral border, no accent. */
.btn-chip.mode-seg.active,
.btn-chip.auth-tab.active,
.btn-chip.mode-tab.active,
#tabPreview.active,
#tabLive.active {
    background: var(--panel);
    border-color: var(--accent-blue);
    color: var(--text-primary);
    box-shadow: none;
}
[data-color-critical] .btn-chip.mode-seg.active,
[data-color-critical] #tabPreview.active,
[data-color-critical] #tabLive.active { border-color: var(--border-strong); }
/* Tally without red: blue dot = monitoring the preview, orange dot = on
   air (orange is the theme's attention/live colour). */
.mode-seg .seg-dot { background: var(--border-strong); box-shadow: none; }
#tabPreview.active .seg-dot { background: var(--accent-blue); box-shadow: none; }
#tabLive.active .seg-dot { background: var(--accent-orange); box-shadow: none; }
.auth-tabs-row,
.mode-tabs-row,
#configurationSection > .mode-tabs-row {
    display: flex;
    gap: 8px;
    background: transparent;
    border: 0;
    box-shadow: none;
    padding: 0;
    margin: 0 0 16px;
    overflow: visible;
}

.src-btn {
    background: var(--panel-soft);
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--text-primary);
    font-family: var(--font-body);
    font-size: 12px;
    font-weight: 500;
}
.src-btn:hover { background: var(--panel); border-color: var(--border-strong); }
.switcher.mode-preview .src-btn.active,
.switcher.mode-live .src-btn.active {
    background: var(--panel);
    border-color: var(--border-strong);
    color: var(--text-primary);
    box-shadow: inset 0 0 0 1px var(--border-strong);
}

/* ---- Monitor: theme .monitor; mode shown by a .status-strip, not a
   coloured frame (a saturated ring beside the key biases the judgement). */
#workbenchPreview.tally-preview .player-stage,
#workbenchPreview.tally-live .player-stage,
.player-stage.monitor {
    border: 1px solid var(--panel-inset);
    border-radius: 4px;
    box-shadow: var(--shadow);
}
.preview-mode-hint {
    top: 12px;
    left: 12px;
    right: auto;
    display: block;
    padding: 7px 12px;
    font-family: var(--font-body);
    font-size: 12px;
    font-weight: 400;
    letter-spacing: 0;
    color: var(--text-primary);
    background: var(--panel-soft);
    border: 1px solid var(--border);
    border-radius: 4px;
}
.preview-mode-hint::before {
    content: '';
    display: inline-block;
    margin-right: 8px;
    vertical-align: middle;
    width: 6px;
    height: 6px;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--accent-orange);
}
.player-placeholder { color: var(--text-primary); font-size: 14px; }

/* ---- Source cards (FG / BG) = .panel at the nested tier ------------- */
.source-card {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 4px;
    box-shadow: var(--shadow);
    padding: 14px;
}
.source-card:hover { border-color: var(--border); }
.source-row-label {
    font-family: var(--font-heading);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.09em;
    color: var(--text-primary);
}
.source-upload,
.btn-chip.source-pill,
.stream-group-btn,
.bg-combo-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 30px;
    padding: 6px 14px;
    background: var(--panel-soft);
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--text-primary);
    font-family: var(--font-body);
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
}
.source-upload:hover,
.btn-chip.source-pill:hover,
.stream-group-btn:hover {
    background: var(--panel);
    border-color: var(--border-strong);
    color: var(--text-primary);
}
.stream-group-btn { border-radius: 0 999px 999px 0; min-width: 36px; }
.bg-combo-toggle { border-radius: 0 8px 8px 0; min-height: 0; padding: 0 10px; }
.bg-combo-toggle:hover { background: var(--panel) !important; color: var(--text-primary) !important; }

/* ---- Field-shaped boxes = theme input: --bg fill, 1px border, 8px --- */
.stream-group,
.bg-combo-field,
.value-input,
.rgb-value,
.hex-row-compact input,
.per-tag-input,
.sc-head-tags,
input.grow,
#reuseIngestId,
#targetCount,
#bareTargetCount,
#ffmpegBgFile {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: none;
    color: var(--text-primary);
}
.stream-group input,
.bg-combo-input {
    background: transparent;
    border: 0;
    color: var(--text-primary);
}
.stream-group input::placeholder,
.bg-combo-input::placeholder { color: var(--text-muted); font-style: normal; }
.stream-group:focus-within,
.bg-combo-field:focus-within,
.sc-head-tags:focus-within {
    border-color: var(--accent-blue);
    box-shadow: none;
}
.bg-combo.ov-combo .bg-combo-field { border-color: var(--border); }
input.grow {
    padding: 10px 12px;
    font-family: var(--font-body);
    font-size: 14px;
}
/* .source-select is a plain <select>: the theme's own select rule draws
   its chevron, so nothing here may set the background shorthand. */
select.source-select {
    padding: 7px 34px 7px 12px;
    max-width: 170px !important;
    height: auto;
    font-size: 13px;
}
/* Numeric readouts beside sliders = .badge--value (neutral mono pill). */
.value-input {
    border-radius: 999px;
    font-family: var(--font-mono);
    font-size: 12px;
    text-align: center;
}
.value-input:focus { outline: 2px solid var(--accent-blue); outline-offset: 1px; }

/* ---- Key colour: .color-swatch (theme); state = .active from JS ----- */
.color-swatch.preset-btn {
    gap: 8px;
    margin: 0;
    padding: 5px 12px 5px 8px;
    background: var(--panel-soft);
    border: 1px solid var(--border);
    border-radius: 999px;
    box-shadow: none;
    color: var(--text-primary);
    font-family: var(--font-body);
    font-size: 13px;
    font-weight: 400;
}
.color-swatch.preset-btn.picker-label { padding-left: 12px; }
.color-swatch.preset-btn:hover:not(.active) {
    background: var(--panel-soft);
    border-color: var(--border-strong);
}
.color-swatch.preset-btn.active {
    background: var(--panel);
    border-color: var(--border-strong);
    box-shadow: inset 0 0 0 1px var(--border-strong);
    color: var(--text-primary);
}
.color-indicator code,
#colorHex {
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--text-primary);
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 2px 8px;
}

/* ---- Despill / EQ colour radios: neutral pill, colour is the data --- */
.color-radio {
    background: var(--panel-soft);
    border: 1px solid var(--border);
    border-radius: 999px;
    box-shadow: none;
    color: var(--text-primary);
}
.color-radio:has(input:checked) {
    background: var(--panel);
    border-color: var(--border-strong);
    box-shadow: inset 0 0 0 1px var(--border-strong);
    color: var(--text-primary);
}

/* ---- Filter-string and command readouts = theme code box ------------ */
.filter-string,
.ffmpeg-cmd,
#despillPreview,
#eqPreview {
    margin-top: 10px;
    padding: 8px 12px;
    background: var(--bg) !important;
    border: 1px solid var(--border) !important;
    border-radius: 8px;
    font-family: var(--font-mono);
    font-size: 12px;
    line-height: 1.5;
    color: var(--text-primary) !important;
    word-break: break-all;
    white-space: normal;
}

/* ---- Apply block -------------------------------------------------------
   Sticky at the bottom of the rail so Apply to Stream is always reachable
   (position: sticky comes from the older rule above). A sticky block paints
   OVER whatever scrolls beneath it, so it must never be see-through: solid
   --panel fill (the rail's own surface), its own divider, and a stacking
   level above the rail content. The rail and, below 1224px, the page reserve
   its height as scroll padding, so focusing or scrolling to a control never
   leaves it hidden underneath. */
.workbench-controls > .action-row {
    position: sticky;
    bottom: 0;
    z-index: 2;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin: 16px 0 0;
    padding: 16px 0 12px;
    background: var(--panel);
    border: 0;
    border-top: 1px solid var(--border);
    border-radius: 0;
    box-shadow: none;
}
.workbench-controls { scroll-padding-bottom: 190px; }
@media (max-width: 1224px) {
    html { scroll-padding-bottom: 190px; }
}
/* Hint text holds an inline <strong>: block flow keeps normal word
   spacing (the theme's .status-strip is a flex row). Own full row. */
.workbench-controls > .action-row > #applyModeHint {
    display: block;
    flex: 1 1 100%;
    margin: 0;
}
/* Toggle labels wrap inside the rail instead of running past its edge. */
.workbench-controls > .action-row > .switch-label {
    flex: 0 1 auto;
    min-width: 0;
    white-space: normal;
    line-height: 1.3;
}
.workbench-controls > .action-row > .switch-label > input { flex-shrink: 0; }
/* Ingest control: its own full row. */
.workbench-controls > .action-row > div:last-child {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    flex: 1 1 100%;
}
.workbench-controls .btn { margin: 0; }
.btn .btn-glyph { margin-right: 6px; }

/* ---- Theme buttons inside legacy rows: no legacy margins ------------ */
.form-row .btn,
.action-row .btn,
.switcher-outputs .btn { margin: 0; }

/* ---- Narrow viewports: theme collapses the grid below 1224px; drop the
   old fixed minimums that forced 1140px of page width. */
@media (max-width: 1224px) {
    .workbench-layout { grid-template-columns: minmax(0, 1fr); }
    .workbench-controls { position: static; max-height: none; overflow: visible; }
}
.workbench-main, .workbench-preview, .source-inputs, .source-card { min-width: 0; }
@media (max-width: 760px) {
    .source-inputs { grid-template-columns: minmax(0, 1fr); }
    .workbench > details.section,
    .workbench > .section,
    .workbench > #workbenchBlock { width: 100%; }
}

/* ---- Embed mode (?embed=1): hide page chrome around the workbench ---- */
html.embed-wb .header,
html.embed-wb .footer { display: none !important; }
html.embed-wb .workbench { margin-top: 6px; }

/* Disclosure headers keep the theme's 24px minimum hit area (governing
   rule 9 in product-theme.css). */
details.collapsible > summary,
#overlaySection > summary { min-height: 24px; }

/* ---- Targets table (create mode) -----------------------------------
   Headers were nowrap in fixed-width columns, so at narrow widths
   "Background MP4 · PNG · JPG · STREAM" ran over Tags and Overlay. Let
   them wrap, and below 760px keep the columns wide enough to use: the
   table scrolls sideways inside .stream-table-wrap instead of squeezing
   the inputs. */
.create-table th {
    white-space: normal;
    vertical-align: bottom;
    line-height: 1.3;
}
.create-table th .asset-hint {
    display: inline-block;
    max-width: 100%;
    white-space: normal;
}
.create-table th .th-opt { white-space: nowrap; }
@media (max-width: 760px) {
    .create-table { min-width: 760px; }
}

/* =====================================================================
   UX guidance layer (2026-10-30, from the main-vs-branch walk-through)
   ---------------------------------------------------------------------
   Puts back the cues the first-time workflow leans on, without red and
   without tinting the parameter panel (sliders, presets, value pills).
   Tokens only; state still comes from what the JS already sets.
   ===================================================================== */

/* ---- Switches: the theme's [role="switch"] geometry (knob travels
   14px), with a filled track so "on" reads at a glance. Blue is the
   theme's checked-control colour (--accent-blue). Deliberately also
   inside [data-color-critical]: Stop & unlock after Apply restarts the
   ingest, so its state must not depend on spotting a knob position. */
input[type="checkbox"][role="switch"]:checked,
[data-color-critical] input[type="checkbox"][role="switch"]:checked {
    background: var(--accent-blue);
    border-color: var(--accent-blue);
}
input[type="checkbox"][role="switch"]:checked::after {
    background: var(--text-on-accent);
}

/* ---- Live cue (Live mode only; Preview stays neutral) ---------------
   The Live chip turns solid orange and the stage gets an orange frame.
   Orange is the theme's attention / live colour; no red. */
#tabLive.active,
[data-color-critical] #tabLive.active {
    background: var(--accent-orange);
    border-color: var(--accent-orange);
    color: var(--text-on-accent);
}
#tabLive.active .seg-dot { background: var(--text-on-accent); }
#tabLive.active .tab-sync-dot { background: var(--text-on-accent); box-shadow: none; }
#workbenchPreview.tally-live #livePane .player-stage {
    border: 2px solid var(--accent-orange);
    box-shadow: var(--shadow);
}
.switcher.mode-live .src-btn.active,
[data-color-critical] .switcher.mode-live .src-btn.active {
    border-color: var(--accent-orange);
    box-shadow: inset 0 0 0 1px var(--accent-orange);
}

/* Stream cards: "In preview" is a quiet neutral frame; ON AIR is the
   orange frame plus a solid orange tag. */
.stream-cards .stream-card.target.is-active {
    border-color: var(--border-strong);
    box-shadow: inset 0 0 0 1px var(--border-strong);
}
.stream-cards .stream-card.target.is-active::before { background: var(--border-strong); }
.stream-cards .stream-card.is-active .sc-active-tag {
    color: var(--text-primary);
    background: var(--panel-soft);
    border: 1px solid var(--border-strong);
}
.stream-cards .stream-card.target.is-onair {
    border-color: var(--accent-orange);
    box-shadow: inset 0 0 0 1px var(--accent-orange);
}
.stream-cards .stream-card.target.is-onair::before { background: var(--accent-orange); }
.stream-cards .stream-card.is-onair .sc-active-tag {
    color: var(--text-on-accent);
    background: var(--accent-orange);
    border: 1px solid var(--accent-orange);
}

/* ---- Required fields: orange until filled -------------------------
   Background fields (create table and stream cards) and Targets
   (required in the markup, so empty or out of 1–12 is :invalid). The
   preview's own BG slot in the workbench has its own rule in the
   "Guidance cues" block below (orange until a background is chosen). */
#streamInfo .bg-combo-field:has(.bg-combo-input[data-kind="bg"]:placeholder-shown),
#targetCount:invalid {
    border-color: var(--accent-orange);
    box-shadow: inset 0 0 0 1px var(--accent-orange);
}

/* ---- Create new / Reuse: the selected tab is a solid fill ----------- */
.btn-chip.mode-tab.active {
    background: var(--accent-blue);
    border-color: var(--accent-blue);
    color: var(--text-on-accent);
}

/* ---- Messages: orange = error / attention, blue = success ----------
   show() in nano-chroma-tuner.js adds .is-error to errors; any other
   message in these rows (progress and confirmations) is set in blue.
   Upload results already carry .result.success / .result.error. */
#tokenStatus.is-error, #createStatus.is-error, #reuseStatus.is-error,
#bareStreamStatus.is-error, #adjStatus.is-error, #lockStatus.is-error,
#autotuneStatus.is-error, #addTargetStatus.is-error, #fgStatus.is-error,
#bgStatus.is-error, #playerStatus.is-error {
    color: var(--accent-orange) !important;
    font-weight: 600;
}
#tokenStatus:not(.is-error):not(:empty),
#createStatus:not(.is-error):not(:empty),
#reuseStatus:not(.is-error):not(:empty),
#bareStreamStatus:not(.is-error):not(:empty),
#adjStatus:not(.is-error):not(:empty),
#lockStatus:not(.is-error):not(:empty),
#autotuneStatus:not(.is-error):not(:empty),
#addTargetStatus:not(.is-error):not(:empty) {
    color: var(--accent-blue-hover) !important;
    font-weight: 600;
}
/* Preview stays calm: the "Preview mode" hint carries no accent dot. */
.preview-mode-hint::before { background: var(--border-strong); }
.result.success {
    background: var(--panel-soft);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent-blue);
    color: var(--text-primary);
}
.result.error {
    background: var(--panel-soft);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent-orange);
    color: var(--text-primary);
}

/* =====================================================================
   Guidance cues (2026-11-02, second main-vs-branch pass)
   ---------------------------------------------------------------------
   Rule: orange = the user needs to act here. Brings back main's cues for
   the first-time workflow; status that needs no action stays neutral
   (environment pill, Copy full URL, Preview button, the parameter panel).
   Tokens only (tints via color-mix of --accent-orange, as the theme does);
   state comes from what the JS already renders, no JS changes.
   ===================================================================== */

/* ---- FG "Ingest": orange until a foreground is loaded ---------------
   The JS hides #canvasPlaceholder (inline display:none) once a frame is
   on the canvas, so "placeholder visible" = no foreground yet. */
#canvasPane:has(#canvasPlaceholder:not([style*="none"])) #fgIngestBtn {
    color: var(--accent-orange);
    background: transparent;
    border-color: var(--accent-orange);
    font-weight: 700;
}
#canvasPane:has(#canvasPlaceholder:not([style*="none"])) #fgIngestBtn:hover {
    color: var(--text-on-accent);
    background: var(--accent-orange);
    border-color: var(--accent-orange);
}

/* ---- BG field under the player: orange until a background is chosen --
   Chosen = the combobox has a value, or #bgStatus no longer shows its
   default help (an upload or load replaces it with plain text). */
.source-row:has(#bgStatus strong) #bgSourceSlot .bg-combo-field:has(.bg-combo-input:placeholder-shown) {
    border-color: var(--accent-orange);
    box-shadow: inset 0 0 0 1px var(--accent-orange);
}

/* ---- "Waiting for signal": orange-tinted banner, orange title -------- */
.sc-signal.idle {
    background: color-mix(in srgb, var(--accent-orange) 14%, transparent);
    border-left-color: var(--accent-orange);
    border-bottom-color: color-mix(in srgb, var(--accent-orange) 35%, transparent);
}
.sc-signal.idle strong { color: var(--accent-orange); }

/* ---- Preview mode hint: full-width bar across the top of the stage,
   orange text. The stage itself keeps its neutral frame in Preview. */
.preview-mode-hint {
    top: 0;
    left: 0;
    right: 0;
    padding: 6px 12px;
    font-weight: 700;
    text-align: center;
    color: var(--accent-orange);
    background: color-mix(in srgb, var(--accent-orange) 14%, var(--panel-inset));
    border: 0;
    border-bottom: 1px solid color-mix(in srgb, var(--accent-orange) 35%, transparent);
    border-radius: 4px 4px 0 0;
}
.preview-mode-hint::before { display: none; }
.preview-mode-hint strong { color: var(--accent-orange); }

/* ---- "+ Add output": the theme's .btn .btn-primary look ---------------
   The button is rendered by JS with only class="btn-sm", which neither the
   theme nor this file styled, so it fell back to the browser default. */
.sc-section-actions .btn-sm {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 6px 15px;
    font-family: var(--font-heading);
    font-size: 14px;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: 0.01em;
    color: var(--text-on-accent);
    background: var(--accent-orange);
    border: none;
    border-radius: 999px;
    cursor: pointer;
}
.sc-section-actions .btn-sm:hover:not(:disabled) { background: var(--accent-orange-hover); }

/* ---- Card badges --------------------------------------------------
   Needs Apply (action pending): orange outlined pill.
   In preview (status, no action): orange text on a neutral pill.
   ON AIR keeps its solid orange tag from the UX guidance layer. */
.stream-card.needs-apply .sc-dirty-tag {
    color: var(--accent-orange);
    background: transparent;
    box-shadow: inset 0 0 0 1px var(--accent-orange);
}
.stream-card.needs-apply .sc-dirty-tag::before { background: var(--accent-orange); }
.stream-cards .stream-card.is-active:not(.is-onair) .sc-active-tag {
    color: var(--accent-orange);
    background: var(--panel-soft);
    border: 1px solid var(--border-strong);
}

/* ---- File type hints in the create table: orange outlined chips that
   stay on the header's first line (MP4 · PNG · JPG · STREAM, PNG). */
.create-table th .asset-hint {
    display: inline-block;
    padding: 0 4px;
    margin-left: 4px;
    font-size: 11px;
    letter-spacing: 0.03em;
    white-space: nowrap;
    vertical-align: 1px;
    color: var(--accent-orange);
    border: 1px solid color-mix(in srgb, var(--accent-orange) 45%, transparent);
    border-radius: 3px;
}
.create-table thead th:nth-child(2),
.create-table thead th:nth-child(4) { white-space: nowrap; }

/* ---- FG mini-player: size from its 16:9 aspect ratio ----------------
   height:100% !important (meant for NanoPlayer's injected divs) also hit
   the container, a cyclic percentage inside an auto-height column, so the
   row was laid out at the player's height and "✕ Hide preview" hung over
   the FG card's bottom edge. The injected divs keep their 100%. */
#fgMiniPlayer { height: auto !important; }

/* ---- From main, Tuner 3.56.1 (merged 2026-11-09) ---------------------
   A long background name never runs past its button, and on a narrow
   screen the source tabs get a row of their own instead of being squeezed
   beside the Preview | Live switch. Last in the file so the theme layer's
   .src-btn rules above cannot undo it. */
.src-btn { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 760px) { .bus-btns { flex-basis: 100%; } }

/* =====================================================================
   Guidance cues restored from main (Tuner 3.56.x), 2026-11-10.
   Product owner review of the Product Theme restyle: three cues that the
   setup flow relies on had been flattened, and clients were getting stuck
   at exactly these points. Last in the file on purpose, so the theme
   alignment and guidance blocks above cannot undo them. Literal colours
   here are colour-as-signal (vision-mixer tally: amber = preview, red =
   on air; green = receiving), not decoration.
   ===================================================================== */
:root {
    --tally-amber: var(--accent-orange);
    --tally-red: #e03c3c;
    --tally-red-text: #ff6b6b;
    --signal-ok: #44c767;
    --signal-err: #ff6b5f;
}

/* ---- 1. Ingest card: the entry point of the whole setup --------------
   Blue ring + tinted header and publish panel (as on main), and while the
   ingest is WAITING FOR SIGNAL the whole card lights up: red accent bar,
   red ring, red-tinted strip with the pulsing dot. Once Bintu reports the
   ingest live the card calms down to green. */
.stream-card.ingest {
    border-color: rgba(31, 155, 209, 0.45);
    box-shadow: 0 0 0 1px rgba(31, 155, 209, 0.18), 0 6px 20px rgba(0, 0, 0, 0.22);
}
.stream-card.ingest .sc-head { background: linear-gradient(180deg, rgba(15, 141, 200, 0.09), transparent); }
.stream-card.ingest .stream-type-badge.ingest-badge {
    background: rgba(31, 155, 209, 0.24);
    color: #9ad8f5;
    box-shadow: inset 0 0 0 1px rgba(31, 155, 209, 0.45);
}
.sc-ingest-note { color: var(--text-muted); }
.sc-ingest-note strong { color: #9ad8f5; }
.sc-publish { background: linear-gradient(180deg, rgba(31, 155, 209, 0.13), rgba(31, 155, 209, 0.05)); }
.stream-card.ingest.is-live .sc-publish { background: rgba(31, 155, 209, 0.04); }

.sc-signal.idle {
    background: linear-gradient(90deg, rgba(255, 107, 95, 0.22), rgba(255, 107, 95, 0.04));
    border-left-color: var(--signal-err);
    border-bottom-color: rgba(255, 107, 95, 0.35);
}
.sc-signal.idle strong { color: var(--signal-err); }
.sc-signal.idle .sc-wait-dot { background: var(--signal-err); }
.sc-signal.idle .sc-wait-dot::after {
    border-color: var(--signal-err);
    animation: sc-ping 1.6s ease-out infinite;
}
/* The whole card, not just the strip, says "act here" while waiting. */
.stream-card.ingest:has(.sc-signal.idle) {
    border-color: rgba(255, 107, 95, 0.6);
    box-shadow:
        0 0 0 1px rgba(255, 107, 95, 0.28),
        0 0 26px rgba(255, 107, 95, 0.22),
        0 6px 20px rgba(0, 0, 0, 0.22);
}
.stream-card.ingest:has(.sc-signal.idle)::before { background: var(--signal-err); }
.stream-card.ingest:has(.sc-signal.idle) .sc-publish {
    background: linear-gradient(180deg, rgba(255, 107, 95, 0.12), rgba(255, 107, 95, 0.03));
}

.sc-signal.live {
    background: linear-gradient(90deg, rgba(68, 199, 103, 0.2), rgba(68, 199, 103, 0.05));
    border-left-color: var(--signal-ok);
    border-bottom-color: rgba(68, 199, 103, 0.3);
}
.sc-signal.live strong { color: var(--signal-ok); }
.sc-bars i {
    background: var(--signal-ok);
    box-shadow: 0 0 6px rgba(68, 199, 103, 0.6);
    animation: sc-bar 1.1s ease-in-out infinite;
}
.stream-card.ingest.is-live { border-color: rgba(68, 199, 103, 0.45); }
.stream-card.ingest.is-live::before { background: var(--signal-ok); }

/* One-shot "look here" pulse after a setup is created or loaded. */
@keyframes sc-attention {
    0%   { box-shadow: 0 0 0 0 rgba(31, 155, 209, 0.75), 0 6px 20px rgba(0, 0, 0, 0.22); }
    100% { box-shadow: 0 0 0 14px rgba(31, 155, 209, 0), 0 6px 20px rgba(0, 0, 0, 0.22); }
}
@media (prefers-reduced-motion: reduce) {
    .sc-bars i, .sc-signal.idle .sc-wait-dot::after { animation: none; }
}

/* ---- 2. Preview | Live: a segmented tally switch, amber vs red --------
   The two modes must read differently at a glance, and the way to switch
   must be obvious. Back to main's boxed segment control (uppercase,
   amber fill while previewing, red fill on air), the active source tab
   coloured by the mode, and a tally frame on the stage itself. */
.switcher {
    padding: 8px;
    border-radius: 10px;
    background: var(--surface-2);
    border: 1px solid var(--border);
}
.switcher-bus {
    padding: 5px 8px;
    border-radius: 7px;
    background: rgba(0, 0, 0, 0.18);
}
.switcher .mode-toggle {
    display: flex;
    gap: 0;
    padding: 0;
    border: 1px solid var(--border-strong);
    border-radius: 7px;
    overflow: hidden;
    background: var(--bg);
}
.switcher .mode-toggle .mode-seg {
    gap: 7px;
    margin: 0;
    padding: 8px 16px;
    border: 0;
    border-radius: 0;
    background: transparent;
    font-family: var(--font-display);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.switcher .mode-toggle .mode-seg + .mode-seg { border-left: 1px solid var(--border-strong); }
.switcher .mode-toggle .mode-seg .seg-dot { background: var(--border-strong); box-shadow: none; }

#tabPreview.active,
[data-color-critical] #tabPreview.active {
    background: rgba(244, 130, 32, 0.18);
    border-color: transparent;
    color: var(--tally-amber);
    box-shadow: none;
}
#tabPreview.active .seg-dot { background: var(--tally-amber); box-shadow: 0 0 6px rgba(244, 130, 32, 0.7); }

#tabLive.active,
[data-color-critical] #tabLive.active {
    background: rgba(224, 60, 60, 0.2);
    border-color: transparent;
    color: var(--tally-red-text);
    box-shadow: none;
}
#tabLive.active .seg-dot { background: var(--tally-red); box-shadow: 0 0 6px rgba(224, 60, 60, 0.75); }
#tabLive.active .tab-sync-dot { background: var(--tally-amber); }

.src-btn { border-radius: 6px; color: var(--text-muted); }
.src-btn:hover { color: var(--text-primary); }
.switcher.mode-preview .src-btn.active,
[data-color-critical] .switcher.mode-preview .src-btn.active {
    background: rgba(244, 130, 32, 0.16);
    border-color: var(--tally-amber);
    color: var(--tally-amber);
    box-shadow: inset 0 0 0 1px rgba(244, 130, 32, 0.4);
}
.switcher.mode-live .src-btn.active,
[data-color-critical] .switcher.mode-live .src-btn.active {
    background: rgba(224, 60, 60, 0.18);
    border-color: var(--tally-red);
    color: var(--tally-red-text);
    box-shadow: inset 0 0 0 1px rgba(224, 60, 60, 0.45);
}

/* Tally frame on the stage: amber while previewing, red while on air. */
#workbenchPreview.tally-preview .player-stage {
    border: 1px solid var(--tally-amber);
    box-shadow:
        0 0 0 1px rgba(244, 130, 32, 0.35),
        0 0 16px rgba(244, 130, 32, 0.3),
        var(--shadow);
}
#workbenchPreview.tally-live .player-stage,
#workbenchPreview.tally-live #livePane .player-stage {
    border: 1px solid var(--tally-red);
    box-shadow:
        0 0 0 1px rgba(224, 60, 60, 0.4),
        0 0 16px rgba(224, 60, 60, 0.35),
        var(--shadow);
}
.preview-mode-hint {
    color: var(--tally-amber);
    background: rgba(244, 130, 32, 0.14);
    border-bottom: 1px solid rgba(244, 130, 32, 0.35);
}
.preview-mode-hint strong { color: #ffb066; }

/* ---- 3. No separate foreground preview player -------------------------
   The keyed result is already on the stage (Preview) and the real output
   is one click away (Live), so the FG card no longer shows its own
   player. NanoPlayer still needs a mounted element to decode the ingest
   for frame capture, so the mini-player keeps running off-screen at its
   240x135 size instead of being removed; the "Hide preview" button goes
   with it. The status line ("Buffering…", errors) stays visible. */
#fgMiniPlayerWrap {
    position: absolute;
    left: -10000px;
    top: 0;
    width: 240px;
    height: 135px;
    margin: 0;
    padding: 0;
    overflow: hidden;
    opacity: 0;
    pointer-events: none;
}
#fgMiniPlayer { width: 240px !important; height: 135px !important; }

/* ---- Stream Setup heading: text inset like every other panel ---------
   The theme block drops the heading's border and left padding, but the
   panel background stays, so "Stream Setup" sat on the box's left edge.
   Inset it by the panel padding, so the title lines up with the content
   of the cards below it. */
#configurationSection > h3 { padding-left: 22px; }

/* ---- Switcher source tabs: one row first, then wrap ---------------------
   Ingest and the output tabs used to break lines at their natural width
   as soon as the Player links left too little room. Now each output tab
   has a floor of 150px and a ceiling of its own text, so the tabs sit in
   one row, shorten with an ellipsis as the row tightens, and only when
   150px each no longer fits does the row grow by a line. Ingest is short
   and always keeps its full label. */
.bus-btns .src-btn {
    flex: 1 1 0;
    min-width: 150px;
    max-width: max-content;
}
.bus-btns .src-btn[data-idx="-1"] {
    flex: 0 0 auto;
    min-width: max-content;
}

/* ---- Targets number box: same height as the Ingest tags field ---------
   The number input in the create toolbar had lost the theme's control
   padding (1px 2px, 23px tall) and sat visibly shorter than the tags
   field on its right (29px). Size it like that field. */
.setup-toolbar #targetCount {
    height: 29px;
    padding: 0 6px 0 8px;
    font-size: 13px;
    line-height: 27px;
    box-sizing: border-box;
}
