/* Front panel: the B2 "Module" board (Justin, Oct 28, 2026). A flat black
   panel with white silkscreen print; knobs read by their angle against a
   printed tick scale; the vowel pad and the routing are bezelled screens.
   One panel designed at 1200x750 and scaled to fit; drawers for the lanes
   and the keyboard add height. */
:root {
  --bg: #0f1012;
  --panel: #17181b;       /* the panel: flat black */
  --panel-2: #121316;     /* header, bars, keys and menus */
  --edge: #2e3136;
  --key: #121316;
  --key-edge: #3a3d42;
  --text: #efe9de;
  --print: #efe9de;       /* printed labels: white silkscreen */
  --head: #f2ede4;        /* section names */
  --rule: rgba(242, 237, 228, 0.5);  /* the rule under a section's name */
  --flow: #33363b;        /* the lines between sections */
  --arrow: #9a958c;       /* the flow arrows, and the small group names (Partials, Grit) */
  --dim: #7d786f;
  --accent: #f0a640;
  --accent-dim: #6b4a17;
  --ink: #1a1408;         /* text on amber */
  --mod: #5ab4e0;         /* where modulation takes a knob */
  --mod-text: #7cc4ee;
  --wild: #d6453b;        /* the wild part of a knob's range */
  --oled: #ffb347;
  --oled-bg: #0b0a08;
  --led-green: #2fae5c;
  --led-yellow: #e0a20f;
  --led-red: #d6453b;
  --danger: #e0645a;

  /* Colours used in one or two places, named so they can be tried live like the rest */
  --drop: rgba(0, 0, 0, 0.5);           /* the shadow under the panel and its menus */
  --overlay: rgba(10, 11, 13, 0.82);    /* the veil over the panel before Start */
  --hover: #26282c;                     /* a menu row under the pointer */
  --chip-hover: #2a2d31;                /* a chip under the pointer */
  --option-bg: #1a1b1e;                 /* the lists the screens drop */
  --sep: #34373c;                       /* the header's upright dividers */
  --key-text: #9a958c;                  /* a key's print while it is off */
  --key-edge-hover: #55595f;            /* a key's or button's edge under the pointer */
  --key-glow: rgba(240, 166, 64, 0.5);  /* round a lit key */
  --key-led-off: #2c2f33;               /* the small lamp on a push key */
  --key-led-glow: rgba(240, 166, 64, 0.85);
  --mode-text: #b9b3a7;                 /* a mode key (Uni): the same colours either way */
  --icon-glow: rgba(240, 166, 64, 0.8); /* round a lit bare icon (a lane's On) */
  --panic-edge: #5a3330;
  --panic-hover: #3a2220;
  --led-off: #2a2d32;                   /* an unlit LED */
  --led-shade: rgba(0, 0, 0, 0.5);      /* the shadow inside an unlit LED */
  --led-shade-lit: rgba(0, 0, 0, 0.35); /* and inside a lit one */
  --led-green-glow: rgba(47, 174, 92, 0.85);
  --led-yellow-glow: rgba(224, 162, 15, 0.85);
  --led-red-glow: rgba(214, 69, 59, 0.9);
  --glow-off: #3a2c14;                  /* the amber stage lights (Drive, Feedback): dark */
  --glow-on: rgba(240, 166, 64, 0.95);  /* their glow */
  --glow-core: rgba(255, 225, 170, 0.8); /* and its hot centre */
  --print-faded: rgba(242, 237, 228, 0.22); /* a group's name while the panel is dimmed to a light's knobs */
  --rule-faded: rgba(242, 237, 228, 0.12); /* and its rule */
  --knob-tick: rgba(242, 237, 228, 0.85); /* a knob's pointer line */
  --knob-edge: #2a2c30;
  --knob-shadow: rgba(0, 0, 0, 0.6);
  --knob-knurl: rgba(0, 0, 0, 0.4);
  --knob-top: #191b1f;
  --knob-top-edge: #0b0c0e;
  --screen-inset: #000;                 /* the dark line inside a screen's bezel */
  --oled-glow: rgba(255, 160, 40, 0.4); /* the screens' text glow */
  --oled-line-glow: rgba(255, 160, 40, 0.5); /* the screens' drawn lines glow */
  --oled-zero: #2a2416;                 /* the envelope graph's zero line */
  --oled-rule: #3d2c10;                 /* the line under a routing's lists */
  --oled-knob-tick: #6b4a17;            /* the routing's amount knobs */
  --oled-knob-cap: #1a1308;
  --oled-knob-edge: #5a3f14;
  --step-off: #1c1e22;                  /* the sequencer bar's trigger steps: one that is off */
  --step-now-glow: rgba(240, 166, 64, 0.7); /* round the step now playing */
  --step-mid: #33363b;                  /* a step bar's centre line */
  --step-text-shadow: #000;             /* behind a step's value */
  --white-key: #e9e6df;                 /* the keyboard drawer */
  --white-key-edge: #9a968e;
  --black-key: #222428;
  --white-key-down: #f6cd8a;
  --selected-outline: rgba(240, 166, 64, 0.45); /* Smart Random: a selected control's dashes, outside select mode */

  --sans: "Jost", system-ui, sans-serif;                 /* values (100%, 2 ms, Init) */
  --label: "Jost", system-ui, sans-serif;                /* printed labels and headings, in spaced capitals */
  --wordmark: "Bodoni Moda", Didot, serif;               /* the name, an italic like a marking in a score */
  --screen: "Bitcount Grid Single", ui-monospace, monospace;  /* the screens (vowel pad, routing): a dot-matrix display */
  --screen-size: 12px;                                   /* the screens' text: big enough for the dots to read as dots */
  color-scheme: dark;
}

/* ---- Layout: the panel's main measurements, in one place ----
   Try them live: in the browser's DevTools select <html> (or :root) and change
   any of these; the whole panel follows. The panel is designed at 1200 wide
   and scales to the window, so a taller panel shrinks a little to fit. Knob
   sizes are set where each knob is built (web/main.js, web/moddeck.js). */
