--- alwaysApply: true description: CSS Variables theme system best practices --- # CSS Variables Theme System ## Core Principle: Pure CSS Variables for Theming This project uses **CSS Variables exclusively** for theming. No Tailwind `dark:` classes or conditional CSS classes. ## ✅ Architecture Pattern ### CSS Structure ```css :root { /* Light theme (default values) */ --background: #f1f5f9; --foreground: #0f172a; --primary: #0891b2; --success: #059669; --destructive: #dc2626; --accent: #d97706; --purple: #8b5cf6; --yellow: #eab308; --green: #059669; --blue: #2563eb; --gray: #6b7280; --gray-light: #e5e7eb; } .dark { /* Dark theme (override values) */ --background: #1e293b; --foreground: #f1f5f9; --primary: #06b6d4; --success: #10b981; --destructive: #ef4444; --accent: #f59e0b; --purple: #8b5cf6; --yellow: #eab308; --green: #10b981; --blue: #3b82f6; --gray: #9ca3af; --gray-light: #374151; } ``` ### Theme Application - **Single source of truth**: [ThemeContext.tsx](mdc:src/contexts/ThemeContext.tsx) applies theme class to `document.documentElement` - **No duplication**: Theme is applied only once, not in multiple places - **SSR safe**: Initial theme from server-side preferences ## ✅ Component Usage Patterns ### Correct: Using CSS Variables ```tsx // ✅ GOOD: CSS Variables in className
// ✅ GOOD: CSS Variables in style prop
// ✅ GOOD: CSS Variables with color-mix for transparency
``` ### ❌ Forbidden: Tailwind Dark Mode Classes ```tsx // ❌ BAD: Tailwind dark: classes
// ❌ BAD: Conditional classes
// ❌ BAD: Hardcoded colors
``` ## ✅ Color System ### Semantic Color Tokens - `--background`: Main background color - `--foreground`: Main text color - `--card`: Card/panel background - `--card-hover`: Card hover state - `--card-column`: Column background (darker than cards) - `--border`: Border color - `--input`: Input field background - `--primary`: Primary brand color - `--primary-foreground`: Text on primary background - `--muted`: Muted text color - `--muted-foreground`: Secondary text color - `--accent`: Accent color (orange/amber) - `--destructive`: Error/danger color (red) - `--success`: Success color (green) - `--purple`: Purple accent - `--yellow`: Yellow accent - `--green`: Green accent - `--blue`: Blue accent - `--gray`: Gray color - `--gray-light`: Light gray background ### Color Mixing Patterns ```css /* Background with transparency */ background-color: color-mix(in srgb, var(--primary) 10%, transparent); /* Border with transparency */ border-color: color-mix(in srgb, var(--primary) 20%, var(--border)); /* Text with opacity */ color: color-mix(in srgb, var(--destructive) 80%, transparent); ``` ## ✅ Theme Context Usage ### ThemeProvider Setup ```tsx // In layout.tsx {children} ``` ### Component Usage ```tsx import { useTheme } from '@/contexts/ThemeContext'; function MyComponent() { const { theme, toggleTheme, setTheme } = useTheme(); return ( ); } ``` ## ✅ Future Extensibility This system is designed to support: - **Custom color themes**: Easy to add new color variables - **User preferences**: Colors can be dynamically changed - **Theme presets**: Multiple predefined themes - **Accessibility**: High contrast modes ## 🚨 Anti-patterns to Avoid 1. **Don't mix approaches**: Never use both CSS variables and Tailwind dark: classes 2. **Don't duplicate theme application**: Theme should be applied only in ThemeContext 3. **Don't hardcode colors**: Always use semantic color tokens 4. **Don't use conditional classes**: Use CSS variables instead 5. **Don't forget transparency**: Use `color-mix()` for semi-transparent colors ## 📁 Key Files - [globals.css](mdc:src/app/globals.css) - CSS Variables definitions - [ThemeContext.tsx](mdc:src/contexts/ThemeContext.tsx) - Theme management - [UserPreferencesContext.tsx](mdc:src/contexts/UserPreferencesContext.tsx) - Preferences sync - [layout.tsx](mdc:src/app/layout.tsx) - Theme provider setup Remember: **CSS Variables are the single source of truth for theming. Keep it pure and consistent.**