/* Oxo Drums theme editor (products/oxo_drums/theme_editor). A copy of
   oxo_simple_theme_editor.css nested under .oxo-drums-editor: the Drums
   canvas is 1360 x 853 (the plugin's Shared/DrumsLayout.swift) — the Drums
   top bar across the top (with the engine tabs), the Browser (top-left) / Sequencer (top-right) /
   Pads (bottom-left) zones drawn by theme.js from the same geometry, and
   Simple's 1024 x 335 panel mockup UNCHANGED inside `.simple-zone` at
   (336, 470) — its own top bar hidden — exactly like the plugin embeds it.
   The Drums-only keys (accent, browser_*, seq_*, pad_*) are --t-* vars too. */

/* Solid page background: the site's photo + vignette (body::before/::after
   in styles.css) fight with the colors being edited. */
body.theme-editor-page::before,
body.theme-editor-page::after { background: #3a3a3a; }

.oxo-drums-editor {
  --editor-scale: 1;
  display: grid;
  justify-content: center;
  gap: 24px 0;
  zoom: var(--editor-scale);        /* set by theme.js so the 1024 px panel fits narrow screens */
  -webkit-font-smoothing: antialiased;

  * { box-sizing: border-box; margin: 0; padding: 0; }

  & {
    /* Element colors, one per theme JSON key (--t-<key>, underscores as
       hyphens). Defaults = the plugin's original palette (themes.js "default");
       theme.js overrides them inline from the theme. #rrggbb or #rrggbbaa. */
    --t-bg: #101113;
    --t-panel-bg: #141518;
    --t-panel-border: #8a8f981f;
    --t-topbar-bg: #00000000;
    --t-topbar-logo: #8b846899;
    --t-topbar-play: #cfc19e;
    --t-topbar-text: #6b6b70;
    --t-topbar-text-accent: #607594;
    --t-topbar-button-bg: #1c1c20;
    --t-topbar-button-border: #232323;
    --t-topbar-button-text: #6b6b70;
    --t-group-label: #8a8f9880;
    --t-knob-ring: #101012;
    --t-knob-outer-ring: #8a8f981a;
    --t-knob-ticks: #7f848b4d;
    --t-knob-label: #6e7480;
    --t-knob-modulation: #e0a15e;
    --t-mini-knob-body: #121418;
    --t-mini-knob-border: #4a555d;
    --t-mini-knob-dial: #8ac8d4;
    --t-mini-knob-label: #8a8f98b8;
    --t-chip-bg: #16181c;
    --t-chip-border: #6e748061;
    --t-chip-text: #6e7480;
    --t-input-chip-border: #2c313c;
    --t-input-chip-dot: #4a4f58;
    --t-input-chip-on: #4a2b2b;
    --t-input-chip-text-on: #9a9ea5;
    --t-input-chip-text-off: #6e7480;
    --t-button-bg: #1d1f27;
    --t-button-text: #7f8592;
    --t-button-pressed-bg: #bcb6a3;
    --t-button-pressed-text: #101012;
    --t-button-lit-bg: #632926;
    --t-button-lit-text: #f2dede;
    --t-mute-active: #cb585b;
    --t-solo-active: #e0d152;
    --t-rec-dot: #b8433d;
    --t-meter-off: #23262b;
    --t-meter-low: #48a35a;
    --t-meter-mid: #d9a441;
    --t-meter-high: #cf4c47;
    --t-seg-bg: #160f10;
    --t-seg-border: #191314;
    --t-seg-text: #ff4a4399;
    --t-wave-bg: #090b0d;
    --t-wave-bg-selected: #0f1214;
    --t-wave-fg: #ffffff21;
    --t-wave-fg-selected: #ffffff56;
    --t-wave-center-line: #6f768157;
    --t-wave-trim: #ebeef3eb;
    --t-wave-play-points: #a878e8;
    --t-wave-voice-playhead: #969ca647;
    --t-wave-info-label: #8a929e73;
    --t-wave-info-value: #b4bcc899;
    --t-wave-sample-name: #8a929e73;
    --t-slider-track: #060709;
    --t-slider-track-line: #0f1418;
    --t-slider-track-border: #8a8f981a;
    --t-slider-handle: #11161a;
    --t-slider-handle-border: #212d3b;
    --t-slider-led: #8dcfd8;
    --t-slider-ruler: #8bcfd7;
    /* OXO DRUMS keys (OxoThemeColor's Drums block, defaults = the mockup). */
    --t-accent: #c4c0b4;
    --t-accent-text: #141517;
    --t-browser-bg: #1b1c1f;
    --t-browser-text: #a9a9ac;
    --t-browser-line: #ffffff0f;
    --t-seq-bg: #1b1c1f;
    --t-seq-grid: #000000;
    --t-seq-step-active: #000000;
    --t-seq-lane-event: #6f86a8;
    --t-seq-last-step: #e8412a;
    --t-seq-selection: #e8b04a;
    --t-seq-labels: #d6d6d8;
    --t-seq-playhead-bg: #3a3b3e;
    --t-seq-row-selected-bg: #2a2b2e;
    --t-seq-row-selected-fg: #d6d6d8;
    --t-seq-button-bg: #26272a;
    --t-seq-button-text: #b4b4b8;
    --t-pad-bg: #1e1f22;
    --t-pad-border: #2e2f33;
    --t-pad-label: #c2c2c4;
    --t-pad-selected-bg: #34363b;
    --t-pad-selected-label: #ececee;
    --t-pad-activity: #8dcfd8;
    --t-button-radius: 2px;          /* wave-row buttons (button_radius) */
    --t-topbar-button-radius: 2px;   /* top-bar chips (topbar_button_radius) */
    --t-seq-button-radius: 3px;      /* sequencer chips (seq_button_radius) */
    --t-background-image-alpha: 1;   /* background image opacity (background_image_alpha) */

    /* Audio editor palette: the theme's nested `audio_editor` object, one
       --ae-<key> each (AudioEditorThemeColor defaults). */
    --ae-topbar-bg: #101113;
    --ae-topbar-button-bg: #101113;
    --ae-topbar-button-border: #232323;
    --ae-topbar-button-text: #6b6b70;
    --ae-topbar-action-bg: #1d1f27;
    --ae-topbar-action-border: #00000000;
    --ae-topbar-action-text: #7f8592;
    --ae-accent-bg: #6b6b70;         /* a mode that is ON + any button while pressed */
    --ae-accent-fg: #101113;
    --ae-ruler-bg: #1d1f27;
    --ae-ruler-text: #8a929e;
    --ae-wave-bg: #090b0d;
    --ae-wave-fg: #ffffff;
    --ae-wave-grid: #ffffff12;
    --ae-wave-selection: #5c84c04d;
    --ae-wave-cursor: #e0504a;
    --ae-wave-playhead: #969ca647;
    --ae-info-text: #8a929eb3;
    --ae-dialog-bg: #101113;
    --ae-dialog-text: #6b6b70;

    /* EQ palette: the theme's nested `eq` object, one --eq-<key> each
       (EqThemeColor defaults, Shared/EqCore.swift). */
    --eq-topbar-bg: #101113;
    --eq-topbar-button-bg: #101113;
    --eq-topbar-button-border: #232323;
    --eq-topbar-button-text: #6b6b70;
    --eq-accent-bg: #6b6b70;         /* EQ / band power ON, the selected insert, any pressed button */
    --eq-accent-fg: #101113;
    --eq-graph-bg: #090b0d;
    --eq-graph-grid: #ffffff12;
    --eq-graph-text: #8a929e;
    --eq-zero-line: #e0504a80;
    --eq-curve: #ffffff;
    --eq-curve-fill: #ffffff1a;
    --eq-band-curve: #5c84c099;
    --eq-node: #ffffff;
    --eq-node-off: #6b6b70;
    --eq-node-active: #e0504a;
    --eq-info-text: #8a929eb3;
    --eq-analyzer-in: #e0a15e66;     /* analyzer washes: before / after the EQ */
    --eq-analyzer-out: #5c84c080;
    --eq-band-bg: #1d1f27;
    --eq-band-title: #8a929e;
    --eq-knob-body: #6e7179;
    --eq-knob-dial: #141517;
    --eq-knob-ring: #000000;
    --eq-knob-label: #8a929e;
    --eq-lfo-knob-body: #5c84c0;     /* band 3's LFO SPEED / DEPTH knobs */
    --eq-lfo-knob-dial: #141517;

    --bg: var(--t-bg);
    --panel: var(--t-panel-bg);
    --well: #0e0f11;
    --line: rgba(138, 143, 152, .12);
    --line-strong: rgba(138, 143, 152, .3);
    --text: #d7d9dd;
    --text-light: #9a9ea5;
    --label: #6f747f;
    --muted: #6e7480;
    --top-step: #1c1c20;
    --top-border: #232323;
    --top-text: #d0d0d3;
    --top-muted: #6b6b70;
    --top-btn-text: #6b6b6f;
    --btn-text: #808490;
    --knob-track: #121317;
    --knob-ring: var(--t-knob-ring);
    --knob-ring-edge: var(--t-knob-outer-ring);
    --knob-dot: var(--t-knob-ticks);
    --knob-pointer: #141517;
    --orange: #e0a15e;
    --beige: #bcb6a3;
    --blue: #64a5b6;
    --green: #429984;
    --gray: #6e7179;
    --purple: #8c79a7;
    --seg-red: #ff4a43;
    --rec: #632926;
    --rec-border: #331410;
    --slider: #8dcfd8;
    --topbar-h: 50px;
    --app-bg-image: none;              /* theme.js: the theme's background_image data URL, if any */
    --app-bg-position: center;       /* theme.js: center when taller than the canvas, top when shorter */
    --wave-row-top: 140px;             /* button row under the waveform */
    --wave-row-h: 26px;
    --font: -apple-system, "Helvetica Neue", Helvetica, Arial, sans-serif;

    /* Theme slots: big knobs point at one of these (set by theme.js).
       Each slot is a pair: body color + dial (pointer) color. */
    --theme-1: var(--orange);   --theme-1-dial: var(--knob-pointer);
    --theme-2: var(--beige);    --theme-2-dial: var(--knob-pointer);
    --theme-3: var(--purple);   --theme-3-dial: var(--knob-pointer);
    --theme-4: var(--gray);     --theme-4-dial: var(--knob-pointer);
    --theme-5: var(--blue);     --theme-5-dial: var(--knob-pointer);
    --theme-6: var(--green);    --theme-6-dial: var(--knob-pointer);
    --theme-7: var(--slider);   --theme-7-dial: var(--knob-pointer);
    --theme-8: #c96b6b;         --theme-8-dial: var(--knob-pointer);
    --theme-9: #d4c26a;         --theme-9-dial: var(--knob-pointer);
    --theme-10: #e8e6df;        --theme-10-dial: var(--knob-pointer);
  }



  .app {
    /* Sticks under the site header while the editor below scrolls. */
    position: sticky;
    top: var(--sticky-top, 0px);
    z-index: 5;
    width: 1360px;
    height: 853px;
    /* The theme's optional image (alpha OK) over the flat color, placed like
       the plugin (OxoBackgroundImageView): fit to the 1360 px width, ratio
       kept; taller than the canvas = centred and cropped, shorter = top-aligned
       with the base color below. The opaque #0E0E10 underneath is the
       plugin's window color: a transparent `bg` shows it, not the page. */
    background: linear-gradient(var(--bg), var(--bg)), #0e0e10;
    overflow: hidden;
  }
  /* The image on its own layer so background_image_alpha can dim it; first
     in paint order, every absolute child sits over it. */
  .app::before {
    content: '';
    position: absolute; inset: 0;
    background: var(--app-bg-image, none) var(--app-bg-position) / 1360px auto no-repeat;
    opacity: var(--t-background-image-alpha, 1);
    pointer-events: none;
  }
  /* Simple's canvas (1024 x 335) where the plugin puts it: its plate lands
     on the bottom zone's top edge (y 568), right edge on the canvas' right
     edge. Its own top bar is not drawn (the Drums bar spans the canvas);
     the audio editor / EQ layers replace the panel inside this zone. */
  .simple-zone { left: 336px; top: 518px; width: 1024px; height: 335px; overflow: hidden; }
  .simple-zone > .topbar { display: none; }


  /* ---------- theme editor (page tooling, not part of the plugin UI) ---------- */

  /* Four numbered, foldable sections under the panel (1 Themes, 2 Knob
     colors, 3 Panel colors, 4 Background image). */
  .theme-section {
    width: 1360px;
    border: 1px solid rgba(255, 255, 255, .09);
    border-radius: 8px;
    background: rgba(6, 8, 12, .3);
    color: var(--text);
    font-family: var(--font);
  }
  .theme-section summary {
    list-style: none;
    display: flex; align-items: baseline; gap: 12px;
    padding: 8px 8px 8px 16px;
    cursor: default; user-select: none;
  }
  .theme-section summary::-webkit-details-marker { display: none; }
  /* Only the chevron button folds the section (clicking the title is inert,
     so it can be used to move focus etc.). */
  .section-fold {
    flex: none; margin-left: auto; align-self: center;
    width: 28px; height: 28px; padding: 0;
    display: grid; place-items: center;
    background: none; border: 0; border-radius: 6px;
    cursor: pointer;
  }
  .section-fold:hover { background: rgba(255, 255, 255, .08); }
  .section-fold:focus-visible { outline: 1.5px solid var(--text-light); outline-offset: -1px; }
  .section-fold::after {
    content: "";
    width: 7px; height: 7px;
    border: solid var(--text-light); border-width: 0 1.5px 1.5px 0;
    rotate: 45deg; translate: 0 -2px;
    transition: rotate .15s;
  }
  .section-fold:hover::after { border-color: #fff; }
  .theme-section:not([open]) .section-fold::after { rotate: -45deg; translate: -2px 0; }
  .section-num {
    flex: none;
    width: 20px; height: 20px; align-self: center;
    border-radius: 50%;
    background: rgba(255, 255, 255, .1);
    font: 700 11px/20px var(--font); text-align: center;
    color: var(--text);
  }
  .section-title { font: 700 13px var(--font); letter-spacing: .2px; color: var(--text); }
  .section-hint { font: 12px var(--font); color: var(--text-light); }
  .section-body { padding: 4px 16px 16px; display: grid; gap: 14px; }

  /* Prose inside the sections. */
  .section-help, .section-note, .field-help, .bg-note, .section-steps {
    font: 12px/1.5 var(--font); color: var(--text-light);
    b { color: var(--text); font-weight: 600; }
    code { font: 11px "Menlo", "Courier New", monospace; color: var(--text); }
    a { text-decoration: underline; text-underline-offset: 2px; }
    a:hover { color: #fff; }
  }
  .section-steps { padding-left: 18px; display: grid; gap: 6px; align-content: start; }
  .section-steps li::marker { color: var(--text); font-weight: 700; }

  /* Section 1: three columns, one per theme source. */
  .theme-row { display: grid; grid-template-columns: 1.1fr 1fr 1fr; gap: 24px; align-items: start; }
  .theme-field { display: grid; gap: 8px; align-content: start; }
  .field-label { font: 700 9px var(--font); letter-spacing: .8px; text-transform: uppercase; color: var(--text-light); }
  .theme-presets { display: flex; flex-wrap: wrap; gap: 6px; }
  .theme-presets button {
    height: 26px; padding: 0 10px;
    border-radius: 13px;
    border: 1px solid rgba(255, 255, 255, .15);
    background: #1d1f26; color: var(--text-light);
    font: 600 11px var(--font); letter-spacing: .3px;
    cursor: pointer;
  }
  .theme-presets button:hover { color: var(--text); background: #262932; }
  .theme-presets button.active { color: #fff; border-color: #fff; background: #262932; }
  .theme-saved { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
  .theme-saved select, .theme-saved button {
    height: 26px; padding: 0 10px;
    border-radius: 6px;
    border: 1px solid rgba(255, 255, 255, .15);
    background: #1d1f26; color: var(--text);
    font: 600 11px var(--font);
    cursor: pointer;
  }
  .theme-saved select { min-width: 150px; }
  .theme-saved button:hover:not(:disabled) { background: #262932; }
  .theme-saved :disabled { opacity: .45; cursor: default; }

  /* Section 2: swatch grid on the left, the three steps on the right. */
  .theme-bar { display: flex; align-items: flex-start; gap: 28px; }
  .theme-bar .section-steps { flex: 1; min-width: 0; padding-top: 2px; }
  /* 2 rows (body / dial) x 10 slots, with a row label in the first column. */
  .swatches { display: grid; grid-template-columns: auto repeat(10, 32px); gap: 8px; align-items: center; }
  .swatches .row-label { font: 700 9px var(--font); letter-spacing: .8px; text-transform: uppercase; color: var(--text-light); padding-right: 6px; }
  .swatch {
    position: relative; touch-action: manipulation;   /* no double-tap zoom on iPad */
    width: 32px; height: 32px;
    border-radius: 6px;
    background: var(--c);
    border: 2px solid rgba(255, 255, 255, .12);
    cursor: pointer;
    font: 700 9px/1 var(--font);
    color: rgba(0, 0, 0, .55);
    display: flex; align-items: flex-end; justify-content: flex-end;
    padding: 3px;
  }
  .swatch.dial { color: rgba(255, 255, 255, .45); }
  .swatch.selected { border-color: #fff; box-shadow: 0 0 0 2px rgba(255, 255, 255, .25); }
  .swatch input[type="color"] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }   /* takes the tap itself: iOS ignores synthetic click() on color inputs */
  .theme-actions { display: flex; flex-wrap: wrap; gap: 8px; }
  .theme-actions button {
    height: 26px; padding: 0 12px;
    border-radius: 6px;
    border: 1px solid rgba(255, 255, 255, .15);
    background: #1d1f26; color: var(--text);
    font: 600 11px var(--font);
    cursor: pointer;
  }
  .theme-actions button:hover { background: #262932; }
  .theme-actions .save-theme { background: #2b4f5c; border-color: #3d6b7c; }   /* the main exit of the page */
  .theme-actions .save-theme:hover { background: #335f6e; }
  .load-error { color: #e07070; }
  .load-error[hidden] { display: none; }

  /* Section 4: buttons + the "not part of the JSON" note. */
  .theme-bg { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
  .theme-bg .bg-name { font: 11px var(--font); color: var(--text-light); }
  .theme-bg :disabled { opacity: .45; cursor: default; }
  .theme-bg .bg-note, .theme-bg .bg-error { flex: 1 1 100%; }
  .theme-bg .bg-alpha { display: flex; align-items: center; gap: 8px; font: 11px var(--font); color: var(--text-light); }
  .theme-bg .bg-alpha input { width: 120px; }

  /* Section 3: element colors, groups of rows (label / swatch / alpha / hex). */
  .theme-elements {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px 28px;
    align-items: start;
  }
  .theme-elements .element-group h4 {
    margin: 0 0 6px;
    font: 700 9px var(--font); letter-spacing: .8px; text-transform: uppercase;
    color: var(--text-light);
  }
  .element-row {
    display: grid; grid-template-columns: 1fr 22px 60px 70px; gap: 8px; align-items: center;
    height: 24px;
    font: 500 11px var(--font); color: var(--text);
  }
  .element-row > span:first-child { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .element-row .element-swatch {
    position: relative; touch-action: manipulation;
    width: 22px; height: 18px; border-radius: 4px;
    border: 1px solid rgba(255, 255, 255, .18);
    background: linear-gradient(var(--c), var(--c)),
                repeating-conic-gradient(#666 0 25%, #333 0 50%) 0 0 / 8px 8px;
    cursor: pointer;
  }
  .element-row .element-swatch input[type="color"] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }
  .element-row input[type="range"] { width: 60px; height: 14px; accent-color: #8dcfd8; cursor: pointer; }
  .element-row .element-hex {
    width: 70px; height: 20px; padding: 0 4px;
    border: 1px solid rgba(255, 255, 255, .12); border-radius: 4px;
    background: #0e0f11; color: var(--text-light);
    font: 10px "Menlo", "Courier New", monospace;
  }
  .element-row .element-hex.invalid { border-color: #e07070; }
  .element-row.radius { grid-template-columns: 1fr 90px 40px; }
  .element-row .element-value { font: 10px "Menlo", "Courier New", monospace; color: var(--text-light); text-align: right; }
  .theme-bg button {
    height: 26px; padding: 0 12px;
    border-radius: 6px;
    border: 1px solid rgba(255, 255, 255, .15);
    background: #1d1f26; color: var(--text);
    font: 600 11px var(--font);
    cursor: pointer;
    white-space: nowrap;
  }
  .theme-bg button:hover:not(:disabled) { background: #262932; }
  .theme-bg button[hidden] { display: none; }

  .app .knob:not(.top) { cursor: pointer; }

  /* Everything inside .app is absolute in design coordinates. */
  .app div, .app svg { position: absolute; }

  /* ---------- generic: labels ---------- */

  .label, .mini-label, .group-label span, .toggle {
    font-size: 8px;
    font-weight: 700;
    letter-spacing: .8px;
    text-transform: uppercase;
    color: var(--t-knob-label);
    text-align: center;
    white-space: nowrap;
  }

  /* ---------- generic: knobs ---------- */

  .knob {
    width: 33px;
    height: 46.8px;
    --v: attr(data-value type(<number>), 0);      /* 0..100 */
    --color: var(--gray);
  }
  .knob .label {
    position: absolute;
    left: -10px; right: -10px; top: 0;
    height: 10px;
    line-height: 10px;
  }
  /* Ring + 11 tick dots every 27deg over the 270deg sweep
     (centre 16.5 / 32.4, dot radius 17.5). */
  .knob::before {
    content: "";
    position: absolute;
    left: -1.5px; top: 14.4px;
    width: 36px; height: 36px;
    border-radius: 50%;
    background:
      radial-gradient(circle at 5.63px 30.37px,  var(--knob-dot) 0 .7px, transparent .9px),
      radial-gradient(circle at 1.36px 23.41px,  var(--knob-dot) 0 .7px, transparent .9px),
      radial-gradient(circle at .72px 15.26px,   var(--knob-dot) 0 .7px, transparent .9px),
      radial-gradient(circle at 3.84px 7.71px,   var(--knob-dot) 0 .7px, transparent .9px),
      radial-gradient(circle at 10.06px 2.41px,  var(--knob-dot) 0 .7px, transparent .9px),
      radial-gradient(circle at 18px .5px,       var(--knob-dot) 0 .7px, transparent .9px),
      radial-gradient(circle at 25.94px 2.41px,  var(--knob-dot) 0 .7px, transparent .9px),
      radial-gradient(circle at 32.16px 7.71px,  var(--knob-dot) 0 .7px, transparent .9px),
      radial-gradient(circle at 35.28px 15.26px, var(--knob-dot) 0 .7px, transparent .9px),
      radial-gradient(circle at 34.64px 23.41px, var(--knob-dot) 0 .7px, transparent .9px),
      radial-gradient(circle at 30.37px 30.37px, var(--knob-dot) 0 .7px, transparent .9px);
  }
  .knob::after {
    content: "";
    position: absolute;
    left: 3px; top: 18.9px;
    width: 27px; height: 27px;
    border-radius: 50%;
    background: var(--knob-ring);
    box-shadow: 0 0 0 1px var(--knob-ring-edge);
  }
  .knob .dial {
    position: absolute;
    left: 4.5px; top: 20.4px;
    width: 24px; height: 24px;
    border-radius: 50%;
    background: var(--color);
    box-shadow: inset 0 -1px 1px rgba(0, 0, 0, .18);
    transform: rotate(calc(-135deg + var(--v) * 2.7deg));
    z-index: 1;
  }
  .knob .dial::after {               /* pointer: r 4 -> r 10 */
    content: "";
    position: absolute;
    left: 50%; top: 2.5px;
    width: 2px; height: 6px;
    margin-left: -1px;
    border-radius: 1px;
    background: var(--pointer, var(--knob-pointer));
  }
  /* Sequencer control-lane modulation: a thin arc just outside the tick dots
     (r 18.7, like the plugin's 18 * 1.04) from the knob's value to the
     modulated one (--mod, signed 0..100 offset set inline). The dial stays put. */
  .knob .mod {
    position: absolute;
    left: -3.5px; top: 12.4px;
    width: 40px; height: 40px;
    border-radius: 50%;
    --a0: calc(-135deg + var(--v) * 2.7deg);
    --a1: calc(-135deg + clamp(0, var(--v) + var(--mod, 0), 100) * 2.7deg);
    --from: min(var(--a0), var(--a1));
    --sweep: max(var(--a0) - var(--a1), var(--a1) - var(--a0));
    background: conic-gradient(from var(--from), var(--t-knob-modulation) 0 var(--sweep), transparent var(--sweep));
    -webkit-mask: radial-gradient(circle, transparent 17.8px, #000 18px, #000 19.5px, transparent 19.7px);
    mask: radial-gradient(circle, transparent 17.8px, #000 18px, #000 19.5px, transparent 19.7px);
    pointer-events: none;
    z-index: 2;
  }

  /* Default theme slot per group (theme.js overrides per knob via inline --color/--pointer). */
  .knob.rec.input  { --color: var(--theme-1); --pointer: var(--theme-1-dial); }
  .knob.rec.monitor{ --color: var(--theme-2); --pointer: var(--theme-2-dial); }
  .knob.wave       { --color: var(--theme-3); --pointer: var(--theme-3-dial); }
  .knob.tune       { --color: var(--theme-4); --pointer: var(--theme-4-dial); }
  .knob.lfo        { --color: var(--theme-5); --pointer: var(--theme-5-dial); }
  .knob.filter     { --color: var(--theme-6); --pointer: var(--theme-6-dial); }
  .knob.shape      { --color: var(--theme-5); --pointer: var(--theme-5-dial); }
  .knob.output     { --color: var(--theme-2); --pointer: var(--theme-2-dial); }

  /* ---------- generic: mini knobs ---------- */

  .mini-knob {
    width: 14px; height: 14px;
    border-radius: 50%;
    background: var(--t-mini-knob-body);
    border: 1px solid var(--t-mini-knob-border);
    box-shadow: inset 0 0 0 1px #21262c;
    --v: attr(data-value type(<number>), 0);
    transform: rotate(calc(-135deg + var(--v) * 2.7deg));
  }
  .mini-knob::after {
    content: "";
    position: absolute;
    left: 50%; top: 1.5px;
    width: 1.5px; height: 4.5px;
    margin-left: -.75px;
    border-radius: 1px;
    background: var(--t-mini-knob-dial);
  }

  /* ---------- generic: toggles (chips) ---------- */

  .toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--t-chip-border);
    border-radius: 3px;
    background: var(--t-chip-bg);
    color: var(--t-chip-text);
  }
  .toggle.mini { width: 49px; height: 14px; font-size: 7.5px; }
  .toggle.mini.dim { color: color-mix(in srgb, var(--t-chip-text) 35%, transparent); }

  /* ---------- generic: buttons ---------- */

  .button {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    border-radius: var(--t-button-radius);
    color: var(--t-button-text);
    font-size: 11.5px;
    font-weight: 600;
    white-space: nowrap;
  }
  .button svg {
    position: static;
    width: 16px; height: 16px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  .button.top  { height: 28px; border-radius: var(--t-topbar-button-radius); background: var(--t-topbar-button-bg); border: 1px solid var(--t-topbar-button-border); font-size: 12px; color: var(--t-topbar-button-text); }
  .button.wave { top: 0; height: var(--wave-row-h); width: 60px; background: var(--t-button-bg); }
  .button.lit { background: var(--t-button-lit-bg); color: var(--t-button-lit-text); }
  .button.lit .dot { background: var(--t-button-lit-text); }
  .disabled { opacity: .38; }

  /* ============ TOP BAR ============ */

  /* The DRUMS top bar: Simple's row across the 1360 canvas — logo / play at
     the left, the preset name over the Browser's FILES column, the ENGINE
     tabs from the sequencer's M column (see .engine-*); from the right: menu,
     Save, Presets, REC, redo, undo, volume (DrumsL.TopBar, 10px gaps; RESYNC
     and the swing knob live in the SCENE BAR, see .scene-chip). */
  .topbar { left: 0; top: 0; width: 1360px; height: var(--topbar-h); background: var(--t-topbar-bg); }

  .logo {
    left: 20px; top: 16px; width: 68px; height: 18px;
    fill: none;
    stroke: var(--t-topbar-logo);
    stroke-width: 56;
  }


  /* Preset name + size over the Browser's FILES column (DrumsL.TopBar.presetName: x 128, 198 wide), tail ellipsis. */
  .preset { left: 128px; top: 11px; width: 198px; height: 38px; }
  .preset-name { left: 0; top: 0; width: 198px; height: 28px; line-height: 28px; font-size: 12px; font-weight: 700; color: var(--t-topbar-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .preset-size { left: 0; top: 24px; height: 14px; line-height: 14px; font-size: 7px; letter-spacing: .5px; color: var(--t-topbar-text-accent); }

  /* ENGINE TABS (DrumsL.Engines, in the top bar row): 4 groups of a tiny
     M / S pair (the sequencer rows' toggles) + a 64 x 28 tab (UNDO's
     height) in the top-bar chip chrome + the ENGINE LEVEL knob, the first
     M on the sequencer's left edge (x 352); the selected tab lit in the
     ACCENT pair, a muted engine's label dims (0.4), a SOUNDING engine shows
     the pad activity LED under its name. */
  .engine-tab {
    display: flex; align-items: center; justify-content: center; padding: 0 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    border-radius: var(--t-topbar-button-radius); background: var(--t-topbar-button-bg);
    border: 1px solid var(--t-topbar-button-border); color: var(--t-topbar-button-text);
    font-size: 9px; font-weight: 700; cursor: pointer; box-sizing: border-box;
  }
  .engine-tab.lit { background: var(--t-accent); border-color: var(--t-accent); color: var(--t-accent-text); }
  .engine-tab.muted { color: color-mix(in srgb, var(--t-topbar-button-text) 40%, transparent); }
  .engine-tab.lit.muted { color: color-mix(in srgb, var(--t-accent-text) 40%, transparent); }
  /* A SOUNDING engine: the pad cells' activity LED under the name. */
  .engine-tab.sounding::after { content: ''; position: absolute; left: 50%; margin-left: -8px; bottom: 3px; width: 16px; height: 2px; border-radius: 1px; background: var(--t-pad-activity); }
  .engine-ms { display: flex; align-items: center; justify-content: center; font-size: 8px; font-weight: 700; border-radius: 2px; color: color-mix(in srgb, var(--t-seq-labels) 85%, transparent); cursor: pointer; }
  .engine-ms.mute.lit { background: var(--t-mute-active); color: var(--t-accent-text); }
  .engine-ms.solo.lit { background: var(--t-solo-active); color: var(--t-accent-text); }
  /* SCENE BAR (DrumsL.Scenes, built by theme.js between the top bar and
     the Sequencer): every chip in the SEQUENCER chip chrome (the PATTERNS
     row's: seq_button_*, seq_button_radius, no border) at the top bar's
     28 px height; the selected scene lit in the ACCENT pair, a PENDING
     scene (a launch some engine still waits on) and an ARMED Resync fill
     left -> right with their progress in the accent. */
  .scene-chip {
    display: flex; align-items: center; justify-content: center; gap: 5px; padding: 0 6px; box-sizing: border-box;
    border-radius: var(--t-seq-button-radius); background: var(--t-seq-button-bg); color: var(--t-seq-button-text);
    font-size: 10px; font-weight: 600; white-space: nowrap; overflow: hidden; cursor: pointer;
  }
  .scene-chip .chev { position: static; width: 0; height: 0; border: 3.5px solid transparent; border-top: 4.5px solid currentColor; margin-top: 4px; }
  .scene-chip.lit { background: var(--t-accent); color: var(--t-accent-text); }
  .scene-chip.pending, .scene-chip.resync.lit {
    background: linear-gradient(to right, var(--t-accent) 0 var(--progress, 40%), var(--t-seq-button-bg) var(--progress, 40%));
  }
  .scene-chip.resync.lit { color: var(--t-accent-text); }
  /* Swing knob (oxo_steps' TopBarSwingKnob) in the scene bar after Resync
     (DrumsL.Scenes.swing: 34 x 28, geometry inline from theme.js): a 15 px
     knob OVER its "swing" label (blank at 50): 270deg ring in
     knob_outer_ring, the set part in the accent, pointer in topbar_text. */
  .swing-knob .ring {
    left: 9.5px; top: 2px; width: 15px; height: 15px; border-radius: 50%;
    background: conic-gradient(from 225deg, var(--t-accent) 0 120deg, var(--t-knob-outer-ring) 120deg 270deg, transparent 270deg);
    -webkit-mask: radial-gradient(circle, transparent 6px, #000 6.6px);
    mask: radial-gradient(circle, transparent 6px, #000 6.6px);
  }
  .swing-knob .pointer { left: 16.25px; top: 4.5px; width: 1.5px; height: 4px; background: var(--t-topbar-text); transform-origin: .75px 5px; transform: rotate(-15deg); }
  .swing-knob .swing-label { left: 0; top: 18px; width: 34px; height: 10px; line-height: 10px; text-align: center; font-size: 7px; font-weight: 600; color: color-mix(in srgb, var(--t-seq-labels) 55%, transparent); }

  /* REC (live step record): a dot + "Rec", lit in the button_lit pair. */
  .button.top.rec { left: 1124px; top: 11px; width: 52px; gap: 5px; cursor: pointer; }
  /* MIDI IN CAPTURE (Simple's Presets slot is gone): Sample's keyboard
     glyph, 3 outlined keys + 2 black keys (13 x 11, 1 px strokes), lit
     in the button_lit pair like Rec. */
  .button.top.midi-capture { left: 1186px; top: 11px; width: 36px; cursor: pointer; }
  .button.top.midi-capture .keys { position: relative; width: 13px; height: 11px; border: 1px solid currentColor; box-sizing: border-box; }
  .button.top.midi-capture .keys i { position: absolute; top: 0; width: 1px; height: 9px; background: currentColor; }
  .button.top.midi-capture .keys i::after { content: ""; position: absolute; left: -.5px; top: 0; width: 2px; height: 6px; background: currentColor; }
  .button.top.midi-capture .keys i:nth-child(1) { left: 3px; }
  .button.top.midi-capture .keys i:nth-child(2) { left: 7px; }
  .button.top.rec .dot { position: static; width: 7px; height: 7px; border-radius: 50%; background: color-mix(in srgb, var(--t-topbar-button-text) 70%, transparent); }
  .button.top.rec.lit .dot { background: var(--t-button-lit-text); }

  .knob.top.volume { left: 994px; top: 11px; width: 36px; height: 28px; }
  /* Same look as the panel's mini knobs, 16px like the plugin's
     TopBarVolumeKnob (the minis are 14px), centered in the chip. */
  .knob.top.volume .dial {
    left: 10px; top: 6px;
    width: 16px; height: 16px;
    background: var(--t-mini-knob-body);
    border: 1px solid var(--t-mini-knob-border);
    box-shadow: inset 0 0 0 1px #21262c;
  }
  .knob.top.volume::before, .knob.top.volume::after { content: none; }
  .knob.top.volume .dial::after { top: 1.5px; height: 4.5px; width: 1.5px; margin-left: -.75px; background: var(--t-mini-knob-dial); }
  /* ENGINE LEVEL knobs (built by theme.js after each engine tab): the same
     knob in a 20 px box, geometry inline. */
  .knob.top.engine-level .dial { left: 2px; }

  .button.top.undo    { left: 1040px; top: 11px; width: 32px; }
  .button.top.redo    { left: 1082px; top: 11px; width: 32px; }
  .button.top.save    { left: 1232px; top: 11px; width: 76px; }
  .button.top.menu    { left: 1318px; top: 11px; width: 32px; }

  /* ============ AUDIO EDITOR (Edit button) ============ */
  /* OXO DRUMS: fills the 1024 x 285 SAMPLER ZONE only (`DrumsL.samplerZone`
     = the simple-zone under its hidden 50 px top bar; the browser, sequencer
     and pads stay usable around it): top bar 50, body 235 (rulers 16 / 24,
     lanes 109.5), 28px chips, 11px font, 8px gap, 10px side margin —
     AudioEditorLayout, the panel's own bar / chip heights;
     shown while .app has .editing. Colours are the --ae-* palette only. */

  .audio-editor { inset: 50px 0 0; background: var(--ae-topbar-bg); display: none; z-index: 3; font-family: var(--font); }
  .app.editing .audio-editor { display: block; }
  .app.editing .panel { visibility: hidden; }
  /* Flex / grid children back to static (`.app div` makes everything absolute). */
  .ae-topbar > div, .ae-button svg, .ae-dialog-panel div { position: static; }

  .ae-topbar { position: absolute; left: 0; top: 0; width: 1024px; height: 50px; padding: 0 10px; display: flex; align-items: center; gap: 8px; }
  .ae-spacer { flex: 1; }
  .ae-button, .ae-action {
    display: inline-flex; align-items: center; gap: 5px;
    height: 28px; padding: 0 10px;
    border-radius: var(--t-topbar-button-radius);
    font: 600 11px var(--font); white-space: nowrap;
    cursor: pointer; user-select: none;
  }
  .ae-button { background: var(--ae-topbar-button-bg); border: 1px solid var(--ae-topbar-button-border); color: var(--ae-topbar-button-text); }
  .ae-action { background: var(--ae-topbar-action-bg); border: 1px solid var(--ae-topbar-action-border); color: var(--ae-topbar-action-text); }
  .ae-button svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
  .ae-topbar .dim { opacity: .35; }
  /* Play modes (MIDI capture + Loop), set apart from the actions; ON = the
     accent pair, like any button while it is held down; Loop is dimmed
     while MIDI capture is OFF. */
  .ae-modes { display: flex; gap: 8px; margin-right: 12px; }
  .ae-modes > div { position: static; }
  .ae-midi.on, .ae-loop.on,
  .ae-button:active, .ae-action:active { background: var(--ae-accent-bg); border-color: var(--ae-accent-bg); color: var(--ae-accent-fg); }
  /* 13 x 11 keyboard glyph: outline + 2 separators + 2 black keys, in currentColor. */
  .ae-keys {
    display: block; position: relative; width: 13px; height: 11px;
    border: 1px solid currentColor;
    background:
      linear-gradient(currentColor, currentColor) 3px 0 / 1px 9px no-repeat,
      linear-gradient(currentColor, currentColor) 7px 0 / 1px 9px no-repeat,
      linear-gradient(currentColor, currentColor) 2.5px 0 / 2px 6px no-repeat,
      linear-gradient(currentColor, currentColor) 6.5px 0 / 2px 6px no-repeat;
  }

  .ae-body { position: absolute; left: 0; top: 50px; width: 1024px; height: 235px; background: var(--ae-ruler-bg); }
  .ae-corner { position: absolute; left: 0; top: 0; width: 24px; height: 16px; font: 600 8px var(--font); color: var(--ae-ruler-text); display: flex; align-items: center; justify-content: center; }
  .ae-time-ruler { position: absolute; left: 24px; top: 0; width: 1000px; height: 16px; overflow: hidden; }
  .ae-time-ruler span { position: absolute; top: 1px; padding-left: 3px; border-left: 1px solid color-mix(in srgb, var(--ae-ruler-text) 80%, transparent); height: 15px; font: 500 8px var(--font); color: var(--ae-ruler-text); line-height: 10px; }
  .ae-level-ruler { position: absolute; left: 0; top: 16px; width: 24px; height: 219px; }
  .ae-level-ruler span { position: absolute; right: 4px; font: 500 7px var(--font); color: var(--ae-ruler-text); line-height: 8px; }

  .ae-wave { position: absolute; left: 24px; top: 16px; width: 1000px; height: 219px; background: var(--ae-wave-bg); overflow: hidden; }
  .ae-selection { position: absolute; left: 290px; top: 0; width: 370px; height: 219px; background: var(--ae-wave-selection); }
  .ae-lane { position: absolute; left: 0; width: 1000px; height: 109.5px; }
  .ae-lane + .ae-lane { top: 109.5px; }
  .ae-lane-wave { position: absolute; left: 0; top: 0; width: 1000px; height: 109.5px; fill: none; stroke: var(--ae-wave-fg); stroke-width: 1; }
  .ae-lane-wave path { vector-effect: non-scaling-stroke; }
  /* Centre line (wave colour at 25%) + the -3 / -6 dB grid lines
     (wave_grid), both halves. */
  .ae-center {
    --grid: linear-gradient(var(--ae-wave-grid), var(--ae-wave-grid));
    position: absolute; left: 0; top: 0; width: 1000px; height: 109.5px; display: block;
    background:
      linear-gradient(color-mix(in srgb, var(--ae-wave-fg) 25%, transparent), color-mix(in srgb, var(--ae-wave-fg) 25%, transparent)) 0 55px / 100% 1px no-repeat,
      var(--grid) 0 16px / 100% 1px no-repeat,
      var(--grid) 0 27px / 100% 1px no-repeat,
      var(--grid) 0 82px / 100% 1px no-repeat,
      var(--grid) 0 93px / 100% 1px no-repeat;
  }
  /* Vertical grid: the buffer in 16ths, full height. Quarters in wave_grid,
     eighths at 75 %, sixteenths at 50 % of its alpha. Each layer is a
     repeating tile with its 1 px line INSIDE the tile (never at x = 0), the
     element inset 1 px / 999 wide so neither edge gets a line; quarters
     paint over the fainter layers. */
  .ae-vgrid {
    --g4: var(--ae-wave-grid);
    --g8: color-mix(in srgb, var(--ae-wave-grid) 75%, transparent);
    --g16: color-mix(in srgb, var(--ae-wave-grid) 50%, transparent);
    position: absolute; left: 1px; top: 0; width: 999px; height: 219px; display: block;
    background:
      linear-gradient(to right, transparent 249px, var(--g4) 249px) 0 0 / 250px 100% repeat-x,
      linear-gradient(to right, transparent 124px, var(--g8) 124px 125px, transparent 125px) 0 0 / 250px 100% repeat-x,
      linear-gradient(to right, transparent 61px, var(--g16) 61px 62px, transparent 62px) 0 0 / 125px 100% repeat-x;
  }
  .ae-playhead { position: absolute; top: 0; width: 1px; height: 219px; background: var(--ae-wave-playhead); }
  .ae-cursor { position: absolute; left: 660px; top: 0; width: 1px; height: 219px; background: var(--ae-wave-cursor); }
  .ae-info { position: absolute; right: 6px; bottom: 6px; display: flex; gap: 10px; font: 500 9px var(--font); color: var(--ae-info-text); }
  .ae-info span { display: inline-flex; gap: 4px; }
  .ae-info em { font-style: normal; opacity: .6; }
  .ae-info b { font-weight: 500; font-variant-numeric: tabular-nums; }

  /* Gain dialog (click Gain): scrim + panel, dialog_bg / dialog_text, steppers = actions, Cancel / OK = buttons. */
  .ae-dialog { position: absolute; inset: 0; }
  .ae-dialog[hidden] { display: none; }
  .ae-dialog-scrim { position: absolute; inset: 0; background: rgba(0, 0, 0, .35); cursor: pointer; }
  .ae-dialog-panel {
    position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
    display: grid; gap: 14px; justify-items: center;
    padding: 20px; border-radius: 6px;
    background: var(--ae-dialog-bg); border: 1px solid var(--ae-topbar-button-border);
    box-shadow: 0 4px 12px rgba(0, 0, 0, .35);
  }
  .ae-dialog-title { font: 600 13px var(--font); color: var(--ae-dialog-text); }
  .ae-dialog-row { display: flex; align-items: center; gap: 12px; }
  .ae-dialog-row > span { min-width: 70px; font: 700 10px var(--font); letter-spacing: .8px; color: var(--ae-dialog-text); }
  .ae-stepper { min-width: 96px; justify-content: center; cursor: default; }
  .ae-stepper i { display: inline-block; width: 6px; height: 6px; border: solid currentColor; border-width: 0 1px 1px 0; transform: rotate(45deg) translateY(-2px); opacity: .7; }
  .ae-dialog-buttons { display: flex; gap: 8px; justify-self: end; margin-top: 10px; }
  /* Cancel / OK share one width (dialogButtonWidth). */
  .ae-dialog-buttons .ae-button { min-width: 72px; justify-content: center; }

  /* ============ EQ (EQ chip) ============ */
  /* OXO DRUMS: fills the 1024 x 285 sampler zone like the editor (top bar
     50, graph 161 with a 26px dB column, band strip 74 — EqLayout); shown while .app has .eqing.
     Colours are the --eq-* palette only. The curve is drawn by theme.js
     (the plugin's RBJ maths) into the SVG. */

  .eq-dialog { inset: 50px 0 0; background: var(--eq-topbar-bg); display: none; z-index: 3; font-family: var(--font); }
  .app.eqing .eq-dialog { display: block; }
  .app.eqing .panel { visibility: hidden; }
  .eq-dialog .eq-topbar > div, .eq-dialog .eq-button svg, .eq-dialog .eq-band, .eq-dialog .eq-band > div, .eq-dialog .eq-band-row > div, .eq-dialog .eq-knob > span, .eq-dialog .eq-gain, .eq-dialog .eq-gain > div { position: static; }

  .eq-topbar { position: absolute; left: 0; top: 0; width: 1024px; height: 50px; padding: 0 10px; display: flex; align-items: center; gap: 7px; }
  .eq-spacer { flex: 1; }
  .eq-label { margin-left: 10px; font: 600 11px var(--font); color: var(--eq-topbar-button-text); white-space: nowrap; }
  .eq-button {
    display: inline-flex; align-items: center; justify-content: center; gap: 5px;
    height: 28px; padding: 0 10px;
    border-radius: var(--t-topbar-button-radius);
    background: var(--eq-topbar-button-bg); border: 1px solid var(--eq-topbar-button-border); color: var(--eq-topbar-button-text);
    font: 600 11px var(--font); white-space: nowrap;
    cursor: pointer; user-select: none;
  }
  .eq-button svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
  .eq-button.dim { opacity: .35; }
  .eq-button.on, .eq-button:active { background: var(--eq-accent-bg); border-color: var(--eq-accent-bg); color: var(--eq-accent-fg); }

  .eq-graph { position: absolute; left: 0; top: 50px; width: 1024px; height: 161px; background: var(--eq-graph-bg); overflow: hidden; }
  .eq-plot { position: absolute; left: 0; top: 0; width: 998px; height: 161px; }
  .eq-plot svg { position: absolute; left: 0; top: 0; width: 998px; height: 161px; overflow: visible; }
  .eq-grid-minor { stroke: color-mix(in srgb, var(--eq-graph-grid) 50%, transparent); }
  .eq-grid-major { stroke: var(--eq-graph-grid); }
  .eq-zero { stroke: var(--eq-zero-line); }
  .eq-band-curve { fill: none; stroke: var(--eq-band-curve); stroke-width: 1; }
  .eq-curve-fill { fill: var(--eq-curve-fill); }
  .eq-analyzer-in { fill: var(--eq-analyzer-in); }
  .eq-analyzer-out { fill: var(--eq-analyzer-out); }
  .eq-curve { fill: none; stroke: var(--eq-curve); stroke-width: 1; stroke-linejoin: round; }
  .eq-freq-label { position: absolute; bottom: 3px; font: 500 8.5px var(--font); color: var(--eq-graph-text); font-variant-numeric: tabular-nums; padding-left: 3px; }
  .eq-node { position: absolute; width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px; border-radius: 50%; background: var(--eq-node); border: 1px solid var(--eq-graph-bg); }
  .eq-node.off { background: var(--eq-node-off); opacity: .55; }
  .eq-node.active { background: var(--eq-node-active); }
  .eq-node::before { content: attr(data-n); position: absolute; left: 50%; top: -13px; transform: translateX(-50%); font: 700 8px var(--font); color: var(--eq-graph-text); }
  .eq-node.off::before { opacity: .55; }
  .eq-db-ruler { position: absolute; left: 998px; top: 0; width: 26px; height: 161px; background: var(--eq-graph-bg); }
  .eq-db-ruler span { position: absolute; left: 4px; font: 500 8.5px var(--font); color: var(--eq-graph-text); line-height: 10px; margin-top: -5px; font-variant-numeric: tabular-nums; }
  .eq-db-ruler .unit { top: 3px; margin-top: 0; font: 600 8px var(--font); }
  /* Readout bottom-right of the plot, above the frequency labels (the plugin's). */
  .eq-info { position: absolute; right: 8px; bottom: 18px; font: 500 10px var(--font); color: var(--eq-info-text); font-variant-numeric: tabular-nums; white-space: pre; }
  .eq-range { position: absolute; left: 946px; top: 6px; width: 48px; height: 20px; padding: 0; font: 600 8px var(--font); font-variant-numeric: tabular-nums; cursor: default; }

  /* Four band columns share the width left of the 96 px output GAIN column (the plugin's
     EqLayout.gainColumnWidth); band 3 is wider by its two LFO knobs (2 x (24 + 14) = 76 px). */
  .eq-bands { position: absolute; left: 0; top: 211px; width: 1024px; height: 74px; background: var(--eq-band-bg); display: flex; }
  .eq-band { width: 213px; padding-top: 11px; display: flex; flex-direction: column; align-items: center; gap: 4px; }
  .eq-band.lfo { width: 289px; }
  .eq-band.lfo .eq-band-title { left: -22px; }
  .eq-knob.lfo .eq-dial { background: var(--eq-lfo-knob-body); }
  .eq-knob.lfo .eq-dial::after { background: var(--eq-lfo-knob-dial); }
  .eq-gain { width: 96px; padding-top: 11px; display: flex; flex-direction: column; align-items: center; gap: 4px; }
  .eq-gain .eq-band-title { left: 0; }
  .eq-dialog.off .eq-gain .eq-knob { opacity: .45; }
  /* Centred on the GAIN knob (row centre + 16), not on the row. */
  .eq-band-title { position: relative; left: 16px; font: 600 8.5px var(--font); letter-spacing: .6px; color: var(--eq-band-title); }
  .eq-band-row { display: flex; align-items: flex-start; gap: 14px; }
  .eq-band-row .eq-button { width: 18px; height: 18px; padding: 0; margin-top: 3px; }
  .eq-band-row .eq-button svg { width: 9px; height: 9px; stroke-width: 2; }
  .eq-knob { display: flex; flex-direction: column; align-items: center; gap: 3px; }
  .eq-knob .eq-dial {
    display: block; width: 24px; height: 24px; border-radius: 50%;
    background: var(--eq-knob-body); border: 2px solid var(--eq-knob-ring); box-sizing: border-box;
    position: relative; transform: rotate(calc(-140deg + 2.8deg * var(--v, 50)));
  }
  .eq-knob .eq-dial::after { content: ""; position: absolute; left: 50%; top: 1.5px; width: 1.6px; height: 6.7px; margin-left: -.8px; border-radius: .8px; background: var(--eq-knob-dial); }
  .eq-knob .eq-knob-label { font: 600 8px var(--font); color: var(--eq-knob-label); }
  .eq-band.off .eq-knob { opacity: .45; }

  /* ============ PANEL ============ */

  /* Layer below the top bar (.app height minus --topbar-h), so children are
     in panel coordinates = .app y - 50. The rounded plate is drawn by ::before. */
  .panel { left: 0; right: 0; top: var(--topbar-h); bottom: 0; }
  .panel::before {
    content: "";
    position: absolute;
    left: 10px; top: -0.02px; width: 1004px; height: 275.02px;
    background: var(--panel);   /* panel_bg as is: its alpha is the plate's only opacity (matches the plugin) */
    border: 1px solid var(--t-panel-border);
    border-radius: 8px;
  }

  .row-divider { left: 11px; top: 178px; width: 1002px; height: 1px; background: var(--line); }

  /* ---------- Rec group ---------- */

  .rec-group { left: 0; top: 0; width: 0; height: 0; }

  /* Upper section: meter bars, INPUT ON, knobs. */
  /* 7 segments, 11.33 wide, 2.39 gap (stride 13.72), centred on the column (x 86.02). */
  .meter-bars { left: 39.19px; top: 28px; width: 93.67px; height: 3px; display: flex; gap: 2.39px; }
  .meter-bars i { position: static; width: 11.33px; height: 3px; border-radius: 1px; background: var(--t-meter-off); }
  .meter-bars i.g { background: var(--t-meter-low); }
  .meter-bars i.o { background: var(--t-meter-mid); }
  .meter-bars i.r { background: var(--t-meter-high); }

  .toggle.input-on {
    left: 28.59px; top: 45px; width: 114.86px; height: 20px;
    border-radius: 4px;
    font-size: 7.5px;
    gap: 6px;
    background: none; border-color: var(--t-input-chip-border); color: var(--t-input-chip-text-off);
    cursor: pointer;
  }
  .toggle.input-on .led { position: static; width: 6px; height: 6px; border-radius: 50%; background: var(--t-input-chip-dot); }
  .toggle.input-on.on { border-color: var(--t-input-chip-on); color: var(--t-input-chip-text-on); }
  .toggle.input-on.on .led { background: var(--t-input-chip-on); }

  .knob.rec.input   { left: 35.59px;  top: 77px; }
  .knob.rec.monitor { left: 103.59px; top: 77px; }

  /* Lower section: record button on the wave-button row, full column width. */
  .button.record {
    left: 28.59px; top: var(--wave-row-top); width: 114.86px; height: var(--wave-row-h);
    background: var(--t-button-bg);
    gap: 8px;
    cursor: pointer;
  }
  .button.record .dot { position: static; width: 9px; height: 9px; border-radius: 50%; background: var(--t-rec-dot); }
  /* After .button.record on purpose: same specificity, so source order decides. */
  .button.record.lit { background: var(--t-button-lit-bg); }
  .button.record.lit .dot { background: var(--t-button-lit-text); }

  /* ---------- Waveform ---------- */

  .wave-box { left: 175px; top: 4px; width: 725px; height: 126px; }
  /* 18px gutter (panel color) for the flags, the display well below it with
     the plugin's 3px corners (OxoInlineWaveform.displayCornerRadius). */
  .wave-area { left: 0; top: 0; width: 725px; height: 111px; overflow: hidden; }
  .wave-well { left: 0; top: 18px; width: 725px; height: 93px; background: var(--t-wave-bg); border-radius: 3px; }
  .selection { left: 262px; top: 18px; width: 313px; height: 93px; background: var(--t-wave-bg-selected); }
  .waveform { left: 0; top: 18px; width: 725px; height: 93px; fill: none; stroke: var(--t-wave-fg); stroke-width: 1; vector-effect: non-scaling-stroke; }
  .waveform path { vector-effect: non-scaling-stroke; }
  /* Second copy of the wave (cloned by theme.js), clipped to the selection. */
  .waveform.selected { stroke: var(--t-wave-fg-selected); clip-path: inset(0 150px 0 262px); }
  .center-line { left: 0; top: 64px; width: 725px; height: 1px; background: var(--t-wave-center-line); }
  /* Voice playheads (dim, live voices). */
  .voice-playhead { top: 18px; width: 1px; height: 93px; background: var(--t-wave-voice-playhead); }
  /* START / END / LOOP play points: 1px line + letter. */
  .play-point { top: 18px; width: 1px; height: 93px; background: color-mix(in srgb, var(--t-wave-play-points) 30%, transparent); }
  .play-point::after {
    content: attr(data-letter);
    position: absolute; top: 2px; left: 3px;
    font: 600 8px var(--font); color: color-mix(in srgb, var(--t-wave-play-points) 50%, transparent);
  }
  .play-point.bottom::after { top: auto; bottom: 2px; }

  .marker { top: 0; width: 2px; height: 111px; background: var(--t-wave-trim); }
  .marker::before {                   /* flag in the 18px gutter */
    content: "";
    position: absolute;
    top: .5px; width: 8px; height: 14px;
    background: var(--t-wave-trim);
  }
  .marker.start { left: 261px; }
  .marker.start::before { left: 2px; clip-path: polygon(0 0, 100% 50%, 0 100%); }
  .marker.end { left: 575px; }
  .marker.end::before { right: 2px; clip-path: polygon(100% 0, 0 50%, 100% 100%); }

  .wave-info {
    left: 0; top: 111px; width: 725px; height: 15px;
    display: flex; justify-content: space-between; align-items: center;
    font-size: 8.5px; letter-spacing: .6px;
  }
  .wave-info .file { color: var(--t-wave-sample-name); font-weight: 600; text-transform: uppercase; }
  .wave-info .stats { display: flex; gap: 4px; align-items: baseline; }
  .wave-info em { font-style: normal; color: var(--t-wave-info-label); text-transform: lowercase; }
  .wave-info b { font-weight: 600; color: var(--t-wave-info-value); margin-right: 4px; }

  /* Button row under the waveform; children are relative to this box. */
  .wave-tools { left: 175px; top: var(--wave-row-top); width: 725px; height: var(--wave-row-h); }
  .button.wave.edit  { left: 0; }
  /* OXO DRUMS: no Clear / Load on the wave row; the EQ button sits in
     LOAD's place (lit while the EQ is ON, click opens the EQ layer). */
  .button.wave.eq    { left: 585px; cursor: pointer; }
  .button.wave.prev  { left: 651px; width: 34px; }
  .button.wave.next  { left: 691px; width: 34px; }
  /* Single-cycle field (click toggles the lit state) and the POSITION slider. */
  .button.wave.cycle { left: 168px; width: 85px; font-size: 10px; cursor: pointer; }
  .button.wave.cycle .lock { position: static; width: 7px; height: 8px; border: 1.5px solid currentColor; border-radius: 2px; border-top-left-radius: 3px; border-top-right-radius: 3px; }
  .hslider {
    left: 264px; top: 7px; width: 236px; height: 12px;
    background: linear-gradient(transparent calc(50% - .5px), var(--t-slider-track-line) calc(50% - .5px), var(--t-slider-track-line) calc(50% + .5px), transparent calc(50% + .5px)), var(--t-slider-track);
    border: 1px solid var(--t-slider-track-border); border-radius: 1px;
  }
  .hslider .handle {
    left: 62px; top: 1px; width: 16px; height: 8px;
    background: var(--t-slider-handle); border: 1px solid var(--t-slider-handle-border); border-radius: 1px;
  }
  .hslider .handle::after {
    content: ""; position: absolute; left: 6px; top: 0; width: 4px; height: 6px; border-radius: 1px;
    background: var(--t-slider-led); box-shadow: 0 0 4px var(--t-slider-led);
  }
  /* Modulation line behind the handle: from the handle centre (62 + 8) over
     +5 % of the 218 px travel (the plugin's 2 px bar). */
  .hslider .mod {
    left: 70px; top: 4px; width: 40px; height: 2px; border-radius: 1px;
    background: var(--t-knob-modulation);
  }
  .hslider .ruler {
    left: 3px; top: 14px; width: 230px; height: 6px;
    background: repeating-linear-gradient(to right, var(--t-slider-ruler) 0 1px, transparent 1px 8px);
    opacity: .3;
  }

  /* Gain field sits right after Edit (60 + 6 gap). */
  .gain-field {
    left: 66px; top: 0; width: 96px; height: var(--wave-row-h);
    display: flex; align-items: center; justify-content: center; gap: 10px;
    background: var(--t-button-bg); border-radius: var(--t-button-radius);
    font-size: 11.5px; font-weight: 600; color: var(--t-button-text);
  }
  .gain-field .stepper { position: relative; width: 6px; height: 10px; }
  .gain-field .stepper::before, .gain-field .stepper::after {
    content: ""; position: absolute; left: 0;
    border: 3px solid transparent;
  }
  .gain-field .stepper::before { top: -2px; border-bottom-color: currentColor; }
  .gain-field .stepper::after { bottom: -2px; border-top-color: currentColor; }

  /* START / END / LOOP column */
  /* Section spans x 900-1014, y 4-170: START flush top, LOOP flush bottom. */
  .knob.wave.start { left: 914px; top: 4px; }
  .knob.wave.end   { left: 914px; top: 61.6px; }
  .knob.wave.loop  { left: 914px; top: 121.2px; }
  .mini-label { width: 36px; height: 7.2px; line-height: 7.2px; font-size: 6px; color: var(--t-mini-knob-label); }
  /* Right column centred at x 980.5 (equal outer margins) and on the
     START / END / LOOP dial centres (y 36.4 / 94 / 153.6). */
  .mini-label.random { left: 962.5px; top: 18.4px; }
  .mini-label.xfade  { left: 962.5px; top: 135.6px; }
  .mini-knob.wave.random { left: 973.5px; top: 29.4px; }
  .mini-knob.wave.xfade  { left: 973.5px; top: 146.6px; }
  .toggle.loop-mode {
    left: 966.5px; top: 86px; width: 28px; height: 16px;
    font-size: 6.5px; font-weight: 700;
  }

  /* ============ CONTROLS ROW ============ */

  .group-label {
    top: 180px; height: 9px;
    display: flex; align-items: center; gap: 6px;
  }
  .group-label::before, .group-label::after { content: ""; flex: 1; height: 1px; background: var(--t-group-label); }
  .group-label span { position: static; color: var(--t-group-label); font-size: 6.5px; }

  .group-label.tune   { left: 28.59px;  width: 182.41px; }
  .group-label.lfo    { left: 241.5px;  width: 86px; }
  .group-label.filter { left: 358px;    width: 245px; }
  .group-label.shape  { left: 634px;    width: 192px; }
  .group-label.output { left: 856.41px; width: 139px; }

  /* Knob row: y 213.2, stride 53. Minis at y 195.2 centred over their knob. */
  .knob.tune, .knob.lfo, .knob.filter, .knob.shape, .knob.output { top: 213.2px; }
  .toggle.mini { top: 195.2px; }
  .mini-knob.tune, .mini-knob.filter, .mini-knob.shape, .mini-knob.output { top: 195.2px; }

  /* TUNE */
  .seg.root { left: 28.59px; top: 213.2px; width: 27.33px; height: 46.8px; }
  .seg .label { position: absolute; left: -6px; right: -6px; top: 0; height: 10px; line-height: 10px; }
  .seg .digits {
    position: absolute; left: 0; top: 20.1px; width: 27.2px; height: 24.6px;
    background: radial-gradient(var(--t-seg-bg), color-mix(in srgb, var(--t-seg-bg) 65%, #000));
    border: 1px solid var(--t-seg-border);
    border-radius: 3px;
    font: 13px/22.6px "Menlo", "Courier New", monospace;
    letter-spacing: .5px;
    text-align: center;
    color: var(--t-seg-text);
  }
  .toggle.mini.voice-mode { left: 64px; }
  .mini-knob.portamento   { left: 134.5px; }
  .mini-knob.tune.analog  { left: 187.5px; }   /* ANALOG (voice tuning amount) over FINE */
  .knob.tune.octave { left: 72px; }
  .knob.tune.coarse { left: 125px; }
  .knob.tune.fine   { left: 178px; }

  /* LFO */
  .toggle.mini.lfo.target { left: 286.5px; }
  .knob.lfo.speed { left: 241.5px; }
  .knob.lfo.depth { left: 294.5px; }

  /* FILTER */
  .toggle.mini.filter.bypass { left: 350px; }
  .mini-knob.filter.vel_to_lpf { left: 473.5px; }
  .mini-knob.filter.key_to_lpf { left: 579.5px; }
  .knob.filter.hpf  { left: 358px; }
  .knob.filter.gain { left: 411px; }
  .knob.filter.lpf  { left: 464px; }
  .knob.filter.res  { left: 517px; }
  .knob.filter.env  { left: 570px; }

  /* SHAPE (ENV2 ADSR minis over the amp ADSR) */
  .mini-knob.shape.env2_attack  { left: 643.5px; }
  .mini-knob.shape.env2_decay   { left: 696.5px; }
  .mini-knob.shape.env2_sustain { left: 749.5px; }
  .mini-knob.shape.env2_release { left: 802.5px; }
  .knob.shape.attack  { left: 634px; }
  .knob.shape.decay   { left: 687px; }
  .knob.shape.sustain { left: 740px; }
  .knob.shape.release { left: 793px; }

  /* OUTPUT: SAMPLE DELAY mini knob over SPREAD (the chorus is gone), the
     output BUS chip over PAN (dim on MASTER, lit = routed to an OUT). */
  .mini-knob.output.sample_delay { left: 865.91px; }
  .toggle.mini.output.bus { left: 901.41px; letter-spacing: .7px; font-size: 7.2px; cursor: pointer; }
  .mini-knob.output.vel_to_level { left: 971.91px; }
  .knob.output.spread { left: 856.41px; }
  .knob.output.pan    { left: 909.41px; }
  .knob.output.level  { left: 962.41px; }

  /* ============ OXO DRUMS ZONES (Browser / Sequencer / Pads) ============ */
  /* Geometry (left / top / width / height) is inline, written by theme.js
     from the plugin's DrumsL table; these rules only paint. Everything is
     a `.dz` (drums zone element) so the Simple rules never match. */

  .dz { font-family: var(--font); white-space: nowrap; }
  .dz-plate { border-radius: 8px; }
  .browser-col { background: var(--t-browser-bg); }
  .browser-header {
    display: flex; align-items: center; gap: 6px; padding: 0 6px;
    font-size: 8px; font-weight: 700; letter-spacing: 1.2px;
    color: color-mix(in srgb, var(--t-browser-text) 70%, transparent);
    border-bottom: 1px solid var(--t-browser-line);
  }
  .browser-header .sub { font-weight: 400; letter-spacing: 0; color: color-mix(in srgb, var(--t-browser-text) 50%, transparent); }
  /* The bottom bars: the title bar's chrome with the line on top, buttons
     aligned left (`.right` = the last one pushed to the right edge). */
  .browser-footer {
    display: flex; align-items: center; gap: 6px; padding: 0 6px;
    border-top: 1px solid var(--t-browser-line);
  }
  .browser-footer .chip, .pads .chip {
    position: static; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    width: 30px; height: 14px; border-radius: 2px;
    background: var(--t-seq-button-bg); color: var(--t-seq-button-text);
    font-size: 7px; font-weight: 700; letter-spacing: .8px;
  }
  .browser-footer .chip.autoload { width: 60px; }
  .browser-footer .chip.speaker { width: 22px; }
  .browser-footer .chip.right { margin-left: auto; }
  .browser-footer .chip.lit, .pads .chip.lit { background: var(--t-accent); color: var(--t-accent-text); }
  .pads .chip.pads-trigger { position: absolute; }
  .browser-row {
    display: flex; align-items: center; gap: 4px; padding: 0 6px;
    font-size: 10px; color: var(--t-browser-text);
    border-bottom: 1px solid var(--t-browser-line);
    cursor: pointer;
  }
  .browser-row .size { margin-left: auto; font-size: 7.5px; opacity: .55; }
  .browser-row .x { margin-left: auto; font-size: 7px; opacity: .7; }
  .browser-row .wave-icon { position: static; display: inline-flex; gap: 1px; align-items: center; width: 13px; height: 10px; margin-right: 3px; opacity: .7; }
  .browser-row .wave-icon i { position: static; display: block; width: 1px; background: currentColor; }
  .browser-row.parent { opacity: .6; }
  .browser-row.dim { opacity: .45; }
  .browser-row.lit { background: var(--t-accent); color: var(--t-accent-text); font-weight: 600; }
  /* A FOLDERS section title (USER / FAVOURITES; FACTORY has none): the
     column title's type, dimmed. */
  .browser-row.section {
    font-size: 8px; font-weight: 700; letter-spacing: 1.2px; cursor: default;
    color: color-mix(in srgb, var(--t-browser-text) 55%, transparent);
  }

  .seq-plate { background: var(--t-seq-bg); }
  .seq-row-band.lit { background: var(--t-seq-row-selected-bg); }
  .seq-ruler { font-size: 9px; font-weight: 600; line-height: 12px; padding-left: 3px; color: color-mix(in srgb, var(--t-seq-labels) 70%, transparent); }
  .seq-name { display: flex; align-items: center; padding-left: 6px; font-size: 9.5px; font-weight: 500; color: var(--t-seq-labels); cursor: pointer; }
  .seq-name.lit { font-weight: 700; color: var(--t-seq-row-selected-fg); }
  .seq-name.dim { opacity: .45; }
  .seq-name.lit.dim { opacity: 1; }
  .seq-ms { display: flex; align-items: center; justify-content: center; font-size: 8px; font-weight: 700; border-radius: 2px; color: color-mix(in srgb, var(--t-seq-labels) 85%, transparent); cursor: pointer; }
  .seq-ms.mute.lit { background: var(--t-mute-active); color: var(--t-accent-text); }
  .seq-ms.solo.lit { background: var(--t-solo-active); color: var(--t-accent-text); }
  /* One grid cell: the lines are its top / left borders (beat columns
     stronger); the step block is the inner div at the velocity's opacity. */
  .seq-cell { border-top: 1px solid color-mix(in srgb, var(--t-seq-grid) 35%, transparent); border-left: 1px solid color-mix(in srgb, var(--t-seq-grid) 35%, transparent); cursor: pointer; }
  .seq-cell.beat { border-left-color: color-mix(in srgb, var(--t-seq-grid) 75%, transparent); }
  .seq-cell.playhead { background: var(--t-seq-playhead-bg); }
  .seq-cell.beyond { background: color-mix(in srgb, var(--t-seq-grid) 18%, transparent); }
  .seq-cell .step { left: 3px; right: 3px; top: 3px; bottom: 3px; border-radius: 2px; background: var(--t-seq-step-active); opacity: var(--vel, 1); }
  .seq-cell .bar { left: 3px; right: 3px; bottom: 1px; background: var(--t-seq-lane-event); opacity: var(--vel, 1); }
  .seq-grid-edge { border-right: 1px solid color-mix(in srgb, var(--t-seq-grid) 75%, transparent); border-bottom: 1px solid color-mix(in srgb, var(--t-seq-grid) 35%, transparent); pointer-events: none; }
  .seq-last-step { background: var(--t-seq-last-step); pointer-events: none; }
  .seq-cell .step.selected { background: var(--t-seq-selection); }
  .seq-selection-rect { border: 1px solid var(--t-seq-selection); background: color-mix(in srgb, var(--t-seq-selection) 12%, transparent); pointer-events: none; }
  .seq-chip {
    display: flex; align-items: center; justify-content: center; gap: 4px;
    border-radius: var(--t-seq-button-radius); font-size: 10px; font-weight: 600;
    background: var(--t-seq-button-bg); color: var(--t-seq-button-text);
    cursor: pointer;
  }
  .seq-chip.lit { background: var(--t-accent); color: var(--t-accent-text); }
  .seq-chip .chev { position: static; width: 0; height: 0; border: 3px solid transparent; border-top: 4px solid currentColor; margin-top: 3px; }
  /* The playhead's page: a dot in the label colour. */
  .seq-chip .dot { left: auto; right: 3px; top: 3px; width: 4px; height: 4px; border-radius: 50%; background: currentColor; }
  /* "There are events here": Sample's presence line at the chip's bottom, in the accent. */
  .seq-chip.present::after { content: ''; position: absolute; left: 3px; right: 3px; bottom: 0; height: 1px; background: var(--t-accent); }
  .seq-label { display: flex; align-items: center; padding-left: 2px; font-size: 8.5px; font-weight: 600; letter-spacing: 1.5px; color: color-mix(in srgb, var(--t-seq-labels) 55%, transparent); }

  .pad {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
    border-radius: 3px; background: var(--t-pad-bg); border: 1px solid var(--t-pad-border);
    color: var(--t-pad-label); cursor: pointer;
  }
  .pad .num { position: static; font-size: 11px; font-weight: 600; }
  .pad .name { position: static; font-size: 8px; opacity: .7; }
  .pad .name.dim { opacity: .3; }
  .pad.lit { background: var(--t-pad-selected-bg); color: var(--t-pad-selected-label); }
  .pad.pressed { background: var(--t-accent); color: var(--t-accent-text); }
  .pad .led { left: 50%; margin-left: -8px; bottom: 5px; width: 16px; height: 2px; border-radius: 1px; background: var(--t-pad-activity); }
}
