// RangerHQ Tuner — Theme helpers (v0.5.0) // // Three modes: // auto — follow OS via @media (prefers-color-scheme: light) // dark — force dark regardless of OS // light — force light regardless of OS // // Stored in chrome.storage.local under `tuner.theme`. Default: auto. // // Application strategy: set/remove `data-theme` attribute on . // - "auto" → attribute removed → @media in each stylesheet decides // - "dark" → data-theme="dark" → CSS forces dark vars // - "light" → data-theme="light" → CSS forces light vars // // Used from popup.js, newtab.js, and options.js on init + on cross-surface // sync. export const THEME_KEY = 'tuner.theme'; export const THEME_AUTO = 'auto'; export const THEME_DARK = 'dark'; export const THEME_LIGHT = 'light'; export const THEME_DEFAULT = THEME_AUTO; export const VALID_THEMES = [THEME_AUTO, THEME_DARK, THEME_LIGHT]; /** Read the stored theme preference, falling back to "auto". */ export async function getTheme() { if (typeof chrome === 'undefined' || !chrome.storage?.local) return THEME_DEFAULT; const o = await chrome.storage.local.get(THEME_KEY); const v = o[THEME_KEY]; return VALID_THEMES.includes(v) ? v : THEME_DEFAULT; } /** Persist a theme preference. Any cross-surface listeners will pick it up. */ export async function setTheme(theme) { if (!VALID_THEMES.includes(theme)) theme = THEME_DEFAULT; if (typeof chrome === 'undefined' || !chrome.storage?.local) return theme; await chrome.storage.local.set({ [THEME_KEY]: theme }); return theme; } /** Apply a theme to the current document. Pass "auto" to clear the override. */ export function applyTheme(theme) { const t = VALID_THEMES.includes(theme) ? theme : THEME_DEFAULT; const html = document.documentElement; if (t === THEME_AUTO) { html.removeAttribute('data-theme'); } else { html.setAttribute('data-theme', t); } } /** Convenience: read the stored theme and apply it. */ export async function initTheme() { applyTheme(await getTheme()); }