:root{
  --danger: #e53935; /* reserved for Panic button (unchanged by accent picker) */
  --accent-red: #e62a28; /* configurable accent used for non-panic red elements */
  --accent-red-outline: rgba(230,40,40,0.18);
  --accent-red-dark: #900000; /* darker variant used for small strokes */
  /* theme-aware thumb background for range inputs (defaults to dark) */
  --range-thumb-bg: #4a4a4a;

  /* thin, theme-appropriate border used around all thumbs (knobs draw with neutral border instead of accent) */
  --thumb-border: rgba(0,0,0,0.12);

  /* unified slider sizing: all tracks share one height and thumbs are 8px taller */
  --range-track-height: 18px; /* default track height (adjustable) */
  --range-thumb-height: calc(var(--range-track-height) + 8px);
  --range-thumb-width: calc(var(--range-thumb-height)); /* square-ish knobs by default */
}

/* Light theme variant applied to the controls panel when .light-theme is present on the controls element.
   This switches the panel to a light appearance while keeping the canvas/grid handling controlled by JS. */
.panel.light-theme{
  background: #fafafa;
  color: #000; /* primary text in panel -> black for readability */
  border: 1px solid rgba(0,0,0,0.06);
  box-shadow: 0 10px 30px rgba(0,0,0,0.06);
}
/* Header should inherit the light background and use black text */
.panel.light-theme .panel-header{
  background: #ffffff;
  color: #000;
  border-bottom: 1px solid rgba(0,0,0,0.06);
}

/* Ensure most control text inside the light panel is black (force all non-accent text to black while preserving accent fills) */
.panel.light-theme,
.panel.light-theme .panel-header,
.panel.light-theme .panel-body,
.panel.light-theme .tabs,
.panel.light-theme .tab-btn,
.panel.light-theme .panel-foot,
.panel.light-theme .filter-display,
.panel.light-theme .filter-placeholder,
.panel.light-theme .output-step,
.panel.light-theme .panel-body label,
.panel.light-theme .panel-body input,
.panel.light-theme .panel-body select,
.panel.light-theme .panel-body button {
  color: #000 !important;
}

/* Stronger rule to override inline light-gray styles inside the panel/header so all ordinary text becomes black in light mode.
   Exclude elements that are explicitly accent-colored via classes (like .panic-btn) by using :not here to avoid clobbering colored UI. */
.panel.light-theme .panel-header *:not(.panic-btn):not(.rotate-btn):not(.lock-btn):not(.spectrum-pin),
.panel.light-theme .panel-body *:not(.panic-btn):not(.rotate-btn):not(.lock-btn):not(.spectrum-pin) {
  color: #000 !important;
}

/* Tabs */
.panel.light-theme .tab-btn{
  background: transparent;
  color: #000;
  border: 1px solid rgba(0,0,0,0.06);
}
.panel.light-theme .tab-btn.active{
  background: rgba(0,0,0,0.03);
  box-shadow: inset 0 -2px 0 rgba(0,0,0,0.04);
  border: 2px solid var(--accent-red);
  outline: 1px solid rgba(0,0,0,0.02);
}

/* Ensure specific pitch / equave inputs & selects have visible borders in light theme */
.panel.light-theme #basePitch,
.panel.light-theme #basePitchSelect,
.panel.light-theme #equaveRatio,
.panel.light-theme #equaveSelect {
  border: 1px solid rgba(0,0,0,0.12) !important;
  background: #fff !important;
  color: #000 !important;
  box-shadow: none !important;
}

/* Inputs / selects: keep white backgrounds but black text */
.panel.light-theme .panel-body input[type="text"],
.panel.light-theme .panel-body input[type="number"],
.panel.light-theme select,
.panel.light-theme #tab-pitch input[type="text"],
.panel.light-theme #tab-pitch select {
  background: #fff;
  color: #000;
  border: 1px solid rgba(0,0,0,0.08);
}

/* Keep lock/rotate button outlines but enforce readable black text when not using accent fills.
   Preserve the existing colored "locked" filled states which intentionally use white text. */
.panel.light-theme .lock-btn{
  border:2px solid var(--danger);
  background: transparent;
  color: var(--danger);
}
.panel.light-theme .lock-btn.locked{
  background: var(--accent-green);
  color: #fff;
  border-color: #000;
}
.panel.light-theme .rotate-btn{
  border:2px solid var(--accent-red);
  background: rgba(230,40,40,0.06);
  color: var(--accent-red);
}
.panel.light-theme .rotate-btn.locked{
  background: var(--accent-red);
  color: #fff;
}

/* Panic button remains high-contrast white-on-danger so it stands out (keep unchanged) */
.panel.light-theme .panic-btn{
  background: var(--danger);
  color: #fff;
  box-shadow: 0 3px 10px rgba(229,57,53,0.08);
}

/* Filter / placeholder styles for light theme with black text where applicable */
.panel.light-theme .filter-display{
  background: #ffffff;
  box-shadow: 0 8px 24px rgba(0,0,0,0.06);
  border: 1px solid rgba(0,0,0,0.06);
  color: #000;
}
.panel.light-theme .filter-placeholder{
  background: rgba(255,255,255,0.92);
  border: 1px dashed rgba(0,0,0,0.04);
  color:#444;
}

