/* MTAedit — style cloned from /opt/Recode/static/index.html */

:root, [data-theme="dark"] {
    --bg-primary: #0d1117;
    --bg-secondary: #161b22;
    --bg-tertiary: #1c2129;
    --bg-card: #1c2333;
    --bg-hover: #22272e;
    --bg-input: #0d1117;
    --border: #30363d;
    --border-light: #3d444d;
    --text-primary: #e6edf3;
    --text-secondary: #8b949e;
    --text-muted: #6e7681;
    --accent: #58a6ff;
    --accent-dim: #1f6feb;
    --success: #3fb950;
    --success-dim: #238636;
    --warning: #d29922;
    --warning-dim: #9e6a03;
    --error: #f85149;
    --error-dim: #da3633;
    --purple: #bc8cff;
    --cyan: #39d2e0;
    --orange: #f0883e;
    --radius: 8px;
    --radius-lg: 12px;
    --transition: 0.2s ease;
    --font: 'Segoe UI', -apple-system, BlinkMacSystemFont, sans-serif;
    --font-mono: 'Cascadia Code', 'Fira Code', 'JetBrains Mono', monospace;
}

[data-theme="light"] {
    --bg-primary: #f0f2f5;
    --bg-secondary: #f6f8fa;
    --bg-tertiary: #eef1f5;
    --bg-card: #ffffff;
    --bg-hover: #f0f3f6;
    --bg-input: #ffffff;
    --border: #d0d7de;
    --border-light: #bbc0c7;
    --text-primary: #1f2328;
    --text-secondary: #656d76;
    --text-muted: #8b949e;
    --accent: #0969da;
    --accent-dim: #0550ae;
    --success: #1a7f37;
    --warning: #9a6700;
    --error: #cf222e;
    --purple: #8250df;
    --cyan: #1b7c83;
    --orange: #bc4c00;
}

/* Theme-driven font scaling — applied via data-font-size on <html>.
 * Bare `:root` sets the default so the page paints at 14px even
 * before applySettings runs and sets data-font-size. */
:root                          { font-size: 14px; }
:root[data-font-size="small"]  { font-size: 13px; }
:root[data-font-size="medium"] { font-size: 14px; }
:root[data-font-size="large"]  { font-size: 16px; }

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    height: 100%;
}

body {
    font-family: var(--font);
    /* font-size driven by :root[data-font-size] so the theme setting
       can scale the entire UI proportionally. */
    font-size: 1rem;
    line-height: 1.5;
    background: var(--bg-primary);
    color: var(--text-primary);
    -webkit-font-smoothing: antialiased;
}

/* Hide all scrollbars globally — elements still scroll via wheel /
 * keyboard / touch, the visual bar just doesn't render. Per user
 * request. */
* { scrollbar-width: none; -ms-overflow-style: none; }
*::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* App shell — height reserves room for the fixed footer at the bottom
   (the editor's flex children compute against this height, so without
   the carve-out the timeline + sidebar would slide under the footer).
   Footer renders ~38px tall on desktop, ~64px when the trademark line
   wraps below 900px. */
.app {
    display: flex;
    flex-direction: column;
    height: calc(100vh - 38px);
}
@media (max-width: 900px) {
    .app { height: calc(100vh - 64px); }
}

/* Header */
header#header {
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--border);
    padding: 12px 24px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: sticky;
    top: 0;
    z-index: 100;
    gap: 24px;
}

.logo {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 20px;
    font-weight: 600;
    letter-spacing: 0.2px;
}
.brand-mark {
    flex-shrink: 0;
    filter: drop-shadow(0 2px 6px rgba(76, 139, 245, 0.35));
}
.brand-text {
    background: linear-gradient(135deg, var(--accent), var(--purple));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    color: transparent;
}
/* "MTA Studio Editor" / "Library" / "Device" — the suite name comes in
 * the gradient, and the per-app suffix sits immediately after in a
 * softer weight so the wordmark reads as one thing. */
.brand-app {
    font-weight: 400;
    opacity: 0.85;
    /* Parent .brand-text uses -webkit-background-clip: text + transparent
       fill. In Chromium/WebKit that clip doesn't always extend to a child
       span's own text runs — so without its own gradient the child would
       render as invisible "transparent on transparent". Give it the same
       gradient so "Edit" / "Connect" / "Manage" actually show. */
    background: linear-gradient(135deg, var(--accent), var(--purple));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    color: transparent;
}

#app-version-badge,
.app-version-badge {
    font-size: 11px;
    font-weight: 400;
    color: var(--text-muted);
    -webkit-text-fill-color: var(--text-muted);
    background: none;
    align-self: center;
    vertical-align: middle;
    margin-left: -4px;
    letter-spacing: 0.2px;
}

/* #app-footer styling now lives in /static/footer.js so it travels with
   the script that injects the footer into every page (auth/admin/editor).
   This block intentionally left blank. */

#song-info {
    display: flex;
    align-items: center;
    gap: 16px;
    flex: 1;
    min-width: 0;
}

#song-info span { white-space: nowrap; }
.header-me {
    color: var(--text-secondary, #8b949e);
    font-size: 12px;
    margin-left: 16px;
}
.header-me strong {
    color: var(--text-primary, #e6edf3);
    font-weight: 600;
    margin-left: 4px;
}

#song-title {
    font-size: 15px;
    font-weight: 600;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
}

#song-artist {
    font-size: 13px;
    color: var(--text-secondary);
}

.editable-meta {
    cursor: text;
    padding: 1px 4px;
    border-radius: 3px;
    border: 1px solid transparent;
    transition: border-color var(--transition), background var(--transition);
}

.editable-meta:hover {
    border-color: var(--border);
}

.editable-meta[contenteditable="true"] {
    background: var(--bg-input);
    border-color: var(--accent);
    outline: none;
    color: var(--text-primary);
}
/* Empty editable cell — render a "Click to add foo" placeholder so the
   span is visible / clickable instead of zero-width. Wiped on focus. */
.editable-meta.is-empty {
    color: var(--text-muted);
    font-style: italic;
    opacity: 0.75;
}
.editable-meta.is-empty:hover {
    opacity: 1;
}

#song-duration, #song-bpm, #song-key {
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--text-secondary);
    padding: 2px 7px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 4px;
}

#gpu-indicator {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 7px;
    border-radius: 4px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.2px;
    text-transform: uppercase;
    background: rgba(63,185,80,0.15);
    color: var(--success);
}

#gpu-indicator.cpu {
    background: rgba(139,148,158,0.25);
    color: var(--text-secondary);
}

header nav {
    display: flex;
    gap: 8px;
}

/* Buttons — Recode glassmorphic style */
.btn, header nav button, #transport button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    /* Fixed 36px tall so every .btn lines up — header, overlays,
     * sidebar, action bars all read as the same control. Use box-sizing
     * so the border doesn't push it past 36. */
    box-sizing: border-box;
    height: 36px;
    padding: 0 16px;
    border: 1px solid rgba(139,148,158,0.2);
    border-radius: 6px;
    background: rgba(139,148,158,0.08);
    color: var(--text-primary);
    font-family: var(--font);
    font-size: 13px;
    font-weight: 500;
    /* Anchors styled as .btn (e.g. Open in the project manager) inherit
       the default <a> underline without this — kill it everywhere. */
    text-decoration: none;
    cursor: pointer;
    transition: all var(--transition);
    white-space: nowrap;
    backdrop-filter: blur(4px);
}

.btn:hover, header nav button:hover, #transport button:hover {
    background: rgba(139,148,158,0.15);
    border-color: rgba(139,148,158,0.3);
}

.btn:active, header nav button:active, #transport button:active {
    transform: scale(0.98);
}

.btn:disabled, header nav button:disabled, #transport button:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

.btn-primary {
    background: rgba(31,111,235,0.2);
    border-color: rgba(31,111,235,0.3);
    color: var(--accent);
}

.btn-primary:hover {
    background: rgba(31,111,235,0.3);
    border-color: rgba(31,111,235,0.4);
}

.btn-success {
    background: rgba(63,185,80,0.15);
    border-color: rgba(63,185,80,0.25);
    color: var(--success);
}

.btn-success:hover { background: rgba(63,185,80,0.25); }

.btn-danger {
    background: rgba(248,81,73,0.15);
    border-color: rgba(248,81,73,0.25);
    color: var(--error);
}

.btn-danger:hover { background: rgba(248,81,73,0.25); }

/* Inline confirm: first click "arms" the button, second click runs.
   Pulses red so the user can see it's waiting for confirmation. */
.btn-armed,
.btn.btn-armed,
.project-delete.btn-armed {
    background: var(--error) !important;
    border-color: var(--error) !important;
    color: #fff !important;
    animation: btn-armed-pulse 1.4s ease-in-out infinite;
}

@keyframes btn-armed-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(248,81,73,0.5); }
    50%      { box-shadow: 0 0 0 4px rgba(248,81,73,0.0); }
}

/* Inline action status flash — used by flashBtnStatus() to paint a
 * button green/red/blue for a moment after it's clicked, replacing
 * the textual label with a success/error/busy indicator so the
 * outcome lands exactly where the user acted. */
.btn.btn-status-success,
.btn.btn-status-error,
.btn.btn-status-busy {
    transition: background 0.2s, border-color 0.2s, color 0.2s;
}
.btn.btn-status-success {
    background: rgba(63, 185, 80, 0.22) !important;
    border-color: rgba(63, 185, 80, 0.45) !important;
    color: var(--success) !important;
}
.btn.btn-status-error {
    background: rgba(248, 81, 73, 0.22) !important;
    border-color: rgba(248, 81, 73, 0.45) !important;
    color: var(--error) !important;
}
.btn.btn-status-busy {
    background: rgba(88, 166, 255, 0.18) !important;
    border-color: rgba(88, 166, 255, 0.4) !important;
    color: var(--accent) !important;
}

.btn-sm {
    padding: 4px 10px;
    font-size: 12px;
}

#btn-export { }
#btn-realign { }

/* Layout */
.layout {
    display: flex;
    flex: 1;
    min-height: 0;
    overflow: hidden;
}

.main-wrapper {
    flex: 1;
    display: flex;
    flex-direction: row;
    min-width: 0;
    overflow: hidden;
}

/* Sidebar — sits in a fixed slot reserved on .layout via padding-left,
 * but the actual aside is always position:absolute so width changes
 * (collapse / hover-expand) never reflow the main pane. */
.layout { position: relative; padding-left: 320px; transition: padding-left 0.18s ease; }
body[data-sidebar="collapsed"] .layout { padding-left: 56px; }

.sidebar {
    position: absolute;
    top: 0; left: 0; bottom: 0;
    width: 320px;
    background: var(--bg-secondary);
    border-right: 1px solid var(--border);
    overflow-y: auto;
    overflow-x: hidden;
    /* Trim 2px off the top so the first section lines up with the
     * transport row. */
    padding: 13px 16px 16px;
    display: flex;
    flex-direction: column;
    gap: 16px;
    z-index: 10;
    transition: width 0.18s ease, padding 0.18s ease, box-shadow 0.18s ease;
}

.sidebar[hidden] { display: none; }

/* Section icon + label always exist in the DOM; only the label/body
 * are hidden when collapsed. */
.sidebar-section h3 {
    display: flex;
    align-items: center;
    gap: 8px;
    white-space: nowrap;
}
.sidebar-section-icon {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--accent);
}
/* Per-section accent colour so each card's header reads at a glance.
 * Stroke svgs use currentColor, so a single `color` override does it. */
.sidebar-section[data-section="projects"] .sidebar-section-icon { color: #4c8bf5; }
.sidebar-section[data-section="source"]   .sidebar-section-icon { color: #58c4ff; }
.sidebar-section[data-section="song"]     .sidebar-section-icon { color: #66d68a; }
.sidebar-section[data-section="chapters"] .sidebar-section-icon { color: #ffb454; }
.sidebar-section[data-section="chords"]   .sidebar-section-icon { color: #bc8cff; }
.sidebar-section[data-section="status"]   .sidebar-section-icon { color: #ffd166; }
.sidebar-section-label { flex: 1 1 auto; }

/* Sidebar toggle lives in the transport bar (next to the time
 * readout). Chevron flips direction based on collapsed/pinned. */
.sidebar-toggle-btn { transition: transform 0.18s ease; }
body[data-sidebar="collapsed"] .sidebar-toggle-btn { transform: rotate(180deg); }

/* Lyric-editor toggle mirrors the sidebar toggle but on the right.
 * Chevron flips from ">" to "<" when the editor is collapsed. The
 * editor panel shrinks to a 30px vertical strip showing the "Lyrics"
 * tab. Same 0.18s transition curve as the sidebar. */
.editor-toggle-btn { transition: transform 0.18s ease; }
body[data-editor="collapsed"] .editor-toggle-btn { transform: rotate(180deg); }
body[data-editor="collapsed"] #editor {
    flex: 0 0 30px !important;
    min-width: 30px !important;
    max-width: 30px !important;
    padding: 0 !important;
}
body[data-editor="collapsed"] #editor #lyrics-document,
body[data-editor="collapsed"] #editor #editor-actions {
    display: none;
}
.editor-collapsed-tab { display: none; }
body[data-editor="collapsed"] .editor-collapsed-tab {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    padding: 0;
    margin: 0;
    background: var(--bg-secondary);
    border: 0;
    cursor: pointer;
    user-select: none;
    transition: background 0.15s ease, color 0.15s ease;
}
body[data-editor="collapsed"] .editor-collapsed-tab > span {
    writing-mode: vertical-rl;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--text-secondary);
}
body[data-editor="collapsed"] .editor-collapsed-tab:hover {
    background: color-mix(in srgb, var(--accent) 8%, var(--bg-secondary));
}
body[data-editor="collapsed"] .editor-collapsed-tab:hover > span {
    color: var(--accent);
}

/* ---------- Collapsed: 56px icon strip, no main-pane shift ---------- */
body[data-sidebar="collapsed"] .sidebar {
    width: 56px;
    padding: 13px 6px 16px;
}
body[data-sidebar="collapsed"] .sidebar-section {
    padding: 10px 0;
    text-align: center;
    border: none;
    background: transparent;
}
body[data-sidebar="collapsed"] .sidebar-section h3 {
    justify-content: center;
    margin: 0;
    font-size: 0;
}
body[data-sidebar="collapsed"] .sidebar-section-label,
body[data-sidebar="collapsed"] .sidebar-section-body { display: none; }

/* ---------- Hover-expand (only when collapsed) ---------- */
body[data-sidebar="collapsed"] .sidebar:hover {
    width: 320px;
    padding: 13px 16px 16px;
    box-shadow: 4px 0 24px rgba(0,0,0,0.5);
}
body[data-sidebar="collapsed"] .sidebar:hover .sidebar-section {
    padding: 14px;
    text-align: left;
    border: 1px solid var(--border);
    background: var(--bg-card);
}
body[data-sidebar="collapsed"] .sidebar:hover .sidebar-section h3 {
    justify-content: flex-start;
    margin: 0 0 12px;
    font-size: 11px;
}
body[data-sidebar="collapsed"] .sidebar:hover .sidebar-section-label,
body[data-sidebar="collapsed"] .sidebar:hover .sidebar-section-body { display: block; }

.sidebar-section {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px;
}

.sidebar-section h3 {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: var(--text-muted);
    margin: 0 0 12px;
    font-weight: 600;
}

.sidebar-section .kv-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 4px 0;
    font-size: 12px;
    color: var(--text-secondary);
    border-bottom: 1px dashed var(--border);
}

.sidebar-section .kv-row:last-child { border-bottom: none; }

.sidebar-section .kv-row .value {
    font-family: var(--font-mono);
    color: var(--text-primary);
}

#sidebar-sections {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

#sidebar-sections li {
    padding: 6px 8px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 12px;
    color: var(--text-secondary);
    display: flex;
    justify-content: space-between;
    align-items: center;
    transition: background var(--transition), color var(--transition);
    border-left: 2px solid transparent;
}

#sidebar-sections li:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}

#sidebar-sections li.active {
    background: rgba(88,166,255,0.08);
    color: var(--accent);
    border-left-color: var(--accent);
    padding-left: 6px;
}

#sidebar-sections li .timecode {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--text-muted);
}

#sidebar-sections li.active .timecode { color: var(--accent); }

.upload-row {
    margin-top: 10px;
    display: flex;
    gap: 6px;
}

.upload-row > label,
.upload-row > a {
    flex: 1 1 0;
    min-width: 0;
    cursor: pointer;
}

#sidebar-projects {
    display: flex;
    flex-direction: column;
    gap: 4px;
    max-height: 180px;
    overflow-y: auto;
}

.sidebar-project {
    display: flex;
    flex-direction: column;
    padding: 6px 8px;
    margin-bottom: 4px;
    border-radius: 4px;
    font-size: 12px;
    cursor: pointer;
    color: var(--text-secondary);
    background: rgba(255,255,255,0.03);
    border: 1px solid rgba(255,255,255,0.05);
    border-left: 2px solid transparent;
    text-decoration: none;
}

.sidebar-project:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}

.sidebar-project.active {
    background: rgba(88,166,255,0.08);
    color: var(--accent);
    border-left-color: var(--accent);
    padding-left: 6px;
    position: relative;
}
/* Close pill on the active sidebar project — hidden until the row is
   hovered, slides in with the door-arrow icon + "Close" label. Far more
   discoverable than the 22px × glyph it replaced. */
.sidebar-project-close {
    margin-top: 8px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    width: fit-content;
    padding: 4px 10px;
    border: 1px solid rgba(255,255,255,0.10);
    border-radius: 999px;
    background: rgba(255,255,255,0.04);
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.2px;
    cursor: pointer;
    opacity: 0;
    transform: translateY(-2px);
    transition:
        opacity 0.16s ease,
        transform 0.16s ease,
        background 0.16s ease,
        border-color 0.16s ease,
        color 0.16s ease;
}
.sidebar-project-close svg { display: block; flex-shrink: 0; }
.sidebar-project-close-label { line-height: 1; }

.sidebar-project.active:hover .sidebar-project-close,
.sidebar-project-close:focus-visible {
    opacity: 1;
    transform: translateY(0);
}
.sidebar-project-close:hover {
    background: rgba(255,255,255,0.08);
    border-color: rgba(255,255,255,0.18);
    color: var(--text-primary);
}
.sidebar-project-close.btn-armed {
    opacity: 1;
    transform: translateY(0);
    background: rgba(244,67,54,0.18);
    border-color: rgba(244,67,54,0.55);
    color: #ff8a8a;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    animation: sidebar-close-pulse 1.2s ease-in-out infinite;
}
@keyframes sidebar-close-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(244,67,54,0.0); }
    50%      { box-shadow: 0 0 0 4px rgba(244,67,54,0.18); }
}

.sidebar-project .project-title {
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sidebar-project .project-sub {
    font-size: 10px;
    color: var(--text-muted);
    display: flex;
    justify-content: space-between;
}

.sidebar-projects-totals {
    position: sticky;
    bottom: 0;
    margin-top: 8px;
    padding: 8px 0 0;
    font-size: 10px;
    font-weight: 600;
    color: var(--text-secondary);
    display: flex;
    justify-content: space-between;
    text-transform: uppercase;
    letter-spacing: 0.4px;
}

.sidebar-projects-actions {
    display: flex;
    gap: 8px;
    margin-top: 10px;
}
.sidebar-projects-actions .btn {
    flex: 1 1 0;
    min-width: 0;
}

#sidebar-actions {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

#sidebar-actions .btn {
    justify-content: flex-start;
    width: 100%;
}

#sidebar-actions .btn:disabled {
    background: var(--bg-tertiary);
    color: var(--text-muted);
    cursor: not-allowed;
}

#sidebar-actions .action-hint {
    font-size: 10px;
    color: var(--text-muted);
    margin-top: 2px;
    padding: 0 4px;
}

#sidebar-source-info .source-row {
    display: flex;
    justify-content: space-between;
    padding: 4px 0;
    border-bottom: 1px dashed var(--border);
    font-size: 11px;
}

#sidebar-source-info .source-row:last-child {
    border-bottom: none;
}

#sidebar-source-info .source-row .k { color: var(--text-secondary); }
#sidebar-source-info .source-row .v {
    color: var(--text-primary);
    font-family: var(--font-mono);
    text-align: right;
    max-width: 55%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

#sidebar-source-info .badge-info {
    display: inline-block;
    padding: 2px 6px;
    border-radius: 3px;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.3px;
}

#sidebar-source-info .badge-info.present {
    background: rgba(63,185,80,0.15);
    color: var(--success);
}

#sidebar-source-info .badge-info.absent {
    background: rgba(139,148,158,0.2);
    color: var(--text-muted);
}

#sidebar-source-info .link-action {
    display: block;
    margin-top: 8px;
    padding: 6px 8px;
    background: rgba(88,166,255,0.1);
    border: 1px solid rgba(88,166,255,0.25);
    border-radius: 4px;
    color: var(--accent);
    font-size: 11px;
    text-align: center;
    cursor: pointer;
    font-weight: 600;
}

#sidebar-source-info .link-action:hover {
    background: rgba(88,166,255,0.2);
}

#sidebar-source-info .note {
    font-size: 10px;
    color: var(--text-muted);
    margin-top: 6px;
    line-height: 1.4;
}

#lyrics-modal {
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    background: rgba(0,0,0,0.35);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    z-index: 210;
    display: flex;
    align-items: center;
    justify-content: center;
}

#lyrics-modal[hidden] { display: none; }

#send-merish-modal {
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    background: rgba(0,0,0,0.35);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    z-index: 220;
    display: flex;
    align-items: center;
    justify-content: center;
}
#send-merish-modal[hidden] { display: none; }

/* Merish + Projects open as centered modals from inside the editor —
 * sized to 90vw / 90vh so they feel like a real workspace, with the
 * standard .modal header / body chrome from the rest of the app. */
#merish-overlay,
#projects-overlay {
    position: fixed;
    top: 0; left: 0; right: 0;
    /* Leave room for the sticky site footer at the bottom (38px,
       64px on narrow viewports) — without this the overlay covers
       the footer entirely. */
    bottom: 38px;
    background: var(--bg-primary);
    z-index: 180;
    display: flex;
    align-items: stretch;
    justify-content: stretch;
}
@media (max-width: 900px) {
    #merish-overlay, #projects-overlay { bottom: 64px; }
}
#merish-overlay[hidden],
#projects-overlay[hidden] { display: none; }

.modal.modal-fullscale {
    width: 100vw;
    height: 100vh;
    max-width: none;
    max-height: none;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
    border-radius: 0;
    border: none;
}

.modal.modal-fullscale .modal-body {
    flex: 1 1 auto;
    overflow: hidden;
    padding: 0;
    display: flex;
    flex-direction: column;
    min-height: 0;
}

/* Merish view inside a modal — its own header is redundant with the
 * modal-header above it, and its calc(100vh - …) height was pushing
 * the workspace up over the modal chrome. Fill the modal-body
 * naturally and hide the inner title. */
#merish-overlay .merish-view {
    height: 100%;
    max-width: none;
    margin: 0;
    padding: 12px 16px 16px;
}
#merish-overlay .merish-view-head {
    padding: 0 0 8px 0;
    background: transparent;
    border: none;
    border-radius: 0;
}
#merish-overlay .merish-view-head .merish-title-text {
    display: none;  /* the modal-header already shows the title */
}

.merish-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    min-height: 120px;
    padding: 24px;
    background: var(--bg-tertiary);
    border: 1px dashed var(--border);
    border-radius: 6px;
    color: var(--text-muted);
    font-size: 13px;
    text-align: center;
}

/* Connect onboarding panel — replaces the bare IP/Port row in the
 * disconnected state with a richer panel including help. */
