/* ============================================================
   v6 Polish — late-stage fixes that override looser layer rules
   ============================================================
   This file lands LAST in the cascade so it wins. Fixes:
     1. .v6-session-group buttons were merging into one blob —
        give them clear dividers + ensure icons render at the
        right size.
     2. AI strip cramped — uniform button heights, breathing
        room between groups.
     3. Sidebar toolbar floated without anchor since the
        "Pattern Library" h2 was removed — give it a background
        so it reads as the sidebar's header.
     4. Tap-tempo button alignment + visible label.
     5. Snap-to-Scale toggle remains visibly on by default.
     6. The new Compose / Quick AI / Refine / Randomize cluster
        gets a tasteful generative-gradient background.

   Explicit layer ORDER declaration. Without this, cascade-layer
   ordering depended on first-appearance of each `@layer` block,
   which is fragile. By explicitly listing layers from lowest
   priority to highest (for normal declarations), we make:
     - normal: v6-polish wins (declared last)
     - !important: v6-polish wins (declared LAST, but !important
       reverses → declared LAST → still wins because un-layered
       legacy rules are lowest)
   Note the rule for !important in author origin:
     earliest layer beats later layer beats unlayered.
   So we keep v6-polish declared LAST and use !important. The
   only way this loses is if v6-shell/v6-tokens/v6-components
   adds a competing !important rule — none of them do for the
   selectors we care about (verified via grep). */
@layer v6-tokens, v6-shell, v6-editor, v6-components, v6-legacy-bridge, v6-polish;

/* ============================================================
   CACHE DIAGNOSTIC — removed.
   This used to render a fixed "v9.8 vary (non-destructive)" badge in the
   bottom-left corner (z-index 99999), which overlapped the song-arrangement
   ruler and status bar. It was a dev cache-check, not a shipping element —
   removed so the bottom-left of the app is clean.
   ============================================================ */

/* ============================================================
   AI cluster consolidation.
   The unified "AI ▾" menu (#aiMenuBtn) already contains Compose / Quick AI /
   Refine / Randomize, so the standalone buttons are redundant chrome. Hide
   them — they stay in the DOM (display:none still allows programmatic
   .click()) so AIMenuButton's proxy and the MidiLearn / CommandPalette /
   AIQuickActions anchors keep working.
   ============================================================ */
#v6ComposeBtn,
#exampleBtn,
#refineBtn,
#randomizeSongBtn {
  display: none !important;
}

/* ============================================================
   The 2026-08 "toolbar declutter" hid #tapTempoBtn and
   #scaleHighlightToggle outright. Item 2.2 gives both a home instead:
   Tap lives in the Tempo popover, the scale eye in #editorToolbar
   beside the chord strip. Hiding them here now would hide them there.
   ============================================================ */

/* ============================================================
   Workflow hint — one-line "Patterns → Edit → Arrange" explainer
   (WorkflowHint.js), dismissible. Clarifies the three places.
   ============================================================ */
