Migrated from design-system-swarm with fresh git history.
Old project history preserved in /home/overbits/apps/design-system-swarm
Core components:
- MCP Server (Python FastAPI with mcp 1.23.1)
- Claude Plugin (agents, commands, skills, strategies, hooks, core)
- DSS Backend (dss-mvp1 - token translation, Figma sync)
- Admin UI (Node.js/React)
- Server (Node.js/Express)
- Storybook integration (dss-mvp1/.storybook)
Self-contained configuration:
- All paths relative or use DSS_BASE_PATH=/home/overbits/dss
- PYTHONPATH configured for dss-mvp1 and dss-claude-plugin
- .env file with all configuration
- Claude plugin uses ${CLAUDE_PLUGIN_ROOT} for portability
Migration completed: $(date)
🤖 Clean migration with full functionality preserved
373 lines
7.7 KiB
Markdown
373 lines
7.7 KiB
Markdown
# Design System Customization Guide
|
|
|
|
How to customize the design system for your project while maintaining its integrity.
|
|
|
|
## Customization Hierarchy
|
|
|
|
The design system is organized into customization layers:
|
|
|
|
1. **Token Overrides** (safest): Modify `design-tokens.json` and regenerate CSS
|
|
2. **Theme Customization** (safe): Override colors in `2-theme/`
|
|
3. **Component Extension** (consider carefully): Add new variants in `4-components/`
|
|
4. **Admin Overrides** (last resort): Use `5-admin/` for project-specific changes
|
|
|
|
## Token Customization
|
|
|
|
### Modifying Tokens
|
|
|
|
Edit `design-tokens.json` to change design decisions:
|
|
|
|
```json
|
|
{
|
|
"colors": {
|
|
"primary": {
|
|
"value": "oklch(0.65 0.18 250)",
|
|
"description": "Brand color - MODIFY THIS"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
After editing, regenerate the CSS variable files:
|
|
|
|
```bash
|
|
npm run generate-tokens
|
|
# or manually update src/styles/1-tokens/_colors.css
|
|
```
|
|
|
|
### Adding New Tokens
|
|
|
|
```json
|
|
{
|
|
"colors": {
|
|
"brand-blue": {
|
|
"value": "oklch(0.55 0.20 230)",
|
|
"description": "Custom brand blue",
|
|
"category": "custom"
|
|
}
|
|
},
|
|
"spacing": {
|
|
"custom-large": {
|
|
"value": "3rem",
|
|
"description": "Custom large spacing"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Then add CSS variables:
|
|
|
|
```css
|
|
:root {
|
|
--color-brand-blue: oklch(0.55 0.20 230);
|
|
--space-custom-large: 3rem;
|
|
}
|
|
```
|
|
|
|
## Theme Customization
|
|
|
|
### Creating a Light/Dark Theme
|
|
|
|
Edit `2-theme/_palette.css`:
|
|
|
|
```css
|
|
:root {
|
|
--primary: var(--color-primary);
|
|
--primary-hover: var(--color-primary-hover);
|
|
/* ... map tokens to semantic roles ... */
|
|
}
|
|
```
|
|
|
|
Override colors for light mode:
|
|
|
|
```css
|
|
@media (prefers-color-scheme: light) {
|
|
:root {
|
|
--foreground: oklch(0.15 0.02 280);
|
|
--background: oklch(0.98 0.01 280);
|
|
/* ... */
|
|
}
|
|
}
|
|
```
|
|
|
|
### Brand-Specific Theme
|
|
|
|
Create a new theme file in `2-theme/`:
|
|
|
|
```css
|
|
/* src/styles/2-theme/_brand-acme.css */
|
|
:root[data-brand="acme"] {
|
|
--primary: oklch(0.70 0.15 25); /* Acme red */
|
|
--secondary: oklch(0.65 0.18 45); /* Acme orange */
|
|
--accent: oklch(0.75 0.12 210); /* Acme blue */
|
|
}
|
|
```
|
|
|
|
Import in `index.css`:
|
|
|
|
```css
|
|
@import url('./2-theme/_palette.css');
|
|
@import url('./2-theme/_brand-acme.css');
|
|
@import url('./2-theme/_theme-dark.css');
|
|
```
|
|
|
|
## Component Customization
|
|
|
|
### Creating a New Component Variant
|
|
|
|
Add to the appropriate component file in `4-components/`:
|
|
|
|
```css
|
|
/* In _buttons.css */
|
|
button.btn-outline {
|
|
background: transparent;
|
|
border: 2px solid var(--primary);
|
|
color: var(--primary);
|
|
}
|
|
|
|
button.btn-outline:hover {
|
|
background: var(--primary);
|
|
color: var(--primary-foreground);
|
|
}
|
|
```
|
|
|
|
### Extending Panels
|
|
|
|
```css
|
|
/* In _panels.css */
|
|
.panel--highlighted {
|
|
border-left: 4px solid var(--primary);
|
|
background: var(--primary-light, oklch(0.65 0.18 250 / 0.05));
|
|
}
|
|
|
|
.panel--compact {
|
|
padding: var(--space-2);
|
|
}
|
|
```
|
|
|
|
### Custom Navigation
|
|
|
|
```css
|
|
/* In _navigation.css */
|
|
.nav-item--large {
|
|
padding: var(--space-4) var(--space-3);
|
|
min-height: 48px;
|
|
}
|
|
|
|
.nav-item--small {
|
|
padding: var(--space-1) var(--space-3);
|
|
font-size: var(--text-xs);
|
|
}
|
|
```
|
|
|
|
## Admin-Level Customization
|
|
|
|
### Project-Specific Styles
|
|
|
|
For changes that only apply to your project, use Layer 5:
|
|
|
|
```css
|
|
/* src/styles/5-admin/_custom-ui.css */
|
|
|
|
/* Custom layout for admin pages */
|
|
.admin-layout {
|
|
display: grid;
|
|
grid-template-columns: 200px 1fr;
|
|
gap: var(--space-6);
|
|
}
|
|
|
|
/* Custom admin card styles */
|
|
.admin-card {
|
|
padding: var(--space-6);
|
|
background: var(--card);
|
|
border: 2px solid var(--primary);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
}
|
|
```
|
|
|
|
Import in `index.css`:
|
|
|
|
```css
|
|
@import url('./5-admin/_custom-ui.css');
|
|
```
|
|
|
|
### Responsive Overrides
|
|
|
|
For project-specific responsive changes:
|
|
|
|
```css
|
|
/* src/styles/5-admin/_responsive-custom.css */
|
|
|
|
@media (max-width: 768px) {
|
|
.admin-layout {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.sidebar {
|
|
height: auto;
|
|
flex-direction: row;
|
|
border-right: none;
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
}
|
|
```
|
|
|
|
## Dangerous Customizations (Avoid!)
|
|
|
|
### Don't Override Tokens Locally
|
|
|
|
❌ **Bad**: Hardcoding values
|
|
```css
|
|
button {
|
|
background: #5B21B6; /* ❌ No! Use tokens */
|
|
padding: 12px; /* ❌ No! Use spacing scale */
|
|
}
|
|
```
|
|
|
|
✅ **Good**: Using tokens
|
|
```css
|
|
button {
|
|
background: var(--primary); /* ✓ Use token */
|
|
padding: var(--space-3); /* ✓ Use spacing */
|
|
}
|
|
```
|
|
|
|
### Don't Break the Cascade
|
|
|
|
❌ **Bad**: Adding high-specificity rules
|
|
```css
|
|
div.page-content button.nav-item.active { /* ❌ Too specific */
|
|
color: var(--primary);
|
|
}
|
|
```
|
|
|
|
✅ **Good**: Working with cascade
|
|
```css
|
|
button.nav-item.active { /* ✓ Appropriate specificity */
|
|
color: var(--primary);
|
|
}
|
|
```
|
|
|
|
### Don't Duplicate Components
|
|
|
|
❌ **Bad**: Creating similar but separate components
|
|
```css
|
|
.card { /* ... */ }
|
|
.panel { /* ... */ }
|
|
.container { /* ... */ }
|
|
```
|
|
|
|
✅ **Good**: Extending existing components
|
|
```css
|
|
.card { /* base styles */ }
|
|
.card--highlighted { /* variant */ }
|
|
.card--compact { /* variant */ }
|
|
```
|
|
|
|
## Migration Path
|
|
|
|
When updating the design system:
|
|
|
|
1. **Update tokens**: Change `design-tokens.json`
|
|
2. **Regenerate CSS**: Run token generation script
|
|
3. **Test components**: Check all component variants
|
|
4. **Iterate themes**: Update color overrides
|
|
5. **Test responsive**: Verify mobile/tablet views
|
|
6. **Update docs**: Document any new tokens or patterns
|
|
|
|
## Accessibility Considerations
|
|
|
|
When customizing:
|
|
|
|
- **Color Contrast**: Test contrast ratios for text/background
|
|
- **Focus States**: Ensure focus indicators are visible
|
|
- **Motion**: Respect `prefers-reduced-motion`
|
|
- **Sizing**: Use spacing scale for consistent padding/margin
|
|
- **Typography**: Maintain readable font sizes and line heights
|
|
|
|
### WCAG Compliance
|
|
|
|
Test customizations against WCAG 2.1 AA:
|
|
|
|
```css
|
|
/* Good: High contrast */
|
|
.dark-text {
|
|
color: oklch(0.20 0.02 280); /* ✓ WCAG AAA on light bg */
|
|
background: oklch(0.98 0.01 280);
|
|
}
|
|
|
|
/* Bad: Low contrast */
|
|
.muted-text {
|
|
color: oklch(0.85 0.01 280); /* ❌ Fails WCAG on light bg */
|
|
background: oklch(0.98 0.01 280);
|
|
}
|
|
```
|
|
|
|
## Performance Considerations
|
|
|
|
### CSS File Size
|
|
|
|
- Keep Layer 5 minimal (only project-specific styles)
|
|
- Reuse utility classes instead of creating new ones
|
|
- Import only needed theme variations
|
|
|
|
### CSS Specificity
|
|
|
|
- Avoid `!important` (breaks cascade)
|
|
- Use lowest specificity possible
|
|
- Let the cascade work for you
|
|
|
|
## Exporting Customizations
|
|
|
|
To share customizations with other projects:
|
|
|
|
1. **Extract tokens**: Export `design-tokens.json` with your changes
|
|
2. **Export theme**: Create exportable theme file in `2-theme/`
|
|
3. **Document changes**: Update TOKEN-REFERENCE.md
|
|
4. **Version**: Tag the release (e.g., v1.0.0)
|
|
|
|
### Sharing Format
|
|
|
|
```
|
|
my-design-system/
|
|
├── design-tokens.json
|
|
├── src/styles/
|
|
│ ├── 1-tokens/
|
|
│ ├── 2-theme/
|
|
│ │ └── _custom-brand.css
|
|
│ └── index.css
|
|
├── TOKEN-REFERENCE.md
|
|
└── CUSTOMIZATION-GUIDE.md
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Colors Look Wrong
|
|
|
|
1. Check browser supports OKLCH (modern browsers do)
|
|
2. Verify `2-theme/_palette.css` mappings
|
|
3. Check dark mode detection (prefers-color-scheme)
|
|
4. Compare against design-tokens.json values
|
|
|
|
### Spacing Is Inconsistent
|
|
|
|
1. Verify all custom styles use token variables
|
|
2. Check Layer 5 for hardcoded values
|
|
3. Ensure no margins/padding in Layer 4 conflict
|
|
4. Use spacing scale consistently
|
|
|
|
### Components Not Styled
|
|
|
|
1. Verify CSS link in HTML: `<link rel="stylesheet" href="/src/styles/index.css">`
|
|
2. Check browser network tab (file loading?)
|
|
3. Verify HTML class names match CSS selectors
|
|
4. Check browser dev tools for CSS overrides
|
|
|
|
### Focus Indicators Not Visible
|
|
|
|
1. Ensure `--ring` token is defined
|
|
2. Check focus styles in Layer 4 components
|
|
3. Verify outline isn't removed elsewhere
|
|
4. Test with keyboard navigation (Tab)
|