.merish-connect-panel {
    width: 100%;
    max-width: 1100px;
    margin: 0 auto;
    padding: 28px 30px;
    background:
        radial-gradient(circle at 0% 0%, rgba(76,139,245,0.10), transparent 55%),
        radial-gradient(circle at 100% 100%, rgba(188,100,255,0.08), transparent 55%),
        var(--bg-card, #1c2333);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 8px 32px rgba(0,0,0,0.3);
}

/* New two-card Connect layout. Tight header at top, side-by-side
 * primary/secondary cards, expandable setup instructions below.
 * Matches the card-heavy look of the rest of the app (projects,
 * settings, Merish workspace). */
.merish-connect-header {
    text-align: left;
    margin-bottom: 20px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--border);
}
.merish-connect-header .merish-connect-title {
    font-size: 22px;
    margin-bottom: 6px;
    text-align: left;
}
.merish-connect-header .merish-connect-tag {
    color: var(--text-secondary, #8b949e);
    font-size: 13px;
    line-height: 1.5;
    margin: 0 0 10px;
}
.merish-connect-header .merish-connect-chips {
    justify-content: flex-start;
    margin-top: 0;
}

.merish-connect-grid {
    display: grid;
    grid-template-columns: 1.15fr 0.85fr;
    gap: 16px;
    margin-bottom: 18px;
}
@media (max-width: 900px) {
    .merish-connect-grid { grid-template-columns: 1fr; }
}

.merish-connect-card {
    background: color-mix(in srgb, var(--bg-card) 60%, transparent);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 18px 20px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.merish-connect-card-primary {
    background:
        radial-gradient(circle at 0% 0%, rgba(76,139,245,0.08), transparent 60%),
        color-mix(in srgb, var(--bg-card) 60%, transparent);
    border-color: color-mix(in srgb, var(--purple, #bc8cff) 25%, var(--border));
}
.merish-connect-card-head {
    display: flex;
    align-items: flex-start;
    gap: 12px;
}
.merish-connect-card-head h3 {
    margin: 0 0 4px;
    font-size: 15px;
    font-weight: 600;
    color: var(--text-primary);
}
.merish-connect-card-lede {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--text-secondary, #8b949e);
}
.merish-connect-card-ico {
    width: 44px;
    height: 44px;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
    background:
        radial-gradient(circle at 30% 30%, rgba(108,170,255,0.25), transparent 60%),
        radial-gradient(circle at 70% 70%, rgba(188,100,255,0.22), transparent 60%),
        rgba(255,255,255,0.03);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.08);
}
/* Primary card contains the download-cards grid — let them flow full
 * width inside the card rather than the extra wrapper padding they
 * had as a standalone section. */
.merish-connect-card .desktop-cta-cards-wrap {
    padding: 0;
    background: none;
    border: 0;
    box-shadow: none;
}
.merish-connect-card .desktop-cta-grid {
    grid-template-columns: 1fr;  /* stack inside a narrower card column */
    gap: 10px;
}
@media (min-width: 1100px) {
    .merish-connect-card .desktop-cta-grid {
        /* Side-by-side when the panel is wide enough. */
        grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    }
}

/* Discovery status dot in the primary card head (native app only). */
.merish-connect-card-head .merish-dot {
    margin-top: 6px;
    flex-shrink: 0;
}

/* Expandable first-time setup section at the bottom of the panel. */
.merish-connect-setup {
    border: 1px solid var(--border);
    border-radius: 10px;
    background: color-mix(in srgb, var(--bg-card) 70%, transparent);
    padding: 0;
}
.merish-connect-setup > summary {
    list-style: none;
    cursor: pointer;
    padding: 12px 16px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-primary);
    position: relative;
    user-select: none;
}
.merish-connect-setup > summary::-webkit-details-marker { display: none; }
.merish-connect-setup > summary::after {
    content: "▸";
    float: right;
    font-size: 11px;
    color: var(--text-muted);
    transition: transform 150ms ease;
}
.merish-connect-setup[open] > summary::after { transform: rotate(90deg); }
.merish-connect-setup .merish-connect-steps {
    padding: 4px 16px 16px;
}
/* Legacy head retained for layouts outside the onboarding panel. */
.merish-connect-head {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    margin-bottom: 22px;
}
.merish-connect-head .merish-dot {
    margin-top: 6px;
    flex-shrink: 0;
}

/* New hero for the disconnected Merish onboarding panel — a centered
   device illustration, bigger gradient title, lede tag, and a row of
   compatibility chips. Replaces the tiny-dot-plus-stacked-text look. */
.merish-connect-hero {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 10px;
    margin-bottom: 26px;
    padding: 6px 0 2px;
}
.merish-connect-hero-ico {
    position: relative;
    width: 96px;
    height: 96px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 4px;
    border-radius: 24px;
    background:
        radial-gradient(circle at 30% 30%, rgba(108,170,255,0.22), transparent 60%),
        radial-gradient(circle at 70% 70%, rgba(188,100,255,0.20), transparent 60%),
        rgba(255,255,255,0.02);
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,0.06),
        0 10px 28px rgba(76,139,245,0.18);
}
.merish-connect-hero-ico::after {
    /* Soft outer halo — pulses gently so the onboarding panel has some
       life while it's waiting for the user to connect. */
    content: "";
    position: absolute;
    inset: -4px;
    border-radius: 28px;
    background: radial-gradient(circle at center, rgba(108,170,255,0.22), transparent 70%);
    filter: blur(6px);
    z-index: -1;
    animation: merish-hero-pulse 3.6s ease-in-out infinite;
}
@keyframes merish-hero-pulse {
    0%, 100% { opacity: 0.55; transform: scale(0.96); }
    50%      { opacity: 1.0;  transform: scale(1.04); }
}
.merish-connect-title {
    margin: 0;
    font-size: 28px;
    font-weight: 700;
    letter-spacing: -0.4px;
    line-height: 1.2;
    background: linear-gradient(135deg, #6aa2ff 0%, #9d7aff 50%, #bc64ff 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
.merish-connect-tag {
    margin: 0;
    max-width: 560px;
    color: var(--text-secondary);
    font-size: 14px;
    line-height: 1.6;
}
.merish-connect-tag strong {
    color: var(--text-primary);
    font-weight: 600;
}
.merish-connect-chips {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
    margin-top: 6px;
}
.merish-device-chip {
    display: inline-flex;
    align-items: center;
    padding: 5px 12px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.2px;
    color: #cfd8ff;
    background: linear-gradient(135deg, rgba(108,170,255,0.12), rgba(188,100,255,0.12));
    border: 1px solid rgba(108,170,255,0.25);
    border-radius: 999px;
    white-space: nowrap;
}
@media (max-width: 600px) {
    .merish-connect-title { font-size: 22px; }
    .merish-connect-hero-ico { width: 80px; height: 80px; }
}

.merish-connect-form {
    display: grid;
    grid-template-columns: 1fr 110px auto;
    gap: 12px;
    align-items: end;
    margin-bottom: 24px;
}

/* Send-to-Merish modal: IP + port + Connect button laid out so all
   three share the same 36px height (matches the global .btn rule). */
.send-merish-connect-row {
    display: grid;
    grid-template-columns: 1fr 110px auto;
    gap: 8px;
    align-items: stretch;
}
.send-merish-connect-row input {
    height: 36px;
    box-sizing: border-box;
    padding: 0 10px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text-primary);
    font-size: 13px;
    font-family: inherit;
}
.send-merish-connect-row input:focus {
    outline: none;
    border-color: var(--accent);
}
.send-merish-connect-row .btn {
    /* Override .btn-sm if it ever sneaks in here — explicit 36px keeps
       the row a clean rectangle. */
    height: 36px;
    padding: 0 18px;
    font-size: 13px;
}
.merish-connect-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.merish-connect-field > span {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-muted);
}
.merish-connect-field input {
    height: 30px;
    padding: 0 12px;
    background: rgba(0,0,0,0.30);
    border: 1px solid rgba(255,255,255,0.10);
    border-radius: 8px;
    color: var(--text-primary);
    font-size: 14px;
    font-family: inherit;
    box-sizing: border-box;
    transition: border-color .15s, box-shadow .15s, background .15s;
}
.merish-connect-field input:focus {
    outline: none;
    border-color: rgba(108,140,250,0.6);
    box-shadow: 0 0 0 3px rgba(88,166,255,0.18);
    background: rgba(0,0,0,0.45);
}
.merish-connect-btn {
    height: 30px !important;
    padding: 0 22px !important;
    background: linear-gradient(135deg, #4c8bf5, #6f7af8 50%, #bc64ff) !important;
    color: #fff !important;
    font-weight: 600 !important;
    font-size: 14px !important;
    border: 0 !important;
    border-radius: 8px !important;
    box-shadow: 0 4px 14px rgba(76,139,245,0.32);
}
.merish-connect-btn:hover {
    filter: brightness(1.08);
    box-shadow: 0 6px 20px rgba(76,139,245,0.42);
}
@media (max-width: 600px) {
    .merish-connect-form {
        grid-template-columns: 1fr;
    }
}

/* ─── Connect onboarding steps (v0.2.356+) ──────────────────────────
 * Two numbered cards stacked under the connect form: Transfer mode +
 * port forwarding. Each card has a gradient-bordered numbered badge
 * floating in the top-left, a coloured left accent bar, and a glass
 * background that picks up the same blue→purple brand gradient as the
 * home cards. */
.merish-connect-steps {
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin-top: 22px;
}
.merish-step {
    position: relative;
    display: grid;
    grid-template-columns: 56px 1fr;
    gap: 18px;
    padding: 22px 22px 22px 18px;
    background:
        linear-gradient(135deg, rgba(76,139,245,0.06), rgba(188,100,255,0.04)),
        rgba(255,255,255,0.02);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 14px;
    overflow: hidden;
    transition: border-color 0.18s ease, transform 0.18s ease;
}
.merish-step::before {
    content: "";
    position: absolute;
    top: 0; bottom: 0; left: 0;
    width: 4px;
    background: linear-gradient(180deg, #4c8bf5 0%, #bc64ff 100%);
    border-top-left-radius: 14px;
    border-bottom-left-radius: 14px;
}
.merish-step:hover {
    border-color: rgba(106,162,255,0.35);
}

.merish-step-num {
    width: 44px;
    height: 44px;
    border-radius: 12px;
    background: linear-gradient(135deg, #4c8bf5 0%, #bc64ff 100%);
    color: #fff;
    font-size: 22px;
    font-weight: 700;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-shadow:
        0 6px 16px rgba(76,139,245,0.32),
        inset 0 1px 0 rgba(255,255,255,0.18);
    flex-shrink: 0;
}

.merish-step-body { min-width: 0; }
.merish-step-title {
    margin: 4px 0 6px;
    font-size: 16px;
    font-weight: 700;
    color: var(--text-primary);
    letter-spacing: -0.1px;
}
.merish-step-title em {
    font-style: normal;
    background: linear-gradient(135deg, #6aa2ff, #bc64ff);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
    font-weight: 700;
}
.merish-step-lede {
    margin: 0 0 12px;
    color: var(--text-secondary);
    font-size: 13px;
    line-height: 1.55;
}
.merish-step-list {
    margin: 0 0 10px;
    padding-left: 22px;
    color: var(--text-secondary);
    font-size: 13px;
    line-height: 1.75;
}
.merish-step-list li { margin: 4px 0; }
.merish-step-list strong { color: var(--text-primary); font-weight: 600; }
.merish-step-list code {
    background: rgba(0,0,0,0.40);
    padding: 2px 6px;
    border-radius: 4px;
    font-family: ui-monospace, "SF Mono", "Cascadia Code", monospace;
    font-size: 12px;
    color: var(--text-primary);
}
.merish-step-list em { color: var(--text-muted); font-style: italic; }
.merish-step-list a { color: var(--accent, #6aa2ff); text-decoration: underline; }
.merish-step-list a:hover { text-decoration: none; }

.merish-step-warn {
    margin: 14px 0 0;
    padding: 10px 14px;
    background: rgba(255, 165, 0, 0.10);
    border: 1px solid rgba(255, 165, 0, 0.35);
    border-radius: 8px;
    color: var(--text-primary);
    font-size: 12.5px;
    line-height: 1.55;
}

@media (max-width: 600px) {
    .merish-step {
        grid-template-columns: 40px 1fr;
        padding: 18px 16px 18px 14px;
        gap: 14px;
    }
    .merish-step-num { width: 36px; height: 36px; font-size: 18px; }
    .merish-step-title { font-size: 15px; }
}

/* Legacy merish-connect-help rules (still used elsewhere — leave for now). */
.merish-connect-help {
    border-top: 1px solid var(--border);
    padding-top: 18px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.merish-connect-help details {
    background: rgba(0, 0, 0, 0.18);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 8px;
    padding: 10px 14px;
    transition: background .15s;
}
.merish-connect-help details[open] {
    background: rgba(0, 0, 0, 0.28);
}
.merish-connect-help summary {
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-primary);
    user-select: none;
}
.merish-connect-help summary::-webkit-details-marker { display: none; }
.merish-connect-help summary::after {
    content: "+";
    margin-left: auto;
    color: var(--text-muted);
    font-size: 18px;
    transition: transform .15s;
}
.merish-connect-help details[open] summary::after { content: "−"; }
.merish-help-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 6px;
    background: rgba(76,139,245,0.18);
    color: var(--accent, #58a6ff);
    font-size: 12px;
    font-weight: 700;
    flex-shrink: 0;
}
.merish-connect-help ol,
.merish-connect-help ul {
    margin: 12px 0 4px;
    padding-left: 22px;
    color: var(--text-secondary);
    font-size: 13px;
    line-height: 1.7;
}
.merish-connect-help p {
    margin: 12px 0 8px;
    color: var(--text-secondary);
    font-size: 13px;
    line-height: 1.6;
}
.merish-connect-help strong { color: var(--text-primary); }
.merish-connect-help code {
    background: rgba(0,0,0,0.45);
    padding: 1px 6px;
    border-radius: 4px;
    font-family: ui-monospace, "SF Mono", "Cascadia Code", monospace;
    font-size: 12px;
    color: var(--text-primary);
}
.merish-connect-help em { color: var(--text-muted); font-style: italic; }
.merish-connect-help a { color: var(--accent, #6ea8ff); text-decoration: underline; }
.merish-connect-help a:hover { text-decoration: none; }
.merish-connect-help p.merish-warn {
    background: rgba(255, 165, 0, 0.10);
    border: 1px solid rgba(255, 165, 0, 0.35);
    border-radius: 8px;
    padding: 10px 14px;
    margin-top: 14px;
    color: var(--text-primary);
    font-size: 12.5px;
    line-height: 1.55;
}
.merish-connect-help p.merish-tip {
    background: rgba(106, 162, 255, 0.10);
    border: 1px solid rgba(106, 162, 255, 0.35);
    border-radius: 8px;
    padding: 10px 14px;
    margin-top: 12px;
    color: var(--text-primary);
    font-size: 12.5px;
    line-height: 1.55;
}
.merish-empty[hidden] { display: none !important; }
.merish-empty p { margin: 0; }

#projects-overlay .modal-body.projects-overlay-inner {
    overflow-y: auto;
    padding: 16px 24px 24px;
}

/* Processing modal — full-screen blur during long jobs */
#processing-modal {
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    background: rgba(0,0,0,0.5);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    z-index: 500;
    display: flex;
    align-items: center;
    justify-content: center;
}

#processing-modal[hidden] { display: none; }

#processing-modal .processing-inner {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 28px 32px 24px;
    width: min(700px, 92vw) !important;
    max-width: none !important;
    height: 580px !important;
    max-height: 90vh !important;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    text-align: center;
    overflow: hidden;
    box-shadow: 0 20px 60px rgba(0,0,0,0.6);
}

/* Multi-file mode: same box as the default, just left-aligned body
 * text since per-file rows carry the granular status. */
#processing-modal.multi-file .processing-inner {
    text-align: left;
}
#processing-modal.multi-file .processing-spinner {
    display: none;
}
#processing-modal.multi-file h2 {
    text-align: center;
    font-size: 18px;
    margin-bottom: 2px;
}
#processing-modal.multi-file .processing-step-name {
    text-align: center;
    margin-bottom: 14px;
}
#processing-modal.multi-file .processing-bar {
    height: 10px;
}
#processing-modal.multi-file .processing-pct {
    text-align: center;
}

/* Mini per-substep progress bars inside the processing modal.
 * Populated by updateProcessingModal when the job's progress messages
 * include a "Step X of Y: NAME" prefix. Each row shows the step name,
 * its own fill, and its own percent readout. Rows that have completed
 * get an accent-green fill + ✓ glyph so the user sees the whole pipeline
 * advancing through stages. */
/* Substeps list uses the same card-row design as the multi-file
 * filelist — each job step renders as a card with icon, label,
 * progress bar, and status. The pf-* class rules below apply to
 * rows in BOTH .processing-filelist and .processing-substeps. */
.processing-substeps {
    list-style: none;
    margin: 14px 0 0;
    padding: 6px 2px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    flex: 1 1 0;
    min-height: 0;
    overflow-y: auto;
    scrollbar-gutter: stable;
}
.processing-substeps[hidden] { display: none; }

/* Cancel button centred under the progress area. Only visible while
 * the modal has an active job — hidden again on terminal states. */
.processing-cancel-wrap {
    margin-top: 14px;
    display: flex;
    justify-content: center;
}
.processing-cancel-wrap[hidden] { display: none; }

