Files
shahondin1624 60f3d8eeda 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>
2026-03-12 12:54:04 +01:00

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.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