From 6576c452bfa1b2be05734319be040e2042def223 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Mar 2026 18:52:35 +0000 Subject: [PATCH 1/3] Initial plan From e8096e6d8af296d1ab0f088501ee9100446662ea Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Mar 2026 19:05:25 +0000 Subject: [PATCH 2/3] feat: add Dark Mode toggle for foreground UI theming - Add useColorMode hook (src/lib/colorMode.ts) with light|dark|system preference, localStorage persistence under roflbox.colorMode, and prefers-color-scheme system fallback - Add FOUC-prevention inline script to index.html - Add [data-color-mode] CSS tokens (--text-primary, --surface-1, etc.) plus Shadcn variable overrides for light mode in index.css - Add keyboard-accessible Dark mode toggle (role=switch, aria-label, aria-checked) to BackgroundSwitcher settings panel with (system) hint - Wire useColorMode into App.tsx and pass props to BackgroundSwitcher Co-authored-by: zealsprince <1859270+zealsprince@users.noreply.github.com> --- index.html | 13 ++++++ src/App.tsx | 14 +++++- src/components/BackgroundSwitcher.tsx | 49 ++++++++++++++++++++- src/index.css | 59 ++++++++++++++++++++++++++ src/lib/colorMode.ts | 61 +++++++++++++++++++++++++++ 5 files changed, 193 insertions(+), 3 deletions(-) create mode 100644 src/lib/colorMode.ts diff --git a/index.html b/index.html index 2be2e94..3e9de1e 100644 --- a/index.html +++ b/index.html @@ -5,6 +5,19 @@ GIT GUD GET ROFLBOX + +
diff --git a/src/App.tsx b/src/App.tsx index 7bc36d8..5650053 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3,6 +3,7 @@ import { Button } from '@/components/ui/button' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { BackgroundSwitcher } from '@/components/BackgroundSwitcher' import { BG_THEMES, DEFAULT_THEME_ID, type BgTheme } from '@/lib/themes' +import { useColorMode } from '@/lib/colorMode' import { TutorialProvider } from '@/components/TutorialProvider' import { TutorialOverlay } from '@/components/TutorialOverlay' import { useTutorial } from '@/lib/tutorial' @@ -29,6 +30,9 @@ function App() { const [matrixText, setMatrixText] = useState('INITIALIZING...') const [chaosMode, setChaosMode] = useState(false) + // Color mode state – persisted in localStorage under 'roflbox.colorMode' + const { preference: colorModePreference, resolvedMode: resolvedColorMode, setColorMode } = useColorMode() + // Background theme state – persisted in localStorage const [currentTheme, setCurrentTheme] = useState(() => { const saved = localStorage.getItem(STORAGE_KEY) @@ -102,8 +106,14 @@ function App() { className={`min-h-screen flex flex-col items-center justify-start p-4 relative ${chaosClass('perspective-crazy')}`} style={{ overflow: 'visible', background: currentTheme.value }} > - {/* Background theme switcher */} - + {/* Background theme + dark mode switcher */} + {/* FLOATING CHAOS - ABSOLUTE POSITIONED MADNESS - Only in chaos mode */} {chaosMode && ( diff --git a/src/components/BackgroundSwitcher.tsx b/src/components/BackgroundSwitcher.tsx index b1b08e3..05f3926 100644 --- a/src/components/BackgroundSwitcher.tsx +++ b/src/components/BackgroundSwitcher.tsx @@ -2,16 +2,33 @@ import { useState } from 'react' import { Button } from '@/components/ui/button' import { BG_THEMES, type BgTheme } from '@/lib/themes' import { useTutorial } from '@/lib/tutorial' +import { type ColorModePreference, type ColorMode } from '@/lib/colorMode' interface BackgroundSwitcherProps { currentThemeId: string onThemeChange: (theme: BgTheme) => void + colorModePreference: ColorModePreference + resolvedColorMode: ColorMode + onColorModeChange: (pref: ColorModePreference) => void } -export function BackgroundSwitcher({ currentThemeId, onThemeChange }: BackgroundSwitcherProps) { +export function BackgroundSwitcher({ + currentThemeId, + onThemeChange, + colorModePreference, + resolvedColorMode, + onColorModeChange, +}: BackgroundSwitcherProps) { const [open, setOpen] = useState(false) const { start: startTutorial, completed: tutorialCompleted } = useTutorial() + const isDark = resolvedColorMode === 'dark' + + const handleDarkModeToggle = () => { + // Clicking the toggle sets an explicit light/dark preference (overrides system). + onColorModeChange(isDark ? 'light' : 'dark') + } + return (
+ + {/* Dark mode toggle */} +
+ + +
+
+ {(['system', 'light', 'dark'] as const).map((pref) => { + const labels = { system: 'System', light: 'Light', dark: 'Dark' } + const isSelected = colorModePreference === pref + return ( + + ) + })} +
+ {colorModePreference === 'system' && ( +
+ effective: {resolvedColorMode} +
+ )}