/* ==========================================================================
   ARKENSTONE AI STUDIO — workspace theme
   A deliberately distinct, focused dark chrome: entering the Studio should
   feel like stepping into another app. Self-contained palette (st- vars) so
   it renders identically regardless of the registry theme.
   ========================================================================== */

#studioApp {
    /* Follows the app theme (dark by default, [data-theme="light"] flips the
       inherited variables) — the Studio is a workspace, not a second theme. */
    --st-bg:        var(--color-canvas-primary,   #0e1013);
    --st-panel:     var(--color-canvas-secondary, #16191e);
    --st-panel-2:   var(--color-surface-card,     #1c2026);
    --st-border:    var(--color-border-rule,      #2a2f37);
    --st-ink:       var(--color-ink-primary,      #e8eaed);
    --st-ink-mut:   var(--color-ink-muted,        #9aa2ad);
    --st-gold:      var(--gold,                   #c9a961);
    --st-gold-soft: var(--gold-faint,             rgba(201,169,97,0.14));
    --st-cost:      var(--gold-light,             #ffd98a);
    --st-danger:    #e06c5f;
    --st-ok:        #5fbf8f;

    position: fixed;
    inset: 0;
    z-index: 5000;
    display: flex;
    flex-direction: column;
    background: var(--st-bg);
    color: var(--st-ink);
    font-family: var(--font-body, inherit);
    font-size: 14px;
}
/* The container and its overlays (picker modal, inspector, views) toggle via
   the HTML hidden attribute — author display rules must never defeat it. */
#studioApp[hidden],
#studioApp [hidden] { display: none !important; }
body.studio-mode { overflow: hidden; }

#studioApp button { font-family: inherit; }
#studioApp a { color: var(--st-gold); }

/* ── top bar ── */
.st-topbar {
    display: flex; align-items: center; gap: 14px;
    padding: 10px 16px;
    background: var(--st-panel);
    border-bottom: 1px solid var(--st-border);
    flex: 0 0 auto;
}
.st-back {
    display: flex; align-items: center; gap: 7px;
    background: none; border: 1px solid var(--st-border); border-radius: 8px;
    color: var(--st-ink-mut); padding: 7px 12px; cursor: pointer; font-size: 13px;
}
.st-back:hover { color: var(--st-ink); border-color: var(--st-gold); }
.st-brand { display: flex; align-items: center; gap: 8px; font-size: 15px; letter-spacing: 0.2px; }
.st-brand i { color: var(--st-gold); font-size: 19px; }
.st-brand b { font-weight: 700; }
.st-project { max-width: 240px; }
.st-top-right { margin-left: auto; display: flex; align-items: center; gap: 12px; }

/* spend meter */
.st-meter { display: flex; flex-direction: column; gap: 3px; min-width: 150px; }
.st-meter-bar { height: 4px; background: var(--st-panel-2); border-radius: 3px; overflow: hidden; }
.st-meter-bar span { display: block; height: 100%; background: var(--st-gold); border-radius: 3px; transition: width 0.4s; }
.st-meter-label { font-size: 11px; color: var(--st-ink-mut); text-align: right; }
.st-meter.warn .st-meter-bar span { background: #d9a441; }
.st-meter.over .st-meter-bar span { background: var(--st-danger); }
.st-meter.over .st-meter-label { color: var(--st-danger); font-weight: 600; }

.st-icon-btn {
    background: none; border: 1px solid var(--st-border); border-radius: 8px;
    color: var(--st-ink-mut); width: 32px; height: 32px; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center; font-size: 15px;
}
.st-icon-btn:hover { color: var(--st-ink); border-color: var(--st-gold); }

/* ── body: rail + main + inspector ── */
.st-body { flex: 1 1 auto; display: flex; min-height: 0; }

.st-rail {
    flex: 0 0 76px;
    display: flex; flex-direction: column; gap: 6px;
    padding: 14px 8px;
    background: var(--st-panel);
    border-right: 1px solid var(--st-border);
}
.st-rail-btn {
    display: flex; flex-direction: column; align-items: center; gap: 4px;
    background: none; border: none; border-radius: 10px;
    color: var(--st-ink-mut); padding: 10px 4px; cursor: pointer; font-size: 11px;
}
.st-rail-btn i { font-size: 20px; }
.st-rail-btn:hover { color: var(--st-ink); background: var(--st-panel-2); }
.st-rail-btn.active { color: var(--st-gold); background: var(--st-gold-soft); }

.st-main { flex: 1 1 auto; min-width: 0; overflow-y: auto; padding: 18px; }
/* §14.7: wide desktops kept ~1500px of content in a sea of blank margin —
   the studio views (boards grid + composer panel included) now breathe to
   the window, with a generous gutter so ultrawides don't go wall-to-wall. */
.st-view { max-width: none; margin: 0 auto; padding-left: clamp(16px, 2vw, 48px); padding-right: clamp(16px, 2vw, 48px); }

/* ── banners / empty states ── */
.st-banner {
    display: flex; align-items: center; gap: 10px;
    background: var(--st-panel); border: 1px solid var(--st-border);
    border-radius: 10px; padding: 12px 16px; margin-bottom: 16px;
    color: var(--st-ink-mut); font-size: 13px;
}
.st-banner.warn { border-color: rgba(217,164,65,0.5); color: #d9a441; }
.st-empty {
    text-align: center; padding: 60px 20px; color: var(--st-ink-mut);
}
.st-empty i { font-size: 42px; color: var(--st-gold); opacity: 0.6; }
.st-empty h3 { margin: 14px 0 6px; color: var(--st-ink); font-weight: 600; }
.st-empty p { max-width: 460px; margin: 0 auto; font-size: 13px; line-height: 1.55; }

/* ── gallery grid + cards ── */
/* masonry (CSS columns) — mixed 9:16 / 1:1 / 16:9 cards pack with no ragged
   white space, unlike a fixed grid where a row's height = its tallest card */
.st-grid {
    column-width: 230px;
    column-gap: 14px;
}
.st-grid > .st-empty, .st-grid > .st-loader { column-span: all; }   /* full-width states */
.st-card {
    position: relative; border-radius: 12px; overflow: hidden;
    background: var(--st-panel-2); border: 1px solid var(--st-border);
    cursor: pointer; transition: transform 0.15s, border-color 0.15s;
    break-inside: avoid; margin: 0 0 14px;      /* column flow, not grid tracks */
}
.st-card:hover { transform: translateY(-2px); border-color: var(--st-gold); }
.st-card img { display: block; width: 100%; aspect-ratio: auto; }
/* library multi-select */
.st-card-check {
    position: absolute; top: 8px; left: 8px; z-index: 3;
    width: 24px; height: 24px; border-radius: 7px; cursor: pointer;
    background: rgba(0,0,0,0.55); border: 1.5px solid rgba(255,255,255,0.75);
    color: transparent; display: flex; align-items: center; justify-content: center;
    opacity: 0; transition: opacity .12s, background .12s, color .12s;
}
.st-card:hover .st-card-check, .st-card-check.on { opacity: 1; }
.st-card-check i { font-size: 14px; }
.st-card-check.on { background: #e879b0; border-color: #e879b0; color: #fff; }
.st-card.st-selected { border-color: #e879b0; box-shadow: 0 0 0 2px color-mix(in srgb, #e879b0 55%, transparent); }
/* bulk action bar (library) */
.st-bulk-bar {
    position: sticky; bottom: 14px; z-index: 20; margin: 6px auto 0; width: fit-content;
    display: flex; align-items: center; gap: 10px;
    background: var(--st-panel); border: 1px solid #e879b0; border-radius: 999px;
    padding: 8px 10px 8px 16px; box-shadow: 0 8px 26px rgba(0,0,0,0.35);
}
.st-bulk-count { font-size: 12.5px; font-weight: 700; color: var(--st-ink); }
.st-bulk-btn {
    display: inline-flex; align-items: center; gap: 5px;
    background: #e879b0; border: none; border-radius: 999px; color: #fff;
    font-size: 12.5px; font-weight: 600; padding: 7px 14px; cursor: pointer;
}
.st-bulk-btn.ghost { background: none; color: var(--st-ink-mut); padding: 7px 10px; }
.st-bulk-btn.ghost:hover { color: var(--st-ink); }
.st-card-overlay {
    position: absolute; top: 8px; left: 8px; right: 8px;
    display: flex; justify-content: space-between; align-items: center;
    pointer-events: none;
}
.st-card-cost {
    background: rgba(0,0,0,0.65); backdrop-filter: blur(4px);
    border-radius: 6px; padding: 2px 7px; font-size: 11px; color: #ffd98a; /* over-image badge stays light in both themes */
}
.st-card-kept { color: #ff7d95; font-size: 15px; filter: drop-shadow(0 1px 2px rgba(0,0,0,0.6)); }
.st-card-foot {
    display: flex; align-items: center; gap: 6px;
    padding: 7px 9px; font-size: 11px; color: var(--st-ink-mut);
}
.st-card-by { font-weight: 600; color: var(--st-ink); }
.st-card-age { margin-left: auto; }

/* shimmer used by in-progress generation cards (.st-genning) */
@keyframes stShimmer { to { background-position: -200% 0; } }
.st-spin { animation: stSpin 0.9s linear infinite; }
@keyframes stSpin { to { transform: rotate(360deg); } }

/* ── library bar ── */
.st-lib-bar {
    display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
    margin-bottom: 16px;
}
.st-lib-bar .st-input { flex: 1 1 200px; }
.st-lib-totals { margin-left: auto; font-size: 12px; color: var(--st-ink-mut); white-space: nowrap; }
.st-lib-totals b { color: var(--st-cost); }
.st-chip-btn {
    background: var(--st-panel-2); border: 1px solid var(--st-border); border-radius: 8px;
    color: var(--st-ink-mut); padding: 8px 10px; cursor: pointer;
}
.st-chip-btn.active { color: #ff7d95; border-color: #ff7d95; }

/* ── inputs ── */
#studioApp .st-input, #studioApp .st-select {
    background: var(--st-panel-2); border: 1px solid var(--st-border);
    color: var(--st-ink); border-radius: 8px; padding: 8px 10px; font-size: 13px;
    outline: none;
}
#studioApp .st-input:focus, #studioApp .st-select:focus, #studioApp .st-prompt:focus { border-color: var(--st-gold); }

/* ── inspector ── */
.st-inspector {
    flex: 0 0 320px;
    background: var(--st-panel); border-left: 1px solid var(--st-border);
    overflow-y: auto; padding: 14px;
    display: flex; flex-direction: column; gap: 12px;
}
.st-insp-head { display: flex; justify-content: space-between; align-items: center; font-weight: 600; }
/* .st-act is shared chrome: lightbox actions, queue buttons, load-more */
.st-act {
    display: flex; align-items: center; gap: 9px;
    background: var(--st-panel-2); border: 1px solid var(--st-border); border-radius: 9px;
    color: var(--st-ink); padding: 10px 12px; cursor: pointer; font-size: 13px;
    text-decoration: none;
}
.st-act:hover { border-color: var(--st-gold); }
.st-act.danger { color: var(--st-danger); }
.st-act.danger:hover { border-color: var(--st-danger); }

/* ── prompt bar ── */
.st-promptbar {
    flex: 0 0 auto;
    background: var(--st-panel);
    border-top: 1px solid var(--st-border);
    padding: 10px 16px 12px;
    display: flex; flex-direction: column; gap: 8px;
}
.st-modes { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; }
.st-modes::-webkit-scrollbar { display: none; }
.st-mode-btn {
    display: flex; align-items: center; gap: 6px; white-space: nowrap;
    background: none; border: 1px solid transparent; border-radius: 20px;
    color: var(--st-ink-mut); padding: 6px 13px; cursor: pointer; font-size: 12.5px;
}
.st-mode-btn:hover { color: var(--st-ink); }
.st-mode-btn.active { color: var(--st-gold); border-color: var(--st-gold); background: var(--st-gold-soft); }

.st-bar-row { display: flex; gap: 10px; align-items: flex-end; }
.st-refs { display: flex; gap: 6px; align-items: center; flex: 0 0 auto; }
.st-ref-add {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
    width: 52px; height: 52px;
    background: var(--st-panel-2); border: 1px dashed var(--st-border); border-radius: 10px;
    color: var(--st-ink-mut); cursor: pointer; font-size: 10px;
}
.st-ref-add:hover { border-color: var(--st-gold); color: var(--st-gold); }
.st-ref-chip { position: relative; width: 52px; height: 52px; border-radius: 10px; overflow: hidden; border: 1px solid var(--st-border); }
.st-ref-chip img { width: 100%; height: 100%; object-fit: cover; }
.st-ref-chip button {
    position: absolute; top: 2px; right: 2px;
    width: 17px; height: 17px; border-radius: 50%;
    background: rgba(0,0,0,0.7); border: none; color: #fff; font-size: 10px;
    display: flex; align-items: center; justify-content: center; cursor: pointer;
    /* Above the invisible full-chip role <select> (inset:0, later in the DOM)
       — without this the select owns the whole chip and the × is unclickable
       on any chip that carries a role (the base chip has none, which is why
       only ITS × worked). */
    z-index: 2;
}
/* Role strip — every reference AFTER the base says what it is, because the
   model otherwise infers a role from position and guesses "another scene".
   Sits INSIDE the chip's bounds so the chip keeps overflow:hidden. */
/* Role: a legible BADGE for reading, and an invisible full-chip <select> for
   changing it. The badge and the control were the same 15px-tall, 8.5px-font
   element before, which made it both unreadable and undiscoverable. Splitting
   them keeps the chip at 52×52 — the .st-ref-add tile matches that exactly, so
   the tray must not reflow — while the whole thumbnail becomes the hit target
   and the native list opens at system font size. */
.st-ref-tag {
    position: absolute; left: 0; right: 0; bottom: 0; height: 14px;
    background: rgba(0,0,0,0.72); color: #fff;
    font-size: 9px; font-weight: 700; letter-spacing: .04em;
    display: flex; align-items: center; justify-content: center;
    pointer-events: none;                 /* the select underneath owns the click */
    overflow: hidden; white-space: nowrap;
}
.st-ref-chip .st-ref-role {
    position: absolute; inset: 0; width: 100%; height: 100%;
    opacity: 0; cursor: pointer; border: none;
    appearance: none; -webkit-appearance: none;
}
.st-ref-chip .st-ref-role:focus-visible {
    opacity: 1; background: rgba(0,0,0,0.55); color: #fff;
    outline: 2px solid var(--st-gold); outline-offset: -2px;
}
.st-ref-add:disabled { opacity: .45; cursor: not-allowed; }
/* the native popup is the light system list — keep its options readable */
.st-ref-chip .st-ref-role option { background: #fff; color: #222; font-size: 12px; }
.st-prompt {
    flex: 1 1 auto; resize: none; min-height: 52px; max-height: 120px;
    background: var(--st-panel-2); border: 1px solid var(--st-border);
    color: var(--st-ink); border-radius: 12px; padding: 15px 14px;
    font-size: 14px; font-family: inherit; outline: none; line-height: 1.45;
}
.st-controls { display: flex; gap: 7px; align-items: center; flex: 0 0 auto; }
.st-generate {
    display: flex; align-items: center; gap: 8px;
    background: var(--st-gold); border: none; border-radius: 10px;
    color: #16191e; padding: 13px 20px; cursor: pointer;
    font-size: 14px; font-weight: 700;
}
.st-generate:hover { filter: brightness(1.08); }
.st-generate:disabled { opacity: 0.6; cursor: default; }
.st-generate em { font-style: normal; font-size: 11px; font-weight: 600; opacity: 0.75; }
.st-mode-hint { font-size: 11.5px; color: var(--st-ink-mut); padding-left: 2px; }
.st-mode-hint i { color: var(--st-gold); }

/* ── source picker modal ── */
.st-modal {
    position: absolute; inset: 0; z-index: 20;
    background: rgba(0,0,0,0.6); backdrop-filter: blur(3px);
    display: flex; align-items: center; justify-content: center; padding: 20px;
}
.st-modal-card {
    width: min(860px, 100%); max-height: 84vh;
    background: var(--st-panel); border: 1px solid var(--st-border); border-radius: 14px;
    display: flex; flex-direction: column;
    overflow: visible;      /* let the project dropdown escape the card, not clip */
}
.st-modal-head { border-radius: 14px 14px 0 0; }
.st-modal-head {
    display: flex; justify-content: space-between; align-items: center;
    padding: 14px 18px; font-weight: 600; border-bottom: 1px solid var(--st-border);
}
.st-picker-bar { display: flex; gap: 10px; padding: 12px 18px; border-bottom: 1px solid var(--st-border);
                 align-items: center; flex-wrap: wrap; }
.st-picker-bar .st-select { flex: 1; }
/* Project media vs the studio-wide reference library. A segmented control
   rather than a dropdown: two options, and which one you are on has to be
   readable without opening anything. */
.st-picker-tabs { display: inline-flex; background: var(--st-panel-2);
                  border: 1px solid var(--st-border); border-radius: 8px; padding: 2px; }
.st-picker-tabs[hidden] { display: none; }
.st-picker-tab {
    background: none; border: none; cursor: pointer; border-radius: 6px;
    padding: 6px 12px; font-size: 12.5px; color: var(--st-ink-mut); white-space: nowrap;
}
.st-picker-tab.active { background: var(--st-gold-soft); color: var(--st-ink); font-weight: 600; }
.st-picker-tab:hover:not(.active) { color: var(--st-ink); }
.st-upload-btn {
    display: flex; align-items: center; gap: 7px;
    background: var(--st-panel-2); border: 1px solid var(--st-border); border-radius: 8px;
    color: var(--st-ink); padding: 8px 14px; cursor: pointer; font-size: 13px;
}
.st-upload-btn:hover { border-color: var(--st-gold); }
.st-picker-grid { overflow-y: auto; padding: 14px 18px; border-radius: 0 0 14px 14px; }
.st-picker-hint { color: var(--st-ink-mut); font-size: 13px; padding: 20px 0; text-align: center; }
.st-picker-cat { font-size: 12px; font-weight: 700; color: var(--st-gold); margin: 10px 0 8px; text-transform: uppercase; letter-spacing: 0.5px; }
/* masonry: each thumbnail keeps its NATURAL aspect ratio (9:16 tall, 16:9
   wide) and packs tightly — no letterbox, no wasted background */
.st-picker-row { columns: 132px; column-gap: 10px; }
.st-picker-thumb {
    display: block; width: 100%; break-inside: avoid; margin: 0 0 10px;
    background: var(--st-panel-2); border: 1px solid var(--st-border); border-radius: 10px;
    overflow: hidden; cursor: pointer; padding: 0; text-align: left;
}
.st-picker-thumb:hover { border-color: var(--st-gold); }
.st-picker-imgwrap { position: relative; display: block; width: 100%; line-height: 0; }
.st-picker-imgwrap img { display: block; width: 100%; height: auto; }
.st-ratio {
    position: absolute; right: 4px; bottom: 4px;
    background: rgba(0,0,0,0.72); color: #fff; font-size: 9px; font-weight: 700;
    border-radius: 4px; padding: 1px 5px; letter-spacing: 0.3px;
}
.st-picker-thumb > span {
    display: block; padding: 5px 8px; font-size: 10.5px; color: var(--st-ink-mut);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* custom-model experiment picker rows */
.st-model-row {
    display: flex; flex-direction: column; gap: 1px; width: 100%;
    background: var(--st-panel-2); border: 1px solid var(--st-border); border-radius: 9px;
    color: var(--st-ink); padding: 9px 12px; margin-bottom: 6px; cursor: pointer; text-align: left;
}
.st-model-row:hover { border-color: var(--st-gold); }
.st-model-row b { font-size: 13px; font-weight: 600; }
.st-model-row small { font-size: 10.5px; color: var(--st-ink-mut); }

/* ══ SMART PROJECT DROPDOWN (QT-picker pattern: search + client subtitle) ══ */
.st-dd { position: relative; min-width: 190px; }
#stProjDD { max-width: 280px; }
.st-dd-btn {
    display: flex; align-items: center; gap: 9px; width: 100%;
    background: var(--st-panel-2); border: 1px solid var(--st-border); border-radius: 9px;
    color: var(--st-ink); padding: 6px 10px; cursor: pointer; font-size: 13px; text-align: left;
}
.st-dd-btn:hover { border-color: var(--st-gold); }
.st-dd-btn > .ph-caret-down { margin-left: auto; font-size: 11px; color: var(--st-ink-mut); }
.st-dd-thumb {
    width: 30px; height: 30px; border-radius: 7px; overflow: hidden; flex: 0 0 auto;
    background: var(--st-panel); display: inline-flex; align-items: center; justify-content: center;
    color: var(--st-ink-mut); font-size: 14px; border: 1px solid var(--st-border);
}
.st-dd-thumb img { width: 100%; height: 100%; object-fit: cover; }
.st-dd-thumb.none { color: var(--st-gold); }
.st-dd-info { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.st-dd-info b { font-weight: 600; font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-dd-info b em { font-style: normal; color: var(--st-gold); font-size: 11px; }
.st-dd-info small { font-size: 11px; color: var(--st-ink-mut); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-dd-panel {
    position: absolute; top: calc(100% + 6px); left: 0; z-index: 40;
    width: max(100%, 300px); max-height: 340px;
    background: var(--st-panel); border: 1px solid var(--st-border); border-radius: 12px;
    box-shadow: var(--shadow-deep, 0 18px 50px rgba(0,0,0,0.45));
    display: flex; flex-direction: column; overflow: hidden;
}
.st-dd-search {
    margin: 10px 10px 8px; padding: 8px 11px;
    background: var(--st-panel-2); border: 1px solid var(--st-border); border-radius: 8px;
    color: var(--st-ink); font-size: 13px; outline: none;
}
.st-dd-search:focus { border-color: var(--st-gold); }
.st-dd-list { overflow-y: auto; padding: 0 6px 8px; }
.st-dd-item {
    display: flex; align-items: center; gap: 9px; width: 100%;
    background: none; border: none; border-radius: 8px;
    color: var(--st-ink); padding: 7px 8px; cursor: pointer; text-align: left;
}
.st-dd-item:hover { background: var(--st-gold-soft); }
.st-dd-empty { padding: 14px; text-align: center; color: var(--st-ink-mut); font-size: 12.5px; }
/* studio-collections section in the scope dropdown */
.st-dd-group {
    padding: 8px 10px 3px; font-size: 10px; font-weight: 800; letter-spacing: 0.6px;
    text-transform: uppercase; color: var(--st-ink-mut);
}
.st-dd-coll { color: #e879b0 !important; background: color-mix(in srgb, #e879b0 12%, transparent); }
.st-dd-new { color: var(--st-gold); font-weight: 700; }
.st-dd-new .st-dd-coll { color: var(--st-gold) !important; background: var(--st-gold-soft); }

/* add-to-collection chooser (modal) */
.st-coll-list { padding: 8px; display: flex; flex-direction: column; gap: 2px; max-height: 60vh; overflow-y: auto; }
.st-coll-opt {
    display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
    background: none; border: none; border-radius: 9px; padding: 8px 10px; cursor: pointer; color: var(--st-ink);
}
.st-coll-opt:hover { background: var(--st-gold-soft); }
.st-coll-opt.active { background: color-mix(in srgb, #e879b0 12%, transparent); }
.st-coll-opt-info { display: flex; flex-direction: column; line-height: 1.25; flex: 1; min-width: 0; }
.st-coll-opt-info b { font-size: 13px; font-weight: 600; }
.st-coll-opt-info small { font-size: 11px; color: var(--st-ink-mut); }
.st-coll-check { color: #e879b0; font-size: 16px; }
.st-coll-opt.new { color: var(--st-gold); font-weight: 600; }
.st-coll-opt.remove { color: var(--st-ink-mut); }
/* lightbox action reflects that the asset is already in a collection */
.st-act.on { color: #e879b0; border-color: color-mix(in srgb, #e879b0 45%, transparent); }

/* ══ ACTIVE LOADER — mode-tinted ring + staged copy + live timer ══ */
.st-loader {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 14px; padding: 28px 16px; text-align: center; width: 100%;
}
.st-loader-ring {
    position: relative; width: 54px; height: 54px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    color: var(--stm, var(--st-gold)); font-size: 22px;
}
.st-loader-ring::before {
    content: ''; position: absolute; inset: 0; border-radius: 50%;
    border: 2.5px solid transparent;
    border-top-color: var(--stm, var(--st-gold));
    border-right-color: var(--stm, var(--st-gold));
    animation: stSpin 0.9s linear infinite;
}
.st-loader-ring::after {
    content: ''; position: absolute; inset: 6px; border-radius: 50%;
    background: color-mix(in srgb, var(--stm, var(--st-gold)) 12%, transparent);
    animation: stPulse 1.8s ease-in-out infinite;
}
.st-loader-ring i { position: relative; z-index: 1; }
@keyframes stPulse { 0%,100% { transform: scale(0.9); opacity: 0.5; } 50% { transform: scale(1.08); opacity: 1; } }
.st-loader-copy { display: flex; flex-direction: column; gap: 4px; align-items: center; }
.st-loader-stage { font-size: 12.5px; font-weight: 600; color: var(--st-ink); }
.st-loader-stage.flip { animation: stStageIn 0.35s ease; }
@keyframes stStageIn { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }
.st-loader-timer { font-size: 11px; color: var(--st-ink-mut); font-variant-numeric: tabular-nums; }

/* generation-in-progress card */
.st-genning {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    min-height: 220px; cursor: default;
    border: 1px dashed color-mix(in srgb, var(--stm, var(--st-gold)) 55%, transparent);
    background:
        linear-gradient(100deg, transparent 40%, color-mix(in srgb, var(--stm, var(--st-gold)) 7%, transparent) 50%, transparent 60%) var(--st-panel-2);
    background-size: 200% 100%;
    animation: stShimmer 1.6s infinite;
}
.st-genning:hover { transform: none; border-color: color-mix(in srgb, var(--stm, var(--st-gold)) 55%, transparent); }
/* The in-progress card's footer. It used to be shrink-to-fit and centred by the
   card's `align-items: center`, so at a narrow column — the Activity panel open,
   six columns — its natural width exceeded the card and `overflow: hidden` sliced
   the cost pill in half, leaving "~AED 0." butted against the next card.

   Now it spans the card, the label ellipsises, and the price is never the thing
   that gets cut: a truncated mode name still reads, a truncated number lies. */
.st-gen-meta {
    display: flex; align-items: center; gap: 8px;
    width: 100%; box-sizing: border-box; padding: 0 10px 12px;
    font-size: 11px; color: var(--st-ink-mut);
}
.st-gen-meta > span:first-child {
    min-width: 0;                       /* without this a flex item refuses to shrink */
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.st-gen-meta .st-card-cost { flex: 0 0 auto; margin-left: auto; }

/* ══ MODE COLOUR-CODING (context accents) ══ */
.st-mode-btn.active {
    color: var(--stm, var(--st-gold));
    border-color: var(--stm, var(--st-gold));
    background: color-mix(in srgb, var(--stm, var(--st-gold)) 13%, transparent);
}
.st-promptbar .st-generate { background: var(--stm, var(--st-gold)); color: #16130c; }
.st-mode-hint i { color: var(--stm, var(--st-gold)); }
.st-mode-chip {
    display: inline-flex; align-items: center; gap: 4px;
    background: rgba(0,0,0,0.62); backdrop-filter: blur(4px);
    border-left: 3px solid var(--stm, var(--st-gold));
    border-radius: 6px; padding: 2px 8px; font-size: 10.5px; color: #fff;
}
.st-mode-chip i { color: var(--stm, var(--st-gold)); font-size: 12px; }
.st-mode-chip.lg {
    background: color-mix(in srgb, var(--stm, var(--st-gold)) 14%, transparent);
    border: 1px solid color-mix(in srgb, var(--stm, var(--st-gold)) 45%, transparent);
    border-left-width: 3px; color: var(--st-ink); font-size: 11px; padding: 3px 10px; border-radius: 20px;
}
.st-inspector { border-top: 2px solid var(--stm, transparent); }

/* reframe continuity verdict chips (2026-08-14) */
.st-cont-warn {
    display: inline-flex; align-items: center; gap: 4px;
    background: rgba(0,0,0,0.62); backdrop-filter: blur(4px);
    border-left: 3px solid #e67e22;
    border-radius: 6px; padding: 2px 8px; font-size: 10.5px; color: #ffd9b3;
}
.st-cont-warn i { color: #e67e22; font-size: 12px; }
.st-cont-ok {
    display: inline-flex; align-items: center;
    background: rgba(0,0,0,0.62); backdrop-filter: blur(4px);
    border-radius: 6px; padding: 2px 6px; font-size: 12px; color: #7ac68f;
}
.st-cont-modelhint { display: flex; align-items: flex-start; gap: 6px; margin-top: 6px; }
.st-cont-modelhint i { color: var(--st-gold); margin-top: 1px; }

/* base image required → pulse the add button in the mode colour */
.st-ref-add.needed {
    border-color: var(--stm, var(--st-gold));
    color: var(--stm, var(--st-gold));
    animation: stNeed 1.6s ease-in-out infinite;
}
@keyframes stNeed {
    0%,100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--stm, var(--st-gold)) 45%, transparent); }
    55%     { box-shadow: 0 0 0 7px transparent; }
}

/* new result cards ease in */
.st-enter { animation: stEnter 0.4s ease; }
@keyframes stEnter { from { opacity: 0; transform: translateY(8px) scale(0.98); } to { opacity: 1; transform: none; } }

/* ══ PROMPT ASSIST ══ */
.st-prompt-wrap { position: relative; flex: 1 1 auto; display: flex; }
.st-prompt-wrap .st-prompt { flex: 1; padding-right: 46px; }
.st-assist {
    position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
    width: 34px; height: 34px; border-radius: 9px;
    background: var(--st-gold-soft); border: 1px solid transparent;
    color: var(--st-gold); font-size: 16px; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
}
.st-assist:hover { border-color: var(--st-gold); }
.st-assist.busy { opacity: 0.7; }

/* ══ PRESETS ══ */
.st-preset-btn {
    display: flex; align-items: center; white-space: nowrap;
    background: none; border: 1px solid var(--st-border); border-radius: 20px;
    color: var(--st-ink-mut); padding: 6px 11px; cursor: pointer; font-size: 14px;
}
.st-preset-btn:hover { color: var(--st-gold); border-color: var(--st-gold); }
.st-preset-panel {
    position: absolute; bottom: calc(100% + 8px); left: 14px; z-index: 45;
    width: min(360px, calc(100vw - 28px)); max-height: 420px; overflow-y: auto;
    background: var(--st-panel); border: 1px solid var(--st-border); border-radius: 14px;
    box-shadow: var(--shadow-deep, 0 18px 50px rgba(0,0,0,0.45));
    padding: 6px;
}
.st-promptbar { position: relative; }
.st-preset-head {
    display: flex; justify-content: space-between; align-items: center;
    padding: 8px 10px 6px; font-weight: 600; font-size: 13px;
}
.st-preset-head i { color: var(--st-gold); }
.st-preset-save {
    display: flex; align-items: center; gap: 8px; width: 100%;
    background: var(--st-gold-soft); border: 1px dashed var(--st-gold); border-radius: 9px;
    color: var(--st-gold); padding: 9px 12px; cursor: pointer; font-size: 12.5px;
    margin-bottom: 6px;
}
.st-preset-item { display: flex; align-items: stretch; gap: 4px; margin-bottom: 3px; }
.st-preset-apply {
    flex: 1; display: flex; align-items: center; gap: 10px; min-width: 0;
    background: none; border: none; border-left: 3px solid var(--stm, var(--st-gold));
    border-radius: 8px; color: var(--st-ink); padding: 8px 10px; cursor: pointer; text-align: left;
}
.st-preset-apply:hover { background: color-mix(in srgb, var(--stm, var(--st-gold)) 10%, transparent); }
.st-preset-apply i { color: var(--stm, var(--st-gold)); font-size: 16px; flex: 0 0 auto; }
.st-preset-apply span { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; }
.st-preset-apply b { font-size: 12.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-preset-apply small { font-size: 10.5px; color: var(--st-ink-mut); }
.st-preset-del {
    background: none; border: none; color: var(--st-ink-mut); cursor: pointer;
    padding: 0 8px; border-radius: 8px; font-size: 13px;
}
.st-preset-del:hover { color: var(--st-danger); }

/* ══ VIDEO WORKSPACE (P3) ══ */
.st-rail-video.active { color: #e879b0; background: color-mix(in srgb, #e879b0 13%, transparent); }
.st-rail-video:hover  { color: #e879b0; }

/* FIRST → LAST keyframe slots */
/* ── camera / motion preset chips (video bar) ── */
.st-motion {
    display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
    padding: 8px 2px 2px; margin-bottom: 2px;
}
.st-motion-label {
    display: inline-flex; align-items: center; gap: 4px;
    font-size: 10px; font-weight: 800; letter-spacing: 0.5px; text-transform: uppercase;
    color: #e879b0; margin-right: 2px;
}
.st-motion-chip {
    display: inline-flex; align-items: center; gap: 4px;
    background: var(--st-panel-2); border: 1px solid var(--st-border); border-radius: 999px;
    color: var(--st-ink); font-size: 11.5px; padding: 4px 10px; cursor: pointer;
    transition: border-color .12s, background .12s, color .12s;
}
.st-motion-chip:hover { border-color: #e879b0; }
.st-motion-chip.active { background: color-mix(in srgb, #e879b0 16%, transparent); border-color: #e879b0; color: #e879b0; font-weight: 600; }
.st-motion-chip i { font-size: 12px; }
.st-icon-btn.danger:hover { color: #e06c5f; }

.st-frames { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.st-frame-arrow { color: var(--st-ink-mut); font-size: 13px; }
.st-frame-slot {
    position: relative; height: 60px; width: auto; aspect-ratio: 9 / 16;
    min-width: 30px; max-width: 128px; border-radius: 10px; overflow: hidden;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
    font-size: 9.5px; cursor: pointer; flex: 0 0 auto;
}
.st-frame-slot.empty {
    background: var(--st-panel-2); border: 1px dashed color-mix(in srgb, #e879b0 55%, transparent);
    color: #e879b0;
}
.st-frame-slot.empty:hover { border-style: solid; }
.st-frame-slot.empty.off { opacity: 0.4; cursor: not-allowed; border-color: var(--st-border); color: var(--st-ink-mut); }
.st-frame-slot.filled { border: 1px solid #e879b0; background: #000; }
/* box already matches the image ratio → contain shows the true frame, no crop */
.st-frame-slot.filled img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.st-frame-slot-tag {
    position: absolute; left: 3px; bottom: 3px; z-index: 1;
    background: rgba(0,0,0,0.75); color: #e879b0;
    font-size: 8px; font-weight: 800; letter-spacing: 0.4px;
    border-radius: 4px; padding: 1px 5px;
}
.st-frame-x {
    position: absolute; top: 2px; right: 2px; z-index: 2;
    width: 17px; height: 17px; border-radius: 50%;
    background: rgba(0,0,0,0.7); border: none; color: #fff; font-size: 10px;
    display: flex; align-items: center; justify-content: center; cursor: pointer;
}
/* keyframe aspect mismatches the other frame → offer a one-tap reframe */
.st-frame-slot.mismatch { border-color: #f0a05a; border-width: 2px; }
.st-frame-reframe {
    position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
    display: flex; align-items: center; justify-content: center; gap: 2px;
    background: rgba(240,160,90,0.92); border: none; color: #1a1206;
    font-size: 8.5px; font-weight: 800; padding: 2px 0; cursor: pointer;
}
.st-frame-reframe i { font-size: 10px; }
.st-frame-slot.reframing { opacity: 0.6; pointer-events: none; }
.st-frame-slot.reframing::after {
    content: ''; position: absolute; inset: 0; z-index: 3;
    background: rgba(0,0,0,0.35) url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="%23f0a05a" stroke-width="3"><path d="M12 2a10 10 0 0 1 10 10"><animateTransform attributeName="transform" type="rotate" from="0 12 12" to="360 12 12" dur="0.8s" repeatCount="indefinite"/></path></svg>') center no-repeat;
}

/* right-side render queue */
.st-inspector.st-queue { border-top-color: #e879b0; }
.st-queue-list { display: flex; flex-direction: column; gap: 6px; }
.st-queue-row {
    display: flex; align-items: center; gap: 10px;
    background: var(--st-panel-2); border: 1px solid var(--st-border); border-radius: 10px;
    padding: 9px 11px;
}
.st-queue-row:hover { border-color: #e879b0; }
.st-queue-row.failed { border-color: rgba(224,108,95,0.4); }
.st-queue-row > i { flex: 0 0 auto; }
.st-queue-info { flex: 1; display: flex; flex-direction: column; min-width: 0; line-height: 1.35; }
.st-queue-info b { font-size: 12px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-queue-info small { font-size: 10.5px; color: var(--st-ink-mut); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-queue-thumb {
    position: relative; width: 46px; height: 34px; border-radius: 7px; overflow: hidden;
    flex: 0 0 auto; background: #000;
    display: flex; align-items: center; justify-content: center; color: #e879b0;
}
.st-queue-thumb img { width: 100%; height: 100%; object-fit: cover; }
.st-queue-thumb > .ph-play {
    position: absolute; color: #fff; font-size: 12px;
    filter: drop-shadow(0 1px 2px rgba(0,0,0,0.8));
}
.st-queue-pills { display: flex; gap: 4px; margin-top: 3px; flex-wrap: wrap; }
.st-queue-pills em {
    font-style: normal; font-size: 9.5px; color: var(--st-ink-mut);
    background: var(--st-panel); border: 1px solid var(--st-border);
    border-radius: 5px; padding: 1px 6px;
}
.st-queue-pills em.cost { color: var(--st-cost); }
.st-queue-acts { display: flex; gap: 5px; flex: 0 0 auto; }
.st-queue-acts .st-icon-btn { width: 28px; height: 28px; font-size: 13px; }

/* avatars inside panel rows: fixed circles, never stretched by flex */
.st-card-foot .member-avatar,
.st-stat-row .member-avatar, .st-queue-row .member-avatar, .st-lb-by .member-avatar {
    flex: 0 0 auto; border-radius: 50%; overflow: hidden;
    display: inline-flex; align-items: center; justify-content: center;
}
.st-stat-row .member-avatar img, .st-queue-row .member-avatar img, .st-lb-by .member-avatar img {
    width: 100%; height: 100%; object-fit: cover;
}

/* library kind segment */
.st-seg { display: flex; gap: 2px; background: var(--st-panel-2); border: 1px solid var(--st-border); border-radius: 9px; padding: 3px; }
.st-seg button {
    display: flex; align-items: center; gap: 5px;
    background: none; border: none; border-radius: 7px;
    color: var(--st-ink-mut); padding: 6px 11px; cursor: pointer; font-size: 12px;
}
.st-seg button.active { background: var(--st-panel); color: var(--stm, var(--st-gold)); box-shadow: 0 1px 4px rgba(0,0,0,0.25); }

/* Settings panel must float ABOVE the Studio (its normal z-index is 220,
   the workspace sits at 5000) — opening Settings no longer exits the Studio */
body.studio-mode .settings-panel   { z-index: 6001; }
body.studio-mode #settingsOverlay  { z-index: 6000; }

/* settings card — connected-models summary */
.st-models-summary {
    display: flex; flex-wrap: wrap; gap: 8px 18px;
    background: rgba(95,191,143,0.08); border: 1px solid rgba(95,191,143,0.35);
    border-radius: 9px; padding: 10px 13px; font-size: 12.5px;
}
.st-models-summary.warn { background: rgba(217,164,65,0.08); border-color: rgba(217,164,65,0.4); }
.st-models-summary i { color: var(--gold, #c9a84c); }
.st-models-warn { flex-basis: 100%; color: #d9a441; font-size: 12px; }

/* context-panel stat rows */
.st-side-sec {
    font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.6px;
    color: var(--st-ink-mut); margin: 14px 2px 7px;
}
.st-stat-row {
    display: flex; align-items: center; gap: 9px;
    background: var(--st-panel-2); border: 1px solid var(--st-border); border-radius: 9px;
    padding: 8px 11px; margin-bottom: 5px; font-size: 12.5px;
}
.st-stat-row i { color: var(--st-gold); font-size: 15px; }
.st-stat-row span { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-stat-row b { font-weight: 700; }
.st-stat-row em { font-style: normal; font-size: 11px; color: var(--st-cost); min-width: 54px; text-align: right; }
.st-side-chips { display: flex; flex-wrap: wrap; gap: 6px; }

.st-empty-video i { color: #e879b0; }
.st-empty-note { font-size: 11.5px !important; opacity: 0.8; margin-top: 10px !important; }
.st-vid-badge {
    position: absolute; left: 50%; top: 45%; transform: translate(-50%, -50%);
    display: flex; align-items: center; gap: 6px;
    background: rgba(0,0,0,0.55); backdrop-filter: blur(3px);
    border-radius: 30px; padding: 8px 14px; color: #fff; font-size: 15px;
    pointer-events: none;
}
.st-vid-badge span { font-size: 11px; font-weight: 600; }
.st-card.st-vid-ph {
    min-height: 200px;
    background:
        radial-gradient(circle at 50% 42%, color-mix(in srgb, #e879b0 16%, transparent), transparent 65%) var(--st-panel-2);
}
/* native first-frame thumbnail (no server poster available) + hover preview */
.st-card-vidthumb { display: block; width: 100%; background: #000; pointer-events: none; }
.st-card-vidthumb.st-hoverprev { position: absolute; inset: 0; height: calc(100% - 32px); object-fit: cover; z-index: 1; }
.st-card.st-previewing .st-vid-badge { opacity: 0; }
.st-vid-badge { transition: opacity 0.2s; }

/* library load-more sentinel */
.st-lib-more { display: flex; justify-content: center; padding: 18px 0 8px; }
.st-lib-more .st-act { flex: 0 0 auto; }

/* ══ STRUCTURE LOCK (fal FLUX + depth ControlNet) ══ */
.st-struct {
    display: flex; align-items: center; gap: 6px; white-space: nowrap;
    background: var(--st-panel-2); border: 1px solid var(--st-border); border-radius: 8px;
    color: var(--st-ink-mut); padding: 8px 11px; cursor: pointer; font-size: 12.5px;
}
.st-struct:hover { border-color: #5fbf8f; color: #5fbf8f; }
.st-struct.active {
    color: #5fbf8f; border-color: #5fbf8f;
    background: color-mix(in srgb, #5fbf8f 12%, transparent);
}
#studioApp .st-select:disabled { opacity: 0.45; cursor: not-allowed; }

/* ══ SMART LOCK — the measured, read-only structural constraint ══
   Sits directly above the prompt so the designer reads the geometry the model
   is being held to. Deliberately NOT a textarea: it is measured, not written.
   Any facet can be dropped when they actually want it to change. */
.st-lockblock {
    border: 1px solid color-mix(in srgb, var(--st-ok) 38%, var(--st-border));
    background: color-mix(in srgb, var(--st-ok) 7%, var(--st-panel-2));
    border-radius: 11px; padding: 9px 11px; margin-bottom: 9px;
}
.st-lock-head {
    display: flex; align-items: center; gap: 7px;
    font-size: 12px; color: var(--st-ok); margin-bottom: 7px;
}
.st-lock-head strong { font-weight: 700; letter-spacing: 0.01em; }
.st-lock-sub { color: var(--st-ink-mut); font-weight: 400; font-size: 11.5px; }
.st-lock-re {
    margin-left: auto; background: none; border: none; cursor: pointer;
    color: var(--st-ink-mut); font-size: 14px; padding: 2px 4px; border-radius: 6px;
}
.st-lock-re:hover { color: var(--st-ok); background: color-mix(in srgb, var(--st-ok) 14%, transparent); }
.st-lock-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 7px; }
.st-lock-chip {
    display: inline-flex; align-items: center; gap: 5px;
    background: color-mix(in srgb, var(--st-ok) 13%, transparent);
    border: 1px solid color-mix(in srgb, var(--st-ok) 34%, transparent);
    color: var(--st-ok); border-radius: 999px; padding: 4px 10px;
    font-size: 11.5px; cursor: pointer; white-space: nowrap;
}
.st-lock-chip.off {
    background: transparent; border-color: var(--st-border);
    color: var(--st-ink-mut); text-decoration: line-through;
}
.st-lock-body {
    color: var(--st-ink); font-size: 12.5px; line-height: 1.5;
    max-height: 84px; overflow-y: auto;
    /* read-only by construction: no input, and text selection stays available
       so a designer can still copy a constraint into their own prompt */
    user-select: text;
}
.st-lock-wait, .st-lock-warn { color: var(--st-ink-mut); display: flex; align-items: center; gap: 6px; }
.st-lock-warn { color: var(--st-cost); }

/* ══ STRUCTURE CHECK — did the lock hold? ══ */
.st-check {
    display: inline-flex; align-items: center; gap: 4px;
    border-radius: 999px; padding: 2px 7px; font-size: 10.5px; font-weight: 600;
    white-space: nowrap; border: 1px solid transparent;
}
.st-check.loading { color: var(--st-ink-mut); border-color: var(--st-border); }
.st-check.ok   { color: var(--st-ok);     border-color: color-mix(in srgb, var(--st-ok) 42%, transparent);     background: color-mix(in srgb, var(--st-ok) 13%, transparent); }
.st-check.warn { color: var(--st-cost);   border-color: color-mix(in srgb, var(--st-cost) 42%, transparent);   background: color-mix(in srgb, var(--st-cost) 13%, transparent); }
.st-check.bad  { color: var(--st-danger); border-color: color-mix(in srgb, var(--st-danger) 42%, transparent); background: color-mix(in srgb, var(--st-danger) 13%, transparent); }
.st-lb-retry {
    display: inline-flex; align-items: center; gap: 5px;
    background: color-mix(in srgb, var(--st-danger) 14%, transparent);
    border: 1px solid color-mix(in srgb, var(--st-danger) 45%, transparent);
    color: var(--st-danger); border-radius: 8px; padding: 3px 9px;
    font-size: 11.5px; cursor: pointer;
}
.st-lb-retry:hover { background: color-mix(in srgb, var(--st-danger) 22%, transparent); }

/* ══ MASK EDITOR (paint the editable region) ══ */
.st-mask-card { width: min(1040px, 100%); }
.st-mask-stage {
    display: flex; align-items: center; justify-content: center;
    padding: 16px; min-height: 240px; overflow: auto;
}
.st-mask-wrap { position: relative; border-radius: 10px; overflow: hidden; box-shadow: 0 6px 24px rgba(0,0,0,0.35); }
.st-mask-wrap canvas { display: block; }
#stMaskOver {
    position: absolute; inset: 0; opacity: 0.5; cursor: crosshair;
    touch-action: none;                       /* draw, don't scroll, on touch */
}
.st-mask-tools {
    display: flex; align-items: center; gap: 10px;
    padding: 12px 18px; border-top: 1px solid var(--st-border);
}
.st-mask-tool {
    width: 38px; height: 38px; border-radius: 9px;
    background: var(--st-panel-2); border: 1px solid var(--st-border);
    color: var(--st-ink-mut); font-size: 16px; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
}
.st-mask-tool.active { color: #f0a05a; border-color: #f0a05a; background: color-mix(in srgb, #f0a05a 12%, transparent); }
#stMaskSize { width: 120px; accent-color: #f0a05a; }

/* mask chip in the refs tray */
.st-mask-open { border-color: #f0a05a55; color: #f0a05a; }
.st-mask-chip { border-color: #f0a05a; }
.st-mask-flag {
    position: absolute; left: 3px; bottom: 3px; font-size: 12px; color: #fff;
    background: #f0a05a; border-radius: 5px; padding: 2px;
}

/* ══ LIGHTBOX ══ */
#stLb {
    position: absolute; inset: 0; z-index: 60;
    background: rgba(8, 8, 10, 0.93); backdrop-filter: blur(6px);
    display: flex; flex-direction: column;
    animation: stLbIn 0.18s ease;
}
@keyframes stLbIn { from { opacity: 0; } to { opacity: 1; } }

.st-lb-top {
    display: flex; align-items: center; gap: 12px;
    padding: 12px 16px; flex: 0 0 auto; color: #e8eaed;
}
.st-lb-count { font-size: 12px; color: #9aa2ad; font-variant-numeric: tabular-nums; }
.st-lb-by { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: #cdd2d9; }
.st-lb-cost { color: #ffd98a; font-weight: 700; font-size: 13px; }
.st-lb-right { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.st-lb-zoom {
    display: flex; align-items: center; gap: 6px;
    background: rgba(255,255,255,0.07); border-radius: 8px; padding: 3px 6px;
}
.st-lb-zoom button {
    background: none; border: none; color: #cdd2d9; cursor: pointer;
    width: 24px; height: 24px; font-size: 13px;
    display: flex; align-items: center; justify-content: center;
}
.st-lb-zoom b { font-size: 11px; min-width: 42px; text-align: center; font-variant-numeric: tabular-nums; }
.st-lb-close { border-color: rgba(255,255,255,0.2); color: #e8eaed; }

.st-lb-stage {
    flex: 1 1 auto; min-height: 0;
    display: flex; align-items: center; justify-content: center;
    overflow: hidden; touch-action: none;
}
.st-lb-img {
    max-width: 96%; max-height: 100%;
    border-radius: 6px; user-select: none;
    transition: transform 0.08s linear; cursor: zoom-in;
}
.st-lb-img.zoomed { cursor: grab; transition: none; }
.st-lb-video { max-width: 96%; max-height: 100%; border-radius: 6px; background: #000; }

.st-lb-arrow {
    position: absolute; top: 50%; transform: translateY(-50%);
    width: 46px; height: 64px;
    background: rgba(0,0,0,0.45); border: 1px solid rgba(255,255,255,0.12);
    color: #fff; font-size: 22px; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    transition: background 0.15s;
}
.st-lb-arrow:hover { background: rgba(0,0,0,0.75); }
.st-lb-arrow.prev { left: 0; border-radius: 0 12px 12px 0; border-left: none; }
.st-lb-arrow.next { right: 0; border-radius: 12px 0 0 12px; border-right: none; }

.st-lb-foot {
    flex: 0 0 auto; padding: 10px 18px 14px;
    display: flex; flex-direction: column; gap: 9px; color: #e8eaed;
    background: linear-gradient(transparent, rgba(0,0,0,0.55));
}
.st-lb-prompt {
    display: flex; align-items: flex-start; gap: 10px;
    max-width: 900px; margin: 0 auto; width: 100%;
}
.st-lb-prompt p {
    flex: 1; margin: 0; font-size: 12.5px; line-height: 1.5; color: #cdd2d9;
    max-height: 60px; overflow-y: auto;
}
.st-lb-prompt .st-icon-btn { border-color: rgba(255,255,255,0.18); color: #cdd2d9; flex: 0 0 auto; }
.st-lb-chips {
    display: flex; flex-wrap: wrap; gap: 6px; justify-content: center;
}
.st-lb-chips span {
    background: rgba(255,255,255,0.07); border: 1px solid rgba(255,255,255,0.1);
    border-radius: 20px; padding: 3px 11px; font-size: 11px; color: #cdd2d9;
    display: inline-flex; align-items: center; gap: 5px;
}
.st-lb-actions {
    display: flex; flex-wrap: wrap; gap: 7px; justify-content: center;
}
.st-lb-actions .st-act {
    flex: 0 0 auto; padding: 8px 14px;
    background: rgba(255,255,255,0.07); border-color: rgba(255,255,255,0.14); color: #e8eaed;
}
.st-lb-actions .st-act:hover { border-color: var(--st-gold); }
.st-lb-actions .st-act.danger { color: #ff9c8f; }

@media (max-width: 900px) {
    .st-lb-top { flex-wrap: wrap; gap: 8px; padding: 10px; }
    .st-lb-by { display: none; }
    .st-lb-zoom { display: none; }               /* pinch covers zoom on touch */
    .st-lb-arrow { display: none; }              /* swipe covers nav */
    .st-lb-prompt p { max-height: 44px; }
    .st-lb-actions .st-act { padding: 8px 11px; font-size: 12px; }
}

/* ══ SNIP OVERLAY (target Macro / Zoom-in precisely) ══ */
#stSnip {
    position: absolute; inset: 0; z-index: 70;
    background: rgba(8,8,10,0.95); backdrop-filter: blur(4px);
    display: flex; flex-direction: column;
}
.st-snip-head {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    padding: 14px; color: #e8eaed; font-size: 13.5px; font-weight: 600;
}
.st-snip-stage {
    flex: 1 1 auto; min-height: 0; position: relative;
    display: flex; align-items: center; justify-content: center;
    touch-action: none; cursor: crosshair; padding: 8px;
}
.st-snip-stage img { max-width: 100%; max-height: 100%; user-select: none; border-radius: 6px; }
.st-snip-rect {
    position: absolute; pointer-events: none;
    border: 2px solid var(--gold, #c9a84c);
    background: rgba(201,168,76,0.14);
    box-shadow: 0 0 0 9999px rgba(0,0,0,0.45);
    border-radius: 4px;
}
.st-snip-foot {
    flex: 0 0 auto; display: flex; justify-content: center; gap: 10px; padding: 12px 16px 16px;
}
.st-snip-foot .st-act { flex: 0 0 auto; background: rgba(255,255,255,0.07); border-color: rgba(255,255,255,0.14); color: #e8eaed; }

/* ══ LIGHTBOX A/B COMPARE ══ */
.st-lb-cmp {
    display: flex; align-items: center; gap: 6px;
    background: rgba(255,255,255,0.07); border: 1px solid rgba(255,255,255,0.14); border-radius: 8px;
    color: #cdd2d9; padding: 6px 12px; cursor: pointer; font-size: 12px;
}
.st-lb-cmp.active { color: var(--st-gold); border-color: var(--st-gold); }
/* the wrapper is sized EXPLICITLY in JS to the generated image's contained
   fit within the stage — both layers then fill the exact same box, so the
   overlay is pixel-honest (identical scale, identical centring) */
.st-lb-cmpwrap {
    position: relative; line-height: 0;
    touch-action: none; cursor: ew-resize;
}
.st-lb-cmpwrap .st-lb-img {
    position: relative; z-index: 1; cursor: ew-resize;
    width: 100%; height: 100%; max-width: none; max-height: none; object-fit: contain;
}
.st-lb-cmpbase {
    position: absolute; inset: 0; width: 100%; height: 100%;
    object-fit: contain; z-index: 0; border-radius: 6px; background: #0a0a0c;
}
.st-lb-cmpdiv {
    position: absolute; top: 0; bottom: 0; width: 2px; z-index: 2;
    background: var(--st-gold, #c9a84c); pointer-events: none;
    transform: translateX(-1px);
}
.st-lb-cmpdiv span {
    position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
    display: flex; align-items: center; gap: 1px;
    background: var(--st-gold, #c9a84c); color: #16130c;
    border-radius: 20px; padding: 5px 7px; font-size: 11px;
}
.st-lb-cmptag {
    position: absolute; top: 8px; z-index: 2; pointer-events: none;
    background: rgba(0,0,0,0.72); color: #fff;
    font-size: 9px; font-weight: 800; letter-spacing: 0.5px;
    border-radius: 4px; padding: 2px 7px;
}
.st-lb-cmptag.base { left: 8px; }
.st-lb-cmptag.gen  { right: 8px; color: var(--st-gold, #c9a84c); }

/* ══ COST DASHBOARD ══ */
.st-meter { cursor: default; }
body.is-admin .st-meter { cursor: pointer; }
.st-spend-top { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.st-spend-top b { font-size: 14px; min-width: 130px; }
.st-spend-total { margin-left: auto; font-weight: 700; color: var(--st-cost); }
.st-spend-total em { font-style: normal; font-weight: 400; color: var(--st-ink-mut); font-size: 11px; }
.st-spend-total.warn { color: #d9a441; }
.st-spend-total.over { color: var(--st-danger); }
.st-spend-kinds { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.st-spend-sec { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--st-ink-mut); margin: 14px 0 8px; }
.st-spend-sec small { text-transform: none; letter-spacing: 0; font-weight: 400; }
.st-spend-list { display: flex; flex-direction: column; gap: 5px; }
.st-spend-row {
    display: flex; align-items: center; gap: 9px;
    background: var(--st-panel-2); border: 1px solid var(--st-border); border-radius: 9px;
    padding: 8px 11px; font-size: 12.5px;
}
.st-spend-row.sm { padding: 6px 10px; font-size: 12px; }
.st-spend-name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-spend-jobs { color: var(--st-ink-mut); font-size: 11px; }
.st-spend-row b { color: var(--st-cost); min-width: 62px; text-align: right; }
.st-spend-cap { display: flex; align-items: center; gap: 4px; color: var(--st-ink-mut); font-size: 11px; }
.st-spend-cap input {
    width: 62px; background: var(--st-panel); border: 1px solid var(--st-border); border-radius: 6px;
    color: var(--st-ink); padding: 3px 6px; font-size: 11px; text-align: right;
}
.st-spend-cap input:focus { border-color: var(--st-gold); outline: none; }
.st-spend-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 640px) { .st-spend-cols { grid-template-columns: 1fr; } }

/* welcome */
.st-welcome-row { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 10px; }
.st-welcome-row i { font-size: 18px; flex: 0 0 auto; margin-top: 1px; }
.st-welcome-row b { color: var(--st-ink); }

/* ── nav visibility (registry side) ── */
.nav-studio { display: none; }
body.perm-studio .nav-studio,
body.is-admin   .nav-studio { display: flex; }

/* ══ RESPONSIVE (heavily used on phones — standing rule) ═════════════════ */
@media (max-width: 900px) {
    .st-topbar { flex-wrap: wrap; gap: 8px; padding: 8px 10px; }
    .st-brand span { display: none; }
    .st-project { max-width: 150px; flex: 1; }
    .st-meter { min-width: 110px; }

    .st-body { flex-direction: column; }
    /* Five sections at `padding: 8px 16px` in a centred non-scrolling row needs
       ~450px; a phone has 412, so the last one (Reels) was simply cut off with
       no way to reach it. Icon-over-label wins the width back, and the row
       scrolls as a backstop for whatever gets added next. */
    .st-rail {
        order: 2; flex: 0 0 auto;
        flex-direction: row; justify-content: space-between;
        gap: 0; padding: 2px 4px;
        border-right: none; border-top: 1px solid var(--st-border);
        overflow-x: auto; scrollbar-width: none;
        padding-bottom: max(2px, env(safe-area-inset-bottom));
    }
    .st-rail::-webkit-scrollbar { display: none; }
    .st-rail-btn {
        flex: 1 0 auto; flex-direction: column; gap: 2px;
        padding: 7px 6px; min-width: 62px; font-size: 10px; white-space: nowrap;
    }
    .st-rail-btn i { font-size: 19px; }
    .st-main { order: 1; padding: 12px; }
    .st-grid { column-width: 150px; column-gap: 10px; }
    .st-grid .st-card { margin-bottom: 10px; }

    /* inspector becomes a bottom sheet */
    .st-inspector {
        position: fixed; left: 0; right: 0; bottom: 0; top: auto;
        max-height: 72vh; flex: none; z-index: 30;
        border-left: none; border-top: 1px solid var(--st-border);
        border-radius: 16px 16px 0 0;
        box-shadow: 0 -12px 40px rgba(0,0,0,0.5);
    }

    .st-dd { min-width: 0; flex: 1; }
    .st-dd-panel { position: fixed; left: 10px; right: 10px; width: auto; top: 20vh; max-height: 55vh; }
    .st-lib-bar .st-dd { flex: 1 1 160px; }

    /* queue panel is desktop chrome — on phones the job cards in the grid
       carry the status; the bottom sheet is reserved for real selections */
    .st-inspector.st-queue { display: none; }
    .st-frames { flex-wrap: wrap; }
    .st-seg { flex: 1 1 100%; }
    .st-seg button { flex: 1; justify-content: center; }

    .st-promptbar { padding: 8px 10px 10px; }
    .st-bar-row { flex-wrap: wrap; }
    .st-prompt-wrap { flex-basis: 100%; order: -1; }
    .st-prompt { min-height: 44px; padding: 11px 12px; padding-right: 46px; }
    .st-preset-panel { left: 8px; right: 8px; width: auto; }
    .st-controls { flex-wrap: wrap; width: 100%; }
    .st-controls .st-select { flex: 1; min-width: 0; padding: 8px 6px; }
    .st-generate { flex: 1 1 100%; justify-content: center; padding: 12px; }
    .st-mode-btn span { font-size: 11.5px; }
}

/* ══ MATERIAL SWAP — swatch slot + read specification ══ */
.st-matblock {
    border-color: color-mix(in srgb, #b98adf 40%, var(--st-border));
    background: color-mix(in srgb, #b98adf 7%, var(--st-panel-2));
}
.st-mat-head { color: #b98adf; }
.st-mat-target { display: flex; align-items: center; gap: 8px; margin-bottom: 7px; flex-wrap: wrap; }
.st-mat-target label { font-size: 11.5px; color: var(--st-ink-mut); white-space: nowrap; }
.st-mat-target input {
    flex: 1 1 220px; min-width: 0;
    background: var(--st-panel-2); border: 1px solid var(--st-border);
    color: var(--st-ink); border-radius: 8px; padding: 7px 10px; font-size: 12.5px;
    font-family: inherit; outline: none;
}
.st-mat-target input:focus { border-color: #b98adf; }
.st-mat-chip { outline: 2px solid #b98adf; outline-offset: 1px; }
.st-mat-open { border-color: color-mix(in srgb, #b98adf 45%, transparent) !important; color: #b98adf !important; }

/* ══════════════════════════════════════════════════════════════════════════
   COMPOSER LAYOUT — the prompt gets its own row
   ══════════════════════════════════════════════════════════════════════════
   Measured in headless Chrome before this change (Studio open, no project):

        1440px  prompt box 368 x 50      1280px  prompt box 215 x 50
         834px  prompt box 812 x 42       390px  prompt box 368 x 42

   Tablet and phone were already fine — the max-width:900px block below stacks
   the bar. Everything ABOVE 900px had no treatment at all, so the textarea was
   the only flexible item in a single row it shared with the refs tray, the
   structure toggle, a model <select> rendering ~40 characters ("Balanced —
   Google: Nano Banana 2 (Gemini 3.1 Flash Image Preview) · AED 0.00"), aspect,
   resolution, count and Generate. On a 13" MacBook that left 215px — you could
   not read your own prompt.

   Fix: the prompt takes a full-width row of its own, controls sit beneath it.
   Same pattern every serious generation UI converges on, and it costs one flex
   rule rather than a markup rewrite (which would break the inline handlers). */
.st-bar-row { flex-wrap: wrap; align-items: center; row-gap: 9px; }
.st-prompt-wrap { flex: 1 1 100%; order: 1; }          /* row 1, full width */
.st-refs   { order: 2; }                                /* row 2 … */
.st-frames { order: 2; }
.st-controls { order: 3; margin-left: auto; flex-wrap: wrap; justify-content: flex-end; }

/* Now that it owns a row, let it actually grow — a long prompt was previously
   capped at 120px of a 215px-wide box. stAutoGrow caps to match. */
.st-prompt { min-height: 60px; max-height: 210px; }

/* The model select was the single worst offender for horizontal space. Cap it
   and ellipsise: the full label still shows on hover and in the dropdown. */
#studioApp .st-select { max-width: 260px; text-overflow: ellipsis; }
#studioApp #stTier, #studioApp #stVTier { max-width: 300px; }

/* Laptops (the reported case): tighten the controls so they hold one row. */
@media (max-width: 1200px) {
    #studioApp .st-select { max-width: 210px; }
    #studioApp #stTier, #studioApp #stVTier { max-width: 230px; }
    .st-controls { gap: 6px; }
    .st-generate { padding: 12px 16px; }
}

/* Narrow laptops / large tablets — before the 900px stack takes over. */
@media (max-width: 1024px) {
    .st-modes { overflow-x: auto; flex-wrap: nowrap; scrollbar-width: none; }
    .st-modes::-webkit-scrollbar { display: none; }
    .st-mode-btn { flex: 0 0 auto; }
    #studioApp .st-select { max-width: 170px; }
    #studioApp #stTier, #studioApp #stVTier { max-width: 190px; }
}

/* Phones: the controls row wraps, so let it breathe and keep Generate reachable
   with a thumb rather than stranded at the end of a scrolling row. */
@media (max-width: 640px) {
    .st-bar-row { row-gap: 8px; }
    .st-prompt { min-height: 56px; max-height: 160px; font-size: 16px; }  /* 16px = no iOS zoom-on-focus */
    .st-controls { width: 100%; margin-left: 0; justify-content: space-between; }
    .st-generate { flex: 1 1 auto; justify-content: center; }
    #studioApp .st-select, #studioApp #stTier, #studioApp #stVTier { max-width: none; flex: 1 1 auto; min-width: 0; }
    .st-lock-head, .st-mat-head { flex-wrap: wrap; }
    .st-lock-sub { flex-basis: 100%; }
    .st-mat-target { flex-direction: column; align-items: stretch; gap: 5px; }
    .st-mat-target label { white-space: normal; }
    .st-lock-body { max-height: 120px; }
}

/* Card overlay collision (caught in a 390px capture): the mode chip and the
   cost badge sit at opposite ends of one row, and a long label like
   "Site → Design" ran straight under "AED 0.20". Let the label truncate and
   keep the price intact — the price is the one you must be able to trust. */
@media (max-width: 640px) {
    .st-card-overlay { gap: 6px; }
    .st-mode-chip { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .st-card-cost { flex: 0 0 auto; }
}

/* Neutral informational note (distinct from .st-lock-warn, which signals a real
   problem). Prompt-only material swap is a valid path, not a fault. */
.st-lock-note { color: var(--st-ink-mut); display: flex; align-items: center; gap: 6px; }
.st-lock-note i { color: #b98adf; }

/* Folded-mode presets (e.g. Site → Design inside From Image). A chip rather
   than a pill: it modifies the active mode instead of replacing it. */
.st-preset-row { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.st-preset-chip {
    display: inline-flex; align-items: center; gap: 6px;
    background: var(--st-panel-2); border: 1px solid var(--st-border);
    color: var(--st-ink-mut); border-radius: 999px; padding: 5px 12px;
    font-size: 12px; cursor: pointer; white-space: nowrap;
}
.st-preset-chip:hover { color: var(--stm); border-color: var(--stm); }
.st-preset-chip.on {
    color: var(--stm); border-color: var(--stm);
    background: color-mix(in srgb, var(--stm) 14%, transparent); font-weight: 600;
}

/* ══ IMAGE QUEUE — in-flight job cards live IN the masonry ══
   Reuse the established .st-genning shimmer/loader look; only add the cancel
   affordance. They share the grid with results (single render owner) so they
   can never overlap the gallery the way the old prepended skeletons did. */
.st-jobcard { position: relative; }
.st-job-x {
    position: absolute; top: 7px; right: 7px; z-index: 4;
    width: 26px; height: 26px; border-radius: 7px; cursor: pointer;
    background: rgba(0,0,0,0.55); border: 1px solid rgba(255,255,255,0.28);
    color: #fff; display: flex; align-items: center; justify-content: center; font-size: 13px;
}
.st-job-x:hover { background: var(--st-danger); border-color: var(--st-danger); }
/* Activity-panel queue rows: cancel affordance for queued jobs */
.st-queue-row { position: relative; }
.st-queue-x {
    margin-left: auto; background: none; border: none; cursor: pointer;
    color: var(--st-ink-mut); font-size: 13px; padding: 4px 6px; border-radius: 6px;
}
.st-queue-x:hover { color: var(--st-danger); background: color-mix(in srgb, var(--st-danger) 14%, transparent); }

/* ══════════════════════════════════════════════════════════════════════════
   DESIGN BOARDS — a section of Studio, not one of its generation modes.
   Kept in studio.css because it ships with the Studio bundle and shares its
   tokens; a separate stylesheet would be a second request for one panel.
   ══════════════════════════════════════════════════════════════════════════ */
.bd-wrap { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.bd-head {
    display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap;
    padding: 14px 18px; border-bottom: 1px solid var(--color-border-rule);
}
.bd-head-main { flex: 1; min-width: 220px; }
.bd-title { font-family: var(--font-display); font-size: 19px; margin: 0 0 2px; }
.bd-sub { font-size: 12px; color: var(--color-ink-muted); margin: 0; max-width: 62ch; }
.bd-head-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* Boards gets its own button rather than borrowing .st-generate: that class
   means "spend money and make a picture", and nothing in this section does. */
.bd-btn {
    display: inline-flex; align-items: center; gap: 7px;
    background: none; border: 1px solid var(--st-line, var(--color-border-rule));
    border-radius: 9px; padding: 8px 14px; cursor: pointer;
    font-family: var(--font-body); font-size: 12.5px; font-weight: 600;
    color: var(--st-ink, var(--color-ink-primary));
    transition: border-color .12s, background .12s, filter .12s;
}
.bd-btn:hover:not(:disabled) { border-color: var(--st-gold, var(--gold)); }
.bd-btn.primary {
    background: var(--st-gold, var(--gold)); border-color: transparent; color: #16191e;
}
.bd-btn.primary:hover:not(:disabled) { filter: brightness(1.08); }
.bd-btn:disabled { opacity: .5; cursor: default; }
.bd-btn.active { border-color: var(--st-gold, var(--gold)); background: color-mix(in srgb, var(--gold) 12%, transparent); }
.bd-btn.tiny { padding: 4px 9px; font-size: 11px; border-radius: 7px; }
.bd-badge {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 17px; height: 17px; padding: 0 4px; border-radius: 9px;
    background: var(--gold); color: #16191e; font-size: 10px; font-weight: 700;
}
.bd-hint-in { width: 220px; max-width: 42vw; padding: 7px 10px; }

/* Two tabs, not a route: composing and curating are the same session — a member
   files a stray reference mid-board and goes straight back to picking. */
.bd-tabs {
    display: flex; align-items: center; gap: 4px;
    padding: 0 18px; border-bottom: 1px solid var(--color-border-rule);
}
.bd-tab {
    background: none; border: none; cursor: pointer; position: relative;
    font-family: var(--font-body); font-size: 12.5px; font-weight: 600;
    color: var(--color-ink-muted); padding: 10px 12px;
}
.bd-tab.active { color: var(--color-ink-primary); }
.bd-tab.active::after {
    content: ''; position: absolute; left: 12px; right: 12px; bottom: -1px;
    height: 2px; background: var(--gold); border-radius: 2px 2px 0 0;
}
.bd-tab-count { margin-left: auto; font-size: 11px; color: var(--color-ink-muted); }

.bd-filters {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    padding: 10px 18px; border-bottom: 1px solid var(--color-border-rule);
}
.bd-filters:empty { display: none; }
.bd-domains { display: flex; gap: 4px; }
.bd-dchip {
    background: none; border: 1px solid var(--color-border-rule); border-radius: 999px;
    padding: 5px 12px; cursor: pointer; font-family: var(--font-body);
    font-size: 11.5px; font-weight: 600; color: var(--color-ink-muted);
    transition: border-color .12s, color .12s, background .12s;
}
.bd-dchip:hover { color: var(--color-ink-primary); }
.bd-dchip.active {
    border-color: var(--gold); color: var(--color-ink-primary);
    background: color-mix(in srgb, var(--gold) 14%, transparent);
}
.bd-sel {
    font-family: var(--font-body); font-size: 11.5px; padding: 6px 8px;
    border: 1px solid var(--color-border-rule); border-radius: 8px;
    background: var(--color-surface-card); color: var(--color-ink-primary);
    max-width: 170px;
}
.bd-sel:disabled { opacity: .45; }
.bd-search {
    display: flex; align-items: center; gap: 6px; flex: 1; min-width: 150px; max-width: 280px;
    border: 1px solid var(--color-border-rule); border-radius: 8px;
    padding: 5px 9px; background: var(--color-surface-card);
}
.bd-search i { font-size: 13px; color: var(--color-ink-muted); }
.bd-search input {
    flex: 1; min-width: 0; border: none; background: none; outline: none;
    font-family: var(--font-body); font-size: 11.5px; color: var(--color-ink-primary);
}
.bd-review-flag {
    background: color-mix(in srgb, #c99a2e 16%, transparent); border: none; cursor: pointer;
    border-radius: 999px; padding: 4px 10px; font-family: var(--font-body);
    font-size: 11px; font-weight: 600; color: var(--color-ink-primary);
}

.bd-body { flex: 1; display: flex; min-height: 0; }
.bd-picker { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.bd-picker-head {
    display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
    padding: 9px 18px; font-size: 12px; font-weight: 600;
    border-bottom: 1px solid var(--color-border-rule);
}
.bd-hint { font-size: 11px; font-weight: 400; color: var(--color-ink-muted); }
.bd-source-grid { flex: 1; overflow-y: auto; padding: 12px 18px 24px; }
.bd-cat {
    font-size: 10px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
    color: var(--color-ink-muted); margin: 14px 0 7px;
}
.bd-cat:first-child { margin-top: 0; }
/* The count is the point of a heading in a picker — it tells you whether a
   group is worth opening before you scan it. */
.bd-cat span {
    margin-left: 6px; font-weight: 600; letter-spacing: 0;
    color: var(--color-ink-muted); opacity: .7;
}
/* Group and Sort change the SHAPE of the results rather than which results
   there are, so they are labelled where the filters above them are not. */
.bd-ctl { display: inline-flex; align-items: center; gap: 5px; }
.bd-ctl > span {
    font-size: 10px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
    color: var(--color-ink-muted);
}
.bd-more-wrap {
    display: flex; align-items: center; justify-content: center; gap: 12px;
    padding: 18px 0 6px;
}
.bd-more-note { font-size: 11px; color: var(--color-ink-muted); }

/* Bulk actions over the current selection. Library tab only — on Moodboard the
   same selection means "these go on the board", and a Remove button there sits
   right next to the picks you just made. */
.bd-bulk {
    display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
    padding: 8px 18px; border-bottom: 1px solid var(--color-border-rule);
    background: var(--color-canvas-secondary);
}
.bd-bulk[hidden] { display: none; }
.bd-bulk-n { font-size: 12px; font-weight: 600; color: var(--color-ink-primary); margin-right: 2px; }
.bd-btn.tiny.danger { color: #9c2f2f; }
.bd-btn.tiny.danger:hover { background: #fbeaea; border-color: #e2b8b8; }

/* ── the browse-phase rail ───────────────────────────────────────────────
   Before a board is composed the rail answers "what is in here" and "what have
   I got so far", instead of holding a placard for the whole selection phase. */
.bd-rail-sec { padding: 2px 0 16px; }
.bd-rail-sec + .bd-rail-sec { border-top: 1px solid var(--color-border-rule); padding-top: 14px; }
.bd-rail-h {
    display: flex; align-items: center; gap: 8px;
    font-size: 10px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
    color: var(--color-ink-muted); margin-bottom: 8px;
}
.bd-rail-clear {
    margin-left: auto; background: none; border: none; cursor: pointer; padding: 0;
    font: inherit; letter-spacing: inherit; color: var(--color-ink-muted); text-decoration: underline;
}
.bd-rail-clear:hover { color: var(--color-ink-primary); }
.bd-rail-big { margin: 0 0 10px; font-size: 22px; font-weight: 600; line-height: 1;
               color: var(--color-ink-primary); }
.bd-rail-big span { font-size: 12px; font-weight: 400; color: var(--color-ink-muted); }
/* Every count is a filter, and every row carries its share as LENGTH.

   Three colour jobs, deliberately separated (see bdPanelLibraryHtml):
   the dot is IDENTITY — the dominant colour of the images filed under that
   style, read off the references themselves; the bar is MAGNITUDE — one
   recessive ink-derived token for every row, so nothing is coloured by rank;
   amber is STATUS and is reserved for "needs your call". The brand gold is not
   available for the bar: it measures 1.94:1 against this cream panel. */
/* MAGNITUDE is the row's own fill, so the encoding gets the full width. A 46px
   bar between the label and the count was a hairline over an invisible track —
   unreadable as a proportion, which was its only job. --pct is set inline and
   omitted entirely for a one-entry section, where there is nothing to compare
   and a full-width tint would read as a selected row.

   Scaled to the LARGEST row, not the total: at 12 of 20 for one style, scaling
   to the total leaves every other bar a stub and the shape of the tail is lost. */
.bd-rail-row {
    --pct: 0%;
    position: relative; isolation: isolate;
    display: grid; width: 100%; align-items: center;
    grid-template-columns: auto 1fr auto; gap: 8px;
    padding: 6px 8px; margin: 1px 0; border: none; border-radius: 5px;
    background: none; cursor: pointer; text-align: left;
    font-size: 12px; color: var(--color-ink-primary);
}
.bd-rail-row::before {
    content: ''; position: absolute; inset: 0; z-index: -1;
    width: var(--pct); border-radius: 5px;
    background: color-mix(in srgb, var(--color-ink-muted) 17%, transparent);
    transition: width .25s ease;
}
.bd-rail-lbl { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bd-rail-row b { font-weight: 600; color: var(--color-ink-muted);
                 font-variant-numeric: tabular-nums; min-width: 1.4em; text-align: right; }
.bd-rail-row:hover::before { background: color-mix(in srgb, var(--color-ink-muted) 28%, transparent); }
.bd-rail-row:hover { background: color-mix(in srgb, var(--color-ink-muted) 8%, transparent); }
.bd-rail-row.active { font-weight: 600; box-shadow: inset 0 0 0 1px var(--color-border-rule); }
.bd-rail-row.active::before { background: color-mix(in srgb, var(--gold) 30%, transparent); }
.bd-rail-row.active b { color: var(--color-ink-primary); }

/* IDENTITY. Ringed, because a swatch read off a photograph can land on any
   value — a pale one dissolves into the cream without it. */
.bd-rail-dot {
    width: 10px; height: 10px; border-radius: 50%;
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .35), 0 0 0 1px rgba(255, 255, 255, .35);
}
.bd-rail-dot.none { background: none; box-shadow: inset 0 0 0 1px var(--color-border-rule); }
.bd-rail-ico { font-size: 12px; line-height: 1; width: 10px; }
.bd-rail-row:not(.warn) .bd-rail-ico { color: var(--color-ink-muted); }

@media (prefers-reduced-motion: reduce) { .bd-rail-row::before { transition: none; } }

/* STATUS, reserved. Never colour alone — both of these carry an icon and words. */
.bd-rail-row.warn .bd-rail-lbl { color: #9a7b1e; font-weight: 600; }
.bd-rail-row.warn .bd-rail-ico { color: #9a7b1e; }
.bd-rail-row.warn b { color: #9a7b1e; }
.bd-rail-ok {
    display: flex; align-items: center; gap: 6px; margin: 2px 0 0;
    font-size: 11.5px; color: #2e7d54;
}
.bd-rail-ok i { font-size: 13px; }

/* The library's own colours. Not decoration — it is the one thing a reference
   library has that a column of counts cannot show. */
.bd-rail-strip {
    display: flex; gap: 3px; margin: 0 0 12px; height: 22px;
    border-radius: 5px; overflow: hidden;
}
.bd-rail-strip i { flex: 1; display: block; }
.bd-rail-note { margin: 8px 0 0; font-size: 11px; line-height: 1.4; color: var(--color-ink-muted); }
.bd-rail-by {
    margin: 14px 0 0; padding-top: 10px; font-size: 10.5px;
    color: var(--color-ink-muted); border-top: 1px solid var(--color-border-rule);
}
.bd-rail-by b { font-weight: 600; color: var(--color-ink-primary); }
.bd-rail-hexes { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 4px; }
.bd-rail-hexes i {
    width: 20px; height: 20px; border-radius: 4px; display: block;
    border: 1px solid var(--color-border-rule);
}
.bd-mini-chips { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 4px; }
.bd-mini-chip {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 2px 7px; border-radius: 10px; font-size: 11px;
    background: var(--color-canvas-secondary); color: var(--color-ink-primary);
}
.bd-mini-chip b { font-weight: 600; color: var(--color-ink-muted); }

/* Upload + filing progress. One element for both phases, because from the
   uploader's side it is one wait — and it outlives a toast, which is the whole
   reason it exists. Bottom-left so it never covers the right rail. */
.bd-tray {
    position: fixed; left: 18px; bottom: 18px; z-index: 60;
    width: 260px; max-width: calc(100vw - 36px);
    padding: 10px 12px 11px;
    background: var(--color-canvas-primary);
    border: 1px solid var(--color-border-rule); border-radius: 10px;
    box-shadow: 0 8px 26px rgba(0, 0, 0, .16);
    font-size: 12px;
}
.bd-tray[hidden] { display: none; }
.bd-tray-top { display: flex; align-items: center; gap: 8px; }
.bd-tray-label { flex: 1; min-width: 0; font-weight: 600; color: var(--color-ink-primary);
                 overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bd-tray-x { background: none; border: none; cursor: pointer; padding: 0 2px;
             color: var(--color-ink-muted); font-size: 13px; line-height: 1; }
.bd-tray-x:hover { color: var(--color-ink-primary); }
.bd-tray-bar { height: 4px; margin-top: 8px; border-radius: 3px; overflow: hidden;
               background: var(--color-canvas-secondary); }
.bd-tray-bar > i { display: block; height: 100%; border-radius: 3px;
                   background: var(--gold); transition: width .3s ease; }
/* Nothing countable yet — a bar frozen at 0% reads as a hang. */
.bd-tray-bar.idle > i { animation: bdTrayPulse 1.1s ease-in-out infinite; opacity: .55; }
@keyframes bdTrayPulse { 0%, 100% { opacity: .25; } 50% { opacity: .7; } }
.bd-tray-note { margin-top: 7px; font-size: 11px; line-height: 1.35; color: var(--color-ink-muted); }
.bd-tray.done .bd-tray-bar > i { background: #2e7d54; }
.bd-tray.warn .bd-tray-bar > i { background: #9a7b1e; }
@media (prefers-reduced-motion: reduce) {
    .bd-tray-bar > i { transition: none; }
    .bd-tray-bar.idle > i { animation: none; opacity: .5; }
}
/* Masonry, not a fixed grid. Every reference was centre-cropped to 4:3 in the
   one module whose entire job is judging pictures. Matches .rl-masonry
   (studio.css:1880) and .st-picker-row (:334), which already do this — Boards
   was the outlier among three correct implementations.

   Known trade-off: CSS columns make reading order column-major, so "newest
   first" reads down column one. Both siblings accept this. */
.bd-row { columns: 132px; column-gap: 9px; display: block; }

/* break-inside goes on the WRAP, not the tile: the wrap holds the tile AND the
   caption, and on the tile alone the caption splits into the next column. */
.bd-tile-wrap { break-inside: avoid; display: flex; flex-direction: column; gap: 4px;
                min-width: 0; margin: 0 0 9px; }
.bd-tile {
    display: block; width: 100%; position: relative; padding: 0;
    border: 2px solid transparent; border-radius: 9px;
    background: var(--color-canvas-secondary); cursor: pointer; overflow: hidden;
    transition: border-color .12s, transform .12s;
}
.bd-tile-img { position: relative; display: block; width: 100%; line-height: 0; }
.bd-tile-img img { display: block; width: 100%; height: auto; }
.bd-tile:hover { transform: translateY(-1px); border-color: var(--color-border-rule); }
.bd-tile.picked { border-color: var(--gold); }
/* An unfiled image is usable but the composer knows less about it — a dashed
   edge says "still landing" without hiding it from the grid. */
.bd-tile.unfiled { border-style: dashed; border-color: color-mix(in srgb, #c99a2e 55%, transparent); }
/* The order badge is the point: selection order carries into the board, so it
   has to be visible while picking rather than discovered afterwards. */
.bd-tick {
    position: absolute; top: 6px; left: 6px;
    width: 22px; height: 22px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 11px; font-weight: 700; color: #fff;
    background: rgba(0,0,0,.42); backdrop-filter: blur(3px);
    opacity: 0; transition: opacity .12s;
}
.bd-tile.picked .bd-tick { opacity: 1; background: var(--gold); }

/* Grid, not flex, so the NAME can span the full width on its own line while the
   filing chip and the row actions share the line beneath it. Doing it in CSS
   keeps the markup flat — no wrapper div whose only job is to be a row. */
.bd-tile-meta { display: grid; grid-template-columns: 1fr auto; align-items: center;
                column-gap: 4px; min-width: 0; }
/* What the image IS. The only line that differs from tile to tile, so it gets
   the weight and the ink; the style chip below it repeats across dozens of
   tiles and reads as texture. Two lines, because a four-to-eight-word title
   truncated to one is usually cut before the words that identify it — and the
   grid is masonry, so uneven tile heights cost nothing. */
.bd-tile-name {
    grid-column: 1 / -1; min-width: 0;
    font-size: 11.5px; line-height: 1.3; font-weight: 600;
    color: var(--color-ink-primary);
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden; overflow-wrap: anywhere;
}
.bd-tag {
    grid-column: 1; min-width: 0; font-size: 10.5px; font-weight: 500;
    color: var(--color-ink-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bd-tag em { font-style: normal; font-weight: 400; color: var(--color-ink-muted); opacity: .75; }
.bd-tag.warn { color: #9a7b1e; font-weight: 600; }
/* Row actions stay out of the way until the tile is approached — the grid is
   for browsing, not administration. Touch keeps them on: no hover to reveal. */
.bd-tile-acts { grid-column: 2; display: flex; gap: 2px; opacity: 0; transition: opacity .12s; }
.bd-tile-wrap:hover .bd-tile-acts,
.bd-tile-wrap:focus-within .bd-tile-acts { opacity: 1; }
.bd-tile-acts button {
    background: none; border: none; cursor: pointer; padding: 2px 3px;
    color: var(--color-ink-muted); font-size: 12px; border-radius: 5px;
}
.bd-tile-acts button:hover { color: var(--color-ink-primary); background: var(--color-canvas-secondary); }
@media (hover: none) { .bd-tile-acts { opacity: 1; } }

.bd-tile-sub {
    font-size: 10px; color: var(--color-ink-muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.bd-detail-row { display: flex; justify-content: space-between; gap: 16px; padding: 5px 0;
                 border-bottom: 1px solid var(--color-border-rule); font-size: 12.5px; }
.bd-detail-row:last-child { border-bottom: none; }
.bd-detail-row span { color: var(--color-ink-muted); }
.bd-detail-row b { font-weight: 600; text-align: right; }

/* Mirrors .bd-tick at the opposite corner, and .bd-tile-acts' touch rule: on a
   device with no hover there is no other way to reach it. */
.bd-zoom {
    position: absolute; top: 6px; right: 6px;
    width: 22px; height: 22px; border-radius: 6px;
    display: flex; align-items: center; justify-content: center;
    background: rgba(0,0,0,0.55); color: #fff; font-size: 12px;
    opacity: 0; transition: opacity .12s; cursor: pointer;
}
.bd-tile:hover .bd-zoom, .bd-tile:focus-visible .bd-zoom { opacity: 1; }
.bd-zoom:hover { background: var(--gold); color: #1a1608; }
@media (hover: none) { .bd-zoom { opacity: 1; } }

/* Picks survive filtering, so they need somewhere to stay visible — otherwise
   choosing across three styles feels like losing the earlier ones. */
.bd-strip {
    display: flex; gap: 6px; overflow-x: auto; padding: 8px 18px;
    border-bottom: 1px solid var(--color-border-rule);
}
.bd-chip {
    position: relative; flex: 0 0 auto; width: 52px; height: 40px; padding: 0;
    border: 1px solid var(--color-border-rule); border-radius: 7px;
    overflow: hidden; cursor: pointer; background: none;
}
.bd-chip img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bd-chip span {
    position: absolute; top: 2px; left: 2px; min-width: 14px; height: 14px; padding: 0 3px;
    border-radius: 7px; background: var(--gold); color: #16191e;
    font-size: 9px; font-weight: 700; display: flex; align-items: center; justify-content: center;
}
.bd-chip i {
    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    background: rgba(0,0,0,.55); color: #fff; font-size: 14px; opacity: 0; transition: opacity .12s;
}
.bd-chip:hover i { opacity: 1; }

.bd-panel {
    flex: 0 0 340px; border-left: 1px solid var(--color-border-rule);
    overflow-y: auto; background: var(--color-canvas-secondary);
}
.bd-empty {
    padding: 28px 18px; text-align: center; font-size: 12.5px; color: var(--color-ink-muted);
}
.bd-panel-empty { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.bd-panel-empty i { font-size: 26px; opacity: .5; }
.bd-spin { animation: spin 1s linear infinite; }

.bd-dir { padding: 14px 16px 20px; }
.bd-lbl {
    display: block; font-size: 10px; font-weight: 700; letter-spacing: .09em;
    text-transform: uppercase; color: var(--color-ink-muted); margin: 16px 0 6px;
}
.bd-lbl:first-child { margin-top: 0; }
.bd-in {
    width: 100%; font-family: var(--font-body); font-size: 12.5px;
    color: var(--color-ink-primary); background: var(--color-surface-card);
    border: 1px solid var(--color-border-rule); border-radius: 8px;
    padding: 7px 9px; resize: vertical;
}
.bd-in:focus { outline: none; border-color: var(--gold); }
.bd-in-title { font-size: 14px; font-weight: 600; }
.bd-cached {
    font-size: 11px; color: var(--color-ink-muted); margin-bottom: 10px;
    display: flex; align-items: center; gap: 5px;
}

.bd-pal { display: flex; flex-direction: column; gap: 6px; }
.bd-sw {
    display: flex; align-items: center; gap: 9px;
    padding: 6px 8px; border-radius: 8px; background: var(--color-surface-card);
    border: 1px solid var(--color-border-rule);
}
.bd-sw-chip { width: 26px; height: 26px; border-radius: 6px; flex-shrink: 0; border: 1px solid rgba(0,0,0,.14); }
.bd-sw-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.bd-sw-name { font-size: 12px; font-weight: 600; }
.bd-sw-match { font-size: 10.5px; color: var(--color-ink-muted); }
.bd-sw-match.exact { color: #2d7a4e; }
.bd-sw-match.close { color: #9a7b1e; }
/* An unmatched swatch must LOOK unmatched — this is the refusal the whole
   matcher is built around, so it can't read like a quiet omission. */
.bd-sw-match.none { color: #c0392b; font-style: italic; }
.bd-sw-hex { font-size: 10px; color: var(--color-ink-muted); font-variant-numeric: tabular-nums; }

.bd-mats { display: flex; flex-direction: column; gap: 6px; }
.bd-mat {
    display: flex; flex-direction: column; gap: 2px;
    padding: 7px 9px; border-radius: 8px;
    background: var(--color-surface-card); border: 1px solid var(--color-border-rule);
}
.bd-mat-name { font-size: 12px; font-weight: 600; }
.bd-mat-desc { font-size: 11px; color: var(--color-ink-muted); line-height: 1.4; }
.bd-mat-hit { font-size: 10.5px; color: #2d7a4e; display: flex; align-items: center; gap: 4px; }

.bd-mat-hit.none { color: #c0392b; font-style: italic; }

/* The layout list is the board's running order — small enough to scan, editable
   in place, and it never hides the fact that exactly one tile is the hero. */
.bd-tiles { display: flex; flex-direction: column; gap: 5px; }
.bd-trow {
    position: relative; display: flex; align-items: center; gap: 8px;
    padding: 5px 7px; border-radius: 8px;
    background: var(--color-surface-card); border: 1px solid var(--color-border-rule);
}
.bd-trow.hero { border-color: var(--gold); }
.bd-trow > img { width: 46px; height: 34px; object-fit: cover; border-radius: 5px; flex-shrink: 0; }
.bd-trow-ctl { flex: 1; min-width: 0; display: flex; align-items: center; gap: 6px; }
.bd-size {
    font-family: var(--font-body); font-size: 10.5px; font-weight: 700; padding: 3px 4px;
    border: 1px solid var(--color-border-rule); border-radius: 6px;
    background: var(--color-canvas-secondary); color: var(--color-ink-primary);
}
.bd-cap {
    flex: 1; min-width: 0; font-family: var(--font-body); font-size: 11.5px;
    border: none; border-bottom: 1px dashed var(--color-border-rule);
    background: none; color: var(--color-ink-primary); padding: 2px 0;
}
.bd-cap:focus { outline: none; border-bottom-color: var(--gold); }
.bd-hero-flag { position: absolute; top: 3px; right: 5px; font-size: 10px; color: var(--gold); }

.bd-sugg { display: flex; flex-direction: column; gap: 6px; }
.bd-sug {
    display: flex; align-items: center; gap: 8px; padding: 6px 7px; border-radius: 8px;
    background: var(--color-surface-card); border: 1px solid var(--color-border-rule);
}
.bd-sug img { width: 42px; height: 32px; object-fit: cover; border-radius: 5px; flex-shrink: 0; }
.bd-sug-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.bd-sug-txt b { font-size: 11.5px; }
.bd-sug-txt span { font-size: 10.5px; color: var(--color-ink-muted); line-height: 1.35; }

.bd-plan { display: flex; flex-direction: column; align-items: flex-start; gap: 7px; }
.bd-plan img {
    width: 100%; max-height: 150px; object-fit: contain; border-radius: 8px;
    background: var(--color-canvas-secondary); border: 1px solid var(--color-border-rule);
}
.bd-check {
    display: flex; flex-wrap: wrap; align-items: center; gap: 7px;
    font-size: 12px; cursor: pointer;
}
.bd-check input { accent-color: var(--gold); }
.bd-check .bd-hint { flex-basis: 100%; }

/* The re-file dialog rides inside uiConfirm, so it inherits the dialog's width
   and only has to lay its own fields out. */
.bd-file-form { display: flex; flex-direction: column; gap: 3px; text-align: left; }
.bd-file-img {
    width: 100%; max-height: 150px; object-fit: cover; border-radius: 8px; margin-bottom: 8px;
}
.bd-f-lbl {
    font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    color: var(--color-ink-muted); margin-top: 9px;
}
.bd-pal-chks { display: flex; flex-wrap: wrap; gap: 5px 12px; padding: 3px 0; }
.bd-pal-chk { display: flex; align-items: center; gap: 5px; font-size: 11.5px; cursor: pointer; }
.bd-pal-chk input { accent-color: var(--gold); }
.bd-f-note { font-size: 10.5px; color: var(--color-ink-muted); margin: 10px 0 0; line-height: 1.4; }

.bd-drops, .bd-gaps { display: flex; flex-direction: column; gap: 5px; }
.bd-drop, .bd-gap {
    font-size: 11.5px; padding: 6px 9px; border-radius: 7px;
    background: var(--color-surface-card); border: 1px solid var(--color-border-rule);
}
.bd-gap { display: flex; flex-direction: column; gap: 2px; }
.bd-gap span { color: var(--color-ink-muted); font-size: 11px; }
.bd-panel-foot { display: flex; gap: 8px; margin-top: 20px; }
.bd-panel-foot .bd-btn { flex: 1; justify-content: center; }

.bd-preview-btn { width: 100%; justify-content: center; margin-top: 8px; }

/* ── saved boards ───────────────────────────────────────────────────── */
.bd-saved { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 12px; }
.bd-saved-card {
    display: flex; flex-direction: column; gap: 6px;
    border: 1px solid var(--color-border-rule); border-radius: 10px;
    background: var(--color-surface-card); padding: 8px; min-width: 0;
}
.bd-saved-cover {
    aspect-ratio: 4 / 3; border: none; border-radius: 7px; overflow: hidden; padding: 0;
    background: var(--color-canvas-secondary); cursor: pointer;
    display: flex; align-items: center; justify-content: center;
}
.bd-saved-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bd-saved-cover i { font-size: 26px; color: var(--color-ink-muted); }
.bd-saved-meta { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.bd-saved-meta b { font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bd-saved-meta span { font-size: 10.5px; color: var(--color-ink-muted); }
.bd-saved-acts { display: flex; gap: 2px; }
.bd-saved-acts button {
    flex: 1; background: none; border: 1px solid var(--color-border-rule); border-radius: 6px;
    padding: 4px 0; cursor: pointer; color: var(--color-ink-muted); font-size: 13px;
}
.bd-saved-acts button:hover { color: var(--color-ink-primary); border-color: var(--gold); }

/* ══════════════════════════════════════════════════════════════════════════
   THE BOARD CANVAS — the moodboard itself, on screen.

   Deliberately NOT themed to the app: this is what a prospect sees, so it is
   always the printed article — paper white, brand gold, serif display — inside
   whatever theme the member is using.
   ══════════════════════════════════════════════════════════════════════════ */
/* Above #studioApp (5000) — the board is opened FROM Studio and must cover it.
   Still below the settings panel (6000), which is allowed to interrupt anything. */
.bdc-ov {
    position: fixed; inset: 0; z-index: 5200;
    display: flex; flex-direction: column;
    background: rgba(14, 15, 18, .88); backdrop-filter: blur(4px);
}
.bdc-ov-bar {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 10px 14px; background: var(--color-canvas-secondary);
    border-bottom: 1px solid var(--color-border-rule); flex-wrap: wrap;
}
.bdc-ov-left, .bdc-ov-right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* Column, not row: a multi-page board stacks N `.bdc` sheets (bdCanvasHtml),
   and a row stage sat them side by side with bdFitCanvas only ever scaling the
   first (querySelector, singular) — sheets 2..N rendered full-size and blew out
   the stage. flex-start on the main (vertical) axis, not center: centering an
   overflowing column can leave a scrollable stage that can't actually be
   scrolled to its own start in some engines. align-items:center replaces the
   old justify-content:center to keep every sheet horizontally centred; the gap
   is the only spacing between stacked sheets. */
.bdc-ov-stage { flex: 1; overflow: auto; padding: 20px; display: flex;
                flex-direction: column; justify-content: flex-start; align-items: center; gap: 24px; }
.bdc-ov-stage > .bdc { flex: 0 0 auto; }

/* EXACT page size, not a minimum. Two reasons: the preview has to be the thing
   that prints (a sheet that grows on screen silently becomes a second PDF page),
   and `1fr` grid rows can only resolve against a definite height — with
   min-height the row sizing is circular and the tiles stop filling the page. */
.bdc {
    background: #fff; color: #2a2417; font-family: var(--font-body), "DM Sans", Arial, sans-serif;
    width: 794px; height: 1123px;                /* A4 at 96dpi */
    overflow: hidden;
    padding: 60px 57px 53px; display: flex; flex-direction: column;
    box-shadow: 0 12px 44px rgba(0, 0, 0, .4);
}
/* Horizontal padding is 76px = 20mm at 96dpi, matching board-layout.js's
   a3-landscape `margin:20` token (measure = 420 - 2*20 = 380mm). It used to be
   60px (~16mm), which quietly drew a 388mm content box while the packer was
   solving rows for 380mm — invisible until IMPORTANT-2 (bdCompose sending a
   real format) started actually exercising this rule. Vertical stays 53px:
   head/foot are handled separately by board-layout.js's headBlock/footBlock. */
.bdc[data-format="a3-landscape"] { width: 1587px; height: 1123px; padding: 53px 76px; }
/* M3 — #C9A84C is spec §6's gold (see the ink/paper/gold comment further down,
   by .bdc-kicker). This border and .bdc-zone predate that spec and were still
   on an earlier #C9A227 — a second, slightly different gold nobody had ever
   put side by side with the first. Unified to the one spec gold here and at
   .bdc-zone below; the .16-alpha zone FILL is the same swatch, so its rgb()
   triplet moves with it. Mirrored in BD_PRINT_CSS (Assets/js/boards.js) —
   the two must move together (see the comment atop that constant). */
.bdc-head {
    display: flex; align-items: flex-end; justify-content: space-between;
    border-bottom: 2px solid #C9A84C; padding-bottom: 8px; margin-bottom: 14px;
}
.bdc-co { font-family: var(--font-display), Georgia, serif; font-size: 22px; font-weight: 700; display: block; line-height: 1; }
.bdc-co-sub { font-size: 9.5px; color: #8a7f68; letter-spacing: .05em; }
.bdc-date { font-size: 10px; color: #8a7f68; }
.bdc-title { font-family: var(--font-display), Georgia, serif; font-size: 34px; font-weight: 700; margin: 0 0 4px; line-height: 1.05; }
.bdc-statement { font-size: 12px; color: #6a6048; margin: 0 0 14px; max-width: 70ch; line-height: 1.5; }

/* Task 8 §6 (density round): chrome slim — head ~12mm / foot ~8mm targets, so
   the packer's body budget (bodyHeight) has more of the page to fill with
   pictures instead of type. Scoped to [data-recipe] — bdPageHtml's multi-page
   sheets always carry that attribute (even data-recipe=""), the legacy
   single-sheet header/footer (.bdc-co/.bdc-title <h1>/.bdc-foot-col columns)
   never does — so this cannot touch the older render path, which shares
   .bdc-head/.bdc-title/.bdc-foot's class names but not their layout. The
   measured result of this slim is what board-layout.js's FORMATS.headBlock/
   footBlock are set to — see the comment there.

   Task 9 (spec §13.4): the real typography pass Task 8 deferred — wordmark
   + small-caps title left (.bdc-head-left, new wrapper so space-between
   puts that PAIR at one end and the page-type kicker at the other, not all
   three spread across the band), page-type kicker right. Must still fit the
   ~12mm/~8mm band Task 8 measured: shrink type here if it doesn't, never
   regrow the band (board-layout.js FORMATS.headBlock/footBlock are Task 8's,
   not touched by this round). Mirrored in BD_PRINT_CSS (Assets/js/boards.js)
   — the two must move together. */
.bdc[data-recipe] .bdc-head { padding-bottom: 6px; margin-bottom: 10px; }
.bdc-head-left { display: flex; align-items: center; gap: 3mm; }
.bdc[data-recipe] .bdc-head .bdc-title {
    font-family: var(--font-display), Georgia, serif; font-size: 11pt; font-weight: 500;
    letter-spacing: .05em; text-transform: uppercase; color: #1E1A10; line-height: 1; margin: 0;
}
.bdc-head-kicker {
    font-family: var(--font-body), "DM Sans", Arial, sans-serif; font-size: 7pt;
    letter-spacing: .30em; text-transform: uppercase; color: #C9A84C;
}
.bdc[data-recipe] .bdc-foot { padding-top: 12px; }
/* The multi-page foot's own two bare spans (bdPageHtml: board title ◆
   Arkenstone, page number) — direct children only, so the legacy footer's
   .bdc-foot-col columns (divs, not spans) can never match this. Carried no
   font-size at all before Task 8, which meant 16px browser-default text on
   a printed sheet; Task 9 gives it its real typographic treatment — natural
   case, not uppercase, a quieter byline than the head's page-type kicker. */
.bdc[data-recipe] .bdc-foot > span { font-size: 7pt; letter-spacing: .06em; line-height: 1.3; color: #8A7A58; }
/* The diamond ◆ — the house separator glyph throughout the chrome (spec
   §13.6), reused inline wherever running text needs one: this footer line,
   and the atelier cover's topbar (bdCoverHtml). */
.bdc-dia { color: #C9A84C; }

/* Task 9 (spec §13.6): furniture grounds — warm canvas + a faint gold wash
   on materials/closing (the pages with cards/a closer image sitting on
   real content, not a dense photo spread), near-white flat paper on the
   spread/direction pages so images stay the visual weight. The base rule
   here covers direction + all three ordinary spread recipes (single-air/
   offset-quad/index-grid all carry [data-recipe] with no further match
   below); materials/closing override it. Never matches the cover — that
   `<section>` carries data-concept, not data-recipe (bdCoverHtml). */
.bdc[data-recipe] { background: #FDFCF9; }
.bdc[data-recipe="materials"], .bdc[data-recipe="closing"] {
    background:
        radial-gradient(1200px 800px at 80% 0%, rgba(201, 168, 76, .08), transparent 60%),
        radial-gradient(900px 700px at 10% 100%, rgba(201, 168, 76, .04), transparent 70%),
        #FAF7F0;
}

/* `1fr` rows against the sheet's definite height: the tiles STRETCH to fill the
   page, so a four-image board is a full sheet rather than a cluster at the top
   over half a page of white. minmax(0,…) rather than a pixel floor — a floor
   would push a busy board past the page edge, and clipping a reference is worse
   than printing it small. */
.bdc-grid {
    display: grid; grid-template-columns: repeat(6, 1fr);
    grid-auto-rows: minmax(0, 1fr); gap: 5px; grid-auto-flow: dense; flex: 1;
    /* Both min-height:0 lines are load-bearing. Without them the automatic
       minimum size of a flex/grid item is its CONTENT — here the intrinsic pixel
       height of a 1600px photograph — so the grid refuses to shrink to the page
       and shoves the palette and materials off the bottom of the sheet. */
    min-height: 0;
}
.bdc-tile {
    position: relative; margin: 0; overflow: hidden; border-radius: 3px;
    background: #eceae5; min-height: 0;
}
.bdc-tile img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bdc-tile figcaption {
    position: absolute; left: 0; right: 0; bottom: 0; height: 28px;
    display: flex; align-items: flex-end; padding: 0 8px 5px;
    font-size: 8.5px; letter-spacing: .05em; text-transform: uppercase; color: #fff;
    background: linear-gradient(transparent, rgba(0, 0, 0, .62));
}

.bdc-planwrap { margin-top: 12px; }
.bdc-planhead, .bdc-foot h2 {
    font-size: 8.5px; font-weight: 700; letter-spacing: .14em;
    text-transform: uppercase; color: #9a8f78; margin: 0 0 6px;
}
.bdc-plan { position: relative; border: 1px solid #e4dfd2; border-radius: 3px; overflow: hidden; background: #fbfaf7; }
.bdc-plan img { width: 100%; display: block; max-height: 416px; object-fit: contain; }
/* Drawing needs the pointer stream, so touch scrolling has to be suppressed on
   the plan — but only while zoning, or the board can't be scrolled on a tablet. */
.bdc-planwrap.zoning .bdc-plan { cursor: crosshair; touch-action: none; }
.bdc-zone {
    position: absolute; border: 1.5px solid #C9A84C;
    background: rgba(201, 168, 76, .16); border-radius: 2px;
}
.bdc-planwrap.zoning .bdc-zone { cursor: pointer; }
.bdc-planwrap.zoning .bdc-zone:hover { background: rgba(192, 57, 43, .18); border-color: #c0392b; }
.bdc-zone.ghost { border-style: dashed; pointer-events: none; }
.bdc-zone span {
    position: absolute; left: 0; top: 0; transform: translateY(-100%);
    background: #C9A84C; color: #1a1407; font-size: 8px; font-weight: 700;
    padding: 1px 5px; border-radius: 2px 2px 0 0; white-space: nowrap;
}

/* Task 9: hairline is the `line` token (rgba(30,26,16,.08)) — shared with
   the legacy single-sheet footer below it too (harmless there, arguably an
   improvement; the old #e8e3d6 was an unrelated ad-hoc approximation). */
.bdc-foot { display: flex; gap: 22px; margin-top: auto; padding-top: 10px; border-top: 1px solid rgba(30, 26, 16, .08); }
.bdc-foot-col { flex: 1; min-width: 0; }
.bdc-pal { display: flex; flex-wrap: wrap; gap: 8px 14px; }
.bdc-sw { display: flex; align-items: center; gap: 6px; }
/* Task 9 (spec §13.2 materials density): was 16px (~4.2mm) — enlarged to a
   real mm value so it holds its size independent of screen DPI, matching
   the density round's "bigger, not thumbnails" directive. */
.bdc-sw-chip { width: 7mm; height: 7mm; border-radius: 1.5mm; border: 1px solid rgba(0, 0, 0, .12); flex-shrink: 0; }
.bdc-sw-name { font-size: 9.5px; color: #4a4535; }
.bdc-mats { margin: 0; padding: 0; list-style: none; columns: 2; column-gap: 14px; }
.bdc-mats li { font-size: 9.5px; color: #4a4535; line-height: 1.65; break-inside: avoid; }
.bdc-light p { font-size: 9.5px; color: #6a6048; margin: 0; line-height: 1.5; }

/* Justified rows: the packer already solved every width in millimetres, so the
   browser only has to lay them side by side. No flex-grow on a ROW/CELL —
   growing one would change its aspect and crop the picture.
   Task 8 §6: gutter 5mm → 4mm at A4 — mirrors board-layout.js FORMATS.gutter.
   A3 is untouched (stays 6mm).
   Task 9: flex:1 on the BODY itself (min-height:0 so it can still shrink —
   the same auto-minimum trap .bdc-grid's own comment documents) is new. Most
   recipes' rows already sum to ~bodyHeight via the packer's own fill pass
   (Task 8: "a page must end >= 90% of bodyHeight filled"), so this is a
   no-op for them — cosmetically identical, the same small residual gap just
   moves from after .bdc-body (where .bdc-foot's margin-top:auto used to
   absorb it) to inside it. Originally added for the (fix round 1: retired)
   materials page, whose banner needed this to be height-constrained rather
   than hugging its content; the closing page's own bands (fix round 1: the
   materials band, the meta band) are fixed-height, server-reserved, and
   don't depend on it — kept anyway as the generically correct behaviour for
   a sheet body regardless of which recipe currently needs it. */
.bdc-body { display: flex; flex-direction: column; gap: 4mm; flex: 1 1 auto; min-height: 0; }
.bdc[data-format="a3-landscape"] .bdc-body { gap: 6mm; }
.bdc-row { display: flex; gap: 4mm; align-items: flex-start; }
.bdc[data-format="a3-landscape"] .bdc-row { gap: 6mm; }
/* Justified rows already sum to the measure, so this is a no-op for them —
   it only centres PINNED rows (the direction pair, a single closer, a short
   final row) that would otherwise hug the left edge on a3's 380mm measure.
   a4-portrait keeps its current left alignment, the approved look there.
   Mirrored in BD_PRINT_CSS (Assets/js/boards.js) — the two must move
   together (see the comment atop that constant). */
.bdc[data-format="a3-landscape"] .bdc-row { justify-content: center; }
/* Task 8 (spec §13.1, gentle-crop fill model): the CELL now carries BOTH
   dimensions inline (bdSpreadBodyHtml/bdSpineRowHtml, Assets/js/boards.js) —
   width AND height, exactly i.wMm/i.hMm as the packer solved or grew them —
   and the IMG inside is width:100%/height:100% with object-fit:cover, not a
   per-image inline height with object-fit:fill. For an UNGROWN row wMm/hMm
   is exactly the source aspect, so cover on an exact-aspect box is a no-op:
   pixel-identical to the old fill behaviour. A GROWN row's box is taller
   than the image's own aspect at that width (heightMm rose by up to
   CROP_MAX, board-layout.js, while wMm — the solved slot width — did not),
   so cover scales the image up to cover the box and crops the excess evenly
   off both sides: the gentle crop itself, entirely in CSS.
   This is NOT the earlier column-flex-cell bug this comment used to warn
   about (image at flex:1 1 auto, height on the cell, a captioned neighbour
   stealing space back and squashing the image ~9-10%): .bdc-cell stays a
   plain block, never a flex container of its own, so the IMG's own
   width/height:100% is sized against the cell's fixed box directly — there
   is no flex distribution for a caption to compete in. The figcaption still
   flows below the image in normal flow and is allowed to overflow that now-
   fixed box (no overflow:hidden on .bdc-cell) — the row's own inline height
   above already reserves BD_CAPTION_MM of real extra room for exactly this,
   so the caption lands in uncrowded space rather than being clipped or
   squashing the image. */
/* position:relative is LOAD-BEARING: the §14.5 plan chip inside is absolute
   — without this it anchors to the board overlay and floats in the viewport
   corner (found live: "plan in one far-off corner") */
.bdc-cell { margin: 0; flex: 0 0 auto; position: relative; }
.bdc-cell img { display: block; width: 100%; height: 100%; object-fit: cover; border-radius: 3px; }
/* Task 9 (spec §13.4): DM Sans 6.5pt / .14em / uppercase / 60% ink — was
   7pt/.02em/never-uppercase, an unrelated leftover from before this round's
   token set existed. */
.bdc-cell figcaption { font-family: var(--font-body), "DM Sans", Arial, sans-serif; font-size: 6.5pt; letter-spacing: .14em; text-transform: uppercase; margin-top: 1.5mm; color: rgba(30, 26, 16, .6); }

/* Task 4 additions — spine pages (direction/closing — fix round 1: materials
   retired, spec §13.7-2), the wordmark and its fallback. LOCKSTEP with the
   equivalent block in BD_PRINT_CSS (Assets/js/boards.js, search
   ".bdc-kicker" there): the print popup never links this stylesheet, so a
   rule added to only one silently never reaches the printed PDF — exactly
   the failure mode the comment atop BD_PRINT_CSS warns about.

   Task 9 (spec §13.4/§13.6) restyle: gold small-caps kicker (was muted, no
   rules attached — the direction page-body kicker, NOT the cover's own
   flanked-rule kicker, _bdKickerHtml in boards.js); 30/34pt weight-300
   statement (was 28/36pt weight-600); the A3 kicker size bump this used to
   carry is dropped — the brief gives one size for the kicker token at both
   formats, unlike title/strap/statement which each name two. */
.bdc-kicker {
    display: block; font-family: var(--font-body), "DM Sans", Arial, sans-serif;
    font-size: 7pt; font-weight: 700; letter-spacing: .38em;
    text-transform: uppercase; color: #C9A84C; margin: 0 0 3mm;
}
/* Scoped to the direction page only — the bare .bdc-statement rule above
   (the legacy single-sheet subtitle, still used by bdCanvasHtml) is
   deliberately left alone; a legacy sheet never carries
   data-recipe="direction" so the two rules can never collide.
   Task 9: max-width widened from the spec's literal 78% to 92% — real-
   render testing found 78% too narrow to reliably hold a realistic
   statement to 3 lines within STATEMENT_BAND_MM at 30pt Cormorant Garamond
   (see the longer comment on _bdDirectionStatement, Assets/js/boards.js,
   which pairs this with a display-only character clamp). */
.bdc[data-recipe="direction"] .bdc-statement {
    font-family: var(--font-display), Georgia, serif; font-size: 30pt; font-weight: 300;
    color: #1E1A10; max-width: 92%; line-height: 1.18; margin: 0;
}
.bdc[data-format="a3-landscape"][data-recipe="direction"] .bdc-statement { font-size: 34pt; }
/* Fix round 1 (spec §13.7-2): the materials PAGE this used to lay out
   (.bdc-mat-grid/.bdc-mat-card/.bdc-mat-media/.bdc-mat-banner(+chip)/
   .bdc-mat-fam/.bdc-mat-qual/.bdc-mat-note/.bdc-mat-hit/.bdc-note-line) is
   retired outright, and its CSS with it — grepped first, confirmed nothing
   else referenced any of these selectors. See .bdc-closing-materials below
   for the compact band that replaces it, on the closing page. Mirrored in
   BD_PRINT_CSS. */
/* Task 9: the wordmark (bdMarkHtml, boards.js) replaces the old diamond
   monogram ("Logo Symbol.webp") this class used to hold — same idiom, a
   taller box (the artwork's aspect is much wider than the old square mark)
   with per-context height modifiers, since the SAME function now serves the
   page head (~6mm), the cover lockup (~10mm) and atelier's centred wordmark
   (~16mm). */
.bdc-wordmark { display: inline-flex; align-items: center; height: 6mm; }
.bdc-wordmark img { height: 100%; width: auto; display: block; }
.bdc-wordmark.sz-cover { height: 10mm; }
.bdc-wordmark.sz-hero { height: 16mm; }
.bdc-wordmark-fb {
    font-family: var(--font-body), "DM Sans", Arial, sans-serif;
    font-size: 9px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
}
.bdc-wordmark.w-white .bdc-wordmark-fb { color: #FCFBF7; }
.bdc-wordmark.w-black .bdc-wordmark-fb { color: #1E1A10; }
/* Fix round 1 (spec §13.7-2): the closing page's compact materials band —
   replaces the retired materials page (.bdc-note-line, its last element,
   retired with it). Server-side (composer.js MATERIALS_BAND_MM) reserves
   36mm below the closer image for this, ONLY when the board carries
   materials — max-height hard-caps the rendered band to match, so an
   unusually large materials count (up to LIM.materials=8, composer.js)
   wraps and clips rather than ever exceeding what was reserved, the same
   "never dominate the page" contract the old .bdc-mat-banner's own cap
   used. Mirrored in BD_PRINT_CSS. */
.bdc-closing-materials { margin-top: 5mm; max-height: 36mm; overflow: hidden; }
.bdc-cm-chips { display: flex; flex-wrap: wrap; gap: 3mm 5mm; margin-bottom: 3mm; }
.bdc-cm-chip { display: flex; align-items: center; gap: 2mm; }
.bdc-cm-swatch {
    width: 9mm; height: 9mm; border-radius: 1.5mm; flex-shrink: 0;
    overflow: hidden; background-color: #eceae5;
}
.bdc-cm-swatch img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bdc-cm-txt { display: flex; flex-direction: column; line-height: 1.3; }
.bdc-cm-fam { font-size: 7pt; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: #1E1A10; }
.bdc-cm-qual { font-size: 6.5pt; color: #4a4535; }
.bdc-cm-pal { display: flex; gap: 2.5mm; }
.bdc-cm-dot { width: 4mm; height: 4mm; border-radius: 50%; border: 1px solid rgba(0, 0, 0, .12); display: inline-block; }
/* Task 9 (spec §13.4): the closing page's meta band — Task 8 left this to
   the client ("mark, project line, date completing the page"); see the
   longer comment on bdClosingBodyHtml (Assets/js/boards.js) for why it is
   deliberately compact rather than assuming a guaranteed height budget. The
   meta grid itself (.bdc-ed-meta, Task 5/9 cover block below) is reused
   here in its LIGHT form — this page's ground is #FAF7F0, not ink. */
.bdc-closing-meta { margin-top: 6mm; }
.bdc-closing-foot { display: flex; align-items: center; justify-content: space-between; margin-top: 4mm; }
.bdc-closing-url {
    font-family: var(--font-body), "DM Sans", Arial, sans-serif;
    font-size: 7pt; letter-spacing: .18em; text-transform: uppercase; color: #C9A84C;
}

/* Task 5 additions, restyled Task 9 (spec §13.3/§13.4/§13.6) — the cover
   sheet, on the Prequalification Portfolio's own grammar. LOCKSTEP with the
   equivalent block in BD_PRINT_CSS (Assets/js/boards.js, search
   ".bdc-cover" there) — same reasoning as the Task 4 comment above: the
   print popup never links this stylesheet. The cover keeps the base .bdc
   sheet size/format/page-break rules (width/height/data-format, "just
   another sheet" in print) — only padding is overridden to 0 so a
   full-bleed concept can bleed edge to edge.

   Four concepts replace the old cinematic/duotone/mosaic/editorial set —
   'duotone' (the gold-map treatment the user called "a heavy yellow tint")
   is gone outright, its slot renamed 'atelier' and redesigned as the
   portfolio's dark editorial cover below; the .duo class / #bdDuo filter /
   .bdc-cover-grain this used to reference are gone with it (grepped both
   stylesheets and server/test-browser — nothing else names them). */
.bdc-cover { padding: 0; position: relative; }

/* The frame + corner brackets — every concept gets this (spec §13.6),
   painted last (after the media layer, in DOM order — see bdCoverHtml) so
   it always sits on top; no explicit z-index anywhere in this block, DOM
   order alone determines stacking for same-context absolutely-positioned
   siblings. Ported from the portfolio reference's own .cover-frame almost
   verbatim. */
.bdc-cover-frame { position: absolute; inset: 9mm; border: .5px solid rgba(201, 168, 76, .30); pointer-events: none; }
.bdc-cover-frame::before {
    content: ""; position: absolute; width: 9mm; height: 9mm; top: -.5px; left: -.5px;
    border-top: 1px solid #C9A84C; border-left: 1px solid #C9A84C;
}
.bdc-cover-frame::after {
    content: ""; position: absolute; width: 9mm; height: 9mm; bottom: -.5px; right: -.5px;
    border-bottom: 1px solid #C9A84C; border-right: 1px solid #C9A84C;
}

/* ── the editorial stack — shared by all four concepts, and (for the kicker
   and meta grid) by the direction statement band / closing meta band too,
   via the same _bdKickerHtml/_bdMetaGridHtml builders (Assets/js/
   boards.js) ─────────────────────────────────────────────────────────── */
.bdc-ed-kicker {
    display: flex; align-items: center; gap: 5mm;
    font-family: var(--font-body), "DM Sans", Arial, sans-serif;
    font-size: 7pt; letter-spacing: .38em; text-transform: uppercase; color: #C9A84C;
}
/* Only the flanked (centred, atelier) form needs an explicit width — the
   left-anchored covers size the kicker to its own text, which the parent's
   align-items:center already centres correctly with no width at all (see
   .bdc-cover-center below); flanked needs real room for its two flex:1
   rules to grow into, or they collapse to nothing. */
.bdc-ed-kicker.flanked { width: 100%; }
.bdc-ed-kicker-rule { flex: 1 1 auto; height: .5px; background: #C9A84C; opacity: .45; max-width: 22mm; }

.bdc-ed-title {
    font-family: var(--font-display), Georgia, serif; font-weight: 300; letter-spacing: -.02em;
    line-height: .93; font-size: 54pt; color: #F0EBE0; margin: 0;
}
.bdc[data-format="a3-landscape"] .bdc-ed-title { font-size: 64pt; }
.bdc-ed-title-turn { display: block; font-style: italic; font-weight: 400; color: #C9A84C; }

.bdc-ed-strap {
    font-family: var(--font-display), Georgia, serif; font-style: italic; font-weight: 300;
    font-size: 12pt; line-height: 1.5; max-width: 70%; margin: 0; color: rgba(240, 235, 224, .8);
}
.bdc[data-format="a3-landscape"] .bdc-ed-strap { font-size: 13pt; }

/* Light (default) form — the closing page's own reuse of this grid, on a
   #FAF7F0 ground (bdClosingBodyHtml). `.dark` is every cover concept that
   shows one — cinematic, split and atelier; bdCoverHtml never renders it
   for mosaic. */
.bdc-ed-meta {
    display: grid; grid-template-columns: repeat(4, 1fr); gap: 6mm;
    padding-top: 4mm; border-top: 1px solid rgba(30, 26, 16, .14);
}
.bdc-ed-meta .lbl {
    display: block; font-family: var(--font-body), "DM Sans", Arial, sans-serif;
    font-size: 7.5pt; letter-spacing: .22em; text-transform: uppercase; color: #8A7A58;
}
.bdc-ed-meta .val {
    display: block; margin-top: 1.5mm;
    font-family: var(--font-display), Georgia, serif; font-size: 15pt; color: #1E1A10;
}
.bdc-ed-meta.dark { border-top-color: rgba(240, 235, 224, .18); }
.bdc-ed-meta.dark .lbl { color: rgba(240, 235, 224, .5); }
.bdc-ed-meta.dark .val { color: #F0EBE0; }

/* atelier only — the topbar row and the diamond divider under the wordmark
   (.bdc-dia, the shared inline glyph, is defined with the Task 4 chrome
   above — reused here and by the page foot). */
.bdc-ed-topbar {
    display: flex; justify-content: space-between; align-items: flex-start; width: 100%;
    font-family: var(--font-body), "DM Sans", Arial, sans-serif;
    font-size: 7pt; letter-spacing: .30em; text-transform: uppercase; color: rgba(201, 168, 76, .45);
}
.bdc-ed-diamond { color: #C9A84C; font-size: 9pt; letter-spacing: .6em; opacity: .6; }

/* ── cinematic — full-bleed colour hero, no tint ──────────────────────── */
.bdc-cover-img { position: absolute; inset: 0; }
.bdc-cover-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Ink-toned scrim (not pure black), transparent until the 52% mark, so the
   top half of the photo stays completely clean — this direction is the
   actual fix for the "heavy yellow tint" complaint: nothing recolours the
   photograph at all any more, on any concept. */
.bdc-cover-scrim { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(20, 17, 10, 0) 52%, rgba(20, 17, 10, .78) 100%); }

/* ── split — top ~60% image band, bottom ink panel ────────────────────── */
.bdc-cover-split-img { position: absolute; top: 0; left: 0; right: 0; height: 60%; overflow: hidden; }
.bdc-cover-split-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bdc-cover-split-panel {
    position: absolute; left: 0; right: 0; bottom: 0; top: 60%;
    background: #1C1810; border-top: 1px solid rgba(201, 168, 76, .5);
    display: flex; flex-direction: column; justify-content: center; gap: 5mm;
    padding: 0 15mm; color: #F0EBE0;
}
.bdc[data-format="a3-landscape"] .bdc-cover-split-panel { padding: 0 20mm; }

/* ── mosaic — full-colour tiles on the ink ground; a flat veil for
   cohesion PLUS a steeper scrim confined to the lower ~38% for the title
   band (replaces the old single full-height gradient). The feature tile
   (index 0 spans 2x2) is an inline style from bdCoverHtml, nothing here. */
.bdc-cover-mosaic {
    position: absolute; inset: 0; background: #1E1A10;
    display: grid; grid-template-columns: repeat(auto-fill, minmax(28mm, 1fr));
    grid-auto-rows: 30mm; gap: 2mm; overflow: hidden;
}
.bdc-cover-tile { overflow: hidden; }
.bdc-cover-tile img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bdc-cover-veil { position: absolute; inset: 0; background: rgba(20, 17, 10, .22); }
.bdc-cover-bottom-scrim {
    position: absolute; left: 0; right: 0; bottom: 0; height: 38%;
    background: linear-gradient(180deg, rgba(20, 17, 10, .05), rgba(20, 17, 10, .66));
}

/* ── atelier — the portfolio's dark editorial cover, image-free by default,
   everything centred ──────────────────────────────────────────────────── */
.bdc-cover[data-concept="atelier"] {
    background:
        radial-gradient(1200px 800px at 80% 0%, rgba(201, 168, 76, .12), transparent 60%),
        radial-gradient(900px 700px at 10% 100%, rgba(201, 168, 76, .06), transparent 70%),
        #1C1810;
}
.bdc-cover-center {
    position: absolute; inset: 0; display: flex; flex-direction: column;
    align-items: center; justify-content: center; text-align: center; gap: 4mm;
    padding: 0 20mm; color: #F0EBE0;
}
.bdc[data-format="a3-landscape"] .bdc-cover-center { padding: 0 30mm; }
/* The optional framed plate — only when the best available image can
   actually carry it (bdCoverHtml: long edge >= 1200). */
.bdc-cover-plate { width: 34%; border: .5px solid rgba(201, 168, 76, .45); padding: 2mm; }
.bdc-cover-plate img { display: block; width: 100%; height: auto; }

/* ── shared top-left lockup + bottom-left stack — cinematic + mosaic only;
   split moves the wordmark into its own panel above, atelier centres
   everything (both above) ────────────────────────────────────────────── */
.bdc-cover-lockup { position: absolute; top: 16mm; left: 15mm; }
.bdc[data-format="a3-landscape"] .bdc-cover-lockup { top: 14mm; left: 20mm; }
.bdc-cover-stack {
    position: absolute; left: 15mm; right: 15mm; bottom: 14mm;
    display: flex; flex-direction: column; gap: 5mm; color: #F0EBE0;
}
.bdc[data-format="a3-landscape"] .bdc-cover-stack { left: 20mm; right: 20mm; bottom: 16mm; }

/* bdFitCanvas() scales the sheet to the stage rather than reflowing it — see the
   comment there. This only supplies the origin the transform needs. */
.bdc { transform-origin: top left; }
@media (max-width: 860px) {
    .bdc-ov-stage { padding: 10px; display: block; }
    .bdc-ov-bar { padding: 8px 10px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   PROJECT REELS — pre-production. Shares the Boards tokens (.bd-btn, .bd-in,
   .bd-lbl) on purpose: they are one section of Studio to a user, and a second
   button language would make them feel like two bolted-together tools.
   ══════════════════════════════════════════════════════════════════════════ */
.rl-wrap { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.rl-head {
    display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap;
    padding: 14px 18px; border-bottom: 1px solid var(--color-border-rule);
}
.rl-head-main { flex: 1; min-width: 220px; }
.rl-title { font-family: var(--font-display); font-size: 19px; margin: 0 0 2px; }
.rl-sub { font-size: 12px; color: var(--color-ink-muted); margin: 0; max-width: 64ch; }
.rl-head-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rl-tab {
    background: none; border: none; cursor: pointer; position: relative;
    font-family: var(--font-body); font-size: 12.5px; font-weight: 600;
    color: var(--color-ink-muted); padding: 10px 12px;
}
.rl-tab.active { color: var(--color-ink-primary); }
.rl-tab.active::after {
    content: ''; position: absolute; left: 12px; right: 12px; bottom: -1px;
    height: 2px; background: var(--gold); border-radius: 2px 2px 0 0;
}
/* The meter is the module's conscience — duration and money, always visible,
   updating the instant a shot drops to Tier 1. */
.rl-meter { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.rl-m { font-size: 11px; color: var(--color-ink-muted); font-variant-numeric: tabular-nums; }
.rl-m.warn { color: #c0392b; font-weight: 700; }
.rl-m.paid { color: #9a7b1e; font-weight: 700; }
.rl-m.cost { font-size: 13px; font-weight: 700; color: var(--color-ink-primary); }

.rl-body { flex: 1; overflow-y: auto; min-height: 0; }

.rl-setup { padding: 16px 18px 26px; max-width: 900px; }
.rl-setup-row { margin-bottom: 4px; }
.rl-setup-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-bottom: 4px; }
.rl-sources { margin-top: 8px; }

/* ── storyboard strip ── */
.rl-look {
    display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
    padding: 9px 18px; background: var(--color-canvas-secondary);
    border-bottom: 1px solid var(--color-border-rule);
}
.rl-look-lbl { font-size: 9.5px; font-weight: 700; letter-spacing: .12em; color: var(--color-ink-muted); }
.rl-look-in {
    flex: 1; min-width: 110px; font-family: var(--font-body); font-size: 11.5px;
    background: var(--color-surface-card); color: var(--color-ink-primary);
    border: 1px solid var(--color-border-rule); border-radius: 7px; padding: 5px 8px;
}
.rl-look-in:focus { outline: none; border-color: var(--gold); }

.rl-strip {
    display: flex; gap: 9px; overflow-x: auto; padding: 12px 18px;
    border-bottom: 1px solid var(--color-border-rule);
}
.rl-card {
    flex: 0 0 132px; display: flex; flex-direction: column; gap: 3px;
    border: 2px solid transparent; border-radius: 10px; padding: 7px;
    background: var(--color-surface-card); cursor: pointer; position: relative;
    transition: border-color .12s, transform .12s;
}
.rl-card.sel { border-color: var(--gold); }
.rl-card.dragging { opacity: .45; }
.rl-card.dragover { border-color: var(--color-ink-muted); transform: translateY(-2px); }
.rl-card-n {
    position: absolute; top: 3px; left: 3px; z-index: 2;
    width: 19px; height: 19px; border-radius: 50%;
    background: rgba(0,0,0,.55); color: #fff; font-size: 10px; font-weight: 700;
    display: flex; align-items: center; justify-content: center;
}
.rl-card-img {
    aspect-ratio: 4 / 3; border-radius: 6px; overflow: hidden;
    background: var(--color-canvas-secondary);
}
.rl-card-img img { width: 100%; height: 100%; object-fit: cover; display: block; will-change: transform; }
.rl-card-tier { font-size: 8.5px; font-weight: 700; letter-spacing: .07em; }
.rl-card-tier.paid { color: #9a7b1e; }
.rl-card-tier.free { color: #2d7a4e; }
.rl-card-move { font-size: 11px; font-weight: 600; }
.rl-card-dur { font-size: 10px; color: var(--color-ink-muted); font-variant-numeric: tabular-nums; }
.rl-card-status { font-size: 10px; color: var(--color-ink-muted); }
.rl-card-status.ready { color: #2d7a4e; }
.rl-card-status.failed { color: #c0392b; }
.rl-card-status.queued, .rl-card-status.running { color: #9a7b1e; }

/* ── shot inspector ── */
.rl-insp { padding: 14px 18px 28px; max-width: 880px; }
.rl-insp-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.rl-insp-head b { font-size: 13px; }
.rl-subj {
    flex: 1; min-width: 180px; font-family: var(--font-body); font-size: 13px; font-weight: 600;
    background: none; border: none; border-bottom: 1px dashed var(--color-border-rule);
    color: var(--color-ink-primary); padding: 3px 0;
}
.rl-subj:focus { outline: none; border-bottom-color: var(--gold); }
.rl-insp-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.rl-tiers { display: flex; gap: 8px; flex-wrap: wrap; }
.rl-tier {
    flex: 1; min-width: 170px; display: flex; align-items: center; gap: 7px;
    border: 1px solid var(--color-border-rule); border-radius: 9px;
    padding: 9px 11px; font-size: 12px; cursor: pointer;
}
.rl-tier.on { border-color: var(--gold); background: color-mix(in srgb, var(--gold) 10%, transparent); }
.rl-tier b { margin-left: auto; font-variant-numeric: tabular-nums; }
.rl-tier input { accent-color: var(--gold); }
/* The nudge is the module doing its job out loud: it names the free alternative
   at the moment someone is about to pay for it. */
.rl-nudge {
    display: flex; align-items: flex-start; gap: 7px; margin: 9px 0 0;
    background: color-mix(in srgb, var(--gold) 12%, transparent);
    border-radius: 8px; padding: 9px 11px; font-size: 11.5px; line-height: 1.5;
}
.rl-nudge i { font-size: 14px; margin-top: 1px; }
.rl-why { margin: 7px 0 0; }
.rl-free-note { margin: 10px 0 0; line-height: 1.55; }
.rl-link {
    background: none; border: none; padding: 0 0 0 6px; cursor: pointer;
    font-family: var(--font-body); font-size: inherit; font-weight: 600;
    color: var(--gold); text-decoration: underline;
}
.rl-edited { font-size: 9.5px; font-weight: 600; color: #9a7b1e; text-transform: none; letter-spacing: 0; }
.rl-prompt { font-family: ui-monospace, Consolas, monospace; font-size: 11.5px; line-height: 1.5; }
.rl-hist { display: flex; flex-direction: column; gap: 4px; }
.rl-take {
    font-size: 11px; padding: 5px 8px; border-radius: 7px;
    background: var(--color-surface-card); border: 1px solid var(--color-border-rule);
}

/* ── cost gate (inside uiConfirm) ── */
.rl-gate { text-align: left; font-size: 12px; }
.rl-gate-row {
    display: flex; align-items: baseline; gap: 10px; padding: 5px 0;
    border-bottom: 1px solid var(--color-border-rule);
}
.rl-gate-row span:first-child { flex: 1; min-width: 0; }
.rl-gate-row span:nth-child(2) { color: var(--color-ink-muted); font-size: 10.5px; }
.rl-gate-row b { font-variant-numeric: tabular-nums; }
.rl-gate-total {
    display: flex; justify-content: space-between; align-items: baseline;
    padding: 9px 0 0; font-size: 13px; font-weight: 700;
}
.rl-gate-save {
    display: flex; align-items: flex-start; gap: 7px; margin: 10px 0 0;
    background: color-mix(in srgb, var(--gold) 12%, transparent);
    border-radius: 8px; padding: 9px 11px; font-size: 11.5px; line-height: 1.5;
}

/* ── the picker: TRUE ASPECT, masonry ─────────────────────────────────────
   A previous version cropped every tile to the reel's output ratio, which turned
   a wall of landscape renders into a column of portraits — the crop described
   the reel and told you nothing about the picture. Same masonry the Studio
   library uses, so both pickers behave the same way.

   CSS columns rather than grid: a photograph's height is whatever it is, and
   columns pack mixed heights without leaving the ragged gaps a fixed-row grid
   produces. */
.rl-masonry { column-width: 132px; column-gap: 9px; }
.rl-pick {
    display: block; width: 100%; break-inside: avoid; margin: 0 0 9px;
    position: relative; padding: 0; border: 2px solid transparent;
    border-radius: 9px; overflow: hidden; background: var(--color-canvas-secondary);
    cursor: pointer; transition: border-color .12s, transform .12s;
}
.rl-pick:hover { transform: translateY(-1px); border-color: var(--color-border-rule); }
.rl-pick.picked { border-color: var(--gold); }
.rl-pick-img { position: relative; display: block; width: 100%; line-height: 0; }
.rl-pick-img img { display: block; width: 100%; height: auto; }
.img-ratio {
    position: absolute; right: 4px; bottom: 4px;
    background: rgba(0, 0, 0, .72); color: #fff; font-size: 9px; font-weight: 700;
    border-radius: 4px; padding: 1px 5px; letter-spacing: .3px;
}
.img-ratio[hidden] { display: none; }

/* A tile whose file could not be loaded keeps its slot and its shape instead of
   collapsing the masonry column around a broken-image glyph. */
.img-missing {
    display: flex; align-items: center; justify-content: center;
    width: 100%; aspect-ratio: 4 / 3;
    background: var(--color-canvas-secondary);
    color: var(--color-ink-muted); font-size: 20px;
}
.rl-pick-img.is-missing { line-height: normal; }
.rl-pick .bd-tick { opacity: 0; }
.rl-pick.picked .bd-tick { opacity: 1; background: var(--gold); }

/* Storyboard cards DO crop, and should: a card is a slot in a sequence, so a
   uniform frame is what makes the running order readable. The picker is where
   you judge the picture; the strip is where you judge the cut. */
.rl-card-img { aspect-ratio: var(--rl-aspect, 4 / 3); }

@media (max-width: 900px) {
    .rl-head { padding: 12px 14px; }
    .rl-look, .rl-strip, .rl-insp, .rl-setup { padding-left: 14px; padding-right: 14px; }
    .rl-meter { width: 100%; margin-left: 0; padding: 4px 14px 8px; justify-content: space-between; }
    .rl-card { flex-basis: 116px; }
    /* Tabs sat on two lines at 412px ("Saved / reels") and ate a row of height. */
    .rl-tab, .bd-tab { padding: 9px 9px; font-size: 12px; white-space: nowrap; }
    .bd-tabs { overflow-x: auto; scrollbar-width: none; }
    .bd-tabs::-webkit-scrollbar { display: none; }
    .rl-title, .bd-title { font-size: 17px; }
    .rl-sub, .bd-sub { font-size: 11.5px; }
    /* One field per row reads better than three cramped selects. */
    .rl-setup-grid { grid-template-columns: 1fr 1fr; }
    .rl-insp-grid { grid-template-columns: 1fr; }
    .rl-tier { min-width: 0; }
    /* The head actions wrapped under a full-width hint field and pushed the
       primary button off the first screen. */
    .rl-head-actions, .bd-head-actions { width: 100%; }
    .rl-head-actions .bd-btn, .bd-head-actions .bd-btn { flex: 1; justify-content: center; }
    .bd-hint-in { order: 3; width: 100%; max-width: none; }
}

/* Touch: everything tappable clears a thumb. */
@media (pointer: coarse) {
    .rl-tab, .bd-tab { min-height: 44px; }
    .st-rail-btn { min-height: 46px; }
    .rl-card { flex-basis: 124px; }
    .bd-sel, .bd-in, .rl-look-in { min-height: 38px; }
    .rl-link { padding: 6px 8px; }
    .bd-saved-acts button, .rl-tier { min-height: 40px; }
}

.bd-err { padding: 18px 16px; font-size: 12.5px; }
.bd-err i { font-size: 22px; color: #c0392b; }
.bd-err pre { white-space: pre-wrap; font-size: 10.5px; max-height: 200px; overflow: auto;
              background: var(--color-canvas-secondary); padding: 8px; border-radius: 6px; }
.bd-err .bd-btn { margin-top: 10px; }

/* Boards are a create-on-desktop, review-anywhere surface: the panel drops
   below the picker rather than pretending a 340px sidebar fits a phone. */
@media (max-width: 900px) {
    .bd-body { flex-direction: column; }
    .bd-panel { flex: 0 0 auto; border-left: none; border-top: 1px solid var(--color-border-rule); }
    /* .bd-row is a CSS-columns masonry now, not a grid, so the
       grid-template-columns that used to live here did nothing at all: a phone
       kept the 132px desktop column and fitted two references across where
       three belong. Narrow the COLUMN, not a track that no longer exists. */
    .bd-row { columns: 96px; }
    /* The filter row scrolls sideways rather than wrapping into four lines and
       pushing the grid off a phone screen. */
    .bd-filters {
        flex-wrap: nowrap; overflow-x: auto; padding: 9px 14px;
        scrollbar-width: none; -webkit-overflow-scrolling: touch;
    }
    .bd-filters::-webkit-scrollbar { display: none; }
    .bd-domains, .bd-sel, .bd-search, .bd-review-flag { flex-shrink: 0; }
    .bd-search { max-width: 190px; }
    .bd-head { padding: 12px 14px; }
    .bd-head-actions { width: 100%; }
    .bd-hint-in { flex: 1; width: auto; max-width: none; }
    .bd-tabs, .bd-picker-head, .bd-strip, .bd-source-grid { padding-left: 14px; padding-right: 14px; }
}
/* Touch: the tile action buttons are 12px glyphs, which is nothing to a thumb. */
@media (pointer: coarse) {
    .bd-tile-acts button { min-width: 32px; height: 30px; font-size: 14px; }
    .bd-dchip { padding: 7px 14px; }
    .bd-chip { width: 60px; height: 46px; }
}

/* ── Advanced: model-specific controls ─────────────────────────────────────
   A quiet sibling of the Smart-lock block (.st-lockblock above), which is the
   adjacent sub-panel in the same prompt bar — same construction, gold instead
   of green because green is the structure lock's identity.

   The first version of this used --st-surface-2 / --st-surface / --st-dim,
   none of which exist anywhere in the codebase, so all three fell back to raw
   rgba black laid over a cream light-theme bar: the flat grey slab. The real
   palette is the eleven --st-* tokens declared on #studioApp at the top of this
   file. Every token below is one of those. */
.st-adv {
    display: flex; flex-wrap: wrap; gap: 9px 14px; align-items: flex-end;
    padding: 10px 12px; margin-top: 8px;
    background: color-mix(in srgb, var(--st-gold) 5%, var(--st-panel-2));
    border: 1px solid color-mix(in srgb, var(--st-gold) 26%, var(--st-border));
    border-radius: 11px;
}
.st-adv[hidden] { display: none; }

/* header — mirrors .st-lock-head so the two sub-panels read as the same kind
   of thing, and names the model so it is obvious these knobs are per-model */
.st-adv-head {
    flex: 1 1 100%;
    display: flex; align-items: center; gap: 7px;
    font-size: 12px; color: var(--st-gold); margin-bottom: 2px;
}
.st-adv-head strong { font-weight: 700; letter-spacing: 0.01em; }
.st-adv-sub { color: var(--st-ink-mut); font-weight: 400; font-size: 11.5px;
              overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-adv-head .st-icon-btn { margin-left: auto; }

.st-adv-row { display: flex; align-items: center; gap: 7px; font-size: 12.5px; }
.st-adv-label { color: var(--st-ink-mut); white-space: nowrap; }
/* layout only — colour, radius, padding, font-size and focus all come from
   #studioApp .st-input / .st-select, which these elements also carry */
.st-adv-input, .st-adv-sel { min-width: 150px; flex: 1 1 150px; }
.st-adv-bool { cursor: pointer; user-select: none; color: var(--st-ink); }
.st-adv-bool input { accent-color: var(--st-gold); cursor: pointer; }

/* the negative prompt is the one people actually type into — give it the room */
.st-adv-row.is-wide { flex: 1 1 320px; }
.st-adv-row.is-wide .st-adv-input { min-width: 240px; }

/* a seed you can re-roll without selecting the text first */
.st-adv-dice { flex: 0 0 auto; }

/* the toggle reads as ON, same treatment as an active mode button */
#stAdvBtn.active { color: var(--st-gold); border-color: var(--st-gold);
                   background: var(--st-gold-soft); }

@media (max-width: 900px) { .st-adv-row, .st-adv-input, .st-adv-sel { flex-basis: 220px; } }
@media (max-width: 640px) {
    .st-adv { gap: 8px; }
    .st-adv-row, .st-adv-input, .st-adv-sel { flex-basis: 100%; }
    .st-adv-row.is-wide { flex-basis: 100%; }
}

/* one-click additions for a free-text control (the negative prompt) */
.st-adv-chips { flex: 1 1 100%; display: flex; flex-wrap: wrap; gap: 5px; margin-top: -3px; }
.st-adv-chip {
    padding: 3px 9px; border-radius: 999px; cursor: pointer;
    font-size: 10.5px; line-height: 1.5;
    background: transparent; color: var(--st-ink-mut);
    border: 1px solid var(--st-border);
}
.st-adv-chip:hover { color: var(--st-ink); border-color: var(--st-gold); }
.st-adv-chip.on { color: var(--st-gold); border-color: var(--st-gold); background: var(--st-gold-soft); }

/* Video conditioning refs — a separate strip beside the keyframes, because the
   keyframe row is written wholesale and targeted by :first-child/:last-child. */
.st-vrefs { padding-left: 8px; border-left: 1px solid var(--st-border); }

/* The attach tile is the entry point to the whole reference system and read as
   decorative furniture: a pale dashed 52px square labelled "Base". Given it is
   the only way in, it earns a visible edge and a wider footprint when empty. */
.st-ref-add.is-primary {
    width: auto; min-width: 92px; padding: 0 12px;
    border-style: solid;
    border-color: color-mix(in srgb, var(--st-gold) 55%, var(--st-border));
    background: color-mix(in srgb, var(--st-gold) 8%, transparent);
    color: var(--st-gold);
}
.st-ref-add.is-primary:hover { background: var(--st-gold-soft); }

/* ── §14.2 LAYOUT page — full-page plan plate + zone overlays ── */
.bdc-plan-page { display: flex; flex-direction: column; height: 100%; }
.bdc-plan-frame { position: relative; flex: 1; min-height: 0; background: #FFFFFF; border: 0.5px solid rgba(201,168,76,.35); border-radius: 2mm; overflow: hidden; }
/* superseded by .bdc-plan-inner (§14.4-full) */
.bdc-plan-caption { margin-top: 2mm; font-size: 6.5pt; letter-spacing: .14em; text-transform: uppercase; color: rgba(30,26,16,.6); }

/* §14.3 tile-list drag reorder */
.bd-trow { cursor: grab; }
.bd-trow-grip { color: var(--color-ink-muted, #9a8a68); font-size: 13px; flex-shrink: 0; }

/* §14.5 per-tile plan thumbnail chip */
.bdc-plan-chip { position: absolute; right: 2mm; bottom: 2mm; width: 26%; max-width: 30mm; border: 0.5px solid rgba(201,168,76,.55); border-radius: 1.5mm; overflow: hidden; background: #fff; box-shadow: 0 1px 4px rgba(30,26,16,.18); }
.bdc-plan-chip img { width: 100%; height: auto; display: block; }

/* §14.4 plan zone legend (screen side of the lockstep pair) */
.bdc-plan-legend { display: flex; flex-wrap: wrap; gap: 3mm; margin-top: 2mm; }
.bdc-plan-leg { display: inline-flex; align-items: center; gap: 1.2mm; font-size: 6.5pt; letter-spacing: .12em; text-transform: uppercase; color: #4a4535; }
.bdc-plan-leg i { width: 3mm; height: 3mm; border-radius: .6mm; display: inline-block; }

/* §14.1 plan-attach picker */
/* above #studioApp (5000) and the board overlay (5200), below settings (6000) */
.bd-planpick { position: fixed; inset: 0; background: rgba(30,26,16,.35); z-index: 5600; display: flex; align-items: center; justify-content: center; }
/* --color-bg-card is defined NOWHERE in the app, so this always fell back to
   #fff while the text inherited body's --color-ink-primary (#F0EAD6 in the
   default dark theme) — cream on white, about 1.15:1, effectively invisible.
   The house token is --color-surface-card; colour is set explicitly so the rule
   is self-contained wherever the overlay is mounted. */
.bd-planpick-card { background: var(--color-surface-card, #FDFAF0); color: var(--color-ink-primary, #1E1A10); border-radius: 14px; width: min(420px, 92vw); max-height: 70vh; overflow-y: auto; padding: 12px; }
.bd-planpick-head { display: flex; justify-content: space-between; align-items: center; font-weight: 600; margin-bottom: 8px; }
.bd-planpick-row { display: flex; align-items: center; gap: 10px; width: 100%; background: none; border: 1px solid var(--color-border-rule, #e5e0d2); border-radius: 10px; padding: 6px; margin-bottom: 6px; cursor: pointer; text-align: left; }
.bd-planpick-row img { width: 54px; height: 40px; object-fit: cover; border-radius: 6px; }
.bd-planpick-row:hover { border-color: var(--gold, #C9A84C); }

/* §14.3 pointer-drag reorder states + arrows */
.bd-trow-grip { cursor: grab; touch-action: none; color: var(--color-ink-muted, #9a8a68); display: inline-flex; padding: 4px 2px; flex-shrink: 0; }
.bd-trow.dragging { opacity: .55; }
.bd-trow.drop-here { outline: 2px solid var(--gold, #C9A84C); outline-offset: 1px; border-radius: 10px; }
.bd-trow-arrows { display: inline-flex; flex-direction: column; gap: 0; flex-shrink: 0; }
.bd-trow-arrows button { background: none; border: none; padding: 0 2px; cursor: pointer; color: var(--color-ink-muted, #9a8a68); font-size: 11px; line-height: 1.1; }
.bd-trow-arrows button:disabled { opacity: .3; cursor: default; }
.bd-trow-arrows button:hover:not(:disabled) { color: var(--gold, #C9A84C); }

/* §14.4-full — LAYOUT page annotation layers. .bdc-plan-inner shrink-wraps
   the image so every normalised overlay (zones + markups) aligns with the
   IMAGE, not the letterboxed frame. */
.bdc-plan-frame { display: flex; align-items: center; justify-content: center; }
.bdc-plan-inner { position: relative; display: inline-flex; max-width: 100%; max-height: 100%; }
.bdc-plan-inner img { max-width: 100%; max-height: 100%; width: auto; height: auto; display: block; }
.bdc-plan-annosvg { position: absolute; inset: 0; width: 100%; height: 100%; }
.bdc-plan-textanno { position: absolute; transform: translate(-2%, -50%); font-size: 7.5pt; font-weight: 700; letter-spacing: .02em; text-shadow: 0 0 3px #fff, 0 0 3px #fff; white-space: nowrap; }
.bdc-plan-pin { position: absolute; transform: translate(-50%, -50%); width: 4.2mm; height: 4.2mm; border-radius: 50%; color: #fff; font-size: 6.5pt; font-weight: 800; display: inline-flex; align-items: center; justify-content: center; box-shadow: 0 0 0 1px #fff; }
.bdc-plan-notes { display: flex; flex-wrap: wrap; gap: 2mm 6mm; margin-top: 2mm; }
.bdc-plan-note { font-size: 7pt; color: #4a4535; } .bdc-plan-note b { color: #1E1A10; } .bdc-plan-note i { color: #8a7f78; font-style: normal; }
