fix+feat: correct light/dark palette scoping, add theme toggle

Fix: palette overrides now use @media(prefers-color-scheme:light) +
[data-theme=light] only — no more :root:not([data-theme=dark]) which
incorrectly matched OS-dark with no attribute set.

Feat: theme toggle button in nav (🌙/☀️), persisted to localStorage,
applied via data-theme attribute on <html>. Respects OS preference on
first visit.
This commit is contained in:
Falkan
2026-03-17 10:55:10 -04:00
parent 6f3d02d31c
commit 062850280c
2 changed files with 55 additions and 22 deletions

View File

@@ -1,8 +1,30 @@
<script lang="ts">
import '@picocss/pico/css/pico.min.css';
import '../app.css';
import { browser } from '$app/environment';
let { children } = $props();
// Resolve initial theme: stored pref > OS preference
function resolveInitialTheme(): 'light' | 'dark' {
if (!browser) return 'light';
const stored = localStorage.getItem('theme');
if (stored === 'light' || stored === 'dark') return stored;
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
let theme = $state<'light' | 'dark'>(resolveInitialTheme());
// Apply theme to <html> and persist
$effect(() => {
if (!browser) return;
document.documentElement.setAttribute('data-theme', theme);
localStorage.setItem('theme', theme);
});
function toggleTheme() {
theme = theme === 'light' ? 'dark' : 'light';
}
</script>
<header>
@@ -14,6 +36,11 @@
<li><a href="/">Converter</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
<li>
<button class="theme-toggle outline secondary" onclick={toggleTheme} aria-label="Toggle light/dark mode">
{theme === 'light' ? '🌙' : '☀️'}
</button>
</li>
</ul>
</nav>
</header>