:root {
  /* Edges and bars */
  --side-pad: 20px;            /* left/right margin of the panel, bottom row, sequencer bar and drawers */
  --header-height: 42px;
  --header-pad: 16px;          /* header's left/right margin */
  --button-size: 22px;         /* every button's height; a button with an icon is this square */
  --header-gap: 6px;           /* the least room between header groups (they spread out evenly) */
  --header-end-gap: 12px;      /* between Level, Volume and Panic */
  --header-volume-value: 50px; /* room for Volume's value, so the header holds still as it changes */
  --seqbar-height: 36px;
  --slot-columns: 10px 100px 6px 108px 26px minmax(0, 1fr);  /* routing: n, source, ›, destination, amount (the knob), range */
  --lane-head-width: 270px;
  --lane-how-columns: 36px 74px 50px 22px 22px;  /* a lane's Len, Depth, Rate, Glide, Uni */
  --clock-gap: 32px;           /* between the clock settings over the lanes (Clock, Division, Tempo, Rate, Poly) */    /* a lane's On over its Lock, then its name and routing over Len, Rate and keys (left of its steps) */

  /* Sound path: the top two rows (Play ... Body, Fold ... Master) */
  --path-top: 16px;            /* space above the first row */
  --path-row-height: 200px;    /* each row, heading included */
  --path-row-gap: 14px;        /* between the two rows */
  --path-section-gap: 24px;    /* between sections in a row (the printed line, and its arrow, sit in it) */
  --heading-gap: 4px;          /* from a section's rule to its controls */
  --play-width: 104px;
  --excite-width: 330px;       /* Body takes what's left of row 1 */
  --excite-cell-gap: 10px;     /* between Excite's two columns */
  --body-material-gap: 24px;   /* from Material to Body's groups */
  --body-group-gap: 18px;      /* between Partials, Tuning and Strike */
  --group-knob-gap: 10px;      /* between the knobs of a group (Body's) */
  --master-knob-gap: 6px;      /* between the knobs of a Master group (Grit, Stereo...) */
  --fold-width: 80px;
  --vowel-width: 200px;
  --tone-width: 64px;          /* Master takes what's left of row 2 */
  --master-pad: 0px;           /* inside Master, left and right */
  --master-group-gap: 8px;     /* between Grit, Stereo, Reverb, Output */
  --group-label-gap: 6px;      /* from a group's name (Grit, Partials...) to its knobs */

  /* Bottom row: envelopes, LFOs, routing */
  --deck-height: 240px;        /* also the keyboard drawer's height */
  --deck-top: 12px;
  --deck-bottom: 10px;
  --deck-section-gap: 22px;
  --amp-width: 184px;
  --modenv-width: 268px;
  --lfo-width: 190px;          /* Routing takes what's left */
  --env-knob-row: 70px;        /* both envelopes' knob rows (knob, name, value line), so their graphs match */

  /* Sequencer lanes */
  --step-opts-width: 28px;     /* a step's probability/ratchet column (fits "100%"), so the bar never changes width */

  /* Knobs */
  --value-room: 13px;          /* the line kept under every knob's label for its value (shown on hover or touch) */
}

* { box-sizing: border-box; }
html, body {
  margin: 0; height: 100%; overflow: hidden;   /* rule: no scrolling */
  background: var(--bg); color: var(--text); font-family: var(--sans);
  font-variant-numeric: tabular-nums;   /* every digit the same width: numbers hold still as they change */
  user-select: none; -webkit-user-select: none;
}

/* ---- Stage: fixed design size, scaled to the window ---- */
.stage-wrap { position: absolute; left: 50%; top: 0; transform-origin: top center; }
.stage {
  width: 1200px; background: var(--panel); display: flex; flex-direction: column;
  box-shadow: 0 10px 40px var(--drop);
}

/* ---- Header ---- */
.hdr {
  height: var(--header-height); flex: none; display: flex; align-items: center; justify-content: space-between; gap: var(--header-gap); padding: 0 var(--header-pad);
  background: var(--panel-2); border-bottom: 1px solid var(--edge);
}
/* Only the patch name gives way when the header runs short (it ends in …), so nothing falls off the edge. */
.hdr > * { flex-shrink: 0; }
.hdr > .hpatch { flex-shrink: 1; min-width: 0; display: flex; align-items: center; gap: var(--header-gap); }
.hpatch > .patchbar { flex-shrink: 1; min-width: 0; }
.hend { display: flex; align-items: center; gap: var(--header-end-gap); }
.wordmark { font-family: var(--wordmark); font-style: italic; font-weight: 600; font-size: 23px; line-height: 1; color: var(--accent); white-space: nowrap;
  position: relative; top: -3.2px; }  /* Bodoni sits low in its box: this centres the a's ink between the header's top and its bottom line */
