<script lang="ts"> import { onMount } from 'svelte'; let theme = $state<'light' | 'dark'>('light'); onMount(() => { const stored = (localStorage.getItem('theme') as 'light' | 'dark' | null) ?? null; const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; theme = stored ?? (prefersDark ? 'dark' : 'light'); apply(theme); }); function apply(next: 'light' | 'dark') { const root = document.documentElement; root.classList.toggle('dark', next === 'dark'); root.classList.toggle('light', next === 'light'); root.style.colorScheme = next; } function toggle() { theme = theme === 'dark' ? 'light' : 'dark'; localStorage.setItem('theme', theme); apply(theme); }</script> <button type="button" class="icon-link theme-toggle" onclick={toggle} aria-label={theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'} title={theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'}> {#if theme === 'dark'} <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" > <circle cx="12" cy="12" r="4" /> <path d="M12 2v2" /> <path d="M12 20v2" /> <path d="m4.93 4.93 1.41 1.41" /> <path d="m17.66 17.66 1.41 1.41" /> <path d="M2 12h2" /> <path d="M20 12h2" /> <path d="m6.34 17.66-1.41 1.41" /> <path d="m19.07 4.93-1.41 1.41" /> </svg> {:else} <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" > <path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" /> </svg> {/if}</button> <style> .theme-toggle { background: transparent; border: 0; cursor: pointer; padding: 0; }</style>
<script lang="ts">
import { onMount } from 'svelte';
let theme = $state<'light' | 'dark'>('light');
onMount(() => {
const stored = (localStorage.getItem('theme') as 'light' | 'dark' | null) ?? null;
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
theme = stored ?? (prefersDark ? 'dark' : 'light');
apply(theme);
});
function apply(next: 'light' | 'dark') {
const root = document.documentElement;
root.classList.toggle('dark', next === 'dark');
root.classList.toggle('light', next === 'light');
root.style.colorScheme = next;
}
function toggle() {
theme = theme === 'dark' ? 'light' : 'dark';
localStorage.setItem('theme', theme);
apply(theme);
}
</script>
<button
type="button"
class="icon-link theme-toggle"
onclick={toggle}
aria-label={theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'}
title={theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'}
>
{#if theme === 'dark'}
<svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<circle cx="12" cy="12" r="4" />
<path d="M12 2v2" />
<path d="M12 20v2" />
<path d="m4.93 4.93 1.41 1.41" />
<path d="m17.66 17.66 1.41 1.41" />
<path d="M2 12h2" />
<path d="M20 12h2" />
<path d="m6.34 17.66-1.41 1.41" />
<path d="m19.07 4.93-1.41 1.41" />
</svg>
{:else}
<svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" />
</svg>
{/if}
</button>
<style>
.theme-toggle {
background: transparent;
border: 0;
cursor: pointer;
padding: 0;
}
</style>