/*
 * SCENE-CONTROL-SURFACE.CSS - Clean control panel
 * 
 * A proper control surface with:
 * - Inset beveled panel with metallic frame
 * - LED status cluster
 * - Clean data fields (character-accented)
 * - Uniform selector bays for Select2
 * - Separated action deck for buttons
 * - Collapsible prompt drawer
 */

/* ═══════════════════════════════════════════════════════════════════
   CSS VARIABLES - Scene uses warm amber tones
   ═══════════════════════════════════════════════════════════════════ */

.scene-control-surface {
    /* Directional hair→eyes sweep across the bar (left→right), like the header —
       a deliberate 2-color gradient, NOT a uniform wash. The buttons are opaque
       now, so this tints the surface without bleeding through them. */
    --surface-bg: linear-gradient(90deg,
        color-mix(in srgb, var(--primary) 14%, var(--card-base)) 0%,
        color-mix(in srgb, var(--secondary) 14%, var(--card-base)) 100%);
    --panel-bg: linear-gradient(90deg,
        color-mix(in srgb, var(--primary) 14%, var(--card-base)) 0%,
        color-mix(in srgb, var(--secondary) 14%, var(--card-base)) 100%);
    --panel-border-outer: var(--card-base);
    --panel-border-inner: rgba(255, 255, 255, 0.2);
    --panel-inset: inset 0 2px 6px rgba(0, 0, 0, 0.3),
                   inset 0 -1px 0 rgba(255, 255, 255, 0.1);

    /* Display colors */
    --display-bg: var(--card-base);
}

/* ═══════════════════════════════════════════════════════════════════
   MAIN CONTAINER - Outer frame with character-themed border
   ═══════════════════════════════════════════════════════════════════ */

.scene-control-surface {
    width: 100%;
    background: var(--surface-bg);
    border-radius: 12px;
    padding: 4px;
    /* Plain grey 2px frame — was slot-tinted via outfit-accent, but
       outfit is rarely set outside admin, and the color-mix would
       collapse to near-invisible alpha when --outfit-accent was
       transparent. Solid grey reads as "beveled control surface"
       on every character regardless of which slots are populated. */
    border: 2px solid rgba(255, 255, 255, 0.15);
    box-shadow:
        0 4px 20px rgba(0, 0, 0, 0.4),
        0 0 12px transparent,
        inset 0 1px 0 rgba(255, 255, 255, 0.06);
    transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

.scene-control-surface:hover {
    border-color: rgba(255, 255, 255, 0.22);
    box-shadow:
        0 6px 25px rgba(0, 0, 0, 0.5),
        0 0 18px transparent,
        inset 0 1px 0 rgba(255, 255, 255, 0.08);
}

/* ═══════════════════════════════════════════════════════════════════
   CONTROL PANEL - The beveled inset housing
   ═══════════════════════════════════════════════════════════════════ */

.control-panel {
    background: var(--panel-bg);
    border-radius: 10px;
    border: 1px solid var(--panel-border-outer);
    box-shadow: var(--panel-inset);
    padding: 0;
    overflow: hidden;
}

/* ═══ Generate — the 6th transport button. Base is plain .generate-btn. The
   block below is a SELF-CONTAINED copy of the card-front circular treatment
   (3px tread ring, 1.4rem icon, base treads in sync with the icon, conic-fill
   progress ring) so it matches the card-front / generate-card trio — without
   touching any shared class, so nothing else changes. Card-only bits (display,
   absolute corner, card-zoom) are dropped; everything else is verbatim. ═══ */
/* Let the straddling button poke through the toolbar's top border. The tray
   keeps its own radius + border, so opening the panel only reveals the button's
   overhang — nothing else leaks. */
.scene-control-surface:not(.scene-control-surface--header) .control-panel { overflow: visible; }

/* ── Where-am-i TAB, notched INTO the toolbar frame (grid) ────────────────────
   The footer surface becomes a 2×2 grid whose top row is [tab | open edge] and
   whose body spans below. The frame's 2px border is drawn by the grid boxes so
   the tab is a genuine NOTCH in the top border (open bottom → its interior is the
   toolbar's), left-aligned with the frame's left border — not a float over it.
   Engages ONLY when a tab is present (:has), so a no-context toolbar is unchanged.
   The top row is mostly transparent (carousel shows through) except the tab + the
   top-border line, matching "a 3rd row, transparent but for the tab cutout".
   Neutral text — legibility is the whole point (a black outfit must not hide it). */
.scene-control-surface:not(.scene-control-surface--header):has(.scs-tab) {
    display: grid;
    grid-template-columns: auto 1fr auto;   /* left tab | top-border | RIGHT (mirror) tab */
    /* Row 1 is ZERO height so the tab OVERLAPS upward into the preview (like the
       generate button) instead of adding a row that pushes the toolbar down. */
    grid-template-rows: 0 1fr;
    border: none;                     /* frame moves onto the grid boxes below */
    padding: 0;
    background: transparent;
    overflow: visible;                /* let the tab poke up out of the surface */
}
.scene-control-surface:not(.scene-control-surface--header) .scs-tab {
    grid-row: 1;
    grid-column: 1;
    align-self: end;                  /* bottom on the frame's top line; height extends UP into the preview */
    box-sizing: border-box;
    height: 26px;                     /* how far the tab pokes up; SVG ramp matches this */
    position: relative;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;          /* centre the label — symmetric tabs */
    width: 80px;                      /* fixed ~7-char width; both tabs match */
    padding: 0 6px;
    /* LEFT tab: HAIR fill (gradient's left stop). Border is neutral grey — like the
       rest of the chrome; works with any character + keeps the edges crisp. */
    --scs-tab-fill: color-mix(in srgb, var(--primary) 14%, var(--card-base));
    --scs-tab-border: rgba(255, 255, 255, 0.15);
    border: 2px solid var(--scs-tab-border);
    border-bottom: none;              /* OPEN bottom — the tab's interior IS the toolbar's */
    border-right: none;               /* the SVG ramp draws the diagonal right edge */
    border-radius: 8px 0 0 0;
    background: var(--scs-tab-fill);
    /* Raised bevel — a top-edge inner highlight so the tab reads as catching light
       on its rounded-over top, like the original surface's inset highlight (which
       the notch redesign dropped). Pairs with the grey border = a soft bevelled lip. */
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
    font-size: 0.66rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.85);
    white-space: nowrap;
}
/* Rounded 45° '\' ramp (SVG) — hair fill + 2px frame stroke on the curve, open
   bottom, landing on the toolbar's top line. Sized to match the tab height so the
   viewBox renders 1:1 (no distortion). The Bézier control points in the template
   are the shape knobs (how round each corner is). */
.scene-control-surface:not(.scene-control-surface--header) .scs-tab-ramp {
    position: absolute;
    left: 100%;
    bottom: 0;
    width: 26px;                      /* horizontal run = height ⇒ ~45° */
    height: 26px;
    overflow: visible;
}
.scene-control-surface:not(.scene-control-surface--header) .scs-tab-ramp-fill {
    fill: var(--scs-tab-fill);        /* same muted-hair as the tab body (inherited) */
}
.scene-control-surface:not(.scene-control-surface--header) .scs-tab-ramp-line {
    fill: none;
    stroke: var(--scs-tab-border, rgba(255, 255, 255, 0.15));   /* inherits the tab's slot border colour */
    stroke-width: 2;
}
.scene-control-surface:not(.scene-control-surface--header) .scs-tab-edge {
    grid-row: 1;
    grid-column: 2;
    align-self: end;                  /* border-bottom lands on the frame's top line */
    height: 0;
    border-bottom: 2px solid rgba(255, 255, 255, 0.15);   /* plain grey, matches the chrome */
}
/* MIRROR tab (top-right) — the loved tab flipped, so the one square corner becomes
   a matching tab. Inherits .scs-tab; overrides put it in col 3 with the box's RIGHT
   border + a top-right radius, and flip the ramp to a '/' on its left. */
.scene-control-surface:not(.scene-control-surface--header) .scs-tab--right {
    grid-column: 3;
    /* RIGHT tab: EYES fill (gradient's right stop); grey border like the left. */
    --scs-tab-fill: color-mix(in srgb, var(--secondary) 14%, var(--card-base));
    border-left: none;                /* the flipped ramp draws the left edge */
    border-right: 2px solid var(--scs-tab-border);   /* = the box's right border */
    border-radius: 0 8px 0 0;         /* top-right */
    padding: 0 6px;
}
.scene-control-surface:not(.scene-control-surface--header) .scs-tab--right .scs-tab-ramp {
    left: auto;
    right: 100%;                      /* ramp on the tab's LEFT */
    transform: scaleX(-1);            /* '\' → '/' */
}
/* Body — BOTH button rows wrapped in one cell (row 2, spanning). It carries the
   frame's left/right/bottom border + the toolbar gradient (the top border is drawn
   by the tab + edge above). Gated on :has(.scs-tab) so a no-context toolbar keeps
   the surface's own frame and .scs-body is just an invisible pass-through wrapper. */
.scene-control-surface:not(.scene-control-surface--header):has(.scs-tab) .scs-body {
    grid-row: 2;
    grid-column: 1 / -1;              /* span all three top columns (left tab | edge | right tab) */
    border: 2px solid rgba(255, 255, 255, 0.15);
    border-top: none;
    border-radius: 0 0 11px 11px;
    background: var(--surface-bg);
    /* Restore the surface's bevel highlight on the frame that now lives here — the
       original .scene-control-surface carried inset 0 1px 0 rgba(255,255,255,0.06). */
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
    padding: 4px;                     /* the old surface gap around the inner panel */
}

/* ═══════════════════════════════════════════════════════════════════
   HEADER FRAME TABS — the footer context tabs MIRRORED to poke DOWN off the
   header's bottom edge, framing the TOP of the carousel (symmetric with the
   footer's up-tabs). Same notch machinery flipped on Y: grid rows 1fr/0 (body,
   then a 0-height tab row at the BOTTOM), tabs align-self:start + extend DOWN,
   border on the bottom, ramp SVG scaleY(-1). Pure visual frame (no labels).
   Portrait/desktop; landscape dissolves it (below).
   ═══════════════════════════════════════════════════════════════════ */
