<!-- SS · part 91 -->
(); renderRoll(); drawTimeline();
    if (p[s] && E && !playing && Tone.getContext().state === 'running') { try { E.inst[lane].triggerAttackRelease(lane === 'chords' ? chordNotes(v) : v, '8n'); } catch (x) {} }
  });
  $('#es-load-ai').addEventListener('click', function () {
    var n = selName(); if (!S.ai || !S.ai[n]) return toast('Generate a song first — then this restores the AI pattern for ' + cap(n) + '.');
    S.sections[n].patterns = normPat(S.ai[n].patterns); refreshSection(); toast('AI pattern restored for ' + cap(n) + '.');
  });
  $('#es-clear').addEventListener('click', function () { if (!confirm('Clear every lane in ' + cap(selName()) + '?')) return; S.sections[selName()].patterns = emptyPat(); refreshSection(); });
  function regen(track, btn) {
    busy(btn, true);
    api('POST', '/api/ss/pattern', { track: track, section: selName(), key: S.key, bpm: S.bpm, chords: S.chords, genre: S.genre, mood: S.mood, current: selPat()[track] })
      .then(function (j) { var p = selPat(); if (track === 'drums') p.drums = normPat({ drums: j.pattern }).drums; else p[track] = j.pattern; refreshSection(); toast(cap(track) + ' regenerated for ' + cap(selName()) + '.'); })
      .catch(function (e) { toast(e.message, 5000); }).then(function () { busy(btn, false); });
  }
  $$('[data-regen]').forEach(function (b) { b.addEventListener('click', function () { regen(b.getAttribute('data-regen'), b); }); });
  $('#es-roll-regen').addEventListener('click', function () { regen(S.rollLane, this); });
  var kitSel = $('select[data-snd="drums"]');
  kitSel.innerHTML = SOUNDS.drums.map(function (o) { return '<option' + (S.sounds.drums === o ? ' selected' : '') + '>' + o + '</option>'; }).join('');
  kitSel.addEventListener('change', function () { S.sounds.drums = this.value; setSound(E, 'drums', this.value); renderFaders(); save(); });

  // ------------------------------------------------------------------ transport readouts
  var keySel = $('#es-key'); keySel.innerHTML = KEYS.map(function (k) { return '<option>' + k + '</option>'; }).join('');
  function syncTop() { $('#es-bpm').value = S.bpm; $('#es-swing').value = S.swing; if (KEYS.indexOf(S.key) < 0) S.key = parseKey(S.key).name; keySel.value = S.key; }
  $('#es-bpm').addEventListener('change', function () { S.bpm = Math.min(200, Math.max(60, Math.round(+this.value || 92))); this.value = S.bpm; if (E) E.T.bpm.value = S.bpm; save(); drawTimeline(); drawCurve(); if (playing) play(0); });
  $('#es-swing').addEventListener('input', function () { S.swing = +this.value; if (E) E.T.swing = S.swing; save(); });
  keySel.addEventListener('change', function () { S.key = this.value; save(); renderRoll(); });

  // ------------------------------------------------------------------ mixer + master + spectrum
  function renderFaders() {
    $('#es-faders').innerHTML = LANES.map(function (t) {
      return '<div class="es-fader" style="--c:' + LANE_C[t] + '"><b>' + t.toUpperCase() + '</b><input type="range" min="-36" max="6" step="1" value="' + (S.vols[t] || 0) + '" data-fader="' + t + '" aria-label="' + t + ' volume">' +
        '<div class="es-ms"><button type="button" data-mute="' + t + '" class="' + (S.mutes[t] ? 'is-on' : '') + '" title="Mute">M</button><button type="button" data-solo="' + t + '" class="' + (S.solos[t] ? 'is-on' : '') + '" title="Solo">S</button></div>' +
        (t === 'vocals' ? '<span class="es-hint">Kokoro</span>' : '<select data-fsnd="' + t + '" aria-label="' + t + ' sound">' + SOUNDS[t].map(function (o) { return '<option' + (S.sounds[t] === o ? ' selected' : '') + '>' + o + '</option>'; }).join('') + '</select>') + '</div>';
    }).join('');
  }
  $('#es-faders').addEventListener('input', function (e) { var f = e.target.getAttribute('data-fader'); if (!f) return; S.vols[f] = +e.target.value; applyMix(E); save(); });
  $('#es-faders').addEventListener('click', function (e) {
    var m = e.target.getAttribute('data-mute'), so = e.target.getAttribute('data-solo');
    if (m) { S.mutes[m] = !S.mutes[m]; e.target.classList.toggle('is-on', S.mutes[m]); }
    else if (so) { S.solos[so] = !S.solos[so]; e.target.classList.toggle('is-on', S.solos[so]); } else return;
    applyMix(E); save();
  });
  $('#es-faders').addEventListener('change', function (e) { var t = e.target.getAttribute('data-fsnd'); if (!t) return; S.sounds[t] = e.target.value; setSound(E, t, e.target.value); if (t === 'drums') kitSel.value = e.target.value; if (t === S.rollLane) renderRoll(); save(); });
  function syncKnobs() { $$('[data-m-k]').forEach(function (k) { k.value = S.master[k.getAttribute('data-m-k')]; }); $('#es-master-state').textContent = 'MASTER: ' + (S.master.on ? 'ON · COMP · EQ · LIMITER' : 'OFF'); $('#es-master').classList.toggle('is-on', !!S.master.on); }
  $('#es-knobs').addEventListener('input', function (e) { var k = e.target.getAttribute('data-m-k'); if (!k) return; S.master[k] = +e.target.value; applyMaster(E); save(); });
  $('#es-master').addE