diff --git a/src/app.js b/src/app.js index 50eab2b..d29cdc0 100644 --- a/src/app.js +++ b/src/app.js @@ -1485,15 +1485,39 @@ }); // Settings dialog (puppy name + birthday) + // ---------- theme ---------- + // Preference is device-global (not per user). No stored choice → follow the + // OS via the prefers-color-scheme media query; a choice sets data-theme on + // , which the CSS treats as an override. The
applies any saved + // choice before first paint; this just resolves state and reacts to the toggle. + const THEME_KEY = "puppy-tracker:theme"; + const prefersDark = () => + window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches; + function effectiveTheme() { + const s = localStorage.getItem(THEME_KEY); + return s === "light" || s === "dark" ? s : (prefersDark() ? "dark" : "light"); + } + function setTheme(theme) { + document.documentElement.dataset.theme = theme; + try { localStorage.setItem(THEME_KEY, theme); } catch { /* ignore */ } + } + const settingsDialog = document.getElementById("settings-dialog"); const settingsForm = document.getElementById("settings-form"); const settingsName = document.getElementById("settings-name"); const settingsBirthday = document.getElementById("settings-birthday"); + const settingsTheme = document.getElementById("settings-theme"); + + // Apply live so the toggle previews immediately (independent of Save/Cancel). + settingsTheme.addEventListener("change", () => { + setTheme(settingsTheme.checked ? "dark" : "light"); + }); function openSettingsDialog() { const cfg = loadConfig(); settingsName.value = cfg.name; settingsBirthday.value = cfg.birthday; + settingsTheme.checked = effectiveTheme() === "dark"; settingsDialog.showModal(); setTimeout(() => settingsName.focus(), 50); } diff --git a/src/index.html b/src/index.html index f330b29..0e23c46 100644 --- a/src/index.html +++ b/src/index.html @@ -9,6 +9,16 @@ +