Theming & Branding
Customize the panel appearance to match your application's design.
Build with AI
Generate theme from my brand
Tip: Use⌘.to enable Plan mode in Cursor for best results
# Generate Pillar Theme from My Brand
Analyze my app's design system and generate a matching Pillar theme configuration.
## What Theme Config Does
Pillar's theme config lets you:
- Match your brand colors for buttons, links, and accents
- Configure light and dark mode colors separately
- Sync with your app's theme mode (auto, light, dark)
## Your Task
### 1. Find My Design Tokens
Look for color definitions in:
- `tailwind.config.js` or `tailwind.config.ts` (theme.extend.colors)
- `globals.css` or `variables.css` (CSS custom properties)
- Theme provider config (next-themes, styled-components, etc.)
- Component library theme (Chakra, MUI, etc.)
### 2. Identify Key Colors
- **Primary**: Main brand color (buttons, links, accents)
- **Background**: Main page background
- **Background Secondary**: Cards, inputs, secondary surfaces
- **Text**: Primary text color
- **Text Muted**: Secondary/helper text
- **Border**: Border colors
### 3. Generate Theme Config
```tsx
config={{
theme: {
mode: 'auto', // or sync with my app's theme
colors: {
primary: '#....', // My primary brand color
primaryHover: '#....', // Slightly darker/lighter
background: '#....', // Light mode background
backgroundSecondary: '#....',
text: '#....',
textMuted: '#....',
border: '#....',
borderLight: '#....',
},
darkColors: {
primary: '#....', // Adjusted for dark mode
primaryHover: '#....',
background: '#....', // Dark mode background
backgroundSecondary: '#....',
text: '#....',
textMuted: '#....',
border: '#....',
borderLight: '#....',
},
},
}}
```
### 4. Create ThemeSync Component (if needed)
If my app has a theme toggle, sync it with Pillar:
```tsx
function ThemeSync() {
const { setTheme } = usePillar();
const { theme } = useTheme(); // My app's theme hook
useEffect(() => {
setTheme({ mode: theme === 'dark' ? 'dark' : 'light' });
}, [theme, setTheme]);
return null;
}
```
## Requirements
- Ensure WCAG AA contrast ratios (4.5:1 for text)
- Primary color should work on both light and dark backgrounds
- Test hover states for sufficient contrast
## Start Here
1. Look at my tailwind.config or CSS variables
2. Find my theme provider setup
3. Extract primary, background, and text colors
4. Generate both light and dark mode configs
Basic Setup
examples/guides/theme/basic-setup.tsx
<PillarProviderproductKey="..."publicKey="..."config={{theme: {mode: 'auto',colors: {primary: '#2563eb',},},}}>
Color Mode
| Value | Description |
|---|---|
'auto' | Follow system preference (default) |
'light' | Always light mode |
'dark' | Always dark mode |
Auto Mode
examples/guides/theme/auto-mode.tsx
theme: {mode: 'auto', // Respects prefers-color-scheme}
Fixed Mode
examples/guides/theme/fixed-mode.tsx
theme: {mode: 'dark', // Always dark}
Color Customization
Available Colors
examples/guides/theme/available-colors.tsx
theme: {colors: {primary: '#2563eb', // Brand color (buttons, links)primaryHover: '#1d4ed8', // Hover statebackground: '#ffffff', // Main backgroundbackgroundSecondary: '#f9fafb', // Cards, inputstext: '#111827', // Primary texttextMuted: '#6b7280', // Secondary textborder: '#e5e7eb', // BordersborderLight: '#f3f4f6', // Subtle borders},darkColors: {primary: '#3b82f6',primaryHover: '#60a5fa',background: '#111827',backgroundSecondary: '#1f2937',text: '#f9fafb',textMuted: '#9ca3af',border: '#374151',borderLight: '#1f2937',},}
Minimal Customization
Just set your brand color:
examples/guides/theme/minimal-customization.tsx
theme: {colors: { primary: '#8b5cf6' },darkColors: { primary: '#a78bfa' },}
Runtime Updates
Change the theme at runtime:
examples/guides/theme/runtime-updates.tsx
const { setTheme } = usePillar();// Toggle modesetTheme({ mode: isDarkMode ? 'dark' : 'light' });// Update colorssetTheme({ colors: { primary: '#10b981' } });
Sync with Your App
examples/guides/theme/sync-with-app.tsx
function ThemeSync() {const { setTheme } = usePillar();const { theme } = useTheme(); // Your app's theme hookuseEffect(() => {setTheme({ mode: theme === 'dark' ? 'dark' : 'light' });}, [theme, setTheme]);return null;}
Custom CSS
Inject custom CSS for advanced styling:
examples/guides/theme/custom-css.tsx
config={{customCSS: `.pillar-header {padding: 20px;border-bottom: 2px solid var(--pillar-primary);}.pillar-message-user {border-radius: 16px;}.pillar-button {font-weight: 600;}`,}}
Available CSS Classes
| Class | Element |
|---|---|
.pillar-panel | Main panel container |
.pillar-header | Panel header |
.pillar-content | Content area |
.pillar-footer | Panel footer |
.pillar-message-user | User message bubble |
.pillar-message-assistant | AI message bubble |
.pillar-input | Chat input |
.pillar-button | Buttons |
.pillar-card | Card components |
CSS Variables
examples/guides/theme/css-variables.css
.pillar-panel {--pillar-primary: #2563eb;--pillar-primary-hover: #1d4ed8;--pillar-bg: #ffffff;--pillar-bg-secondary: #f9fafb;--pillar-text: #111827;--pillar-text-muted: #6b7280;--pillar-border: #e5e7eb;}
Best Practices
Maintain Contrast
Ensure text is readable:
examples/guides/theme/maintain-contrast.tsx
// ❌ Low contrastcolors: {text: '#aaaaaa',background: '#ffffff',}// ✅ Good contrastcolors: {text: '#374151',background: '#ffffff',}
Test Both Modes
If using mode: 'auto', test in both light and dark:
examples/guides/theme/test-both-modes.tsx
// For testingsetTheme({ mode: 'light' });// Verify...setTheme({ mode: 'dark' });// Verify...setTheme({ mode: 'auto' }); // Reset