/* ════════════════════════════════════════════════════════════════════════
 * styles/_overrides.css — THE "JUST DO IT" CSS LAYER.
 *
 * Loads LAST in the cascade (after universal.css, mobile-landing.css,
 * and all surface CSS). Rules here win on equal specificity because of
 * source order. Append-only — no `!important` battles, no specificity
 * gymnastics, no editing 22K-line surface files for a 5px nudge.
 *
 * ──────────────────────────────────────────────────────────────────────
 * HOW TO USE FROM A SURFACE CHAT
 * ──────────────────────────────────────────────────────────────────────
 *
 *   1. APPEND rules to the bottom of this file, never to the surface
 *      CSS files. Surface files are read-only for cosmetic tweaks now.
 *
 *   2. Prefix every rule with a `--- ov:NAME` comment so it can be
 *      grepped + reverted by a single delete. Example:
 *
 *          --- ov:create-button-flush-right
 *          .input-bar .btn-create { right: 18px; }
 *
 *   3. If a rule still loses to an existing `!important` declaration
 *      in a surface CSS file, add `!important` to your override.
 *      `!important` here beats `!important` there because we're LATER
 *      in the cascade at equal specificity. Keep using the same
 *      selector you'd normally use — no need for big specificity
 *      chains.
 *
 *   4. To revert a specific override: search for `--- ov:NAME` and
 *      delete that block.
 *
 *   5. To revert EVERYTHING: comment-out the `<link>` to this file in
 *      index.html. One-line kill switch.
 *
 * ──────────────────────────────────────────────────────────────────────
 * SURFACE GATING (when an override should ONLY apply on one surface)
 * ──────────────────────────────────────────────────────────────────────
 *
 *   Wrap surface-specific rules under the body class for that surface:
 *
 *     --- ov:bigger-mic-on-chat-only
 *     body.chat-engine-active .ce-mic-btn { transform: scale(1.2); }
 *
 *     --- ov:music-only-tweak
 *     body.music-studio-active .music-studio-inline-host .ms-foo { ... }
 *
 *   Surfaces:
 *     • body.chat-engine-active       → Chat surface active
 *     • body.music-studio-active      → Music Studio active
 *     • (no body class)               → Visual Studio is the default
 *
 *   Music Studio renders INLINE in the parent DOM (not in an iframe,
 *   despite the legacy `.music-studio-inline-host` class name). All
 *   Music Studio CSS rules MUST be prefixed with `.music-studio-inline-host`
 *   purely for organizational scoping — the class wraps the studio's
 *   markup so unprefixed rules won't match.
 *
 * ──────────────────────────────────────────────────────────────────────
 * CONVENTIONS REMINDER
 * ──────────────────────────────────────────────────────────────────────
 *
 *   • `[hidden]` is still sacred. Never override its `display:none`.
 *   • Don't add animations here that run forever — see b.903 audit.
 *   • CSS only. For DOM moves, behaviour changes, monkey-patches —
 *     use src/_overrides.js (the JS half of this system).
 * ════════════════════════════════════════════════════════════════════════ */

/* ──────────────────────────────────────────────────────────────────────
 * Active overrides start below this line. Sorted bottom-up = newest
 * first (so recent changes are easy to find / revert).
 * ────────────────────────────────────────────────────────────────────── */

/* --- ov:hydration-cloak
   BULLETPROOF FOUC PREVENTION. Pre-hydration, the header tabs row +
   right-cluster pills (Menu / My coins / My library / My account) +
   the canvas nav pill appear briefly in unstyled / wrong-state
   form for ~3-5 seconds while async CSS finishes loading, fonts
   download, and the JS idle-collapse timers wire up. Cloak them
   until JS confirms hydration; reveal with a soft 200ms fade so
   the appearance feels intentional (not a flash).

   The brand wordmark, the background video / orbs, and the chat
   input bar stay visible the whole time — the user sees "Shades
   of Joy" + background + input bar from frame zero, then the
   tab cluster + right cluster fade in cleanly together.

   The JS half lives in src/_overrides.js (ov:add-hydration-class).
   It adds `body.soj-hydrated` on window 'load' AND on a 1500ms hard
   timeout, so the page can never get stuck cloaked even if some
   script hangs or fails. */
.tabs, .tabs-menu-pill, .h-right, .canvas-nav-row,
.ce-inputbar, .ce-input-row, .ce-input-meta {
  transition: opacity .25s ease-out;
}
body:not(.soj-hydrated) .tabs,
body:not(.soj-hydrated) .tabs-menu-pill,
body:not(.soj-hydrated) .h-right,
body:not(.soj-hydrated) .canvas-nav-row,
body:not(.soj-hydrated) .ce-inputbar,
body:not(.soj-hydrated) .ce-input-row,
body:not(.soj-hydrated) .ce-input-meta {
  opacity: 0 !important;
  pointer-events: none !important;
}

/* --- ov:fouc-hide-modal-hosts
   K reports a 5-second "weird UI bleed" on first page load: the Live
   Debate textarea, voice overlay placeholders, and other modal hosts
   render visible until JS finishes booting. Root cause: their default
   `display: none` rules live in visual-studio.css, which is loaded
   ASYNC (`media="print" onload="this.media='all'"`) so it doesn't apply
   until after first paint. universal.css + chat.css apply sync, but
   they don't carry rules for these specific elements.
   This override sits in the SYNC chain (_overrides-v8.css loads with
   default media) so the rules apply on first paint, killing the bleed.
   Each modal host opens via a state attribute or class that JS adds
   when the user enters that mode — the `:not(...)` clauses preserve
   the unmodified open state. */
.ld-host:not([data-open="true"]),
.vm-host:not([data-open="true"]),
.mm-host:not([data-open="true"]),
.video-tip {
  display: none !important;
}
/* canvas-expose is opened via body.canvas-expose-active (NOT a class on
   the element itself), so the negation needs to be on the body, not the
   element. */
body:not(.canvas-expose-active) .canvas-expose {
  display: none !important;
}

/* --- ov:canvas-nav-row-hide-outside-vs
   The Visual Studio canvas timeline nav (prev / Exposé / next pill) is
   gated in visual-studio.css against body[data-active-tab="chat"|"music"|"vibe"],
   but the live app actually marks active surfaces via body classes
   (chat-engine-active, music-studio-active). Result: the pill leaks onto
   the Chat and Music surfaces. Hide it whenever a non-Visual-Studio
   surface is active. Also hide the Exposé overlay itself for the same
   reason. */
body.chat-engine-active .canvas-nav-row,
body.music-studio-active .canvas-nav-row,
body.vibe-active .canvas-nav-row,
body.chat-engine-active .canvas-expose,
body.music-studio-active .canvas-expose,
body.vibe-active .canvas-expose {
  display: none !important;
}

/* --- ov:chat-history-popover-tabs
   Tabbed History popover (Chat history · Books · Artefacts).
   Sits at the top of the popover; the search input + lists live below. */
@media (min-width: 1025px) {
  body.chat-engine-active .ce-history-popover {
    width: 440px !important;
    max-height: 70vh !important;
    /* Let the caret (.ce-tp-caret, bottom:-9px) escape the popover so the
       pointer sits on the History button. Inner panes carry their own
       overflow:auto, so the rounded corners are still respected. */
    overflow: visible !important;
  }
  /* Elegant tear-drop caret — slightly larger than the generic .ce-tp-caret
     (which is shared with tier / judge popovers). Glass shell, drop shadow,
     border kissed by the popover's own border tone. */
  body.chat-engine-active .ce-history-popover .ce-tp-caret {
    position: absolute;
    bottom: -9px;
    width: 18px;
    height: 18px;
    transform: translateX(-50%) rotate(45deg);
    background: var(--lg-fill, rgba(255,255,255,.10));
    border-right: 1.5px solid var(--lg-stroke-hi, rgba(255,255,255,.30));
    border-bottom: 1.5px solid var(--lg-stroke-hi, rgba(255,255,255,.30));
    -webkit-backdrop-filter: blur(40px) saturate(1.8) brightness(1.05);
    backdrop-filter: blur(40px) saturate(1.8) brightness(1.05);
    border-bottom-right-radius: 4px;
    box-shadow: 4px 4px 12px -4px rgba(0,0,0,.35);
    z-index: 1;
  }
  body.chat-engine-active .ce-hp-tabs {
    display: flex;
    flex-direction: row;
    gap: 4px;
    padding: 8px 8px 0;
    border-bottom: 1px solid var(--lg-stroke, rgba(255,255,255,.12));
  }
  body.chat-engine-active .ce-hp-tab {
    flex: 1 1 auto;
    padding: 7px 10px;
    font-family: var(--font-ui);
    font-size: 11.5px;
    font-weight: 600;
    border-radius: 10px 10px 0 0;
    border: 1px solid transparent;
    border-bottom: none;
    background: transparent;
    color: var(--text-muted, rgba(255,255,255,.62));
    cursor: pointer;
    letter-spacing: .01em;
    transition: color .15s var(--ease), background .15s var(--ease);
  }
  body.chat-engine-active .ce-hp-tab:hover {
    color: var(--text, #fff);
    background: var(--lg-fill-hover, rgba(255,255,255,.06));
  }
  body.chat-engine-active .ce-hp-tab.on {
    color: var(--text, #fff);
    background: var(--lg-fill-active, rgba(255,255,255,.10));
    border-color: var(--lg-stroke, rgba(255,255,255,.18));
    border-bottom: 1px solid var(--lg-fill-active, rgba(255,255,255,.10));
    margin-bottom: -1px;
  }
  body.chat-engine-active .ce-hp-pane {
    overflow-y: auto;
    flex: 0 1 auto;
    /* No min-height — pane shrinks to its content so the popover stays
       tight around what's actually inside (sparse Books/Artefacts tab no
       longer looks like a half-empty box). */
    max-height: 50vh;
  }
  body.chat-engine-active .ce-hp-pane[hidden] {
    display: none !important;
  }
}

/* --- ov:voice-strip-no-bounce
   When voice mode is on, the inputbar's children (meta row, file row, input
   row) all hide and only the voice strip remains. Pre-fix: the inputbar
   collapsed onto bottom:8 (because rowH became 0), which made the whole bar
   jump downward — the visible "bounce". Now: keep the inputbar at its
   normal bottom value (chat.js apply() handles that) AND hoist the voice
   strip itself to bottom:8 with position:fixed, so it occupies the input
   row's slot directly — no movement of any container. */
@media (min-width: 1025px) {
  body.chat-engine-active .ce-inputbar[data-vm="on"] .ce-vm-strip,
  body.vm-active .ce-vm-strip,
  body.chat-engine-active .ce-vm-strip {
    /* The strip's [hidden] attribute still hides it when voice mode is off
       (CSS `[hidden] { display: none }` is set elsewhere). When it's shown,
       these rules give it the exact same slot the input row had. */
    position: fixed !important;
    left: 22px !important;
    right: 34px !important;
    bottom: 8px !important;
    margin: 0 !important;
    z-index: 11 !important;
  }
}

/* --- ov:skill-mode-hide-model-sel
   Skill mode locks the model server-side, so the "Claude · Sonnet 4.6 ·
   locked" pill is just noise next to the active skill chip. Hide it. */
body.chat-engine-active #chatEngine .ce-skill-mode-row .ce-skill-model-sel,
body.chat-engine-active #ceSkillModelSel {
  display: none !important;
}

/* --- ov:skill-mode-input-row-cleanup
   When skill mode is on (star button gets `.skill-mode-on`), hide every
   other tool button in the input row so only the star remains. The star
   is the last button in DOM order; once the others are display:none it
   naturally becomes the leftmost visible item. The textarea (flex:1)
   expands to fill the freed space — no extra width override needed. */
body.chat-engine-active .ce-input-row:has(#ceSkillBtn.skill-mode-on) .ce-tool-btn:not(#ceSkillBtn) {
  display: none !important;
}

/* --- ov:skill-mode-row-anchor
   When a skill is selected, the chosen-skill chip + param pills live in
   .ce-skill-mode-row, which is a sibling of .ce-input-row in DOM order.
   Both inputbar and input-row are position:fixed, so they leave the flex
   flow — which dumps the skill row at the TOP of #chatEngine instead of
   above the input bar. Pin it directly above the input row. */
body.chat-engine-active #chatEngine .ce-skill-mode-row,
html body.chat-engine-active .ce-skill-mode-row {
  position: fixed !important;
  left: 22px !important;
  right: 22px !important;
  /* 8px input-row floor + ~52px input-row height + 8px gap = 68 → round 70 */
  bottom: 70px !important;
  top: auto !important;
  z-index: 9 !important;
  margin: 0 !important;
  padding: 0 !important;
  /* No glass bar — chips float directly on the page background. */
  background: transparent !important;
  border: none !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  box-shadow: none !important;
}
body.chat-engine-active #chatEngine .ce-skill-mode-row[hidden] {
  display: none !important;
}
/* Hide the row until a skill is actually selected. While the picker is
   open but nothing's been chosen yet, the row stays invisible so the
   picker is the only thing on screen. The skill chip drops its `hidden`
   attribute once a skill is selected, which un-hides this whole row. */
