feat(decnet_web/Layout): topbar dark/light toggle with circular reveal
User-facing theme toggle ships now that the design system has been audited end-to-end. A Sun/Moon button lives between the threat indicator and the SYSTEM status pill in the topbar — same slim 28x28 voice as the rest of the topbar controls, no chrome shouting at the user. Click coords drive a View Transitions API circle clip-path that grows from the cursor to the farthest viewport corner over 520ms with the project's standard --ease curve. Browsers without startViewTransition (older Firefox, Safari < 18) fall through to an unanimated swap — the hook returns instantly in that case. Persistence is two-tier: - localStorage decnet_theme — the user's saved preference, the thing the topbar toggle writes. Survives reloads, applies everywhere. - sessionStorage decnet_theme_lab — dev-mode lab override (Task 3). Tab-scoped, wins on boot so devs can A/B without nuking the saved preference. App.tsx hydrates both on first mount in the right order so the correct theme is on <html> before the first paint. useThemeToggle is a small hook in lib/ rather than a Layout-only helper so the same toggle can be reused later from a settings page or hotkey.
This commit is contained in:
@@ -92,6 +92,8 @@ export { default as Terminal } from 'lucide-react/dist/esm/icons/terminal';
|
||||
export { default as Timer } from 'lucide-react/dist/esm/icons/timer';
|
||||
export { default as Trash2 } from 'lucide-react/dist/esm/icons/trash-2';
|
||||
export { default as Upload } from 'lucide-react/dist/esm/icons/upload';
|
||||
export { default as Moon } from 'lucide-react/dist/esm/icons/moon';
|
||||
export { default as Sun } from 'lucide-react/dist/esm/icons/sun';
|
||||
export { default as UploadCloud } from 'lucide-react/dist/esm/icons/cloud-upload';
|
||||
export { default as UserPlus } from 'lucide-react/dist/esm/icons/user-plus';
|
||||
export { default as Users } from 'lucide-react/dist/esm/icons/users';
|
||||
|
||||
Reference in New Issue
Block a user