Add a dark theme, default, with a switch in the top bar
Colours move into theme tokens (light values in :root, dark in [data-theme=dark]); the closing contact band inverts on each theme. The choice is stored in localStorage and applied by a head script before the first paint. Voxel covers and image shadows follow the theme. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XtcZtnG4GQA1d6mW5PNrS9
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect, useState } from 'react'
|
||||
import styles from './topbar.module.css'
|
||||
|
||||
type Theme = 'dark' | 'light'
|
||||
|
||||
/** Switches between the dark (default) and light theme; the choice is remembered in this browser. */
|
||||
export default function ThemeToggle() {
|
||||
const [theme, setTheme] = useState<Theme>('dark')
|
||||
|
||||
// The page starts dark; a small script in <head> applies a stored "light" choice before the first paint.
|
||||
useEffect(() => {
|
||||
setTheme(document.documentElement.dataset.theme === 'light' ? 'light' : 'dark')
|
||||
}, [])
|
||||
|
||||
const toggle = () => {
|
||||
const next: Theme = theme === 'dark' ? 'light' : 'dark'
|
||||
document.documentElement.dataset.theme = next
|
||||
try {
|
||||
localStorage.setItem('theme', next)
|
||||
} catch {
|
||||
// Storage can be blocked; the theme still switches for this visit.
|
||||
}
|
||||
setTheme(next)
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className={styles.toggle}
|
||||
onClick={toggle}
|
||||
aria-label={theme === 'dark' ? 'Switch to the light theme' : 'Switch to the dark theme'}
|
||||
>
|
||||
{theme === 'dark' ? (
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<circle cx="12" cy="12" r="4" />
|
||||
<path d="M12 2.5v2.2M12 19.3v2.2M4.2 4.2l1.6 1.6M18.2 18.2l1.6 1.6M2.5 12h2.2M19.3 12h2.2M4.2 19.8l1.6-1.6M18.2 5.8l1.6-1.6" />
|
||||
</svg>
|
||||
) : (
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="M20.5 14.2A8.5 8.5 0 0 1 9.8 3.5a8.5 8.5 0 1 0 10.7 10.7z" />
|
||||
</svg>
|
||||
)}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user