/* Jam Room DAW. "Warm Analog" look from the Premonition plugin (via the
   Claude Design export): cream panels, a dark chrome header, amber as the
   only color that means sound. Light is the default; [data-theme='dark']
   on <html> swaps in the dark variant (a per-user pref, ui/theme.js).
   Canvas views read their colors from these tokens via cssVar(), so
   retheming here retints the playlist, piano roll, rack and devices too. */

@font-face { font-family: 'DM Mono'; font-weight: 400; font-display: swap; src: url('../fonts/dm-mono-400-latin.woff2') format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: 'DM Mono'; font-weight: 400; font-display: swap; src: url('../fonts/dm-mono-400-latin-ext.woff2') format('woff2'); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: 'DM Mono'; font-weight: 500; font-display: swap; src: url('../fonts/dm-mono-500-latin.woff2') format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: 'DM Mono'; font-weight: 500; font-display: swap; src: url('../fonts/dm-mono-500-latin-ext.woff2') format('woff2'); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
/* Space Grotesk is a variable font: one file covers 400–600. */
@font-face { font-family: 'Space Grotesk'; font-weight: 300 700; font-display: swap; src: url('../fonts/space-grotesk-latin.woff2') format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: 'Space Grotesk'; font-weight: 300 700; font-display: swap; src: url('../fonts/space-grotesk-latin-ext.woff2') format('woff2'); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }

:root {
  /* surfaces + ink (Warm Analog light, Premonition Theme.h kThemes[0]) */
  --bg: #D9CFBD;
  --panel: #F1ECE1;
  --panel-2: #EDE7DA;
  --panel-3: #E9E2D3;
  --foot: #E3DBCA;
  --line: rgba(36, 25, 22, 0.2);
  --line-soft: rgba(36, 25, 22, 0.14);
  --text: #241916;
  --muted: #8A7A6C;
  --muted-2: #5B504A;
  --faint: #B3A599;
  --accent: #D39203;
  --folder: #4F6285; /* browser folder names (slate-blue) */
  --folder-bg: rgba(79, 98, 133, 0.16);
  --accent-ink: #241916;
  --warn: #A24617;
  --warn-ink: #F1ECE1;
  --solo: #2F6E7A;
  --solo-ink: #F1ECE1;
  --rec: #A24617;
  --rec-dot: #D9643A;
  --fill: #241916;
  --on-fill: #F1ECE1;
  --input-bg: #F1ECE1;

  /* the dark header band */
  --chrome: #241916;
  --chrome-2: #2E211C;
  --on-chrome: #F1ECE1;
  --chrome-muted: #B3A599;
  --chrome-line: rgba(241, 236, 225, 0.14);
  --chrome-on: #F1ECE1;
  --chrome-on-ink: #241916;
  /* hover tips (ui/tooltip.js) */
  --tip-bg: #2E211C;
  --tip-line: rgba(241, 236, 225, 0.14);
  --tip-muted: #B3A599;

  /* canvas */
  --grid-bg: #F1ECE1;
  --grid-row-black: #E9E2D3;
  --grid-row-scale: #EEE3CB;
  --grid-line: rgba(36, 25, 22, 0.06);
  --grid-beat: rgba(36, 25, 22, 0.12);
  --grid-bar: rgba(36, 25, 22, 0.24);
  --ruler-bg: #E3DBCA;
  --lane-bg: #E9E2D3;
  --row-alt: #EDE7DA;
  --row-sel: #E4DCCB;
  --key-white: #F1ECE1;
  --key-black: #241916;
  --key-label: #5B504A;
  --playhead: #D39203;
  --marker: #A24617;
  --loop: #D39203;
  --loop-tint: rgba(211, 146, 3, 0.06);
  --select: #241916;
  --clip-ink: #241916;
  --note-ink: #241916;
  --on-color: #F1ECE1; /* text on a solid track/pattern/user color */
  --ink-on-light: #241916; /* text on a light colour (inkOn, ui/util.js) */
  --ink-on-dark: #F1ECE1; /* text on a dark colour */
  --clip-end-shade: rgba(36, 25, 22, 0.08);
  --dim: rgba(36, 25, 22, 0.12);
  --meter-bg: #E3DBCA;
  --meter-lo: #218447;
  --meter-hi: #A24617;
  --step-off: rgba(36, 25, 22, 0.1);
  --step-alt: rgba(162, 70, 23, 0.16);
  --range-track: rgba(36, 25, 22, 0.16);
  --range-ring: #F1ECE1;

  --shadow: 0 14px 30px -22px rgba(36, 25, 22, 0.45);
  --pop-shadow: 0 16px 36px -14px rgba(36, 25, 22, 0.45);
  --scrim: rgb(36 25 22 / 0.35);

  --sans: 'Space Grotesk', ui-sans-serif, system-ui, sans-serif;
  --mono: 'DM Mono', ui-monospace, Menlo, monospace;
  --radius: 10px;
  --radius-sm: 6px;
  --header-h: 52px;
  --dock-h: 46vh;
  --devices-h: 250px; /* ui/devices.js sets it (folded: 30px) */
  font-family: var(--sans);
  font-size: 13px;
  color-scheme: light;
}

/* Warm Analog dark (Theme.h kThemes[0].dark). --solo is a lighter teal so
   it still reads on the dark panels. */
:root[data-theme='dark'] {
  --bg: #0F0907;
  --panel: #1B1210;
  --panel-2: #1E1512;
  --panel-3: #241916;
  --foot: #150E0C;
  --line: rgba(240, 230, 216, 0.2);
  --line-soft: rgba(240, 230, 216, 0.12);
  --text: #F0E6D8;
  --muted: #9A8474;
  --muted-2: #C8B7A5;
  --faint: #6B5B4E;
  --accent: #E0A01A;
  --folder: #8C9BB4;
  --folder-bg: rgba(140, 155, 180, 0.16);
  --accent-ink: #1B1210;
  --warn: #E87A30;
  --warn-ink: #1B1210;
  --solo: #4A9AA6;
  --solo-ink: #1B1210;
  --rec: #E87A30;
  --rec-dot: #E87A30;
  --fill: #F0E6D8;
  --on-fill: #1B1210;
  --input-bg: #150E0C;

  --chrome: #140D0B;
  --chrome-2: #1E1512;
  --on-chrome: #F0E6D8;
  --chrome-muted: #9A8474;
  --chrome-line: rgba(240, 230, 216, 0.12);
  --chrome-on: #F0E6D8;
  --chrome-on-ink: #140D0B;
  /* tips sit a step above the dark panels so they don't sink into them */
  --tip-bg: #4A382F;
  --tip-line: rgba(240, 230, 216, 0.24);
  --tip-muted: #C4B2A1;

  --grid-bg: #1B1210;
  --grid-row-black: #160F0D;
  --grid-row-scale: #2F2011;
  --grid-line: rgba(240, 230, 216, 0.05);
  --grid-beat: rgba(240, 230, 216, 0.1);
  --grid-bar: rgba(240, 230, 216, 0.22);
  --ruler-bg: #150E0C;
  --lane-bg: #150E0C;
  --row-alt: #1E1512;
  --row-sel: #2A1E19;
  --key-white: #E8DDCC;
  --key-black: #140D0B;
  --key-label: #5B504A;
  --playhead: #E0A01A;
  --marker: #E87A30;
  --loop: #E0A01A;
  --loop-tint: rgba(224, 160, 26, 0.07);
  --select: #F0E6D8;
  --clip-ink: #F0E6D8;
  --note-ink: #F0E6D8;
  --on-color: #F0E6D8;
  --ink-on-light: #1B1210;
  --ink-on-dark: #F0E6D8;
  --clip-end-shade: rgba(0, 0, 0, 0.25);
  --dim: rgba(0, 0, 0, 0.3);
  --meter-bg: #150E0C;
  --meter-lo: #62C878;
  --meter-hi: #E87A30;
  --step-off: rgba(240, 230, 216, 0.08);
  --step-alt: rgba(232, 122, 48, 0.18);
  --range-track: rgba(240, 230, 216, 0.16);
  --range-ring: #1B1210;

  --shadow: 0 14px 30px -18px rgba(0, 0, 0, 0.7);
  --pop-shadow: 0 16px 36px -12px rgba(0, 0, 0, 0.75);
  --scrim: rgb(0 0 0 / 0.6);
  color-scheme: dark;
}

/* Studio Dark: the default theme (ADR 2026-11-08_studio-dark-theme).
   Neutral near-black surfaces with a faint cool cast, stepping lighter from
   the work area out to the chrome; hairline dividers; white ink at a few
   fixed strengths; colour only for state. Amber still means sound only.
   Tokens read by hexA() (--text, --accent, --loop, --marker, --solo, --warn)
   must stay #RRGGBB. Brief: 04-plans/2026-11-08_studio-dark-theme-brief.md */
:root[data-theme='studio'] {
  --bg: #0F0F11;
  --panel: #16161A;
  --panel-2: #1A1A1E;
  --panel-3: #1E1E22;
  --foot: #131316;
  --line: rgba(255, 255, 255, 0.09);
  --line-soft: rgba(255, 255, 255, 0.05);
  --text: #DCDCE1;
  --muted: #7C7C84;
  --muted-2: #A4A4AC;
  --faint: #55555C;
  --accent: #E0A126;
  --folder: #8C9BB4;
  --folder-bg: rgba(140, 155, 180, 0.16);
  --accent-ink: #111113;
  --warn: #CF4136;
  --warn-ink: #F4F4F6;
  --solo: #C9A40E;
  --solo-ink: #111113;
  --rec: #CF4136;
  --rec-dot: #FF4F44;
  --fill: #E8E8EE;
  --on-fill: #111113;
  --input-bg: #111113;

  --chrome: #232327;
  --chrome-2: #2C2C31;
  --on-chrome: #DCDCE1;
  --chrome-muted: #8A8A92;
  --chrome-line: rgba(255, 255, 255, 0.08);
  --chrome-on: #E8E8EE;
  --chrome-on-ink: #111113;
  --tip-bg: #2E2E33;
  --tip-line: rgba(255, 255, 255, 0.14);
  --tip-muted: #A4A4AC;

  --grid-bg: #111113;
  --grid-row-black: #0D0D0F;
  --grid-row-scale: #1A1A20;
  --grid-line: rgba(255, 255, 255, 0.03);
  --grid-beat: rgba(255, 255, 255, 0.07);
  --grid-bar: rgba(255, 255, 255, 0.13);
  --ruler-bg: #1A1A1E;
  --lane-bg: #0D0D0F;
  --row-alt: #131316;
  --row-sel: #222229;
  --key-white: #D8D8DE;
  --key-black: #18181B;
  --key-label: #55555C;
  --playhead: #E0A126;
  --marker: #CF4136;
  --loop: #E0A126;
  --loop-tint: rgba(224, 161, 38, 0.06);
  --select: #E8E8EE;
  --clip-ink: #F4F4F6;
  --note-ink: #F4F4F6;
  --on-color: #F4F4F6;
  --ink-on-light: #111113;
  --ink-on-dark: #F4F4F6;
  --clip-end-shade: rgba(0, 0, 0, 0.28);
  --dim: rgba(0, 0, 0, 0.35);
  --meter-bg: #0D0D0F;
  --meter-lo: #62C878;
  --meter-hi: #CF4136;
  --step-off: rgba(118, 118, 130, 0.16);
  --step-alt: rgba(118, 118, 130, 0.28);
  --range-track: rgba(118, 118, 130, 0.22);
  --range-ring: #16161A;

  --shadow: 0 10px 24px -16px rgba(0, 0, 0, 0.8);
  --pop-shadow: 0 14px 32px -12px rgba(0, 0, 0, 0.85);
  --scrim: rgb(0 0 0 / 0.6);

  /* density: system UI type, tighter corners, a slimmer control bar */
  --sans: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', system-ui, sans-serif;
  --radius: 4px;
  --radius-sm: 3px;
  --header-h: 46px;
  font-size: 12px;
  color-scheme: dark;
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  display: grid;
  grid-template-rows: var(--header-h) minmax(120px, 1fr) 6px var(--dock-h) var(--devices-h);
  grid-template-columns: var(--insp-w, 0px) minmax(0, 1fr); /* --insp-w: the inspector column, set by ui/inspector.js (0px when hidden) */
  overflow: hidden;
}

button, input, select { font: inherit; color: inherit; }

button {
  background: transparent;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.3rem 0.6rem;
  cursor: pointer;
}
button:hover:not(:disabled) { border-color: var(--muted); background: var(--panel-2); }
button:disabled { opacity: 0.4; cursor: default; }
button:focus-visible, input:focus-visible, select:focus-visible, canvas:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
canvas:focus { outline: none; }

select, input[type='number'], input[type='text'] {
  background: var(--input-bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.25rem 0.4rem;
}

.ic { width: 14px; height: 14px; display: block; }
.spacer { flex: 1; }
input[type='number'] { font-family: var(--mono); font-variant-numeric: tabular-nums; }
/* Sliders are drawn from tokens: the native track can't be themed and
   glares near-white in dark mode. The fill uses the element's --c (track
   color) or amber; theme.js keeps --lo/--hi (fill start/end) in step with
   the value, and ranges that span zero (pan) fill out from the center. */
input[type='range'] {
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  height: 14px;
  cursor: pointer;
  --range-fill: var(--c, var(--accent));
  --range-grad: linear-gradient(to right, var(--range-track) var(--lo, 0%), var(--range-fill) var(--lo, 0%), var(--range-fill) var(--hi, 50%), var(--range-track) var(--hi, 50%));
}
input[type='range']::-webkit-slider-runnable-track { height: 4px; border-radius: 2px; background: var(--range-grad); }
input[type='range']::-moz-range-track { height: 4px; border-radius: 2px; background: var(--range-grad); }
input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 12px;
  height: 12px;
  margin-top: -4px;
  border: 0;
  border-radius: 50%;
  background: var(--range-fill);
  box-shadow: 0 0 0 2px var(--range-ring), 0 0 0 3px var(--line);
}
input[type='range']::-moz-range-thumb {
  width: 12px;
  height: 12px;
  border: 0;
  border-radius: 50%;
  background: var(--range-fill);
  box-shadow: 0 0 0 2px var(--range-ring), 0 0 0 3px var(--line);
}
/* Rotary knobs (ui/knob.js): an SVG face over a hidden range input, which
   keeps focus, keyboard arrows and events. The value arc uses --c (the
   track color) or amber; bipolar ranges (pan) turn out from the top. */
.knob { display: inline-grid; justify-items: center; gap: 1px; flex: none; user-select: none; line-height: 1.1; }
.knob-dial { position: relative; display: block; border-radius: 50%; }
.knob-dial svg { display: block; cursor: ns-resize; touch-action: none; }
.knob-dial input[type='range'] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; pointer-events: none; }
.knob-dial:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 1px; }
.knob-track { fill: none; stroke: var(--line); stroke-width: 3.5; stroke-linecap: round; }
.knob-val { fill: none; stroke: var(--c, var(--accent)); stroke-width: 3.5; stroke-linecap: round; }
.knob-face { fill: var(--panel-2); stroke: var(--line); stroke-width: 1; }
.knob-ptr { stroke: var(--text); stroke-width: 2.2; stroke-linecap: round; }
.knob-label { font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted); }
.knob-text { font-family: var(--mono); font-size: 10px; letter-spacing: 0.06em; color: var(--text); font-variant-numeric: tabular-nums; }
.knob:has(input:disabled) { opacity: 0.4; }
.knob:has(input:disabled) svg { cursor: default; }
.knob:has(.rk-swing), .rk-ctl .knob:has(.vol) { --c: var(--accent); }
kbd {
  font-family: var(--mono);
  font-size: 0.74rem;
  background: var(--panel-3);
  border: 1px solid var(--line);
  border-bottom-width: 2px;
  border-radius: 4px;
  padding: 0 0.35em;
  white-space: nowrap;
}