body.chat-engine-active #chatEngine .ce-skill-mode-row:not(:has(.ce-skill-chip:not([hidden]))) {
  display: none !important;
}

/* --- ov:skill-picker-anchor-fix
   vibe-code.js's _openSkillPopup anchors the picker via `bottom:
   innerHeight - addRect.top + 8` against the "+ Add Skill" pill, but with
   maxHeight cleared in the desktop branch the popup grows to its content
   height — which on K's set of skills exceeds viewport height. CSS `bottom`
   then pushes the TOP of the popup above the viewport, leaving only the
   first section visible at the very top of the screen. Cap height + force
   it to sit ABOVE the skill row (just over the input bar) so it always
   visually opens from the star / Add Skill button. */
#ceSkillPopup {
  max-height: 50vh !important;
  overflow-y: auto !important;
  /* Force the popup to live just above the input row regardless of what
     vibe-code.js's positioner does. left:22 lines it up with the input
     bar's left edge; bottom:70 leaves space for the input row (~50px)
     plus the skill row (~16px) plus an 8px gap. */
  bottom: 70px !important;
  top: auto !important;
  left: 22px !important;
  right: auto !important;
  width: min(440px, calc(100vw - 44px)) !important;
}

/* --- ov:meta-row-right-cluster-align
   K wants History + New chat aligned with the right side of the input bar
   below them (right:22 of viewport). Default flex placement (margin-left:
   auto on .ce-meta-actions) already puts the cluster at the right edge of
   .ce-input-meta which is at right:22, so we zero out margin-right and
   nudge slightly negatively so the buttons sit FLUSH with the input bar's
   visible right border instead of leaving a small gap inside the meta row's
   wrap reflow buffer. */
body.chat-engine-active #chatEngine .ce-input-meta > .ce-meta-actions,
html body.chat-engine-active #chatEngine .ce-input-meta > .ce-meta-actions,
html body.chat-engine-active #chatEngine > .ce-inputbar .ce-input-meta > .ce-meta-actions,
html body .ce-meta-actions {
  /* +4px more left → 31px from the parent's right edge. */
  margin-right: 31px !important;
  margin-left: auto !important;
  /* +3px down — translateY shifts visually without breaking flex. */
  transform: translateY(3px) !important;
}

/* ───────────────────────────────────────────────────────────────────
   ov:account-modal-v2 — full redesign of "Your account" modal
   Tabs reorder + sub-tabs + asset/song/project/artwork rows + backdrop
   ─────────────────────────────────────────────────────────────────── */

/* Backdrop — transparent so the live theme background shows through.
   No blur, no tint. Still needs pointer-events to catch outside clicks.
   UNCONDITIONAL z-index so backdrop + modal always beat pills (90) and
   the expanded bal-card (9999). */
.modal-back.show {
  background: transparent !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  z-index: 100000 !important;
}
#modal.show {
  z-index: 100001 !important;
}

/* ── CURTAIN v2 — pure CSS via :has(), no JS dependency ─────────────────
   When #modal.show exists (modal is open), hide EVERY direct body child
   except the modal stack, bg-stage, and bg-playback. No body class needed,
   no JS required — fires the instant .show lands on #modal.
   Supported: Chrome 105+, Safari 15.4+, Firefox 121+.
   ─────────────────────────────────────────────────────────────────────── */
body:has(#modal.show) > *:not(#modal):not(#modalBack):not(.bg-stage):not(.bg-playback):not(script):not(style):not(template) {
  display: none !important;
  visibility: hidden !important;
}
/* Modal stack always visible + interactive */
body:has(#modal.show) #modal,
body:has(#modal.show) #modalBack { display: block !important; visibility: visible !important; pointer-events: auto !important; }
/* bg-stage stays rendered so the animated theme shows through */
body:has(#modal.show) .bg-stage { display: block !important; visibility: visible !important; pointer-events: none !important; }

/* ── Legacy body-class curtain (belt-and-suspenders for older logic) ───── */
html body.soj-popup-open > *:not(.bg-stage):not(.bg-playback):not(.modal-back):not(#modal):not(.soj-dialog):not(.soj-cp):not(.soj-cp-shell):not(.cast-modal):not(.dm-popover):not(script):not(style):not(template) {
  display: none !important;
}
html body.soj-popup-open .modal-back.show,
html body.soj-popup-open #modal.show,
html body.soj-popup-open .bg-stage { display: block !important; visibility: visible !important; }
html body.soj-popup-open .modal-back.show,
html body.soj-popup-open #modal.show { pointer-events: auto !important; }

/* Modal size — ~20% smaller than the previous 1240px max */
html body #modal,
html body .modal {
  width: min(980px, calc(100vw - 28px)) !important;
  max-height: calc(100vh - 100px) !important;
}
html body #modal .modal-body,
html body #modal #modalBody { padding: 12px 16px 14px !important; }

/* Profile head — tighter, aligned, no overflow. Higher specificity to
   beat the legacy .profile-head rule in universal.css that pulls the
   sign-out button to flex-start. */
html body #modal .profile-head,
html body #modal .profile-head.v2 {
  display: grid !important;
  grid-template-columns: 44px minmax(0, 1fr) auto !important;
  align-items: center !important;
  gap: 12px !important;
  padding: 10px 14px 10px 14px !important;
  margin-bottom: 12px !important;
  border: 1px solid var(--glass-border) !important;
  border-radius: 14px !important;
  background: rgba(255,255,255,.04) !important;
  -webkit-backdrop-filter: blur(12px) !important;
  backdrop-filter: blur(12px) !important;
}
html body #modal .profile-head .ava-lg,
html body #modal .profile-head.v2 .ava-lg {
  width: 44px !important; height: 44px !important;
  border-radius: 12px !important;
  flex: none !important;
  align-self: center !important;
  background:
    radial-gradient(60% 60% at 0% 0%, rgba(255,210,170,.20) 0%, transparent 70%),
    radial-gradient(60% 60% at 100% 0%, rgba(180,200,255,.18) 0%, transparent 70%),
    radial-gradient(80% 80% at 50% 100%, rgba(220,185,240,.16) 0%, transparent 70%),
    rgba(255, 255, 255, .10) !important;
  border: 1.5px solid rgba(255, 255, 255, .45) !important;
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  backdrop-filter: blur(14px) saturate(1.4);
  display: grid !important;
  place-items: center !important;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 18px;
  color: var(--text);
}
html body #modal .profile-head .info .nm,
html body #modal .profile-head.v2 .info .nm {
  font-size: 15px !important;
}
html body #modal .profile-head .info .em,
html body #modal .profile-head.v2 .info .em {
  font-size: 11.5px !important;
}
html body #modal .profile-head.v2 .info { min-width: 0 !important; }
html body #modal .profile-head.v2 .info .nm {
  font-family: var(--font-display); font-weight: 800;
  font-size: 17px !important; line-height: 1.15 !important;
  color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
html body #modal .profile-head.v2 .info .em {
  font-family: var(--font-display); font-weight: 600;
  font-size: 12px !important; line-height: 1.2 !important;
  color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  margin-top: 2px;
}
html body #modal .profile-head .signout-top,
html body #modal .profile-head.v2 .signout-top {
  align-self: center !important;
  justify-self: end !important;
  flex: none !important;
  height: 34px !important;
  padding: 0 14px !important;
  margin-right: 2px !important;
  border-radius: 10px !important;
  background: rgba(255,255,255,.06) !important;
  border: 1px solid var(--glass-border) !important;
  font-family: var(--font-display); font-weight: 700;
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-muted) !important;
  cursor: pointer;
  display: inline-flex !important;
  align-items: center !important;
  transition: background .2s, color .2s, border-color .2s;
}
html body #modal .profile-head.v2 .signout-top:hover {
  background: rgba(255,255,255,.10) !important;
  color: var(--text) !important;
  border-color: var(--glass-border-strong) !important;
}

/* Balance row — SINGLE-LINE: label · coin · value · spacer · buy.
   Reduces vertical bulk by ~30px compared to the stacked layout. */
html body #modal .profile-balance,
html body #modal .profile-balance.v2 {
  display: flex !important;
  align-items: center !important;
  gap: 14px !important;
  padding: 10px 14px 10px 18px !important;
  border-radius: 12px !important;
  border: 1px solid var(--glass-border) !important;
  background: rgba(255,255,255,.02) !important;
  margin-bottom: 12px !important;
}
html body #modal .profile-balance .pb-left,
html body #modal .profile-balance.v2 .pb-left {
  display: inline-flex !important;
  flex-direction: row !important;
  align-items: center !important;
  gap: 12px !important;
  min-width: 0;
}
html body #modal .profile-balance .lbl,
html body #modal .profile-balance.v2 .lbl {
  font-family: var(--font-display); font-weight: 700;
  font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-muted);
}
html body #modal .profile-balance .v,
html body #modal .profile-balance.v2 .v {
  font-family: var(--font-display); font-weight: 800;
  font-size: 20px !important; color: var(--text);
  display: inline-flex; align-items: center; gap: 8px; line-height: 1;
}
html body #modal .profile-balance .v .joy-coin,
html body #modal .profile-balance.v2 .v .joy-coin { width: 1.3em; height: 1.3em; }
/* push the buy button to the right edge */
html body #modal .profile-balance .balance-buy,
html body #modal .profile-balance.v2 .balance-buy { margin-left: auto !important; }
html body #modal .profile-balance .balance-buy,
html body #modal .profile-balance.v2 .balance-buy {
  flex: none;
  height: 38px; padding: 0 18px;
  border-radius: 12px;
  /* Liquid glass — same recipe as the modal shell, not orb-tinted */
  background:
    radial-gradient(60% 60% at 0% 0%, rgba(255,210,170,.20) 0%, transparent 70%),
    radial-gradient(60% 60% at 100% 0%, rgba(180,200,255,.18) 0%, transparent 70%),
    radial-gradient(80% 80% at 50% 100%, rgba(220,185,240,.16) 0%, transparent 70%),
    rgba(255, 255, 255, .10) !important;
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  backdrop-filter: blur(14px) saturate(1.4);
  border: 1.5px solid rgba(255, 255, 255, .45) !important;
  color: var(--text);
  font-family: var(--font-display); font-weight: 800;
  font-size: 12px; letter-spacing: .04em; text-transform: uppercase;
  cursor: pointer; line-height: 1;
  position: relative; isolation: isolate;
  transition: transform .2s, background .2s, border-color .2s;
}
html body #modal .profile-balance .balance-buy:hover,
html body #modal .profile-balance.v2 .balance-buy:hover {
  background: rgba(255,255,255,.16) !important;
  border-color: rgba(255,255,255,.65) !important;
  transform: translateY(-1px);
}
/* KILL the .liquid::before conic gradient on all buy/CTA buttons inside
   the modal — the Garden theme's orb colors bleed through as green wash.
   Pure glass treatment only: frosted backdrop + subtle border. */