/* Output steps: ensure labels are black in light mode */
.panel.light-theme .output-step{
  background: rgba(0,0,0,0.01);
  border: 1px solid rgba(0,0,0,0.04);
  color: #000; /* ensure step labels are black */
}
.panel.light-theme .amp-fill{
  background: linear-gradient(90deg, #4caf50, #ff7043); /* small internal gradient for meters is acceptable */
}

/* Grid (canvas) color helper CSS is minimal because the canvas is painted by JS. */

/* Provide light-mode-friendly helper variables (JS may read these via getComputedStyle if desired) */
:root{
  --grid-light-fill: #ffffff;
  --grid-light-stroke: #000000;
  --grid-dark-fill: #1b1b1d;
  --grid-dark-stroke: #222426;
  --grid-light-octave-fill: #fff0f0;
  --grid-dark-octave-fill: #2a2a2a;
}
html,body{
  height:100%;
  margin:0;
  background:#0f0f10;
  color: #e6e6e6;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial;
}
canvas{
  display:block;
  width:100vw;
  height:100vh;
  touch-action:none; /* we'll handle gestures */
  user-select: none;
  -webkit-user-select: none;
}

/* Top info pill rendered in front of everything (subtle dark translucent at top-right) */
.top-bar{
  position: fixed;
  top: 0;
  right: 0;
  left: auto;
  height: 30px;
  min-width: 120px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px 10px;
  background: rgba(10,10,10,0.6);
  color: #f1f1f1;
  font-size: 12px;
  font-weight: 600;
  border-radius: 0;
  z-index: 9999; /* keep topBar above all windows */
  box-shadow: 0 6px 18px rgba(0,0,0,0.45);
  pointer-events: none; /* non-interactive */
}

/* Floating panel styles: dark mode */
.panel{
  position: fixed;
  left: 8px; /* compact left gutter */
  top: 12px;
  width: auto;
  min-width: 220px; /* narrower panel baseline to be more compact on the left */
  max-width: calc(100% - 24px);
  background: #141417;
  border: 1px solid rgba(255,50,50,0.08);
  box-shadow: 0 10px 36px rgba(0,0,0,0.68);
  border-radius: 10px;
  z-index: 50;
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;
}
.panel-header{
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  height: 36px;
  padding: 0 10px;
  padding-right: 14px;
  font-weight: 600;
  cursor: grab;
  border-bottom: none;
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
  display: flex;
  align-items: center;
  gap: 10px;
  justify-content: space-between;
  color: #f3f3f3;
  position: relative;
}

/* Expanded (default) header styling */
.panel:not(.minimized):not(.minimized-collapsed) .panel-header{
  background: transparent !important;
  box-shadow: none !important;
  border-bottom: none !important;
}

/* Minimized header styling - apply dark header only when NOT in light theme */
.panel:not(.light-theme).minimized:not(.minimized-collapsed) .panel-header{
  /* keep the header visually consistent with the main panel when minimized (dark mode) */
  background: #141417;
  color: #f3f3f3;
  box-shadow: none;
  border-bottom: none;
  /* Ensure the header keeps the same full-width footprint as the expanded panel when NOT deep-collapsed */
  width: 100%;
  min-width: 260px;
}

/* When the panel is minimized but in light theme, let the light-theme header rules govern appearance */
.panel.light-theme.minimized:not(.minimized-collapsed) .panel-header{
  background: #ffffff;
  color: #000;
  box-shadow: none;
  border-bottom: none;
}

/* Deep-collapsed header styling */
.panel.minimized.minimized-collapsed{
  width: fit-content;
  height: 48px;
  overflow: visible;
  border-radius: 10px;
  background: transparent; /* removed solid dark rectangle behind header when deeply collapsed */
  padding: 6px;
  /* ensure there is no leftover minimum width from the general panel rule */
  min-width: 0 !important;
}

/* make the collapsed header size itself to its contents so the grabbable area matches visual width */
.panel.minimized.minimized-collapsed .panel-header{
  background: transparent; /* remove faint translucent box when fully collapsed */
  box-shadow: none;
  border-bottom: none;
  border: none;
  padding: 0 6px;
  height: 48px;
  gap: 6px;
  justify-content: flex-start;
  min-width: 0;
  width: auto;
}

/* left group */
.panel-header .header-left{
  display:flex;
  align-items:center;
  gap: 10px;
  flex: 0 0 auto;
}

/* right group */
.panel-header .header-right{
  display:flex;
  align-items:center;
  gap: 8px;
  flex: 0 0 auto;
}

/* spacer */
.panel-header .header-spacer{
  flex: 1 1 auto;
  min-width: 12px;
}

/* title stability */
.panel-header .panel-title{
  flex: 0 0 auto;
  padding: 0 8px;
  white-space: nowrap;
  overflow: visible;
  text-overflow: clip;
  z-index: 1;
}

/* Reduced padding for header buttons in compact mode: NOTE: header sizing should remain stable,
   so we DO NOT apply any header button changes here. Compact mode now targets only panel body/tabs. */

/* Slightly closer tabs and smaller gaps when compact */
.panel.compact-body .tabs{
  gap:6px;
  padding:6px 6px 6px 6px;
}
.panel.compact-body .tab-btn{
  padding:6px 8px;
  font-size:13px;
}

/* Tighter panel-body padding in compact mode (affects only body content, not header) */
.panel.compact-body .panel-body{
  padding:6px;
  gap:6px;
}



/* header buttons sizing */
.panel-header .lock-btn,
.panel-header .rotate-btn,
.panel-header .panic-btn{
  flex: 0 0 auto;
  box-sizing: border-box;
  padding: 6px 6px;
  height: 40px;
  min-height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: normal;
  text-align: center;
  line-height: 1;
}

/* panic specifics */
.panel-header .panic-btn{
  flex: 0 0 auto;
  width: 72px;
  min-width: 72px;
  margin-left: 8px;
  padding: 6px 10px;
  height: 40px;
  border-radius:8px;
}

/* lock button */
:root{
  --accent-green: #2e7d32;
}
.lock-btn{
  margin-left: 2px;
  margin-right: 2px;
  width: 64px;
  min-width: 56px;
  height:40px;
  padding:6px 6px;
  border-radius:8px;
  border:2px solid var(--danger);
  background: transparent;
  color: var(--danger);
  font-weight:700;
  cursor:pointer;
  font-size:13px;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  white-space: nowrap;
  word-break: normal;
}
.lock-btn.locked{
  background: var(--accent-green);
  color: #fff;
  border-color: var(--accent-green);
}

/* rotate button */
.rotate-btn{
  margin-left: 2px;
  height:40px;
  width:40px;
  padding:0;
  border-radius:8px;
  border:2px solid var(--accent-red);
  background: rgba(230,40,40,0.06);
  color: var(--accent-red);
  font-weight:700;
  cursor:pointer;
  font-size:12px;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  box-shadow: 0 4px 8px rgba(230,40,40,0.10);
  line-height:1;
  transition: background 180ms ease, color 150ms ease, border-color 150ms ease, box-shadow 150ms ease, transform 80ms ease;
}
.rotate-btn svg{
  display: block;
  width: 28px;
  height: 28px;
  margin: 0;
  padding: 0;
  /* allow strokes and decorative parts to extend outside the SVG viewBox so arrow edges are not clipped */
  overflow: visible;
}

.rotate-btn .pad-shackle-locked{ display: none; }
.rotate-btn .pad-shackle-unlocked{ display: inline; }

.rotate-btn.locked .pad-shackle-locked{ display: inline; }
.rotate-btn.locked .pad-shackle-unlocked{ display: none; }
.rotate-btn:active{ transform: translateY(1px); }

.rotate-btn.locked{
  background: var(--accent-red);
  color: #fff;
  border-color: var(--accent-red);
  box-shadow: 0 6px 16px rgba(230,40,40,0.18);
}

/* keep invisible rotate footprint */
.rotate-btn.invisible{
  display: inline-flex !important;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
}

/* header element non-shrink */
.panel-header .rotate-btn,
.panel-header .panic-btn,
.panel-header .lock-btn{
  flex: 0 0 auto;
  margin-right: 0;
}

/* Icon-specific coloring */
.rotate-icon .rot-arrow{
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
}
.rotate-icon .pad-body,
.rotate-icon .pad-key,
.rotate-icon .pad-key-rect{
  fill: currentColor;
  stroke: none;
}
.rotate-icon .pad-shackle{
  stroke: currentColor;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* Single continuous shackle: move the whole shackle element up/down as one unit */
.rotate-icon .pad-shackle{
  transform-origin: 50% 100%;
  transition: transform 160ms ease;
  /* default: shackle seated (down) */
  transform: translateY(0);
}
/* When rotate is unlocked (no .locked class) lift the entire shackle to show the gap */
.rotate-btn:not(.locked) .rotate-icon .pad-shackle{
  /* reduced rise amount: previously -6px, now half that (-3px) */
  transform: translateY(-3px);
}
/* When rotate button is locked, shackle sits down/closed */
.rotate-btn.locked .rotate-icon .pad-shackle{
  transform: translateY(0);
}

/* Tabs */
.tabs{
  display:flex;
  gap:8px;
  padding:8px 6px 0 6px; /* removed bottom padding so content sits directly under tabs */
  flex-wrap: wrap; /* allow tabs to wrap to multiple rows */
  align-items: flex-start;
  /* slightly reduced row gap for a tighter packing */
  row-gap: 6px;
}

/* thin divider between tabs and tab content: spans full panel inner width */
.tabs-divider{
  height: 1px;
  /* extend the divider beyond the tab container's internal padding so the line aligns with the panel borders */
  width: calc(100% + 16px);
  margin: 0 -8px; /* compensate for the panel-body 8px horizontal padding */
  background: rgba(255,255,255,0.04);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.02);
  border-radius: 0; /* very thin full-width line, no corner rounding */
}

/* Ensure the divider remains visible in light theme by using a dark subtle line and matching inset */
.panel.light-theme .tabs-divider{
  /* match the full-width behavior in light theme as well */
  width: calc(100% + 16px);
  margin: 0 -8px;
  background: rgba(0,0,0,0.06);
  box-shadow: inset 0 1px 0 rgba(0,0,0,0.02);
  border-radius: 0;
}

/* Ensure the small section header divider is visible in light theme (use a stronger dark line and force override) */
.panel.light-theme .section-header > div:last-child{
  background: rgba(0,0,0,0.08) !important;
}
/* make tab buttons flex so two fit per row; calc accounts for gap */
.tab-btn{
  /* Three-column layout: each tab is about a third of the row so buttons form three compact columns */
  flex: 0 0 calc(33.333% - 8px);
  max-width: calc(33.333% - 8px);
  min-width: 100px;             /* reduced minimum to keep three columns on narrower viewports */
  box-sizing: border-box;
  background: transparent;
  border: 1px solid rgba(255,255,255,0.12);
  padding:10px 12px;
  border-radius:10px;
  font-size:14px;
  cursor:pointer;
  height:26px;                  /* reduced height (~40% smaller) for denser three-column layout */
  display:inline-flex;
  align-items:center;
  justify-content:center;
  color: #eaeaea;
}
.tab-btn.active{
  background: rgba(255,255,255,0.045);
  box-shadow: inset 0 -2px 0 rgba(255,50,50,0.12), 0 0 0 2px var(--accent-red-outline);
  border: 2px solid var(--accent-red);
  outline: none;
}
.tab-content{
  margin-top:8px;
}

/* Filter display styling */
.filter-display{
  /* docked filter now uses full inner width without extra padding so it cannot overhang the panel */
  width: calc(100% - 2px); /* leave a 1px gutter to respect panel border */
  max-width: none;
  min-width: 160px;
  box-sizing: border-box;
  padding: 0;                /* remove interior padding so canvas occupies full area */
  margin: 0 auto;           /* center horizontally inside the panel body */
}
.filter-display canvas{
  width: 100%;
  height: 168px;
  display:block;
  border-radius:6px;
  background: #0b0b0b;
  box-shadow: none;         /* remove inset shadow so it doesn't imply extra interior spacing */
  transition: height 120ms linear;
  margin: 0;
}

/* EQ controls */
.eq-controls{
  display:flex;
  gap:10px;
  padding:8px;
  box-sizing:border-box;
  /* center the EQ grid and constrain its maximum width so 4 columns fit inside the panel with gutters */
  justify-content: center;
  align-items: flex-start;
  max-width: calc(100% - 24px);
  margin: 0 auto;
  overflow: hidden;
  /* allow wrapping for very narrow viewports so columns break gracefully */
  flex-wrap: wrap;
}
.eq-pole{
  /* use a 4-column responsive basis so 4 poles fit neatly centered in the panel */
  flex: 0 0 calc((100% - 30px) / 4);
  display:flex;
  flex-direction:column;
  gap:0.4px; /* reduced vertical spacing between settings */
  align-items:stretch;
  /* keep sensible min/max so columns don't collapse or grow too large */
  min-width:110px;
  max-width:260px;
  box-sizing: border-box;
  position: relative; /* allow absolute positioning of the pole-enable button */
}

/* tighten header row inside each pole so title, freq and enable button sit on a single compact line */
.eq-pole .eq-header{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:6px;               /* slightly smaller gap so header is more compact */
  padding: 4px 6px 2px 6px; /* remove extra vertical padding that made headers tall */
}

/* Align the small pole-enable button to the top-right corner of each pole so it lines up with the pole header */
.eq-pole .pole-enable-btn,
.eq-pole .pole-enable {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 12;
}

/* Centered frequency label placed above each pole's shape select (moved out of header).
   Keep compact sizing and theme-aware color to match existing pole sublabels. */
.eq-freq-label{
  font-size:11px;
  color: #cfcfcf;
  text-align: center;
  /* reduced top margin so the freq label sits closer to the header and reduces header height */
  margin: 2px 0 0 0;
  line-height: 1;
}

/* pole disabled state: fade and grey out inputs */
.eq-pole.disabled{
  /* keep controls usable (toggle remains interactive) but remove the heavy grey/disabled visual */
  opacity: 1;
  filter: none;
  /* pointer-events remain enabled so the pole-enable switch stays clickable */
  pointer-events: auto;
  /* visually indicate "off" state by subtly muting accent rendering on contained controls (handled below) */
}
.eq-pole.disabled .eq-shape,
.eq-pole.disabled .eq-freq,
.eq-pole.disabled .eq-q,
.eq-pole.disabled .eq-gain,
.eq-pole.disabled .pole-enable{
  /* keep elements interactive (so the enable toggle still works) but reduce accent emphasis */
  pointer-events: auto;
  opacity: 0.95;
  /* mute the accent fill for sliders in visually-off poles by making their fill very subtle */
}
.eq-pole.disabled .eq-freq::-webkit-slider-runnable-track,
.eq-pole.disabled .eq-q::-webkit-slider-runnable-track,
.eq-pole.disabled .eq-gain::-webkit-slider-runnable-track {
  /* faded accent fill for disabled poles, aligned precisely to the knob center */
  background-image:
    linear-gradient(90deg, var(--accent-red-outline) 0%, var(--accent-red-outline) var(--pos)),
    linear-gradient(90deg, rgba(255,255,255,0.03), rgba(255,255,255,0.03)) !important;
  background-repeat: no-repeat, repeat;
  /* ensure the accent fill meets knob center: prefer --pos-fill or fallback to calc from --pos */
  background-size: var(--pos-fill, calc(var(--pos, 0%) - var(--range-thumb-half))) 100%, 100% 100% !important;
  /* keep track subtle while preserving the faint accent fill */
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.42) !important;
  border-color: rgba(0,0,0,0.08) !important;
}
.eq-pole.disabled .eq-freq::-moz-range-track,
.eq-pole.disabled .eq-q::-moz-range-track,
.eq-pole.disabled .eq-gain::-moz-range-track {
  /* faded accent fill for disabled poles in Firefox, aligned to knob center */
  background-image:
    linear-gradient(90deg, var(--accent-red-outline) 0%, var(--accent-red-outline) var(--pos)),
    linear-gradient(90deg, rgba(255,255,255,0.03), rgba(255,255,255,0.03)) !important;
  background-repeat: no-repeat, repeat;
  background-size: calc(var(--pos, 0%) - var(--range-thumb-half)) 100%, 100% 100% !important;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.42) !important;
  border-color: rgba(0,0,0,0.08) !important;
}

/* small style nicety to align the pole enable toggle in header area */
.pole-enable{ display:inline-flex; align-items:center; justify-content:center; }

/* Compact squared pole enable buttons styled/animated like the view lock button.
   - Uses the same "locked" class for the filled state animation semantics.
   - By default the button is a small squared outline in accent; when pressed it becomes solid accent with contrasting text. */
.pole-enable-btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:28px; /* 40px * 0.7 */
  height:28px; /* 40px * 0.7 */
  min-width:28px;
  min-height:28px;
  box-sizing:border-box;
  border-radius:8px;
  cursor:pointer;
  user-select:none;
  padding:4px;
  background: transparent;
  border: 2px solid var(--accent-red);
  color: var(--accent-red);
  font-weight:700;
  font-size:14px;
  /* explicit transition for animated press/release visuals */
  transition: background 180ms cubic-bezier(.2,.9,.25,1), color 180ms cubic-bezier(.2,.9,.25,1), border-color 180ms cubic-bezier(.2,.9,.25,1), box-shadow 180ms cubic-bezier(.2,.9,.25,1), transform 90ms ease;
  will-change: background, color, border-color, box-shadow, transform;
  line-height:1;
}

/* Compact EQ power button used above the spectrum; mirrors pole-enable look but slightly smaller to save vertical space */
.eq-power-btn{
  position: absolute;
  top: 8px;
  right: 88px; /* moved further right to give breathing room from the soft-clipper and label */
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:28px;
  height:28px;
  min-width:28px;
  min-height:28px;
  box-sizing:border-box;
  border-radius:8px;
  cursor:pointer;
  user-select:none;
  padding:4px;
  background: transparent;
  border: 2px solid var(--accent-red);
  color: var(--accent-red);
  font-weight:700;
  font-size:12px;
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease, box-shadow 120ms ease, transform 80ms ease;
  line-height:1;
  z-index: 80; /* ensure it sits above the canvas inside the filter-display */
}
.eq-power-btn.locked{
  background: var(--accent-red);
  color: #fff;
  border-color: var(--accent-red);
  box-shadow: 0 6px 14px rgba(0,0,0,0.35);
}
.eq-power-btn:active{ transform: translateY(1px); }
.eq-power-btn:focus{ outline: 2px solid rgba(255,255,255,0.06); outline-offset: 2px; }

/* Soft clipper button: same compact styling as eq-power-btn, placed slightly left of it (so pin remains at right:8px) */
.softclip-btn{
  position: absolute;
  top: 8px;
  right: 48px; /* shifted right to avoid overlap with EQ power button */
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:28px;
  height:28px;
  min-width:28px;
  min-height:28px;
  box-sizing:border-box;
  border-radius:8px;
  cursor:pointer;
  user-select:none;
  /* reduced vertical padding only so icon can expand vertically while keeping horizontal inset */
  padding:1px 4px;
  background: transparent;
  border: 2px solid var(--accent-red);
  color: var(--accent-red);
  font-weight:700;
  font-size:12px;
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease, box-shadow 120ms ease, transform 80ms ease;
  line-height:1;
  z-index: 80;
}
/* By default show the 'off' waveform and hide the clipped 'on' glyph; swap when button has .locked */
.softclip-btn svg .soft-on{ display:none; }
.softclip-btn svg .soft-off{ display:inline; }
.softclip-btn.locked svg .soft-on{ display:inline; }
.softclip-btn.locked svg .soft-off{ display:none; }