.scene-control-surface--header:has(.scs-tab) {
    display: grid;
    grid-template-columns: auto 1fr auto;   /* left tab | bottom-border | right tab */
    grid-template-rows: 1fr 0;              /* body, then a 0-height tab row at the BOTTOM */
    border: none;                     /* frame moves onto the grid boxes below */
    padding: 0;
    background: transparent;
    overflow: visible;                /* let the tabs poke DOWN out of the header */
}
.scene-control-surface--header .scs-tab {
    grid-row: 2;
    grid-column: 1;
    align-self: start;                /* top on the frame's bottom line; height extends DOWN into the preview */
    box-sizing: border-box;
    height: 26px;                     /* how far the tab pokes down; SVG ramp matches this */
    position: relative;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 80px;
    padding: 0 6px;
    --scs-tab-fill: color-mix(in srgb, var(--primary) 14%, var(--card-base));
    --scs-tab-border: rgba(255, 255, 255, 0.15);
    border: 2px solid var(--scs-tab-border);
    border-top: none;                 /* OPEN top — the tab's interior IS the header's */
    border-right: none;               /* the SVG ramp draws the diagonal right edge */
    border-radius: 0 0 0 8px;         /* bottom-left */
    background: var(--scs-tab-fill);
    box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.1);   /* bottom-edge bevel highlight */
}
.scene-control-surface--header .scs-tab-ramp {
    position: absolute;
    left: 100%;
    top: 0;                           /* ramp rides the tab's TOP now (was bottom) */
    width: 26px;
    height: 26px;
    overflow: visible;
    transform: scaleY(-1);            /* flip the '\' ramp to curve DOWN to the header line */
}
.scene-control-surface--header .scs-tab-ramp-fill { fill: var(--scs-tab-fill); }
.scene-control-surface--header .scs-tab-ramp-line {
    fill: none;
    stroke: var(--scs-tab-border, rgba(255, 255, 255, 0.15));
    stroke-width: 2;
}
/* Button on the tab — the only hit target. TAPE-DECK grey: the .transport-btn recipe (matte
   white-over-card-base fill, raised bevel, brighten + press-in on hover). Neutral, so it
   always matches and stays readable regardless of the character's colors. (Swap the fill to
   --primary/--secondary or --outfit-top/bottom to try the slot-painted versions.) */
.scene-control-surface--header .scs-tab-btn {
    position: absolute;
    inset: 0 -1.5px 3px 4.5px;  /* pulled 2px DOWN off the header line; shifted right 3px */
    box-sizing: border-box;
    padding: 0 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 5px;
    background: color-mix(in srgb, white 5%, var(--card-base));
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.08),
        inset 0 -2px 3px rgba(0, 0, 0, 0.2);
    color: rgba(255, 255, 255, 0.5);
    text-decoration: none;   /* no underline if a tab-btn is ever an <a> */
    cursor: pointer;
    transition: all 0.12s ease;
    z-index: 4;
}
.scene-control-surface--header .scs-tab-btn:hover {
    background: color-mix(in srgb, white 9%, var(--card-base));
    color: var(--ui-text-strong);
    border-color: rgba(255, 255, 255, 0.18);
    box-shadow:
        inset 0 2px 4px rgba(0, 0, 0, 0.4),
        inset 0 -1px 0 rgba(255, 255, 255, 0.08);
}
.scene-control-surface--header .scs-tab-btn:active {
    transform: translateY(1px);
}
/* Overlays-ON state (the gallery TAGS toggle): persistent pressed-lit, like a
   held-down transport button. .active is toggled on by the overlay handler. */
.scene-control-surface--header .scs-tab-btn.active {
    background: color-mix(in srgb, white 9%, var(--card-base));
    color: var(--ui-text-strong);
    border-color: rgba(255, 255, 255, 0.18);
    box-shadow:
        inset 0 2px 4px rgba(0, 0, 0, 0.4),
        inset 0 -1px 0 rgba(255, 255, 255, 0.08);
}
/* Toggle tabs (USAGE + TAGS) read their in/out from .active (card up / overlays on),
   NOT from hover: otherwise the hover press masks a toggle-OFF and the button
   "sticks" pushed-in until the cursor leaves. So while OFF, hover stays RAISED (just
   brightens) — the pressed bevel is reserved for .active — and a click flips it in/out. */
.scene-control-surface--header .scs-tab-btn--toggle:not(.active):hover {
    background: color-mix(in srgb, white 9%, var(--card-base));
    color: var(--ui-text-strong);
    border-color: rgba(255, 255, 255, 0.18);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.08),
        inset 0 -2px 3px rgba(0, 0, 0, 0.2);
}
/* Eyes-tab button — mirror of the hair-tab button: shifted LEFT. Same grey. */
.scene-control-surface--header .scs-tab-btn--right {
    inset: 0 4.5px 3px -1.5px;
}
/* ── FOOTER context-tab buttons — same grey; footer tabs poke UP so the button grows DOWN
   (insets flipped). Left carries the title. ── */
.scene-control-surface:not(.scene-control-surface--header) .scs-tab-btn {
    position: absolute;
    inset: 3px -1.5px 0 4.5px;   /* pulled 2px UP off the footer line; shifted right */
    box-sizing: border-box;
    padding: 0 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 5px;
    background: color-mix(in srgb, white 5%, var(--card-base));
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.08),
        inset 0 -2px 3px rgba(0, 0, 0, 0.2);
    color: rgba(255, 255, 255, 0.5);
    cursor: pointer;
    transition: all 0.12s ease;
    z-index: 4;
}
.scene-control-surface:not(.scene-control-surface--header) .scs-tab-btn:hover {
    background: color-mix(in srgb, white 9%, var(--card-base));
    color: var(--ui-text-strong);
    border-color: rgba(255, 255, 255, 0.18);
    box-shadow:
        inset 0 2px 4px rgba(0, 0, 0, 0.4),
        inset 0 -1px 0 rgba(255, 255, 255, 0.08);
}
.scene-control-surface:not(.scene-control-surface--header) .scs-tab-btn:active {
    transform: translateY(1px);
}
/* Footer toggle (the chat VOICE tab): same in/out read as the header toggles —
   .active = pressed-lit (card up), and while OFF hover stays RAISED so a tap flips
   it cleanly in/out. Footer needs its own copy to out-specify the footer :hover. */
.scene-control-surface:not(.scene-control-surface--header) .scs-tab-btn.active {
    background: color-mix(in srgb, white 9%, var(--card-base));
    color: var(--ui-text-strong);
    border-color: rgba(255, 255, 255, 0.18);
    box-shadow:
        inset 0 2px 4px rgba(0, 0, 0, 0.4),
        inset 0 -1px 0 rgba(255, 255, 255, 0.08);
}
.scene-control-surface:not(.scene-control-surface--header) .scs-tab-btn--toggle:not(.active):hover {
    background: color-mix(in srgb, white 9%, var(--card-base));
    color: var(--ui-text-strong);
    border-color: rgba(255, 255, 255, 0.18);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.08),
        inset 0 -2px 3px rgba(0, 0, 0, 0.2);
}
.scene-control-surface:not(.scene-control-surface--header) .scs-tab-btn--right {
    inset: 3px 4.5px 0 -1.5px;   /* mirrored horizontally */
}
/* Tab-button text — all-caps, small, letter-spaced to read as a control label. */
.scs-tab-label {
    font-size: 9px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    line-height: 1;
    white-space: nowrap;
}
.scene-control-surface--header .scs-tab-edge {
    grid-row: 2;
    grid-column: 2;
    align-self: start;                /* border-top lands on the frame's bottom line */
    height: 0;
    border-top: 2px solid rgba(255, 255, 255, 0.15);
}
.scene-control-surface--header .scs-tab--right {
    grid-column: 3;
    --scs-tab-fill: color-mix(in srgb, var(--secondary) 14%, var(--card-base));
    border-left: none;                /* the flipped ramp draws the left edge */
    border-right: 2px solid var(--scs-tab-border);
    border-radius: 0 0 8px 0;         /* bottom-right */
    padding: 0 6px;
}
.scene-control-surface--header .scs-tab--right .scs-tab-ramp {
    left: auto;
    right: 100%;                      /* ramp on the tab's LEFT */
    transform: scaleX(-1) scaleY(-1); /* mirror horizontally AND flip down */
}
.scene-control-surface--header:has(.scs-tab) .scs-body {
    grid-row: 1;
    grid-column: 1 / -1;              /* span all three columns */
    border: 2px solid rgba(255, 255, 255, 0.15);
    border-bottom: none;              /* the tabs + edge draw the bottom line */
    border-radius: 11px 11px 0 0;     /* top corners */
    background: var(--surface-bg);
    box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.06);
    padding-bottom: 3px;              /* 3px wrap between the buttons and the bottom border
                                         (the line between the tabs) — mirrors the footer/
                                         landscape button-to-frame gap */
}
/* Landscape (the rail): SHOW the frame tabs, PINNED — using the FOOTER's EXACT mechanism.
   The footer tab pins perfectly because it's position:ABSOLUTE inside its fixed rail (one
   fixed element, top:0/bottom:0, no overflow clip): it measures off the RAIL's box, so it
   rides the rail continuously on resize — no lag. We mirror that here. The header rail is
   also fixed top:0/bottom:0, so absolute positions map 1:1 to viewport coords (same on-screen
   spot as the old fixed values) but now they TRACK THE RAIL instead of the viewport → the
   hair stops lagging-then-snapping. The rail's overflow:hidden (which clips the vertical
   brand/username) is flipped to visible here so the absolute tabs can poke out; the text is
   re-clipped on the strip itself (below), same division of labor as the footer. */
/* min-width guard — see standalone-carousel.css: without it this overlapped the
   portrait `max-width:700px` rules, so both layouts applied at once and the rail
   header collided with the portrait fixed footer. Keep these three in step. */
@media (orientation: landscape) and (max-height: 600px) and (min-width: 701px) {
    /* Kill the portrait frame-tab GRID in landscape. It was leaking in: the tabs are
       position:absolute, and an absolute child of a GRID container is contained by its
       assigned grid AREA — hair→col1 (bottom-left), eyes→col3 (bottom-RIGHT). So eyes'
       top:/left: were measured from the bottom-right cell and it teleported off-screen.
       display:block → both tabs resolve against the rail's padding box, so top: = the real
       top border, bottom: = the real bottom border. This is what makes them pin. */
    .scene-control-surface--header:has(.scs-tab) {
        display: block;
    }
    .scene-control-surface--header .scs-body { display: contents; }
    /* Clip the vertical brand/username on its own strip (the rail itself no longer clips —
       it's set up plainly like the footer rail). The tabs live outside this strip. */
    body:has(.entity-2col) .scene-control-surface--header .aurora-header__strip {
        overflow: hidden;
    }
    /* Borderline between the two tabs — a vertical line, ABSOLUTE in the rail like the tabs.
       top: meets the EYES pin, bottom: meets the HAIR pin, so it stretches between them and
       rides the rail on resize. This is the frame's left edge. */
    .scene-control-surface--header .scs-tab-edge {
        display: block;
        position: absolute;
        top: 27px;                     /* meet the eyes tab (top) */
        bottom: 27px;                  /* meet the hair tab (bottom) */
        left: 96px;                    /* the tabs' rail-side edge */
        width: 2px;                    /* solid bar (not a border on a 0-width box) */
        height: auto;
        border: none;
        background: rgba(255, 255, 255, 0.15);   /* match the tab border tone */
        z-index: 49;                   /* just under the tabs — shows the frame in the gap */
    }
    /* ABSOLUTE inside the rail (NOT fixed) — the footer's mechanism. HAIR pinned to the
       BOTTOM border (bottom:), EYES to the TOP (top:). Center pivot → top/bottom/left ARE
       the real on-screen position. Frame the carousel's left edge. */
    .scene-control-surface--header .scs-tab {
        display: flex;
        position: absolute;
        bottom: 25px;                  /* HAIR — pinned to the BOTTOM border */
        top: auto;
        left: 67px;                    /* poke right of the rail */
        right: auto;
        width: 80px;
        height: 26px;
        z-index: 50;                   /* above the rail's inner content (deck/brand) — as
                                          position:absolute the tabs now live INSIDE the rail's
                                          stacking context, so the top-anchored eyes was being
                                          covered by the admin/brand content at the rail's top */
        transform-origin: center;
        transform: rotate(-90deg);
    }
    .scene-control-surface--header .scs-tab--right {
        top: 25px;                     /* EYES — pinned to the TOP border */
        bottom: auto;
        left: 67px;
        right: auto;
    }
}

