/* Стойка и контролы редизайна (дизайн-система, docs/design/system/). Подключается после style.css */
/* Клавиша со светодиодом в лунке (карточка Key): обод выпуклый, лицо вогнутое; нажатая — ниже на 0,5 px и светодиод горит.
   .row — ряд формы волны 44 × 32, светодиод под значком; .power — включение 28 × 20, только светодиод */
.well{display:inline-flex;flex:none;padding:2px;border-radius:var(--radius-10);background:var(--well);box-shadow:var(--shadow-well)}
.well:has(:focus-visible){outline:2px solid var(--accent-text);outline-offset:2px}
.key{position:relative;box-sizing:border-box;width:56px;height:var(--size-key);padding:0;border:1px solid transparent;border-radius:var(--radius-8);
  display:flex;align-items:center;justify-content:center;gap:6px;font:400 var(--fs-micro)/14px var(--sans);color:var(--text-2);cursor:pointer;
  background:linear-gradient(var(--light-concave),var(--keycap-hi),var(--keycap) 55%,var(--keycap-lo)) padding-box,
    linear-gradient(var(--light-convex),var(--keycap-rim-hi),var(--keycap-rim) 50%,var(--keycap-rim-lo)) border-box;
  box-shadow:var(--shadow-key)}
/* Без :has — обводка остаётся у самой клавиши */
@supports selector(:has(*)){.key:focus-visible{outline:none}}
@media(hover:hover){.key:hover:not(:disabled){background:linear-gradient(var(--light-concave),var(--keycap-hover-hi),var(--keycap) 55%,var(--keycap-lo)) padding-box,
  linear-gradient(var(--light-convex),var(--keycap-rim-hover),var(--keycap-rim) 50%,var(--keycap-rim-lo)) border-box}}
.key[aria-pressed=true],.key[aria-checked=true]{transform:translate(-0.5px,0.5px);color:var(--text);box-shadow:var(--shadow-key-pressed)}
.well:has(.key:disabled){opacity:var(--opacity-off)}
.key:disabled{cursor:default}
.key.row{width:44px;height:var(--size-key-row);flex-direction:column-reverse;gap:3px}
.key.power{width:28px;height:var(--size-key-power)}
.key svg{flex:none;width:24px;height:12px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;overflow:visible}
.led{flex:none;width:var(--size-led);height:var(--size-led);border-radius:50%;background:var(--led-off);box-shadow:var(--shadow-led-off)}
.key[aria-pressed=true] .led,.key[aria-checked=true] .led{background:var(--led-on);box-shadow:var(--shadow-led)}
.keys{display:flex;justify-content:space-between;gap:4px}
/* В блоке 208 лунки по 48 — по краям; в более узком блоке (FM, эффекты) клавиши сжимаются вместе с лункой */
.keys .well{flex:0 1 48px;min-width:0}
.keys .key{width:100%}
/* Палец: зона касания 44 px вокруг клавиши */
@media(pointer:coarse){.key::before{content:'';position:absolute;inset:50% auto auto 50%;width:var(--size-touch);height:var(--size-touch);
  transform:translate(-50%,-50%)}
  .keys .key::before{width:calc(100% + 4px)}
  /* Октава: в лунке зона касания — сама лунка (иначе окно закрывает точки), у ▲ ▼ — не заходит в лунку */
  .oct-rail .key::before{content:none}
  .key.oct-step::before{height:28px}}
/* Ручка (карточка Knob): ячейка 64 — шкала из 11 точек (SVG, r 28), ободок 38 выпуклый, лицо 35 с риской; подпись и значение под ней.
   input прозрачный поверх ручки — фокус и клавиши его, указатель ловит ручка (knob.js). Пока тянут — точки до значения горят */
.knobs{display:grid;grid-template-columns:repeat(3,var(--grid-knob-col));gap:var(--space-8);align-items:start}
.knob{position:relative;display:flex;flex-direction:column;align-items:center;gap:2px;min-width:0}
.knob input[type=range]{position:absolute;top:0;left:50%;width:var(--grid-knob-col);height:var(--grid-knob-col);margin:0 0 0 calc(var(--grid-knob-col) / -2);
  opacity:0;pointer-events:none}
.knob-dial{position:relative;flex:none;width:var(--grid-knob-col);height:var(--grid-knob-col);cursor:ns-resize;touch-action:none}
.knob-dial svg{position:absolute;inset:0;overflow:visible;fill:none;stroke:var(--tick);stroke-width:2.5;stroke-linecap:round}
.knob[data-drag] .knob-lit{stroke:var(--accent)}
.knob-cap{position:absolute;inset:calc((var(--grid-knob-col) - var(--size-knob)) / 2);padding:1.5px;border-radius:50%;box-sizing:border-box;
  background:linear-gradient(var(--light-convex),var(--knob-rim-hi),var(--knob-rim) 50%,var(--knob-rim-lo));box-shadow:var(--shadow-raised)}
.knob[data-drag] .knob-cap{box-shadow:var(--shadow-raised-pressed)}
@media(hover:hover){.knob-dial:hover .knob-cap{background:linear-gradient(var(--light-convex),var(--knob-rim-hover),var(--knob-rim) 50%,var(--knob-rim-lo))}}
.knob input:focus-visible+.knob-dial .knob-cap{outline:2px solid var(--accent-text);outline-offset:2px}
.knob-face{display:block;position:relative;height:100%;border-radius:50%;background:var(--knob)}
.knob-face::before{content:'';position:absolute;top:1.5px;left:calc(50% - 1px);width:2px;height:8px;border-radius:1px;background:var(--knob-mark)}
.knob label{font-size:var(--fs-micro);line-height:14px;color:var(--text-2);white-space:nowrap}
.knob output{font-size:var(--fs-body);line-height:16px;color:var(--text);font-variant-numeric:tabular-nums;white-space:nowrap}
/* Шаговая ручка (карточка StepKnob): риски 1,5 у положений (r 24 → 29) вместо точек, риска на ручке длиннее — 2 × 12 */
.knob.step .knob-dial svg{stroke-width:1.5}
.knob.step .knob-face::before{height:12px}
/* Слайдеры со световодом (карточки Fader, Slider) — родной input range: канал и трубка — дорожка (--track-bg), колпачок — бегунок
   (--cap-bg), риски — фон input; --track-bg и --cap-bg заданы один раз на input для -webkit- и -moz-. Светится часть трубки до колпачка:
   --f — доля хода (showSlider, controls.js). --thumb — длина колпачка по ходу (её читает resetOnDouble). Трубка короче канала
   на 5 px с концов */
.fader input[type=range],.slider input[type=range]{--f:0;--halo:color-mix(in srgb,var(--glow) 45%,transparent);
  --halo-edge:color-mix(in srgb,var(--glow) 25%,transparent);-webkit-appearance:none;appearance:none;margin:0;background-repeat:no-repeat}
.fader input[type=range]::-moz-range-progress,.slider input[type=range]::-moz-range-progress{background:transparent}
.fader input[type=range]::-webkit-slider-runnable-track,.slider input[type=range]::-webkit-slider-runnable-track{background:var(--track-bg)}
.fader input[type=range]::-moz-range-track,.slider input[type=range]::-moz-range-track{background:var(--track-bg)}
.fader input[type=range]::-webkit-slider-thumb,.slider input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;
  box-sizing:border-box;box-shadow:var(--shadow-raised);background:var(--cap-bg)}
.fader input[type=range]::-moz-range-thumb,.slider input[type=range]::-moz-range-thumb{box-sizing:border-box;box-shadow:var(--shadow-raised);
  background:var(--cap-bg)}
.fader input[type=range]:focus-visible,.slider input[type=range]:focus-visible{outline:2px solid var(--accent-text);outline-offset:2px}
/* Fader — ячейка 48 × 136: input 44 × 120, канал 10 × 120, ход 112, трубка 3 × 110, колпачок серый 28 × 8. Риски слева — у центра
   колпачка на каждой десятой хода (4 + 11,2 · i от верха), каждая пятая длиннее. Свет — от низа трубки до низа колпачка:
   f · 112 − 5 (112 = 100 % трубки + 2 px); под нитью — ореол glow (полоса 5, размытие 1,5, прозрачность 0,5 на карточке —
   здесь поперечным градиентом шириной 10). Касание двигает фейдер, а не страницу */
