Frontend (62 components, ~64 rules):
- Replace hardcoded `color: white` / `#fff` with `var(--btn-primary-text)`
in every rule that paints text on `var(--accent-primary)`. Covers in-rule
cases (BulkActionBar, GenreFilterButton, KeybindingsSettings, settings
views, login, modal primary buttons, wizard steps, etc.) plus descendant
selectors (`.parent.selected .child`).
- Semi-transparent rgba(255,255,255,X) over selected accent rows now use
`color-mix(in srgb, var(--btn-primary-text) X%, transparent)` so the mute
level inherits the per-theme token color.
Theme tokens in app.css (--btn-primary-text fixes):
- rose-pine-dawn: #faf4ed → #575279 (was the bg color, ratio 2.60 FAIL;
now 5.71 AA against coral accent)
- kurosaki: #fbf9f2 → #262424 (was the bg color, ratio 1.76 FAIL;
now 8.33 AA against gold accent)
- snow-storm: #eceff4 → #2e3440 (was the bg color, ratio 3.50 AA-Large;
now 6.13 AA against blue accent)
- stratego: #0a0a0a → #ffffff (visual choice; 4.14 AA-Large is
acceptable for button labels and matches palette intent)
Auto-theme generator (src-tauri/src/auto_theme/generator.rs):
- pick_btn_text_for_accent_set(): WCAG-aware FG selection that holds
across accent / hover / active states. Replaces the broken
`luminance < 0.5` threshold which produced 2.0:1 ratios on mid-luminance
accents (Catppuccin lavender, Dracula purple, rose-pine coral).
- ensure_text_contrast_target(text, bg, is_dark, target): generalize the
iterative contrast helper to accept a target ratio. Apply to
text_secondary (4.5) and text_muted (3.0).
- Add --btn-danger-text and --btn-warning-text tokens via
pick_btn_text_for_bg for future status-button consumers.
Misc fixes:
- SettingsView.svelte: extract initialTitlebarMode to const, avoids the
Svelte 5 state_referenced_locally warning.
- QueuePanel.svelte: wrap .stop-after-marker in :global() (the class is
forwarded to a Svelte component child, not a native element) and fix
var(--accent) typo to the correct var(--accent-primary).
Tests: 13 generator tests pass (8 prior + 5 new). svelte-check 0 errors,
31 warnings (down from 33).
cc
Instead of using wallpaper k-means + accent override (which produced
wrong backgrounds), the system source now reads ALL colors from the
DE config (kdeglobals for KDE, dconf hints for GNOME).
Maps Window/View/Button/Selection/Header sections directly to CSS
variables — bg-primary from Window, bg-secondary from View,
bg-tertiary from Button, accent from Selection, text from
ForegroundNormal, etc.
Adds SystemColorScheme type, get_system_color_scheme() in system.rs,
generate_theme_from_scheme() in generator.rs, and two new V2 commands:
v2_generate_theme_from_system_colors and v2_get_system_color_scheme.
Frontend tryAccentColorTheme() replaced with trySystemColorSchemeTheme()
which calls the new endpoint. Old color math helpers removed.
- V2 commands (generate_theme_from_image, generate_theme_from_wallpaper,
extract_palette) now use tokio::task::spawn_blocking to avoid freezing
the main thread during CPU-bound image decoding and k-means clustering.
This lets the UI spinner animate properly.
- KDE accent detection now falls back to Colors:Selection DecorationFocus
and BackgroundNormal from kdeglobals when no explicit AccentColor is set.
This reads the actual KDE color scheme accent instead of only looking
for the Plasma 6 custom accent field.
cc
Rust module auto_theme/ with:
- K-means clustering (k=6) on downsampled images for palette extraction
- CSS variable generator producing all ~40 required theme tokens
- WCAG AA contrast enforcement for text and accent colors
- Desktop environment detection (GNOME, KDE Plasma, COSMIC, XFCE, Cinnamon)
- Wallpaper path retrieval per DE (gsettings, Plasma config, COSMIC config)
- System accent color retrieval (GNOME 47+, KDE, COSMIC)
cc