.drawer-controls--transport .transport-btn--generate {
    /* placement + size for the row */
    flex: 0 0 auto;
    width: 60px;
    height: 60px;
    align-self: flex-end;
    /* 5px gap left/right, 3px bottom; negative top margin straddles the border.
       margin box = 60 − 15 + 3 = 48 = row (mobile: 56 − 15 + 3 = 44). */
    margin: -15px 5px 3px;
    z-index: 3;
    /* circle, icon-only */
    padding: 0;
    min-height: 0;
    border-radius: 50%;
}
.drawer-controls--transport .transport-btn--generate::before {
    border-radius: 50%;
    inset: -3px;
    padding: 3px;
    opacity: 0.95;
}
.drawer-controls--transport .transport-btn--generate .generate-icon { font-size: 1.4rem; }
.drawer-controls--transport .transport-btn--generate .generate-label { display: none; }
.drawer-controls--transport .transport-btn--generate .progress-gauge {
    position: absolute;
    inset: 2px;
    width: auto;
    height: auto;
    border-radius: 50%;
    pointer-events: none;
}
.drawer-controls--transport .transport-btn--generate .progress-bar {
    position: absolute;
    inset: 0;
    width: auto;
    height: auto;
    background: transparent;
    border: 2px solid rgba(255, 255, 255, 0.04);
    border-radius: 50%;
    overflow: visible;
}
.drawer-controls--transport .transport-btn--generate .progress-bar-fill {
    position: absolute;
    inset: 0;
    width: auto !important;
    height: auto;
    background: transparent;
    border: 2px solid var(--secondary);
    border-radius: 50%;
    box-shadow: 0 0 6px color-mix(in srgb, var(--secondary) 60%, transparent);
    mask: conic-gradient(from 0deg, black var(--progress, 0%), transparent var(--progress, 0%));
    -webkit-mask: conic-gradient(from 0deg, black var(--progress, 0%), transparent var(--progress, 0%));
}

/* ═══════════════════════════════════════════════════════════════════
   PANEL HEADER - Title bar with status LEDs
   ═══════════════════════════════════════════════════════════════════ */

.panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.6rem 0.8rem;
    background: linear-gradient(180deg,
        rgba(255, 255, 255, 0.03) 0%,
        transparent 50%,
        rgba(0, 0, 0, 0.2) 100%);
    border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

.header-left {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.panel-badge {
    font-size: 1rem;
    filter: drop-shadow(0 0 4px transparent);
}

.panel-title {
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.15em;
    color: var(--neutral);
}

.header-right {
    display: flex;
    align-items: center;
}

.scene-id {
    font-size: 0.7rem;
    font-family: 'SF Mono', Monaco, monospace;
    color: rgba(255, 255, 255, 0.5);
    padding: 0.2rem 0.5rem;
    background: rgba(0, 0, 0, 0.3);
    border-radius: 4px;
}

/* ═══════════════════════════════════════════════════════════════════
   PROFILE DRAWER - Beveled container for transport + settings
   ═══════════════════════════════════════════════════════════════════ */

.profile-drawer,
.action-panel {
    margin: 0.3rem 0.4rem;
    border-radius: 6px;
    overflow: hidden;
    border: 1px solid color-mix(in srgb, var(--primary) 15%, rgba(255, 255, 255, 0.06));
    /* Clean 2-stop hair → eyes — always-on character traits.
       Outfit slots were dropping out when disabled and leaving half the
       surface transparent. */
    background: linear-gradient(
        135deg,
        color-mix(in srgb, var(--primary) 18%, var(--card-base)) 0%,
        color-mix(in srgb, var(--secondary) 14%, var(--card-base)) 100%
    );
    transition: border-color 0.3s ease;
}

.profile-drawer:hover,
.action-panel:hover {
    border-color: color-mix(in srgb, var(--primary) 22%, rgba(255, 255, 255, 0.08));
}

/* Housing gives the transport bar top padding within the drawer */
.transport-housing {
    padding: 0.25rem 0.3rem 0.2rem;
    background: linear-gradient(180deg, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0.2) 100%);
}

/* Chevron button in transport bar */
.transport-btn--chevron {
    color: rgba(255, 255, 255, 0.35);
    width: 26px;
}

.transport-btn--chevron .chevron-svg {
    transition: transform 0.25s ease;
}

.transport-btn--chevron.active {
    color: var(--ui-text-strong);
}

.transport-btn--chevron.active .chevron-svg {
    transform: rotate(180deg);
}

/* Drawer content - collapse/expand */
.profile-drawer .drawer-content {
    overflow: hidden;
    transition: max-height 0.3s ease, opacity 0.25s ease;
    border-top: 1px solid rgba(0, 0, 0, 0.3);
}

.profile-drawer .drawer-content.collapsed {
    max-height: 0;
    opacity: 0;
    border-top-color: transparent;
}

.profile-drawer .drawer-content:not(.collapsed) {
    max-height: 400px;
    opacity: 1;
}

/* ═══════════════════════════════════════════════════════════════════
   DATA SECTION - Character-themed thumbnail + fields
   Uses --slot-1, --slot-2, --slot-3 from parent
   ═══════════════════════════════════════════════════════════════════ */

.data-section {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.75rem;
    margin: 0.6rem;
    padding: 0.6rem;
    /* Brighter background to reduce accent contrast */
    background: linear-gradient(
        135deg,
        color-mix(in srgb, var(--primary) 20%, var(--card-base)) 0%,
        color-mix(in srgb, var(--secondary) 15%, var(--card-base)) 50%,
        var(--card-base) 100%
    );
    border-radius: 6px;
    border: 1px solid rgba(255, 255, 255, 0.06);
    box-shadow: 
        inset 0 1px 0 color-mix(in srgb, var(--primary) 8%, transparent),
        0 2px 8px rgba(0, 0, 0, 0.15);
    transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

.data-section:hover {
    border-color: rgba(255, 255, 255, 0.08);
    box-shadow: 
        inset 0 1px 0 color-mix(in srgb, var(--primary) 12%, transparent),
        0 4px 12px transparent;
}

/* Thumbnail - character-accented border with glow */
.data-thumbnail {
    width: 90px;
    align-self: stretch;
    border-radius: 4px;
    overflow: hidden;
    background: linear-gradient(
        135deg,
        color-mix(in srgb, var(--primary) 12%, rgba(0, 0, 0, 0.4)) 0%,
        rgba(0, 0, 0, 0.35) 100%
    );
    /* Softer accent border */
    border: 2px solid rgba(255, 255, 255, 0.1);
    box-shadow: 
        0 0 8px transparent,
        inset 0 0 20px rgba(0, 0, 0, 0.4);
    transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

.data-section:hover .data-thumbnail {
    border-color: rgba(255, 255, 255, 0.15);
    box-shadow: 
        0 0 14px transparent,
        inset 0 0 20px rgba(0, 0, 0, 0.4);
}

.thumbnail-img {
    width: 100%;
    height: 200%;  /* Show only top half */
    object-fit: cover;
    object-position: top center;
}

.thumbnail-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    color: rgba(255, 255, 255, 0.15);
}

/* Grid of label/value pairs - styled as mini read-only fields */
.data-grid {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.35rem 0.5rem;
    align-content: center;
}

.data-label {
    font-size: 0.55rem;
    font-weight: 700;
    color: var(--neutral);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    align-self: center;
    padding-right: 0.25rem;
}

.data-value {
    font-size: 0.75rem;
    font-weight: 500;
    color: rgba(255, 255, 255, 0.9);
    align-self: center;
    padding: 0.3rem 0.5rem;
    background: rgba(0, 0, 0, 0.2);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-left: 2px solid transparent;
    border-radius: 4px;
    transition: border-color 0.2s ease, background 0.2s ease;
}

.data-value:hover {
    border-left-color: transparent;
    background: rgba(0, 0, 0, 0.3);
}

/* Caption - can wrap, italic style */
.data-value--caption {
    font-size: 0.7rem;
    font-style: italic;
    color: rgba(255, 255, 255, 0.7);
    line-height: 1.3;
    border-left-color: color-mix(in srgb, var(--secondary) 60%, transparent);
}

.data-value--caption:hover {
    border-left-color: var(--secondary);
}

/* Monospace values - seed display */
.data-value--mono,
.data-grid .seed-value--inline {
    font-family: 'SF Mono', Monaco, monospace;
    font-size: 0.7rem;
    letter-spacing: 0.02em;
    color: color-mix(in srgb, var(--primary) 80%, white);
    border-left-color: color-mix(in srgb, var(--primary) 60%, transparent);
}

.data-value--mono:hover,
.data-grid .seed-value--inline:hover {
    border-left-color: var(--primary);
}

/* Status indicator */
.data-value--status {
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: rgba(255, 255, 255, 0.6);
    border-left-color: rgba(74, 222, 128, 0.5);
}

.data-value--status:hover {
    border-left-color: rgba(74, 222, 128, 0.8);
}

/* Environment value */
.data-value--env {
    color: rgba(255, 255, 255, 0.85);
    border-left-color: color-mix(in srgb, var(--slot-12) 60%, transparent);
}

.data-value--env:hover {
    border-left-color: var(--slot-12);
}

/* ═══════════════════════════════════════════════════════════════════
   THUMBNAIL LINK - Clickable image with hover overlay
   ═══════════════════════════════════════════════════════════════════ */

.data-thumbnail--link {
    display: block;
    position: relative;
    text-decoration: none;
    cursor: pointer;
}

.data-thumbnail--link:hover {
    border-color: var(--neutral);
    box-shadow:
        0 0 14px transparent,
        inset 0 0 20px rgba(0, 0, 0, 0.4);
}

.thumbnail-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.5);
    color: var(--neutral);
    opacity: 0;
    transition: opacity 0.2s ease;
    border-radius: 2px;
}

.data-thumbnail--link:hover .thumbnail-overlay {
    opacity: 1;
}

.thumbnail-overlay svg {
    filter: drop-shadow(0 0 6px currentColor);
}

/* ═══════════════════════════════════════════════════════════════════
   DRAWER BODY - Extension of transport control surface
   Recessed tray matching .transport-bar--main bevels.
   ═══════════════════════════════════════════════════════════════════ */

.drawer-body {
    padding: 0.25rem 0.3rem 0.3rem;
    background: linear-gradient(180deg, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0.2) 100%);
}

