Add theme switching with three modes (system/light/dark) using Tailwind v4 class-based dark mode. Theme preference is persisted in localStorage and defaults to the system's prefers-color-scheme. All components updated with dark: variants for consistent dark mode rendering including SVG elements. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2.9 KiB
2.9 KiB
Issue #18: Dark/Light Theme Toggle
Status: COMPLETED
Overview
Add a dark/light theme toggle to the UI with three modes (system, light, dark), persisted in localStorage, defaulting to system preference.
Implementation Details
1. Tailwind v4 Dark Mode Configuration
- Updated
src/app.csswith@variant dark (&:where(.dark, .dark *));for class-based dark mode
2. Theme Store (src/lib/stores/theme.svelte.ts)
- Svelte 5 runes-based store with three modes: 'light', 'dark', 'system'
- Loads preference from localStorage on init, defaults to 'system'
- Listens to
prefers-color-schememedia query when in 'system' mode - Applies/removes
darkclass ondocument.documentElement - Adds temporary
theme-transitionclass for smooth CSS transitions
3. ThemeToggle Component (src/lib/components/ThemeToggle.svelte)
- Compact button that cycles: system -> light -> dark -> system
- SVG icons: monitor (system), sun (light), moon (dark)
- Text label showing current mode
- Dark mode aware styling
4. Layout Integration
- Theme store initialized via
$effectin+layout.svelte - Global CSS transition styles for smooth theme switching
- ThemeToggle added to all page headers (chat, lineage, memory, audit, home)
5. Dark Mode Classes Applied To
src/routes/+page.svelte(home page)src/routes/chat/+page.svelte(chat page)src/routes/lineage/+page.svelte(lineage page)src/routes/memory/+page.svelte(memory page)src/routes/audit/+page.svelte(audit page)src/lib/components/SessionSidebar.sveltesrc/lib/components/ConfigSidebar.sveltesrc/lib/components/MessageBubble.sveltesrc/lib/components/MessageList.sveltesrc/lib/components/MessageInput.sveltesrc/lib/components/OrchestrationProgress.sveltesrc/lib/components/ThinkingSection.sveltesrc/lib/components/FinalResult.sveltesrc/lib/components/LineageTree.sveltesrc/lib/components/MemoryCandidateCard.sveltesrc/lib/components/AuditTimeline.svelte
Color Mapping Applied
bg-white->dark:bg-gray-900bg-gray-50->dark:bg-gray-800bg-gray-100->dark:bg-gray-700bg-gray-200->dark:bg-gray-600/dark:bg-gray-700text-gray-900->dark:text-gray-100text-gray-700->dark:text-gray-300text-gray-500->dark:text-gray-400text-gray-400->dark:text-gray-500border-gray-200->dark:border-gray-700border-gray-300->dark:border-gray-600- Colored backgrounds (blue, green, amber, red, purple) use opacity-based dark variants (e.g.,
dark:bg-blue-900/40) - SVG elements in LineageTree use reactive color values based on
themeStore.isDark
Files Changed
src/app.css- Added dark mode variant configurationsrc/lib/stores/theme.svelte.ts- New theme storesrc/lib/components/ThemeToggle.svelte- New toggle componentsrc/routes/+layout.svelte- Theme init and transition styles- All page and component files listed above - Added dark: variants