html body #modal .balance-buy.liquid::before,
html body #modal .balance-buy::before,
html body #modal .pack .buy.liquid::before,
html body #modal .pack .buy::before {
  display: none !important;
  content: none !important;
}

/* Pack buy buttons — pure liquid glass, no color tint */
html body #modal .pack .buy {
  background: rgba(255,255,255,.06) !important;
  border: 1px solid rgba(255,255,255,.16) !important;
  -webkit-backdrop-filter: blur(16px) saturate(1.4) !important;
  backdrop-filter: blur(16px) saturate(1.4) !important;
  color: var(--text) !important;
  font-weight: 700 !important;
  letter-spacing: .11em !important;
  transition: background .2s, border-color .2s, transform .15s !important;
}
html body #modal .pack .buy:hover {
  background: rgba(255,255,255,.12) !important;
  border-color: rgba(255,255,255,.30) !important;
  transform: translateY(-1px) !important;
}
/* Featured pack buy button gets a slightly brighter glass to stand out */
html body #modal .pack.featured .buy {
  background: rgba(255,255,255,.10) !important;
  border-color: rgba(255,255,255,.24) !important;
}

/* INR and USD price — equal font size so neither feels secondary */
html body #modal .pack .price .usd {
  font-size: inherit !important;
  color: var(--text-muted) !important;
  margin-left: 8px !important;
}

/* Studio top tabs — connected segmented control, no big gaps */
html body #modal .studio-tabs,
html body #modal .studio-tabs.v2 {
  display: flex !important; gap: 4px !important;
  padding: 4px !important; border-radius: 12px !important;
  background: rgba(255,255,255,.04) !important;
  border: 1px solid var(--glass-border) !important;
  margin: 0 0 12px !important;
  overflow-x: auto;
}
html body #modal .studio-tabs .studio-tab,
html body #modal .studio-tabs.v2 .studio-tab {
  flex: 1 1 0 !important;
  min-width: 0;
  padding: 9px 12px !important;
  font-size: 12px !important; letter-spacing: .06em;
  white-space: nowrap;
  height: 36px;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
}

/* Sub-tabs — connected segmented control feel */
html body #modal .vs-subtabs {
  display: flex !important;
  flex-wrap: wrap;
  gap: 4px !important;
  padding: 4px !important;
  border-radius: 10px !important;
  background: rgba(255,255,255,.04) !important;
  border: 1px solid var(--glass-border) !important;
  margin: 0 0 10px !important;
}
html body #modal .vs-subtabs .vs-subtab {
  padding: 7px 14px !important;
  font-size: 10.5px !important; letter-spacing: .08em;
  border-radius: 8px !important;
  text-transform: uppercase;
  height: 30px;
  display: inline-flex !important;
  align-items: center !important;
}
html body #modal .vs-subtabs .vs-subtab.on {
  background: rgba(255,255,255,.10) !important;
  color: var(--text) !important;
  box-shadow: 0 1px 0 rgba(255,255,255,.04) inset;
}

/* Empty / loading / error messages */
html body #modal .acct-empty,
html body #modal .acct-loading,
html body #modal .acct-err {
  font-family: var(--font-body);
  font-weight: 600; font-size: 13.5px;
  text-align: center; padding: 28px 12px;
  color: var(--text-muted);
}
html body #modal .acct-err { color: #ff9b9b; }

/* Chat history list */
html body #modal .acct-chat-filter {
  display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 12px;
}
html body #modal .acct-filter {
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(255,255,255,.04);
  border: 1px solid var(--glass-border);
  color: var(--text-muted);
  font-family: var(--font-display); font-weight: 700;
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  cursor: pointer;
}
html body #modal .acct-filter.on {
  background: rgba(255,255,255,.12);
  color: var(--text);
  border-color: var(--glass-border-strong);
}
html body #modal .acct-chat-list {
  display: flex; flex-direction: column; gap: 6px;
  max-height: 360px; overflow-y: auto;
}
html body #modal .acct-chat-row {
  display: grid;
  grid-template-columns: 80px 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 8px 14px;
  min-height: 56px;
  text-align: left;
  border-radius: 10px;
  background: rgba(255,255,255,.025);
  border: 1px solid var(--glass-border);
  color: var(--text);
  cursor: pointer;
  transition: background .15s, border-color .15s, transform .15s;
}
html body #modal .acct-chat-row:hover {
  background: rgba(255,255,255,.06);
  border-color: var(--glass-border-strong);
  transform: translateY(-1px);
}
html body #modal .acct-chat-mode {
  font-family: var(--font-display); font-weight: 800;
  font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase;
  text-align: center;
  padding: 6px 8px;
  border-radius: 8px;
  background: rgba(252,166,0,.16);
  color: #fca600;
}
html body #modal .acct-chat-mode.mode-debate { background: rgba(112,72,236,.16); color: #b59cff; }
html body #modal .acct-chat-mode.mode-consensus { background: rgba(72,200,236,.16); color: #7fd0ec; }
html body #modal .acct-chat-mode.mode-argue { background: rgba(236,72,108,.16); color: #f08aa0; }
html body #modal .acct-chat-mode.mode-coach { background: rgba(72,236,154,.16); color: #82e8b4; }
html body #modal .acct-chat-meta { min-width: 0; }
html body #modal .acct-chat-title {
  font-family: var(--font-display); font-weight: 700;
  font-size: 14px; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
html body #modal .acct-chat-preview {
  font-family: var(--font-body); font-weight: 500;
  font-size: 12.5px; color: var(--text-muted);
  margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
html body #modal .acct-chat-when {
  font-family: var(--font-display); font-weight: 600;
  font-size: 11px; letter-spacing: .04em;
  color: var(--text-muted); white-space: nowrap;
}

/* Story rows */
html body #modal .acct-story-list { display: flex; flex-direction: column; gap: 10px; }
html body #modal .acct-story-row {
  display: grid; grid-template-columns: 64px 1fr; gap: 12px; align-items: center;
  padding: 10px 12px;
  border-radius: 12px;
  background: rgba(255,255,255,.025);
  border: 1px solid var(--glass-border);
  cursor: pointer;
  transition: background .15s, transform .15s;
}
html body #modal .acct-story-row:hover { background: rgba(255,255,255,.06); transform: translateY(-1px); }
html body #modal .acct-story-row .ssr-thumb {
  width: 64px; height: 64px; border-radius: 10px;
  background: rgba(255,255,255,.04) center/cover no-repeat;
}
html body #modal .acct-story-row .ssr-title {
  font-family: var(--font-display); font-weight: 700; font-size: 14px;
  color: var(--text);
}
html body #modal .acct-story-row .ssr-sub {
  font-family: var(--font-body); font-weight: 500; font-size: 12px;
  color: var(--text-muted); margin-top: 2px;
}

/* Song + project rows */
html body #modal .acct-song-list,
html body #modal .acct-proj-list { display: flex; flex-direction: column; gap: 8px; }
html body #modal .acct-song-row,
html body #modal .acct-proj-row {
  display: grid; grid-template-columns: 48px 1fr auto; gap: 12px; align-items: center;
  padding: 10px 14px;
  border-radius: 12px;
  background: rgba(255,255,255,.025);
  border: 1px solid var(--glass-border);
  transition: background .15s;
}
html body #modal .acct-song-row:hover, html body #modal .acct-proj-row:hover {
  background: rgba(255,255,255,.06);
}
html body #modal .acct-song-thumb {
  width: 48px; height: 48px; border-radius: 10px;
  background: rgba(255,255,255,.04) center/cover no-repeat;
}
html body #modal .acct-song-thumb-empty {
  display: grid; place-items: center;
  font-family: var(--font-display); font-weight: 700; color: var(--text-muted);
}
html body #modal .acct-song-title,
html body #modal .acct-proj-title {
  font-family: var(--font-display); font-weight: 700; font-size: 14px;
  color: var(--text);
}
html body #modal .acct-song-sub,
html body #modal .acct-proj-sub {
  font-family: var(--font-body); font-weight: 500; font-size: 12px;
  color: var(--text-muted); margin-top: 2px;
}
html body #modal .acct-proj-glyph {
  width: 48px; height: 48px; border-radius: 10px;
  display: grid; place-items: center;
  background: linear-gradient(135deg, rgba(252,166,0,.18), rgba(112,72,236,.14));
  color: var(--text);
  font-size: 22px; font-weight: 800;
}
html body #modal .acct-song-play {
  width: 36px; height: 36px; border-radius: 50%;
  background: rgba(255,255,255,.08);
  border: 1px solid var(--glass-border);
  color: var(--text); cursor: pointer;
  display: grid; place-items: center;
}

/* "+ New character" / "+ New space" button at top of those panes */
html body #modal .acct-pane-head {
  display: flex; justify-content: flex-end;
  margin: 0 0 10px;
}
html body #modal .acct-new-btn {
  height: 30px; padding: 0 14px;
  border-radius: 8px;
  background: rgba(255,255,255,.06);
  border: 1px solid var(--glass-border);
  color: var(--text);
  font-family: var(--font-display); font-weight: 700;
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  cursor: pointer;
  transition: background .15s, border-color .15s, transform .15s;
}
html body #modal .acct-new-btn:hover {
  background: rgba(255,255,255,.14);
  border-color: var(--glass-border-strong);
  transform: translateY(-1px);
}

/* Vibe Code project rows */
html body #modal .acct-vibe-list { display: flex; flex-direction: column; gap: 6px; }
html body #modal .acct-vibe-row {
  display: grid; grid-template-columns: 44px 1fr; gap: 12px; align-items: center;
  padding: 10px 14px;
  border-radius: 10px;
  background: rgba(255,255,255,.025);
  border: 1px solid var(--glass-border);
  cursor: pointer;
  transition: background .15s, transform .15s;
}
html body #modal .acct-vibe-row:hover { background: rgba(255,255,255,.06); transform: translateY(-1px); }
html body #modal .acct-vibe-glyph {
  width: 44px; height: 44px; border-radius: 10px;
  display: grid; place-items: center;
  background: linear-gradient(135deg, rgba(112,72,236,.18), rgba(72,200,236,.14));
  color: var(--text);
  font-size: 20px; font-weight: 800;
}
html body #modal .acct-vibe-title {
  font-family: var(--font-display); font-weight: 700; font-size: 14px;
  color: var(--text);
}
html body #modal .acct-vibe-sub {
  font-family: var(--font-body); font-weight: 500; font-size: 12px;
  color: var(--text-muted); margin-top: 2px;
}

