qdbus6 refreshCurrentShell sometimes reloads the page before the
WebEngine has settled, leaving innerWidth/Height at 0. Canvas stays
0x0 and the rAF loops draw nothing. initCanvases() now polls every
80ms until dimensions are valid before calling resizeCanvas/resizeFloor.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
music-light fetches synced LRC lyrics from lrclib.net on track change,
tracks playback position via a 0.5s background thread, and exposes the
current lyric line in /current. dancer.html polls /current at 700ms and
displays the line bottom-left with a cyan glow, subtitle style.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rgba(20,0,50,0.72) lets the gradient bleed through the bands, reducing
harsh contrast while keeping the stripe effect visible.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
280px circle with repeating stripe overlay (13px gap / 4px band),
yellow→orange→magenta→purple gradient, positioned half-buried at the
horizon so the floor grid renders over the lower half and the fog floats
in front. Atmospheric halo via ::after pseudo-element.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fewer compositing layers speeds up WebEngine initialization after deploy.
will-change hint lets the browser pre-promote layers before animation starts.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Five blurred elliptic wisps anchored at the horizon line, each drifting
upward at different speeds (8-15s) and delays for an organic breathing
effect. Color synced with the dominant album art color via applyTheme.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extract a hue-distinct secondary color from album art and apply a
primary→secondary gradient across the VU meter bars (bass end = primary,
treble end = secondary). Falls back to complementary hue if no distinct
color is found.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Pre-compute star RGB components to avoid 3 string.replace() calls per
star per frame (~40K string allocs/sec eliminated)
- Cache floor gradient object; rebuild only on canvas resize
- Batch CAVA bar DOM updates through requestAnimationFrame so SSE events
never trigger mid-frame style mutations
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fetch() from file:// was blocked by missing Access-Control-Allow-Origin
on the music-light server. Both color and album art now work.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Avoids WebEngine mixed-content block on http:// img src from file://.
music-light now saves the PIL image to disk on each track change.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
img src http:// from file:// page is blocked; fetch() to localhost
works, so fetch the blob and use a blob: URL instead.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CSS background-image url() from http:// is blocked in WebEngine local
context even when fetch() works; <img src> does not have this restriction.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
WebEngine blocks fetching external Spotify URLs from local content.
Now uses http://127.0.0.1:8765/art which proxies the image locally.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Direct background-image URLs to external hosts are blocked in the
local WebEngineView context; fetch the image as a blob and convert
to data URL instead.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fetches art_url from music-light /current and displays it as a
background-image div with themed box-shadow. Fades in/out with music.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Meteors now dissolve as they approach the horizon line (fade from
50% to 60% viewport height) via CSS mask-image on their container.
Also fixed spawnMeteor appending to #meteorLayer instead of .scene.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>