feat(player): run playback fully in-browser via rockbox-wasm master
Move uploaded-track playback off the remote rockbox server + HLS and onto the in-browser rockbox-wasm engine (decoders + DSP + queue + crossfade in WebAssembly) in both apps/web and apps/web-mobile. No HLS, no remote-rockbox API calls in the audible path. Core - lib/audio/rockbox-engine.ts: lazy RockboxPlayer singleton (baseUrl /rockbox), exact-URL metadata registry, applyAudioSettings/applyEq/applyCrossfade. - useRockboxEngine: mirror engine track/progress/status/queue events into the jotai atoms (replaces the old GraphQL/<audio> polling). - useUploadPlayer: drive the wasm queue; start only the chosen track then background-fill the rest so playback begins immediately. - web: useAudioSettings persists to localStorage + the atproto lexicon and pushes to the engine (drops rockbox saveSettings GraphQL). - vite: copy rockbox-wasm/dist -> public/rockbox (createRequire resolve, robust across Node/CI); optimizeDeps.exclude rockbox-wasm. Fixes - app-proxy: serve /rockbox/* from the Pages deploy (was an empty CDN -> 404 -> SPA html -> worklet AbortError); narrow match to the /rockbox/ prefix; drop the COOP/COEP the single-threaded build no longer needs. - init the AudioContext within the user gesture (was created after an awaited stream-token fetch -> "Unable to load a worklet's module"). - keep the mini-player visible while playing (was cleared by the engine's startup "stopped, queue_len 0" status, which also detached listeners). - EQ band centre frequencies are keyed by index (32 Hz … 16 kHz), never a stale persisted cutoff; labels show 32 … 500 / 1kHz … 16kHz. UI - EQ band faders reverted to native styled sliders (HeroUI broke global styles; its stylesheet was a global reset); baseweb Slider for the mobile crossfade. - web-mobile: drop the <audio> element + custom DSP AudioWorklet + WAV fallback. rockbox-wasm bumped to 0.1.3 (fixes the skipTo -> undefined beginManual crash).