.faders{display:flex;justify-content:space-between}
.fader{display:flex;flex-direction:column;align-items:center;gap:2px;width:48px;min-width:0}
.fader label{font-size:var(--fs-micro);line-height:14px;color:var(--text-2);white-space:nowrap}
.fader output{font-size:var(--fs-body);line-height:16px;color:var(--text);font-variant-numeric:tabular-nums;white-space:nowrap}
.fader input[type=range]{--thumb:8px;width:44px;height:120px;margin:8px 0;writing-mode:vertical-lr;direction:rtl;touch-action:none;
  background-image:repeating-linear-gradient(transparent 0 3.25px,var(--tick) 3.25px 4.75px,transparent 4.75px 11.2px),
    repeating-linear-gradient(transparent 0 3.25px,var(--tick) 3.25px 4.75px,transparent 4.75px 56px);
  background-size:6px 120px,10px 120px;background-position:6px 0,2px 0;
  --track-bg:linear-gradient(to top,var(--glow-core) calc(var(--f) * (100% + 2px) - 5px),transparent 0) 50% 50% / 3px calc(100% - 10px)
    no-repeat,linear-gradient(to right,transparent,var(--halo-edge) 2.5px,var(--halo) 5px,var(--halo-edge) 7.5px,transparent)
    50% calc(100% - 5px) / 10px max(0px,calc(var(--f) * (100% - 8px) - 3px)) no-repeat,
    linear-gradient(var(--guide-unlit),var(--guide-unlit)) 50% 50% / 3px calc(100% - 10px) no-repeat,
    linear-gradient(to right,var(--hole-lit),var(--slot) 40%,var(--slot-deep));
  --cap-bg:linear-gradient(var(--cap-groove),var(--cap-groove)) center / 24px 1.5px no-repeat,
    linear-gradient(var(--light-convex),var(--cap-hi),var(--cap) 50%,var(--cap-lo))}
.fader input[type=range]::-webkit-slider-runnable-track{width:10px;height:100%;border-radius:5px}
.fader input[type=range]::-moz-range-track{width:10px;height:100%;border-radius:5px}
.fader input[type=range]::-webkit-slider-thumb{width:28px;height:8px;margin:0 0 0 -9px;border:0;border-radius:2px}
.fader input[type=range]::-moz-range-thumb{width:28px;height:8px;border:0;border-radius:2px}
/* Slider (по SVG карточки, ширина 208) — последней строкой блока: подпись и значение над каналом; ряд 40, ось канала на 19.
   input — сам канал 10 с отступом 6 от краёв (ширина − 12), трубка 3 с отступом 5 внутри канала. Колпачок акцентный 28 × 20:
   ободок 2, лицо вогнутое; на карточке он ходит 8…ширина − 36 (на 2 внутри канала), у родного — от края до края канала:
   сдвиг 2 − 4f. Свет — до колпачка без 2: f · (ход) − 5 от начала трубки (ход = 100 % трубки − 22 px), под ним ореол.
   Ореол на 2 длиннее нити — его торец под колпачком. Риски — под каналом от 30 (ось + 11; на пальце input на 3 выше — от 33), шагом в десятую хода ((ширина − 28) / 10) с 13,75; каждая пятая — 8 вместо 4.
   На пальце input выше, рисунок тот же. Вертикальный свайп по слайдеру прокручивает страницу */
.slider{display:flex;flex-direction:column;gap:2px;font-size:var(--fs-micro);line-height:14px}
.slider-head{display:flex;justify-content:space-between;gap:8px}
.slider label{color:var(--text-2)}
.slider output{color:var(--text);font-variant-numeric:tabular-nums}
.slider input[type=range]{--thumb:28px;width:calc(100% - 12px);height:38px;margin:0 6px 2px;touch-action:pan-y;
  background-image:linear-gradient(to right,var(--tick) 1.5px,transparent 0),linear-gradient(to right,var(--tick) 1.5px,transparent 0);
  background-repeat:repeat-x;background-size:calc((100% - 16px) / 10) 4px,calc((100% - 16px) / 2) 8px;
  background-position:7px 30px;
  --track-bg:linear-gradient(to right,var(--glow-core) calc(var(--f) * (100% - 22px) - 5px),transparent 0) 50% 50% / calc(100% - 10px) 3px
    no-repeat,linear-gradient(transparent,var(--halo-edge) 2.5px,var(--halo) 5px,var(--halo-edge) 7.5px,transparent)
    5px 50% / max(0px,calc(var(--f) * (100% - 32px) - 3px)) 10px no-repeat,
    linear-gradient(var(--guide-unlit),var(--guide-unlit)) 50% 50% / calc(100% - 10px) 3px no-repeat,
    linear-gradient(to top,var(--hole-lit),var(--slot) 40%,var(--slot-deep));
  --cap-bg:linear-gradient(var(--light-concave),var(--accent-hi),var(--accent) 50%,var(--accent-deep)) padding-box,
    linear-gradient(var(--light-convex),var(--accent-hi),var(--accent) 50%,var(--accent-deep)) border-box}
@media(hover:hover){.slider input[type=range]:hover{
  --cap-bg:linear-gradient(var(--light-concave),var(--accent-hover-hi),var(--accent-hover) 50%,var(--accent-deep)) padding-box,
    linear-gradient(var(--light-convex),var(--accent-hover-hi),var(--accent-hover) 50%,var(--accent-deep)) border-box}}
.slider input[type=range]::-webkit-slider-runnable-track{height:10px;border-radius:5px}
.slider input[type=range]::-moz-range-track{height:10px;border-radius:5px}
.slider input[type=range]::-webkit-slider-thumb{width:28px;height:20px;margin-top:-5px;border:2px solid transparent;border-radius:6px;
  transform:translateX(calc(2px - 4px * var(--f)))}
.slider input[type=range]::-moz-range-thumb{width:28px;height:20px;border:2px solid transparent;border-radius:6px;
  transform:translateX(calc(2px - 4px * var(--f)))}
/* Палец: зона касания 44 */
@media(pointer:coarse){.slider input[type=range]{height:44px;margin:-3px 6px -1px;background-position:7px 33px}}
/* Экраны (карточка Screen): e-ink без рамки — стекло screen утоплено в плашку (shadow-screen-flush), radius-12; подписи — только
   screen-label в углах. Блочные (АЧХ Filter, огибающие) — 80 в высоту, кривая с полями 10 по бокам и 26 сверху (подписи
   до 22 и зазор 4, как на доске), снизу 8; у Filter снизу — подписи частот по оси (screen-ink-2). Выхода (Scope, Spectrum) — 96, холсты рисует scope.js */
.response,.scope-panel{position:relative;margin:0;border-radius:var(--radius-12);background:var(--screen);
  box-shadow:var(--shadow-screen-flush);overflow:hidden}
.response{--pad-top:26px;--pad-side:10px;--pad-bottom:8px;box-sizing:border-box;height:var(--size-screen);
  padding:var(--pad-top) var(--pad-side) var(--pad-bottom)}
.response:has(.response-axis){--pad-bottom:20px}
.response svg{display:block;width:100%;height:100%;overflow:visible}
.response svg *{vector-effect:non-scaling-stroke}
/* Кривая — screen-ink 1,6 без заливки; сетка и ноль — screen-ink-2 пунктиром 2 / 4; срез — screen-mark */
.response-line{fill:none;stroke:var(--screen-ink);stroke-width:1.6;stroke-linejoin:round}
.response-grid line{stroke:var(--screen-ink-2);stroke-width:1;stroke-dasharray:2 4}
.response-cutoff{stroke:var(--screen-mark);stroke-width:1.5;stroke-dasharray:3 3}
.response-axis{position:absolute;left:10px;right:10px;bottom:3px;height:14px;color:var(--screen-ink-2);font-size:var(--fs-micro);
  line-height:14px;font-variant-numeric:tabular-nums}