/* The version, quiet beside the name (until 1.0: from then it is the wordmark's tip only), on the wordmark's baseline */
.brand { display: flex; align-items: baseline; gap: 6px; }
.version { font-family: var(--sans); font-size: 10px; letter-spacing: 0.04em; color: var(--dim); white-space: nowrap; position: relative; top: -3.2px; }
.version.expiring { color: var(--arrow); }
.version.expired { color: var(--danger); }
/* Patch bar: ◀ name ▶ ☆ Save, the name drops the patch menu */
.patchbar { display: flex; align-items: center; gap: 3px; }
.patch {
  font: inherit; font-size: 12px; color: var(--text); padding: 3px 8px 3px 10px; border: 1px solid var(--key-edge); border-radius: 2px;
  background: var(--key); cursor: pointer; display: inline-flex; align-items: center; width: 136px; min-width: 80px; flex-shrink: 1; white-space: nowrap;
}
.patchbar > * { flex-shrink: 0; }
.patchbar > .pmenu-wrap { flex-shrink: 1; min-width: 80px; display: flex; }
.pmenu-wrap > .patch { width: 136px; max-width: 100%; }
.patch .pname { overflow: hidden; text-overflow: ellipsis; }
.patch .pmod { color: var(--accent); }
.patch .caret { margin-left: auto; padding-left: 6px; color: var(--arrow); font-size: 11px; }
.rbtn.fav.on, .picon.on { color: var(--accent); }
.pmenu-wrap { position: relative; }
.pmenu {
  position: absolute; left: 0; top: calc(100% + 6px); z-index: 30; display: flex; width: 470px; height: 340px;
  background: var(--panel-2); border: 1px solid var(--key-edge); border-radius: 4px; box-shadow: 0 8px 24px var(--drop);
}
.pmenu.hidden { display: none; }
.pcats { width: 180px; flex: none; padding: 6px; border-right: 1px solid var(--edge); display: flex; flex-direction: column; gap: 1px; overflow: hidden; }
.pcat {
  font: inherit; font-size: 12px; text-align: left; background: transparent; border: 0; color: var(--text); cursor: pointer;
  padding: 4px 8px; border-radius: 3px; display: flex; justify-content: space-between; gap: 6px; white-space: nowrap;
}
.pcat:hover, .pcat.open { background: var(--hover); }
.pcat.open { color: var(--accent); }
.pcat.pback { color: var(--accent); overflow: hidden; text-overflow: ellipsis; }
.pcount { color: var(--dim); font-size: 11px; }
.psep { height: 1px; background: var(--edge); margin: 4px 2px; }
.plist { flex: 1; min-width: 0; padding: 6px; display: flex; flex-direction: column; gap: 1px; overflow-y: auto; }
.prow-item { display: flex; align-items: center; border-radius: 3px; }
.prow-item:hover { background: var(--hover); }
.prow-item.current .pitem { color: var(--accent); }
.pitem {
  flex: 1; min-width: 0; font: inherit; font-size: 12px; text-align: left; background: transparent; border: 0; color: var(--text);
  cursor: pointer; padding: 4px 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.puser { margin-left: 6px; font-size: 9.5px; color: var(--dim); font-family: var(--label); letter-spacing: 0.06em; }
.picon { font: inherit; font-size: 11px; background: transparent; border: 0; color: var(--dim); cursor: pointer; padding: 3px 5px; white-space: nowrap; }
.picon:hover { color: var(--text); }
.picon.del:hover { color: var(--danger); }
.pempty { font-size: 11px; color: var(--dim); padding: 6px; }
.psave { display: flex; flex-direction: column; gap: 8px; padding: 6px; }
.psave .saved-name { flex: none; }
.plabel { font-family: var(--label); font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--arrow); }
.pselect { font: inherit; font-size: 12px; color: var(--text); background: var(--key); border: 1px solid var(--key-edge); border-radius: 2px; padding: 3px 6px; }
.psave .rbtn { align-self: flex-start; }
.vsep { width: 1px; height: 20px; background: var(--sep); }
.level { display: flex; align-items: center; gap: 7px; font-family: var(--label); font-size: 9.5px; letter-spacing: 0.14em; color: var(--arrow); }
.led-big { width: 14px; height: 14px; border-radius: 50%; background: var(--led-off); box-shadow: inset 0 -2px 3px var(--led-shade); }
.led-big.green { background: var(--led-green); box-shadow: 0 0 9px var(--led-green-glow), inset 0 -2px 3px var(--led-shade-lit); }
.led-big.yellow { background: var(--led-yellow); box-shadow: 0 0 9px var(--led-yellow-glow), inset 0 -2px 3px var(--led-shade-lit); }
.led-big.red { background: var(--led-red); box-shadow: 0 0 10px var(--led-red-glow), inset 0 -2px 3px var(--led-shade-lit); }

/* Stage lights (Justin, Nov 2, 2026): one at each stage, where the fix is. Voices (on the
   Play heading) and Output (on Trim) are safety nets: off / green / yellow / red, stepped.
   Drive and Feedback are the sound you chose: they glow amber with the signal, a meter rather
   than a step. */
.stagelight { position: relative; width: 7px; height: 7px; border-radius: 50%; background: var(--led-off); box-shadow: inset 0 -1px 2px var(--led-shade); flex: none; cursor: help; }
.stagelight.green { background: var(--led-green); box-shadow: 0 0 6px var(--led-green-glow), inset 0 -1px 2px var(--led-shade-lit); }
.stagelight.yellow { background: var(--led-yellow); box-shadow: 0 0 6px var(--led-yellow-glow), inset 0 -1px 2px var(--led-shade-lit); }
.stagelight.red { background: var(--led-red); box-shadow: 0 0 7px var(--led-red-glow), inset 0 -1px 2px var(--led-shade-lit); }
/* A glow: an ember, with the lit amber over it at the glow's strength (--g, 0..1). The lit
   layer is composited on its own, so a light moving all the time doesn't redraw the scaled panel. */
.stagelight.glow { --g: 0; background: var(--glow-off); }
.stagelight.glow::after {
  content: ''; position: absolute; inset: 0; border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 7px var(--glow-on), 0 0 2px var(--glow-core); opacity: var(--g); will-change: opacity;
}
.knob .stagelight { position: absolute; right: -1px; top: 3px; }
.gl .stagelight { margin-left: 4px; }
/* Pointing at a light: the panel dims to the knobs that change what that light reads (and
   the light itself; a light on a bright knob stays bright). A heading dims by its colour, so
   the light on it keeps its own. */
body.fixing .panel [data-key]:not(.fix), body.fixing .panel :is(.sublabel, .gap, .xypad), body.fixing .moddeck,
body.fixing .panel :not(.fix) > .stagelight:not(.fix) { opacity: 0.22; }
body.fixing .panel .gl { color: var(--print-faded); border-bottom-color: var(--rule-faded); }

/* Buttons in the header and bars: dark keys with a thin edge, like the panel's push buttons */
.rbtn {
  font: inherit; font-family: var(--label); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 4px 8px; border-radius: 2px; cursor: pointer; white-space: nowrap;
  border: 1px solid var(--key-edge); background: var(--key); color: var(--text); display: inline-flex; align-items: center; gap: 6px;
}
.rbtn:hover { border-color: var(--key-edge-hover); }
.rbtn.prime { background: var(--accent); border-color: var(--accent); color: var(--ink); font-weight: 600; }
.rbtn.small { font-size: 10px; padding: 2px 7px; }
.rbtn:disabled { opacity: 0.35; cursor: default; }
.rbtn.blink { animation: rblink 0.8s steps(2, start) infinite; border-color: var(--accent); }
@keyframes rblink { to { background: var(--accent); color: var(--ink); } }
.rbtn .badge { font-size: 10px; background: var(--ink); color: var(--accent); border-radius: 8px; padding: 0 5px; }
.rbtn.prime .badge { background: var(--ink); color: var(--accent); }
.rbtn .badge.hidden { display: none; }
.rbtn.icon { padding: 4px 7px; }
/* ---- Icons (icons.js) ----
   In the toolbars an icon sits in its button box (as tall as the worded ones); a
   switch there fills in when on. Inside the instrument an on/off switch is the bare
   icon ("bare"): dim, or lit and glowing like the panel's lights, its click area as
   tall as Glide. Parts marked when-on / when-off show the state by shape. */
