/* ============================================================================
   KNOBS.CSS — animated rotary knob controls
   ----------------------------------------------------------------------------
   Progressive enhancement for <input type="range"> elements. The native range
   stays in the DOM as the single source of truth (so every existing handler,
   .value read and preset/reset keeps working); this stylesheet only paints the
   knob that knobs.js builds around it.

   Applied to:
     - Re-Production Studio  · Step 6 (Advanced Settings)  #panel-advanced
     - Re-Production Studio  · Step 7 (Final Blend)        #panel-preview
     - Re-Performance Studio · Part 3 (Human feel)         #rp-sliders
   ============================================================================ */

.avh-knob-native { display: none !important; }

.avh-knob {
  --knob-size: 58px;
  --knob-accent: var(--accent-2, #35c2ff);
  --knob-accent-2: var(--accent, #ff6b35);
  position: relative;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  min-width: var(--knob-size);
  width: auto;
  margin: 2px 4px 2px 0;
  vertical-align: middle;
  outline: none;
  -webkit-user-select: none;
  user-select: none;
  touch-action: none;
  cursor: ns-resize;
  opacity: 0;
  transform: translateY(4px) scale(.96);
  animation: avh-knob-in .34s cubic-bezier(.22, 1, .36, 1) forwards;
}

@keyframes avh-knob-in {
  to { opacity: 1; transform: translateY(0) scale(1); }
}

/* ---- dial (SVG) ---------------------------------------------------------- */
.avh-knob-dial {
  width: var(--knob-size);
  height: var(--knob-size);
  display: block;
  overflow: visible;
  transition: filter .18s ease;
}

.avh-knob-track {
  fill: none;
  stroke: #2a2f3a;
  stroke-width: 7;
  stroke-linecap: round;
}

.avh-knob-fill {
  fill: none;
  stroke: url(#avhKnobGrad);
  stroke-width: 7;
  stroke-linecap: round;
  filter: drop-shadow(0 0 3px rgba(53, 194, 255, .55));
  transition: stroke-dasharray .12s cubic-bezier(.22, 1, .36, 1);
}

.avh-knob-tick {
  stroke: #3a4150;
  stroke-width: 1.4;
  stroke-linecap: round;
}

.avh-knob-tick.major { stroke: #59627a; stroke-width: 2; }

/* the rotating cap face */
.avh-knob-face {
  fill: url(#avhKnobFace);
  stroke: #333a47;
  stroke-width: 1;
}

.avh-knob-face-inner {
  fill: none;
  stroke: rgba(255, 255, 255, .05);
  stroke-width: 1;
}

/* ---- needle (HTML overlay, rotates via CSS) ------------------------------ */
.avh-knob-needle-wrap {
  position: absolute;
  top: 0;
  left: 50%;
  width: var(--knob-size);
  height: var(--knob-size);
  display: flex;
  justify-content: center;
  align-items: flex-start;
  pointer-events: none;
  transform: translateX(-50%);
  transform-origin: 50% 50%;
  transition: transform .13s cubic-bezier(.22, 1, .36, 1);
  /* NOTE: no permanent `will-change: transform` here. There are ~50 knobs on
     the Step 5 rack, and a permanent will-change promoted every one of them to
     its own compositor layer for the whole life of the page -- 50 extra layers
     to composite on every scroll frame. The hint is now applied only while a
     knob is actually being dragged (see .avh-knob.is-active below), which is
     the only time the transform changes rapidly. */
}

.avh-knob.is-active .avh-knob-needle-wrap {
  will-change: transform;
}

.avh-knob-needle {
  width: 3px;
  height: 22%;
  margin-top: 12%;
  border-radius: 3px;
  background: linear-gradient(180deg, #ffffff, var(--knob-accent));
  box-shadow: 0 0 6px rgba(53, 194, 255, .85);
}

/* ---- value readout ------------------------------------------------------- */
.avh-knob-val {
  font-size: 10.5px;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  color: var(--accent-2, #35c2ff);
  font-weight: 600;
  white-space: nowrap;
  max-width: 112px;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: center;
  transition: color .15s ease;
}

.avh-knob.no-readout .avh-knob-val { display: none; }

/* ---- interaction states -------------------------------------------------- */
.avh-knob:hover .avh-knob-dial { filter: brightness(1.12); }
.avh-knob:focus-visible .avh-knob-dial { filter: brightness(1.15) drop-shadow(0 0 4px rgba(53, 194, 255, .6)); }

.avh-knob.is-active .avh-knob-dial {
  filter: brightness(1.2) drop-shadow(0 0 7px rgba(53, 194, 255, .55));
}
.avh-knob.is-active .avh-knob-face { stroke: var(--knob-accent); }
.avh-knob.is-active .avh-knob-val { color: #fff; }

.avh-knob.is-disabled {
  cursor: not-allowed;
  opacity: .4;
  pointer-events: none;
  filter: grayscale(.5);
}

/* ---- multi-knob rows (a single control with two ranges, e.g. Mud) -------- */
.avh-knob-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 10px 14px;
  margin: 2px 0;
}

/* ---- contextual sizing --------------------------------------------------- */
.ctrl .avh-knob { --knob-size: 58px; }
.knob-row .avh-knob { --knob-size: 54px; }
.aim-ctrl .avh-knob,
.aim-module .avh-knob { --knob-size: 52px; }
.track-strip .avh-knob { --knob-size: 42px; margin: 0 2px; }
.track-strip .avh-knob-val { font-size: 9.5px; }
.rp-slider .avh-knob { --knob-size: 56px; }

/* keep the knob centered inside the small mixer strips */
.vol-slider .avh-knob,
.pan-slider .avh-knob { margin: 0; }

/* the native range that used to sit in these slots no longer reserves space */
.vol-slider, .pan-slider { display: inline-flex; align-items: center; justify-content: center; }

/* ---- light-touch layout help where a knob replaced a full-width slider --- */
.ctrl .avh-knob-row { justify-content: flex-start; }
.aim-ctrl .avh-knob-row { justify-content: flex-start; }

/* ---- accessibility: never rely on the entrance animation for visibility -- */
@media (prefers-reduced-motion: reduce) {
  .avh-knob {
    animation: none;
    opacity: 1;
    transform: none;
  }
  .avh-knob-needle-wrap,
  .avh-knob-fill { transition: none; }
}

