| name | build-design-system |
| description | Build a design system from scratch using the Design Graph methodology. Use when starting a component library, creating design tokens, establishing typography scales, or structuring a theme. Based on Brent Jackson's (jxnblk) constraint-based systems. |
Build a Design System
Based on the Design Graph methodology by Brent Jackson and mathematical typography principles.
When This Activates
- "Create a design system"
- "Set up design tokens"
- "Build a component library"
- "Create a theme"
- "Establish a type scale"
- "Structure my styles"
The Design Graph
A constraint-based system with 4 interconnected nodes:
SCALES ──────► COMPONENTS
│ │
│ │
▼ ▼
THEMES ◄────── VARIANTS
1. Scales
Raw design values mapped to specific properties.
const scales = {
colors: {
primary: '#0066cc',
secondary: '#666',
background: '#fff',
text: '#1a1a1a',
muted: '#f5f5f5',
},
// Powers of 2 spacing (base 4 or 8)
space: [0, 4, 8, 16, 32, 64, 128],
// Mathematical type scale (1.25 ratio)
fontSizes: [12, 14, 16, 20, 24, 32, 48],
// Limited font weights
fontWeights: {
normal: 400,
medium: 500,
bold: 700,
},
// Consistent radii
radii: [0, 2, 4, 8, 16, 9999],
}
Rules:
- Use powers of 2 for spacing: 4, 8, 16, 32, 64
- Limit to 6-7 values per scale (matches heading levels)
- Name semantically where possible (primary, muted)
2. Components
UI elements constrained by scales.
const Button = {
// Base styles (always applied)
padding: scales.space[2], // 8px
fontSize: scales.fontSizes[2], // 16px
fontWeight: scales.fontWeights.medium,
borderRadius: scales.radii[2], // 4px
// Only use values from scales - never magic numbers
}
Rules:
- Components ONLY reference scale values
- No magic numbers (no
padding: 13px) - Base styles define the default state
3. Variants
Partial styles for contextual changes.
const variants = {
buttons: {
primary: {
bg: 'primary',
color: 'white',
},
secondary: {
bg: 'transparent',
color: 'primary',
border: '1px solid',
borderColor: 'primary',
},
ghost: {
bg: 'transparent',
color: 'text',
},
},
text: {
heading: {
fontWeight: 'bold',
lineHeight: 1.25,
},
body: {
fontWeight: 'normal',
lineHeight: 1.5,
},
caption: {
fontSize: 0, // scales.fontSizes[0]
color: 'muted',
},
},
}
Rules:
- Variants are additive (applied on top of base)
- Name by purpose, not appearance (primary, not blue)
- Keep variants minimal (3-5 per component)
4. Themes
Collections of scales that define visual language.
const lightTheme = {
colors: {
text: '#1a1a1a',
background: '#ffffff',
primary: '#0066cc',
muted: '#f5f5f5',
},
}
const darkTheme = {
colors: {
text: '#f5f5f5',
background: '#1a1a1a',
primary: '#66b3ff',
muted: '#333333',
},
}
Rules:
- Themes swap scales, not components
- Same keys, different values
- Components automatically adapt
Mathematical Typography
Use powers of 2 for a mathematically coherent system:
BASE: 16px (2⁴) = 1rem
TYPE SCALE (1.25 ratio):
- xs: 12px (0.75rem)
- sm: 14px (0.875rem)
- base: 16px (1rem)
- lg: 20px (1.25rem)
- xl: 24px (1.5rem)
- 2xl: 32px (2rem)
- 3xl: 48px (3rem)
SPACING (powers of 2):
- 4px (0.25rem)
- 8px (0.5rem)
- 16px (1rem)
- 32px (2rem)
- 64px (4rem)
LINE HEIGHT:
- Headings: 1.25
- Body: 1.5
- Tight: 1.125
Why powers of 2:
- Digital displays are binary
- Common screen sizes divisible by 16
- Halving/doubling always yields integers
- Creates subtle mathematical relationships
Output Format
When building a design system, output:
DESIGN SYSTEM SPEC
SCALES:
colors: [list with hex values]
space: [array in px]
fontSizes: [array in px]
fontWeights: [object]
radii: [array in px]
COMPONENTS:
[ComponentName]:
base: [styles referencing scales]
variants: [list]
THEMES:
light: [scale overrides]
dark: [scale overrides]
IMPLEMENTATION:
[Code for theme provider, tokens, or CSS variables]
Quick Start Template
// theme.ts
export const theme = {
colors: {
text: '#1a1a1a',
background: '#ffffff',
primary: '#0066cc',
secondary: '#666666',
muted: '#f5f5f5',
border: '#e5e5e5',
},
space: [0, 4, 8, 16, 32, 64],
fontSizes: [12, 14, 16, 20, 24, 32],
fontWeights: { normal: 400, medium: 500, bold: 700 },
lineHeights: { tight: 1.25, normal: 1.5 },
radii: [0, 4, 8, 16, 9999],
}
Anti-Patterns
| Bad | Good |
|---|---|
padding: 13px |
padding: space[3] (16px) |
| 20+ font sizes | 6-7 font sizes max |
Colors by name (blue) |
Colors by purpose (primary) |
| Styles in components | Styles from theme |
| Per-component theming | Global theme swap |
References
- Design Graph - Brent Jackson
- Mathematical Web Typography - Brent Jackson
- Two Steps Forward - CSS methodology evolution