e666465d62
Replace the fixed 5-min rotation with end-driven shuffle: each track plays through, and a short crossfade a few seconds before it ends rolls a random OTHER track (pickNextIndex, no immediate repeat) — so Music is always playing while selected. An 'ended' handler is the safety net (short track / missed timeupdate) and a watchdog resumes an unexpectedly-paused active track. Crossfade injectable via window.__hefMusicXfadeMs. music-playlist.spec.ts reworked to the end-driven model. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>