- 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>
227 lines
6.0 KiB
Markdown
227 lines
6.0 KiB
Markdown
# 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`](./src/theme/tokens.ts):
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
1. **Tokens** → CSS Variables → Tailwind Classes → Components
|
|
2. No hardcoded hex values or color classes allowed anywhere
|
|
3. Theme switching handled automatically via CSS variables
|
|
|
|
## Changing Colors
|
|
|
|
### To rebrand the entire application:
|
|
|
|
1. Edit colors in `src/theme/tokens.ts`
|
|
2. Save the file - Vite HMR will update everything automatically
|
|
3. That's it! 🎉
|
|
|
|
### Example: Change gold to blue:
|
|
|
|
```typescript
|
|
// 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 background
|
|
- `bg-secondary` - Secondary background
|
|
- `bg-tertiary` - Tertiary background
|
|
- `bg-elevated` - Cards, modals
|
|
- `bg-overlay` - Modal overlays
|
|
|
|
### Text Colors
|
|
- `text-primary` - Primary text
|
|
- `text-secondary` - Secondary text
|
|
- `text-muted` - Muted text
|
|
- `text-inverse` - Inverse text (white on dark backgrounds)
|
|
- `text-disabled` - Disabled text
|
|
|
|
### Accent Colors
|
|
- `accent-primary-{50-900}` - Warm gray scale
|
|
- `accent-secondary-{50-900}` - Purple scale
|
|
- `accent-gold-{50-900}` - Gold/brand scale
|
|
- `accent-{color}-text` - Text color for each accent
|
|
|
|
### Semantic Colors
|
|
- `success-{bg|border|text|accent}` - Success states
|
|
- `warning-{bg|border|text|accent}` - Warning states
|
|
- `error-{bg|border|text|accent}` - Error states
|
|
- `info-{bg|border|text|accent}` - Info states
|
|
|
|
### Border Colors
|
|
- `border` - Default border (mapped to `border-default`)
|
|
- `border-muted` - Subtle borders
|
|
- `border-strong` - Emphasized borders
|
|
|
|
### Glass Effects
|
|
- `glass-bg` - Glass background
|
|
- `glass-border` - Glass border
|
|
- `glass-shadow` - Glass shadow
|
|
|
|
## Examples
|
|
|
|
### ✅ Correct Usage (Semantic tokens)
|
|
```tsx
|
|
<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)
|
|
```tsx
|
|
<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:
|
|
```tsx
|
|
<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:
|
|
```tsx
|
|
<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 `.dark` classes
|
|
- No JavaScript required for color changes
|
|
- Blocking script in `index.html` prevents FOUC
|
|
|
|
## Validation & Linting
|
|
|
|
The system includes validation to prevent hardcoded colors from sneaking back in:
|
|
|
|
```bash
|
|
# 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"):
|
|
|
|
1. Add tokens to `src/theme/tokens.ts`:
|
|
```typescript
|
|
export const highContrastTokens: ThemeTokens = {
|
|
background: {
|
|
primary: '#000000',
|
|
// ... high contrast values
|
|
},
|
|
// ...
|
|
};
|
|
```
|
|
|
|
2. Update CSS generation in `src/theme/cssVariables.ts`
|
|
3. Update theme context to support new theme
|
|
|
|
## No-FOUC Implementation
|
|
|
|
The theme is applied via a blocking script in `index.html` before React mounts:
|
|
|
|
```javascript
|
|
// 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. |