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 */}
+
+
+
+
+