/* h-grid — exactly 6 cards per row at the widened modal width */
html body #modal .h-grid {
  display: grid !important;
  grid-template-columns: repeat(6, 1fr) !important;
  gap: 10px !important;
}
/* Card aspect ratio — keep them square-ish so they don't get tall when
   the row is narrower than expected */
html body #modal .h-grid .h-card { aspect-ratio: 1 / 1.15; }
html body #modal .h-grid .h-card .h-media { min-height: 0; }

/* Card hover — liquid glass so text stays legible over any background */
html body #modal .h-grid .h-card:hover {
  -webkit-backdrop-filter: blur(28px) saturate(1.6) !important;
  backdrop-filter: blur(28px) saturate(1.6) !important;
  background: rgba(12, 10, 28, .82) !important;
  border-color: rgba(255, 255, 255, .32) !important;
  box-shadow:
    0 12px 36px -8px rgba(0, 0, 0, .70),
    inset 0 0 0 1px rgba(255, 255, 255, .12) !important;
  transform: translateY(-2px) !important;
}

@media (max-width: 1100px) {
  html body #modal .h-grid { grid-template-columns: repeat(4, 1fr) !important; }
}
@media (max-width: 800px) {
  html body #modal .h-grid { grid-template-columns: repeat(3, 1fr) !important; }
}
@media (max-width: 600px) {
  html body #modal,
  html body .modal { max-height: calc(100vh - 20px) !important; }
  html body #modal .h-grid { grid-template-columns: repeat(2, 1fr) !important; }
  html body #modal .studio-tabs.v2 .studio-tab {
    padding: 9px 8px !important;
    font-size: 11px !important;
  }
  html body #modal .vs-subtabs .vs-subtab {
    padding: 8px 12px !important;
  }
  html body #modal .acct-chat-row {
    grid-template-columns: 70px 1fr;
  }
  html body #modal .acct-chat-when { display: none; }
}

/* --- ov:std-stage-card-unclip
   Root cause: visual-studio.css sets translateY(-30px) on .bubble.result.staged,
   then clips it via overflow:hidden on .chat. Two-part fix:
   1. Kill the translateY entirely — use margin-bottom for the below-center offset instead.
   2. Use ID selectors (#chat, #thread) for specificity (1,x,x) to definitively beat
      any class-based !important rules in visual-studio.css. */
html body.std-result-stage .main {
  overflow: visible !important;
}
html body.std-result-stage #chat {
  flex: 1 !important;
  min-height: 0 !important;
  overflow: visible !important;
}
html body.std-result-stage #thread {
  overflow: visible !important;
}
html body.std-result-stage #chat #thread > .msg {
  overflow: visible !important;
}
html body.std-result-stage .bubble.result.staged {
  transform: none !important;
  margin-bottom: 60px !important;
}

/* --- ov:std-stage-art-cover
   Root cause: object-fit:contain on the art element letterboxes whenever the
   frame's content-box ratio diverges from the image ratio (14px padding on a
   9:16 frame makes the content box slightly taller-proportional than 9:16,
   so a 9:16 image doesn't fill all the way to the top/bottom edges).
   Fix: cover fills the box completely — for matching-ratio content (which we
   always generate) there is zero crop; for any minor ratio drift the crop
   is sub-pixel and invisible. Scoped to staged mode only so browse-mode
   thumbnails are unaffected. */
html body.std-result-stage .bubble.result.staged .result-frame img.art,
html body.std-result-stage .bubble.result.staged .result-frame video.art {
  object-fit: cover !important;
}

/* --- ov:engine-popover-section-fade
   When the engine popover re-renders (innerHTML replaced), the section content
   fades in softly. This makes the SD/HD tier row appearing (GPT) or disappearing
   (Banana) feel like an intentional design transition rather than a jarring snap.
   Same applies to the story-mode image engine section. */
@keyframes ep-section-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.engine-popover-section {
  animation: ep-section-in 0.18s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.story-imgeng {
  animation: ep-section-in 0.18s cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* --- ov:engine-btn-always-clickable
   Root cause: body.std-result-stage sets pointer-events:none on .controls
   (and everything inside it), but ov:std-stage-card-unclip's overflow:visible
   lets the translateY(140%) controls visually leak into the viewport — the
   engine button looks clickable but pointer-events:none blocks all interaction.
   std-canvas-input-active (which restores pointer-events) is only added by
   Edit/Create-New, creating a chicken-and-egg: you can't click the button to
   change engines before generating. Fix: always keep the engine button
   interactive regardless of stage state. */
html body.std-result-stage .input-bar #engineSelectBtn,
html body.std-result-stage #inputBar #engineSelectBtn {
  pointer-events: auto !important;
}

/* --- ov:director-drawer (b.933)
   Right-side slide-in drawer replaces the fullscreen Director Console modal.
   .director-drawer class added to #directorModal; all new styles scoped here.
   Body-level swap: JS replaces body.director-open → body.director-drawer-open
   so the old fullscreen blackout rules never fire in drawer mode. */

/* ── 1. Drawer outer shell — override fullscreen modal positioning ── */
.director-modal.director-drawer {
  position: fixed !important;
  top: 0 !important;
  right: 0 !important;
  bottom: 0 !important;
  left: auto !important;
  width: 440px !important;
  max-width: 100vw !important;
  height: 100dvh !important;
  padding: 0 !important;
  display: flex !important;
  flex-direction: column !important;
  align-items: stretch !important;
  justify-content: flex-start !important;
  background: transparent !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  overflow: visible !important;
  z-index: 95 !important;
  transform: translateX(calc(100% + 2px)) !important;
  visibility: hidden !important;
  transition: transform 0.34s cubic-bezier(0.22, 0.61, 0.36, 1),
              visibility 0.34s step-end !important;
}

/* Keep flex layout while hidden for slide animation (override UA display:none on [hidden]) */
.director-modal.director-drawer[hidden] {
  display: flex !important;
  transform: translateX(calc(100% + 2px)) !important;
  visibility: hidden !important;
  pointer-events: none !important;
}

/* Shown state — slide in from right */
.director-modal.director-drawer:not([hidden]) {
  transform: translateX(0) !important;
  visibility: visible !important;
  pointer-events: auto !important;
  transition: transform 0.34s cubic-bezier(0.22, 0.61, 0.36, 1),
              visibility 0s step-start !important;
}

/* ── 2. Inner glass shell ── */
.dm-shell-v3 {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  /* Neutral liquid glass — lets theme colour and brightness show through.
     Low opacity fill + strong blur = the scene behind tints the glass. */
  background: rgba(10, 10, 18, 0.32);
  border-left: 1px solid rgba(255, 255, 255, 0.14);
  box-shadow:
    -2px 0 0 rgba(255, 255, 255, 0.06) inset,
    -20px 0 48px -8px rgba(0, 0, 0, 0.40);
  backdrop-filter: blur(52px) saturate(1.8) brightness(0.92);
  -webkit-backdrop-filter: blur(52px) saturate(1.8) brightness(0.92);
  overflow: hidden;
  position: relative;
}

/* Ambient glow at top of drawer */
.dm-shell-v3::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 160px;
  pointer-events: none;
  background: radial-gradient(ellipse 80% 60% at 50% -10%,
    rgba(184, 115, 51, 0.14), transparent 70%);
  z-index: 0;
}

/* ── 3. Header ── */
.dm-drw-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 10px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
  flex-shrink: 0;
  position: relative;
  z-index: 1;
  background: rgba(255, 255, 255, 0.04);
  box-shadow: 0 1px 0 rgba(255,255,255,0.10) inset;
}
.dm-drw-brand {
  display: flex;
  align-items: center;
  gap: 8px;
}
.dm-drw-icon {
  width: 20px;
  height: 20px;
  color: rgba(184, 115, 51, 0.85);
  flex-shrink: 0;
}
.dm-drw-title {
  font-size: 15px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.88);
  letter-spacing: -0.01em;
}
.dm-drw-head-right {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* Cost pill */
.dm-scene-cost {
  display: flex;
  align-items: center;
  gap: 5px;
  background: rgba(184, 115, 51, 0.12);
  border: 1px solid rgba(184, 115, 51, 0.24);
  border-radius: 20px;
  padding: 4px 10px 4px 8px;
}
.dm-scene-cost-value {
  font-size: 13px;
  font-weight: 600;
  color: rgba(252, 166, 0, 0.90);
  font-variant-numeric: tabular-nums;
}

/* Close button */
.dm-shell-v3 .dm-close {
  position: static !important;
  width: 32px !important;
  height: 32px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  background: rgba(255, 255, 255, 0.05) !important;
  border: 1px solid rgba(255, 255, 255, 0.10) !important;
  border-radius: 8px !important;
  color: rgba(255, 255, 255, 0.50) !important;
  cursor: pointer !important;
  transition: background 0.15s, color 0.15s !important;
  flex-shrink: 0 !important;
}
.dm-shell-v3 .dm-close:hover {
  background: rgba(255, 255, 255, 0.10) !important;
  color: rgba(255, 255, 255, 0.88) !important;
}
.dm-shell-v3 .dm-close svg { width: 14px; height: 14px; }

/* ── 4. Duration slider ── */
.dm-drw-duration {
  padding: 10px 10px 10px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  flex-shrink: 0;
  position: relative;
  z-index: 1;
}
.dm-drw-dur-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 7px;
}
.dm-drw-dur-label {
  font-size: 11px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.40);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.dm-drw-dur-label .dm-video-only {
  color: rgba(255, 255, 255, 0.24);
  font-size: 10px;
}
.dm-duration-secs {
  font-size: 12px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.70);
  font-variant-numeric: tabular-nums;
}
.dm-duration-slider {
  width: 100%;
  height: 3px;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  background: rgba(255, 255, 255, 0.12);
  border-radius: 2px;
  outline: none;
  accent-color: rgba(184, 115, 51, 0.85);
}
.dm-duration-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: rgba(184, 115, 51, 0.90);
  cursor: pointer;
  box-shadow: 0 0 0 3px rgba(184, 115, 51, 0.20);
}

/* ── 5. Tab bar ── */
.dm-drw-tabs {
  display: flex;
  gap: 2px;
  padding: 8px 10px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  flex-shrink: 0;
  position: relative;
  z-index: 1;
}
.dm-drw-tab {
  flex: 1;
  padding: 7px 8px 9px;
  font-size: 12.5px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.40);
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  cursor: pointer;
  text-align: center;
  letter-spacing: 0.01em;
  transition: color 0.15s, border-color 0.15s;
  margin-bottom: -1px;
}
.dm-drw-tab:hover { color: rgba(255, 255, 255, 0.72); }
.dm-drw-tab.dm-drw-tab-on {
  color: rgba(255, 255, 255, 0.92);
  border-bottom-color: rgba(184, 115, 51, 0.85);
}

