feat: add light/dark theme toggle with system preference detection

- Implement theme store with localStorage persistence
- Add ThemeToggle component with animated icon transitions
- Update color system with semantic tokens for light/dark modes
- Add blocking script in app.html to prevent FOUC
- Apply theme-aware styling across all public and admin pages
This commit is contained in:
2026-01-06 20:31:24 -06:00
parent 0149dc1df9
commit 5c4d3b6efa
26 changed files with 336 additions and 190 deletions
+11 -3
View File
@@ -2,23 +2,31 @@
import { cn } from "$lib/utils";
import type { Snippet } from "svelte";
import Dots from "./Dots.svelte";
import ThemeToggle from "./ThemeToggle.svelte";
let {
class: className = "",
backgroundClass = "",
bgColor = "bg-black",
bgColor = "",
showThemeToggle = true,
children,
}: {
class?: string;
backgroundClass?: string;
bgColor?: string;
showThemeToggle?: boolean;
children?: Snippet;
} = $props();
</script>
<div class={cn("pointer-events-none fixed inset-0 -z-20", bgColor)}></div>
<div class={cn("pointer-events-none fixed inset-0 -z-20 bg-white dark:bg-black transition-colors duration-300", bgColor)}></div>
<Dots class={[backgroundClass]} />
<main class={cn("relative min-h-screen text-zinc-50", className)}>
{#if showThemeToggle}
<div class="fixed top-5 right-6 z-50">
<ThemeToggle />
</div>
{/if}
<main class={cn("relative min-h-screen text-zinc-900 dark:text-zinc-50 transition-colors duration-300", className)}>
{#if children}
{@render children()}
{/if}