/* ---------- join overlay ---------- */

.overlay {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  padding: 16px;
  background: radial-gradient(circle at 50% 30%, var(--panel-2) 0%, var(--bg) 70%);
}
.overlay[hidden] { display: none; }
.join-card {
  width: min(520px, 100%);
  max-height: calc(100vh - 32px);
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: var(--shadow);
  padding: 2rem;
  display: grid;
  gap: 1rem;
}
.join-card h1 {
  margin: 0;
  font-size: 30px;
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--text);
}
.join-card p { margin: 0; color: var(--muted-2); line-height: 1.6; }
.join-card label { display: grid; gap: 0.35rem; color: var(--muted); }
.join-card label[hidden] { display: none; }
.join-card input { padding: 0.6rem 0.75rem; }
.join-card button[type='submit'] {
  background: var(--fill);
  color: var(--on-fill);
  border: 0;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  padding: 0.9rem;
}
.hint { color: var(--muted); font-size: 0.85rem; }
.hint code { color: var(--text); font-family: var(--mono); }

/* Sign-in on the join card + the Share popover (ui/share.js). ADR 2026-10-21_own-accounts. */
.auth { border: 1px solid var(--line-soft); border-radius: var(--radius); padding: 0.8rem 1rem 1rem; margin: 0; display: grid; gap: 0.7rem; }
.auth[hidden] { display: none; }
.auth legend { color: var(--text); font-weight: 600; padding: 0 0.3rem; }
.linkbtn { border: 0; background: none; padding: 0; color: var(--text); text-decoration: underline; font: inherit; cursor: pointer; }
.join-card .join-error { color: var(--warn); font-size: 0.9rem; line-height: 1.45; }
.join-error[hidden], #signed-in[hidden], #join-invited[hidden], #new-room[hidden], #join-go[hidden] { display: none; }
#new-room { color: var(--text); }
.share-pop {
  position: fixed;
  z-index: 160;
  width: 360px;
  max-width: calc(100vw - 16px);
  max-height: min(480px, calc(100vh - 80px));
  overflow-y: auto;
  padding: 10px 12px 12px;
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--pop-shadow);
  font-size: 12.5px;
}
.share-pop[hidden] { display: none; }
.share-pop h3 { font: 10px var(--mono); letter-spacing: 0.2em; text-transform: uppercase; color: var(--muted-2); margin: 10px 0 6px; }
.share-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.share-head h3 { margin-top: 0; }
.share-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.share-invite, .share-person { display: flex; align-items: center; gap: 6px; min-width: 0; }
.share-when, .share-email { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted-2); }
.share-name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 40%; }
.share-tag { font: 10px var(--mono); color: var(--muted); }
.share-note { color: var(--muted-2); line-height: 1.45; margin: 4px 0; }
.share-acts { display: flex; align-items: center; gap: 6px; }
.share-role { font-size: 11px; background: var(--panel-2); color: var(--text); border: 1px solid var(--line); border-radius: 4px; padding: 1px 4px; }
/* Roles: "Contributor" / "Listener" beside the Live pill (owner/editor show none). */
.role-pill { padding: 2px 10px; border-radius: 999px; border: 1px solid var(--line); color: var(--muted); font-size: 11px; font-weight: 600; white-space: nowrap; }
.role-pill[hidden] { display: none; }
/* Listen-link guests (no account): read-only, nothing to share, chat about or export. */
.is-guest #t-chat, .is-guest #t-export, .is-guest #invite, .is-guest #t-push, .is-guest #t-asks, .is-guest #t-room { display: none !important; }

/* ---------- transport ---------- */

.transport {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0 16px;
  background: var(--chrome);
  color: var(--on-chrome);
  border-bottom: 1px solid var(--chrome);
  min-width: 0;
  overflow-x: auto;
  overflow-y: hidden;
}
.brand { font-weight: 700; letter-spacing: 0.12em; white-space: nowrap; }
.brand .room { color: var(--chrome-muted); font-weight: 400; letter-spacing: 0; font-family: var(--mono); font-size: 12px; }
.transport button { background: var(--chrome-2); border-color: var(--chrome-line); color: var(--on-chrome); }
.transport button:hover:not(:disabled) { border-color: var(--chrome-muted); background: var(--chrome-2); }
.transport input { background: var(--chrome-2); border-color: var(--chrome-line); color: var(--on-chrome); }
#t-follow.on, #t-follow-continuous.on { background: var(--chrome-on); color: var(--chrome-on-ink); border-color: var(--chrome-on); }
#invite { font-family: var(--mono); font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase; background: var(--chrome-on); color: var(--chrome-on-ink); border-color: var(--chrome-on); padding: 0.5rem 0.9rem; }
#invite:hover:not(:disabled) { background: var(--chrome-on); border-color: var(--accent); }
.tgroup { display: flex; align-items: center; gap: 0.3rem; flex: none; }
.tbtn { padding: 0.35rem 0.5rem; line-height: 1; }
.tbtn.play.active, .toggle.on, .transport .tbtn.play.active, .transport .toggle.on { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.toggle { font-size: 0.85rem; }
.lcd {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  font-variant-numeric: tabular-nums;
  background: var(--chrome-2);
  color: var(--on-chrome);
  border: 1px solid var(--chrome-line);
  border-radius: var(--radius);
  padding: 0.3rem 0.6rem;
  min-width: 7.5rem;
  text-align: center;
  flex: none;
}
.tfield { display: flex; align-items: center; gap: 0.4rem; color: var(--chrome-muted); font-family: var(--mono); font-size: 9px; letter-spacing: 0.22em; flex: none; }
.tfield input { font-size: 12px; letter-spacing: 0; }
.tfield input { width: 4.2rem; }
#users { list-style: none; display: flex; align-items: center; margin: 0; padding: 0 0 0 4px; flex: none; }
#users li { display: flex; margin-left: -4px; }
/* Avatar stack (ui/presence.js): click someone to follow their view. */
.avatar {
  width: 24px;
  height: 24px;
  padding: 0;
  border-radius: 50%;
  border: 2px solid var(--chrome);
  background: var(--user);
  color: var(--ink, var(--on-color)); /* --ink set per avatar by inkOn */
  /* Halo ring in the counter-ink: initials sit on a mid-tone user colour that
     neither ink clears AA against. --ink-halo set per avatar by haloOn. */
  text-shadow:
    -1px 0 var(--ink-halo, transparent), 1px 0 var(--ink-halo, transparent),
    0 -1px var(--ink-halo, transparent), 0 1px var(--ink-halo, transparent);
  font: 600 10px/1 var(--sans);
  letter-spacing: 0.02em;
  display: grid;
  place-items: center;
  cursor: pointer;
  position: relative;
}
.avatar:hover:not(:disabled) { background: var(--user); border-color: var(--chrome); transform: translateY(-1px); z-index: 1; }
.avatar:focus-visible { outline: 2px solid var(--chrome-on); outline-offset: 1px; z-index: 1; }
.avatar.me, .avatar:disabled { cursor: default; opacity: 1; }
.avatar.me::after { content: ''; position: absolute; inset: -4px; border-radius: 50%; border: 1px dashed var(--chrome-muted); }
.avatar.following { box-shadow: 0 0 0 2px var(--chrome), 0 0 0 4px var(--user); z-index: 2; }
.avatar.more { background: var(--chrome-2); color: var(--chrome-muted); cursor: default; }
/* Follow mode: a frame in the followed person's colour + a pill to stop. */
.follow-frame { position: fixed; inset: 0; z-index: 150; pointer-events: none; box-shadow: inset 0 0 0 3px var(--user); }
.follow-frame[hidden] { display: none; }
.follow-pill {
  position: absolute;
  bottom: 3px;
  right: 16px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 3px 4px 3px 10px;
  border-radius: 8px 8px 0 0;
  background: var(--user);
  color: var(--on-color);
  font: 600 11px var(--sans);
  white-space: nowrap;
  max-width: calc(100vw - 32px);
  pointer-events: auto;
}
.follow-text { overflow: hidden; text-overflow: ellipsis; }
.follow-stop { padding: 1px 8px; font-size: 10px; border-radius: 4px; border: 1px solid var(--on-color); background: transparent; color: var(--on-color); }
.follow-stop:hover:not(:disabled) { background: var(--on-color); color: var(--user); border-color: var(--on-color); }
#invite { flex: none; white-space: nowrap; }
/* Room Play (ui/roomplay.js): the button next to Play, the session chip and
   the join card. The leader's presence colour (--user), never amber. */
.rp-wrap { display: flex; align-items: center; margin-left: 0.2rem; }
.rp-wrap [hidden] { display: none; }
.rp-chip {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 2px 3px 2px 9px;
  border-radius: var(--radius);
  background: var(--user);
  color: var(--on-color);
  font: 600 11px var(--sans);
  white-space: nowrap;
  max-width: 16rem;
}
.rp-chip-text { overflow: hidden; text-overflow: ellipsis; }
.transport .rp-chip-btn,
.rp-card button { padding: 2px 8px; font-size: 10px; border-radius: 4px; border: 1px solid var(--on-color); background: transparent; color: var(--on-color); white-space: nowrap; }
.transport .rp-chip-btn:hover:not(:disabled),
.rp-card button:hover:not(:disabled) { background: var(--on-color); color: var(--user); border-color: var(--on-color); }
.rp-card {
  position: fixed;
  z-index: 55;
  display: grid;
  gap: 8px;
  padding: 10px 12px;
  max-width: min(26rem, calc(100vw - 16px));
  border-radius: var(--radius);
  background: var(--user);
  color: var(--on-color);
  box-shadow: var(--pop-shadow);
  font: 12px var(--sans);
}
.rp-card[hidden] { display: none; }
.rp-msg { margin: 0; overflow-wrap: anywhere; }
.rp-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.rp-card .rp-join { background: var(--on-color); color: var(--user); }
#t-perf { color: var(--chrome-muted); font-family: var(--mono); font-size: 10px; letter-spacing: 0.04em; white-space: nowrap; }
#t-perf[hidden] { display: none; }
#status { color: var(--chrome-muted); font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em; white-space: nowrap; }

/* ---------- workspace: browser + playlist ---------- */

.workspace {
  display: grid;
  grid-template-columns: var(--browser-w, 460px) 1fr; /* --browser-w: per-user pref, set by ui/browser.js */
  min-height: 0;
}

.browser {
  background: var(--panel);
  border-right: 1px solid var(--line);
  overflow-y: auto;
  padding: 10px 8px;
}

/* ---------- playlist (FL × Ableton) ----------
   Track controls default to the RIGHT (Ableton); .left flips them (FL).
   --head-w is the per-user header width. Both are local preferences. */

.playlist {
  display: grid;
  grid-template-rows: 32px 1fr;
  min-height: 0;
  min-width: 0;
}
.pl-toolbar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 8px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  min-width: 0;
  overflow-x: auto;
}
.pl-title { font-family: var(--mono); font-size: 9px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted); margin-right: 4px; }
.pl-toolbar button { font-size: 0.86rem; min-height: 32px; padding: 0.25rem 0.6rem; white-space: nowrap; flex: none; }
.pl-recmode::before, .pl-recrep::before, .pl-recpunch::before, .pl-recset::before { display: inline-block; margin-right: 0.35em; font-size: 1.1em; line-height: 1; }
.pl-recmode::before { content: '◀|'; }
.pl-recrep::before { content: '⊕'; }
.pl-recpunch::before { content: '|●|'; }
.pl-recset::before { content: '⚙'; }
.pl-rec .record-icon { color: var(--rec); font-size: 1.1em; }
.pl-rec.on .record-icon { color: inherit; }
.pl-tools { display: flex; gap: 2px; flex: none; }
.pl-tool { padding: 0.25rem 0.4rem !important; }
.pl-tool.on,
.pl-recq.on,
.pl-recq.on:hover,
.pl-recrep.on,
.pl-recrep.on:hover,
.pl-recpunch.on,
.pl-recpunch.on:hover { background: var(--fill); color: var(--on-fill); border-color: var(--fill); }
.pl-recmode.on,
.pl-recmode.on:hover { background: var(--fill); color: var(--on-fill); border-color: var(--fill); }
.toggle.metro { padding-inline: 0.45rem; }
.pl-rec.on { background: var(--rec); color: var(--warn-ink); border-color: var(--rec); animation: rec-blink 1s steps(2) infinite; }
@keyframes rec-blink { 50% { opacity: 0.6; } }

