<!-- SS · part 103 -->
function (it, i) {
      g.fillStyle = it.i === S.sel ? 'rgba(227,18,44,.10)' : (i % 2 ? 'rgba(255,255,255,.025)' : 'rgba(0,0,0,0)'); g.fillRect(it.start * bx, 0, it.bars * bx, h);
      g.strokeStyle = 'rgba(232,195,106,.45)'; g.beginPath(); g.moveTo(it.start * bx + .5, 0); g.lineTo(it.start * bx + .5, h); g.stroke();
    });
    g.font = '9px ui-monospace,Menlo,monospace';
    var tick = Math.max(1, Math.ceil(bars / Math.max(4, Math.floor(w / 46))));
    for (var b = 0; b <= bars; b += tick) { g.fillStyle = '#888'; g.fillText(mmss(b * barSec()), b * bx + 2, 13); g.fillStyle = '#333'; g.fillRect(b * bx, 16, 1, 4); }
    g.fillStyle = '#1b1b1b'; g.fillRect(0, RU - 1, w, 1);
    for (var li = 1; li < 5; li++) { g.fillStyle = '#141414'; g.fillRect(0, RU + li * LH, w, 1); }
    var spx = bx / 16, tot = totalSec() || 1;
    vocalPlan().forEach(function (v) {
      var c = VOX.clips[v.text], x0 = v.t / tot * w;
      if (!c) { g.fillStyle = 'rgba(255,48,72,.22)'; g.fillRect(x0, RU + 16, Math.max(2, Math.min(v.slot, 3) / tot * w - 1), LH - 32); return; }
      var cw = Math.max(2, c.dur / tot * w), pk = c.peaks; g.fillStyle = LANE_C.vocals;
      for (var x = 0; x < cw; x++) { var a = pk[Math.floor(x / cw * pk.length)] || 0, hh = Math.max(1, a * (LH - 8)); g.fillRect(x0 + x, RU + LH / 2 - hh / 2, 1, hh); }
    });
    hook('draw', g, w, RU, LH, tot);
    PLAN.items.forEach(function (it) {
      var p = S.sections[it.name].patterns;
      for (var rb = 0; rb < it.bars; rb++) {
        var bar0 = (it.start + rb) * bx;
        for (var s = 0; s < 16; s++) {
          var x = bar0 + s * spx;
          var amp = (p.drums.kick[s] ? .9 : 0) + (p.drums.snare[s] ? .7 : 0) + (p.drums.hat[s] ? .3 : 0) + (p.drums.perc[s] ? .4 : 0);
          if (amp) { var hh = Math.min(1, amp) * (LH - 10); g.fillStyle = LANE_C.drums; g.fillRect(x, RU + LH + LH / 2 - hh / 2, Math.max(1, spx * .6), hh); }
          ['bass', 'chords', 'lead'].forEach(function (t, ti) {
            var v = p[t][s]; if (!v) return; var y0 = RU + (2 + ti) * LH;
            var len = 1; for (var q = s + 1; q < 16 && !p[t][q]; q++) len++; if (t !== 'chords') len = Math.min(len, t === 'bass' ? 2 : 1);
            var mids = t === 'chords' ? chordMidis(v) : [noteMidi(v)]; if (!mids) return;
            g.fillStyle = LANE_C[t];
            mids.forEach(function (m) { if (m == null) return; var lo = t === 'bass' ? 24 : t === 'chords' ? 55 : 58, hi = t === 'bass' ? 52 : t === 'chords' ? 80 : 86; var yy = y0 + LH - 6 - (Math.max(lo, Math.min(hi, m)) - lo) / (hi - lo) * (LH - 12); g.fillRect(x, yy - 1.5, Math.max(1.5, len * spx - 1), 3); });
          });
        }
      }
    });
  }
  $('#es-tl-wrap').addEventListener('click', function (e) {
    var r = this.getBoundingClientRect(), t = (e.clientX - r.left) / r.width * totalSec();
    var it = locate(Math.floor(t / barSec())); if (it && it.i !== S.sel) { S.sel = it.i; refreshSection(); }
    seekTo(t);
  });
  function renderSecButtons() {
    $('#es-secs').innerHTML = PLAN.items.map(function (it) {
      return '<button type="button" class="es-secbtn' + (it.i === S.sel ? ' is-sel' : '') + '" data-i="' + it.i + '" style="flex-grow:' + it.bars + '">' + it.name.toUpperCase() + '<small>' + mmss(it.start * barSec()) + '–' + mmss((it.start + it.bars) * barSec()) + '</small></button>';
    }).join('');
  }
  $('#es-secs').addEventListener('click', function (e) { var b = e.target.closest('.es-secbtn'); if (!b) return; S.sel = +b.getAttribute('data-i'); refreshSection(); if (!playing) seekTo(PLAN.items[S.sel].start * barSec()); else if (loopSection) play(); });
  function moveSel(d) { var i = S.sel, j = i + d; if (j < 0 || j >= S.arrangement.length) return; var a = S.arrangement, t = a[i]; a[i] = a[j]; a[j] = t; S.sel = j; arrChanged(); }
  $('#es-arr-left').addEventListener('click', function () { moveSel(-1); });
  $('#es-arr-right').addEventListener('click', function () { moveSel(1); });
  $('#es-arr-dup').addEventListener('click', function () { if (S.arrangement.length >= 24) return toast('24 sections max.'); S.arrangement.splice(S.sel + 1, 0, selName()); S.sel++; arrChanged(); });
  $('#es-arr-del').addEventListener('click', function () { if (S.arrangement.length <= 1) return; S.arrangement.splice(S.sel, 1); S.sel = Math.min(S.sel, S.arrangement.length - 1); arrChanged(); });
  $('#es-arr-add').addEventListener('change', function () { var v = this.value; this.value = ''; if (!v) return; if (S.arrangement.length >= 24) return toast('24 sections max.'); S.arrangement.splice(S.sel + 1, 0, v); S.sel++; arrChanged(); });
  $('#es-sec-bars').addEventListener('change', function () { var n = Math.max(1, Math.min(16, Math.round(+this.value || 4))); this.value = n; S.sections[selName()].bars = n; arrChanged(); });
  function arrChanged() { save(); PLAN = plan(); refreshSection(); drawCurve(); if (playing) play(Math.min(curPos(), Math.max(0, totalSec() - 0.1))); }

  // ----------------------------------------