- Add comprehensive analytics components with export functionality - Implement territory management with manager performance tracking - Add seatmap components for venue layout management - Create customer management features with modal interface - Add advanced hooks for dashboard flags and territory data - Implement seat selection and venue management utilities - Add type definitions for ticketing and seatmap systems 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
6.0 KiB
Theming System Guide
Overview
This application uses a unified theming system where all colors are defined in ONE place and consumed everywhere else through semantic CSS variables and Tailwind utilities.
Single Source of Truth
All colors are defined in src/theme/tokens.ts:
// Change brand colors here and see them propagate throughout the app
export const baseColors = {
gold: {
500: '#d99e34', // Primary brand color
// ... full scale
},
warmGray: { /* ... */ },
purple: { /* ... */ },
};
export const lightTokens = {
background: {
primary: baseColors.pure.white,
secondary: '#f8fafc',
// ... semantic names only
},
// ...
};
How It Works
- Tokens → CSS Variables → Tailwind Classes → Components
- No hardcoded hex values or color classes allowed anywhere
- Theme switching handled automatically via CSS variables
Changing Colors
To rebrand the entire application:
- Edit colors in
src/theme/tokens.ts - Save the file - Vite HMR will update everything automatically
- That's it! 🎉
Example: Change gold to blue:
// src/theme/tokens.ts
export const baseColors = {
gold: {
50: '#eff6ff', // was: '#fefcf0'
100: '#dbeafe', // was: '#fdf7dc'
// ... continue with blue scale
500: '#3b82f6', // was: '#d99e34' - Primary brand color
// ... rest of blue scale
},
};
Available Token Classes
Background Colors
bg-primary- Main backgroundbg-secondary- Secondary backgroundbg-tertiary- Tertiary backgroundbg-elevated- Cards, modalsbg-overlay- Modal overlays
Text Colors
text-primary- Primary texttext-secondary- Secondary texttext-muted- Muted texttext-inverse- Inverse text (white on dark backgrounds)text-disabled- Disabled text
Accent Colors
accent-primary-{50-900}- Warm gray scaleaccent-secondary-{50-900}- Purple scaleaccent-gold-{50-900}- Gold/brand scaleaccent-{color}-text- Text color for each accent
Semantic Colors
success-{bg|border|text|accent}- Success stateswarning-{bg|border|text|accent}- Warning stateserror-{bg|border|text|accent}- Error statesinfo-{bg|border|text|accent}- Info states
Border Colors
border- Default border (mapped toborder-default)border-muted- Subtle bordersborder-strong- Emphasized borders
Glass Effects
glass-bg- Glass backgroundglass-border- Glass borderglass-shadow- Glass shadow
Examples
✅ Correct Usage (Semantic tokens)
<div className="bg-primary text-text-primary border border-border">
<button className="bg-accent-gold text-text-inverse hover:opacity-90">
Click me
</button>
</div>
❌ Wrong Usage (Hardcoded colors)
<div className="bg-white text-slate-900 border border-slate-200">
<button className="bg-yellow-500 text-white hover:bg-yellow-600">
Click me
</button>
</div>
Component Patterns
Button with token-based styling:
<button className="bg-accent-gold text-text-inverse hover:bg-accent-gold-600
border border-accent-gold-500 rounded-lg px-4 py-2">
Primary Action
</button>
Card with glass effect:
<div className="bg-glass-bg border border-glass-border backdrop-blur-lg
rounded-xl p-6 shadow-glass">
<h3 className="text-text-primary">Card Title</h3>
<p className="text-text-secondary">Card content</p>
</div>
Theme Switching
The system automatically handles light/dark theme switching:
- Uses CSS variables that change based on
[data-theme="dark"]or.darkclasses - No JavaScript required for color changes
- Blocking script in
index.htmlprevents FOUC
Validation & Linting
The system includes validation to prevent hardcoded colors from sneaking back in:
# Check for hardcoded colors
npm run validate:theme
# Lint will catch violations too
npm run lint
Adding New Themes
To add a third theme (e.g., "high-contrast"):
- Add tokens to
src/theme/tokens.ts:
export const highContrastTokens: ThemeTokens = {
background: {
primary: '#000000',
// ... high contrast values
},
// ...
};
- Update CSS generation in
src/theme/cssVariables.ts - Update theme context to support new theme
No-FOUC Implementation
The theme is applied via a blocking script in index.html before React mounts:
// Sets theme class before any content renders
document.documentElement.setAttribute('data-theme', theme);
Contrast & Accessibility
All color combinations are validated for WCAG AA compliance using src/utils/contrast.ts. The utility now reads CSS variables directly, so contrast ratios are always accurate for the current theme.
Migration from Hardcoded Colors
Common replacements when migrating existing components:
| Old (hardcoded) | New (semantic) |
|---|---|
text-slate-900 |
text-text-primary |
text-slate-600 |
text-text-secondary |
text-slate-400 |
text-text-muted |
bg-white |
bg-bg-primary |
bg-slate-100 |
bg-bg-secondary |
border-slate-200 |
border-border |
text-white |
text-text-inverse |
Benefits
✅ Single source of truth - Change colors in one file ✅ Type safety - TypeScript ensures valid tokens ✅ No FOUC - Theme applies before React renders ✅ Automatic contrast - WCAG compliance built-in ✅ Lint protection - Prevents hardcoded colors ✅ Easy rebrand - Update tokens, everything changes ✅ Theme switching - Seamless light/dark modes
Architecture
src/theme/tokens.ts // Single source of truth
↓
src/theme/cssVariables.ts // Generate CSS variables
↓
src/styles/tokens.css // CSS variables output
↓
tailwind.config.js // Map to Tailwind classes
↓
Components // Use semantic classes
This architecture ensures that changing colors in tokens.ts propagates through the entire application automatically.