.pl-body {
  --head-w: 230px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 5px var(--head-w);
  min-height: 0;
  min-width: 0;
}
.pl-body.left { grid-template-columns: var(--head-w) 5px minmax(0, 1fr); }
.pl-body.left .pl-heads { order: -2; }
.pl-body.left .pl-handle { order: -1; }
.pl-timeline { position: relative; min-width: 0; min-height: 0; }
#pl-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; touch-action: none; }
#pl-canvas[data-tool='draw'], #pl-canvas[data-tool='paint'] { cursor: cell; }
.pl-handle { background: var(--line-soft); cursor: col-resize; }
.pl-handle:hover, .pl-handle.drag { background: var(--accent); }

.pl-heads {
  display: grid;
  grid-template-rows: 46px 1fr;
  background: var(--panel);
  min-height: 0;
  min-width: 0;
}
.pl-corner {
  display: grid;
  grid-template-rows: 15px 1fr;
  align-items: center;
  padding: 0 8px;
  border-bottom: 1px solid var(--line);
  color: var(--muted);
  font-family: var(--mono);
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.22em;
}
.pl-corner-pat { font-size: 0.62rem; opacity: 0.7; }
.pl-head-scroll { overflow: hidden; position: relative; min-height: 0; }
.pl-head-list { position: absolute; left: 0; right: 0; top: 0; }

.ph {
  position: absolute;
  left: 0;
  right: 0;
  display: grid;
  grid-template-columns: 5px minmax(0, 1fr);
  border-bottom: 1px solid var(--line-soft);
  background: var(--panel);
  overflow: hidden;
}
.pl-body.right .ph { grid-template-columns: minmax(0, 1fr) 5px; }
.pl-body.right .ph .ph-color { order: 2; }
.ph.sel { background: var(--row-sel); }
.ph.child .ph-main { padding-left: 14px; }
.pl-body.right .ph.child .ph-main { padding-left: 6px; padding-right: 14px; }
/* Left mode is the mirror of right mode: the controls (fold, M, S, arm,
   vol, pan) hug the timeline edge and the name/menu sit on the outer edge,
   like FL's left-side headers. Only the layout flips; text stays LTR. */
.pl-body.left .ph-line { flex-direction: row-reverse; }
.ph.group { background: color-mix(in srgb, var(--c) 9%, var(--panel)); }
.ph.drop-before { box-shadow: inset 0 3px var(--select); }
.ph.drop-after { box-shadow: inset 0 -3px var(--select); }
.ph .ph-color { background: var(--c); border: 0; border-radius: 0; padding: 0; cursor: pointer; min-width: 0; }
.ph .ph-color.auto { background: color-mix(in srgb, var(--warn) 35%, transparent); cursor: default; }
.ph-main { display: flex; flex-direction: column; justify-content: center; gap: 3px; padding: 2px 6px; min-width: 0; }
.ph-line { display: flex; align-items: center; gap: 3px; min-width: 0; }
/* input.ph-name: beats the generic input[type='text'] box, so the name has
   no bubble until it's being renamed. */
input.ph-name {
  background: transparent;
  border: 1px solid transparent;
  padding: 0.05rem 0.25rem;
  font-weight: 600;
  min-width: 0;
  flex: 1;
}
input.ph-name:not([readonly]) { border-color: var(--line); background: var(--input-bg); }
.ph-name:focus { border-color: var(--line); background: var(--input-bg); }
/* Read-only until double-click / Rename: clicks fall through to the header
   (select, Shift/⌘-click to add) instead of starting a text edit. */
.ph-name[readonly] { pointer-events: none; cursor: default; text-overflow: ellipsis; user-select: none; }
.ph.muted .ph-name { opacity: 0.5; }
.ph button { padding: 0.02rem 0.32rem; font-size: 0.7rem; min-width: 20px; line-height: 1.4; flex: none; }
.ph-fold { border: 0 !important; background: transparent !important; min-width: 14px !important; padding: 0 !important; }
.ph-m { min-width: 20px !important; height: 16px; padding: 0 3px !important; border-radius: 3px !important; font: 600 10px/14px var(--mono) !important; text-align: center; background: var(--step-off) !important; border-color: var(--line) !important; color: var(--muted); }
.ph-m.on { background: var(--accent) !important; border-color: var(--accent) !important; color: var(--accent-ink); }
.ph-m.solo { outline: 2px solid var(--solo); }
.ph-s.on { background: var(--solo); color: var(--solo-ink); border-color: var(--solo); }
.ph.song-off, .strip.song-off, .rk-row.song-off { background-image: repeating-linear-gradient(135deg, var(--faint) 0 1px, transparent 1px 7px); }
.ph.song-off .ph-m, .rk-row.song-off .rk-led, .strip.song-off .sbtns .m { opacity: 0.45; }
.ph-arm.on { background: var(--rec); color: var(--warn-ink); border-color: var(--rec); }
.ph-kind { font-size: 0.68rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ph-vol { width: 60px; min-width: 30px; flex: 1; }
.ph-pan { width: 34px; flex: none; }
.ph-more { border: 0 !important; background: transparent !important; color: var(--muted); }
.pl-grid { font: 10px var(--mono); color: var(--muted); letter-spacing: 0.05em; margin: 0 4px; white-space: nowrap; }
.ph-size { position: absolute; left: 0; right: 0; bottom: 0; height: 4px; cursor: row-resize; }
.ph-size:hover { background: var(--accent); }
.ph.short .ph-line.full-only { display: none; }
.ph-auto { background: var(--lane-bg); }
.ph-auto-label { font-family: var(--mono); font-size: 9px; color: var(--warn); text-transform: uppercase; letter-spacing: 0.2em; }
.ph-param { font-size: 0.75rem; padding: 0.02rem 0.2rem; min-width: 0; flex: 1; }
.ph-mini { font-size: 0.68rem !important; }
/* Narrow header = FL-style compact: color, numbered activator, name. */
.pl-heads.compact .full-only { display: none !important; }

/* ---------- channel rack ---------- */

#pane-rack { grid-template-rows: auto 1fr auto; }
#pane-rack.active { display: grid; }
.rack-toolbar { display: flex; align-items: center; gap: 6px; padding: 6px 10px; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.rack-swatch { width: 10px; height: 18px; border-radius: 2px; }
.rack { overflow: auto; padding: 6px 8px 14px; min-height: 0; user-select: none; }
.rack[hidden] { display: none; }
.rack-empty { color: var(--muted); padding: 2rem; text-align: center; }
.rack-empty[hidden] { display: none; }
.rk-group { padding: 6px 4px 2px; font-family: var(--mono); font-size: 9px; text-transform: uppercase; letter-spacing: 0.22em; color: var(--c); }
.rk-row { display: flex; align-items: center; gap: 6px; height: 28px; width: max-content; min-width: 100%; }
.rk-row.child { padding-left: 12px; }
.rk-ctl { display: flex; align-items: center; gap: 4px; width: 132px; flex: none; }
.rk-row.sub .rk-ctl { visibility: hidden; }
.rk-led { width: 12px; height: 12px; border-radius: 50%; padding: 0; background: var(--step-off); flex: none; }
.rk-led.on { background: var(--accent); border-color: var(--accent); }
.rk-led.solo { outline: 2px solid var(--solo); }
.rk-knob { width: 40px; flex: none; }
.rk-knob.pan { width: 32px; }
.rk-ins { font: 10px var(--mono); color: var(--muted); min-width: 16px; text-align: right; }
.rk-name {
  width: 120px;
  flex: none;
  text-align: left;
  font-size: 0.78rem;
  padding: 0.2rem 0.5rem;
  border-left: 3px solid var(--c);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rk-row.sel .rk-name { background: var(--panel-3); border-color: var(--c); }
.rk-light { width: 8px; height: 20px; padding: 0; border-radius: 2px; background: var(--step-off); flex: none; }
.rk-light.on { background: var(--accent); }
.rk-steps { display: flex; gap: 2px; flex: none; }
.rk-steps[hidden] { display: none; }
.rk-step { width: 18px; height: 24px; padding: 0; border-radius: 3px; background: var(--step-off); border-color: transparent; }
.rk-step:hover:not(:disabled) { background: var(--step-off); border-color: var(--line); }
.rk-step.alt { background: var(--step-alt); }
.rk-step.on, .rk-step.on:hover:not(:disabled) { background: var(--c); border-color: var(--c); }
.rk-step:nth-child(4n + 1) { margin-left: 3px; }
.rk-preview { height: 24px; border-radius: 3px; border: 1px solid var(--line); cursor: pointer; flex: none; }
.rk-preview[hidden] { display: none; }
.rk-swing { width: 72px; --c: var(--accent); }
#rack-graph-btn[aria-pressed='true'] { background: var(--fill); border-color: var(--fill); color: var(--on-fill); }

/* Graph Editor (under the rack, FL style) */
.rk-graph { border-top: 1px solid var(--line); background: var(--panel); min-width: 0; }
.rk-graph[hidden] { display: none; }
.rk-graph-bar { display: flex; align-items: center; gap: 8px; padding: 4px 10px; flex-wrap: wrap; }
.rk-graph-tabs { display: flex; gap: 2px; }
.rk-graph-tabs button { font-size: 0.72rem; padding: 0.15rem 0.5rem; }
.rk-graph-tabs button[aria-selected='true'] { background: var(--fill); border-color: var(--fill); color: var(--on-fill); }
.rk-graph-row { font-size: 0.75rem; color: var(--muted); }
.rk-graph-canvas { display: block; width: 100%; height: 96px; touch-action: none; cursor: crosshair; }

/* ---------- setup + settings ---------- */

#setup-steps { display: grid; gap: 0.8rem; }
#setup-steps[hidden] { display: none; }
.setup-step { border: 0; padding: 0; margin: 0; display: grid; gap: 0.45rem; }
.setup-step legend { color: var(--text); font-weight: 600; margin-bottom: 0.4rem; }
.setup-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; }
.setup-cards.three { grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); }
.setup-card { display: flex !important; gap: 0.5rem; align-items: flex-start; border: 1px solid var(--line); border-radius: var(--radius); padding: 0.55rem 0.6rem; cursor: pointer; background: var(--panel-2); }
.setup-card:has(input:checked) { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.setup-card input { margin-top: 0.2rem; accent-color: var(--accent); }
.setup-card-body { display: grid; gap: 0.15rem; font-size: 0.8rem; color: var(--muted); }
.setup-card-body b { color: var(--text); font-size: 0.9rem; }
.setup-more summary { cursor: pointer; color: var(--muted); font-size: 0.8rem; }
.cheat-table { width: 100%; border-collapse: collapse; font-size: 0.76rem; margin-top: 0.4rem; }
.cheat-table th, .cheat-table td { text-align: left; padding: 0.25rem 0.35rem; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
.cheat-table th { color: var(--muted); font-family: var(--mono); font-size: 9px; font-weight: 400; letter-spacing: 0.2em; text-transform: uppercase; }
.settings-card { background: var(--panel); border: 1px solid var(--line); border-radius: 16px; box-shadow: var(--pop-shadow); padding: 1rem 1.2rem 1.2rem; width: min(620px, calc(100vw - 32px)); max-height: calc(100vh - 48px); overflow: auto; }
.settings-card h2 { margin: 0; font-size: 19px; font-weight: 600; letter-spacing: -0.01em; }
.settings-card h3 { font-family: var(--mono); font-size: 10px; font-weight: 400; text-transform: uppercase; letter-spacing: 0.26em; color: var(--muted); margin: 1rem 0 0.5rem; }
.set-radios { display: flex; gap: 1rem; flex-wrap: wrap; }
.set-radios label, .set-check { display: flex; align-items: center; gap: 0.4rem; cursor: pointer; }
.set-radios input, .set-check input { accent-color: var(--accent); }
.set-row { display: flex; gap: 0.5rem; margin-top: 0.6rem; }

/* ---------- splitter + dock ---------- */

.splitter {
  background: var(--line-soft);
  cursor: row-resize;
  border-top: 1px solid var(--line);
}
.splitter:hover, .splitter.drag { background: var(--accent); }

.dock {
  display: grid;
  grid-template-rows: 32px 1fr;
  background: var(--panel);
  min-height: 0;
}
.dock-tabs {
  display: flex;
  align-items: stretch;
  gap: 2px;
  padding: 0 8px;
  border-bottom: 1px solid var(--line);
}
.dock-tabs button {
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  color: var(--muted);
  padding: 0 0.9rem;
}
.dock-tabs button.active { color: var(--text); border-bottom-color: var(--accent); }
.dock-title { margin-left: auto; align-self: center; color: var(--muted); font-size: 12px; }

.tab-pane { display: none; min-height: 0; }
.tab-pane.active { display: grid; }
.floating-panel {
  position: fixed;
  z-index: 90;
  display: grid;
  grid-template-rows: 32px minmax(0, 1fr);
  min-width: min(320px, 100vw);
  min-height: min(180px, 100vh);
  max-width: 100vw;
  max-height: 100vh;
  resize: both;
  overflow: hidden;
  background: var(--bg);
  border: 1px solid var(--line);
  box-shadow: var(--pop-shadow);
}
.floating-panel[hidden] { display: none; }
.floating-panel #rack-float { display: none; }
.floating-panel-head {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 6px 0 10px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  cursor: move;
  touch-action: none;
  user-select: none;
}
.floating-panel-head > span { flex: 1; }
.panel-close { min-width: 28px; text-align: center; }
.dock-tabs .panel-close { padding: 0 8px; font-size: 16px; }
.dock-tabs [data-tab].floating-open { outline: 1px solid var(--select); outline-offset: -2px; }
#pane-roll { grid-template-rows: auto auto 1fr auto; }
#pane-mixer { overflow: auto; }

/* ---------- piano roll chrome ---------- */

.roll-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 0.8rem;
  padding: 6px 10px;
  border-bottom: 1px solid var(--line);
}
.clip-name { font-weight: 700; max-width: 16rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.glabel { font-family: var(--mono); font-size: 9px; letter-spacing: 0.24em; text-transform: uppercase; color: var(--muted); }
.seg { display: inline-flex; }
.seg .rbtn { border-radius: 0; margin-left: -1px; }
.seg .rbtn:first-child { border-radius: var(--radius) 0 0 var(--radius); margin-left: 0; }
.seg .rbtn:last-child { border-radius: 0 var(--radius) var(--radius) 0; }
.rbtn { padding: 0.25rem 0.5rem; font-size: 0.82rem; line-height: 1.2; }
.rbtn.tool.on, .rbtn.on { background: var(--fill); color: var(--on-fill); border-color: var(--fill); position: relative; }
/* keep the on-state fill under the global button:hover (0,2,1), or the --on-fill label vanishes on --panel-2 */
.rbtn.on:hover:not(:disabled) { background: var(--fill); border-color: var(--fill); }
.rinput { font-size: 0.82rem; padding: 0.2rem 0.3rem; }
.art-swatch { width: 12px; height: 12px; border-radius: 3px; background: var(--c, var(--muted)); }

.legendbar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 4px 10px;
  border-bottom: 1px solid var(--line);
  min-height: 30px;
  overflow-x: auto;
}
.legend-key-label { font-family: var(--mono); font-size: 9px; letter-spacing: 0.24em; text-transform: uppercase; color: var(--muted); }
.legend-chips { display: flex; gap: 0.3rem; flex-wrap: nowrap; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.78rem;
  padding: 0.12rem 0.5rem;
  border-radius: 999px;
  white-space: nowrap;
  border: 1px solid var(--line);
  background: var(--panel-2);
}
.chip .sw { width: 9px; height: 9px; border-radius: 50%; background: var(--c); }
.chip .num { color: var(--muted); font-family: var(--mono); font-size: 0.7rem; font-variant-numeric: tabular-nums; }
.chip.current { border-color: var(--c); }
.legend-status { margin-left: auto; color: var(--muted); font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; white-space: nowrap; }

.roll-stage { position: relative; min-height: 0; }
#roll-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; touch-action: none; }
/* Middle-button drag pan (ui/middlepan.js); beats the hover cursor the views set inline. */
#pl-canvas.panning, #roll-canvas.panning { cursor: grabbing !important; }
.roll-empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--muted);
  pointer-events: none;
}
.roll-empty[hidden] { display: none; }