.softclip-btn.locked{
  background: var(--accent-red);
  color: #fff;
  border-color: var(--accent-red);
  box-shadow: 0 6px 14px rgba(0,0,0,0.35);
}
.softclip-btn:active{ transform: translateY(1px); }
.softclip-btn:focus{ outline: 2px solid rgba(255,255,255,0.06); outline-offset: 2px; }

/* Small EQ label placed immediately to the left of the master power button */
.eq-master-label{
  position: absolute;
  top: 10px;
  right: 120px; /* moved further right to avoid overlap with EQ power and soft-clipper buttons */
  font-size: 12px;
  color: #cfcfcf;
  background: transparent;
  padding: 2px 6px;
  border-radius: 6px;
  z-index: 81;
  pointer-events: none;
  font-weight:700;
}

/* position adjustments to keep minimal vertical empty space inside the filter-display */
.filter-display .filter-header{
  height:28px;
  padding:0 6px;
  align-items:center;
  gap:8px;
  /* reduce top padding to keep vertical space minimal */
  padding-top:6px;
  padding-bottom:6px;
}

/* pressed/active state: use same class semantics as .lock-btn.locked so animation is consistent */
.pole-enable-btn.locked{
  background: var(--accent-red);
  color: #fff;
  border-color: var(--accent-red);
  box-shadow: 0 6px 14px rgba(0,0,0,0.35);
}

/* focus/active affordances to mirror lock button */
.pole-enable-btn:active{ transform: translateY(1px); }
.pole-enable-btn:focus{ outline: 2px solid rgba(255,255,255,0.06); outline-offset: 2px; }

/* Ensure the small enable remains interactive and visually distinct even when its parent pole is visually muted */
.eq-pole.disabled .pole-enable-btn{
  opacity: 1 !important;
  filter: none !important;
  pointer-events: auto;
}
.eq-title{
  font-size:12px;
  color:#cfcfcf;
  font-weight:700;
}
.eq-sub{
  font-size:11px;
  color:#9aa5ad;
}
.eq-pole select.eq-shape{
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  color: #dfe6ea;
  border: 2px solid var(--accent-red);
  padding:6px 8px;
  border-radius:6px;
  font-size:12px;
  box-shadow: 0 2px 6px rgba(0,0,0,0.25);
}

/* make control rows horizontal: label at left, slider to the right; tighten vertical spacing */
.eq-control{
  display:flex;
  flex-direction:column;
  align-items:stretch;
  gap:0.4px;
  margin:0;
  padding:0;
  flex-wrap: nowrap;
}
.eq-control > div[style] {
  width: auto;
  display:flex;
  align-items:center;
  gap:4px;
}
/* smaller label variant used under sliders */
.eq-control-label{
  font-size:11px;
  color:#9aa5ad;
  font-weight:600;
  text-align:center;
  margin-top:0px;
  line-height:1;
}
.eq-control-label.small{
  font-size:10px;
  color:#9aa5ad;
  font-weight:600;
  opacity:0.95;
  margin-top:0px;
}

/* range inputs simplified visuals; tracks rely on --pos var for filled portion produced via background layers */
.eq-freq,
.eq-q{
  -webkit-appearance: none;
  appearance: none;
  height: 30px;
  background: transparent;
  width: 100%;
  box-sizing: border-box;
  border-radius:8px;
  padding:6px;
  outline: none;
  border: 1px solid rgba(255,255,255,0.06);
  overflow: hidden;
}
.eq-freq::-webkit-slider-runnable-track,
.eq-q::-webkit-slider-runnable-track,
.eq-gain::-webkit-slider-runnable-track{
  height:100%;
  border-radius:8px;
  background-image:
    linear-gradient(90deg, var(--accent-red) 0%, var(--accent-red) var(--pos)),
    linear-gradient(90deg, rgba(255,255,255,0.03), rgba(255,255,255,0.03));
  background-repeat: no-repeat, repeat;
  background-size: var(--pos-fill, var(--pos, 0%)) 100%, 100% 100%;
  background-position: left center, left center;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.56);
  border: 1px solid rgba(0,0,0,0.08);
  overflow: hidden;
}
.eq-freq::-webkit-slider-thumb,
.eq-q::-webkit-slider-thumb{
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius:50%;
  background: #fff;
  box-shadow: 0 2px 6px rgba(0,0,0,0.35);
  margin-top: -6px;
}
.eq-freq::-moz-range-track,
.eq-q::-moz-range-track{
  height:100%;
  border-radius:8px;
  background-image: linear-gradient(90deg, var(--accent-red, #e62a28), rgba(255,255,255,0.08)), linear-gradient(90deg, rgba(255,255,255,0.03), rgba(255,255,255,0.03));
  background-size: var(--pos, 0%) 100%, 100% 100%;
}
.eq-freq::-moz-range-thumb,
.eq-q::-moz-range-thumb{
  width: 16px;
  height: 16px;
  border-radius:50%;
  background:#fff;
  border: none;
}

/* responsive EQ tweaks */
@media (max-width:780px){
  .eq-controls{ gap:6px; padding:6px; justify-content:center; }
  /* stacked two-column layout on small screens so controls remain readable and never overflow */
  .eq-pole{
    flex: 0 0 calc(50% - 6px);
    gap:4px;
    min-width:80px;
    max-width:48%;
    box-sizing: border-box;
  }
  .eq-freq, .eq-q{ height:28px; }
}

/* default --pos for ranges */
input[type="range"]{
  --pos: var(--pos, 0%);
}

/* resizer handle */
.filter-resizer{
  position: absolute;
  right: 8px;
  bottom: 8px;
  width: 28px;
  height: 28px;
  cursor: nwse-resize;
  background:
    linear-gradient(135deg, transparent 50%, rgba(255,255,255,0.08) 50%);
  background-repeat: no-repeat;
  background-position: right bottom;
  background-size: 100% 100%;
  border-radius: 6px;
  opacity: 1;
  box-shadow: 0 6px 16px rgba(0,0,0,0.45);
  touch-action: none;
  transition: transform 120ms ease;
}
.filter-resizer:active{ transform: scale(0.98); }

/* tab panes */
.tab-pane{ display:none; }
.tab-pane.active{ display:block; }

/* Output panel (simplified and consistent layout)
   - Labels live in a fixed-size inline container (fits text width)
   - Controls (slider + meter) occupy the remaining row space immediately to the right
   - Numeric dB/percent value sits to the far right with reserved width so sliders/meters do not overflow
*/
.output-panel{
  display:flex;
  flex-direction:column;
  gap:6px;
}
.output-list{
  padding:6px;
  display:flex;
  flex-direction:column;
  gap:8px;
  box-sizing:border-box;
}
.output-step{
  display:flex;
  align-items:center;
  gap:0;
  padding:6px 8px;
  border-radius:8px;
  background: rgba(255,255,255,0.01);
  border: 1px solid rgba(255,255,255,0.02);
  min-height:48px;
  box-sizing: border-box;
}
/* Label: only as wide as its content so control container can fill the rest */
.output-step .step-label{
  flex: 0 0 auto;
  padding-right:10px;
  font-size:13px;
  color:#e6e6e6;
  font-weight:600;
  white-space:nowrap;
  align-self:center;
  min-width:0;
}

/* Control container fills remaining width immediately to the right of the label */
.amp-wrap{
  flex: 1 1 auto;
  display:flex;
  flex-direction:column;
  gap:6px;
  align-items:stretch;
  justify-content:center;
  padding-right:12px; /* inner right gutter so controls don't reach panel edge */
  box-sizing:border-box;
  min-width:0;
}

/* meter always under the slider, spans full amp-wrap width */
.amp-meter{
  width:100%;
  height:8px;
  border-radius:6px;
  overflow:hidden;
  background: rgba(0,0,0,0.35);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.02);
}
.amp-fill{
  height:100%;
  width:0%;
  background: linear-gradient(90deg,#4caf50,#ff7043);
  transition: width 80ms linear;
}

/* Slider spans amp-wrap width (accounting for amp-wrap right padding) */
.amp-wrap .output-slider{
  width:100%;
  box-sizing:border-box;
  height:14px;
  margin:0;
  background:transparent;
  -webkit-appearance:none;
  appearance:none;
  /* expose --pos so JS can position the accent fill like other ranges */
  --pos: var(--pos, 0%);
  --range-track-height: 14px;
  --range-thumb-width: 12px;
  --range-thumb-half: calc(var(--range-thumb-width) / 2);
}

/* Track: use the same accent fill approach as other range inputs so the filled portion meets the thumb center */
.amp-wrap .output-slider::-webkit-slider-runnable-track{
  height:100%;
  border-radius:8px;
  background-image:
    linear-gradient(90deg, var(--accent-red) 0%, var(--accent-red) var(--pos)),
    linear-gradient(90deg, rgba(255,255,255,0.03), rgba(255,255,255,0.03));
  background-repeat: no-repeat, repeat;
  background-size: var(--pos, 0%) 100%, 100% 100%;
  background-position: left center, left center;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.12);
  border: 1px solid rgba(0,0,0,0.08);
}

/* Firefox track parity */
.amp-wrap .output-slider::-moz-range-track{
  height:100%;
  border-radius:8px;
  background-image:
    linear-gradient(90deg, var(--accent-red) 0%, var(--accent-red) var(--pos)),
    linear-gradient(90deg, rgba(255,255,255,0.03), rgba(255,255,255,0.03));
  background-repeat: no-repeat, repeat;
  background-size: calc(var(--pos, 0%) - var(--range-thumb-half)) 100%, 100% 100%;
  background-position: left center, left center;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.12);
  border: 1px solid rgba(0,0,0,0.08);
}

