feat: add persistent light/dark mode toggle

- Add CSS custom property token system to globals.css (dark + light variants)
- Add anti-FOUC inline script in layout.tsx head to apply stored theme before hydration
- Create useTheme hook (src/hooks/useTheme.ts) backed by usePersistentState
- Add Sun/Moon toggle button to LeftToolbar above Settings
- Wire useTheme into ThreePanelLayout and pass theme/onThemeToggle to LeftToolbar
- Migrate hardcoded hex values to CSS vars in LeftToolbar and ThreePanelLayout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
“BeeRad”
2026-03-17 19:32:06 +11:00
co-authored by Claude Sonnet 4.6
parent 4802187f5e
commit bf175ad125
5 changed files with 144 additions and 13 deletions
+28
View File
@@ -0,0 +1,28 @@
"use client";
import { useEffect } from 'react';
import { usePersistentState } from './usePersistentState';
export type Theme = 'dark' | 'light';
function getInitialTheme(): Theme {
if (typeof document === 'undefined') {
return 'dark';
}
return document.documentElement.getAttribute('data-theme') === 'light' ? 'light' : 'dark';
}
export function useTheme(): [Theme, () => void] {
const [theme, setTheme] = usePersistentState<Theme>('ui.theme', getInitialTheme());
useEffect(() => {
document.documentElement.setAttribute('data-theme', theme);
}, [theme]);
const toggleTheme = () => {
setTheme((prev) => (prev === 'dark' ? 'light' : 'dark'));
};
return [theme, toggleTheme];
}