.processing-filelist {
    list-style: none;
    margin: 12px 0 0;
    padding: 6px 2px;
    flex: 1 1 0;
    min-height: 0;
    overflow-y: auto;
    scrollbar-gutter: stable;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.processing-filelist[hidden] { display: none; }

.pf-row {
    display: grid;
    grid-template-columns: 22px 1fr;
    gap: 10px;
    align-items: center;
    padding: 10px 12px;
    background: var(--bg-primary);
    border: 1px solid var(--border);
    border-radius: 6px;
    transition: background 0.2s ease, border-color 0.2s ease;
}
.pf-row.is-running {
    border-color: color-mix(in srgb, var(--accent) 55%, var(--border));
}
.pf-row.is-done {
    border-color: color-mix(in srgb, var(--success, #238636) 55%, var(--border));
    background: color-mix(in srgb, var(--success, #238636) 8%, var(--bg-primary));
}
.pf-row.is-failed {
    border-color: color-mix(in srgb, var(--error-dim, #da3633) 60%, var(--border));
    background: color-mix(in srgb, var(--error-dim, #da3633) 8%, var(--bg-primary));
}
.pf-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    color: var(--text-secondary);
}
.pf-row.is-pending .pf-icon::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--text-secondary);
    opacity: 0.35;
}
.pf-row.is-running .pf-icon::before {
    content: "";
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 2px solid color-mix(in srgb, var(--accent) 30%, transparent);
    border-top-color: var(--accent);
    animation: spin 0.9s linear infinite;
}
.pf-row.is-done .pf-icon::before {
    content: "✓";
    font-size: 14px;
    font-weight: 700;
    color: var(--success, #3fb950);
}
.pf-row.is-failed .pf-icon::before {
    content: "✕";
    font-size: 14px;
    font-weight: 700;
    color: var(--error-dim, #f85149);
}

.pf-body {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.pf-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
}
.pf-name {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.pf-size {
    font-family: var(--font-mono);
    font-size: 10px;
    color: var(--text-secondary);
    flex-shrink: 0;
}
.pf-bar {
    height: 4px;
    background: var(--bg-card);
    border-radius: 2px;
    overflow: hidden;
}
.pf-fill {
    height: 100%;
    width: 0%;
    background: linear-gradient(
        90deg,
        rgba(31,111,235,0.6),
        rgba(88,166,255,0.8),
        rgba(188,140,255,0.6)
    );
    background-size: 200% 100%;
    animation: shimmer 2s linear infinite;
    transition: width 0.3s ease;
}
.pf-row.is-done .pf-fill {
    background: var(--success, #238636);
    animation: none;
}
.pf-row.is-failed .pf-fill {
    background: var(--error-dim, #da3633);
    animation: none;
}
.pf-row.is-pending .pf-fill { width: 0% !important; }
.pf-row.is-pending .pf-name { opacity: 0.5; }
.pf-row.is-pending .pf-size { display: none; }
.pf-status {
    font-size: 11px;
    color: var(--text-secondary);
    font-family: var(--font-mono);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.pf-row.is-done .pf-status { color: var(--success, #3fb950); }
.pf-row.is-failed .pf-status { color: var(--error-dim, #f85149); }

.processing-spinner {
    display: none;
}

.processing-actions {
    display: flex;
    gap: 8px;
    justify-content: center;
    margin-top: 18px;
}

.processing-actions[hidden] { display: none; }

#processing-modal h2 {
    margin: 0 0 4px;
    font-size: 16px;
    font-weight: 600;
    color: var(--text-primary);
    height: 22px;
    line-height: 22px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.processing-step-name {
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--accent);
    letter-spacing: 0.5px;
    text-transform: uppercase;
    margin-bottom: 16px;
    height: 14px;
    line-height: 14px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.processing-bar {
    height: 8px;
    background: var(--bg-primary);
    border: 1px solid var(--border);
    border-radius: 4px;
    overflow: hidden;
    margin-bottom: 8px;
    position: relative;
}

.processing-fill {
    height: 100%;
    width: 0%;
    background: linear-gradient(
        90deg,
        rgba(31,111,235,0.35),
        rgba(88,166,255,0.6),
        rgba(188,140,255,0.35)
    );
    background-size: 200% 100%;
    animation: shimmer 2s linear infinite;
    transition: width 0.3s ease;
}

.processing-pct {
    font-family: var(--font-mono);
    font-size: 13px;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 8px;
}

.processing-msg {
    font-size: 11px;
    color: var(--text-secondary);
    height: 16px;
    line-height: 16px;
    font-family: var(--font-mono);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

@keyframes spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

/* Inline "opening / loading" spinner reusable inside any .btn —
   used by the Backup button's "Opening…" state while the modal
   spins up (which needs a SystemInfo round-trip before rendering). */
.btn-busy { opacity: 0.75; cursor: wait; }
.btn-busy-spinner {
    display: inline-block;
    width: 12px;
    height: 12px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: spin 0.7s linear infinite;
    vertical-align: -2px;
    margin-right: 6px;
}

#lyrics-modal .modal {
    width: 960px;
    height: 800px;
    min-width: 360px;
    min-height: 260px;
    max-width: 95vw;
    max-height: 95vh;
    resize: both;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

#lyrics-modal .modal-body {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}

#lyrics-modal #lyrics-textarea {
    flex: 1 1 auto;
    width: 100%;
    resize: none;
    min-height: 0;
}

/* Vocal-source radio on stem rows */
.stem-waveform-row.vocal-source {
    border-color: var(--accent);
    box-shadow: 0 0 0 1px rgba(88,166,255,0.3);
}

/* Chord-source highlight on stem rows — uses the same warm amber as
 * the C badge so they read as the same selection at a glance. When a
 * stem is BOTH a vocal source and a chord source, the chord box-shadow
 * stacks beside the vocal border (different sides of the row). */
.stem-waveform-row.chord-source {
    border-color: #c48a2a;
    box-shadow: 0 0 0 1px rgba(196,138,42,0.3);
}

.stem-waveform-row.vocal-source.chord-source {
    border-color: var(--accent);
    box-shadow:
        0 0 0 1px rgba(88,166,255,0.3),
        inset 3px 0 0 #c48a2a;
}

.stem-waveform-row.dragging {
    opacity: 0.35;
    cursor: grabbing;
}

.stem-waveform-row.drop-above {
    border-top: 3px solid var(--accent);
    margin-top: -2px;
}

.stem-waveform-row.drop-below {
    border-bottom: 3px solid var(--accent);
    margin-bottom: -2px;
}

.stem-waveform-row .stem-name-input {
    cursor: text;
}

/* Default cursor across the whole row is the normal arrow — only the
 * track-number badge shows the grab affordance. Buttons and
 * waveform areas keep their own cursors (pointer / default). */
.stem-waveform-row {
    cursor: default;
}

.stem-waveform-row .stem-num {
    cursor: grab;
}

.stem-waveform-row.dragging .stem-num,
.stem-waveform-row .stem-num:active {
    cursor: grabbing;
}

.stem-waveform-row .stem-waveform {
    cursor: default;
}

.stem-waveform-row button {
    cursor: pointer;
}

/* Active state for the V (vocal source) badge — matches the mute/solo
 * treatment, lit up when this stem is one of the vocal sources. */
.stem-waveform-row.vocal-source .stem-btn.vocal {
    background: var(--accent-dim);
    color: #fff;
    border-color: var(--accent-dim);
}

/* Active state for the C (chord source) badge — uses a warm amber so
 * the vocal and chord sources read as distinct categories at a glance. */
.stem-waveform-row.chord-source .stem-btn.chord {
    background: #c48a2a;
    color: #fff;
    border-color: #c48a2a;
}

#mix-presets {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

#mix-presets button {
    flex: 0 0 auto;
    min-width: 0;
}

#mix-presets.mix-presets-transport {
    display: inline-flex;
    gap: 3px;
    flex-wrap: nowrap;
}

.transport-sep {
    width: 1px;
    height: 18px;
    background: var(--border);
    margin: 0 4px;
}

.stem-row {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 8px;
    padding: 6px 0;
    border-bottom: 1px dashed var(--border);
}

.stem-row:last-child {
    border-bottom: none;
}

.stem-row .stem-mute {
    width: 24px;
    height: 24px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 4px;
    cursor: pointer;
    font-size: 12px;
    color: var(--text-secondary);
}

.stem-row.muted .stem-mute {
    background: var(--error-dim);
    color: #fff;
    border-color: var(--error-dim);
}

.stem-row .stem-label {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.stem-row .stem-name {
    font-size: 12px;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.stem-row .stem-role {
    font-size: 10px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.4px;
}

.stem-row.role-vocal .stem-role { color: var(--accent); }
.stem-row.role-harmonic .stem-role { color: var(--purple); }
.stem-row.role-bass .stem-role { color: var(--cyan); }
.stem-row.role-drums .stem-role,
.stem-row.role-percussion .stem-role { color: var(--warning); }

.stem-row input[type="range"] {
    width: 72px;
    -webkit-appearance: none;
    appearance: none;
    height: 4px;
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: 2px;
    outline: none;
    cursor: pointer;
}

.stem-row input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--accent);
    border: 1px solid var(--bg-card);
    cursor: pointer;
}

.stem-row input[type="range"]::-moz-range-thumb {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--accent);
    border: 1px solid var(--bg-card);
    cursor: pointer;
}

#mix-presets button.active {
    background: rgba(31,111,235,0.35);
    border-color: rgba(31,111,235,0.5);
    color: var(--accent);
}

.chord-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

.chord-chip {
    font-family: var(--font-mono);
    font-size: 11px;
    padding: 3px 8px;
    background: rgba(188,140,255,0.15);
    color: var(--purple);
    border: 1px solid rgba(188,140,255,0.25);
    border-radius: 4px;
    cursor: pointer;
    transition: all var(--transition);
}

.chord-chip:hover {
    background: rgba(188,140,255,0.25);
    border-color: rgba(188,140,255,0.4);
}

.chord-redetect {
    flex-basis: 100%;
    margin-top: 6px;
}

/* Send-to-Merish folder browser rows */
.sm-fs-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 10px;
    font-size: 12px;
    border-bottom: 1px solid var(--border);
    cursor: default;
    color: var(--text-primary);
}
.sm-fs-row:last-child { border-bottom: none; }
.sm-fs-dir { cursor: pointer; font-weight: 500; }
.sm-fs-dir:hover { background: var(--bg-hover); }
.sm-fs-file:hover { background: var(--bg-hover); }
.sm-fs-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    color: var(--text-muted);
}
.sm-fs-icon svg { width: 14px; height: 14px; }
.sm-fs-name {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Per-type icon colours — mirror the Connect-card palette so users
   recognise file types across both views. */
.sm-fs-row[data-type="folder"] .sm-fs-icon { color: #e0b860; }
.sm-fs-row[data-type="mta"]    .sm-fs-icon { color: #5ab0ff; }
.sm-fs-row[data-type="midi"]   .sm-fs-icon { color: #b58aff; }
.sm-fs-row[data-type="audio"]  .sm-fs-icon { color: #4caf50; }
.sm-fs-row[data-type="wav"]    .sm-fs-icon { color: #ff8c42; }
.sm-fs-row[data-type="video"]  .sm-fs-icon { color: #e0707b; }
.sm-fs-row[data-type="image"]  .sm-fs-icon { color: #f5c452; }
.sm-fs-row[data-type="text"]   .sm-fs-icon { color: #9aa0a6; }
.sm-fs-row[data-type="backup"] .sm-fs-icon { color: #7a8691; }
.sm-fs-row[data-type="data"]   .sm-fs-icon { color: #6fbcc9; }

/* Inline new-folder edit row inside the Send-to-Merish browser. Uses
   the same dark-input styling as the other modal inputs so it doesn't
   render as a bare white browser-default field. */
.sm-fs-row.pending { background: var(--bg-hover); }
.sm-fs-row .sm-inline-edit {
    flex: 1;
    height: 26px;
    padding: 0 8px;
    background: var(--bg-tertiary);
    border: 1px solid var(--accent);
    border-radius: 4px;
    color: var(--text-primary);
    font-family: inherit;
    font-size: 12px;
}
.sm-fs-row .sm-inline-edit:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(88, 166, 255, 0.18);
}
.sm-fs-row .sm-inline-edit::placeholder {
    color: var(--text-muted);
}

/* Send-to-Merish progress step list */
.sm-step {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 14px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 13px;
    transition: border-color 0.18s ease, background 0.18s ease;
}
.sm-progress-header {
    padding: 10px 14px 12px;
    margin-bottom: 10px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 8px;
    border-left: 3px solid var(--accent);
}
.sm-progress-filename {
    font-family: var(--font-mono);
    font-size: 13px;
    color: var(--text-primary);
    word-break: break-all;
}
.sm-progress-path {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--text-muted);
    margin-top: 4px;
    word-break: break-all;
}
.sm-progress-path:empty { display: none; }

/* 28px circular state indicator. Drawn entirely with CSS so each state
   can animate / recolour cleanly without swapping any DOM. */
.sm-step-icon {
    position: relative;
    width: 28px;
    height: 28px;
    flex-shrink: 0;
    box-sizing: border-box;
    border-radius: 50%;
    background: transparent;
    border: 2px solid var(--border);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    font-size: 14px;
    font-weight: 700;
    line-height: 1;
    transition: border-color 0.18s ease, background 0.18s ease;
}

/* Pending — empty thin ring, slightly muted row. */
.sm-step[data-state="pending"] { opacity: 0.55; }

/* Active — spinning arc. border-top transparent + linear spin gives a
   classic loader without an extra inline SVG. */
.sm-step[data-state="active"] {
    border-color: var(--accent);
    background: rgba(88, 166, 255, 0.06);
}
.sm-step[data-state="active"] .sm-step-icon {
    border-color: var(--accent);
    border-top-color: transparent;
    animation: sm-spin 0.8s linear infinite;
}

/* Done — solid green disc with white check. */
.sm-step[data-state="done"] {
    border-color: rgba(76, 175, 80, 0.4);
}
.sm-step[data-state="done"] .sm-step-icon {
    background: #4caf50;
    border-color: #4caf50;
}
.sm-step[data-state="done"] .sm-step-icon::before {
    content: "✓";
}

/* Failed — solid red disc with white cross + red row border. */
.sm-step[data-state="failed"] {
    border-color: var(--error);
    background: rgba(244, 67, 54, 0.06);
}
.sm-step[data-state="failed"] .sm-step-icon {
    background: var(--error);
    border-color: var(--error);
}
.sm-step[data-state="failed"] .sm-step-icon::before {
    content: "✕";
}

.sm-step-label {
    color: var(--text-primary);
    font-weight: 600;
    font-size: 13px;
    flex-shrink: 0;
}
.sm-step-detail {
    color: var(--text-muted);
    font-size: 12px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
}

@keyframes sm-spin {
    to { transform: rotate(360deg); }
}

/* Queue checklist above the per-item step panel. Shown only when
 * the Send-to-Merish modal is opened with 2+ projects — each row
 * ticks off as the current project finishes. Mirrors the visual
 * idiom of the multi-file audio-import modal so the interaction
 * feels familiar. */
.sm-queue-list {
    list-style: none;
    padding: 6px;
    margin: 10px 0 12px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    max-height: 180px;
    overflow-y: auto;
    background: rgba(15, 15, 18, 0.35);
    border: 1px solid var(--border);
    border-radius: 6px;
}
.sm-queue-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 8px;
    border-radius: 4px;
    font-size: 12px;
    transition: background 120ms ease, color 120ms ease, opacity 120ms ease;
}
.sm-queue-row[data-state="pending"]  { opacity: 0.55; }
.sm-queue-row[data-state="running"]  {
    background: color-mix(in srgb, var(--purple, #bc8cff) 18%, transparent);
    color: color-mix(in srgb, var(--purple, #bc8cff) 95%, white);
}
.sm-queue-row[data-state="done"]     {
    color: #8ee3a4;
    background: rgba(63, 185, 80, 0.08);
}
.sm-queue-row[data-state="failed"]   {
    color: #fca5a5;
    background: rgba(248, 81, 73, 0.10);
}
.sm-queue-num {
    font-variant-numeric: tabular-nums;
    font-size: 11px;
    color: var(--text-muted);
    min-width: 28px;
    flex-shrink: 0;
}
.sm-queue-label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 500;
}
.sm-queue-status {
    flex-shrink: 0;
    font-size: 11px;
    color: inherit;
    opacity: 0.85;
}

/* Sidebar "+ Click track" button next to the BPM value. Inherits
 * the standard .btn-sm footprint but sits inline so it tucks beside
 * the BPM number without pushing the row to two lines. */
.sidebar-click-btn {
    margin-left: 8px;
    padding: 4px 10px !important;
    height: auto !important;
    min-height: 0 !important;
    font-size: 11px !important;
    line-height: 1 !important;
    display: inline-flex;
    align-items: center;
    color: color-mix(in srgb, var(--purple, #bc8cff) 90%, white);
    background: color-mix(in srgb, var(--purple, #bc8cff) 12%, transparent);
    border-color: color-mix(in srgb, var(--purple, #bc8cff) 30%, transparent);
}
.sidebar-click-btn:hover {
    background: color-mix(in srgb, var(--purple, #bc8cff) 25%, transparent);
    border-color: color-mix(in srgb, var(--purple, #bc8cff) 50%, transparent);
    color: #fff;
}
/* Icon before the number: subtle dot for pending, spinner for
 * running, check for done, × for failed. Uses an ::before on the
 * .sm-queue-num so we don't need extra DOM. */
.sm-queue-num::before {
    content: "";
    display: inline-block;
    width: 8px;
    height: 8px;
    margin-right: 6px;
    border-radius: 50%;
    background: var(--text-muted);
    vertical-align: 0;
    transform: translateY(1px);
}
.sm-queue-row[data-state="running"] .sm-queue-num::before {
    background: color-mix(in srgb, var(--purple, #bc8cff) 95%, white);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--purple, #bc8cff) 30%, transparent);
    animation: sm-queue-pulse 1s ease-in-out infinite;
}
.sm-queue-row[data-state="done"] .sm-queue-num::before {
    background: #3fb950;
}
.sm-queue-row[data-state="failed"] .sm-queue-num::before {
    background: #f85149;
}
@keyframes sm-queue-pulse {
    0%, 100% { transform: translateY(1px) scale(1); }
    50%      { transform: translateY(1px) scale(1.3); }
}

#sidebar-chords .empty,
#sidebar-sections .empty {
    font-size: 12px;
    color: var(--text-muted);
    font-style: italic;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 4px 0;
}

.inline-detect {
    /* Inline Detect buttons in the sidebar are intentionally small —
     * override the global 36px .btn height so they don't dominate
     * their cards. */
    padding: 3px 10px;
    height: auto;
    min-height: 0;
    font-size: 11px;
    white-space: nowrap;
}

/* Banner (processing strip above layout) */
#banner {
    background: linear-gradient(90deg, rgba(88,166,255,0.15), rgba(88,166,255,0.05));
    border-bottom: 1px solid var(--accent);
    padding: 10px 20px;
    display: flex;
    align-items: center;
    gap: 12px;
    font-size: 12px;
    color: var(--text-secondary);
    z-index: 90;
}

#banner[hidden] { display: none; }

#banner.error {
    background: linear-gradient(90deg, rgba(248,81,73,0.15), rgba(248,81,73,0.05));
    border-bottom-color: var(--error);
}

#banner.success {
    background: linear-gradient(90deg, rgba(63,185,80,0.15), rgba(63,185,80,0.05));
    border-bottom-color: var(--success);
}

#banner .banner-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 6px var(--accent);
    animation: pulse 1.2s ease-in-out infinite;
    flex-shrink: 0;
}

#banner.error .banner-dot {
    background: var(--error);
    box-shadow: 0 0 6px var(--error);
}

#banner.success .banner-dot {
    background: var(--success);
    box-shadow: 0 0 6px var(--success);
    animation: none;
}

#banner .banner-text {
    flex: 1;
    color: var(--text-primary);
    font-weight: 500;
}

#banner .banner-bar {
    position: relative;
    width: 200px;
    height: 6px;
    background: var(--bg-primary);
    border: 1px solid var(--border);
    border-radius: 3px;
    overflow: hidden;
}

#banner .banner-fill {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    background: linear-gradient(
        90deg,
        rgba(31,111,235,0.35),
        rgba(88,166,255,0.4),
        rgba(188,140,255,0.35)
    );
    background-size: 200% 100%;
    animation: shimmer 2s linear infinite;
    transition: width 0.5s ease;
}

#banner .banner-pct {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--text-muted);
    min-width: 38px;
    text-align: right;
}

@keyframes shimmer {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

@keyframes pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}

/* Toasts */
#toasts {
    position: fixed;
    bottom: 16px;
    right: 16px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    z-index: 300;
    pointer-events: none;
}

.toast {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
    border-radius: 6px;
    color: var(--text-primary);
    font-size: 12px;
    max-width: 360px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.5);
    animation: slide-in 0.2s ease;
    pointer-events: auto;
    backdrop-filter: blur(4px);
}

.toast.toast-success { border-left-color: var(--success); }
.toast.toast-success .toast-icon { color: var(--success); }

.toast.toast-error { border-left-color: var(--error); }
.toast.toast-error .toast-icon { color: var(--error); }

.toast.toast-warning { border-left-color: var(--warning); }
.toast.toast-warning .toast-icon { color: var(--warning); }

.toast.toast-info { border-left-color: var(--accent); }
.toast.toast-info .toast-icon { color: var(--accent); }

.toast-icon {
    font-size: 14px;
    font-weight: 700;
    flex-shrink: 0;
}

.toast.fade-out {
    animation: slide-out 0.2s ease forwards;
}

@keyframes slide-in {
    from { transform: translateX(30px); opacity: 0; }
    to { transform: translateX(0); opacity: 1; }
}

@keyframes slide-out {
    to { transform: translateX(30px); opacity: 0; }
}

/* Timeline region (multi-stem view) — now the LEFT column */
#timeline {
    flex: 1 1 auto;
    min-width: 0;
    background: var(--bg-secondary);
    border-right: 1px solid var(--border);
    padding: 8px 16px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    overflow: hidden;
}

/* Two scroll-locked rails (chapters + chords) wrapped in one shared
 * card so they read as a single "markers" panel. Card padding aligns
 * with .stem-waveform-row so the 210px label column lines up with
 * the stem-controls column directly beneath. */
#waveform-rails {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 2px 12px 3px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    flex-shrink: 0;
}

/* Single-row grid: heading sits in the 210px label column on the
 * left, vertically centred with the lane on its right. */
.waveform-rail {
    display: grid;
    grid-template-columns: 210px 1fr;
    column-gap: 10px;
    align-items: center;
}
.waveform-rail + .waveform-rail {
    border-top: 1px solid color-mix(in srgb, var(--border) 50%, transparent);
    padding-top: 1px;
    margin-top: 1px;
}

.waveform-rail-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--text-secondary);
    text-align: left;
    line-height: 1;
    user-select: none;
}

.marker-lane {
    height: 20px;
    background: transparent;
    border: 0;
    position: relative;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
}

.marker-lane::-webkit-scrollbar { height: 0; display: none; }

/* Soft rounded corners at the lane's viewport edges — replaces the
 * previous mask-image fade. overflow-x: auto on .marker-lane already
 * clips horizontally; a small border-radius just rounds the edges
 * so a chapter / chord scrolling off doesn't meet a hard right-angle
 * cut. Applied to both marker lanes for visual consistency. */
#marker-lane-sections,
#marker-lane-chords {
    border-radius: 4px;
}

.marker-lane-content {
    position: relative;
    height: 100%;
    width: 100%;
}


#stem-rows {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 8px;
    overflow-y: auto;
    padding: 4px 4px 8px 0;
    min-height: 0;
}

/* Fit mode — CSS flex does the work: every row gets an equal share
 * of the available space via flex: 1 1 0; min-height: 0 lets them
 * shrink below their natural size; overflow: hidden clips anything
 * (inc. the controls column) that doesn't fit its slice. JS doesn't
 * compute heights any more — it just measures each row after layout
 * settles and tells wavesurfer to draw its canvas at that height. */
#stem-rows.fit-mode {
    /* Allow the column to scroll once the per-row min-height below
     * forces the combined stem height past the viewport. Without
     * overflow-y: auto the rows would get clipped at the edge. */
    overflow-y: auto;
}

/* Highlight the whole stem column while an external audio file is
 * being dragged over it so the user knows dropping will append. */
#stem-rows.is-drop-target {
    outline: 2px dashed var(--accent);
    outline-offset: -4px;
}

/* Persistent "drop more audio here" footer — thin dashed row at the
 * bottom of the stems list; doubles as a click-to-pick file picker.
 * Stays flex: 0 so it never steals vertical space from the stems. */
.stem-addmore-footer {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 36px;
    margin-top: 6px;
    border: 1px dashed color-mix(in srgb, var(--border) 70%, var(--accent));
    border-radius: var(--radius);
    background: color-mix(in srgb, var(--bg-card) 60%, transparent);
    color: var(--text-secondary);
    font-size: 12px;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.stem-addmore-footer:hover {
    background: color-mix(in srgb, var(--accent) 10%, var(--bg-card));
    border-color: var(--accent);
    color: var(--text-primary);
}
.stem-addmore-footer .stem-addmore-icon {
    display: inline-flex;
    width: 18px;
    height: 18px;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: color-mix(in srgb, var(--accent) 30%, transparent);
    color: var(--accent);
    font-weight: 700;
    font-size: 13px;
    line-height: 1;
}

#stem-rows.fit-mode .stem-waveform-row {
    flex: 1 1 0;
    min-height: 60px;
    overflow: hidden;
}

.stem-waveform-row {
    display: grid;
    grid-template-columns: 210px 1fr;
    gap: 10px;
    align-items: stretch;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 10px 12px;
}

.stem-waveform-row.muted {
    opacity: 0.45;
}

.stem-waveform-row.solo {
    border-color: var(--success);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--success) 35%, transparent);
}

.stem-waveform-row .stem-controls {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 0;
    justify-content: flex-start;
    padding: 4px 2px 6px;
    /* Pin the controls column to the wave height so it never forces
     * the grid row taller than the wave. min-height: 0 is critical —
     * without it CSS grid falls back to the column's min-content
     * height (all the controls stacked) and stretches the row. */
    height: var(--wave-h, 108px);
    min-height: 0;
    overflow: hidden;
}

/* Spacer absorbs the leftover vertical room between the name +
 * LMS/volume rows (pushed to the top) and the thin audio level bar
 * pinned at the bottom. */
.stem-waveform-row .stem-controls-spacer {
    flex: 1 1 auto;
    min-height: 0;
}

/* Segmented LED-style live level meter at the bottom of each stem's
 * controls column. Driven by StemPlayer.getLevel(slug) every animation
 * frame via MultiTimeline.updatePlayhead. */
.stem-waveform-row .stem-audio-bar {
    flex: 0 0 auto;
    height: 9px;
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: 2px;
    margin: 3px 2px 0;
    overflow: hidden;
    position: relative;
    /* Dark vertical gaps between LED segments — stacked ON TOP of
     * the fill via ::after so they cut through the gradient. */
}

.stem-waveform-row .stem-audio-bar::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: repeating-linear-gradient(
        to right,
        transparent 0,
        transparent 5px,
        var(--bg-secondary) 5px,
        var(--bg-secondary) 7px
    );
    z-index: 2;
}

.stem-waveform-row .stem-audio-bar-fill {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 0%;
    background: linear-gradient(
        to right,
        #39d353 0%,
        #39d353 55%,
        #e3b341 75%,
        #f85149 100%
    );
    box-shadow: 0 0 3px rgba(57, 211, 83, 0.5) inset;
    transition: width 0.06s linear;
    z-index: 1;
}

/* Compact (fit) mode keeps the level meter visible but shrinks the
 * spacer to nothing so it hugs the bottom edge of the tight card. */
.stem-waveform-row.compact .stem-controls-spacer {
    display: none;
}

.stem-waveform-row.compact .stem-audio-bar {
    height: 7px;
    /* margin-top: auto pushes the bar to the bottom of the card so
     * there's breathing room above it even on tight compact rows. */
    margin: auto 0 2px;
}

.stem-waveform-row .stem-name-row {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

/* Small role icon next to the track-number badge. Tint via
 * --role-fill (set per-row by JS from _roleColor) so it matches the
 * waveform + volume-bar colour. */
.stem-waveform-row .stem-name-row .stem-family-icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    color: var(--role-fill, var(--accent));
}
.stem-waveform-row .stem-name-row .stem-family-icon svg {
    width: 100%;
    height: 100%;
    display: block;
}
.stem-waveform-row.compact .stem-name-row .stem-family-icon {
    width: 14px;
    height: 14px;
}

/* Custom family picker — replaces the native <select> so each option
 * can display its instrument icon. Trigger matches the old select's
 * bordered-input look; menu is a floating card. */
.stem-family-picker {
    position: relative;
    display: block;
}
.stem-family-picker-trigger {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 6px;
    background: var(--bg-input);
    border: 1px solid var(--border);
    color: var(--text-secondary);
    font-size: 11px;
    font-family: var(--font);
    padding: 2px 6px 2px 4px;
    border-radius: 3px;
    cursor: pointer;
    min-height: 22px;
    text-align: left;
}
.stem-family-picker-trigger:hover {
    border-color: color-mix(in srgb, var(--accent) 40%, var(--border));
}
.stem-family-picker-trigger[aria-expanded="true"] {
    border-color: var(--accent);
    outline: none;
}
.stem-family-picker-icon {
    flex: 0 0 auto;
    width: 14px;
    height: 14px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--role-fill, var(--text-muted));
}
.stem-family-picker-icon svg {
    width: 100%;
    height: 100%;
    display: block;
}
.stem-family-picker-label {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.stem-family-picker-chevron {
    flex: 0 0 auto;
    width: 12px;
    height: 12px;
    opacity: 0.6;
}
.stem-family-picker-menu[hidden] { display: none !important; }
.stem-family-picker-menu {
    /* position: fixed so the menu isn't clipped by .stem-controls'
     * overflow: hidden (which caps the column to the wave height).
     * JS positions it based on the trigger's bounding-rect. */
    position: fixed;
    top: 0;
    left: 0;
    min-width: 160px;
    max-height: 280px;
    overflow-y: auto;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 4px;
    box-shadow: 0 6px 20px rgba(0,0,0,0.45);
    padding: 4px;
    z-index: 1000;
    display: flex;
    flex-direction: column;
    gap: 1px;
}
.stem-family-picker-option {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 5px 8px;
    background: transparent;
    border: 0;
    color: var(--text-secondary);
    font-size: 12px;
    font-family: var(--font);
    text-align: left;
    border-radius: 3px;
    cursor: pointer;
}
.stem-family-picker-option:hover {
    background: color-mix(in srgb, var(--accent) 10%, transparent);
    color: var(--text-primary);
}
.stem-family-picker-option.is-current {
    background: color-mix(in srgb, var(--accent) 18%, transparent);
    color: var(--text-primary);
}
.stem-family-picker-option-icon {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
}
.stem-family-picker-option-icon svg {
    width: 100%;
    height: 100%;
    display: block;
}
.stem-family-picker-option-label {
    flex: 1 1 auto;
}
.stem-waveform-row.compact .stem-family-picker { display: none; }

.stem-waveform-row .stem-num {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
    height: 20px;
    padding: 0 6px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 3px;
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 700;
    color: var(--text-muted);
    letter-spacing: 0.3px;
}

/* NOTE: the auto "role-vocal = blue badge" rule was removed because
 * it conflicted with the user-selected state — vocal stems always
 * looked "selected" and wouldn't appear to deselect. Only
 * .stem-waveform-row.selected paints the # badge blue now. */

/* User-selected stems — click the # badge to toggle. Selected stems
 * can be drag-reordered together as a contiguous block. JS owns the
 * .selected class + the drag mechanics; CSS just paints the badge so
 * the user can see which rows are in the selection. */
.stem-waveform-row.selected .stem-num {
    background: rgba(88,166,255,0.18);
    color: var(--accent);
    border-color: rgba(88,166,255,0.45);
    box-shadow: 0 0 0 1px rgba(88,166,255,0.25);
    cursor: grab;
}
.stem-waveform-row.selected .stem-num:active {
    cursor: grabbing;
}
.stem-waveform-row.dragging { opacity: 0.7; }
.stem-waveform-row.drop-above {
    box-shadow: 0 -2px 0 0 var(--accent);
}
.stem-waveform-row.drop-below {
    box-shadow: 0 2px 0 0 var(--accent);
}

.stem-waveform-row .stem-name-input {
    background: transparent;
    border: 1px solid transparent;
    color: var(--text-primary);
    font-size: 13px;
    font-weight: 600;
    padding: 2px 4px;
    border-radius: 3px;
    min-width: 0;
    flex: 1 1 0;
}

.stem-waveform-row .stem-name-input:hover {
    border-color: var(--border);
}

.stem-waveform-row .stem-name-input:focus {
    outline: none;
    background: var(--bg-input);
    border-color: var(--accent);
}

.stem-waveform-row .stem-family-select {
    background: var(--bg-input);
    border: 1px solid var(--border);
    color: var(--text-secondary);
    font-size: 11px;
    font-family: var(--font);
    padding: 2px 4px;
    border-radius: 3px;
    cursor: pointer;
}

.stem-waveform-row .stem-family-select:focus {
    outline: none;
    border-color: var(--accent);
}

.stem-waveform-row .stem-bottom-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.stem-waveform-row .stem-buttons {
    display: flex;
    gap: 4px;
    flex-shrink: 0;
}

.stem-waveform-row .stem-btn {
    width: 24px;
    height: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 3px;
    color: var(--text-secondary);
    font-size: 10px;
    font-weight: 700;
    cursor: pointer;
    padding: 0;
}

.stem-waveform-row.muted .stem-btn.mute {
    background: var(--error-dim);
    color: #fff;
    border-color: var(--error-dim);
}

.stem-waveform-row.solo .stem-btn.solo {
    background: var(--success);
    color: #fff;
    border-color: var(--success);
}

/* Split button is now icon-only (a Y "branch" glyph) so it matches
 * the square M/S/L/C buttons. Lives on its own row below LCMS so the
 * main control row stays tight. */
.stem-waveform-row .stem-btn.split {
    width: 24px;
    padding: 0;
}
.stem-waveform-row .stem-btn.split svg {
    display: block;
}
.stem-waveform-row .stem-btn.split.btn-armed {
    background: var(--warning, #d67e2a);
    color: #fff;
    border-color: var(--warning, #d67e2a);
}

/* Top-right translucent delete button floating over the stem card.
 * Anchored to the row (position: relative on the parent below).
 * Default is subtle so it doesn't shout at you; armed state goes
 * solid red so "one more click deletes" is unmistakable. */
.stem-waveform-row { position: relative; }
.stem-delete-btn {
    position: absolute;
    /* Compact rows at 5 / 8 px insets — close to the pre-nudge
     * baseline, with a one-pixel tweak each direction to line the
     * icon up with the compact card's chrome. Expanded rows
     * override both top and right below so the icon sits in the
     * right spot relative to the taller card's rounded corner. */
    top: 5px;
    right: 8px;
    width: 16px;
    height: 16px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    /* Square, slightly rounded to match the card's corner radius, with
     * a hair of padding from the border so it sits INSIDE the card
     * rather than tucked into the chrome. */
    border-radius: 4px;
    background: rgba(255, 255, 255, 0.05);
    color: var(--text-secondary);
    border: 1px solid rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    cursor: pointer;
    opacity: 0.5;
    transition: opacity 0.15s ease,
                background 0.15s ease,
                color 0.15s ease,
                border-color 0.15s ease;
    z-index: 3;
}
.stem-waveform-row:hover .stem-delete-btn {
    opacity: 1;
}
.stem-waveform-row:not(.compact) .stem-delete-btn {
    top: 12px;
    right: 14px;
}
.stem-delete-btn:hover {
    background: color-mix(in srgb, var(--error-dim, #da3633) 28%, rgba(0,0,0,0.4));
    color: #fff;
    border-color: color-mix(in srgb, var(--error-dim, #da3633) 55%, transparent);
}
.stem-delete-btn.is-armed {
    opacity: 1;
    background: var(--error-dim, #da3633);
    color: #fff;
    border-color: var(--error-dim, #da3633);
    animation: stem-delete-pulse 1.2s ease-in-out infinite;
}
@keyframes stem-delete-pulse {
    0%, 100% { box-shadow: inset 0 0 0 0 color-mix(in srgb, var(--error-dim, #da3633) 60%, transparent); }
    50%      { box-shadow: inset 0 0 0 2px color-mix(in srgb, #fff 45%, transparent); }
}

/* The source stem that was split gets renamed to "Split Source Stem"
 * and is muted by default so the new split products take over, but
 * when the user unmutes it we want it to look exactly like any other
 * stem — no permanent dim, no pill badge. Mute state alone now drives
 * the dim (see .stem-waveform-row.muted). */

.stem-waveform-row .stem-vol {
    flex: 1;
    min-width: 0;
    align-self: center;
}

.stem-waveform-row .stem-waveform {
    background: var(--bg-primary);
    border: 1px solid var(--border);
    border-radius: 4px;
    overflow-x: auto;
    overflow-y: hidden;
    min-width: 0;
    /* Lock the container's height to the wavesurfer canvas via the
     * per-row --wave-h custom property (set by _applyHeights). No
     * min-height floor and no align-self: stretch — otherwise the
     * bordered container stays 108 px tall while the canvas shrinks
     * inside it, making the waveform appear to "float" within its
     * border in the 60-108 range of the V zoom slider. */
    height: var(--wave-h, 108px);
    scrollbar-width: none;
}
.stem-waveform-row .stem-waveform::-webkit-scrollbar,
.stem-waveform-row .stem-waveform *::-webkit-scrollbar {
    width: 0 !important;
    height: 0 !important;
    display: none !important;
}
.stem-waveform-row .stem-waveform * {
    scrollbar-width: none;
    -ms-overflow-style: none;
}

/* Compact mode: visually a miniature of the full card — same vertical
   layout (name → family → mute/solo+vol → vocal button) just shrunk
   down so many stems fit on screen at once. Triggered automatically
   in fit mode and when manual Zoom V drops below 90 px. */
.stem-waveform-row.compact {
    padding: 3px 6px;
    gap: 6px;
    grid-template-columns: 150px 1fr;
}

.stem-waveform-row.compact .stem-controls {
    /* Same vertical column layout as full mode, just tighter.
     * Now that fit mode is CSS-flex driven (not JS pixel math), the
     * padding here can breathe a little without breaking anything —
     * flex will just clip the bottom if a card gets too short. */
    flex-direction: column;
    gap: 4px;
    padding: 4px 6px 4px 2px;
}

.stem-waveform-row.compact .stem-name-row {
    gap: 4px;
}

.stem-waveform-row.compact .stem-num {
    height: 16px;
    min-width: 20px;
    padding: 0 5px;
    font-size: 10px;
}

.stem-waveform-row.compact .stem-name-input {
    font-size: 11px;
    padding: 2px 6px;
    height: 16px;
}

/* Hide the family select in compact/fit mode — it's configuration,
 * not monitoring, and the full (non-fit) layout is where you'd
 * actually edit it. Recovered ~13 px of vertical budget per card. */
.stem-waveform-row.compact .stem-family-select {
    display: none;
}

.stem-waveform-row.compact .stem-bottom-row {
    gap: 4px;
    height: 11px;
}

.stem-waveform-row.compact .stem-buttons {
    gap: 2px;
}

.stem-waveform-row.compact .stem-btn {
    width: 16px;
    height: 11px;
    font-size: 8px;
}

/* Split SVG — the LCMS letters scale via font-size, but the <svg> has
 * a fixed width/height attribute so we have to shrink it explicitly
 * in compact mode to match the smaller button. */
.stem-waveform-row.compact .stem-btn.split svg {
    width: 8px;
    height: 8px;
}

.stem-waveform-row.compact .stem-vol {
    height: 11px;
}

.stem-waveform-row.compact .stem-vol::-webkit-slider-thumb {
    width: 9px;
    height: 9px;
}

.stem-waveform-row.compact .stem-vol::-moz-range-thumb {
    width: 9px;
    height: 9px;
}

/* Vocal source badge (V) sits inline with mute/solo — no special
 * compact override needed, just inherits the .stem-btn sizes above. */

.stem-waveform-row.compact .stem-waveform {
    min-height: 0;
}

/* Two visual treatments share the same .marker-bar element. The
 * fillLane() JS doesn't need to know which lane it's drawing into;
 * differentiation is done per-lane via the parent ID:
 *   #marker-lane-sections — chapters as soft tinted bands spanning
 *     the section's duration. Width tells you how long the part is.
 *   #marker-lane-chords   — chord changes as small pills hugging the
 *     chord text (NOT the duration), so they stay readable when chord
 *     density is high.
 * .current is toggled per-frame by highlightActiveSection() and
 * highlightActiveChord(); the eye tracks Verse → Chorus → Bridge and
 * chord changes during playback. */
.marker-bar {
    position: absolute;
    top: 0;
    bottom: 0;
    /* Inner horizontal padding keeps the label off the bar's rounded
     * corners so Verse / Chorus / Guitar Solo read cleanly instead
     * of crashing into either edge. */
    padding: 0 10px;
    display: flex;
    align-items: center;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.3px;
    white-space: nowrap;
    /* NOTE: deliberately NOT overflow:hidden. overflow:hidden on a
     * parent creates a scroll-container context for sticky children,
     * which would bind .marker-bar-label to the (non-scrolling) bar
     * instead of the outer .marker-lane and break the sticky effect.
     * Clipping now lives on the label itself. */
    pointer-events: none;
    border-radius: 3px;
    box-sizing: border-box;
}

/* Sticky chapter label — pins to the lane's visible left edge while
 * the bar's right edge is still on-screen, so a long chapter's name
 * stays readable no matter how far the user scrubs into it. */
.marker-bar-label {
    position: sticky;
    /* Extra sticky offset so the pinned label also sits clear of the
     * viewport edge when the bar scrolls partially out of view. */
    left: 10px;
    display: inline-block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

/* Chapters: soft tinted band, label inside */
#marker-lane-sections .marker-bar {
    background: color-mix(in srgb, var(--accent) 15%, transparent);
    color: color-mix(in srgb, var(--accent) 90%, white);
    text-transform: uppercase;
    letter-spacing: 0.8px;
    font-size: 10px;
    transition: background-color 90ms linear, color 90ms linear,
                box-shadow 90ms linear;
}
#marker-lane-sections .marker-bar.current {
    background: color-mix(in srgb, var(--accent) 45%, transparent);
    color: white;
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 65%, transparent);
}

/* Chords: small purple-tinted pill that hugs the chord text only —
 * NOT the chord's full duration. The duration width set inline by JS
 * is overridden so each pill shrinks to fit its label. */
#marker-lane-chords { cursor: pointer; }
#marker-lane-chords .marker-bar {
    width: auto !important;
    background: color-mix(in srgb, var(--purple) 18%, transparent);
    color: color-mix(in srgb, var(--purple) 90%, white);
    border: 0;
    border-radius: 3px;
    font-family: var(--font-mono);
    font-size: 11px;
    padding: 0 6px;
    cursor: pointer;
    /* The base .marker-bar rule disables pointer events so chapter
     * bars in the other lane don't eat clicks through the waveform.
     * Chord pills need the opposite — we WANT clicks on them so
     * users can edit / delete individual chords. Without this the
     * click landed on the lane background and got treated as
     * empty-space (create-new-chord). */
    pointer-events: auto;
    transition: background-color 90ms linear, color 90ms linear,
                box-shadow 90ms linear, transform 90ms ease-out;
}
/* Strong hover — chord pills are narrow; make the affordance obvious
 * so users see they're clickable before they commit. Outline picks up
 * the theme's purple at full saturation, label goes white, and the
 * pill lifts slightly so it reads as "pressable." */
#marker-lane-chords .marker-bar:hover {
    background: color-mix(in srgb, var(--purple) 55%, transparent);
    color: white;
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--purple) 80%, transparent),
                0 2px 6px color-mix(in srgb, var(--purple) 40%, transparent);
    transform: translateY(-1px);
    z-index: 2;
}
#marker-lane-chords .marker-bar.current:hover {
    background: color-mix(in srgb, var(--purple) 75%, transparent);
}
#marker-lane-chords .marker-bar.current {
    background: color-mix(in srgb, var(--purple) 60%, transparent);
    color: white;
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--purple) 70%, transparent);
    transform-origin: center;
    animation: chord-bulge 300ms ease-out;
    /* Bump the corner radius only during the bulge so the scaled-up
     * pill still reads as rounded. Resting pill stays at 3px to
     * match the non-highlighted pills around it. */
    border-radius: 7px;
}

/* One-shot pop when a chord first becomes current — the pill briefly
 * scales up then settles back to its highlighted resting state. */
@keyframes chord-bulge {
    0%   { transform: scale(1); }
    45%  { transform: scale(1.25); }
    100% { transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
    #marker-lane-chords .marker-bar.current {
        animation: none;
    }
}

/* Transport */
#transport {
    display: flex;
    align-items: center;
    gap: 4px 8px;
    padding-top: 4px;
}

#current-time, #total-time {
    font-family: var(--font-mono);
    font-size: 13px;
    color: var(--text-secondary);
    padding: 4px 8px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    /* Fixed width + tabular-nums so digits never reflow the row when
       the playhead updates each frame. min-width alone wasn't enough
       because the fallback font has proportional digits. */
    width: 88px;
    flex: 0 0 88px;
    text-align: center;
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum";
}

#current-time { color: var(--accent); }

/* The general rule `#transport button { height: 36px }` would beat a
 * plain `button.transport-btn` selector, so qualify ours with #transport
 * to win on specificity. Restores the original 30px transport height. */
#transport button.transport-btn {
    width: 36px;
    height: 30px;
    padding: 0 4px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

button.transport-btn svg {
    display: block;
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}

/* Transport button colour coding — the glyph takes the colour, the
   background stays neutral so the row reads as a tinted row of icons.
   Colours mirror the semantic groups the user already thinks in:
   navigation = blue, play = green, rate = amber, mix presets = violet. */
#transport button#btn-begin,
#transport button#btn-prev,
#transport button#btn-next,
#transport button#btn-end {
    color: #58a6ff;
}
#transport button#btn-begin:hover,
#transport button#btn-prev:hover,
#transport button#btn-next:hover,
#transport button#btn-end:hover {
    background: rgba(88,166,255,0.15);
    border-color: rgba(88,166,255,0.35);
}

#transport button#btn-playpause {
    color: #3fb950;
}
#transport button#btn-playpause:hover {
    background: rgba(63,185,80,0.18);
    border-color: rgba(63,185,80,0.4);
}

#transport button#btn-rate {
    color: #e3b341;
    font-weight: 600;
}
#transport button#btn-rate:hover {
    background: rgba(227,179,65,0.15);
    border-color: rgba(227,179,65,0.4);
}

#transport #mix-presets button.transport-btn {
    color: #bc8cff;
}
#transport #mix-presets button.transport-btn:hover {
    background: rgba(188,140,255,0.15);
    border-color: rgba(188,140,255,0.4);
}
#transport #mix-presets button.transport-btn.active {
    background: rgba(188,140,255,0.2);
    border-color: rgba(188,140,255,0.5);
    color: #d0b3ff;
}

/* Metronome button — lives inside #mix-presets but breaks out of the
 * purple mix-preset family with an amber/gold tone so the rhythm
 * control reads as a distinct category. Amber sits next to the
 * drums wave colour in _roleColor() so the click tool visually
 * connects with percussion work.
 * Click handler + pendulum animation live in app.js. */
#transport #mix-presets button.transport-btn.metronome-btn,
.metronome-btn {
    color: #d29922;
}
.metronome-btn .metronome-svg {
    overflow: visible; /* let the swinging arm escape the viewBox edges */
}
.metronome-btn .metronome-arm,
.metronome-btn .metronome-arm-weight {
    /* Rotate around the base of the pendulum (x=12 in the SVG's
     * coordinate system). transform-box: fill-box makes SVG honour
     * transform-origin in user-space units, which is what we want. */
    transform-box: fill-box;
    transform-origin: 50% 100%;
}
/* The weight's own origin needs to match the arm so they swing
 * together as one rigid pendulum. transform-box on the circle uses
 * its bounding box which is centred, so we shift the origin so the
 * circle pivots with the arm's base. Calculated: weight is at
 * y=12, arm base at y=21 — so the circle sits 9 units above its
 * pivot, which works out to 9/3 = 3 arm-lengths above centre. */
.metronome-btn .metronome-arm-weight {
    transform-origin: 50% calc(100% + 9px);
}
/* Rest state: pendulum vertical. The pendulum is JS-driven off the
 * audio clock (see _startMetronomeLoop in app.js) — the rAF loop sets
 * inline transforms only while playback is active. When play stops,
 * the loop clears the inline transform and this transition eases the
 * arm back to centre. */
.metronome-btn .metronome-arm,
.metronome-btn .metronome-arm-weight {
    transform: rotate(0deg);
    transition: transform 120ms ease-out;
}
.metronome-btn:hover {
    background: rgba(210, 153, 34, 0.15);
    border-color: rgba(210, 153, 34, 0.45);
    color: #f0c64a;
}
.metronome-btn.is-busy {
    pointer-events: none;
    /* Amber glow that pulses while the click track is generating —
     * reads as "actively working" far more clearly than a dim opacity
     * change, and matches the icon's own amber tint. */
    animation: metronome-glow 1.1s ease-in-out infinite alternate;
    color: #f0c64a;
}
.metronome-btn.is-busy .metronome-arm,
.metronome-btn.is-busy .metronome-arm-weight {
    /* While the server is generating the click track, a fast CSS
     * swing provides a "working" cue. The JS loop detects the busy
     * class and leaves inline transforms cleared so this animation
     * runs unopposed. */
    animation: metronome-swing 220ms ease-in-out infinite alternate;
    transition: none;
}
@keyframes metronome-swing {
    0%   { transform: rotate(-28deg); }
    100% { transform: rotate( 28deg); }
}
@keyframes metronome-glow {
    0% {
        box-shadow:
            0 0 0 0 rgba(210, 153, 34, 0.28),
            0 0 4px 1px rgba(210, 153, 34, 0.12) inset;
        background: rgba(210, 153, 34, 0.06);
        border-color: rgba(210, 153, 34, 0.30);
    }
    100% {
        box-shadow:
            0 0 8px 2px rgba(240, 198, 74, 0.38),
            0 0 14px 6px rgba(240, 198, 74, 0.16),
            0 0 6px 1px rgba(240, 198, 74, 0.22) inset;
        background: rgba(240, 198, 74, 0.12);
        border-color: rgba(240, 198, 74, 0.55);
    }
}
@media (prefers-reduced-motion: reduce) {
    .metronome-btn.is-busy { animation: none; }
    .metronome-btn.is-busy .metronome-arm,
    .metronome-btn.is-busy .metronome-arm-weight { animation: none; }
}

