/* ══════════════════════════════════════════════════════════
   APPROACHABLE MUSIC  ·  Light Panel Design
   Clean white face · Monospace labels · Vivid quality colors
══════════════════════════════════════════════════════════ */

/* Self-hosted fonts (was a render-blocking Google Fonts @import — a two-hop
   serialized chain on the critical path that also couldn't be cached for offline).
   woff2 files live in public/fonts/; unicode-range preserved from Google's CSS so
   the browser only downloads the subset it needs. font-display:swap = no FOIT. */
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url(fonts/dmmono-300-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url(fonts/dmmono-300.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-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/dmmono-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/dmmono-400.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-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(fonts/dmmono-500-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(fonts/dmmono-500.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: 'Share Tech Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/sharetechmono-400.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;
}

/* ── Design tokens ──────────────────────────────────────── */
:root {
  /* Panel face */
  --panel:        #eeeef2;
  --panel-light:  #ffffff;
  --panel-edge:   #d0d0da;

  /* Label text */
  --engrave:      #1a1a2e;
  --engrave-dim:  rgba(26,26,46,0.70);
  --engrave-faint:rgba(26,26,46,0.52);

  /* Section dividers */
  --div-hi:       rgba(255,255,255,0.90);
  --div-lo:       rgba(0,0,0,0.10);

  /* Phosphor display — kept dark for contrast */
  --phos-bg:      #0d1a0d;
  --phos-fg:      #44ff88;
  --phos-dim:     #22993a;
  --phos-glow:    rgba(68,255,136,0.25);
  /* On-LIGHT green: bright phosphor green is illegible as text/border on the light
     panels. Use this readable dark green for green text/active states on light bg.
     (~4.8:1 on white.) Keep --phos-fg ONLY for green-on-dark LCD readouts. */
  --phos-on-light:     #0c7a32;
  --phos-on-light-dim: rgba(12,122,50,0.78);

  /* Quality LED colors */
  --led-major:    #22c55e;
  --led-minor:    #ca8a04;
  --led-dim:      #f97316;
  --led-dom:      #fb923c;
  --led-aug:      #a855f7;
  --led-ext:      #9090aa;

  /* Scale-degree palette — "same scale, moving home" key coloring.
     Glued to the scale degree FROM the tonic (1 is always the same), so the
     home is always degree 1 regardless of key/scale. Applied as a low-alpha
     tint so the navy --engrave note text stays legible (light-theme rule). */
  --deg-1:  #ff5a5f;   /* root / home */
  --deg-2:  #ff9f43;
  --deg-3:  #ffd23f;
  --deg-4:  #3ddc84;
  --deg-5:  #34c3ff;
  --deg-6:  #5a7bff;
  --deg-7:  #b46bff;
  /* Relative-twin markers */
  --rel-maj: #e8a13a;  /* relative major (Ionian) — gold */
  --rel-min: #5566d8;  /* relative minor (Aeolian) — indigo */

  /* Surfaces */
  --surface:      rgba(0,0,0,0.04);
  --surface2:     rgba(0,0,0,0.07);
  --border:       rgba(0,0,0,0.12);
  --border2:      rgba(0,0,0,0.20);

  /* Knob arc / needle */
  --knob-arc:     #22c55e;
  --knob-track:   rgba(0,0,0,0.10);
  --knob-face:    #e0e0e8;

  /* ── Control language (--ctl-*) ─────────────────────────
     The .key pad is the gold-standard physical control on this panel: light
     face, 1px edge, soft drop + top-highlight/bottom-shade insets at rest,
     lift on hover, sink + glow when pressed. These tokens NAME that system so
     every other button family (looper transport, FX rack, patches, tabs …)
     can adopt the same depth without copy-pasting shadow stacks.
     Values are extracted verbatim from .key — adopting them is pixel-identical. */
  --ctl-radius:   8px;
  --ctl-face:     var(--panel-light);
  --ctl-edge:     var(--border);
  --ctl-shadow-rest:
    0 2px 6px rgba(0,0,0,0.10),
    inset 0 1px 0 rgba(255,255,255,0.9),
    inset 0 -1px 0 rgba(0,0,0,0.06);
  --ctl-shadow-hover:
    0 4px 12px rgba(0,0,0,0.14),
    inset 0 1px 0 rgba(255,255,255,0.9),
    inset 0 -1px 0 rgba(0,0,0,0.06);
  /* --key-glow resolves per-element (inline on each pad), so the pressed glow
     stays per-key even though the stack is defined once here. */
  --ctl-shadow-pressed:
    0 0 16px var(--key-glow, rgba(34,197,94,0.60)),
    0 0 12px var(--key-glow, rgba(34,197,94,0.30)),
    inset 0 3px 9px rgba(0,0,0,0.16);

  /* Compact-control variants — the same physical language scaled for the
     18–28px-tall button families (looper transport, FX rack, QA, patches).
     Rest = shallow drop + top-highlight/bottom-shade; hover = slight lift;
     active/pressed adds a shared shallow inset so every control "sinks". */
  --ctl-radius-sm: 5px;
  --ctl-shadow-rest-sm:
    0 1px 3px rgba(0,0,0,0.08),
    inset 0 1px 0 rgba(255,255,255,0.85),
    inset 0 -1px 0 rgba(0,0,0,0.05);
  --ctl-shadow-hover-sm:
    0 2px 6px rgba(0,0,0,0.12),
    inset 0 1px 0 rgba(255,255,255,0.85),
    inset 0 -1px 0 rgba(0,0,0,0.05);
  --ctl-inset-active: inset 0 1px 3px rgba(0,0,0,0.12);

  /* Phosphor window bezel — every dark LCD zone reads as a window INSET into
     the light hardware panel: unified phosphor edge, deep interior inset, and
     a 1px light catch under the bottom edge (the classic bezel-lip trick).
     -sm is for the tiny meters/mini-canvases where a 12px blur would be mud. */
  --lcd-edge: rgba(68,255,136,0.18);
  --lcd-bezel:
    inset 0 0 12px rgba(0,0,0,0.50),
    inset 0 1.5px 3px rgba(0,0,0,0.55),
    0 1px 0 rgba(255,255,255,0.65),
    0 0 8px rgba(68,255,136,0.05);
  --lcd-bezel-sm:
    inset 0 0 4px rgba(0,0,0,0.50),
    inset 0 1px 2px rgba(0,0,0,0.50),
    0 1px 0 rgba(255,255,255,0.55);

  /* 4-stop label type scale — the target rail for the 7/7.5/8/10/11/13px
     drift across button families. .key adopts the stops it already sits on;
     later phases move the strays onto the nearest stop.
     --type-nano is a deliberate 5th stop for the dense LCD-adjacent chrome
     (looper tool/snap strip, tab rail) where 9px would wrap the 390px bar. */
  --type-nano:    7px;    /* dense chrome: looper tools, snap grid, tabs */
  --type-micro:   9px;    /* shortcut badges, tiniest tags */
  --type-label:   11px;   /* section labels, corner badges */
  --type-value:   12px;   /* readouts, roman numerals, body */
  --type-title:   15px;   /* hero labels (key mood) */
}

/* ── Reset ──────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }

/* No text-selection / long-press callout / double-tap zoom on the instrument
   surface — this is a playable control panel, not a document. Inputs and
   contenteditable stay selectable so users can still edit their own text. */
html {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  touch-action: manipulation;
}
input, textarea, select, [contenteditable="true"] {
  -webkit-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}

/* ── Panel body ─────────────────────────────────────────── */
body {
  background: var(--panel);
  color: var(--engrave);
  font-family: 'DM Mono', 'Share Tech Mono', monospace;
  display: flex;
  flex-direction: column;
  height: 100dvh;
  overflow-y: auto;
  gap: 0;

  /* Subtle grain texture */
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.025'/%3E%3C/svg%3E");
  background-size: 180px 180px;
}

/* ── Nameplate strip ────────────────────────────────────── */
.nameplate {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 5px 16px;
  background: var(--panel-light);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 1px 3px rgba(0,0,0,0.07);
  flex-shrink: 0;
  gap: 12px;
}

.brand-name {
  font-size: 12px;
  letter-spacing: 4px;
  color: var(--engrave);
  text-transform: uppercase;
  opacity: 0.50;
  font-weight: 500;
  white-space: nowrap;
}

.master-section {
  display: flex;
  align-items: center;
  gap: 6px;
}

/* ── Engraved section label style ───────────────────────── */
.engrave-label {
  font-size: 13px;
  letter-spacing: 3px;
  color: var(--engrave-dim);
  text-transform: uppercase;
  font-weight: 500;
  font-family: 'DM Mono', monospace;
}

/* ── Scale layout toggle (1–8 vs 1–4·QR) ───────────────── */
#scaleLayoutToggle { display: flex; align-items: center; gap: 3px; }
.scale-layout-btn {
  cursor: pointer;
  font-size: 9px;
  letter-spacing: 1px;
  padding: 2px 6px;
  border-radius: 3px;
  color: var(--engrave-dim);
  font-family: 'DM Mono', monospace;
  text-transform: uppercase;
  border: 1px solid transparent;
  transition: background 0.15s, color 0.15s;
}
.scale-layout-btn:hover { border-color: var(--engrave-dim); }
.scale-layout-btn.active { background: var(--accent,#44ff88); color: #000; border-color: transparent; }

/* ── Section divider ────────────────────────────────────── */
.panel-divider {
  height: 24px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 12px;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--div-hi);
  background: rgba(0,0,0,0.04);
  flex-shrink: 0;
}

.panel-divider .engrave-label {
  white-space: nowrap;
}

.panel-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, var(--engrave-faint) 0%, transparent 100%);
}

/* ── Collapsible songs toggle ───────────────────────────── */
.songs-toggle {
  cursor: pointer;
  user-select: none;
}
.songs-toggle:hover { background: rgba(0,0,0,0.05); }
.songs-chevron {
  margin-left: auto;
  font-size: 8px;
  color: var(--engrave-faint);
  flex-shrink: 0;
}

/* ── Top panel (circle + display + controls) ────────────── */
.panel-top {
  display: flex;
  gap: 16px;
  padding: 6px 16px;
  flex-shrink: 0;
  height: 140px;
  background: var(--panel-light);
  border-bottom: 1px solid var(--border);
}

.circle-section {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}

.panel-top-right {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 0;
}

/* Info row: phosphor display + mode/octave side by side */
.panel-top-info-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}

/* ── Phosphor display — intentionally dark for contrast ─── */
.phosphor-display {
  background: var(--phos-bg);
  border: 1px solid rgba(68,255,136,0.22);
  border-radius: 6px;
  padding: 7px 12px;
  display: flex;
  gap: 18px;
  align-items: center;
  box-shadow:
    inset 0 0 12px rgba(0,0,0,0.6),
    0 0 8px rgba(68,255,136,0.06);
  flex-shrink: 0;
}

.display-cell {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.display-label {
  font-size: 9px;
  letter-spacing: 2.5px;
  color: var(--phos-dim);
  text-transform: uppercase;
}

.display-value {
  font-size: 20px;
  color: var(--phos-fg);
  letter-spacing: 1px;
  text-shadow: 0 0 8px var(--phos-glow), 0 0 18px rgba(68,255,136,0.15);
  font-family: 'Share Tech Mono', monospace;
  font-weight: 400;
  white-space: nowrap;
}

.display-value.small {
  font-size: 14px;
  letter-spacing: 0.3px;
}

/* ── Mode toggle ────────────────────────────────────────── */
.mode-section {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.toggle-switch {
  position: relative;
  display: flex;
  align-items: center;
  background: var(--panel-edge);
  border: 1px solid var(--border2);
  border-radius: 4px;
  padding: 3px;
  cursor: pointer;
  box-shadow: inset 0 1px 3px rgba(0,0,0,0.12);
  gap: 2px;
  user-select: none;
}

.toggle-option {
  font-size: 11px;
  letter-spacing: 2.5px;
  color: var(--engrave-dim);
  padding: 5px 14px;
  border-radius: 3px;
  transition: color 0.15s, background 0.15s;
  position: relative;
}

.toggle-option.active {
  color: #ffffff;
  background: #22c55e;
  box-shadow: 0 0 8px rgba(34,197,94,0.35);
}

.toggle-option.active::before {
  content: '';
  position: absolute;
  top: -5px;
  left: 50%;
  transform: translateX(-50%);
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #22c55e;
  box-shadow: 0 0 6px #22c55e;
}

/* ── Octave + right-side controls ───────────────────────── */
.top-controls {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}

.octave-display {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

/* Waveform strip */
.wave-strip {
  flex: 1;
  width: 100%;
  border-radius: 5px;
  border: 1px solid var(--border);
  background: var(--phos-bg);
  display: block;
  min-height: 0;
}

/* ══════════════════════════════════════════════════════════
   TWO-HAND PLAYING SURFACE
════════════════════════════════════════════════════════ */
.playing-surface {
  display: flex;
  flex: 1;
  min-height: 0;
}

/* ── Touch-action: only lock the circle canvas (custom drag handling) */
#circleCanvas { touch-action: none; }

/* ── Left zone (chord degree) ───────────────────────────── */
.play-left {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  border-right: 2px solid rgba(34,197,94,0.20);
}

/* ── Right zone (chord quality) ─────────────────────────── */
.play-right {
  width: 360px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: rgba(99,102,241,0.02);
}

/* ── Zone banner strips ─────────────────────────────────── */
.zone-banner {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 2px 12px;
  flex-shrink: 0;
  border-bottom: 1px solid;
}

.zone-banner-left {
  background: rgba(34,197,94,0.07);
  border-color: rgba(34,197,94,0.20);
}
.zone-banner-right {
  background: rgba(99,102,241,0.08);
  border-color: rgba(99,102,241,0.20);
}

.zone-arrow {
  font-size: 14px;
  font-weight: 300;
  line-height: 1;
  flex-shrink: 0;
}
.zone-banner-left  .zone-arrow { color: #16a34a; }
.zone-banner-right .zone-arrow { color: #4338ca; }

.zone-name {
  font-size: 9px;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  font-weight: 500;
  flex-shrink: 0;
}
.zone-banner-left  .zone-name { color: #15803d; }
.zone-banner-right .zone-name { color: #4338ca; }

.zone-sub {
  font-size: 8px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--engrave-faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.zone-banner-left  .zone-sub { margin-left: auto; }
.zone-banner-right .zone-sub { margin-right: auto; }

/* ── Quality panel — 5-col keyboard grid ────────────────── */
.quality-panel {
  flex: 1;
  padding: 8px;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  grid-template-rows: auto repeat(3, 1fr);
  gap: 4px;
  overflow-y: auto;
}

/* Column family headers (row 1 of grid) */
.qual-family-hdr {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 5px 2px 5px;
  border-radius: 5px 5px 2px 2px;
  font-size: 9px;
  letter-spacing: 2px;
  font-weight: 700;
  text-transform: uppercase;
  color: rgba(var(--qrgb), 1);
  background: rgba(var(--qrgb), 0.10);
  border-bottom: 2px solid rgba(var(--qrgb), 0.45);
  user-select: none;
}

/* Individual keyboard-style quality key */
.qual-key {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 14px 8px;
  border: 1.5px solid rgba(var(--qrgb), 0.25);
  border-bottom: 3px solid rgba(var(--qrgb), 0.40); /* physical key depth */
  border-radius: 5px;
  background: rgba(var(--qrgb), 0.05);
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  transition: background 0.07s, border-color 0.07s, transform 0.05s, box-shadow 0.07s;
  position: relative;
}
.qual-key:hover {
  background: rgba(var(--qrgb), 0.10);
  border-color: rgba(var(--qrgb), 0.42);
}
/* HELD = physically pressed in */
.qual-key.held {
  background: rgba(var(--qrgb), 0.22);
  border-color: rgba(var(--qrgb), 0.75);
  border-bottom-width: 1px;          /* depth collapses on press */
  transform: translateY(2px);        /* physical key travel */
  box-shadow: inset 0 2px 5px rgba(0,0,0,0.14),
              0 0 12px rgba(var(--qrgb), 0.22);
}

/* Key label (keyboard letter) */
.qk-kb {
  font-family: 'Share Tech Mono', monospace;
  font-size: 19px;
  font-weight: 700;
  color: rgba(var(--qrgb), 0.80);
  line-height: 1;
}
/* Quality name */
.qk-name {
  font-size: 14px;
  font-weight: 500;
  color: rgba(var(--qrgb), 0.60);
  letter-spacing: 0.2px;
  line-height: 1;
}
.qual-key.held .qk-kb  { color: rgba(var(--qrgb), 1); }
.qual-key.held .qk-name { color: rgba(var(--qrgb), 0.90); font-weight: 700; }

/* Row-complexity tints — rows get slightly richer as you go deeper */
.qual-key[data-row="1"] { background: rgba(var(--qrgb), 0.04); }
.qual-key[data-row="2"] { background: rgba(var(--qrgb), 0.06); }
.qual-key[data-row="3"] { background: rgba(var(--qrgb), 0.08); }

/* Quick Flavours row — Z X C V hold keys */
.quick-flavours-row {
  display: flex;
  gap: 4px;
  padding: 5px 8px;
  flex-shrink: 0;
  border-top: 1px solid rgba(0,0,0,0.07);
}
.quick-flv-key {
  flex: 1;
  position: relative;
}

/* Edit pencil shown on hover */
.flv-edit-btn {
  position: absolute;
  top: 3px;
  right: 4px;
  font-size: 9px;
  line-height: 1;
  opacity: 0;
  color: rgba(var(--qrgb), 0.8);
  cursor: pointer;
  transition: opacity 0.12s;
  user-select: none;
}
.quick-flv-key:hover .flv-edit-btn { opacity: 0.55; }
.quick-flv-key.slot-editing .flv-edit-btn { opacity: 1; }

/* Slot in edit/assign mode — pulsing border */
.quick-flv-key.slot-editing {
  border-color: rgba(var(--qrgb), 0.9) !important;
  box-shadow: 0 0 0 2px rgba(var(--qrgb), 0.35), 0 0 10px rgba(var(--qrgb), 0.2);
  animation: slot-pulse 1s ease-in-out infinite alternate;
}
@keyframes slot-pulse {
  from { box-shadow: 0 0 0 2px rgba(var(--qrgb), 0.35), 0 0 8px rgba(var(--qrgb), 0.15); }
  to   { box-shadow: 0 0 0 2px rgba(var(--qrgb), 0.70), 0 0 14px rgba(var(--qrgb), 0.35); }
}

/* Qual-panel keys — subtle glow when a slot is waiting for assignment */
.qual-key.assign-mode {
  border-color: rgba(var(--qrgb), 0.50);
  box-shadow: 0 0 6px rgba(var(--qrgb), 0.15);
  cursor: crosshair;
}
.qual-key.assign-mode:hover {
  background: rgba(var(--qrgb), 0.18);
  border-color: rgba(var(--qrgb), 0.75);
}

/* Qual-key being dragged */
.qual-key.dragging {
  opacity: 0.45;
  transform: scale(0.95);
}

/* Quick-flv slot being dragged over */
.quick-flv-key.drag-over {
  border-color: rgba(var(--qrgb), 0.85) !important;
  background: rgba(var(--qrgb), 0.18) !important;
  box-shadow: 0 0 12px rgba(var(--qrgb), 0.35);
  transform: scale(1.04);
}

/* Live quality readout strip below the grid */
.qual-readout {
  flex-shrink: 0;
  padding: 4px 8px;
  background: var(--phos-bg);
  border-top: 1px solid rgba(68,255,136,0.15);
  display: flex;
  align-items: center;
  gap: 8px;
}
.qual-readout-label {
  font-size: 8.5px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--phos-dim);
}
.qual-readout-val {
  font-family: 'Share Tech Mono', monospace;
  font-size: 15px;
  color: var(--phos-fg);
  text-shadow: 0 0 8px rgba(68,255,136,0.5);
  letter-spacing: 1px;
}

/* ── Key sections ───────────────────────────────────────── */
.chord-section {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 5px 10px;
  min-height: 200px;
}

.ext-section {
  display: flex;
  flex-direction: row;  /* oct column + ext keys side by side */
  align-items: stretch;
  padding: 4px 10px;
  min-height: 90px;
  max-height: 110px;
  flex-shrink: 0;
  gap: 5px;
}

/* ── Octave up/down column in ext section ───────────────── */
.ext-oct-col {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex-shrink: 0;
  justify-content: center;
}

.ext-oct-btn {
  width: 32px;
  flex: 1;
  border: 1px solid var(--border2);
  border-radius: 5px;
  background: var(--panel-light);
  color: var(--engrave-dim);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  user-select: none;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.1s, color 0.1s, box-shadow 0.1s;
  box-shadow: 0 1px 3px rgba(0,0,0,0.10);
  touch-action: none;
}
.ext-oct-btn:hover {
  background: var(--panel-edge);
  color: var(--engrave);
}
.ext-oct-btn.mod-active {
  background: var(--phos-bg);
  color: var(--phos-fg);
  border-color: rgba(68,255,136,0.5);
  box-shadow: 0 0 10px rgba(68,255,136,0.25);
}

.keys-row {
  flex: 1;
  display: flex;
  gap: 4px;
  min-height: 0;
  /* iOS 15+ needs user-select:none on the PARENT too, or the long-press
     callout/zoom can still fire on the child pad. */
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

/* ── Slide animations (kept in CSS but not triggered) ───── */
@keyframes slideInFromLeft {
  from { opacity: 0.2; transform: translateX(-14px); }
  to   { opacity: 1;   transform: translateX(0); }
}
@keyframes slideInFromRight {
  from { opacity: 0.2; transform: translateX(14px); }
  to   { opacity: 1;   transform: translateX(0); }
}
.slide-from-left  { animation: slideInFromLeft  0.2s ease-out; }
.slide-from-right { animation: slideInFromRight 0.2s ease-out; }


/* ── Key pads ───────────────────────────────────────────── */
.key {
  flex: 1;
  border-radius: var(--ctl-radius);
  border: 1px solid var(--ctl-edge);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
  user-select: none;
  -webkit-user-select: none;
  /* Touch armour: the pad owns its gesture — no long-press callout, no text
     selection / magnifier loupe, no double-tap zoom, no drag-image, no tap flash.
     This is what stops "holding a chord" from triggering the OS selection UI. */
  -webkit-touch-callout: none;
  -webkit-user-drag: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: none;
  min-width: 0;
  overflow: hidden;
  background: var(--ctl-face);
  box-shadow: var(--ctl-shadow-rest);
  transition:
    transform       0.07s,
    filter          0.07s,
    background-color 0.25s,
    border-color     0.25s;
  /* box-shadow intentionally NOT transitioned: the pressed key recomposites
     every frame under the visualizer, so animating its wide-blur glow was a
     recurring paint cost. The glow now snaps in — crisper key feedback. */
  padding: 0;
  gap: 0;
}

.key:hover {
  filter: brightness(0.97);
  transform: translateY(-1px);
  box-shadow: var(--ctl-shadow-hover);
}

/* Pressed state */
.key.pressed {
  transform: scale(0.96) translateY(2px);
  filter: brightness(0.82);
  border-color: rgba(0,0,0,0.30) !important;
  box-shadow: var(--ctl-shadow-pressed);
}

/* Per-key oscilloscope — inline flex child between note name and voice buttons */
.key-osc-canvas {
  width: 100%;
  height: 44px;
  flex-shrink: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.14s ease;
  display: block;
}
.key.pressed .key-osc-canvas { opacity: 1; }
body.mode-locked .key-osc-canvas { height: 68px; }

/* Quality classes — backgrounds handled inline by JS */
.q-major, .q-minor, .q-diminished, .q-dominant, .q-augmented, .q-default {}

/* Octave root key — green top bar marker */
.oct-root-key::after {
  content: '';
  position: absolute;
  top: 0; left: 10%; right: 10%;
  height: 2px;
  background: var(--phos-fg);
  border-radius: 0 0 2px 2px;
  opacity: 0.7;
  box-shadow: 0 0 6px var(--phos-fg);
}

/* ── "Same scale, moving home" learn coloring ──────────────
   Decoration applied by applyLearnDecor() in app.js. The pad background /
   border come from --deg-* (inline, with the alpha baked in by JS); these
   rules style the home crown, the scale-degree badge and the relative-twin
   tags that ride on top. Quality info still lives on the .key-led dot. */
/* Crown sits INSIDE the pad (the pad is overflow:hidden, so a negative top would
   be clipped). Top-left corner; on the home pad the degree-number badge is
   hidden so they don't collide. */
.key-crown {
  position: absolute;
  top: 3px; left: 7px;
  font-size: 14px;
  z-index: 7;
  pointer-events: none;
  filter: drop-shadow(0 1px 1px rgba(0,0,0,0.30));
}
/* Home ring — NOT !important, so `.key.pressed`'s glow takes over during a hold. */
.key.lc-home {
  box-shadow:
    0 0 0 3px var(--engrave) inset,
    0 6px 18px rgba(20,35,58,0.20);
}
.key.lc-relmaj { border-color: var(--rel-maj) !important; border-width: 3px !important; }
.key.lc-relmin { border-color: var(--rel-min) !important; border-width: 3px !important; }

/* Scale-degree number — small, top-left corner */
.key-deg-badge {
  position: absolute;
  top: 5px; left: 7px;
  font-size: var(--type-label);
  font-weight: 800;
  color: var(--engrave);
  opacity: 0.55;
  z-index: 6;
  pointer-events: none;
  font-family: 'DM Mono', monospace;
}

/* Relative-twin tag — names the mode you'd be in if this pad were home.
   Tappable (tap-to-explain), so it owns pointer events. */
.lc-twin-tag {
  position: absolute;
  bottom: 6px; left: 50%;
  transform: translateX(-50%);
  z-index: 7;
  padding: 2px 8px 3px;
  border-radius: 8px;
  color: #fff;
  text-align: center;
  line-height: 1.12;
  white-space: nowrap;
  font-family: 'DM Mono', monospace;
  /* Pure label while playing — taps pass straight through to the pad. The
     tap-to-explain popover only arms in Info mode (see body.info-mode-active),
     so the badge never gets in the way of mobile playing. */
  pointer-events: none;
}
body.info-mode-active .lc-twin-tag { pointer-events: auto; cursor: pointer; }
.lc-twin-tag b { display: block; font-size: 9px;  font-weight: 800; letter-spacing: 0.05em; }
.lc-twin-tag i { display: block; font-size: 9.5px; font-style: normal; font-weight: 700; opacity: 0.92; }
.lc-twin-tag.maj { background: var(--rel-maj); }
.lc-twin-tag.min { background: var(--rel-min); }

/* Free mode: notes outside the current scale are greyed (7-of-12 truth). */
.key.lc-outscale { opacity: 0.38; }

/* Locked mode already shows the scale degree as the big centre number, so the
   small corner degree badge would be redundant there — hide it. */
body.mode-locked .key-deg-badge { display: none !important; }

/* ── Lesson strip ──────────────────────────────────────────
   Collapsible teaching panel under the Scale Chords header. Narrates the
   relative-major/minor relationship and can momentarily recolor the pads to an
   alternate scheme (interval rainbow / tension heat), then revert to degree. */
.lesson-strip {
  display: none;
  margin: 6px 0 4px;
  padding: 9px 12px 11px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: rgba(0,0,0,0.025);
  font-family: 'DM Mono', monospace;
}
.lesson-strip.open { display: block; }
.lesson-strip-text {
  font-size: 12px;
  line-height: 1.45;
  color: var(--engrave);
  opacity: 0.82;
}
.lesson-strip-text b { color: var(--phos-on-light); opacity: 1; }
.lesson-scheme-row {
  display: flex;
  gap: 6px;
  margin-top: 9px;
  flex-wrap: wrap;
}
.lesson-scheme-btn {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 5px 11px;
  border-radius: 999px;
  border: 1.5px solid var(--border2);
  background: var(--panel-light);
  color: var(--engrave);
  cursor: pointer;
  font-family: 'DM Mono', monospace;
}
.lesson-scheme-btn.active {
  background: var(--engrave);
  color: #fff;
  border-color: var(--engrave);
}
.lesson-toggle.active { color: var(--phos-on-light); }

/* Tap-to-explain popover */
.lesson-pop {
  position: fixed;
  z-index: 90;
  max-width: 260px;
  padding: 11px 13px;
  border-radius: 12px;
  background: #16233a;
  color: #fff;
  font-family: 'DM Mono', monospace;
  font-size: 12px;
  line-height: 1.45;
  box-shadow: 0 12px 34px rgba(0,0,0,0.35);
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.14s, transform 0.14s;
  pointer-events: none;
}
.lesson-pop.show { opacity: 1; transform: translateY(0); pointer-events: auto; }
.lesson-pop b { color: #ffd23f; }

/* LED quality dot */
.key-led {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-top: 7px;
  flex-shrink: 0;
  opacity: 0.85;
  /* box-shadow dropped from the transition (glow snaps with the press); keep the
     background-color crossfade for chord/mode LED color changes. */
  transition: opacity 0.1s, transform 0.1s, background-color 0.25s;
}

.key.pressed .key-led {
  opacity: 1;
  transform: scale(1.6);
  box-shadow: 0 0 10px 3px var(--key-glow, rgba(34,197,94,0.55)) !important;
}

/* Mood word — hero label */
.key-mood {
  font-size: var(--type-title);
  font-weight: 500;
  letter-spacing: 2.5px;
  color: var(--engrave);
  text-align: center;
  margin-top: 4px;
  opacity: 0.50;
  flex-shrink: 0;
  font-family: 'DM Mono', monospace;
}

/* Chord name — primary identity */
.key-chord-name {
  font-size: 40px;
  font-weight: 400;
  letter-spacing: -0.5px;
  color: var(--engrave);
  text-align: center;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  font-family: 'Share Tech Mono', monospace;
}

/* Roman numeral */
.key-roman {
  font-size: var(--type-value);
  letter-spacing: 0.5px;
  color: var(--engrave-dim);
  opacity: 0.65;
  text-align: center;
  font-family: 'DM Mono', monospace;
  flex-shrink: 0;
}

/* Keyboard shortcut badge */
.key-shortcut {
  font-size: var(--type-micro);
  letter-spacing: 1px;
  color: var(--engrave-faint);
  background: rgba(0,0,0,0.07);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 1px 5px;
  font-family: 'DM Mono', monospace;
  margin-bottom: 4px;
  flex-shrink: 0;
  opacity: 0;
  transition: opacity 0.15s;
}

.key:hover .key-shortcut { color: var(--engrave-dim); opacity: 1; }

/* ── Center row: [oct knob] [note name] [flv knob] ──────── */
.key-center-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: 1;
  width: 100%;
  padding: 0 6px;
  min-height: 0;
  gap: 4px;
}

/* Name + roman numeral stacked in the middle */
.key-name-group {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex: 1;
  min-width: 0;
}

.mini-knob-slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex-shrink: 0;
}

/* Extension keys — slightly smaller */
.ext-key {
  flex: 0.85;
}

.ext-key .key-mood { font-size: 11px; letter-spacing: 2px; }
.ext-key .key-chord-name { font-size: 22px; }
.ext-key .key-roman { display: none; }
.ext-key .key-voice-panel { display: none; }
.ext-key .mini-knob-slot { display: none; }

/* ── Tooltip ─────────────────────────────────────────────── */
.key-tooltip {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  width: 200px;
  background: var(--panel-light);
  border: 1px solid var(--border2);
  border-radius: 6px;
  padding: 10px 12px;
  font-size: 9px;
  line-height: 1.5;
  color: var(--engrave);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.18s;
  z-index: 100;
  box-shadow: 0 8px 24px rgba(0,0,0,0.16);
}

.key:hover .key-tooltip { opacity: 1; }

.tooltip-header {
  font-size: 8px;
  letter-spacing: 2px;
  color: var(--phos-on-light);   /* tooltip bg is --panel-light (white); bright green is illegible as text there */
  margin-bottom: 6px;
  text-transform: uppercase;
}

.tooltip-desc {
  color: var(--engrave-dim);
  font-size: 8.5px;
  line-height: 1.6;
  margin-bottom: 8px;
}

.tooltip-meters {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.tooltip-meter {
  display: flex;
  align-items: center;
  gap: 6px;
}

.tooltip-meter-label {
  font-size: 7px;
  letter-spacing: 1.5px;
  color: var(--engrave-dim);
  width: 50px;
  flex-shrink: 0;
}

.tooltip-meter-bar {
  display: flex;
  gap: 2px;
}

.meter-pip {
  width: 5px;
  height: 5px;
  border-radius: 1px;
  background: rgba(0,0,0,0.08);
  border: 1px solid rgba(0,0,0,0.10);
}

.meter-pip.on {
  background: #22c55e;
  box-shadow: 0 0 4px rgba(34,197,94,0.5);
  border-color: rgba(34,197,94,0.4);
}

/* ── Global knob section (ENVELOPE + TIMBRE) ────────────── */
.voice-section {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 14px;
  flex-shrink: 0;
  background: var(--panel-light);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--div-hi);
}

.knob-group {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.knob-group-label {
  font-size: 7px;
  letter-spacing: 2px;
  color: var(--engrave-faint);
  text-transform: uppercase;
}

.knob-row {
  display: flex;
  gap: 6px;
  align-items: flex-start;
}

.knob-slot {
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* Group separator */
.voice-sep {
  width: 1px;
  height: 48px;
  background: linear-gradient(180deg, transparent, var(--border), transparent);
  flex-shrink: 0;
  align-self: center;
}

/* ── Knob component styles ──────────────────────────────── */
.knob-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

.knob-label {
  font-size: 11px;
  letter-spacing: 2px;
  color: var(--engrave-dim);
  text-transform: uppercase;
  text-align: center;
  font-family: 'DM Mono', monospace;
}

/* Mini-knob specific — side-mounted, keep label compact */
.mini-knob-slot .knob-label {
  font-size: 7.5px;
  letter-spacing: 1.5px;
}

/* ── Sound / Patch Bank section ─────────────────────────── */
.sound-section {
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  background: var(--panel-light);
  border-top: 1px solid var(--border);
}

/* ── Patch bank: emoji tabs + preset grid ───────────────── */
.patch-bank {
  display: flex;
  flex-direction: column;
  gap: 0;
}

/* ── Emoji category tab strip ───────────────────────────── */
.patch-cat-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
  padding: 4px 8px;
  border-bottom: 1px solid var(--border);
}

.patch-cat-tab {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  padding: 3px 6px 3px;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--surface);
  cursor: pointer;
  user-select: none;
  transition: background 0.1s, border-color 0.1s, box-shadow 0.1s;
  flex-shrink: 0;
}
.patch-cat-tab:hover {
  background: var(--surface2);
  border-color: var(--border2);
}
.patch-cat-tab.active {
  background: rgba(34,197,94,0.09);
  border-color: rgba(34,197,94,0.45);
  box-shadow: 0 0 8px rgba(34,197,94,0.12), inset 0 1px 0 rgba(255,255,255,0.6);
}

/* Emoji glyph */
.pct-emoji {
  font-size: 16px;
  line-height: 1.15;
  display: block;
}
/* Category label under emoji */
.pct-label {
  font-size: 7px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--engrave-faint);
  font-family: 'DM Mono', monospace;
  white-space: nowrap;
  display: block;
  transition: color 0.1s;
}
.patch-cat-tab.active .pct-label { color: #15803d; }

/* ── Preset button grid ─────────────────────────────────── */
.patch-preset-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
  padding: 6px 10px 5px;
  align-content: flex-start;
  min-height: 34px;
}

/* ── Audio QA Lab ─────────────────────────────────────── */
.qa-inline {
  display: flex;
  align-items: center;
  gap: 5px;
  flex: 0 1 430px;
  min-width: 300px;
  height: 28px;
  padding: 2px 5px;
  border: 1px solid rgba(0,0,0,0.12);
  border-radius: 5px;
  background: rgba(255,255,255,0.54);
  overflow: hidden;
}
.qa-toggle-btn {
  height: 22px;
  padding: 0 8px;
  border: 1px solid rgba(99,102,241,0.35);
  border-radius: 4px;
  background: rgba(99,102,241,0.08);
  color: #4f46e5;
  font-family: 'DM Mono', monospace;
  font-size: 8px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  cursor: pointer;
  flex-shrink: 0;
}
.qa-toggle-btn.active {
  border-color: rgba(34,197,94,0.55);
  background: rgba(34,197,94,0.12);
  color: #15803d;
}
.qa-summary {
  font-size: 9px;
  letter-spacing: 1px;
  color: var(--engrave-dim);
  text-transform: uppercase;
  min-width: 80px;
  max-width: 140px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.qa-live-meter {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 152px;
  flex-shrink: 0;
}
.qa-meter-label {
  font-size: 8px;
  letter-spacing: 1px;
  color: var(--engrave-faint);
}
.qa-meter-track {
  width: 34px;
  height: 6px;
  border-radius: 2px;
  background: rgba(0,0,0,0.10);
  overflow: hidden;
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.12);
}
.qa-meter-track span {
  display: block;
  width: 0%;
  height: 100%;
  background: #22c55e;
  transition: width 0.08s linear, background 0.08s linear;
}
.qa-meter-track span.warn { background: #ca8a04; }
.qa-meter-track span.hot { background: #ef4444; }
.qa-meter-db {
  width: 46px;
  font-size: 8px;
  letter-spacing: 1px;
  color: var(--engrave-dim);
  text-align: right;
}

.qa-action-btn {
  height: 22px;
  padding: 0 7px;
  border: 1px solid rgba(34,197,94,0.45);
  border-radius: 4px;
  background: rgba(34,197,94,0.08);
  color: #15803d;
  font-family: 'DM Mono', monospace;
  font-size: 8px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  cursor: pointer;
  flex-shrink: 0;
}
.qa-action-btn:hover { background: rgba(34,197,94,0.14); }
.qa-action-btn.secondary {
  border-color: var(--border);
  background: rgba(0,0,0,0.03);
  color: var(--engrave-dim);
}

.qa-panel-body {
  padding: 8px 12px 10px;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  background: rgba(0,0,0,0.025);
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: none;
}
#patchesStripBody.qa-open {
  height: auto;
  min-height: 86px;
  flex-direction: column;
}
#patchesStripBody.qa-open .patches-strip-bank {
  min-height: 86px;
  flex: 0 0 86px;
}

.qa-stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(88px, 1fr));
  gap: 6px;
}
.qa-stat {
  min-height: 42px;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: rgba(255,255,255,0.72);
}
.qa-safety-card {
  min-height: 28px;
  padding: 6px 8px;
  border: 1px solid rgba(34,197,94,0.24);
  border-radius: 6px;
  background: rgba(34,197,94,0.055);
  color: #15803d;
  font-family: 'DM Mono', monospace;
  font-size: 8px;
  letter-spacing: 1px;
  text-transform: uppercase;
  display: flex;
  align-items: center;
}
.qa-safety-card.warn {
  border-color: rgba(239,68,68,0.42);
  background: rgba(239,68,68,0.055);
  color: #dc2626;
}
.qa-stat-label {
  display: block;
  font-size: 7px;
  letter-spacing: 1.4px;
  color: var(--engrave-faint);
  text-transform: uppercase;
}
.qa-stat-value {
  display: block;
  margin-top: 4px;
  font-size: 13px;
  color: var(--engrave);
}

.qa-filter-row {
  display: flex;
  align-items: center;
  gap: 5px;
  flex-wrap: wrap;
}
.qa-filter {
  height: 24px;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: rgba(255,255,255,0.62);
  color: var(--engrave-dim);
  font-family: 'DM Mono', monospace;
  font-size: 8px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  cursor: pointer;
}
.qa-filter.active {
  border-color: rgba(34,197,94,0.55);
  background: rgba(34,197,94,0.12);
  color: #15803d;
}

.qa-active-card {
  min-height: 0;
}
.qa-active-card:not(:empty) {
  display: grid;
  grid-template-columns: minmax(180px, 1.4fr) repeat(4, minmax(72px, 0.45fr));
  gap: 6px;
  align-items: stretch;
}
.qa-active-cell {
  padding: 6px 8px;
  border: 1px solid rgba(34,197,94,0.25);
  border-radius: 6px;
  background: rgba(34,197,94,0.06);
}
.qa-active-title {
  font-size: 10px;
  letter-spacing: 1px;
  color: #15803d;
  text-transform: uppercase;
}
.qa-active-detail {
  margin-top: 3px;
  font-size: 8px;
  color: var(--engrave-dim);
  letter-spacing: 0.6px;
}

.qa-results {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 6px;
  max-height: 220px;
  overflow-y: auto;
  padding-right: 2px;
}
.qa-result {
  border: 1px solid var(--border);
  border-radius: 6px;
  background: rgba(255,255,255,0.72);
  padding: 7px 8px;
  display: grid;
  gap: 6px;
}
.qa-result.qa-risk { border-color: rgba(239,68,68,0.45); background: rgba(239,68,68,0.04); }
.qa-result.qa-watch { border-color: rgba(202,138,4,0.42); background: rgba(202,138,4,0.045); }
.qa-result.qa-tail { border-color: rgba(34,197,94,0.30); background: rgba(34,197,94,0.035); }
.qa-result.qa-hit { border-color: rgba(14,165,233,0.30); background: rgba(14,165,233,0.035); }
.qa-result-top {
  display: flex;
  gap: 6px;
  align-items: center;
}
.qa-result-name {
  flex: 1;
  min-width: 0;
  font-size: 10px;
  letter-spacing: 0.8px;
  color: var(--engrave);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.qa-jump-btn {
  flex-shrink: 0;
  padding: 3px 7px;
  border: 1px solid rgba(34,197,94,0.35);
  border-radius: 4px;
  background: rgba(34,197,94,0.08);
  color: #15803d;
  font-family: 'DM Mono', monospace;
  font-size: 7px;
  letter-spacing: 1px;
  cursor: pointer;
}
.qa-result-metrics {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
}
.qa-mini {
  padding: 3px 4px;
  border-radius: 3px;
  background: rgba(0,0,0,0.035);
}
.qa-mini span {
  display: block;
  font-size: 6px;
  letter-spacing: 1px;
  color: var(--engrave-faint);
  text-transform: uppercase;
}
.qa-mini strong {
  display: block;
  margin-top: 2px;
  font-size: 9px;
  color: var(--engrave);
  font-weight: 500;
}
.qa-flags {
  display: flex;
  gap: 3px;
  flex-wrap: wrap;
}
.qa-flag {
  padding: 2px 5px;
  border-radius: 999px;
  background: rgba(0,0,0,0.06);
  color: var(--engrave-dim);
  font-size: 6px;
  letter-spacing: 1px;
  text-transform: uppercase;
}
.qa-flag.risk { background: rgba(239,68,68,0.11); color: #dc2626; }
.qa-flag.watch { background: rgba(202,138,4,0.12); color: #a16207; }
.qa-flag.info { background: rgba(34,197,94,0.10); color: #15803d; }
.qa-flag.tail { background: rgba(14,165,233,0.10); color: #0369a1; }
.qa-flag.hit { background: rgba(99,102,241,0.10); color: #4f46e5; }
.qa-empty {
  grid-column: 1 / -1;
  font-size: 9px;
  letter-spacing: 1px;
  color: var(--engrave-dim);
  text-transform: uppercase;
  padding: 6px 0;
}

/* ── User patches row ───────────────────────────────────── */
.patch-user-row {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 4px 12px 6px;
  border-top: 1px solid var(--border);
  flex-wrap: wrap;
  row-gap: 4px;
}

.patch-user-label { flex-shrink: 0; }

.patch-user-slots {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  flex: 1;
  min-height: 22px;
  align-items: center;
}

.user-patch-hint {
  font-size: 7.5px;
  color: var(--engrave-faint);
  letter-spacing: 1px;
  font-family: 'DM Mono', monospace;
}

/* ── User patch chip with delete ────────────────────────── */
.user-patch-wrap {
  display: inline-flex;
  align-items: stretch;
  overflow: hidden;
  border-radius: 3px;
  border: 1px solid var(--border2);
  background: var(--panel-light);
  box-shadow: 0 1px 2px rgba(0,0,0,0.07);
  transition: background 0.1s, border-color 0.1s, box-shadow 0.1s;
}
.user-patch-wrap:has(.user-patch-btn.active) {
  background: rgba(34,197,94,0.16);
  border-color: rgba(34,197,94,0.80);
  box-shadow: 0 0 14px rgba(34,197,94,0.40), inset 0 0 8px rgba(34,197,94,0.08);
}

/* Strip the preset-btn styling off the inner button so the wrap is the pill */
.user-patch-btn.preset-btn {
  border: none !important;
  border-radius: 0 !important;
  background: none !important;
  box-shadow: none !important;
}
.user-patch-btn.preset-btn::before { display: none; }
.user-patch-btn.preset-btn.active  {
  color: #4ade80;
  text-shadow: 0 0 8px rgba(34,197,94,0.55);
  background: none !important;
  box-shadow: none !important;
}

/* shared strip style for both edge buttons */
.user-patch-save,
.user-patch-del {
  flex-shrink: 0;
  width: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
  color: var(--engrave-dim);
  opacity: 0.3;
  transition: opacity 0.15s, background 0.15s, color 0.15s;
}
.user-patch-wrap:hover .user-patch-save,
.user-patch-wrap:hover .user-patch-del { opacity: 1; }

.user-patch-save { border-right: 1px solid var(--border2); }
.user-patch-save:hover { background: rgba(34,197,94,0.12); color: #16a34a; }

.user-patch-del { border-left: 1px solid var(--border2); }
.user-patch-del:hover { background: rgba(220,38,38,0.10); color: #dc2626; }
.user-patch-del.holding {
  opacity: 1;
  animation: upatch-del-charge 0.7s linear forwards;
}
@keyframes upatch-del-charge {
  0%   { background: none;                 color: var(--engrave-dim); }
  60%  { background: rgba(255,80,40,0.15); color: rgba(220,60,30,0.9); }
  100% { background: rgba(220,38,38,0.18); color: #dc2626; }
}

.user-patch-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
}
.user-patch-name {
  font-size: 10.5px;
  font-family: 'DM Mono', monospace;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  pointer-events: none;
}
.user-patch-key {
  font-size: 7px;
  letter-spacing: 0.4px;
  color: var(--engrave-dim);
  opacity: 0.65;
  font-family: 'DM Mono', monospace;
  text-transform: none;
  font-weight: normal;
  line-height: 1;
  pointer-events: none;
}
.user-patch-btn.active .user-patch-key {
  color: rgba(74,222,128,0.75);
  opacity: 1;
}


/* ── Save patch button ──────────────────────────────────── */
.patch-save-btn {
  flex-shrink: 0;
  padding: 4px 10px;
  border: 1px solid rgba(34,197,94,0.35);
  border-radius: 4px;
  background: rgba(34,197,94,0.06);
  color: #15803d;
  font-size: 8px;
  font-family: 'DM Mono', monospace;
  letter-spacing: 1px;
  cursor: pointer;
  transition: background 0.1s, box-shadow 0.1s;
  text-transform: uppercase;
}
.patch-save-btn:hover {
  background: rgba(34,197,94,0.14);
  box-shadow: 0 0 8px rgba(34,197,94,0.20);
}

.patch-load-wt-btn {
  flex-shrink: 0;
  padding: 4px 8px;
  border: 1px solid rgba(168,85,247,0.35);
  border-radius: 4px;
  background: rgba(168,85,247,0.06);
  color: #a855f7;
  font-size: 8px;
  font-family: 'DM Mono', monospace;
  letter-spacing: 1px;
  cursor: pointer;
  transition: background 0.1s, box-shadow 0.1s;
  text-transform: uppercase;
}
.patch-load-wt-btn:hover {
  background: rgba(168,85,247,0.14);
  box-shadow: 0 0 8px rgba(168,85,247,0.20);
}

/* ── Illuminated pushbuttons (shared: factory + user) ───── */
.preset-btn {
  position: relative;
  padding: 5px 11px;
  border: 1px solid var(--border2);
  border-radius: 3px;
  background: var(--panel-light);
  color: var(--engrave-dim);
  font-size: 10.5px;
  font-family: 'DM Mono', monospace;
  letter-spacing: 0.6px;
  cursor: pointer;
  transition: background 0.1s, color 0.1s, border-color 0.1s, box-shadow 0.1s;
  box-shadow: 0 1px 2px rgba(0,0,0,0.07);
  text-transform: uppercase;
  white-space: nowrap;
}

.preset-btn::before {
  content: '';
  position: absolute;
  top: -4px;
  left: 50%;
  transform: translateX(-50%);
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--led-ext);
  opacity: 0.4;
  transition: background 0.1s, opacity 0.1s, box-shadow 0.1s;
}

.preset-btn:hover {
  background: var(--panel-edge);
  color: var(--engrave);
  border-color: var(--border2);
}

.preset-btn.active {
  background: rgba(34,197,94,0.16);
  color: #4ade80;
  border-color: rgba(34,197,94,0.80);
  box-shadow: 0 0 14px rgba(34,197,94,0.40), inset 0 0 8px rgba(34,197,94,0.08);
  text-shadow: 0 0 8px rgba(34,197,94,0.55);
}

.preset-btn.active::before {
  background: #22c55e;
  opacity: 1;
  box-shadow: 0 0 10px #22c55e, 0 0 20px rgba(34,197,94,0.55);
}

/* ── Save patch modal ───────────────────────────────────── */
.save-modal {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.save-modal-panel {
  background: var(--phos-bg);
  border: 1px solid rgba(68,255,136,0.35);
  border-radius: 8px;
  padding: 20px 24px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 240px;
  box-shadow: 0 0 40px rgba(68,255,136,0.15);
}

.save-modal-header {
  font-size: 9px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--phos-dim);
  font-family: 'DM Mono', monospace;
}

.save-modal-input {
  background: rgba(68,255,136,0.06);
  border: 1px solid rgba(12,122,50,0.32);
  border-radius: 4px;
  color: var(--phos-on-light);
  font-family: 'Share Tech Mono', monospace;
  font-size: 16px;
  letter-spacing: 2px;
  padding: 8px 12px;
  text-transform: uppercase;
  outline: none;
  width: 100%;
}
.save-modal-input:focus {
  border-color: rgba(68,255,136,0.65);
  box-shadow: 0 0 12px rgba(68,255,136,0.20);
}
.save-modal-input::placeholder { color: rgba(34,153,58,0.5); }

.save-modal-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

.save-modal-btn {
  padding: 6px 16px;
  border-radius: 4px;
  font-family: 'DM Mono', monospace;
  font-size: 8px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.1s, box-shadow 0.1s;
}
.save-modal-btn.cancel {
  background: transparent;
  border: 1px solid rgba(68,255,136,0.20);
  color: var(--phos-dim);
}
.save-modal-btn.cancel:hover {
  border-color: rgba(12,122,50,0.45);
  color: var(--phos-on-light);
}
.save-modal-btn.confirm {
  background: rgba(34,197,94,0.15);
  border: 1px solid rgba(34,197,94,0.45);
  color: #22c55e;
}
.save-modal-btn.confirm:hover {
  background: rgba(34,197,94,0.25);
  box-shadow: 0 0 10px rgba(34,197,94,0.25);
}

/* ══════════════════════════════════════════════════════════
   VPC PANEL  —  two-column Voice + Patches layout
══════════════════════════════════════════════════════════ */
.vpc-panel {
  display: flex;
  flex-shrink: 0;
  background: var(--panel-light);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--div-hi);
  min-height: 0;
  overflow-x: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(0,0,0,0.10) transparent;
}

.vpc-col {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.vpc-voice {
  flex: 0 0 auto;
}

.vpc-patches {
  flex: 1;
  min-width: 200px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.vpc-col-hdr {
  padding: 4px 10px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.vpc-vdiv {
  width: 1px;
  background: linear-gradient(180deg, transparent, var(--border) 15%, var(--border) 85%, transparent);
  flex-shrink: 0;
}

.vpc-knob-groups {
  display: flex;
  flex-direction: row;       /* groups side-by-side, not stacked */
  align-items: flex-start;
  gap: 0;
  padding: 7px 10px 5px;
}

.vpc-knob-group {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-right: 12px;
  margin-right: 12px;
  border-right: 1px solid var(--border);
}
.vpc-knob-group:last-child {
  padding-right: 0;
  margin-right: 0;
  border-right: none;
}

.vpc-group-lbl {
  font-size: 8.5px;
  letter-spacing: 2px;
  text-transform: uppercase;
  font-family: 'DM Mono', monospace;
  border-bottom: 1px solid var(--border);
  padding-bottom: 2px;
  margin-bottom: 4px;
  white-space: nowrap;
}

.vpc-env-lbl { color: #22c55e; }
.vpc-flt-lbl { color: #6366f1; }
.vpc-chr-lbl { color: #e67e22; }

/* ── Section preset pill strip ──────────────────────────── */
.vpc-sec-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  margin-top: 4px;
}

.vpc-sec-preset-btn {
  padding: 2px 8px;
  border: 1px solid var(--border2);
  border-radius: 3px;
  background: var(--surface);
  color: var(--engrave-dim);
  font-size: 8px;
  font-family: 'DM Mono', monospace;
  letter-spacing: 1px;
  text-transform: uppercase;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.1s, color 0.1s, border-color 0.1s, box-shadow 0.1s;
}
.vpc-sec-preset-btn:hover {
  background: var(--panel-edge);
  color: var(--engrave);
}

/* Active state — each group gets its accent colour */
.vpc-env-presets .vpc-sec-preset-btn.active {
  background: rgba(34,197,94,0.10);
  color: #15803d;
  border-color: rgba(34,197,94,0.45);
  box-shadow: 0 0 6px rgba(34,197,94,0.15);
}
.vpc-flt-presets .vpc-sec-preset-btn.active {
  background: rgba(99,102,241,0.10);
  color: #4338ca;
  border-color: rgba(99,102,241,0.45);
  box-shadow: 0 0 6px rgba(99,102,241,0.15);
}
.vpc-chr-presets .vpc-sec-preset-btn.active {
  background: rgba(230,126,34,0.10);
  color: #c2410c;
  border-color: rgba(230,126,34,0.45);
  box-shadow: 0 0 6px rgba(230,126,34,0.15);
}

.vpc-knob-row {
  display: flex;
  gap: 4px;
  align-items: flex-start;
}

/* ── Playback knob group ─────────────────────────────────── */
.vpc-playback-group {
  border-top: 1px solid var(--border);
  padding-top: 6px;
  margin-top: 0;
  padding: 5px 10px 7px;
}
.vpc-pb-lbl { color: #8b5cf6; }

/* Knobs + pill buttons on one horizontal line */
.vpc-playback-row {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 4px;
}

/* Pill buttons stacked vertically inside the row, centred on the knobs */
.vpc-playback-pills {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-left: 4px;
}

.led-pill-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px 3px 7px;
  border: 1px solid var(--border2);
  border-radius: 12px;
  background: var(--surface);
  color: var(--engrave-dim);
  font-size: 9px;
  font-family: 'DM Mono', monospace;
  letter-spacing: 2px;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s, box-shadow 0.15s;
}
.led-pill-btn:hover {
  background: var(--panel-edge);
  color: var(--engrave);
}
.led-pill-btn.led-pill-active {
  background: rgba(34,197,94,0.08);
  color: #15803d;
  border-color: rgba(34,197,94,0.40);
  box-shadow: 0 0 8px rgba(34,197,94,0.15);
}

/* Override (Lock Voice / Lock FX) pill group — sits at the right edge of a panel header */
.hdr-pill-group {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: auto;
}
.hdr-pill-group .led-pill-btn { padding: 2px 8px 2px 6px; }
.hdr-pill-group .fx-preset-btn { padding: 2px 6px; line-height: 1; }

/* Sustain pedal — visually distinct from mode toggles */
.pedal-btn {
  border-color: rgba(251,191,36,0.35);
  font-weight: 600;
  letter-spacing: 1.8px;
  margin-bottom: 2px;
}
.pedal-btn:hover {
  border-color: rgba(251,191,36,0.55);
}
.pedal-btn.led-pill-active {
  background: rgba(251,191,36,0.10);
  color: #92400e;
  border-color: rgba(251,191,36,0.55);
  box-shadow: 0 0 10px rgba(251,191,36,0.20);
}
.pedal-btn.led-pill-active .led-pip {
  background: #d97706;
  box-shadow: 0 0 5px rgba(217,119,6,0.8);
}

/* LED pip — small circle that lights up */
.led-pip {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--engrave-faint);
  border: 1px solid rgba(0,0,0,0.15);
  flex-shrink: 0;
  transition: background 0.15s, box-shadow 0.15s;
}
.led-pip.led-pip-on {
  background: #22c55e;
  box-shadow: 0 0 5px rgba(34,197,94,0.70), 0 0 10px rgba(34,197,94,0.30);
}

/* Compact knobs in the vpc voice column — handled by .vpc-voice-flat rules below */
.vpc-voice .knob-wrap svg {
  width: 52px;
  height: 52px;
}
.vpc-voice .knob-label {
  font-size: 11px;
  letter-spacing: 1.5px;
}

/* Patches column: let patch-bank fill and scroll if needed */
.vpc-patches .patch-bank {
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.vpc-patches .patch-preset-grid {
  flex: 1;
  overflow-y: auto;
  align-content: flex-start;
  min-height: 40px;
}

/* Mobile: stack vpc columns vertically */
@media (max-width: 700px) {
  .vpc-panel { flex-direction: column; }
  .vpc-vdiv  { width: auto; height: 1px; background: var(--border); }
  .vpc-voice { flex: none; }
  .vpc-patches { flex: none; }
  .qa-inline { flex: 0 0 auto; min-width: 220px; max-width: 300px; }
  .qa-summary {
    min-width: 0;
    flex: 1;
  }
  .qa-live-meter {
    display: none;
  }
  .qa-stat-row,
  .qa-active-card:not(:empty) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .qa-results {
    grid-template-columns: 1fr;
    max-height: 320px;
  }
}

/* ── Sound sep (legacy, keep for mobile) ────────────────── */
.sound-group { display: flex; align-items: center; gap: 6px; }
.sound-sep { width: 1px; height: 22px; background: var(--border); flex-shrink: 0; }

/* Flavour / style buttons */
.flav-btn {
  padding: 4px 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--panel-light);
  color: var(--engrave-dim);
  font-size: 8px;
  font-family: 'DM Mono', monospace;
  letter-spacing: 0.5px;
  cursor: pointer;
  transition: background 0.1s, color 0.1s, border-color 0.1s;
  text-transform: uppercase;
}

.flav-btn:hover { background: var(--panel-edge); color: var(--engrave); border-color: var(--border2); }

.flav-btn.active {
  background: #f0fff8;
  color: #15803d;
  border-color: rgba(34,197,94,0.40);
}

/* Keyboard shortcut hint inside quality buttons */
.flav-kb {
  font-size: 6px;
  letter-spacing: 0;
  font-weight: 400;
  opacity: 0.40;
  vertical-align: super;
  margin-left: 2px;
  font-style: normal;
}
.flav-btn.active .flav-kb { opacity: 0.65; }

/* ── Mobile ──────────────────────────────────────────────── */
@media (max-width: 700px) {
  body {
    height: auto;
    min-height: 100dvh;
    overflow: auto;
  }

  .circle-section { width: 100%; align-items: center; }

  .chord-section { height: 200px; flex: none; }
  .ext-section   { height: 100px; }

  .keys-row { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .key     { min-width: 76px; flex: 0 0 76px; }
  .ext-key { min-width: 66px; flex: 0 0 66px; }

  .voice-section { flex-wrap: wrap; }
  .sound-section { flex-direction: column; }
  .patch-user-row { flex-wrap: wrap; }
  .sound-sep { display: none; }
  .song-row-artist { display: none; }
  .songs-player-chords { overflow-x: auto; flex-wrap: nowrap; }
}

/* ══════════════════════════════════════════════════════════
   SONG PROGRESSIONS
══════════════════════════════════════════════════════════ */

/* ── Key pad highlight when sequencer is active ─────────── */
.key.songs-active {
  border-color: rgba(34,197,94,0.60) !important;
  box-shadow:
    0 0 20px rgba(34,197,94,0.25),
    inset 0 1px 0 rgba(255,255,255,0.9) !important;
  filter: brightness(0.95);
}

/* ── Outer section ──────────────────────────────────────── */
.songs-section {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  background: var(--panel-light);
  border-top: 1px solid var(--border);
}

/* ── Genre filter + BPM row ─────────────────────────────── */
.songs-filter-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 12px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

.songs-genre-strip {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}

.songs-genre-btn {
  padding: 3px 9px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--panel-light);
  color: var(--engrave-dim);
  font-size: 8px;
  font-family: 'DM Mono', monospace;
  letter-spacing: 1px;
  cursor: pointer;
  transition: background 0.1s, color 0.1s, border-color 0.1s;
  text-transform: uppercase;
  box-shadow: 0 1px 2px rgba(0,0,0,0.06);
}

.songs-genre-btn:hover {
  background: var(--panel-edge);
  color: var(--engrave);
  border-color: var(--border2);
}

.songs-genre-btn.active {
  background: #f0fff8;
  color: #15803d;
  border-color: rgba(34,197,94,0.40);
}

.songs-filter-sep { flex: 1; }

/* ── Song list ───────────────────────────────────────────── */
.songs-list {
  max-height: 140px;
  overflow-y: auto;
  padding: 3px 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  scrollbar-width: thin;
  scrollbar-color: rgba(34,197,94,0.3) transparent;
}

/* ── Song row ────────────────────────────────────────────── */
.song-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 8px;
  border-radius: 4px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
  background: rgba(0,0,0,0.02);
  min-height: 28px;
}

.song-row:hover {
  background: rgba(0,0,0,0.05);
  border-color: var(--border);
}

.song-row.active {
  background: rgba(34,197,94,0.08);
  border-color: rgba(34,197,94,0.28);
}

.song-row-title {
  font-size: 9.5px;
  color: var(--engrave);
  font-family: 'DM Mono', monospace;
  letter-spacing: 0.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  min-width: 0;
}

.song-row-artist {
  font-size: 8px;
  color: var(--engrave-dim);
  font-family: 'DM Mono', monospace;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 0.8;
  min-width: 0;
  opacity: 0.75;
}

.song-row-genre {
  font-size: 7px;
  letter-spacing: 1.5px;
  color: var(--engrave-dim);
  opacity: 0.5;
  text-transform: uppercase;
  flex-shrink: 0;
  width: 40px;
  text-align: right;
}

.song-difficulty {
  display: flex;
  gap: 2px;
  flex-shrink: 0;
}

.song-diff-dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: rgba(0,0,0,0.08);
  border: 1px solid rgba(0,0,0,0.10);
}

.song-diff-dot.on {
  background: var(--engrave-dim);
  box-shadow: 0 0 3px rgba(26,26,46,0.3);
}

/* ── Player bar ──────────────────────────────────────────── */
.songs-player {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 7px 14px;
  border-top: 1px solid var(--border);
  background: rgba(0,0,0,0.03);
  flex-shrink: 0;
}

.songs-player-info {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.songs-player-title {
  font-size: 9px;
  color: #15803d;
  font-family: 'Share Tech Mono', monospace;
  letter-spacing: 1.5px;
  text-transform: uppercase;
}

.songs-player-artist {
  font-size: 8px;
  color: var(--engrave-dim);
  font-family: 'DM Mono', monospace;
  opacity: 0.7;
}

/* ── Chord cards + controls row ─────────────────────────── */
.songs-player-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.songs-player-chords {
  display: flex;
  gap: 4px;
  align-items: center;
  flex-wrap: wrap;
  flex: 1;
  min-width: 0;
}

/* ── Chord card ──────────────────────────────────────────── */
.songs-chord-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  background: var(--panel-light);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 3px 9px;
  min-width: 36px;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, box-shadow 0.12s;
  box-shadow: 0 1px 3px rgba(0,0,0,0.07);
}

.songs-chord-card:hover {
  border-color: var(--border2);
  background: var(--panel-edge);
}

.songs-chord-card.active-step {
  background: #f0fff8;
  border-color: rgba(34,197,94,0.55);
  box-shadow: 0 0 14px rgba(34,197,94,0.20);
}

.songs-chord-roman {
  font-size: 7px;
  color: var(--engrave-dim);
  font-family: 'DM Mono', monospace;
  letter-spacing: 0.5px;
  opacity: 0.65;
  line-height: 1;
}

.songs-chord-name {
  font-size: 15px;
  color: var(--engrave);
  font-family: 'Share Tech Mono', monospace;
  line-height: 1.1;
}

.songs-chord-arrow {
  font-size: 10px;
  color: var(--engrave-faint);
  flex-shrink: 0;
  user-select: none;
}

/* ── Playback controls ───────────────────────────────────── */
.songs-player-controls {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}

.songs-btn {
  padding: 4px 12px;
  border: 1px solid var(--border2);
  border-radius: 4px;
  background: var(--panel-light);
  color: var(--engrave-dim);
  font-size: 8.5px;
  font-family: 'DM Mono', monospace;
  letter-spacing: 1.5px;
  cursor: pointer;
  transition: background 0.1s, color 0.1s, border-color 0.1s, box-shadow 0.1s;
  text-transform: uppercase;
  box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}

.songs-btn:hover {
  background: var(--panel-edge);
  color: var(--engrave);
  border-color: var(--border2);
}

.songs-btn-play.playing {
  background: #f0fff8;
  color: #15803d;
  border-color: rgba(34,197,94,0.40);
  box-shadow: 0 0 10px rgba(34,197,94,0.15);
}

.songs-btn-stop { color: var(--engrave-faint); }
.songs-btn-stop:hover { color: var(--engrave-dim); }

/* ── Mode mismatch warning ───────────────────────────────── */
.songs-mode-warning {
  font-size: 7.5px;
  color: #b45309;
  font-family: 'DM Mono', monospace;
  letter-spacing: 1px;
  opacity: 0.9;
}

/* ══════════════════════════════════════════════════════════
   INFO MODE
══════════════════════════════════════════════════════════ */

/* Nameplate left group */
.nameplate-left {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

/* Info mode toggle button */
.info-mode-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px 3px 7px;
  border: 1px solid var(--border2);
  border-radius: 12px;
  background: var(--surface);
  color: var(--engrave-dim);
  font-size: 9px;
  font-family: 'DM Mono', monospace;
  letter-spacing: 2px;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s, box-shadow 0.15s;
}
.info-mode-btn:hover {
  background: var(--panel-edge);
  color: var(--engrave);
}
.info-mode-btn.info-btn-active {
  background: rgba(96,165,250,0.10);
  color: #1d4ed8;
  border-color: rgba(96,165,250,0.40);
  box-shadow: 0 0 8px rgba(96,165,250,0.15);
}

/* LED pip inside info button */
.info-btn-pip {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--engrave-faint);
  border: 1px solid rgba(0,0,0,0.15);
  flex-shrink: 0;
  transition: background 0.15s, box-shadow 0.15s;
}
.info-btn-active .info-btn-pip {
  background: #60a5fa;
  box-shadow: 0 0 5px rgba(96,165,250,0.70), 0 0 10px rgba(96,165,250,0.30);
}

/* Hover highlight on interactive elements when info mode is on */
body.info-mode-active [data-info] { cursor: help; }
body.info-mode-active [data-info]:hover {
  outline: 1.5px solid rgba(96,165,250,0.50);
  outline-offset: 4px;
  border-radius: 6px;
}

/* ── Info tooltip card ───────────────────────────────────── */
.info-tip {
  position: fixed;
  z-index: 9000;
  width: 240px;
  background: #0b1220;
  border: 1px solid rgba(96,165,250,0.32);
  border-radius: 8px;
  box-shadow: 0 10px 32px rgba(0,0,0,0.55), 0 0 0 1px rgba(96,165,250,0.08);
  font-family: 'DM Mono', monospace;
  pointer-events: all;
  animation: info-tip-in 0.13s ease;
  overflow: hidden;
}

@keyframes info-tip-in {
  from { opacity: 0; transform: translateY(-5px) scale(0.97); }
  to   { opacity: 1; transform: none; }
}

.info-tip.info-tip-pinned {
  border-color: rgba(96,165,250,0.55);
  box-shadow: 0 10px 32px rgba(0,0,0,0.60), 0 0 16px rgba(96,165,250,0.08);
}

.info-tip-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 7px 10px 6px;
  border-bottom: 1px solid rgba(96,165,250,0.10);
}

.info-tip-title {
  font-size: 9.5px;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: #93c5fd;
  font-weight: 500;
}

.info-tip-actions {
  display: flex;
  gap: 2px;
  align-items: center;
}

.info-tip-pin,
.info-tip-close {
  border: none;
  background: none;
  cursor: pointer;
  padding: 1px 5px;
  font-size: 11px;
  color: rgba(147,197,253,0.42);
  border-radius: 4px;
  line-height: 1;
  transition: color 0.1s, background 0.1s;
}
.info-tip-pin:hover  { color: #93c5fd; background: rgba(96,165,250,0.10); }
.info-tip-close:hover{ color: #f87171; background: rgba(248,113,113,0.10); }

.info-tip-context {
  padding: 3px 10px 3px;
  font-size: 8px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: rgba(147,197,253,0.45);
  border-bottom: 1px solid rgba(96,165,250,0.07);
}

.info-tip-canvas {
  display: block;
  width: 100%;
  border-bottom: 1px solid rgba(96,165,250,0.08);
  image-rendering: auto;
}

.info-tip-desc {
  padding: 7px 10px 9px;
  font-size: 8.5px;
  line-height: 1.60;
  color: rgba(147,197,253,0.58);
  letter-spacing: 0.2px;
}

/* ══════════════════════════════════════════════════════════
   TEACH ME MODE
══════════════════════════════════════════════════════════ */

/* ── Nameplate button ────────────────────────────────────── */
.teach-mode-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px 3px 7px;
  border: 1px solid var(--border2);
  border-radius: 12px;
  background: var(--surface);
  color: var(--engrave-dim);
  font-size: 9px;
  font-family: 'DM Mono', monospace;
  letter-spacing: 2px;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s, box-shadow 0.15s;
}
.teach-mode-btn:hover {
  background: var(--panel-edge);
  color: var(--engrave);
}
.teach-mode-btn.teach-btn-active {
  background: rgba(251,191,36,0.10);
  color: #92400e;
  border-color: rgba(251,191,36,0.45);
  box-shadow: 0 0 8px rgba(251,191,36,0.18);
}
.teach-btn-pip {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--engrave-faint);
  border: 1px solid rgba(0,0,0,0.15);
  flex-shrink: 0;
  transition: background 0.15s, box-shadow 0.15s;
}
.teach-pip-on {
  background: #fbbf24;
  box-shadow: 0 0 5px rgba(251,191,36,0.80), 0 0 10px rgba(251,191,36,0.35);
}

/* ── Spotlight on targeted elements ────────────────────────── */
.teach-spotlight {
  outline: 2px solid rgba(251,191,36,0.85) !important;
  outline-offset: 4px;
  border-radius: 6px;
  animation: teach-spotlight-pulse 1.8s ease-in-out infinite;
}
/* The leading dark ring (0 0 0 2px) backs the amber so the spotlight reads on the LIGHT
   pastel pads too (amber-on-white is only ~1.9:1); it's invisible on dark LCD panels. */
@keyframes teach-spotlight-pulse {
  0%, 100% { outline-color: rgba(251,191,36,0.70); box-shadow: 0 0 0 2px rgba(8,15,12,0.55), 0 0 0 6px rgba(251,191,36,0.14); }
  50%       { outline-color: rgba(251,191,36,1.00); box-shadow: 0 0 0 2px rgba(8,15,12,0.60), 0 0 0 9px rgba(251,191,36,0.24), 0 0 20px rgba(251,191,36,0.15); }
}

/* ── Teach panel ────────────────────────────────────────────── */
.teach-panel {
  position: fixed;
  bottom: max(20px, env(safe-area-inset-bottom));   /* clear the home indicator / notch */
  right: max(20px, env(safe-area-inset-right));
  width: 300px;
  z-index: 8500;
  background: #0e1626;
  border: 1px solid rgba(251,191,36,0.35);
  border-radius: 12px;
  box-shadow: 0 16px 48px rgba(0,0,0,0.60), 0 0 0 1px rgba(251,191,36,0.08);
  font-family: 'DM Mono', monospace;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: teach-panel-in 0.22s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes teach-panel-in {
  from { opacity: 0; transform: translateY(20px) scale(0.95); }
  to   { opacity: 1; transform: none; }
}

/* Header */
.teach-hdr {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px 8px;
  border-bottom: 1px solid rgba(251,191,36,0.14);
  background: rgba(251,191,36,0.05);
}
.teach-hdr-left {
  display: flex; align-items: center; gap: 8px;
}
.teach-hdr-icon {
  font-size: 16px; line-height: 1;
}
.teach-hdr-label {
  font-size: 9px; letter-spacing: 3px; text-transform: uppercase;
  color: rgba(251,191,36,0.80); font-weight: 500;
}
.teach-hdr-right {
  display: flex; align-items: center; gap: 8px;
}
.teach-lesson-counter {
  font-size: 8px; letter-spacing: 1px; color: rgba(251,191,36,0.45);
}
.teach-close-btn {
  border: none; background: none; cursor: pointer;
  font-size: 11px; color: rgba(251,191,36,0.40); padding: 2px 4px;
  border-radius: 4px; transition: color 0.1s, background 0.1s;
}
.teach-close-btn:hover { color: #f87171; background: rgba(248,113,113,0.10); }

/* Lesson navigation (dot row) */
.teach-lesson-nav {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 12px;
  border-bottom: 1px solid rgba(251,191,36,0.08);
}
.teach-nav-btn {
  border: none; background: none; cursor: pointer;
  font-size: 9px; color: rgba(251,191,36,0.40); padding: 2px 5px;
  border-radius: 4px; transition: color 0.1s, background 0.1s; flex-shrink: 0;
}
.teach-nav-btn:hover { color: #fbbf24; background: rgba(251,191,36,0.10); }
.teach-lesson-dots {
  display: flex; gap: 5px; flex: 1; justify-content: center; flex-wrap: wrap;
}
.teach-lesson-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: rgba(251,191,36,0.15); border: 1px solid rgba(251,191,36,0.25);
  cursor: pointer; transition: background 0.15s, border-color 0.15s;
}
.teach-lesson-dot.active {
  background: #fbbf24; border-color: #fbbf24;
  box-shadow: 0 0 6px rgba(251,191,36,0.60);
}
.teach-lesson-dot.done {
  background: rgba(251,191,36,0.45); border-color: rgba(251,191,36,0.55);
}

/* Body */
.teach-body {
  padding: 12px 14px 8px;
  flex: 1;
  overflow-y: auto;
}
.teach-step-title {
  font-size: 10px; font-weight: 500;
  letter-spacing: 2px; text-transform: uppercase;
  color: #fbbf24; margin-bottom: 8px;
}
.teach-canvas {
  display: block; width: 100%;
  border-radius: 6px; margin-bottom: 10px;
  border: 1px solid rgba(251,191,36,0.10);
}
.teach-text {
  font-size: 8.5px; line-height: 1.70;
  color: rgba(255,255,255,0.60);
  letter-spacing: 0.2px;
}
.teach-text strong { color: rgba(255,255,255,0.88); }
.teach-text code {
  font-family: 'DM Mono', monospace;
  background: rgba(251,191,36,0.12);
  border: 1px solid rgba(251,191,36,0.25);
  border-radius: 3px; padding: 0 3px;
  color: #fcd34d; font-size: 8px;
}
.teach-text em { color: rgba(251,191,36,0.80); font-style: normal; }

/* Try-it box */
.teach-tryit {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: 10px;
  padding: 8px 10px;
  border: 1px solid rgba(251,191,36,0.28);
  border-radius: 8px;
  background: rgba(251,191,36,0.07);
  font-size: 8.5px;
  color: rgba(251,191,36,0.75);
  transition: background 0.25s, border-color 0.25s;
}
.teach-tryit.teach-tryit-done {
  background: rgba(34,197,94,0.10);
  border-color: rgba(34,197,94,0.40);
  color: rgba(34,197,94,0.85);
}
.teach-tryit-icon { font-size: 12px; flex-shrink: 0; }
.teach-tryit-text { flex: 1; }
.teach-tryit-ok {
  font-size: 14px; color: #22c55e; font-weight: bold; flex-shrink: 0;
  animation: teach-ok-pop 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes teach-ok-pop {
  from { transform: scale(0); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
}

/* Ear-training quiz */
.teach-quiz {
  margin-top: 10px;
  padding: 10px;
  border: 1px solid rgba(251,191,36,0.28);
  border-radius: 8px;
  background: rgba(251,191,36,0.07);
}
.teach-quiz-play {
  display: block; width: 100%;
  padding: 8px 10px; min-height: 44px; margin-bottom: 8px;   /* 44px touch target */
  border: 1px solid rgba(251,191,36,0.45);
  border-radius: 7px;
  background: rgba(251,191,36,0.14);
  color: #fcd34d; font-size: 10px; font-weight: 700; letter-spacing: 0.08em;
  cursor: pointer;
  transition: background 0.15s;
}
.teach-quiz-play:hover { background: rgba(251,191,36,0.24); }
.teach-quiz-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 6px;
}
.teach-quiz-btn {
  padding: 7px 6px;
  min-height: 44px;   /* 44px touch target */
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: 7px;
  background: rgba(255,255,255,0.05);
  color: rgba(255,255,255,0.82); font-size: 8.5px; font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, transform 0.1s;
}
.teach-quiz-btn:hover:not(:disabled) { background: rgba(255,255,255,0.10); }
.teach-quiz-btn:disabled { opacity: 0.55; cursor: default; }
.teach-quiz-btn.teach-quiz-right {
  background: rgba(34,197,94,0.18); border-color: rgba(34,197,94,0.60);
  color: #22c55e; opacity: 1;
}
.teach-quiz-btn.teach-quiz-wrong {
  background: rgba(239,68,68,0.16); border-color: rgba(239,68,68,0.55);
  color: #f87171;
  animation: teach-quiz-shake 0.3s;
}
@keyframes teach-quiz-shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-3px); }
  75% { transform: translateX(3px); }
}
.teach-quiz-status {
  margin-top: 8px; font-size: 8.5px; color: rgba(251,191,36,0.75);
  text-align: center;
}

/* Footer */
.teach-footer {
  padding: 8px 12px 10px;
  border-top: 1px solid rgba(251,191,36,0.10);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.teach-step-pips {
  display: flex; gap: 5px; justify-content: center;
}
.teach-step-pip {
  width: 5px; height: 5px; border-radius: 50%;
  background: rgba(255,255,255,0.12);
  transition: background 0.15s;
}
.teach-step-pip.active { background: #fbbf24; box-shadow: 0 0 5px rgba(251,191,36,0.60); }
.teach-step-pip.done   { background: rgba(251,191,36,0.45); }

.teach-step-btns {
  display: flex; gap: 8px;
}
.teach-step-btn {
  flex: 1; padding: 6px 0;
  border: 1px solid rgba(251,191,36,0.25);
  border-radius: 6px;
  background: rgba(251,191,36,0.06);
  color: rgba(251,191,36,0.70);
  font-size: 8.5px; letter-spacing: 1.5px; text-transform: uppercase;
  font-family: 'DM Mono', monospace;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.teach-step-btn:hover:not(:disabled) {
  background: rgba(251,191,36,0.14);
  color: #fbbf24;
  border-color: rgba(251,191,36,0.50);
}
.teach-step-btn:disabled {
  opacity: 0.28; cursor: default;
}
.teach-step-next {
  background: rgba(251,191,36,0.12);
  color: #fbbf24;
  border-color: rgba(251,191,36,0.40);
}
.teach-step-next:hover:not(:disabled) {
  background: rgba(251,191,36,0.22);
  box-shadow: 0 0 10px rgba(251,191,36,0.15);
}

/* ══ Looper ═══════════════════════════════════════════════ */

.looper-toggle {
  cursor: pointer;
  user-select: none;
}
.looper-toggle:hover { background: rgba(0,0,0,0.05); }
.looper-chevron {
  margin-left: auto;
  font-size: 8px;
  color: var(--engrave-faint);
  letter-spacing: 0;
}

/* ── Outer section ──────────────────────────────────────── */
.looper-section {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  background: var(--panel-light);
  padding: 8px 12px 0;
  border-bottom: 1px solid var(--border);
  min-height: 0;
}

/* ── Bottom controls bar ────────────────────────────────── */
.looper-bottom-bar {
  display: flex;
  flex-direction: row;
  align-items: center;
  padding: 5px 6px;
  background: rgba(0,0,0,0.20);
  border: 1px solid rgba(68,255,136,0.12);
  border-top: none;
  border-radius: 0 0 3px 3px;
  margin-bottom: 8px;
  flex-wrap: wrap;
  row-gap: 4px;
  gap: 0;
}
.lbb-group {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 3px;
}
.lbb-label {
  font-family: 'DM Mono', 'Share Tech Mono', monospace;
  /* Phase 6: 6px engrave-faint was below the legibility floor on the dark
     transport strip — nano (7px) + engrave-dim keeps the labels quiet but
     actually readable. Mobile overrides to 11px full-width further down. */
  font-size: var(--type-nano);
  letter-spacing: 1.2px;
  color: var(--engrave-dim);
  margin-right: 2px;
  text-transform: uppercase;
}
.lbb-sep {
  width: 1px;
  height: 16px;
  background: var(--border2);
  margin: 0 6px;
  flex-shrink: 0;
}
.lbb-push { flex: 1; min-width: 6px; }

/* ── Transport / edit buttons ───────────────────────────── */
.looper-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 3px 6px;
  border: 1px solid var(--border2);
  border-radius: 4px;
  background: var(--panel-light);
  color: var(--engrave-dim);
  font-family: 'DM Mono', 'Share Tech Mono', monospace;
  font-size: 8px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(0,0,0,0.08);
  transition: background 0.12s, color 0.12s, border-color 0.12s;
  white-space: nowrap;
}
.looper-btn:hover {
  background: var(--panel-edge);
  color: var(--engrave);
  border-color: var(--border2);
}
.looper-btn:disabled {
  opacity: 0.30;
  cursor: default;
}
.looper-btn.active {
  background: rgba(68,255,136,0.14);
  color: var(--phos-on-light);
  border-color: rgba(12,122,50,0.55);
  box-shadow: 0 0 6px rgba(68,255,136,0.12);
}
.looper-btn-clear {
  color: var(--engrave-faint);
  font-size: 7px;
}
.looper-btn-clear:hover { color: #ef4444; border-color: rgba(239,68,68,0.40); }

/* REC button — LED states */
.looper-btn-rec .led-pip { transition: background 0.15s, box-shadow 0.15s; }
.looper-btn-rec .led-pip-rec {
  background: #ef4444;
  box-shadow: 0 0 5px rgba(239,68,68,0.80), 0 0 10px rgba(239,68,68,0.35);
}
@keyframes looper-blink {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.15; }
}
.looper-btn.recording .led-pip {
  animation: looper-blink 0.75s ease-in-out infinite;
}

/* ARM button */
.looper-btn-arm.armed {
  background: rgba(251,191,36,0.12);
  color: #fbbf24;
  border-color: rgba(251,191,36,0.40);
  box-shadow: 0 0 6px rgba(251,191,36,0.15);
}
.looper-btn-arm .led-pip { transition: background 0.15s, box-shadow 0.15s; }
.led-pip-arm {
  background: #fbbf24 !important;
  box-shadow: 0 0 5px rgba(251,191,36,0.80), 0 0 10px rgba(251,191,36,0.35) !important;
  animation: looper-blink 1.0s ease-in-out infinite;
}

/* CLICK mode — count-in popover */
.looper-click-wrap { position: relative; display: inline-flex; }
.looper-click-pop {
  display: none;
  position: absolute;
  bottom: calc(100% + 6px);
  right: 0;
  z-index: 8600;   /* above the teach-panel (8500) so it isn't buried when a lesson is open */
  min-width: 188px;
  padding: 8px;
  background: var(--panel-light);
  border: 1px solid var(--border2);
  border-radius: 6px;
  box-shadow: 0 6px 18px rgba(0,0,0,0.18);
}
.looper-click-pop.open { display: block; }
.lcp-row {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-bottom: 6px;
}
.lcp-row:last-child { margin-bottom: 0; }
.lcp-label {
  flex: 0 0 50px;
  font-family: 'DM Mono', 'Share Tech Mono', monospace;
  font-size: 8px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--engrave-dim);
}
.lcp-hint {
  font-family: 'DM Mono', 'Share Tech Mono', monospace;
  font-size: 7px;
  letter-spacing: 0.5px;
  color: var(--engrave-faint);
}
.lcp-btn {
  padding: 3px 7px;
  border: 1px solid var(--border2);
  border-radius: 4px;
  background: var(--panel-light);
  color: var(--engrave-dim);
  font-family: 'DM Mono', 'Share Tech Mono', monospace;
  font-size: 8px;
  letter-spacing: 1px;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.lcp-btn:hover { color: var(--engrave); border-color: var(--engrave-dim); }
.lcp-btn.active {
  background: var(--phos-on-light);
  color: #fff;
  border-color: var(--phos-on-light);
}
.lcp-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: 'DM Mono', 'Share Tech Mono', monospace;
  font-size: 8px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--engrave);
  cursor: pointer;
}
.lcp-toggle input { accent-color: var(--phos-on-light); cursor: pointer; }

/* BPM + time-sig inputs */
.looper-bpm-input {
  width: 44px;
  padding: 2px 3px;
  background: var(--panel-light);
  border: 1px solid var(--border2);
  border-radius: 3px;
  color: var(--engrave-dim);
  font-family: 'DM Mono', 'Share Tech Mono', monospace;
  font-size: 8px;
  letter-spacing: 0.5px;
  text-align: center;
}
.looper-bpm-input:focus {
  outline: none;
  border-color: rgba(12,122,50,0.55);
  color: var(--phos-on-light);
}
.looper-timesig-sel {
  padding: 2px 3px;
  background: var(--panel-light);
  border: 1px solid var(--border2);
  border-radius: 3px;
  color: var(--engrave-dim);
  font-family: 'DM Mono', 'Share Tech Mono', monospace;
  font-size: 8px;
  cursor: pointer;
}
.looper-timesig-sel:focus { outline: none; border-color: rgba(68,255,136,0.35); }

/* ── Tool buttons ───────────────────────────────────────── */
.looper-tool-btn {
  padding: 3px 6px;
  border: 1px solid var(--border2);
  border-radius: 3px;
  background: var(--panel-light);
  color: var(--engrave-faint);
  font-family: 'DM Mono', 'Share Tech Mono', monospace;
  font-size: 7px;
  letter-spacing: 1px;
  cursor: pointer;
  text-align: center;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.looper-tool-btn:hover {
  background: var(--panel-edge);
  color: var(--engrave-dim);
}
.looper-tool-btn.active {
  background: rgba(68,255,136,0.14);
  color: var(--phos-on-light);
  border-color: rgba(12,122,50,0.55);
  box-shadow: 0 0 5px rgba(68,255,136,0.10);
}

/* ── Status readout ─────────────────────────────────────── */
.looper-status {
  padding: 3px 8px;
  background: var(--phos-bg);
  border: 1px solid rgba(68,255,136,0.18);
  border-radius: 3px;
  font-family: 'Share Tech Mono', 'DM Mono', monospace;
  font-size: 7.5px;
  letter-spacing: 2px;
  color: var(--phos-fg);
  text-shadow: 0 0 6px var(--phos-glow);
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
}

/* ── Canvas editor ──────────────────────────────────────── */
.looper-editor {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0;
  min-width: 0;
}

.looper-canvas {
  display: block;
  width: 100%;
  height: 220px;
  background: #0a1a0a;
  border: 1px solid rgba(68,255,136,0.15);
  border-radius: 3px 3px 0 0;
  cursor: col-resize;
  box-shadow: inset 0 0 12px rgba(0,0,0,0.40);
}

/* Snap buttons */
.lbb-snap-btn {
  padding: 3px 6px;
  border: 1px solid var(--border2);
  border-radius: 3px;
  background: var(--panel-light);
  color: var(--engrave-faint);
  font-family: 'DM Mono', 'Share Tech Mono', monospace;
  font-size: 7px;
  letter-spacing: 1px;
  cursor: pointer;
  text-align: center;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.lbb-snap-btn:hover {
  background: var(--panel-edge);
  color: var(--engrave-dim);
}
.lbb-snap-btn.active {
  background: rgba(255,187,68,0.10);
  color: #fbbf24;
  border-color: rgba(255,187,68,0.40);
  box-shadow: 0 0 5px rgba(255,187,68,0.12);
}

/* ══════════════════════════════════════════════════════════
   HEADER STRIP  —  compact toolbar, no circle (moves to sidebar)
══════════════════════════════════════════════════════════ */
.header-strip {
  display: flex;
  align-items: stretch;
  height: 90px;
  background: var(--panel-light);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 1px 3px rgba(0,0,0,0.07);
  flex-shrink: 0;
}

/* ── Left: compact brand + two pills ───────────────────── */
.hs-left {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  padding: 8px 12px;
  flex-shrink: 0;
  max-width: 110px;
}

.hs-left .brand-name {
  font-size: 9px;
  letter-spacing: 2px;
  line-height: 1.4;
  opacity: 0.55;
}

.hs-pills {
  display: flex;
  flex-direction: row;
  gap: 4px;
  /* .hs-left is capped at 110px — a third pill must wrap rather than overflow
     underneath the phosphor display. */
  flex-wrap: wrap;
}

/* Compact pill buttons in the header */
.hs-pills .info-mode-btn,
.hs-pills .teach-mode-btn,
.hs-pills .sound-check-pill {
  padding: 2px 7px 2px 5px;
  font-size: 8px;
  letter-spacing: 1.5px;
}
.hs-pills .sound-check-pill .sc-light { width: 6px; height: 6px; }

/* Vertical divider between header sections */
.hs-vdiv {
  width: 1px;
  background: linear-gradient(180deg, transparent, var(--border) 20%, var(--border) 80%, transparent);
  flex-shrink: 0;
  margin: 10px 0;
}

/* ── Display: Root + Scale stacked, fixed width ─────────── */
.hs-display {
  display: flex;
  align-items: center;
  padding: 0 14px;
  flex-shrink: 0;
}

.hs-display .phosphor-display {
  flex-direction: column;
  gap: 5px;
  align-items: flex-start;
  padding: 8px 12px;
  min-width: 160px;
}

.hs-display .display-cell {
  flex-direction: row;
  align-items: baseline;
  gap: 7px;
}

/* ── Mode: vertical Scale / Free toggle ─────────────────── */
.hs-mode {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 6px 12px;
  flex-shrink: 0;
}

.toggle-vertical {
  flex-direction: column;
  gap: 2px;
  padding: 3px;
}

.toggle-vertical .toggle-option {
  padding: 5px 10px;
  text-align: center;
}

/* Static header instrument selector — desktop hides it (patches strip owns the
   instrument picker there); shown only on mobile, see the mobile media block. */
.hs-sound-select { display: none; }
.hs-sound-selects { display: none; }

/* ── Params: Octave + Master side by side, compact ──────── */
.hs-params {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  flex-shrink: 0;
}

.hs-param-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

.hs-params .knob-wrap svg {
  width: 42px;
  height: 42px;
}

.hs-params .knob-label {
  font-size: 10px;
  letter-spacing: 1px;
}

/* ── Wave: fills remaining width ────────────────────────── */
.hs-wave {
  display: flex;
  align-items: stretch;
  flex: 1;
  min-width: 80px;
  padding: 8px 12px;
}

.hs-wave .wave-strip {
  flex: 1;
  width: 100%;
  height: 100%;
}

/* ══════════════════════════════════════════════════════════
   PATCHES STRIP  —  horizontal scrollable patch bank
   Lives between header and chord keys
══════════════════════════════════════════════════════════ */
.patches-strip {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  background: var(--panel-light);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  height: auto;
  overflow: hidden;
}

/* Desktop patches body — horizontal row identical to the old layout */
#patchesStripBody {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  height: 86px;
  overflow: hidden;
}

.patches-strip-bank {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  flex: 1;
  min-width: 0;
  overflow: hidden;
}

.patch-browser-main {
  display: flex;
  align-items: stretch;
  flex: 1;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
}

.patch-tools-row {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 38px;
  padding: 5px 8px 4px;
  border-bottom: 1px solid var(--border);
  background: rgba(255,255,255,0.58);
  box-sizing: border-box;
  overflow: hidden;
}

.patch-search-input {
  width: 170px;
  height: 26px;
  flex: 0 0 170px;
  border: 1px solid rgba(0,0,0,0.13);
  border-radius: 5px;
  background: rgba(255,255,255,0.82);
  color: var(--engrave);
  font-family: 'DM Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.8px;
  padding: 0 9px;
  outline: none;
}
.patch-search-input:focus {
  border-color: rgba(34,197,94,0.52);
  box-shadow: 0 0 0 2px rgba(34,197,94,0.08);
}

.patch-filter-row,
.patch-audition-row {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
}
.patch-filter-row {
  flex: 1;
  overflow-x: auto;
  scrollbar-width: none;
}
.patch-filter-row::-webkit-scrollbar { display: none; }
.patch-filter-btn,
.patch-audition-btn {
  height: 24px;
  padding: 0 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: rgba(255,255,255,0.66);
  color: var(--engrave-dim);
  font-family: 'DM Mono', monospace;
  font-size: 7.5px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  cursor: pointer;
  flex-shrink: 0;
}
.patch-filter-btn.active,
.patch-audition-btn.active {
  border-color: rgba(34,197,94,0.55);
  background: rgba(34,197,94,0.12);
  color: #15803d;
}
.patch-audition-btn.quiet {
  border-color: rgba(0,0,0,0.10);
  background: rgba(0,0,0,0.035);
}
.patch-audition-status {
  min-width: 62px;
  max-width: 130px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--engrave-faint);
  font-family: 'DM Mono', monospace;
  font-size: 7px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
}

/* Family-grouped category rail: inactive families stay compact, active one opens. */
.patches-strip-bank .patch-cat-tabs {
  display: flex;
  flex-wrap: nowrap;
  overflow-x: auto;
  gap: 6px;
  padding: 5px 8px;
  border-bottom: none;
  border-right: 1px solid var(--border);
  flex-shrink: 0;
  align-items: center;
  max-width: 46vw;
  scrollbar-width: none;
}
.patches-strip-bank .patch-cat-tabs::-webkit-scrollbar { display: none; }

.patch-cat-family {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  padding: 3px 4px;
  border: 1px solid rgba(0,0,0,0.08);
  border-radius: 6px;
  background: rgba(0,0,0,0.025);
  flex-shrink: 0;
  transition: background 0.14s, border-color 0.14s, box-shadow 0.14s;
}
.patch-cat-family.active {
  background: rgba(34,197,94,0.055);
  border-color: rgba(34,197,94,0.24);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.6);
}
.patch-cat-family-label {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-size: 6.5px;
  letter-spacing: 1px;
  line-height: 1;
  color: var(--engrave-faint);
  text-transform: uppercase;
  flex-shrink: 0;
}
.patch-cat-family.active .patch-cat-family-label { color: rgba(21,128,61,0.65); }
.patch-cat-family-buttons {
  display: flex;
  align-items: center;
  gap: 3px;
}
.patches-strip-bank .pct-emoji {
  font-size: 14px;
  line-height: 1;
  flex-shrink: 0;
}
.patches-strip-bank .pct-label {
  display: inline-block;
  max-width: 0;
  overflow: hidden;
  opacity: 0;
  color: var(--engrave-faint);
  font-size: 8px;
  letter-spacing: 1px;
  text-transform: uppercase;
  white-space: nowrap;
  transition: max-width 0.16s, opacity 0.16s, color 0.16s;
}
.patches-strip-bank .patch-cat-tab {
  width: 28px;
  height: 28px;
  padding: 0;
  border-radius: 5px;
  justify-content: center;
  gap: 0;
  overflow: hidden;
  transition: width 0.16s, padding 0.16s, background 0.12s, border-color 0.12s, box-shadow 0.12s;
}
.patches-strip-bank .patch-cat-tab.active {
  width: auto;
  min-width: 78px;
  max-width: 150px;
  padding: 0 9px;
  flex-direction: row;
  gap: 6px;
}
.patches-strip-bank .patch-cat-tab.active .pct-label {
  max-width: 96px;
  opacity: 1;
  color: #15803d;
}

/* Preset grid — single horizontal scrollable row */
.patches-strip-bank .patch-preset-grid {
  display: flex;
  flex-wrap: nowrap;
  overflow-x: auto;
  gap: 4px;
  padding: 5px 10px;
  flex: 1;
  min-height: 0;
  align-items: center;
  scrollbar-width: thin;
  scrollbar-color: rgba(0,0,0,0.10) transparent;
}
.patches-strip-bank .patch-preset-grid .preset-btn {
  height: 30px;
  max-width: 132px;
  padding: 5px 10px;
  color: rgba(26,26,46,0.52);
  overflow: hidden;
  transition: max-width 0.16s, min-width 0.16s, padding 0.16s, background 0.12s, color 0.12s, border-color 0.12s, box-shadow 0.12s;
}
.patches-strip-bank .patch-preset-grid .preset-btn .preset-btn-text {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
}
.patches-strip-bank .patch-preset-grid .preset-btn.active {
  min-width: 136px;
  max-width: 260px;
  padding-inline: 14px;
  color: #15803d;
  background: rgba(34,197,94,0.14);
  border-color: rgba(34,197,94,0.72);
  text-shadow: none;
}

.patches-strip-user {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border-left: 1px solid var(--border);
  flex-shrink: 0;
}

/* ══════════════════════════════════════════════════════════
   VPC PANEL  —  flat single-row voice knobs (no patches column)
══════════════════════════════════════════════════════════ */
.vpc-panel {
  overflow-x: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(0,0,0,0.08) transparent;
}

.vpc-voice-flat {
  display: flex;
  align-items: center;
  gap: 0;
  padding: 5px 12px;
  min-width: max-content;
}

/* Inline group: label + knobs */
.vpc-group-inline {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0 10px;
}
.vpc-group-inline:first-child { padding-left: 0; }

/* Rotated group label */
.vpc-gi-lbl {
  font-size: 10px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  font-family: 'DM Mono', monospace;
  writing-mode: vertical-lr;
  transform: rotate(180deg);
  flex-shrink: 0;
  line-height: 1;
  margin-right: 1px;
}
.vpc-gi-lbl.vpc-env-lbl { color: #22c55e; }
.vpc-gi-lbl.vpc-flt-lbl { color: #6366f1; }
.vpc-gi-lbl.vpc-chr-lbl { color: #e67e22; }
.vpc-gi-lbl.vpc-pb-lbl  { color: #8b5cf6; }

/* Thin vertical divider between groups */
.vpc-gi-div {
  width: 1px;
  height: 44px;
  background: linear-gradient(180deg, transparent, var(--border), transparent);
  flex-shrink: 0;
}

/* Knob sizes in the flat voice row */
.vpc-voice-flat .knob-wrap svg {
  width: 52px;
  height: 52px;
}
.vpc-voice-flat .knob-label {
  font-size: 11px;
  letter-spacing: 1.5px;
}

/* Pills go horizontal in the flat row */
.vpc-voice-flat .vpc-playback-pills {
  flex-direction: row;
  gap: 3px;
  margin-left: 4px;
}

/* ── Group mini-viewer canvases — inline beside each knob group */
.grp-mini-canvas {
  width: 88px;
  height: 44px;
  flex-shrink: 0;
  align-self: center;
  margin-left: 4px;
  background: #060e06;
  border: 1px solid rgba(68,255,136,0.12);
  border-radius: 2px;
  box-shadow: inset 0 0 6px rgba(0,0,0,0.5);
  cursor: pointer;
  position: relative;
}

.mini-badge {
  position: absolute;
  top: 2px;
  right: 3px;
  font-family: 'Share Tech Mono', monospace;
  font-size: 5px;
  padding: 1px 3px;
  border-radius: 2px;
  pointer-events: none;
  z-index: 5;
  letter-spacing: 0.3px;
}

.mini-badge.t-mode {
  color: rgba(68,255,136,0.40);
  border: 1px solid rgba(68,255,136,0.18);
}

.mini-badge.d-mode {
  color: rgba(255,215,55,0.55);
  border: 1px solid rgba(255,215,55,0.25);
  animation: badge-pulse 2s ease-in-out infinite;
}

@keyframes badge-pulse {
  0%,100% { opacity: 0.6; }
  50% { opacity: 1; }
}

/* ══════════════════════════════════════════════════════════
   CIRCLE OF FIFTHS SIDEBAR
   Lives as the leftmost column of the playing surface
══════════════════════════════════════════════════════════ */
.circle-panel {
  width: 220px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 6px;
  padding: 10px 8px;
  overflow-y: auto;
  overflow-x: hidden;
  border-right: 1px solid rgba(34,197,94,0.18);
  background: var(--panel-light);
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.018'/%3E%3C/svg%3E");
}

/* ── Relative major/minor display ────────────────────────── */
.rel-display {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  margin-top: 2px;
}
.rel-row {
  display: flex;
  align-items: baseline;
  gap: 4px;
  font-family: 'DM Mono', monospace;
  font-size: 12px;
  color: rgba(68,255,136,0.65);
  letter-spacing: 0.02em;
  line-height: 1.2;
}
.rel-sym {
  font-size: 9px;
  color: rgba(68,255,136,0.5);
}
.rel-lbl {
  font-size: 9px;
  color: rgba(68,255,136,0.5);
}
#relMaj, #relMin {
  font-size: 14px;
  font-weight: 700;
  color: rgba(68,255,136,0.88);
}

/* ── Desktop: hide mobile-only elements (must come BEFORE media blocks so media can override) */
.patches-always-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px;
  height: 36px;
  flex-shrink: 0;
  overflow: hidden;
}
.patches-sound-lbl { flex-shrink: 0; }
.patches-always-vdiv { width: 1px; height: 22px; background: var(--border); flex-shrink: 0; margin: 0 2px; }
.patches-always-row > .patch-user-slots { flex: 1; min-width: 0; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
.patches-always-row > .patch-user-slots::-webkit-scrollbar { display: none; }

/* Instrument rotary dial */
.inst-rotary {
  display: flex;
  align-items: center;
  gap: 1px;
  background: rgba(0,0,0,0.22);
  border: 1px solid rgba(255,255,255,0.07);
  border-radius: 5px;
  padding: 2px 2px;
  flex-shrink: 0;
}
.inst-rotary-adj {
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  background: none;
  border: none;
  border-radius: 3px;
  cursor: pointer;
  opacity: 0.45;
  transition: opacity 0.15s, background 0.15s;
  flex-shrink: 0;
  padding: 0;
  color: inherit;
}
.inst-rotary-adj:hover { opacity: 1; background: rgba(255,255,255,0.10); }
.inst-rotary-center {
  display: flex;
  align-items: center;
  gap: 5px;
  cursor: pointer;
  padding: 2px 7px;
  border-radius: 3px;
  user-select: none;
  min-width: 0;
}
.inst-rotary-center:hover { background: rgba(255,255,255,0.06); }
.inst-rotary-cat { font-size: 14px; flex-shrink: 0; }
.inst-rotary-center #patchesSummaryName {
  font-family: 'Share Tech Mono', monospace;
  font-size: 11px;
  font-weight: 600;
  color: var(--engrave);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* FIXED width (not max-width): the rotary is flex-shrink:0, so a content-sized
     name field makes the whole dial widen/narrow as you change instruments,
     shoving the quick-select and the ◀🎲▶ preset nav sideways. Pinning the name
     to a constant width keeps the random button anchored in place. */
  width: 108px;
  text-align: center;
  flex: none;
}
.patch-quick-select {
  flex: 0 1 220px;
  min-width: 150px;
  max-width: 280px;
  height: 26px;
  padding: 0 26px 0 10px;
  border: 1px solid rgba(0,0,0,0.16);
  border-radius: 5px;
  background:
    linear-gradient(45deg, transparent 50%, rgba(26,26,46,0.55) 50%) calc(100% - 14px) 10px / 5px 5px no-repeat,
    linear-gradient(135deg, rgba(26,26,46,0.55) 50%, transparent 50%) calc(100% - 9px) 10px / 5px 5px no-repeat,
    rgba(255,255,255,0.72);
  color: var(--engrave);
  font-family: 'DM Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}
.patch-quick-select:hover,
.patch-quick-select:focus {
  outline: none;
  border-color: rgba(34,197,94,0.55);
  box-shadow: 0 0 0 2px rgba(34,197,94,0.08);
}

/* ── Preset navigator (◀ / 🎲 / ▶) ──────────────────────────────────────────
   Desktop patches-strip variant: light, matches .patch-quick-select. */
.preset-nav { display: flex; gap: 4px; align-items: center; }
.preset-nav-btn {
  height: 26px; min-width: 28px; padding: 0 7px;
  font-size: 12px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  background: var(--panel-light, #fff);
  color: var(--engrave, #1a1a2e);
  border: 1px solid rgba(0,0,0,0.16);
  border-radius: 5px; cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
.preset-nav-btn:hover  { border-color: rgba(0,0,0,0.40); background: rgba(0,0,0,0.04); }
.preset-nav-btn:active { transform: scale(0.88); }
.preset-nav-btn { transition: transform 90ms ease, background 120ms ease, border-color 120ms ease; }
.preset-nav-rand { font-size: 14px; }
.preset-nav-rand.spinning { animation: presetDiceSpin 420ms cubic-bezier(.3,.7,.3,1); }
@keyframes presetDiceSpin { from { transform: rotate(0deg) scale(1); } 60% { transform: rotate(340deg) scale(1.18); } to { transform: rotate(360deg) scale(1); } }

/* Transient preset-name overlay (animation handled in JS via WAAPI). */
#presetToast {
  position: fixed;
  top: 22vh; left: 50%;
  transform: translate(-50%, 0);
  z-index: 1200;
  display: none;
  pointer-events: none;
  background: rgba(8,18,10,0.94);
  color: var(--phos-fg, #39ff14);
  font-family: 'DM Mono', monospace;
  font-size: 18px; font-weight: 500; letter-spacing: 0.5px;
  padding: 11px 22px;
  border: 1px solid var(--phos-fg, #39ff14);
  border-radius: 12px;
  box-shadow: 0 6px 26px rgba(0,0,0,0.32), 0 0 0 4px rgba(57,255,20,0.06);
  max-width: 80vw; text-align: center; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
/* Mobile instrument-header variant: dark/phosphor to match .hs-sound-select. Compact,
   INLINE on the same row as the two selects (the grandparent .hs-left is a fixed-height
   single-row container, so a wrapped row would overflow + get painted over). The category
   select is narrowed and the instrument select shrinks (min-width:0) to make room. */
.hs-sound-selects .preset-nav { flex: 0 0 auto; gap: 4px; }
.hs-sound-selects .preset-nav-btn {
  flex: 0 0 auto; min-width: 30px; padding: 0 6px; font-size: 14px;
  align-self: stretch;
  background: #08120a; color: var(--phos-fg, #39ff14);
  border: 1px solid var(--border2); border-radius: 6px;
}
.hs-sound-selects .preset-nav-btn:hover { border-color: var(--phos-fg, #39ff14); background: #0c1a0e; }
.patches-expand-btn {
  margin-left: auto;
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px 8px;
  color: var(--engrave-dim);
  font-size: 11px;
  border-radius: 4px;
  flex-shrink: 0;
  transition: background 0.15s, color 0.15s;
}
.patches-expand-btn:hover { background: rgba(255,255,255,0.08); color: var(--engrave); }
.vpc-panel-header       { display: flex; align-items: center; gap: 10px; padding: 0 14px; height: 28px; cursor: pointer; user-select: none; border-bottom: 1px solid var(--border); flex-shrink: 0; }
.circle-panel-summary   { display: none; }
.mobile-circle-selects  { display: none; }

/* ── Circle panel summary (mobile toggle header) ─────────── */
.circle-panel-summary {
  align-items: center;
  gap: 10px;
  padding: 0 14px;
  height: 40px;
  cursor: default;
  width: 100%;
  flex-shrink: 0;
  background: var(--panel-light);
  border-top: 2px solid rgba(34,197,94,0.25);
  border-bottom: 1px solid rgba(34,197,94,0.15);
  box-sizing: border-box;
}
.circle-summary-text {
  flex: 1;
  font-family: 'Share Tech Mono', monospace;
  font-size: 14px;
  font-weight: 700;
  color: var(--engrave);
}
.circle-panel-chevron { font-size: 13px; color: var(--engrave); }

/* ── Mobile mode toggle (Scale / Free) inside circle summary ── */
.mob-mode-toggle { display: none; }
@media (max-width: 430px) {
  .mob-mode-toggle {
    display: flex;
    gap: 3px;
    flex-shrink: 0;
  }
  .mob-mode-btn {
    font-family: 'DM Mono', monospace;
    font-size: 8px;
    letter-spacing: 1px;
    text-transform: uppercase;
    padding: 4px 6px;
    border-radius: 4px;
    border: 1px solid rgba(34,197,94,0.3);
    background: transparent;
    color: rgba(200,181,154,0.6);
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    white-space: nowrap;
  }
  .mob-mode-btn.active {
    background: #22c55e;
    border-color: #22c55e;
    color: #fff;
    box-shadow: 0 0 6px rgba(34,197,94,0.4);
  }
}

/* ── Mobile overrides ────────────────────────────────────── */
@media (max-width: 700px) {
  .header-strip {
    height: auto;
    flex-direction: column;
    align-items: stretch;
  }
  .hs-left    { max-width: 100%; min-width: 0; box-sizing: border-box; flex-direction: row; align-items: center; padding: 8px 12px 4px; gap: 10px; }
  .hs-pills   { flex-direction: row; }
  .hs-vdiv    { display: none; }
  /* Hide the top-left ROOT/SCALE readout on mobile — the Key/Scale selectors
     (.mobile-circle-selects) below cover the same function. */
  .hs-display { display: none; }
  /* MODE stays on the playing surface but as a compact horizontal segmented
     control (the OCT/VOL, Key/Scale, patches and Info/Teach all move into the
     Studio drawer on mobile via _studioPanelEls). */
  .hs-mode    { flex-direction: row; align-items: center; gap: 8px; padding: 6px 12px; }
  .hs-mode .toggle-vertical { flex-direction: row; flex: 1; }
  .hs-mode .toggle-vertical .toggle-option { flex: 1; }

  /* Static Category + Instrument dropdowns live in the top header space. */
  .hs-left { flex-wrap: wrap; }
  /* Horizontally scrollable: if the selects + nav don't fit the phone width, swipe the row
     left/right to reach everything (nothing gets clipped off-screen). Children don't shrink
     below usable widths — they overflow and scroll instead. */
  .hs-sound-selects {
    display: flex; gap: 5px; flex: 1 1 100%; margin-top: 4px;
    /* min-width:0 is REQUIRED: without it the non-shrinking children below
       (cat 104 + instr 150 + nav + FX ≈ 401px) become this flex item's
       min-content width, which propagates up through .hs-left → .header-strip
       → body and overflows the whole PAGE horizontally on any phone < ~400px
       (every row gets clipped on the right). With min-width:0 the item can be
       narrower than its content, so overflow-x scrolls the row internally and
       the page stays at viewport width. */
    min-width: 0; max-width: 100%;
    overflow-x: auto; overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .hs-sound-selects::-webkit-scrollbar { display: none; }
  .hs-sound-select {
    display: block;
    flex: 1 1 0;
    min-width: 0;
    font-family: 'DM Mono', monospace;
    font-size: 14px;
    padding: 8px 30px 8px 10px;
    background-color: #08120a;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2339ff14' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
    background-repeat: no-repeat;
    background-position: right 9px center;
    color: var(--phos-fg, #39ff14);
    border: 1px solid var(--border2);
    border-radius: 6px;
    -webkit-appearance: none;
    appearance: none;
  }
  /* Category fixed-narrow; instrument grows to fill but may shrink (truncating its
     label with the native ellipsis) down to a still-readable 64px so the whole row
     — cat + instrument + ◀🎲▶ nav + FX — FITS a 375–430px phone without scrolling.
     overflow-x (above) remains only as a last-resort fallback for ultra-narrow screens. */
  .hs-cat-select   { flex: 0 0 92px; }
  /* Instrument fills leftover space but shrinks freely and truncates its label
     (native single-line ellipsis) so cat + instrument + ◀🎲▶ + FX always fit the
     screen — the long names just get cut with "…" instead of widening the page. */
  .hs-instr-select { flex: 1 1 60px; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .hs-params  { padding: 4px 12px; }
  /* Hide the big waveform/spectrum scope on mobile — purely decorative and
     eats a lot of vertical space on a phone. (Was only hidden <430px before.) */
  .hs-wave    { display: none; }

  .circle-panel {
    width: 100%;
    border-right: none;
    border-bottom: 1px solid rgba(34,197,94,0.18);
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    padding: 0;
    height: auto;
    gap: 0;
  }
  .circle-panel-desktop-label { display: none; }

  /* Mobile: hide canvas drum-roller; show dropdown selects instead */
  .circle-panel #circleCanvas { display: none; }
  .circle-panel .rel-display  { display: none; }
  .mobile-circle-selects {
    display: flex;
    flex-direction: row;
    gap: 10px;
    padding: 10px 14px;
    width: 100%;
    box-sizing: border-box;
  }
  .mob-sel-group {
    display: flex;
    flex-direction: column;
    flex: 1;
    gap: 4px;
  }
  .mob-sel-label {
    font-family: 'DM Mono', monospace;
    font-size: 8px;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: rgba(68,255,136,0.45);
  }
  .mob-select {
    background-color: #151518;
    /* chevron so it's obvious these are tappable dropdowns (appearance:none
       strips the native arrow). */
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2344ff88' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
    background-repeat: no-repeat;
    background-position: right 12px center;
    color: var(--phos-on-light);
    border: 1px solid rgba(12,122,50,0.32);
    border-radius: 6px;
    font-family: 'DM Mono', monospace;
    font-size: 15px;
    font-weight: 700;
    padding: 10px 36px;
    width: 100%;
    box-sizing: border-box;
    -webkit-appearance: none;
    appearance: none;
    cursor: pointer;
    text-align: center;
    text-align-last: center;
  }
  .mob-select:focus { outline: none; border-color: rgba(68,255,136,0.55); }

  /* Keyboard shortcut hints — useless on touch devices */
  .kbd-hint { display: none; }

  /* Patches scroll: contain within viewport, let inner grid scroll */
  .patches-strip { height: auto; flex-wrap: wrap; overflow: hidden; max-width: 100vw; }
  .patches-strip-bank { flex-direction: column; overflow: hidden; width: 100%; min-width: 0; }
  #patchesStripBody { width: 100%; height: 128px; overflow: hidden; }
  #patchesStripBody.qa-open .patches-strip-bank { min-height: 128px; flex-basis: 128px; }
  .patch-tools-row { height: 40px; overflow-x: auto; -webkit-overflow-scrolling: touch; touch-action: pan-x; }
  .patch-search-input { width: 140px; flex-basis: 140px; }
  .patch-browser-main { flex-direction: column; }
  .patches-strip-bank .patch-cat-tabs { max-width: none; border-right: none; border-bottom: 1px solid var(--border); overflow-x: auto; -webkit-overflow-scrolling: touch; touch-action: pan-x; }
  .patch-cat-family-label { writing-mode: horizontal-tb; transform: none; }
  .patches-strip-bank .patch-preset-grid { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; touch-action: pan-x; width: 100%; }

  /* ── Instrument rotary: large tap targets on mobile ─────── */
  .inst-rotary-adj {
    width: 44px;
    height: 44px;
    font-size: 20px;
    opacity: 0.75;
  }
  .inst-rotary {
    gap: 0;
  }

  /* ── Patches: always-visible row (mobile) ──────────────── */
  .patches-always-row {
    height: 52px;
    padding: 0 12px;
    gap: 8px;
    overflow-x: auto;
    overflow-y: visible;            /* was overflow:hidden — that clipped everything past the edge */
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    border-top: 2px solid rgba(34,197,94,0.35);
    border-bottom: 2px solid rgba(34,197,94,0.35);
    flex-shrink: 0;
  }
  .patches-always-row::-webkit-scrollbar { display: none; }
  /* Instrument picker now lives in the notes panel (Option A) — drop the
     duplicate rotary + quick-select from the top strip on mobile. The ▶ expand
     button still opens the full preset browser, and saved patches/Save/WT stay. */
  .inst-rotary,
  .patch-quick-select,
  .patches-always-vdiv { display: none; }
  .patches-always-row .engrave-label {
    font-size: 11px;
    letter-spacing: 2px;
    color: var(--engrave-dim);
  }
	  .inst-rotary-center #patchesSummaryName {
	    font-size: 13px;
	    font-weight: 700;
	    max-width: 110px;
	    flex: none;
	  }
  .patch-quick-select {
    flex: 0 0 170px;
    min-width: 150px;
    max-width: 170px;
    height: 34px;
    font-size: 11px;
  }
  .qa-inline { display: none; }   /* QA loudness lab is a desktop tuning tool — reclaim ~250px on phones */
  .qa-toggle-btn,
  .qa-action-btn {
    height: 28px;
  }
  #patchesSummaryChevron { font-size: 14px; color: var(--engrave); }

  /* Full sound browser as a slide-up bottom sheet on phones (was display:none). */
  #patchesStripBody {
    display: none;            /* collapsed default; togglePatchesStrip() sets inline flex to open */
    position: fixed; left: 0; right: 0; bottom: 0; top: auto;
    z-index: 1200;
    width: 100%; height: auto; max-height: 76vh;
    flex-direction: column;
    overflow-x: hidden; overflow-y: auto;
    background: #08120a;
    border-top: 2px solid rgba(34,197,94,0.55);
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -16px 48px rgba(0,0,0,0.7);
    padding-bottom: calc(env(safe-area-inset-bottom) + 10px);
  }
  #patchesStripBody::before {
    content: ''; display: block; flex: none;
    width: 44px; height: 5px; margin: 8px auto 4px;
    border-radius: 3px; background: rgba(124,255,176,0.4);
  }
  #patchesStripBody, #patchesStripBody * { box-sizing: border-box; }
  #patchesStripBody .patches-strip-bank,
  #patchesStripBody .patch-browser-main,
  #patchesStripBody .patch-preset-grid {
    width: 100% !important; max-width: 100% !important; min-width: 0 !important;
  }
  #patchesStripBody .patch-preset-grid {
    flex-wrap: wrap !important; flex-direction: row !important;
    overflow-x: hidden !important; gap: 7px; padding: 8px;
  }
  #patchesStripBody .patch-preset-grid .preset-btn {
    flex: 0 0 calc(50% - 4px) !important; width: calc(50% - 4px) !important;
    max-width: calc(50% - 4px) !important; min-width: 0 !important;
    min-height: 44px; font-size: 13px; box-sizing: border-box;
  }
  .patch-tools-row { position: sticky; top: 0; background: #08120a; z-index: 2; height: auto; padding: 8px; }
  .patch-search-input { width: 100%; flex-basis: auto; font-size: 16px; height: 42px; }

  /* ── VPC: always visible on mobile (knobs need to init visible) */
  .vpc-voice-flat { flex-wrap: wrap; gap: 4px; min-width: unset; }
  .vpc-group-inline { padding: 4px 6px; }
  .vpc-gi-div { display: none; }
  .grp-mini-canvas { display: none; }

  /* ── Playing surface: stack vertically so chord keys are visible */
  .playing-surface { flex: none; height: auto; flex-direction: column; }
  .play-left  { flex: none; height: auto; border-right: none; border-bottom: 2px solid rgba(34,197,94,0.20); }
  .play-right { width: 100%; flex-shrink: 0; height: auto; max-height: 260px; overflow-y: auto; border-left: none; border-top: 2px solid rgba(99,102,241,0.30); }

  /* ── Zone banners: slim, no subtitle ──────────────────── */
  .zone-banner { padding: 2px 8px; min-height: 0; }
  .zone-sub    { display: none; }
  .panel-divider { height: 28px; }

  /* ── Scale + octave rows: 4×2 grid — all 8 keys visible ───
     The octave rows must use the grid too: with touch-action:none + pointer
     capture on each pad, a horizontal-scroll row would strand keys 5-8
     off-screen and unreachable in scale (Locked) mode. The grid removes the
     scroller so every key is on-screen. */
  .chord-section { height: auto; padding: 5px 6px; }
  #scaleRow, #oct2Row, #oct3Row, #oct4Row,
  #freeRow1, #freeRow2, #freeRow3, #freeRow4 {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 4px;
    overflow: visible;
    flex: none;
  }
  #scaleRow .key, #oct2Row .key, #oct3Row .key, #oct4Row .key,
  #freeRow1 .key, #freeRow2 .key, #freeRow3 .key, #freeRow4 .key { min-width: 0; flex: none; height: 120px; }

  /* Octave 1 (scaleRow) uses the full chord-key, which shows an oscilloscope
     canvas in Locked mode (desktop flourish, 68px). On the 120px mobile grid
     that eats the keycap + note name, making Octave 1 look broken vs the simple
     Octave 2-4 cards. Hide the canvas on mobile so all octaves render alike. */
  body.mode-locked #scaleRow .key-osc-canvas { display: none; }

  /* ── Looper bottom bar: stack control groups into clean labeled rows with
     finger-sized targets instead of the dense desktop wrap. ─────────────── */
  .looper-bottom-bar { flex-direction: column; align-items: stretch; gap: 10px; padding: 10px; row-gap: 10px; }
  .lbb-sep, .lbb-push { display: none; }
  .lbb-group { flex-wrap: wrap; width: 100%; gap: 6px; align-items: stretch; }
  .lbb-label { width: 100%; font-size: 11px; letter-spacing: 2px; margin: 0 0 2px; }
  .looper-bottom-bar .looper-btn,
  .looper-bottom-bar .looper-tool-btn,
  .looper-bottom-bar .lbb-snap-btn {
    flex: 1 1 auto; min-width: 60px; min-height: 44px;
    font-size: 14px; padding: 10px 8px; border-radius: 8px;
  }
  .looper-bpm-input, .looper-timesig-sel { min-height: 44px; font-size: 15px; flex: 1 1 auto; }
  .looper-status { width: 100%; text-align: center; min-height: 40px; display: flex; align-items: center; justify-content: center; }

  /* ── Ext row: 4 keys fill without scrolling ───────────── */
  .ext-section { height: auto; padding: 4px 6px; }
  #extRow { overflow: visible; }
  #extRow .ext-key { flex: 1; min-width: 0; height: 80px; }

  /* ── Keys: hide mini-knobs (too cramped at mobile widths) */
  .key .mini-knob-slot { display: none; }

  /* ── Keys: tighter text ────────────────────────────────── */
  .key-mood       { font-size: 9px; letter-spacing: 1px; margin-top: 3px; }
  .key-chord-name { font-size: 22px; }
  .key-roman      { font-size: 9px; }
  .key-shortcut   { display: none; }
  .ext-key .key-chord-name { font-size: 17px; }
}


/* ══════════════════════════════════════════════════════════
   PHONE PORTRAIT  ·  ≤430px
══════════════════════════════════════════════════════════ */
@media (max-width: 430px) {

  /* ── Body: let content determine height, page scrolls ── */
  body { height: auto; min-height: 100dvh; }

  /* ── Touch targets ──────────────────────────────────── */
  .qual-key        { min-height: 48px; }
  .qual-family-hdr { min-height: 32px; padding: 4px 2px; }
  .panel-divider   { height: 40px; }
  .hs-params .knob-wrap svg          { width: 44px !important; height: 44px !important; }
  .vpc-voice-flat .knob-wrap svg     { width: 44px !important; height: 44px !important; }

  /* ── Header: single compact row ─────────────────────── */
  .header-strip {
    flex-direction: row;
    height: 52px;
    flex-wrap: nowrap;
    overflow: visible;
  }
  .hs-left .brand-name { display: none; }
  .hs-mode             { display: none; }
  .hs-params           { display: none; }
  .hs-wave             { display: none; }
  .hs-display          { flex: 1; min-width: 0; }
  .hs-display .phosphor-display { min-width: 0; }


  /* ── Playing surface: natural height, page scrolls ────── */
  .playing-surface { flex: none; height: auto; flex-direction: column; }

  /* circle: always shown — summary bar has mode toggle */
  .circle-panel { height: auto; }
  .circle-panel-summary { display: flex; cursor: default; }
  #circlePanelBody { display: block; }

  /* chord keys: auto height */
  .play-left { flex: none; height: auto; border-right: none; border-bottom: 2px solid rgba(34,197,94,0.20); }

  /* quality grid: full width, scrollable */
  .play-right {
    width: 100%;
    flex-shrink: 0;
    height: auto;
    max-height: 260px;
    overflow-y: auto;
    overflow-x: hidden;
    border-left: none;
    border-top: 2px solid rgba(99,102,241,0.30);
    scrollbar-width: thin;
  }
  /* Prevent scrollbar from clipping 5th column */
  .quality-panel { padding-right: 4px; }

  /* ── Zone banners: slim down, hide subtitle ─────────── */
  .zone-banner { padding: 2px 8px; min-height: 0; }
  .zone-sub    { display: none; }

  /* ── Master volume: show as small pill in header ───── */
  .hs-params { display: flex; }
  .hs-params .hs-param-item:first-child { display: none; }  /* hide Oct knob */
  .hs-params .engrave-label { display: none; }
  .hs-params .knob-wrap svg { width: 36px !important; height: 36px !important; }

  /* ── VPC momentum scroll on iOS ─────────────────────── */
  #vpcVoiceFlat { -webkit-overflow-scrolling: touch; }

  /* ── Teach panel: don't overflow narrow screens ──────── */
  .teach-panel { width: calc(100vw - 24px); right: 12px; left: 12px; }
}

/* ── Touch drag ghost element ──────────────────────────────── */
.touch-drag-ghost {
  position: fixed;
  z-index: 9999;
  pointer-events: none;
  padding: 5px 12px;
  background: rgba(var(--qrgb), 0.92);
  border: 1px solid rgba(255,255,255,0.25);
  border-radius: 8px;
  font-family: 'DM Mono', monospace;
  font-size: 12px;
  font-weight: 700;
  color: #fff;
  letter-spacing: 1px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.5);
  transform: scale(1.08);
  white-space: nowrap;
}

/* ── Inline voicing controls — inside each key ───────────────── */
/* Solid dark panel — always contrasts with any key colour */
.key-voice-panel {
  margin: 6px 4px 2px;
  background: #080e08;
  border-radius: 5px;
  border: 1px solid rgba(68,255,136,0.22);
  padding: 5px 4px 4px;
  /* Hidden by default — voicing lives behind the ✎ editor for clean keys.
     "Quick Chording" mode brings the inline controls back. */
  display: none;
  flex-direction: column;
  gap: 4px;
}
body.quick-chording .key-voice-panel { display: flex; }
body.quick-chording .ext-key .key-voice-panel,
body.quick-chording.mode-locked .key-voice-panel { display: none; }

.key-voice-tones,
.key-voice-exts {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
  justify-content: center;
  width: 100%;
  box-sizing: border-box;
}
.key-voice-exts {
  padding-top: 4px;
  border-top: 1px solid rgba(68,255,136,0.12);
}

/* Base pill */
.key-vp-btn {
  font-family: 'Share Tech Mono', monospace;
  font-size: 10px;
  letter-spacing: 0;
  padding: 3px 6px;
  border-radius: 3px;
  border: 1px solid rgba(68,255,136,0.25);
  background: rgba(8,14,8,0.0);
  color: rgba(68,255,136,0.45);
  cursor: pointer;
  transition: all 0.1s;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
  line-height: 1.2;
  white-space: nowrap;
}
.key-vp-btn.on {
  border-color: rgba(12,122,50,0.7);
  color: var(--phos-on-light);
  background: rgba(68,255,136,0.14);
  box-shadow: 0 0 6px rgba(68,255,136,0.25);
}
.key-vp-btn.off {
  border-color: rgba(68,255,136,0.12);
  color: rgba(68,255,136,0.3);
  text-decoration: line-through;
}
/* OMIT row — same green palette, full brightness when active */
.key-vp-btn.key-vp-omit.on  { border-color: rgba(12,122,50,0.7); color: var(--phos-on-light); background: rgba(68,255,136,0.16); }
.key-vp-btn.key-vp-omit.off { border-color: rgba(68,255,136,0.15); color: rgba(68,255,136,0.35); text-decoration: line-through; }
/* Structural tone (built into extension chord) — amber, non-interactive */
.key-vp-btn.key-vp-structural { border-color: rgba(251,191,36,0.65); color: rgba(251,191,36,0.9); background: rgba(251,191,36,0.09); cursor: default; }

/* ADD/extension pill — indigo accent */
.key-vp-btn.key-vp-ext {
  border-color: rgba(99,102,241,0.3);
  color: rgba(160,163,255,0.5);
}
.key-vp-btn.key-vp-ext.on {
  border-color: rgba(99,102,241,0.85);
  color: #c4c6ff;
  background: rgba(99,102,241,0.16);
  box-shadow: 0 0 6px rgba(99,102,241,0.3);
}
/* Natural extension — fits this chord quality without being active */
.key-vp-btn.key-vp-ext.natural {
  border-color: rgba(251,191,36,0.45);
  color: rgba(251,191,36,0.75);
}
.key-vp-btn.key-vp-ext.natural.on {
  border-color: rgba(99,102,241,0.85);
  color: #c4c6ff;
  background: rgba(99,102,241,0.16);
  box-shadow: 0 0 6px rgba(99,102,241,0.3), 0 0 4px rgba(251,191,36,0.2);
}
.key-vp-btn:hover { filter: brightness(1.35); }

/* Inversion row */
.key-voice-inv {
  display: flex;
  gap: 3px;
  justify-content: center;
  width: 100%;
  box-sizing: border-box;
  padding-top: 4px;
  border-top: 1px solid rgba(68,255,136,0.12);
}
.key-vp-btn.key-vp-inv {
  border-color: rgba(68,255,136,0.18);
  color: rgba(68,255,136,0.38);
}
.key-vp-btn.key-vp-inv.active {
  border-color: rgba(12,122,50,0.8);
  color: var(--phos-on-light);
  background: rgba(68,255,136,0.14);
  box-shadow: 0 0 6px rgba(68,255,136,0.22);
}

/* Diamond dot — appears when any voicing is customised */
.key-voice-dot {
  position: absolute;
  bottom: 7px;
  left: 7px;
  width: 5px;
  height: 5px;
  background: var(--phos-fg);
  box-shadow: 0 0 5px rgba(68,255,136,0.8), 0 0 10px rgba(68,255,136,0.35);
  transform: rotate(45deg);
  opacity: 0;
  transition: opacity 0.2s;
  pointer-events: none;
  border-radius: 1px;
}
.key.voice-custom .key-voice-dot { opacity: 1; }

/* ✎ Per-key voicing-editor affordance — a deliberate tap target that opens the
   voicing sheet. Replaces the old long-press (which collided with press-and-hold
   sustain). Subtle on desktop (reveals on hover), always visible on touch. */
.key-edit-btn {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  margin: 0;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: rgba(255,255,255,0.82);
  color: var(--engrave-dim);
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 0.15s, background 0.1s, border-color 0.1s, color 0.1s;
  z-index: 4;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.key:hover .key-edit-btn { opacity: 0.95; }
/* In Quick Chording the inline controls are visible, so the ✎ recedes. */
body.quick-chording .key-edit-btn { opacity: 0; }
body.quick-chording .key:hover .key-edit-btn { opacity: 0.9; }
.key-edit-btn:hover { background: rgba(34,197,94,0.14); border-color: rgba(34,197,94,0.45); color: #15803d; }
.key-edit-btn:active { transform: scale(0.92); }
.ext-key .key-edit-btn { display: none; } /* extension keys have no inline voicing panel */
body.mode-locked .key-edit-btn { display: none; }
/* On touch, the edit affordance is the ONLY way into the voicing sheet (the old
   long-press is gone), so it's always visible and a comfortable tap target. */
@media (max-width: 700px) {
  .key-edit-btn {
    opacity: 0.92;
    width: 30px;
    height: 30px;
    top: 5px;
    right: 5px;
    font-size: 14px;
    background: rgba(255,255,255,0.9);
  }
  /* Mobile: piano + BOTH guitar voicings on a single row (scaled to fit width).
     `.cci` prefix lifts specificity above the later base `.cci-displays{column}`
     and `.cci-guitars{column}` rules. */
  .cci .cci-displays { flex-direction: row; flex-wrap: nowrap; align-items: center; justify-content: center; gap: 8px; }
  .cci .cci-guitars { flex-direction: row; gap: 6px; }
  .cci-piano  svg { width: 116px; height: auto; }
  .cci-guitar svg { width: 92px;  height: auto; }
}

/* ── Mobile bottom sheet (long-press) ────────────────────────── */
.voc-editor-inner {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.voc-editor-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.voc-editor-title {
  font-family: 'Share Tech Mono', monospace;
  font-size: 9px;
  letter-spacing: 3px;
  color: var(--phos-dim);
  text-transform: uppercase;
  flex: 1;
}
.voc-editor-base {
  font-family: 'Share Tech Mono', monospace;
  font-size: 9px;
  letter-spacing: 2px;
  color: rgba(34,153,58,0.65);
}
.voc-editor-btn {
  background: transparent;
  border: 1px solid rgba(68,255,136,0.25);
  border-radius: 3px;
  color: var(--phos-dim);
  font-family: 'Share Tech Mono', monospace;
  font-size: 9px;
  letter-spacing: 1px;
  padding: 3px 7px;
  cursor: pointer;
  transition: all 0.12s;
}
.voc-editor-btn:hover { color: var(--phos-on-light); border-color: rgba(12,122,50,0.5); }
.voc-editor-section-label {
  font-family: 'Share Tech Mono', monospace;
  font-size: 8px;
  letter-spacing: 2px;
  color: rgba(34,153,58,0.5);
  text-transform: uppercase;
  margin-bottom: 4px;
}
.voc-editor-row { display: flex; flex-wrap: wrap; gap: 5px; }
.voc-editor-hint {
  font-family: 'Share Tech Mono', monospace;
  font-size: 9px;
  color: rgba(34,153,58,0.4);
}
.voice-editor-sheet-backdrop {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.4);
  z-index: 590;
}
.voice-editor-sheet {
  position: fixed; bottom: 0; left: 0; right: 0;
  background: var(--phos-bg);
  border-top: 1px solid rgba(68,255,136,0.35);
  border-radius: 10px 10px 0 0;
  padding: 8px 20px 28px;
  box-shadow: 0 -4px 40px rgba(68,255,136,0.12);
  z-index: 600;
  transform: translateY(100%);
  transition: transform 0.22s ease;
}
.voice-editor-sheet.open { transform: translateY(0); }
.voice-editor-sheet-handle {
  width: 36px; height: 4px;
  background: rgba(68,255,136,0.25);
  border-radius: 2px;
  margin: 0 auto 12px;
}
/* Sheet reuses larger voc-tone-btn size */
.voice-editor-sheet .voc-tone-btn {
  min-width: 48px; height: 48px;
  font-family: 'Share Tech Mono', monospace;
  font-size: 11px;
  border: 1px solid rgba(68,255,136,0.2);
  border-radius: 4px;
  background: transparent;
  color: var(--phos-dim);
  cursor: pointer;
  touch-action: manipulation;
}
.voice-editor-sheet .voc-tone-btn.on  { border-color: rgba(12,122,50,0.6); color: var(--phos-on-light); background: rgba(68,255,136,0.10); }
.voice-editor-sheet .voc-tone-btn.off { border-color: rgba(68,255,136,0.1); color: rgba(34,153,58,0.3); text-decoration: line-through; }

/* ── Inline chord inspector (circle panel) ──────────────────────────────── */
.cci {
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  font-family: 'Share Tech Mono', monospace;
  background: #f5f6f2;
  border-radius: 8px;
  border: 1px solid rgba(0,0,0,0.10);
  padding: 8px 6px 10px;
  box-sizing: border-box;
}
.cci-divider {
  width: 80%;
  height: 1px;
  background: rgba(0,0,0,0.10);
  margin: 2px 0 4px;
}
.cci-name-row {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
}
.cci-name {
  font-size: 18px;
  color: var(--engrave);
  letter-spacing: 0.5px;
}
.cci-deg {
  font-size: 10px;
  color: var(--engrave-dim);
}
.cci-lbl {
  font-size: 7px;
  letter-spacing: 2px;
  color: rgba(0,0,0,0.35);
  align-self: flex-start;
  margin-top: 2px;
}
/* Option A: compact instrument selector inside the notes panel, synced with the
   top patch quick-select via populatePatchQuickSelect() + applyPreset(). */
.cci-sound-select {
  margin-left: auto;
  flex: 1 1 60px;
  min-width: 0;
  max-width: 150px;
  font-family: 'DM Mono', monospace;
  font-size: 10.5px;
  color: var(--engrave);
  background: var(--panel-light);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 3px 6px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.cci-sound-select:focus { outline: none; border-color: rgba(34,197,94,0.55); }
.cci-sound-select option,
.cci-sound-select optgroup { background: #ffffff; color: var(--engrave); }
/* Stacked by default (safe in the narrow desktop TUNE column); piano + guitar go
   side by side on mobile (full-width) to conserve vertical space — see @media. */
.cci-displays {
  display: flex;
  flex-direction: column;
  gap: 10px;
  justify-content: center;
  align-items: center;
  width: 100%;
  max-width: 100%;
}
.cci-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  min-width: 0;
}
.cci-col .cci-lbl { align-self: center; margin-top: 0; }
.cci-guitars {
  display: flex;
  flex-direction: column;   /* stack the two voicings so the guitar column stays narrow beside the piano */
  gap: 6px;
  align-items: center;
}
.cci-piano svg,
.cci-guitar svg { display: block; }

/* Collapse toggle — hide the note diagrams, keep just the chord name + instrument selector. */
.cci-collapse-btn {
  flex: none;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--engrave-dim);
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  transition: transform 0.18s, color 0.12s, border-color 0.12s;
}
.cci-collapse-btn:hover { border-color: rgba(34,197,94,0.45); color: #15803d; }
.cci.notes-collapsed .cci-collapse-btn { transform: rotate(-90deg); }
.cci.notes-collapsed .cci-displays,
.cci.notes-collapsed .cci-divider { display: none; }
.cci.notes-collapsed { padding-bottom: 8px; gap: 0; }

/* Quick Chording toggle — show/hide the inline per-key voicing controls. */
.qc-toggle {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: 'Share Tech Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--engrave-dim);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 3px 9px;
  height: 20px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  transition: color 0.12s, border-color 0.12s, background 0.12s;
}
.qc-toggle:hover { border-color: var(--engrave-dim); color: var(--engrave); }
.qc-pip {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex: none;
  background: rgba(0,0,0,0.10);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.12);
  transition: background 0.15s, box-shadow 0.15s;
}
body.quick-chording .qc-toggle {
  color: #15803d;
  border-color: rgba(34,197,94,0.40);
  background: rgba(34,197,94,0.08);
}
body.quick-chording .qc-pip {
  background: #22c55e;
  box-shadow: 0 0 6px rgba(34,197,94,0.45);
}

/* ══════════════════════════════════════════════════════════
   SNAPSHOTS STRIP
══════════════════════════════════════════════════════════ */
.snapshots-strip {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 14px;
  background: var(--panel-light);
  border-bottom: 1px solid rgba(34,197,94,0.15);
  min-height: 36px;
  flex-shrink: 0;
  overflow: hidden;
}
.snap-hdr-lbl {
  flex-shrink: 0;
  font-size: 9px;
  letter-spacing: 2px;
  color: var(--engrave);
}
.snap-slot-row {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.snap-empty {
  font-family: 'DM Mono', monospace;
  font-size: 10px;
  color: rgba(68,255,136,0.25);
  white-space: nowrap;
}
.snap-chip {
  display: flex;
  align-items: stretch;
  gap: 0;
  border-radius: 4px;
  border: 1px solid rgba(34,197,94,0.35);
  background: rgba(34,197,94,0.06);
  flex-shrink: 0;
  overflow: hidden;
}
.snap-chip-lbl {
  font-family: 'Share Tech Mono', monospace;
  font-size: 10px;
  color: rgba(68,255,136,0.8);
  background: none;
  border: none;
  padding: 3px 7px;
  cursor: pointer;
  white-space: nowrap;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 1px;
  flex: 1;
  min-width: 0;
}
.snap-chip-lbl:hover { color: var(--phos-on-light); }
.snap-chip-name {
  display: block;
  pointer-events: none;
}
.snap-chip-key {
  display: block;
  font-size: 8px;
  color: rgba(68,255,136,0.45);
  letter-spacing: 0.5px;
  line-height: 1;
  pointer-events: none;
}
.snap-chip-lbl:hover .snap-chip-key { color: rgba(68,255,136,0.7); }
.snap-chip-over {
  font-size: 10px;
  color: rgba(68,255,136,0.3);
  background: none;
  border: none;
  border-right: 1px solid rgba(34,197,94,0.2);
  padding: 2px 6px;
  cursor: pointer;
  line-height: 1;
  flex-shrink: 0;
  display: flex;
  align-items: center;
}
.snap-chip-over:hover { color: var(--phos-on-light); background: rgba(34,197,94,0.08); }
.snap-chip-del {
  font-size: 11px;
  color: rgba(68,255,136,0.3);
  background: none;
  border: none;
  border-left: 1px solid rgba(34,197,94,0.2);
  padding: 2px 6px;
  cursor: pointer;
  line-height: 1;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  transition: color 0.1s, background 0.1s;
}
.snap-chip-del:hover { color: rgba(255,80,80,0.6); }
.snap-chip-del.holding {
  animation: snap-del-charge 0.7s linear forwards;
}
@keyframes snap-del-charge {
  0%   { color: rgba(68,255,136,0.3);  background: none; }
  60%  { color: rgba(255,120,60,0.8);  background: rgba(255,80,40,0.08); }
  100% { color: rgba(255,60,60,1);     background: rgba(255,60,60,0.18); }
}
.snap-save-btn {
  flex-shrink: 0;
  font-family: 'Share Tech Mono', monospace;
  font-size: 9px;
  letter-spacing: 1px;
  color: rgba(68,255,136,0.7);
  background: none;
  border: 1px solid rgba(34,197,94,0.35);
  border-radius: 4px;
  padding: 3px 8px;
  cursor: pointer;
}
.snap-save-btn:hover { background: rgba(34,197,94,0.08); color: var(--phos-on-light); }

/* Snaps rendered inside the patches panel grid */
.snap-in-patches {
  display: flex !important;
  flex-direction: row;
  flex-wrap: wrap;
  align-content: flex-start;
  gap: 6px;
  padding: 8px 10px;
  overflow-y: auto;
}
.snap-in-patches .snap-empty {
  align-self: center;
  width: 100%;
  text-align: center;
  padding: 16px 0;
}


/* ══════════════════════════════════════════════════════════
   LOCKED MODE  ·  two-octave keyboard layout
   ══════════════════════════════════════════════════════════ */

/* Hide controls not needed in locked mode */
body.mode-locked .key .mini-knob-slot { display: none; }
body.mode-locked .key-voice-panel     { display: none; }
body.mode-locked .key-voice-dot       { display: none; }
body.mode-locked .key-mood            { display: none; }

/* Reorder key children: LED → keycap → note → roman */
body.mode-locked .key-led        { order: 1; }
body.mode-locked .key-shortcut   { order: 2; }
body.mode-locked .key-center-row { order: 3; }

/* Large keycap badge */
body.mode-locked .key-shortcut {
  font-size: 28px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--engrave);
  background: rgba(0,0,0,0.06);
  border: 1px solid var(--border2);
  border-bottom: 3px solid var(--border2);
  border-radius: 6px;
  padding: 5px 12px;
  margin: 6px 0 2px;
  font-family: 'DM Mono', monospace;
  display: block;
  opacity: 1;
}

body.mode-locked .key:hover .key-shortcut { color: var(--engrave); }

/* Slightly smaller note name since keycap now dominates */
body.mode-locked .key-chord-name { font-size: 20px; }

/* Oct2 row shares the same height as the scale row */
#oct2Section { height: auto; }


/* ══════════════════════════════════════════════════════════
   FX CHAIN PANEL
══════════════════════════════════════════════════════════ */

/* ── Panel wrapper ───────────────────────────────────────── */
.fx-panel {
  background: var(--panel-light);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--div-hi);
  flex-shrink: 0;
}

.fx-panel-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
  height: 28px;
  cursor: pointer;
  user-select: none;
  border-bottom: 1px solid var(--border);
  transition: background 0.1s;
}
.fx-panel-header:hover { background: var(--surface); }

.fx-chevron { font-size: 10px; color: var(--engrave-dim); margin-left: auto; }

/* Header summary dots (shown collapsed) */
.fx-header-summary {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 1;
}
.fx-summary-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  display: inline-block;
  opacity: 0.85;
}

/* ── Panel body ──────────────────────────────────────────── */
.fx-panel-body { border-top: 1px solid var(--border); }

/* ── Chain strip ─────────────────────────────────────────── */
.fx-chain-strip {
  display: flex;
  align-items: center;
  padding: 9px 12px;
  overflow-x: auto;
  min-height: 76px;
  gap: 0;
  scrollbar-width: thin;
  scrollbar-color: rgba(0,0,0,0.10) transparent;
}

.fx-wire {
  width: 18px;
  height: 1px;
  background: var(--border2);
  flex-shrink: 0;
}

.fx-terminal {
  padding: 0 5px;
  flex-shrink: 0;
}

/* ── Effect block ────────────────────────────────────────── */
.fx-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 5px 6px 5px;
  border-radius: 7px;
  background: var(--surface2);
  border: 1.5px solid var(--border);
  cursor: pointer;
  flex-shrink: 0;
  user-select: none;
  transition: border-color 0.12s, box-shadow 0.12s, opacity 0.12s;
}
.fx-block:hover { border-color: rgba(0,0,0,0.22); }
.fx-block.fx-selected {
  border-color: var(--fx-color);
  box-shadow: 0 0 0 1px var(--fx-color), inset 0 0 6px rgba(0,0,0,0.04);
}
.fx-block.fx-bypassed { opacity: 0.38; }
.fx-block.fx-dragging { opacity: 0.4; cursor: grabbing; }

.fx-block-top {
  display: flex;
  align-items: center;
  gap: 5px;
}

.fx-led {
  width: 7px; height: 7px;
  border-radius: 50%;
  border: none;
  cursor: pointer;
  flex-shrink: 0;
  transition: background 0.12s;
  box-shadow: 0 0 0 0 transparent;
}
.fx-led.fx-led-on {
  box-shadow: 0 0 4px 1px var(--fx-color, #22c55e);
}

.fx-block-name {
  font-size: 8px;
  letter-spacing: 1.2px;
  color: var(--engrave);
  font-weight: 500;
  text-transform: uppercase;
}

.fx-block-canvas {
  display: block;
  border-radius: 3px;
  background: #060e06;
  width: 72px;
  height: 38px;
  max-width: 100%;
  max-height: 64px;
}

/* ── Add button ──────────────────────────────────────────── */
.fx-add-btn {
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 1.5px dashed var(--border2);
  background: transparent;
  color: var(--engrave-dim);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: border-color 0.1s, color 0.1s, background 0.1s;
}
.fx-add-btn:hover {
  border-color: var(--engrave);
  color: var(--engrave);
  background: var(--surface);
}

/* ── Picker ──────────────────────────────────────────────── */
.fx-picker {
  border-top: 1px solid var(--border);
  padding: 8px 12px 10px;
  background: var(--surface);
}
.fx-picker-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}
.fx-picker-title {
  font-size: 9px;
  letter-spacing: 2px;
  color: var(--engrave-dim);
  text-transform: uppercase;
}
.fx-picker-close {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 12px;
  color: var(--engrave-dim);
  padding: 2px 5px;
}
.fx-picker-close:hover { color: var(--engrave); }

.fx-picker-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.fx-picker-card {
  width: 82px;
  padding: 7px 6px 6px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--panel-light);
  cursor: pointer;
  text-align: center;
  transition: background 0.1s, border-color 0.1s;
}
.fx-picker-card:hover {
  background: var(--panel);
  border-color: var(--border2);
}
.fx-picker-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  margin: 0 auto 5px;
}
.fx-picker-name {
  font-size: 8px;
  letter-spacing: 1.2px;
  color: var(--engrave);
  font-weight: 500;
  text-transform: uppercase;
  margin-bottom: 3px;
}
.fx-picker-desc {
  font-size: 7px;
  color: var(--engrave-dim);
  line-height: 1.3;
}

/* ── Params row ──────────────────────────────────────────── */
.fx-params-row {
  border-top: 1px solid var(--border);
  padding: 7px 12px 9px;
  flex-direction: column;
  gap: 7px;
  background: var(--panel-light);
}

.fx-params-row.fx-params-collapsed .fx-params-content {
  display: none;
}

.fx-collapse-btn {
  font-size: 10px;
  padding: 3px 7px;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--engrave-dim);
  cursor: pointer;
  transition: transform 0.15s;
}
.fx-params-row.fx-params-collapsed .fx-collapse-btn { transform: rotate(-90deg); }

.fx-params-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 6px;
}

.fx-params-title {
  font-size: 10px;
  letter-spacing: 2.5px;
  font-weight: 500;
  text-transform: uppercase;
}

.fx-params-actions {
  display: flex;
  align-items: center;
  gap: 6px;
}

.fx-bypass-btn {
  font-size: 9px;
  padding: 3px 9px;
  border-radius: 4px;
  border: 1px solid var(--border);
  cursor: pointer;
  letter-spacing: 0.5px;
  transition: background 0.1s, color 0.1s, border-color 0.1s;
}
.fx-bypass-btn:hover { opacity: 0.8; }

.fx-remove-btn {
  font-size: 9px;
  padding: 3px 9px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: transparent;
  cursor: pointer;
  color: var(--engrave-dim);
  letter-spacing: 0.5px;
  transition: border-color 0.1s, color 0.1s;
}
.fx-remove-btn:hover { border-color: #ef4444; color: #ef4444; }

.fx-params-content {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  flex-wrap: wrap;
}

.fx-params-knobs {
  display: flex;
  gap: 6px;
  align-items: flex-start;
  flex-wrap: wrap;
}

.fx-param-group {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

.fx-param-label {
  font-size: 7px;
  letter-spacing: 1px;
  color: var(--engrave-dim);
  text-transform: uppercase;
  text-align: center;
}

.fx-knob-slot { display: inline-block; }

.fx-param-toggles {
  display: flex;
  gap: 3px;
  margin-top: 2px;
}

.fx-param-toggle-btn {
  font-size: 7px;
  letter-spacing: 0.5px;
  padding: 2px 5px;
  border-radius: 3px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--engrave-dim);
  cursor: pointer;
  transition: background 0.1s, color 0.1s, border-color 0.1s;
}
.fx-param-toggle-btn.active {
  background: var(--fx-color, #22c55e);
  border-color: var(--fx-color, #22c55e);
  color: #fff;
  opacity: 0.9;
}

.fx-params-mini {
  border-radius: 5px;
  background: #060e06;
  flex-shrink: 0;
  width: 120px;
  height: 64px;
  max-width: 100%;
  max-height: 380px;
}

/* ── FX Controls Bar (presets + mix) ─────────────────────── */
.fx-controls-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 12px;
  height: 28px;
  border-bottom: 1px solid var(--border);
  background: rgba(0,0,0,0.04);
  flex-shrink: 0;
  overflow: hidden;
}

.fx-preset-row {
  display: flex;
  align-items: center;
  gap: 5px;
  flex: 1;
  min-width: 0;
  overflow: hidden;
}

.fx-mix-row {
  display: flex;
  align-items: center;
  gap: 5px;
  flex-shrink: 0;
}

/* Matches .engrave-label in weight/case but smaller to fit the chain bar */
.fx-ctrl-label {
  font-size: 8px;
  letter-spacing: 2.5px;
  color: var(--engrave-dim);
  font-weight: 500;
  text-transform: uppercase;
  font-family: 'DM Mono', monospace;
  white-space: nowrap;
  flex-shrink: 0;
}

.fx-preset-select {
  -webkit-appearance: none;
  appearance: none;
  background: var(--surface2);
  border: 1px solid var(--border2);
  color: var(--engrave);
  font-size: 9px;
  font-family: 'DM Mono', monospace;
  letter-spacing: 0.5px;
  border-radius: 4px;
  padding: 1px 18px 1px 6px;
  cursor: pointer;
  max-width: 110px;
  min-width: 70px;
  height: 18px;
  /* custom chevron */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5'%3E%3Cpath d='M0 0l4 5 4-5z' fill='%231a1a2e66'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 5px center;
}
.fx-preset-select:focus { outline: none; border-color: rgba(0,0,0,0.3); }

.fx-preset-btn {
  font-size: 8px;
  font-family: 'DM Mono', monospace;
  letter-spacing: 0.5px;
  padding: 1px 7px;
  height: 18px;
  border-radius: 4px;
  border: 1px solid var(--border2);
  background: transparent;
  color: var(--engrave-dim);
  cursor: pointer;
  transition: border-color 0.1s, color 0.1s;
  white-space: nowrap;
  flex-shrink: 0;
}
.fx-preset-btn:hover { border-color: rgba(0,0,0,0.3); color: var(--engrave); }
.fx-preset-btn.fx-preset-del { color: rgba(239,68,68,0.5); border-color: rgba(239,68,68,0.25); }
.fx-preset-btn.fx-preset-del:hover { color: #ef4444; border-color: #ef4444; }

.fx-mix-knob-slot { display: inline-block; }

/* Master bypass pill — fits inside the 28px controls bar */
.fx-bypass-master {
  font-size: 8px;
  padding: 1px 7px;
  height: 18px;
  letter-spacing: 1px;
  margin-left: 4px;
}
.fx-bypass-master .led-pip { width: 5px; height: 5px; }

/* ── Level meters in terminal nodes ──────────────────────── */
.fx-terminal {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}
.fx-terminal-label {
  font-size: 7px;
  letter-spacing: 2px;
  color: var(--engrave-dim);
  font-weight: 500;
}
.fx-level-meter {
  display: block;
  border-radius: 2px;
  background: #060e06;
  border: 1px solid rgba(255,255,255,0.06);
  flex-shrink: 0;
}

/* ══════════════════════════════════════════════════════════
   LOOPER v2  —  MIDI Roll · Layers · Metronome LED
══════════════════════════════════════════════════════════ */

/* ── MIDI Piano Roll canvas ──────────────────────────────── */
.looper-midi-canvas {
  display: block;
  width: 100%;
  height: 64px;
  background: #050d05;
  border-bottom: 1px solid rgba(68,255,136,0.08);
}

/* ── Layer tab bar ───────────────────────────────────────── */
.looper-tab-bar {
  flex-direction: row;
  align-items: flex-end;
  gap: 2px;
  padding: 4px 6px 0;
  flex-wrap: wrap;
}
.looper-tab {
  background: rgba(68,255,136,0.05);
  border: 1px solid rgba(12,122,50,0.22);
  border-bottom: 2px solid transparent;
  color: var(--phos-on-light-dim);
  font-family: 'DM Mono', 'Share Tech Mono', monospace;
  font-size: 7px;
  letter-spacing: 1px;
  padding: 2px 8px;
  cursor: pointer;
  border-radius: 3px 3px 0 0;
  transition: color 0.15s, border-bottom-color 0.15s;
}
.looper-tab:hover {
  color: var(--phos-on-light);
  border-bottom-color: rgba(12,122,50,0.45);
}
.looper-tab-active {
  color: #fff;
  border-bottom-color: var(--tab-color, #0c7a32);
  background: rgba(12,122,50,0.92);
}
.looper-tab-add {
  color: var(--phos-on-light-dim);
  border-style: dashed;
  margin-left: 6px;
}
.looper-tab-add:hover { color: var(--phos-on-light); border-color: rgba(12,122,50,0.55); }

/* ── Live layer mixer ────────────────────────────────────── */
.looper-layers-panel {
  flex-direction: column;
  gap: 1px;
  padding: 4px 8px 6px;
  background: rgba(0,0,0,0.18);
  border: 1px solid rgba(68,255,136,0.10);
  border-top: none;
  max-height: 160px;
  overflow-y: auto;
}
.looper-layer-row {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 3px 2px;
  border-bottom: 1px solid rgba(68,255,136,0.05);
}
.looper-layer-row:last-child { border-bottom: none; }
.looper-layer-row-active { background: rgba(68,255,136,0.06); border-left: 2px solid rgba(68,255,136,0.35); padding-left: 0; }
.looper-layer-muted { opacity: 0.45; }
.looper-layer-pip {
  width: 7px; height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
}
/* ── Per-layer status LED ───────────────────────────────────────────── */
.looper-layer-led {
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
  background: rgba(68,255,136,0.12);
  transition: background 0.15s, box-shadow 0.15s;
}
.looper-layer-led[data-state="ll-rec"]  { background: #ef4444; box-shadow: 0 0 6px rgba(239,68,68,0.6); animation: looper-blink 0.6s ease-in-out infinite; }
.looper-layer-led[data-state="ll-play"] { background: #44ff88; box-shadow: 0 0 4px rgba(68,255,136,0.4); }
.looper-layer-led[data-state="ll-odub"] { background: #ffaa44; box-shadow: 0 0 4px rgba(255,170,68,0.5); }
.looper-layer-led[data-state="ll-empty"] { background: rgba(68,255,136,0.25); }
/* ── Per-layer transport buttons ────────────────────────────────────── */
.looper-layer-btn.ll-rec-btn  { color: rgba(239,68,68,0.60); border-color: rgba(239,68,68,0.20); }
.looper-layer-btn.ll-rec-btn:hover { color: #ef4444; border-color: rgba(239,68,68,0.50); background: rgba(239,68,68,0.08); }
.looper-layer-btn.ll-play-btn { color: rgba(68,255,136,0.55); border-color: rgba(68,255,136,0.18); }
.looper-layer-btn.ll-play-btn:hover { color: var(--phos-on-light); border-color: rgba(12,122,50,0.45); }
.looper-layer-btn.ll-dub-btn  { color: rgba(255,170,68,0.55); border-color: rgba(255,170,68,0.18); }
.looper-layer-btn.ll-dub-btn:hover { color: #ffaa44; border-color: rgba(255,170,68,0.45); background: rgba(255,170,68,0.06); }
.looper-layer-btn.ll-dub-btn.active { color: #ffaa44; background: rgba(255,170,68,0.14); border-color: rgba(255,170,68,0.50); }
.looper-layer-btn.ll-und-btn  { color: rgba(68,255,136,0.35); border-color: rgba(68,255,136,0.12); }
.looper-layer-btn.ll-und-btn.active { color: #ffbb44; border-color: rgba(255,187,68,0.35); background: rgba(255,187,68,0.08); }
.looper-layer-btn.ll-und-btn:hover { color: #ffbb44; border-color: rgba(255,187,68,0.35); }
.looper-layer-name {
  font-family: 'DM Mono', 'Share Tech Mono', monospace;
  font-size: 8px;
  letter-spacing: 0.5px;
  color: var(--phos-on-light);
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
}
.looper-layer-name:hover { color: #0a5f27; }
.looper-layer-btn {
  background: rgba(68,255,136,0.08);
  border: 1px solid rgba(12,122,50,0.30);
  color: var(--phos-on-light-dim);
  font-family: 'DM Mono', 'Share Tech Mono', monospace;
  font-size: 7px;
  letter-spacing: 0.5px;
  padding: 2px 5px;
  cursor: pointer;
  border-radius: 2px;
  flex-shrink: 0;
}
.looper-layer-btn:hover { color: var(--phos-on-light); border-color: rgba(12,122,50,0.45); }
.looper-layer-btn.active { color: #fff; background: rgba(12,122,50,0.92); border-color: rgba(12,122,50,0.92); }
.looper-layer-btn.looper-layer-del { color: rgba(239,68,68,0.50); border-color: rgba(239,68,68,0.20); }
.looper-layer-btn.looper-layer-del:hover { color: #ef4444; border-color: rgba(239,68,68,0.55); background: rgba(239,68,68,0.06); }
.looper-layer-vol {
  width: 64px;
  accent-color: #44ff88;
  height: 3px;
  flex-shrink: 0;
  cursor: pointer;
}

/* Per-layer pan: narrower than volume, cyan accent, centre = no pan. */
.looper-layer-pan {
  width: 44px;
  accent-color: #44cfff;
  height: 3px;
  flex-shrink: 0;
  cursor: pointer;
}

/* Speed toggle: amber when not 1× so an off-speed layer is obvious at a glance. */
.looper-layer-btn.ll-spd-btn { min-width: 26px; }
.looper-layer-btn.ll-spd-btn.active { color: #ffbb44; border-color: rgba(255,187,68,0.40); background: rgba(255,187,68,0.08); }

/* Reverse toggle: violet when engaged. */
.looper-layer-btn.ll-rev-btn.active { color: #bf88ff; border-color: rgba(191,136,255,0.45); background: rgba(191,136,255,0.10); }

/* ════════════════════════════════════════════════════════════════════════
   MOBILE STUDIO DRAWER — one pull-up sheet that absorbs Voice / FX / Looper /
   Songs so the playing surface stays clean. Reuses the voice-editor-sheet
   slide pattern + the patches-strip safe-area/scroll. Mobile-only (≤700px);
   on desktop the FAB is hidden and the panels stay in normal flow.
   ════════════════════════════════════════════════════════════════════════ */

/* Floating trigger — bottom-right, clear of the iOS home indicator. */
.settings-fab {
  display: none;
  position: fixed;
  right: 14px;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 14px);
  z-index: 1050;
  align-items: center;
  gap: 7px;
  padding: 0 16px 0 13px;
  height: 46px;
  border-radius: 23px;
  border: 1px solid #16a34a;
  background: #22c55e;
  color: #ffffff;
  font-family: 'DM Mono', monospace;
  font-size: 13px;
  letter-spacing: 1px;
  text-transform: uppercase;
  box-shadow: 0 6px 20px rgba(0,0,0,0.22), 0 0 14px rgba(34,197,94,0.30);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.settings-fab:active { transform: scale(0.95); }
.settings-fab:focus-visible { outline: 3px solid #fff; outline-offset: 2px; box-shadow: 0 0 0 5px rgba(34,197,94,0.55); }
.settings-fab-icon { font-size: 18px; line-height: 1; }

.settings-drawer-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.5);
  z-index: 1090;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.22s ease;
}
.settings-drawer-backdrop.open { opacity: 1; pointer-events: auto; }

.settings-drawer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1100;
  display: flex;
  flex-direction: column;
  max-height: 86vh;
  background: var(--panel);
  border-top: 2px solid rgba(34,197,94,0.45);
  border-radius: 16px 16px 0 0;
  box-shadow: 0 -16px 44px rgba(0,0,0,0.32);
  transform: translateY(100%);
  transition: transform 0.26s cubic-bezier(0.22, 1, 0.36, 1);
  visibility: hidden;
}
.settings-drawer.open { transform: translateY(0); visibility: visible; }
/* While a drag is in progress we drive translateY inline and kill the transition. */
.settings-drawer.dragging { transition: none; }

.settings-drawer-handle {
  width: 44px;
  height: 5px;
  flex-shrink: 0;
  margin: 9px auto 2px;
  border-radius: 3px;
  background: rgba(0,0,0,0.22);
  cursor: grab;
  touch-action: none;
}
.settings-drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 16px 10px;
  flex-shrink: 0;
  border-bottom: 1px solid var(--border);
}
.settings-drawer-title {
  font-family: 'DM Mono', monospace;
  font-size: 11px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--engrave-dim);
}
.settings-drawer-close {
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--engrave-dim);
  font-size: 15px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.settings-drawer-close:active { transform: scale(0.92); }

.settings-drawer-body {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: 6px 10px calc(env(safe-area-inset-bottom, 0px) + 16px);
}
/* Panels relocated into the drawer fill its width with a little breathing room. */
.settings-drawer-body > .vpc-panel,
.settings-drawer-body > .fx-panel,
.settings-drawer-body > .looper-section,
.settings-drawer-body > .songs-section { margin-bottom: 6px; }
.settings-drawer-body > .panel-divider { margin-top: 4px; }

@media (max-width: 700px) {
  .settings-fab { display: flex; }
  /* Leave room so the FAB never covers the last row of the playing surface. */
  body.has-studio-fab { padding-bottom: 64px; }
  body.drawer-open { overflow: hidden; }
}
@media (min-width: 701px) {
  /* Desktop never shows the drawer chrome even if state leaks. */
  .settings-fab, .settings-drawer, .settings-drawer-backdrop { display: none !important; }
}

/* ── XY FX-Touch (Kaoss-pad gesture) ──────────────────────────────────────── */
/* Arm/disarm toggle — sits in the on-surface instrument row (hs-sound-selects)
   beside the ◀🎲▶ nav, so it stays reachable on mobile and never overlaps a
   chord/quality pad. Phosphor styling to match the nav buttons; active = green
   glow + pulse. The gesture happens on the pads; the HUD shows the live X/Y. */
.hs-fx-toggle {
  flex: 0 0 auto; min-width: 34px; padding: 0 9px;
  align-self: stretch;
  display: flex; align-items: center; justify-content: center;
  font-family: 'DM Mono', monospace;
  font-size: 10px; font-weight: 800; letter-spacing: .1em;
  background: #08120a;
  color: color-mix(in srgb, var(--phos-fg, #39ff14) 72%, #cfe);
  border: 1px solid var(--border2); border-radius: 6px;
  cursor: pointer; -webkit-appearance: none; appearance: none;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
  transition: background .15s, color .15s, border-color .15s, box-shadow .15s, transform 90ms ease;
}
.hs-fx-toggle:hover  { border-color: var(--phos-fg, #39ff14); background: #0c1a0e; }
.hs-fx-toggle:active { transform: scale(.9); }
.hs-fx-toggle.active {
  color: var(--phos-fg, #39ff14);
  border-color: var(--phos-fg, #39ff14);
  background: #0c2412;
  animation: fxToggleGlow 1.4s ease-in-out infinite;
}
@keyframes fxToggleGlow {
  0%, 100% { box-shadow: 0 0 0 1px var(--phos-fg, #39ff14), 0 0 8px  color-mix(in srgb, var(--phos-fg, #39ff14) 40%, transparent); }
  50%      { box-shadow: 0 0 0 1px var(--phos-fg, #39ff14), 0 0 16px color-mix(in srgb, var(--phos-fg, #39ff14) 70%, transparent); }
}

/* Live XY indicator — a non-blocking HUD; opacity-toggled (display stays block so
   the .on opacity transition actually animates). Shown only while a gesture is
   actively modulating; pointer-events:none so it never blocks the pads. */
.fx-touch-ind {
  display: block;
  position: fixed; left: 50%; top: 34%; transform: translate(-50%, -50%);
  z-index: 1039; pointer-events: none;
  opacity: 0; transition: opacity .18s ease;
}
.fx-touch-ind.on { opacity: 1; }
.fx-touch-pad {
  position: relative; width: 120px; height: 120px;
  border-radius: 16px;
  border: 1px solid color-mix(in srgb, var(--phos-fg) 30%, transparent);
  background:
    linear-gradient(color-mix(in srgb, var(--phos-fg) 12%, transparent) 1px, transparent 1px) 0 0 / 100% 24px,
    linear-gradient(90deg, color-mix(in srgb, var(--phos-fg) 12%, transparent) 1px, transparent 1px) 0 0 / 24px 100%,
    color-mix(in srgb, var(--phos-bg) 92%, transparent);
  box-shadow: 0 6px 22px rgba(0,0,0,.45);
}
.fx-touch-dot {
  position: absolute; left: 50%; top: 50%;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--phos-fg);
  box-shadow: 0 0 10px var(--phos-fg), 0 0 22px color-mix(in srgb, var(--phos-fg) 60%, transparent);
  transform: translate(-50%, -50%);
  transition: transform .04s linear;
}
.fx-touch-ax {
  position: absolute; font-size: 8px; font-weight: 800; letter-spacing: .14em;
  color: color-mix(in srgb, var(--phos-fg) 70%, #cfe);
}
.fx-touch-ax-x { right: 6px; bottom: 4px; }
.fx-touch-ax-y { left: 6px; top: 4px; }
/* Live numeric readout under the pad — phosphor LCD language (dark HUD, ok). */
.fx-touch-val {
  margin-top: 6px; text-align: center;
  font-size: 10px; font-weight: 800; letter-spacing: .1em;
  font-variant-numeric: tabular-nums;
  color: var(--phos-fg);
  text-shadow: 0 0 8px color-mix(in srgb, var(--phos-fg) 55%, transparent);
  background: color-mix(in srgb, var(--phos-bg) 88%, transparent);
  border: 1px solid color-mix(in srgb, var(--phos-fg) 25%, transparent);
  border-radius: 8px; padding: 3px 8px;
}

@media (prefers-reduced-motion: reduce) {
  .hs-fx-toggle.active { animation: none; }
}

/* ═══════════════════════════════════════════════════════════
   Phase 5 — unified control language ( --ctl-* rollout )
   One override layer instead of edits scattered through 15
   family rules: every compact control adopts the .key physical
   language (radius rail, rest depth, hover lift, active sink),
   every dark LCD zone adopts the shared window bezel. Family
   COLOR semantics (green transport, amber snap, blue info,
   quality tints) are untouched — only depth/shape/type unify.
   Mobile keeps its own ergonomics: the ≤700px rules elsewhere
   (44px looper bar, 28px QA buttons) out-rank this layer on
   specificity, so nothing here fights the phone layout.
   ═══════════════════════════════════════════════════════════ */

/* ── Rect compact buttons: radius rail + rest depth ────────── */
.looper-btn, .lcp-btn, .looper-tool-btn, .lbb-snap-btn, .songs-btn,
.fx-preset-btn, .fx-bypass-btn, .fx-remove-btn, .preset-nav-btn,
.qa-toggle-btn, .qa-action-btn, .qa-filter, .qa-jump-btn,
.lesson-scheme-btn, .mob-mode-btn, .patch-cat-tab {
  border-radius: var(--ctl-radius-sm);
  box-shadow: var(--ctl-shadow-rest-sm);
}
/* Pills keep their 12px capsule shape but gain the same depth. */
.led-pill-btn, .info-mode-btn, .teach-mode-btn, .qc-toggle {
  box-shadow: var(--ctl-shadow-rest-sm);
}
/* The dark phosphor header variant must not get light-panel insets. */
.hs-sound-selects .preset-nav-btn { box-shadow: none; }

/* ── Hover lift ────────────────────────────────────────────── */
.looper-btn:hover, .lcp-btn:hover, .looper-tool-btn:hover,
.lbb-snap-btn:hover, .songs-btn:hover, .fx-preset-btn:hover,
.fx-bypass-btn:hover, .fx-remove-btn:hover, .preset-nav-btn:hover,
.qa-toggle-btn:hover, .qa-action-btn:hover, .qa-filter:hover,
.qa-jump-btn:hover, .lesson-scheme-btn:hover, .patch-cat-tab:hover,
.led-pill-btn:hover, .info-mode-btn:hover, .teach-mode-btn:hover,
.qc-toggle:hover {
  box-shadow: var(--ctl-shadow-hover-sm);
}
.looper-btn:disabled { box-shadow: var(--ctl-shadow-rest-sm); }

/* ── Momentary press: shared sink (replaces per-family scales) ─ */
.looper-btn:active, .lcp-btn:active, .looper-tool-btn:active,
.lbb-snap-btn:active, .songs-btn:active, .fx-preset-btn:active,
.fx-bypass-btn:active, .fx-remove-btn:active, .preset-nav-btn:active,
.qa-toggle-btn:active, .qa-action-btn:active, .qa-filter:active,
.qa-jump-btn:active, .lesson-scheme-btn:active, .mob-mode-btn:active,
.patch-cat-tab:active, .led-pill-btn:active, .info-mode-btn:active,
.teach-mode-btn:active, .qc-toggle:active {
  transform: translateY(1px);
  box-shadow: var(--ctl-inset-active);
}

/* ── Latched/active states: family glow + shared inset sink ──
   (0,2,0 selectors so they take over from the originals) */
.looper-btn.active, .looper-tool-btn.active {
  box-shadow: 0 0 6px rgba(68,255,136,0.12), var(--ctl-inset-active);
}
.lbb-snap-btn.active {
  box-shadow: 0 0 5px rgba(255,187,68,0.12), var(--ctl-inset-active);
}
.lcp-btn.active,
.lesson-scheme-btn.active {
  box-shadow: var(--ctl-inset-active);
}
.qa-toggle-btn.active, .qa-filter.active {
  box-shadow: 0 0 8px rgba(34,197,94,0.12), var(--ctl-inset-active);
}
.led-pill-btn.led-pill-active {
  box-shadow: 0 0 8px rgba(34,197,94,0.15), var(--ctl-inset-active);
}
.info-mode-btn.info-btn-active {
  box-shadow: 0 0 8px rgba(96,165,250,0.15), var(--ctl-inset-active);
}
.teach-mode-btn.teach-btn-active {
  box-shadow: 0 0 8px rgba(251,191,36,0.18), var(--ctl-inset-active);
}
.songs-btn-play.playing {
  box-shadow: 0 0 10px rgba(34,197,94,0.15), var(--ctl-inset-active);
}
.patch-cat-tab.active {
  box-shadow: 0 0 8px rgba(34,197,94,0.12), var(--ctl-inset-active),
              inset 0 1px 0 rgba(255,255,255,0.6);
}
body.quick-chording .qc-toggle {
  box-shadow: 0 0 8px rgba(34,197,94,0.15), var(--ctl-inset-active);
}

/* ── Label type rail ───────────────────────────────────────
   micro (9px): transport / QA / pills — was an 8/8.5/9 spread.
   nano  (7px): dense LCD-adjacent chrome — tokenized, size kept. */
.looper-btn, .lcp-btn, .fx-preset-btn, .fx-bypass-btn, .fx-remove-btn,
.qa-toggle-btn, .qa-action-btn, .qa-filter, .songs-btn, .mob-mode-btn,
.led-pill-btn, .info-mode-btn, .teach-mode-btn, .lesson-scheme-btn,
.qc-toggle {
  font-size: var(--type-micro);
}
.looper-tool-btn, .lbb-snap-btn, .qa-jump-btn, .looper-tab {
  font-size: var(--type-nano);
}

/* ── Phosphor windows: shared bezel on every dark LCD zone ─── */
.phosphor-display, .looper-canvas, .looper-status {
  border: 1px solid var(--lcd-edge);
  box-shadow: var(--lcd-bezel);
}
.grp-mini-canvas, .fx-block-canvas, .fx-level-meter {
  border: 1px solid var(--lcd-edge);
  box-shadow: var(--lcd-bezel-sm);
}

/* ── QA panel tidy: solid cards, rail sizes, hover feedback ── */
.qa-inline { background: rgba(255,255,255,0.85); }
.qa-stat, .qa-result { background: var(--panel-light); }
.qa-flag { font-size: var(--type-nano); }
.qa-filter:not(.active):hover { background: rgba(0,0,0,0.04); }

/* On phones the patches body becomes a DARK bottom sheet (#08120a) —
   light-panel insets/drop shadows read wrong there, so strip them. */
@media (max-width: 700px) {
  #patchesStripBody .patch-cat-tab,
  #patchesStripBody .patch-cat-tab:hover,
  #patchesStripBody .patch-cat-tab:active { box-shadow: none; }
}


/* ══════════════════════════════════════════════════════════
   Phase 6 — chord-key progressive disclosure
   Always-on: chord name, mood word, quality LED, the learn colour tint,
   the home crown and the REL border colours — the "what do I press" layer.
   Gated: the corner degree badge and the REL·MAJOR/MINOR twin tags — the
   "theory annotation" layer. They stay invisible while simply playing and
   fade in when the player is in a learning posture:
     · hovering a pad (desktop)  · holding a pad (.pressed — the touch reveal)
     · Info mode                 · lesson strip open (body.lesson-open)
     · an active Teach spotlight (body.teach-has-spotlight)
   Opacity-only gating: applyLearnDecor()/_lcDecoratePad() keep managing
   `display` inline (badge hidden on the home pad, tags added/removed), so
   the JS and CSS layers compose instead of fighting.
   ══════════════════════════════════════════════════════════ */
.key-deg-badge,
.lc-twin-tag {
  opacity: 0;
  transition: opacity 0.18s ease;
}
.key:hover .key-deg-badge,
.key.pressed .key-deg-badge,
body.info-mode-active .key-deg-badge,
body.lesson-open .key-deg-badge,
body.teach-has-spotlight .key-deg-badge { opacity: 0.55; }
.key:hover .lc-twin-tag,
.key.pressed .lc-twin-tag,
body.info-mode-active .lc-twin-tag,
body.lesson-open .lc-twin-tag,
body.teach-has-spotlight .lc-twin-tag { opacity: 1; }


/* ══════════════════════════════════════════════════════════
   Phase 7 — motion polish
   Entrances for the display-toggled accordions/sheets, envelope-
   matched key-LED release, ultra-wide containment, and a global
   prefers-reduced-motion guard for everything added here (the
   circle spin + studio drawer check the media query in JS/CSS
   already). All one-shot or release-only — nothing animates
   continuously, so looper-playback rAF headroom is untouched.
   ══════════════════════════════════════════════════════════ */

/* ── Accordion / sheet entrances ─────────────────────────────
   All of these are display:none-toggled by JS; a keyframe fires
   naturally when the element becomes rendered, so no JS changes. */
@keyframes am-panel-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}
#patchesStripBody, #qaPanelBody, #fxPanelBody, #songsSection,
#vpcVoiceFlat, #extSection, #looperSection, .lesson-strip.open {
  animation: am-panel-in 0.20s ease-out;
}

/* ── Key-LED release matched to the sound's envelope ─────────
   applyPreset() publishes the active preset's release time as
   --key-release (clamped 0.12–1.4s). Press-in still snaps (the
   .pressed rule below wins while held); on release the tiny 8px
   LED's glow + scale decay in step with the audible tail. The
   pad's own wide-blur shadow stays untransitioned (style.css
   ~832 — known paint cost); the LED is a trivially small layer. */
.key-led {
  box-shadow: 0 0 0 0 rgba(34,197,94,0);   /* interpolable rest state */
  transition:
    opacity 0.1s,
    background-color 0.25s,
    transform  var(--key-release, 0.1s) ease-out,
    box-shadow var(--key-release, 0.1s) ease-out;
}
.key.pressed .key-led {
  transition: opacity 0.1s, background-color 0.25s,
              transform 0.06s, box-shadow 0.06s;  /* attack: snap in */
}

/* ── Ultra-wide containment ──────────────────────────────────
   Past ~1800px the hardware panel stops stretching: the unit is
   capped and centered on a dark stage so key pads and the looper
   don't become comically wide. */
@media (min-width: 1800px) {
  html { background: #101014; }
  body {
    max-width: 1720px;
    margin: 0 auto;
    border-left:  1px solid rgba(0,0,0,0.45);
    border-right: 1px solid rgba(0,0,0,0.45);
    box-shadow: 0 0 70px rgba(0,0,0,0.50);
  }
}

/* ── Reduced motion: everything above degrades to instant ──── */
@media (prefers-reduced-motion: reduce) {
  #patchesStripBody, #qaPanelBody, #fxPanelBody, #songsSection,
  #vpcVoiceFlat, #extSection, #looperSection, .lesson-strip.open {
    animation: none;
  }
  .key-led, .key.pressed .key-led {
    transition: opacity 0.1s, background-color 0.25s;
  }
  .settings-drawer { transition: none; }
  .key-deg-badge, .lc-twin-tag { transition: none; }
}

/* ════════════════════════════════════════════════════════════
   PHASE 8 — cold-open guidance + one-time discoverability
   First-visit only (never when a saved session exists). Light
   panel language throughout: --phos-on-light green, engrave text.
   ════════════════════════════════════════════════════════════ */

/* Gentle ring pulse on the HOME key inviting the first tap.
   Uses its own outline-style shadow layer — the .key box-shadow
   itself stays untransitioned (paint-cost rule at .key). */
@keyframes am-cold-pulse {
  0%, 100% { outline: 3px solid rgba(12,122,50,0);    outline-offset: 2px; }
  50%      { outline: 3px solid rgba(12,122,50,0.45); outline-offset: 4px; }
}
.key.cold-open-pulse { animation: am-cold-pulse 2.2s ease-in-out infinite; }

/* Dismissible first-visit chip */
.cold-open-chip {
  position: fixed;
  left: 50%; bottom: 18px;
  transform: translateX(-50%);
  z-index: 240;
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px 9px 14px;
  background: var(--panel-light, #fff);
  border: 1px solid rgba(16,42,67,0.18);
  border-radius: 10px;
  box-shadow: 0 6px 22px rgba(16,42,67,0.18);
  font-family: 'DM Mono', monospace;
  font-size: 12px;
  letter-spacing: 0.4px;
  color: var(--engrave, #102a43);
  animation: am-panel-in 0.25s ease-out;
  max-width: min(92vw, 420px);
}
.cold-open-chip b { color: var(--phos-on-light, #0c7a32); font-weight: 700; }
.cold-open-x {
  border: 1px solid rgba(16,42,67,0.22);
  background: transparent;
  color: var(--engrave-dim, rgba(16,42,67,0.70));
  border-radius: 6px;
  width: 22px; height: 22px;
  line-height: 1;
  font-size: 11px;
  cursor: pointer;
  flex: none;
}
.cold-open-x:hover { background: rgba(16,42,67,0.07); }

/* One-time discoverability dot on the Looper / Song Progressions
   dividers — cleared forever once each section is opened. */
@keyframes am-disc-pulse {
  0%, 100% { opacity: 0.35; transform: scale(0.85); }
  50%      { opacity: 1;    transform: scale(1.15); }
}
.disc-dot {
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--phos-on-light, #0c7a32);
  margin-left: 8px;
  vertical-align: 1px;
  animation: am-disc-pulse 1.8s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .key.cold-open-pulse { animation: none; outline: 3px solid rgba(12,122,50,0.35); outline-offset: 3px; }
  .disc-dot { animation: none; opacity: 0.8; }
  .cold-open-chip { animation: none; }
}

/* ══════════════════════════════════════════════════════════
   ACCESSIBILITY  ·  added 2026-07-14
   (1) .sr-only — screen-reader-only text for the page <h1> and
       landmark labels (removed visually, still announced).
   (2) :focus-visible ring — one consistent, high-contrast keyboard
       focus indicator. :focus-visible paints ONLY for keyboard /
       assistive-tech navigation, so mouse and touch users see no
       change; this is purely a keyboard-user win. !important lets the
       ring survive the various `outline:none` rules on individual
       inputs (those replace it with a border highlight; buttons/pads
       had no keyboard focus indicator at all before this).
══════════════════════════════════════════════════════════ */
:root { --focus-ring: #0a5cff; }
.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}
:focus-visible {
  outline: 3px solid var(--focus-ring) !important;
  outline-offset: 2px !important;
}
/* Pads sit on dark backgrounds where a blue ring can lose contrast — a white
   inner outline keeps the indicator visible on any surface the focus lands on. */
.key:focus-visible, .ext-key:focus-visible {
  outline: 3px solid #fff !important;
  outline-offset: -3px !important;
  box-shadow: 0 0 0 3px var(--focus-ring);
}

/* ── Sound Check ───────────────────────────────────────────────────────────────
   Audio diagnostics panel. Light-themed like every other control surface; the
   ONLY phosphor-on-dark element here is the .sc-details LCD readout, per the
   app's convention that green-on-dark means "instrument readout". */
.sound-check-pill, .sound-check-btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--panel-light); color: var(--engrave);
  border: 1px solid rgba(0, 0, 0, 0.18); border-radius: 999px;
  padding: 4px 10px; font-size: 12px; cursor: pointer;
}
.sc-light { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--phos-on-light); }
.sc-good  { background: var(--phos-on-light); }
.sc-watch { background: #c98a00; }
.sc-bad   { background: #c0392b; }

.sound-check-card {
  position: fixed; inset: auto 12px 12px 12px; z-index: 9000;
  background: var(--panel-light); color: var(--engrave);
  border: 1px solid rgba(0, 0, 0, 0.18); border-radius: 12px;
  padding: 12px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
  display: none; max-height: 70vh; overflow: auto;
}
.sound-check-card.open { display: block; }
@media (min-width: 701px) {
  .sound-check-card { inset: auto auto 20px 20px; width: 420px; }
}
.sc-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.sc-verdict { font-weight: 600; flex: 1; }
.sc-close {
  background: none; border: none; font-size: 16px; cursor: pointer;
  color: var(--engrave); opacity: 0.7;
}
/* Thumb-sized on purpose: it is pressed in a hurry, right after hearing a glitch. */
.sc-mark {
  width: 100%; padding: 14px; font-size: 15px; font-weight: 600;
  border-radius: 10px; border: 1px solid rgba(0, 0, 0, 0.18);
  background: var(--panel-light); color: var(--engrave); cursor: pointer;
}
.sc-actions { display: flex; gap: 8px; margin-top: 10px; }
.sc-btn {
  flex: 1; padding: 8px; font-size: 12px; border-radius: 8px;
  border: 1px solid rgba(0, 0, 0, 0.18); background: var(--panel-light);
  color: var(--engrave); cursor: pointer;
}
.sc-details {
  margin-top: 10px; padding: 8px; border-radius: 8px;
  background: var(--phos-bg); color: var(--phos-fg);
  font: 11px/1.4 ui-monospace, Menlo, monospace;
  white-space: pre; overflow-x: auto; max-height: 40vh;
}
