Track a dirty flag set by every state mutation (inline edit, drag, delete, modal save, fetch playlist, clear, image-from-music, playlist URL input) and cleared by a successful save. Intercept back-link clicks with the existing ask() confirm modal. Use beforeunload for tab close / refresh. Also refactor ask() so cancel paths properly discard the pending callback instead of leaking handlers. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>