/* Unified slider styling — applied to every range input in the transport
   bar and the per-stem volume sliders */
.slider-value {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 48px;
    height: 22px;
    padding: 0 8px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 4px;
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 600;
    color: var(--accent);
    flex-shrink: 0;
    transition: border-color var(--transition), color var(--transition);
}

.slider-value.active {
    border-color: var(--accent);
    background: rgba(88,166,255,0.08);
}

#transport input[type="range"],
.stem-waveform-row .stem-vol {
    -webkit-appearance: none;
    appearance: none;
    height: 4px;
    border: none;
    border-radius: 2px;
    outline: none;
    cursor: pointer;
    margin: 0;
    padding: 0;
    /* The thumb is 3px wide (line-style). Native range inputs position
     * the thumb's CENTER at `thumbRadius + value/max * (width-thumbWidth)`
     * so the thumb never clips at the edges. We mirror that math in the
     * gradient so the fill always ends exactly at the thumb center. */
    --thumb-w: 3px;
    background: linear-gradient(
        to right,
        rgba(88,166,255,0.5) 0,
        rgba(88,166,255,0.5)
            calc(var(--thumb-w) / 2 + (100% - var(--thumb-w)) * var(--fill-ratio, 0)),
        rgba(255,255,255,0.07)
            calc(var(--thumb-w) / 2 + (100% - var(--thumb-w)) * var(--fill-ratio, 0)),
        rgba(255,255,255,0.07) 100%
    );
}

#transport #rate,
#transport #volume,
#transport #zoom-h,
#transport #zoom-v {
    flex: 1;
    min-width: 0;
    margin: 0 4px;
}

.stem-waveform-row .stem-vol {
    margin: 0 4px;
}

.transport-sliders {
    display: flex;
    gap: 2px;
    margin-left: auto;
    align-items: stretch;
    background: rgba(255,255,255,0.03);
    border: 1px solid rgba(255,255,255,0.06);
    border-radius: 8px;
    padding: 2px;
    flex-shrink: 1;
    min-width: 0;
}

.tslider {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 0 10px;
    border-radius: 6px;
    min-width: 80px;
    height: 25px;
    flex-shrink: 1;
    transition: background 0.15s ease;
}

.tslider-sm {
    min-width: 60px;
    padding: 0 8px;
}

.tslider:hover {
    background: rgba(255,255,255,0.04);
}

.tslider-head {
    display: flex;
    align-items: center;
    gap: 0;
    flex-shrink: 0;
}

.tslider-label {
    font-size: 8px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: rgba(255,255,255,0.3);
    line-height: 1;
}

.tslider-val {
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: rgba(255,255,255,0.55);
    line-height: 1;
    font-variant-numeric: tabular-nums;
    transition: color 0.15s ease;
    /* Reserve enough width for "100%" / "1.00x" so digit-count changes
     * (1→2→3 chars) don't reflow the surrounding sliders. Right-aligned
     * so the digits grow leftward into the reserved space. */
    display: inline-block;
    min-width: 32px;
    text-align: right;
    flex-shrink: 0;
}

.tslider:hover .tslider-val {
    color: rgba(255,255,255,0.8);
}

#transport input[type="range"]::-webkit-slider-thumb,
.stem-waveform-row .stem-vol::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 3px;
    height: 14px;
    border-radius: 1.5px;
    background: rgba(255,255,255,0.7);
    border: none;
    cursor: pointer;
    transition: background 0.12s ease, height 0.1s ease;
}

#transport input[type="range"]:hover::-webkit-slider-thumb,
.stem-waveform-row .stem-vol:hover::-webkit-slider-thumb {
    background: #fff;
    height: 16px;
}

#transport input[type="range"]:active::-webkit-slider-thumb,
.stem-waveform-row .stem-vol:active::-webkit-slider-thumb {
    background: var(--accent);
    height: 16px;
}

#transport input[type="range"]::-moz-range-thumb,
.stem-waveform-row .stem-vol::-moz-range-thumb {
    width: 3px;
    height: 14px;
    border-radius: 1.5px;
    background: rgba(255,255,255,0.7);
    border: none;
    cursor: pointer;
}

#transport input[type="range"]::-moz-range-track,
.stem-waveform-row .stem-vol::-moz-range-track {
    height: 4px;
    background: rgba(255,255,255,0.07);
    border-radius: 2px;
}

#transport input[type="range"]::-moz-range-progress,
.stem-waveform-row .stem-vol::-moz-range-progress {
    height: 4px;
    background: rgba(88,166,255,0.5);
    border-radius: 2px;
}

.transport-label {
    font-size: 11px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.4px;
    font-weight: 600;
}

/* Editor region */
#editor {
    flex: 0 0 420px;
    min-width: 360px;
    max-width: 520px;
    padding: 0;
    background: var(--bg-primary);
    border-left: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
    transition: flex-basis 0.18s ease, min-width 0.18s ease,
                max-width 0.18s ease, padding 0.18s ease;
}

#editor #lyrics-document {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 16px 20px;
    min-height: 0;
}

#editor-actions {
    flex: 0 0 auto;
    display: flex;
    gap: 8px;
    padding: 10px 14px;
    background: var(--bg-secondary);
    border-top: 1px solid var(--border);
}

#editor-actions .btn {
    flex: 1 1 0;
    min-width: 0;
}

/* Sync Lyrics popover: a small floating menu of languages, anchored
 * above the Sync Lyrics button. */
.lang-popover {
    z-index: 9999;
    min-width: 160px;
    max-height: 60vh;
    overflow-y: auto;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.35);
    padding: 4px;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    display: flex;
    flex-direction: column;
}

.lang-popover-item {
    appearance: none;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 6px;
    color: var(--text-primary);
    text-align: left;
    padding: 6px 12px;
    font: inherit;
    cursor: pointer;
    transition: border-color 0.1s ease, background 0.1s ease;
}

.lang-popover-item:hover {
    background: rgba(255,255,255,0.06);
    border-color: var(--accent, #4c8bf5);
}

.lang-popover-item.active {
    color: var(--accent, #4c8bf5);
    font-weight: 600;
}

@media (max-width: 1400px) {
    #editor {
        flex: 0 0 360px;
        min-width: 320px;
    }
}

#lyrics-document {
    max-width: none;
    margin: 0;
}

/* When not in project-editor mode, #editor needs to stop behaving
 * like a fixed right-hand lyric pane and let the inner content
 * (project list / merish manager / home) take the full available width. */
body[data-view="merish"] #editor,
body[data-view="projects"] #editor,
body[data-view="home"] #editor {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
    max-width: none;
    border-left: none;
    background: var(--bg-primary);
}

/* Home view needs the same full-flex layout as merish so its
 * three big tiles can actually sit side-by-side. */
body[data-view="home"] #editor #lyrics-document {
    flex: 1 1 auto;
    display: flex;
    min-height: 0;
    padding: 0;
}

body[data-view="projects"] #editor #lyrics-document {
    padding: 20px 28px;
}

/* In merish mode, thread flex all the way down so .merish-view can
 * fill the available vertical space and its file list can scroll. */
body[data-view="merish"] #editor #lyrics-document {
    flex: 1 1 auto;
    display: flex;
    min-height: 0;
    padding: 0;
}

body[data-view="merish"] #editor-actions,
body[data-view="projects"] #editor-actions {
    display: none;
}

.lyric-line {
    display: block;
    padding: 10px 12px 6px;
    border-left: 3px solid transparent;
    border-radius: 0;
    /* Lyric body — same family as the settings nav heading with
     * slight letter-spacing for chart-like readability. Size is
     * driven by the lyric_editor.font_size_px setting via the
     * --lyric-font-size CSS variable on #lyrics-document. */
    font-family: var(--font);
    font-size: var(--lyric-font-size, 15px);
    font-weight: 400;
    letter-spacing: 0.5px;
    /* Room for the chord superscript above each word without clashing
       with the line above. */
    line-height: 2.2;
    transition: background var(--transition);
    color: var(--text-primary);
}

.word-cell {
    display: inline-block;
    position: relative;
    vertical-align: bottom;
}

/* Chord sits as a superscript directly above the word, close enough to
   feel like part of the lyric line but with breathing room around it. */
.word-chord {
    display: block;
    position: absolute;
    left: 2px;
    bottom: 100%;
    margin-bottom: -8px;
    padding: 1px 4px;
    font-family: var(--font-mono);
    font-size: 12px;
    font-weight: 700;
    color: var(--purple);
    letter-spacing: 0.2px;
    line-height: 1;
    /* Click to add / edit a chord above the word. Empty slots get a
     * small "+" affordance on hover so they're discoverable. */
    pointer-events: auto;
    cursor: pointer;
    white-space: nowrap;
    border-radius: 3px;
    transition: background 0.12s ease, color 0.12s ease;
    min-width: 12px;
    min-height: 13px;
}
/* Strong hover — same treatment as the timeline chord rail so the
 * chord chip feels "pressable." Only applies to .has-chord so the
 * empty "+" placeholder slots stay subtle. */
.word-chord:hover { background: rgba(188,140,255,0.18); }
.word-chord.has-chord {
    transition: background 120ms ease, color 120ms ease,
                box-shadow 90ms linear, transform 90ms ease-out;
}
.word-chord.has-chord:hover {
    background: color-mix(in srgb, var(--purple) 55%, transparent);
    color: #fff;
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--purple) 80%, transparent),
                0 2px 6px color-mix(in srgb, var(--purple) 40%, transparent);
    transform: translateY(-1px);
    z-index: 2;
}
.word-chord.has-chord.current:hover {
    background: color-mix(in srgb, var(--purple) 75%, transparent);
}

/* Instrumental chord strip — shows chord chips for sections of the
   song with no lyrics (intros, solos, outros). Renders in the same
   scroll stream as the lyric lines so playback sync still maps
   correctly. */
.lyric-line.lyric-line-instrumental {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    padding: 6px 14px;
    opacity: 0.85;
    border-left-color: var(--purple);
    background: rgba(188,140,255,0.05);
}
.lyric-line-instrumental .instr-chord-label {
    font-size: 16px;
    color: var(--purple);
    opacity: 0.6;
    margin-right: 4px;
}
.lyric-line-instrumental .instr-chord-chip {
    position: static;
    margin: 0;
    padding: 3px 8px;
    background: color-mix(in srgb, var(--purple) 18%, transparent);
    border-radius: 4px;
    font-size: 12px;
    transition: background 120ms ease, color 120ms ease,
                box-shadow 90ms linear, transform 90ms ease-out;
}
.lyric-line-instrumental .instr-chord-chip:hover {
    background: color-mix(in srgb, var(--purple) 55%, transparent);
    color: #fff;
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--purple) 80%, transparent),
                0 2px 6px color-mix(in srgb, var(--purple) 40%, transparent);
    transform: translateY(-1px);
    z-index: 2;
}

/* Active chord in the lyrics view — matches the timeline pill: a
 * one-shot bulge when it first becomes current, then rests in the
 * highlighted state until the next chord takes over. */
.word-chord.has-chord.current {
    background: color-mix(in srgb, var(--purple) 55%, transparent);
    color: #fff;
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--purple) 70%, transparent);
    transform-origin: center;
    animation: word-chord-bulge 300ms ease-out;
}

@keyframes word-chord-bulge {
    0%   { transform: scale(1); }
    45%  { transform: scale(1.35); }
    100% { transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
    .word-chord.has-chord.current { animation: none; }
}
.word-cell:hover .word-chord:not(.has-chord)::before {
    content: "+";
    color: rgba(188,140,255,0.6);
    font-weight: 600;
    font-size: 11px;
}

/* Inline chord-edit popover */
.chord-edit-pop {
    z-index: 10000;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 6px;
    box-shadow: 0 6px 20px rgba(0,0,0,0.5);
    padding: 6px;
    display: flex;
    align-items: center;
    gap: 6px;
}
.chord-edit-pop input {
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-primary);
    font-family: var(--font-mono);
    font-size: 13px;
    padding: 4px 8px;
    width: 64px;
    outline: none;
}
.chord-edit-pop input:focus { border-color: var(--accent); }
.chord-edit-pop input.invalid { border-color: #f85149; }
/* Buttons inside the chord-edit popover are shorter than the standard
 * 36px .btn height — they match the inline input next to them. */
.chord-edit-pop .chord-edit-btn {
    height: 26px;
    min-height: 0;
    padding: 0 8px;
    font-size: 12px;
    line-height: 1;
}
.chord-edit-pop .chord-edit-btn svg { display: block; }
.chord-edit-err {
    flex-basis: 100%;
    color: #f85149;
    font-size: 11px;
    padding: 0 2px;
}

.lyric-line.playing {
    border-left-color: var(--accent);
    background: rgba(88,166,255,0.08);
}

/* Lines produced by the Transcribe step before Align is run — visible
 * but not followed by the playhead. */
.lyric-line.unaligned {
    opacity: 0.65;
    font-style: italic;
}

.lyric-line.unaligned::after {
    content: "needs sync";
    margin-left: 8px;
    padding: 1px 6px;
    font-family: var(--font);
    font-size: 9px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--warning);
    background: rgba(210,153,34,0.12);
    border: 1px solid rgba(210,153,34,0.3);
    border-radius: 3px;
    vertical-align: middle;
    font-style: normal;
}

.lyric-line.section-header {
    font-family: var(--font);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: var(--accent);
    padding: 14px 12px 4px;
    margin-top: 14px;
    border-left: none;
    border-bottom: 1px solid var(--border);
}

.lyric-line.section-header:first-child {
    margin-top: 0;
}

.word {
    display: inline-block;
    padding: 1px 3px;
    border-radius: 3px;
    cursor: pointer;
    transition: background var(--transition), color var(--transition);
}

.word:hover {
    background: rgba(88,166,255,0.12);
}

.word.selected {
    outline: 1px solid var(--accent);
    background: color-mix(in srgb, var(--accent) 15%, transparent);
}

/* Nudge feedback — brief flash on the word that just moved + a
 * floating "+50 ms" toast above it so the user can see WHAT got
 * nudged and HOW FAR. CSS-only animation so no JS cleanup needed
 * beyond removing the class once it's done playing. */
.word.nudged {
    animation: word-nudge-flash 0.55s ease-out;
    border-radius: 3px;
}

@keyframes word-nudge-flash {
    0%   { background: var(--accent); color: #fff; transform: scale(1.12); }
    60%  { background: color-mix(in srgb, var(--accent) 40%, transparent); transform: scale(1); }
    100% { background: color-mix(in srgb, var(--accent) 15%, transparent); color: inherit; transform: scale(1); }
}

.nudge-toast {
    position: fixed;
    transform: translate(-50%, -100%);
    background: var(--accent);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    padding: 4px 9px;
    border-radius: 11px;
    pointer-events: none;
    z-index: 9999;
    white-space: nowrap;
    font-family: var(--font-mono, ui-monospace, "SF Mono", Menlo, monospace);
    box-shadow: 0 4px 12px rgba(0,0,0,0.35);
    animation: nudge-toast-rise 0.7s ease-out forwards;
}

@keyframes nudge-toast-rise {
    0%   { opacity: 0; transform: translate(-50%, -50%); }
    25%  { opacity: 1; transform: translate(-50%, -110%); }
    100% { opacity: 0; transform: translate(-50%, -200%); }
}

.word.playing {
    background: rgba(88, 166, 255, 0.35);
    color: #fff;
    /* Deliberately NO font-weight change here — switching to bold mid-
     * line shifts the glyph widths and causes the surrounding words to
     * jump when the playhead crosses them. */
}

.word.low-confidence {
    color: var(--error);
    border-bottom: 1px dotted var(--error);
}

/* Inline edit state for a word or section header being typed into.
 * Uses orange (deliberately NOT the accent blue used for playing
 * words) so the user can see at a glance which element is in edit
 * mode versus which is just the playhead. */
.word.editing,
.lyric-line.section-header.editing {
    /* Punchier than the old faint orange — solid orange background
     * with white text and a bright accent ring so you can spot the
     * editing target instantly. */
    background: var(--orange, #f0883e);
    color: #fff;
    outline: 2px solid #ffd166;
    outline-offset: 2px;
    box-shadow: 0 0 0 4px rgba(240, 136, 62, 0.25),
                0 4px 14px rgba(240, 136, 62, 0.45);
    border-radius: 3px;
    cursor: text;
    font-weight: 700;
}

.lyric-line.section-header {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: grab;
}

.lyric-line.section-header.dragging {
    opacity: 0.4;
    cursor: grabbing;
}

.lyric-line.drop-above {
    box-shadow: inset 0 3px 0 0 var(--accent);
}

.lyric-line.drop-below {
    box-shadow: inset 0 -3px 0 0 var(--accent);
}

.lyric-line.section-header .section-label {
    cursor: pointer;
    padding: 2px 4px;
    border-radius: 3px;
    transition: color var(--transition), background var(--transition);
}

.lyric-line.section-header .section-label:hover {
    color: var(--accent);
    background: rgba(88,166,255,0.08);
}

.lyric-line.section-header .section-controls {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    opacity: 0;
    transition: opacity var(--transition);
}

.lyric-line.section-header:hover .section-controls,
.lyric-line.section-header .section-controls:focus-within {
    opacity: 1;
}

.section-ctrl-btn {
    width: 22px;
    height: 22px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 3px;
    color: var(--text-secondary);
    font-size: 12px;
    line-height: 1;
    cursor: pointer;
    padding: 0;
    transition: all var(--transition);
}

.section-ctrl-btn:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
    border-color: var(--border-light);
}

.section-ctrl-btn.danger:hover {
    background: var(--error-dim);
    color: #fff;
    border-color: var(--error-dim);
}

/* "+ Chapter" insertion button — floats at the top-right of every
 * lyric line on hover, so the user can insert a chapter break right
 * before the line without going through a chapter header's own +. */
.lyric-line {
    position: relative;
}

.line-chapter-insert {
    position: absolute;
    top: -10px;
    right: 12px;
    height: 20px;
    padding: 0 8px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 10px;
    color: var(--accent);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    line-height: 1;
    cursor: pointer;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--transition);
    z-index: 2;
}

.lyric-line:hover .line-chapter-insert {
    opacity: 1;
    pointer-events: auto;
}

.line-chapter-insert:hover {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
}

/* lyric_editor.timestamp_display:
 *   hidden   → no timestamps anywhere
 *   on_hover → only on word hover (default; uses native title attr)
 *   always   → numeric range under each word
 */
#lyrics-document[data-timestamps="hidden"] .word { -webkit-user-modify: read-only; }
#lyrics-document[data-timestamps="hidden"] .word::after { content: none !important; }

#lyrics-document[data-timestamps="always"] .word::after {
    content: attr(data-start-ms) "→" attr(data-end-ms);
    display: inline-block;
    margin-left: 4px;
    padding: 0 4px;
    font-family: var(--font-mono);
    font-size: 9px;
    color: var(--text-muted);
    background: var(--bg-tertiary);
    border-radius: 3px;
    vertical-align: super;
}

/* lyric_editor.currently_playing_style — overrides the default
 * .word.playing rule above based on the user's preference. */
#lyrics-document[data-playing-style="highlight_only"] .word.playing {
    background: rgba(88, 166, 255, 0.35);
    color: #fff;
    font-weight: 400;
}
#lyrics-document[data-playing-style="border_only"] .word.playing {
    background: transparent;
    color: var(--text-primary);
    outline: 2px solid var(--accent);
    font-weight: 400;
}
#lyrics-document[data-playing-style="bold_only"] .word.playing {
    background: transparent;
    color: var(--accent);
    /* No font-weight change — would shift surrounding glyphs */
    text-shadow: 0 0 1px var(--accent);
}

/* lyric_editor.uppercase — render every lyric word in CAPS without
 * mutating the underlying data. */
#lyrics-document[data-uppercase="true"] .word,
#lyrics-document[data-uppercase="true"] .lyric-line.section-header {
    text-transform: uppercase;
}

/* Project list (shown when no ?project=) */
.project-list {
    max-width: 820px;
    margin: 40px auto;
}

.project-list h2 {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: var(--text-muted);
    margin: 0 0 16px;
}

.project-list-toolbar {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 12px;
}

/* Home view is a clean workspace picker — strip the header nav down
 * to nothing so only the logo + three tiles are on screen. */
/* Home is a clean landing page: hide every chrome element so only the
 * hero + 3 cards remain. The editor's .layout stays in DOM (so going
 * back to it doesn't reload stems) but is hidden from view. */
/* Account tab — matches the .set-row idiom of the other tabs.
   Inputs use the same 7px/10px padding as .set-row inputs elsewhere,
   so they're the same height as Chord/Lyric/MTA tab fields. */
.set-section[data-section="account"] input[type="email"],
.set-section[data-section="account"] input[type="password"],
.set-section[data-section="account"] input[type="text"] {
    width: 100%;
    max-width: 360px;
    padding: 7px 10px;
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-primary);
    font-size: 13px;
    font-family: inherit;
    box-sizing: border-box;
}
.set-section[data-section="account"] input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(88,166,255,0.15);
}
.set-section[data-section="account"] input:disabled {
    opacity: 0.6;
}
/* Account-tab buttons sit alongside short form inputs; the global 36px
 * .btn looks chunky here. Shrink them to match the input scale. */