.zt-workflow-hint {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 4px 0 12px;
  padding: 8px 12px;
  background: linear-gradient(90deg, rgba(139, 92, 246, 0.12), rgba(236, 72, 153, 0.10));
  border: 1px solid var(--border-default, rgba(255, 255, 255, 0.10));
  border-radius: 10px;
  font-size: 12px;
  color: var(--text-secondary, #a1a1aa);
}
.zt-workflow-hint b { color: var(--text-primary, #fafafa); font-weight: 600; }
.zt-wh-arrow { color: var(--accent-primary, #8b5cf6); font-weight: 700; }
.zt-wh-close {
  margin-left: auto;
  background: transparent;
  border: none;
  color: var(--text-secondary, #a1a1aa);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 2px 6px;
  border-radius: 6px;
}
.zt-wh-close:hover { background: rgba(255, 255, 255, 0.08); color: #fff; }

/* ============================================================
   Pattern ⇄ Song view toggle + Song-mode full-screen arrangement
   (ViewModeToggle.js). Unlayered + !important — which is enough here
   because the base layout rules these fight (style-v2.css, and
   layout-overhaul.css inside @layer v6-shell) are all NORMAL
   declarations. It is NOT the blanket win over layered rules this
   comment used to claim it was: for !important the cascade is REVERSED,
   so an !important declaration inside a @layer outranks an unlayered one.
   See the EMERGENCY LAYOUT BYPASS at the bottom of this file, which is
   layered for exactly that reason.
   ============================================================ */
.zt-view-toggle {
  display: inline-flex;
  border: 1px solid var(--border-default, rgba(255, 255, 255, 0.14));
  border-radius: 8px;
  overflow: hidden;
  margin-right: 8px;
  flex: 0 0 auto;
}
.zt-view-toggle__btn {
  background: transparent;
  border: none;
  color: var(--text-secondary, #a1a1aa);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 6px 14px;
  cursor: pointer;
}
.zt-view-toggle__btn.is-active {
  background: var(--accent-primary, #8b5cf6);
  color: #fff;
}

/* Song mode: hide the pattern-editing surface, keep the transport/AI strip
   (.control-panel), and let the arrangement fill the whole workspace. */
body.zt-song-mode .container > *:not(.control-panel) { display: none !important; }
/* The edit-context banner lives inside .control-panel but is pattern-clip
   context — hide it in Song mode. */
body.zt-song-mode .edit-context-banner { display: none !important; }
/* Shrink the (now mostly-empty) pattern container to its content so the
   arrangement can take the freed space. */
body.zt-song-mode .main-content > .container { flex: 0 0 auto !important; min-height: 0 !important; }
/* ── Item 2.4: the arranger flexes; nothing guesses a height ─────────────
   The ~40px dead band under the transport was a HARDCODED CONSTANT.
   .song-timeline-container is position:fixed with bottom:0 and
   left:var(--sidebar-width) (style-v2.css:1661-1672), so its height set its
   TOP edge, and the Song-mode height calc subtracted a measured
   .control-panel height (132px, then 124px after item 2.2 shrank the rows).
   Every future change to the transport re-opened the gap. Now Song mode
   makes .main-content a real column that stops at the status bar and lets
   the arranger take whatever is left: nothing is measured, so nothing drifts.

   `min-height: 0` is load-bearing. style-v2.css:536-541 gives .main-content
   `min-height: 100vh` UNLAYERED; layout-overhaul.css's `min-height: 0` sits
   inside `@layer v6-shell`, and a NORMAL layered declaration loses to a
   normal unlayered one — so without this the column stays >= 100vh and the
   arranger's bottom edge ends up underneath the fixed status bar.

   CASCADE, correctly (an earlier comment in this file had it backwards and
   the EMERGENCY LAYOUT BYPASS at the bottom records how that failed): for
   !important the layer order is REVERSED — !important INSIDE a @layer beats
   !important OUTSIDE every layer. Unlayered !important only outranks NORMAL
   declarations. These rules are unlayered + !important because everything
   they have to beat (style-v2's unlayered .main-content /
   .song-timeline-container, layout-overhaul's layered normal rules) is
   normal. The one layered !important in play — layout-overhaul.css's
   `.main-content { overflow: hidden !important }` — outranks these and
   happens to agree with them. */
body.zt-song-mode .main-content {
  display: flex !important;
  flex-direction: column !important;
  height: calc(100vh - var(--v6-app-bar-h, 56px) - var(--statusbar-h, 26px)) !important;
  min-height: 0 !important;
  /* style-v2.css:1690 reserves --timeline-height for the FIXED arranger. In
     the flow it would be 140px of nothing under the canvas. */
  padding-bottom: 0 !important;
  overflow: hidden !important;
}
body.zt-song-mode #songTimelineContainer {
  /* Back into the flow — un-pin every viewport-anchored property style-v2
     sets for Pattern view. */
  position: relative !important;
  left: auto !important;
  right: auto !important;
  bottom: auto !important;
  height: auto !important;
  max-height: none !important;
  flex: 1 1 auto !important;
  min-height: 320px !important;
  display: flex !important;
  flex-direction: column !important;
}
body.zt-song-mode .timeline-canvas-wrapper {
  height: auto !important;
  flex: 1 1 auto !important;
  min-height: 0 !important;
}
/* Nothing populates #timelineTrackHeaders (the per-track arranger headers
   were never built; plan item 7.7 deletes the node). Empty, it still draws
   its 1px border-top across the bottom of the canvas — visible now that the
   canvas ends AT the status bar. Keep it out of the Song-mode column. */
body.zt-song-mode #timelineTrackHeaders { display: none !important; }
/* In song mode the arrangement header/sections stay their natural size; the
   canvas wrapper (above) grows to fill the rest. */

/* --statusbar-h was a 7px lie, and it is the bottom edge of the column above.
   StatusBar mounts a <footer>, and style-v2.css:2263's UNLAYERED
   `footer { padding: var(--space-4) }` (16px) beats shell.css's
   `.v6-statusbar { padding: 0 12px }`, which sits inside @layer v6-shell —
   normal unlayered wins over normal layered. With border-box, 32px of vertical
   padding cannot fit inside `height: 26px`, so the used height became
   padding + border = 33px while every consumer of the token reserved 26: the
   body's bottom padding (the EMERGENCY LAYOUT BYPASS below),
   instrument-panel.css:35's `calc(100vh - var(--statusbar-h))`, and this
   item's Song-mode column, whose canvas therefore ran 7px UNDER the bar.
   Restore the intended padding at the same origin the legacy rule uses —
   unlayered, one class more specific than `footer`, so no !important. */
body > .v6-statusbar { padding: 0 12px; }

/* ============================================================
   DEFENSIVE OVERRIDES — un-layered + very high specificity.
   These bypass any cascade-layer weirdness by living outside any
   @layer at all. For author origin un-layered rules with !important,
   they beat ALL un-layered author rules without !important (which
   is where the legacy .btn-ghost rules live). And the high
   specificity prevents accidental shadowing. */
body.v6-app-bar-active .v6-app-bar .v6-session-group button.btn,
body.v6-app-bar-active .v6-app-bar .v6-session-group button.btn.btn-ghost,
body.v6-app-bar-active .v6-app-bar .v6-session-group button.btn.btn-sm {
  background: rgba(255, 255, 255, 0.05) !important;
  border: 1px solid rgba(255, 255, 255, 0.10) !important;
  border-radius: 7px !important;
  height: 28px !important;
  padding: 0 14px !important;
  color: #a1a1aa !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 6px !important;
  letter-spacing: 0.01em !important;
}
body.v6-app-bar-active .v6-app-bar .v6-session-group {
  background: rgba(0, 0, 0, 0.30) !important;
  border: 1px solid rgba(255, 255, 255, 0.10) !important;
  border-radius: 999px !important;
  padding: 4px !important;
  gap: 4px !important;
  display: inline-flex !important;
  align-items: center !important;
}
body.v6-app-bar-active .v6-app-bar .v6-session-group button.btn:hover {
  background: rgba(255, 255, 255, 0.14) !important;
  border-color: rgba(255, 255, 255, 0.22) !important;
  color: #fff !important;
}

/* Same defensive treatment for the AI strip Versions/Randomize collision. */
body.v6-app-bar-active .v6-ai-strip button.v6-versions__pill,
body.v6-app-bar-active .v6-ai-strip .v6-ai-actions__toggle {
  background: rgba(255, 255, 255, 0.06) !important;
  border: 1px solid rgba(255, 255, 255, 0.14) !important;
  border-radius: 6px !important;
  height: 30px !important;
  padding: 0 12px !important;
  color: #a1a1aa !important;
}

/* ============================================================
   COMPOSE MODAL — defensive padding overrides.
   The modal's `.v6-composer__body` and `.v6-composer__section`
   were rendering edge-to-edge because some legacy / cascade-layer
   rule was zeroing their padding. We put horizontal padding
   directly on the section (so every child — slider, opts grid,
   scale picker — sits inside a padded zone without needing
   `margin-left` tricks). The body itself also gets generous
   padding so the section accent-bars don't kiss the modal edge.
   ============================================================ */
body .v6-composer .v6-composer__body {
  padding: 14px 28px 20px !important;
}
body .v6-composer .v6-composer__section {
  /* 18px top/bottom + 20px LEFT (for the accent-bar) + 14px right */
  padding: 18px 14px 14px 20px !important;
}
body .v6-composer .v6-composer__section h3 {
  padding-left: 0 !important;
  margin: 0 0 14px !important;
  /* Accent bar sits OUTSIDE the section padding (to the left of it). */
}
body .v6-composer .v6-composer__section h3::before {
  left: -10px !important;
}
/* Defeat the legacy margin-left:14px trick — padding on the section
   now handles indentation. */
body .v6-composer .v6-composer__section > *:not(h3) {
  margin-left: 0 !important;
  margin-right: 0 !important;
}
/* Slider sections — slider + scale labels stretch full-width inside
   the section's padded zone. */
body .v6-composer .v6-composer__section--slider > .v6-composer__slider,
body .v6-composer .v6-composer__section--slider > .v6-composer__slider-scale,
body .v6-composer .v6-composer__section--slider > .v6-composer__slider-scale--abs {
  width: 100% !important;
  margin: 12px 0 0 !important;
}
/* Footer + header: keep their generous horizontal padding */
body .v6-composer .v6-composer__head {
  padding: 18px 26px !important;
}
body .v6-composer .v6-composer__footer {
  padding: 16px 26px !important;
}
/* The mood/genre/length card grids fill the section's inner padded
   width — no extra left margin offset. */
body .v6-composer .v6-composer__opts,
body .v6-composer .v6-composer__opts--wrap {
  margin: 0 !important;
}

/* ============================================================
   PLAN A — Compose modal final polish
   ============================================================ */

/* A1. Slider tracks — make them actually visible. Old gradient was
   too transparent against the dark modal so the thumb appeared to
   float in a void. */
body .v6-composer .v6-composer__slider {
  height: 8px !important;
  background:
    linear-gradient(90deg,
      rgba(139, 92, 246, 0.55) 0%,
      rgba(236, 72, 153, 0.65) 100%),
    rgba(255, 255, 255, 0.08) !important;
  border: 1px solid rgba(255, 255, 255, 0.10) !important;
  border-radius: 999px !important;
  box-shadow:
    0 2px 4px rgba(0, 0, 0, 0.45) inset,
    0 0 12px rgba(139, 92, 246, 0.18) !important;
}

/* A2. Section dividers — subtle 1px line between sections. */
body .v6-composer .v6-composer__section + .v6-composer__section {
  border-top: 1px solid rgba(255, 255, 255, 0.06) !important;
  margin-top: 4px !important;
}

/* A3. Tick label at right edge — anchor to right: 0 instead of
   transform: translateX(-50%), so "12 · EPIC" / "170" don't clip. */
body .v6-composer .v6-composer__slider-scale--abs {
  position: relative !important;
  height: 18px !important;
  margin: 6px 0 0 !important;
}
body .v6-composer .v6-composer__slider-scale--abs .v6-composer__slider-tick {
  position: absolute !important;
  transform: translateX(-50%) !important;
}
body .v6-composer .v6-composer__slider-scale--abs .v6-composer__slider-tick:first-child {
  transform: none !important;
  left: 0 !important;
  text-align: left !important;
}
body .v6-composer .v6-composer__slider-scale--abs .v6-composer__slider-tick:last-child {
  transform: none !important;
  left: auto !important;
  right: 0 !important;
  text-align: right !important;
}

/* A4. Mood / Genre / Length cards — hover lift + active gradient. */
body .v6-composer .v6-composer__opt {
  background: linear-gradient(180deg,
    rgba(255, 255, 255, 0.04),
    rgba(255, 255, 255, 0.01)) !important;
  border: 1px solid rgba(255, 255, 255, 0.10) !important;
  border-radius: 8px !important;
  padding: 10px 12px !important;
  transition:
    background 120ms,
    border-color 120ms,
    transform 120ms !important;
}
body .v6-composer .v6-composer__opt:hover {
  background: linear-gradient(180deg,
    rgba(255, 255, 255, 0.08),
    rgba(255, 255, 255, 0.03)) !important;
  border-color: rgba(255, 255, 255, 0.20) !important;
  transform: translateY(-1px) !important;
}
body .v6-composer .v6-composer__opt--active {
  background: linear-gradient(180deg,
    rgba(139, 92, 246, 0.35),
    rgba(139, 92, 246, 0.18)) !important;
  border-color: #8b5cf6 !important;
  box-shadow:
    0 0 0 1px rgba(139, 92, 246, 0.40) inset,
    0 4px 16px rgba(139, 92, 246, 0.25) !important;
}

/* A5. Footer button hierarchy — Cancel (ghost) | Surprise me (accent
   ghost, push-right) | Compose (gradient hero). */
body .v6-composer .v6-composer__footer > [data-action="close"] {
  background: transparent !important;
  border: 1px solid rgba(255, 255, 255, 0.14) !important;
  color: #a1a1aa !important;
  height: 36px !important;
  padding: 0 18px !important;
  border-radius: 8px !important;
  font-weight: 600 !important;
}
body .v6-composer .v6-composer__footer > [data-action="close"]:hover {
  background: rgba(255, 255, 255, 0.06) !important;
  color: #fff !important;
}
body .v6-composer .v6-composer__footer > [data-action="random-all"] {
  margin-left: auto !important;
  background: rgba(236, 72, 153, 0.12) !important;
  border: 1px solid rgba(236, 72, 153, 0.50) !important;
  color: #fff !important;
  height: 36px !important;
  padding: 0 18px !important;
  border-radius: 8px !important;
  font-weight: 600 !important;
  text-transform: none !important;
  letter-spacing: 0 !important;
}
body .v6-composer .v6-composer__footer > [data-action="random-all"]:hover {
  background: rgba(236, 72, 153, 0.25) !important;
  border-color: #ec4899 !important;
  box-shadow: 0 0 16px rgba(236, 72, 153, 0.30) !important;
}
body .v6-composer .v6-composer__footer > [data-action="compose"],
body .v6-composer .v6-composer__footer > .v6-composer__go {
  background: linear-gradient(135deg, #8b5cf6, #ec4899) !important;
  border: 1px solid rgba(236, 72, 153, 0.60) !important;
  color: #fff !important;
  height: 42px !important;
  padding: 0 24px !important;
  border-radius: 10px !important;
  font-weight: 700 !important;
  min-width: 160px !important;
  box-shadow:
    0 6px 20px rgba(139, 92, 246, 0.35),
    0 0 0 1px rgba(255, 255, 255, 0.08) inset !important;
}
body .v6-composer .v6-composer__footer > [data-action="compose"]:hover,
body .v6-composer .v6-composer__footer > .v6-composer__go:hover {
  filter: brightness(1.10) !important;
  transform: translateY(-1px) !important;
}

/* A6. Header subtitle — clamp to one line, ellipsis if too long. */
body .v6-composer .v6-composer__subtitle {
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  max-width: 380px !important;
}

/* ============================================================
   PLAN B — Sections strip overhaul
   ============================================================ */

/* B1. "+ Section" button — bordered tile so it's visibly separate
   from "Build Song". */
body .v6-section-strip__add {
  background: rgba(255, 255, 255, 0.05) !important;
  border: 1px solid rgba(255, 255, 255, 0.14) !important;
  color: #a1a1aa !important;
  height: 28px !important;
  padding: 0 12px !important;
  border-radius: 6px !important;
  font-weight: 600 !important;
}
body .v6-section-strip__add:hover {
  background: rgba(139, 92, 246, 0.15) !important;
  border-color: #8b5cf6 !important;
  color: #fff !important;
}
/* B2. "Build from my sections" — SECONDARY, not a hero.
   It runs the identical composeFullSong pipeline as Create ▾, so painting
   it with the accent gradient made one feature look like two. It now wears
   the same bordered tile as "+ Section".
   These declarations must stay explicit (and !important) rather than letting
   .btn-ghost through: this file also carries the rule inside `@layer
   v6-polish`, and an !important inside a layer outranks unlayered !important,
   which outranks every normal declaration — so a no-!important .btn-ghost
   could never win here. Removing the colour is not enough; it has to be
   REPLACED, in both copies. */
body .v6-section-strip__build {
  background: rgba(255, 255, 255, 0.05) !important;
  border: 1px solid rgba(255, 255, 255, 0.14) !important;
  color: #a1a1aa !important;
  height: 28px !important;
  padding: 0 14px !important;
  border-radius: 6px !important;
  font-weight: 600 !important;
  box-shadow: none !important;
}
body .v6-section-strip__build:hover {
  background: rgba(139, 92, 246, 0.15) !important;
  border-color: #8b5cf6 !important;
  color: #fff !important;
}
/* B3. Group spacing only. This rule used to add a left border so the buttons
   "didn't kiss the band area" — but since item 2.6 they are not next to the
   bands at all: they sit in .timeline-header, where the rule left a 1px rule
   hanging in space, separating nothing. The header's own .timeline-separator
   does that job. */
body .v6-section-strip__actions {
  gap: 8px !important;
}
/* B4. Empty-state hint inside the band area — clearer typography. */
body .v6-section-strip__empty {
  font-size: 11px !important;
  color: #71717a !important;
}
body .v6-section-strip__empty strong {
  color: #fafafa !important;
  background: rgba(255, 255, 255, 0.06) !important;
  padding: 1px 6px !important;
  border-radius: 4px !important;
  margin: 0 3px !important;
}

/* ============================================================
   PLAN C — Edit Context banner ("Pattern A · Independent Copy ·
   lock · VARIATIONS · scope text · status")
   ============================================================ */

/* C1. The banner itself: more horizontal padding, gap between
   left/right groups. */
body .edit-context-banner {
  padding: 8px 16px !important;
  gap: 12px !important;
}
body .edit-context-left {
  gap: 10px !important;
}
body .edit-context-right {
  gap: 10px !important;
}

/* C2. Lock toggle: proper 24x24 bordered tile. */
body .edit-context-link-toggle {
  width: 24px !important;
  height: 24px !important;
  background: rgba(255, 255, 255, 0.06) !important;
  border: 1px solid rgba(255, 255, 255, 0.12) !important;
  border-radius: 6px !important;
  cursor: pointer !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  transition: background 120ms, border-color 120ms !important;
}
body .edit-context-link-toggle:hover {
  background: rgba(139, 92, 246, 0.18) !important;
  border-color: #8b5cf6 !important;
}

/* C3. The scope text ("Independent — changes only affect this clip")
   becomes a subtle pill so it reads as a state indicator. */
body .edit-context-scope {
  font-style: normal !important;
  font-size: 11px !important;
  padding: 2px 8px !important;
  background: rgba(255, 255, 255, 0.04) !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  border-radius: 999px !important;
  color: #a1a1aa !important;
}

/* C4. The "+ VARIATIONS" link should read as a button. */
body .v6-variation-switcher-add,
body button[id*="variation"][id*="Add"],
body [class*="variation"][class*="add"] {
  background: rgba(255, 255, 255, 0.05) !important;
  border: 1px solid rgba(255, 255, 255, 0.14) !important;
  border-radius: 6px !important;
  height: 24px !important;
  padding: 0 10px !important;
  color: #a1a1aa !important;
  font-size: 11px !important;
  font-weight: 600 !important;
}

/* The Help modal's styles moved to src/styles/v6/help.css.
   What was here was a rescue block recovered from the deleted style.css so the
   guide would stop rendering as raw markup — never a design. The replacement is
   built on the v6 tokens and docs/visual-spec.md. */

/* ============================================================
   REGRESSION FIX 3 — sidebar collapse + expand button styling
   were in style.css too.
   ============================================================ */
body .pattern-library-sidebar.collapsed {
  width: 0 !important;
  min-width: 0 !important;
  opacity: 0 !important;
  pointer-events: none !important;
  overflow: hidden !important;
  transition: width 200ms, opacity 200ms !important;
}
body .daw-layout.sidebar-collapsed {
  /* style-v2.css already sets `grid-template-columns: var(--sidebar-collapsed) 1fr`.
     That alone collapses the sidebar column. */
}
body .sidebar-expand-btn {
  position: fixed;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  z-index: 50;
  width: 32px;
  height: 64px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(180deg,
    rgba(139, 92, 246, 0.85),
    rgba(236, 72, 153, 0.65));
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-left: none;
  border-top-right-radius: 10px;
  border-bottom-right-radius: 10px;
  color: #fff;
  cursor: pointer;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.50);
  transition: width 120ms, background 120ms;
}
body .sidebar-expand-btn:hover {
  width: 44px;
  filter: brightness(1.10);
}
body .sidebar-expand-btn.hidden {
  display: none !important;
}
body .sidebar-expand-btn .v6-icon {
  width: 16px;
  height: 16px;
}

/* ============================================================
   REGRESSION FIX — legacy modal positioning lived in style.css.
   ============================================================
   Removing style.css killed the positioning rules for every
   modal that uses the BaseModal pattern (`.modal-overlay >
   .modal-dialog`). They were flowing as block elements at the
   bottom of <body>, so "My Songs" / Export / Confirm / Help /
   etc. all rendered behind / below the editor.

   Restore the centred-overlay layout in the v6 cascade so every
   legacy modal pops to the center of the viewport on a dimmed
   backdrop, same UX as the new v6 Compose modal.
   ============================================================ */
body .modal-overlay {
  position: fixed !important;
  inset: 0 !important;
  z-index: 9000 !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  background: radial-gradient(ellipse at center,
    rgba(20, 20, 30, 0.65) 0%,
    rgba(0, 0, 0, 0.85) 100%) !important;
  backdrop-filter: blur(6px) !important;
  -webkit-backdrop-filter: blur(6px) !important;
  padding: 24px !important;
  overflow: auto;
}
body .modal-overlay .modal-dialog {
  position: relative !important;
  max-width: 100% !important;
  max-height: calc(100vh - 48px);
  margin: 0 !important;
  background: linear-gradient(180deg,
    var(--surface-300, #18181b) 0%,
    var(--surface-200, #111113) 100%);
  color: var(--text-primary, #fafafa);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 14px;
  box-shadow:
    0 32px 80px rgba(0, 0, 0, 0.75),
    0 0 0 1px rgba(139, 92, 246, 0.12) inset !important;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
/* The .hidden utility class still wins to hide modals when not open. */
body .modal-overlay.hidden,
body .modal-overlay[hidden],
body .modal-overlay[aria-hidden="true"] {
  display: none !important;
}
/* Default Confirm / Export / Help / etc. — give them a sensible width
   so they aren't full-width by default. Specific modals can override. */
body .modal-overlay .modal-dialog:not(.song-browser-modal):not(.export-modal):not(.ai-modal) {
  width: min(560px, calc(100vw - 48px));
}

/* ============================================================
   ADD TRACK MODAL — inner content styling.
   The legacy markup used .modal-header / .modal-body / .modal-footer
   classes whose styles vanished with style.css. Rebuild them here in
   the v6 cascade so the dialog actually looks like a modal.
   ============================================================ */
body .add-track-modal .modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 24px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  background: linear-gradient(180deg,
    rgba(139, 92, 246, 0.08) 0%,
    rgba(139, 92, 246, 0) 100%);
}
body .add-track-modal .modal-header h3 {
  margin: 0;
  font-size: 17px;
  font-weight: 600;
  color: var(--text-primary, #fafafa);
  letter-spacing: 0.01em;
}
body .add-track-modal .modal-close {
  appearance: none;
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-secondary, #a1a1aa);
  width: 32px;
  height: 32px;
  border-radius: 8px;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
body .add-track-modal .modal-close:hover {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.12);
  color: var(--text-primary, #fafafa);
}
body .add-track-modal .modal-body {
  padding: 20px 24px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  overflow-y: auto;
}
body .add-track-modal .modal-description {
  margin: 0;
  color: var(--text-secondary, #a1a1aa);
  font-size: 13px;
}
body .add-track-modal .track-type-options {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
body .add-track-modal .track-type-option {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  padding: 14px 14px 12px;
  background: var(--surface-400, #1f1f23);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  color: var(--text-primary, #fafafa);
  cursor: pointer;
  text-align: left;
  transition: background .15s, border-color .15s, transform .12s;
}
body .add-track-modal .track-type-option:hover {
  background: rgba(139, 92, 246, 0.10);
  border-color: rgba(139, 92, 246, 0.45);
  transform: translateY(-1px);
}
body .add-track-modal .track-type-option.selected {
  background: linear-gradient(135deg,
    rgba(139, 92, 246, 0.22),
    rgba(236, 72, 153, 0.18));
  border-color: rgba(139, 92, 246, 0.75);
  box-shadow: 0 0 0 1px rgba(139, 92, 246, 0.35) inset;
}
body .add-track-modal .track-type-icon {
  display: inline-flex;
  width: 36px;
  height: 36px;
  align-items: center;
  justify-content: center;
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.05);
  color: var(--accent-primary, #8b5cf6);
}
body .add-track-modal .track-type-name {
  font-size: 14px;
  font-weight: 600;
}
body .add-track-modal .track-type-desc {
  font-size: 12px;
  color: var(--text-secondary, #a1a1aa);
  line-height: 1.35;
}
body .add-track-modal .preset-section {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
body .add-track-modal .preset-section.hidden { display: none; }
body .add-track-modal .preset-section label {
  font-size: 12px;
  color: var(--text-secondary, #a1a1aa);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
body .add-track-modal .modal-select {
  background: var(--surface-400, #1f1f23);
  color: var(--text-primary, #fafafa);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 13px;
}
body .add-track-modal .track-count-info {
  font-size: 12px;
  color: var(--text-secondary, #a1a1aa);
  text-align: right;
}
body .add-track-modal .modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 14px 24px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(0, 0, 0, 0.25);
}

/* ============================================================
   v7.7 — UNIFIED AI MENU
   ============================================================
   Single primary "AI" button replaces the four-button cluster
   (Compose, Quick AI, Refine, Randomize). The legacy buttons
   stay in the DOM (needed by MidiLearn / CommandPalette /
   VersionsPopover / AIQuickActions) but are hidden via CSS.
   The AIQuickActions chevron is hidden too — its functionality
   (focus-axis refine) is power-user territory; access it via the
   command palette if needed.
   ============================================================ */
body .v6-ai-strip__group--generative #v6ComposeBtn,
body .v6-ai-strip__group--generative #exampleBtn,
body .v6-ai-strip__group--generative #refineBtn,
body .v6-ai-strip__group--generative #randomizeSongBtn,
body .v6-ai-strip__group--generative .v6-ai-actions__toggle {
  display: none !important;
}

/* Primary AI button — a generative-accent gradient that reads as
   the highest-energy control on the strip. */
body .v6-ai-menu__btn {
  display: inline-flex !important;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%) !important;
  color: #fff !important;
  border: 1px solid rgba(255, 255, 255, 0.18) !important;
  border-radius: 10px;
  font-weight: 600;
  letter-spacing: 0.01em;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.18) inset,
    0 8px 24px -8px rgba(139, 92, 246, 0.55);
  transition: transform .12s, box-shadow .15s, filter .15s;
}
body .v6-ai-menu__btn:hover {
  transform: translateY(-1px);
  filter: brightness(1.08);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.22) inset,
    0 12px 30px -8px rgba(139, 92, 246, 0.75);
}
body .v6-ai-menu__btn:active { transform: translateY(0); filter: brightness(0.96); }
body .v6-ai-menu__btn[aria-expanded="true"] {
  filter: brightness(1.05);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.22) inset,
    0 0 0 2px rgba(236, 72, 153, 0.40);
}
body .v6-ai-menu__btn .v6-icon { width: 18px; height: 18px; }
body .v6-ai-menu__btn-caret {
  font-size: 11px;
  opacity: 0.85;
  margin-left: 2px;
  transition: transform .15s;
}
body .v6-ai-menu__btn[aria-expanded="true"] .v6-ai-menu__btn-caret {
  transform: rotate(180deg);
}

/* Popover — anchored under the button by JS-set top/left. */
body .v6-ai-menu {
  position: fixed;
  z-index: 9500;
  min-width: 340px;
  max-width: 380px;
  background: linear-gradient(180deg,
    rgba(30, 28, 38, 0.98) 0%,
    rgba(18, 17, 24, 0.98) 100%);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 14px;
  box-shadow:
    0 24px 60px rgba(0, 0, 0, 0.6),
    0 0 0 1px rgba(139, 92, 246, 0.10) inset;
  opacity: 0;
  transform: translateY(-4px) scale(0.98);
  transition: opacity .14s ease, transform .14s ease;
  overflow: hidden;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
body .v6-ai-menu--visible {
  opacity: 1;
  transform: translateY(0) scale(1);
}
body .v6-ai-menu__header {
  padding: 10px 16px 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--text-secondary, #a1a1aa);
}
body .v6-ai-menu__list {
  display: flex;
  flex-direction: column;
  padding: 4px;
}
body .v6-ai-menu__item {
  appearance: none;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 10px;
  padding: 10px 12px;
  display: grid;
  grid-template-columns: 32px 1fr;
  gap: 12px;
  align-items: start;
  text-align: left;
  color: var(--text-primary, #fafafa);
  cursor: pointer;
  transition: background .12s, border-color .12s;
}
body .v6-ai-menu__item:hover,
body .v6-ai-menu__item:focus-visible {
  background: rgba(139, 92, 246, 0.12);
  border-color: rgba(139, 92, 246, 0.35);
  outline: none;
}
body .v6-ai-menu__item-icon {
  display: inline-flex;
  width: 32px;
  height: 32px;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: linear-gradient(135deg,
    rgba(139, 92, 246, 0.20),
    rgba(236, 72, 153, 0.20));
  color: #fff;
}
body .v6-ai-menu__item-icon .v6-icon { width: 16px; height: 16px; }
body .v6-ai-menu__item-glyph { font-size: 18px; line-height: 1; }
body .v6-ai-menu__item-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
body .v6-ai-menu__item-label {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.2;
}
body .v6-ai-menu__item-sub {
  font-size: 12px;
  color: var(--text-secondary, #a1a1aa);
  line-height: 1.35;
}
body .v6-ai-menu__footer {
  padding: 8px 16px 10px;
  font-size: 11px;
  color: var(--text-secondary, #a1a1aa);
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  background: rgba(0, 0, 0, 0.25);
}
body .v6-ai-menu__footer kbd {
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 4px;
  padding: 1px 5px;
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 10px;
}

/* ============================================================
   v8.4 — PER-TRACK AI MENU + TOAST
   ============================================================
   Popover anchored to .btn-ai-generate. Same visual treatment as the
   global AI menu but slightly narrower since it's per-track.
   ============================================================ */
body .v6-track-ai-menu {
  position: fixed;
  z-index: 9600;
  min-width: 320px;
  max-width: 360px;
  background: linear-gradient(180deg,
    rgba(30, 28, 38, 0.98) 0%,
    rgba(18, 17, 24, 0.98) 100%);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 12px;
  box-shadow:
    0 20px 50px rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(139, 92, 246, 0.08) inset;
  opacity: 0;
  transform: translateY(-4px) scale(0.98);
  transition: opacity .14s ease, transform .14s ease;
  overflow: hidden;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
body .v6-track-ai-menu--visible {
  opacity: 1;
  transform: translateY(0) scale(1);
}
body .v6-track-ai-menu__header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 14px 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-secondary, #a1a1aa);
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
body .v6-track-ai-menu__header-icon {
  display: inline-flex;
  color: var(--accent-primary, #8b5cf6);
}
body .v6-track-ai-menu__header-icon .v6-icon { width: 14px; height: 14px; }

body .v6-track-ai-menu__item {
  appearance: none;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 9px;
  padding: 9px 12px;
  margin: 4px;
  width: calc(100% - 8px);
  display: grid;
  grid-template-columns: 28px 1fr;
  gap: 10px;
  align-items: start;
  text-align: left;
  color: var(--text-primary, #fafafa);
  cursor: pointer;
  transition: background .12s, border-color .12s;
}
body .v6-track-ai-menu__item:hover:not(:disabled),
body .v6-track-ai-menu__item:focus-visible:not(:disabled) {
  background: rgba(139, 92, 246, 0.12);
  border-color: rgba(139, 92, 246, 0.35);
  outline: none;
}
body .v6-track-ai-menu__item:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
body .v6-track-ai-menu__item--alt {
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 0 0 9px 9px;
  margin-top: 4px;
}
body .v6-track-ai-menu__icon {
  display: inline-flex;
  width: 28px;
  height: 28px;
  align-items: center;
  justify-content: center;
  border-radius: 7px;
  background: linear-gradient(135deg,
    rgba(139, 92, 246, 0.18),
    rgba(236, 72, 153, 0.18));
  font-size: 16px;
  line-height: 1;
}
body .v6-track-ai-menu__body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
body .v6-track-ai-menu__label {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.2;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
body .v6-track-ai-menu__sub {
  font-size: 11.5px;
  color: var(--text-secondary, #a1a1aa);
  line-height: 1.35;
}
body .v6-track-ai-menu__badge {
  background: rgba(139, 92, 246, 0.25);
  color: var(--accent-primary, #c4b5fd);
  border: 1px solid rgba(139, 92, 246, 0.45);
  border-radius: 999px;
  padding: 1px 7px;
  font-size: 10px;
  font-weight: 700;
  line-height: 1.4;
}
/* v9.8 — Vary actions get a distinct green accent so users instantly
   see that the option is NON-DESTRUCTIVE. Destructive (regen) actions
   stay purple/pink; vary actions are green. */
body .v6-track-ai-menu__badge--vary {
  background: rgba(16, 185, 129, 0.20);
  color: #6ee7b7;
  border-color: rgba(16, 185, 129, 0.45);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
body .v6-track-ai-menu__item--vary {
  border-left: 2px solid rgba(16, 185, 129, 0.45);
}
body .v6-track-ai-menu__item--vary:hover {
  background: rgba(16, 185, 129, 0.10) !important;
  border-color: rgba(16, 185, 129, 0.40) !important;
}
body .v6-track-ai-menu__item--vary .v6-track-ai-menu__icon {
  background: linear-gradient(135deg,
    rgba(16, 185, 129, 0.25),
    rgba(34, 197, 94, 0.20));
}
body .v6-track-ai-menu__progress {
  padding: 8px 14px;
  background: rgba(139, 92, 246, 0.12);
  border-top: 1px solid rgba(139, 92, 246, 0.30);
  color: var(--text-primary, #fafafa);
  font-size: 12px;
  font-family: ui-monospace, SFMono-Regular, monospace;
  display: flex;
  align-items: center;
  gap: 8px;
}
body .v6-track-ai-menu__progress::before {
  content: '';
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.18);
  border-top-color: var(--accent-primary, #8b5cf6);
  animation: v6-spin 0.9s linear infinite;
}
@keyframes v6-spin {
  to { transform: rotate(360deg); }
}

/* Floating toast used by TrackAIMenu — generic enough to reuse later */
body .v6-toast {
  position: fixed;
  z-index: 9700;
  right: 16px;
  bottom: 32px;
  max-width: 360px;
  padding: 10px 14px;
  background: linear-gradient(135deg,
    rgba(30, 28, 38, 0.96),
    rgba(18, 17, 24, 0.96));
  color: var(--text-primary, #fafafa);
  border: 1px solid rgba(139, 92, 246, 0.40);
  border-radius: 10px;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.6);
  font-size: 13px;
  font-weight: 500;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .22s ease, transform .22s ease;
}
body .v6-toast--visible {
  opacity: 1;
  transform: translateY(0);
}
body .v6-toast--error {
  border-color: rgba(239, 68, 68, 0.6);
  box-shadow: 0 18px 40px rgba(239, 68, 68, 0.20);
}

/* ============================================================
   v8.6 — INSTRUMENT-PANEL APPLY-SCOPE TOGGLE
   ============================================================
   Segmented control at the top of the InstrumentPanel that decides
   whether parameter writes (preset, ADSR, filter, LFO, FX, oscillators,
   octave, volume, drum kit) apply across the whole song or only to
   the pattern currently in the editor.
   ============================================================ */
body .panel-scope-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 10px 18px;
  background: linear-gradient(180deg,
    rgba(139, 92, 246, 0.10) 0%,
    rgba(139, 92, 246, 0.04) 100%);
  border-bottom: 1px solid rgba(139, 92, 246, 0.20);
  font-size: 12px;
  color: var(--text-primary, #fafafa);
}
body .panel-scope-bar--local {
  background: linear-gradient(180deg,
    rgba(245, 158, 11, 0.10) 0%,
    rgba(245, 158, 11, 0.04) 100%);
  border-bottom-color: rgba(245, 158, 11, 0.28);
}
body .panel-scope-bar__label {
  font-weight: 600;
  color: var(--text-secondary, #a1a1aa);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 10px;
}
body .panel-scope-bar__toggle {
  display: inline-flex;
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
  padding: 2px;
  gap: 2px;
}
body .panel-scope-bar__opt {
  appearance: none;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-secondary, #a1a1aa);
  font-size: 12px;
  font-weight: 600;
  padding: 5px 12px;
  border-radius: 6px;
  cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
body .panel-scope-bar__opt:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-primary, #fafafa);
}
body .panel-scope-bar__opt--active {
  background: linear-gradient(135deg,
    rgba(139, 92, 246, 0.85),
    rgba(236, 72, 153, 0.85));
  color: #fff;
  border-color: rgba(255, 255, 255, 0.18);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.30);
}
body .panel-scope-bar--local .panel-scope-bar__opt--active {
  background: linear-gradient(135deg,
    rgba(245, 158, 11, 0.85),
    rgba(217, 119, 6, 0.85));
}
body .panel-scope-bar__hint {
  margin-left: auto;
  color: var(--text-secondary, #a1a1aa);
  font-size: 11px;
  font-style: italic;
}

/* ============================================================
   PLAN G — CONTRAST PASS (accessibility)
   ============================================================
   User reported small text + slider tracks are barely visible.
   Two root causes:
     1. Muted text color (#71717a) is too close to surface gray
     2. Slider track gradient was 55-65% opacity over near-black
   Fix: bump every "muted" color up the contrast scale + give
   slider tracks a brighter base + bigger thumb.

   These overrides apply to ALL .v6-* components, not just Compose,
   so the contrast win is global. Theme toggle below lets the user
   dial it back if they prefer.
   ============================================================ */

/* G1. Compose modal — small text and slider visibility. */
body .v6-composer .v6-composer__slider {
  height: 10px !important;
  background:
    linear-gradient(90deg,
      rgba(139, 92, 246, 0.85) 0%,
      rgba(236, 72, 153, 0.95) 100%),
    rgba(255, 255, 255, 0.14) !important;
  border: 1px solid rgba(255, 255, 255, 0.22) !important;
  box-shadow:
    0 2px 6px rgba(0, 0, 0, 0.50) inset,
    0 0 16px rgba(139, 92, 246, 0.25) !important;
}
/* Bigger, more pronounced slider thumb */
body .v6-composer .v6-composer__slider::-webkit-slider-thumb {
  width: 24px !important;
  height: 24px !important;
  background: radial-gradient(circle at 30% 30%, #ffffff 0%, #e5e7eb 70%) !important;
  border: 2px solid #8b5cf6 !important;
  box-shadow:
    0 0 0 5px rgba(139, 92, 246, 0.30),
    0 4px 14px rgba(0, 0, 0, 0.55) !important;
}
body .v6-composer .v6-composer__slider::-moz-range-thumb {
  width: 24px !important;
  height: 24px !important;
  background: radial-gradient(circle at 30% 30%, #ffffff 0%, #e5e7eb 70%) !important;
  border: 2px solid #8b5cf6 !important;
}

/* G2. Tick labels under sliders — readable, not whisper-gray. */
body .v6-composer .v6-composer__slider-tick {
  color: #cbd5e1 !important;   /* was #71717a */
  font-size: 10px !important;  /* was 9 */
  font-weight: 600 !important;
  letter-spacing: 0.06em !important;
}

/* G3. Section header text — strong enough to scan at a glance. */
body .v6-composer .v6-composer__section h3 {
  color: #e4e4e7 !important;   /* was #a1a1aa */
  font-size: 12px !important;  /* was 11 */
  letter-spacing: 0.12em !important;
}

/* G4. Caption pills (Steady, Medium, Standard, 1 pattern · single loop). */
body .v6-composer .v6-composer__caption {
  font-size: 12px !important;
  padding: 4px 12px !important;
  background: linear-gradient(180deg,
    rgba(139, 92, 246, 0.30),
    rgba(139, 92, 246, 0.18)) !important;
  border: 1px solid rgba(139, 92, 246, 0.55) !important;
  color: #ffffff !important;
}

/* G5. Genre group header text — visible. */
body .v6-composer .v6-composer__genre-header {
  color: #cbd5e1 !important;
  font-size: 10px !important;
  font-weight: 700 !important;
  letter-spacing: 0.10em !important;
}

/* G6. Mood card label + hint — bigger labels, readable hints. */
body .v6-composer .v6-composer__opt-label {
  font-size: 14px !important;
  font-weight: 700 !important;
  color: #fafafa !important;
}
body .v6-composer .v6-composer__opt-hint {
  color: #a1a1aa !important;   /* was #71717a */
  font-size: 11px !important;
  line-height: 1.4 !important;
}

/* G7. Scale description — readable, not italic-whisper. */
body .v6-composer .v6-composer__scale-desc {
  color: #cbd5e1 !important;
  font-size: 12px !important;
  font-style: normal !important;
  font-weight: 500 !important;
}

/* G8. Help ? icon — visible at rest, more visible on hover. */
body .v6-composer .v6-composer__section-help {
  background: rgba(255, 255, 255, 0.10) !important;
  border: 1px solid rgba(255, 255, 255, 0.18) !important;
  color: #d4d4d8 !important;
}

/* G9. Dice button — visible at rest. */
body .v6-composer .v6-composer__dice-btn {
  background: rgba(236, 72, 153, 0.20) !important;
  border: 1px solid rgba(236, 72, 153, 0.55) !important;
}

/* G10. Header subtitle — readable. */
body .v6-composer .v6-composer__subtitle {
  color: #cbd5e1 !important;
  font-size: 13px !important;
  font-style: normal !important;
  font-weight: 500 !important;
}

/* G11. Global contrast bump for all v6 muted text. Catches the
   transport scale picker / mute icons / track names / status bar
   / pattern library card metadata. */
body[data-contrast="high"] {
  --text-muted: #cbd5e1;
  --text-secondary: #e4e4e7;
}
body[data-contrast="standard"] {
  --text-muted: #a1a1aa;
  --text-secondary: #d4d4d8;
}
body[data-contrast="dim"] {
  --text-muted: #71717a;
  --text-secondary: #a1a1aa;
}

/* ============================================================
   PLAN H — THEME TOGGLE (Dark / Dim / Light)
   ============================================================
   The user wondered whether a theme toggle would help. Three modes:
     - Dim   = current dark theme, low contrast (energy-friendly)
     - Dark  = current dark theme, HIGH contrast (default after this fix)
     - Light = light background, dark text (sunny rooms, projectors)

   Toggle button in the v6 app bar (sun/moon glyph that cycles) writes
   to `<body data-theme="...">` + `<body data-contrast="...">`. The
   JS lives in src/ui/ThemeToggle.js (added in this pass).
   ============================================================ */

/* H1. Default to high-contrast dark unless a theme is explicitly set. */
body:not([data-theme]) {
  --text-muted: #a1a1aa;
  --text-secondary: #d4d4d8;
}

/* H2. Light theme — full palette swap. */
body[data-theme="light"] {
  /* Surfaces */
  --surface-100: #ffffff;
  --surface-200: #f8fafc;
  --surface-300: #f1f5f9;
  --surface-400: #e2e8f0;
  --surface-500: #cbd5e1;
  --surface-600: #94a3b8;
  --v6-bg: #f8fafc;
  --v6-panel: #ffffff;

  /* Text */
  --text-primary: #0f172a;
  --text-secondary: #334155;
  --text-muted: #64748b;

  /* Borders */
  --v6-border-faint:  rgba(15, 23, 42, 0.08);
  --v6-border:        rgba(15, 23, 42, 0.16);
  --v6-border-strong: rgba(15, 23, 42, 0.24);
  --border-default:   rgba(15, 23, 42, 0.16);
  --border-subtle:    rgba(15, 23, 42, 0.08);

  background: #f8fafc !important;
  color: #0f172a !important;
}
/* Light theme — inverted modal frame for Compose */
body[data-theme="light"] .v6-composer__card {
  background: linear-gradient(180deg, #ffffff 0%, #f8fafc 100%) !important;
  border: 1px solid rgba(15, 23, 42, 0.16) !important;
  box-shadow: 0 32px 80px rgba(15, 23, 42, 0.25) !important;
}
body[data-theme="light"] .v6-composer__head {
  background: linear-gradient(135deg,
    rgba(139, 92, 246, 0.10),
    rgba(236, 72, 153, 0.04)) !important;
  border-bottom: 1px solid rgba(15, 23, 42, 0.08) !important;
}
body[data-theme="light"] .v6-composer__body {
  background: #ffffff !important;
}
body[data-theme="light"] .v6-composer__footer {
  background: #f1f5f9 !important;
  border-top: 1px solid rgba(15, 23, 42, 0.08) !important;
}
body[data-theme="light"] .v6-composer__opt {
  background: linear-gradient(180deg,
    rgba(15, 23, 42, 0.02),
    rgba(15, 23, 42, 0.01)) !important;
  border: 1px solid rgba(15, 23, 42, 0.10) !important;
}
body[data-theme="light"] .v6-composer__opt-label  { color: #0f172a !important; }
body[data-theme="light"] .v6-composer__opt-hint   { color: #475569 !important; }
body[data-theme="light"] .v6-composer__section h3 { color: #1e293b !important; }
body[data-theme="light"] .v6-composer__slider-tick { color: #475569 !important; }
body[data-theme="light"] .v6-composer__scale-desc  { color: #475569 !important; }
body[data-theme="light"] .v6-composer__caption     { color: #ffffff !important; }

/* H2b. Light theme — the Create menu, the per-track AI menu and the toast
   they raise.

   These three surfaces hard-code the dark gradient (`rgba(30,28,38)` →
   `rgba(18,17,24)`) while their text reads `--text-primary` / `--text-secondary`,
   which Light redefines to slate. The result was a dark card with dark text:
   the menu opened and nothing on it could be read. Every other popover in the
   app builds on `--v6-panel` / `--surface-*` and follows the theme by itself;
   these were the only three that did not.

   The overrides invert the frame to a light card (matching .v6-composer__card
   above) and re-tune the pieces whose colours were authored for a dark ground:
   the white icon glyph, the white-alpha chips / kbd / dividers, the light-green
   and amber "Free" / "Sign in" chips, the black footer wash. Hover fills are
   purple alpha and read fine on both, so they are left alone. Dark is untouched:
   nothing here matches without data-theme="light". */
body[data-theme="light"] .v6-ai-menu,
body[data-theme="light"] .v6-track-ai-menu {
  background: linear-gradient(180deg, #ffffff 0%, #f8fafc 100%);
  border-color: rgba(15, 23, 42, 0.16);
  box-shadow:
    0 24px 60px rgba(15, 23, 42, 0.22),
    0 0 0 1px rgba(139, 92, 246, 0.10) inset;
}
body[data-theme="light"] .v6-ai-menu__item-icon {
  color: #6d28d9;
  background: linear-gradient(135deg,
    rgba(139, 92, 246, 0.16),
    rgba(236, 72, 153, 0.16));
}
body[data-theme="light"] .v6-ai-menu__cost {
  background: rgba(15, 23, 42, 0.06);
  border-color: rgba(15, 23, 42, 0.12);
}
body[data-theme="light"] .v6-ai-menu__cost--free {
  color: #15803d;
  background: rgba(34, 197, 94, 0.12);
  border-color: rgba(34, 197, 94, 0.35);
}
body[data-theme="light"] .v6-ai-menu__cost--locked {
  color: #b45309;
  background: rgba(245, 158, 11, 0.14);
  border-color: rgba(245, 158, 11, 0.40);
}
body[data-theme="light"] .v6-ai-menu__disclosure,
body[data-theme="light"] .v6-track-ai-menu__item--alt {
  border-top-color: rgba(15, 23, 42, 0.08);
}
body[data-theme="light"] .v6-ai-menu__footer {
  background: #f1f5f9;
  border-top-color: rgba(15, 23, 42, 0.08);
}
body[data-theme="light"] .v6-ai-menu__footer kbd {
  background: rgba(15, 23, 42, 0.06);
  border-color: rgba(15, 23, 42, 0.14);
}
body[data-theme="light"] .v6-track-ai-menu__header {
  border-bottom-color: rgba(15, 23, 42, 0.08);
}
body[data-theme="light"] .v6-track-ai-menu__badge--vary {
  color: #047857;
}
body[data-theme="light"] .v6-track-ai-menu__progress::before {
  border-color: rgba(15, 23, 42, 0.18);
  border-top-color: var(--accent-primary, #8b5cf6);
}
body[data-theme="light"] .v6-toast {
  background: linear-gradient(135deg, #ffffff, #f8fafc);
  box-shadow: 0 18px 40px rgba(15, 23, 42, 0.22);
}
/* UndoToast.js sets the Undo button's white-alpha border inline, so this is
   the one place !important is needed to make it visible on a light card. */
body[data-theme="light"] .v6-toast__undo {
  border-color: rgba(15, 23, 42, 0.25) !important;
}

/* H3. Theme toggle button in the app bar (rendered by ThemeToggle.js). */
.v6-theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.10);
  color: #cbd5e1;
  cursor: pointer;
  transition: all 120ms;
  margin: 0 6px;
}
.v6-theme-toggle:hover {
  background: rgba(139, 92, 246, 0.18);
  border-color: #8b5cf6;
  color: #fff;
}
body[data-theme="light"] .v6-theme-toggle {
  background: rgba(15, 23, 42, 0.04);
  border-color: rgba(15, 23, 42, 0.14);
  color: #475569;
}
body[data-theme="light"] .v6-theme-toggle:hover {
  background: rgba(139, 92, 246, 0.12);
  color: #1e293b;
}
.v6-theme-toggle__glyph {
  font-size: 14px;
  line-height: 1;
}

@layer v6-polish {

  /* ============================================================
     1. Session group — visible button tiles + proper separation
     ============================================================
     The previous design relied on a single shared pill background and
     hover-only feedback, which made the three buttons (My Songs / Save /
     New) collapse into one unreadable blob — `.btn-ghost` from
     style-v2.css has `background: transparent; border: none`. Give each
     button its OWN visible tile so they read as three distinct controls
     even at rest. */
  .v6-session-group {
    padding: 4px !important;
    gap: 4px !important;
    background: rgba(0, 0, 0, 0.30) !important;
    border: 1px solid rgba(255, 255, 255, 0.10) !important;
  }
  .v6-app-bar .v6-session-group .btn,
  .v6-session-group .btn.btn-ghost,
  .v6-session-group .btn {
    border-radius: 7px !important;
    /* Subtle dark tile — visible at rest, brightens on hover */
    background: rgba(255, 255, 255, 0.05) !important;
    border: 1px solid rgba(255, 255, 255, 0.08) !important;
    height: 28px !important;
    padding: 0 14px !important;
    color: var(--text-secondary, #a1a1aa) !important;
    font-size: 12px !important;
    font-weight: 600 !important;
    letter-spacing: 0.01em !important;
    display: inline-flex !important;
    align-items: center !important;
    gap: 6px !important;
  }
  .v6-session-group .btn .v6-icon,
  .v6-session-group .btn .icon .v6-icon {
    width: 13px !important;
    height: 13px !important;
    flex-shrink: 0;
  }
  .v6-session-group .btn:hover {
    background: rgba(255, 255, 255, 0.12) !important;
    border-color: rgba(255, 255, 255, 0.18) !important;
    color: var(--text-primary, #fafafa) !important;
  }
  /* Save reads as the primary save action — distinct accent on hover */
  .v6-session-group #saveSongBtn:hover {
    background: rgba(34, 197, 94, 0.18) !important;
    border-color: rgba(34, 197, 94, 0.45) !important;
    color: #fff !important;
  }
  /* "+ New" gets a violet accent on hover so it reads as a "create" action */
  .v6-session-group #newSongBtn:hover {
    background: rgba(139, 92, 246, 0.25) !important;
    border-color: var(--accent-primary, #8b5cf6) !important;
    color: #fff !important;
  }
  /* "My Songs" — neutral hover. */
  .v6-session-group #mySongsBtn:hover {
    background: rgba(255, 255, 255, 0.14) !important;
    border-color: rgba(255, 255, 255, 0.20) !important;
  }
  /* Defensive: drop the legacy ::before divider since each button now
     has its own visible border. */
  .v6-session-group .btn + .btn::before {
    content: none !important;
  }

  /* ============================================================
     2. AI strip — uniform heights, spacing
     ============================================================ */
  .v6-ai-strip {
    padding: 6px 14px !important;
    gap: 10px !important;
    min-height: var(--ai-row-h, 40px);
  }
  .v6-ai-strip__group {
    gap: 6px !important;
  }
  .v6-ai-strip__group--generative {
    padding: 4px 6px !important;
  }
  .v6-ai-strip .btn {
    height: 30px !important;
    display: inline-flex !important;
    align-items: center !important;
    gap: 6px !important;
    white-space: nowrap !important;
  }
  .v6-ai-strip .btn-sm {
    height: 26px !important;
    padding: 0 10px !important;
  }
  .v6-ai-strip .btn .btn-text {
    line-height: 1;
  }
  .v6-ai-strip .btn .v6-icon {
    width: 13px !important;
    height: 13px !important;
    flex-shrink: 0;
  }

  /* Compose is the hero — gradient + glow */
  .v6-ai-strip #v6ComposeBtn {
    background: linear-gradient(135deg,
      var(--accent-primary, #8b5cf6) 0%,
      var(--accent-secondary, #ec4899) 100%) !important;
    border: 1px solid var(--accent-secondary, #ec4899) !important;
    color: #fff !important;
    font-weight: 700 !important;
    box-shadow: 0 0 0 1px rgba(236, 72, 153, 0.25) inset,
                0 0 14px rgba(236, 72, 153, 0.25);
  }
  .v6-ai-strip #v6ComposeBtn:hover {
    filter: brightness(1.10);
  }
  /* Quick AI — clear secondary status, NOT truncated */
  .v6-ai-strip #exampleBtn {
    min-width: 88px !important;
    color: var(--text-secondary, #a1a1aa) !important;
  }
  .v6-ai-strip #exampleBtn:hover {
    color: #fff !important;
  }
  /* Refine — distinct violet outline (not solid accent, so Compose pops) */
  .v6-ai-strip #refineBtn {
    background: rgba(139, 92, 246, 0.10) !important;
    border: 1px solid rgba(139, 92, 246, 0.50) !important;
    color: #fff !important;
    font-weight: 600 !important;
    box-shadow: none !important;
  }
  .v6-ai-strip #refineBtn:hover {
    background: rgba(139, 92, 246, 0.20) !important;
    border-color: var(--accent-primary, #8b5cf6) !important;
  }
  /* Randomize — ghost dice */
  .v6-ai-strip #randomizeSongBtn {
    background: rgba(236, 72, 153, 0.08) !important;
    border: 1px solid rgba(236, 72, 153, 0.30) !important;
    color: var(--text-secondary, #a1a1aa) !important;
  }
  .v6-ai-strip #randomizeSongBtn:hover {
    background: rgba(236, 72, 153, 0.18) !important;
    color: #fff !important;
  }

  /* Versions pill — was inheriting .btn-ghost (transparent + no border)
     so "Versions" visually merged with the neighbouring Randomize
     button. Give it the same visible tile treatment as the other
     AI strip buttons. */
  .v6-ai-strip .v6-versions__pill,
  .v6-ai-strip__group .v6-versions__pill {
    background: rgba(255, 255, 255, 0.05) !important;
    border: 1px solid rgba(255, 255, 255, 0.14) !important;
    color: var(--text-secondary, #a1a1aa) !important;
    border-radius: 6px !important;
    padding: 0 12px !important;
    height: 30px !important;
  }
  .v6-ai-strip .v6-versions__pill:hover {
    background: rgba(139, 92, 246, 0.15) !important;
    border-color: var(--accent-primary, #8b5cf6) !important;
    color: #fff !important;
  }

  /* AI Quick-Actions chevron next to Refine — also a ghost button.
     Give it a tiny visible tile so it doesn't visually merge with Refine. */
  .v6-ai-strip .v6-ai-actions__toggle {
    background: rgba(255, 255, 255, 0.04) !important;
    border: 1px solid rgba(255, 255, 255, 0.10) !important;
    border-radius: 6px !important;
  }
  .v6-ai-strip .v6-ai-actions__toggle:hover {
    background: rgba(139, 92, 246, 0.15) !important;
    border-color: var(--accent-primary, #8b5cf6) !important;
  }
  /* Output group — small Export + small ghost Clear */
  .v6-ai-strip #exportWavBtn {
    background: rgba(34, 197, 94, 0.10) !important;
    border: 1px solid rgba(34, 197, 94, 0.50) !important;
    color: #fff !important;
  }
  .v6-ai-strip #exportWavBtn:hover {
    background: rgba(34, 197, 94, 0.25) !important;
  }
  .v6-ai-strip #clearBtn {
    color: var(--text-muted, #71717a) !important;
    border: 1px solid transparent !important;
  }
  .v6-ai-strip #clearBtn:hover {
    color: var(--accent-danger, #ef4444) !important;
    border-color: rgba(239, 68, 68, 0.40) !important;
    background: rgba(239, 68, 68, 0.08) !important;
  }

  /* ============================================================
     3. Sidebar toolbar — anchor it as the sidebar header
     ============================================================ */
  .v6-sidebar-toolbar {
    padding: 8px 12px !important;
    background: var(--surface-200, #111113) !important;
    border-bottom: 1px solid var(--v6-border, rgba(255, 255, 255, 0.10)) !important;
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.30);
    align-items: center;
  }
  /* Tone down the New Pattern button — was an over-prominent accent pill */
  .v6-sidebar-toolbar #sidebarNewPatternBtn {
    background: linear-gradient(135deg,
      rgba(139, 92, 246, 0.85),
      rgba(236, 72, 153, 0.85)) !important;
    border: none !important;
    color: #fff !important;
    height: 26px !important;
    padding: 0 12px !important;
    font-size: 11px !important;
    font-weight: 600 !important;
    border-radius: 999px !important;
    display: inline-flex !important;
    align-items: center !important;
    gap: 5px !important;
    box-shadow: 0 1px 6px rgba(139, 92, 246, 0.30);
  }
  .v6-sidebar-toolbar #sidebarNewPatternBtn:hover {
    filter: brightness(1.10);
  }
  .v6-sidebar-toolbar #sidebarNewPatternBtn .v6-icon {
    width: 11px !important;
    height: 11px !important;
  }
  .v6-sidebar-toolbar #sidebarNewPatternBtn .btn-text {
    line-height: 1;
  }
  /* Collapse button — barely visible chevron */
  .v6-sidebar-toolbar .sidebar-collapse-btn {
    background: transparent !important;
    border: 1px solid var(--v6-border-faint, rgba(255, 255, 255, 0.06)) !important;
    color: var(--text-muted, #71717a) !important;
    border-radius: 6px !important;
  }
  .v6-sidebar-toolbar .sidebar-collapse-btn:hover {
    background: rgba(255, 255, 255, 0.06) !important;
    color: var(--text-primary, #fafafa) !important;
  }

  /* ============================================================
     4. Tap-tempo button — keep label visible at typical widths
     ============================================================ */
  .v6-tempo-tap__label {
    display: inline-block !important;
    margin-left: 2px;
  }
  .v6-tempo-tap {
    height: 24px !important;
  }

  /* ============================================================
     5. SNAP toggle — actually look ON by default
     ============================================================ */
  .v6-scale-snap.v6-scale-snap--on {
    background: linear-gradient(180deg,
      rgba(139, 92, 246, 0.40),
      rgba(139, 92, 246, 0.20)) !important;
    border-color: var(--accent-primary, #8b5cf6) !important;
    color: #fff !important;
  }

  /* ============================================================
     6. Pattern library — fix "Used in this song" pill default state
     ============================================================ */
  .v6-library-chip {
    height: 24px !important;
    padding: 0 10px !important;
  }
  .v6-library-chip .v6-icon {
    width: 11px !important;
    height: 11px !important;
  }

  /* ============================================================
     7. App bar — ensure the logo wordmark is readable even if
     background-clip:text fails (Firefox/older Safari quirks)
     ============================================================ */
  @supports not (background-clip: text) {
    .v6-app-bar__logo-text {
      background: none !important;
      -webkit-text-fill-color: initial !important;
      color: var(--accent-primary, #8b5cf6) !important;
    }
  }

  /* ============================================================
     8. Sidebar Used-in-Song filter row — small breathing room
     ============================================================ */
  .v6-library-filters {
    padding: 6px 10px 4px !important;
    border-bottom: 1px solid var(--v6-border-faint, rgba(255, 255, 255, 0.04));
  }

  /* ============================================================
     9. Section strip actions — separate "+ Section" from "Build Song"
        so they don't visually collide.
     ============================================================ */
  .v6-section-strip__actions {
    gap: 8px !important;
  }
  /* "+ Section" — give it a visible tile so it doesn't disappear next to
     the bright Build Song pill. */
  .v6-section-strip__add {
    background: rgba(255, 255, 255, 0.05) !important;
    border: 1px solid rgba(255, 255, 255, 0.14) !important;
    color: var(--text-secondary, #a1a1aa) !important;
    height: 26px !important;
    padding: 0 12px !important;
    border-radius: 6px !important;
    font-weight: 600 !important;
  }
  .v6-section-strip__add:hover {
    background: rgba(139, 92, 246, 0.15) !important;
    border-color: var(--accent-primary, #8b5cf6) !important;
    color: #fff !important;
  }
  /* "Build from my sections" — the SAME secondary tile as "+ Section".
     This copy lives inside @layer v6-polish, whose !important beats the
     unlayered !important above, so it is the one that actually paints. */
  .v6-section-strip__build {
    background: rgba(255, 255, 255, 0.05) !important;
    border: 1px solid rgba(255, 255, 255, 0.14) !important;
    color: var(--text-secondary, #a1a1aa) !important;
    height: 26px !important;
    padding: 0 14px !important;
    border-radius: 6px !important;
    font-weight: 600 !important;
    box-shadow: none !important;
  }
  .v6-section-strip__build:hover {
    background: rgba(139, 92, 246, 0.15) !important;
    border-color: var(--accent-primary, #8b5cf6) !important;
    color: #fff !important;
  }

  /* ============================================================
     10. Pattern A / edit context banner — small spacing fixes
     ============================================================ */
  .edit-context-banner {
    gap: 10px;
  }
  .edit-context-left {
    gap: 8px !important;
  }
  .edit-context-link-toggle {
    margin-left: 4px;
    width: 22px;
    height: 22px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: 6px;
    cursor: pointer;
    transition: background var(--duration-fast, 120ms), border-color var(--duration-fast, 120ms);
  }
  .edit-context-link-toggle:hover {
    background: rgba(139, 92, 246, 0.15);
    border-color: var(--accent-primary, #8b5cf6);
  }
  .edit-context-name {
    font-weight: 600;
    margin-right: 2px;
  }
  .edit-context-badge {
    margin-left: 4px;
  }

  /* ============================================================
     11. Transport row — subtle dividers between chip groups.
         This was written when row 1 carried THIRTEEN inline controls, where
         wrapping was a mercy. Item 2.2 cut it to eight, and the wrap became
         the bug: at 1280x800 the volume chip dropped to a second line that
         overflowed the 44px bar, with Tempo and Key riding 15px above it.
         nowrap is now the contract the item is verified against
         (scripts/cdp/item22.mjs, check 2.2b).
     ============================================================ */
  .playback-bar .playback-settings {
    gap: 10px !important;
    flex-wrap: nowrap;
  }
  .playback-bar .setting-compact {
    padding: 0 10px;
    border-radius: 6px;
    background: rgba(0, 0, 0, 0.20);
    border: 1px solid rgba(255, 255, 255, 0.04);
    height: 32px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
  }
  /* The tempo cluster has its own framing — don't double-frame it. */
  .playback-bar .v6-tempo-cluster {
    background: transparent !important;
    border: none !important;
    padding: 0 !important;
  }
}

/* ============================================================
   v9.3 — calmer save-status indicator (dot + label)
   ============================================================
   Replaces the alarm-red "Unsaved changes" pill. The dot pulses
   amber while autosave is queued, then settles to steady green.
   No more anxiety prompts — autosave runs every 30s anyway.
   ============================================================ */
body .save-status {
  display: inline-flex !important;
  align-items: center;
  gap: 6px;
  padding: 0 !important;
  background: transparent !important;
  border: 0 !important;
  color: var(--text-secondary, #a1a1aa) !important;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.01em;
}
body .save-status__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #10b981; /* steady green */
  box-shadow: 0 0 6px rgba(16, 185, 129, 0.45);
}
body .save-status--unsaved .save-status__dot {
  background: #f59e0b;
  box-shadow: 0 0 8px rgba(245, 158, 11, 0.55);
  animation: save-status-pulse 1.4s ease-in-out infinite;
}
body .save-status--saving .save-status__dot {
  background: #a78bfa;
  box-shadow: 0 0 8px rgba(167, 139, 250, 0.65);
  animation: save-status-pulse 0.6s ease-in-out infinite;
}
body .save-status--unsaved {
  color: var(--text-primary, #fafafa) !important;
}
@keyframes save-status-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.55; transform: scale(0.85); }
}

/* ============================================================
   v9.7 — EXPORT MODAL — full visual rewrite
   ============================================================
   The export modal had been falling back to no-style after the
   v7.x style.css removal (the progress bar didn't even show
   as a bar — only as text). This rebuilds the entire visual
   layer in the v6 dark-DAW aesthetic, adds a real progress bar,
   adds metadata fields, and adds a Stems toggle.
   ============================================================ */
body .export-modal .modal-content,
body .export-modal .modal-dialog {
  width: min(560px, calc(100vw - 48px)) !important;
  max-width: 560px;
}
body .export-modal-content {
  padding: 16px 20px 12px !important;
  color: var(--text-primary, #fafafa);
}
body .export-modal .export-section {
  margin: 0 0 14px 0;
}
body .export-modal .export-label {
  display: block;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  color: var(--text-secondary, #a1a1aa);
  margin-bottom: 8px;
}

/* Radio group — bigger hit targets, clearer selected state */
body .export-modal .export-radio-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
body .export-modal .radio-option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
  cursor: pointer;
  transition: background .12s, border-color .12s;
  font-size: 13px;
}
body .export-modal .radio-option:hover {
  background: rgba(139, 92, 246, 0.08);
  border-color: rgba(139, 92, 246, 0.30);
}
body .export-modal .radio-option:has(input:checked) {
  background: rgba(139, 92, 246, 0.15);
  border-color: rgba(139, 92, 246, 0.55);
}
body .export-modal .radio-option .option-info {
  margin-left: auto;
  font-family: ui-monospace, monospace;
  font-size: 11px;
  color: var(--text-secondary, #a1a1aa);
}

/* Format cards — keep two side-by-side but slim them down */
body .export-modal .format-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
body .export-modal .format-card {
  display: grid;
  grid-template-columns: 28px 1fr;
  grid-template-rows: auto auto;
  column-gap: 10px;
  row-gap: 4px;
  align-items: center;
  padding: 10px 12px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 10px;
  cursor: pointer;
  transition: background .12s, border-color .12s, transform .12s;
  text-align: left;
  position: relative;
}
body .export-modal .format-card:hover {
  background: rgba(139, 92, 246, 0.08);
  border-color: rgba(139, 92, 246, 0.40);
  transform: translateY(-1px);
}
body .export-modal .format-card.selected {
  background: linear-gradient(135deg,
    rgba(139, 92, 246, 0.20),
    rgba(236, 72, 153, 0.15));
  border-color: rgba(139, 92, 246, 0.65);
  box-shadow: 0 0 0 1px rgba(139, 92, 246, 0.40) inset;
}
body .export-modal .format-card-icon {
  grid-row: 1 / 3;
  font-size: 20px;
  text-align: center;
}
body .export-modal .format-card-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary, #fafafa);
}
body .export-modal .format-card-subtitle {
  font-size: 11px;
  color: var(--text-secondary, #a1a1aa);
}
body .export-modal .format-card-uses {
  grid-column: 1 / 3;
  font-size: 10.5px;
  color: rgba(161, 161, 170, 0.75);
  margin-top: 4px;
}
body .export-modal .format-card-check {
  position: absolute;
  top: 8px;
  right: 8px;
  color: var(--accent-primary, #c4b5fd);
  font-size: 12px;
  font-weight: 700;
  display: none;
}
body .export-modal .format-card.selected .format-card-check { display: inline; }

/* Inputs / selects */
body .export-modal .export-input,
body .export-modal .export-select {
  width: 100%;
  background: rgba(255, 255, 255, 0.04);
  color: var(--text-primary, #fafafa);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 13px;
  font-family: inherit;
  transition: border-color .15s, background-color .15s;
}
body .export-modal .export-input:focus,
body .export-modal .export-select:focus {
  outline: none;
  border-color: var(--accent-primary, #8b5cf6);
  background: rgba(255, 255, 255, 0.06);
  box-shadow: 0 0 0 2px rgba(139, 92, 246, 0.20);
}

/* Metadata grid (filename + artist) */
body .export-modal .export-meta-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
body .export-modal .export-field-label {
  display: block;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--text-secondary, #a1a1aa);
  margin-bottom: 4px;
}

/* Checkbox + helper text */
body .export-modal .export-checkbox-label {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  font-size: 13px;
  color: var(--text-primary, #fafafa);
}
body .export-modal .export-checkbox {
  appearance: none;
  -webkit-appearance: none;
  width: 32px;
  height: 18px;
  background: rgba(255, 255, 255, 0.10);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 999px;
  position: relative;
  cursor: pointer;
  transition: background .18s, border-color .18s;
  flex-shrink: 0;
}
body .export-modal .export-checkbox::after {
  content: '';
  position: absolute;
  left: 1.5px;
  top: 1.5px;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: #fafafa;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.30);
  transition: transform .18s;
}
body .export-modal .export-checkbox:checked {
  background: linear-gradient(135deg, #8b5cf6, #ec4899);
  border-color: rgba(255, 255, 255, 0.10);
}
body .export-modal .export-checkbox:checked::after {
  transform: translateX(14px);
}
body .export-modal .export-stems-hint {
  margin-left: auto;
  font-size: 11px;
  color: var(--text-secondary, #a1a1aa);
  font-style: italic;
}

/* Loudness sub-options (Quiet / Balanced / Loud) */
body .export-modal .loudness-options {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  margin-top: 8px;
}
body .export-modal .loudness-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 6px 10px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 7px;
  color: var(--text-secondary, #a1a1aa);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: background .12s, border-color .12s, color .12s;
}
body .export-modal .loudness-btn:hover {
  background: rgba(139, 92, 246, 0.10);
  color: var(--text-primary, #fafafa);
}
body .export-modal .loudness-btn.selected {
  background: linear-gradient(135deg,
    rgba(139, 92, 246, 0.35),
    rgba(236, 72, 153, 0.30));
  border-color: rgba(139, 92, 246, 0.65);
  color: var(--text-primary, #fafafa);
}
body .export-modal .loudness-badge {
  color: gold;
  font-size: 10px;
}
body .export-modal .export-help-text {
  margin-top: 6px;
  font-size: 11px;
  color: rgba(161, 161, 170, 0.75);
}

/* Summary strip (size + duration + format-spec) */
body .export-modal .export-summary {
  margin: 6px 0 4px;
  padding: 10px 12px;
  background: rgba(0, 0, 0, 0.25);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 8px;
}
body .export-modal .export-summary-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
body .export-modal .export-summary-pill {
  display: inline-flex;
  align-items: center;
  font-family: ui-monospace, monospace;
  font-size: 11px;
  font-weight: 600;
  padding: 3px 8px;
  background: rgba(139, 92, 246, 0.15);
  color: var(--accent-primary, #c4b5fd);
  border: 1px solid rgba(139, 92, 246, 0.30);
  border-radius: 6px;
}
body .export-modal .export-summary-pill--time {
  background: rgba(236, 72, 153, 0.12);
  color: #f9a8d4;
  border-color: rgba(236, 72, 153, 0.30);
}
body .export-modal .export-summary-pill--spec {
  background: rgba(255, 255, 255, 0.05);
  color: var(--text-secondary, #a1a1aa);
  border-color: rgba(255, 255, 255, 0.10);
  margin-left: auto;
}

/* ============================================================
   THE PROGRESS BAR (the missing piece from the screenshot)
   ============================================================ */
body .export-modal .export-progress {
  margin-top: 12px;
  padding: 12px 14px;
  background: linear-gradient(180deg,
    rgba(139, 92, 246, 0.10),
    rgba(139, 92, 246, 0.03));
  border: 1px solid rgba(139, 92, 246, 0.30);
  border-radius: 9px;
}
body .export-modal .export-progress-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}
body .export-modal .export-progress-label {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-primary, #fafafa);
}
body .export-modal .export-progress-status {
  font-family: ui-monospace, monospace;
  font-size: 12px;
  font-weight: 700;
  color: var(--accent-primary, #c4b5fd);
}
body .export-modal .export-progress-bar {
  width: 100%;
  height: 8px;
  background: rgba(0, 0, 0, 0.40);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 999px;
  overflow: hidden;
  position: relative;
}
body .export-modal .export-progress-fill {
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, #8b5cf6 0%, #ec4899 100%);
  border-radius: 999px;
  transition: width 200ms ease;
  box-shadow: 0 0 8px rgba(139, 92, 246, 0.50);
  position: relative;
}
body .export-modal .export-progress-fill::after {
  /* Animated shimmer overlay so the bar feels alive even at constant % */
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,
    transparent,
    rgba(255, 255, 255, 0.18) 50%,
    transparent);
  animation: export-shimmer 1.4s linear infinite;
}
@keyframes export-shimmer {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

/* Advanced options expand */
body .export-modal .export-advanced {
  margin: 6px 0 12px;
  padding: 8px 12px;
  background: rgba(0, 0, 0, 0.20);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 7px;
}
body .export-modal .export-advanced-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--text-secondary, #a1a1aa);
  text-transform: uppercase;
  list-style: none;
}
body .export-modal .export-advanced-toggle::-webkit-details-marker { display: none; }
body .export-modal .export-advanced-content {
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
body .export-modal .export-advanced .export-section { margin: 0; }

/* Footer buttons (the bottom row) */
body .export-modal .modal-footer {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  padding: 12px 20px !important;
  border-top: 1px solid rgba(255, 255, 255, 0.08) !important;
  background: rgba(0, 0, 0, 0.30) !important;
}
body .export-modal .modal-footer button {
  padding: 9px 18px;
  font-size: 13px;
  font-weight: 600;
  border-radius: 8px;
  cursor: pointer;
  border: 1px solid rgba(255, 255, 255, 0.10);
  transition: filter .12s, transform .12s;
}
body .export-modal .modal-footer button.btn-secondary {
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-secondary, #a1a1aa);
}
body .export-modal .modal-footer button.btn-secondary:hover {
  background: rgba(255, 255, 255, 0.10);
  color: var(--text-primary, #fafafa);
}
body .export-modal .modal-footer button.btn-primary {
  background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
  color: #fff;
  border-color: rgba(255, 255, 255, 0.18);
  box-shadow: 0 8px 22px -6px rgba(139, 92, 246, 0.55);
}
body .export-modal .modal-footer button.btn-primary:hover {
  filter: brightness(1.10);
  transform: translateY(-1px);
}
body .export-modal .modal-footer button:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  filter: grayscale(0.40);
}

/* ============================================================
   v8 — Export modal redesign (.xp-* design system)
   Single source of truth for format, an "Included" transparency
   panel, segmented selectors, and a cohesive dark-DAW aesthetic.
   Supersedes the older .format-card / .radio-option / .loudness-*
   styling above (those classes are no longer emitted).
   ============================================================ */
body .export-modal .modal-dialog,
body .export-modal .modal-content {
  width: min(600px, calc(100vw - 40px)) !important;
  max-width: 600px;
}
body .export-modal .modal-dialog { display: flex; flex-direction: column; max-height: calc(100dvh - 32px) !important; }
body .export-modal .modal-body { min-height: 0; max-height: none; overflow-y: auto; padding: 0; }
body .export-modal .modal-header,
body .export-modal .modal-footer { flex-shrink: 0; }
/* Author display:flex previously overrode the browser's native [hidden] rule. */
body .export-modal [hidden] { display: none !important; }
body .export-modal-content.xp {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 18px 22px 14px !important;
}
body .export-modal .v6-icon { width: 16px; height: 16px; flex: none; }

/* Groups + labels */
body .export-modal .xp-group { display: flex; flex-direction: column; gap: 9px; }
body .export-modal .xp-group.is-disabled { opacity: 0.45; }
body .export-modal .xp-group-label {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--text-secondary, #a1a1aa);
}
body .export-modal .xp-hint {
  font-weight: 500; text-transform: none; letter-spacing: 0;
  font-size: 11px; color: rgba(161, 161, 170, 0.6);
}

/* ── Source tiles ── */
body .export-modal .xp-source { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
body .export-modal .xp-source-tile {
  display: flex; align-items: center; gap: 11px;
  padding: 13px 14px; text-align: left; cursor: pointer;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 12px;
  color: var(--text-primary, #fafafa);
  transition: background .14s, border-color .14s, transform .14s;
}
body .export-modal .xp-source-tile:hover {
  background: rgba(139, 92, 246, 0.08); border-color: rgba(139, 92, 246, 0.35); transform: translateY(-1px);
}
body .export-modal .xp-source-tile .v6-icon { width: 20px; height: 20px; color: var(--text-secondary, #a1a1aa); }
body .export-modal .xp-source-tile.is-active {
  background: linear-gradient(135deg, rgba(139, 92, 246, 0.22), rgba(236, 72, 153, 0.16));
  border-color: rgba(139, 92, 246, 0.70);
  box-shadow: 0 0 0 1px rgba(139, 92, 246, 0.45) inset, 0 8px 24px -12px rgba(139, 92, 246, 0.6);
}
body .export-modal .xp-source-tile.is-active .v6-icon { color: #c4b5fd; }
body .export-modal .xp-source-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
body .export-modal .xp-source-title { font-size: 13.5px; font-weight: 650; }
body .export-modal .xp-source-sub {
  font-size: 11px; color: var(--text-secondary, #a1a1aa);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
body .export-modal .xp-source-dur {
  font-family: ui-monospace, monospace; font-size: 11px; color: var(--text-secondary, #a1a1aa); flex: none;
}

/* ── Included panel ── */
body .export-modal .xp-included {
  background: rgba(0, 0, 0, 0.28);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 10px;
  padding: 6px;
  display: flex; flex-direction: column; gap: 1px;
  max-height: 190px; overflow-y: auto;
}
body .export-modal .xp-inc-row {
  display: flex; align-items: center; gap: 9px;
  padding: 6px 8px; border-radius: 6px; font-size: 12.5px;
}
body .export-modal .xp-inc-row:hover { background: rgba(255, 255, 255, 0.03); }
body .export-modal .xp-inc-row .v6-icon { width: 15px; height: 15px; color: var(--text-secondary, #a1a1aa); }
body .export-modal .xp-inc-name {
  flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  color: var(--text-primary, #fafafa);
}
body .export-modal .xp-inc-row.is-muted { opacity: 0.4; }
body .export-modal .xp-inc-row.is-muted .xp-inc-name { text-decoration: line-through; }
body .export-modal .xp-chip {
  font-size: 9.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em;
  padding: 2px 6px; border-radius: 4px;
  background: rgba(139, 92, 246, 0.16); color: #c4b5fd; border: 1px solid rgba(139, 92, 246, 0.28);
}
body .export-modal .xp-chip--audio { background: rgba(6, 182, 212, 0.14); color: #67e8f9; border-color: rgba(6, 182, 212, 0.30); }
body .export-modal .xp-inc-tag {
  font-size: 9.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em;
  padding: 2px 6px; border-radius: 4px; color: var(--text-secondary, #a1a1aa);
  background: rgba(255, 255, 255, 0.06);
}
body .export-modal .xp-inc-tag--solo { color: #fcd34d; background: rgba(251, 191, 36, 0.14); }
body .export-modal .xp-inc-master {
  display: flex; align-items: center; gap: 9px;
  margin-top: 4px; padding: 7px 8px; border-top: 1px dashed rgba(255, 255, 255, 0.08);
  font-size: 11px; color: var(--text-secondary, #a1a1aa);
}
body .export-modal .xp-inc-master .v6-icon { width: 14px; height: 14px; }
body .export-modal .xp-inc-master strong { color: #fcd34d; font-weight: 700; }
body .export-modal .xp-inc-empty {
  padding: 14px; text-align: center; color: var(--text-secondary, #a1a1aa); font-size: 12px; font-style: italic;
}

/* ── Segmented controls ── */
body .export-modal .xp-seg {
  display: flex; gap: 4px; padding: 4px;
  background: rgba(0, 0, 0, 0.30); border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 10px;
}
body .export-modal .xp-seg-btn {
  flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 8px 10px; border: 0; border-radius: 7px; cursor: pointer;
  background: transparent; color: var(--text-secondary, #a1a1aa);
  font-size: 12.5px; font-weight: 600; white-space: nowrap;
  transition: background .12s, color .12s;
}
body .export-modal .xp-seg-btn em { font-style: normal; font-weight: 500; font-size: 10px; opacity: 0.7; }
body .export-modal .xp-seg-btn .v6-icon { width: 15px; height: 15px; }
body .export-modal .xp-seg-btn:hover:not(.is-active):not(:disabled) { background: rgba(255, 255, 255, 0.05); color: var(--text-primary, #fafafa); }
body .export-modal .xp-seg-btn.is-active {
  background: linear-gradient(135deg, #8b5cf6, #a855f7); color: #fff;
  box-shadow: 0 2px 10px -3px rgba(139, 92, 246, 0.7);
}
body .export-modal .xp-seg-btn.is-active .v6-icon { color: #fff; }
body .export-modal .xp-seg-btn:disabled { opacity: 0.5; cursor: not-allowed; }
body .export-modal .xp-seg--container .xp-seg-btn { padding: 11px; font-size: 13px; }
body .export-modal .xp-seg--container .xp-seg-main { font-weight: 700; }
body .export-modal .xp-sub { margin-top: 8px; display: flex; flex-direction: column; gap: 10px; }
body .export-modal .xp-option-label { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; font-size: 11px; color: var(--text-secondary, #a1a1aa); }
body .export-modal .xp-sub.is-disabled .xp-seg { opacity: .55; }
body .export-modal .xp-sub.is-disabled .xp-seg-btn.is-active,
body .export-modal .xp-group.is-disabled .xp-seg-btn.is-active {
  background: rgba(255, 255, 255, .08); box-shadow: none; color: var(--text-secondary, #a1a1aa);
}
body .export-modal .xp-note { margin: 0; font-size: 11px; line-height: 1.5; color: var(--text-secondary, #a1a1aa); }
body .export-modal .xp-source-tile:disabled,
body .export-modal .xp-input:disabled { opacity: .55; cursor: not-allowed; }
body .export-modal .xp-toggle:has(input:disabled) { opacity: .55; cursor: not-allowed; }
body .export-modal .xp-toggle input:focus-visible + .xp-toggle-track { outline: 2px solid var(--accent-primary, #8b5cf6); outline-offset: 3px; }
body .export-modal .xp-seg-btn:focus-visible,
body .export-modal .xp-source-tile:focus-visible { outline: 2px solid var(--accent-primary, #8b5cf6); outline-offset: 2px; }

/* sample-rate row */
body .export-modal .xp-row { display: flex; align-items: center; gap: 12px; }
body .export-modal .xp-row-label { font-size: 12px; color: var(--text-secondary, #a1a1aa); }
body .export-modal .xp-row .xp-seg { flex: 1; max-width: 300px; margin-left: auto; }

/* ── DAW toggle (switch) ── */
body .export-modal .xp-toggle { display: flex; align-items: center; gap: 10px; cursor: pointer; padding: 2px; }
body .export-modal .xp-toggle input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
body .export-modal .xp-toggle-track {
  position: relative; width: 38px; height: 21px; border-radius: 999px; flex: none;
  background: rgba(255, 255, 255, 0.14); transition: background .15s;
}
body .export-modal .xp-toggle-thumb {
  position: absolute; top: 2px; left: 2px; width: 17px; height: 17px; border-radius: 50%;
  background: #fff; transition: transform .15s; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}
body .export-modal .xp-toggle input:checked + .xp-toggle-track { background: linear-gradient(135deg, #8b5cf6, #ec4899); }
body .export-modal .xp-toggle input:checked + .xp-toggle-track .xp-toggle-thumb { transform: translateX(17px); }
body .export-modal .xp-toggle-text { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--text-primary, #fafafa); }
body .export-modal .xp-toggle-text em { font-style: normal; font-size: 10.5px; color: var(--text-secondary, #a1a1aa); }
body .export-modal .xp-toggle-text .v6-icon { width: 15px; height: 15px; color: var(--text-secondary, #a1a1aa); }

/* ── Fields ── */
body .export-modal .xp-field { display: flex; flex-direction: column; gap: 5px; }
body .export-modal .xp-fields-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 10px; }
body .export-modal .xp-field-label { font-size: 11px; color: var(--text-secondary, #a1a1aa); display: flex; gap: 6px; align-items: baseline; }
body .export-modal .xp-field-label em { font-style: normal; font-size: 9px; text-transform: uppercase; letter-spacing: 0.05em; opacity: 0.55; }
body .export-modal .xp-input {
  width: 100%; padding: 9px 11px; font-size: 13px;
  background: rgba(255, 255, 255, 0.04); border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 8px; color: var(--text-primary, #fafafa); transition: border-color .12s, background .12s;
}
body .export-modal .xp-input:focus { outline: none; border-color: rgba(139, 92, 246, 0.6); background: rgba(139, 92, 246, 0.06); }
body .export-modal .xp-input::placeholder { color: rgba(161, 161, 170, 0.5); }

/* ── Summary bar ── */
body .export-modal .xp-summary {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 14px; border-radius: 10px;
  background: linear-gradient(135deg, rgba(139, 92, 246, 0.12), rgba(236, 72, 153, 0.08));
  border: 1px solid rgba(139, 92, 246, 0.25);
}
body .export-modal .xp-summary-spec { font-family: ui-monospace, monospace; font-size: 12.5px; font-weight: 600; color: #e9d5ff; letter-spacing: 0.02em; }
body .export-modal .xp-summary-meta { font-family: ui-monospace, monospace; font-size: 12px; color: var(--text-secondary, #a1a1aa); white-space: nowrap; }
body .export-modal .xp-summary-meta .xp-dot { opacity: 0.5; margin: 0 2px; }

/* ── Progress ── */
body .export-modal .xp-progress { display: flex; flex-direction: column; gap: 6px; }
body .export-modal .xp-progress-head { display: flex; justify-content: space-between; font-size: 11.5px; color: var(--text-secondary, #a1a1aa); }
body .export-modal .xp-progress-bar { height: 6px; border-radius: 999px; background: rgba(255, 255, 255, 0.08); overflow: hidden; }
body .export-modal .xp-progress-fill { height: 100%; width: 0; border-radius: 999px; background: linear-gradient(90deg, #8b5cf6, #ec4899); transition: width .3s ease; }
body .export-modal .xp-progress-head { gap: 12px; font-weight: 600; color: var(--text-primary, #fafafa); }
body .export-modal .xp-progress-detail,
body .export-modal .xp-progress-timing { font-size: 11px; line-height: 1.5; color: var(--text-secondary, #a1a1aa); }
body .export-modal .xp-progress-timing { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 4px 12px; font-variant-numeric: tabular-nums; }
body .export-modal .xp-progress-bar.is-indeterminate .xp-progress-fill { width: 35% !important; animation: xpProgressWorking 1.5s ease-in-out infinite alternate; }
@keyframes xpProgressWorking { from { transform: translateX(0); } to { transform: translateX(185%); } }
body .export-modal .xp-error { margin: 0; padding: 10px 12px; border: 1px solid rgba(239, 68, 68, .3); border-radius: 8px; background: rgba(239, 68, 68, .08); color: #fca5a5; font-size: 12px; line-height: 1.5; }

/* Footer button icon alignment */
body .export-modal .modal-footer { flex-direction: column; align-items: stretch; gap: 14px; }
body .export-modal .xp-footer-actions { display: flex; justify-content: flex-end; gap: 8px; }
body .export-modal .modal-footer button { display: inline-flex; align-items: center; gap: 7px; }
body .export-modal .modal-footer .v6-icon { width: 16px; height: 16px; }
@media (max-width: 520px) {
  body .modal-overlay.export-modal { padding: 10px !important; }
  body .export-modal .modal-dialog { width: calc(100vw - 20px) !important; max-width: calc(100vw - 20px) !important; max-height: calc(100dvh - 20px) !important; }
  body .export-modal .export-modal-content.xp { padding: 16px !important; }
  body .export-modal .xp-group-label { flex-wrap: wrap; }
  body .export-modal .xp-source { gap: 6px; }
  body .export-modal .xp-source-tile { flex-wrap: wrap; padding: 10px; }
  body .export-modal .xp-source-dur { margin-left: auto; }
  body .export-modal .xp-summary { flex-wrap: wrap; }
  body .export-modal .xp-toggle-text { flex-wrap: wrap; }
  body .export-modal .xp-seg-btn { min-width: 0; padding-inline: 6px; }
  body .export-modal #xpLoudness .xp-seg-btn { flex-direction: column; gap: 2px; }
  body .export-modal .xp-row { flex-wrap: wrap; }
}
@media (prefers-reduced-motion: reduce) {
  body .export-modal .xp-progress-bar.is-indeterminate .xp-progress-fill { animation: none; width: 100% !important; opacity: .55; }
  body .export-modal .xp-progress-fill { transition: none; }
}

/* ============================================================
   v8.1 — Export modal "stunning" elevation
   Backdrop, dialog material/depth, header + ghost close button,
   entrance motion, accent details, refined scrollbars.
   ============================================================ */

/* Backdrop: deep blur + a soft purple glow falling from the top */
body .modal-overlay.export-modal {
  background:
    radial-gradient(120% 60% at 50% -10%, rgba(139, 92, 246, 0.16), transparent 60%),
    rgba(6, 7, 10, 0.62) !important;
  backdrop-filter: blur(14px) saturate(130%);
  -webkit-backdrop-filter: blur(14px) saturate(130%);
}

/* Dialog: layered near-black surface, hairline + inner top highlight,
   big soft shadow, generous radius, clipped gradient accent edge. */
body .export-modal .modal-dialog {
  position: relative;
  background: linear-gradient(180deg, #17171d 0%, #0f0f13 100%) !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  border-radius: 18px !important;
  overflow: hidden;
  box-shadow:
    0 28px 80px -20px rgba(0, 0, 0, 0.85),
    0 0 0 1px rgba(255, 255, 255, 0.02),
    inset 0 1px 0 rgba(255, 255, 255, 0.07) !important;
  animation: xpModalIn 0.30s cubic-bezier(0.2, 0.8, 0.2, 1);
}
/* Gradient accent edge across the very top */
body .export-modal .modal-dialog::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, #8b5cf6, #ec4899);
  z-index: 2;
}
@keyframes xpModalIn {
  from { opacity: 0; transform: translateY(14px) scale(0.985); }
  to   { opacity: 1; transform: none; }
}

/* Header: left-aligned title, hairline divider, ghost close button */
body .export-modal .modal-header {
  display: flex !important; align-items: center; justify-content: space-between;
  padding: 15px 20px !important;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06) !important;
  background: linear-gradient(180deg, rgba(139, 92, 246, 0.07), transparent) !important;
}
body .export-modal .modal-title {
  margin: 0 !important; text-align: left !important;
  font-size: 15px !important; font-weight: 700 !important; letter-spacing: 0.01em;
  color: var(--text-primary, #fafafa) !important;
}
body .export-modal .modal-close-btn {
  width: 30px; height: 30px; padding: 0 !important; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 9px;
  border: 1px solid transparent !important;
  background: rgba(255, 255, 255, 0.05) !important;
  color: var(--text-secondary, #a1a1aa) !important;
  font-size: 18px !important; line-height: 1 !important; cursor: pointer;
  box-shadow: none !important;
  transition: background 0.12s, color 0.12s, transform 0.12s;
}
body .export-modal .modal-close-btn:hover {
  background: rgba(255, 255, 255, 0.11) !important;
  color: var(--text-primary, #fafafa) !important;
  transform: rotate(90deg);
}

/* Leading accent tick on every group label */
body .export-modal .xp-group-label::before {
  content: '';
  width: 3px; height: 11px; border-radius: 2px; flex: none;
  background: linear-gradient(180deg, #8b5cf6, #ec4899);
}

/* Slightly more breathing room */
body .export-modal-content.xp { gap: 20px; padding: 20px 22px 16px !important; }

/* Make the summary bar read like a crisp receipt */
body .export-modal .xp-summary { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05); }

/* Refined thin scrollbars inside the modal */
body .export-modal .modal-body::-webkit-scrollbar,
body .export-modal .xp-included::-webkit-scrollbar { width: 10px; }
body .export-modal .modal-body::-webkit-scrollbar-thumb,
body .export-modal .xp-included::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.12);
  border: 3px solid transparent; background-clip: padding-box; border-radius: 8px;
}
body .export-modal .modal-body::-webkit-scrollbar-thumb:hover,
body .export-modal .xp-included::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.20); background-clip: padding-box; }
body .export-modal .modal-body::-webkit-scrollbar-track,
body .export-modal .xp-included::-webkit-scrollbar-track { background: transparent; }

/* ============================================================
   EMERGENCY LAYOUT BYPASS (2026-05-28, v2 — LAYERED)
   ─────────────────────────────────────────────────────────────
   v1 (unlayered) failed: shell.css / app-bar.css declare their
   `body { display: grid !important }` inside `@layer v6-shell`, and
   for !important the cascade is REVERSED — !important INSIDE a layer
   beats !important OUTSIDE a layer. So every unlayered override I
   wrote silently lost. Wrapping the same overrides in @layer v6-shell
   puts them in the SAME layer, and since polish.css loads after
   shell/app-bar, source order means MY rules win.
   ============================================================ */
@layer v6-shell {
  body.v6-app-bar-active,
  body:has(> .v6-app-bar) {
    display: block !important;
    min-height: 100vh !important;
    padding-top: var(--v6-app-bar-h, 56px) !important;
    padding-bottom: var(--statusbar-h, 26px) !important;
    box-sizing: border-box !important;
    grid-template-rows: unset !important;
    grid-template-columns: unset !important;
  }
  body.v6-app-bar-active > header.v6-app-bar,
  body:has(> .v6-app-bar) > header.v6-app-bar {
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    height: var(--v6-app-bar-h, 56px) !important;
    z-index: 200 !important;
  }
  body.v6-app-bar-active > .v6-statusbar,
  body:has(> .v6-app-bar) > .v6-statusbar {
    position: fixed !important;
    bottom: 0 !important;
    left: 0 !important;
    right: 0 !important;
    height: var(--statusbar-h, 26px) !important;
    z-index: 200 !important;
  }
  body.v6-app-bar-active > .daw-layout,
  body:has(> .v6-app-bar) > .daw-layout {
    min-height: calc(100vh - var(--v6-app-bar-h, 56px) - var(--statusbar-h, 26px)) !important;
    height: auto !important;
    position: relative !important;
  }
}

/* Solo button (v12) — injected next to each track's Mute. Note tracks only ever
   had mute, so isolating one part meant muting every other track by hand. */
.solo-btn {
  font-weight: 700;
  font-size: 0.72rem;
  line-height: 1;
  color: var(--text-secondary, #a1a1aa);
}
.solo-btn.is-active {
  color: #18181b;
  background: var(--accent-warning, #f59e0b);
}

/* Play button transport state (v13.1 — the transport tells the truth).
   UIManager.updatePlayButton used to set an inline colour that lost to
   style-v2's `#playBtn { background !important }`, so the button was green
   whether the song was playing, paused or stopped. Colour roles per the visual
   spec: green = playing, amber = paused; stopped keeps the .btn-primary accent.
   Deliberately UNLAYERED: style-v2's .btn-primary rules are unlayered too, and
   an id+class selector outranks them without reaching for !important. */
#playBtn.is-playing {
  background: var(--accent-success, #22c55e);
  border-color: var(--accent-success, #22c55e);
  color: #18181b;
}
#playBtn.is-paused {
  background: var(--accent-warning, #f59e0b);
  border-color: var(--accent-warning, #f59e0b);
  color: #18181b;
}

/* Exact-pitch notes that cannot fit the eight scale rows. Separate preview
   lanes keep the step editor's row-addressed paint/erase gestures intact. */
.grid-event-lanes { padding: 0 var(--space-1, 4px) var(--space-2, 8px); min-width: 0; }
.track.collapsed .grid-event-lanes { display: none; }
.grid-event-header { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 3px 0 5px; }
.grid-event-title { color: var(--text-secondary, #a1a1aa); font-size: 10px; }
.grid-event-open { color: var(--text-primary, #fafafa); background: var(--surface-400, #27272a); border: 1px solid var(--border-default); border-radius: 4px; padding: 3px 7px; font-size: 10px; cursor: pointer; }
.grid-event-open:hover, .grid-event-open:focus-visible { border-color: var(--accent-primary, #8b5cf6); outline: 2px solid var(--accent-primary, #8b5cf6); outline-offset: 1px; }
.grid-event-body { max-height: 200px; overflow-y: auto; overflow-x: hidden; }
.grid-event-row { display: flex; align-items: stretch; gap: var(--space-1, 4px); min-width: 0; margin-bottom: 2px; }
.grid-event-pitch { flex: 0 0 36px; box-sizing: border-box; text-align: right; padding-right: var(--space-1, 4px); font: 10px/18px var(--font-mono, monospace); color: var(--text-secondary, #a1a1aa); }
.grid-event-lane { flex: 1; min-width: 0; height: 18px; position: relative; overflow: hidden; border-radius: 3px; background-color: var(--surface-300, #18181b); background-image: linear-gradient(to right, var(--border-default, #333) 1px, transparent 1px); background-size: 6.25% 100%; }
.grid-event-note { position: absolute; top: 2px; height: 14px; min-width: 2px; box-sizing: border-box; background: var(--track-color, var(--accent-primary, #8b5cf6)); border: 1px solid rgba(255,255,255,.35); border-radius: 3px; opacity: calc(.55 + .3 * var(--event-velocity, 1)); }
.grid-event-note:hover { opacity: 1; filter: brightness(1.2); }
.grid-event-playhead { display: none; position: absolute; top: 0; bottom: 0; width: 2px; left: var(--event-playhead, 0%); background: var(--accent-warning, #f59e0b); pointer-events: none; }
.grid-event-lanes.is-playing .grid-event-playhead { display: block; }
.tracks-container.condensed .grid-event-lanes { padding-left: var(--space-1, 4px); padding-right: var(--space-1, 4px); }
.tracks-container.condensed .grid-event-pitch { flex-basis: 28px; }
