/* ── Producer Layout ── */

/* Full-viewport producer app (uses BlankLayout — no navbar/footer).
   dvh, not vh: on phones 100vh includes the area behind the URL bar, which
   forces the page taller than the visible viewport and everything scrolls. */
.producer-layout {
    display: flex;
    flex-direction: column;
    background: #1a1a2e;
    color: #e0e0e0;
    width: 100vw;
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
}

/* Exit button — top-left corner, away from live controls */
.producer-exit {
    position: absolute;
    top: 6px;
    left: 6px;
    z-index: 10;
    font-size: 0.7rem;
    font-weight: 600;
    text-decoration: none;
    color: #8888aa;
    padding: 3px 8px;
    border-radius: 4px;
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.1);
    white-space: nowrap;
    transition: background 0.15s, color 0.15s;
}

.producer-exit:hover {
    background: rgba(255,255,255,0.15);
    color: #fff;
}

/* ── Single preview (normal mode) ── */
.single-preview {
    flex: 1;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 6px;
    container-type: size;
}

/* Largest 16:9 box that fits the available space.
   cqw/cqh from the size-container give reliable dimensions
   without flex cross-size ambiguity.
   Pick the smaller constraint: full width vs full height. */
.single-preview .preview-wrapper {
    --w-limited: min(100cqw, 1200px);
    --h-limited: calc(100cqh * 16 / 9);
    width:  min(var(--w-limited), var(--h-limited));
    height: min(calc(var(--w-limited) * 9 / 16), 100cqh);
    flex: 0 0 auto;
}

/* ── Source add form + list ── */
.source-add-form {
    display: flex;
    gap: 4px;
    align-items: center;
    margin-bottom: 6px;
    flex-shrink: 0;
}

.source-add-form select,
.source-add-form input {
    background: #0a0a1a;
    color: #e0e0e0;
    border: 1px solid #2a2a4a;
    flex: 1;
    min-width: 0;
    font-size: 0.7rem;
    padding: 2px 4px;
    height: 26px;
}

.source-add-form .btn {
    flex-shrink: 0;
    height: 26px;
    line-height: 1;
}

.source-edit-form {
    padding: 3px 8px 4px;
    background: #111;
    border-left: 2px solid #f0ad4e;
    border-bottom: 1px solid #1e2a44;
}

.source-edit-form select {
    background: #0a0a1a;
    color: #e0e0e0;
    border: 1px solid #2a2a4a;
    font-size: 0.65rem;
    height: 24px;
    width: 100%;
}

.source-list {
    display: flex;
    flex-direction: column;
    gap: 0;
}

.source-list-item {
    font-size: 0.7rem;
    padding: 3px 8px;
    background: #0a0a1a;
    color: #d0d0e0;
    border-left: 2px solid #4d8dff;
    border-bottom: 1px solid #1e2a44;
    display: flex;
    align-items: center;
    gap: 4px;
}

.source-label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.source-remove-btn {
    background: none;
    border: none;
    color: #555;
    cursor: pointer;
    font-size: 0.6rem;
    padding: 0 2px;
    line-height: 1;
    flex-shrink: 0;
}