/* Button tray — a SOLID neutral well, one shade darker than the matte-grey
   buttons so they read as raised on it (no gradient, no black). Tight matched
   padding (all sides) so the buttons dominate the tray, not the frame. */
.drawer-controls {
    display: flex;
    align-items: stretch;
    gap: 2px;
    padding: 2px;
    background: color-mix(in srgb, black 10%, var(--card-base));
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, 0.06);
}

/* Tactile drawer button — mirrors .transport-btn, stacked icon + tiny label */
.drawer-btn {
    flex: 0 0 48px;
    width: 48px;
    height: 48px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: 0 0.35rem;
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 5px;
    /* Matte grey, opaque (no panel wash bleeding through) with a faint raised
       bevel — state changes ride brightness + bevel, not a metallic gradient. */
    background: color-mix(in srgb, white 5%, var(--card-base));
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.06),
        inset 0 -2px 3px rgba(0, 0, 0, 0.2);
    color: rgba(255, 255, 255, 0.55);
    cursor: pointer;
    transition: all 0.12s ease;
    flex-shrink: 0;
}

.drawer-btn:hover {
    /* Brighter matte grey + pressed bevel (top-dark inset) — no metallic
       gradient, no heavy outline. Grey icon, not slot-1 (black hair vanishes). */
    background: color-mix(in srgb, white 9%, var(--card-base));
    color: var(--ui-text-strong);
    border-color: rgba(255, 255, 255, 0.18);
    box-shadow:
        inset 0 2px 4px rgba(0, 0, 0, 0.35),
        inset 0 -1px 0 rgba(255, 255, 255, 0.08);
}

.drawer-btn:active {
    transform: translateY(1px);
    background:
        linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3)),
        var(--card-base);
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.4);
}

.drawer-btn.active {
    background: color-mix(in srgb, white 12%, var(--card-base));
    border-color: rgba(255, 255, 255, 0.18);
    color: var(--ui-text-strong);
    box-shadow:
        inset 0 2px 4px rgba(0, 0, 0, 0.4),
        inset 0 -1px 0 rgba(255, 255, 255, 0.08);
}

.drawer-btn-icon {
    font-size: 0.95rem;
    line-height: 1;
    filter: brightness(1.5);
}

.drawer-btn-label {
    font-size: 0.45rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: inherit;
    opacity: 0.65;
    line-height: 1;
}

.drawer-btn:hover .drawer-btn-label,
.drawer-btn.active .drawer-btn-label {
    opacity: 1;
}

/* Speed slider row — label + slider + value inline */
.slot-control--speed {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.speed-slider {
    flex: 1;
    -webkit-appearance: none;
    appearance: none;
    height: 4px;
    border-radius: 2px;
    background: rgba(255, 255, 255, 0.15);
    outline: none;
    cursor: pointer;
}

.speed-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--secondary) 80%, white);
    border: 1px solid rgba(255, 255, 255, 0.3);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
    cursor: pointer;
}

.speed-slider::-moz-range-thumb {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--secondary) 80%, white);
    border: 1px solid rgba(255, 255, 255, 0.3);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
    cursor: pointer;
}

.speed-value {
    font-size: 0.6rem;
    font-weight: 700;
    color: rgba(255, 255, 255, 0.7);
    letter-spacing: 0.04em;
    min-width: 2.2em;
    text-align: right;
}

/* ═══════════════════════════════════════════════════════════════════
   TRANSPORT BAR (MAIN) - Full-width tape deck controls
   ═══════════════════════════════════════════════════════════════════ */

.transport-bar--main {
    display: flex;
    align-items: center;
    gap: 2px;
    margin: 0;
    padding: 4px;
    background: rgba(0, 0, 0, 0.4);
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, 0.06);
    box-shadow:
        inset 0 2px 4px rgba(0, 0, 0, 0.5),
        0 1px 0 rgba(255, 255, 255, 0.04);
}

/* Transport buttons */
.transport-btn {
    width: 36px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 5px;
    /* Matte grey, opaque (no bar wash bleeds through) + raised bevel; states
       ride brightness + bevel, not a wash or a metallic gradient. */
    background: color-mix(in srgb, white 5%, var(--card-base));
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.08),
        inset 0 -2px 3px rgba(0, 0, 0, 0.2);
    color: rgba(255, 255, 255, 0.5);
    cursor: pointer;
    transition: all 0.12s ease;
    padding: 0;
    flex-shrink: 0;
}

.transport-btn:hover {
    /* Press in + brighten — opaque matte grey so the bar gradient can't bleed
       through (the deliberate prev/next colour reveal is set explicitly below). */
    background: color-mix(in srgb, white 9%, var(--card-base));
    color: var(--ui-text-strong);
    border-color: rgba(255, 255, 255, 0.18);
    box-shadow:
        inset 0 2px 4px rgba(0, 0, 0, 0.4),
        inset 0 -1px 0 rgba(255, 255, 255, 0.08);
}

/* Deliberate forward/reverse colour reveal — reverse (prev) glows hair, forward
   (next) glows eyes, matching the bar's left→right hair→eyes sweep. Set
   explicitly (not via transparency) so it survives the now-opaque tray + buttons
   and doesn't become a general bleed. */
#scs-prev:hover,
#gcs-prev:hover {
    background: color-mix(in srgb, var(--primary) 22%, var(--card-base));
    color: var(--ui-text-strong);
}
#scs-next:hover,
#gcs-next:hover {
    background: color-mix(in srgb, var(--secondary) 22%, var(--card-base));
    color: var(--ui-text-strong);
}

.transport-btn:active {
    transform: translateY(1px);
    background:
        linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3)),
        var(--card-base);
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.4);
}

/* Shared nav tabs — ONE neutral grey for every state, matching the other transport
   buttons (white 5% base). State rides the BEVEL (raised = available, inset = the
   page you're on) + OPACITY (dim = disabled), NOT a colour swing: two AVAILABLE
   buttons must read IDENTICALLY. (A lit 'chats' join used to sit lighter than the
   plain tab beside it, so two available buttons looked like different buttons — the
   inconsistency that made the old hair-washed version impossible to read.) The
   unselected tab = the base .transport-btn grey; nothing to add but the bg. */
.scs-mobile-nav .aurora-header__nav-btn:not(.transport-btn--header-active),
.scene-control-surface--header .aurora-header__nav-btn:not(.transport-btn--header-active) {
    background: color-mix(in srgb, white 5%, var(--card-base));
    /* NEUTRAL nav text everywhere — editor/chat/gallery, header row and toolbar,
       page tabs and face tabs. Out-specifies BOTH the .aurora-standalone a eyes
       tint (the <a> Create/Discover tabs) and the header's blanket
       ui-text-strong, so every inactive tab reads the same grey; active/hover
       brighten to ui-text-strong via the rules below. */
    color: rgba(255, 255, 255, 0.55);
}

/* The page you're ON — pressed-in bevel + a modest lift so it's unmistakably the
   current tab. A small 5% → 10% step (not the old 5% → 16% swing); the inset carries
   the signal, so it never reads as a different-coloured button. */
.scs-mobile-nav .transport-btn--header-active,
.scene-control-surface--header .transport-btn--header-active {
    background: color-mix(in srgb, white 10%, var(--card-base));
    border-color: rgba(255, 255, 255, 0.22);
    box-shadow:
        inset 0 2px 5px rgba(0, 0, 0, 0.5),
        inset 0 -1px 0 rgba(255, 255, 255, 0.1);
    color: var(--ui-text-strong);
}
/* On the live toolbar the selected tab IS the current page (its active state keys
   purely off request.path), so make it INERT — clicking it only reloaded the page
   you're already on. The header-rail variant stays clickable: there the active state
   also flags the EDITOR, which is a real navigation, not a self-reload. */
.scs-mobile-nav .transport-btn--header-active {
    pointer-events: none;
}

/* Hover on an available tab — a small brighten + light press, same grey family.
   Selected is excluded (it's the inert current page). */
.scs-mobile-nav .aurora-header__nav-btn:hover:not(.transport-btn--header-active),
.scene-control-surface--header .aurora-header__nav-btn:hover:not(.transport-btn--header-active) {
    background: color-mix(in srgb, white 8%, var(--card-base));
    box-shadow:
        inset 0 1px 3px rgba(0, 0, 0, 0.3),
        inset 0 -1px 0 rgba(255, 255, 255, 0.06);
    color: var(--ui-text-strong);
}

/* ═══════════════════════════════════════════════════════════════════════════
   OUTFIT BODY-MAPPING — the character wears the toolbar (experiment 2026-07-17)

   A deliberate, scoped exception to "buttons carry no slot colour": the toolbar
   is the ONE canvas for the outfit palette (its own gradient, can't share a
   surface with hair/eyes). Body-mapping: the card-flipper row (image/scene/
   memory/chat) wears the outfit TOP, the Create/Discover nav wears the outfit
   BOTTOM. A one-piece dress fills both — the dress↔two-piece mutex means
   --outfit-top and --outfit-bottom resolve to the same colour (derived live in
   color-propagation.js: tops||dress, bottoms||dress).

   Recipe (James): base + text SAME hue, text lifted lighter (more white). The
   colour also fixes the 2-button-nav problem — the active tab lights up in the
   outfit hue while its neighbour sits as a faint tint of the same, so "which
   one's on" reads at a glance without needing a third button for context.
   Falls gracefully to near-neutral when a character wears no outfit
   (--outfit-* == transparent → color-mix collapses toward card-base / white).
   Percentages are first-pass, tune to taste. ══════════════════════════════ */

/* Card-flipper row → outfit TOP */
.aurora-header__scene-tabs .aurora-header__nav-btn:not(.transport-btn--header-active) {
    background: color-mix(in srgb, var(--outfit-top) 16%, var(--card-base));
    color: color-mix(in srgb, var(--outfit-top) 50%, white);
}
/* Selected — :hover included so hovering the current tab HOLDS its outfit fill.
   Without it, fieldsets-base's `.scene-control-surface--header
   .transport-btn--header-active:hover` grey (same 0,3,0 specificity) wins and the
   selected button greys out until the mouse leaves. This file loads later, so the
   tie goes to us. */
.aurora-header__scene-tabs .transport-btn--header-active,
.aurora-header__scene-tabs .transport-btn--header-active:hover {
    background: color-mix(in srgb, var(--outfit-top) 36%, var(--card-base));
    border-color: color-mix(in srgb, var(--outfit-top) 45%, transparent);
    color: color-mix(in srgb, var(--outfit-top) 26%, white);
}
.aurora-header__scene-tabs .aurora-header__nav-btn:hover:not(.transport-btn--header-active) {
    /* Gentle LIFT, not a saturation jump: hold the inactive 16% outfit tint and
       brighten with a little white so hover reads lighter, never darker. */
    background: color-mix(in srgb, white 7%, color-mix(in srgb, var(--outfit-top) 16%, var(--card-base)));
    color: color-mix(in srgb, var(--outfit-top) 40%, white);
}