svg.ico { display: block; width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
svg.ico .f { fill: currentColor; stroke: none; }
.has-icon .when-on, .has-icon.on .when-off { display: none; }
.has-icon.on .when-on { display: inline; }
/* One height for every button; a button with an icon is square. */
.rbtn, .key, .gate.key, .gl .gate.key, .octave button, .patch {
  box-sizing: border-box; height: var(--button-size); padding-top: 0; padding-bottom: 0; line-height: 1;
}
.key, .gate.key { display: inline-flex; align-items: center; justify-content: center; }
button.has-icon:not(.bare) { width: var(--button-size); padding: 0; display: inline-grid; place-items: center; }
.key.has-icon.on { color: var(--ink); background: var(--accent); border-color: var(--accent); }
/* A mode, not an on/off switch (Uni: ± or +): the same colours either way, only the icon changes. */
.gate.key.mode.on { background: var(--key); border-color: var(--key-edge); color: var(--mode-text); box-shadow: none; }
.gate.key.mode { color: var(--mode-text); }
/* Roll: the die, with the count of rolls as a badge on its corner. */
.rbtn.has-icon { position: relative; }
.rbtn.has-icon .badge { position: absolute; z-index: 2;  /* over Clear's corner */ top: -6px; right: -7px; font-size: 9px; line-height: 13px; padding: 0 4px; border: 1px solid var(--accent); }
button.gate.key.bare {   /* "button": outranks the keys' own padding (.gl .gate.key) */
  box-sizing: border-box; width: 21px; height: 21px; padding: 0; display: grid; place-items: center;
  background: transparent; border-color: transparent; color: var(--dim);
}
button.gate.key.bare:hover { color: var(--text); border-color: transparent; }
button.gate.key.bare.on { background: transparent; border-color: transparent; box-shadow: none; color: var(--accent); filter: drop-shadow(0 0 3px var(--icon-glow)); }
.gate.key.bare svg.ico { width: 15px; height: 15px; }
.randombar { display: flex; align-items: center; gap: 4px; }
/* Header groups: a faint frame around what belongs together, its name
   printed inside like the other header labels (Level). */
.hgroup { display: flex; align-items: center; gap: 6px; height: 30px; padding: 0 4px 0 8px; border: 1px solid var(--edge); border-radius: 3px; }
.hlabel { font-family: var(--label); font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--arrow); white-space: nowrap; }
/* Get the plugin (browser version only): a link drawn as a header key, in amber */
.rbtn.buy { color: var(--accent); border-color: var(--accent-dim); text-decoration: none; }
.rbtn.buy:hover { border-color: var(--accent); }
.rbtn.panic { color: var(--danger); border-color: var(--panic-edge); }
.rbtn.panic:hover { background: var(--panic-hover); }
.rbtn.panic:active { background: var(--danger); color: var(--ink); }

/* ---- Panel groups: each section framed by its name over a rule ---- */
.panel { flex: none; padding: var(--path-top) var(--side-pad) 0; display: flex; flex-direction: column; gap: var(--path-row-gap); }
.prow { display: flex; height: var(--path-row-height); }
.grp { display: flex; flex-direction: column; min-width: 0; }
.gl {
  font-family: var(--label); font-size: 11px; font-weight: 600; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--head); display: flex; align-items: center; gap: 8px; white-space: nowrap; height: 16px; line-height: 16px; flex: none;
}
.grp > .gl, .lfo > .gl { box-sizing: content-box; padding-bottom: 2px; border-bottom: 1.5px solid var(--rule); margin-bottom: var(--heading-gap); }
.gl .gate.key { padding: 0 7px; line-height: 14px; }
.gl button.gate.key.has-icon { padding: 0; }  /* Perc, an LFO's Uni: square like every icon button */
.gl b { color: var(--accent); font-weight: 600; }
.gl b.m { color: var(--mod); }
.gl i { flex: 1; }  /* the keys in a heading (Perc, Continue, Uni) sit at its right */
/* Between sections: a printed line, with an arrow where the sound flows on. */
.gap { flex: none; width: var(--path-section-gap); position: relative; }
.gap::before, .gap::after { content: ''; position: absolute; left: calc(50% - 0.5px); width: 1px; background: var(--flow); }
.gap::before { top: 14px; bottom: 36px; }
.gap::after { display: none; }
.gap.flow::before { bottom: calc(50% + 22px); }
.gap.flow::after { display: block; top: 50%; bottom: 36px; }
.gap.flow i {
  position: absolute; left: calc(50% - 5px); top: calc(50% - 16px); width: 0; height: 0;
  border-top: 5px solid transparent; border-bottom: 5px solid transparent; border-left: 10px solid var(--arrow);
}
/* Each section's controls sit centred in the space the section has. */
.gbody { flex: 1; display: flex; align-items: center; gap: 10px; min-height: 0; }
.col { display: flex; flex-direction: column; align-items: center; gap: 6px; }
#g-play { width: var(--play-width); }
#g-play .gbody { flex-direction: column; justify-content: center; gap: 9px; }
#g-play .knobpair { display: flex; gap: 8px; align-items: flex-end; }  /* Glide and Vibrato side by side */
/* Excite: the four sources in a 2x2 grid, each a knob with its selector and the flavour names beside it. */
#g-excite { width: var(--excite-width); }
#g-excite .gbody { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; gap: 0 var(--excite-cell-gap); align-items: center; }
.cell { display: flex; align-items: center; gap: 6px; min-width: 0; }
#g-body { flex: 1; }
#g-body .gbody { gap: var(--body-material-gap); }
/* Body's seven knobs in one row, under their group names (Partials, Tuning, Strike). */
#g-body .groups { flex: 1; display: flex; align-items: flex-end; justify-content: space-between; gap: var(--body-group-gap); padding-bottom: 12px; }
#g-fold { width: var(--fold-width); }
#g-fold .gbody { flex-direction: column; justify-content: center; gap: 10px; }
#g-vowel { width: var(--vowel-width); }
#g-vowel .gbody { justify-content: center; gap: 16px; }
#g-vowel .col:last-child { gap: 10px; }
#g-tone { width: var(--tone-width); }
#g-tone .gbody { justify-content: center; }
#g-master { flex: 1; }
/* Master's groups sit as Body's do: centred, with the same room under them for a hovered value. */
#g-master .subrow { gap: var(--master-knob-gap); }
#g-master .gbody { justify-content: space-between; align-items: center; gap: var(--master-group-gap); padding: 0 var(--master-pad) 12px; }
/* A group of knobs (Body's Partials, Master's Grit...): a small printed name under a rule. */
.sub { display: flex; flex-direction: column; justify-content: center; gap: var(--group-label-gap); }
.sublabel {
  font-family: var(--label); font-size: 8.5px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--arrow);
  text-align: center; border-top: 1px solid var(--key-edge); padding-top: 4px; white-space: nowrap;
}
.subrow { display: flex; align-items: center; justify-content: center; gap: var(--group-knob-gap); }