/* Compact thumb so it doesn't visually overhang the panel while remaining easy to drag */
.amp-wrap .output-slider::-webkit-slider-thumb{
  -webkit-appearance:none;
  width:12px;
  height:12px;
  border-radius:50%;
  background:var(--range-thumb-bg,#4a4a4a);
  border:1px solid var(--thumb-border, rgba(0,0,0,0.12));
  margin-top:0;
  box-shadow:0 2px 4px rgba(0,0,0,0.25);
}
.amp-wrap .output-slider::-moz-range-thumb{
  width:12px;
  height:12px;
  border-radius:50%;
  background:var(--range-thumb-bg,#4a4a4a);
  border:1px solid var(--thumb-border, rgba(0,0,0,0.12));
  box-shadow:0 2px 4px rgba(0,0,0,0.25);
}

/* Numeric value at right reserved so meters/sliders don't overrun the panel edge */
.amp-value{
  flex: 0 0 64px;
  text-align:right;
  color:#bfc9cc;
  font-size:11px;
  margin-left:8px;
}

/* Responsive tweaks keep layout intact on narrow screens */
@media (max-width:480px){
  .output-step{ padding:6px; }
  .output-step .step-label{ flex:0 0 80px; overflow:hidden; text-overflow:ellipsis; }
  .amp-value{ flex:0 0 56px; font-size:11px; }
}

/* play-warning */
.play-warning{
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: 8px;
  z-index: 70;
  background: rgba(0,0,0,0.65);
  color: #fff;
  padding: 6px 12px;
  border-radius: 8px;
  font-size: 12px;
  pointer-events: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: calc(100% - 40px);
  border: 1px solid rgba(255,255,255,0.04);
  box-shadow: 0 6px 20px rgba(0,0,0,0.4);
  transition: opacity 1s linear, transform 220ms ease;
}

/* helper bubble */
.play-warning-helper{
  position: fixed;
  left: 50%;
  transform: translateX(-50%) translateY(-6px);
  bottom: 48px;
  z-index: 75;
  background: rgba(0,0,0,0.85);
  color: #fff;
  padding: 6px 10px;
  border-radius: 8px;
  font-size: 12px;
  pointer-events: none;
  border: 1px solid rgba(255,255,255,0.04);
  box-shadow: 0 6px 18px rgba(0,0,0,0.45);
  opacity: 0;
  transform-origin: center bottom;
  transition: opacity 180ms linear, transform 180ms cubic-bezier(.2,.8,.2,1);
  will-change: opacity, transform;
}

/* Soft clipper transient toast (brief 500ms feedback) */
.softclip-toast{
  position: fixed;
  left: 50%;
  transform: translateX(-50%) translateY(0);
  bottom: 88px; /* place a bit above the play-warning area */
  z-index: 10002;
  background: rgba(0,0,0,0.88);
  color: #fff;
  padding: 8px 14px;
  border-radius: 10px;
  font-size: 13px;
  pointer-events: none;
  border: 1px solid rgba(255,255,255,0.06);
  box-shadow: 0 8px 26px rgba(0,0,0,0.45);
  opacity: 0;
  transition: opacity 120ms linear, transform 160ms cubic-bezier(.2,.8,.2,1);
  will-change: opacity, transform;
}
.softclip-toast.show{
  opacity: 1;
  transform: translateX(-50%) translateY(-6px);
}

/* multi-tap helper */
.play-warning-helper.multi-tap-warning{
  left: 50%;
  transform: translateX(-50%) translateY(-6px);
  bottom: 48px;
  position: fixed;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}

.play-warning-helper.show{
  opacity: 1;
  transform: translateX(-50%) translateY(-6px);
}

.play-warning.fade-out,
.play-warning.fade-out .play-warning-helper{
  opacity: 0;
  pointer-events: none;
  transition: opacity 1s linear;
}

/* screen-border overlay kept with its flash animation (gradients allowed here per spec) */
.screen-border{
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 10001;
  box-sizing: border-box;
  border: 2px solid transparent;
  border-radius: 0;
  transition: none;
  will-change: border-color, box-shadow;
}
.screen-border.unlocked{
  border-color: rgba(255,80,80,0.49);
  border-width: 5px;
  box-shadow: 0 0 36px rgba(255,80,80,0.21) inset;
}
@keyframes screenBorderFlash {
  0% { border-color: rgba(80,220,120,0.95); box-shadow: 0 0 36px rgba(80,220,120,0.21) inset; border-width: 5px; }
  100% { border-color: rgba(80,220,120,0.0); box-shadow: 0 0 0 rgba(0,0,0,0) inset; border-width: 5px; }
}
.screen-border.flash {
  border-color: rgba(80,220,120,0.95);
  border-width: 5px;
  box-shadow: 0 0 36px rgba(80,220,120,0.21) inset;
  animation: screenBorderFlash 1.5s linear forwards;
}

/* panel body */
.panel-body{
  padding: 8px;
  display: grid;
  gap: 8px;
}
.panel-body label{
  display:flex;
  flex-direction:column;
  align-items: flex-start;
  font-size: 13px;
  color: #e8e8e8;
  gap: 4px;
}
.panel-body input[type="text"],
.panel-body input[type="number"]{
  margin-top:0;
  padding:8px 10px;
  border-radius:8px;
  border:1px solid rgba(255,255,255,0.10);
  background: rgba(255,255,255,0.06);
  color: #f5f5f5;
  font-size:13px;
  width: auto;
  min-width: 68px;
  max-width: calc(100% - 24px);
  box-sizing: border-box;
  align-self: flex-start;
}

/* select/dropdown styling */
#basePitchSelect{
  width: auto;
  min-width: 120px;
  max-width: 100%;
  align-self: flex-start;
  padding:8px 10px;
  border-radius:8px;
  border:1px solid rgba(255,255,255,0.06);
  background: rgba(255,255,255,0.03);
  color: #f5f5f5;
  white-space: nowrap;
  box-sizing: border-box;
}
#equaveSelect{
  width: auto;
  min-width: 68px;
  max-width: 100%;
  align-self: flex-start;
  padding:8px 10px;
  border-radius:8px;
  border:1px solid rgba(255,255,255,0.06);
  background: rgba(255,255,255,0.03);
  color: #f5f5f5;
}

/* toggle layout */
.toggle-row{
  display:flex;
  flex-direction:column;
  gap:8px;
}

/* Accent-colored checkbox for "Allow sustain" and similar toggles:
   Use the accent color variable so the checkbox thumb/checkbox accent matches the UI accent
   instead of the platform default blue. Provide a fallback for browsers that don't support accent-color
   by tinting the ::before appearance for webkit/moz where appropriate. */
#sustainToggle,
#sustainToggle[type="checkbox"] {
  accent-color: var(--accent-red);
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 4px;
  border: 2px solid rgba(255,255,255,0.12);
  background: transparent;
  position: relative;
  vertical-align: middle;
  display: inline-block;
  box-sizing: border-box;
}

/* Visual checked state using pseudo-element for browsers without native accent-color support */
#sustainToggle::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 44%;
  width: 6px;
  height: 10px;
  border: 2px solid transparent;
  border-left: none;
  border-top: none;
  transform: translate(-50%,-60%) rotate(45deg) scale(0);
  transform-origin: center;
  transition: transform 140ms ease, border-color 140ms ease;
}

/* Checked: fill background and show tick in accent color */
#sustainToggle:checked {
  background: var(--accent-red);
  border-color: var(--accent-red);
}
#sustainToggle:checked::after {
  transform: rotate(45deg) scale(1);
  border-color: #fff;
}

/* Provide graceful fallback for browsers that honor accent-color (keeps checkbox white check on accent fill) */
#sustainToggle::-moz-focus-inner { border: 0; }

/* Improved sustain checkbox visuals:
   - Center the checkmark perfectly using translate(-50%,-50%) so it remains aligned regardless of size.
   - Ensure a clear border and subtle shadow remain when unchecked so the control doesn't 'vanish' in muted states.
   - Keep the checkmark white on accent when active. */
#sustainToggle,
#sustainToggle[type="checkbox"]{
  accent-color: var(--accent-red);
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 18px;
  border-radius: 4px;
  border: 2px solid rgba(255,255,255,0.12);
  background: transparent;
  position: relative;
  vertical-align: middle;
  display: inline-block;
  box-sizing: border-box;
  /* keep visible when visually muted by overlays */
  box-shadow: 0 2px 6px rgba(0,0,0,0.28) inset, 0 1px 0 rgba(255,255,255,0.02);
}

/* Visual checked state using centered pseudo-element for consistent centering */
#sustainToggle::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 44%;
  width: 6px;
  height: 10px;
  border: 2px solid transparent;
  border-left: none;
  border-top: none;
  transform: translate(-50%,-60%) rotate(45deg) scale(0);
  transform-origin: center;
  transition: transform 140ms ease, border-color 140ms ease, opacity 120ms ease;
  opacity: 0;
  pointer-events: none;
}

/* Checked: fill background and show tick in accent color */
#sustainToggle:checked {
  background: var(--accent-red);
  border-color: var(--accent-red);
  box-shadow: 0 3px 10px rgba(0,0,0,0.28) inset;
}
#sustainToggle:checked::after {
  transform: translate(-50%,-50%) rotate(45deg) scale(1);
  border-color: #fff;
  opacity: 1;
}

/* Ensure the toggle still reads clearly when disabled/visually muted: keep border visible */
#sustainToggle[disabled],
#sustainToggle[aria-disabled="true"]{
  opacity: 0.85;
  filter: none;
  border-color: rgba(255,255,255,0.10);
  box-shadow: 0 1px 2px rgba(0,0,0,0.18) inset;
}

.toggle-options{
  display:flex;
  gap:4px;               /* remove horizontal breathing room */
  align-items:center;
  justify-content:flex-start; /* keep controls compact and left-aligned */
  padding: 0;            /* remove any implicit horizontal padding */
}

/* SWITCH: default horizontal/compact switch styling for most toggles; ADSR uses a dedicated vertical variant below */
.switch{
  /* sizing defaults for horizontal switches */
  --switch-padding: 2px;
  --switch-knob-width: 28px;
  display:inline-flex;
  align-items:center;
  gap:8px;
  cursor:pointer;
  user-select:none;
}

/* horizontal track: short and wide; knob moves left/right */
.switch .switch-track{
  position: relative;
  width: 56px;
  height: 28px;
  background: transparent;
  border-radius: 999px;
  padding: 0;
  box-sizing: border-box;
  transition: background 160ms ease, box-shadow 160ms ease;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.56);
  border: 1px solid rgba(0,0,0,0.12);
  overflow: visible;
}

/* filled portion grows left-to-right for horizontal switches */
.switch .switch-track::before{
  content: "";
  position: absolute;
  left: 0;
  right: auto;
  top: 0;
  bottom: 0;
  width: 0%;
  background: var(--accent-red);
  transition: width 140ms linear;
  border-radius: 999px;
  box-shadow: inset 0 2px 0 var(--accent-red-outline);
}

/* knob positioned by 'left' so it slides horizontally; centered vertically inside track */
.switch .switch-knob{
  position: absolute;
  top: 50%;
  left: var(--switch-padding);
  transform: translateY(-50%);
  width: var(--switch-knob-width);
  height: var(--switch-knob-width);
  background: #4a4a4a;
  border-radius: 50%;
  box-shadow: 0 3px 10px rgba(0,0,0,0.35);
  transition: left 160ms cubic-bezier(.2,.9,.25,1), transform 110ms ease, background 140ms ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
}

/* inner icon alignment */
.switch .switch-knob .switch-icon {
  display:inline-block;
  margin: 0;
  padding: 0;
  font-size: 12px;
  line-height: 1;
}