/* Create/Discover nav → outfit BOTTOM */
.drawer-controls--nav .aurora-header__nav-btn:not(.transport-btn--header-active),
.scs-mobile-nav .aurora-header__nav-btn:not(.transport-btn--header-active) {
    background: color-mix(in srgb, var(--outfit-bottom) 16%, var(--card-base));
    color: color-mix(in srgb, var(--outfit-bottom) 50%, white);
}
/* Selected — :hover included so the current nav tab holds its outfit fill (same
   reason as the flipper row: beat fieldsets-base's grey active:hover on the tie). */
.drawer-controls--nav .transport-btn--header-active,
.drawer-controls--nav .transport-btn--header-active:hover,
.scs-mobile-nav .transport-btn--header-active,
.scs-mobile-nav .transport-btn--header-active:hover {
    background: color-mix(in srgb, var(--outfit-bottom) 36%, var(--card-base));
    border-color: color-mix(in srgb, var(--outfit-bottom) 45%, transparent);
    color: color-mix(in srgb, var(--outfit-bottom) 26%, white);
}
.drawer-controls--nav .aurora-header__nav-btn:hover:not(.transport-btn--header-active),
.scs-mobile-nav .aurora-header__nav-btn:hover:not(.transport-btn--header-active) {
    /* Gentle LIFT, not a saturation jump (see the flipper-row hover). */
    background: color-mix(in srgb, white 7%, color-mix(in srgb, var(--outfit-bottom) 16%, var(--card-base)));
    color: color-mix(in srgb, var(--outfit-bottom) 40%, white);
}

/* 'chats' join needs NO special fill — when a clone is centered it simply becomes
   AVAILABLE (the JS drops --disabled), reading EXACTLY like the tab beside it; when
   not, it's dim-disabled. Availability is opacity, not a lighter colour — so both
   available buttons match. (The .chats-nav--join class stays as the JS state marker.) */

/* Gallery action LINKS (edit / download) are <a>, so the app-wide
   `.aurora-standalone a { color: var(--secondary) }` link tint overrides the
   transport grey and makes them vanish when that slot is empty. Pin them to
   the same grey as the <button> controls; hover keeps the slot-1 tint like
   the rest of the tape deck. */
.scene-control-surface--gallery a.transport-btn {
    color: rgba(255, 255, 255, 0.5);
}
.scene-control-surface--gallery a.transport-btn:hover {
    color: var(--ui-text-strong);
}
/* Load/Edit/Chat promoted to the transport CENTER — the big primary actuator. flex:2
   against prev/next's flex:1 makes it HALF the row while they're a quarter each, so it
   deliberately breaks the even grid of the page-tabs row below (editor/download/search)
   instead of lining up. Icon + label inline; state + enable/disable ride syncChatsNav. */
.scene-control-surface--gallery .drawer-controls--transport .chats-nav--primary {
    flex: 2 1 0;   /* out-specifies .drawer-controls--transport .transport-btn's flex:1 1 0 */
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    text-decoration: none;   /* it's an <a> without .aurora-header__nav-btn, so kill the underline */
}
.scene-control-surface--gallery .chats-nav--primary .aurora-header__nav-label {
    font-size: 1.05rem;   /* the primary reads a touch LARGER than the Editor/Search tabs */
}

/* Play button - wider, character-tinted background but grey triangle so it
   stays visible when slot-1 is near-black (e.g. black hair). */
.transport-btn--play {
    width: 40px;
    height: 34px;
    /* Starts grey like the other buttons (only the triangle icon stays bright);
       tints hair on hover/active so the states have room to brighten to. */
    color: var(--ui-text-strong);
}

.transport-btn--play:hover {
    /* Brighter, and keep the OUTWARD (raised) bevel — only the active/pause
       state presses in, so the three states read distinctly. */
    background: color-mix(in srgb, var(--primary) 30%, var(--card-base));
    border-color: rgba(255, 255, 255, 0.18);
    color: var(--ui-text-strong);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.08),
        inset 0 -2px 3px rgba(0, 0, 0, 0.2);
}

.transport-btn--play.active {
    /* Playing / pause = pressed in (inset bevel) + brightest — clearly distinct
       from the raised hover. */
    background: color-mix(in srgb, var(--primary) 50%, var(--card-base));
    border-color: rgba(255, 255, 255, 0.18);
    color: var(--ui-text-strong);
    box-shadow:
        inset 0 2px 4px rgba(0, 0, 0, 0.45),
        inset 0 -1px 0 rgba(255, 255, 255, 0.08);
}

/* Record button (auto-generate) */
.transport-btn--record {
    color: rgba(225, 80, 80, 0.85);
}

.transport-btn--record:hover {
    /* Play colours (hair tint + raised bevel); only the icon stays red. */
    background: color-mix(in srgb, var(--primary) 30%, var(--card-base));
    border-color: rgba(255, 255, 255, 0.18);
    color: var(--danger);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.08),
        inset 0 -2px 3px rgba(0, 0, 0, 0.2);
}

/* Delete button (gallery edit/delete pair). Mirrors --record's red
   treatment — destructive action, same visual semantics. */
.transport-btn--del {
    color: rgba(225, 80, 80, 0.85);
}

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

/* Set-avatar camera button — after tapping, its face shows the staged scene
   (setAvatarBtnPreview) instead of the camera glyph, so you see what Save will
   commit. The preview is a SQUARE sized to the button's HEIGHT (aspect-ratio:1
   off height:100%) and centred — the button may be wider, but the avatar is
   never stretched across it. The button is already a centering flexbox. */
.cec-editor-set-avatar { overflow: hidden; }
.cec-editor-set-avatar.has-preview svg { display: none; }
.cec-editor-set-avatar .cec-avatar-preview {
    display: block;
    /* Fill the button (whatever size it is) and crop — do NOT derive width from
       height via aspect-ratio, which in the mobile-landscape rail (tall buttons)
       forced the width to match the tall height and stretched the row off-screen. */
    width: 100%;
    height: 100%;
    max-width: 100%;
    object-fit: cover;
    border-radius: 3px;
}

.transport-btn--record.active {
    /* Armed = play colours pressed in (inset bevel, "engaged") + the pulse;
       only the icon is red. No red bg/border/glow. */
    color: var(--danger);
    background: color-mix(in srgb, var(--primary) 50%, var(--card-base));
    border-color: rgba(255, 255, 255, 0.18);
    box-shadow:
        inset 0 2px 4px rgba(0, 0, 0, 0.4),
        inset 0 -1px 0 rgba(255, 255, 255, 0.08);
    animation: record-pulse 1.5s ease-in-out infinite;
}

@keyframes record-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.6; }
}

/* ── Busy lockout — surgical, record only ──
   While a generation / crystallize is in flight (#form-content carries
   .generating or .crystallizing), we do NOT wash out the surface — the
   border, panel bg, slot colors and the carousel nav (prev/next) all
   stay fully lit so the user has the tape deck to play with during the
   wait. Only the record (auto-generate) button freezes, so a new
   auto-gen loop can't be armed mid-flight. `animation: none` kills the
   record-pulse so a frozen-while-armed button reads as dim/locked
   rather than pulsing; it resumes between scenes when the busy class
   clears. */
:is(.generating, .crystallizing, .prompt-locked) .scene-control-surface .transport-btn--record {
    opacity: 0.3;
    pointer-events: none;
    animation: none;
}

/* ── Scene-count gate — two tiers, keyed on REAL (imaged) scenes ──
   The deck is a slideshow controller; the count that matters is rendered
   scene cards, NOT strip-cards. The generate card carries a real pending
   Scene id (data-entity-id), so an entity-id count would see it as a
   scene and light the deck on a card that can't drive anything — the
   broken first impression. Since commit 81a86e7 sweeps that orphan card
   the moment scene 1 lands, we can hard-gate on real scenes instead:

     0 scenes  (generate card / mid scene-1 gen) → whole deck inert.
                A button's first introduction must not be a dead button,
                same lesson as the model + broken tools.
     1 scene   → play / record light up (stop only under play — see the
                run-state rules below); prev / next stay inert (one
                frame, nothing to navigate to).
     ≥2 scenes → nav lights up too — full transport.

   Same dim language as the busy lockout — one consistent "not now" read.
   Both classes toggled by the inline script (realSceneCount) off
   carousel:centered / generation:complete / load. record-pulse is killed
   under the full lock so a stale-armed record can't pulse through. */
.scene-control-surface.transport-locked .transport-btn {
    /* Opaque dim (not opacity) so a disabled button shows a flat dark fill, not
       the bar gradient bleeding through it. */
    background: color-mix(in srgb, black 30%, var(--card-base));
    color: rgba(255, 255, 255, 0.22);
    border-color: rgba(255, 255, 255, 0.06);
    box-shadow: none;
    pointer-events: none;
    animation: none;
}

.scene-control-surface.transport-no-nav #scs-prev,
.scene-control-surface.transport-no-nav #scs-next {
    background: color-mix(in srgb, black 30%, var(--card-base));
    color: rgba(255, 255, 255, 0.22);
    border-color: rgba(255, 255, 255, 0.06);
    box-shadow: none;
    pointer-events: none;
}

/* ── Run-state gating — keyed on record-armed / playing ──
   These layer on top of the scene-count gate and react to live deck
   state, not scene count.

   Record armed (#scs-record.active): you're auto-generating, not
   browsing — prev/next are meaningless and their play-mode speed-ramp
   role would fight the loop. Dimmed via :has() so the record click
   handler stays a pure flag (no JS class plumbing). Composes with
   transport-no-nav — either reason dims the same pair. */
.scene-control-surface:has(#scs-record.active) #scs-prev,
.scene-control-surface:has(#scs-record.active) #scs-next {
    opacity: 0.3;
    pointer-events: none;
}

/* Stop is inert by default and lights when there's something a stop
   would act on:
     - the slideshow is running (.transport-playing, set by
       setPlayState() — play or play+record), OR
     - record is armed but not yet playing (#scs-record.active). Armed
       gives the user a clear two-button choice — Play or Stop — instead
       of relying on them knowing a second Record click disarms; Stop
       reads clearer. stop() resets everything (pause() no-ops when not
       playing, the record-disarm + speed-reset still run), so after a
       click the deck is back to default and Stop is the only inert
       button again.
   The ID + run-state selectors outweigh the flat default, and both
   outrank the scene-count tiers. */
.scene-control-surface #scs-stop {
    opacity: 0.3;
    pointer-events: none;
}

.scene-control-surface .drawer-controls--transport.transport-playing #scs-stop,
.scene-control-surface:has(#scs-record.active) #scs-stop {
    opacity: 1;
    pointer-events: auto;
}

/* LCD styles removed — replaced by frame selector + settings gear */

/* Playing state glow — follows the transport into the drawer */
.drawer-controls--transport.transport-playing {
    border-color: rgba(255, 255, 255, 0.22);
    box-shadow:
        inset 0 2px 4px rgba(0, 0, 0, 0.5);
}

/* Transport buttons stretch to fill the drawer — more room than the top bar */
.drawer-controls--transport {
    gap: 4px;
}