.overlay-panel {
  position: absolute;
  inset: 12px;
  z-index: 5;
  overflow: auto;
  background: color-mix(in srgb, var(--panel) 97%, transparent);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--pop-shadow);
  padding: 14px 18px;
}
.overlay-panel[hidden] { display: none; }
.panel-head { display: flex; align-items: center; justify-content: space-between; }
.panel-head h2 { margin: 0; font-size: 1rem; }
.cheat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 0 2rem; }
.cheat-col h3 { font-family: var(--mono); font-size: 10px; font-weight: 400; text-transform: uppercase; letter-spacing: 0.26em; color: var(--muted); margin: 1rem 0 0.4rem; }
.cheat-row { display: grid; grid-template-columns: 7.5rem 1fr; gap: 0.6rem; align-items: center; padding: 0.18rem 0; font-size: 0.85rem; }
.cheat-row kbd { justify-self: start; }

.lane-footer {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 4px 10px;
  border-top: 1px solid var(--line);
  min-height: 32px;
  overflow-x: auto;
}
.lane-footer .num { width: 48px; text-align: center; font-family: var(--mono); font-variant-numeric: tabular-nums; cursor: ns-resize; -moz-appearance: textfield; }
.lane-footer .num::-webkit-outer-spin-button, .lane-footer .num::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.foot-sep { align-self: stretch; width: 1px; margin: 3px 0.25em; background: var(--line); }
.foot-label { font-family: var(--mono); font-size: 9px; letter-spacing: 0.24em; text-transform: uppercase; color: var(--muted); }
.foot-hint { color: var(--muted); font-size: 0.78rem; white-space: nowrap; }
.lane-footer.cc-mode .vel-tool { opacity: 0.35; pointer-events: none; }

/* ---------- context menu ---------- */

.ctx-menu {
  position: fixed;
  z-index: 60;
  min-width: 190px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 4px;
  box-shadow: var(--pop-shadow);
  display: grid;
}
.ctx-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: transparent;
  border: 0;
  border-radius: 5px;
  padding: 0.35rem 0.6rem;
  text-align: left;
}
.ctx-item:hover:not(:disabled) { background: var(--panel-3); }
.ctx-item .swatch { width: 10px; height: 10px; border-radius: 3px; flex: none; border: 1px solid var(--line-soft); }
.ctx-item .ctx-hint { margin-left: auto; color: var(--muted); font-family: var(--mono); font-size: 10px; }
.ctx-sep { height: 1px; background: var(--line); margin: 4px 2px; }
.ask-box { min-width: 220px; gap: 4px; padding: 8px; }
.ask-label { font-size: 0.72rem; color: var(--muted); }
.ask-input { width: 100%; }
/* "+ FX" search picker (ui/fxpicker.js) */
.fx-picker { width: 260px; gap: 4px; padding: 6px; }
.fx-pick-input { width: 100%; }
.fx-pick-list { display: grid; max-height: 320px; overflow-y: auto; }
.fx-pick-list .ctx-item.active:not(:disabled) { background: var(--panel-3); }
.fx-pick-head { padding: 0.4rem 0.6rem 0.15rem; color: var(--muted); font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; }
.fx-pick-empty, .fx-pick-note { padding: 0.6rem; color: var(--muted); text-align: center; font-size: 0.8rem; }

/* ---------- mixer ---------- */

.mixer { display: flex; gap: 8px; padding: 10px; align-items: stretch; min-height: 100%; }
.strip {
  width: 86px;
  flex: none;
  display: grid;
  grid-template-rows: auto auto auto 1fr auto auto;
  gap: 6px;
  justify-items: center;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-top: 3px solid var(--c);
  border-radius: 14px;
  padding: 8px 6px;
}
.strip.master { --c: var(--fill); border-top-color: var(--accent); margin-left: auto; }
/* Shared strip selection (ui/devicechain.js): every selected strip, and a
   thin text-coloured edge on the primary one (the Devices panel's). */
.strip.sel { background: var(--panel-3); }
.strip.primary { box-shadow: 0 0 0 1px var(--text); }
.strip .sname { font-size: 0.78rem; font-weight: 600; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.strip .pan { width: 70px; }
.strip .fader-row { display: flex; gap: 6px; align-items: stretch; min-height: 0; }
.strip .fader {
  writing-mode: vertical-lr;
  direction: rtl;
  width: 22px;
  min-height: 80px;
  height: auto;
  --range-grad: linear-gradient(to top, var(--range-track) var(--lo, 0%), var(--range-fill) var(--lo, 0%), var(--range-fill) var(--hi, 50%), var(--range-track) var(--hi, 50%));
}
.strip .fader::-webkit-slider-runnable-track { width: 4px; height: 100%; }
.strip .fader::-moz-range-track { width: 4px; height: 100%; }
.strip .fader::-webkit-slider-thumb { margin-top: 0; margin-left: -4px; }
.strip canvas.meter { width: 10px; height: 100%; min-height: 80px; background: var(--meter-bg); border-radius: 2px; cursor: pointer; }
.strip .sbtns { display: flex; gap: 3px; }
.strip .sbtns button { padding: 0.05rem 0.4rem; font-size: 0.72rem; }
.strip .sbtns .m.on { background: var(--warn); color: var(--warn-ink); border-color: var(--warn); }
.strip .sbtns .s.on { background: var(--solo); color: var(--solo-ink); border-color: var(--solo); }
.strip .db { font-family: var(--mono); font-size: 10px; color: var(--muted); font-variant-numeric: tabular-nums; }
.strip .fx-slots { display: grid; gap: 3px; width: 100%; max-height: 84px; overflow-y: auto; }
.strip .fx-slots button {
  width: 100%;
  padding: 0.05rem 0.3rem;
  font-size: 0.66rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--muted);
}
.strip.master { --c: var(--text); }
.strip.master .lufs { font-size: 10px; font-variant-numeric: tabular-nums; text-align: center; color: var(--muted); cursor: pointer; user-select: none; white-space: nowrap; }
.strip.master .lufs:hover, .strip.master .lufs:focus-visible { color: var(--text); }
.fx-row { display: flex; align-items: center; gap: 4px; min-width: 0; }
.strip .fx-row .fx-slot { flex: 1; min-width: 0; text-align: left; color: var(--text); }
.strip .fx-row.off .fx-slot { color: var(--muted); }
.strip .fx-row .fx-dot {
  flex: 0 0 10px; width: 10px; height: 10px; padding: 0;
  border: 1px solid var(--c); border-radius: 50%; background: transparent;
  touch-action: none;
}
.strip .fx-dot[aria-pressed=true], .strip .fx-dot.swiping[data-swipe-on=true] { background: var(--c); }
.strip .fx-dot.swiping[data-swipe-on=false] { background: transparent; }
.strip .fx-dot.swiping { outline: 1px solid var(--text); outline-offset: 2px; }
.strip .fx-add { border-style: dashed; }
/* ---------- Devices panel (ui/devices.js; mockup 3b) ---------- */

.devices {
  display: grid;
  grid-template-rows: 5px 30px minmax(0, 1fr);
  background: var(--panel);
  border-top: 1px solid var(--line);
  min-height: 0;
  overflow: hidden;
}
.devices.folded { grid-template-rows: 0 30px 0; }
.dev-resize { cursor: ns-resize; background: var(--panel-2); border-bottom: 1px solid var(--line); touch-action: none; }
.dev-resize:hover, .dev-resize.drag { background: var(--muted); }
.devices.folded .dev-resize { visibility: hidden; }
.dhead { display: flex; align-items: center; gap: 10px; padding: 0 10px; border-bottom: 1px solid var(--line-soft); min-width: 0; }
.dhead .sp, .dvh .sp { flex: 1; }
.dev-label { color: var(--faint); font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase; }
.dev-all {
  width: 12px;
  height: 12px;
  padding: 0;
  flex: none;
  border-radius: 3px;
  border: 1.5px solid var(--c);
  background: transparent;
  transition: background-color 0.12s, transform 0.12s cubic-bezier(0.23, 1, 0.32, 1);
}
.dev-all.on { background: var(--c); }
.dev-all:hover:not(:disabled) { border-color: var(--c); background: transparent; box-shadow: 0 0 0 3px var(--line-soft); }
.dev-all.on:hover:not(:disabled) { background: var(--c); }
.dev-all:active { transform: scale(0.85); }
.dev-all[hidden] { display: none; }
.dev-strip { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.dev-more { font-size: 11px; color: var(--muted-2); background: var(--panel-3); border: 1px solid var(--line); border-radius: 10px; padding: 1px 8px; white-space: nowrap; }
.dev-more[hidden] { display: none; }
.dev-insert { font-family: var(--mono); font-size: 11px; color: var(--muted-2); white-space: nowrap; }
.dev-fold { border: 0; padding: 0 4px; color: var(--muted); line-height: 1; }
.dev-fold:hover:not(:disabled) { color: var(--text); background: var(--panel-2); }
.devices.folded .dchain { display: none; }

.dchain { position: relative; display: flex; align-items: stretch; padding: 10px; overflow-x: auto; overflow-y: hidden; min-height: 0; }
.dchain.chainoff .dev { opacity: 0.45; filter: saturate(0.3); }
.dev {
  flex: none;
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--panel-3);
  border: 1px solid var(--line);
  border-radius: 5px;
  transition: border-color 0.2s, opacity 0.15s;
}
.dev.moving { opacity: 0.5; }
.dev.flash { animation: dev-flash 0.6s cubic-bezier(0.23, 1, 0.32, 1); }
@keyframes dev-flash {
  from { border-color: var(--select); box-shadow: 0 0 0 3px var(--select); }
  to { box-shadow: 0 0 0 0 transparent; }
}
.dvh {
  height: 26px;
  flex: none;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 0 8px;
  background: var(--panel-2);
  border-bottom: 1px solid var(--line-soft);
  border-radius: 5px 5px 0 0;
  cursor: grab;
  min-width: 0;
}
.dvh:active { cursor: grabbing; }
.dev-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.dev-pwr {
  width: 10px;
  height: 10px;
  padding: 0;
  flex: none;
  border-radius: 50%;
  border: 1.5px solid var(--c);
  background: transparent;
}
.dev-pwr.on { background: var(--c); }
.dev-pwr:hover:not(:disabled) { border-color: var(--c); box-shadow: 0 0 0 3px var(--line-soft); }
.dev-pwr.on:hover:not(:disabled) { background: var(--c); }
.dev-del { border: 0; padding: 0 3px; line-height: 1; color: var(--muted); opacity: 0; transition: opacity 0.12s; }
/* opacity, not visibility: the × stays in the tab order (keyboard users reach it). */
.dev:hover .dev-del, .dev:focus-within .dev-del, .dev-del:focus-visible { opacity: 1; }
.dev-del:hover:not(:disabled) { color: var(--text); background: var(--panel-3); }
.fx-warn { color: var(--warn); cursor: default; }
.fx-warn[hidden] { display: none; }
.dvb { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; padding: 10px; display: flex; flex-direction: column; gap: 8px; font-size: 0.78rem; transition: opacity 0.15s; }
.dev.off .dvb { opacity: 0.4; }
/* Folded card: a thin strip with its name running down. */
.dev.folded { width: 28px !important; }
.dev.folded .dvb, .dev.folded .dev-del, .dev.folded .fx-warn { display: none; }
.dev.folded .dvh { height: 100%; flex-direction: column; padding: 8px 0; border-bottom: 0; border-radius: 5px; }
.dev.folded .dev-name { writing-mode: vertical-rl; }
/* The source card (read-only: what makes this strip's sound). */
.dev-src { width: 150px; }
.dev-src .dvh { cursor: default; }
.dev-swatch { width: 10px; height: 10px; flex: none; border-radius: 2px; background: var(--c); }
.dev-src .dvb { align-items: center; justify-content: center; }
.dev-src-sw { width: 44px; height: 44px; border-radius: 6px; background: var(--c); opacity: 0.85; }
.dev-src-kind { font-family: var(--mono); font-size: 10px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; }
/* Level between two cards (amber: it's sound). */
.dmeter { position: relative; flex: none; width: 5px; margin: 16px 6px 6px; background: var(--meter-bg); border-radius: 2px; overflow: hidden; }
.dmeter i { position: absolute; left: 0; right: 0; bottom: 0; height: 0; background: var(--meter-lo); border-radius: 2px; }
.dadd {
  flex: none;
  width: 120px;
  margin-left: 8px;
  border: 1px dashed var(--line);
  border-radius: 5px;
  background: transparent;
  color: var(--faint);
  font-size: 18px;
}
.dadd:hover:not(:disabled) { color: var(--muted-2); border-color: var(--muted); background: transparent; }
.dadd[hidden] { display: none; }
/* Where a drop lands: a white bar in the gap. */
.dev-bar { position: absolute; top: 8px; bottom: 8px; width: 2px; border-radius: 1px; background: var(--select); pointer-events: none; }
.dev-bar[hidden] { display: none; }