/* theme-specific knob color */
.panel.light-theme .switch .switch-knob { background: #fff !important; }
.panel:not(.light-theme) .switch .switch-knob { background: #4a4a4a !important; }

/* ON state: grow horizontal fill and move knob to the right edge */
.switch[aria-checked="true"] .switch-track::before{
  width: calc(100% - (var(--switch-knob-width) / 2) - (var(--switch-padding)));
}
.switch[aria-checked="true"] .switch-knob{
  left: calc(100% - var(--switch-padding) - var(--switch-knob-width));
}
.switch:active .switch-knob{ transform: translateY(-50%) scale(0.98); }

/* compact labels (if present) remain to the right of switch */
.switch .switch-labels{
  display:flex;
  gap:6px;
  align-items:center;
  color: #dfe6ea;
  font-size:12px;
}
.switch .switch-labels .left,
.switch .switch-labels .right{
  min-width:36px;
  text-align:center;
  opacity:0.95;
}

/* Rotated switch helper: reuse the standard switch markup/behavior but rotate 90deg clockwise.
   This keeps all sizing, fill behavior and knob movement identical to other switches while
   presenting it vertically; knob content (icons) remains intact inside the knob. */
.switch.rotated-switch {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* rotate the entire control 90deg clockwise */
  transform: rotate(90deg);
  transform-origin: center;
  /* ensure the rotated element doesn't create unexpected overflow in flex containers */
  will-change: transform;
}
/* rotate the inner icon 90deg counterclockwise so its glyphs read vertically */
.switch.rotated-switch .switch-icon{
  display: inline-block;
  transform: rotate(-90deg);
  transform-origin: center;
}
/* When the switch is rotated its internal pseudo-fill and knob still use the same logic as horizontal switches.
   No additional vertical-only CSS is required because the element is physically rotated. */

/* legacy horizontal switch rules remain below and will not interfere because the vertical variant uses explicit dimensions above */

/* caption area */
.switch-caption,
.toggle-options .switch-caption,
.switch .switch-caption {
  display: flex;
  justify-content: center;
  gap: 8px;
  width: 100%;
  margin-top: 6px;
  font-size: 12px;
  color: #dfe6ea;
  align-items: center;
  text-align: center;
}

/* Minimized panel appearance */
.panel.minimized{
  /* Keep the minimized panel flexible and allow the header to match the expanded width.
     The deep-collapsed variant (.minimized-collapsed) still enforces the small footprint. */
  width: auto;
  height: 44px;
  overflow: visible;
  background: transparent; /* remove the dark rectangle behind the header */
  border-radius: 10px;
}
.panel.minimized .panel-body{
  display: none;
}
.panel.minimized.minimized-show-filter{
  width: auto;
  height: auto;
  min-width: 260px;
  min-height: 44px;
  overflow: visible;
}
.panel.minimized.minimized-show-filter .panel-body{
  display: block;
  position: relative;
  padding: 8px;
}
.panel.minimized.minimized-show-filter .filter-display{
  position: absolute;
  right: 12px;
  top: 44px;
  z-index: 65;
  background: transparent;
  box-shadow: 0 8px 28px rgba(0,0,0,0.6);
  border-radius: 10px;
}
.panel.minimized .panel-header{
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  height: 36px;
  padding: 0 10px;
  padding-right: 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  justify-content: space-between;
  cursor: grab;
}

/* light-theme override for minimized header */
.panel.light-theme.panel.minimized .panel-header {
  background: #ffffff;
  color: #000;
  border-bottom: 1px solid rgba(255,255,255,0.06);
}
.minimize-btn{
  width:26px;
  height:22px;
  padding:0;
  border-radius:6px;
  border:none;
  background: rgba(255,255,255,0.02);
  box-shadow: none;
  cursor: pointer;
  font-size:14px;
  line-height:1;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  color: #f2f2f2;
  padding-top:4px;
  padding-bottom:4px;
}

/* deep-collapsed */
.panel.minimized.minimized-collapsed{
  width: fit-content;
  height: 48px;
  overflow: visible;
  border-radius: 10px;
  background: transparent; /* removed solid dark rectangle behind header when deeply collapsed */
  padding: 6px;
}

/* Ensure the header spacer does not reserve width when deeply collapsed so buttons sit adjacent */
.panel.minimized.minimized-collapsed .panel-header .header-spacer{
  display: none;
  width: 0;
  min-width: 0;
}

/* Remove the invisible rotate-button footprint when deeply collapsed (view-lock may have previously added .invisible) */
.panel.minimized.minimized-collapsed .rotate-btn.invisible{
  display: none !important;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
}
.panel.minimized.minimized-collapsed .panel-header .header-left > *:not(.minimize-btn):not(.panic-btn){
  display: none;
}
.panel.minimized.minimized-collapsed .panel-header{
  padding: 0 6px;
  height: 48px;
  gap: 6px;
  justify-content: flex-start;
  min-width: 0;
  width: fit-content;
}
.panel.minimized.minimized-collapsed .minimize-btn{
  width:38px;
  height:38px;
  border-radius:8px;
  background: rgba(255,255,255,0.02);
  color: #f2f2f2;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  font-size:16px;
  padding-top:2px;
}
.panel.minimized.minimized-collapsed .panic-btn{
  width:36px;
  height:36px;
  min-width: 36px;
  padding:0;
  margin-left:6px;
  border-radius:8px;
  background: var(--danger);
  color: transparent;
  font-weight:700;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  box-shadow: 0 2px 8px rgba(229,57,53,0.25);
  border: none;
  position: relative;
}
.panel.minimized.minimized-collapsed .panic-btn::after{
  content: "!";
  color: #fff;
  font-weight: 900;
  font-size: 18px;
  line-height: 1;
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.panel.minimized.minimized-collapsed .panel-header .panic-btn,
.panel.minimized.minimized-collapsed .panel-header .minimize-btn{
  touch-action: manipulation;
}
.panel.minimized.minimized-collapsed .minimize-btn:focus,
.panel.minimized.minimized-collapsed .panic-btn:focus{
  outline: 2px solid rgba(255,255,255,0.12);
  outline-offset: 2px;
}

/* Panic button visible in header even when minimized */
.panic-btn{
  margin-left:8px;
  height:22px;
  padding:0 8px;
  border-radius:6px;
  border:none;
  background:var(--danger);
  color:#fff;
  font-weight:700;
  cursor:pointer;
  font-size:12px;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  box-shadow: 0 2px 8px rgba(229,57,53,0.25);
}
.panic-btn:active{ transform: none; }
.minimize-btn:active{ transform: translateY(1px); }
.panel-title{
  font-weight:700;
  font-size:13px;
  color: #f3f3f3;
}
.panel-foot{
  display:flex;
  justify-content:flex-end;
  margin-top:8px;
}
.panel-foot button,
.danger-btn{
  padding:8px 12px;
  border-radius:8px;
  border: none;
  background:var(--danger);
  color:white;
  cursor:pointer;
  font-size:13px;
  box-shadow: 0 3px 10px rgba(0,0,0,0.5);
}
.panel-foot button:active,
.danger-btn:active{ transform: translateY(1px); }

/* filter placeholder */
.filter-placeholder{
  width: 100%;
  height: 168px;
  border-radius: 8px;
  border: 1px dashed rgba(255,255,255,0.03);
  background: rgba(0,0,0,0.72);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #9aa5ad;
  position: relative;
  overflow: hidden;
}
.filter-placeholder-label{
  font-size: 13px;
  color: #b7c2c8;
  opacity: 0.9;
}

/* floating spectrum */
.filter-display{
  position: absolute;
  left: 50%;
  top: 44px;
  transform: translateX(-50%); /* center inside panel */
  z-index: 65;
  /* use full inner width minus 2px to avoid crossing panel borders */
  width: calc(100% - 2px);
  height: 168px;
  background: #0b0b0b;
  border-radius: 6px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.6);
  touch-action: none;
  display:flex;
  flex-direction:column;
  gap:0;
  padding:0; /* remove interior padding */
  user-select:none;
  -webkit-user-select:none;
  /* normal state allows pointer interactions */
  pointer-events: auto;
  box-sizing: border-box;
}

/* When the panel is minimized we must NOT let the filter-display invisibly capture input
   or cast its docked shadow outside the header footprint. Disable pointer events and shadow.
   When the minimized state explicitly shows the filter (minimized-show-filter) we restore
   visual appearance and pointer interaction only for that visible case. */
.panel.minimized .filter-display{
  pointer-events: none;
  box-shadow: none;
  background: transparent;
}

/* exception: when minimized but intentionally showing the filter, restore interaction/visuals */
.panel.minimized.minimized-show-filter .filter-display{
  pointer-events: auto;
  box-shadow: 0 8px 28px rgba(0,0,0,0.6);
  background: #0b0b0b;
}

.filter-display.pinned{
  /* Keep the same visual appearance as the default .filter-display.
     Appearance (background / box-shadow) is controlled only by theme (.panel.light-theme). */
  box-shadow: 0 8px 28px rgba(0,0,0,0.6);
  border: 1px solid rgba(255,255,255,0.02);
}
.filter-header{
  display:flex;
  align-items:center;
  gap:8px;
  height:28px;
  padding:0 6px;
  cursor: grab;
  color:#ccc;
}
.filter-header:active{ cursor: grabbing; }
.spectrum-pin{
  position: absolute;
  right: 8px;
  top: 8px;
  width:30px;
  height:28px;
  border-radius:6px;
  border:none;
  background: transparent;
  color:#cfcfcf;
  font-size:14px;
  cursor:pointer;
  z-index: 70;
  display:flex;
  align-items:center;
  justify-content:center;
  box-shadow: none;
}
#spectrumCanvas{
  touch-action: none;
  cursor: crosshair;
  position: relative;
}
.spectrum-pin[aria-pressed="true"]{
  background: rgba(255,255,255,0.06);
  color: #fff;
}
.filter-display.floating{
  /* Floating state keeps the same visual styling as docked state;
     only positioning is different — do not alter background/box-shadow here so grab/drag won't change appearance. */
  position: fixed;
  left: auto;
  top: auto;
  right: auto;
  bottom: auto;
  box-shadow: 0 8px 28px rgba(0,0,0,0.6);
  background: #0b0b0b;
  border-radius: 10px;
}
.filter-display canvas{
  width: 100%;
  height: calc(100% - 36px);
  border-radius: 6px;
  display:block;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.02);
}
.filter-placeholder.over {
  box-shadow:
    0 0 28px 6px rgba(80,200,120,0.12),
    0 0 18px 2px rgba(80,200,120,0.08) inset;
  border-color: rgba(80,200,120,0.18);
  transition: box-shadow 140ms ease, border-color 120ms ease;
}

/* tabs sizing tweaks */
.tabs .tab-btn{
  /* ensure wrapped buttons center their contents and respect new two-column sizing */
  display:inline-flex;
  align-items:center;
  justify-content:center;
  padding:6px 10px;
  min-width: 0;
  white-space: nowrap;
  box-sizing: border-box;
  text-align: center;
}
/* remove per-tab max-width overrides so all tabs share the uniform three-column sizing */
.tabs .tab-btn:nth-child(1),
.tabs .tab-btn:nth-child(2),
.tabs .tab-btn:nth-child(3){
  max-width: none;
}

/* range rows compact */
.range-row{ display:flex; gap:4px; align-items:center; width:100%; position: relative; }

/* range sliders adopt same --pos-based fill; thumb styles kept */
.range-row input[type="range"]{
  -webkit-appearance: none;
  appearance: none;
  height: 42px;
  padding: 0;               /* removed inner padding so thumb math and visual center are exact */
  background: transparent;
  flex: 1;
  margin: 0;
  box-sizing: border-box;
  cursor: pointer;
  transition: opacity 120ms linear;
}
.range-row input[type="range"]::-webkit-slider-runnable-track{
  height: 100%;
  border-radius: 999px;
  background-image:
    linear-gradient(90deg, var(--accent-red) 0%, var(--accent-red) var(--pos)),
    linear-gradient(90deg, rgba(255,255,255,0.03), rgba(255,255,255,0.03));
  background-repeat: no-repeat, repeat;
  background-size: var(--pos-fill, var(--pos, 0%)) 100%, 100% 100%;
  background-position: left center, left center;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.56);
  border: 1px solid rgba(0,0,0,0.12);
  transition: background 120ms linear, box-shadow 180ms ease;
}
.range-row input[type="range"]::-moz-range-track{
  height: 100%;
  border-radius: 999px;
  background-image: linear-gradient(90deg, var(--accent-red, #e62a28), rgba(255,255,255,0.08)), linear-gradient(90deg, rgba(255,255,255,0.03), rgba(255,255,255,0.03));
  background-repeat: no-repeat, repeat;
  background-size: var(--pos, 0%) 100%, 100% 100%;
  background-position: left center, left center;
  border: 1px solid rgba(0,0,0,0.12);
  transition: background 120ms linear;
}
.range-row input[type="range"]::-webkit-slider-thumb{
  -webkit-appearance: none;
  appearance: none;
  width: 25px;
  height: 25px;
  border-radius: 50%;
  background: #4a4a4a;
  box-shadow: 0 3px 10px rgba(0,0,0,0.35);
  margin-top: -4px;
  transition: transform 110ms ease, box-shadow 150ms ease;
}

/* light-theme: thumbs white */
.panel.light-theme .range-row input[type="range"]::-webkit-slider-thumb,
.panel.light-theme .eq-freq::-webkit-slider-thumb,
.panel.light-theme .eq-q::-webkit-slider-thumb,
.panel.light-theme .eq-gain::-webkit-slider-thumb,
.panel.light-theme .tab-pane#tab-2 .range-row input[type="range"]::-webkit-slider-thumb{
  background: #fff;
  box-shadow: 0 3px 10px rgba(0,0,0,0.35);
}
.range-row input[type="range"]::-moz-range-thumb{
  width: 25px;
  height: 25px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 3px 10px rgba(0,0,0,0.35);
  border: none;
  transition: transform 110ms ease, box-shadow 150ms ease;
}

/* active/focus states */
.range-row input[type="range"]:active::-webkit-slider-runnable-track,
.range-row input[type="range"]:focus::-webkit-slider-runnable-track{
  background: linear-gradient(90deg, rgba(255,255,255,0.03), var(--accent-red));
  box-shadow: inset 0 -2px 0 var(--accent-red-outline);
}
.range-row input[type="range"]:active::-webkit-slider-thumb,
.range-row input[type="range"]:focus::-webkit-slider-thumb{
  transform: scale(0.98);
}

/* numeric inputs next to ranges */
.range-row input[type="text"],
.range-row input[type="number"]{
  width:56px;
  margin-left:4px;
  padding:5px 6px;
  box-sizing:border-box;
  font-size:13px;
}

/* remove any leftover dark divider - only apply dark override when NOT in light theme */
.panel:not(.light-theme).minimized .panel-header{
  /* ensure minimized header remains opaque and readable in dark mode */
  background: #141417 !important;
  color: #f3f3f3 !important;
  box-shadow: none !important;
  border-bottom: none !important;
}

/* In light-theme, ensure minimized header uses the light appearance */
.panel.light-theme.minimized .panel-header{
  background: #ffffff !important;
  color: #000 !important;
  box-shadow: none !important;
  border-bottom: none !important;
}

/* exponential icon tweak */
.switch .switch-icon.exp{
  display:inline-block;
  font-size:16px;
  line-height:1;
}

/* Timbre tweaks */
.tab-pane#tab-2{
  padding-right: 4px;
  padding-left: 4px;
  position: relative;
}
/* slightly smaller, unbold curve label already inline-styled in HTML, ensure left alignment of toggle caption */
.tab-pane#tab-2 .toggle-row {
  align-items: center;
  gap: 10px;
  justify-content: flex-start;
}
.tab-pane#tab-2 .toggle-row .switch-caption {
  justify-content: flex-start;
  margin-top: 6px;
  font-size: 12px;
  color: #dfe6ea;
}
.tab-pane#tab-2 .toggle-row > span {
  display: inline-block;
  text-align: left;
  font-weight: 400;
  font-size: 13px;
  color: #e8e8e8;
}

