# 2.2 Color Harmony & Theming ## Design Philosophy The dashboard implements a **multi-theme dark-mode system** inspired by the visual palettes of contemporary video games—each theme evokes a distinct atmospheric mood while preserving functional readability. Rather than simple light/dark toggles, the system uses **CSS custom property overrides** to establish semantic color mappings that propagate through Tailwind CSS v4's `@theme` directive. This architecture decouples color values from component logic, allowing instantaneous theme switching without JavaScript-driven style computation or class list mutation. ## Theme Taxonomy Nine themes are available, each named after a video game that informed its color palette: | Theme ID | Display Name | Primary Accent | Atmosphere | |----------|-------------|----------------|------------| | `souls` | Dark Souls | `#cd853f` (warm bronze) | Gothic decay, ash, and bonfire light | | `diablo` | Diablo | `#c0392b` (deep crimson) | Demonic hellfire and blood-red shadows | | `gothic` | Gothic | `#4a6741` (moss green) | Deep forest and obsidian stone | | `cyberpunk` | Cyberpunk 2077 | `#1abc9c` (neon cyan) | Synthwave neon and tech-noir | | `stellar` | Stellar Blade | `#e84393` (electric magenta) | Sci-fi futurism and chrome | | `ghostwire` | Ghostwire Tokyo | `#1dd1a1` (spirit teal) | Supernatural ether and urban mysticism | | `deathspace` | Dead Space | `#8e44ad` (necrotic purple) | Industrial decay and cosmic horror | | `nioh` | Nioh | `#e74c3c` (sanguine red) | Feudal Japan and supernatural corruption | | `pragmata` | Pragmata | `#4a6de5` (cobalt steel) | Lunar station, cold and precise | ## Theme Architecture ### CSS Custom Property Override Each theme is a self-contained CSS file that overrides variables on `:root[data-theme='{id}']`: ```css /* themes/souls.css (excerpt) */ :root[data-theme='souls'] { --color-accent-primary: #e6a23c; --color-accent-secondary: #8b6914; --color-glow: #b8860b; --color-status-success: #7cb342; --color-status-warning: #f0a030; --color-status-error: #e74c3c; --color-status-info: #5dade2; --color-tab-rest: #cd853f; --color-tab-mcp: #c19665; --color-tab-debug: #d4a574; --color-tab-preprocessing: #e6a23c; --color-harmony-1: #f4d03f; --color-harmony-2: #cd853f; --color-harmony-3: #5d6d7e; --color-harmony-4: #5d4e37; --color-bg-primary: #0d0c0a; --color-bg-secondary: #1a1814; --color-bg-tertiary: #252018; --color-fg-primary: #e8dcc8; --color-fg-secondary: #c9b99a; --color-fg-muted: #9a8b75; --color-divider: #3d3228; } ``` ### Global Color Registry The `colors.css` file defines a **semantic color system** accessible via Tailwind v4's `@theme` block: ```css @theme { /* Fonts */ --font-mono: 'JetBrains Mono', 'Fira Code', monospace; --font-sans: 'Inter', system-ui, sans-serif; /* Semantic Tokens */ --color-status-success: #00cc7f; --color-status-warning: #ff9933; --color-status-error: #ff4466; --color-status-info: #00cccc; --color-method-get: #00cc7f; --color-method-post: #00aadd; --color-method-put: #ddaa00; --color-method-delete: #dd4466; --color-method-patch: #aa44dd; --color-bg-primary: #0a0a0f; --color-bg-secondary: #12121a; --color-bg-tertiary: #1a1a2e; --color-fg-primary: #e8e8e8; --color-fg-secondary: #b8b8c8; --color-fg-muted: #9090a0; --color-accent-primary: #ff8c00; --color-accent-secondary: #4a3728; /* Harmony Colors */ --color-harmony-1: #ffd700; --color-harmony-2: #9932cc; --color-harmony-3: #ff8c00; --color-harmony-4: #5f9ea0; /* Backward Compatibility */ --color-primary: var(--color-bg-primary); --color-secondary: var(--color-bg-secondary); --color-brand: var(--color-accent-primary); --color-gold: var(--color-harmony-1); /* Tab Semantic Mapping */ --color-tab-primary: var(--color-harmony-1); --color-tab-secondary: var(--color-harmony-2); --color-tab-tertiary: var(--color-harmony-3); /* Semantic Harmony Roles */ --color-accent-hover: var(--color-harmony-2); --color-accent-active: var(--color-harmony-1); --color-accent-border: var(--color-harmony-3); --color-accent-muted: var(--color-harmony-4); --color-accent-glow: var(--color-harmony-1); } ``` ### Theme Activation The `ThemeStore` applies themes by setting a `data-theme` attribute on `document.documentElement`: ```typescript // stores/theme.ts export const useThemeStore = defineStore('theme', () => { const currentTheme = ref('souls'); function applyTheme(theme: ThemeName) { document.documentElement.setAttribute('data-theme', theme); } watch(currentTheme, (newTheme) => { localStorage.setItem('theme', newTheme); applyTheme(newTheme); }); function initTheme() { const saved = localStorage.getItem('theme') as ThemeName | null; if (saved && validThemes.includes(saved)) currentTheme.value = saved; applyTheme(currentTheme.value); } return { currentTheme, themeColors, darkThemes, darkThemes2, applyTheme, initTheme }; }); ``` Theme state is persisted to `localStorage` and restored on application mount, ensuring consistency across sessions. ## Theme Grouping Themes are visually grouped in the `AppThemeSwitcher` component: - **darkThemes**: `souls`, `diablo`, `gothic`, `cyberpunk`, `stellar`, `pragmata` - **darkThemes2**: `ghostwire`, `deathspace`, `nioh` This grouping controls layout spacing in the theme switcher sidebar and allows future extension (e.g., light theme categories) without UI refactoring. ## Color Harmony System Each theme defines four **harmony accent colors** (`--color-harmony-1` through `--color-harmony-4`) that serve semantic roles across the interface. These roles abstract away raw color values, enabling theme-agnostic component styling: | Semantic Role | CSS Variable | Default Mapping | Usage | |--------------|-------------|-----------------|-------| | Primary Accent | `--color-harmony-1` | `#ffd700` (gold) | Active states, primary buttons, highlights | | Secondary Accent | `--color-harmony-2` | `#9932cc` (purple) | Hover states, secondary highlights | | Border/Divider | `--color-harmony-3` | `#ff8c00` (orange) | Subtle separation elements | | Muted/Disabled | `--color-harmony-4` | `#5f9ea0` (teal) | Disabled controls, secondary text | The **Cyberpunk theme** demonstrates a cool-analogous harmony with complementary accents: ```css /* themes/cyberpunk.css */ :root[data-theme='cyberpunk'] { --color-accent-primary: #1abc9c; /* primary: cyan */ --color-accent-secondary: #16a085; --color-glow: #148f77; --color-harmony-1: #e84393; /* complementary: magenta */ --color-harmony-2: #f1c40f; /* complementary: gold */ --color-harmony-3: #8e44ad; /* analogous: purple */ --color-harmony-4: #3498db; /* analogous: sky blue */ } ``` ### Tab Color Mapping Each theme assigns a distinct color to functional tabs, creating visual differentiation without relying solely on iconography: | Tab | Default Color | Souls Theme | Cyberpunk Theme | |-----|--------------|-------------|-----------------| | **REST** (`tab-rest`) | `#ff8c00` | `#cd853f` (bronze) | `#1abc9c` (cyan) | | **MCP** (`tab-mcp`) | `#ffd700` | `#c19665` (light bronze) | `#1dd1a1` (teal) | | **Debug** (`tab-debug`) | `#00cc7f` | `#d4a574` (tan) | `#20e5b5` (aquamarine) | | **Preprocessing** (`tab-preprocessing`) | `#ff6347` | `#e6a23c` (amber) | `#23f9ca` (mint) | ## AppThemeSwitcher Component The theme switcher is a fixed-position sidebar rendered on the right edge of the viewport. It uses dynamic gradient backgrounds and text-shadow effects to preview each theme: ```html ``` The component uses **CSS viewport-unit positioning** (`fixed right-0 top-1/2`) to remain accessible without consuming main-content layout space. ## Toast Color Integration Theme colors propagate to the Toastification system via CSS overrides: ```css :root[data-theme='souls'] { --toastify-color-dark: #1a1814; --toastify-color-success: #7cb342; --toastify-color-warning: #f0a030; --toastify-color-error: #e74c3c; --toastify-color-info: #5dade2; } ``` This ensures toast notifications harmonize with the active theme rather than falling back to generic light/dark defaults. ## Semantic Status Colors Status colors are mapped per theme to maintain contrast and cultural consistency: | Status | Souls Theme | Cyberpunk Theme | Pragmata Theme | |--------|-------------|-----------------|----------------| | Success | `#7cb342` (moss) | `#2ecc71` (neon green) | `#2a9d8f` (seafoam) | | Warning | `#f0a030` (ember) | `#f1c40f` (electric yellow) | `#e9c46a` (brass) | | Error | `#e74c3c` (blood) | `#e74c3c` (alert red) | `#e07a5f` (rust) | | Info | `#5dade2` (frost) | `#3498db` (ice blue) | `#a8dadc` (moonlight) | ## Method Colors HTTP method badges are color-coded consistently across themes, ensuring API operation visibility: | Method | Default Hex | Tailwind Class | |--------|------------|---------------| | `GET` | `#00cc7f` | `text-method-get` | | `POST` | `#00aadd` | `text-method-post` | | `PUT` | `#ddaa00` | `text-method-put` | | `DELETE` | `#dd4466` | `text-method-delete` | | `PATCH` | `#aa44dd` | `text-method-patch` | | System | `#888899` | `text-method-system` | ## Contrast and Accessibility All foreground text colors (`--color-fg-primary`, `--color-fg-secondary`) are calibrated against their respective background colors to maintain a minimum WCAG 2.1 AA contrast ratio of 4.5:1 for normal text. The theme system is intentionally **dark-mode only** to reduce eye strain during prolonged debugging sessions and to preserve the atmospheric aesthetic. ## Related Documentation - [2. Dashboard Overview](2-dashboard.md) — Dashboard functional panels - [2.1 Frontend Architecture](2.1-architecture.md) — Component hierarchy and composables - [2.3 State Management & Real-time Events](2.3-state-and-realtime.md) — ThemeStore integration with persistence