.response-axis span{position:absolute;top:0;transform:translateX(-50%);white-space:nowrap}
/* Подписи в верхних углах (screen-label, controls.js): термин капителью, значение как есть — «CUTOFF 2,0 kHz»; точка этапа
   огибающей — screen-mark Ø 6 на кривой (--x, --y — доли поля кривой внутри полей --pad-* экрана) */
.screen-label{position:absolute;top:8px;max-width:calc(100% - 20px);overflow:hidden;font:600 var(--fs-micro)/14px var(--sans);
  letter-spacing:.04em;color:var(--screen-ink-2);font-variant-numeric:tabular-nums;white-space:nowrap;text-overflow:ellipsis;pointer-events:none}
.screen-label.l{left:10px}
.screen-label.r{right:10px}
/* Две подписи: левая (термин и значение) длиннее — ей 65 % ширины, правой 35 %; одна — вся */
.screen-label.l:has(~.screen-label.r){max-width:calc(65% - 14px)}
.screen-label.l~.screen-label.r{max-width:calc(35% - 14px)}
.screen-label>span{text-transform:uppercase}
.screen-mark{position:absolute;left:calc(var(--pad-side) + var(--x,0) * (100% - 2 * var(--pad-side)));
  top:calc(var(--pad-top) + var(--y,0) * (100% - var(--pad-top) - var(--pad-bottom)));width:6px;height:6px;border-radius:50%;background:var(--screen-mark);transform:translate(-50%,-50%);pointer-events:none}
.scope-panel canvas{display:block;width:100%;height:var(--size-screen-out);touch-action:manipulation}
.scope-panel figcaption{position:absolute;top:10px;left:12px;font:600 var(--fs-micro)/14px var(--sans);letter-spacing:.04em;text-transform:uppercase;
  color:var(--screen-ink-2);pointer-events:none}
/* Подпись источника справа (scope.js: tags) — как название слева; не наезжает на него */
.scope-panel>.screen-label{top:10px}
.scope-panel>.screen-label.r{right:12px;max-width:calc(100% - 110px)}
/* «?» на стекле экрана выхода — чернилами экрана; наведение и открытая справка — как везде */
.scope>.card-picker .card-open:not(:hover,[aria-expanded=true]){color:var(--screen-ink-2)}
/* Подпись спектра — левее «?» */
.scope-panel[data-panel=spectrum]>.screen-label.r{right:36px}
/* Стойка (карточки Stand, Block, Blank): плита stand, столбцы по 240 (grid-module, не сжимаются), плашки surface без зазоров — шов
   из кромок shadow-plate; первая строка — экраны выхода (#scope ставит app.js). Без overflow:hidden — его обрезали бы поповеры
   карточек «?»: скругление — у угловых плашек. Секции, ярусы и столбцы собирает app.js по data-layout-* (≥ 1232 — пять столбцов,
   900 — три, 600 — два, телефон — один); последняя плашка столбца — до его низа (заглушки, Amp Envelope высотой Filter Envelope) */
.stand{margin-bottom:16px;border-radius:var(--radius-20);background:var(--stand);box-shadow:var(--shadow-stand)}
.stand>.scope{margin:0;padding:var(--space-16);border-radius:var(--radius-20) var(--radius-20) 0 0;background:var(--surface);
  box-shadow:var(--shadow-plate)}
/* «?» экранов — на стекле, как без стойки */
.stand>.scope>.card-picker{top:22px;right:22px}
.stand>.scope{gap:var(--space-16)}
.stand .blocks,.stand-tier{display:flex}
.stand-sec{display:flex;flex-direction:column}
.stand-col{display:flex;flex:none;flex-direction:column;width:var(--grid-module)}
.stand-col>:last-child{flex:1}
.stand .block,.block-fill{box-sizing:border-box;padding:var(--space-16);gap:var(--space-16);border-radius:0;background:var(--surface);
  box-shadow:var(--shadow-plate)}
.block-fill{display:flex}
.block-fill[hidden]{display:none}
/* До раскладки app.js (первый кадр модуля) разметка — пять столбцов: уже 1232 — сетка по 240 и шире без заглушек, без прокрутки вбок */
@media(width<1232px){
  .stand .blocks:not([data-size]){display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--grid-module),1fr));grid-auto-flow:row}
  .blocks:not([data-size]) .stand-col{display:contents}
  .blocks:not([data-size]) .block-fill{display:none}
}
.blocks>:nth-child(1 of .stand-sec)>.stand-tier:last-child>.stand-col:first-child>:last-child{border-bottom-left-radius:var(--radius-20)}
.blocks>:nth-last-child(1 of .stand-sec)>.stand-tier:last-child>.stand-col:last-child>:last-child{border-bottom-right-radius:var(--radius-20)}
/* Subtractive и FM — в одной ячейке сетки (.screens в index.html): строки экранов выхода, двух ярусов и Effects общие для обеих
   стоек (subgrid), поэтому высоты стойки и ярусов не меняются при смене вкладки; скрытая вкладка невидима и не в фокусе.
   Секция из одного яруса занимает оба. Стойка и Effects — одной колонкой по центру */
@media(min-width:600px){
  .screens{display:grid;grid-template:repeat(4,auto) / minmax(0,1fr);align-self:center;width:calc(2 * var(--grid-module))}
  .screens:not(:has(>.screen:not([hidden]))){display:none}
  .screens>.screen,.screens>.screen[hidden]{display:contents}
  .screens>.screen[hidden]>*{visibility:hidden}
  .screens .stand{display:grid;grid-area:1/1/4/2;grid-template:subgrid / minmax(0,1fr)}
  .screens .stand>.scope{grid-row:1}
  .screens .fx{grid-row:4}
  .screens .blocks{display:grid;grid-row:2/4;grid-template-rows:subgrid;grid-auto-flow:column}
  .screens .stand-sec{display:grid;grid-row:1/-1;grid-template-rows:subgrid}
  .screens .stand-tier:only-child{grid-row:1/-1}
}
@media(min-width:900px){.screens{width:calc(3 * var(--grid-module))}}
@media(min-width:1232px){
  .screens,.screen:has(>.nodes-stand){align-self:center;width:calc(5 * var(--grid-module))}
  /* Oscillator вровень с Noise: шапка, зазор и строка слайдера (подпись 14 + 2 + дорожка 40 с полями, и на сенсорном экране);
     Oscillator 2 ниже на столько же — у него запас внизу */
  .stand-col>.block-osc{min-height:calc(3 * var(--space-16) + var(--size-block-head) + 56px)}
}
/* Телефон — один столбец во всю ширину (вид блоков на телефоне — 7.24); граница — как у matchMedia в app.js, без зазора 599–600 */
/* Внутри блок тот же (доска Stage6Phone): экраны, слайдеры, ряды форм волны и ADSR — по ширине, ручки — три равные колонки;
   Scope и Spectrum — друг под другом, «?» — на стекле Spectrum (у Scope справа своя подпись) */
@media(width<600px){
  .screens{display:contents}
  .stand-sec,.stand-col{flex:1;width:auto}
  .stand .knobs:not(.two){grid-template-columns:repeat(3,minmax(0,1fr));justify-items:center}
  /* Карта Carrier — во всю ширину двух столбцов, до Ratio (рисунок по ширине — fm.js) */
  .fm-car .fm-map{justify-self:stretch}
  /* И до переезда полосы в стойку (app.js) — один столбец */
  .scope{grid-template-columns:minmax(0,1fr)}
  .stand>.scope>.card-picker{top:calc(2 * var(--space-16) + var(--size-screen-out) + 6px)}
}
/* Шапка блока 28: название, «?» (вид — style.css, справка Help), клавиша включения */
.stand .block-head{height:var(--size-block-head);gap:var(--space-8)}
.stand .block-head h2{flex:1;line-height:20px}
.stand .block-head .card-picker{margin-left:0}
/* Две ручки в ряду — по центру (низ Filter Envelope) */
.knobs.two{grid-template-columns:repeat(2,var(--grid-knob-col));justify-content:center}
/* Экраны FM (карточка Screen, доска Stage4FM): рисунок во весь экран в точных размерах (без полей кривой), подписи — screen-label.
   Operator 3 — 208 × 80, схема выбранного алгоритма: рамки screen-ink, несущий — screen-mark, выключенный Operator 3 — пунктиром
   screen-ink-2. Carrier — слева от Ratio во всю ширину двух столбцов ручек (136 × 80, на телефоне шире: рисунок по ширине — fm.js):
   сетка гармоник пунктиром, риски полос screen-ink 2,
   отражённые — пунктиром 3 / 2, не на гармониках ноты — screen-mark */
