diff --git a/frontend/src/lib/theme.ts b/frontend/src/lib/theme.ts new file mode 100644 index 0000000..b7b3cb8 --- /dev/null +++ b/frontend/src/lib/theme.ts @@ -0,0 +1,60 @@ +import { writable } from 'svelte/store'; + +export type Theme = 'light' | 'dark'; + +// Get initial theme from localStorage or system preference +function getInitialTheme(): Theme { + if (typeof window === 'undefined') return 'light'; + + const stored = localStorage.getItem('theme') as Theme; + if (stored === 'light' || stored === 'dark') { + return stored; + } + + // Check system preference + if (window.matchMedia('(prefers-color-scheme: dark)').matches) { + return 'dark'; + } + + return 'light'; +} + +// Create the theme store +function createThemeStore() { + const { subscribe, set, update } = writable(getInitialTheme()); + + return { + subscribe, + set: (theme: Theme) => { + if (typeof window !== 'undefined') { + localStorage.setItem('theme', theme); + document.documentElement.setAttribute('data-theme', theme); + } + set(theme); + }, + toggle: () => { + update(current => { + const newTheme = current === 'light' ? 'dark' : 'light'; + if (typeof window !== 'undefined') { + localStorage.setItem('theme', newTheme); + document.documentElement.setAttribute('data-theme', newTheme); + } + return newTheme; + }); + }, + init: () => { + const theme = getInitialTheme(); + if (typeof window !== 'undefined') { + document.documentElement.setAttribute('data-theme', theme); + } + set(theme); + } + }; +} + +export const theme = createThemeStore(); + +// Initialize theme on module load +if (typeof window !== 'undefined') { + theme.init(); +} \ No newline at end of file