/* connector graphic styling to keep lines subtle and aligned left inside the Timbre tab */
.curve-connector {
  margin-right: 8px;
  display: block;
  align-self: flex-start;
  margin-top: 4px;
  opacity: 0.92;
  pointer-events: none;
}

/* left-side ADSR connector used inside .adsr-with-connector */
/* ADSR connector SVG sits in the left gutter and must never block input; styling kept minimal.
   JS will set the exact endpoints and stroke color based on theme. */
#adsrConnectorSVG, #adsrConnectorSVG_STATIC {
  pointer-events: none;
  display: block;
  overflow: visible;
  position: absolute;
}
#adsrConnectorLine, #adsrConnectorLine_STATIC {
  vector-effect: non-scaling-stroke; /* keep stroke thickness stable on svg scaling */
  pointer-events: none;
  /* always visible and crisp like other panel borders */
  stroke-width: 1;
  stroke: #000; /* default for light-theme panel (black line) */
  visibility: visible;
}
/* light/dark theme-specific stroke color for line */
.panel.light-theme #adsrConnectorLine_STATIC,
.panel.light-theme #adsrConnectorLine {
  stroke: #000;
}
.panel:not(.light-theme) #adsrConnectorLine_STATIC,
.panel:not(.light-theme) #adsrConnectorLine {
  stroke: rgba(210,210,210,0.86);
}

#adsrConnectorSVG_STATIC {
  /* tightened left gutter and reduced horizontal padding so the line hugs the panel edge */
  left: 0;
  top: 8px;
  width: 48px;   /* slightly narrower footprint */
  height: 200px;
  z-index: 2;
}

/* wrapper above the SVG so the rotated switch and its labels are painted on top at all times;
   wrapper itself remains non-interactive (pointer-events none) while allowing the switch element inside to accept input. */
#adsrConnectorWrapper {
  position: absolute;
  left: 0;                 /* remove horizontal padding so toggle sits flush */
  width: 36px;             /* tighter width for compact left side */
  height: 200px;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  pointer-events: none; /* wrapper doesn't block events */
  z-index: 3; /* above svg */
}
#adsrConnectorWrapper .switch {
  pointer-events: auto; /* allow the switch itself to be interactive */
  z-index: 4;
  /* ensure the rotated switch's labels are visible on top of the line */
  position: relative;
}

/* Ensure the JS can position the ADSR connector wrapper without being overridden by inline styles:
   allow the script to compute and set top; initial inline top will be ignored so the line renders correctly
   on first paint and the toggle can be vertically centered by the script. */
/* removed top: auto !important so JS can set wrapper.style.top to vertically center the toggle */
/* ensure the reserved left gutter for the connector doesn't collapse on very small viewports */
.adsr-with-connector { min-height: 220px; }

/* make the new Oscillators section compact and tidy */
.osc-section {
  border-radius: 8px;
  padding: 6px;
  /* remove the extra top gap so the section hugs the tabs divider; keep a small bottom gap */
  margin-top: 0;
  margin-bottom: 4px;
}

/* Section header used across small panel sections (centered title + subtle divider) */
.section-header{
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  text-align:center;
  width:100%;
  padding: 2px 6px 4px 6px;
  box-sizing: border-box;
  pointer-events: none; /* header is purely decorative */
}
.section-header > div:first-child{
  font-weight: 600;
  color: #e8e8e8;
  font-size: 13px;
}
.section-header > div:nth-child(2){
  font-size: 12px;
  color: #9aa5ad;
  margin-top: 6px;
}
.section-header > div:last-child{
  display:block;
  width:100%;
  height:1px;
  background: rgba(255,255,255,0.04);
  margin-top:10px;
}

/* keep range rows in Timbre compact */
.tab-pane#tab-2 .range-row input[type="range"]{ min-width: 40px; }

/* Timbre accent tracks */
.tab-pane#tab-2 .range-row input[type="range"]::-webkit-slider-runnable-track{
  height: 100%;
  border-radius: 999px;
  background-image:
    linear-gradient(90deg, var(--accent-red) 0%, var(--accent-red) var(--pos)),
    linear-gradient(90deg, rgba(255,255,255,0.03), rgba(255,255,255,0.03));
  background-repeat: no-repeat, repeat;
  background-size: var(--pos, 0%) 100%, 100% 100%;
  background-position: left center, left center;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.56);
  border: 1px solid rgba(0,0,0,0.12);
  transition: background 180ms ease, box-shadow 180ms ease;
}
.tab-pane#tab-2 .range-row input[type="range"]::-moz-range-track{
  height: 100%;
  border-radius: 999px;
  background-image:
    linear-gradient(90deg, var(--accent-red, #e62a28) 0%, rgba(255,255,255,0.03) 100%),
    linear-gradient(90deg, rgba(255,255,255,0.03), rgba(255,255,255,0.03));
  background-repeat: no-repeat, repeat;
  background-size: var(--pos, 0%) 100%, 100% 100%;
  border: 1px solid rgba(0,0,0,0.12);
}

/* Timbre thumb */
.panel.light-theme .tab-pane#tab-2 .range-row input[type="range"]::-webkit-slider-thumb{
  -webkit-appearance: none;
  appearance: none;
  width: 33px;
  height: 33px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 3px 10px rgba(0,0,0,0.35), 0 0 0 3px rgba(0,0,0,0.04);
  border: 3px solid rgba(255,255,255,0.92);
  transition: transform 110ms ease, box-shadow 150ms ease, border-color 180ms ease;
}
.panel.light-theme .tab-pane#tab-2 .range-row input[type="range"]:focus::-webkit-slider-thumb,
.panel.light-theme .tab-pane#tab-2 .range-row input[type="range"]:active::-webkit-slider-thumb{
  box-shadow: 0 6px 18px rgba(0,0,0,0.35), 0 0 0 6px rgba(0,0,0,0.03), 0 0 12px rgba(0,0,0,0.04);
  border-color: var(--accent-red);
}
.panel.light-theme .tab-pane#tab-2 .range-row input[type="range"]::-moz-range-thumb{
  width: 25px;
  height: 25px;
  border-radius: 50%;
  background: #fff;
  border: 3px solid rgba(255,255,255,0.92);
  box-shadow: 0 3px 10px rgba(0,0,0,0.35);
  transition: transform 110ms ease, box-shadow 150ms ease, border-color 180ms ease;
}

/* numeric smaller in Timbre */
.tab-pane#tab-2 .range-row input[type="text"],
.tab-pane#tab-2 .range-row input[type="number"]{ width:54px; padding:4px 6px; }

/* pitch tab layout */
.tab-pane#tab-pitch > label[style],
.tab-pane#tab-pitch > label {
  display: flex;
  gap: 6px;
  align-items: flex-start;
  align-content: flex-start;
}
.tab-pane#tab-pitch > label > div {
  align-self: flex-start;
}
.tab-pane#tab-pitch input[type="text"],
.tab-pane#tab-pitch input[type="number"]{
  min-width: 34px;
  width: 50%;
  max-width: calc(50% - 12px);
  padding: 6px 8px;
  box-sizing: border-box;
}
.tab-pane#tab-pitch #basePitchSelect{
  min-width: 120px;
  width: auto;
  max-width: calc(100% - 12px);
  padding: 6px 8px;
  box-sizing: border-box;
  white-space: nowrap;
}

/* Authoritative switch block consolidated above; thumb labels injected by JS follow */
.thumb-value{
  position: absolute;
  top: 6px;
  transform: translate(-50%, -40%);
  min-width: 28px;
  padding: 2px 6px;
  border-radius: 999px;
  background: rgba(0,0,0,0.72);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  pointer-events: none;
  z-index: 40;
  text-align: center;
  box-shadow: 0 4px 10px rgba(0,0,0,0.45);
}
.range-row{ position: relative; }

/* eq-gain default - unified with site-wide slider appearance */
.eq-gain{
  --pos: var(--pos, 0%);
  /* inherit unified track/thumb sizing so eq-gain renders identically to other ranges */
  height: var(--range-track-height);
  box-sizing: border-box;
}

/* Track: single accent fill that terminates at --pos percentage */
.eq-gain::-webkit-slider-runnable-track{
  height: var(--range-track-height);
  border-radius: calc(var(--range-track-height) * 0.55);
  background-image:
    linear-gradient(90deg, var(--accent-red) 0%, var(--accent-red) var(--pos)),
    linear-gradient(90deg, rgba(255,255,255,0.03), rgba(255,255,255,0.03));
  background-repeat: no-repeat, repeat;
  background-size: var(--pos, 0%) 100%, 100% 100%;
  background-position: left center, left center;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.02), inset 0 -1px 0 rgba(0,0,0,0.06);
  border: 1px solid rgba(0,0,0,0.12);
}

/* Thumb: use the same unified thumb sizing and styling used across other sliders */
.eq-gain::-webkit-slider-thumb{
  -webkit-appearance: none;
  appearance: none;
  width: var(--range-thumb-width);
  height: var(--range-thumb-height);
  border-radius: 50%;
  background: var(--range-thumb-bg);
  box-shadow: 0 3px 10px rgba(0,0,0,0.35);
  border: 1px solid var(--thumb-border);
  margin-top: calc((var(--range-track-height) - var(--range-thumb-height)) / 2);
  transition: transform 110ms ease, box-shadow 150ms ease, border-color 180ms ease;
  outline: none;
  position: relative;
  z-index: 2;
}
.eq-gain::-moz-range-thumb{
  width: var(--range-thumb-width);
  height: var(--range-thumb-height);
  border-radius: 50%;
  background: var(--range-thumb-bg);
  border: 3px solid var(--accent-red);
  box-shadow: 0 3px 10px rgba(0,0,0,0.35);
  outline: none;
}

/* Firefox track parity */
.eq-gain::-moz-range-track{
  height: var(--range-track-height);
  border-radius: calc(var(--range-track-height) * 0.55);
  background-image: linear-gradient(90deg, var(--accent-red) 0%, var(--accent-red) var(--pos)), linear-gradient(90deg, rgba(255,255,255,0.03), rgba(255,255,255,0.03));
  background-repeat: no-repeat, repeat;
  background-size: calc(var(--pos, 0%) - var(--range-thumb-half)) 100%, 100% 100%;
  background-position: left center, left center;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.02), inset 0 -1px 0 rgba(0,0,0,0.06);
  border: 1px solid rgba(0,0,0,0.12);
}

/* Make Max Voices slider match the other slider knobs too (unified styling) */
#envMaxVoicesRange,
#envMaxVoicesRange[type="range"]{
  --pos: var(--pos, 0%);
  height: var(--range-track-height);
  box-sizing: border-box;
}

/* Use a single-layer accent fill for the Max Voices track so it doesn't render a nested/duplicate track */
#envMaxVoicesRange::-webkit-slider-runnable-track{
  height: var(--range-track-height);
  border-radius: calc(var(--range-track-height) * 0.55);
  background-image:
    linear-gradient(90deg, var(--accent-red) 0%, var(--accent-red) var(--pos));
  background-repeat: no-repeat;
  background-size: var(--pos, 0%) 100%;
  background-position: left center;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.02), inset 0 -1px 0 rgba(0,0,0,0.06);
  border: 1px solid rgba(0,0,0,0.12);
}

/* Thumb styling (unified) */
#envMaxVoicesRange::-webkit-slider-thumb{
  -webkit-appearance: none;
  appearance: none;
  width: var(--range-thumb-width);
  height: var(--range-thumb-height);
  border-radius: 50%;
  background: var(--range-thumb-bg);
  box-shadow: 0 3px 10px rgba(0,0,0,0.35);
  border: 1px solid var(--thumb-border);
  margin-top: calc((var(--range-track-height) - var(--range-thumb-height)) / 2);
  transition: transform 110ms ease, box-shadow 150ms ease, border-color 180ms ease;
  outline: none;
  position: relative;
  z-index: 2;
}
#envMaxVoicesRange::-moz-range-thumb{
  width: var(--range-thumb-width);
  height: var(--range-thumb-height);
  border-radius: 50%;
  background: var(--range-thumb-bg);
  border: 3px solid var(--accent-red);
  box-shadow: 0 3px 10px rgba(0,0,0,0.35);
  outline: none;
}

