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>
69 lines
2.9 KiB
Markdown
69 lines
2.9 KiB
Markdown
# 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
|