/* Device bodies (ui/fxpanel.js buildCard): graph on top, knobs below. */
.knob[hidden], .fx-body [hidden] { display: none !important; }
.sc-row { display: grid; grid-template-columns: 64px 1fr 58px; align-items: center; gap: 6px; }
.sc-row select { grid-column: 2 / 4; min-width: 0; }
.sc-check { display: flex; align-items: center; gap: 6px; color: var(--muted); }
.sc-gr { display: grid; grid-template-columns: 64px 1fr 58px; align-items: center; gap: 6px; }
.sc-gr-bar { height: 6px; background: var(--meter-bg); border-radius: 2px; overflow: hidden; }
.sc-gr-fill { height: 100%; width: 0; background: var(--warn); }
.sc-gr-text { color: var(--muted); font-family: var(--mono); font-size: 10px; font-variant-numeric: tabular-nums; text-align: right; }
.fx-modes { display: grid; grid-template-columns: 1fr 1fr; gap: 3px; }
.fx-modes button { font-size: 0.74rem; color: var(--muted); padding: 0.15rem 0.3rem; }
.fx-modes button[aria-selected='true'] { color: var(--text); border-color: var(--c, var(--text)); background: var(--panel-2); }
.fx-key { display: grid; gap: 5px; }
.fx-trig { display: grid; grid-template-columns: 52px 1fr auto; gap: 6px; align-items: center; color: var(--muted); font-size: 0.74rem; }
.fx-trig select { min-width: 0; }
.fx-body canvas { width: 100%; flex: none; display: block; background: var(--lane-bg); border: 1px solid var(--line-soft); border-radius: var(--radius-sm); }
.fx-shape { height: 80px; cursor: grab; touch-action: none; display: none !important; }
.fx-body.shape .fx-shape { display: block !important; }
.fx-scope { height: 72px; }
.fx-eq-curve { height: 100px; cursor: grab; touch-action: none; }
.fx-modes.three { grid-template-columns: 1fr 1fr 1fr; }
.fx-clip-curve { height: 80px; }
.fx-delay-taps { height: 64px; }
.fx-modes.four { grid-template-columns: repeat(4, 1fr); }
.fx-verb-tail { height: 72px; }
.fx-lim-hist { height: 64px; }
.fx-knobs { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 8px; }
.fx-knob-x { display: inline-grid; justify-items: center; gap: 2px; }
.fx-auto { display: flex; align-items: center; gap: 3px; color: var(--muted); font-size: 0.68rem; }

/* ---------- narrow screens ---------- */

@media (max-width: 760px) {
  :root { --dock-h: 52vh; }
  .workspace { grid-template-columns: 1fr; }
  .pl-body { --head-w: 120px !important; }
  .pl-heads .full-only { display: none !important; }
  .setup-cards, .setup-cards.three { grid-template-columns: 1fr; }
  .brand .room, #status, #t-perf { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  * { scroll-behavior: auto !important; }
}
#settings { background: var(--scrim); }

/* ---------- plugin picker (ui/pluginpicker.js; reuses .settings-card) ---------- */
.plugin-picker { background: var(--scrim); }
.plugin-picker .pp-search { width: 100%; margin: 0.8rem 0 0.5rem; padding: 0.45rem 0.6rem; background: var(--input-bg); color: var(--text); border: 1px solid var(--line); border-radius: 6px; font: inherit; }
.plugin-picker .pp-list { display: grid; gap: 2px; max-height: min(52vh, 460px); overflow: auto; }
.plugin-picker .pp-row { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; padding: 0.4rem 0.6rem; background: none; color: var(--text); border: 0; border-radius: 5px; text-align: left; font: inherit; cursor: pointer; }
.plugin-picker .pp-row:hover, .plugin-picker .pp-row:focus-visible { background: var(--line-soft); outline: none; }
.plugin-picker .pp-row.current { color: var(--accent); }
.plugin-picker .pp-row small { color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.plugin-picker .pp-note { margin: 0.6rem 0 0; font-size: 0.76rem; }

/* ---------- browser panel (ui/browser.js): sidebar + tree + preview ----------
   13 px text, 28 px rows. Hover/selection tints mix --text so they show in
   every theme. Folders use --folder / --folder-bg; amber (--accent) = sound. */
.browser { display: grid; grid-template-columns: 156px minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr) auto; padding: 0; overflow: hidden; font-size: 13px; position: relative; }
.br-side { grid-row: 1 / 4; overflow-y: auto; padding: 2px 0 10px; border-right: 1px solid var(--line-soft); min-width: 0; }
.br-head { color: var(--faint); font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase; padding: 12px 12px 5px; margin: 0; font-weight: 400; font-family: var(--sans); }
.br-cat { display: flex; align-items: center; gap: 8px; width: calc(100% - 8px); height: 27px; padding: 0 8px; margin: 0 4px; border: 0; border-radius: 5px; background: transparent; color: var(--muted-2); text-align: left; font-size: 13px; min-width: 0; }
.br-cat:hover:not(:disabled) { color: var(--text); background: color-mix(in srgb, var(--text) 7%, transparent); }
.br-cat.on, .br-cat.on:hover { color: var(--text); background: color-mix(in srgb, var(--text) 13%, transparent); }
.br-cat.dim { opacity: 0.55; }
.br-cat span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.br-cat .br-meta { margin-left: auto; padding-left: 6px; }
.br-main { display: flex; flex-direction: column; min-width: 0; min-height: 0; grid-column: 2; grid-row: 1 / 3; }
.br-search { display: flex; align-items: center; gap: 7px; flex: none; margin: 8px 10px 6px; padding: 0 9px; height: 30px; border-radius: 6px; background: var(--bg); border: 1px solid var(--line-soft); }
.br-search:focus-within { border-color: var(--select); }
.br-search svg { flex: none; stroke: var(--muted); fill: none; }
.br-search input { flex: 1; min-width: 0; background: none; border: 0; outline: none; box-shadow: none; padding: 0; color: var(--text); font: inherit; font-size: 13px; }
.br-search input::placeholder { color: var(--faint); }
.br-tree { flex: 1; min-height: 0; overflow: auto; padding: 4px 6px 10px; outline: none; }
.br-row { display: flex; align-items: center; gap: 7px; height: 28px; padding-right: 8px; border-radius: 5px; white-space: nowrap; position: relative; color: var(--text); }
.br-row:hover { background: color-mix(in srgb, var(--text) 6%, transparent); }
.br-row.sel { background: color-mix(in srgb, var(--text) 12%, transparent); }
.br-tree:focus .br-row.sel { background: color-mix(in srgb, var(--text) 17%, transparent); }
.br-tree:focus .br-row.sel.focus-edge, .br-row.focus-edge { box-shadow: inset 2px 0 0 var(--select); }
.br-chev { width: 14px; height: 14px; display: grid; place-items: center; color: var(--faint); flex: none; border-radius: 3px; background: transparent; border: 0; padding: 0; }
.br-chev svg { stroke: currentColor; fill: none; }
.br-row.open > .br-chev svg { transform: rotate(90deg); }
.br-chev:hover { color: var(--text); }
.br-ico { flex: none; width: 16px; height: 16px; display: grid; place-items: center; color: var(--muted); }
.br-ico svg { stroke: currentColor; fill: none; }
.br-swatch { flex: none; width: 9px; height: 9px; border-radius: 2px; background: var(--c, var(--muted)); }
.br-name { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.br-meta { margin-left: auto; padding-left: 10px; font-family: var(--mono); font-size: 10.5px; color: var(--muted); }
.br-path { font-family: var(--mono); font-size: 10px; color: var(--faint); overflow: hidden; text-overflow: ellipsis; min-width: 0; flex: 0 1 auto; margin-left: 6px; }
.br-row.folder .br-ico { color: var(--folder); }
.br-row.folder .br-ico svg { fill: var(--folder-bg); }
.br-row.folder .br-name { color: var(--folder); font-weight: 500; }
.br-row.folder.device .br-name { color: var(--text); }
.br-row.folder .br-meta { color: var(--faint); font-size: 10px; }
.br-mark { background: color-mix(in srgb, var(--text) 18%, transparent); color: var(--text); border-radius: 2px; padding: 0 1px; }
.br-row.playing .br-ico { color: var(--accent); }
.br-preview { grid-column: 2; display: flex; flex-direction: column; gap: 6px; min-width: 0; padding: 8px 10px 10px; border-top: 1px solid var(--line-soft); }
.br-preview[hidden] { display: none; }
.brp-bar { display: flex; align-items: center; gap: 8px; min-width: 0; height: 22px; }
.brp-phones { flex: none; width: 24px; height: 22px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 4px; background: transparent; color: var(--faint); }
.brp-phones svg { stroke: currentColor; fill: none; stroke-width: 1.3; stroke-linejoin: round; }
.brp-phones:hover { color: var(--text); background: color-mix(in srgb, var(--text) 7%, transparent); }
.brp-phones.on { color: var(--accent); }
.brp-seg { display: flex; flex: none; border: 1px solid var(--line-soft); border-radius: 4px; overflow: hidden; }
.brp-mode { height: 20px; padding: 0 8px; border: 0; border-radius: 0; background: transparent; color: var(--muted); font-size: 11px; }
.brp-mode + .brp-mode { border-left: 1px solid var(--line-soft); }
.brp-mode:hover:not(:disabled) { color: var(--text); }
.brp-mode.on { color: var(--text); background: color-mix(in srgb, var(--text) 13%, transparent); }
.brp-mode:disabled { opacity: 0.4; cursor: default; }
.brp-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font-size: 11.5px; margin-left: auto; }
.brp-wave { display: block; width: 100%; height: 38px; border-radius: 4px; cursor: pointer; }
.br-preview.off .brp-wave { opacity: 0.5; }
.br-resize { position: absolute; top: 0; right: 0; bottom: 0; width: 6px; cursor: col-resize; z-index: 5; background: transparent; }
.br-resize:hover, .br-resize.on { background: color-mix(in srgb, var(--text) 18%, transparent); }
.br-row[draggable='true'] { cursor: grab; }
.br-row.hit .br-name { flex-shrink: 0; max-width: 65%; } /* search results: the path gives way first */
.br-row.status { color: var(--muted); padding-left: 10px; }
.br-cat svg { flex: none; stroke: currentColor; fill: none; }
.br-cat.fold svg { color: var(--folder); fill: var(--folder-bg); }
.br-main [hidden] { display: none; }
/* Sample folders (data: ui/samples.js): a folder that lost read access after a
   reload shows one Reconnect row; a folder dragged in from Finder outlines the pane. */
