diff --git a/src/app.css b/src/app.css index 89b49a8c..1c9e6109 100644 --- a/src/app.css +++ b/src/app.css @@ -1,5 +1,11 @@ @import 'tailwindcss'; +/* Enable class-based dark mode for Tailwind v4. + Without this, Tailwind v4 defaults to @media (prefers-color-scheme: dark), + which ignores the .dark class on and always follows the OS setting. + This makes the dark/light toggle in e_app_theme.svelte actually work. */ +@custom-variant dark (&:where(.dark, .dark *)); + @import '@skeletonlabs/skeleton'; diff --git a/src/app.html b/src/app.html index f6b3dd12..8ac1b8ed 100644 --- a/src/app.html +++ b/src/app.html @@ -1,5 +1,5 @@ - + diff --git a/src/lib/app_components/e_app_theme.svelte b/src/lib/app_components/e_app_theme.svelte index 3c1d4f09..f6054d48 100644 --- a/src/lib/app_components/e_app_theme.svelte +++ b/src/lib/app_components/e_app_theme.svelte @@ -149,13 +149,7 @@ if ($ae_loc.app_cfg.theme_mode == 'light') { $ae_loc.theme_mode = 'light'; } - if ($ae_loc.theme_mode == 'light') { - document.documentElement.classList.remove('dark'); - document.documentElement.classList.add('light'); - } else if ($ae_loc.theme_mode == 'dark') { - document.documentElement.classList.remove('light'); - document.documentElement.classList.add('dark'); - } + // DOM sync is handled reactively by the layout effect in +layout.svelte }} title="Change light and dark mode" > diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 8ea0a959..afd8b9ba 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -161,9 +161,19 @@ $effect(() => { if (!browser) return; - // Theme DOM update + // Theme name — controls which Skeleton color palette is active document.documentElement.setAttribute('data-theme', $ae_loc?.theme_name ?? 'nouveau'); + // Dark/light class — controls Tailwind v4 class-based dark mode variant. + // @custom-variant dark in app.css registers this; without it the class does nothing. + if ($ae_loc?.theme_mode === 'dark') { + document.documentElement.classList.add('dark'); + document.documentElement.classList.remove('light'); + } else { + document.documentElement.classList.add('light'); + document.documentElement.classList.remove('dark'); + } + // Hydration overlay timer if ($ae_loc?.account_id) { const timer = setTimeout(() => is_hydrating = false, 500);