feat: add dark/light theme toggle with system preference support (#18)
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>
This commit is contained in:
68
implementation-plans/issue-018.md
Normal file
68
implementation-plans/issue-018.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# 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.css` with `@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-scheme` media query when in 'system' mode
|
||||
- Applies/removes `dark` class on `document.documentElement`
|
||||
- Adds temporary `theme-transition` class 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 `$effect` in `+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.svelte`
|
||||
- `src/lib/components/ConfigSidebar.svelte`
|
||||
- `src/lib/components/MessageBubble.svelte`
|
||||
- `src/lib/components/MessageList.svelte`
|
||||
- `src/lib/components/MessageInput.svelte`
|
||||
- `src/lib/components/OrchestrationProgress.svelte`
|
||||
- `src/lib/components/ThinkingSection.svelte`
|
||||
- `src/lib/components/FinalResult.svelte`
|
||||
- `src/lib/components/LineageTree.svelte`
|
||||
- `src/lib/components/MemoryCandidateCard.svelte`
|
||||
- `src/lib/components/AuditTimeline.svelte`
|
||||
|
||||
### Color Mapping Applied
|
||||
- `bg-white` -> `dark:bg-gray-900`
|
||||
- `bg-gray-50` -> `dark:bg-gray-800`
|
||||
- `bg-gray-100` -> `dark:bg-gray-700`
|
||||
- `bg-gray-200` -> `dark:bg-gray-600`/`dark:bg-gray-700`
|
||||
- `text-gray-900` -> `dark:text-gray-100`
|
||||
- `text-gray-700` -> `dark:text-gray-300`
|
||||
- `text-gray-500` -> `dark:text-gray-400`
|
||||
- `text-gray-400` -> `dark:text-gray-500`
|
||||
- `border-gray-200` -> `dark:border-gray-700`
|
||||
- `border-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 configuration
|
||||
- `src/lib/stores/theme.svelte.ts` - New theme store
|
||||
- `src/lib/components/ThemeToggle.svelte` - New toggle component
|
||||
- `src/routes/+layout.svelte` - Theme init and transition styles
|
||||
- All page and component files listed above - Added dark: variants
|
||||
Reference in New Issue
Block a user