.br-row.reconnect { width: 100%; border: 0; background: transparent; font: inherit; text-align: left; color: var(--warn); cursor: pointer; }
.br-row.reconnect:hover { background: color-mix(in srgb, var(--text) 6%, transparent); }
.br-main.br-drop, .br-side.br-drop { outline: 1px dashed var(--text); outline-offset: -2px; border-radius: 4px; }
@media (max-width: 760px) { .browser { display: none; } } /* after the grid rule above, so it still wins */
/* The Info box (ui/tooltip.js) sits under both columns. */
.browser > .info-view { grid-column: 1 / -1; position: static; margin: 0; }


/* ---------- piano roll: track picker, instrument button, multi-track chips ---------- */
.roll-track { max-width: 10rem; font-weight: 700; }
#roll-inst { display: inline-flex; align-items: center; gap: 0.3rem; max-width: 12rem; }
#roll-inst-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.roll-multi { display: inline-flex; align-items: center; gap: 0.25rem; flex-wrap: wrap; }
.roll-multi[hidden] { display: none; }
.roll-multi .chip { cursor: pointer; opacity: 0.7; }
.roll-multi .chip.current { opacity: 1; border-color: var(--c); background: var(--panel); font-weight: 700; }

/* ---------- live cursors (ui/presence.js): other people's pointers over the Channel Rack ---------- */
#rack { position: relative; }
.peer-layer { position: absolute; top: 0; left: 0; width: 0; height: 0; z-index: 5; pointer-events: none; }
.peer-cursor { position: absolute; top: 0; left: 0; transition: transform 60ms linear, opacity 0.4s; will-change: transform; }
.peer-cursor svg { display: block; overflow: visible; }
.peer-cursor path { fill: var(--c); stroke: var(--on-color); stroke-width: 1.5; stroke-linejoin: round; }
.peer-tag {
  position: absolute;
  left: 10px;
  top: 15px;
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--c);
  color: var(--on-color);
  font: 600 10px var(--sans);
  white-space: nowrap;
}
@media (prefers-reduced-motion: reduce) { .peer-cursor { transition: none; } }

/* ---------- export dialog (ui/exportdialog.js; reuses .settings-card) ---------- */
.export-dialog { background: var(--scrim); }
.export-dialog .set-radios { flex-direction: column; gap: 0.35rem; }
.export-dialog .ex-off { color: var(--muted); cursor: default; }
.export-dialog .ex-grid { display: flex; flex-wrap: wrap; gap: 0.8rem; margin: 0.8rem 0 0.6rem; }
.export-dialog .ex-grid label { display: grid; gap: 0.25rem; font-size: 0.76rem; color: var(--muted); }
.export-dialog .ex-grid input { width: 5rem; }
.export-dialog .set-check { margin-top: 0.35rem; }
.export-dialog .ex-warn { margin: 0.6rem 0 0; }
.export-dialog .ex-progress { display: flex; align-items: center; gap: 0.6rem; margin-top: 0.6rem; }
.export-dialog .ex-progress[hidden] { display: none; }
.export-dialog progress { flex: 1; accent-color: var(--accent); }
.export-dialog .ex-plugins { margin-top: 0.6rem; }
.export-dialog .ex-plugins > p { margin: 0; }
.export-dialog .ex-plugins .ex-warn { margin: 0.15rem 0 0 1.6rem; }
.export-dialog .ex-cancel[hidden] { display: none; }
/* recording latency dialog (ui/latencydialog.js) */
.latency-dialog .lat-rows { display: grid; gap: 0.3rem; margin-top: 0.6rem; }
.latency-dialog .lat-row { display: flex; justify-content: space-between; gap: 1rem; font-size: 0.86rem; }
.latency-dialog .lat-row b { font-family: var(--mono); font-weight: 500; }
.latency-dialog .lat-msg:empty { display: none; }
.latency-dialog .ov-grid { display: grid; grid-template-columns: auto 1fr 1fr; gap: 0.4rem 0.6rem; align-items: center; margin-top: 0.6rem; }
.latency-dialog .ov-col { font-size: 0.8rem; font-weight: 600; }
.latency-dialog .ov-label { font-size: 0.82rem; color: var(--muted); text-align: right; }
.latency-dialog .ov-sel { width: 100%; min-width: 0; }

/* ---------- hover tips (ui/tooltip.js) ---------- */
.tip {
  position: fixed;
  z-index: 200;
  max-width: 280px;
  padding: 7px 9px;
  border-radius: 6px;
  background: var(--tip-bg);
  color: var(--on-chrome);
  border: 1px solid var(--tip-line);
  box-shadow: var(--pop-shadow);
  font: 12px/1.35 var(--sans);
  pointer-events: none;
}
.tip[hidden], .tip [hidden] { display: none; }
.tip-head { display: flex; align-items: baseline; gap: 8px; }
.tip-name { font-weight: 600; }
.tip-key {
  font: 10px var(--mono);
  letter-spacing: 0.04em;
  padding: 1px 5px;
  border-radius: 3px;
  border: 1px solid var(--tip-line);
  color: var(--tip-muted);
}
.tip-value { margin-left: auto; padding-left: 10px; font: 11px var(--mono); color: var(--on-chrome); font-variant-numeric: tabular-nums; white-space: nowrap; }
.tip-desc { margin-top: 3px; color: var(--on-chrome); opacity: 0.86; }
.tip-head[hidden] + .tip-desc { margin-top: 0; }
.tip-reset { margin-top: 4px; font: 10px var(--mono); letter-spacing: 0.04em; color: var(--tip-muted); }
/* The Info box (pref tipPlace 'box'): docked at the bottom of the left
   panel like Ableton's Info View. Same rows as .tip, panel colours. */
.info-view {
  position: sticky;
  bottom: -10px;
  margin: auto -8px -10px;
  padding: 8px 26px 10px 10px;
  min-height: 92px;
  flex: none;
  background: var(--panel-2);
  border-top: 1px solid var(--line);
  color: var(--text);
  font: 12px/1.35 var(--sans);
}
.info-view[hidden], .info-view [hidden] { display: none; }
.info-view .tip-key { border-color: var(--line); color: var(--muted); }
.info-view .tip-value, .info-view .tip-desc { color: var(--text); }
.info-view .tip-reset { color: var(--muted); }
.info-idle { color: var(--muted); }
.info-close { position: absolute; top: 4px; right: 4px; width: 20px; height: 20px; padding: 0; line-height: 1; background: none; border: 0; color: var(--muted); cursor: pointer; }
.info-close:hover { color: var(--text); }

/* ---------- room chat (ui/chat.js): a third workspace column ---------- */
.workspace.chat-open { grid-template-columns: var(--browser-w, 460px) minmax(0, 1fr) 280px; }
.chat-btn { position: relative; flex: none; display: inline-flex; align-items: center; gap: 5px; }
.chat-ico { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linejoin: round; }
.chat-btn .badge {
  position: absolute;
  top: -5px;
  right: -6px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 8px;
  background: var(--warn);
  color: var(--warn-ink);
  font: 600 10px/16px var(--sans);
  text-align: center;
  box-shadow: 0 0 0 2px var(--chrome);
}
.chat-btn .badge[hidden] { display: none; }
.chat {
  display: grid;
  grid-template-rows: 32px minmax(0, 1fr) auto;
  min-height: 0;
  min-width: 0;
  background: var(--panel);
  border-left: 1px solid var(--line);
}
.chat[hidden] { display: none; }
.chat-head { display: flex; align-items: center; justify-content: space-between; padding: 0 6px 0 12px; border-bottom: 1px solid var(--line-soft); background: var(--panel-2); }
.chat-title { font: 10px var(--mono); letter-spacing: 0.2em; text-transform: uppercase; color: var(--muted-2); }
.chat-x { border: 0; padding: 0 6px; font-size: 16px; line-height: 1; color: var(--muted-2); }
.chat-list { list-style: none; margin: 0; padding: 8px 12px; overflow-y: auto; overscroll-behavior: contain; }
.chat-msg { margin-top: 10px; }
.chat-msg.cont { margin-top: 3px; }
.chat-msg:first-child { margin-top: 0; }
.chat-meta { display: flex; align-items: center; gap: 6px; margin-bottom: 2px; min-width: 0; }
.chat-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--user); flex: none; }
.chat-name { font-weight: 600; font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-time { margin-left: auto; font: 10px var(--mono); color: var(--muted); flex: none; }
.chat-text { padding-left: 14px; white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.4; }
.chat-empty { color: var(--muted); font-size: 12px; line-height: 1.45; padding-top: 4px; }
.chat-form { position: relative; display: flex; align-items: flex-end; gap: 6px; padding: 8px; border-top: 1px solid var(--line-soft); }
#chat-input {
  flex: 1;
  min-width: 0;
  resize: none;
  font: inherit;
  line-height: 1.35;
  padding: 6px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--input-bg);
  color: var(--text);
  max-height: 120px;
}
#chat-input:focus-visible { outline: 2px solid var(--select); outline-offset: 0; }
#chat-input.bad { border-color: var(--warn); }
.chat-count { position: absolute; right: 70px; top: -14px; font: 10px var(--mono); color: var(--muted); }
.chat-count[hidden] { display: none; }
.chat-send { flex: none; }

/* ---------- timeline comments (ui/comments.js): flags in the ruler + popover ---------- */
.cm-pop {
  position: fixed;
  z-index: 160;
  width: 340px;
  max-width: calc(100vw - 16px);
  max-height: min(460px, calc(100vh - 80px));
  overflow-y: auto;
  padding: 10px 12px 12px;
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--pop-shadow);
  font-size: 12.5px;
}
.cm-bar { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; min-width: 0; }
.cm-bar .spacer { flex: 1; }
.cm-pos { font: 10px var(--mono); letter-spacing: 0.06em; color: var(--muted-2); white-space: nowrap; }
.cm-track { font-size: 11px; padding: 1px 6px; border-radius: 4px; background: var(--c); color: var(--on-color); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; max-width: 120px; flex: 0 1 auto; }
.cm-bar .cm-btn, .cm-pos { flex: none; }
.cm-track.all { background: var(--panel-3); color: var(--muted-2); }
.cm-head { display: flex; align-items: center; gap: 6px; min-width: 0; }
.cm-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.cm-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cm-time { margin-left: auto; font: 10px var(--mono); color: var(--muted); flex: none; }
.cm-text { margin: 3px 0 0 14px; white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.4; }
.cm-pop.resolved > .cm-text { color: var(--muted-2); }
.cm-own { margin: 2px 0 0 14px; }
.cm-replies { list-style: none; margin: 10px 0 0; padding: 8px 0 0; border-top: 1px solid var(--line-soft); display: grid; gap: 8px; }
.cm-reply { margin-top: 10px; }
.cm-input {
  display: block;
  width: 100%;
  margin-top: 8px;
  resize: vertical;
  min-height: 2.6em;
  max-height: 160px;
  font: inherit;
  line-height: 1.35;
  padding: 6px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--input-bg);
  color: var(--text);
}
.cm-reply .cm-input { margin-top: 0; }
.cm-input:focus-visible { outline: 2px solid var(--select); outline-offset: 0; }
.cm-actions { display: flex; justify-content: flex-end; gap: 6px; margin-top: 6px; }
.cm-btn { font-size: 11px; padding: 2px 8px; border-radius: var(--radius-sm); white-space: nowrap; }
.cm-btn.primary { background: var(--fill); color: var(--on-fill); border-color: var(--fill); }
.cm-btn.primary:hover:not(:disabled) { background: var(--fill); border-color: var(--fill); opacity: 0.9; }
.cm-btn.danger:hover:not(:disabled) { border-color: var(--warn); color: var(--warn); background: transparent; }
.cm-btn.ghost { border-color: transparent; }
.cm-btn.x { padding: 0 5px; font-size: 14px; line-height: 1; color: var(--muted-2); }
.cm-head .cm-btn.x { margin-left: 2px; }
.cm-btn.link { border: 0; padding: 0; color: var(--muted-2); text-decoration: underline; text-underline-offset: 2px; }

/* ---------- Studio Dark polish (2026-11-08) ----------
   Amber means sound only: under Studio, focus rings use the cool --select
   and controls without a track colour fill in neutral grey, so the playhead,
   loop and meters are the only amber on screen. */
:root[data-theme='studio'] :is(button, input, select, canvas):focus-visible,
:root[data-theme='studio'] .knob-dial:has(input:focus-visible) { outline-color: var(--select); }
:root[data-theme='studio'] input[type='range'] { --range-fill: var(--c, var(--muted-2)); }
:root[data-theme='studio'] .knob-val { stroke: var(--c, var(--muted-2)); }
/* controls that set --c to amber on purpose (FX rows, swing, rack volume) */
:root[data-theme='studio'] :is(.sc-row input[type='range'], .rk-swing, .knob:has(.rk-swing), .rk-ctl .knob:has(.vol)) { --c: var(--muted-2); }
:root[data-theme='studio'] #invite:hover:not(:disabled) { border-color: var(--select); }
:root[data-theme='studio'] :is(.setup-card, .set-radios, .set-check) input { accent-color: var(--select); }

/* Press feedback (all themes): mouse presses only, since keyboard actions
   never animate. Transform only, so no layout or paint work. */
button { transition: transform 100ms cubic-bezier(0.23, 1, 0.32, 1); }
button:active:not(:disabled) { transform: scale(0.97); }

/* Dialog entrance (all themes): settings, plugin picker, export. A short
   fade with a small scale from the centre; closing stays instant ([hidden]
   is display:none), so exit is faster than entry. */
:is(#settings, .plugin-picker, .export-dialog) {
  transition: opacity 180ms cubic-bezier(0.23, 1, 0.32, 1), display 180ms allow-discrete;
  @starting-style { opacity: 0; }
}
:is(#settings, .plugin-picker, .export-dialog) > .settings-card {
  transition: transform 180ms cubic-bezier(0.23, 1, 0.32, 1);
  @starting-style { transform: scale(0.97); }
}

