v0.11.0: web mixes pick their own color

The export dialog gains an accent color — the hover background on links and
tracklist rows, and the player's progress fill — and the rest of the bar loses
its 2010 gold so that choice is the only color in it.

The accent travels as a `:root { --accent }` custom property declared in
index.html, which player.css reads as `var(--accent, #8c764a)`. That keeps the
stylesheet in the verbatim copyfile loop: index.html is still the only rendered
template. `normalize_accent` is the injection gate — the value lands raw inside
a <style> block and string.Template escapes nothing — and `contrast_text` flips
the hover text black or white, since the old page hard-coded white and a pale
accent made it unreadable.

The bar itself is now fixed light gray with black text. Its sprite glyphs are
pale lavender and yellow, drawn for the dark gold bar, so they're recolored
with `filter: brightness(0)` rather than by editing the GIF — which still ships
byte-identical, spinner and all.

Not persisted: the picker opens on #8c764a every time, so an export nobody
touches looks exactly like the mixes already online.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JBSM2bFC6UToiEg8BE4dqj
This commit is contained in:
2026-08-22 15:14:36 -04:00
co-authored by Claude Opus 5
parent 2a317bcae9
commit 800e8ffb5d
11 changed files with 351 additions and 33 deletions
+11 -2
View File
@@ -183,8 +183,17 @@ persistence) → GUI (Qt widgets that read the manager and connect to its signal
replaced audio.js + jQuery (abandoned since 2012; jQuery was only ever glue —
audio.js never used it). `player-graphics.gif` must ship **byte-identical**:
it's an animated GIF whose loading frame is a spinner, not a flat sprite
sheet. Registered in `setup.py` via `package_data`; loaded with
`importlib.resources` so an installed copy finds it.
sheet — which is why Round 41 recolors its pale glyphs to black with
`filter: brightness(0)` in CSS rather than editing the file. The one
user-chosen color (link/row hover backgrounds + the progress fill) travels as
a `:root { --accent }` custom property declared in `index.html`, so
`player.css` can read it while staying a verbatim `shutil.copyfile` — the page
is still the only rendered template. `exporter.normalize_accent` is a hard
gate, not politeness: the value lands raw inside a `<style>` block and
`string.Template` escapes nothing. The accent is **not** persisted, so an
untouched export still renders the original `#8c764a`. Templates are
registered in `setup.py` via `package_data`; loaded with
`importlib.resources` so an installed copy finds them.
- **`lintunes/cast/`** — Chromecast playback (Connections menu), using the
**media-receiver model**: `server.py` runs a `ThreadingHTTPServer` on an