/* Ensure eq-gain also uses the single-layer track (removes duplicate inner track) */
.eq-gain {
  --pos: var(--pos, 0%);
  height: var(--range-track-height);
  box-sizing: border-box;
}
.eq-gain::-webkit-slider-runnable-track{
  height: var(--range-track-height);
  border-radius: calc(var(--range-track-height) * 0.55);
  /* single accent fill only */
  background-image: linear-gradient(90deg, var(--accent-red) 0%, var(--accent-red) var(--pos));
  background-repeat: no-repeat;
  background-size: var(--pos, 0%) 100%;
  background-position: left center;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.02), inset 0 -1px 0 rgba(0,0,0,0.06);
  border: 1px solid rgba(0,0,0,0.12);
}
.eq-gain::-webkit-slider-thumb{
  -webkit-appearance: none;
  appearance: none;
  width: var(--range-thumb-width);
  height: var(--range-thumb-height);
  border-radius: 50%;
  background: var(--range-thumb-bg);
  box-shadow: 0 3px 10px rgba(0,0,0,0.35);
  border: 1px solid var(--thumb-border);
  margin-top: calc((var(--range-track-height) - var(--range-thumb-height)) / 2);
  transition: transform 110ms ease, box-shadow 150ms ease, border-color 180ms ease;
  outline: none;
  position: relative;
  z-index: 2;
}
.eq-gain::-moz-range-thumb{
  width: var(--range-thumb-width);
  height: var(--range-thumb-height);
  border-radius: 50%;
  background: var(--range-thumb-bg);
  border: 3px solid var(--accent-red);
  box-shadow: 0 3px 10px rgba(0,0,0,0.35);
  outline: none;
}

/* light-theme overrides: keep knobs white in light theme (same behavior as other sliders) */
.panel.light-theme .eq-gain::-webkit-slider-thumb,
.panel.light-theme #envMaxVoicesRange::-webkit-slider-thumb,
.panel.light-theme .eq-gain::-moz-range-thumb,
.panel.light-theme #envMaxVoicesRange::-moz-range-thumb{
  background: #fff;
  box-shadow: 0 3px 10px rgba(0,0,0,0.35);
  border-color: var(--accent-red);
}

/* light-theme overrides for thumbs */
.panel.light-theme .eq-gain::-webkit-slider-thumb,
.panel.light-theme input[type="range"]::-webkit-slider-thumb{
  background: #fff;
  box-shadow: 0 3px 8px rgba(0,0,0,0.35);
  border-color: var(--thumb-border);
}
.panel.light-theme .eq-gain::-moz-range-thumb,
.panel.light-theme input[type="range"]::-moz-range-thumb{
  background: #fff;
  border-color: var(--accent-red);
}

/* eq-gain track fill using --pos (single-layer fill to avoid nested/duplicate tracks) */
.eq-gain::-webkit-slider-runnable-track{
  height:100%;
  border-radius:8px;
  /* single accent fill layer that terminates at the knob center via --pos */
  background-image: linear-gradient(90deg, var(--accent-red) 0%, var(--accent-red) var(--pos));
  background-repeat: no-repeat;
  background-size: var(--pos, 0%) 100%;
  background-position: left center;
  box-shadow: none;
  border: none;
}
.eq-gain::-moz-range-track{
  height:100%;
  border-radius:8px;
  /* single accent fill layer for Firefox */
  background-image: linear-gradient(90deg, var(--accent-red) 0%, var(--accent-red) var(--pos));
  background-repeat: no-repeat;
  background-size: var(--pos, 0%) 100%;
  background-position: left center;
  border: none;
}

/* Force consistent cross-browser thumb styling for all range inputs (prevents blue/default platform thumbs).
   EQ gain and other specialized sliders inherit these rules; thumb color follows --range-thumb-bg which is theme-aware. 
   Also explicitly disable platform accent-color so native blue/colored knobs are suppressed. */
input[type="range"],
.eq-gain {
  /* prevent UA accent from coloring the track/thumb on newer browsers */
  accent-color: transparent !important;
  padding-left: 0 !important;  /* ensure no accidental padding remains */
  padding-right: 0 !important;
}

/* Explicit, authoritative thumb styling for WebKit-based browsers (Chrome, Safari, Edge Chromium) */
input[type="range"]::-webkit-slider-thumb,
.eq-gain::-webkit-slider-thumb,
#envMaxVoicesRange::-webkit-slider-thumb,
.range-row input[type="range"]::-webkit-slider-thumb,
.eq-freq::-webkit-slider-thumb,
.eq-q::-webkit-slider-thumb,
input[type="range"]::-webkit-slider-thumb:active {
  -webkit-appearance: none !important;
  appearance: none !important;
  width: 25px !important;
  height: 25px !important;
  border-radius: 50% !important;
  /* neutral thin border for thumbs; background color remains theme-aware */
  border: 1px solid var(--thumb-border) !important;
  box-shadow: 0 3px 10px rgba(0,0,0,0.35) !important;
  background: var(--range-thumb-bg) !important; /* theme-aware thumb background */
  margin-top: -4px !important;
  transition: transform 110ms ease, box-shadow 150ms ease, border-color 180ms ease !important;
  outline: none !important;
}

/* Firefox thumb parity: ensure no native blue and match background/border */
input[type="range"]::-moz-range-thumb,
.eq-gain::-moz-range-thumb,
#envMaxVoicesRange::-moz-range-thumb,
.range-row input[type="range"]::-moz-range-thumb,
.eq-freq::-moz-range-thumb,
.eq-q::-moz-range-thumb {
  -moz-appearance: none !important;
  width: 25px !important;
  height: 25px !important;
  border-radius: 50% !important;
  border: 3px solid var(--accent-red) !important;
  box-shadow: 0 3px 10px rgba(0,0,0,0.35) !important;
  background: var(--range-thumb-bg) !important;
  outline: none !important;
}

/* Windows/Edge pseudo-element parity */
input[type="range"]::-ms-thumb {
  width: 25px !important;
  height: 25px !important;
  border-radius: 50% !important;
  border: 3px solid var(--accent-red) !important;
  box-shadow: 0 3px 10px rgba(0,0,0,0.35) !important;
  background: var(--range-thumb-bg) !important;
  outline: none !important;
}

/* Light theme: thumbs should appear white for better contrast (override earlier rules) */
.panel.light-theme input[type="range"]::-webkit-slider-thumb,
.panel.light-theme .eq-gain::-webkit-slider-thumb,
.panel.light-theme #envMaxVoicesRange::-webkit-slider-thumb,
.panel.light-theme .range-row input[type="range"]::-webkit-slider-thumb,
.panel.light-theme input[type="range"]::-moz-range-thumb,
.panel.light-theme .eq-gain::-moz-range-thumb,
.panel.light-theme #envMaxVoicesRange::-moz-range-thumb {
  background: #fff !important;
  box-shadow: 0 3px 8px rgba(0,0,0,0.35) !important;
  border-color: var(--accent-red) !important;
}

/* Focus states: keep color consistent and avoid platform-blue outlines */
input[type="range"]:focus::-webkit-slider-thumb,
input[type="range"]:active::-webkit-slider-thumb,
input[type="range"]:focus::-moz-range-thumb,
input[type="range"]:active::-moz-range-thumb {
  outline: none !important;
  box-shadow: 0 6px 18px rgba(0,0,0,0.35) !important;
  transform: scale(0.98) !important;
  border-color: var(--accent-red) !important;
}

/* Ensure thumbs become white in light theme by overriding the theme-aware variable */
.panel.light-theme {
  --range-thumb-bg: #ffffff;
  /* lighter thumb border in the light-theme for better contrast */
  --thumb-border: rgba(0,0,0,0.08);
}

/* Restore a subtle inner border and inset stroke for slider tracks so the filled area reads against a defined track.
   Use !important to ensure this visual takes precedence over earlier declarations. */
input[type="range"]::-webkit-slider-runnable-track,
.eq-freq::-webkit-slider-runnable-track,
.eq-q::-webkit-slider-runnable-track,
.eq-gain::-webkit-slider-runnable-track,
.range-row input[type="range"]::-webkit-slider-runnable-track {
  border: 1px solid rgba(0,0,0,0.12) !important;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.02), inset 0 -1px 0 rgba(0,0,0,0.06) !important;
  background-clip: padding-box !important;
}

input[type="range"]::-moz-range-track,
.eq-freq::-moz-range-track,
.eq-q::-moz-range-track,
.eq-gain::-moz-range-track {
  border: 1px solid rgba(0,0,0,0.12) !important;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.02), inset 0 -1px 0 rgba(0,0,0,0.06) !important;
  background-clip: padding-box !important;
}

/* ms-track for Edge/IE parity */
input[type="range"]::-ms-track {
  border: 1px solid rgba(0,0,0,0.12) !important;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.02), inset 0 -1px 0 rgba(0,0,0,0.06) !important;
  background-clip: padding-box !important;
}

/* Unified slider sizing & stacking:
   - All slider tracks use --range-track-height.
   - Thumbs are exactly 8px taller than tracks ( --range-thumb-height ).
   - Thumbs are drawn visually in front of the track; on-knob labels (.thumb-value) keep a higher z-index so they sit above knobs.
*/
input[type="range"],
.eq-freq,
.eq-q,
.eq-gain,
#envMaxVoicesRange,
.range-row input[type="range"],
.tab-pane#tab-2 .range-row input[type="range"] {
  height: var(--range-track-height) !important;
  min-height: var(--range-track-height) !important;
  box-sizing: border-box;
  position: relative; /* allow thumb stacking to be more consistent */
  --pos: var(--pos, 0%);

  /* ensure the track has left/right padding equal to half the thumb so the thumb can overhang
     without being visually clipped and so the fill math aligns with the visual center of the knob */
  padding-left: var(--range-thumb-half);
  padding-right: var(--range-thumb-half);
  overflow: visible;
}

/* Standardize thumb size and appearance across browsers; thumbs sit visually above the track */
input[type="range"]::-webkit-slider-thumb,
.eq-gain::-webkit-slider-thumb,
#envMaxVoicesRange::-webkit-slider-thumb,
.range-row input[type="range"]::-webkit-slider-thumb,
.eq-freq::-webkit-slider-thumb,
.eq-q::-webkit-slider-thumb {
  -webkit-appearance: none !important;
  appearance: none !important;
  width: var(--range-thumb-width) !important;
  height: var(--range-thumb-height) !important;
  border-radius: 50% !important;
  border: 1px solid var(--thumb-border) !important;
  box-shadow: 0 3px 10px rgba(0,0,0,0.35) !important;
  background: var(--range-thumb-bg) !important;
  margin-top: calc((var(--range-track-height) - var(--range-thumb-height)) / 2) !important; /* vertically center thumb over track */
  transition: transform 110ms ease, box-shadow 150ms ease, border-color 180ms ease !important;
  outline: none !important;
  z-index: 2; /* attempt to draw above track */
  position: relative;
}

/* Firefox parity for thumbs */
input[type="range"]::-moz-range-thumb,
.eq-gain::-moz-range-thumb,
#envMaxVoicesRange::-moz-range-thumb,
.range-row input[type="range"]::-moz-range-thumb,
.eq-freq::-moz-range-thumb,
.eq-q::-moz-range-thumb {
  width: var(--range-thumb-width) !important;
  height: var(--range-thumb-height) !important;
  border-radius: 50% !important;
  border: 3px solid var(--accent-red) !important;
  box-shadow: 0 3px 10px rgba(0,0,0,0.35) !important;
  background: var(--range-thumb-bg) !important;
  outline: none !important;
  z-index: 2;
}

/* Ensure track visuals use the new track height for their internal geometry */
input[type="range"]::-webkit-slider-runnable-track,
.eq-freq::-webkit-slider-runnable-track,
.eq-q::-webkit-slider-runnable-track,
.eq-gain::-webkit-slider-runnable-track,
.range-row input[type="range"]::-webkit-slider-runnable-track {
  height: var(--range-track-height) !important;
  border-radius: calc(var(--range-track-height) * 0.55) !important;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.02), inset 0 -1px 0 rgba(0,0,0,0.06) !important;
  background-clip: padding-box !important;
}