@media (prefers-reduced-motion: reduce) {
  button, button:active:not(:disabled) { transition: none; transform: none; }
  :is(#settings, .plugin-picker, .export-dialog) > .settings-card { transition: none; }
  .pl-rec.on { animation: none; }
}

/* "All devices off" tag under a strip's slots (devices bypassed with the Devices-panel square). */
.strip .fx-off {
  width: 100%;
  padding: 0.05rem 0.3rem;
  font-size: 0.6rem;
  letter-spacing: 0.04em;
  background: var(--warn);
  color: var(--warn-ink);
  border: 1px solid var(--warn);
}
.strip .fx-off[hidden] { display: none; }

/* Drafts: notice pill (ui/util.js notice), e.g. "That's Ben's draft…". */
.notice {
  position: fixed; left: 50%; bottom: 28px; transform: translateX(-50%); z-index: 60;
  max-width: min(560px, calc(100vw - 32px)); padding: 8px 14px; border-radius: 999px;
  background: var(--tip-bg); color: var(--on-chrome); border: 1px solid var(--tip-line);
  font-size: 12px; box-shadow: var(--shadow); pointer-events: none;
}
.notice[hidden] { display: none; }

/* Drafts: "Hear their draft" toggle in the follow pill (ui/presence.js). */
.follow-hear { padding: 1px 8px; font-size: 10px; border-radius: 4px; border: 1px solid var(--on-color); background: transparent; color: var(--on-color); opacity: 0.7; }
.follow-hear[aria-pressed='true'] { background: var(--on-color); color: var(--user); opacity: 1; }
.follow-hear:hover:not(:disabled) { opacity: 1; }

/* Drafts: version selector popover (ui/versions.js). */
.ver-pop { min-width: 250px; gap: 1px; }
.ver-head { padding: 0.3rem 0.6rem 0.2rem; color: var(--muted); font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; }
.ver-item { display: flex; align-items: center; gap: 2px; }
.ver-item .ver-row { flex: 1; min-width: 0; }
.ver-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ver-dot { width: 7px; height: 7px; border-radius: 50%; border: 1px solid var(--muted); flex: none; }
.ver-row[aria-pressed='true'] { background: var(--panel-3); }
.ver-row[aria-pressed='true'] .ver-dot { background: var(--text); border-color: var(--text); }
.ver-btn { flex: none; width: 24px; height: 24px; padding: 0; border: 0; border-radius: 5px; background: transparent; color: var(--muted); font-size: 11px; }
.ver-btn:hover:not(:disabled) { background: var(--panel-3); color: var(--text); }

/* Drafts: push panel (ui/push.js; reuses .settings-card). */
.push-dialog { background: var(--scrim); }
.push-list { display: grid; gap: 0.3rem; margin: 0.6rem 0; }
.push-list .push-clip { padding-left: 1.4rem; }
.push-chip { width: 10px; height: 10px; border-radius: 3px; flex: none; border: 1px solid var(--line-soft); }
.push-track { font-weight: 600; }
.push-tag { margin-left: 0.4rem; padding: 0 0.35rem; border-radius: 4px; background: var(--panel-3); color: var(--muted-2); font-size: 10px; }
.push-clashes { border-top: 1px solid var(--line); margin-top: 0.4rem; }
.push-clash { display: grid; gap: 0.35rem; padding: 0.5rem 0; border-bottom: 1px solid var(--line-soft); }
.push-clash-head { display: flex; align-items: center; gap: 0.4rem; }
.push-clash-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.push-foot { display: flex; justify-content: flex-end; margin-top: 0.8rem; }
.push-go { padding: 0.4rem 1rem; }
.push-btn { white-space: nowrap; }

/* Push nudge (04-plans/2026-11-12_push-nudge-plan.md): one pulse when you
   leave a plugin-track clip with unpushed edits, so you find Push at the
   moment it matters. ui/push.js adds .nudge and drops it on animationend.
   Not amber: amber means sound. Reduced motion gets the ring without the
   movement, held until the tip is restored. */
#t-push.nudge { animation: push-nudge 0.9s cubic-bezier(0.23, 1, 0.32, 1); }
@keyframes push-nudge {
  from { border-color: var(--select); box-shadow: 0 0 0 4px var(--select); }
  to { box-shadow: 0 0 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) {
  #t-push.nudge { animation: none; border-color: var(--select); box-shadow: 0 0 0 2px var(--select); }
}

/* Drafts: "Live" pill while Edit live is on (ui/transport.js). Not amber:
   amber means sound. */
.live-pill { padding: 2px 10px; border-radius: 999px; border: 1px solid var(--warn); background: var(--warn); color: var(--warn-ink); font-size: 11px; font-weight: 600; white-space: nowrap; }
.live-pill[hidden] { display: none; }
.live-pill:hover:not(:disabled) { filter: brightness(1.08); }

/* Version history (ui/history.js): Chat | History tabs in the side panel,
   the preview bar + recovered banner over the playlist, the broken-room
   screen. Neutral tokens: amber means sound only. */
.side-tabs { display: flex; gap: 2px; align-self: stretch; }
.side-tab {
  border: 0; border-bottom: 2px solid transparent; border-radius: 0; background: none; padding: 0 8px;
  font: 10px var(--mono); letter-spacing: 0.2em; text-transform: uppercase; color: var(--muted-2);
}
.side-tab.on { color: var(--text); border-bottom-color: var(--select); }
.chat.hist-on .chat-list, .chat.hist-on .chat-form { display: none; }
.hist { grid-row: 2 / 4; display: grid; grid-template-rows: auto minmax(0, 1fr) auto; min-height: 0; }
.hist[hidden] { display: none; }
.hist-top { padding: 8px; border-bottom: 1px solid var(--line-soft); }
.hist-top button { width: 100%; }
.hist-list { list-style: none; margin: 0; padding: 4px 0 8px; overflow-y: auto; overscroll-behavior: contain; }
.hist-day { padding: 10px 12px 4px; font: 10px var(--mono); letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.hist-row { display: grid; grid-template-columns: 12px minmax(0, 1fr) auto auto; align-items: center; gap: 6px; padding: 4px 12px; cursor: pointer; font-size: 12px; }
.hist-row:hover, .hist-row:focus-visible { background: var(--row-sel); outline: none; }
.hist-row.on { box-shadow: inset 2px 0 0 var(--select); background: var(--row-alt); }
.hist-row.named .hist-title { font-weight: 600; }
.hist-star { color: var(--text); font-size: 11px; }
.hist-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hist-who { display: inline-flex; gap: 3px; align-items: center; min-width: 0; }
.hist-by { color: var(--muted-2); max-width: 70px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hist-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--user, var(--muted)); }
.hist-time { font: 10px var(--mono); color: var(--muted); }
.hist-empty { padding: 8px 12px; color: var(--muted); font-size: 12px; line-height: 1.45; }
.hist-foot { padding: 6px 12px; border-top: 1px solid var(--line-soft); font: 10px var(--mono); color: var(--muted); min-height: 14px; }
.hist-confirm { max-width: 300px; }
.hist-confirm p { margin: 0 0 6px; line-height: 1.4; }
.hist-confirm-btns { display: flex; justify-content: flex-end; gap: 6px; }

.playlist { position: relative; }
.playlist.has-bar { grid-template-rows: auto 32px 1fr; }
.playlist:not(.has-bar) .pv-wrap { display: none; }
.pv-bar {
  display: flex; align-items: center; gap: 8px; padding: 4px 8px 4px 12px;
  background: var(--tip-bg); color: var(--on-chrome); border-bottom: 1px solid var(--tip-line);
  box-shadow: inset 3px 0 0 var(--select); font-size: 12px;
}
.pv-bar[hidden] { display: none; }
.pv-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pv-bar button { flex: none; }
.pv-x { border: 0; background: none; color: inherit; font-size: 16px; line-height: 1; padding: 0 4px; }

.broken {
  position: absolute; inset: 0; z-index: 5; display: grid; place-content: center; gap: 12px; padding: 24px;
  background: var(--panel); text-align: center;
}
.broken[hidden] { display: none; }
.broken-text { max-width: 440px; margin: 0; line-height: 1.5; overflow-wrap: anywhere; }
.broken-btns { display: flex; gap: 8px; justify-content: center; }

/* ---------- track inspector (ui/inspector.js) ---------- */
/* A full-height column at the far left: under the top bar, beside the
   workspace, splitter, dock and Devices panel. Every in-flow body child is
   placed explicitly so the second column doesn't reshuffle them. */
header.transport { grid-column: 1 / -1; grid-row: 1; }
body > .workspace { grid-column: 2; grid-row: 2; }
body > #splitter { grid-column: 2; grid-row: 3; }
body > #dock { grid-column: 2; grid-row: 4; }
body > #devices { grid-column: 2; grid-row: 5; }
.inspector {
  grid-column: 1;
  grid-row: 2 / -1;
  position: relative;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--panel-2);
  border-right: 1px solid var(--line);
  color: var(--text);
  font-size: 12px;
  overflow: hidden;
}
.inspector[hidden] { display: none; }
.insp-resize { position: absolute; top: 0; right: 0; width: 5px; height: 100%; cursor: col-resize; z-index: 2; }
.insp-resize:hover, .insp-resize.on { background: var(--line); }
.pl-insp { display: inline-grid; place-items: center; padding: 0.3rem 0.4rem; line-height: 0; }
.pl-insp .ic { width: 14px; height: 14px; }
.pl-insp[aria-pressed="true"] { border-color: var(--muted); background: var(--panel-2); }
.insp-body { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }
.insp-head { flex: none; }
.insp-head { padding: 8px 10px 8px; border-bottom: 1px solid var(--line); display: grid; gap: 6px; }
.insp-head-top, .insp-head-row { display: flex; align-items: center; gap: 6px; min-width: 0; }
.insp-head [hidden] { display: none; }
.insp-head .sp { flex: 1; }
.insp-label { color: var(--faint); font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase; }
.insp-name { font-weight: 600; font-size: 13px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: text; border-radius: 3px; }
.insp-name[contenteditable="true"], .insp-name[contenteditable="plaintext-only"] { outline: 1px solid var(--muted); background: var(--bg); text-overflow: clip; padding: 0 3px; }
/* A narrow column with "+N selected" and "▸ Track" showing: the label gives
   way first, then the count; the toggle never shrinks. */
.insp-head-top .insp-label, .insp-head-top .dev-more { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.insp-head-top .insp-label { flex-shrink: 4; }
/* "▸ Track" in the header: shows / hides the Track rows above the strips. */
.insp-track-toggle { flex: none; padding: 1px 6px; border-color: transparent; background: transparent; color: var(--muted); font-size: 11px; white-space: nowrap; }
.insp-track-toggle:hover:not(:disabled) { color: var(--text); border-color: var(--line); background: transparent; }
.insp-track-toggle[aria-expanded="true"] { color: var(--text); }
.insp-rows { display: grid; gap: 4px; }
.insp-rows + .insp-rows { margin-top: 4px; padding-top: 4px; border-top: 1px solid var(--line-soft); }
.insp-row { display: grid; grid-template-columns: 76px minmax(0, 1fr); align-items: center; gap: 6px; min-height: 24px; }
.insp-key { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.insp-row > :last-child { justify-self: start; max-width: 100%; }
.insp-val { font-family: var(--mono); color: var(--muted-2); }
.insp-inst { display: flex; align-items: center; gap: 6px; padding: 2px 8px; max-width: 100%; min-width: 0; }
.insp-inst .swatch { width: 9px; height: 9px; border-radius: 2px; flex: none; }
.insp-inst-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.insp-toggle { padding: 1px 10px; font-size: 11px; color: var(--muted); }
.insp-toggle[aria-pressed="true"] { color: var(--text); border-color: var(--muted); background: var(--panel-3); }
.insp-select { max-width: 100%; background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius); padding: 2px 4px; }
/* Two channel strips side by side (this strip + Master), filling the column
   under the header. The fader, the dB numbers and the meter share one map
   (inspectorview.js dbToPos); the numbers and meter are inset by half the
   fader thumb (6px) so they line up with the cap's travel. */
.insp-rows-block { flex: none; max-height: 40%; overflow-y: auto; overflow-x: hidden; padding: 6px 10px 8px; }
.insp-rows-block[hidden] { display: none; }
/* The strips share their rows (subgrid), so slots, pan, level box, fader,
   M / S and name plate line up across both. The slots row grows to its
   content while the fader keeps 120px, then scrolls. */
.insp-strips {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: minmax(0, max-content) auto auto minmax(120px, 1fr) auto auto;
  row-gap: 5px;
  border-top: 1px solid var(--line);
}
.insp-strips.one { grid-template-columns: minmax(0, 1fr); }
.insp-strip { grid-row: 1 / -1; display: grid; grid-template-rows: subgrid; min-width: 0; min-height: 0; padding: 6px 5px 5px; border-right: 1px solid var(--line); }
.insp-strip:last-child { border-right: 0; }
.insp-strip.selected { background: var(--panel-3); box-shadow: inset 0 0 0 1px var(--muted); }
.insp-strip-master { --c: var(--muted-2); }
.insp-slots { min-height: 0; overflow-y: auto; overflow-x: hidden; }
.insp-strip-pan { height: 30px; display: grid; place-items: center; }
.insp-level, .insp-level-edit { justify-self: center; box-sizing: border-box; width: 100%; max-width: 76px; height: 20px; padding: 0 4px; font-family: var(--mono); font-size: 11px; font-variant-numeric: tabular-nums; text-align: center; color: var(--muted-2); border-radius: 3px; }
.insp-level { border: 1px solid var(--line); background: var(--bg); }
.insp-level:hover:not(:disabled) { color: var(--text); border-color: var(--muted); background: var(--bg); }
.insp-level-edit { border: 1px solid var(--muted); background: var(--bg); color: var(--text); outline: none; }
/* The fader's top is its real maximum (--fader-top, set from FADER_TOP in
   inspector.js), so its 12px thumb travels only that share of the scale. */
.insp-strip-zone { min-height: 120px; display: flex; justify-content: center; gap: 3px; }
.insp-fader-wrap { flex: none; width: 22px; display: flex; flex-direction: column; justify-content: flex-end; }
.inspector .insp-fader {
  writing-mode: vertical-lr;
  direction: rtl;
  width: 22px;
  height: calc(var(--fader-top, 1) * (100% - 12px) + 12px);
  flex: none;
  --range-grad: linear-gradient(to top, var(--range-track) var(--lo, 0%), var(--range-fill) var(--lo, 0%), var(--range-fill) var(--hi, 50%), var(--range-track) var(--hi, 50%));
}
.inspector .insp-fader::-webkit-slider-runnable-track { width: 4px; height: 100%; }
.inspector .insp-fader::-moz-range-track { width: 4px; height: 100%; }
.inspector .insp-fader::-webkit-slider-thumb { margin-top: 0; margin-left: -4px; }
.insp-scale-wrap, .insp-meter-wrap { flex: none; display: flex; flex-direction: column; padding: 6px 0; }
.insp-scale-wrap { width: 18px; }
.insp-scale { position: relative; flex: 1; min-height: 0; user-select: none; }
.insp-scale span { position: absolute; right: 0; transform: translateY(-50%); font-family: var(--mono); font-size: 8.5px; line-height: 1; color: var(--muted); font-variant-numeric: tabular-nums; }
.insp-meter-wrap { width: 8px; }
.insp-meter { display: block; flex: 1; min-height: 0; width: 8px; background: var(--meter-bg); border-radius: 2px; cursor: pointer; }
.insp-ms { height: 20px; display: flex; justify-content: center; gap: 3px; }
.insp-ms button { padding: 0.05rem 0.45rem; font-size: 0.72rem; }
.insp-ms .m.on { background: var(--warn); color: var(--warn-ink); border-color: var(--warn); }
.insp-ms .s.on { background: var(--solo); color: var(--solo-ink); border-color: var(--solo); }
.insp-strip.song-off .insp-strip-zone { background-image: repeating-linear-gradient(135deg, var(--faint) 0 1px, transparent 1px 7px); }
.insp-strip.song-off .insp-ms .m { opacity: 0.45; }
.insp-plate { min-height: 18px; padding: 2px 4px; border-radius: 3px; font-size: 11px; font-weight: 600; text-align: center; color: var(--ink-on-light); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.insp-strip-master .insp-plate { background: var(--muted-2); color: var(--bg); }
/* Effect slots (Logic style 2): centred name, power button on the left edge
   shown on hover / focus / swipe. Off = pale. No --accent: that's sound. */
.insp-slot-list { display: grid; gap: 2px; }
.insp-slot { display: flex; align-items: stretch; height: 18px; border-radius: 3px; background: var(--panel-3); overflow: hidden; }
.insp-slot.off { background: var(--panel-2); }
.insp-pow { flex: none; width: 12px; padding: 0; border: 0; border-right: 1px solid var(--line); border-radius: 0; background: transparent; font-size: 9px; line-height: 1; color: var(--text); opacity: 0; touch-action: none; }
.insp-slot.off .insp-pow { color: var(--faint); }
.insp-slots:hover .insp-pow, .insp-slots:focus-within .insp-pow, .insp-slots.swiping .insp-pow { opacity: 1; }
.insp-pow:hover:not(:disabled) { background: var(--line-soft); color: var(--text); }
.insp-slot.off .insp-pow:hover:not(:disabled) { color: var(--faint); }
.insp-slot-name { flex: 1; min-width: 0; padding: 0 3px; border: 0; border-radius: 0; background: transparent; font-size: 11px; line-height: 18px; text-align: center; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.insp-slot.off .insp-slot-name { color: var(--faint); }
.insp-slot-name:hover:not(:disabled) { background: var(--line-soft); }
.insp-slot.off .insp-slot-name:hover:not(:disabled) { color: var(--faint); }
/* .insp-slot clips overflow, so focus rings sit inside the button. */
.insp-pow:focus-visible, .insp-slot-name:focus-visible { outline: 2px solid var(--select); outline-offset: -2px; }
.insp-slot-add { display: block; box-sizing: border-box; width: 100%; height: 18px; margin-top: 2px; padding: 0; border: 1px dashed var(--line); border-radius: 3px; background: transparent; font-size: 12px; line-height: 1; color: var(--muted); }
.insp-slot-add:hover:not(:disabled) { color: var(--text); border-color: var(--muted); background: transparent; }
/* Playlist toolbar too narrow (e.g. inspector open): it scrolls sideways
   (ui/toolbarscroll.js turns the wheel sideways) and fades the edge that has
   more buttons behind it. The mask only uses alpha, never a colour. */
.pl-toolbar { scrollbar-width: none; }
.pl-toolbar::-webkit-scrollbar { display: none; }
.pl-toolbar.more-r { -webkit-mask-image: linear-gradient(to right, var(--text) calc(100% - 28px), transparent); mask-image: linear-gradient(to right, var(--text) calc(100% - 28px), transparent); }
.pl-toolbar.more-l { -webkit-mask-image: linear-gradient(to left, var(--text) calc(100% - 28px), transparent); mask-image: linear-gradient(to left, var(--text) calc(100% - 28px), transparent); }
.pl-toolbar.more-l.more-r { -webkit-mask-image: linear-gradient(to right, transparent, var(--text) 28px, var(--text) calc(100% - 28px), transparent); mask-image: linear-gradient(to right, transparent, var(--text) 28px, var(--text) calc(100% - 28px), transparent); }

/* ---- audio editor ---- */
/* ui/audioeditor.js: #pane-roll.audio-mode swaps the piano roll for
   #audio-editor (left clip panel + waveform stage). No accent here:
   amber means sound. */
#pane-roll.audio-mode { grid-template-rows: minmax(0, 1fr); }
#pane-roll.audio-mode > .roll-toolbar,
#pane-roll.audio-mode > .legendbar,
#pane-roll.audio-mode > .roll-stage,
#pane-roll.audio-mode > .lane-footer { display: none; }
#pane-roll.audio-mode > #audio-editor { display: grid; }
#pane-roll > #audio-editor[hidden] { display: none; }
#audio-editor { grid-template-columns: 170px minmax(0, 1fr); min-height: 0; outline: none; }
.ae-panel {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px 10px;
  border-right: 1px solid var(--line);
  background: var(--panel-2);
  overflow-y: auto;
  min-height: 0;
}
.ae-head { min-width: 0; padding-bottom: 4px; border-bottom: 1px solid var(--line-soft); }
.ae-name { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ae-file { color: var(--muted); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ae-row { display: flex; align-items: center; gap: 4px; min-width: 0; }
.ae-row[hidden] { display: none; }
.ae-row > .glabel { flex: 0 0 56px; letter-spacing: 0.06em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ae-num {
  width: 52px;
  min-width: 0;
  text-align: right;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  -moz-appearance: textfield;
}
.ae-num::-webkit-outer-spin-button, .ae-num::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.ae-strength { width: 44px; }
.ae-gain { cursor: ns-resize; }
.ae-gain:focus { cursor: text; }
.ae-unit { color: var(--muted); font-size: 11px; }
.ae-warp { min-width: 44px; }
.ae-q { min-width: 26px; font-weight: 700; }
.ae-panel .rbtn:disabled, .ae-panel .rinput:disabled { opacity: 0.45; cursor: default; }
.ae-foot { margin-top: auto; padding-top: 6px; }
.ae-reset { width: 100%; }
.ae-stage {
  position: relative;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  min-width: 0;
  min-height: 0;
  background: var(--grid-bg);
}
.ae-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3px 8px;
  border-bottom: 1px solid var(--line);
  background: var(--panel-2);
}
.ae-bar > .glabel { letter-spacing: 0.06em; }
#audio-canvas { display: block; width: 100%; height: 100%; min-height: 0; outline: none; }

/* Mixer device drag insertion: overlays rows without shifting the gap. */
.strip .fx-slots { position: relative; }
.fx-ins { position: absolute; left: 0; right: 0; height: 2px; background: var(--text); pointer-events: none; z-index: 1; }
.strip.drop-ok { outline: 1px solid var(--text); outline-offset: -2px; }
.fx-row.moving { opacity: 0.5; }

/* ---------- panel visibility (main.js: prefs browserOpen / dockOpen) ---------- */
/* The Browser column hides; a closed dock keeps just its tab strip. */
.workspace.no-browser { grid-template-columns: minmax(0, 1fr); }
.workspace.no-browser.chat-open { grid-template-columns: minmax(0, 1fr) 280px; }
.workspace.no-browser > .browser { display: none; }
body.dock-closed .dock > .tab-pane { display: none; }
body.dock-closed .dock-tabs button.active { color: var(--muted); border-bottom-color: transparent; }

/* ---------- calmer pass (2026-11-12, FL-feel step 2; ADR 2026-11-12_fl-feel-quieter) ----------
   Less ink at rest: toolbar buttons lose their idle outline (it comes back
   on hover, and "on" states keep their fill), so a toolbar stops reading as
   a grid of little boxes. Track-header M/S/arm, chips, slots and dialog
   buttons keep their outlines: there the box is the control. */
:is(.pl-toolbar, .tgroup, .seg, .lane-footer, .rack-toolbar, .ae-bar, .ae-row, .panel-head, .dhead) > button:not(.on):not(.active):not(.chip),
.transport button:not(.on):not(.active):not(#invite):not(.avatar) {
  border-color: transparent;
  background: transparent;
}
:is(.pl-toolbar, .tgroup, .seg, .lane-footer, .rack-toolbar, .ae-bar, .ae-row, .panel-head, .dhead) > button:not(.on):not(.active):not(.chip):hover:not(:disabled) {
  border-color: var(--line);
  background: var(--panel-2);
}
.transport button:not(.on):not(.active):not(#invite):not(.avatar):hover:not(:disabled) {
  border-color: var(--chrome-line);
  background: var(--chrome-2);
}

/* Amber means sound only: Loop "on" is lit white (like Follow), not amber.
   Play, metronome and count-in stay amber because they make sound. */
.transport #t-loop.on { background: var(--chrome-on); color: var(--chrome-on-ink, var(--chrome)); border-color: var(--chrome-on); }

/* Fewer caps labels: drop the ones whose control already says what it is
   (tool icons, −/+ zoom, the legend chips, the playlist itself); the rest
   are sentence case, not spaced-out caps. */
.lbl-opt { display: none !important; }
:is(.glabel, .foot-label, .pl-corner, .insp-label, .dev-label) {
  text-transform: none;
  letter-spacing: 0.02em;
  font-family: var(--sans);
  font-size: 11px;
}

/* Quieter grid under Studio: bars still lead, beats and steps recede. */
:root[data-theme='studio'] {
  --grid-line: rgba(255, 255, 255, 0.022);
  --grid-beat: rgba(255, 255, 255, 0.05);
  --grid-bar: rgba(255, 255, 255, 0.10);
}

.input-chooser { display: flex; flex-direction: column; min-width: 0; width: 100%; gap: 2px; }
.input-chooser meter { width: 100%; height: 6px; }

/* Floating panes retain their own layout while the Devices row yields its space. */
body.devices-floating { --devices-h: 0px !important; }
.floating-panel .panel-float, .floating-panel .dhead [aria-label="Float Devices"] { display: none; }
.floating-panel .dhead .dev-fold { display: none; }
.floating-panel .devices { height: 100%; grid-template-rows: 0 30px minmax(0, 1fr); }
.floating-panel .dev-resize { visibility: hidden; }
#pane-mixer > .panel-float { position: sticky; left: 0; top: 0; z-index: 2; }

/* Compact Settings: keep the category navigation visible while content scrolls. */
#settings .settings-card { display: flex; flex-direction: column; width: min(680px, calc(100vw - 32px)); max-height: min(680px, calc(100vh - 48px)); overflow: hidden; padding: 16px 0 0; }
#settings .panel-head { padding: 0 18px 12px; }
#settings-body { display: flex; flex-direction: column; min-height: 0; }
.settings-tabs { display: flex; overflow-x: auto; flex: none; padding: 0 12px; border-bottom: 1px solid var(--line); gap: 2px; }
.settings-tabs button { white-space: nowrap; border: 0; border-radius: 0; border-bottom: 2px solid transparent; background: transparent; padding: 9px 10px; color: var(--muted); }
.settings-tabs button[aria-selected="true"] { color: var(--text); border-bottom-color: var(--accent); }
.settings-content { overflow: auto; padding: 4px 18px 18px; }
.settings-content [hidden] { display: none; }
.settings-shortcuts { overflow-x: auto; margin-top: 10px; }
.settings-shortcuts .cheat-table:not(.show-all)[data-profile="jam"] :is(th, td):nth-child(n+3),
.settings-shortcuts .cheat-table:not(.show-all)[data-profile="ableton"] :is(th, td):is(:nth-child(2), :nth-child(n+4)),
.settings-shortcuts .cheat-table:not(.show-all)[data-profile="fl"] :is(th, td):is(:nth-child(2), :nth-child(3), :nth-child(5)),
.settings-shortcuts .cheat-table:not(.show-all)[data-profile="logic"] :is(th, td):is(:nth-child(2), :nth-child(3), :nth-child(4)) { display: none; }