/* ── 6. Tab content body ── */
.dm-drw-body {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  position: relative;
  z-index: 1;
  min-height: 0;
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,0.10) transparent;
}
.dm-drw-body::-webkit-scrollbar { width: 4px; }
.dm-drw-body::-webkit-scrollbar-track { background: transparent; }
.dm-drw-body::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.10);
  border-radius: 2px;
}
.dm-drw-pane {
  padding: 14px 2px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.dm-drw-pane-off { display: none !important; }

/* Shell action buttons (+ Add character, Dialogues) */
.dm-cast-shell-head { display: flex; flex-direction: column; gap: 8px; }
.dm-shell-action-stack {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.dm-shell-action {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 6px 13px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 20px;
  font-size: 12.5px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.60);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.dm-shell-action:hover {
  background: rgba(255, 255, 255, 0.10);
  color: rgba(255, 255, 255, 0.90);
}
.dm-shell-action-count {
  background: rgba(184, 115, 51, 0.25);
  color: rgba(252, 166, 0, 0.90);
  border-radius: 10px;
  padding: 1px 6px;
  font-size: 11px;
  font-weight: 600;
}
.dm-drw-cast-extras { margin-top: 2px; }

/* Storyboard CTA */
.dm-storyboard-cta {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 13px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 11px;
  cursor: pointer;
  text-align: left;
  width: 100%;
  transition: background 0.15s, border-color 0.15s;
  margin-top: 4px;
}
.dm-storyboard-cta:hover {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.13);
}
.dm-sb-cta-ico {
  width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(184, 115, 51, 0.10);
  border: 1px solid rgba(184, 115, 51, 0.18);
  border-radius: 9px;
  flex-shrink: 0;
  color: rgba(184, 115, 51, 0.78);
}
.dm-sb-cta-ico svg { width: 16px; height: 16px; }
.dm-sb-cta-text { display: flex; flex-direction: column; gap: 2px; flex: 1; }
.dm-sb-cta-title { font-size: 13px; font-weight: 500; color: rgba(255,255,255,0.78); }
.dm-sb-cta-sub { font-size: 11.5px; color: rgba(255,255,255,0.35); }
.dm-sb-cta-arrow { font-size: 16px; color: rgba(255,255,255,0.25); flex-shrink: 0; }

/* Dialogue pane */
.dm-drw-dlg-hint {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.36);
  line-height: 1.55;
}
.dm-drw-dlg-hint code {
  background: rgba(255, 255, 255, 0.07);
  border-radius: 4px;
  padding: 1px 4px;
  font-size: 11px;
  color: rgba(184, 115, 51, 0.82);
}
.dm-drw-dlg-hint-tone { display: block; margin-top: 2px; opacity: 0.72; }
.dm-dialogue-chips { display: flex; flex-wrap: wrap; gap: 6px; min-height: 0; }
.dm-dialogue-textarea,
.dm-avoid-textarea {
  width: 100%;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 13px;
  font-family: inherit;
  color: rgba(255, 255, 255, 0.85);
  resize: vertical;
  outline: none;
  transition: border-color 0.15s;
  box-sizing: border-box;
}
.dm-dialogue-textarea:focus,
.dm-avoid-textarea:focus { border-color: rgba(184, 115, 51, 0.40); }
.dm-dialogue-textarea::placeholder,
.dm-avoid-textarea::placeholder { color: rgba(255, 255, 255, 0.20); font-size: 12px; }
.dm-avoid-block {
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 10px;
  overflow: hidden;
}
.dm-avoid-summary {
  padding: 8px 12px;
  font-size: 12.5px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.46);
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 6px;
  background: rgba(255, 255, 255, 0.03);
  transition: color 0.15s;
}
.dm-avoid-summary::-webkit-details-marker { display: none; }
.dm-avoid-summary:hover { color: rgba(255, 255, 255, 0.72); }
.dm-avoid-summary .dm-avoid-hint { font-weight: 400; color: rgba(255,255,255,0.26); }
.dm-avoid-block .dm-avoid-textarea {
  border-radius: 0; border: none;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
}
.dm-avoid-note {
  padding: 5px 12px 8px;
  font-size: 11px;
  color: rgba(255, 255, 255, 0.26);
  background: rgba(255, 255, 255, 0.02);
}
.dm-avoid-note code { color: rgba(184, 115, 51, 0.68); font-size: 10.5px; }
.dm-dialogue-preview {
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 10px;
  padding: 10px 12px;
  background: rgba(255, 255, 255, 0.03);
  font-size: 12.5px;
  color: rgba(255, 255, 255, 0.58);
  line-height: 1.6;
}

/* ── 7. Ask the Director input ── */
.dm-shell-v3 .dm-co-director-v2 {
  display: flex !important;
  align-items: center !important;
  gap: 8px !important;
  padding: 9px 20px !important;
  background: rgba(255, 255, 255, 0.03) !important;
  border-top: 1px solid rgba(255, 255, 255, 0.06) !important;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06) !important;
  flex-shrink: 0 !important;
  position: relative;
  z-index: 1;
}
.dm-shell-v3 .dm-co-director-v2 .dm-co-icon {
  width: 16px; height: 16px;
  color: rgba(255, 255, 255, 0.28); flex-shrink: 0;
}
.dm-shell-v3 .dm-co-director-v2 .dm-co-icon svg { width: 100%; height: 100%; }
.dm-shell-v3 .dm-co-director-v2 .dm-co-input {
  flex: 1 !important;
  background: transparent !important;
  border: none !important;
  outline: none !important;
  font-size: 12.5px !important;
  color: rgba(255, 255, 255, 0.80) !important;
  padding: 0 !important;
}
.dm-shell-v3 .dm-co-director-v2 .dm-co-input::placeholder {
  color: rgba(255, 255, 255, 0.22) !important;
}
.dm-shell-v3 .dm-co-director-v2 .dm-co-go {
  padding: 5px 12px !important;
  background: rgba(184, 115, 51, 0.16) !important;
  border: 1px solid rgba(184, 115, 51, 0.28) !important;
  border-radius: 16px !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  color: rgba(252, 166, 0, 0.88) !important;
  cursor: pointer !important;
  transition: background 0.15s !important;
  white-space: nowrap !important;
}
.dm-shell-v3 .dm-co-director-v2 .dm-co-go:hover {
  background: rgba(184, 115, 51, 0.26) !important;
}

/* ── 8. Parameter strip (slides in above the 6 cards) ── */
.dm-drw-param-strip {
  flex-shrink: 0;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  background: rgba(255, 255, 255, 0.02);
  position: relative;
  z-index: 1;
  overflow: hidden;
  max-height: 0;
  transition: max-height 0.22s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.dm-drw-param-strip:not([hidden]) { max-height: 120px; }
/* override [hidden] UA display:none for the strip (we animate max-height) */
.dm-drw-param-strip[hidden] {
  display: block !important;
  max-height: 0 !important;
  pointer-events: none !important;
}
.dm-param-strip-label {
  padding: 8px 20px 4px;
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: rgba(255, 255, 255, 0.36);
}
.dm-param-strip-scroll {
  display: flex;
  gap: 6px;
  padding: 4px 20px 10px;
  overflow-x: auto;
  scrollbar-width: none;
}
.dm-param-strip-scroll::-webkit-scrollbar { display: none; }

/* Strip chips */
.dm-strip-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 11px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 20px;
  font-size: 12px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.62);
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
  transition: background 0.13s, border-color 0.13s, color 0.13s;
}
.dm-strip-chip:hover {
  background: rgba(255, 255, 255, 0.10);
  color: rgba(255, 255, 255, 0.88);
}
.dm-strip-chip.dm-strip-chip-on {
  background: rgba(184, 115, 51, 0.20);
  border-color: rgba(184, 115, 51, 0.50);
  color: rgba(252, 166, 0, 0.90);
}

/* ── 9. Six parameter cards (2 × 3 grid) ── */
.dm-drw-params {
  flex-shrink: 0 !important;
  padding: 8px 10px 6px !important;
  border-top: 1px solid rgba(255, 255, 255, 0.06) !important;
  position: relative !important;
  z-index: 1 !important;
  box-sizing: border-box !important;
  width: 100% !important;
}
.dm-drw-params-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  margin-bottom: 6px;
}
.dm-drw-pc {
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 3px !important;
  padding: 8px 4px 7px !important;
  background: rgba(255,255,255,0.07) !important;
  border: 1px solid rgba(255,255,255,0.20) !important;
  border-radius: 13px !important;
  cursor: pointer !important;
  transition: filter 0.18s, border-color 0.18s, box-shadow 0.18s !important;
  min-height: 72px !important;
  position: relative !important;
  backdrop-filter: blur(18px) saturate(1.4) brightness(1.08) !important;
  -webkit-backdrop-filter: blur(18px) saturate(1.4) brightness(1.08) !important;
  box-shadow:
    0 1px 0 rgba(255,255,255,0.35) inset,
    0 -1px 0 rgba(0,0,0,0.12) inset,
    0 8px 20px -6px rgba(0,0,0,0.38) !important;
  overflow: hidden !important;
}
.dm-drw-pc:hover {
  background: rgba(255, 255, 255, 0.07) !important;
  border-color: rgba(255, 255, 255, 0.14) !important;
}
.dm-drw-pc.strip-open {
  background: rgba(184, 115, 51, 0.12) !important;
  border-color: rgba(184, 115, 51, 0.36) !important;
}
.dm-drw-pc-swatch {
  width: 8px !important; height: 8px !important;
  border-radius: 50% !important;
  background: rgba(255, 255, 255, 0.14) !important;
  flex-shrink: 0 !important;
  display: block !important;
  transition: background 0.15s !important;
}
.dm-drw-pc-val {
  font-size: 11.5px !important;
  font-weight: 600 !important;
  color: rgba(255, 255, 255, 0.80) !important;
  line-height: 1.2 !important;
  text-align: center !important;
  max-width: 100% !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  white-space: nowrap !important;
  padding: 0 4px !important;
}
.dm-drw-pc-label {
  font-size: 9.5px !important;
  font-weight: 400 !important;
  color: rgba(255, 255, 255, 0.32) !important;
  text-transform: uppercase !important;
  letter-spacing: 0.06em !important;
  line-height: 1 !important;
}
/* has-value from dmRefreshDeck */
.dm-drw-pc.has-value {
  background: rgba(184, 115, 51, 0.08) !important;
  border-color: rgba(184, 115, 51, 0.22) !important;
}
.dm-drw-pc.has-value .dm-drw-pc-val {
  color: rgba(252, 166, 0, 0.88) !important;
}
.dm-drw-pc.has-value .dm-drw-pc-label {
  color: rgba(184, 115, 51, 0.52) !important;
}
.dm-drw-pc.has-value .dm-drw-pc-swatch {
  background: rgba(184, 115, 51, 0.70) !important;
}