.source-remove-btn:hover { color: #e63946; }

.source-list-item.stale { border-left-color: #f0ad4e; }
.source-stale-badge { color: #f0ad4e; font-size: 0.7rem; flex-shrink: 0; cursor: help; }

.source-add-error {
    margin-top: 4px;
    padding: 4px 6px;
    font-size: 0.72rem;
    line-height: 1.3;
    color: #ffb4ba;
    background: rgba(230, 57, 70, 0.12);
    border: 1px solid rgba(230, 57, 70, 0.4);
    border-radius: 3px;
}

.scene-setting {
    margin-bottom: 8px;
}

.scene-setting select {
    background: #0a0a1a;
    color: #e0e0e0;
    border: 1px solid #2a2a4a;
    font-size: 0.7rem;
    height: 26px;
}

.source-list-item.satellite {
    border-left-color: #17a2b8;
}

.source-list-item.satellite.offline {
    border-left-color: #6c757d;
    color: #9fb0c7;
}

.source-status-badge {
    font-size: 0.6rem;
    line-height: 1;
    padding: 2px 6px;
    border-radius: 999px;
    border: 1px solid transparent;
    flex-shrink: 0;
}

.source-status-badge.online {
    color: #9ff0c1;
    background: rgba(76, 205, 123, 0.14);
    border-color: rgba(76, 205, 123, 0.3);
}

.source-status-badge.offline {
    color: #c9d4e3;
    background: rgba(108, 117, 125, 0.18);
    border-color: rgba(201, 212, 227, 0.2);
}

/* Media leg of a shared event source — whether its video actually arrives,
   as opposed to the registry's Online (heartbeat) badge. */
.source-status-badge.media-connected {
    color: #9ff0c1;
    background: rgba(76, 205, 123, 0.14);
    border-color: rgba(76, 205, 123, 0.3);
}

.source-status-badge.media-connecting {
    color: #ffd479;
    background: rgba(255, 193, 7, 0.12);
    border-color: rgba(255, 193, 7, 0.3);
}

.source-status-badge.media-failed {
    color: #ff9d99;
    background: rgba(220, 53, 69, 0.14);
    border-color: rgba(220, 53, 69, 0.35);
}

.preview-wrapper {
    flex: 1;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #000;
    border-radius: 6px;
    overflow: hidden;
    position: relative;
}

/* Inner frame: largest 16:9 box that fits the wrapper.
   width:100% + aspect-ratio derives height; max-height:100% clamps when
   the wrapper is shorter than 16:9. overflow:hidden clips sub-pixel rounding. */
.preview-frame {
    position: relative;
    aspect-ratio: 16/9;
    width: 100%;
    max-height: 100%;
    overflow: hidden;
}

#compositor-canvas {
    width: 100%;
    height: 100%;
    display: block;
    background: #000;
}

/* Overlay design layered on top of the canvas */
.preview-overlay {
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    overflow: hidden;
    container-type: size;
}

/* Streaming-from-the-iGPU warning — the encoded output corrupts while the
   preview looks fine, so this is deliberately the loudest thing on the page. */
.producer-gpu-warning {
    background: #b91c1c;
    color: #fff;
    font-weight: 700;
    padding: 0.5rem 1rem;
    text-align: center;
    z-index: 50;
}

/* The live scene-overlay page (/monitor/overlay/scene/{id}) framed over the
   preview canvas — the same self-scaling, self-updating surface the broadcast
   output and the commentary feed layer over their video. pointer-events stays
   none so the canvas underneath keeps its framing drag/wheel interactions. */
.preview-overlay-frame {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
    background: transparent;
    pointer-events: none;
}

/* Override overlay.css's position:fixed so the overlay fits within the
   producer preview frame instead of covering the entire viewport.
   Render at native 1920×1080 and scale down with container-query-based
   inline size so text and elements maintain correct proportions. */
.preview-overlay .overlay-root {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    transform: none !important;
}

.preview-overlay .overlay-stage {
    width: 100% !important;
    height: 100% !important;
    --stageH: 100cqh;
}


/* ── Bottom toolbar ── */
.producer-toolbar {
    display: flex;
    /* The row carries status and links too — wrap beats overflow at any width. */
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 16px;
    padding: 6px 10px;
    background: #16213e;
    border-top: 1px solid #2a2a4a;
    flex-shrink: 0;
    font-size: 0.8rem;
}

.toolbar-group {
    display: flex;
    align-items: center;
    gap: 6px;
}

/* The controls-sheet toggle only exists on phones — see the narrow/short
   media query at the end of the producer section. */
.toolbar-mobile-only {
    display: none;
}

.toolbar-label {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: #8888aa;
    font-weight: 600;
}

.toolbar-value {
    font-size: 0.8rem;
    color: #e0e0e0;
    max-width: 140px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.toolbar-link {
    font-size: 0.75rem;
    color: #8888aa;
    text-decoration: none;
    border: 1px solid #2a2a4a;
    border-radius: 4px;
    padding: 3px 8px;
    white-space: nowrap;
}

.toolbar-link:hover {
    color: #e0e0e0;
    border-color: #8888aa;
}

.toolbar-sep {
    width: 1px;
    height: 20px;
    background: #2a2a4a;
}

.dest-toggle {
    font-size: 0.8rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 4px;
}

/* ── Studio Mode ── */

/* Preview row: Preview | CUT | Program */
.studio-previews {
    display: flex;
    flex: 1;
    min-height: 0;
    gap: 4px;
    padding: 6px 6px 0;
    align-items: center;
}

.studio-panel {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
}

.studio-label {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    padding: 2px 8px;
    color: #4d8dff;
    flex-shrink: 0;
}

.studio-label.program-label {
    color: #e63946;
}

/* Red border on program preview */
.studio-panel.program .preview-wrapper {
    border: 2px solid #e63946;
    border-radius: 6px;
}

/* CUT button between previews */
.studio-transition {
    display: flex;
    align-items: center;
    padding: 0 4px;
    flex-shrink: 0;
}

/* Controls strip — shared between studio and normal mode */
.producer-controls {
    display: flex;
    gap: 12px;
    padding: 6px 8px;
    background: #16213e;
    border-top: 1px solid #2a2a4a;
    flex-shrink: 0;
    overflow-x: auto;
    align-items: stretch;
    max-height: 220px;
}

.producer-controls .control-group {
    min-width: 0;
    overflow-y: auto;
}

.producer-controls .control-group {
    flex: 1 1 0;
}

.control-group h5 {
    margin: 0 0 6px 0;
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: #8888aa;
    font-weight: 600;
}

/* Scene buttons stacked vertically with color-coded left border */
.scene-stack {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.scene-stack .btn {
    width: 100%;
    text-align: left;
    font-size: 0.75rem;
    padding: 4px 8px;
    border-left: 3px solid transparent;
    background: #0a0a1a;
    color: #e0e0e0;
    border-top: 1px solid #2a2a4a;
    border-right: 1px solid #2a2a4a;
    border-bottom: 1px solid #2a2a4a;
    border-radius: 4px;
}

.scene-stack .btn:hover {
    background: #1e2a44;
}

.scene-stack .btn.is-program {
    border-left-color: #e63946;
    background: #2a1520;
}

.scene-stack .btn.is-preview,
.scene-stack .btn.is-active {
    border-left-color: #4d8dff;
    background: #1a2540;
}

/* CUT button */
.btn-cut {
    background: #f0ad4e;
    color: #000;
    font-weight: 700;
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    padding: 6px 12px;
    border-radius: 4px;
    border: none;
    cursor: pointer;
    transition: background 0.15s;
}

.btn-cut:hover {
    background: #ec971f;
}

/* ── Audio mixer (compact) ── */
.audio-tracks {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.mixer-track-compact {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 3px 0;
    border-bottom: 1px solid #1e2a44;
}

.mixer-track-header {
    display: flex;
    align-items: center;
    gap: 4px;
}

.mixer-track-compact .track-label {
    font-size: 0.6rem;
    color: #8888aa;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.mute-btn {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    border-radius: 3px;
    border: 1px solid #2a2a4a;
    background: transparent;
    color: #e0e0e0;
    cursor: pointer;
    font-size: 0.55rem;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
}

.mute-btn:hover { background: #1e2a44; }

.mixer-track-compact.muted .mute-btn {
    background: #e63946;
    border-color: #e63946;
    color: #fff;
}

.vu-meter {
    width: 100%;
    height: 8px;
    border-radius: 2px;
    background: #0a0a1a;
}

.vol-slider {
    width: 100%;
    accent-color: #4d8dff;
    height: 12px;
}

.mixer-track-compact.muted .vol-slider { opacity: 0.35; }

/* Per-strip monitor toggle — dim when the strip is out of the monitor mix
   (mix-minus); never affects program audio. */
.monitor-btn {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    margin-left: auto;
    border-radius: 3px;
    border: 1px solid #2a2a4a;
    background: transparent;
    color: #e0e0e0;
    cursor: pointer;
    font-size: 0.55rem;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0.3;
}

.monitor-btn:hover { background: #1e2a44; }
.monitor-btn.on { opacity: 1; border-color: #4d8dff; }

/* Monitor bus — lives in the bottom toolbar next to Destinations (both are
   outputs): master toggle + level inline, per-output toggles like the
   destination checkboxes, details in the Monitor Outputs drawer. */
.monitor-level {
    width: 70px;
    accent-color: #4d8dff;
}

.monitor-output-label {
    display: inline-block;
    max-width: 11ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
}

.monitor-card-device {
    flex: 1;
    font-size: 0.75rem;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.monitor-agent-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 0;
}

.monitor-agent-row .btn { margin-left: auto; }

/* Preview canvas in studio mode */
#compositor-canvas-preview {
    width: 100%;
    height: 100%;
    display: block;
    background: #000;
}

/* ── Commentary Layout ── */
.commentary-layout {
    display: grid;
    grid-template-columns: 420px 1fr;
    grid-template-rows: 1fr auto;
    grid-template-areas:
        "panel feed"
        "panel controls";
    height: 100vh;
    background: #0f0a05;
    color: #f4ead8;
}

.commentary-layout > .board-feed { grid-area: feed; }
.commentary-layout > .commentary-controls { grid-area: controls; }
.commentary-layout > .commentator-match-panel-slot {
    grid-area: panel;
    padding: 10px 0 10px 10px;
    min-height: 0;
    display: flex;
}

@media (max-width: 900px) {
    .commentary-layout {
        grid-template-columns: 1fr;
        grid-template-rows: auto 1fr auto;
        grid-template-areas: "panel" "feed" "controls";
    }
    .commentary-layout > .commentator-match-panel-slot {
        padding: 10px;
        height: 60vh;
    }
}

/* View-config variants — the commentator can drop the side panel and/or the
   bottom controls bar so the feed goes edge-to-edge. Higher specificity than
   the base + mobile rules, so these win in both. */
.commentary-layout.no-panel {
    grid-template-columns: 1fr;
    grid-template-areas:
        "feed"
        "controls";
}
.commentary-layout.no-controls {
    grid-template-rows: 1fr;
    grid-template-areas: "panel feed";
}
.commentary-layout.no-panel.no-controls {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr;
    grid-template-areas: "feed";
}

/* Floating essentials over the feed (always present, so a full-screen feed
   never strands the commentator without mic / settings / leave). */
.feed-toolbar {
    position: absolute;
    top: 12px;
    right: 12px;
    display: flex;
    gap: 8px;
    z-index: 20;
}
.feed-toolbar .ft-btn {
    width: 38px;
    height: 38px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.05rem;
    line-height: 1;
    border-radius: 9px;
    border: 1px solid #3a2a18;
    background: rgba(26, 18, 10, 0.82);
    color: #f4ead8;
    cursor: pointer;
    transition: background .12s, border-color .12s, transform .06s;
}
.feed-toolbar .ft-btn:hover { background: rgba(58, 42, 24, 0.92); }
.feed-toolbar .ft-btn:active { transform: translateY(1px); }
.feed-toolbar .ft-btn.active { border-color: #ffc85a; color: #ffc85a; }
.feed-toolbar .ft-btn.muted { border-color: #b4472e; color: #ff9d84; }
.feed-toolbar .ft-btn.leave:hover { background: #7a2416; border-color: #b4472e; }

/* Settings popover */
.feed-settings {
    position: absolute;
    top: 58px;
    right: 12px;
    z-index: 20;
    width: 220px;
    padding: 10px 12px 12px;
    background: rgba(20, 14, 8, 0.96);
    border: 1px solid #3a2a18;
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .5);
    color: #f4ead8;
}
.feed-settings .fs-title {
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: #b79a72;
    font-weight: 700;
    margin-bottom: 6px;
}
.feed-settings .fs-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 2px;
    font-size: .82rem;
    cursor: pointer;
    user-select: none;
}
.feed-settings .fs-row.master { font-weight: 600; }
.feed-settings .fs-row input[type=checkbox] { accent-color: #ffc85a; cursor: pointer; }
.feed-settings .fs-sub {
    margin: 2px 0 2px 10px;
    padding-left: 8px;
    border-left: 1px solid #3a2a18;
}
.feed-settings .fs-reset {
    margin-top: 8px;
    width: 100%;
    padding: 5px;
    font-size: .74rem;
    border-radius: 6px;
    border: 1px solid #3a2a18;
    background: transparent;
    color: #b79a72;
    cursor: pointer;
}
.feed-settings .fs-reset:hover { border-color: #ffc85a; color: #ffc85a; }

.board-feed {
    flex: 1;
    display: flex;
    flex-direction: column;
    background: #000;
    position: relative;
    min-height: 0;
}

/* The video region — the self-view sits in its own strip BELOW this, never over
   the feed. Centres the 16:9 stage and hosts the floating toolbar/overlays. */
.commentary-stage-area {
    flex: 1;
    position: relative;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* The fixed 16:9 stage: the largest 16:9 box centred in the region (the classic
   absolute + inset:0 + margin:auto + max-* trick). The board video AND the scene
   overlay iframe both fill it, so the HTML overlay (names/score/clock) lines up
   with the frame exactly regardless of the region's own shape. */
.commentary-stage-area .commentary-stage {
    position: absolute;
    inset: 0;
    margin: auto;
    aspect-ratio: 16 / 9;
    max-width: 100%;
    max-height: 100%;
}

.commentary-stage .commentary-board-video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: #000;
}

/* The scene overlay, rendered by the OverlayScene page in a transparent iframe
   sized to the stage — its own 16:9 layout then matches the video. */
.commentary-overlay-frame {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
    background: transparent;
    pointer-events: none;
    z-index: 10;
}

/* Self-view strip — BELOW the video, so it never covers any of the broadcast.
   A small mirrored tile plus a label; hidden (display) when the camera is off or
   the commentator turns it off in settings. */
.commentary-self-strip {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 12px;
    background: #0a0704;
    border-top: 1px solid #3a2a18;
}

.commentary-self-strip .commentary-self-view {
    width: 132px;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    border: 2px solid #ffc85a;
    border-radius: 6px;
    background: #000;
    transform: scaleX(-1); /* mirror, like a selfie */
}

.commentary-self-strip .self-view-label {
    font-size: 0.8rem;
    color: #c9b896;
    letter-spacing: 0.02em;
}

/* Non-blocking status note (e.g. camera unavailable) at the foot of the feed. */
.feed-note {
    position: absolute;
    left: 50%;
    bottom: 12px;
    transform: translateX(-50%);
    max-width: 80%;
    padding: 6px 12px;
    background: rgba(26, 18, 10, 0.92);
    border: 1px solid #b4472e;
    color: #ffd9c9;
    border-radius: 8px;
    font-size: 0.85rem;
    text-align: center;
    z-index: 20;
}

.join-overlay,
.connecting-overlay,
.error-overlay {
    text-align: center;
    padding: 2rem;
}

.commentary-controls {
    padding: 12px 16px;
    background: #1a120a;
    border-top: 1px solid #3a2a18;
    display: flex;
    align-items: center;
    gap: 16px;
}

.mic-status {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* ── Source Slot Cards ── */
.sources-group {
    min-width: 200px !important;
}

.slot-cards {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-bottom: 8px;
}

.slot-card {
    background: #0a0a1a;
    border: 1px solid #2a2a4a;
    border-radius: 4px;
    padding: 5px 8px;
}

.slot-card.bound {
    border-color: #2d6a4f;
}

.slot-card-header {
    display: flex;
    align-items: center;
    gap: 5px;
    margin-bottom: 4px;
}

.slot-card-indicator {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    flex-shrink: 0;
}

.slot-card.bound .slot-card-indicator {
    background: #4ccd7b;
}

.slot-card.unbound .slot-card-indicator {
    background: #555;
}

.slot-card.selected {
    border-color: #0096ff;
    box-shadow: 0 0 4px rgba(0,150,255,0.3);
}

.slot-card-name {
    font-size: 0.72rem;
    font-weight: 600;
    color: #d0d0e0;
    text-transform: capitalize;
    flex-grow: 1;
}

.st-reset-btn {
    font-size: 0.65rem;
    padding: 0 4px;
    line-height: 1;
    color: #888;
    border: none;
    background: none;
}

.st-reset-btn:hover { color: #e63946; }

.st-adjust-btn {
    font-size: 0.75rem;
    padding: 0 4px;
    line-height: 1;
    color: #888;
    border: none;
    background: none;
}

.st-adjust-btn:hover { color: #ffc85a; }
.st-adjust-btn.active { color: #ffc85a; text-shadow: 0 0 6px rgba(255, 200, 90, .8); }

.slot-transform-info {
    display: flex;
    gap: 6px;
    font-size: 0.6rem;
    color: #6b7280;
    margin-top: 3px;
}

.slot-card-select {
    background: #0f1629 !important;
    color: #e0e0e0 !important;
    border: 1px solid #2a2a4a !important;
    font-size: 0.7rem !important;
    padding: 2px 6px !important;
    width: 100%;
}

.slot-empty-hint {
    font-size: 0.65rem;
    color: #666;
    font-style: italic;
    margin-bottom: 6px;
}
.sources-loading {
    color: #8ab4f8;
    animation: pulse-loading 1.5s ease-in-out infinite;
}
@keyframes pulse-loading {
    0%, 100% { opacity: .5; }
    50% { opacity: 1; }
}

.cameras-section {
    border-top: 1px solid #1e2a44;
    padding-top: 6px;
    margin-top: 2px;
}

.cameras-header {
    font-size: 0.6rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: #6b7280;
    margin-bottom: 4px;
}

/* ── Right drawer — shared slide-over for admin panels on full-screen
     pages (destinations today; future producer panels slot in the same
     way). Full-width on phones. ── */
.right-drawer-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 1040;
}

.right-drawer {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(440px, 100vw);
    background: #0f1629;
    border-left: 1px solid #2a2a4a;
    box-shadow: -8px 0 24px rgba(0, 0, 0, 0.45);
    z-index: 1050;
    display: flex;
    flex-direction: column;
    animation: right-drawer-in 0.18s ease-out;
}

@keyframes right-drawer-in {
    from { transform: translateX(100%); }
    to { transform: translateX(0); }
}

.right-drawer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    border-bottom: 1px solid #2a2a4a;
    color: #e0e0e0;
    font-weight: 600;
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.right-drawer-close {
    background: none;
    border: 1px solid #2a2a4a;
    border-radius: 4px;
    color: #8888aa;
    cursor: pointer;
    width: 32px;
    height: 32px;
    line-height: 1;
}

.right-drawer-close:hover {
    color: #e0e0e0;
    border-color: #8888aa;
}

.right-drawer-body {
    flex: 1;
    overflow-y: auto;
    padding: 12px 16px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* ── Destination cards inside the drawer ── */
.dest-card {
    background: #131b30;
    border: 1px solid #2a2a4a;
    border-radius: 6px;
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.dest-card-head {
    display: flex;
    align-items: center;
    gap: 10px;
}

.dest-card-head .dest-card-platform {
    flex: 1;
}

.dest-card-enabled {
    display: flex;
    align-items: center;
    gap: 5px;
    color: #b0b0c8;
    font-size: 0.8rem;
    cursor: pointer;
    margin: 0;
    white-space: nowrap;
}

.dest-field {
    display: flex;
    flex-direction: column;
    gap: 3px;
    margin: 0;
}

.dest-field > span {
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #8888aa;
}

.dest-add-card {
    border-style: dashed;
}

.dest-add-title {
    color: #e0e0e0;
    font-size: 0.85rem;
    font-weight: 600;
}

.dest-add-btn {
    align-self: flex-end;
}

.dest-input {
    background: #0a0a1a !important;
    color: #e0e0e0 !important;
    border: 1px solid #2a2a4a !important;
    font-size: 0.75rem !important;
}

select.dest-input {
    padding-right: 22px;
}

.dest-hint {
    font-size: 0.7rem;
    padding: 2px 4px 0;
}

/* ── Commentators panel inside the drawer ── */
.commentator-panel {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.commentator-intro {
    font-size: 0.8rem;
    color: #b0b0c8;
    line-height: 1.4;
    margin: 0;
}

.commentator-invite {
    display: flex;
    gap: 8px;
}

.commentator-invite .form-control {
    background: #0a0a1a !important;
    color: #e0e0e0 !important;
    border: 1px solid #2a2a4a !important;
    font-size: 0.8rem !important;
}

.commentator-invite .btn {
    white-space: nowrap;
}

.commentator-invite-field {
    position: relative;
    flex: 1;
}

.user-search-dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    margin-top: 3px;
    z-index: 30;
    background: #131b30;
    border: 1px solid #2a2a4a;
    border-radius: 6px;
    max-height: 220px;
    overflow-y: auto;
    box-shadow: 0 8px 24px rgba(0,0,0,.5);
}

.user-search-item {
    display: block;
    width: 100%;
    text-align: left;
    padding: 7px 10px;
    background: none;
    border: none;
    color: #e0e0e0;
    font-size: 0.82rem;
    cursor: pointer;
}

.user-search-item:hover {
    background: rgba(255,138,60,.14);
}

.user-search-empty {
    padding: 7px 10px;
    color: #8888aa;
    font-size: 0.78rem;
}

.commentator-error {
    color: #ff8a8a;
    font-size: 0.8rem;
}

.commentator-message {
    color: #7fd68a;
    font-size: 0.8rem;
}

.commentator-section-title {
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #8888aa;
    margin-top: 4px;
}

.commentator-empty {
    font-size: 0.8rem;
    color: #8888aa;
}

.commentator-row {
    display: flex;
    align-items: center;
    gap: 10px;
    background: #131b30;
    border: 1px solid #2a2a4a;
    border-radius: 6px;
    padding: 8px 10px;
}

.commentator-name {
    flex: 1;
    color: #e0e0e0;
    font-size: 0.85rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.commentator-enabled {
    display: flex;
    align-items: center;
    gap: 5px;
    color: #b0b0c8;
    font-size: 0.8rem;
    cursor: pointer;
    margin: 0;
    white-space: nowrap;
}

.commentator-pending {
    border-style: dashed;
}

.commentator-expiry {
    font-size: 0.7rem;
    color: #8888aa;
    white-space: nowrap;
}

/* Validation and command failures as visible text — a disabled button's
   tooltip doesn't exist on touch, and a silent failure reads as "broken". */
.dest-validation,
.dest-error {
    font-size: 0.75rem;
    color: #ffb3a3;
    background: rgba(255, 99, 71, 0.12);
    border: 1px solid rgba(255, 99, 71, 0.5);
    border-radius: 6px;
    padding: 4px 8px;
}

/* ── Narrow viewports (phone portrait): the drawer takes the full width.
     The producer is a landscape page on phones, so this only kicks in if
     someone insists on portrait. ── */
@media (max-width: 640px) {
    .right-drawer {
        width: 100vw;
        border-left: none;
    }
}

/* ── Phones, portrait or landscape: the controls strip eats the viewport —
     the video shrinks to a stamp. Collapse it into a panel the toolbar's
     Controls button expands. Expanded it keeps the desktop column layout;
     equal-share columns would crush to a fifth of a phone screen, so each
     keeps a usable fixed width and the strip scrolls sideways (it already
     has overflow-x). Desktop is untouched. ── */
@media (max-width: 820px), (max-height: 540px) {
    .toolbar-mobile-only {
        display: flex;
    }

    .producer-controls {
        display: none;
    }

    .producer-controls.open {
        display: flex;
    }

    .producer-controls.open .control-group {
        flex: 0 0 min(78vw, 300px);
    }
}

/* ── Touch devices, any orientation — a landscape phone is ~850px wide and
     must NOT get mouse-sized controls. 16px input text also stops iOS
     Safari from zooming the page on focus. ── */
@media (pointer: coarse) {
    .right-drawer .dest-input {
        font-size: 16px !important;
        min-height: 42px;
    }

    .right-drawer .dest-add-btn,
    .right-drawer .dest-card-head .btn,
    .right-drawer-close {
        min-height: 44px;
        min-width: 44px;
    }

    .dest-card-enabled input[type="checkbox"] {
        width: 20px;
        height: 20px;
    }
}

/* ── PTZ (Insta360 LINK pan/tilt/zoom) ───────────────────────────────────── */

/* Per-camera adjust trigger in the source rows — quiet until hovered, then the
   golden accent that marks an interactive control here. */
.source-ptz-btn {
    background: none;
    border: none;
    color: #8a7a3a;
    cursor: pointer;
    font-size: 0.72rem;
    padding: 0 2px;
    line-height: 1;
    flex-shrink: 0;
}

.source-ptz-btn:hover { color: #f0c419; }

/* Adjustment panel body (inside the RightDrawer). */
.ptz-panel {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    padding: 6px 2px 2px;
}

.ptz-panel-head {
    display: flex;
    align-items: center;
    gap: 8px;
    align-self: stretch;
}

.ptz-panel-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
    color: #e8e8f2;
}

.ptz-panel-model {
    font-size: 0.62rem;
    padding: 1px 6px;
    border-radius: 999px;
    background: rgba(77, 141, 255, 0.16);
    border: 1px solid rgba(77, 141, 255, 0.4);
    color: #9fc0ff;
    flex-shrink: 0;
}

.ptz-target-pick {
    align-self: stretch;
    display: flex;
    flex-direction: column;
    gap: 3px;
    font-size: 0.68rem;
    color: #9fb0c7;
}

/* Directional pad — three rows: up / (left · center · right) / down. */
.ptz-pad {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
}

.ptz-pad-row {
    display: flex;
    gap: 6px;
}

.ptz-dir {
    width: 46px;
    height: 46px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.05rem;
    color: #d7e2f5;
    background: #0d1226;
    border: 1px solid #2a3a63;
    border-radius: 8px;
    cursor: pointer;
    user-select: none;
    -webkit-user-select: none;
    touch-action: none; /* pointer hold must not scroll or long-press-select */
    transition: background 0.08s, border-color 0.08s, color 0.08s;
}

.ptz-dir:hover { border-color: #4d8dff; }

/* Pressed = actively driving the gimbal — the golden "live" accent. */
.ptz-dir:active {
    background: #2a2410;
    border-color: #f0c419;
    color: #ffd95a;
}

.ptz-center {
    color: #9fb0c7;
    font-size: 1.15rem;
}

.ptz-center:active {
    background: #10202a;
    border-color: #4d8dff;
    color: #cfe6ff;
}

/* Zoom row: −  [ slider ]  + */
.ptz-zoom {
    display: flex;
    align-items: center;
    gap: 8px;
    align-self: stretch;
}

.ptz-zoom-range {
    flex: 1;
    accent-color: #f0c419;
}

.ptz-zoom-btn {
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.1rem;
    line-height: 1;
    color: #d7e2f5;
    background: #0d1226;
    border: 1px solid #2a3a63;
    border-radius: 6px;
    cursor: pointer;
}

.ptz-zoom-btn:hover { border-color: #4d8dff; }
.ptz-zoom-btn:active { border-color: #f0c419; color: #ffd95a; }

.ptz-hint {
    align-self: stretch;
    font-size: 0.66rem;
    line-height: 1.35;
    color: #8b9bb4;
}