.set-section[data-section="account"] .btn {
    height: auto;
    padding: 6px 14px;
    font-size: 12px;
}
.set-section[data-section="account"] .btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}
.acct-field-row {
    display: flex;
    align-items: center;
    gap: 8px;
    max-width: 480px;
}
.acct-field-row input { flex: 1; }
.acct-confirm-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 8px;
    max-width: 480px;
}
.acct-confirm-row input { flex: 1; }
.btn-armed {
    background: rgba(248, 81, 73, 0.20) !important;
    border-color: rgba(248, 81, 73, 0.50) !important;
    color: var(--error, #f85149) !important;
}
.acct-pw-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    max-width: 480px;
}
.acct-action-row {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 10px;
}
.acct-status {
    font-size: 12px;
    color: var(--text-muted, #6e7681);
}
.acct-status.ok    { color: var(--success, #3fb950); }
.acct-status.error { color: var(--error, #f85149); }

.acct-sessions {
    margin-top: 4px;
    margin-bottom: 8px;
    max-width: 540px;
    border: 1px solid var(--border);
    border-radius: 6px;
    overflow: hidden;
    background: var(--bg-card, #1c2333);
}
.acct-sessions-loading,
.acct-sessions-empty {
    padding: 14px 16px;
    color: var(--text-muted);
    font-size: 12px;
}
.acct-session {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
}
.acct-session:last-child { border-bottom: 0; }
.acct-session-main { flex: 1; min-width: 0; }
.acct-session-device {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-primary);
    display: flex;
    align-items: center;
    gap: 8px;
}
.acct-session-tag {
    background: rgba(88, 166, 255, 0.15);
    color: var(--accent, #58a6ff);
    font-size: 10px;
    padding: 2px 8px;
    border-radius: 999px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
}
.acct-session-meta {
    margin-top: 2px;
    font-size: 11px;
    color: var(--text-muted);
}

/* Top-right corner of home: signed-in identity + Sign out, or a
 * compact "Sign in" entry-point. Sits above the cards. */
.home-corner {
    position: absolute;
    top: 18px;
    right: 24px;
    z-index: 5;
    display: flex;
    align-items: center;
    gap: 12px;
    font-size: 12px;
    color: var(--text-muted, #6e7681);
}
.home-corner-me strong {
    color: var(--text-secondary, #8b949e);
    font-weight: 600;
}
.home-corner-btn {
    border: 1px solid rgba(255, 255, 255, 0.10);
    background: rgba(255, 255, 255, 0.05);
    color: var(--text-primary, #e6edf3);
    padding: 6px 14px;
    border-radius: 6px;
    cursor: pointer;
    font: inherit;
    font-size: 12px;
    transition: background 0.15s, border-color 0.15s;
}
.home-corner-btn:hover {
    background: rgba(255, 255, 255, 0.10);
    border-color: rgba(255, 255, 255, 0.20);
}

/* ──────────────────────────────────────────────────────────────────────
 * Inline login form rendered into a home card when an anonymous user
 * clicks it. The card keeps its size + position; the inner content is
 * swapped to the form. Cancel (×) restores the original markup.
 * ──────────────────────────────────────────────────────────────────── */
.home-card.is-login {
    overflow: hidden;
}
.home-card.is-login .home-card-shot,
.home-card.is-login .home-card-glass {
    display: none !important;
}
.home-card-login {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(circle at 20% 0%, rgba(76,139,245,0.18), transparent 55%),
        radial-gradient(circle at 100% 100%, rgba(188,100,255,0.16), transparent 55%),
        rgba(13, 17, 23, 0.96);
    backdrop-filter: blur(14px) saturate(1.2);
    -webkit-backdrop-filter: blur(14px) saturate(1.2);
    display: flex;
    flex-direction: column;
    padding: 26px 24px 22px;
    color: var(--text-primary, #e6edf3);
    border-radius: 16px;
    border: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
    z-index: 10;
    animation: home-card-login-in 0.18s ease;
}
@keyframes home-card-login-in {
    from { opacity: 0; transform: scale(0.97); }
    to { opacity: 1; transform: scale(1); }
}
.home-card-login-x {
    position: absolute;
    top: 10px;
    right: 12px;
    width: 30px;
    height: 30px;
    border: 0;
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-muted, #6e7681);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    border-radius: 8px;
    padding: 0;
    transition: background 0.15s, color 0.15s;
}
.home-card-login-x:hover {
    color: var(--text-primary, #e6edf3);
    background: rgba(255, 255, 255, 0.10);
}
.home-card-login-body {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: stretch;
    gap: 14px;
}
.home-card-login-body[hidden] { display: none; }
.home-card-login-mark {
    display: flex;
    justify-content: center;
    margin-bottom: 2px;
}
.home-card-login-title {
    font-size: 22px;
    font-weight: 700;
    text-align: center;
    letter-spacing: -0.3px;
    background: linear-gradient(135deg, #6aa2ff, #bc64ff);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
.home-card-login-sub {
    margin-top: -8px;
    font-size: 13px;
    text-align: center;
    color: var(--text-secondary, #8b949e);
}
.home-card-login-form {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 6px;
}
.home-card-login-field {
    display: flex;
    flex-direction: column;
    gap: 5px;
    text-align: left;
}
.home-card-login-field > span {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    color: var(--text-muted, #6e7681);
}
.home-card-login-form input {
    background: rgba(0, 0, 0, 0.32);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 8px;
    padding: 11px 14px;
    color: var(--text-primary, #e6edf3);
    font: inherit;
    font-size: 14px;
    outline: 0;
    transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;
}
.home-card-login-form input::placeholder { color: var(--text-muted, #6e7681); }
/* Honeypot trap — invisible to humans, visible to dumb form-fillers.
 * Positioned absolute off-screen rather than display:none so motivated
 * bots that skip-non-rendered fields still see it in the DOM. */
.hp-trap {
    position: absolute !important;
    left: -9999px !important;
    top: -9999px !important;
    width: 1px !important;
    height: 1px !important;
    overflow: hidden !important;
    opacity: 0 !important;
    pointer-events: none !important;
    tab-size: 0;
}
.home-card-login-form input:focus {
    border-color: rgba(108, 140, 250, 0.6);
    box-shadow: 0 0 0 3px rgba(88, 166, 255, 0.18);
    background: rgba(0, 0, 0, 0.45);
}
.home-card-login-submit {
    margin-top: 4px;
    height: 42px;
    border: 0;
    border-radius: 8px;
    background: linear-gradient(135deg, #4c8bf5 0%, #6f7af8 50%, #bc64ff 100%);
    color: #fff;
    font: inherit;
    font-weight: 600;
    font-size: 14px;
    letter-spacing: 0.2px;
    cursor: pointer;
    transition: transform 0.1s, filter 0.15s, box-shadow 0.15s;
    box-shadow: 0 4px 14px rgba(76, 139, 245, 0.32);
}
.home-card-login-submit:hover {
    filter: brightness(1.08);
    box-shadow: 0 6px 20px rgba(76, 139, 245, 0.42);
}
.home-card-login-submit:active { transform: translateY(1px); }
.home-card-login-submit:disabled {
    opacity: 0.55; cursor: wait; filter: none;
    box-shadow: none;
}
.home-card-login-msg {
    min-height: 16px;
    font-size: 12px;
    color: var(--text-muted, #6e7681);
    text-align: center;
}
.home-card-login-msg.error { color: var(--error, #f85149); }
.home-card-login-msg.ok { color: var(--success, #3fb950); }
.home-card-login-divider {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 4px 0;
    color: var(--text-muted, #6e7681);
    font-size: 10px;
    letter-spacing: 1px;
    text-transform: uppercase;
}
.home-card-login-divider::before,
.home-card-login-divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background: rgba(255, 255, 255, 0.06);
}
.home-card-login-social {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
}
.home-card-login-soc {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 40px;
    border: 1px solid rgba(255, 255, 255, 0.10);
    background: rgba(255, 255, 255, 0.04);
    border-radius: 8px;
    text-decoration: none;
    transition: background 0.15s, border-color 0.15s, transform 0.1s;
}
.home-card-login-soc:hover {
    background: rgba(255, 255, 255, 0.10);
    border-color: rgba(255, 255, 255, 0.20);
}
.home-card-login-soc:active { transform: translateY(1px); }
.home-card-login-soc[aria-disabled="true"] {
    opacity: 0.45;
    cursor: not-allowed;
    pointer-events: none;
}

.home-card-login-links {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    font-size: 13px;
    color: var(--text-muted, #6e7681);
}
.home-card-login-links a {
    color: var(--accent, #58a6ff);
    text-decoration: none;
    font-weight: 500;
    transition: opacity 0.15s;
}
.home-card-login-links a:hover { opacity: 0.85; text-decoration: underline; }
.home-card-login-links .dot { opacity: 0.5; }

/* Hide the editor's chrome on home — but ONLY the editor's main
 * #header, never every <header> element. The merish overlay's device
 * card is a <header class="merish-device-card"> and an unscoped rule
 * here was nuking it whenever the overlay opened from the home view.
 * NOTE: #app-footer is intentionally NOT hidden on home — the global
 * site footer (Contact / Privacy / Terms / Disclaimer) shows on every
 * view now, replacing the per-view "home-footer" we used to inline. */
body[data-view="home"] #header,
body[data-view="home"] #banner,
body[data-view="home"] .layout { display: none !important; }
body[data-view="home"] #home-page { display: flex !important; flex: 1 1 auto; }

/* Until JS decides which view to show, hide every potential view so
   we don't flash the editor chrome before bouncing to home. The
   site-wide footer is fine to leave visible during boot. */
body[data-view="booting"] header,
body[data-view="booting"] #banner,
body[data-view="booting"] .layout,
body[data-view="booting"] #home-page { display: none !important; }
body[data-view="booting"] { background: var(--bg-app, #0d1117); }

#home-page { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
#home-page[hidden] { display: none; }

/* ============================================================
 * Home view — landing page with 3 mock-screenshot tiles
 * ============================================================ */
.home-view {
    position: relative;
    flex: 1 1 auto;
    width: 100%;
    min-height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    padding: 32px 24px 48px;
    box-sizing: border-box;
    overflow-y: auto;
}

/* Background pattern + ambient glows */
.home-bg {
    position: absolute;
    inset: 0;
    pointer-events: none;
    overflow: hidden;
    z-index: 0;
}
.home-bg-dots {
    position: absolute;
    inset: 0;
    background-image:
        radial-gradient(circle, rgba(255,255,255,0.045) 1px, transparent 1px);
    background-size: 22px 22px;
    background-position: 0 0;
    mask-image: radial-gradient(ellipse at 50% 50%, #000 30%, transparent 80%);
    -webkit-mask-image: radial-gradient(ellipse at 50% 50%, #000 30%, transparent 80%);
}
.home-bg-glow {
    position: absolute;
    width: 720px; height: 720px;
    border-radius: 50%;
    filter: blur(120px);
    opacity: 0.35;
}
.home-bg-glow-1 {
    background: radial-gradient(circle, rgba(76, 139, 245, 0.55), transparent 70%);
    top: -200px; left: -180px;
}
.home-bg-glow-2 {
    background: radial-gradient(circle, rgba(188, 100, 255, 0.45), transparent 70%);
    bottom: -240px; right: -200px;
}

.home-hero {
    position: relative;
    z-index: 1;
    text-align: center;
    margin: 8px 0 28px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
}
.home-logo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    filter: drop-shadow(0 8px 28px rgba(76, 139, 245, 0.35));
}
.home-title {
    margin: 0;
    font-size: 56px;
    font-weight: 700;
    letter-spacing: -1.2px;
    /* Same blue→purple gradient as the editor's header brand-text. */
    background: linear-gradient(135deg, var(--accent), var(--purple));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    color: transparent;
    text-shadow: 0 2px 30px rgba(76, 139, 245, 0.18);
}
.home-tagline {
    margin: 6px 0 0;
    font-size: 15px;
    color: var(--text-secondary);
    letter-spacing: 0.3px;
}

.home-cards {
    position: relative;
    z-index: 1;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 28px;
    width: 100%;
    max-width: 1280px;
    align-items: stretch;
    /* Breathing room between the cards and the sticky footer. */
    margin-bottom: 48px;
}
@media (max-width: 980px) {
    .home-cards { grid-template-columns: 1fr; max-width: 480px; }
}

.home-card {
    position: relative;
    aspect-ratio: 4 / 5.4;
    min-height: 540px;
    border-radius: 16px;
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    cursor: pointer;
    background: linear-gradient(180deg, rgba(255,255,255,0.04), rgba(255,255,255,0.01));
    border: 1px solid rgba(255,255,255,0.08);
    box-shadow:
        0 1px 0 rgba(255,255,255,0.05) inset,
        0 12px 40px rgba(0,0,0,0.45);
    transition:
        transform 0.25s cubic-bezier(.2,.8,.2,1),
        border-color 0.25s ease,
        box-shadow 0.25s ease;
    isolation: isolate;
}
.home-card:hover {
    transform: translateY(-4px);
    border-color: rgba(76, 139, 245, 0.55);
    box-shadow:
        0 1px 0 rgba(255,255,255,0.08) inset,
        0 18px 48px rgba(0,0,0,0.55),
        0 0 0 1px rgba(76, 139, 245, 0.25);
}
.home-card-feature {
    /* Centre tile gets a subtle accent border so the user's eye
     * lands there first (it's the primary action). */
    border-color: rgba(76, 139, 245, 0.35);
}
.home-card-feature:hover { border-color: rgba(76, 139, 245, 0.75); }

/* Mock-screenshot layer — heavily blurred so it reads as a "screenshot
 * behind frosted glass" rather than a precise UI mock. */
.home-card-shot {
    position: absolute;
    inset: 0;
    padding: 18px;
    background: linear-gradient(160deg, #1a2230 0%, #0e1420 100%);
    filter: blur(2.5px) saturate(1.1);
    transform: scale(1.04);
    transition: filter 0.25s ease, transform 0.25s ease;
    overflow: hidden;
}
.home-card:hover .home-card-shot {
    filter: blur(1.5px) saturate(1.15);
    transform: scale(1.06);
}

/* Real-screenshot variant — stretch the screenshot to fill the whole
 * card (height AND width). Aspect ratio not preserved; nothing crops. */
.home-card-shot.home-shot-image {
    padding: 0;
    background-size: 100% 100%;
    background-position: center;
    background-repeat: no-repeat;
    background-color: #0e1420;
}

/* Glass-morphism caption — the readable label sits in the bottom
 * 35% over a frosted gradient. */
.home-card-glass {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    padding: 22px 24px 24px;
    background: linear-gradient(
        180deg,
        rgba(8, 12, 20, 0) 0%,
        rgba(8, 12, 20, 0.78) 55%,
        rgba(8, 12, 20, 0.92) 100%);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}
.home-card-logo {
    margin-bottom: 8px;
    display: inline-flex;
    align-items: center;
    filter: drop-shadow(0 4px 14px rgba(0,0,0,0.5));
}
.home-card-title {
    font-size: 24px;
    font-weight: 600;
    color: #fff;
    letter-spacing: 0.2px;
    text-shadow: 0 2px 8px rgba(0,0,0,0.6);
}
.home-card-sub {
    margin-top: 4px;
    font-size: 13px;
    color: rgba(180, 188, 200, 0.75);
    text-shadow: 0 1px 3px rgba(0,0,0,0.6);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.home-card-detail {
    margin: 12px 0 0;
    font-size: 12px;
    line-height: 1.55;
    color: rgba(170, 178, 190, 0.78);
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
    padding-top: 12px;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
}
.home-card-detail code {
    background: rgba(0, 0, 0, 0.35);
    padding: 1px 6px;
    border-radius: 4px;
    font-size: 11px;
    font-family: ui-monospace, "SF Mono", "Cascadia Code", monospace;
}

/* ===== Projects mock-screenshot ===== */
.home-shot-projects {
    display: flex; flex-direction: column; gap: 14px;
}
.hps-toolbar {
    display: flex; gap: 8px; align-items: center;
    padding-bottom: 10px;
    border-bottom: 1px solid rgba(255,255,255,0.05);
}
.hps-pill {
    width: 50px; height: 18px; border-radius: 9px;
    background: rgba(255,255,255,0.08);
}
.hps-pill:nth-child(2) { width: 80px; }
.hps-pill:nth-child(3) { width: 36px; background: rgba(76,139,245,0.35); }
.hps-rows {
    display: flex; flex-direction: column; gap: 8px;
}
.hps-row {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 12px;
    border-radius: 8px;
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.05);
}
.hps-row.active {
    background: rgba(76, 139, 245, 0.14);
    border-color: rgba(76, 139, 245, 0.4);
}
.hps-thumb {
    width: 28px; height: 28px; border-radius: 5px;
    background: linear-gradient(135deg, rgba(76,139,245,0.4), rgba(188,140,255,0.4));
    flex-shrink: 0;
}
.hps-text {
    height: 8px; border-radius: 3px;
    background: rgba(255,255,255,0.18);
}
.hps-text.wide   { flex: 1; }
.hps-text.mid    { flex: 0.7; }
.hps-text.narrow { flex: 0.45; }
.hps-text.small  { width: 36px; height: 6px; opacity: 0.6; }

/* ===== MTAedit mock-screenshot ===== */
.home-shot-editor {
    display: flex; flex-direction: column; gap: 12px;
}
.hes-transport {
    display: flex; gap: 8px; align-items: center;
    padding-bottom: 8px;
    border-bottom: 1px solid rgba(255,255,255,0.05);
}
.hes-pill {
    width: 22px; height: 22px; border-radius: 5px;
    background: rgba(255,255,255,0.08);
}
.hes-pill.wide { width: 80px; background: rgba(76,139,245,0.25); }
.hes-stems {
    display: flex; flex-direction: column; gap: 6px;
}
.hes-stem {
    display: flex; align-items: center; gap: 8px;
    padding: 6px 8px;
    background: rgba(255,255,255,0.03);
    border: 1px solid rgba(255,255,255,0.05);
    border-radius: 6px;
}
.hes-stem.active {
    border-color: rgba(76, 139, 245, 0.5);
    background: rgba(76, 139, 245, 0.10);
}
.hes-name {
    width: 36px; height: 8px; border-radius: 3px;
    background: rgba(255,255,255,0.2);
    flex-shrink: 0;
}
.hes-stem svg {
    flex: 1; height: 24px;
    fill: none;
    stroke: rgba(76, 139, 245, 0.55);
    stroke-width: 1.5;
    stroke-linecap: round;
}
.hes-stem.active svg { stroke: rgba(120, 180, 255, 0.85); }
.hes-lyrics {
    margin-top: 8px;
    padding: 12px 14px;
    background: rgba(255,255,255,0.03);
    border: 1px solid rgba(255,255,255,0.05);
    border-radius: 6px;
    display: flex; flex-direction: column; gap: 8px;
}
.hes-line {
    height: 10px; border-radius: 3px;
    background: rgba(255,255,255,0.16);
}
.hes-line.short { width: 60%; }
.hes-line.active {
    background: linear-gradient(90deg, rgba(76,139,245,0.85), rgba(188,140,255,0.7));
    box-shadow: 0 0 8px rgba(76,139,245,0.4);
}

/* ===== Merish Manager mock-screenshot ===== */
.home-shot-merish {
    display: flex; flex-direction: column; gap: 14px;
}
.hms-bar {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 12px;
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.06);
    border-radius: 8px;
}
.hms-dot {
    width: 8px; height: 8px; border-radius: 50%;
    background: rgba(255,255,255,0.3);
    flex-shrink: 0;
}
.hms-dot.connected {
    background: #4caf50;
    box-shadow: 0 0 8px rgba(76, 175, 80, 0.6);
}
.hms-name {
    flex: 1; height: 8px; border-radius: 3px;
    background: rgba(255,255,255,0.18);
    max-width: 120px;
}
.hms-files {
    display: flex; flex-direction: column; gap: 6px;
}
.hms-file {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 10px;
    background: rgba(255,255,255,0.03);
    border: 1px solid rgba(255,255,255,0.04);
    border-radius: 6px;
}
.hms-icon {
    width: 14px; height: 14px; border-radius: 3px;
    background: rgba(76, 139, 245, 0.55);
    flex-shrink: 0;
}
.hms-text {
    height: 8px; border-radius: 3px;
    background: rgba(255,255,255,0.16);
}
.hms-text.wide   { flex: 1; }
.hms-text.mid    { flex: 0.7; }
.hms-text.narrow { flex: 0.45; }
.hms-meta {
    width: 28px; height: 6px; border-radius: 3px;
    background: rgba(255,255,255,0.1);
    flex-shrink: 0;
}

/* ===== Features section ===== */
.home-features {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: 1280px;
    margin: 80px auto 0;
    text-align: center;
}
.home-section-heading {
    font-size: 28px;
    font-weight: 600;
    margin: 0 0 8px;
    background: linear-gradient(135deg, #ffffff 0%, #b6c2d4 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
.home-section-lead {
    font-size: 15px;
    line-height: 1.6;
    color: var(--text-secondary);
    max-width: 720px;
    margin: 0 auto 40px;
}
.home-feature-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 28px;
    text-align: left;
}
@media (max-width: 900px) {
    .home-feature-grid { grid-template-columns: 1fr; }
}
.home-feature {
    padding: 22px 22px 20px;
    background: linear-gradient(180deg, rgba(255,255,255,0.04), rgba(255,255,255,0.01));
    border: 1px solid rgba(255,255,255,0.07);
    border-radius: 12px;
    transition: border-color 0.2s ease, transform 0.2s ease, background 0.2s ease;
}
.home-feature:hover {
    border-color: rgba(76, 139, 245, 0.35);
    transform: translateY(-2px);
    background: linear-gradient(180deg, rgba(76,139,245,0.06), rgba(255,255,255,0.01));
}
.home-feature-icon {
    width: 40px; height: 40px;
    border-radius: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, rgba(76,139,245,0.18), rgba(188,140,255,0.12));
    border: 1px solid rgba(76,139,245,0.25);
    color: #b8d4ff;
    margin-bottom: 14px;
}
.home-feature h3 {
    margin: 0 0 6px;
    font-size: 15px;
    font-weight: 600;
    color: var(--text-primary);
}
.home-feature p {
    margin: 0;
    font-size: 13px;
    line-height: 1.5;
    color: var(--text-secondary);
}

/* ---------- Merish device manager view ---------- */

.merish-view {
    flex: 1 1 auto;
    width: 100%;
    max-width: none;
    margin: 0;
    padding: 12px 16px 16px;
    display: flex;
    flex-direction: column;
    gap: 14px;
    min-height: 0;
}
/* Disconnected state: the help panel is taller than the viewport, so let
   the whole view scroll (the connected file list keeps its own internal
   scroll, so we only opt in via :has on the connect panel). */
.merish-view:has(.merish-connect-panel) { overflow-y: auto; }

/* Desktop-app download CTA on the Connect view — only rendered when the
   page is NOT running inside the MTA Studio desktop shell. Three-up
   platform grid (macOS / Windows / Linux) with per-card install
   instructions. One card is highlighted as "Recommended for you"
   based on the detected platform. */
.desktop-cta {
    display: flex;
    flex-direction: column;
    gap: 18px;
    padding: 20px 22px;
    background: linear-gradient(135deg, rgba(88, 166, 255, 0.08), rgba(188, 140, 255, 0.08));
    border: 1px solid rgba(188, 140, 255, 0.25);
    border-radius: 12px;
    flex-shrink: 0;
}
.desktop-cta-header {
    display: flex;
    gap: 14px;
    align-items: center;
}
.desktop-cta-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.desktop-cta-headline h3 {
    margin: 0 0 4px 0;
    font-size: 16px;
    font-weight: 600;
    color: var(--text-primary);
}
.desktop-cta-headline p {
    margin: 0;
    font-size: 13px;
    line-height: 1.5;
    color: var(--text-secondary);
    max-width: 640px;
}

/* Three-column grid on wide viewports, collapses to single column
 * on narrow ones. `auto-fit` with a min-size keeps the cards from
 * squishing below useful width. */
.desktop-cta-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 12px;
}

.desktop-cta-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 16px;
    background: rgba(15, 15, 18, 0.45);
    border: 1px solid var(--border);
    border-radius: 10px;
    transition: border-color 120ms ease, background-color 120ms ease,
                transform 120ms ease, box-shadow 120ms ease;
}
.desktop-cta-card:hover {
    border-color: color-mix(in srgb, var(--purple) 50%, var(--border));
    background: rgba(15, 15, 18, 0.65);
    transform: translateY(-1px);
}
.desktop-cta-card-recommended {
    border-color: color-mix(in srgb, var(--purple) 70%, transparent);
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--purple) 14%, rgba(15, 15, 18, 0.6)),
        rgba(15, 15, 18, 0.55));
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--purple) 40%, transparent),
                0 6px 16px color-mix(in srgb, var(--purple) 18%, transparent);
}
.desktop-cta-card-rec-badge {
    position: absolute;
    top: -9px;
    right: 12px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    padding: 3px 8px;
    border-radius: 10px;
    background: linear-gradient(135deg, #58a6ff, #bc8cff);
    color: #0f0f12;
}
.desktop-cta-card-head {
    display: flex;
    align-items: center;
    gap: 12px;
}
.desktop-cta-card-ico {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-primary);
}
.desktop-cta-card-name {
    display: flex;
    flex-direction: column;
    line-height: 1.2;
    font-size: 15px;
    font-weight: 600;
    color: var(--text-primary);
}
.desktop-cta-card-name span {
    font-size: 11px;
    font-weight: 400;
    color: var(--text-muted);
    margin-top: 2px;
}
.desktop-cta-card-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.desktop-cta-card-buttons .btn {
    flex: 1 1 auto;
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    line-height: 1.2;
    padding: 8px 12px;
    height: auto;
    min-width: 0;
}
.desktop-cta-sub {
    font-size: 10px;
    font-weight: 400;
    opacity: 0.75;
    margin-top: 2px;
}
.desktop-cta-card-help {
    border-top: 1px dashed color-mix(in srgb, var(--border) 70%, transparent);
    padding-top: 10px;
    font-size: 12px;
    line-height: 1.5;
    color: var(--text-secondary);
}
.desktop-cta-card-help summary {
    cursor: pointer;
    font-weight: 600;
    color: var(--text-primary);
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    user-select: none;
}
.desktop-cta-card-help summary::-webkit-details-marker { display: none; }
.desktop-cta-card-help summary::before {
    content: "›";
    font-size: 14px;
    font-weight: 700;
    transition: transform 120ms ease;
    color: var(--purple);
}
.desktop-cta-card-help[open] summary::before { transform: rotate(90deg); }
.desktop-cta-card-help ol {
    margin: 10px 0 4px 0;
    padding-left: 20px;
}
.desktop-cta-card-help li { margin-bottom: 4px; }
.desktop-cta-card-help li:last-child { margin-bottom: 0; }
.desktop-cta-card-help code {
    background: rgba(255, 255, 255, 0.06);
    padding: 1px 5px;
    border-radius: 3px;
    font-size: 11px;
}
.desktop-cta-card-note {
    margin: 10px 0 0 0;
    font-size: 11px;
    color: var(--text-muted);
    line-height: 1.4;
}
/* Linux firewall helper — per-command click-to-copy pills inside
 * the install details. Each row shows the label on the left and a
 * pill-shaped button holding the command on the right. Click
 * anywhere on the button to copy. */
.linux-fw-help {
    margin: 8px 0 4px 0;
    font-size: 11.5px;
    color: var(--text-secondary);
    line-height: 1.5;
}
.linux-fw-script {
    color: var(--purple);
    text-decoration: underline;
}
.linux-fw-cmds {
    list-style: none !important;
    padding: 0 !important;
    margin: 6px 0 0 0 !important;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.linux-fw-cmds > li {
    display: flex;
    flex-direction: column;
    gap: 3px;
    margin: 0 !important;
}
.linux-fw-cmds > li > span {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--text-muted);
}
.linux-fw-copy {
    display: inline-flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    width: 100%;
    border: 1px solid var(--border);
    background: rgba(255, 255, 255, 0.03);
    color: var(--text-primary);
    border-radius: 6px;
    padding: 6px 8px;
    font: inherit;
    cursor: pointer;
    text-align: left;
    transition: border-color 120ms ease, background-color 120ms ease;
}
.linux-fw-copy:hover {
    border-color: color-mix(in srgb, var(--purple) 55%, var(--border));
    background: rgba(255, 255, 255, 0.06);
}
.linux-fw-copy code {
    font-size: 11px;
    overflow-x: auto;
    white-space: nowrap;
    flex: 1 1 auto;
    min-width: 0;
}
.linux-fw-copy > span {
    flex: 0 0 auto;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--purple);
    padding: 2px 6px;
    border-radius: 4px;
    background: color-mix(in srgb, var(--purple) 15%, transparent);
}
.linux-fw-copy.copied {
    border-color: color-mix(in srgb, var(--accent-success, #3fb950) 70%, transparent);
}
.linux-fw-copy.copied > span {
    background: color-mix(in srgb, var(--accent-success, #3fb950) 25%, transparent);
    color: var(--accent-success, #3fb950);
}
@media (max-width: 720px) {
    .desktop-cta { padding: 16px 14px; }
    .desktop-cta-header { flex-direction: column; align-items: flex-start; }
}

/* Native LAN discovery panel — visible only inside the desktop app.
   Auto-populates as the main process sees Merish broadcasts. */
.merish-native-discover {
    background: var(--surface-2);
    border: 1px solid var(--border-soft);
    border-radius: 10px;
    padding: 14px 16px;
    margin-bottom: 14px;
}
.merish-native-discover-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 10px;
}
.merish-native-discover-head .merish-dot {
    flex-shrink: 0;
}
.merish-native-discover-head h3 {
    margin: 0 0 2px 0;
    font-size: 14px;
    font-weight: 600;
}
.merish-native-discover-lede {
    margin: 0;
    font-size: 12px;
    color: var(--text-secondary);
}
.merish-native-discover-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.merish-native-discover-empty {
    padding: 8px 10px;
    font-size: 12px;
    color: var(--text-muted);
    font-style: italic;
}
.merish-native-discover-item {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 14px;
    align-items: center;
    padding: 10px 12px;
    background: var(--surface-1);
    border: 1px solid var(--border-soft);
    border-radius: 8px;
    cursor: pointer;
    transition: background 0.08s, border-color 0.08s;
}
.merish-native-discover-item:hover {
    background: var(--surface-hover, rgba(88, 166, 255, 0.08));
    border-color: var(--accent);
}
.merish-native-discover-mark {
    color: var(--accent);
    display: flex;
    align-items: center;
}
.merish-native-discover-info {
    display: flex;
    flex-direction: column;
    min-width: 0;
}
.merish-native-discover-info strong {
    font-size: 13px;
    font-weight: 600;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.merish-native-discover-info span {
    font-size: 11px;
    color: var(--text-secondary);
    font-family: var(--mono, ui-monospace, SFMono-Regular, monospace);
}
.merish-native-discover-connect {
    font-size: 12px;
    font-weight: 500;
    color: var(--accent);
    opacity: 0;
    transition: opacity 0.1s;
}
.merish-native-discover-item:hover .merish-native-discover-connect { opacity: 1; }
.merish-native-discover-or {
    font-size: 11px;
    color: var(--text-muted);
    margin: 10px 0 6px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
.merish-dot[data-state="discover"] {
    background: var(--accent);
    animation: merish-dot-pulse 1.4s ease-in-out infinite;
}
@keyframes merish-dot-pulse {
    0%, 100% { opacity: 0.4; transform: scale(0.85); }
    50%      { opacity: 1;   transform: scale(1); }
}

.merish-view-head,
.merish-device-card {
    flex-shrink: 0;
    padding: 14px 18px;
    background: linear-gradient(180deg, var(--bg-card) 0%, var(--bg-secondary) 100%);
    border: 1px solid var(--border);
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
/* Disconnected state: the inner .merish-connect-panel is the card —
   strip the outer chrome so we don't render a card-in-a-card. */
.merish-device-card:has(.merish-connect-panel) {
    background: none;
    border: none;
    padding: 0;
    box-shadow: none;
}

/* ========== Disconnected state ========== */
.merish-dc-row {
    display: flex;
    align-items: center;
    gap: 16px;
    min-height: 44px;
}
.merish-dc-row[hidden] { display: none !important; }
.merish-dc-identity {
    display: flex;
    align-items: center;
    gap: 12px;
    flex: 1;
    min-width: 0;
}
.merish-dc-labels {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    flex: 1;
}
.merish-dc-name {
    font-size: 15px;
    font-weight: 600;
    color: var(--text-primary);
    display: flex;
    align-items: center;
    gap: 10px;
    line-height: 1.2;
}
.merish-dc-sub {
    font-size: 11px;
    color: var(--text-muted);
    line-height: 1.2;
}
.merish-dc-form {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
}
.merish-dc-form select,
.merish-dc-form input[type="text"] {
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-primary);
    padding: 6px 10px;
    font-size: 12px;
    height: 30px;
    min-width: 170px;
    outline: none;
}
.merish-dc-form select:focus,
.merish-dc-form input[type="text"]:focus { border-color: var(--accent); }

/* ========== Connected state ========== */
.merish-dc-conn {
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.merish-dc-conn .merish-dc-identity button { flex-shrink: 0; }
.merish-dc-stats {
    display: grid;
    grid-template-columns: repeat(5, auto) 1fr;
    gap: 10px;
    align-items: stretch;
}
.merish-stat-tile {
    padding: 10px 14px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 6px;
    min-width: 78px;
    display: flex;
    flex-direction: column;
    gap: 3px;
    align-items: flex-start;
}
.merish-stat-val {
    font-size: 18px;
    font-weight: 600;
    color: var(--text-primary);
    font-family: var(--font);
    letter-spacing: -0.5px;
    line-height: 1;
}
.merish-stat-lbl {
    font-size: 9px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 1px;
    font-weight: 600;
}
.merish-stat-tile[data-type="mta"]   .merish-stat-val { color: #5ab0ff; }
.merish-stat-tile[data-type="midi"]  .merish-stat-val { color: #b58aff; }
.merish-stat-tile[data-type="audio"] .merish-stat-val { color: #4caf50; }
.merish-stat-tile[data-type="video"] .merish-stat-val { color: #e0707b; }

.merish-dc-disk {
    padding: 10px 14px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 6px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    justify-content: center;
    min-width: 200px;
}
.merish-dc-disk-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.merish-dc-disk-lbl {
    font-size: 9px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 1px;
    font-weight: 600;
}
.merish-dc-disk-pct {
    font-size: 13px;
    font-weight: 600;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
}
.merish-dc-disk-bar {
    height: 6px;
    background: var(--bg-primary);
    border-radius: 3px;
    overflow: hidden;
    position: relative;
}
.merish-dc-disk-fill {
    height: 100%;
    background: linear-gradient(90deg, #4caf50 0%, #79b1ff 70%, #d4a017 90%, #e0707b 100%);
    transition: width var(--transition);
}
.merish-dc-disk-meta {
    font-size: 11px;
    color: var(--text-muted);
    font-family: var(--font-mono);
}

@media (max-width: 1100px) {
    .merish-dc-stats { grid-template-columns: repeat(3, 1fr); }
    .merish-dc-disk { grid-column: 1 / -1; }
}
@media (max-width: 700px) {
    .merish-dc-row { flex-wrap: wrap; }
    .merish-dc-form { width: 100%; justify-content: flex-end; }
}

.merish-title {
    display: flex;
    align-items: center;
    gap: 10px;
}

.merish-title-text {
    font-size: 13px;
    font-weight: 600;
    color: var(--text-primary);
    letter-spacing: 0.3px;
}

.merish-dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--text-muted);
}
.merish-dot[data-state="idle"]       { background: var(--text-muted); }
.merish-dot[data-state="discover"]   { background: #d4a017; animation: merish-pulse 1.2s infinite; }
.merish-dot[data-state="connecting"] { background: #d4a017; animation: merish-pulse 0.9s infinite; }
.merish-dot[data-state="connected"]  { background: #4caf50; }
.merish-dot[data-state="error"]      { background: var(--error); }

@keyframes merish-pulse {
    0%,100% { box-shadow: 0 0 0 0 rgba(212,160,23,0.7); }
    50%     { box-shadow: 0 0 0 5px rgba(212,160,23,0); }
}

.merish-head-actions {
    display: flex;
    gap: 6px;
    align-items: center;
    flex-wrap: wrap;
}

.merish-head-actions select,
.merish-head-actions input[type="text"] {
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-primary);
    padding: 5px 8px;
    font-size: 12px;
    min-width: 160px;
}

/* Info payload is now rendered directly inside .merish-view-head so
   the whole device info + disk + Disconnect sits on one row. */
.merish-info {
    font-size: 12px;
    flex: 1 1 auto;
    min-width: 0;
}

.merish-job-status {
    flex-shrink: 0;
    padding: 10px 14px;
    background: rgba(100, 150, 255, 0.08);
    border: 1px solid var(--accent);
    border-radius: var(--radius);
}
.merish-job-status[hidden] { display: none !important; }
.merish-job-head {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 12px;
    color: var(--text-primary);
    margin-bottom: 6px;
}
.merish-job-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--accent);
    animation: merish-pulse 1.2s infinite;
    flex-shrink: 0;
}
.merish-job-count {
    font-size: 11px;
    color: var(--text-secondary);
    font-family: var(--font-mono);
}
.merish-job-breakdown {
    font-size: 11px;
    color: var(--text-muted);
    font-family: var(--font-mono);
    padding-left: 10px;
    border-left: 1px solid var(--border);
    margin-left: 4px;
}
.merish-job-eta {
    font-size: 11px;
    color: #d4a017;
    font-family: var(--font-mono);
    font-weight: 600;
    padding-left: 10px;
    border-left: 1px solid var(--border);
}
.merish-job-current {
    flex: 1;
    font-size: 11px;
    color: #4caf50;
    font-family: var(--font-mono);
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-align: right;
}
.merish-job-bar {
    height: 4px;
    background: var(--bg-tertiary);
    border-radius: 2px;
    overflow: hidden;
}
.merish-job-bar > div {
    height: 100%;
    background: var(--accent);
    transition: width var(--transition);
}

.merish-info-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 0;
    min-width: 0;
}
.merish-info-main { min-width: 0; }

.merish-info-host {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin-bottom: 4px;
}
.merish-info-host strong {
    font-size: 14px;
    color: var(--text-primary);
}
.merish-tag {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: var(--accent);
    background: rgba(100, 150, 255, 0.1);
    border: 1px solid var(--accent);
    padding: 2px 6px;
    border-radius: 999px;
    white-space: nowrap;
    position: relative;
    top: -1px;
}
/* Colour-code by detected Merish generation so the MTA8 vs MTA16
   difference is obvious at a glance. */
.merish-tag.merish-tag-mta8 {
    color: #4caf50;
    background: rgba(76,175,80,0.1);
    border-color: #4caf50;
}
.merish-tag.merish-tag-mta16 {
    color: #d4a017;
    background: rgba(212,160,23,0.1);
    border-color: #d4a017;
}
.merish-tag.merish-tag-unknown {
    color: var(--text-muted);
    background: transparent;
    border-color: var(--border);
}
.merish-info-sub { font-size: 11px; color: var(--text-secondary); }

.merish-disk {
    min-width: 220px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    align-items: flex-end;
}
.merish-disk-bar {
    width: 200px;
    height: 6px;
    background: var(--bg-tertiary);
    border-radius: 3px;
    overflow: hidden;
}
.merish-disk-fill {
    height: 100%;
    background: linear-gradient(90deg, var(--accent), #79b1ff);
}
.merish-disk-lbl { font-size: 10px; color: var(--text-muted); }

.merish-workspace {
    display: grid;
    grid-template-columns: 320px 1fr;
    gap: 14px;
    flex: 1 1 auto;
    min-height: 0;
}
.merish-workspace[hidden] { display: none !important; }
.merish-info[hidden] { display: none !important; }

/* The sidebar itself is just a flex column — each section below now
   owns its own card chrome, so the outer wrapper stays transparent. */
.merish-sidebar {
    background: transparent;
    border: none;
    border-radius: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
    overflow-y: auto;
    min-height: 0;
}

/* Every sidebar section renders as a card, matching the Library /
   Projects view's visual language so the Connect overlay doesn't
   feel like a separate design system. */
.merish-side-section {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px 14px;
    transition: border-color 0.15s ease;
}
.merish-side-section:hover { border-color: var(--border-light, var(--border)); }
.merish-side-section[hidden] { display: none; }

.merish-side-section h4 {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: var(--text-muted);
    margin: 0 0 10px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.merish-side-section ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

/* Sidebar Backups section — one-line summary rows + live progress bar
   during an in-flight backup/restore. */
.merish-side-note {
    margin: 0 0 4px;
    font-size: 12px;
    color: var(--text-secondary);
    line-height: 1.35;
}
.merish-side-note strong { color: var(--text-primary); font-weight: 600; }
.merish-backups-side .btn { width: 100%; margin-top: 4px; }
.merish-side-progress {
    height: 4px;
    background: var(--border);
    border-radius: 2px;
    overflow: hidden;
    margin: 6px 0;
}
.merish-side-progress > div {
    height: 100%;
    background: var(--accent);
    transition: width 0.18s ease-out;
}
.merish-side-current {
    font-family: var(--font-mono);
    font-size: 10px;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin: 0 0 4px;
}

.merish-jump {
    width: 100%;
    text-align: left;
    background: transparent;
    border: 1px solid transparent;
    color: var(--text-secondary);
    padding: 5px 8px;
    border-radius: 4px;
    font-size: 12px;
    cursor: pointer;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.merish-jump:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
    border-color: var(--border);
}

.merish-muted-sm { font-size: 11px; color: var(--text-muted); }

.merish-side-section input[type="search"] {
    width: 100%;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-primary);
    padding: 5px 8px;
    font-size: 12px;
}

.merish-check {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    color: var(--text-secondary);
    margin-top: 6px;
}

.merish-main {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;
}

.merish-toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    border-bottom: 1px solid var(--border);
    background: var(--bg-secondary);
}
/* Shrink the Parent-folder / Up button so it lines up with the 30px
   breadcrumb bar next to it instead of towering 6px over it. */
.merish-toolbar > button[data-act="up"] {
    height: 30px;
}

.merish-breadcrumbs {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 2px;
    overflow-x: auto;
    white-space: nowrap;
    font-size: 12px;
    height: 30px;
    padding: 0 6px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    scrollbar-width: thin;
}
.merish-breadcrumbs::-webkit-scrollbar { height: 4px; }
.merish-breadcrumbs::-webkit-scrollbar-thumb {
    background: var(--border);
    border-radius: 2px;
}
/* Send-to-Merish modal breadcrumb: +4 px vs the base so it aligns
 * with the taller Up / Refresh / New-folder buttons sitting beside
 * it in the modal's header row. */
#send-merish-crumbs.merish-breadcrumbs { height: 36px; }

/* Descendant rules retheme only the Connect-card breadcrumb. The Send
   modal + backup picker use bare .merish-crumb (legacy rules below). */
.merish-breadcrumbs .merish-crumb {
    background: transparent;
    border: 1px solid transparent;
    color: var(--text-secondary);
    padding: 3px 10px;
    border-radius: 6px;
    cursor: pointer;
    font-family: inherit;
    font-size: 12px;
    font-weight: 500;
    height: 22px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: background 0.12s ease, color 0.12s ease;
    flex-shrink: 0;
}
.merish-breadcrumbs .merish-crumb:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
    border-color: transparent;
}
.merish-breadcrumbs .merish-crumb.current {
    color: var(--accent);
    background: color-mix(in srgb, var(--accent) 15%, transparent);
    font-weight: 600;
    cursor: default;
}
.merish-breadcrumbs .merish-crumb.current:hover {
    background: color-mix(in srgb, var(--accent) 18%, transparent);
}
.merish-breadcrumbs .merish-crumb-root { padding: 3px 7px; color: var(--text-muted); }
.merish-breadcrumbs .merish-crumb-root:hover { color: var(--text-primary); }
.merish-breadcrumbs .merish-crumb-sep {
    color: var(--text-muted);
    padding: 0;
    user-select: none;
    display: inline-flex;
    align-items: center;
    opacity: 0.5;
    flex-shrink: 0;
}

/* Legacy rules for Send modal + backup picker crumbs (no container). */
.merish-crumb {
    background: transparent;
    border: 1px solid transparent;
    color: var(--text-secondary);
    padding: 3px 8px;
    border-radius: 3px;
    cursor: pointer;
    font-family: var(--font-mono);
    font-size: 12px;
}
.merish-crumb:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
    border-color: var(--border);
}
.merish-crumb-sep {
    color: var(--text-muted);
    padding: 0 1px;
    user-select: none;
}

.merish-toolbar-right {
    display: flex;
    gap: 6px;
    align-items: center;
    margin-left: auto;
}
/* Keep every toolbar-right button at the same 30px height as the
   transport-btn icons on its left so CSV / Backup / Upload don't
   sit a hair shorter than Reload / New-folder. */
.merish-toolbar-right > .btn {
    height: 30px;
    padding: 0 12px;
    font-size: 12px;
}

.merish-filterbar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--border);
    background: var(--bg-card);
}
.merish-filterbar input[type="search"] {
    flex: 1;
    max-width: 420px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-primary);
    padding: 5px 10px;
    font-size: 12px;
    outline: none;
}
.merish-filterbar input[type="search"]:focus { border-color: var(--accent); }
.merish-filterbar .merish-check,
.merish-filterbar .merish-filterbar-toggle {
    margin: 0;
    flex-shrink: 0;
    font-size: 12px;
    color: var(--text-secondary);
}

.merish-colhead {
    display: grid;
    /* checkbox | Title | Artist | Filename | Kind | BPM·Key | Actions */
    grid-template-columns: 32px 2fr 1.3fr 1.5fr 60px 90px 260px;
    gap: 12px;
    align-items: center;
    padding: 6px 12px;
    border-bottom: 1px solid var(--border);
    background: var(--bg-secondary);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    color: var(--text-muted);
}
.merish-colhead [data-sort] {
    cursor: pointer;
}
.merish-colhead [data-sort]:hover { color: var(--text-primary); }

.merish-files {
    flex: 1 1 auto;
    overflow-y: auto;
    background: var(--bg-tertiary);
    min-height: 0;
}

.merish-files.merish-dropping {
    outline: 2px dashed var(--accent);
    outline-offset: -4px;
    background: rgba(100, 150, 255, 0.08);
}

.merish-file {
    display: grid;
    grid-template-columns: 32px 2fr 1.3fr 1.5fr 60px 90px 260px;
    gap: 12px;
    align-items: center;
    padding: 6px 12px;
    border-bottom: 1px solid var(--border);
    font-size: 12px;
    cursor: default;
    /* Let the browser skip layout + paint for rows that aren't in
       the viewport. Dramatically speeds up /ALL SONGS-sized folders
       (1000+ rows) where the full DOM walk was the bottleneck.
       The intrinsic-size hint keeps the scrollbar + scroll-anchor
       positions honest while the offscreen rows are collapsed. */
    content-visibility: auto;
    contain-intrinsic-size: 0 40px;
}
.merish-file:hover { background: var(--bg-hover); }
.merish-file:last-child { border-bottom: none; }

/* .bak / .dat sidecar rows — grouped under their main file when
   Show-all is on. Muted + slightly indented so the main file still
   anchors the visual group, while the sidecars read as children. */
.merish-file.merish-file-sidecar {
    opacity: 0.72;
    background: rgba(255,255,255,0.015);
    border-top: none;
}
.merish-file.merish-file-sidecar .merish-file-title {
    padding-left: 22px;
}
.merish-file.merish-file-sidecar .merish-file-title strong,
.merish-file.merish-file-sidecar .merish-file-fname {
    font-weight: 400;
    color: var(--text-muted);
}

.merish-file-title,
.merish-file-artist,
.merish-file-fname {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text-primary);
}
.merish-file-title {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.merish-file-title strong { font-weight: 600; }
.merish-file-artist {
    color: var(--text-secondary);
}
.merish-file-fname {
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 11px;
}
.merish-file-bpmkey {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--text-muted);
    text-align: left;
}
.merish-file-title-missing {
    color: var(--text-muted);
    opacity: 0.5;
}
.merish-file-icon {
    display: inline-flex;
    align-items: center;
    color: var(--text-secondary);
    flex-shrink: 0;
}
.merish-file-icon svg { display: block; }

/* Per-filetype icon colours + subtle row-name tint so users can scan
   the list at a glance and the sidecar .bak / .dat rows read as
   clearly secondary. Colours chosen to stay readable on dark bg. */
.merish-file[data-type="folder"]  .merish-file-icon { color: #e0b860; }
.merish-file[data-type="mta"]     .merish-file-icon { color: #5ab0ff; }
.merish-file[data-type="midi"]    .merish-file-icon { color: #b58aff; }
.merish-file[data-type="audio"]   .merish-file-icon { color: #4caf50; }
.merish-file[data-type="wav"]     .merish-file-icon { color: #ff8c42; }
.merish-file[data-type="video"]   .merish-file-icon { color: #e0707b; }
.merish-file[data-type="image"]   .merish-file-icon { color: #f5c452; }
.merish-file[data-type="text"]    .merish-file-icon { color: #9aa0a6; }
.merish-file[data-type="backup"]  .merish-file-icon { color: #7a8691; }
.merish-file[data-type="data"]    .merish-file-icon { color: #6fbcc9; }
.merish-file[data-type="other"]   .merish-file-icon { color: var(--text-muted); }

/* Type-labelled "kind" cells pick up the same colour as the icon
   so the file type is readable both visually (icon) and textually
   (kind column) — matches the Send-modal's coloured rows. */
.merish-file[data-type="folder"]  .merish-file-kind { color: #e0b860; }
.merish-file[data-type="mta"]     .merish-file-kind { color: #5ab0ff; }
.merish-file[data-type="midi"]    .merish-file-kind { color: #b58aff; }
.merish-file[data-type="audio"]   .merish-file-kind { color: #4caf50; }
.merish-file[data-type="wav"]     .merish-file-kind { color: #ff8c42; }
.merish-file[data-type="video"]   .merish-file-kind { color: #e0707b; }
.merish-file[data-type="image"]   .merish-file-kind { color: #f5c452; }

/* Sidecar rows are visual dim so the main file is always obviously
   the primary entry when show-all reveals them. */
.merish-file[data-type="backup"],
.merish-file[data-type="data"] {
    opacity: 0.7;
}
.merish-file[data-type="backup"] .merish-file-title strong,
.merish-file[data-type="data"]   .merish-file-title strong {
    color: var(--text-muted);
    font-weight: 500;
    font-style: italic;
}
.merish-file[data-type="backup"] .merish-file-kind { color: #7a8691; }
.merish-file[data-type="data"]   .merish-file-kind { color: #6fbcc9; }

.merish-row-icon {
    width: 28px;
    height: 24px;
    padding: 0 !important;
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
}
.merish-row-icon svg { display: block; }
/* Muted variant — info button when there's no indexed data yet. */
.merish-row-icon.merish-row-icon-muted { opacity: 0.4; }
.merish-row-icon.merish-row-icon-muted:hover { opacity: 0.8; }

/* When armed (e.g. "Sure?" confirmation) expand width so the label
   fits without clipping; the trash SVG comes back on disarm. */
.merish-row-icon.btn-armed {
    width: auto !important;
    padding: 0 10px !important;
    font-size: 11px;
    font-weight: 600;
}

/* Visual feedback for the reload button — one 600ms spin when
   the user clicks so they see the refresh happened. */
button.transport-btn.spinning svg { animation: merish-spin 0.6s linear; }
@keyframes merish-spin { to { transform: rotate(360deg); } }

/* Inline text-edit input used for rename / new-folder in the file list */
.merish-inline-edit {
    background: var(--bg-tertiary);
    border: 1px solid var(--accent);
    color: var(--text-primary);
    padding: 2px 6px;
    border-radius: 3px;
    font-size: 12px;
    font-family: inherit;
    width: 100%;
    max-width: 320px;
    outline: none;
}
.merish-file.pending {
    background: rgba(100, 150, 255, 0.05);
}

/* In-app modal prompt (replaces window.prompt) */
.merish-modal-backdrop {
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    background: rgba(0,0,0,0.32);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    z-index: 300;
    display: flex;
    align-items: center;
    justify-content: center;
}
.merish-modal {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 18px 20px;
    min-width: 360px;
    max-width: 480px;
    box-shadow: 0 8px 32px rgba(0,0,0,0.4);
}

/* Manual tap-sync overlay. Sits above the editor, never steals focus
 * from the lyrics view (so the space key still lands on the document
 * where our capture-phase listener grabs it). */
#manual-sync-overlay {
    position: fixed;
    left: 50%;
    bottom: 24px;
    transform: translateX(-50%);
    z-index: 400;
    pointer-events: auto;
}
#manual-sync-overlay .ms-panel {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 14px 18px;
    box-shadow: 0 16px 48px rgba(0,0,0,0.5);
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 520px;
    max-width: 720px;
}
#manual-sync-overlay .ms-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
}
#manual-sync-overlay .ms-title {
    margin: 0;
    font-size: 15px;
    font-weight: 600;
    color: var(--text-primary);
}
#manual-sync-overlay .ms-progress {
    font-family: var(--font-mono);
    font-size: 13px;
    color: var(--text-secondary);
}
#manual-sync-overlay .ms-progress-n {
    color: var(--accent);
    font-weight: 600;
}
#manual-sync-overlay .ms-hint {
    font-size: 12px;
    color: var(--text-secondary);
    line-height: 1.4;
}
#manual-sync-overlay .ms-steps {
    margin: 0;
    padding: 8px 12px 8px 28px;
    background: var(--bg-primary);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-size: 12px;
    color: var(--text-secondary);
    line-height: 1.55;
}
#manual-sync-overlay .ms-steps li { margin: 2px 0; }
#manual-sync-overlay .ms-steps strong {
    color: var(--text-primary);
    font-weight: 600;
}
#manual-sync-overlay .ms-keys-hint {
    font-size: 11px;
    color: var(--text-muted);
    line-height: 1.45;
}
#manual-sync-overlay .ms-keys-hint strong {
    color: var(--text-secondary);
    font-weight: 600;
}
#manual-sync-overlay kbd {
    display: inline-block;
    padding: 1px 6px;
    font-family: var(--font-mono, monospace);
    font-size: 10.5px;
    color: var(--text-primary);
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-bottom-width: 2px;
    border-radius: 3px;
    line-height: 1.3;
    vertical-align: baseline;
    white-space: nowrap;
}
#manual-sync-overlay .ms-current-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    background: var(--bg-primary);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
#manual-sync-overlay .ms-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-muted);
    flex-shrink: 0;
}
#manual-sync-overlay .ms-current-word {
    font-size: 22px;
    font-weight: 600;
    color: var(--accent);
    font-family: var(--font-mono, inherit);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
}
#manual-sync-overlay .ms-actions {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
}

/* Active-word highlight in the lyrics view while manual sync runs.
 * Distinct from .word.playing (used during normal playback). */
.word.ms-active {
    background: color-mix(in srgb, var(--accent) 30%, transparent);
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    border-radius: 3px;
    transition: background 120ms ease, outline-color 120ms ease;
}
.export-fmt-btn {
    height: auto !important;
    flex-direction: column;
    align-items: flex-start !important;
    justify-content: flex-start !important;
    text-align: left;
    padding: 10px 14px !important;
}
.merish-modal-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 12px;
}

/* Online-lyrics preview sub-modal (LRCLIB "Fetch online" flow). */
.lyr-preview-modal {
    width: min(640px, 92vw);
    max-width: none;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.lyr-preview-match {
    font-size: 12px;
    color: var(--text-muted);
}
.lyr-preview-match strong { color: var(--text-primary); font-weight: 600; }
.lyr-preview-tabs {
    display: flex;
    gap: 4px;
    border-bottom: 1px solid var(--border);
    padding-bottom: 0;
    margin-bottom: -1px;
}
.lyr-preview-tab {
    background: transparent;
    border: 1px solid transparent;
    border-bottom: none;
    color: var(--text-muted);
    padding: 6px 12px;
    font-size: 12px;
    cursor: pointer;
    border-radius: 6px 6px 0 0;
}
.lyr-preview-tab:hover { color: var(--text-primary); }
.lyr-preview-tab.active {
    color: var(--accent);
    border-color: var(--border);
    border-bottom-color: var(--bg-card);
    background: var(--bg-card);
}
.lyr-preview-body {
    width: 100%;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text-primary);
    padding: 10px 12px;
    font-family: var(--font-mono);
    font-size: 12px;
    line-height: 1.5;
    resize: vertical;
    outline: none;
}
.merish-modal-lbl {
    display: block;
    font-size: 11px;
    color: var(--text-muted);
    margin-bottom: 4px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.merish-modal-input {
    width: 100%;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-primary);
    padding: 8px 10px;
    font-size: 13px;
    font-family: var(--font-mono);
    outline: none;
    margin-bottom: 14px;
}
.merish-modal-input:focus { border-color: var(--accent); }
.merish-modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

.merish-folder-picker {
    min-width: 520px;
    max-width: 640px;
}

.merish-backup-modal {
    min-width: 640px;
    max-width: 820px;
    width: 70vw;
}
.merish-backup-summary {
    padding: 10px 12px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 4px;
    font-size: 12px;
    color: var(--text-secondary);
    margin-bottom: 12px;
}
.merish-backup-summary strong {
    color: var(--text-primary);
    font-weight: 600;
}
.merish-backup-list {
    max-height: 360px;
    overflow-y: auto;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 4px;
    margin-bottom: 14px;
}
.merish-backup-row {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "meta actions"
      "browser browser";
    align-items: center;
    gap: 8px 10px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--border);
}
.merish-backup-row:last-child { border-bottom: none; }
.merish-backup-meta {
    grid-area: meta;
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}
.merish-backup-sub {
    font-size: 11px;
    color: var(--text-muted);
    font-family: var(--font-mono);
}
.merish-backup-actions { grid-area: actions; display: flex; gap: 6px; }
.merish-backup-browser {
    grid-area: browser;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 6px;
    margin-top: 2px;
    max-height: 360px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    min-height: 0;
}
.merish-backup-browser-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border-bottom: 1px solid var(--border);
    background: var(--bg-secondary);
    position: sticky;
    top: 0;
    z-index: 1;
}
.merish-backup-browser-filter {
    flex: 1;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-primary);
    padding: 5px 8px;
    font-size: 12px;
}
.merish-backup-browser-count {
    font-size: 11px;
    color: var(--text-muted);
}
.merish-backup-browser-list {
    display: flex;
    flex-direction: column;
}
.merish-backup-file-row {
    display: grid;
    grid-template-columns: auto 1fr auto auto;
    align-items: center;
    gap: 10px;
    padding: 5px 10px;
    font-size: 12px;
    border-bottom: 1px solid var(--border);
}
.merish-backup-file-row:last-child { border-bottom: none; }
.merish-backup-file-row:hover { background: var(--bg-hover); }
.merish-backup-file-icon {
    display: inline-flex;
    width: 16px;
    height: 16px;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
}
.merish-backup-file-icon svg { width: 14px; height: 14px; }
.merish-backup-file-path {
    font-family: var(--font-mono);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text-primary);
}
.merish-backup-file-size {
    color: var(--text-muted);
    font-family: var(--font-mono);
}
/* Match the same per-type icon palette the live file lists use. */
.merish-backup-file-row[data-type="folder"] .merish-backup-file-icon { color: #e0b860; }
.merish-backup-file-row[data-type="mta"]    .merish-backup-file-icon { color: #5ab0ff; }
.merish-backup-file-row[data-type="midi"]   .merish-backup-file-icon { color: #b58aff; }
.merish-backup-file-row[data-type="audio"]  .merish-backup-file-icon { color: #4caf50; }
.merish-backup-file-row[data-type="wav"]    .merish-backup-file-icon { color: #ff8c42; }
.merish-backup-file-row[data-type="video"]  .merish-backup-file-icon { color: #e0707b; }
.merish-backup-file-row[data-type="image"]  .merish-backup-file-icon { color: #f5c452; }
.merish-backup-file-row[data-type="text"]   .merish-backup-file-icon { color: #9aa0a6; }
.merish-backup-file-row[data-type="backup"] .merish-backup-file-icon { color: #7a8691; }
.merish-backup-file-row[data-type="data"]   .merish-backup-file-icon { color: #6fbcc9; }

/* Yellow tint for the toolbar's Backup button icon so it's
   visually distinct from the neighbouring blue/purple actions. */
.btn[data-act="backup"] svg { color: #f5c452; stroke: currentColor; }

.merish-backup-progress {
    margin-bottom: 12px;
    padding: 10px 12px;
    background: rgba(100,150,255,0.08);
    border: 1px solid var(--accent);
    border-radius: 4px;
}
.merish-backup-prog-lbl {
    font-size: 12px;
    color: var(--text-primary);
    margin-bottom: 4px;
}
.merish-backup-prog-current {
    font-family: var(--font-mono);
    font-size: 11px;
    color: #79b1ff;
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    margin-bottom: 6px;
}
.merish-backup-prog-bar {
    height: 6px;
    background: var(--bg-tertiary);
    border-radius: 3px;
    overflow: hidden;
}
.merish-backup-prog-bar > div {
    height: 100%;
    background: var(--accent);
    transition: width var(--transition);
}

/* Info modal — per-file metadata viewer + reindex trigger */
.merish-info-modal {
    min-width: 640px;
    max-width: 820px;
    width: 70vw;
}
.merish-modal-sub {
    font-size: 12px;
    color: var(--text-muted);
    margin: -6px 0 12px;
}
.merish-modal-sub.merish-warn {
    color: #d4a017;
}
.merish-info-table {
    display: grid;
    grid-template-columns: 90px 1fr;
    gap: 6px 12px;
    margin: 0 0 16px;
    padding: 12px 14px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 4px;
}
.merish-info-row {
    display: contents;
}
.merish-info-row dt {
    font-size: 10px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    align-self: center;
}
.merish-info-row dd {
    margin: 0;
    font-size: 13px;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.merish-info-modal .btn svg {
    vertical-align: -2px;
    margin-right: 4px;
}
.merish-info-form {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px 16px;
    margin: 0 0 16px;
}
.merish-info-form label:last-of-type {
    grid-column: 1 / -1;  /* File row spans full width */
}
.merish-info-form label {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 11px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.merish-info-form label > span { font-weight: 600; }
.merish-info-form input {
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-primary);
    padding: 6px 10px;
    font-size: 13px;
    font-family: inherit;
    text-transform: none;
    letter-spacing: normal;
    outline: none;
}
.merish-info-form input:focus { border-color: var(--accent); }
.merish-info-form input:disabled {
    opacity: 0.6;
    font-family: var(--font-mono);
    font-size: 11px;
}
.merish-picker-bar {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 8px;
}
.merish-picker-crumbs {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 2px;
    overflow-x: auto;
    white-space: nowrap;
    font-family: var(--font-mono);
    font-size: 12px;
    padding: 4px 6px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 4px;
    min-height: 22px;
}
.merish-picker-list {
    max-height: 260px;
    overflow-y: auto;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 4px;
    margin-bottom: 10px;
}
.merish-picker-item {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 3px;
    color: var(--text-primary);
    font-size: 12px;
    text-align: left;
    cursor: pointer;
}
.merish-picker-item:hover {
    background: var(--bg-hover);
    border-color: var(--border);
}
.merish-picker-item .merish-file-icon { color: var(--text-secondary); }

.merish-file-kind {
    font-size: 10px;
    text-transform: uppercase;
    color: var(--text-muted);
    font-family: var(--font-mono);
    text-align: left;
    justify-self: start;
}
.col-kind {
    text-align: left;
    justify-self: start;
}

.merish-file-actions {
    display: flex;
    gap: 4px;
    justify-content: flex-end;
    align-items: center;
    opacity: 0.5;
    transition: opacity var(--transition);
}
.merish-file:hover .merish-file-actions { opacity: 1; }

.merish-file-actions .btn-danger {
    background: transparent;
    color: var(--error);
    border-color: var(--border);
}
.merish-file-actions .btn-danger:hover {
    background: var(--error);
    color: #fff;
}

.merish-check-box { cursor: pointer; }

/* Row selection — single-click picks a row and populates the info
   sidebar. Accent border on the left + subtle fill. */
.merish-file.selected {
    background: rgba(100, 150, 255, 0.10);
    box-shadow: inset 3px 0 0 0 var(--accent);
}

/* Sort arrows on the column headers. */
.merish-colhead [data-sort] {
    position: relative;
    padding-right: 14px;
}
.merish-colhead [data-sort].active {
    color: var(--text-primary);
}
.merish-colhead [data-sort].active[data-dir="asc"]::after { content: " ▲"; }
.merish-colhead [data-sort].active[data-dir="desc"]::after { content: " ▼"; }

/* Sidebar "Selected file" panel — reuses the standard form input
   styling from the settings modal so fields match the rest of the app. */
.merish-panel-filename {
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--text-primary);
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    padding: 6px 10px;
    border-radius: 6px;
    margin: 0 0 12px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    line-height: 1.3;
}
.merish-panel-warn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 10px;
    font-weight: 500;
    color: #d4a017;
    padding: 3px 8px;
    background: rgba(212,160,23,0.1);
    border: 1px solid rgba(212,160,23,0.25);
    border-radius: 10px;
    margin: 0 0 10px;
}

/* Two-column grid so BPM + Key sit side-by-side; the other three
   metadata fields (Title / Artist / Author) span the full row. */
.merish-panel-form {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px 8px;
    margin-bottom: 14px;
}
.merish-panel-form label {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 9px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.7px;
    grid-column: 1 / -1;
}
.merish-panel-form label[data-field-half] { grid-column: auto; }
.merish-panel-form label > span { font-weight: 600; }
.merish-panel-form input {
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text-primary);
    padding: 7px 10px;
    font-size: 13px;
    font-family: var(--font-mono);
    text-transform: none;
    letter-spacing: normal;
    outline: none;
    transition: border-color var(--transition);
}
.merish-panel-form input:focus { border-color: var(--accent); }
.merish-panel-actions {
    display: flex;
    gap: 6px;
}
.merish-panel-actions .btn { flex: 1 1 0; min-width: 0; }
.merish-panel-actions svg {
    vertical-align: -2px;
    margin-right: 4px;
}

/* Folder-path label shown before the Go-to button in search rows */
.merish-search-folder {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--font-mono);
    font-size: 10px;
    color: var(--text-muted);
    text-align: left;
    padding-right: 6px;
}

/* "Location" header over the folder column while searching */
.merish-colhead .col-actions {
    text-align: left;
    padding-left: 2px;
}

/* Global-search result row: title + artist + meta all in one strip,
   styled a touch tighter than folder rows so the device library
   density works. */
.merish-global-result .merish-file-name {
    flex-wrap: wrap;
    align-items: baseline;
}
.merish-global-title {
    font-weight: 600;
    color: var(--text-primary);
}
.merish-global-artist {
    font-size: 11px;
    color: var(--text-muted);
    margin-left: 6px;
}
.merish-global-meta {
    font-family: var(--font-mono);
    font-size: 10px;
    color: var(--text-muted);
    opacity: 1 !important;
    padding: 0 6px;
    text-align: right;
}

/* Row is in the middle of a background rename / move — dim it so
   the user can see it's in flux without blocking interaction. */
.merish-file.renaming {
    opacity: 0.55;
    font-style: italic;
    pointer-events: none;
}

.merish-statusbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 6px 12px;
    border-top: 1px solid var(--border);
    background: var(--bg-secondary);
    font-size: 11px;
    color: var(--text-muted);
    min-height: 28px;
}

.merish-muted { color: var(--text-muted); font-size: 12px; padding: 24px; text-align: center; }
.merish-error { color: var(--error); font-size: 12px; padding: 24px; }

/* Prominent loading state — shown while we're waiting on PathList /
   SongsList from the device. The old muted one-liner was too easy
   to miss on slow connections; users would navigate away thinking
   the browser had hung. */
.merish-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    padding: 48px 24px;
    color: var(--text-primary);
    animation: merish-loading-fade-in 0.18s ease-out both;
}
.merish-loading-spinner {
    width: 36px;
    height: 36px;
    border: 3px solid var(--border);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: spin 0.9s linear infinite;
}
.merish-loading-text {
    font-size: 14px;
    font-weight: 500;
    color: var(--text-primary);
    text-align: center;
}
.merish-loading-sub {
    font-size: 12px;
    color: var(--text-muted);
    text-align: center;
    max-width: 320px;
}
@keyframes merish-loading-fade-in {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0); }
}

@media (max-width: 900px) {
    .merish-workspace { grid-template-columns: 1fr; }
    .merish-sidebar { max-height: none; }
}

.project-list .empty {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 24px;
    text-align: center;
    color: var(--text-secondary);
    font-size: 13px;
}

.project-list .empty code {
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 2px 6px;
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--accent);
}

.project-card {
    display: flex;
    align-items: stretch;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    margin-bottom: 8px;
    color: var(--text-primary);
    transition: all var(--transition);
    overflow: hidden;
}

.project-card:hover {
    border-color: var(--border-light);
    background: var(--bg-hover);
}

.project-card .project-card-link {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 16px;
    text-decoration: none;
    color: inherit;
    min-width: 0;
}

.project-card .title {
    font-size: 14px;
    font-weight: 600;
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.project-card .artist {
    font-size: 13px;
    color: var(--text-secondary);
}

.project-card .duration {
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--text-muted);
}

.project-card .size {
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--text-muted);
    min-width: 64px;
    text-align: right;
}

.project-card .project-delete {
    flex: 0 0 auto;
    width: 36px;
    border: none;
    border-left: 1px solid var(--border);
    background: transparent;
    color: var(--text-muted);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    transition: all var(--transition);
}

.project-card .project-delete:hover {
    background: var(--error-dim, #b33a3a);
    color: #fff;
}

/* ===========================================================
 * Project Manager (Manage view)
 * Translucent rows, accent gradients, expandable detail panes.
 * =========================================================== */
.pm {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 18px 22px 28px;
    height: 100%;
    overflow-y: auto;
    color: var(--text-primary);
}

/* ── Toolbar (upload · search · sort · bulk-bar) ───────────── */
.pm-toolbar {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
.pm-spacer { flex: 1 1 auto; }

.pm-search-wrap {
    position: relative;
    flex: 1 1 280px;
    min-width: 220px;
    max-width: 420px;
}
.pm-search-ico {
    position: absolute;
    left: 11px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-muted);
    pointer-events: none;
}
#pm-search {
    width: 100%;
    height: 36px;
    padding: 0 12px 0 34px;
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 8px;
    color: var(--text-primary);
    font-family: inherit;
    font-size: 13px;
}
#pm-search:focus {
    outline: none;
    border-color: var(--accent);
    background: rgba(255,255,255,0.06);
}

.pm-sort {
    height: 36px;
    padding: 0 30px 0 12px;
    background: rgba(255,255,255,0.04) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%238a93a3' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>") no-repeat right 10px center;
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 8px;
    color: var(--text-primary);
    font-family: inherit;
    font-size: 13px;
    appearance: none;
    -webkit-appearance: none;
    cursor: pointer;
}

.pm-bulk {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 8px 4px 12px;
    background: linear-gradient(135deg, rgba(76,139,245,0.18), rgba(188,100,255,0.18));
    border: 1px solid rgba(106,162,255,0.45);
    border-radius: 8px;
}
.pm-bulk[hidden] { display: none; }
.pm-bulk-count {
    font-size: 12px;
    font-weight: 600;
    color: #cfe1ff;
}

/* ── Stats summary strip (translucent glass) ───────────────── */
.pm-stats {
    display: flex;
    gap: 24px;
    padding: 12px 16px;
    background: linear-gradient(135deg, rgba(76,139,245,0.08), rgba(188,100,255,0.05));
    border: 1px solid rgba(255,255,255,0.07);
    border-radius: 10px;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    color: var(--text-secondary);
    font-size: 13px;
}
.pm-stat strong {
    color: var(--text-primary);
    font-weight: 700;
    letter-spacing: -0.2px;
}
.pm-stat-empty { color: var(--text-muted); }

/* ── List header + rows ───────────────────────────────────── */
.pm-list-head, .pm-row {
    display: grid;
    grid-template-columns: 36px 28px minmax(220px, 2fr) minmax(120px, 1fr) 110px 90px 80px 300px;
    align-items: center;
    gap: 10px;
}
.pm-list-head {
    padding: 6px 12px;
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    border-bottom: 1px solid rgba(255,255,255,0.06);
}
@media (max-width: 1100px) {
    .pm-list-head .pm-cell-author,
    .pm-row .pm-cell-author { display: none; }
    .pm-list-head, .pm-row {
        grid-template-columns: 36px 28px minmax(200px, 2fr) 110px 90px 80px 300px;
    }
}
@media (max-width: 800px) {
    .pm-list-head .pm-cell-meta,
    .pm-row .pm-cell-meta { display: none; }
    .pm-list-head, .pm-row {
        grid-template-columns: 36px 28px minmax(200px, 2fr) 90px 80px 300px;
    }
}

.pm-list { display: flex; flex-direction: column; gap: 6px; }

/* ── Admin grouping: projects sectioned per-owner ─────────────────── */
.pm-owner-section {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 22px;
}
.pm-owner-section:last-child { margin-bottom: 0; }
.pm-owner-head {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    background: linear-gradient(135deg, rgba(76,139,245,0.10), rgba(188,100,255,0.06));
    border: 1px solid rgba(106,162,255,0.25);
    border-radius: 10px;
    margin-bottom: 4px;
    color: var(--text-primary);
    font-family: inherit;
    font-size: inherit;
    text-align: left;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.pm-owner-head:hover {
    background: linear-gradient(135deg, rgba(76,139,245,0.16), rgba(188,100,255,0.10));
    border-color: rgba(106,162,255,0.45);
}
.pm-owner-chev {
    flex-shrink: 0;
    color: var(--text-muted);
    transition: transform 0.18s ease, color 0.15s ease;
    transform: rotate(90deg);
}
.pm-owner-section.is-collapsed .pm-owner-chev {
    transform: rotate(0deg);
}
.pm-owner-section.is-collapsed .pm-owner-rows {
    display: none;
}
.pm-owner-section.is-collapsed .pm-owner-head {
    margin-bottom: 0;
}
.pm-owner-section.is-me .pm-owner-head {
    border-color: rgba(102,214,138,0.35);
    background: linear-gradient(135deg, rgba(102,214,138,0.10), rgba(76,139,245,0.06));
}
.pm-owner-self {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 7px;
    background: rgba(102,214,138,0.18);
    border: 1px solid rgba(102,214,138,0.4);
    border-radius: 999px;
    font-size: 10px;
    font-weight: 700;
    color: #b3e8c4;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    vertical-align: 1px;
}
.pm-owner-avatar {
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: linear-gradient(135deg, #4c8bf5, #bc64ff);
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.3px;
}
.pm-owner-meta {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.pm-owner-email {
    font-size: 13px;
    font-weight: 600;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.pm-owner-stats {
    font-size: 11px;
    color: var(--text-secondary);
}
.pm-owner-stats strong { color: var(--text-primary); font-weight: 600; }
.pm-owner-pill {
    padding: 2px 8px;
    border-radius: 999px;
    background: rgba(106,162,255,0.18);
    border: 1px solid rgba(106,162,255,0.4);
    color: #cfe1ff;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.5px;
    text-transform: uppercase;
}
.pm-owner-rows {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding-left: 12px;
    border-left: 2px solid rgba(106,162,255,0.18);
    margin-left: 17px;  /* aligns the line under the centre of the avatar */
}

.pm-row {
    padding: 12px;
    background: rgba(255,255,255,0.025);
    border: 1px solid rgba(255,255,255,0.06);
    border-left: 3px solid transparent;
    border-radius: 8px;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.pm-row:hover {
    background: rgba(255,255,255,0.05);
    border-color: rgba(255,255,255,0.10);
}
.pm-row.is-selected {
    background: rgba(88,166,255,0.10);
    border-color: rgba(106,162,255,0.45);
    border-left-color: var(--accent, #6aa2ff);
}
.pm-row.is-expanded {
    border-left-color: var(--accent, #6aa2ff);
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
}

.pm-cell { display: flex; align-items: center; min-width: 0; }
.pm-cell-check, .pm-cell-expand { justify-content: center; }
.pm-cell-check input { width: 16px; height: 16px; cursor: pointer; }
.pm-expand-btn {
    width: 28px;
    height: 28px;
    padding: 0;
    background: transparent;
    border: 0;
    border-radius: 6px;
    color: var(--text-muted);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.pm-expand-btn:hover { background: rgba(255,255,255,0.06); color: var(--text-primary); }

.pm-cell-title {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    text-decoration: none;
    color: inherit;
    min-width: 0;
    overflow: hidden;
}
.pm-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    width: 100%;
    transition: color 0.15s ease;
}
.pm-cell-title:hover .pm-title { color: var(--accent, #6aa2ff); }
.pm-sub {
    font-size: 12px;
    color: var(--text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    width: 100%;
}
.pm-cell-author {
    font-size: 12px;
    color: var(--text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.pm-cell-meta, .pm-cell-duration, .pm-cell-size {
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--text-muted);
}
.pm-cell-size, .pm-cell-duration { justify-content: flex-end; }
.pm-cell-actions {
    justify-content: flex-end;
    gap: 4px;
    flex-wrap: nowrap;
    overflow: hidden;
}
/* Each row-action button is icon-only now — keep them compact and
   uniform so 7 fit inside the 300px actions cell. */
.pm-cell-actions .btn {
    padding: 0 8px;
    flex-shrink: 0;
}
.pm-row-del.btn-armed {
    background: rgba(244,67,54,0.18) !important;
    border-color: var(--error, #f44336) !important;
    color: #ff8a8a !important;
}

/* ── Expandable detail (stems + project-id + future bits) ──── */
.pm-detail {
    margin-top: -6px;
    padding: 0 14px;
    background: rgba(255,255,255,0.015);
    border: 1px solid rgba(255,255,255,0.06);
    border-top: 0;
    border-left: 3px solid var(--accent, #6aa2ff);
    border-radius: 0 0 8px 8px;
    overflow: hidden;
}
.pm-detail[hidden] { display: none; }
.pm-detail-inner { padding: 14px 4px 18px; }
.pm-detail-loading, .pm-detail-empty {
    color: var(--text-muted);
    font-size: 12.5px;
    font-style: italic;
}
.pm-detail-meta {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    color: var(--text-secondary);
    margin-bottom: 10px;
}

/* Inline metadata editor inside the expanded row — lets the user
   fix title / artist / author / bpm / key without opening the
   project in the editor. */
.pm-detail-form {
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px 14px;
    margin-bottom: 14px;
}
.pm-detail-form-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: var(--text-muted);
    margin-bottom: 10px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border);
}
.pm-detail-fields {
    display: grid;
    /* Six tracks so we can do 1/1 (wide), 1/2 (half) and 1/3 (third)
     * widths cleanly. Wide = span 6, half = span 3, third = span 2. */
    grid-template-columns: repeat(6, 1fr);
    gap: 10px;
    margin-bottom: 10px;
}
.pm-field {
    display: flex;
    flex-direction: column;
    gap: 5px;
    font-size: 11px;
    color: var(--text-secondary);
    letter-spacing: 0.3px;
}
.pm-field-wide  { grid-column: span 6; }
.pm-field-half  { grid-column: span 3; }
.pm-field-third { grid-column: span 2; }
@media (max-width: 700px) {
    /* Collapse to stacked on narrow screens so thirds don't squish
     * the BPM / Key / Genre inputs past readable width. */
    .pm-detail-fields { grid-template-columns: 1fr; }
    .pm-field-wide,
    .pm-field-half,
    .pm-field-third { grid-column: 1 / -1; }
}
.pm-field > span {
    font-weight: 600;
    text-transform: uppercase;
    font-size: 10px;
    letter-spacing: 0.7px;
    color: var(--text-muted);
}
.pm-field input,
.pm-field select {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text-primary);
    padding: 7px 10px;
    font-size: 13px;
    font-family: var(--font-mono);
    text-transform: none;
    letter-spacing: normal;
    outline: none;
    transition: border-color var(--transition);
}
.pm-field input:focus,
.pm-field select:focus { border-color: var(--accent); }
/* Custom chevron on selects — browser-default looks out of place
 * against the rest of the form. Strip appearance and draw our own. */
.pm-field select {
    appearance: none;
    -webkit-appearance: none;
    padding-right: 28px;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path fill='none' stroke='%238b949e' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' d='M1 1l4 4 4-4'/></svg>");
    background-repeat: no-repeat;
    background-position: right 10px center;
    cursor: pointer;
}

/* Genre dropdown + Custom input share one cell. Stack them; the
 * input is only revealed when Custom… is picked in the select. */
.pm-field-genre-wrap {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

/* Split-stem options modal — redesigned for calm, readable density.
 * Section groups with subtle headings, recommended-badge pills, and
 * softer card-backed toggles. */
.split-modal {
    padding: 22px 24px 20px;
    /* Cap modal to the viewport so the footer buttons always stay
     * visible; the body scrolls if the extras grid overflows. */
    max-height: 90vh;
    display: flex;
    flex-direction: column;
}
.split-modal > * {
    flex-shrink: 0;
}
.split-modal-hero {
    display: flex;
    gap: 14px;
    align-items: flex-start;
    margin-bottom: 14px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--border);
}
.split-modal--wide .split-modal-lede { font-size: 12px; line-height: 1.5; }

/* Everything between the hero and the footer scrolls if needed so
 * the action buttons are always in reach regardless of viewport
 * height. On desktop the grid usually fits without scrolling. */
.split-modal-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding-right: 4px;
    margin-right: -4px;
}
.split-modal-hero-ico {
    flex-shrink: 0;
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
    color: var(--accent, #58a6ff);
    background:
        radial-gradient(circle at 30% 30%, rgba(108,170,255,0.22), transparent 60%),
        radial-gradient(circle at 70% 70%, rgba(188,100,255,0.18), transparent 60%),
        rgba(255,255,255,0.03);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.08);
}
.split-modal-lede {
    margin: 4px 0 0;
    font-size: 12.5px;
    line-height: 1.55;
    color: var(--text-secondary, #8b949e);
}
.split-modal-source {
    margin: 8px 0 0;
    font-size: 12px;
    color: var(--text-primary);
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 3px 10px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--accent, #58a6ff) 10%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent, #58a6ff) 30%, transparent);
}
.split-modal-source span {
    font-size: 10px;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    color: var(--text-muted);
}

.split-modal-section {
    margin-bottom: 16px;
}
.split-modal-section:last-of-type { margin-bottom: 0; }
.split-modal-section-title {
    margin: 0 0 8px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: color-mix(in srgb, var(--accent, #58a6ff) 80%, var(--text-secondary));
}

.split-modal-fields {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
}
.split-modal-fields.cols-3 {
    grid-template-columns: 1fr 1fr 1fr;
}
.split-modal-fields .pm-field-wide { grid-column: 1 / -1; }
.split-modal-fields .pm-field-half { grid-column: auto; }
@media (max-width: 700px) {
    .split-modal-fields.cols-3 { grid-template-columns: 1fr; }
}

/* Extras — 2-column card grid so the 7 option cards fit without
 * pushing the footer off-screen. .span-2 lets the multi-pass warn
 * card take the full row because its contents (warning pill) are
 * tall. On narrow screens collapse back to a single column. */
.split-modal-extras-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    align-items: stretch;
}
.split-modal-extras-grid .split-modal-toggle {
    margin-bottom: 0;
}
.split-modal-extras-grid .span-2 {
    grid-column: 1 / -1;
}
@media (max-width: 700px) {
    .split-modal-extras-grid { grid-template-columns: 1fr; }
}

/* Tips card — fills the odd cell at the bottom-right of the extras
 * grid. Visually distinct from the toggles (no hover-as-button
 * feedback, warmer accent, tighter list styling). */
.split-modal-tips {
    grid-column: 1 / -1;
    padding: 12px 14px;
    border: 1px solid color-mix(in srgb, var(--accent, #58a6ff) 30%, var(--border));
    border-radius: 8px;
    background: color-mix(in srgb, var(--accent, #58a6ff) 5%, var(--bg-card));
    font-size: 12px;
    line-height: 1.5;
    color: var(--text-secondary);
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.split-modal-tips-title {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: color-mix(in srgb, var(--accent, #58a6ff) 85%, var(--text-secondary));
}
.split-modal-tips-title::before {
    content: "★ ";
    color: color-mix(in srgb, var(--accent, #58a6ff) 90%, white);
}
.split-modal-tips ul {
    margin: 0;
    padding-left: 18px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px 16px;
}
@media (max-width: 700px) {
    .split-modal-tips ul { grid-template-columns: 1fr; }
}
.split-modal-tips li {
    color: var(--text-secondary);
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.split-modal-tips li strong {
    color: var(--text-primary);
    font-weight: 600;
}
.split-modal-label-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.split-modal-toggle {
    display: grid;
    grid-template-columns: auto 1fr;
    row-gap: 4px;
    column-gap: 12px;
    align-items: start;
    align-content: start;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: color-mix(in srgb, var(--bg-card) 55%, transparent);
    cursor: pointer;
    transition: border-color 120ms, background 120ms;
    margin-bottom: 8px;
}
.split-modal-toggle:last-of-type { margin-bottom: 0; }
.split-modal-toggle:hover {
    border-color: color-mix(in srgb, var(--accent, #58a6ff) 30%, var(--border));
    background: color-mix(in srgb, var(--bg-card) 40%, transparent);
}
.split-modal-toggle input[type="checkbox"] {
    margin-top: 2px;
}
.split-modal-toggle-title {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: var(--text-primary);
    font-weight: 600;
}
.split-modal-toggle .split-modal-hint {
    grid-column: 2 / -1;
    font-size: 12px;
    color: var(--text-muted);
    line-height: 1.5;
}

/* Slider variant: no checkbox in col 1, so the label row, range
 * input, and hint should all span the full card width. */
.split-modal-toggle--slider {
    grid-template-columns: 1fr;
}
.split-modal-toggle--slider .split-modal-label-row,
.split-modal-toggle--slider > input[type="range"],
.split-modal-toggle--slider .split-modal-hint {
    grid-column: 1 / -1;
}

/* Multi-pass toggle gets an amber outline + a warn-coloured notice
 * so users know ahead of clicking that it's going to take a while. */
.split-modal-toggle--warn {
    border-color: color-mix(in srgb, #d29922 40%, var(--border));
    background: color-mix(in srgb, #d29922 4%, var(--bg-card));
}
.split-modal-toggle--warn:hover {
    border-color: color-mix(in srgb, #d29922 60%, var(--border));
    background: color-mix(in srgb, #d29922 7%, var(--bg-card));
}
.split-modal-toggle--warn input[type="checkbox"]:checked {
    background: #d29922;
    border-color: #d29922;
}
.split-modal-toggle--warn .split-modal-warn {
    grid-column: 2 / -1;
    display: block;
    margin-top: 6px;
    padding: 6px 10px;
    font-size: 12px;
    font-weight: 600;
    color: #f0c64a;
    background: color-mix(in srgb, #d29922 14%, transparent);
    border: 1px solid color-mix(in srgb, #d29922 45%, transparent);
    border-radius: 5px;
    letter-spacing: 0.2px;
}
.split-toplabel-badge {
    display: inline-flex;
    align-items: center;
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    color: #f0c64a;
    background: color-mix(in srgb, #d29922 16%, transparent);
    border: 1px solid color-mix(in srgb, #d29922 40%, transparent);
    padding: 1px 7px;
    border-radius: 999px;
}

.split-modal-footer {
    margin-top: 20px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

/* Recommended pill — used both in toggle titles and in dropdown
 * option rows. A small star + tight accent-tinted pill. */
.split-rec-badge,
.dropdown-rec-badge {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    color: color-mix(in srgb, var(--accent, #58a6ff) 90%, white);
    background: color-mix(in srgb, var(--accent, #58a6ff) 16%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent, #58a6ff) 35%, transparent);
    padding: 1px 7px;
    border-radius: 999px;
    white-space: nowrap;
}

/* Dropdown option rows — two-line layout with a muted sub-label so
 * users see the nuance between choices. */
.dropdown-opt-main {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    color: var(--text-primary);
    font-weight: 500;
}
.dropdown-opt-sub {
    display: block;
    margin-top: 2px;
    font-size: 11px;
    color: var(--text-muted);
    line-height: 1.4;
}
.stem-family-picker-option.is-recommended {
    background: color-mix(in srgb, var(--accent, #58a6ff) 6%, transparent);
}

/* Hint line keeps its plain-text look but gets a little room so
 * the inline Recommended pill is legible. */
.split-modal-slider-hint .split-rec-badge {
    margin-left: 6px;
}

/* When multi-pass best-of-breed takes over, every superseded
 * control gets dimmed + non-interactive so the user can see at a
 * glance that its value is being driven by the multi-pass run. */
.split-modal-fields .is-overridden,
.split-modal-toggle.is-overridden {
    opacity: 0.45;
    pointer-events: none;
    cursor: not-allowed;
    filter: grayscale(30%);
}
.split-modal-fields .is-overridden input[type="range"] {
    accent-color: var(--text-muted, #8b949e);
}
.stem-family-picker.is-disabled .stem-family-picker-trigger {
    opacity: 0.5;
    cursor: not-allowed;
    background: color-mix(in srgb, var(--bg-input) 80%, transparent);
}
.stem-family-picker.is-disabled .stem-family-picker-trigger:hover {
    border-color: var(--border);
}

/* Live value readout next to slider labels (shifts / overlap). */
.split-modal-fields .split-modal-val {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 6px;
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 600;
    color: var(--accent, #58a6ff);
    background: color-mix(in srgb, var(--accent, #58a6ff) 14%, transparent);
    border-radius: 3px;
    text-transform: none;
    letter-spacing: 0;
}
.split-modal-fields input[type="range"] {
    width: 100%;
    padding: 0;
    background: transparent;
    border: 0;
    accent-color: var(--accent, #58a6ff);
}

/* Split-modal selects — restyled to match the instrument-family
 * picker (.stem-family-picker-trigger) so every dropdown in the
 * editor reads as one consistent component. Native <select> still
 * works mechanically; only the skin changes. */
.split-modal-fields select {
    width: 100%;
    display: flex;
    align-items: center;
    background: var(--bg-input);
    border: 1px solid var(--border);
    color: var(--text-primary);
    font-family: var(--font);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
    padding: 6px 30px 6px 10px;
    border-radius: 4px;
    cursor: pointer;
    min-height: 28px;
    outline: none;
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path fill='none' stroke='%238b949e' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' d='M1 1l4 4 4-4'/></svg>");
    background-repeat: no-repeat;
    background-position: right 10px center;
    transition: border-color 120ms;
}
.split-modal-fields select:hover {
    border-color: color-mix(in srgb, var(--accent) 40%, var(--border));
}
.split-modal-fields select:focus {
    border-color: var(--accent);
}
/* Plain-English hint line under each slider so a musician knows
 * what a given value buys them without needing to know demucs. */
.split-modal-slider-hint {
    display: block;
    margin-top: 4px;
    font-size: 11px;
    color: var(--text-muted);
    line-height: 1.4;
    text-transform: none;
    letter-spacing: 0;
}
.pm-field-genre-wrap input[data-field="genre_custom"] {
    /* Already inherits .pm-field input styles above. */
}

/* ─── Global native-checkbox theme ────────────────────────────────
 * Bare `<input type="checkbox">` used for multi-select / select-all
 * controls (row checks in Manage, the Merish files list, etc.) get
 * a consistent themed look so they don't stand out as browser-
 * default white squares. Toggle-style switches (.set-toggle /
 * .set-chk / .pm-filter-toggle wrappers) already have their own
 * appearance and are excluded via :not() selectors so we don't
 * fight them. */
input[type="checkbox"]:not(.set-toggle input):not(.set-chk input):not(.pm-filter-toggle input) {
    appearance: none;
    -webkit-appearance: none;
    width: 16px;
    height: 16px;
    border: 1.5px solid color-mix(in srgb, var(--text-muted) 55%, transparent);
    border-radius: 4px;
    background: var(--bg-input, var(--bg-card));
    cursor: pointer;
    position: relative;
    flex-shrink: 0;
    transition: background 120ms, border-color 120ms, box-shadow 120ms;
    vertical-align: middle;
}
input[type="checkbox"]:not(.set-toggle input):not(.set-chk input):not(.pm-filter-toggle input):hover {
    border-color: color-mix(in srgb, var(--accent, #58a6ff) 70%, transparent);
}
input[type="checkbox"]:not(.set-toggle input):not(.set-chk input):not(.pm-filter-toggle input):checked {
    background: var(--accent, #58a6ff);
    border-color: var(--accent, #58a6ff);
}
input[type="checkbox"]:not(.set-toggle input):not(.set-chk input):not(.pm-filter-toggle input):checked::after {
    content: "";
    position: absolute;
    left: 4px;
    top: 0.5px;
    width: 5px;
    height: 9px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: rotate(42deg);
}
input[type="checkbox"]:not(.set-toggle input):not(.set-chk input):not(.pm-filter-toggle input):indeterminate {
    background: var(--accent, #58a6ff);
    border-color: var(--accent, #58a6ff);
}
input[type="checkbox"]:not(.set-toggle input):not(.set-chk input):not(.pm-filter-toggle input):indeterminate::after {
    content: "";
    position: absolute;
    left: 3px;
    right: 3px;
    top: 50%;
    transform: translateY(-50%);
    height: 2px;
    background: #fff;
    border-radius: 1px;
}
input[type="checkbox"]:not(.set-toggle input):not(.set-chk input):not(.pm-filter-toggle input):focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent, #58a6ff) 35%, transparent);
}
input[type="checkbox"]:not(.set-toggle input):not(.set-chk input):not(.pm-filter-toggle input):disabled {
    opacity: 0.45;
    cursor: not-allowed;
}
.pm-field-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
}
.pm-field-hint {
    font-size: 11px;
    color: var(--text-muted);
}
.pm-detail-stems-section { padding-top: 4px; }

/* Set-list card — ordered queue of projects the user is planning to
   export or send to the Merish. Drag/reorder via ↑/↓, persists to
   localStorage so the queue survives reloads. */
.pm-setlist {
    background: var(--bg-card);
    border: 1px solid var(--accent);
    border-radius: var(--radius);
    padding: 10px 14px 12px;
    margin: 10px 0;
}
.pm-setlist-head {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 12px;
    margin-bottom: 8px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border);
}
.pm-setlist-title {
    font-weight: 600;
    font-size: 11px;
    letter-spacing: 0.8px;
    color: var(--accent);
    text-transform: uppercase;
}
.pm-setlist-count { color: var(--text-muted); font-size: 11px; }
.pm-setlist-items {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.pm-setlist-row {
    display: grid;
    grid-template-columns: auto 1fr auto auto auto;
    align-items: center;
    gap: 10px;
    padding: 4px 8px;
    background: var(--bg-tertiary);
    border-radius: 6px;
    font-size: 12.5px;
}
.pm-setlist-idx {
    width: 22px;
    height: 22px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--accent);
    color: #fff;
    border-radius: 11px;
    font-size: 11px;
    font-weight: 700;
}
.pm-setlist-title-cell strong {
    color: var(--text-primary);
    font-weight: 600;
    margin-right: 8px;
}
.pm-setlist-title-cell span { color: var(--text-muted); font-size: 11px; }

/* Filter chip row above the project list. */
.pm-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
    padding: 10px 0;
    margin-bottom: 6px;
    border-bottom: 1px solid var(--border);
}
.pm-filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 5px 10px;
    font-size: 11px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.pm-filter-chip select, .pm-filter-chip input {
    background: transparent;
    border: none;
    color: var(--text-primary);
    font-size: 12px;
    font-family: inherit;
    text-transform: none;
    letter-spacing: normal;
    outline: none;
    min-width: 90px;
}
.pm-filter-chip input { width: 56px; min-width: 0; }
.pm-filter-dash { color: var(--text-muted); }

/* Filter-bar Reset button sits in the same row as the .pm-filter-chip
 * toggles ("Favorites only", "Show archived"). Our base .btn locks a
 * 36 px height which is visibly taller than the chips; match their
 * box model so the row reads as one uniform strip. Scoped to this
 * specific button so the rest of the app's 36 px button rule stands. */
#pm-filter-clear {
    height: auto !important;
    min-height: 0 !important;
    padding: 8px 12px !important;
    font-size: 11px !important;
    line-height: 1 !important;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

/* ─── Manage-section button colour accents ──────────────────────────
 * Each action gets a subtle tint so you can tell Export / Send /
 * Setlist-add / Archive / Delete apart at a glance instead of reading
 * the icon every time. Tints mirror the colour used elsewhere for the
 * same action: blue = info/export, purple = Merish-brand send, amber
 * = set-list build, red = destructive. Applied to the per-row action
 * column, the bulk-action bar, AND the Set-list header so the three
 * surfaces read consistently. */

/* Export — cyan/teal */
.pm-row-export,
#pm-bulk-export,
#pm-setlist-export {
    background: rgba(56, 189, 248, 0.14);
    border-color: rgba(56, 189, 248, 0.30);
    color: #7dd3fc;
}
.pm-row-export:hover,
#pm-bulk-export:hover,
#pm-setlist-export:hover {
    background: rgba(56, 189, 248, 0.24);
    border-color: rgba(56, 189, 248, 0.50);
    color: #e0f2fe;
}

/* Send to Merish — purple (the brand's accent everywhere else) */
.pm-row-send,
#pm-bulk-send,
#pm-setlist-send {
    background: color-mix(in srgb, var(--purple, #bc8cff) 18%, transparent);
    border-color: color-mix(in srgb, var(--purple, #bc8cff) 35%, transparent);
    color: color-mix(in srgb, var(--purple, #bc8cff) 90%, white);
}
.pm-row-send:hover,
#pm-bulk-send:hover,
#pm-setlist-send:hover {
    background: color-mix(in srgb, var(--purple, #bc8cff) 32%, transparent);
    border-color: color-mix(in srgb, var(--purple, #bc8cff) 55%, transparent);
    color: #fff;
}

/* Setlist toggle — amber (build-list vibe). Active set-member state
 * (the button that removes from setlist) gets a filled chip instead
 * of the ghost outline so it's immediately obvious it's in the list. */
.pm-row-setlist {
    background: rgba(251, 191, 36, 0.10);
    border-color: rgba(251, 191, 36, 0.30);
    color: #fcd34d;
}
.pm-row-setlist:hover {
    background: rgba(251, 191, 36, 0.22);
    border-color: rgba(251, 191, 36, 0.50);
    color: #fde68a;
}
.pm-row-setlist[data-in-setlist="1"] {
    background: rgba(251, 191, 36, 0.30);
    border-color: rgba(251, 191, 36, 0.60);
    color: #fef3c7;
}

/* Tag — indigo */
#pm-bulk-tag {
    background: rgba(129, 140, 248, 0.15);
    border-color: rgba(129, 140, 248, 0.30);
    color: #c7d2fe;
}
#pm-bulk-tag:hover {
    background: rgba(129, 140, 248, 0.25);
    border-color: rgba(129, 140, 248, 0.50);
    color: #eef2ff;
}

/* Archive — neutral grey for the "archive" action; warm orange when
 * the button is already in "restore" mode so users can spot archived
 * rows at a glance. */
.pm-row-archive {
    color: #94a3b8;
}
.pm-row-archive:hover {
    background: rgba(148, 163, 184, 0.18);
    border-color: rgba(148, 163, 184, 0.40);
    color: #e2e8f0;
}
.pm-row-archive.is-archived {
    background: rgba(249, 115, 22, 0.14);
    border-color: rgba(249, 115, 22, 0.30);
    color: #fdba74;
}
.pm-row-archive.is-archived:hover {
    background: rgba(249, 115, 22, 0.26);
    border-color: rgba(249, 115, 22, 0.55);
    color: #fed7aa;
}

/* Delete (per-row). Bulk + set-list clear already use .btn-danger so
 * they're red; this gives the per-row trash icon the same language. */
.pm-row-del {
    color: #fca5a5;
}
.pm-row-del:hover {
    background: rgba(248, 113, 113, 0.18);
    border-color: rgba(248, 113, 113, 0.40);
    color: #fecaca;
}

/* Clear selection — subdued grey so it doesn't compete with the
 * coloured action buttons next to it. */
#pm-bulk-clear {
    color: #94a3b8;
}
#pm-bulk-clear:hover {
    background: rgba(148, 163, 184, 0.18);
    border-color: rgba(148, 163, 184, 0.40);
    color: #e2e8f0;
}

/* Row status dot — solid green when ready, hollow amber when partial. */
.pm-status-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    margin-right: 8px;
    flex-shrink: 0;
    vertical-align: 1px;
}
.pm-status-dot.is-ready   { background: #4caf50; }
.pm-status-dot.is-partial { background: #e3b341; }

/* Inline favorite star button inside the row title. */
.pm-fav-btn {
    background: transparent;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 2px 4px;
    margin-right: 4px;
    vertical-align: -2px;
    transition: color 0.12s;
}
.pm-fav-btn:hover { color: #e3b341; }
.pm-fav-btn.is-on { color: #e3b341; }

/* Tag pills shown inline under the row subtitle. */
.pm-tag-pill {
    display: inline-block;
    background: rgba(88,166,255,0.12);
    color: #5ab0ff;
    border: 1px solid rgba(88,166,255,0.3);
    border-radius: 10px;
    padding: 1px 7px;
    font-size: 10px;
    margin-left: 4px;
    text-transform: lowercase;
}

/* Archived pill shown next to the title. */
.pm-archived-pill {
    display: inline-block;
    background: rgba(255,255,255,0.06);
    color: var(--text-muted);
    border-radius: 10px;
    padding: 1px 7px;
    font-size: 10px;
    margin-left: 8px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

/* Toggle-style filter chip (checkbox labelled). */
.pm-filter-toggle {
    cursor: pointer;
}
.pm-filter-toggle input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    width: 14px;
    height: 14px;
    border: 1.5px solid var(--border-light, var(--border));
    border-radius: 3px;
    margin: 0;
    cursor: pointer;
    position: relative;
    vertical-align: -2px;
}
.pm-filter-toggle input[type="checkbox"]:checked {
    background: var(--accent);
    border-color: var(--accent);
}
.pm-filter-toggle input[type="checkbox"]:checked::after {
    content: "✓";
    color: #fff;
    font-size: 10px;
    position: absolute;
    left: 1px;
    top: -2px;
    font-weight: 700;
}

/* Two-column layout inside the expanded detail. */
.pm-detail-twocol {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
}
.pm-detail-col {
    display: flex;
    flex-direction: column;
    gap: 14px;
    min-width: 0;
}
@media (max-width: 900px) {
    .pm-detail-twocol { grid-template-columns: 1fr; }
}

/* Pipeline-status checklist. */
.pm-detail-health {
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px 14px;
}
.pm-detail-health-head {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: var(--text-muted);
    margin-bottom: 10px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border);
}
.pm-detail-health-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4px 12px;
}
.pm-health-row {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
}
.pm-health-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    font-size: 12px;
    font-weight: 700;
    line-height: 1;
}
.pm-health-row[data-ok="1"] .pm-health-mark { background: rgba(76,175,80,0.18); color: #4caf50; }
.pm-health-row[data-ok="0"] .pm-health-mark { background: rgba(255,255,255,0.05); color: var(--text-muted); }
.pm-health-row[data-ok="1"] .pm-health-lbl { color: var(--text-primary); }
.pm-health-row[data-ok="0"] .pm-health-lbl { color: var(--text-muted); }

/* Lyrics preview in the expanded detail. */
.pm-lyrics-preview {
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px 14px;
}
.pm-lyrics-preview.is-empty {
    color: var(--text-muted);
    font-style: italic;
    font-size: 12px;
}
.pm-lyrics-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: var(--text-muted);
    margin-bottom: 8px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border);
}
.pm-lyrics-meta { font-weight: 500; }
.pm-lyrics-body {
    font-size: 12px;
    color: var(--text-primary);
    line-height: 1.5;
    white-space: pre-wrap;
}

/* Inline audio preview — stem dropdown + HTML5 player. */
.pm-audio-preview {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 8px;
}
.pm-audio-preview audio {
    flex: 1;
    min-width: 0;
    height: 36px;
    /* Chromium's native audio control is opaque white-on-light-grey
       by default and clashes with the dark app theme. Hue-rotate +
       invert + a slight opacity bleed the control into the surrounding
       card; the color-scheme hint tells Chromium to render its
       internal glyphs in dark-mode variants so the rotation lands in
       the right hue. */
    color-scheme: dark;
    opacity: 0.92;
    border-radius: 18px;
    background: transparent;
}
.pm-audio-preview audio::-webkit-media-controls-panel {
    background: color-mix(in srgb, var(--bg-tertiary) 85%, transparent);
    border-radius: 18px;
}
.pm-audio-preview audio::-webkit-media-controls-timeline,
.pm-audio-preview audio::-webkit-media-controls-volume-slider {
    /* Subtle accent tint on the progress + volume scrubbers so the
       play bar reads as part of the app rather than a browser widget. */
    filter: hue-rotate(210deg) saturate(0.9);
}
.pm-audio-preview audio::-webkit-media-controls-current-time-display,
.pm-audio-preview audio::-webkit-media-controls-time-remaining-display {
    color: var(--text-secondary);
    font-family: var(--font-mono);
    font-size: 11px;
}
.pm-audio-preview .pm-audio-stem {
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    color: var(--text-primary);
    border-radius: 6px;
    padding: 6px 8px;
    font-size: 12px;
    min-width: 100px;
    max-width: 160px;
    outline: none;
    cursor: pointer;
}
.pm-audio-preview .pm-audio-stem:focus { border-color: var(--accent); }

/* Top strip of the expanded detail: album art thumbnail + audio. */
.pm-detail-header-row {
    display: flex;
    gap: 14px;
    align-items: center;
    margin-bottom: 12px;
}
.pm-cover-art {
    flex-shrink: 0;
    width: 80px;
    height: 80px;
    border-radius: 8px;
    overflow: hidden;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: center;
}
.pm-cover-art img.pm-cover-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.pm-cover-loading {
    width: 20px;
    height: 20px;
    border: 2px solid var(--border);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: spin 0.9s linear infinite;
}
.pm-cover-placeholder {
    color: var(--text-muted);
    opacity: 0.45;
}
.pm-detail-header-body {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
}

/* Duplicate banner. */
.pm-detail-dup {
    background: color-mix(in srgb, var(--warning) 14%, transparent);
    border: 1px solid color-mix(in srgb, var(--warning) 40%, transparent);
    color: var(--text-primary);
    border-radius: var(--radius);
    padding: 10px 14px;
    margin-bottom: 12px;
    font-size: 12.5px;
    line-height: 1.4;
}
.pm-detail-dup strong { color: var(--warning); }
.pm-dup-link {
    color: var(--accent);
    text-decoration: underline;
    margin-right: 4px;
}

/* Read-only info card — created/modified/duration/size/ID/lyrics source. */
.pm-detail-info {
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px 14px;
    margin-bottom: 14px;
}
.pm-detail-info-head {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: var(--text-muted);
    margin-bottom: 10px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border);
}
.pm-detail-info-grid {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 6px 14px;
    margin: 0;
}
.pm-detail-info-grid dt {
    font-size: 11px;
    color: var(--text-muted);
    font-weight: 500;
}
.pm-detail-info-grid dd {
    margin: 0;
    font-size: 12px;
    color: var(--text-primary);
    font-family: var(--font-mono);
    word-break: break-all;
}
.pm-detail-pid code {
    background: rgba(0,0,0,0.35);
    padding: 2px 6px;
    border-radius: 4px;
    font-size: 11px;
    color: var(--text-muted);
}
.pm-stem-list {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.pm-stem-chip {
    --stem-color: #8b949e;
    display: inline-flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px 12px 8px 14px;
    background: color-mix(in srgb, var(--stem-color) 14%, var(--bg-card));
    border: 1px solid color-mix(in srgb, var(--stem-color) 45%, transparent);
    border-left: 4px solid var(--stem-color);
    border-radius: 6px;
    min-width: 110px;
    transition: background 140ms, border-color 140ms;
}
.pm-stem-chip:hover {
    background: color-mix(in srgb, var(--stem-color) 22%, var(--bg-card));
    border-color: color-mix(in srgb, var(--stem-color) 65%, transparent);
}
.pm-stem-name {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--text-primary);
}
.pm-stem-role {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: color-mix(in srgb, var(--stem-color) 70%, var(--text-muted));
    font-weight: 600;
}
/* Family-coloured chips — palette matches the timeline waveform
 * "progress" tones in multi_timeline.js so the same stem reads as
 * the same colour across the app. */
.pm-stem-chip[data-role="vocal"]      { --stem-color: #58a6ff; }
.pm-stem-chip[data-role="bass"]       { --stem-color: #39d2e0; }
.pm-stem-chip[data-role="drums"],
.pm-stem-chip[data-role="percussion"] { --stem-color: #d29922; }
.pm-stem-chip[data-role="guitar"]     { --stem-color: #bc8cff; }
.pm-stem-chip[data-role="keys"],
.pm-stem-chip[data-role="harmonic"]   { --stem-color: #3fb950; }
.pm-stem-chip[data-role="strings"]    { --stem-color: #f0883e; }
.pm-stem-chip[data-role="brass"],
.pm-stem-chip[data-role="winds"]      { --stem-color: #ffa45c; }
.pm-stem-chip[data-role="click"]      { --stem-color: #6e7681; }

.pm-empty {
    padding: 48px 24px;
    text-align: center;
    color: var(--text-muted);
    font-size: 13px;
    background: rgba(255,255,255,0.02);
    border: 1px dashed rgba(255,255,255,0.08);
    border-radius: 10px;
}

.project-card .project-delete:disabled {
    opacity: 0.4;
    cursor: wait;
}

/* Settings panel overlay */
#settings-panel {
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    background: rgba(0,0,0,0.35);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
}

#settings-panel[hidden] { display: none; }

/* Compact icon-only header buttons (settings cog, help) — fixed
 * frame size so adjacent icon buttons always have the same case
 * regardless of the glyph inside. The icon centers via the parent
 * .btn flex-row alignment. */
.btn.btn-icon-only {
    width: 36px;
    height: 36px;
    padding: 0;
    line-height: 1;
    align-self: center;
}

.btn.btn-icon-only svg {
    display: block;
    width: 18px;
    height: 18px;
}


/* Standard-size icon button — same padding & height as a text .btn
 * (like Save) but with an SVG glyph centered instead of text. Used by
 * Undo / Redo so they line up with the header's text buttons. */
.btn.btn-icon-std {
    padding: 8px 14px;
    line-height: 0;
}

.btn.btn-icon-std svg {
    display: block;
}

/* Tabbed settings modal — matches Recode's settings modal exactly
 * (max-width: 1300px; width: 95vw; height: 90vh).
 * Specificity bumped via `.modal.settings-modal` so it beats the
 * generic `.modal` rule that appears later in the file. */
.modal.settings-modal {
    width: 95vw;
    max-width: 1300px;
    height: 90vh;
    max-height: none;
    display: flex;
    flex-direction: column;
}

.settings-layout {
    flex: 1;
    display: flex;
    min-height: 0;
}

.settings-nav {
    width: 240px;
    flex-shrink: 0;
    border-right: 1px solid var(--border);
    padding: 6px 0 8px;
    margin-top: -4px;
    display: flex;
    flex-direction: column;
    background: var(--bg-tertiary);
}

.settings-nav-item {
    white-space: nowrap;
}

.settings-nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 16px;
    font-size: 13px;
    color: var(--text-secondary);
    cursor: pointer;
    border-left: 3px solid transparent;
    transition: all var(--transition);
}
/* Honour the [hidden] attribute despite our explicit display:flex above
 * (CSS specificity would otherwise win over the UA stylesheet). The
 * permission-gating in settings_ui.js sets hidden=true on superuser
 * tabs for non-admin users; without this rule those tabs stay visible. */
.settings-nav-item[hidden],
.settings-nav-divider[hidden],
.settings-nav-section[hidden],
.set-section[hidden] { display: none !important; }

.settings-nav-item .nav-icon {
    flex-shrink: 0;
    width: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: currentColor;
}

.settings-nav-item .nav-icon svg {
    display: block;
}

.settings-nav-item:hover {
    color: var(--text-primary);
    background: var(--bg-hover);
}

.settings-nav-item.active {
    color: var(--accent);
    border-left-color: var(--accent);
    background: var(--bg-hover);
    font-weight: 600;
}

.settings-panel-body {
    flex: 1;
    padding: 22px 28px;
    overflow-y: auto;
    min-width: 0;
}

.settings-footer {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 20px;
    background: var(--bg-tertiary);
    border-top: 1px solid var(--border);
}

.settings-status {
    font-size: 12px;
    color: var(--text-muted);
    transition: color var(--transition);
}

.settings-status[data-kind="dirty"] {
    color: var(--warning);
}

.settings-status[data-kind="saving"] {
    color: var(--accent);
}

.settings-status[data-kind="saved"]::before {
    content: "✓ ";
    color: var(--success);
    font-weight: 700;
}

.settings-status[data-kind="error"] {
    color: var(--error);
}

.set-section { display: none; }
.set-section.active { display: block; }

.set-section-title {
    font-size: 16px;
    font-weight: 700;
    margin: 0 0 4px;
    color: var(--text-primary);
}

.set-section-desc {
    font-size: 12px;
    color: var(--text-secondary);
    margin-bottom: 20px;
    line-height: 1.5;
}

.set-row {
    margin-bottom: 18px;
}

/* Click-track sound picker — one radio-row per sample with a preview
 * button on the right. Each label is the whole clickable row so the
 * radio toggles without needing pixel-perfect aim. */
.click-sound-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    max-width: 520px;
}

/* Summary block inside the Generate Click Track modal — compact
 * two-column key/value rows, same visual language as the sidebar
 * kv-row readouts. */
.click-modal-summary {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 6px 14px;
    padding: 10px 14px;
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 13px;
    margin: 4px 0 14px;
}
.click-modal-summary .label {
    color: var(--text-muted);
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    align-self: center;
}
.click-modal-summary .value {
    color: var(--text-primary);
    font-weight: 600;
}
.click-modal-summary .value.muted {
    color: var(--text-muted);
    font-weight: 400;
    font-style: italic;
}
.click-sound-row {
    display: grid;
    grid-template-columns: 18px 1fr auto auto;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: 6px;
    cursor: pointer;
    transition: border-color 120ms, background 120ms;
}
.click-sound-row:hover {
    border-color: color-mix(in srgb, var(--purple, #bc8cff) 40%, var(--border));
}
.click-sound-row input[type="radio"] {
    width: 16px;
    height: 16px;
    margin: 0;
    accent-color: var(--purple, #bc8cff);
    cursor: pointer;
}
.click-sound-row input[type="radio"]:checked ~ .click-sound-name {
    color: var(--text-primary);
    font-weight: 600;
}
.click-sound-row:has(input[type="radio"]:checked) {
    border-color: color-mix(in srgb, var(--purple, #bc8cff) 55%, var(--border));
    background: color-mix(in srgb, var(--purple, #bc8cff) 8%, var(--bg-input));
}
.click-sound-name {
    font-size: 14px;
    color: var(--text-primary);
}
.click-sound-meta {
    font-size: 12px;
    color: var(--text-muted);
}
.click-sound-preview {
    padding: 0 10px;
}

.set-row > label:not(.set-toggle) {
    display: block;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--text-muted);
    margin-bottom: 6px;
}

.set-row select,
.set-row input[type="text"],
.set-row textarea {
    width: 100%;
    max-width: 360px;
    padding: 7px 10px;
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-primary);
    font-size: 13px;
    font-family: inherit;
}

.set-row textarea {
    font-family: var(--font-mono);
    font-size: 12px;
    resize: vertical;
    line-height: 1.5;
    max-width: 480px;
}

/* Empty-lyrics placeholder shown inside the editor when timings.lines
   has no words. Matches the editor's vertical centering. */
.lyrics-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    text-align: center;
    padding: 60px 32px;
    color: var(--text-muted);
}
.lyrics-empty-icon {
    color: var(--accent);
    opacity: 0.9;
    margin-bottom: 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.lyrics-empty-title {
    font-size: 18px;
    font-weight: 600;
    color: var(--text-secondary);
}
.lyrics-empty-hint {
    font-size: 13px;
    line-height: 1.5;
    max-width: 460px;
}
.lyrics-empty-hint strong { color: var(--text-primary); }

/* Security tab — Recode-style helpers ported into mta-studio */
.form-group { margin-bottom: 12px; }
.form-group:last-child { margin-bottom: 0; }
.form-group > label {
    display: block;
    font-size: 12px;
    color: var(--text-secondary);
    margin-bottom: 4px;
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
}
.form-group input[type="text"],
.form-group input[type="password"],
.form-group select {
    width: 100%;
    padding: 8px 10px;
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text-primary);
    font-size: 13px;
    font-family: inherit;
    box-sizing: border-box;
}
.form-group input[type="text"]:focus,
.form-group input[type="password"]:focus,
.form-group select:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(88,166,255,0.15);
}
.set-desc {
    display: block;
    font-size: 10px;
    color: var(--text-muted);
    margin-top: 2px;
    line-height: 1.3;
    font-weight: normal;
    text-transform: none;
    letter-spacing: 0;
}
.set-chk {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    cursor: pointer;
    padding: 4px 0;
    color: var(--text-secondary);
    user-select: none;
}
.set-chk input[type="checkbox"] {
    -webkit-appearance: none;
    appearance: none;
    width: 34px;
    height: 18px;
    background: var(--bg-input);
    border-radius: 9px;
    position: relative;
    cursor: pointer;
    transition: background 0.2s;
    flex-shrink: 0;
    border: 1px solid var(--border);
    margin: 0;
}
.set-chk input[type="checkbox"]::after {
    content: '';
    position: absolute;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #fff;
    top: 1px;
    left: 1px;
    transition: transform 0.2s;
}
.set-chk input[type="checkbox"]:checked {
    background: var(--accent);
    border-color: var(--accent);
}
.set-chk input[type="checkbox"]:checked::after {
    transform: translateX(16px);
}

.set-row select:focus,
.set-row input[type="text"]:focus,
.set-row textarea:focus {
    outline: none;
    border-color: var(--accent);
}

.set-grid-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px 24px;
    margin-bottom: 8px;
}

.set-grid-2 .set-row {
    margin-bottom: 0;
}

.settings-nav-divider {
    height: 1px;
    background: var(--border);
    margin: 12px 0;
}

.settings-nav-section {
    padding: 4px 16px 6px;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: var(--text-muted);
}

.set-control {
    display: flex;
    align-items: center;
    gap: 12px;
}

.set-control input[type="range"] {
    flex: 1;
    max-width: 320px;
}

.set-value {
    min-width: 70px;
    font-family: var(--font-mono);
    font-size: 12px;
    font-weight: 600;
    color: var(--accent);
}

/* Toggle switches — pixel-for-pixel port of Recode's `.set-chk` style. */
.set-toggle {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    font-size: 13px;
    color: var(--text-primary);
    user-select: none;
}

.set-toggle input[type="checkbox"] {
    -webkit-appearance: none;
    appearance: none;
    width: 34px;
    height: 18px;
    background: var(--bg-hover);
    border-radius: 9px;
    position: relative;
    cursor: pointer;
    transition: background var(--transition);
    flex-shrink: 0;
    border: 1px solid var(--border);
    margin: 0;
}

.set-toggle input[type="checkbox"]::after {
    content: '';
    position: absolute;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #fff;
    top: 1px;
    left: 1px;
    transition: transform var(--transition);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

.set-toggle input[type="checkbox"]:checked {
    background: var(--accent);
    border-color: var(--accent);
}

.set-toggle input[type="checkbox"]:checked::after {
    transform: translateX(16px);
}

.set-toggle input[type="checkbox"]:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.set-hint {
    margin-top: 6px;
    font-size: 11px;
    color: var(--text-muted);
    line-height: 1.5;
}

.modal {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    width: 600px;
    max-width: 90vw;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    box-shadow: 0 20px 60px rgba(0,0,0,0.6);
}

.modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px;
    border-bottom: 1px solid var(--border);
}

.modal-header h2 { font-size: 16px; margin: 0; }

/* Empty editor: shown when ?view=editor with no project. Sidebar is
 * visible so the user can upload an MTA or pick a project. The main
 * pane just carries a centered "no project" hint. */
body.editor-empty .editor-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    height: 100%;
    color: var(--text-secondary);
    padding: 48px 24px;
}
body.editor-empty .editor-empty-state .editor-empty-icon {
    color: var(--accent);
    opacity: 0.85;
    margin-bottom: 14px;
}
body.editor-empty .editor-empty-state h2 {
    font-size: 22px;
    font-weight: 600;
    margin: 0 0 8px;
    color: var(--text-primary);
}
body.editor-empty .editor-empty-state p {
    margin: 0 0 24px;
    font-size: 14px;
    max-width: 440px;
}
body.editor-empty .editor-empty-actions {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    justify-content: center;
}

/* Drop-zone inside #stem-rows when the editor has no project. Big
 * target, shows an upload icon + call to action. Hovering with a
 * dragged file lights it up with the accent border. */
.stems-dropzone {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 32px 24px;
    margin: 12px;
    min-height: 240px;
    border: 2px dashed rgba(139,148,158,0.35);
    border-radius: 12px;
    background: rgba(255,255,255,0.02);
    color: var(--text-secondary);
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.stems-dropzone:hover {
    border-color: rgba(76,139,245,0.55);
    background: rgba(76,139,245,0.05);
    color: var(--text-primary);
}
.stems-dropzone.is-hovered {
    border-color: var(--accent);
    background: rgba(76,139,245,0.12);
    color: var(--text-primary);
    transform: scale(1.005);
}
.stems-dropzone-icon {
    color: var(--accent);
    opacity: 0.85;
    margin-bottom: 14px;
}
.stems-dropzone-title {
    font-size: 17px;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 6px;
}
.stems-dropzone-sub {
    font-size: 13px;
    max-width: 420px;
}

/* Overlay headers (Library + Device) match the editor's main header
 * exactly: same height, padding, background, gap, border. */
.overlay-header {
    padding: 12px 24px !important;
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--border);
    gap: 24px !important;
}
.overlay-nav {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
}

/* Overlay title: gradient app-mark + label */
.overlay-title {
    display: inline-flex;
    align-items: center;
    gap: 10px;
}
.overlay-title-mark {
    flex-shrink: 0;
    filter: drop-shadow(0 2px 6px rgba(76,139,245,0.35));
}

/* Mini-mark icon used inside cross-link buttons in overlay nav and the
 * editor's main header (Library / Device buttons). Slightly down-shifted
 * so the icon's optical centre aligns with the text baseline. */
.overlay-mini-mark {
    flex-shrink: 0;
    filter: drop-shadow(0 1px 3px rgba(0,0,0,0.4));
}

.modal-body { flex: 1; overflow-y: auto; padding: 16px 20px; }

.modal-footer {
    padding: 12px 20px;
    border-top: 1px solid var(--border);
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

/* Status dot */
.dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--text-muted);
    display: inline-block;
}
.dot.ok { background: var(--success); box-shadow: 0 0 6px var(--success); }
.dot.warn { background: var(--warning); }
.dot.err { background: var(--error); }

/* Badges */
.badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 2px 7px;
    border-radius: 4px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.2px;
    white-space: nowrap;
    text-transform: uppercase;
}

/* ===== Help modal — same shell as #settings-panel ===== */
#help-panel {
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    background: rgba(0,0,0,0.35);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
}
#help-panel[hidden] { display: none; }

/* Section pane visibility — only the active one shows */
.help-section { display: none; }
.help-section.active { display: block; }

/* Content typography — adapted from /opt/Recode/static/index.html */
.help-content h3 {
    color: var(--text-primary);
    margin: 28px 0 12px 0;
    font-size: 18px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border);
}
.help-content h3:first-child,
.help-content .help-section > h3:first-child { margin-top: 0; }

.help-content h4 {
    color: var(--accent);
    margin: 22px 0 10px 0;
    font-size: 14px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
}

.help-content p,
.help-content li {
    font-size: 13px;
    color: var(--text-secondary);
    line-height: 1.7;
}
.help-content p { margin: 8px 0; }
.help-content ul, .help-content ol { padding-left: 22px; margin: 8px 0; }
.help-content li { margin-bottom: 4px; }
.help-content strong { color: var(--text-primary); font-weight: 600; }
.help-content em { color: var(--text-primary); font-style: italic; }

.help-content code {
    background: var(--bg-tertiary);
    padding: 2px 6px;
    border-radius: 3px;
    font-size: 12px;
    color: var(--cyan);
    font-family: var(--font-mono, ui-monospace, "SF Mono", Menlo, monospace);
}

/* Tip / warn-tip callout boxes */
.help-content .tip {
    background: color-mix(in srgb, var(--accent) 10%, transparent);
    border-left: 3px solid var(--accent);
    padding: 10px 14px;
    margin: 14px 0;
    border-radius: 0 6px 6px 0;
    font-size: 12px;
    color: var(--text-secondary);
    line-height: 1.6;
}
.help-content .warn-tip {
    background: color-mix(in srgb, var(--error) 10%, transparent);
    border-left: 3px solid var(--error);
    padding: 10px 14px;
    margin: 14px 0;
    border-radius: 0 6px 6px 0;
    font-size: 12px;
    color: var(--text-secondary);
    line-height: 1.6;
}

/* Example boxes — for code snippets / sample output */
.help-content .example-box {
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 14px 16px;
    margin: 14px 0;
}
.help-content .example-box .example-title {
    font-size: 11px;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 8px;
    letter-spacing: 0.5px;
    font-weight: 600;
}

/* Flow diagrams — pipeline / chapter layout illustrations */
.help-content .flow-diagram {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin: 12px 0;
}
.help-content .flow-step {
    padding: 8px 14px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 12px;
    color: var(--text-primary);
    text-align: center;
    white-space: nowrap;
}
.help-content .flow-step.active {
    border-color: var(--accent);
    background: color-mix(in srgb, var(--accent) 12%, var(--bg-tertiary));
    color: var(--accent);
    font-weight: 600;
}
.help-content .flow-step.success {
    border-color: var(--success);
    background: color-mix(in srgb, var(--success) 12%, var(--bg-tertiary));
    color: var(--success);
    font-weight: 600;
}
.help-content .flow-step.danger {
    border-color: var(--error);
    background: color-mix(in srgb, var(--error) 12%, var(--bg-tertiary));
    color: var(--error);
}
.help-content .flow-arrow {
    color: var(--text-muted);
    font-size: 16px;
}

/* Preset cards — palette / option grids */
.help-content .preset-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 10px;
    margin: 12px 0;
}
.help-content .preset-card {
    padding: 12px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 8px;
}
.help-content .preset-card .preset-name {
    font-weight: 600;
    font-size: 13px;
    color: var(--text-primary);
    margin-bottom: 4px;
}
.help-content .preset-card .preset-vals {
    font-size: 11px;
    color: var(--cyan);
    font-family: var(--font-mono, ui-monospace, "SF Mono", Menlo, monospace);
    margin-bottom: 6px;
}
.help-content .preset-card .preset-desc {
    font-size: 11px;
    color: var(--text-muted);
    line-height: 1.5;
}

.help-content pre {
    background: var(--bg-secondary, var(--bg-tertiary));
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 10px 12px;
    overflow-x: auto;
    font-family: var(--font-mono, ui-monospace, "SF Mono", Menlo, monospace);
}

/* ──────────────────────────────────────────────────────────────────
 * Inline alert (injected by the inlineAlert() helper). Replaces the
 * corner toast for actions where the user is reading a specific
 * panel / modal. data-kind tints it: error (default), warning, info,
 * success.
 * ────────────────────────────────────────────────────────────────── */
.inline-alert {
    margin: 0 0 12px;
    padding: 10px 12px;
    background: color-mix(in srgb, var(--error) 12%, transparent);
    border: 1px solid color-mix(in srgb, var(--error) 40%, transparent);
    border-radius: 6px;
    color: var(--error);
    font-size: 13px;
    line-height: 1.4;
}
.inline-alert[data-kind="warning"] {
    background: color-mix(in srgb, var(--warning) 12%, transparent);
    border-color: color-mix(in srgb, var(--warning) 40%, transparent);
    color: var(--warning);
}
.inline-alert[data-kind="info"] {
    background: color-mix(in srgb, var(--accent) 12%, transparent);
    border-color: color-mix(in srgb, var(--accent) 40%, transparent);
    color: var(--accent);
}
.inline-alert[data-kind="success"] {
    background: color-mix(in srgb, var(--success) 12%, transparent);
    border-color: color-mix(in srgb, var(--success) 40%, transparent);
    color: var(--success);
}

/* ──────────────────────────────────────────────────────────────────
 * Lightweight stem volume sliders — overrides the heavier shared
 * "input[type=range]" styling above so the per-stem fader feels like
 * a level meter you can drag. Fill picks up --role-fill (set per-row
 * by _roleColor in multi_timeline.js). Thumb is invisible at rest;
 * a tiny dot appears on hover.
 * ────────────────────────────────────────────────────────────────── */
.stem-waveform-row .stem-vol {
    height: 3px;
    border-radius: 2px;
    --thumb-w: 0px;
    background: linear-gradient(
        to right,
        var(--role-fill, var(--accent)) 0,
        var(--role-fill, var(--accent)) calc(var(--fill-ratio, 0) * 100%),
        rgba(255,255,255,0.06) calc(var(--fill-ratio, 0) * 100%),
        rgba(255,255,255,0.06) 100%
    );
    transition: height 0.1s ease, background 0.12s ease;
}
.stem-waveform-row .stem-vol:hover { height: 4px; }

.stem-waveform-row .stem-vol::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: transparent;
    border: 0;
    cursor: pointer;
    transition: background 0.1s ease, transform 0.1s ease;
}
.stem-waveform-row .stem-vol::-moz-range-thumb {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: transparent;
    border: 0;
    cursor: pointer;
    transition: background 0.1s ease, transform 0.1s ease;
}
.stem-waveform-row .stem-vol:hover::-webkit-slider-thumb {
    background: var(--role-fill, var(--accent));
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--role-fill, var(--accent)) 25%, transparent);
}
.stem-waveform-row .stem-vol:hover::-moz-range-thumb {
    background: var(--role-fill, var(--accent));
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--role-fill, var(--accent)) 25%, transparent);
}
.stem-waveform-row .stem-vol:active::-webkit-slider-thumb {
    background: #fff;
    transform: scale(1.15);
}
.stem-waveform-row .stem-vol:active::-moz-range-thumb {
    background: #fff;
    transform: scale(1.15);
}

/* Compact (fit-mode / narrow) — even thinner. */
.stem-waveform-row.compact .stem-vol {
    height: 2px;
    border-radius: 1px;
}
.stem-waveform-row.compact .stem-vol:hover { height: 3px; }
.stem-waveform-row.compact .stem-vol::-webkit-slider-thumb { width: 7px; height: 7px; }
.stem-waveform-row.compact .stem-vol::-moz-range-thumb { width: 7px; height: 7px; }
