added dark/light mode and control

This commit is contained in:
Hunter W.
2026-03-27 13:01:56 -04:00
parent 8bc880fe10
commit 84a6fe4376
7 changed files with 212 additions and 43 deletions

View File

@@ -24,7 +24,7 @@ export default function Footer() {
>
<div style={{ display: "flex", gap: 16 }}>
<span>
(2026) - Hunter W.
(2026) - Hunter W. - Powered by Next.JS
</span>
</div>
<div style={{ display: "flex", gap: 16 }}>

View File

@@ -0,0 +1,95 @@
'use client'
import { useState, useEffect } from 'react'
import { useTheme } from 'next-themes'
const themes = ['system', 'light', 'dark'] as const
const ThemeSwitch = () => {
const [mounted, setMounted] = useState(false)
const { theme, setTheme } = useTheme()
useEffect(() => {
setMounted(true)
}, [])
if (!mounted) return null
const next = () => {
const i = themes.indexOf(theme as (typeof themes)[number])
setTheme(themes[(i + 1) % themes.length])
}
return (
<button
onClick={next}
aria-label={`Theme: ${theme}`}
title={`Theme: ${theme}`}
style={{
position: 'fixed',
top: 'var(--space-4)',
right: 'var(--space-4)',
zIndex: 9999,
background: 'var(--surface)',
border: '1px solid var(--border)',
borderRadius: 'var(--radius-md)',
color: 'var(--fg-secondary)',
cursor: 'pointer',
padding: '8px',
display: 'grid',
placeItems: 'center',
transition: `background var(--duration-fast) var(--ease-out),
border-color var(--duration-fast) var(--ease-out),
color var(--duration-fast) var(--ease-out)`,
}}
onMouseEnter={e => {
e.currentTarget.style.background = 'var(--surface-hover)'
e.currentTarget.style.borderColor = 'var(--border-strong)'
e.currentTarget.style.color = 'var(--fg)'
}}
onMouseLeave={e => {
e.currentTarget.style.background = 'var(--surface)'
e.currentTarget.style.borderColor = 'var(--border)'
e.currentTarget.style.color = 'var(--fg-secondary)'
}}
>
<svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="1.75"
strokeLinecap="round"
strokeLinejoin="round"
>
{theme === 'dark' ? (
// Moon
<path d="M21 12.79A9 9 0 1 1 11.21 3a7 7 0 0 0 9.79 9.79z" />
) : theme === 'light' ? (
// Sun
<>
<circle cx="12" cy="12" r="5" />
<line x1="12" y1="1" x2="12" y2="3" />
<line x1="12" y1="21" x2="12" y2="23" />
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64" />
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78" />
<line x1="1" y1="12" x2="3" y2="12" />
<line x1="21" y1="12" x2="23" y2="12" />
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36" />
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22" />
</>
) : (
// Monitor (system)
<>
<rect x="2" y="3" width="20" height="14" rx="2" ry="2" />
<line x1="8" y1="21" x2="16" y2="21" />
<line x1="12" y1="17" x2="12" y2="21" />
</>
)}
</svg>
</button>
)
}
export default ThemeSwitch