/* ---- Knob: a printed tick scale, an aluminium body with a knurled rim, a black top and a white pointer ---- */
.knob { position: relative; display: flex; flex-direction: column; align-items: center; cursor: ns-resize; touch-action: none; }
.knob svg { display: block; overflow: visible; }
.k-tick { stroke: var(--knob-tick); }
.k-mod { stroke: var(--mod); }
.k-body { fill: url(#al); stroke: var(--knob-edge); stroke-width: 1; filter: drop-shadow(0 2px 3px var(--knob-shadow)); }
.k-knurl { stroke: var(--knob-knurl); }
.k-top { fill: var(--knob-top); stroke: var(--knob-top-edge); stroke-width: 0.8; }
.k-pointer { stroke: var(--head); }
.k-live { stroke: var(--mod); }
.k-live-dot { fill: var(--mod-text); filter: drop-shadow(0 0 2px var(--mod)); }
.knob .detent { fill: var(--print); font-family: var(--label); font-size: 9px; font-weight: 500; letter-spacing: 0.1em; cursor: pointer; text-transform: uppercase; }
.knob .detent:hover, .knob .detent.active { fill: var(--accent); }
.knob .label { font-family: var(--label); font-size: 9.5px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--print); white-space: nowrap; line-height: 1.3; margin-top: 2px; }
/* The value, in amber under the knob, only while it's touched or hovered. */
/* Every knob keeps the room for it under its label, so a value never lands on the knob below. */
.knob { padding-bottom: var(--value-room); }
.knob .value {
  position: absolute; left: 50%; bottom: 0; transform: translateX(-50%); pointer-events: none;
  font-size: 11px; color: var(--accent); white-space: nowrap; line-height: 1.1; opacity: 0;
}
.knob:hover .value, .knob.touched .value { opacity: 1; pointer-events: auto; }
.knob.inactive { opacity: 0.35; }
.value-input {
  width: 64px; font: inherit; font-size: 11px; text-align: center; color: var(--text);
  background: var(--key); border: 1px solid var(--accent); border-radius: 2px; padding: 0 2px;
}
.knob .value-input { position: absolute; left: 50%; bottom: -1px; transform: translateX(-50%); z-index: 3; }

/* ---- Selector: a small rotary switch, its positions fanning toward their printed names ---- */
.stepper { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.dialsel { display: flex; align-items: center; gap: 5px; }
.dialsel svg { display: block; overflow: visible; flex: none; cursor: pointer; }
.stepper .opts { display: flex; flex-direction: column; }
.stepper .opt {
  display: inline-flex; align-items: center; gap: 3px; cursor: pointer; white-space: nowrap;
  font-family: var(--label); font-size: 8.5px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--dim); line-height: 13px;
}
.stepper .opt.on { color: var(--head); }
/* The voice limit, printed on the Poly position. */
.voice-limit { cursor: ns-resize; }
.voice-limit .chip { display: inline-block; box-sizing: content-box; width: 2.3ch; text-align: left; font-family: var(--label); font-size: 8.5px; letter-spacing: 0.1em; padding: 0 2px; color: inherit; }
.stepper .label { font-family: var(--label); font-size: 9.5px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--print); white-space: nowrap; line-height: 1.3; }
.gate.key { flex: none; min-height: 0; }
.key, .gate.key, .pill {
  font-family: var(--label); font-size: 9.5px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; cursor: pointer; white-space: nowrap;
  padding: 2px 8px; border-radius: 2px; background: var(--key); border: 1px solid var(--key-edge); color: var(--key-text);
}
.key:hover, .pill:hover { border-color: var(--key-edge-hover); }
.gate.key.on, .pill.on { color: var(--ink); background: var(--accent); border-color: var(--accent); box-shadow: 0 0 6px var(--key-glow); }
/* A push button with an LED (Legato): the key stays dark, its LED lights. */
.key.push { gap: 6px; padding: 0 9px; color: var(--print); }
.key.push .led { width: 5px; height: 5px; border-radius: 50%; background: var(--key-led-off); flex: none; }
.gate.key.push.on { color: var(--print); background: var(--key); border-color: var(--key-edge); box-shadow: none; }
.gate.key.push.on .led { background: var(--accent); box-shadow: 0 0 5px var(--key-led-glow); }

/* ---- Screens: black glass in a bezel (the vowel pad, the routing, the envelopes' graphs, the small choice screens) ---- */
.oled, .xypad, .screen, .envgraph, .sscreen { background: var(--oled-bg); border: 1px solid var(--key-edge); border-radius: 2px; box-shadow: inset 0 0 0 1px var(--screen-inset); }

/* ---- Vowel pad ---- */
.xypad {
  position: relative; width: 120px; height: 120px; flex: none; cursor: crosshair; touch-action: none;
  font-family: var(--screen); font-variation-settings: 'ELSH' 0; color: var(--oled);   /* ELSH 0: round dots */
  text-shadow: 0 0 4px var(--oled-glow);
}
.xypad .vowel { position: absolute; transform: translate(-50%, -50%); font-size: var(--screen-size); opacity: 0.5; pointer-events: none; }
.xypad .dot {
  position: absolute; width: 10px; height: 10px; margin: -5px 0 0 -5px; border-radius: 50%;
  background: var(--oled); box-shadow: 0 0 8px var(--oled); pointer-events: none;
}
.xypad .dot.base { background: transparent; box-shadow: none; border: 1.5px solid var(--oled); opacity: 0.7; }
.xypad .live {
  position: absolute; width: 10px; height: 10px; margin: -5px 0 0 -5px; border-radius: 50%;
  background: var(--mod); box-shadow: 0 0 8px var(--mod); pointer-events: none;
}
.xypad .live[hidden] { display: none; }
.xypad .ghost { position: absolute; border: 1px dashed var(--mod); border-radius: 3px; pointer-events: none; min-width: 2px; min-height: 2px; }
/* Vowel X and Y under the pad (the readings are words: Back 20 · Open 20), only while the pad is touched or hovered; out of the layout, like a knob's value. */
.col.pad { position: relative; }
.xy-values {
  position: absolute; left: 50%; bottom: -17px; transform: translateX(-50%);
  display: flex; align-items: center; gap: 5px; font-size: 11px; color: var(--accent); white-space: nowrap; line-height: 1.2; opacity: 0;
}
.xypad:hover ~ .xy-values, .xy-values:hover, .xy-values.touched { opacity: 1; }
.xy-values .sep { color: var(--dim); }
/* Room for "Closed 100", so nothing shifts as the reading changes. */
.xy-values .chip { display: inline-block; box-sizing: border-box; min-width: calc(10ch + 6px); text-align: center; }
.chip { font-size: 11px; font-variant-numeric: tabular-nums; color: var(--text); padding: 0 3px; border-radius: 2px; }
.chip:hover { background: var(--chip-hover); }
.xy-values .chip { color: var(--accent); }

