/* Oxo Simple theme editor (products/oxo_simple/theme_editor). Copied from
   the prototype at ../oxo/oxo_simple_theme_editor/style.css and nested under
   .oxo-simple-editor so it can live in app/assets (loaded via :app) without
   leaking into the rest of the site. Design space 1024 x 335, every element
   is absolutely placed (same table as the plugin's Shared/OxoLayout.swift). */

/* 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-simple-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-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-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;
    --t-button-radius: 2px;          /* wave-row buttons (button_radius) */
    --t-topbar-button-radius: 2px;   /* top-bar chips (topbar_button_radius) */
    --t-background-image-alpha: 1;   /* background image opacity (background_image_alpha) */
    --t-wave-bg-image-alpha: 1;      /* wave picture opacity (wave_bg_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;

    --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: 1024px;
    height: 335px;
    /* The theme's optional image (alpha OK) over the flat color, placed like
       the plugin (OxoBackgroundImageView): fit to the 1024 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) / 1024px auto no-repeat;
    opacity: var(--t-background-image-alpha, 1);
    pointer-events: 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: 1024px;
    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));
  }

  /* 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 ============ */

  .topbar { left: 0; top: 0; width: 1024px; 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;
  }

  /* Play triangle (hold = audition at ROOT), sat back like in the plugin. */
  .play { left: 128px; top: 17px; width: 12px; height: 14px; background: var(--t-topbar-play); opacity: .3; clip-path: polygon(0 0, 100% 50%, 0 100%); }

  .preset { left: 185.34px; top: 11px; width: 305px; height: 38px; }
  .preset-name { left: 0; top: 0; height: 28px; line-height: 28px; font-size: 12px; font-weight: 700; color: var(--t-topbar-text); }
  .preset-size { left: 0; top: 24px; height: 14px; line-height: 14px; font-size: 7px; letter-spacing: .5px; color: var(--t-topbar-text-accent); }

  .knob.top.volume { left: 668px; 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); }

  .button.top.undo    { left: 714px; top: 11px; width: 32px; }
  .button.top.redo    { left: 756px; top: 11px; width: 32px; }
  .button.top.presets { left: 798px; top: 11px; width: 88px; }
  .button.top.save    { left: 896px; top: 11px; width: 76px; }
  .button.top.menu    { left: 982px; top: 11px; width: 32px; }

  /* ============ AUDIO EDITOR (Edit button) ============ */
  /* Covers the whole canvas like in the plugin (top bar 50, rulers 16 / 24,
     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: 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: 285px; 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: 269px; }
  .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: 269px; background: var(--ae-wave-bg); overflow: hidden; }
  .ae-selection { position: absolute; left: 290px; top: 0; width: 370px; height: 269px; background: var(--ae-wave-selection); }
  .ae-lane { position: absolute; left: 0; width: 1000px; height: 134.5px; }
  .ae-lane + .ae-lane { top: 134.5px; }
  .ae-lane-wave { position: absolute; left: 0; top: 0; width: 1000px; height: 134.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: 134.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 67px / 100% 1px no-repeat,
      var(--grid) 0 20px / 100% 1px no-repeat,
      var(--grid) 0 34px / 100% 1px no-repeat,
      var(--grid) 0 101px / 100% 1px no-repeat,
      var(--grid) 0 115px / 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: 269px; 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: 269px; background: var(--ae-wave-playhead); }
  .ae-cursor { position: absolute; left: 660px; top: 0; width: 1px; height: 269px; 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; }

  /* ============ 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); }
  /* theme.js: the theme's wave_bg_image, aspect-fill from the top-left like
     the plugin (cropped right or below, never tiled), at wave_bg_image_alpha. */
  .wave-image {
    left: 0; top: 18px; width: 725px; height: 93px;
    background: var(--wave-bg-image, none) 0 0 / cover no-repeat;
    border-radius: 3px;
    opacity: var(--t-wave-bg-image-alpha, 1);
  }
  .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; }
  .button.wave.clear { left: 519px; }
  .button.wave.load  { left: 585px; }
  .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);
  }
  .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.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; }
  .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 */
  .knob.shape.attack  { left: 634px; }
  .knob.shape.decay   { left: 687px; }
  .knob.shape.sustain { left: 740px; }
  .knob.shape.release { left: 793px; }

  /* OUTPUT */
  .toggle.mini.output.chorus { left: 848.5px; }
  .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; }
}