.drawer-controls--transport .transport-btn {
    flex: 1 1 0;
    width: auto;
    min-width: 48px;
    height: 48px;
}

.drawer-controls--transport .transport-btn--play {
    flex: 1.3 1 0;
    width: auto;
    height: 48px;
}

/* LCD glow removed — no longer present */

/* ── Scene control surface select styling ──
   Native selects (model, voice) + Select2 (frame, aspect).
   Select2 replaces <select> with its own span/div DOM — target both. */

/* Native selects (model preset, voice — not Select2'd) */
.scene-control-surface select {
    /* Local accent so --text-tinted resolves to slot-1 here */
    --accent: var(--primary);
    height: 28px;
    padding: 0 1.5rem 0 0.5rem;
    background-color: rgba(0, 0, 0, 0.3);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' fill='rgba(255,255,255,0.4)' viewBox='0 0 16 16'%3E%3Cpath d='M8 11L3 6h10l-5 5z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.5rem center;
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-left: 3px solid color-mix(in srgb, var(--primary) 60%, transparent);
    border-radius: 4px;
    color: #c0c0c0;
    font-size: 0.8rem;
    line-height: 1.3;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
}

.scene-control-surface select:hover {
    border-color: color-mix(in srgb, var(--primary) 60%, transparent);
    border-left-color: var(--primary);
    background-color: rgba(0, 0, 0, 0.4);
}

.scene-control-surface select:focus {
    outline: none;
    background-color: rgba(0, 0, 0, 0.4);
    border-color: var(--primary);
    box-shadow:
        0 0 0 2px color-mix(in srgb, var(--primary) 25%, transparent);
}

.scene-control-surface select option {
    background: var(--card-base);
    color: rgba(255, 255, 255, 0.9);
    padding: 0.5rem;
}

/* ── Frame selector in transport bar ──
   #id_frame is Select2'd by standalone-select2.js — style the container */

.transport-frame-slot {
    flex: 1;
    min-width: 0;
    margin-left: auto;
    /* standalone-select2.js reads --accent from the closest ancestor on open
       and applies it as --select2-accent to the dropdown panel (search input,
       option hover/selected, scrollbar, glow). Pin it to hair so the open
       dropdown doesn't fall through to the outfit-top fallback. */
    --accent: var(--primary);
}

/* Select2 container inside transport */
.transport-frame-slot .select2-container {
    width: 100%;
}

.transport-frame-slot .select2-selection--single {
    height: 28px;
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 4px;
    display: flex;
    align-items: center;
    padding: 0 0.4rem;
    transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
}

.transport-frame-slot .select2-selection--single:hover {
    border-color: color-mix(in srgb, var(--primary) 60%, transparent);
    background-color: rgba(0, 0, 0, 0.15);
}

.transport-frame-slot .select2-container--open .select2-selection--single {
    background-color: rgba(0, 0, 0, 0.2);
    border-color: var(--primary);
    box-shadow:
        0 0 0 2px color-mix(in srgb, var(--primary) 25%, transparent);
}

.transport-frame-slot .select2-container--default .select2-selection--single .select2-selection__rendered {
    /* Parent is display: flex, so fill it before text-align can center */
    flex: 1;
    /* --accent is set on .transport-frame-slot (slot-1) so --text-tinted
       resolves to a slot-1/white mix here. Same family as .chat-control-deck. */
    color: #c0c0c0;
    font-size: 0.8rem;
    line-height: 28px;
    /* Right padding reserves space for the absolutely-positioned caret */
    padding: 0 24px 0 0;
    text-align: center;
}

/* Center option items in the scoped frame dropdown (class set via
   dropdownCssClass in standalone-select2.js frame init) */
.frame-dropdown .select2-results__option {
    text-align: center;
    padding-left: 0.5rem;
    padding-right: 0.5rem;
}

.transport-frame-slot .select2-selection__arrow {
    position: absolute;
    top: 0;
    right: 0;
    width: 24px;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.transport-frame-slot .select2-selection__arrow b {
    border-color: color-mix(in srgb, var(--primary) 60%, white) transparent transparent transparent;
    border-style: solid;
    border-width: 5px 4px 0;
    margin: 0;
}

/* ── Tape reel button (opens transport drawer) ── */

.transport-btn--reel {
    color: rgba(255, 255, 255, 0.4);
}

.transport-btn--reel:hover {
    /* Grey, not slot-1 — survives black hair. Glow comes from .transport-btn:hover. */
    color: var(--ui-text-strong);
}

.transport-btn--reel.active {
    color: var(--ui-text-strong);
    background:
        linear-gradient(180deg,
            rgba(255, 255, 255, 0.06) 0%,
            rgba(0, 0, 0, 0.1) 100%),
        var(--card-base);
    border-color: rgba(255, 255, 255, 0.22);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.08),
        inset 0 -2px 3px rgba(0, 0, 0, 0.2);
}

/* Top-row drawer-btns shrink to chat-deck-btn dimensions (icon-only)
   so the frame select2 has room to breathe. */
.transport-bar--main .drawer-btn {
    flex: 0 0 auto;
    width: 32px;
    height: 28px;
    min-width: 32px;
    padding: 0;
    gap: 0;
}

.transport-bar--main .drawer-btn .drawer-btn-label {
    display: none;
}

.transport-bar--main .drawer-btn .drawer-btn-icon {
    font-size: 0.9rem;
}

/* Reel button matches the top-row button height */
.transport-btn--reel {
    width: 32px;
    height: 28px;
}

/* ── Option labels ── */

.tape-option-label {
    font-size: 0.5rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    color: rgba(255, 255, 255, 0.35);
    text-transform: uppercase;
}

/* Auto-generate toggle switch */
.tape-option--toggle {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    cursor: pointer;
    padding: 0.3rem 0;
}

.auto-generate-checkbox {
    display: none;
}

.auto-generate-switch {
    width: 28px;
    height: 16px;
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.12);
    position: relative;
    transition: all 0.2s ease;
    flex-shrink: 0;
}

.auto-generate-switch::after {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.35);
    transition: all 0.2s ease;
}

.auto-generate-checkbox:checked + .auto-generate-switch {
    background: rgba(0, 0, 0, 0.3);
    border-color: var(--neutral);
    box-shadow: 0 0 6px color-mix(in srgb, var(--primary) 25%, transparent);
}

.auto-generate-checkbox:checked + .auto-generate-switch::after {
    left: 14px;
    background: var(--neutral);
}

/* ═══════════════════════════════════════════════════════════════════
   CONTEXT BAR - Mood, Location, Description (character-themed)
   ═══════════════════════════════════════════════════════════════════ */

.context-bar {
    display: grid;
    /* 2-row layout: Mood + Location on row 1, Description on row 2 */
    grid-template-columns: 1fr 2fr;
    gap: 0.5rem;
    margin: 0.6rem;
    padding: 0.5rem;
    /* Character + environment color blend */
    background: linear-gradient(
        135deg,
        color-mix(in srgb, var(--primary) 18%, var(--card-base)) 0%,
        var(--card-base) 50%,
        var(--card-base) 100%
    );
    border-radius: 6px;
    border: 1px solid color-mix(in srgb, var(--slot-12) 12%, rgba(255, 255, 255, 0.06));
    transition: border-color 0.3s ease;
}

.context-bar:hover {
    border-color: color-mix(in srgb, var(--slot-12) 20%, rgba(255, 255, 255, 0.08));
}

.context-field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.context-label {
    font-size: 0.55rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    color: var(--neutral);
    text-transform: uppercase;
    padding-left: 0.2rem;
}

/* Style inputs/textareas in context bar - character themed */
.context-field input,
.context-field textarea {
    /* Local accent so --text-tinted picks up slot-3 here */
    --accent: var(--neutral);  /* neutral grey (was --outfit-accent — neutralized) */
    width: 100%;
    padding: 0.4rem 0.5rem;
    background: rgba(0, 0, 0, 0.4);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-left: 2px solid transparent;
    border-radius: 4px;
    color: #c0c0c0;
    font-size: 0.8rem;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.context-field input:hover,
.context-field textarea:hover {
    border-color: rgba(255, 255, 255, 0.18);
    border-left-color: transparent;
}

.context-field input:focus,
.context-field textarea:focus {
    outline: none;
    border-color: var(--neutral);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 25%, transparent);
}

.context-field textarea {
    min-height: 38px;
    resize: none;
}

/* Description field spans full width on second row */
.context-field--wide,
.context-bar .context-field:nth-child(3) {
    grid-column: 1 / -1;
}

/* Select2 inside context bar - character themed */
.context-field .select2-container--admin-autocomplete .select2-selection--single,
.context-field .select2-container--default .select2-selection--single {
    background: rgba(0, 0, 0, 0.2);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-left: 2px solid transparent;
}

.context-field .select2-container--admin-autocomplete .select2-selection--single:hover,
.context-field .select2-container--default .select2-selection--single:hover {
    border-color: rgba(255, 255, 255, 0.18);
    border-left-color: transparent;
}

.context-field .select2-container--admin-autocomplete.select2-container--open .select2-selection--single,
.context-field .select2-container--default.select2-container--open .select2-selection--single {
    background: rgba(0, 0, 0, 0.4);
    border-color: var(--neutral);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 25%, transparent);
}

.context-field .select2-container--admin-autocomplete .select2-selection__arrow b,
.context-field .select2-container--default .select2-selection__arrow b {
    border-color: var(--neutral) transparent transparent transparent;
}

/* ═══════════════════════════════════════════════════════════════════
   SELECTOR BAY - Frame, Aspect, Quality (character-themed)
   ═══════════════════════════════════════════════════════════════════ */

.selector-bay {
    display: grid;
    grid-template-columns: 2fr 1fr auto;
    gap: 0.5rem;
    margin: 0 0.6rem;
    padding: 0.6rem;
    /* Character + environment color blend */
    background: linear-gradient(
        135deg,
        color-mix(in srgb, var(--primary) 20%, var(--card-base)) 0%,
        var(--card-base) 50%,
        var(--card-base) 100%
    );
    border-radius: 6px;
    border: 1px solid rgba(255, 255, 255, 0.08);
    transition: border-color 0.3s ease;
}

.selector-bay:hover {
    border-color: rgba(255, 255, 255, 0.1);
}