/* ── 10. Footer ── */
.dm-shell-v3 .dm-foot-v2 {
  display: flex !important;
  flex-direction: column !important;
  gap: 7px !important;
  padding: 10px 20px 16px !important;
  border-top: 1px solid rgba(255, 255, 255, 0.07) !important;
  flex-shrink: 0 !important;
  position: relative !important;
  z-index: 1 !important;
}
/* If openDirector moves co-director-v2 into the footer, style it there */
.dm-shell-v3 .dm-foot-v2 .dm-co-director-v2 {
  order: -1;
  padding: 0 !important;
  border: none !important;
  background: none !important;
  margin-bottom: 2px !important;
}
.dm-shell-v3 .dm-foot-v2 .dm-reset-btn {
  padding: 9px 16px !important;
  background: rgba(255, 255, 255, 0.05) !important;
  border: 1px solid rgba(255, 255, 255, 0.10) !important;
  border-radius: 10px !important;
  font-size: 13px !important;
  font-weight: 500 !important;
  color: rgba(255, 255, 255, 0.48) !important;
  cursor: pointer !important;
  transition: background 0.15s, color 0.15s !important;
}
.dm-shell-v3 .dm-foot-v2 .dm-reset-btn:hover {
  background: rgba(255, 255, 255, 0.09) !important;
  color: rgba(255, 255, 255, 0.78) !important;
}
.dm-shell-v3 .dm-foot-v2 .dm-generate-btn {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 6px !important;
  padding: 11px 20px !important;
  background: linear-gradient(135deg,
    rgba(184, 115, 51, 0.92) 0%, rgba(232, 176, 74, 0.82) 100%) !important;
  border: none !important;
  border-radius: 10px !important;
  font-size: 14px !important;
  font-weight: 600 !important;
  color: rgba(255, 255, 255, 0.96) !important;
  cursor: pointer !important;
  transition: opacity 0.15s, transform 0.10s !important;
  letter-spacing: -0.01em !important;
}
.dm-shell-v3 .dm-foot-v2 .dm-generate-btn:hover { opacity: 0.90 !important; }
.dm-shell-v3 .dm-foot-v2 .dm-generate-btn:active { transform: scale(0.98) !important; }
.dm-generate-arrow { font-size: 16px; }

/* ── 11. Action tab — scene context textarea ── */
.dm-shell-v3 .dm-context-input {
  width: 100% !important;
  background: rgba(255, 255, 255, 0.04) !important;
  border: 1px solid rgba(255, 255, 255, 0.09) !important;
  border-radius: 10px !important;
  padding: 10px 12px !important;
  font-size: 13px !important;
  font-family: inherit !important;
  color: rgba(255, 255, 255, 0.82) !important;
  resize: vertical !important;
  outline: none !important;
  transition: border-color 0.15s !important;
  box-sizing: border-box !important;
}
.dm-shell-v3 .dm-context-input:focus {
  border-color: rgba(184, 115, 51, 0.40) !important;
}
.dm-shell-v3 .dm-context-input::placeholder {
  color: rgba(255, 255, 255, 0.20) !important;
  font-size: 12px !important;
}

/* ── 12. body.director-drawer-open — JS swaps class; these are insurance ── */
body.director-drawer-open {
  overflow: auto !important;
}
body.director-drawer-open .director-modal.director-drawer {
  visibility: visible !important;
  pointer-events: auto !important;
}

/* ── 13. Roster cards — full-width in drawer context ── */
.dm-shell-v3 .dm-roster-card {
  width: 100% !important;
  box-sizing: border-box !important;
}

/* ── 14. Popover — keep above drawer ── */
.director-modal.director-drawer .dm-popover {
  z-index: 200 !important;
  position: fixed !important;
}

/* ── VISUAL REDESIGN vR3 — Full fidelity to original design:
   transparent shell, full-viewport coverage, connected tab+body box,
   centered title, compact no-scroll layout, tall cinematic param cards.
   ─────────────────────────────────────────────────────────────────── */

/* 1. Cover viewport — explicit height wins over Block 1's 100dvh, flex for child fill */
.director-modal.director-drawer {
  position: fixed !important;
  top: 0 !important;
  bottom: 0 !important;
  right: 0 !important;
  height: 100dvh !important;
  z-index: 9999 !important;
  margin: 0 !important;
  overflow: hidden !important;     /* clip to drawer bounds */
  display: flex !important;
  flex-direction: column !important;
}
/* ::before neutralised — nav coverage is handled by #soj-nav-blocker injected by JS */
.director-modal.director-drawer::before {
  content: none !important;
}

/* 2. Shell — use higher-specificity compound selector to guarantee scroll override.
   Block 1 sets .dm-shell-v3 { overflow: hidden } — this selector wins because it's
   more specific (.director-modal.director-drawer .dm-shell-v3 = 3 classes vs 1). */
.director-modal.director-drawer .dm-shell-v3 {
  flex: 1 !important;
  min-height: 0 !important;        /* critical: lets flex item shrink below content height */
  overflow-y: auto !important;
  overflow-x: hidden !important;
  overscroll-behavior: contain !important;
}

/* 2b. Single-class version: appearance styles (background, shadow, blur) */
.dm-shell-v3 {
  background: rgba(10, 5, 22, 0.28) !important;
  backdrop-filter: blur(48px) saturate(1.9) brightness(0.68) !important;
  -webkit-backdrop-filter: blur(48px) saturate(1.9) brightness(0.68) !important;
  box-shadow: -20px 0 60px -6px rgba(0,0,0,0.44),
              -1px 0 0 rgba(255,255,255,0.07) !important;
  border-left: 1px solid rgba(255,255,255,0.12) !important;
  position: relative !important;
  z-index: 1 !important;
  display: flex !important;
  flex-direction: column !important;
}

.dm-shell-v3::before {
  background: radial-gradient(ellipse 130% 38% at 50% -6%,
    rgba(120, 50, 200, 0.18), transparent 70%) !important;
}

/* 3. Header — centered title, minimal padding, cost pill gone */
.dm-drw-head {
  flex-direction: column !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 0 !important;
  padding: 13px 56px 11px !important;
  border-bottom: 1px solid rgba(255,255,255,0.07) !important;
  position: relative !important;
  flex-shrink: 0 !important;
}
.dm-drw-brand { justify-content: center !important; width: 100% !important; gap: 0 !important; }
.dm-drw-icon { display: none !important; }
.dm-drw-title {
  font-size: 20px !important;
  font-weight: 300 !important;
  letter-spacing: 0.04em !important;
  color: rgba(255,255,255,0.90) !important;
  text-align: center !important;
}
.dm-drw-head-right {
  position: absolute !important;
  top: 50% !important;
  right: 14px !important;
  transform: translateY(-50%) !important;
  gap: 0 !important;
}
/* Hide cost pill — by class AND by ID */
.dm-scene-cost,
#dmSceneCost { display: none !important; }

/* 4. Duration — compact, centered */
.dm-drw-duration {
  padding: 7px 18px 10px !important;
  border-bottom: 1px solid rgba(255,255,255,0.06) !important;
  flex-shrink: 0 !important;
}
.dm-drw-dur-row {
  display: flex !important;
  justify-content: center !important;
  align-items: center !important;
  gap: 10px !important;
  margin-bottom: 8px !important;
}
.dm-drw-dur-label {
  font-size: 14px !important;
  font-weight: 300 !important;
  color: rgba(255,255,255,0.78) !important;
  text-transform: none !important;
  letter-spacing: 0 !important;
}
.dm-drw-dur-label .dm-video-only { display: none !important; }
.dm-duration-secs { font-size: 14px !important; font-weight: 500 !important; color: rgba(255,255,255,0.88) !important; }
.dm-duration-slider {
  width: 100% !important;
  display: block !important;
  box-sizing: border-box !important;
  height: 14px !important;       /* matches thumb height so thumb centers on track */
  background: transparent !important;
  -webkit-appearance: none !important;
  appearance: none !important;
  cursor: pointer !important;
}
.dm-duration-slider::-webkit-slider-runnable-track {
  height: 3px !important;
  background: rgba(255,255,255,0.18) !important;
  border-radius: 3px !important;
}
.dm-duration-slider::-webkit-slider-thumb {
  -webkit-appearance: none !important;
  width: 32px !important;
  height: 14px !important;
  margin-top: -5.5px !important;  /* (14px thumb − 3px track) / 2 */
  border-radius: 10px !important;
  background: rgba(255,255,255,0.94) !important;
  box-shadow: 0 1px 6px rgba(0,0,0,0.50) !important;
  cursor: pointer !important;
}

/* ── 5. TABS — boxy selected tab, flush-merges with body (browser-tab pattern) ──
   Selected tab = rectangular, glass bg, no bottom border → merges into body card.
   Inactive tabs = ghost text, transparent.
   Body card = glass rectangle; top-left corner squared (0) so CAST tab connects flush. */

.dm-drw-tabs {
  margin: 8px 10px 0 !important;
  padding: 0 !important;
  gap: 0 !important;
  display: flex !important;
  align-items: flex-end !important;
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  overflow: visible !important;
  flex-shrink: 0 !important;
  position: relative !important;
  z-index: 3 !important;
}
.dm-drw-tab {
  flex: none !important;
  border: 1.5px solid transparent !important;
  border-bottom: none !important;
  border-radius: 0 !important;
  padding: 8px 16px !important;
  font-size: 10.5px !important;
  font-weight: 600 !important;
  color: rgba(255,255,255,0.36) !important;
  background: transparent !important;
  margin-bottom: 0 !important;
  letter-spacing: 0.05em !important;
  text-align: center !important;
  text-transform: uppercase !important;
  line-height: 1 !important;
  transition: background 0.18s, color 0.18s !important;
  cursor: pointer !important;
  position: relative !important;
  white-space: nowrap !important;
}
.dm-drw-tab:hover:not(.dm-drw-tab-on) {
  color: rgba(255,255,255,0.60) !important;
  background: rgba(255,255,255,0.04) !important;
  border-radius: 6px 6px 0 0 !important;
}
.dm-drw-tab.dm-drw-tab-on {
  background: rgba(255,255,255,0.09) !important;
  color: rgba(255,255,255,0.95) !important;
  border: 1.5px solid rgba(255,255,255,0.26) !important;
  border-bottom: 1.5px solid rgba(255,255,255,0.09) !important; /* matches body bg — invisible seam */
  border-radius: 8px 8px 0 0 !important;
  box-shadow:
    0 1.5px 0 rgba(255,255,255,0.50) inset,
    1.5px 0 0 rgba(255,255,255,0.12) inset,
    -1.5px 0 0 rgba(255,255,255,0.12) inset !important;
  backdrop-filter: blur(28px) saturate(1.5) brightness(1.06) !important;
  -webkit-backdrop-filter: blur(28px) saturate(1.5) brightness(1.06) !important;
  margin-bottom: -1.5px !important; /* overlap body's top border for a seamless merge */
}

/* Body — sits directly below the tabs; top-left corner flat so CAST tab connects flush */
.dm-drw-body {
  margin: 0 10px 10px !important;
  padding-top: 14px !important;
  border-radius: 0 14px 14px 14px !important;
  background: rgba(255,255,255,0.09) !important;
  border: 1.5px solid rgba(255,255,255,0.26) !important;
  backdrop-filter: blur(28px) saturate(1.5) brightness(1.06) !important;
  -webkit-backdrop-filter: blur(28px) saturate(1.5) brightness(1.06) !important;
  box-shadow:
    0 1.5px 0 rgba(255,255,255,0.52) inset,
    1.5px 0 0 rgba(255,255,255,0.12) inset,
    -1.5px 0 0 rgba(255,255,255,0.12) inset,
    0 -1px 0 rgba(0,0,0,0.16) inset,
    0 20px 60px -8px rgba(0,0,0,0.55),
    0 4px 16px rgba(0,0,0,0.28) !important;
  overflow: visible !important;
  flex: none !important;
  position: relative !important;
  z-index: 1 !important;
}

