The table already computed and emitted the drop row for external URL
drops, but PlaylistView._on_files_dropped threw it away, so imported
files always appended. Thread it through: playlist_view.files_dropped
gains a row slot (None = append), MainWindow.import_files and
file_importer.import_paths take an optional position and hand it to
add_tracks_to_playlist, which already supported positional insert.
Files already in the library dedup to the existing track and insert at
the drop position without duplicating the library entry.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- New prefs: visualizer_mode (on/dim/off, saved on every click) and
color_visualizer_gray (None = keep the derived alternateBase look).
- VisualizerWidget takes prefs (optional, so existing call sites/tests
keep working); restores its mode at startup and validates junk values.
- New "Visualizer (gray mode):" row in the Preferences color sliders;
theme.default_gray mirrors the widget's 0.88-lightness derivation so
an untouched slider shows the current appearance.
- TransportBar.refresh_theme() repaints the visualizer so slider drags
preview live.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>