# 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