/* ---- Mod deck ---- */
.moddeck { flex: none; height: var(--deck-height); display: flex; gap: var(--deck-section-gap); padding: var(--deck-top) var(--side-pad) var(--deck-bottom); min-height: 0; }
#g-amp { width: var(--amp-width); }
#g-menv { width: var(--modenv-width); }
#g-lfos { width: var(--lfo-width); }
#g-routing { flex: 1; }
#ampenv, #modenv { flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 12px; padding-top: 2px; }
#ampenv .envgraph, #modenv .envgraph { min-height: 0; }
/* Both knob rows the same height (Mod env's knobs are smaller), so the two graphs match; the values show in the room under the labels. */
#ampenv .knobrow, #modenv .knobrow { height: var(--env-knob-row); flex: none; align-items: flex-start; }

.envgraph { width: 100%; height: 84px; flex: 1; display: block; }
.envgraph .shape { stroke: var(--oled); stroke-width: 1.8; vector-effect: non-scaling-stroke; filter: drop-shadow(0 0 2px var(--oled-line-glow)); }
.envgraph .hold { stroke: var(--accent-dim); stroke-width: 5; vector-effect: non-scaling-stroke; }
.envgraph .zero { stroke: var(--oled-zero); stroke-dasharray: 3 3; vector-effect: non-scaling-stroke; }
.knobrow { display: flex; justify-content: space-between; }
/* Seven readings side by side: a size smaller, or "830 ms" runs into "−100". */
#modenv .knob .value { font-size: 9.5px; }
#lfos { flex-direction: column; align-items: stretch; justify-content: space-between; gap: 6px; }
.lfo { display: flex; flex-direction: column; gap: 4px; }
.lfo > .gl { margin-bottom: 2px; }
.screensel { display: flex; gap: 4px; }
/* A choice on a small screen like the routing screen's (an LFO's shape: the wave, then its name; the sequencer's Division). */
.sscreen {
  box-sizing: border-box; height: var(--button-size); display: flex; align-items: center; gap: 4px; padding: 0 7px; color: var(--oled);
  font-family: var(--screen); font-variation-settings: 'ELSH' 0; font-size: var(--screen-size); text-transform: uppercase;
  text-shadow: 0 0 4px var(--oled-glow);
}
.spic { width: var(--button-size); padding: 0; justify-content: center; flex: none; }
.spic svg { width: 16px; height: 10px; filter: drop-shadow(0 0 2px var(--oled-line-glow)); }
.spic svg path { fill: none; stroke: currentColor; stroke-width: 1.4; }
.sname { flex: 1; min-width: 0; padding: 0; gap: 0; }
.sname:hover { border-color: var(--key-edge-hover); }
/* ‹ and ›: step back and on; the name between them drops the list. */
.sarrow {
  flex: none; width: 20px; height: 100%; padding: 0; border: 0; background: transparent; cursor: pointer;
  font: inherit; color: inherit; text-shadow: inherit; opacity: 0.7;
}
.sarrow:hover { opacity: 1; }
.sselect {
  flex: 1; min-width: 0; height: 100%; padding: 0; border: 0; background: transparent; cursor: pointer; appearance: none; -webkit-appearance: none;
  font: inherit; color: inherit; text-shadow: inherit; text-transform: inherit; text-align: center; text-align-last: center;
}
.sselect option { color: var(--text); background: var(--option-bg); text-transform: none; }
/* An LFO in one row: its shape screens over Shared / Per-note, its Rate knob beside them. */
.lfo-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.lfo-how { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.lfo-how .stepper { align-items: flex-start; }

/* Routing screen */
.screen {
  flex: 1; min-height: 0; padding: 8px 12px;
  font-family: var(--screen); font-variation-settings: 'ELSH' 0; font-size: var(--screen-size); color: var(--oled); text-shadow: 0 0 4px var(--oled-glow);
  display: flex; flex-direction: column;
}
.screen .shead { letter-spacing: 0.1em; opacity: 0.65; display: grid; grid-template-columns: var(--slot-columns); gap: 5px; margin-bottom: 4px; }
.screen .shead > :last-child { padding-left: 6px; text-align: center; }  /* RANGE: over the signs, as its rows centre on them */
.slot {
  display: grid; grid-template-columns: var(--slot-columns);
  gap: 5px; align-items: center; flex: 1; min-height: 0;
}
.slot .n {  /* the number: switches the routing on and off */
  font: inherit; color: inherit; text-shadow: inherit; background: none; border: 0; padding: 0;
  opacity: 0.55; text-align: right; cursor: pointer;
}
.slot .n:hover { opacity: 1; }
.slot.off .n { text-decoration: line-through; }
.slot .arrow { opacity: 0.55; }
.slot select, .slot select.target {
  font: inherit; color: var(--oled); background: transparent; border: 0; border-bottom: 1px solid var(--oled-rule); border-radius: 0;
  padding: 0; text-transform: uppercase; letter-spacing: 0.03em; min-width: 0; width: 100%; text-shadow: inherit; cursor: pointer;
}
.slot select option, .slot select optgroup { color: var(--text); background: var(--option-bg); text-transform: none; }
.slot .lands { display: grid; grid-template-columns: minmax(0, 1fr) 2.4em minmax(0, 1fr); align-items: center; padding-left: 6px; }
.slot .lands > * { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.slot .lands .from { text-align: right; }
.slot .lands .dir { text-align: center; }
/* The amount: the screen's own small dial (no metal), in the screen's colour. */
.slot .knob { position: relative; flex-direction: row; gap: 3px; padding-bottom: 0; cursor: ns-resize; }
.slot .knob .label { display: none; }
.slot .knob .value { display: none; }  /* the amount shows as where it lands (Range); Cmd/Ctrl-click types one */
.slot .knob .value-input { position: absolute; left: -6px; top: 50%; bottom: auto; transform: translateY(-50%); width: 52px; z-index: 3; }
.slot .knob .k-tick { stroke: var(--oled-knob-tick); }
.slot .knob .k-cap { fill: var(--oled-knob-cap); stroke: var(--oled-knob-edge); stroke-width: 1; }
.slot .knob .k-pointer { stroke: var(--oled); }
.slot.empty { opacity: 0.4; }

/* ---- Sequencer bar and lanes drawer ---- */
.seqbar {
  flex: none; height: var(--seqbar-height); display: flex; align-items: center; gap: 14px; padding: 0 var(--side-pad);
  background: var(--panel-2); border-top: 1px solid var(--edge);
}
.seqbar .lbl { font-family: var(--label); font-size: 9.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--arrow); white-space: nowrap; }
/* The tip line: what's under the mouse, in the bar's free middle (two lines at most). */
.seqbar .tipline {
  flex: 1; min-width: 0; font-size: 11px; line-height: 1.3; color: var(--text);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.seqbar .tipline b { font-weight: 600; color: var(--accent); }
.seqbar .tipline.idle { color: var(--mod-text); font-size: 10.5px; }
.seqbar .tipline.how { color: var(--dim); }
.trigs { display: flex; gap: 4px; align-items: center; }
.seqbar .trigwrap { display: flex; align-items: center; gap: 8px; }
.trigs > span { width: 14px; height: 14px; border-radius: 2px; background: var(--step-off); border: 1px solid var(--key-edge); }
.trigs > span.gate { background: var(--accent-dim); }
.trigs > span.now { border-color: var(--accent); box-shadow: 0 0 6px var(--step-now-glow); }
.trigs > span.gate.now { background: var(--accent); }
/* A ratcheted step: one bar per hit. */
.trigs > span.ratchet { display: flex; gap: 1px; padding: 1px; background: var(--step-off); }
.trigs > span.ratchet i { flex: 1; border-radius: 1px; background: var(--accent-dim); }
.trigs > span.ratchet.now i { background: var(--accent); }
.drawer { flex: none; background: var(--panel); border-top: 1px solid var(--edge); padding: 10px var(--side-pad) 12px; }
.drawer.hidden, #lanes-drawer.hidden, #keys-drawer.hidden { display: none; }  /* the ids set their own display */
/* The lanes take the sound path's place, at its height. */
#lanes-drawer { height: calc(var(--path-top) + 2 * var(--path-row-height) + var(--path-row-gap)); display: flex; flex-direction: column; gap: 6px; }
.transport { display: flex; align-items: flex-start; gap: var(--clock-gap); }
/* Every clock setting the same way: its name above, the control under it. Clock and
   Poly are LED keys; Division, Tempo and Rate are small screens (Division steps with
   ‹ ›; Tempo and Rate are readouts you drag, scroll or type into). */
.transport .lbl { font-family: var(--label); font-size: 9.5px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--print); white-space: nowrap; }
.transport .col { align-items: flex-start; gap: 5px; }
.transport .keysel { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; }
.transport .keysel .label { font-family: var(--label); font-size: 9.5px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--print); white-space: nowrap; }
.transport .keys { display: flex; gap: 3px; }
.transport .sname { width: 100px; }
.transport .chipctl { flex-direction: column; align-items: flex-start; gap: 5px; }
.transport .chipctl .label { letter-spacing: 0.12em; }
.transport .chipctl .chip {
  box-sizing: border-box; height: var(--button-size); min-width: 78px; padding: 0 8px; display: flex; align-items: center; justify-content: center;
  background: var(--oled-bg); border: 1px solid var(--key-edge); border-radius: 2px; box-shadow: inset 0 0 0 1px var(--screen-inset);
  font-family: var(--screen); font-variation-settings: 'ELSH' 0; font-size: var(--screen-size); color: var(--oled); text-shadow: 0 0 4px var(--oled-glow);
}
.transport .chipctl .chip:hover { border-color: var(--key-edge-hover); }
.transport .chipctl .value-input { width: 78px; }