/* Pane base — transparent content layer inside the glass body.
   No border/background/backdrop-filter — body owns all of that. */
.dm-drw-pane {
  padding: 0 10px 14px !important;
  gap: 10px !important;
  border-radius: 0 !important;
  background: transparent !important;
  border: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  box-shadow: none !important;
}

/* ── CAST PANE ──
   Layout: the cast shell head has the roster card + action buttons.
   Roster card = the large cast selector (full width, portrait-ish).
   Action buttons = small pills BELOW the roster card.
   SFX toggle stays hidden.
   :not(.dm-drw-pane-off) guard — otherwise this display:flex !important would
   win the cascade over dm-drw-pane-off's display:none (it appears later). */
.dm-drw-pane[data-dmd-pane="cast"]:not(.dm-drw-pane-off) {
  display: flex !important;
  flex-direction: column !important;
  gap: 8px !important;
  padding: 0 10px 12px !important;
}
.dm-drw-pane[data-dmd-pane="cast"] .dm-cast-shell {
  display: flex !important;
  flex-direction: column !important;
  gap: 8px !important;
  width: 100% !important;
}
.dm-drw-pane[data-dmd-pane="cast"] .dm-cast-shell-head {
  display: flex !important;
  flex-direction: column !important;
  gap: 8px !important;
}
/* Cast roster card — HIDDEN in drawer (replaced by slot cards) */
.dm-drw-pane[data-dmd-pane="cast"] .dm-roster-card-cast {
  display: none !important;
}
/* Old action button stack — HIDDEN (slots do the job) */
.dm-drw-pane[data-dmd-pane="cast"] .dm-shell-action-stack {
  display: none !important;
}
/* SFX toggle — keep hidden in drawer */
.dm-drw-cast-extras,
#dmSfxToggle,
.dm-shell-toggle { display: none !important; }

/* ── CHARACTER SLOT GRID ──
   3 equal-width square slots side by side.
   Each slot is a dashed-border 1:1 card with "+" and "Add character" label. */
.dm-char-slots {
  display: grid !important;
  grid-template-columns: repeat(3, 1fr) !important;
  gap: 8px !important;
  width: 100% !important;
  margin: 0 !important;
  box-sizing: border-box !important;
}
.dm-char-slot {
  aspect-ratio: 1 / 1 !important;
  border-radius: 12px !important;
  border: 1.5px dashed rgba(255,255,255,0.35) !important;
  background: rgba(255,255,255,0.08) !important;
  backdrop-filter: blur(20px) saturate(1.5) brightness(1.08) !important;
  -webkit-backdrop-filter: blur(20px) saturate(1.5) brightness(1.08) !important;
  box-shadow:
    0 1.5px 0 rgba(255,255,255,0.40) inset,
    0 -1px 0 rgba(0,0,0,0.15) inset,
    0 6px 20px -4px rgba(0,0,0,0.35) !important;
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 6px !important;
  cursor: pointer !important;
  transition: border-color 0.18s, background 0.18s !important;
  padding: 8px !important;
  box-sizing: border-box !important;
  position: relative !important;
  overflow: hidden !important;
}
.dm-char-slot:hover {
  border-color: rgba(255,255,255,0.45) !important;
  background: rgba(255,255,255,0.07) !important;
}
.dm-char-slot:hover .dm-char-slot-plus {
  opacity: 1 !important;
  transform: scale(1.12) !important;
}
/* Filled slot — shows character thumbnail */
.dm-char-slot.dm-char-slot-filled {
  border: 1.5px solid rgba(255,255,255,0.18) !important;
  background: rgba(28,10,55,0.55) !important;
  cursor: pointer !important;
}
.dm-char-slot.dm-char-slot-filled:hover {
  border-color: rgba(255,255,255,0.35) !important;
  background: rgba(40,16,80,0.70) !important;
}
.dm-char-slot-thumb {
  width: 100% !important;
  height: 100% !important;
  position: absolute !important;
  inset: 0 !important;
  object-fit: cover !important;
  border-radius: 10px !important;
  opacity: 0.85 !important;
}
.dm-char-slot-name {
  position: absolute !important;
  bottom: 6px !important;
  left: 0 !important; right: 0 !important;
  text-align: center !important;
  font-size: 10px !important;
  font-weight: 500 !important;
  color: rgba(255,255,255,0.90) !important;
  letter-spacing: 0.02em !important;
  text-shadow: 0 1px 4px rgba(0,0,0,0.80) !important;
  padding: 0 4px !important;
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
}
/* Empty slot icon + label */
.dm-char-slot-plus {
  font-size: 22px !important;
  line-height: 1 !important;
  color: rgba(255,255,255,0.38) !important;
  font-weight: 200 !important;
  transition: opacity 0.18s, transform 0.18s !important;
  opacity: 0.7 !important;
}
.dm-char-slot-label {
  font-size: 9.5px !important;
  font-weight: 500 !important;
  letter-spacing: 0.05em !important;
  text-transform: uppercase !important;
  color: rgba(255,255,255,0.32) !important;
  text-align: center !important;
  line-height: 1.2 !important;
}

/* ── SPACES & ENVIRONMENT — standalone section always visible below tab body ── */
.dm-drw-spaces-host {
  margin: 6px 10px 0 !important;
  flex-shrink: 0 !important;
}
.dm-drw-spaces-host .dm-space-env-shell {
  border-radius: 12px !important;
  background: var(--lg-fill, rgba(255,255,255,0.06)) !important;
  border: 1px solid var(--lg-stroke, rgba(255,255,255,0.20)) !important;
  backdrop-filter: var(--lg-blur, blur(22px) saturate(1.3) brightness(1.06)) !important;
  -webkit-backdrop-filter: var(--lg-blur, blur(22px) saturate(1.3) brightness(1.06)) !important;
  box-shadow:
    0 1px 0 rgba(255,255,255,0.25) inset,
    0 -1px 0 rgba(0,0,0,0.10) inset,
    0 8px 24px -8px rgba(0,0,0,0.30) !important;
  overflow: hidden !important;
}
.dm-drw-spaces-host .dm-space-shell-head {
  display: flex !important;
  align-items: center !important;
  gap: 8px !important;
  padding: 10px 14px !important;
}
.dm-drw-spaces-host .dm-roster-card-space {
  flex: 1 !important;
  background: transparent !important;
  border: none !important;
  padding: 0 !important;
  text-align: left !important;
  cursor: pointer !important;
}
.dm-drw-spaces-host .dm-roster-label {
  font-size: 12px !important;
  font-weight: 500 !important;
  text-transform: uppercase !important;
  letter-spacing: 0.06em !important;
  color: rgba(255,255,255,0.50) !important;
}
.dm-drw-spaces-host .dm-roster-count {
  font-size: 12.5px !important;
  color: rgba(255,255,255,0.70) !important;
  margin-left: 8px !important;
}
.dm-drw-spaces-host .dm-shell-action-stack { flex-shrink: 0 !important; }
.dm-drw-spaces-host .dm-shell-action {
  display: inline-flex !important;
  align-items: center !important;
  padding: 6px 13px !important;
  border-radius: 18px !important;
  background: rgba(255,255,255,0.07) !important;
  border: 1px solid rgba(255,255,255,0.12) !important;
  font-size: 12px !important;
  color: rgba(255,255,255,0.72) !important;
  cursor: pointer !important;
  white-space: nowrap !important;
}
.dm-drw-spaces-host .dm-shell-action:hover {
  background: rgba(255,255,255,0.13) !important;
  color: rgba(255,255,255,0.92) !important;
}

/* ── ACTION PANE ── */
.dm-drw-pane[data-dmd-pane="action"]:not(.dm-drw-pane-off) {
  display: flex !important;
  flex-direction: column !important;
  gap: 8px !important;
  padding: 12px 10px 14px !important;
}
.dm-shell-v3 .dm-context-input {
  min-height: 62px !important;
  max-height: 62px !important;
  height: 62px !important;
  resize: none !important;
  font-size: 12.5px !important;
  padding: 9px 12px !important;
  border-radius: 10px !important;
  border: 1px solid rgba(255,255,255,0.22) !important;
  background: rgba(255,255,255,0.08) !important;
  backdrop-filter: blur(16px) saturate(1.3) !important;
  -webkit-backdrop-filter: blur(16px) saturate(1.3) !important;
  box-shadow: 0 1px 0 rgba(255,255,255,0.35) inset, 0 -1px 0 rgba(0,0,0,0.12) inset !important;
  color: rgba(255,255,255,0.90) !important;
}
/* Spaces & environment card */
.dm-space-env-shell {
  border-radius: 10px !important;
  background: rgba(255,255,255,0.04) !important;
  border: 1px solid rgba(255,255,255,0.09) !important;
  overflow: hidden !important;
}
.dm-space-shell-head {
  display: flex !important;
  align-items: center !important;
  gap: 8px !important;
  padding: 8px 10px !important;
}
.dm-roster-card-space {
  flex: 1 !important;
  text-align: left !important;
  background: transparent !important;
  border: none !important;
  padding: 0 !important;
  cursor: pointer !important;
}
.dm-space-shell-head .dm-shell-action-stack { flex-shrink: 0 !important; }
.dm-space-shell-head .dm-shell-action {
  padding: 5px 11px !important;
  font-size: 12px !important;
  border-radius: 16px !important;
}
/* Storyboard CTA compact */
.dm-storyboard-cta { padding: 9px 12px !important; border-radius: 10px !important; margin-top: 0 !important; }
.dm-sb-cta-ico { width: 28px !important; height: 28px !important; }
.dm-sb-cta-title { font-size: 12.5px !important; }
.dm-sb-cta-sub   { font-size: 11px !important; }

/* ── DIALOGUE PANE ── */
.dm-drw-pane[data-dmd-pane="dialogue"]:not(.dm-drw-pane-off) { padding: 12px 10px 14px !important; }
.dm-drw-pane[data-dmd-pane="dialogue"] .dm-dialogue-textarea {
  min-height: 72px !important;
  max-height: 72px !important;
  resize: none !important;
  border: 1px solid rgba(255,255,255,0.22) !important;
  background: rgba(255,255,255,0.08) !important;
  border-radius: 10px !important;
  padding: 9px 12px !important;
  backdrop-filter: blur(16px) saturate(1.3) !important;
  -webkit-backdrop-filter: blur(16px) saturate(1.3) !important;
  box-shadow: 0 1px 0 rgba(255,255,255,0.35) inset, 0 -1px 0 rgba(0,0,0,0.12) inset !important;
  color: rgba(255,255,255,0.90) !important;
  font-size: 12.5px !important;
}

/* ── 6. Ask the Director ── */
.dm-shell-v3 .dm-co-director-v2 { padding: 7px 10px !important; flex-shrink: 0 !important; }

/* ── 7. Param strip ── */
.dm-drw-param-strip:not([hidden]) { max-height: 84px !important; }
.dm-param-strip-label {
  font-size: 11.5px !important;
  font-weight: 500 !important;
  color: rgba(255,255,255,0.55) !important;
  text-transform: capitalize !important;
  letter-spacing: 0.02em !important;
  padding: 7px 10px 3px !important;
}
.dm-param-strip-scroll { padding: 3px 10px 8px !important; gap: 5px !important; }
.dm-strip-chip { padding: 5px 13px !important; font-size: 12px !important; }

