🎨 AiQlick Theme System Guide
Overview
The AiQlick frontend uses a semantic design system where components automatically receive the correct styling based on their purpose (semantic ID), and all colors adapt to the user's selected theme.
📋 Architecture
1. Theme Configuration (config/themes.ts)
21 Pre-built Color Themes available:
- Metallic Chic (default)
- Ocean Blue, Sky Blue
- Forest Green, Mint Green, Sage Green
- Royal Purple, Lavender
- Ruby Red, Rose Pink, Coral
- Sunset Orange, Golden Yellow, Amber
- Slate Gray, Charcoal
- And more...
Each theme defines 6 semantic colors:
{
primary: string // Main actions, focus states
secondary: string // Hover states, accents
tertiary: string // Muted elements, icons
light: string // Borders, dividers
background: string // Backgrounds, disabled states
textDark: string // Text content
}
2. Design Tokens (lib/theme/designTokens.ts)
Central configuration for all component styles with automatic semantic mapping:
Button Styles
- positive-primary: Filled buttons with theme primary color
- positive-stroke: Outlined buttons with theme borders
- positive-text: Ghost/text-only buttons
- negative-primary: Destructive actions (always red)
Semantic ID Mapping:
{
save: "positive-primary", // Blue filled button
cancel: "positive-stroke", // Gray outlined button
delete: "negative-primary", // Red filled button
// ... 30+ mapped IDs
}
Input Styles
- standard: Default inputs with theme borders
- search: Search inputs with emphasized focus
Semantic ID Mapping:
{
email: "standard",
password: "standard",
search: "search",
// ... 15+ mapped IDs
}
Link Styles
- primary: Action links (theme primary → secondary on hover)
- navigation: Menu links (text-dark → primary on hover)
- inline: Content links (always underlined)
- subtle: Footer links (low emphasis)
Semantic ID Mapping:
{
view_details: "primary",
nav_home: "navigation",
article_link: "inline",
footer_link: "subtle",
// ... 10+ mapped IDs
}
3. Shared Styles (components/ux/TWSharedStyles.tsx)
STYLE_VARIABLES object with theme-aware Tailwind classes:
colors: {
borderDefault: "border-[var(--light)]", // Theme light
borderFocus: "focus-within:border-[var(--primary)]", // Theme primary
textDefault: "text-[var(--text-dark)]", // Theme text
textSelected: "text-[var(--primary)]", // Theme primary
// ... all colors use CSS variables
}
🎯 Component Status
✅ Fully Theme-Integrated Components
| Component | Uses Theme | Semantic IDs | Notes |
|---|---|---|---|
| TWButton | ✅ Yes | Yes (30+ IDs) | Primary, outline, ghost variants |
| TWSelect | ✅ Yes | Auto | Borders and selected items use theme |
| TWInput | ✅ Yes | Yes (15+ IDs) | Floating label inputs |
| TWTextarea | ✅ Yes | Auto | Inherits from shared styles |
| TWBadge | ✅ Yes | Yes (10+ IDs) | Job status, partner status |
⚠️ Partially Theme-Integrated Components
| Component | Status | What Needs Update |
|---|---|---|
| TWDatepicker | Partial | Hardcoded blue-500, gray-100 colors |
| TWTabs | Unknown | Need to review |
| TWPasswordConfirm | Unknown | Need to review |
| TWSelectAutocomplete | Partial | Uses STYLE_VARIABLES (theme-aware) |
📦 Other Components (Non-Form)
These may or may not need theme integration:
- DeleteConfirmationDialog
- KanbanBoard, KanbanCard
- PipelineCard, ResponsiveScaleCard
- PageLayout, FormCard
🚀 How to Use the Theme System
For Developers
1. Using Buttons
// ✅ Good - Automatic styling via semantic ID
<TWButton id="save" label="Save Changes" />
<TWButton id="cancel" label="Cancel" />
<TWButton id="delete" label="Delete Item" />
// ❌ Avoid - Manual color specification
<TWButton color="brand" variant="primary" label="Save" />
2. Using Inputs
// ✅ Good - Border colors adapt to theme
<TWInput
id="email"
label="Email Address"
type="email"
/>
// Theme handles:
// - Default border: var(--light)
// - Focus border: var(--primary)
// - All state colors
3. Using Links
// ✅ Good - Semantic styling
<a id="view_details" href="/details">View Details</a>
<a id="nav_home" href="/">Home</a>
// Colors adapt automatically to theme
4. Using Selects
// ✅ Automatically theme-aware
<TWSelect
id="country"
label="Country"
options={countries}
/>
// Borders and selections use theme colors
For Theme Developers
Adding a New Theme
- Add to
config/themes.ts:
export const THEMES: Record<string, Theme> = {
// ... existing themes
"my-custom-theme": {
id: "my-custom-theme",
name: "My Custom Theme",
description: "My brand colors",
colors: {
primary: "#FF6B6B",
secondary: "#4ECDC4",
tertiary: "#95E1D3",
light: "#F7F7F7",
background: "#FAFAFA",
textDark: "#2C3E50",
},
},
}
- All components update automatically!
Adding New Semantic IDs
In lib/theme/designTokens.ts:
export const BUTTON_ID_MAP: Record<string, ButtonStyleKey> = {
// ... existing mappings
"my_action": "positive-primary", // Your new button type
}
export const INPUT_ID_MAP: Record<string, InputStyleKey> = {
// ... existing mappings
"my_field": "standard", // Your new input type
}
🎨 CSS Variables Reference
All theme colors are exposed as CSS variables:
--primary /* #3D52A0 in default theme */
--secondary /* #7091E6 */
--tertiary /* #8697C4 */
--light /* #ADBBDA */
--background /* #EDE8F5 */
--text-dark /* #2C3E50 */
Usage in custom components:
<div style={{
borderColor: "var(--light)",
color: "var(--text-dark)"
}}>
Content
</div>
// Or with Tailwind arbitrary values
<div className="border-[var(--primary)] text-[var(--text-dark)]">
Content
</div>
📍 Interactive Demo
Visit the Color Schema Devtools to see all components in action:
URL: http://localhost:4000/devtools/colors
Features:
- Switch between 21 themes in real-time
- Interactive button examples (20+ buttons)
- Form elements (inputs, selects)
- Link styles (4 variants)
- Color palette viewer
- Usage guide for AI agents
🔧 Next Steps (TODO)
High Priority
- Update TWDatepicker - Replace hardcoded colors with theme variables
- Review TWTabs - Ensure theme integration
- Review TWPasswordConfirm - Ensure theme integration
Medium Priority
- Create theme selector component - Allow users to switch themes
- Add theme persistence - Save user preference to localStorage/database
- Create theme preview - Show theme before applying
Low Priority
- Dark mode support - Add dark variants for each theme
- Accessibility audit - Ensure sufficient contrast ratios
- Animation preferences - Respect prefers-reduced-motion
📚 Resources
- Design System Docs:
/CLAUDE.md - Component Library:
/components/ux/ - Theme Config:
/config/themes.ts - Design Tokens:
/lib/theme/designTokens.ts - Shared Styles:
/components/ux/TWSharedStyles.tsx - Interactive Demo:
/app/(shared)/devtools/colors/page.tsx
🤝 Contributing
When creating new components:
- Use semantic IDs instead of color props
- Use CSS variables (
var(--primary)) for colors - Reference STYLE_VARIABLES for consistent styling
- Add semantic ID mappings to design tokens
- Test with multiple themes in devtools
Example:
// ✅ Good
<button
id="save"
className="bg-[var(--primary)] text-white hover:bg-[var(--secondary)]"
>
Save
</button>
// ❌ Avoid
<button className="bg-blue-500 text-white hover:bg-blue-600">
Save
</button>
Last Updated: October 15, 2025