.lanes { flex: 1; display: grid; grid-template-rows: auto repeat(5, minmax(0, 1fr)); gap: 4px; min-height: 0; }
.lane { display: grid; grid-template-columns: var(--lane-head-width) repeat(8, minmax(0, 1fr)); gap: 4px; min-height: 0; }
.lane.numbers .step-num { font-family: var(--label); font-size: 9.5px; color: var(--dim); text-align: center; }
.lane-head { display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-rows: auto auto; column-gap: 10px; row-gap: 7px; align-content: center; min-width: 0; }
.lane-line { display: flex; align-items: center; gap: 10px; min-width: 0; }
/* Len, Depth, Rate, Glide, Uni in fixed columns: they line up down the lanes (Trig too), whatever Depth reads. */
.lane-how { display: grid; grid-template-columns: var(--lane-how-columns); gap: 8px; }
.lane-switches { grid-row: 1 / span 2; align-self: center; display: flex; flex-direction: column; align-items: center; gap: 2px; }  /* On over Lock, centred on the two lines */
.lane-title { flex: none; font-family: var(--label); font-size: 10px; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; color: var(--head); }
.lane-routes { flex: 1; min-width: 0; font-size: 11px; color: var(--mod-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lane-routes.none { color: var(--dim); }
.step { display: flex; align-items: stretch; gap: 3px; min-height: 0; background: var(--panel-2); border: 1px solid transparent; border-radius: 3px; padding: 2px 3px; }
.step.now { border-color: var(--accent); }
.step.beyond { opacity: 0.25; }
.step.muted, .step.off { opacity: 0.45; }  /* a lane not routed, or switched off */
.step-opts { flex: none; width: var(--step-opts-width); display: flex; flex-direction: column; justify-content: space-between; align-items: flex-end; }
.step-opts .chip { font-size: 9.5px; color: var(--dim); }
.chipctl { display: flex; align-items: center; gap: 4px; cursor: ns-resize; touch-action: none; }
.chipctl .label { font-family: var(--label); font-size: 9.5px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--print); }
.chipctl.changed .chip { color: var(--text); }
.stepbar { flex: 1; display: flex; min-height: 0; }
.stepbar .track { position: relative; flex: 1; min-height: 0; cursor: ns-resize; touch-action: none; background: var(--oled-bg); border: 1px solid var(--edge); border-radius: 2px; }
.stepbar .mid { position: absolute; left: 0; right: 0; top: 50%; border-top: 1px solid var(--step-mid); }
.stepbar .fill { position: absolute; left: 2px; right: 2px; background: var(--accent); opacity: 0.55; border-radius: 2px; }
.stepbar .chip { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 10px; pointer-events: none; text-shadow: 0 0 3px var(--step-text-shadow); white-space: nowrap; overflow: hidden; }
.gate { flex: 1; min-height: 0; cursor: pointer; border: 1px solid var(--edge); border-radius: 2px; background: var(--oled-bg); }
.gate.on { background: var(--accent); border-color: var(--accent); }
.gate.on.ratchet { display: flex; gap: 3px; padding: 0; border: 0; background: transparent; }
.gate.ratchet i { flex: 1; border-radius: 2px; background: var(--accent); }
select.target {
  font: inherit; font-size: 11px; color: var(--text); background: var(--key); border: 1px solid var(--key-edge); border-radius: 2px; padding: 2px 4px;
}

/* ---- Keys drawer ---- */
#keys-drawer { height: var(--deck-height); display: grid; grid-template-columns: auto auto 1fr auto; gap: 14px; align-items: center; }
.octave { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--print); }
.octave button { width: 24px; height: 24px; border-radius: 2px; border: 1px solid var(--key-edge); background: var(--key); color: var(--text); cursor: pointer; }
.hint { font-size: 10.5px; color: var(--dim); line-height: 1.5; text-align: right; }
.keyboard { position: relative; height: 84px; display: flex; touch-action: none; }
.keyboard .white { flex: 1; background: var(--white-key); border: 1px solid var(--white-key-edge); border-radius: 0 0 4px 4px; margin: 0 1px; }
.keyboard .black { position: absolute; top: 0; height: 58%; background: var(--black-key); border-radius: 0 0 3px 3px; z-index: 1; }
.keyboard .down.white { background: var(--white-key-down); }
.keyboard .down.black { background: var(--accent-dim); }
.modwheel { position: relative; width: 26px; height: 84px; border-radius: 4px; cursor: ns-resize; touch-action: none; background: var(--panel-2); border: 1px solid var(--key-edge); overflow: hidden; }
.modwheel .fill { position: absolute; left: 0; right: 0; bottom: 0; background: var(--accent-dim); }
.modwheel .label { position: absolute; left: 0; right: 0; top: 4px; text-align: center; font-family: var(--label); font-size: 9px; text-transform: uppercase; color: var(--print); pointer-events: none; }