.selector-slot {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.slot-label {
    font-size: 0.5rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    color: var(--neutral);
    padding-left: 0.2rem;
}

.slot-control {
    min-height: 36px;
    display: flex;
    align-items: center;
}

/* Style native selects in the bay - character themed */
.slot-control select {
    /* Local accent so --text-tinted resolves to slot-3 here */
    --accent: var(--neutral);  /* neutral grey (was --outfit-accent — neutralized) */
    width: 100%;
    height: 36px;
    padding: 0 2rem 0 0.6rem;
    background-color: rgba(0, 0, 0, 0.2);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='rgba(255,255,255,0.4)' viewBox='0 0 16 16'%3E%3Cpath d='M8 11L3 6h10l-5 5z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.6rem center;
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-left: 2px solid transparent;
    border-radius: 4px;
    color: #c0c0c0;
    font-size: 0.8rem;
    font-weight: 500;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.slot-control select:hover {
    border-color: rgba(255, 255, 255, 0.18);
    border-left-color: transparent;
}

.slot-control select:focus {
    outline: none;
    background-color: rgba(0, 0, 0, 0.4);
    border-color: var(--neutral);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 25%, transparent);
}

.slot-control select option {
    background: var(--card-base);
    color: white;
}

/* Select2 container sizing in bay - character themed */
.slot-control .select2-container {
    width: 100%;
}

.slot-control .select2-container--admin-autocomplete .select2-selection--single,
.slot-control .select2-container--default .select2-selection--single {
    height: 36px;
    background-color: rgba(0, 0, 0, 0.2);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-left: 2px solid transparent;
    border-radius: 4px;
    display: flex;
    align-items: center;
    padding: 0 0.4rem;
}

.slot-control .select2-container--admin-autocomplete .select2-selection--single:hover,
.slot-control .select2-container--default .select2-selection--single:hover {
    border-color: rgba(255, 255, 255, 0.18);
    border-left-color: transparent;
}

.slot-control .select2-container--admin-autocomplete.select2-container--open .select2-selection--single,
.slot-control .select2-container--default.select2-container--open .select2-selection--single {
    background: rgba(0, 0, 0, 0.4);
    border-color: var(--neutral);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 25%, transparent);
}

.slot-control .select2-container--admin-autocomplete .select2-selection__arrow b,
.slot-control .select2-container--default .select2-selection__arrow b {
    border-color: var(--neutral) transparent transparent transparent;
}

/* ═══════════════════════════════════════════════════════════════════
   ACTION DECK - Lock (square) + Generate (bar)
   Housing/deck structure mirrors .transport-housing / .transport-bar--main.
   Highlights use slot-1 (hair) with slot-5 (lighting) glow.
   ═══════════════════════════════════════════════════════════════════ */

/* Inner housing — matches .transport-housing: padding + subtle overlay.
   Outer .action-panel carries the margin + colored gradient backdrop. */
.action-housing {
    padding: 0.25rem 0.3rem 0.2rem;
    background: linear-gradient(180deg, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0.2) 100%);
}

.action-deck {
    display: flex;
    align-items: stretch;
    gap: 4px;
    margin: 0;
    padding: 4px;
    background: rgba(0, 0, 0, 0.4);
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, 0.06);
    box-shadow:
        inset 0 2px 4px rgba(0, 0, 0, 0.5),
        0 1px 0 rgba(255, 255, 255, 0.04);
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.action-deck:hover {
    border-color: color-mix(in srgb, var(--primary) 20%, rgba(255, 255, 255, 0.08));
}

/* Base tactile button — shared by lock + generate */
.deck-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.5rem 0.9rem;
    border: 1px solid transparent;
    border-radius: 5px;
    background: linear-gradient(180deg,
        rgba(255, 255, 255, 0.06) 0%,
        rgba(0, 0, 0, 0.1) 100%);
    color: rgba(255, 255, 255, 0.55);
    cursor: pointer;
    transition: all 0.12s ease;
}

.deck-btn:hover {
    background: linear-gradient(180deg,
        rgba(255, 255, 255, 0.1) 0%,
        rgba(0, 0, 0, 0.05) 100%);
    color: var(--primary);
    border-color: color-mix(in srgb, var(--primary) 30%, transparent);
}

.deck-btn:active {
    transform: translateY(1px);
    background: rgba(0, 0, 0, 0.3);
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.4);
}

.btn-icon {
    font-size: 1.1rem;
    line-height: 1;
}

.btn-label {
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

/* ── Lock button — square tactile toggle ──
   Scoped under .action-deck to beat .face-lock-btn's width:100% layout
   rule in fieldsets-base.css (the button carries both classes). */
.action-deck .deck-btn--lock {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    padding: 0;
}

.deck-btn--lock .btn-icon,
.deck-btn--lock .lock-icon {
    font-size: 1.25rem;
}

.deck-btn--lock.active,
.deck-btn--lock.locked {
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--primary) 20%, rgba(255, 255, 255, 0.06)) 0%,
        color-mix(in srgb, var(--primary) 10%, rgba(0, 0, 0, 0.1)) 100%);
    border-color: color-mix(in srgb, var(--primary) 40%, transparent);
    color: var(--primary);
    box-shadow:
        0 0 10px color-mix(in srgb, var(--primary) 30%, transparent),
        inset 0 0 4px color-mix(in srgb, var(--primary) 15%, transparent);
}

/* ── Generate button — primary action, wide, brighter ──
   Scoped under .action-deck to match the lock-button specificity so the
   row lays out as [44px lock] + [flex:1 generate] regardless of which
   stylesheet loaded last. */
.action-deck .deck-btn--generate {
    flex: 1;
    min-width: 0;
    height: 44px;
    padding: 0 1rem;
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--primary) 15%, rgba(255, 255, 255, 0.06)) 0%,
        color-mix(in srgb, var(--primary) 8%, rgba(0, 0, 0, 0.1)) 100%);
    border-color: color-mix(in srgb, var(--primary) 25%, transparent);
    /* Slot-tinted grey — same idea as the element-bubble border floor:
       grey dominates so dark slots stay readable, slot-1 (hair) adds
       character on bright palettes. */
    color: color-mix(in srgb, var(--primary) 30%, var(--ui-text-strong));
}

.deck-btn--generate:hover {
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--primary) 28%, rgba(255, 255, 255, 0.08)) 0%,
        color-mix(in srgb, var(--primary) 14%, rgba(0, 0, 0, 0.05)) 100%);
    border-color: var(--primary);
    color: color-mix(in srgb, var(--primary) 30%, var(--ui-text-strong));
    box-shadow:
        0 0 12px color-mix(in srgb, var(--primary) 35%, transparent);
}

.deck-btn--generate:active {
    transform: translateY(1px);
    box-shadow:
        inset 0 1px 3px rgba(0, 0, 0, 0.4),
        0 0 10px color-mix(in srgb, var(--primary) 25%, transparent);
}

/* ═══════════════════════════════════════════════════════════════════
   PROMPT DRAWER - Collapsible prompt section (matches profile-drawer)
   ═══════════════════════════════════════════════════════════════════ */

.prompt-drawer {
    margin: 0 0.4rem 0.4rem;
    border-radius: 6px;
    overflow: hidden;
    /* Environment-accented prompt drawer */
    border: 1px solid color-mix(in srgb, var(--slot-12) 15%, rgba(255, 255, 255, 0.06));
    background: linear-gradient(
        135deg,
        var(--card-base) 0%,
        color-mix(in srgb, var(--slot-12) 10%, var(--card-base)) 50%,
        var(--card-base) 100%
    );
    transition: border-color 0.3s ease;
}

.prompt-drawer:hover {
    border-color: color-mix(in srgb, var(--slot-12) 22%, rgba(255, 255, 255, 0.08));
}

.prompt-drawer .drawer-toggle {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    padding: 0.6rem 0.75rem;
    background: linear-gradient(180deg, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0.2) 100%);
    border: none;
    border-bottom: 1px solid transparent;
    color: rgba(255, 255, 255, 0.7);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: all 0.2s ease;
    text-align: left;
}

.prompt-drawer .drawer-toggle:hover {
    background: linear-gradient(180deg, rgba(0, 0, 0, 0.15) 0%, rgba(0, 0, 0, 0.25) 100%);
    color: rgba(255, 255, 255, 0.9);
}

.prompt-drawer .drawer-toggle.active {
    color: var(--primary);
    border-bottom-color: color-mix(in srgb, var(--primary) 30%, transparent);
}

.prompt-drawer .toggle-icon {
    font-size: 0.9rem;
    flex-shrink: 0;
}

.prompt-drawer .toggle-label {
    flex: 1;
}

.prompt-drawer .toggle-chevron {
    font-size: 0.5rem;
    flex-shrink: 0;
    transition: transform 0.2s ease;
    opacity: 0.5;
}

.prompt-drawer .drawer-toggle.active .toggle-chevron {
    transform: rotate(180deg);
    opacity: 1;
}

.prompt-drawer .drawer-content {
    overflow: hidden;
    transition: all 0.25s ease;
}

.prompt-drawer .drawer-content.collapsed {
    max-height: 0;
    opacity: 0;
}

.prompt-drawer .drawer-content:not(.collapsed) {
    max-height: 300px;
    opacity: 1;
}

/* Prompt bar inside drawer - no margin needed */
.prompt-drawer .prompt-bar {
    margin: 0;
    padding: 0.5rem;
    background: transparent;
    border: none;
    border-radius: 0;
    border-top: 1px solid rgba(0, 0, 0, 0.3);
}

.prompt-drawer .prompt-bar textarea {
    width: 100%;
    padding: 0.5rem;
    background: rgba(0, 0, 0, 0.2);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-left: 2px solid color-mix(in srgb, var(--slot-12) 40%, transparent);
    border-radius: 4px;
    color: rgba(255, 255, 255, 0.5);
    font-size: 0.75rem;
    font-weight: 300;
    font-family: inherit;
    line-height: 1.5;
    resize: vertical;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.prompt-drawer .prompt-bar textarea:hover {
    border-color: rgba(255, 255, 255, 0.18);
    border-left-color: color-mix(in srgb, var(--slot-12) 60%, transparent);
    color: rgba(255, 255, 255, 0.6);
}

.prompt-drawer .prompt-bar textarea:focus {
    outline: none;
    background: rgba(0, 0, 0, 0.4);
    border-color: var(--neutral);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 25%, transparent);
    color: rgba(255, 255, 255, 0.7);
}

.prompt-drawer .prompt-bar textarea::placeholder {
    color: rgba(255, 255, 255, 0.25);
    font-weight: 300;
}

/* ═══════════════════════════════════════════════════════════════════
   PROMPT BAR - Simple textarea matching context-bar style
   ═══════════════════════════════════════════════════════════════════ */

.prompt-bar {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    margin: 0 0.6rem 0.6rem;
    padding: 0.5rem;
    /* Brighter background to reduce accent contrast */
    background: linear-gradient(
        135deg,
        color-mix(in srgb, var(--primary) 16%, var(--card-base)) 0%,
        color-mix(in srgb, var(--secondary) 12%, var(--card-base)) 50%,
        var(--card-base) 100%
    );
    border-radius: 6px;
    border: 1px solid rgba(255, 255, 255, 0.06);
    transition: border-color 0.3s ease;
}

.prompt-bar:hover {
    border-color: rgba(255, 255, 255, 0.08);
}

.prompt-bar-label {
    font-size: 0.55rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    color: var(--neutral);
    text-transform: uppercase;
    padding-left: 0.2rem;
}

