${/* column rendering stays the same */}
`;
};
```
6. Add `@dragend` as a single stable handler on the virtualizer too (it's already `this.onTrackDragEnd` which is stable).
**CRITICAL:** Event delegation must work through shadow DOM. Since the virtualizer and its children are all within the same shadow root, `event.target.closest('.track-row')` works correctly. But verify with `composedPath()` if needed.
**queue-panel.ts — renderTrackItem:**
Apply the same event delegation pattern:
1. Add `data-index="${track.position}"` (or the loop index) to each `.track-item`
2. Register delegated handlers on the virtualizer in firstUpdated
3. Extract item index via `closest('.track-item')?.dataset.index`
4. Remove all inline closures from the template
**cover-grid.ts — renderAlbumCard/renderGridEntry:**
The cover grid already uses some delegation (it reads `data-index` for some operations). Verify that all click handlers on album cards use delegation. If any inline closures remain in `renderGridEntry` or `renderAlbumCard`, convert them.
**Key rule:** After this change, `renderTrackRow` and `renderTrackItem` should create ZERO new function objects. Every handler reference should be stable (either a bound class method or a property arrow function defined once in the class body).