/* ---- Smart Random: select mode and the saved-selections menu ---- */
body.selecting [data-key], body.selecting [data-keys] { cursor: copy !important; }
body.selecting .gl, body.selecting .sublabel, body.selecting .lane-title, body.selecting .slot .n { cursor: copy; }
body.selecting .gl, body.selecting .sublabel { text-decoration: underline dotted; }
body.selecting .rsel { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
body:not(.selecting) .rsel { outline: 1px dashed var(--selected-outline); outline-offset: 2px; border-radius: 4px; }
/* A knob's selection box: round the knob, its ticks and its name (not the empty value line). */
.knob.rsel { outline: none !important; }
.knob.rsel::after { content: ''; position: absolute; left: -3px; right: -3px; top: -3px; bottom: calc(var(--value-room) - 3px); border-radius: 4px; pointer-events: none; }
body.selecting .knob.rsel::after { border: 2px solid var(--accent); }
body:not(.selecting) .knob.rsel::after { border: 1px dashed var(--selected-outline); }
.slot .knob.rsel::after, .knob.mini.rsel::after { bottom: -3px; }
.saved-wrap { position: relative; }
.saved-menu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 20; width: 240px; padding: 8px;
  background: var(--panel-2); border: 1px solid var(--key-edge); border-radius: 4px; box-shadow: 0 8px 24px var(--drop);
  display: flex; flex-direction: column; gap: 6px;
}
.saved-menu.hidden { display: none; }
.saved-row { display: flex; gap: 6px; }
.saved-name { flex: 1; min-width: 0; font: inherit; font-size: 12px; color: var(--text); background: var(--key); border: 1px solid var(--key-edge); border-radius: 2px; padding: 3px 6px; }
.saved-empty { font-size: 11px; color: var(--dim); }
.saved-item { display: flex; align-items: center; }
.saved-use, .saved-del { font: inherit; font-size: 12px; background: transparent; border: 0; color: var(--text); cursor: pointer; padding: 4px 6px; }
.saved-use { flex: 1; text-align: left; border-radius: 3px; }
.saved-use:hover { background: var(--hover); }
.saved-del { color: var(--dim); }
.saved-del:hover { color: var(--danger); }
/* Random's Depth, in the header: a knob on its side, its value always showing (it's a toolbar, not the panel). */
.knob.mini { flex-direction: row; gap: 5px; cursor: ns-resize; padding-bottom: 0; }
.knob.mini .label { order: -1; margin: 0; }
.knob.mini .value { position: static; transform: none; opacity: 1; pointer-events: auto; color: var(--text); min-width: 32px; text-align: left; }
.knob.mini .value-input { position: static; transform: none; width: 44px; }
.hvolume .knob.mini .value { min-width: var(--header-volume-value); }

/* ---- Start overlay ---- */
.overlay { position: fixed; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; background: var(--overlay); z-index: 10; }
.overlay button { font: inherit; font-size: 16px; padding: 14px 26px; border-radius: 6px; cursor: pointer; background: var(--accent); color: var(--ink); border: 0; font-weight: 600; }
.overlay.hidden { display: none; }
.error { color: var(--danger); max-width: 520px; text-align: center; font-size: 13px; }
.inactive { opacity: 0.35; }

/* The ≡ menu (settings) */
.menu-wrap { position: relative; display: flex; }  /* not a line box: ≡ sits level with ◀ */
.hmenu {
  position: absolute; left: 0; top: calc(100% + 6px); z-index: 20; min-width: 250px; padding: 10px 12px;
  background: var(--panel-2); border: 1px solid var(--key-edge); border-radius: 4px; box-shadow: 0 8px 24px var(--drop);
  display: flex; flex-direction: column; gap: 8px;
}
.hmenu.hidden { display: none; }
.menu-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.menu-label { font-size: 12px; color: var(--print); }
.choices { display: flex; gap: 3px; }
.rbtn.choice.on { background: var(--accent); border-color: var(--accent); color: var(--ink); }

/* ---- The drawers take space from the panel (Justin: "B", Oct 19, 2026) ----
   The lanes take the sound path's place (the routing stays under them); the
   keys take the bottom row's place, and get the whole row. */
.stage .hdr { order: 0; }
.stage .panel { order: 1; }
.stage .moddeck { order: 2; }
.stage .seqbar { order: 3; }
#lanes-drawer { order: 1; border-top: none; padding-top: var(--path-top); }
#keys-drawer { order: 2; border-top: none; }  /* the bottom row's height */
.lanes-open .panel { display: none; }
.keys-open .moddeck { display: none; }
#keys-drawer .keyboard, #keys-drawer .modwheel { height: 196px; }
#keys-drawer .hint { max-width: 230px; }
.lane-head select.rate { width: 50px; flex: none; font-size: 10.5px; }  /* a lane's Rate */
.stepbar.uni .mid { display: none; }  /* a Uni lane: no centre line, bars rise from the bottom */