.prompt-bar textarea {
    width: 100%;
    padding: 0.5rem;
    background: rgba(0, 0, 0, 0.2);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-left: 2px solid transparent;
    border-radius: 4px;
    color: white;
    font-size: 0.8rem;
    font-family: inherit;
    line-height: 1.4;
    resize: vertical;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.prompt-bar textarea:hover {
    border-color: rgba(255, 255, 255, 0.18);
    border-left-color: transparent;
}

.prompt-bar textarea:focus {
    outline: none;
    background: rgba(0, 0, 0, 0.4);
    border-color: var(--neutral);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 25%, transparent);
}

.prompt-bar textarea::placeholder {
    color: rgba(255, 255, 255, 0.3);
}

/* ═══════════════════════════════════════════════════════════════════
   PANEL FOOTER - Decorative tech strip
   ═══════════════════════════════════════════════════════════════════ */

.panel-footer {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    padding: 0.4rem;
    background: linear-gradient(180deg, rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 0.3) 100%);
    border-top: 1px solid rgba(255, 255, 255, 0.02);
}

.tech-strip {
    display: flex;
    gap: 3px;
}

.tech-dot {
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.1);
}

.footer-text {
    font-size: 0.5rem;
    font-weight: 600;
    letter-spacing: 0.15em;
    color: rgba(255, 255, 255, 0.2);
    text-transform: uppercase;
}

/* ═══════════════════════════════════════════════════════════════════
   REALISM SLIDER - sits in the panel-footer slot for illustrious
   checkpoints (replaces the AURORA EDITOR / SCENE CONTROL label).
   CFG dial: 1.7 (real) ↔ 7 (toon). Track tinted via slot-2 to match
   the rest of the surface chrome.
   ═══════════════════════════════════════════════════════════════════ */

.realism-slider {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    max-width: 280px;
    padding: 0 0.4rem;
}

.realism-slider__label {
    font-size: 0.5rem;
    font-weight: 600;
    letter-spacing: 0.15em;
    color: rgba(255, 255, 255, 0.2);
    text-transform: uppercase;
    flex: 0 0 auto;
}

.realism-slider__range {
    flex: 1 1 auto;
    height: 6px;
    -webkit-appearance: none;
    appearance: none;
    background: linear-gradient(90deg,
        color-mix(in srgb, var(--secondary) 35%, rgba(0, 0, 0, 0.4)) 0%,
        color-mix(in srgb, var(--secondary) 15%, rgba(0, 0, 0, 0.4)) 100%);
    border-radius: 3px;
    outline: none;
    cursor: pointer;
}

.realism-slider__range::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--secondary) 60%, white);
    border: 1px solid color-mix(in srgb, var(--secondary) 80%, rgba(0, 0, 0, 0.5));
    cursor: pointer;
}

.realism-slider__range::-moz-range-thumb {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--secondary) 60%, white);
    border: 1px solid color-mix(in srgb, var(--secondary) 80%, rgba(0, 0, 0, 0.5));
    cursor: pointer;
}

/* ═══════════════════════════════════════════════════════════════════
   PROGRESS BAR - Simple generation indicator
   ═══════════════════════════════════════════════════════════════════ */

.progress-gauge {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
}

.progress-bar {
    flex: 1;
    height: 6px;
    background: rgba(0, 0, 0, 0.5);
    border-radius: 3px;
    overflow: hidden;
    border: 1px solid rgba(255, 255, 255, 0.1);
}

.progress-bar-fill {
    height: 100%;
    width: 0%;
    background: linear-gradient(90deg,
        var(--primary) 0%,
        color-mix(in srgb, var(--primary) 70%, white) 100%);
    border-radius: 2px;
    transition: width 0.15s ease-out;
    box-shadow: 0 0 8px var(--primary);
}

.progress-percent {
    font-size: 0.7rem;
    font-weight: 700;
    font-family: 'SF Mono', Monaco, monospace;
    color: var(--primary);
    min-width: 2.5em;
    text-align: right;
}

/* Generating state - show gauge, hide normal content */
.deck-btn--generate.generating .btn-icon,
.deck-btn--generate.generating .btn-label {
    display: none;
}

.deck-btn--generate .progress-gauge {
    display: none;
}

.deck-btn--generate.generating .progress-gauge {
    display: flex;
}

/* Generation in progress */
.scene-control-surface.generating .deck-btn--generate {
    animation: generate-pulse 1s ease-in-out infinite;
}

@keyframes generate-pulse {
    0%, 100% {
        box-shadow: 0 0 8px color-mix(in srgb, var(--primary) 30%, transparent);
    }
    50% {
        box-shadow: 0 0 20px var(--primary), 0 0 30px color-mix(in srgb, var(--primary) 30%, transparent);
    }
}

/* ═══════════════════════════════════════════════════════════════════
   QUEUE COUNT BADGE - Shows +N when multiple images pending
   ═══════════════════════════════════════════════════════════════════ */

.deck-btn--generate .queue-count {
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 20px;
    height: 20px;
    padding: 0 5px;
    background: linear-gradient(135deg,
        var(--secondary) 0%,
        color-mix(in srgb, var(--secondary) 70%, #000) 100%);
    border: 2px solid rgba(0, 0, 0, 0.5);
    border-radius: 10px;
    color: white;
    font-size: 0.65rem;
    font-weight: 700;
    font-family: 'SF Mono', Monaco, monospace;
    line-height: 16px;
    text-align: center;
    box-shadow:
        0 2px 6px rgba(0, 0, 0, 0.4),
        0 0 10px color-mix(in srgb, var(--secondary) 50%, transparent);
    animation: queue-pop 0.3s ease-out;
    z-index: 10;
}

/* Make button position relative for badge positioning */
.deck-btn--generate {
    position: relative;
}

@keyframes queue-pop {
    0% { transform: scale(0); opacity: 0; }
    50% { transform: scale(1.2); }
    100% { transform: scale(1); opacity: 1; }
}

/* ═══════════════════════════════════════════════════════════════════
   MOBILE RESPONSIVE - Stack controls on narrow screens
   ═══════════════════════════════════════════════════════════════════ */

@media (max-width: 600px) {
    /* Selector Bay: Frame on row 1, Aspect + Quality on row 2 */
    .selector-bay {
        grid-template-columns: 2fr 1fr;
        grid-template-rows: auto auto;
    }

    /* Frame spans full width on first row */
    .selector-bay .selector-slot:first-child {
        grid-column: 1 / -1;
    }

    /* Aspect gets 2fr, Quality gets 1fr on second row */
    .selector-bay .selector-slot:nth-child(2) {
        grid-column: 1;
    }

    .selector-bay .selector-slot:nth-child(3) {
        grid-column: 2;
    }

    /* Context Bar: Now uses same 2-row layout at all sizes (desktop = mobile) */
}

/* ── Mobile: the transport control IS the bottom dashboard ──────────────────
   On phones this control surface moves to a fixed bottom bar — its beveled
   control-panel housing + fine-tuned transport buttons come along. The footer's
   real/toon strip is hidden and the page tabs take its place; the site header's
   own nav row is hidden (redundant) on the scene page. Same element, not a copy
   (the #scs-* ids stay unique), so all the real handlers keep working. */
.scs-mobile-nav { display: none; }

@media (max-width: 700px) {
    /* Pin the site header to the top so it stays put as content scrolls under
       it (and gives the gallery a known top boundary to size the card against).
       z-index 50 keeps it above the carousel, below the bottom bar (z-60).
       Portrait only — landscape phones are wider than 700px and use the rail. */
    .scene-control-surface--header {
        position: sticky;
        top: 0;
        z-index: 50;
    }

    /* :not(--header) is load-bearing — the site <header> ALSO carries the
       .scene-control-surface class, so an unscoped rule drags the header to
       the bottom on top of the transport. */
    .scene-control-surface:not(.scene-control-surface--header) {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 60;
        margin: 0;
        padding-bottom: env(safe-area-inset-bottom, 0px);
    }

    .scene-control-surface:not(.scene-control-surface--header) .panel-footer { display: none; }

    /* Taller tool row on mobile — TRANSPORT DRAWER ONLY. The nav buttons share
       .transport-btn (mobile-page-tabs reuses the look), so an unscoped rule
       drags them tall too; scope to .drawer-controls--transport and let the nav
       keep its own thin height below. The generate spinner tracks this row. */
    .scene-control-surface:not(.scene-control-surface--header) .drawer-controls--transport .transport-btn { height: 36px; }

    .scs-mobile-nav {
        display: grid;
        grid-template-columns: 1fr 1fr;   /* create | discover (flip retired → tap the card) */
        gap: 5px;
        padding: 5px 6px;
    }
    .scs-mobile-nav .aurora-header__nav-btn { width: auto; height: 30px; }

    /* Scene page only (where the TRANSPORT control exists — not just the
       header, which is on every page): drop the redundant header nav row and
       reserve room so the chat scroll clears the fixed bar. */
    body:has(.scene-control-surface:not(.scene-control-surface--header)) .scene-control-surface--header .drawer-controls--nav { display: none; }
    /* padding-bottom = fixed-footer clearance (100px) + a COLLAPSING scroll spacer
       (100lvh − 100dvh) = exactly the still-showing part of the URL bar. With the
       chat column hidden there's nothing below the card to scroll, so the bar never
       retracts; this spacer gives just enough scroll to hide it, and SHRINKS to 0 as
       the bar goes (no permanent gap) and is 0 on desktop/no-dynamic-bar. The card
       (100dvh-sized) then stretches into the reclaimed space. */
    body:has(.scene-control-surface:not(.scene-control-surface--header)) { padding-bottom: calc(100px + env(safe-area-inset-bottom, 0px) + (100lvh - 100dvh)); }

    /* Generate spinner on the taller mobile row — big to preview; margin tracks
       (button − row) to hold the row height. */
    /* margin box = 56 − 23 + 3 = 36 = the lowered row, so it still straddles. */
    .drawer-controls--transport .transport-btn--generate { width: 56px; height: 56px; margin-top: -23px; }
}

/* ── Desktop: page nav in the TOOLBAR (not the header) on every carousel page.
   The tabs are already in each toolbar (mobile-page-tabs.html), just hidden
   off-mobile — show + style them, and hide the header nav row. Safe now that
   the carousel is on a DEFINITE height (commit 99daebc4): a taller toolbar
   can't collapse the cards to pips. The nav just MOVES header→toolbar, so the
   total chrome ≈ unchanged (nudge --carousel-chrome if the fill drifts a few
   px). Mobile already shows these tabs in the bottom bar — unchanged. ── */
@media (min-width: 701px) and (min-height: 601px) {
    .scene-control-surface:not(.scene-control-surface--header) .scs-mobile-nav {
        display: grid;
        grid-template-columns: 1fr 1fr;   /* create | discover (flip retired → tap the card) */
        gap: 6px;
        padding: 6px;
    }
    .scene-control-surface:not(.scene-control-surface--header) .scs-mobile-nav .aurora-header__nav-btn {
        width: auto;
        height: 36px;
    }
    /* nav lives in the toolbar now — hide the redundant header nav row on the
       carousel pages (gallery / chat / editor). */
    body:has(.entity-2col) .scene-control-surface--header .drawer-controls--nav {
        display: none;
    }
}