.fm-screen{padding:0}
.fm-screen svg{overflow:hidden}
/* Подписи — по своей длине (на карте «LOW F0» в 35 % не влезло бы) */
.fm-screen>.screen-label.l,.fm-screen>.screen-label.l~.screen-label.r{max-width:none}
/* Карта 136: самые длинные «C:M 0,5:11,5» и «LOW F0» встык — без разрядки (иначе наезжают) */
.fm-map>.screen-label{letter-spacing:0}
.fm-screen text{fill:var(--screen-ink);font:600 var(--fs-micro) var(--sans);text-anchor:middle;dominant-baseline:central}
.fm-algo [data-algo]{display:none}
.fm-algo[data-algorithm=stack] [data-algo=stack],.fm-algo[data-algorithm=parallel] [data-algo=parallel]{display:inline}
.algo-op{fill:none;stroke:var(--screen-ink);stroke-width:1.5}
.algo-carrier{stroke:var(--screen-mark)}
.algo-wire{fill:none;stroke:var(--screen-ink);stroke-width:1.3;marker-end:url(#fm-algo-arrow)}
.algo-head{fill:var(--screen-ink)}
.fm-algo[data-op3-off] .algo-op3>*{stroke:var(--screen-ink-2);stroke-dasharray:2 3}
.fm-algo[data-op3-off] .algo-op3>text{fill:var(--screen-ink-2);stroke:none}
.fm-car .knobs{align-items:start}
.fm-map{grid-column:1/3;width:auto}
.fm-car .knob{grid-column:3}
.map-grid{fill:none;stroke:var(--screen-ink-2);stroke-width:1;stroke-dasharray:2 4;opacity:.6}
.map-axis{stroke:var(--screen-ink-2);stroke-width:1}
.fm-map text{fill:var(--screen-ink-2);font-weight:400}
#fm-map-bands line{stroke:var(--screen-ink);stroke-width:2}
#fm-map-bands .off{stroke:var(--screen-mark)}
#fm-map-bands .reflected{stroke-dasharray:3 2}
/* Заглушки: динамик (отверстие grille, под ним кромка grille-lit со сдвигом к свету) и глухая с винтами Ø 10 в верхних углах */
/* Динамик — по высоте плашки: края по два ряда со ступенями, середина — целое число рядов шагом grid-step (не меньше одного) */
.speaker{align-items:center;justify-content:center}
.grille{display:flex;flex-direction:column;width:208px;height:100%;height:round(down,100%,var(--grid-step));min-height:calc(5 * var(--grid-step))}
.grille svg{display:block;flex:none;width:208px;height:calc(2 * var(--grid-step));overflow:visible}
.grille .grille-mid{flex:1 1 0px;height:auto;min-height:var(--grid-step)}
#grille-lit circle{fill:var(--grille-lit)}
#grille-hole circle{fill:var(--grille)}
.svg-defs{position:absolute}
.blank{justify-content:space-between;align-items:flex-start}
.screw{display:flex;align-items:center;justify-content:center;width:10px;height:10px;border-radius:50%;
  background:linear-gradient(var(--light-convex),var(--screw-hi),var(--screw-lo));box-shadow:var(--shadow-screw)}
.screw::after{content:'';width:6px;height:1.5px;border-radius:1px;background:var(--screw-slot);transform:rotate(-30deg)}
/* Эффекты (карточка Effects, доска Stage4Fx): своя плита стойки 72 (открытый ящик — по самому длинному гнезду); слева «Effects»
   и клавиша ящика 24, справа «?», между ними лоток slot-deep — кассеты 104 × 40 по ходу сигнала, под каждой гнездо с ручками 48.
   --fx-row — высота строки «Effects» и «?»: вровень с кассетами (лоток 48, открытый — 56 с отступом 8) */
.fx{--fx-row:48px;position:relative;display:flex;align-items:flex-start;gap:var(--space-16);margin-bottom:16px;padding:12px var(--space-16);
  border-radius:var(--radius-20);background:var(--surface);box-shadow:var(--shadow-plate),var(--shadow-stand)}
.fx[hidden]{display:none}
.fx.open{--fx-row:56px}
.fx-side{display:flex;flex:none;align-items:center;gap:var(--space-8);width:96px;height:var(--fx-row)}
.fx-side h2{margin:0;font-size:var(--fs-title);line-height:20px;font-weight:500}
.key.fx-drawer{width:24px;height:24px}
.key.fx-drawer svg{width:10px;height:10px}
.fx-drawer[aria-expanded=true] svg{transform:rotate(180deg)}
.fx>.card-picker{display:flex;align-items:center;height:var(--fx-row)}
.fx-well{flex:1;min-width:0;border-radius:var(--radius-12);background:var(--slot-deep);box-shadow:var(--shadow-inset)}
.fx-tray{box-sizing:border-box;display:flex;align-items:center;gap:var(--space-8);height:48px;padding:4px 8px}
.fx.open .fx-tray{height:auto;align-items:flex-start;padding:8px}
.fx-slot{display:flex;flex:none;flex-direction:column;gap:6px;width:var(--size-cassette)}
:is(.fx-slot,.fx-menu>button)[data-fx=saturation]{--fx:var(--fx-saturation)}
:is(.fx-slot,.fx-menu>button)[data-fx=phaser]{--fx:var(--fx-phaser)}
:is(.fx-slot,.fx-menu>button)[data-fx=chorus]{--fx:var(--fx-chorus)}
:is(.fx-slot,.fx-menu>button)[data-fx=delay]{--fx:var(--fx-delay)}
:is(.fx-slot,.fx-menu>button)[data-fx=reverb]{--fx:var(--fx-reverb)}
.fx-next{flex:none;display:flex;align-items:center;width:6px;height:40px;color:var(--keycap-rim-hi);font-size:var(--fs-micro);line-height:14px}
/* Кассета: лицо по light-concave, ярлык 8 цвета эффекта, имя и главное значение чернилами экрана, окошко с катушками.
   Выключенная — выдвинута вверх с тенью, ярлык cassette-off */
.cassette{position:relative;flex:none;width:var(--size-cassette);height:40px;padding:0;border:0;border-radius:6px;font:inherit;cursor:pointer;
  -webkit-touch-callout:none;-webkit-user-select:none;user-select:none;
  background:linear-gradient(var(--light-concave),var(--cassette-lo),var(--cassette) 55%,var(--cassette-hi));
  box-shadow:inset -1px 1px 0 var(--cassette-hi),inset 1px -1px 0 var(--cassette-lo),var(--shadow-raised-sm);transition:transform .15s,box-shadow .15s}
.cassette::before{content:'';position:absolute;top:0;bottom:0;left:0;width:8px;border-radius:6px 0 0 6px;background:var(--fx)}
.cassette[aria-checked=false]{transform:translate(1px,-5px);box-shadow:inset -1px 1px 0 var(--cassette-hi),inset 1px -1px 0 var(--cassette-lo),var(--shadow-raised)}
.cassette[aria-checked=false]::before{background:var(--cassette-off)}
.cassette:focus-visible{outline:2px solid var(--accent-text);outline-offset:2px}
/* Перенос кассеты: гнездо едет за указателем поверх соседей */
.fx-slot.dragging{position:relative;z-index:1;cursor:grabbing}
.fx-slot.dragging .cassette{cursor:grabbing}
.fx-slot.leaving .cassette{opacity:var(--opacity-off)}
.fx-slot[hidden],.fx-next[hidden]{display:none}
/* «+ Effect» — пустое гнездо пунктиром line-strong; меню кассеты («Убрать») и свободных кассет — плашка popover под клавишей,
   пункты 32 с ярлыком цвета эффекта */
.fx-add-key{display:flex;align-items:center;justify-content:center;gap:6px;width:var(--size-cassette);height:40px;padding:0;
  border:1px dashed var(--line-strong);border-radius:6px;background:none;color:var(--text-3);font:inherit;font-size:var(--fs-micro);
  line-height:14px;cursor:pointer}
.fx-add-key>span:first-child{font-size:15px}
.fx-add-key:focus-visible{outline:2px solid var(--accent-text);outline-offset:2px}
@media(hover:hover){.fx-add-key:hover{color:var(--text-2)}}
.fx-menu{position:absolute;z-index:30;display:flex;flex-direction:column;gap:2px;width:220px;box-sizing:border-box;padding:6px;
  border:1px solid var(--line-strong);border-radius:var(--radius-12);background:var(--popover);box-shadow:var(--shadow-popover)}
.fx-menu[hidden]{display:none}
.fx-menu>button{display:flex;align-items:center;gap:10px;height:32px;padding:0 10px;border:0;border-radius:var(--radius-8);background:none;
  color:var(--text);font:inherit;font-size:var(--fs-body);text-align:left;cursor:pointer}
.fx-menu>button[data-fx]::before{content:'';width:6px;height:16px;border-radius:2px;background:var(--fx)}
@media(hover:hover){.fx-menu>button:hover{background:var(--surface)}}
.fx-menu>button:focus-visible{outline:2px solid var(--accent-text);outline-offset:-2px}
.cassette-name{position:absolute;top:6px;left:15px;font-size:var(--fs-micro);line-height:14px;font-weight:600;letter-spacing:.04em;
  text-transform:uppercase;color:var(--screen-ink)}
.cassette-value{position:absolute;bottom:6px;left:15px;max-width:52px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:10px;line-height:12px;color:var(--screen-ink-2);font-variant-numeric:tabular-nums}
.cassette-reels{position:absolute;top:12px;right:7px;width:30px;height:16px}
.cassette-reels>rect{fill:var(--inset)}
.cassette-reels>.tape{fill:var(--popover)}
/* Поворот вокруг центра своей катушки: рамка — сам круг (fill-box); origin в px Safari считал от другой рамки — катушки «летали» */
.reel{transform-box:fill-box;transform-origin:center}
.reel circle{fill:var(--reel)}
.reel .hub{fill:var(--inset)}
.reel path{fill:none;stroke:var(--inset);stroke-width:1.2;stroke-linecap:round}
/* Катушки включённой кассеты крутятся; у Phaser и Chorus — оборот за период LFO (--spin из effects.js) */
@media(prefers-reduced-motion:no-preference){.cassette[aria-checked=true] .reel{animation:fx-spin var(--spin,3s) linear infinite}}
@keyframes fx-spin{to{transform:rotate(360deg)}}
/* Гнездо: inset, полоса 2 цвета ярлыка сверху, ручки 48 в ячейках 52 по две в ряд, нечётная последняя — по центру; у выключенного
   эффекта приглушено, ручки работают. Закрытый ящик — гнёзд не видно */
.fx-socket{position:relative;display:grid;grid-template-columns:52px 52px;row-gap:4px;box-sizing:border-box;padding:10px 0 8px;
  border-radius:6px;background:var(--inset)}
.fx-socket::before{content:'';position:absolute;top:0;right:8px;left:8px;height:2px;border-radius:0 0 2px 2px;background:var(--fx)}
.fx-slot[data-off] .fx-socket{opacity:var(--opacity-off)}
.fx:not(.open) .fx-socket{display:none}
.fx-socket .knob:last-child:nth-child(odd){grid-column:1/3}
/* Малая ручка (size-knob-sm 48): та же ручка в масштабе 3/4 — шкала r 21, ободок 28; толщина точек и риски — как на доске */
.knob.sm{--grid-knob-col:var(--size-knob-sm);--size-knob:28px;gap:0}
.knob.sm .knob-dial svg{stroke-width:2.67}
.knob.sm.step .knob-dial svg{stroke-width:2}
.knob.sm .knob-face::before{top:.75px;height:6px}
.knob.sm.step .knob-face::before{height:9px}
/* Уже 1232 (планшет и телефон, доска Stage6Tablet): «Effects» и «?» — строкой 28 сверху, лунка во всю ширину, лоток прокручивается
   вбок внутри неё. Прокрутка обрезала бы выдвинутую и вытянутую вверх кассету — у лотка запас сверху (--fx-lift: строка, зазор и поле плиты)
   над лункой до края плиты, прозрачный; строка «Effects» и «?» — поверх него, щелчки доходят до них */
@media(max-width:1231px),(orientation:landscape) and (max-height:500px){
  .fx,.fx.open{--fx-row:28px;--fx-gap:12px;--fx-lift:calc(var(--fx-row) + var(--fx-gap) + var(--space-16));flex-wrap:wrap;row-gap:var(--fx-gap);
    padding:var(--space-16)}
  .fx-side{flex:1;width:auto}
  .fx-side,.fx>.card-picker{position:relative;z-index:1}
  .fx>.card-picker{order:1}
  .fx-well{order:2;flex-basis:100%}
  /* Нижние углы — по лунке: прокрученные кассеты и гнёзда не выходят за скругление */
  .fx-tray{height:auto;margin-top:calc(-1 * var(--fx-lift));padding-top:calc(var(--fx-lift) + 4px);overflow-x:auto;
    border-radius:0 0 var(--radius-12) var(--radius-12)}
  .fx.open .fx-tray{padding-top:calc(var(--fx-lift) + 8px)}
  /* Переносимая кассета — над строкой «Effects» */
  .fx-slot.dragging{z-index:2}
}
/* Панель клавиатуры (карточка Keyboard, доска Stage4Keys): на ≥ 1232 — стойка 1200, верх radius-20; строка управления 56 — плашки
   surface по смыслу, шов — кромки shadow-plate; клавиши 56 × 24 со светодиодом, малые ручки — подпись и значение сбоку.
   Уже 1232 — панель во всю ширину, плашки переносятся; на < 900 и телефоне горизонтально — один ряд с прокруткой вбок, иначе
   строка съедает высоту петли (раскладки планшета и телефона — 7.22–7.26) */
.keys-panel{padding:0 0 var(--space-16);background:var(--surface);box-shadow:var(--shadow-plate),0 -8px 24px var(--shadow)}
/* Лупер (карточка Looper, доска Stage4Keys): плашка над строкой управления — диапазон сетки · сетка · колонка действий 24.
   Диапазон — ▲ / ▼ и лунка с окном 20 × 40 (--r — доля пути сверху вниз), как у октавы. Сетка — экран screen 258: полоса тактов 20
   (страницы и подсказка жестов — поверх неё справа), 13 строк по 18, снизу 4; бегущая метка — линия screen-mark 2 px.
   Колонка — клавиши 24, группы через черту. Уже 900 и телефон горизонтально — колонка строкой под сеткой (раскладки — 7.24–7.26) */
.loop{display:flex;gap:var(--space-8);align-items:flex-start;padding:var(--space-16);box-shadow:var(--shadow-plate)}
.loop[hidden]{display:none}
.loop-range{display:flex;flex:none;flex-direction:column;align-items:center;gap:4px;align-self:stretch}
.loop-rail{position:relative;flex:1;box-sizing:border-box;width:24px;border-radius:var(--radius-10);background:var(--well);
  box-shadow:var(--shadow-well);touch-action:none;cursor:pointer}
.key.loop-window{--win:min(40px,100% - 4px);position:absolute;left:2px;top:calc(2px + (100% - 4px - var(--win)) * var(--r,0));width:20px;
  height:var(--win);font-size:10px;line-height:12px;letter-spacing:-.02em;white-space:nowrap;color:var(--text)}
.key.loop-window:focus-visible{outline:2px solid var(--accent-text);outline-offset:1px}
.loop-grid{position:relative;flex:1;min-width:0;height:258px;border-radius:var(--radius-12);background:var(--screen);
  box-shadow:var(--shadow-screen-flush);overflow:hidden}
.loop-grid canvas{display:block;width:100%;height:100%;touch-action:none;cursor:crosshair}
.loop-head{position:absolute;top:20px;bottom:4px;left:0;width:2px;background:var(--screen-mark);pointer-events:none}
.loop-head[hidden],.loop-pages[hidden]{display:none}
.loop-top{position:absolute;top:0;right:10px;left:96px;display:flex;justify-content:flex-end;align-items:center;gap:var(--space-8);height:20px;
  pointer-events:none}
.loop-hint{min-width:0;margin:0;overflow:hidden;font:400 var(--fs-micro)/14px var(--sans);color:var(--screen-ink-2);white-space:nowrap;
  text-overflow:ellipsis}
.loop-pages{display:flex;flex:none;gap:2px;pointer-events:auto}
.loop-pages button{height:16px;padding:0 6px;border:0;border-radius:4px;background:none;font:600 var(--fs-micro)/16px var(--sans);
  letter-spacing:.04em;color:var(--screen-ink-2);cursor:pointer}
.loop-pages button[aria-pressed=true]{background:var(--screen-ink);color:var(--screen)}
.loop-tools{display:flex;flex:none;flex-direction:column;align-items:center}
.loop-rule{display:block;flex:none;width:16px;height:1px;margin:3px 0;background:var(--shadow);opacity:.7;box-shadow:0 1px 0 var(--grille-lit)}
.loop-pair{display:flex;flex-direction:column;gap:4px}
.key.loop-tool{width:24px;height:24px}
.key.loop-tool svg{width:14px;height:14px}
.key.loop-bars{flex-direction:column;gap:2px;font-size:11px;line-height:11px}
.loop-dots{display:flex;gap:2px}
.loop-dots i{width:3px;height:3px;border-radius:50%;background:var(--led-off);box-shadow:var(--shadow-led-off)}
.loop-dots i.on{background:var(--led-on);box-shadow:var(--shadow-led-sm)}
@media(max-width:899px),(orientation:landscape) and (max-height:500px){
  .loop{flex-wrap:wrap}
  .loop-grid{height:180px}
  .loop-tools,.loop-pair{flex-direction:row;gap:4px}
  .loop-tools{order:1;flex-basis:100%;justify-content:flex-end}
  .loop-rule{width:1px;height:16px;margin:0 3px;box-shadow:1px 0 0 var(--grille-lit)}
}
/* Невысокий телефон (360 × 740, 412 × 780): панель иначе выше окна */
@media(max-width:899px) and (max-height:839px){.loop-grid{height:144px}}
@media(orientation:landscape) and (max-height:500px){
  .loop-grid{height:120px}
  /* Подсказке петли места нет (она в справке) */
  .loop-hint{display:none}
}
/* Узкий телефон горизонтально (< 720) с развёрнутой петлёй; ещё ниже (640 × 360) — сетка ниже */
@media(orientation:landscape) and (max-height:500px) and (max-width:719px){.loop-grid{height:112px}}
@media(orientation:landscape) and (max-height:370px) and (max-width:719px){.loop-grid{height:104px}}
/* Плашка пианино (карточка Piano, доска Stage4Keys): клавиши size-piano 136, зазор 2; белые — кромка key-white-lo снизу,
   чёрные 58 % — кромка key-black-lo; нажатая — accent с кромкой accent-deep, подписи on-accent. Над буквой клавиши компьютера
   (только при мыши) — у каждой C название октавы 11 / 600. Справа октава столбцом 24: ▲ (X), лунка с точками C1…C7 — семь полос
   снизу вверх — и окном диапазона (--k — полоса нижней C, --span — октав в окне; не ниже 16 — по центру своих полос, как на доске
   Stage6Phone), ▼ (Z) */
.keys-piano{display:flex;gap:12px;margin:var(--space-16) var(--space-16) 0}
.piano{position:relative;flex:1;min-width:0;display:flex;gap:2px;height:var(--size-piano);box-shadow:inset 0 3px 0 var(--grey-100);
  touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none}
.piano-key{flex:1;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;gap:4px;min-width:0;padding:0 0 10px;
  border:0;border-radius:0 0 6px 6px;background:var(--key-white);box-shadow:inset 0 -4px 0 var(--key-white-lo);color:var(--key-label);
  font:400 var(--fs-micro)/14px var(--sans);cursor:pointer}
.piano-key.black{position:absolute;z-index:1;top:0;left:var(--at);width:var(--black-size);height:58%;padding-bottom:8px;
  border-radius:0 0 5px 5px;background:var(--key-black);box-shadow:inset 0 -5px 0 var(--key-black-lo),-1px 2px 3px var(--shadow);
  color:var(--key-label-black)}
.piano-key.down{background:var(--accent);box-shadow:inset 0 -4px 0 var(--accent-deep);color:var(--on-accent)}
.piano-key.black.down{box-shadow:inset 0 -5px 0 var(--accent-deep),-1px 2px 3px var(--shadow)}
.piano-key kbd{font:inherit}
.piano-key span{font-weight:600;color:var(--key-name)}
.piano-key.down span{color:inherit}
.piano-key:focus-visible{outline-offset:-3px}
@media(hover:none){.piano-key kbd{display:none}}
/* Pitch (карточка Piano): лунка 24 во всю высоту пианино, 11 точек через 1/12 высоты, у нуля — риска 6 × 1,5; бегунок — плоская
   клавиша 20 × 24 с риской knob-mark, --v — bend −1…+1 (ход — половина свободной высоты); отпустили — едет к нулю (.spring).
   На телефоне (< 600 и горизонтально) Pitch нет */
.pitch{position:relative;flex:none;box-sizing:border-box;width:24px;border-radius:var(--radius-10);background:var(--well);
  box-shadow:var(--shadow-well);touch-action:none;cursor:ns-resize}
.pitch:focus-visible{outline:2px solid var(--accent-text);outline-offset:2px}
.pitch>span:not(.key){position:absolute;left:10px;top:calc(2px + (var(--i) + 1) * (100% - 4px) / 12 - 1px);width:2px;height:2px;
  border-radius:1px;background:var(--keycap-rim-hi)}
.pitch>span.pitch-zero{--i:5;left:8px;width:6px;height:1.5px}
.key.pitch-thumb{position:absolute;left:2px;top:calc(2px + (100% - 28px) / 2 * (1 - var(--v,0)));width:20px;height:24px;pointer-events:none}
.key.pitch-thumb::after{content:'';width:10px;height:2px;border-radius:1px;background:var(--knob-mark)}
@media(prefers-reduced-motion:no-preference){.pitch.spring .pitch-thumb{transition:top .12s ease-out}}
@media(max-width:599px),(orientation:landscape) and (max-height:500px){.pitch{display:none}}
.keys-piano>.octave{display:flex;flex:none;flex-direction:column;align-items:center;gap:4px}
.key.oct-step{width:24px;height:24px}
.key.oct-step svg{width:8px;height:8px;fill:currentColor;stroke:none}
.oct-rail{position:relative;flex:1;box-sizing:border-box;width:24px;border-radius:var(--radius-10);background:var(--well);
  box-shadow:var(--shadow-well);touch-action:none;cursor:pointer}
.oct-rail>span{position:absolute;left:11px;bottom:calc(2px + (var(--i) + .5) * (100% - 4px) / 7 - 1px);width:2px;height:2px;border-radius:50%;
  background:var(--keycap-rim-hi)}
.key.oct-window{--win:max(16px,var(--span) * (100% - 4px) / 7);position:absolute;left:2px;
  bottom:calc(2px + (var(--k) + var(--span) / 2) * (100% - 4px) / 7 - var(--win) / 2);width:20px;height:var(--win);font-size:10px;line-height:12px;
  color:var(--text)}
.oct-live{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.key.oct-window:focus-visible{outline:2px solid var(--accent-text);outline-offset:1px}
/* Телефон горизонтально: пианино 84 (74) — лунке между ▲ ▼ остаётся 28, по полосе точки не попасть: точек нет, окно — во всю лунку
   (подпись октавы; тянуть и стрелки — как везде) */
@media(orientation:landscape) and (max-height:500px){
  .oct-rail>span{display:none}
  .key.oct-window{--win:calc(100% - 4px);bottom:2px}
}
.keys-head{display:flex;flex-wrap:wrap;border-radius:inherit}
.keys-plate{display:flex;flex-wrap:wrap;align-items:center;gap:4px 12px;box-sizing:border-box;min-height:56px;padding:4px var(--space-16);
  box-shadow:var(--shadow-plate)}
.keys-plate:first-of-type{border-top-left-radius:inherit}
.keys-plate[hidden]{display:none}
.keys-pair{display:flex;gap:var(--space-8)}
.keys-plate:first-of-type{gap:var(--space-8)}
/* Последняя — Tempo и «?» впритык к 1200 (с экраном петли и ▶ на прочие плашки уходит 1040) */
.keys-end{flex:1;justify-content:flex-end;gap:var(--space-8);border-top-right-radius:inherit}
/* Выключенный Arp: всё, кроме его клавиши, приглушено; Tempo — пока Arp выключен и петля не играет. Ручки работают */
.arp[data-off]>:not(.keys-pair),.arp[data-off] .keys-pair>:last-child,.play-tempo[data-off]{opacity:var(--opacity-off)}
/* Малая ручка с подписью сбоку: колонка текста 44 (длиннее — уходит влево), ручка 48 */
.knob.side{display:grid;grid-template-columns:44px var(--grid-knob-col);column-gap:4px;align-items:center}
.knob.side .knob-dial{grid-area:1/2/3/3}
.knob.side label{grid-area:1/1;justify-self:end;align-self:end}
.knob.side output{grid-area:2/1;justify-self:end;align-self:start}
.knob.side input[type=range]{top:0;right:0;left:auto;margin:0}
/* Экран петли (карточка Looper) 112 × 24 — кнопка: ноты штрихами, такты пунктиром, пустая — надпись Loop; справа за чертой
   стрелка ⌃ развернуть / ⌄ свернуть. ▶ — клавиша 24 × 24 без светодиода: пока петля играет, нажата, значок горит play.
   Ноты — рисунок 92 × 24, тянется по ширине (на телефоне экран 80 и 72), стрелка — 20 × 24 справа */
.loop-screen{position:relative;display:flex;flex:none;width:var(--size-loop-screen);height:24px;padding:0;border:0;
  border-radius:var(--radius-8);background:var(--screen);box-shadow:var(--shadow-screen-flush);cursor:pointer}
.loop-screen:focus-visible{outline:2px solid var(--accent-text);outline-offset:2px}
.loop-screen svg{display:block;height:100%}
.loop-strip{flex:1;min-width:0}
.loop-strip *{vector-effect:non-scaling-stroke}
.loop-arrow{flex:none;width:20px}
.loop-word{position:absolute;top:0;left:10px;font:600 var(--fs-micro)/24px var(--sans);letter-spacing:.04em;text-transform:uppercase;
  color:var(--screen-ink-2);pointer-events:none}
.loop-screen:not(.empty) .loop-word{display:none}
.loop-notes rect{fill:var(--screen-ink)}
.loop-notes .bar{stroke:var(--screen-ink-2);stroke-dasharray:1 2}
.loop-sep{stroke:var(--screen-ink-2);opacity:.5}
.loop-up,.loop-down{fill:none;stroke:var(--screen-ink);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.loop-mark{stroke:var(--screen-mark);stroke-width:1.5;visibility:hidden}
.loop-screen.playing .loop-mark{visibility:visible}
.loop-screen[aria-expanded=true] .loop-up,.loop-screen[aria-expanded=false] .loop-down{display:none}
.key.loop-run{width:24px}
.key.loop-run svg{width:12px;height:12px;fill:currentColor;stroke:none}
.key.loop-run.playing{transform:translate(-0.5px,0.5px);color:var(--play);box-shadow:var(--shadow-key-pressed)}
.loop-run.playing svg{filter:drop-shadow(0 0 2px var(--play))}
/* Строка вкладок и ящик — только уже 900 */
.keys-tabs,.keys-more{display:none}
/* Телефон, планшет 600 и телефон горизонтально (доска Stage6Phone): строка управления 56 — экран петли 80, ▶, Mono, Arp,
   «?» (на телефоне — в строке вкладок) и стрелка ящика; ящик (keyboard.js: .open) — две плашки над ней: Legato, Glide · Tempo (56) и Hold · Mode, Rate, Gate, Oct (88),
   ручки Arp — подпись снизу. Плашки разметки (по смыслу, для 900 и шире) здесь растворены (display:contents): клавиши и ручки
   расставлены order в три ряда, между рядами — шов (::before, ::after). Пианино — одна октава 112 без букв (keyboard.js, style.css) */
@media(max-width:899px),(orientation:landscape) and (max-height:500px){
  .keys-head{display:flex;flex-wrap:wrap;align-items:center;gap:0 var(--space-8);padding:0 var(--space-16);box-shadow:var(--shadow-plate)}
  .keys-head>.keys-plate:not([hidden]),.keys-head .keys-pair{display:contents}
  .keys-head::before,.keys-head::after{content:'';flex:none;order:5;width:calc(100% + 2 * var(--space-16));height:1px;
    margin:0 calc(-1 * var(--space-16));background:var(--shadow);box-shadow:0 1px 0 var(--grille-lit)}
  .keys-head::after{order:11}
  .keys-head .play-modes .keys-pair>:last-child{order:1}
  .keys-head .play-glide{order:2}
  .keys-head .play-tempo{order:3;min-height:56px;margin-left:auto}
  .keys-head .arp .keys-pair>:last-child{order:6}
  .keys-head .arp>.knob{order:7;display:flex;min-height:88px;justify-content:center;min-width:56px}
  .keys-head .arp>.knob:first-of-type{margin-left:auto}
  .keys-head .arp>.knob input[type=range]{left:50%;right:auto;margin-left:calc(var(--grid-knob-col) / -2)}
  .keys-head .arp>.knob label,.keys-head .arp>.knob output{align-self:center}
  .keys-head>.keys-plate:first-of-type>*{order:12}
  .keys-head .play-modes .keys-pair>:first-child{order:14}
  .keys-head .arp .keys-pair>:first-child{order:15}
  .keys-head .keys-end>.card-picker{order:16;margin-left:auto}
  .keys-more{display:flex;order:17;align-items:center;height:56px}
  .keys-head:not(.open) :is(.play-modes .keys-pair>:last-child,.play-glide,.play-tempo,.arp .keys-pair>:last-child,.arp>.knob),
  .keys-head:not(.open)::before,.keys-head:not(.open)::after{display:none}
  .keys-head:not(.open) .keys-more{margin-left:auto}
  .piano-key kbd{display:none}
}
/* Телефон (< 600): сверху строка вкладок 44 — дорожка во всю ширину (app.js переносит её из шапки), справа «?» панели */
@media(max-width:599px) and (not ((orientation:landscape) and (max-height:500px))){
  .keys-panel{--size-loop-screen:80px}
  .keys-tabs{display:flex;flex:none;align-items:center;height:44px;padding:0 48px 0 var(--space-16);box-shadow:var(--shadow-plate);
    border-radius:inherit;border-bottom-left-radius:0;border-bottom-right-radius:0}
  .keys-tabs>.tabs{display:flex;flex:1}
  .keys-tabs .flat{flex:1}
  .keys-head .keys-end>.card-picker{position:absolute;top:10px;right:var(--space-16)}
  .keys-head{border-radius:0}
  .keys-head .keys-more{margin-left:auto}
}
@media(max-width:374px) and (not ((orientation:landscape) and (max-height:500px))){.keys-panel{--size-loop-screen:72px}}
/* Планшет 900 (доска Stage6Tablet): панель шириной стойки (720) по центру, строка управления в два ряда по 56 — петля · Mono, Legato,
   Glide · Tempo и «?», ниже Arp, Hold, Mode, Rate, Gate, Oct и пустая плашка до края; пианино — две октавы (белые ≈ 39), свёрнутая — 280 */
@media(min-width:900px) and (not ((orientation:landscape) and (max-height:500px))),(min-width:1232px){
  .keys-panel{align-self:center;width:calc(3 * var(--grid-module));margin:auto 0 0;border-radius:var(--radius-20) var(--radius-20) 0 0}
}
/* Планшет 600 (доска Stage6Phone) и телефон горизонтально (раскладка 600) — так же шириной стойки (480) по центру */
@media(min-width:600px) and (max-width:899px),(orientation:landscape) and (max-height:500px){
  .keys-panel{align-self:center;width:calc(2 * var(--grid-module));margin:auto 0 0;border-radius:var(--radius-20) var(--radius-20) 0 0}
}
@media(min-width:900px) and (max-width:1231px) and (not ((orientation:landscape) and (max-height:500px))){
  .keys-end{order:1}
  .keys-plate.arp{order:2}
  .keys-head::after{content:'';order:3;flex:1;min-height:56px;box-shadow:var(--shadow-plate)}
}
@media(min-width:1232px){
  .keys-panel{width:calc(5 * var(--grid-module))}
}
/* Меню Presets (карточка Presets, доска PopPresets): 280 под клавишей, popover, рамка line-strong, radius-20, отступ 6; сверху
   «Presets» и кубик «Случайный»; группы — micro text-3; строка 32: метка 4 × 16 (цвет эффекта по характеру звука, Init — line-strong),
   имя, светодиод текущего; «Мои» — с × (tick, наведение — text на line-strong); «+ Добавить текущий» (метка пунктиром) —
   вне прокрутки, под списком (7.15c);
   под списком — объяснение выбранного встроенного (7.15b, micro text-2, над чертой); внизу «Сохранить…» и «Открыть…». На < 900 — нижний лист (style.css), строки 44 */
/* Не ниже окна: на низком экране с объяснением сжимается список */
.presets-popover{width:280px;max-height:calc(100dvh - 112px);box-sizing:border-box;gap:1px;padding:6px;border-radius:var(--radius-20);box-shadow:var(--shadow-popover)}
.presets-head{display:flex;flex:none;align-items:center;height:32px;padding:0 4px 0 10px;border-bottom:1px solid var(--line);margin:0 4px 2px;
  padding-bottom:4px;box-sizing:content-box}
.presets-head h2{flex:1;margin:0;font-size:var(--fs-body);font-weight:500}
.presets-random,.presets-delete,.presets-files button,.presets-add,.presets-pick{border:0;background:none;font:inherit;cursor:pointer}
.presets-random{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border-radius:var(--radius-8);color:var(--text-2)}
.presets-random svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.presets-random .pips{stroke-width:1.8}
.presets-list{display:flex;flex-direction:column;gap:1px;min-height:0;max-height:min(60vh,520px);overflow-y:auto}
/* Ниже есть ещё — нижние 32 px списка затухают (маска — по прозрачности, цвет не важен); строка, к которой прокрутил фокус,
   встаёт над затуханием (scroll-padding) */
.presets-list{scroll-padding-bottom:32px}
.presets-list.more{-webkit-mask-image:linear-gradient(to bottom,#000 calc(100% - 32px),transparent);
  mask-image:linear-gradient(to bottom,#000 calc(100% - 32px),transparent)}
.presets-list>h3{margin:0;padding:8px 10px 2px;font-size:var(--fs-micro);line-height:14px;font-weight:400;color:var(--text-3)}
.presets-item{display:flex;flex:none;align-items:center;height:32px;padding-right:6px;border-radius:var(--radius-8)}
.presets-item:has([aria-pressed=true]){background:var(--selected)}
.presets-pick{display:flex;flex:1;align-items:center;gap:10px;min-width:0;height:100%;padding:0 6px 0 10px;border-radius:var(--radius-8);color:var(--text);
  font-size:var(--fs-body);text-align:left}
.presets-pick:focus-visible,.presets-random:focus-visible,.presets-delete:focus-visible,.presets-files button:focus-visible,
.presets-add:focus-visible{outline:2px solid var(--accent-text);outline-offset:-2px}
.presets-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.presets-tag{flex:none;box-sizing:border-box;width:4px;height:16px;border-radius:2px;background:var(--line-strong)}
.presets-tag.tag-saturation{background:var(--fx-saturation)}
.presets-tag.tag-phaser{background:var(--fx-phaser)}
.presets-tag.tag-chorus{background:var(--fx-chorus)}
.presets-tag.tag-delay{background:var(--fx-delay)}
.presets-tag.tag-reverb{background:var(--fx-reverb)}
.presets-tag.add{border:1px dashed var(--tick);background:none}
.presets-led{flex:none;width:6px;height:6px;border-radius:50%}
[aria-pressed=true]>.presets-led{background:var(--led-on);box-shadow:var(--shadow-led-sm)}
.presets-delete{display:flex;flex:none;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border-radius:6px;color:var(--tick)}
.presets-delete svg,.presets-files svg{fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.presets-delete svg{width:10px;height:10px}
.presets-item.editing{gap:10px;padding:0 6px 0 10px;background:var(--hover)}
.presets-rename{flex:1;min-width:0;height:24px;padding:0 6px;border:1px solid var(--line-strong);border-radius:6px;background:var(--inset);color:var(--text);
  font:inherit;font-size:var(--fs-body)}
.presets-add{display:flex;flex:none;align-items:center;gap:10px;height:32px;padding:0 10px;border-radius:var(--radius-8);color:var(--text-2);
  font-size:var(--fs-body);text-align:left}
.presets-about{flex:none;margin:2px 4px 0;padding:8px 6px 2px;border-top:1px solid var(--line);color:var(--text-2);font-size:var(--fs-micro);
  line-height:16px}
.presets-about p{margin:0}
.presets-about p+p{margin-top:4px}
.presets-status{margin:4px 10px 0;color:var(--accent-text);font-size:var(--fs-micro)}
.presets-status:empty{display:none}
.presets-files{display:grid;flex:none;grid-template-columns:1fr 1fr;gap:2px;margin-top:5px;padding-top:6px;border-top:1px solid var(--line)}
.presets-files button{display:flex;align-items:center;gap:8px;height:32px;padding:0 10px;border-radius:var(--radius-8);color:var(--text);
  font-size:var(--fs-body);text-align:left}
.presets-files svg{flex:none;width:14px;height:14px}
@media(hover:hover){
  .presets-item:not(.editing):hover,.presets-add:hover,.presets-files button:hover,.presets-random:hover{background:var(--hover)}
  .presets-item:has([aria-pressed=true]):hover{background:var(--selected)}
  .presets-delete:hover{background:var(--line-strong);color:var(--text)}
  .presets-random:hover{color:var(--text)}
}
@media(max-width:899px),(orientation:landscape) and (max-height:500px){
  .presets-popover{width:auto;max-height:82vh;padding:8px 16px calc(24px + env(safe-area-inset-bottom))}
  .presets-head h2{visibility:hidden}
  .presets-list{flex:none;max-height:none;overflow:visible}
  .presets-list.more{-webkit-mask-image:none;mask-image:none}
  /* Лист листается целиком — объяснение держится у нижнего края, пока виден список */
  /* bottom — минус нижний отступ листа: под объяснением список не просвечивает */
  .presets-about{position:sticky;bottom:calc(-24px - env(safe-area-inset-bottom));margin:0;
    padding:10px 0 calc(16px + env(safe-area-inset-bottom));background:var(--popover)}
  .presets-item,.presets-add,.presets-files button{height:44px}
  .presets-delete{width:36px;height:36px}
}