/* ── 8. Param cards: tall portrait, cinematic fills ── */
.dm-drw-params { padding: 6px 10px 8px !important; border-top: 1px solid rgba(255,255,255,0.07) !important; flex-shrink: 0 !important; }
.dm-drw-params-row { gap: 7px !important; margin-bottom: 7px !important; }

.dm-drw-pc {
  height: 100px !important;
  min-height: 100px !important;
  max-height: 100px !important;
  justify-content: flex-end !important;
  align-items: center !important;
  padding: 0 0 9px !important;
  gap: 0 !important;
  border-radius: 13px !important;
  overflow: hidden !important;
  border: 1px solid rgba(255,255,255,0.10) !important;
  background: rgba(12,5,26,0.88) !important;
  transition: filter 0.15s, border-color 0.15s !important;
}
.dm-drw-pc:hover { filter: brightness(1.14) !important; border-color: rgba(255,255,255,0.22) !important; }
.dm-drw-pc.strip-open { border-color: rgba(255,255,255,0.40) !important; filter: brightness(1.20) !important; }

.dm-drw-pc[data-dmd-param="palette"]  { background: radial-gradient(ellipse at 65% 22%, rgba(122,30,148,0.94) 0%, rgba(14,4,32,0.98) 78%) !important; }
.dm-drw-pc[data-dmd-param="lighting"] { background: radial-gradient(ellipse at 30% 70%, rgba(20,16,92,0.94) 0%, rgba(4,3,18,0.98) 78%) !important; }
.dm-drw-pc[data-dmd-param="camera"]   { background: radial-gradient(ellipse at 64% 36%, rgba(104,36,8,0.94) 0%, rgba(18,6,1,0.98) 78%) !important; }
.dm-drw-pc[data-dmd-param="lens"]     { background: radial-gradient(ellipse at 38% 28%, rgba(60,18,80,0.94) 0%, rgba(8,2,14,0.98) 78%) !important; }
.dm-drw-pc[data-dmd-param="focal"]    { background: radial-gradient(ellipse at 50% 82%, rgba(152,98,2,0.92) 0%, rgba(24,10,0,0.98) 78%) !important; }
.dm-drw-pc[data-dmd-param="aperture"] { background: radial-gradient(ellipse at 56% 46%, rgba(112,40,6,0.94) 0%, rgba(16,5,1,0.98) 78%) !important; }

.dm-drw-pc-swatch { display: none !important; }
.dm-drw-pc-val   { display: none !important; }
.dm-drw-pc-label {
  font-size: 12.5px !important;
  font-weight: 400 !important;
  color: rgba(255,255,255,0.88) !important;
  text-transform: capitalize !important;
  letter-spacing: 0.01em !important;
  text-shadow: 0 1px 8px rgba(0,0,0,0.90) !important;
  padding: 0 6px !important;
  line-height: 1.3 !important;
}
.dm-drw-pc.has-value { border-color: rgba(184,115,51,0.44) !important; box-shadow: inset 0 0 0 1px rgba(184,115,51,0.16) !important; }
.dm-drw-pc.has-value .dm-drw-pc-label { color: rgba(252,198,68,0.96) !important; }

/* ── 9. Footer compact ── */
.dm-shell-v3 .dm-foot-v2 {
  padding: 7px 10px 12px !important;
  gap: 6px !important;
  flex-shrink: 0 !important;
  background: rgba(255,255,255,0.04) !important;
  border-top: 1px solid rgba(255,255,255,0.12) !important;
  box-shadow: 0 -1px 0 rgba(255,255,255,0.06) !important;
}
.dm-shell-v3 .dm-foot-v2 .dm-reset-btn { padding: 8px 16px !important; font-size: 12.5px !important; }
.dm-shell-v3 .dm-foot-v2 .dm-generate-btn { padding: 10px 20px !important; font-size: 13.5px !important; }

/* ── 10. body.director-drawer-open insurance ── */
body.director-drawer-open { overflow: auto !important; }

/* --- ov:story-mode-controls-cleanup (b.933)
   Two fixes for story mode bottom bar clutter:
   1. Hide the mode-pill (MODE · STORY) in story mode — the pill serves no
      purpose there and adds visual noise to the controls row.
   2. Ensure the Director Default Bar (#directorDefaultBar) is always
      visible in story mode so the "Direct the scene" CTA is accessible
      regardless of storyPhase. The JS uses visibility:hidden via
      .ddb-invisible to keep it in layout without showing it — we override
      that so the bar stays clickable at all story phases. */

/* 1. Mode pill — hidden in story mode */
body.in-story-mode #modePillTop {
  display: none !important;
}

/* 2. Director bar — always visible in story mode (phase-agnostic).
   The .ddb-invisible class sets visibility:hidden!important on the bar.
   We override that with a later !important so the Direct CTA is always
   reachable, letting the user open the drawer at any story phase. */
body.in-story-mode .director-default-bar.ddb-invisible {
  visibility: visible !important;
  pointer-events: auto !important;
}

/* ═══════════════════════════════════════════════════════════════════════
   ABSOLUTE POSITION LOCK — ID selector (specificity 1,0,0) beats every
   class-based !important rule. Guarantees the drawer is pinned to the
   true viewport origin (top:0) and stacks above all page chrome
   (z-index 999999 >> header z-index 10).
   Slide animation (transform/visibility/transition) is still governed
   by the class-based :not([hidden]) / [hidden] rules above — this rule
   only locks position, size, and stacking.
   ═══════════════════════════════════════════════════════════════════════ */
/* ── NUCLEAR v4 — Full-screen transparent overlay; shell slides inside it.
   Moves the slide animation from #directorModal to .dm-shell-v3.
   #directorModal becomes a pure viewport-filling pointer-events-none shell.
   This guarantees top: 0 = true viewport top regardless of any ancestor
   containing-block issue (contain:layout, transform, backdrop-filter, etc.).
   ═══════════════════════════════════════════════════════════════════════ */

/* Overlay: always fixed at full viewport. No animation. No transform. */
#directorModal {
  position: fixed !important;
  inset: 0 !important;           /* top:0 right:0 bottom:0 left:0 */
  width: 100vw !important;
  height: 100dvh !important;
  z-index: 999999 !important;
  margin: 0 !important;
  padding: 0 !important;
  background: transparent !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  transform: none !important;
  visibility: visible !important;
  transition: none !important;
  pointer-events: none !important;  /* pass clicks through the transparent area */
  overflow: visible !important;
  display: block !important;        /* override flex — shell is absolute */
}

/* Right corners of the shell must be flush with the screen edge — no radius.
   Border: only left edge separator visible; top/right/bottom flush with screen.
   Padding zeroed — visual-studio.css sets padding:24px 28px 28px !important on
   .director-modal .dm-shell which bleeds into the shell; override it here. */
#directorModal.director-drawer .dm-shell-v3 {
  border-top-right-radius: 0 !important;
  border-bottom-right-radius: 0 !important;
  border-top: none !important;
  border-right: none !important;
  border-bottom: none !important;
  border-left: 1px solid rgba(255, 255, 255, 0.10) !important;
  padding: 0 !important;
  gap: 0 !important; /* kills vs.css gap: 18px that was breaking tab↔pane connection */
}

/* Shell: position: fixed directly — NOT absolute within overlay.
   This guarantees top: 0 = true viewport top with no dependency on the
   overlay's own position. The overlay (pointer-events:none, transparent)
   and the shell (pointer-events:auto, frosted glass) are independently
   fixed to the viewport. #directorModal has no transform/backdrop-filter
   so it does NOT create a containing block for fixed descendants. */
#directorModal.director-drawer .dm-shell-v3 {
  position: fixed !important;
  top: 0 !important;
  right: 0 !important;
  bottom: 0 !important;
  left: auto !important;
  width: 440px !important;
  max-width: 100vw !important;
  height: 100dvh !important;
  pointer-events: auto !important;
  /* Slide animation */
  transform: translateX(calc(100% + 2px)) !important;
  visibility: hidden !important;
  transition: transform 0.34s cubic-bezier(0.22, 0.61, 0.36, 1),
              visibility 0.34s step-end !important;
  /* Scroll */
  overflow-y: auto !important;
  overflow-x: hidden !important;
  overscroll-behavior: contain !important;
  flex: unset !important;
  min-height: unset !important;
}

/* ── NUCLEAR HIDE — base state: shell ALWAYS hidden unless JS opens it.
   Specificity (1,2,1). The hide and shown rules are MUTUALLY EXCLUSIVE
   so there is no specificity race — exactly one matches at any time.
   Works on ALL HTML versions: old (no [hidden] attr), new, any future state. ── */
body:not(.director-open) #directorModal .dm-shell-v3 {
  transform: translateX(calc(100% + 2px)) !important;
  visibility: hidden !important;
  pointer-events: none !important;
}

/* Shell shown state — ONLY fires when JS explicitly calls openDirector().
   Specificity (1,2,1) — matches the hide rule, but mutually exclusive:
   body.director-open is only set in openDirector(), never on page load.
   OLD fix (#directorModal.director-drawer:not([hidden]) .dm-shell-v3) had
   specificity (1,3,0) which BEAT the hide rule — old HTML with no [hidden]
   attr caused the drawer to appear on every page. THIS fixes that. */
body.director-open #directorModal .dm-shell-v3 {
  transform: translateX(0) !important;
  visibility: visible !important;
  pointer-events: auto !important;
}

/* ── ABSOLUTE NUCLEAR — hide the ENTIRE modal wrapper when not open.
   display:none propagates to ALL descendants including position:fixed children.
   No child CSS rule can make anything inside visible when the parent is display:none.
   This is the CSS equivalent of "pull the power cord". Specificity (1,1,1). ── */
body:not(.director-open) #directorModal {
  display: none !important;
}
body.director-open #directorModal {
  display: flex !important;
}

/* Popover: needs pointer-events even though overlay is none */
#directorModal.director-drawer #dmPopover {
  pointer-events: auto !important;
}

/* --- ov:stem-modal-visible-over-expose
   The stem modal is hoisted to body in a display:contents wrapper that has
   class music-studio-inline-host. When the expose gallery is open,
   body.music-expose-active applies a blanket "display:none" to all direct
   children of .music-studio-inline-host, which silently traps the hoisted
   stem modal before z-index ever matters. This rule punches through that
   to re-show the modal and place it firmly above the expose overlay. */
body.music-expose-active .music-studio-inline-host .ms-stem-modal[data-open="true"] {
  display: flex !important;
  visibility: visible !important;
  pointer-events: auto !important;
  z-index: 500 !important;
}

/* Also target the modal when it's hoisted directly to body (no expose-active guard needed) */
body > [data-soj-popover-wrap] .ms-stem-modal[data-open="true"] {
  display: flex !important;
  visibility: visible !important;
  pointer-events: auto !important;
  z-index: 500 !important;
}

/* ── Vibe-code mobile preview: remove fake Dynamic Island + home indicator bar ── */
.vc-preview-pane[data-device="mobile"]::before,
.vc-preview-pane[data-device="mobile"]::after {
  content: none !important;
}

/* ── Design System modal: kill the near-black canvas overlay — let the real
   theme background show through so the modal looks like liquid glass floating
   over the actual app, not a dark void. ── */
body.vc-ds-open #vibeCodeEngine {
  background: transparent !important;
}
