Adds an Auto / Dark / Light radio group to the Options page that
overrides the OS `prefers-color-scheme` setting. Stored in
chrome.storage.local under tuner.theme. Defaults to Auto.
Architecture:
- src/lib/theme.js (new, ~55 lines) — getTheme/setTheme/applyTheme/initTheme
helpers. applyTheme sets/removes `data-theme` attribute on <html>;
initTheme reads storage + applies.
- popup.js + newtab.js + options.js: call initTheme() FIRST in their
init() so the theme paints before anything else. All three also
listen for chrome.storage.onChanged on the THEME_KEY and live-apply
changes — pick Light in Options, popup + newtab flip instantly.
- options.html: new 'Appearance' card with 3 radio buttons (Auto/Dark/
Light) above the existing Playback card.
- options.css: styled radio group (pill-shaped, accent border on
:checked, hover state). Plus the Auto/Dark/Light CSS overrides
themselves.
- popup.css, newtab.css, options.css: each gets html[data-theme=light]
and html[data-theme=dark] blocks that override :root vars. Attribute
selector specificity beats both :root and the @media :root, so the
manual override wins when set.
UX:
- Default = Auto (follows OS via existing @media block)
- Pick Dark → overrides OS, forces dark palette
- Pick Light → overrides OS, forces light palette
- Selection persists across reloads, syncs across all three surfaces
7 files, ~150 lines added. No new permissions, no new dependencies.
Bundled with v0.4.1-prep back-link + Phase 1 OS-follow light mode for
the v0.5.0 release.