The bespoke reorder ghost read a row's absolute-position inside a ListView, which double-counts the row's own offset, so it only sat at the cursor for row 0 and flew off for the rest. Drive the app-wide DragState directly from the reorder gesture so the shared DragGhost (positioned in AppShell at the proven window coords) renders the reorder ghost; a new DragState.reorder flag keeps the sidebar from claiming it as an add-to-playlist drop and keeps the Rust DragActions path out of it. Removed the buggy local ghost. Reorder logic + persistence unchanged. (state.slint also carries the quality-badge fields for the next commit.)
cc