/* When panel is light-theme, thumbs become white but keep the standardized sizing */
.panel.light-theme input[type="range"]::-webkit-slider-thumb,
.panel.light-theme .eq-gain::-webkit-slider-thumb,
.panel.light-theme #envMaxVoicesRange::-webkit-slider-thumb,
.panel.light-theme .range-row input[type="range"]::-webkit-slider-thumb,
.panel.light-theme input[type="range"]::-moz-range-thumb,
.panel.light-theme .eq-gain::-moz-range-thumb,
.panel.light-theme #envMaxVoicesRange::-moz-range-thumb {
  background: #fff !important;
  box-shadow: 0 3px 8px rgba(0,0,0,0.35) !important;
  border-color: var(--accent-red) !important;
}

/* Keep on-knob labels above thumbs */
.thumb-value {
  z-index: 50 !important;
}

/* Ensure the input element doesn't accidentally render above the labels */
input[type="range"] { z-index: 1; }

/* Make eq-gain thumbs use the unified thumb sizing so they match other sliders */
.eq-gain::-webkit-slider-thumb,
.eq-gain::-moz-range-thumb,
.eq-gain::-ms-thumb {
  width: var(--range-thumb-width) !important;
  height: var(--range-thumb-height) !important;
  border-radius: 50% !important;
  border: 1px solid var(--thumb-border) !important;
  box-shadow: 0 3px 10px rgba(0,0,0,0.35) !important;
  background: var(--range-thumb-bg) !important;
  margin-top: calc((var(--range-track-height) - var(--range-thumb-height)) / 2) !important;
  outline: none !important;
  z-index: 2;
  position: relative;
}

/* Ensure envMaxVoices and other special sliders also respect the unified sizing (parity fallback) */
#envMaxVoicesRange::-webkit-slider-thumb,
#envMaxVoicesRange::-moz-range-thumb,
#envMaxVoicesRange::-ms-thumb {
  width: var(--range-thumb-width) !important;
  height: var(--range-thumb-height) !important;
  margin-top: calc((var(--range-track-height) - var(--range-thumb-height)) / 2) !important;
}

/* Cap the accent-filled track so the right edge of the fill is locked to the visual center of the knob.
   Approach:
   - use a single authoritative calc() that subtracts half the thumb width from the percentage fill.
   - apply it consistently to WebKit/Mozilla/MS implementations, using safe fallbacks when needed.
   - prefer --pos (percentage) as the single source-of-truth; remove reliance on fragmented --pos-fill.
*/
:root{
  /* Ensure a numeric px fallback is available for calc() if a UA doesn't support custom-prop math.
     Consumers should still set --range-thumb-width in pixels (e.g. 25px) via the existing variables. */
  --range-thumb-half: calc(var(--range-thumb-width) / 2);
}

/* WebKit: use CSS calc to subtract half the thumb width from the percentage fill.
   The first background layer is the accent fill; the second is the neutral track base. */
input[type="range"]::-webkit-slider-runnable-track,
.eq-freq::-webkit-slider-runnable-track,
.eq-q::-webkit-slider-runnable-track,
.eq-gain::-webkit-slider-runnable-track,
.range-row input[type="range"]::-webkit-slider-runnable-track,
.tab-pane#tab-2 .range-row input[type="range"]::-webkit-slider-runnable-track {
  /* use --pos-fill when available; otherwise subtract half the thumb so the accent fill ends at the visual center of the knob */
  /* accent fill now maps exactly to the proportional point (--pos) so the fill edge matches the value */
  background-size: var(--pos, 0%) 100%, 100% 100% !important;
  background-position: left center, left center !important;
}

/* Mozilla: Firefox requires a slightly different approach but the same calc semantics work.
   Use calc(var(--pos) - halfThumb) for the primary layer; browsers that don't understand the calc
   will fall back to the full percent (still acceptable). */
input[type="range"]::-moz-range-track,
.eq-freq::-moz-range-track,
.eq-q::-moz-range-track,
.eq-gain::-moz-range-track {
  /* Firefox: subtract half-thumb so the visible accent fill ends at the knob center (matches WebKit calc) */
  background-size: calc(var(--pos, 0%) - var(--range-thumb-half)) 100%, 100% 100% !important;
  background-position: left center, left center !important;
}

/* MS track fallback: older MS engines may not handle mixed percent+px math robustly, so we clamp with a conservative calc.
   This keeps the visible fill always ending at or slightly before the knob center. */
input[type="range"]::-ms-track,
.eq-freq::-ms-track,
.eq-q::-ms-track,
.eq-gain::-ms-track {
  background-size: calc(var(--pos, 0%) - var(--range-thumb-half)) 100% !important;
  background-position: left center !important;
}

/* Ensure --pos is always treated as a percentage string (e.g. "42%"); updateRangeThumbPositions sets --pos.
   If a UA cannot evaluate calc() with a CSS variable, the browsers will render a safe approximation
   but modern browsers will honor the subtraction so the accent fill ends at the knob center. */

/* Keep on-knob labels above thumbs */
.thumb-value {
  z-index: 50 !important;
}

/* Ensure input element doesn't render above the labels */
input[type="range"] { z-index: 1; }

/* --- Disabled-pole visual tweak
   When an EQ pole is disabled we want its slider/select controls to appear visually muted (greyed)
   while leaving the small pole-enable switch fully interactive and unchanged. This targets only
   the form controls inside .eq-pole.disabled and keeps pointer-events enabled so the pole can
   be re-enabled by the user. */
.eq-pole.disabled .eq-freq,
.eq-pole.disabled .eq-q,
.eq-pole.disabled .eq-gain,
.eq-pole.disabled .eq-shape,
.eq-pole.disabled .eq-control input[type="range"],
.eq-pole.disabled select,
.eq-pole.disabled input[type="range"]{
  opacity: 0.55 !important;           /* reduce emphasis (still readable) */
  filter: grayscale(60%) contrast(0.95) !important; /* subtle grey-out */
  box-shadow: none !important;        /* remove any strong inset accents */
}

/* Ensure the disabled pole's slider track uses a neutral base instead of the accent fill so the
   pole reads visually off without disabling interactivity. This only affects visual appearance. */
.eq-pole.disabled .eq-freq::-webkit-slider-runnable-track,
.eq-pole.disabled .eq-q::-webkit-slider-runnable-track,
.eq-pole.disabled .eq-gain::-webkit-slider-runnable-track {
  /* ensure disabled poles show a faint accent fill rather than a blank neutral bar */
  background-image:
    linear-gradient(90deg, var(--accent-red-outline) 0%, var(--accent-red-outline) var(--pos)),
    linear-gradient(90deg, rgba(255,255,255,0.02), rgba(255,255,255,0.02)) !important;
  background-repeat: no-repeat, repeat;
  background-size: var(--pos-fill, calc(var(--pos, 0%) - var(--range-thumb-half))) 100%, 100% 100% !important;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.42) !important;
  border-color: rgba(0,0,0,0.08) !important;
}

/* Firefox parity for disabled pole tracks */
.eq-pole.disabled .eq-freq::-moz-range-track,
.eq-pole.disabled .eq-q::-moz-range-track,
.eq-pole.disabled .eq-gain::-moz-range-track {
  /* Firefox fallback: faded accent for disabled pole tracks */
  background-image:
    linear-gradient(90deg, var(--accent-red-outline) 0%, var(--accent-red-outline) var(--pos)),
    linear-gradient(90deg, rgba(255,255,255,0.02), rgba(255,255,255,0.02)) !important;
  background-repeat: no-repeat, repeat;
  background-size: calc(var(--pos, 0%) - var(--range-thumb-half)) 100%, 100% 100% !important;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.42) !important;
  border-color: rgba(0,0,0,0.08) !important;
}

/* Keep the pole-enable .switch appearance intact and interactive (do NOT grey this toggle). */
.eq-pole.disabled .pole-enable { opacity: 1 !important; filter: none !important; }

/* Master-off visual state:
   When the master EQ is turned off we visually mute each pole by adding a semi-opaque grey overlay
   and tone-down the pole controls while keeping their state preserved. The small pole-enable button
   also appears visually "off" (outline-only) but remains interactive (aria-disabled is set in JS). */
.eq-pole.master-off{
  position: relative;
  /* slightly dim the underlying controls so the overlay feels natural */
  filter: grayscale(60%) contrast(0.9) opacity(0.88);
  /* maintain pointer-events so the small enable button can still be focused/clicked (JS marks it aria-disabled) */
  pointer-events: auto;
}

/* subtle overlay using ::after so inputs remain reachable (pointer-events left to children) */
.eq-pole.master-off::after{
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 8px;
  background: rgba(128,128,128,0.30); /* soft grey veil */
  pointer-events: none; /* keep controls usable */
  z-index: 8;
}

/* When master is off, show pole-enable as visually off (outline only) regardless of its locked state.
   Keep it interactive but convey the override via muted color. */
.eq-pole.master-off .pole-enable-btn{
  background: transparent !important;
  color: rgba(200,200,200,0.85) !important;
  border-color: rgba(200,200,200,0.28) !important;
  box-shadow: none !important;
}

/* Ensure any inner svg/icon inside the small button is also muted */
.eq-pole.master-off .pole-enable-btn svg,
.eq-pole.master-off .pole-enable-btn *{
  color: rgba(200,200,200,0.85) !important;
  fill: rgba(200,200,200,0.85) !important;
}

/* If a pole-enable is visually 'locked' (had .locked) we still prevent the strong filled appearance
   while master is off by forcing the muted outline look. */
.eq-pole.master-off .pole-enable-btn.locked{
  background: transparent !important;
  color: rgba(200,200,200,0.85) !important;
  border-color: rgba(200,200,200,0.28) !important;
  box-shadow: none !important;
}

/* --- Switch knob positioning fix
   Ensure the .switch-track reserves consistent inner padding on both sides so the absolutely positioned
   knob can move to the exact ends (left/right) in both light and dark themes. This prevents the knob
   being visually stuck at center in dark mode; the knob movement is controlled by left calc() rules elsewhere. */
.switch .switch-track{
  /* preserve existing rules while explicitly providing symmetric horizontal spacing that the knob math expects */
  padding-left: 2px !important;
  padding-right: 2px !important;
  box-sizing: border-box;
}



/* Also ensure pole-enable compact switches behave the same way (they reuse the same knob math) */


/* Force accurate accent-fill alignment: ensure the filled portion of range tracks ends at the visual center of the knob.
   Use a single canonical calc(var(--pos) - var(--range-thumb-half)) across WebKit, Gecko and Trident engines so
   the accent bar does not "approach" the knob but precisely meets its center. */
:root{
  /* ensure half-thumb variable exists and is derived from the authoritative thumb width */
  --range-thumb-half: calc(var(--range-thumb-width) / 2);
}

/* WebKit-based browsers (Chrome, Safari, Edge Chromium) */
input[type="range"]::-webkit-slider-runnable-track,
.eq-freq::-webkit-slider-runnable-track,
.eq-q::-webkit-slider-runnable-track,
.eq-gain::-webkit-slider-runnable-track,
.range-row input[type="range"]::-webkit-slider-runnable-track,
.tab-pane#tab-2 .range-row input[type="range"]::-webkit-slider-runnable-track {
  /* use the authoritative percentage --pos so the fill reaches the proportional location in the container */
  background-size: var(--pos, 0%) 100%, 100% 100% !important;
  background-position: left center, left center !important;
}

/* Firefox (Gecko) */
input[type="range"]::-moz-range-track,
.eq-freq::-moz-range-track,
.eq-q::-moz-range-track,
.eq-gain::-moz-range-track {
  background-size: calc(var(--pos, 0%) - var(--range-thumb-half)) 100% !important;
  background-position: left center, left center !important;
}

/* Edge/IE ms-track fallback */
input[type="range"]::-ms-track,
.eq-freq::-ms-track,
.eq-q::-ms-track,
.eq-gain::-ms-track {
  background-size: calc(var(--pos, 0%) - var(--range-thumb-half)) 100% !important;
  background-position: left center !important;
}

/* Defensive: ensure --pos is always expected as a percentage string; if not set, fall back to 0% */
input[type="range"] { --pos: var(--pos, 0%); }

/* Ensure docked filter-display is centered and never overhangs the panel: remove forced right inset
   and use auto-centering; keep a 1px gutter via its own width calc to respect borders. */
.panel .filter-display,
.panel.minimized.minimized-show-filter .filter-display,
.panel.minimized .filter-display {
  right: auto !important;
  left: 50% !important;
  transform: translateX(-50%) !important;
  width: calc(100% - 2px) !important;
  padding: 0 !important;
  box-sizing: border-box !important;
}