Dark Mode
Auto-switch based on Saigon sunrise/sunset, manual toggle, localStorage persistence.
Light & Dark Preview
Light Mode
- Bg: #f5f2eb (kraft paper)
- Surface: #fdfcfa (warm white)
- Text: #1a1a1a (warm black)
- CRT scanlines: 0.06
- CRT noise: 0.045
Dark Mode
- Bg: #0f172a (deep slate)
- Surface: #1e293b (dark slate)
- Text: #e2e8f0 (light gray)
- CRT scanlines: 0.12
- CRT noise: 0.07
How It Works
- Auto-detect: Calculates sunrise/sunset for Saigon (lat 10.82, lon 106.63, UTC+7). If current time is between sunset and sunrise → dark mode.
- Manual toggle: Button in footer (☼/☾) with clock showing GMT+7 time. Overrides auto-detect.
- localStorage: Preference saved as
kycuc-theme= "dark" | "light". Manual preference disables auto-switch. - Periodic check: Every 5 minutes, re-calculates if no manual preference stored.
- Transition:
background-colorandcolortransition 0.3s ease for smooth switch. - Tailwind tokens: 14 light-shade tokens (slate 50-200, orange 50-200, green 50-100, amber 50-100) overridden in
[data-theme="dark"]. - Logo fix: SVG loaded via
<img>cannot inheritcurrentColor→filter: invert(0.9)in dark mode.
CSS Pattern
:root[data-theme="dark"] {
--bg-primary: #0f172a;
--bg-surface: #1e293b;
--text-primary: #e2e8f0;
--accent-orange: var(--color-orange-400);
/* ... all 40+ tokens override */
}
[data-theme="dark"] body::before {
opacity: 0.12; /* CRT scanlines more visible */
}
[data-theme="dark"] .logo-mark {
filter: invert(0.9); /* SVG loaded via img */
} JS Pattern
// DarkModeToggle.astro (is:inline script)
function calcSunriseSunset(date) { /* astronomy math */ }
function isDarkNow() { /* compare with Saigon time */ }
// On load: localStorage ? manual : auto
// On toggle: flip data-theme + save pref
// Every 5min: re-check auto if no manual pref