331 lines
8.4 KiB
Markdown
331 lines
8.4 KiB
Markdown
# Dark Theme Implementation
|
|
|
|
## Overview
|
|
|
|
EVE now features a comprehensive dark theme system that ensures all UI elements look beautiful in both light and dark modes, with automatic system preference detection.
|
|
|
|
## Features
|
|
|
|
### Theme Options
|
|
|
|
1. **Light Mode** ☀️ - Clean, bright interface
|
|
2. **Dark Mode** 🌙 - Easy on the eyes, default theme
|
|
3. **System Mode** 🖥️ - Automatically follows OS theme preference
|
|
|
|
### Key Capabilities
|
|
|
|
- **Automatic Detection** - Respects system dark mode preferences
|
|
- **Persistent Storage** - Theme choice saved across sessions
|
|
- **Instant Switching** - Changes apply immediately
|
|
- **Comprehensive Coverage** - All UI elements support both themes
|
|
- **Beautiful UI** - Carefully crafted color schemes for both modes
|
|
|
|
## Implementation Details
|
|
|
|
### Architecture
|
|
|
|
#### Theme Manager (`src/lib/theme.ts`)
|
|
|
|
A singleton class that handles:
|
|
- Theme state management
|
|
- LocalStorage persistence
|
|
- System preference detection via `prefers-color-scheme` media query
|
|
- Dynamic HTML class application (`dark` class on root element)
|
|
- Real-time system theme change detection
|
|
|
|
```typescript
|
|
export class ThemeManager {
|
|
setTheme(theme: 'light' | 'dark' | 'system'): void
|
|
getTheme(): 'light' | 'dark' | 'system'
|
|
isDark(): boolean
|
|
}
|
|
```
|
|
|
|
#### Settings Store Integration
|
|
|
|
Theme preference is stored in `settingsStore`:
|
|
- Persisted to LocalStorage via Zustand middleware
|
|
- Accessible throughout the app
|
|
- Defaults to `'dark'`
|
|
|
|
#### CSS Variables
|
|
|
|
TailwindCSS dark mode classes are used throughout:
|
|
- `dark:bg-gray-800` for dark backgrounds
|
|
- `dark:text-white` for dark text colors
|
|
- `dark:border-gray-700` for dark borders
|
|
- etc.
|
|
|
|
### Components with Dark Mode
|
|
|
|
All components support dark mode via Tailwind's `dark:` prefix:
|
|
|
|
#### Core UI
|
|
- ✅ `App.tsx` - Main app container
|
|
- ✅ `ChatInterface.tsx` - Chat area
|
|
- ✅ `ChatMessage.tsx` - Message bubbles
|
|
- ✅ `SettingsPanel.tsx` - Settings modal
|
|
|
|
#### Selectors
|
|
- ✅ `ModelSelector.tsx` - AI model dropdown
|
|
- ✅ `CharacterSelector.tsx` - Character picker
|
|
|
|
#### Advanced Features
|
|
- ✅ `ConversationList.tsx` - Conversation browser
|
|
- ✅ `MessageContent.tsx` - Markdown renderer
|
|
- ✅ `CodeBlock.tsx` - Code syntax highlighting
|
|
- ✅ `MermaidDiagram.tsx` - Diagram renderer
|
|
- ✅ `TTSControls.tsx` - Audio controls
|
|
- ✅ `VoiceInput.tsx` - Microphone controls
|
|
- ✅ `FileUpload.tsx` - File upload area
|
|
- ✅ `FilePreview.tsx` - File preview cards
|
|
|
|
### Theme Selector UI
|
|
|
|
Located in `SettingsPanel` > Appearance section:
|
|
|
|
- **Visual Design**: Three large, clickable cards
|
|
- **Icons**: Sun (light), Moon (dark), Monitor (system)
|
|
- **Active State**: Blue border and background highlight
|
|
- **Responsive**: Works on all screen sizes
|
|
- **Accessible**: Clear labels and visual feedback
|
|
|
|
## User Experience
|
|
|
|
### Default Behavior
|
|
|
|
1. App opens in **dark mode** by default
|
|
2. User can change theme in Settings > Appearance
|
|
3. Theme persists across app restarts
|
|
4. System mode respects OS preference changes in real-time
|
|
|
|
### Theme Persistence
|
|
|
|
- Stored in: `localStorage` → `eve-settings` → `theme` field
|
|
- Survives app restarts
|
|
- Synced across all app windows/tabs (if web version)
|
|
|
|
### Visual Consistency
|
|
|
|
#### Dark Mode Palette
|
|
|
|
- **Background**: Gray 900-800 gradient
|
|
- **Cards**: Gray 800
|
|
- **Borders**: Gray 700
|
|
- **Text**: White / Gray 300
|
|
- **Accents**: Blue 500
|
|
|
|
#### Light Mode Palette
|
|
|
|
- **Background**: Blue 50 → Indigo 100 gradient
|
|
- **Cards**: White
|
|
- **Borders**: Gray 200-300
|
|
- **Text**: Gray 800 / Gray 600
|
|
- **Accents**: Blue 500
|
|
|
|
## Technical Implementation
|
|
|
|
### 1. Theme Initialization
|
|
|
|
In `App.tsx`:
|
|
```typescript
|
|
useEffect(() => {
|
|
const themeManager = getThemeManager()
|
|
themeManager.setTheme(theme)
|
|
}, [theme])
|
|
```
|
|
|
|
### 2. HTML Class Application
|
|
|
|
The theme manager adds/removes the `dark` class on `<html>`:
|
|
```typescript
|
|
if (isDark) {
|
|
document.documentElement.classList.add('dark')
|
|
} else {
|
|
document.documentElement.classList.remove('dark')
|
|
}
|
|
```
|
|
|
|
### 3. CSS Variable System
|
|
|
|
In `index.css`:
|
|
```css
|
|
:root {
|
|
--background: 0 0% 100%;
|
|
--foreground: 222.2 84% 4.9%;
|
|
/* ... more variables */
|
|
}
|
|
|
|
.dark {
|
|
--background: 222.2 84% 4.9%;
|
|
--foreground: 210 40% 98%;
|
|
/* ... dark mode overrides */
|
|
}
|
|
```
|
|
|
|
### 4. Component Styling
|
|
|
|
Components use Tailwind's `dark:` prefix:
|
|
```jsx
|
|
<div className="bg-white dark:bg-gray-800 text-gray-800 dark:text-white">
|
|
Content
|
|
</div>
|
|
```
|
|
|
|
## Browser Compatibility
|
|
|
|
- ✅ Chrome/Edge (Chromium)
|
|
- ✅ Firefox
|
|
- ✅ Safari
|
|
- ✅ Tauri Desktop (All platforms)
|
|
|
|
Uses standard web APIs:
|
|
- `matchMedia('(prefers-color-scheme: dark)')`
|
|
- `localStorage`
|
|
- CSS classes
|
|
|
|
## Testing
|
|
|
|
### Manual Testing Checklist
|
|
|
|
- [x] Light theme applies correctly
|
|
- [x] Dark theme applies correctly
|
|
- [x] System theme follows OS preference
|
|
- [x] Theme persists after app restart
|
|
- [x] Theme selector shows correct active state
|
|
- [x] All components visible in both themes
|
|
- [x] Text readable in both themes
|
|
- [x] Borders visible in both themes
|
|
- [x] Hover states work in both themes
|
|
- [x] Focus states work in both themes
|
|
|
|
### OS Integration Testing
|
|
|
|
**macOS**:
|
|
1. System Preferences > General > Appearance
|
|
2. Select "Light" or "Dark"
|
|
3. EVE updates if theme set to "System"
|
|
|
|
**Windows**:
|
|
1. Settings > Personalization > Colors
|
|
2. Choose "Light" or "Dark"
|
|
3. EVE updates if theme set to "System"
|
|
|
|
**Linux**:
|
|
1. DE settings (varies by desktop environment)
|
|
2. Toggle light/dark mode
|
|
3. EVE updates if theme set to "System"
|
|
|
|
## Best Practices
|
|
|
|
### For Future Component Development
|
|
|
|
When creating new components, always include dark mode support:
|
|
|
|
```tsx
|
|
// ✅ Good - Has dark mode support
|
|
<div className="bg-white dark:bg-gray-800">
|
|
<p className="text-gray-800 dark:text-white">Text</p>
|
|
</div>
|
|
|
|
// ❌ Bad - No dark mode support
|
|
<div className="bg-white">
|
|
<p className="text-gray-800">Text</p>
|
|
</div>
|
|
```
|
|
|
|
### Color Guidelines
|
|
|
|
| Element | Light Mode | Dark Mode |
|
|
|---------|-----------|-----------|
|
|
| Primary BG | `bg-white` | `dark:bg-gray-800` |
|
|
| Secondary BG | `bg-gray-50` | `dark:bg-gray-900` |
|
|
| Card BG | `bg-white` | `dark:bg-gray-800` |
|
|
| Text Primary | `text-gray-800` | `dark:text-white` |
|
|
| Text Secondary | `text-gray-600` | `dark:text-gray-300` |
|
|
| Text Muted | `text-gray-500` | `dark:text-gray-400` |
|
|
| Border | `border-gray-200` | `dark:border-gray-700` |
|
|
| Hover BG | `hover:bg-gray-100` | `dark:hover:bg-gray-700` |
|
|
| Accent | `text-blue-500` | (same) |
|
|
|
|
## Benefits
|
|
|
|
### User Benefits
|
|
|
|
✅ **Reduced Eye Strain** - Dark mode easier on eyes in low light
|
|
✅ **Battery Savings** - Dark pixels use less power on OLED screens
|
|
✅ **Personal Preference** - Users choose what they like
|
|
✅ **Modern Feel** - Follows current UI trends
|
|
✅ **Accessibility** - Better for light-sensitive users
|
|
|
|
### Developer Benefits
|
|
|
|
✅ **Consistent System** - Single theme manager for entire app
|
|
✅ **Easy to Maintain** - Standard Tailwind classes
|
|
✅ **Type Safe** - TypeScript theme types
|
|
✅ **Well Documented** - Clear implementation guide
|
|
✅ **Future Proof** - Easy to add more themes
|
|
|
|
## Future Enhancements
|
|
|
|
### Potential Additions
|
|
|
|
- **Custom Themes** - User-defined color schemes
|
|
- **Accent Color Picker** - Customize primary color
|
|
- **Theme Presets** - Additional theme options (Nord, Dracula, etc.)
|
|
- **Contrast Modes** - High contrast variants
|
|
- **Per-Window Themes** - Different themes per window
|
|
- **Theme Animations** - Smooth color transitions
|
|
- **Theme API** - Allow extensions to add themes
|
|
|
|
### Animation Ideas
|
|
|
|
```css
|
|
* {
|
|
transition: background-color 0.2s, color 0.2s, border-color 0.2s;
|
|
}
|
|
```
|
|
|
|
Could make theme switches feel more polished.
|
|
|
|
## Troubleshooting
|
|
|
|
### Theme Not Applying
|
|
|
|
1. Check browser console for errors
|
|
2. Verify `dark` class on `<html>` element
|
|
3. Check LocalStorage for `eve-settings` entry
|
|
4. Clear cache and reload
|
|
|
|
### System Theme Not Detected
|
|
|
|
1. Verify OS has theme preference set
|
|
2. Check browser permissions
|
|
3. Test with `window.matchMedia('(prefers-color-scheme: dark)').matches`
|
|
|
|
### Components Look Wrong
|
|
|
|
1. Check for missing `dark:` classes
|
|
2. Verify color variables are defined
|
|
3. Check for conflicting styles
|
|
4. Use browser DevTools to inspect
|
|
|
|
## Summary
|
|
|
|
EVE now has a professional, fully-featured dark theme system that:
|
|
|
|
- Works automatically out of the box
|
|
- Respects user and system preferences
|
|
- Covers every UI element
|
|
- Persists across sessions
|
|
- Follows modern design principles
|
|
- Is easy to maintain and extend
|
|
|
|
The implementation is complete, tested, and production-ready! 🎉
|
|
|
|
---
|
|
|
|
**Implementation Date**: October 5, 2025
|
|
**Status**: ✅ Complete
|
|
**Version**: v0.2.0-rc
|