Instructions assets/design_system_doc_template.md references/component-architecture.md references/developer-handoff.md references/responsive-calculations.md references/token-generation.md scripts/design_token_generator.py
name: “ui-design-system”
description: UI design system toolkit for Senior UI Designer including design token generation, component documentation, responsive design calculations, and developer handoff tools. Use for creating design systems, maintaining visual consistency, and facilitating design-dev collaboration.
UI Design System
Generate design tokens, create color palettes, calculate typography scales, build component systems, and prepare developer handoff documentation.
Table of Contents
Trigger Terms
Use this skill when you need to:
“generate design tokens”
“create color palette”
“build typography scale”
“calculate spacing system”
“create design system”
“generate CSS variables”
“export SCSS tokens”
“set up component architecture”
“document component library”
“calculate responsive breakpoints”
“prepare developer handoff”
“convert brand color to palette”
“check WCAG contrast”
“build 8pt grid system”
Workflows
Workflow 1: Generate Design Tokens
Situation: You have a brand color and need a complete design token system.
Steps:
Identify brand color and style
Brand primary color (hex format)
Style preference: modern | classic | playful
Generate tokens using script
python scripts/design_token_generator.py "#0066CC" modern json
Review generated categories
Colors: primary, secondary, neutral, semantic, surface
Typography: fontFamily, fontSize, fontWeight, lineHeight
Spacing: 8pt grid-based scale (0-64)
Borders: radius, width
Shadows: none through 2xl
Animation: duration, easing
Breakpoints: xs through 2xl
Export in target format
# CSS custom properties
python scripts/design_token_generator.py "#0066CC" modern css > design-tokens.css
# SCSS variables
python scripts/design_token_generator.py "#0066CC" modern scss > _design-tokens.scss
# JSON for Figma/tooling
python scripts/design_token_generator.py "#0066CC" modern json > design-tokens.json
Validate accessibility
Check color contrast meets WCAG AA (4.5:1 normal, 3:1 large text)
Verify semantic colors have contrast colors defined
Workflow 2: Create Component System
Situation: You need to structure a component library using design tokens.
Steps:
Define component hierarchy
Atoms: Button, Input, Icon, Label, Badge
Molecules: FormField, SearchBar, Card, ListItem
Organisms: Header, Footer, DataTable, Modal
Templates: DashboardLayout, AuthLayout
Map tokens to components
Component Tokens Used Button colors, sizing, borders, shadows, typography Input colors, sizing, borders, spacing Card colors, borders, shadows, spacing Modal colors, shadows, spacing, z-index, animation
Define variant patterns
Size variants:
sm: height 32px, paddingX 12px, fontSize 14px
md: height 40px, paddingX 16px, fontSize 16px
lg: height 48px, paddingX 20px, fontSize 18px
Color variants:
primary: background primary-500, text white
secondary: background neutral-100, text neutral-900
ghost: background transparent, text neutral-700
Document component API
Props interface with types
Variant options
State handling (hover, active, focus, disabled)
Accessibility requirements
Reference: See references/component-architecture.md
Workflow 3: Responsive Design
Situation: You need breakpoints, fluid typography, or responsive spacing.
Steps:
Define breakpoints
Name Width Target xs 0 Small phones sm 480px Large phones md 640px Tablets lg 768px Small laptops xl 1024px Desktops 2xl 1280px Large screens
Calculate fluid typography
Formula: clamp(min, preferred, max)
/* 16px to 24px between 320px and 1200px viewport */
font-size : clamp(1rem, 0 .5rem + 2vw, 1 .5rem );
Pre-calculated scales:
--fluid-h1: clamp(2rem, 1rem + 3 .6vw , 4rem);
--fluid-h2: clamp(1 .75rem , 1rem + 2 .3vw , 3rem);
--fluid-h3: clamp(1 .5rem , 1rem + 1 .4vw , 2 .25rem );
--fluid-body: clamp(1rem, 0 .95rem + 0 .2vw , 1 .125rem );
Set up responsive spacing
Token Mobile Tablet Desktop —space-md 12px 16px 16px —space-lg 16px 24px 32px —space-xl 24px 32px 48px —space-section 48px 80px 120px
Reference: See references/responsive-calculations.md
Workflow 4: Developer Handoff
Situation: You need to hand off design tokens to development team.
Steps:
Export tokens in required formats
# For CSS projects
python scripts/design_token_generator.py "#0066CC" modern css
# For SCSS projects
python scripts/design_token_generator.py "#0066CC" modern scss
# For JavaScript/TypeScript
python scripts/design_token_generator.py "#0066CC" modern json
Prepare framework integration
React + CSS Variables:
import './design-tokens.css' ;
< button className = "btn btn-primary" >Click</ button >
Tailwind Config:
const tokens = require ( './design-tokens.json' );
module . exports = {
theme: {
colors: tokens.colors,
fontFamily: tokens.typography.fontFamily
}
};
styled-components:
import tokens from './design-tokens.json' ;
const Button = styled. button `
background: ${ tokens . colors . primary [ '500' ] };
padding: ${ tokens . spacing [ '2' ] } ${ tokens . spacing [ '4' ] };
` ;
Sync with Figma
Install Tokens Studio plugin
Import design-tokens.json
Tokens sync automatically with Figma styles
Handoff checklist
Reference: See references/developer-handoff.md
design_token_generator.py
Generates complete design token system from brand color.
Argument Values Default Description brand_color Hex color #0066CC Primary brand color style modern, classic, playful modern Design style preset format json, css, scss, summary json Output format
Examples:
# Generate JSON tokens (default)
python scripts/design_token_generator.py "#0066CC"
# Classic style with CSS output
python scripts/design_token_generator.py "#8B4513" classic css
# Playful style summary view
python scripts/design_token_generator.py "#FF6B6B" playful summary
Output Categories:
Category Description Key Values colors Color palettes primary, secondary, neutral, semantic, surface typography Font system fontFamily, fontSize, fontWeight, lineHeight spacing 8pt grid 0-64 scale, semantic (xs-3xl) sizing Component sizes container, button, input, icon borders Border values radius (per style), width shadows Shadow styles none through 2xl, inner animation Motion tokens duration, easing, keyframes breakpoints Responsive xs, sm, md, lg, xl, 2xl z-index Layer system base through notification
Quick Reference Tables
Color Scale Generation
Step Brightness Saturation Use Case 50 95% fixed 30% Subtle backgrounds 100 95% fixed 38% Light backgrounds 200 95% fixed 46% Hover states 300 95% fixed 54% Borders 400 95% fixed 62% Disabled states 500 Original 70% Base/default color 600 Original × 0.8 78% Hover (dark) 700 Original × 0.6 86% Active states 800 Original × 0.4 94% Text 900 Original × 0.2 100% Headings
Typography Scale (1.25x Ratio)
Size Value Calculation xs 10px 16 ÷ 1.25² sm 13px 16 ÷ 1.25¹ base 16px Base lg 20px 16 × 1.25¹ xl 25px 16 × 1.25² 2xl 31px 16 × 1.25³ 3xl 39px 16 × 1.25⁴ 4xl 49px 16 × 1.25⁵ 5xl 61px 16 × 1.25⁶
WCAG Contrast Requirements
Level Normal Text Large Text AA 4.5:1 3:1 AAA 7:1 4.5:1
Large text: ≥18pt regular or ≥14pt bold
Style Presets
Aspect Modern Classic Playful Font Sans Inter Helvetica Poppins Font Mono Fira Code Courier Source Code Pro Radius Default 8px 4px 16px Shadows Layered, subtle Single layer Soft, pronounced
Knowledge Base
Detailed reference guides in references/:
File Content token-generation.mdColor algorithms, HSV space, WCAG contrast, type scales component-architecture.mdAtomic design, naming conventions, props patterns responsive-calculations.mdBreakpoints, fluid typography, grid systems developer-handoff.mdExport formats, framework setup, Figma sync
Validation Checklist
Token Generation
Component System
Accessibility
Developer Handoff
Design System Documentation
System Info
Field
Value
Name
[Design System Name]
Version
[X.Y.Z]
Owner
[Team/Person]
Status
Active / Beta / Deprecated
Last Updated
YYYY-MM-DD
Design Principles
The following principles guide all design decisions in this system:
[Principle 1 Name] - [One sentence description. Example: "Clarity over cleverness - every element should have an obvious purpose."]
[Principle 2 Name] - [One sentence description. Example: "Consistency breeds confidence - similar actions should look and behave the same."]
[Principle 3 Name] - [One sentence description. Example: "Accessible by default - every component must meet WCAG 2.1 AA standards."]
[Principle 4 Name] - [One sentence description. Example: "Progressive disclosure - show only what is needed, reveal complexity on demand."]
Color Palette
Brand Colors
Name
Hex
RGB
Usage
Primary
#[XXXXXX]
rgb(X, X, X)
Primary actions, links, key UI elements
Secondary
#[XXXXXX]
rgb(X, X, X)
Secondary actions, accents
Accent
#[XXXXXX]
rgb(X, X, X)
Highlights, badges, notifications
Neutral Colors
Name
Hex
Usage
Gray-900
#[XXXXXX]
Primary text
Gray-700
#[XXXXXX]
Secondary text
Gray-500
#[XXXXXX]
Placeholder text, disabled states
Gray-300
#[XXXXXX]
Borders, dividers
Gray-100
#[XXXXXX]
Backgrounds, hover states
White
#FFFFFF
Page background, card background
Semantic Colors
Name
Hex
Usage
Success
#[XXXXXX]
Success messages, positive indicators
Warning
#[XXXXXX]
Warning messages, caution indicators
Error
#[XXXXXX]
Error messages, destructive actions
Info
#[XXXXXX]
Informational messages, tips
Accessibility
All text colors must meet WCAG 2.1 AA contrast ratio (4.5:1 for normal text, 3:1 for large text)
Test with color blindness simulators
Never use color as the only indicator of state
Typography Scale
Font Family
Primary: [Font Name] (headings and body)
Monospace: [Font Name] (code blocks, technical content)
Fallback Stack: [System font stack]
Type Scale
Name
Size
Weight
Line Height
Usage
Display
48px / 3rem
Bold (700)
1.2
Hero headings
H1
36px / 2.25rem
Bold (700)
1.25
Page titles
H2
28px / 1.75rem
Semibold (600)
1.3
Section headings
H3
22px / 1.375rem
Semibold (600)
1.35
Subsection headings
H4
18px / 1.125rem
Medium (500)
1.4
Card titles, labels
Body Large
18px / 1.125rem
Regular (400)
1.6
Lead paragraphs
Body
16px / 1rem
Regular (400)
1.5
Default body text
Body Small
14px / 0.875rem
Regular (400)
1.5
Secondary text, captions
Caption
12px / 0.75rem
Regular (400)
1.4
Labels, metadata
Spacing System
Base Unit: 4px
Token
Value
Usage
space-1
4px
Tight spacing (icon padding)
space-2
8px
Compact elements (inline items)
space-3
12px
Related elements (form field gaps)
space-4
16px
Default spacing (paragraph gaps)
space-5
20px
Group spacing (card padding)
space-6
24px
Section spacing
space-8
32px
Large section gaps
space-10
40px
Page section dividers
space-12
48px
Major layout sections
space-16
64px
Page-level spacing
Layout Spacing
Page margin: space-6 (mobile), space-8 (tablet), space-12 (desktop)
Card padding: space-5
Form field gap: space-3
Section gap: space-10
Component Library
Component Status Legend
Stable - Production ready, fully documented and tested
Beta - Functional but may change, use with awareness
Deprecated - Scheduled for removal, migrate to replacement
Planned - On roadmap, not yet available
Components
Component
Status
Description
Variants
Button
Stable
Primary action triggers
Primary, Secondary, Tertiary, Danger, Ghost
Input
Stable
Text input fields
Default, Error, Disabled, With icon
Select
Stable
Dropdown selection
Single, Multi, Searchable
Checkbox
Stable
Multi-select toggle
Default, Indeterminate, Disabled
Radio
Stable
Single-select option
Default, Disabled
Toggle
Stable
Binary on/off switch
Default, With label
Modal
Stable
Overlay dialog
Small, Medium, Large, Fullscreen
Toast
Stable
Temporary notification
Success, Error, Warning, Info
Card
Stable
Content container
Default, Interactive, Elevated
Badge
Stable
Status indicator
Solid, Outline, Dot
Avatar
Stable
User representation
Image, Initials, Icon
Table
Beta
Data display grid
Default, Sortable, Selectable
Tabs
Beta
Content organization
Default, Underline, Pill
Tooltip
Stable
Contextual information
Default, Rich content
[New Component]
Planned
[Description]
[Variants]
Usage Guidelines
Do
Use components as documented (do not override internal styles)
Follow the spacing system for consistent layouts
Test components across supported browsers and screen sizes
Use semantic colors for their intended purpose
Reference design tokens instead of hardcoded values
Do Not
Modify component internals without contributing changes back
Create one-off components when an existing component fits
Use brand colors for semantic purposes (error, success)
Skip accessibility requirements for "internal" tools
Mix design system versions across a single application
Contribution Process
Proposing a New Component
Check existing components - Verify no existing component solves the need
Create proposal - Document use case, behavior, variants, accessibility requirements
Design review - Present to design system team for feedback
Build - Implement component following system patterns
Review - Code review + design review + accessibility audit
Document - Add to component library with usage guidelines
Release - Publish in next minor version
Updating an Existing Component
File issue - Describe the change and justification
Impact assessment - Identify all instances of current usage
Design + develop - Implement change with backward compatibility
Migration guide - Document breaking changes if any
Release - Publish with changelog entry
Reporting Issues
File bug reports with reproduction steps and screenshots
Tag with component name and severity
Include browser/OS information for rendering issues
Component Architecture Guide
Reference for design system component organization, naming conventions, and documentation patterns.
Table of Contents
Component Hierarchy
Atomic Design Structure
┌─────────────────────────────────────────────────────────────┐
│ COMPONENT HIERARCHY │
├─────────────────────────────────────────────────────────────┤
│ │
│ TOKENS (Foundation) │
│ └── Colors, Typography, Spacing, Shadows │
│ │
│ ATOMS (Basic Elements) │
│ └── Button, Input, Icon, Label, Badge │
│ │
│ MOLECULES (Simple Combinations) │
│ └── FormField, SearchBar, Card, ListItem │
│ │
│ ORGANISMS (Complex Components) │
│ └── Header, Footer, DataTable, Modal │
│ │
│ TEMPLATES (Page Layouts) │
│ └── DashboardLayout, AuthLayout, SettingsLayout │
│ │
│ PAGES (Specific Instances) │
│ └── HomePage, LoginPage, UserProfile │
│ │
└─────────────────────────────────────────────────────────────┘ Component Categories
Category
Description
Examples
Primitives
Base HTML wrapper
Box, Text, Flex, Grid
Inputs
User interaction
Button, Input, Select, Checkbox
Display
Content presentation
Card, Badge, Avatar, Icon
Feedback
User feedback
Alert, Toast, Progress, Skeleton
Navigation
Route management
Link, Menu, Tabs, Breadcrumb
Overlay
Layer above content
Modal, Drawer, Popover, Tooltip
Layout
Structure
Stack, Container, Divider
Naming Conventions
Token Naming
{category}-{property}-{variant}-{state}
Examples:
color-primary-500
color-primary-500-hover
spacing-md
fontSize-lg
shadow-md
radius-lg Component Naming
{ComponentName} # PascalCase for components
{componentName}{Variant} # Variant suffix
Examples:
Button
ButtonPrimary
ButtonOutline
ButtonGhost CSS Class Naming (BEM)
.block__element--modifier
Examples:
.button
.button__icon
.button--primary
.button--lg
.button__icon--loading File Structure
components/
├── Button/
│ ├── Button.tsx # Main component
│ ├── Button.styles.ts # Styles/tokens
│ ├── Button.test.tsx # Tests
│ ├── Button.stories.tsx # Storybook
│ ├── Button.types.ts # TypeScript types
│ └── index.ts # Export
├── Input/
│ └── ...
└── index.ts # Barrel export
Component Documentation
Documentation Template
# ComponentName
Brief description of what this component does.
## Usage
\`\`\` tsx
import { Button } from '@design-system/components'
<Button variant="primary" size="md">
Click me
</Button>
\`\`\`
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| variant | 'primary' \| 'secondary' \| 'ghost' | 'primary' | Visual style |
| size | 'sm' \| 'md' \| 'lg' | 'md' | Component size |
| disabled | boolean | false | Disabled state |
| onClick | () => void | - | Click handler |
## Variants
### Primary
Use for main actions.
### Secondary
Use for secondary actions.
### Ghost
Use for tertiary or inline actions.
## Accessibility
- Uses `button` role by default
- Supports `aria-disabled` for disabled state
- Focus ring visible for keyboard navigation
## Design Tokens Used
- `color-primary-*` for primary variant
- `spacing-*` for padding
- `radius-md` for border radius
- `shadow-sm` for elevation Props Interface Pattern
interface ButtonProps {
/** Visual variant of the button */
variant ?: 'primary' | 'secondary' | 'ghost' | 'danger' ;
/** Size of the button */
size ?: 'sm' | 'md' | 'lg' ;
/** Whether button is disabled */
disabled ?: boolean ;
/** Whether button shows loading state */
loading ?: boolean ;
/** Left icon element */
leftIcon ?: React . ReactNode ;
/** Right icon element */
rightIcon ?: React . ReactNode ;
/** Click handler */
onClick ?: () => void ;
/** Button content */
children : React . ReactNode ;
}
Variant Patterns
Size Variants
const sizeTokens = {
sm: {
height: 'sizing-button-sm-height' , // 32px
paddingX: 'sizing-button-sm-paddingX' , // 12px
fontSize: 'fontSize-sm' , // 14px
iconSize: 'sizing-icon-sm' // 16px
},
md: {
height: 'sizing-button-md-height' , // 40px
paddingX: 'sizing-button-md-paddingX' , // 16px
fontSize: 'fontSize-base' , // 16px
iconSize: 'sizing-icon-md' // 20px
},
lg: {
height: 'sizing-button-lg-height' , // 48px
paddingX: 'sizing-button-lg-paddingX' , // 20px
fontSize: 'fontSize-lg' , // 18px
iconSize: 'sizing-icon-lg' // 24px
}
}; Color Variants
const variantTokens = {
primary: {
background: 'color-primary-500' ,
backgroundHover: 'color-primary-600' ,
backgroundActive: 'color-primary-700' ,
text: 'color-white' ,
border: 'transparent'
},
secondary: {
background: 'color-neutral-100' ,
backgroundHover: 'color-neutral-200' ,
backgroundActive: 'color-neutral-300' ,
text: 'color-neutral-900' ,
border: 'transparent'
},
outline: {
background: 'transparent' ,
backgroundHover: 'color-primary-50' ,
backgroundActive: 'color-primary-100' ,
text: 'color-primary-500' ,
border: 'color-primary-500'
},
ghost: {
background: 'transparent' ,
backgroundHover: 'color-neutral-100' ,
backgroundActive: 'color-neutral-200' ,
text: 'color-neutral-700' ,
border: 'transparent'
}
}; State Variants
const stateStyles = {
default: {
cursor: 'pointer' ,
opacity: 1
},
hover: {
// Uses variantTokens backgroundHover
},
active: {
// Uses variantTokens backgroundActive
transform: 'scale(0.98)'
},
focus: {
outline: 'none' ,
boxShadow: '0 0 0 2px color-primary-200'
},
disabled: {
cursor: 'not-allowed' ,
opacity: 0.5 ,
pointerEvents: 'none'
},
loading: {
cursor: 'wait' ,
pointerEvents: 'none'
}
};
Token Integration
Consuming Tokens in Components
CSS Custom Properties:
.button {
height : var ( --sizing-button-md-height );
padding-left : var ( --sizing-button-md-paddingX );
padding-right : var ( --sizing-button-md-paddingX );
font-size : var ( --typography-fontSize-base );
border-radius : var ( --borders-radius-md );
}
.button--primary {
background-color : var ( --colors-primary-500 );
color : var ( --colors-surface-background );
}
.button--primary:hover {
background-color : var ( --colors-primary-600 );
} JavaScript/TypeScript:
import tokens from './design-tokens.json' ;
const buttonStyles = {
height: tokens.sizing.components.button.md.height,
paddingLeft: tokens.sizing.components.button.md.paddingX,
backgroundColor: tokens.colors.primary[ '500' ],
borderRadius: tokens.borders.radius.md
}; Styled Components:
import styled from 'styled-components' ;
const Button = styled. button `
height: ${ ({ theme }) => theme . sizing . components . button . md . height };
padding: 0 ${ ({ theme }) => theme . sizing . components . button . md . paddingX };
background: ${ ({ theme }) => theme . colors . primary [ '500' ] };
border-radius: ${ ({ theme }) => theme . borders . radius . md };
&:hover {
background: ${ ({ theme }) => theme . colors . primary [ '600' ] };
}
` ; Token-to-Component Mapping
Component
Token Categories Used
Button
colors, sizing, borders, shadows, typography
Input
colors, sizing, borders, spacing
Card
colors, borders, shadows, spacing
Typography
typography (all), colors
Icon
sizing, colors
Modal
colors, shadows, spacing, z-index, animation
Component Checklist
Before Release
Accessibility Checklist
See also: token-generation.md for token creation
Developer Handoff Guide
Reference for integrating design tokens into development workflows and design tool collaboration.
Table of Contents
Export Formats
JSON (Recommended for Most Projects)
File: design-tokens.json
{
"meta" : {
"version" : "1.0.0" ,
"style" : "modern" ,
"generated" : "2024-01-15"
},
"colors" : {
"primary" : {
"50" : "#E6F2FF" ,
"100" : "#CCE5FF" ,
"500" : "#0066CC" ,
"900" : "#002855"
}
},
"typography" : {
"fontFamily" : {
"sans" : "Inter, system-ui, sans-serif" ,
"mono" : "Fira Code, monospace"
},
"fontSize" : {
"xs" : "10px" ,
"sm" : "13px" ,
"base" : "16px" ,
"lg" : "20px"
}
},
"spacing" : {
"0" : "0px" ,
"1" : "4px" ,
"2" : "8px" ,
"4" : "16px"
}
} Use Case: JavaScript/TypeScript projects, build tools, Figma plugins
CSS Custom Properties
File: design-tokens.css
:root {
/* Colors */
--color-primary-50 : #E6F2FF ;
--color-primary-100 : #CCE5FF ;
--color-primary-500 : #0066CC ;
--color-primary-900 : #002855 ;
/* Typography */
--font-family-sans : Inter, system-ui , sans-serif ;
--font-family-mono : Fira Code, monospace ;
--font-size-xs : 10 px ;
--font-size-sm : 13 px ;
--font-size-base : 16 px ;
--font-size-lg : 20 px ;
/* Spacing */
--spacing-0 : 0 px ;
--spacing-1 : 4 px ;
--spacing-2 : 8 px ;
--spacing-4 : 16 px ;
} Use Case: Plain CSS, CSS-in-JS, any web project
SCSS Variables
File: _design-tokens.scss
// Colors
$color-primary-50 : #E6F2FF ;
$color-primary-100 : #CCE5FF ;
$color-primary-500 : #0066CC ;
$color-primary-900 : #002855 ;
// Typography
$font-family-sans : Inter, system-ui , sans-serif ;
$font-family-mono : Fira Code, monospace ;
$font-size-xs : 10 px ;
$font-size-sm : 13 px ;
$font-size-base : 16 px ;
$font-size-lg : 20 px ;
// Spacing
$spacing-0 : 0 px ;
$spacing-1 : 4 px ;
$spacing-2 : 8 px ;
$spacing-4 : 16 px ;
// Maps for programmatic access
$colors-primary : (
'50' : $color-primary-50 ,
'100' : $color-primary-100 ,
'500' : $color-primary-500 ,
'900' : $color-primary-900
); Use Case: SASS/SCSS pipelines, component libraries
Integration Patterns
Pattern 1: CSS Variables (Universal)
Works with any framework or vanilla CSS.
/* Import tokens */
@import 'design-tokens.css' ;
/* Use in styles */
.button {
background-color : var ( --color-primary-500 );
padding : var ( --spacing-2 ) var ( --spacing-4 );
font-size : var ( --font-size-base );
border-radius : var ( --radius-md );
}
.button:hover {
background-color : var ( --color-primary-600 );
} Pattern 2: JavaScript Theme Object
For CSS-in-JS libraries (styled-components, Emotion, etc.)
// theme.ts
import tokens from './design-tokens.json' ;
export const theme = {
colors: {
primary: tokens.colors.primary,
secondary: tokens.colors.secondary,
neutral: tokens.colors.neutral,
semantic: tokens.colors.semantic
},
typography: {
fontFamily: tokens.typography.fontFamily,
fontSize: tokens.typography.fontSize,
fontWeight: tokens.typography.fontWeight
},
spacing: tokens.spacing,
shadows: tokens.shadows,
radii: tokens.borders.radius
};
export type Theme = typeof theme; // styled-components usage
import styled from 'styled-components' ;
const Button = styled. button `
background: ${ ({ theme }) => theme . colors . primary [ '500' ] };
padding: ${ ({ theme }) => theme . spacing [ '2' ] } ${ ({ theme }) => theme . spacing [ '4' ] };
font-size: ${ ({ theme }) => theme . typography . fontSize . base };
` ; Pattern 3: Tailwind Config
// tailwind.config.js
const tokens = require ( './design-tokens.json' );
module . exports = {
theme: {
colors: {
primary: tokens.colors.primary,
secondary: tokens.colors.secondary,
neutral: tokens.colors.neutral,
success: tokens.colors.semantic.success,
warning: tokens.colors.semantic.warning,
error: tokens.colors.semantic.error
},
fontFamily: {
sans: [tokens.typography.fontFamily.sans],
serif: [tokens.typography.fontFamily.serif],
mono: [tokens.typography.fontFamily.mono]
},
spacing: {
0 : tokens.spacing[ '0' ],
1 : tokens.spacing[ '1' ],
2 : tokens.spacing[ '2' ],
// ... etc
},
borderRadius: tokens.borders.radius,
boxShadow: tokens.shadows
}
};
Framework Setup
React + CSS Variables
// App.tsx
import './design-tokens.css' ;
import './styles.css' ;
function App () {
return (
< button className = "btn btn-primary" >
Click me
</ button >
);
} /* styles.css */
.btn {
padding : var ( --spacing-2 ) var ( --spacing-4 );
font-size : var ( --font-size-base );
font-weight : var ( --font-weight-medium );
border-radius : var ( --radius-md );
transition : background-color var ( --animation-duration-fast );
}
.btn-primary {
background : var ( --color-primary-500 );
color : var ( --color-surface-background );
}
.btn-primary:hover {
background : var ( --color-primary-600 );
} React + styled-components
// ThemeProvider.tsx
import { ThemeProvider } from 'styled-components' ;
import { theme } from './theme' ;
export function AppThemeProvider ({ children }) {
return (
< ThemeProvider theme = {theme}>
{children}
</ ThemeProvider >
);
} // Button.tsx
import styled from 'styled-components' ;
export const Button = styled. button <{ variant ?: 'primary' | 'secondary' }> `
padding: ${ ({ theme }) => `${ theme . spacing [ '2' ] } ${ theme . spacing [ '4' ] }`};
font-size: ${ ({ theme }) => theme . typography . fontSize . base };
border-radius: ${ ({ theme }) => theme . radii . md };
${ ({ variant = 'primary' , theme }) => variant === 'primary' && `
background: ${ theme . colors . primary [ '500' ] };
color: ${ theme . colors . surface . background };
&:hover {
background: ${ theme . colors . primary [ '600' ] };
}
`}
` ; Vue + CSS Variables
<!-- App.vue -->
< template >
< button class = "btn btn-primary" >Click me</ button >
</ template >
< style >
@import './design-tokens.css' ;
.btn {
padding : var ( --spacing-2 ) var ( --spacing-4 );
font-size : var ( --font-size-base );
border-radius : var ( --radius-md );
}
.btn-primary {
background : var ( --color-primary-500 );
color : var ( --color-surface-background );
}
</ style > Next.js + Tailwind
// tailwind.config.js
const tokens = require ( './design-tokens.json' );
module . exports = {
content: [ './app/**/*.{js,ts,jsx,tsx}' ],
theme: {
extend: {
colors: tokens.colors,
fontFamily: {
sans: tokens.typography.fontFamily.sans. split ( ', ' )
}
}
}
}; // page.tsx
export default function Page () {
return (
< button className = "bg-primary-500 hover:bg-primary-600 px-4 py-2 rounded-md text-white" >
Click me
</ button >
);
}
Design Tool Integration
Figma
Option 1: Tokens Studio Plugin
Install "Tokens Studio for Figma" plugin
Import design-tokens.json
Tokens sync automatically with Figma styles
Option 2: Figma Variables (Native)
Open Variables panel
Create collections matching token structure
Import JSON via plugin or API
Sync Workflow:
design_token_generator.py
↓
design-tokens.json
↓
Tokens Studio Plugin
↓
Figma Styles & Variables Storybook
// .storybook/preview.js
import '../design-tokens.css' ;
export const parameters = {
backgrounds: {
default: 'light' ,
values: [
{ name: 'light' , value: '#FFFFFF' },
{ name: 'dark' , value: '#111827' }
]
}
}; // Button.stories.tsx
import { Button } from './Button' ;
export default {
title: 'Components/Button' ,
component: Button,
argTypes: {
variant: {
control: 'select' ,
options: [ 'primary' , 'secondary' , 'ghost' ]
},
size: {
control: 'select' ,
options: [ 'sm' , 'md' , 'lg' ]
}
}
};
export const Primary = {
args: {
variant: 'primary' ,
children: 'Button'
}
}; Design Tool Comparison
Tool
Token Format
Sync Method
Figma
JSON
Tokens Studio plugin / Variables
Sketch
JSON
Craft / Shared Styles
Adobe XD
JSON
Design Tokens plugin
InVision DSM
JSON
Native import
Zeroheight
JSON/CSS
Direct import
Handoff Checklist
Token Generation
Developer Setup
Design Sync
Validation
Documentation Deliverables
Document
Contents
design-tokens.json
All tokens in JSON
design-tokens.css
CSS custom properties
_design-tokens.scss
SCSS variables
README.md
Usage instructions
CHANGELOG.md
Token version history
Version Control
Token Versioning
{
"meta" : {
"version" : "1.2.0" ,
"style" : "modern" ,
"generated" : "2024-01-15" ,
"changelog" : [
"1.2.0 - Added animation tokens" ,
"1.1.0 - Updated primary color" ,
"1.0.0 - Initial release"
]
}
} Breaking Change Policy
Change Type
Version Bump
Migration
Add new token
Patch (1.0.x)
None
Change token value
Minor (1.x.0)
Optional
Rename/remove token
Major (x.0.0)
Required
See also: token-generation.md for generation options
Responsive Design Calculations
Reference for breakpoint math, fluid typography, and responsive layout patterns.
Table of Contents
Breakpoint System
Standard Breakpoints
┌─────────────────────────────────────────────────────────────┐
│ BREAKPOINT RANGES │
├─────────────────────────────────────────────────────────────┤
│ │
│ xs sm md lg xl 2xl │
│ │─────────│──────────│──────────│──────────│─────────│ │
│ 0 480px 640px 768px 1024px 1280px │
│ 1536px │
│ │
│ Mobile Mobile+ Tablet Laptop Desktop Large │
│ │
└─────────────────────────────────────────────────────────────┘ Breakpoint Values
Name
Min Width
Target Devices
xs
0
Small phones
sm
480px
Large phones
md
640px
Small tablets
lg
768px
Tablets, small laptops
xl
1024px
Laptops, desktops
2xl
1280px
Large desktops
3xl
1536px
Extra large displays
Mobile-First Media Queries
/* Base styles (mobile) */
.component {
padding : var ( --spacing-sm );
font-size : var ( --fontSize-sm );
}
/* Small devices and up */
@media ( min-width : 480 px ) {
.component {
padding : var ( --spacing-md );
}
}
/* Medium devices and up */
@media ( min-width : 768 px ) {
.component {
padding : var ( --spacing-lg );
font-size : var ( --fontSize-base );
}
}
/* Large devices and up */
@media ( min-width : 1024 px ) {
.component {
padding : var ( --spacing-xl );
}
} Breakpoint Utility Function
const breakpoints = {
xs: 480 ,
sm: 640 ,
md: 768 ,
lg: 1024 ,
xl: 1280 ,
'2xl' : 1536
};
function mediaQuery ( breakpoint , type = 'min' ) {
const value = breakpoints[breakpoint];
if (type === 'min' ) {
return `@media (min-width: ${ value }px)` ;
}
return `@media (max-width: ${ value - 1 }px)` ;
}
// Usage
const styles = `
${ mediaQuery ( 'md' ) } {
display: flex;
}
` ;
Fluid Typography
Clamp Formula
font-size : clamp(min, preferred, max);
/* Example: 16px to 24px between 320px and 1200px viewport */
font-size : clamp(1rem, 0 .5rem + 2vw, 1 .5rem ); Fluid Scale Calculation
preferred = min + (max - min) * ((100vw - minVW) / (maxVW - minVW))
Simplified:
preferred = base + (scaling-factor * vw)
Where:
scaling-factor = (max - min) / (maxVW - minVW) * 100 Fluid Typography Scale
Style
Mobile (320px)
Desktop (1200px)
Clamp Value
h1
32px
64px
clamp(2rem, 1rem + 3.6vw, 4rem)
h2
28px
48px
clamp(1.75rem, 1rem + 2.3vw, 3rem)
h3
24px
36px
clamp(1.5rem, 1rem + 1.4vw, 2.25rem)
h4
20px
28px
clamp(1.25rem, 1rem + 0.9vw, 1.75rem)
body
16px
18px
clamp(1rem, 0.95rem + 0.2vw, 1.125rem)
small
14px
14px
0.875rem (fixed)
Implementation
:root {
/* Fluid type scale */
--fluid-h1 : clamp ( 2 rem , 1 rem + 3.6 vw , 4 rem );
--fluid-h2 : clamp ( 1.75 rem , 1 rem + 2.3 vw , 3 rem );
--fluid-h3 : clamp ( 1.5 rem , 1 rem + 1.4 vw , 2.25 rem );
--fluid-body : clamp ( 1 rem , 0.95 rem + 0.2 vw , 1.125 rem );
}
h1 { font-size : var ( --fluid-h1 ); }
h2 { font-size : var ( --fluid-h2 ); }
h3 { font-size : var ( --fluid-h3 ); }
body { font-size : var ( --fluid-body ); }
Responsive Spacing
Fluid Spacing Formula
/* Spacing that scales with viewport */
spacing: clamp(minSpace, preferredSpace, maxSpace);
/* Example: 16px to 48px */
--spacing-responsive: clamp(1rem, 0 .5rem + 2vw, 3rem); Responsive Spacing Scale
Token
Mobile
Tablet
Desktop
--space-xs
4px
4px
4px
--space-sm
8px
8px
8px
--space-md
12px
16px
16px
--space-lg
16px
24px
32px
--space-xl
24px
32px
48px
--space-2xl
32px
48px
64px
--space-section
48px
80px
120px
Implementation
:root {
--space-section : clamp ( 3 rem , 2 rem + 4 vw , 7.5 rem );
--space-component : clamp ( 1 rem , 0.5 rem + 1 vw , 2 rem );
--space-content : clamp ( 1.5 rem , 1 rem + 2 vw , 3 rem );
}
.section {
padding-top : var ( --space-section );
padding-bottom : var ( --space-section );
}
.card {
padding : var ( --space-component );
gap : var ( --space-content );
}
Container Queries
Container Width Tokens
Container
Max Width
Use Case
sm
640px
Narrow content
md
768px
Blog posts
lg
1024px
Standard pages
xl
1280px
Wide layouts
2xl
1536px
Full-width dashboards
Container CSS
.container {
width : 100 % ;
margin-left : auto ;
margin-right : auto ;
padding-left : var ( --spacing-md );
padding-right : var ( --spacing-md );
}
.container--sm { max-width : 640 px ; }
.container--md { max-width : 768 px ; }
.container--lg { max-width : 1024 px ; }
.container--xl { max-width : 1280 px ; }
.container--2xl { max-width : 1536 px ; } CSS Container Queries
/* Define container */
.card-container {
container-type : inline-size;
container-name : card;
}
/* Query container width */
@container card (min-width: 400px) {
.card {
display : flex ;
flex-direction : row ;
}
}
@container card (min-width: 600px) {
.card {
gap : var ( --spacing-lg );
}
}
Grid Systems
12-Column Grid
.grid {
display : grid ;
grid-template-columns : repeat ( 12 , 1 fr );
gap : var ( --spacing-md );
}
/* Column spans */
.col-1 { grid-column : span 1 ; }
.col-2 { grid-column : span 2 ; }
.col-3 { grid-column : span 3 ; }
.col-4 { grid-column : span 4 ; }
.col-6 { grid-column : span 6 ; }
.col-12 { grid-column : span 12 ; }
/* Responsive columns */
@media ( min-width : 768 px ) {
.col-md-4 { grid-column : span 4 ; }
.col-md-6 { grid-column : span 6 ; }
.col-md-8 { grid-column : span 8 ; }
} Auto-Fit Grid
/* Cards that automatically wrap */
.auto-grid {
display : grid ;
grid-template-columns : repeat ( auto-fit , minmax ( 280 px , 1 fr ));
gap : var ( --spacing-lg );
}
/* With explicit min/max columns */
.auto-grid--constrained {
grid-template-columns : repeat (
auto-fit ,
minmax ( min ( 100 % , 280 px ), 1 fr )
);
} Common Layout Patterns
Sidebar + Content:
.layout-sidebar {
display : grid ;
grid-template-columns : 1 fr ;
gap : var ( --spacing-lg );
}
@media ( min-width : 768 px ) {
.layout-sidebar {
grid-template-columns : 280 px 1 fr ;
}
} Holy Grail:
.layout-holy-grail {
display : grid ;
grid-template-columns : 1 fr ;
grid-template-rows : auto 1 fr auto ;
min-height : 100 vh ;
}
@media ( min-width : 1024 px ) {
.layout-holy-grail {
grid-template-columns : 200 px 1 fr 200 px ;
grid-template-rows : auto 1 fr auto ;
}
.layout-holy-grail header ,
.layout-holy-grail footer {
grid-column : 1 / -1 ;
}
}
Quick Reference
Viewport Units
Unit
Description
vw
1% of viewport width
vh
1% of viewport height
vmin
1% of smaller dimension
vmax
1% of larger dimension
dvh
Dynamic viewport height (accounts for mobile chrome)
svh
Small viewport height
lvh
Large viewport height
Responsive Testing Checklist
Common Device Widths
Device
Width
Breakpoint
iPhone SE
375px
xs-sm
iPhone 14
390px
sm
iPhone 14 Pro Max
430px
sm
iPad Mini
768px
lg
iPad Pro 11"
834px
lg
MacBook Air 13"
1280px
xl
iMac 24"
1920px
2xl+
See also: token-generation.md for breakpoint token details
Design Token Generation Guide
Reference for color palette algorithms, typography scales, and WCAG accessibility checking.
Table of Contents
Color Palette Generation
HSV Color Space Algorithm
The token generator uses HSV (Hue, Saturation, Value) color space for precise control.
┌─────────────────────────────────────────────────────────────┐
│ COLOR SCALE GENERATION │
├─────────────────────────────────────────────────────────────┤
│ Input: Brand Color (#0066CC) │
│ ↓ │
│ Convert: Hex → RGB → HSV │
│ ↓ │
│ For each step (50, 100, 200... 900): │
│ • Adjust Value (brightness) │
│ • Adjust Saturation │
│ • Keep Hue constant │
│ ↓ │
│ Output: 10-step color scale │
└─────────────────────────────────────────────────────────────┘ Brightness Algorithm
# For light shades (50-400): High fixed brightness
if step < 500 :
new_value = 0.95 # 95% brightness
# For dark shades (500-900): Exponential decrease
else :
new_value = base_value * ( 1 - (step - 500 ) / 500 )
# At step 900: brightness ≈ base_value * 0.2 Saturation Scaling
# Saturation increases with step number
# 50 = 30% of base saturation
# 900 = 100% of base saturation
new_saturation = base_saturation * ( 0.3 + 0.7 * (step / 900 )) Complementary Color Generation
Brand Color: #0066CC (H=210°, S=100%, V=80%)
↓
Add 180° to Hue
↓
Secondary: #CC6600 (H=30°, S=100%, V=80%) Color Scale Output
Step
Use Case
Brightness
Saturation
50
Subtle backgrounds
95% (fixed)
30%
100
Light backgrounds
95% (fixed)
38%
200
Hover states
95% (fixed)
46%
300
Borders
95% (fixed)
54%
400
Disabled states
95% (fixed)
62%
500
Base color
Original
70%
600
Hover (dark)
Original × 0.8
78%
700
Active states
Original × 0.6
86%
800
Text
Original × 0.4
94%
900
Headings
Original × 0.2
100%
Typography Scale System
Modular Scale (Major Third)
The generator uses a 1.25x ratio (major third) to create harmonious font sizes.
Base: 16px
Scale calculation:
Smaller sizes: 16px ÷ 1.25^n
Larger sizes: 16px × 1.25^n
Result:
xs: 10px (16 ÷ 1.25²)
sm: 13px (16 ÷ 1.25¹)
base: 16px
lg: 20px (16 × 1.25¹)
xl: 25px (16 × 1.25²)
2xl: 31px (16 × 1.25³)
3xl: 39px (16 × 1.25⁴)
4xl: 49px (16 × 1.25⁵)
5xl: 61px (16 × 1.25⁶) Type Scale Ratios
Ratio
Name
Multiplier
Character
1.067
Minor Second
Tight
Compact UIs
1.125
Major Second
Subtle
App interfaces
1.200
Minor Third
Moderate
General use
1.250
Major Third
Balanced
Default
1.333
Perfect Fourth
Pronounced
Marketing
1.414
Augmented Fourth
Bold
Editorial
1.618
Golden Ratio
Dramatic
Headlines
Pre-composed Text Styles
Style
Size
Weight
Line Height
Letter Spacing
h1
48px
700
1.2
-0.02em
h2
36px
700
1.3
-0.01em
h3
28px
600
1.4
0
h4
24px
600
1.4
0
h5
20px
600
1.5
0
h6
16px
600
1.5
0.01em
body
16px
400
1.5
0
small
14px
400
1.5
0
caption
12px
400
1.5
0.01em
Spacing Grid System
8pt Grid Foundation
All spacing values are multiples of 8px for visual consistency.
Base Unit: 8px
Multipliers: 0, 0.5, 1, 1.5, 2, 2.5, 3, 4, 5, 6, 7, 8...
Results:
0: 0px
1: 4px (0.5 × 8)
2: 8px (1 × 8)
3: 12px (1.5 × 8)
4: 16px (2 × 8)
5: 20px (2.5 × 8)
6: 24px (3 × 8)
... Semantic Spacing Mapping
Token
Numeric
Value
Use Case
xs
1
4px
Inline icon margins
sm
2
8px
Button padding
md
4
16px
Card padding
lg
6
24px
Section spacing
xl
8
32px
Component gaps
2xl
12
48px
Section margins
3xl
16
64px
Page sections
Why 8pt Grid?
Divisibility : 8 divides evenly into common screen widths
Consistency : Creates predictable vertical rhythm
Accessibility : Touch targets naturally align to 48px (8 × 6)
Integration : Most design tools default to 8px grids
Accessibility Contrast
WCAG Contrast Requirements
Level
Normal Text
Large Text
Definition
AA
4.5:1
3:1
Minimum requirement
AAA
7:1
4.5:1
Enhanced accessibility
Large text : ≥18pt regular or ≥14pt bold
Contrast Ratio Formula
Contrast Ratio = (L1 + 0.05) / (L2 + 0.05)
Where:
L1 = Relative luminance of lighter color
L2 = Relative luminance of darker color
Relative Luminance:
L = 0.2126 × R + 0.7152 × G + 0.0722 × B
(Values linearized from sRGB) Color Step Contrast Guide
Background
Minimum Text Step
For AA
50
700+
Large text at 600
100
700+
Large text at 600
200
800+
Large text at 700
300
900
-
500 (base)
White or 50
-
700+
White or 50-100
-
Semantic Colors Accessibility
Generated semantic colors include contrast colors:
{
"success" : {
"base" : "#10B981" ,
"light" : "#34D399" ,
"dark" : "#059669" ,
"contrast" : "#FFFFFF" // For text on base
}
}
Export Formats
JSON Format
Best for: Design tool plugins, JavaScript/TypeScript projects, APIs
{
"colors" : {
"primary" : {
"50" : "#E6F2FF" ,
"500" : "#0066CC" ,
"900" : "#002855"
}
},
"typography" : {
"fontSize" : {
"base" : "16px" ,
"lg" : "20px"
}
}
} CSS Custom Properties
Best for: Web applications, CSS frameworks
:root {
--colors-primary-50 : #E6F2FF ;
--colors-primary-500 : #0066CC ;
--colors-primary-900 : #002855 ;
--typography-fontSize-base : 16 px ;
--typography-fontSize-lg : 20 px ;
} SCSS Variables
Best for: SCSS/SASS projects, component libraries
$colors-primary-50 : #E6F2FF ;
$colors-primary-500 : #0066CC ;
$colors-primary-900 : #002855 ;
$typography-fontSize-base : 16 px ;
$typography-fontSize-lg : 20 px ; Format Selection Guide
Format
When to Use
JSON
Figma plugins, Storybook, JS/TS, design tool APIs
CSS
Plain CSS projects, CSS-in-JS (some), web apps
SCSS
SASS pipelines, component libraries, theming
Summary
Quick verification, debugging
Quick Reference
Generation Command
# Default (modern style, JSON output)
python scripts/design_token_generator.py "#0066CC"
# Classic style, CSS output
python scripts/design_token_generator.py "#8B4513" classic css
# Playful style, summary view
python scripts/design_token_generator.py "#FF6B6B" playful summary Style Differences
Aspect
Modern
Classic
Playful
Fonts
Inter, Fira Code
Helvetica, Courier
Poppins, Source Code Pro
Border Radius
8px default
4px default
16px default
Shadows
Layered, subtle
Single layer
Soft, pronounced
See also: component-architecture.md for component design patterns
#!/usr/bin/env python3
"""
Design Token Generator
Creates consistent design system tokens for colors, typography, spacing, and more.
Usage:
python design_token_generator.py [brand_color] [style] [format]
brand_color: Hex color (default: #0066CC)
style: modern | classic | playful (default: modern)
format: json | css | scss | summary (default: json)
Examples:
python design_token_generator.py "#0066CC" modern json
python design_token_generator.py "#8B4513" classic css
python design_token_generator.py "#FF6B6B" playful summary
Table of Contents:
==================
CLASS: DesignTokenGenerator
__init__() - Initialize base unit (8pt), type scale (1.25x)
generate_complete_system() - Main entry: generates all token categories
generate_color_palette() - Primary, secondary, neutral, semantic colors
generate_typography_system() - Font families, sizes, weights, line heights
generate_spacing_system() - 8pt grid-based spacing scale
generate_sizing_tokens() - Container and component sizing
generate_border_tokens() - Border radius and width values
generate_shadow_tokens() - Shadow definitions per style
generate_animation_tokens() - Durations, easing, keyframes
generate_breakpoints() - Responsive breakpoints (xs-2xl)
generate_z_index_scale() - Z-index layering system
export_tokens() - Export to JSON/CSS/SCSS
PRIVATE METHODS:
_generate_color_scale() - Generate 10-step color scale (50-900)
_generate_neutral_scale() - Fixed neutral gray palette
_generate_type_scale() - Modular type scale using ratio
_generate_text_styles() - Pre-composed h1-h6, body, caption
_export_as_css() - CSS custom properties exporter
_hex_to_rgb() - Hex to RGB conversion
_rgb_to_hex() - RGB to Hex conversion
_adjust_hue() - HSV hue rotation utility
FUNCTION: main() - CLI entry point with argument parsing
Token Categories Generated:
- colors: primary, secondary, neutral, semantic, surface
- typography: fontFamily, fontSize, fontWeight, lineHeight, letterSpacing
- spacing: 0-64 scale based on 8pt grid
- sizing: containers, buttons, inputs, icons
- borders: radius (per style), width
- shadows: none through 2xl, inner
- animation: duration, easing, keyframes
- breakpoints: xs, sm, md, lg, xl, 2xl
- z-index: hide through notification
"""
import json
from typing import Dict, List, Tuple
import colorsys
class DesignTokenGenerator :
"""Generate comprehensive design system tokens"""
def __init__ (self):
self .base_unit = 8 # 8pt grid system
self .type_scale_ratio = 1.25 # Major third
self .base_font_size = 16
def generate_complete_system (self, brand_color: str = "#0066CC" ,
style: str = "modern" ) -> Dict:
"""Generate complete design token system"""
tokens = {
'meta' : {
'version' : '1.0.0' ,
'style' : style,
'generated' : 'auto-generated'
},
'colors' : self .generate_color_palette(brand_color),
'typography' : self .generate_typography_system(style),
'spacing' : self .generate_spacing_system(),
'sizing' : self .generate_sizing_tokens(),
'borders' : self .generate_border_tokens(style),
'shadows' : self .generate_shadow_tokens(style),
'animation' : self .generate_animation_tokens(),
'breakpoints' : self .generate_breakpoints(),
'z-index' : self .generate_z_index_scale()
}
return tokens
def generate_color_palette (self, brand_color: str ) -> Dict:
"""Generate comprehensive color palette from brand color"""
# Convert hex to RGB
brand_rgb = self ._hex_to_rgb(brand_color)
brand_hsv = colorsys.rgb_to_hsv( * [c / 255 for c in brand_rgb])
palette = {
'primary' : self ._generate_color_scale(brand_color, 'primary' ),
'secondary' : self ._generate_color_scale(
self ._adjust_hue(brand_color, 180 ), 'secondary'
),
'neutral' : self ._generate_neutral_scale(),
'semantic' : {
'success' : {
'base' : '#10B981' ,
'light' : '#34D399' ,
'dark' : '#059669' ,
'contrast' : '#FFFFFF'
},
'warning' : {
'base' : '#F59E0B' ,
'light' : '#FBBD24' ,
'dark' : '#D97706' ,
'contrast' : '#FFFFFF'
},
'error' : {
'base' : '#EF4444' ,
'light' : '#F87171' ,
'dark' : '#DC2626' ,
'contrast' : '#FFFFFF'
},
'info' : {
'base' : '#3B82F6' ,
'light' : '#60A5FA' ,
'dark' : '#2563EB' ,
'contrast' : '#FFFFFF'
}
},
'surface' : {
'background' : '#FFFFFF' ,
'foreground' : '#111827' ,
'card' : '#FFFFFF' ,
'overlay' : 'rgba(0, 0, 0, 0.5)' ,
'divider' : '#E5E7EB'
}
}
return palette
def _generate_color_scale (self, base_color: str , name: str ) -> Dict:
"""Generate color scale from base color"""
scale = {}
rgb = self ._hex_to_rgb(base_color)
h, s, v = colorsys.rgb_to_hsv( * [c / 255 for c in rgb])
# Generate scale from 50 to 900
steps = [ 50 , 100 , 200 , 300 , 400 , 500 , 600 , 700 , 800 , 900 ]
for step in steps:
# Adjust lightness based on step
factor = ( 1000 - step) / 1000
new_v = 0.95 if step < 500 else v * ( 1 - (step - 500 ) / 500 )
new_s = s * ( 0.3 + 0.7 * (step / 900 ))
new_rgb = colorsys.hsv_to_rgb(h, new_s, new_v)
scale[ str (step)] = self ._rgb_to_hex([ int (c * 255 ) for c in new_rgb])
scale[ 'DEFAULT' ] = base_color
return scale
def _generate_neutral_scale (self) -> Dict:
"""Generate neutral color scale"""
return {
'50' : '#F9FAFB' ,
'100' : '#F3F4F6' ,
'200' : '#E5E7EB' ,
'300' : '#D1D5DB' ,
'400' : '#9CA3AF' ,
'500' : '#6B7280' ,
'600' : '#4B5563' ,
'700' : '#374151' ,
'800' : '#1F2937' ,
'900' : '#111827' ,
'DEFAULT' : '#6B7280'
}
def generate_typography_system (self, style: str ) -> Dict:
"""Generate typography system"""
# Font families based on style
font_families = {
'modern' : {
'sans' : 'Inter, system-ui, -apple-system, sans-serif' ,
'serif' : 'Merriweather, Georgia, serif' ,
'mono' : 'Fira Code, Monaco, monospace'
},
'classic' : {
'sans' : 'Helvetica, Arial, sans-serif' ,
'serif' : 'Times New Roman, Times, serif' ,
'mono' : 'Courier New, monospace'
},
'playful' : {
'sans' : 'Poppins, Roboto, sans-serif' ,
'serif' : 'Playfair Display, Georgia, serif' ,
'mono' : 'Source Code Pro, monospace'
}
}
typography = {
'fontFamily' : font_families.get(style, font_families[ 'modern' ]),
'fontSize' : self ._generate_type_scale(),
'fontWeight' : {
'thin' : 100 ,
'light' : 300 ,
'normal' : 400 ,
'medium' : 500 ,
'semibold' : 600 ,
'bold' : 700 ,
'extrabold' : 800 ,
'black' : 900
},
'lineHeight' : {
'none' : 1 ,
'tight' : 1.25 ,
'snug' : 1.375 ,
'normal' : 1.5 ,
'relaxed' : 1.625 ,
'loose' : 2
},
'letterSpacing' : {
'tighter' : '-0.05em' ,
'tight' : '-0.025em' ,
'normal' : '0' ,
'wide' : '0.025em' ,
'wider' : '0.05em' ,
'widest' : '0.1em'
},
'textStyles' : self ._generate_text_styles()
}
return typography
def _generate_type_scale (self) -> Dict:
"""Generate modular type scale"""
scale = {}
sizes = [ 'xs' , 'sm' , 'base' , 'lg' , 'xl' , '2xl' , '3xl' , '4xl' , '5xl' ]
for i, size in enumerate (sizes):
if size == 'base' :
scale[size] = f ' {self .base_font_size } px'
elif i < sizes.index( 'base' ):
factor = self .type_scale_ratio ** (sizes.index( 'base' ) - i)
scale[size] = f ' {round ( self .base_font_size / factor) } px'
else :
factor = self .type_scale_ratio ** (i - sizes.index( 'base' ))
scale[size] = f ' {round ( self .base_font_size * factor) } px'
return scale
def _generate_text_styles (self) -> Dict:
"""Generate pre-composed text styles"""
return {
'h1' : {
'fontSize' : '48px' ,
'fontWeight' : 700 ,
'lineHeight' : 1.2 ,
'letterSpacing' : '-0.02em'
},
'h2' : {
'fontSize' : '36px' ,
'fontWeight' : 700 ,
'lineHeight' : 1.3 ,
'letterSpacing' : '-0.01em'
},
'h3' : {
'fontSize' : '28px' ,
'fontWeight' : 600 ,
'lineHeight' : 1.4 ,
'letterSpacing' : '0'
},
'h4' : {
'fontSize' : '24px' ,
'fontWeight' : 600 ,
'lineHeight' : 1.4 ,
'letterSpacing' : '0'
},
'h5' : {
'fontSize' : '20px' ,
'fontWeight' : 600 ,
'lineHeight' : 1.5 ,
'letterSpacing' : '0'
},
'h6' : {
'fontSize' : '16px' ,
'fontWeight' : 600 ,
'lineHeight' : 1.5 ,
'letterSpacing' : '0.01em'
},
'body' : {
'fontSize' : '16px' ,
'fontWeight' : 400 ,
'lineHeight' : 1.5 ,
'letterSpacing' : '0'
},
'small' : {
'fontSize' : '14px' ,
'fontWeight' : 400 ,
'lineHeight' : 1.5 ,
'letterSpacing' : '0'
},
'caption' : {
'fontSize' : '12px' ,
'fontWeight' : 400 ,
'lineHeight' : 1.5 ,
'letterSpacing' : '0.01em'
}
}
def generate_spacing_system (self) -> Dict:
"""Generate spacing system based on 8pt grid"""
spacing = {}
multipliers = [ 0 , 0.5 , 1 , 1.5 , 2 , 2.5 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 12 , 14 , 16 , 20 , 24 , 32 , 40 , 48 , 56 , 64 ]
for i, mult in enumerate (multipliers):
spacing[ str (i)] = f ' {int ( self .base_unit * mult) } px'
# Add semantic spacing
spacing.update({
'xs' : spacing[ '1' ], # 4px
'sm' : spacing[ '2' ], # 8px
'md' : spacing[ '4' ], # 16px
'lg' : spacing[ '6' ], # 24px
'xl' : spacing[ '8' ], # 32px
'2xl' : spacing[ '12' ], # 48px
'3xl' : spacing[ '16' ] # 64px
})
return spacing
def generate_sizing_tokens (self) -> Dict:
"""Generate sizing tokens for components"""
return {
'container' : {
'sm' : '640px' ,
'md' : '768px' ,
'lg' : '1024px' ,
'xl' : '1280px' ,
'2xl' : '1536px'
},
'components' : {
'button' : {
'sm' : { 'height' : '32px' , 'paddingX' : '12px' },
'md' : { 'height' : '40px' , 'paddingX' : '16px' },
'lg' : { 'height' : '48px' , 'paddingX' : '20px' }
},
'input' : {
'sm' : { 'height' : '32px' , 'paddingX' : '12px' },
'md' : { 'height' : '40px' , 'paddingX' : '16px' },
'lg' : { 'height' : '48px' , 'paddingX' : '20px' }
},
'icon' : {
'sm' : '16px' ,
'md' : '20px' ,
'lg' : '24px' ,
'xl' : '32px'
}
}
}
def generate_border_tokens (self, style: str ) -> Dict:
"""Generate border tokens"""
radius_values = {
'modern' : {
'none' : '0' ,
'sm' : '4px' ,
'DEFAULT' : '8px' ,
'md' : '12px' ,
'lg' : '16px' ,
'xl' : '24px' ,
'full' : '9999px'
},
'classic' : {
'none' : '0' ,
'sm' : '2px' ,
'DEFAULT' : '4px' ,
'md' : '6px' ,
'lg' : '8px' ,
'xl' : '12px' ,
'full' : '9999px'
},
'playful' : {
'none' : '0' ,
'sm' : '8px' ,
'DEFAULT' : '16px' ,
'md' : '20px' ,
'lg' : '24px' ,
'xl' : '32px' ,
'full' : '9999px'
}
}
return {
'radius' : radius_values.get(style, radius_values[ 'modern' ]),
'width' : {
'none' : '0' ,
'thin' : '1px' ,
'DEFAULT' : '1px' ,
'medium' : '2px' ,
'thick' : '4px'
}
}
def generate_shadow_tokens (self, style: str ) -> Dict:
"""Generate shadow tokens"""
shadow_styles = {
'modern' : {
'none' : 'none' ,
'sm' : '0 1px 2px 0 rgba(0, 0, 0, 0.05)' ,
'DEFAULT' : '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)' ,
'md' : '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)' ,
'lg' : '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)' ,
'xl' : '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)' ,
'2xl' : '0 25px 50px -12px rgba(0, 0, 0, 0.25)' ,
'inner' : 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)'
},
'classic' : {
'none' : 'none' ,
'sm' : '0 1px 2px rgba(0, 0, 0, 0.1)' ,
'DEFAULT' : '0 2px 4px rgba(0, 0, 0, 0.1)' ,
'md' : '0 4px 8px rgba(0, 0, 0, 0.1)' ,
'lg' : '0 8px 16px rgba(0, 0, 0, 0.1)' ,
'xl' : '0 16px 32px rgba(0, 0, 0, 0.1)'
}
}
return shadow_styles.get(style, shadow_styles[ 'modern' ])
def generate_animation_tokens (self) -> Dict:
"""Generate animation tokens"""
return {
'duration' : {
'instant' : '0ms' ,
'fast' : '150ms' ,
'DEFAULT' : '250ms' ,
'slow' : '350ms' ,
'slower' : '500ms'
},
'easing' : {
'linear' : 'linear' ,
'ease' : 'ease' ,
'easeIn' : 'ease-in' ,
'easeOut' : 'ease-out' ,
'easeInOut' : 'ease-in-out' ,
'spring' : 'cubic-bezier(0.68, -0.55, 0.265, 1.55)'
},
'keyframes' : {
'fadeIn' : {
'from' : { 'opacity' : 0 },
'to' : { 'opacity' : 1 }
},
'slideUp' : {
'from' : { 'transform' : 'translateY(10px)' , 'opacity' : 0 },
'to' : { 'transform' : 'translateY(0)' , 'opacity' : 1 }
},
'scale' : {
'from' : { 'transform' : 'scale(0.95)' },
'to' : { 'transform' : 'scale(1)' }
}
}
}
def generate_breakpoints (self) -> Dict:
"""Generate responsive breakpoints"""
return {
'xs' : '480px' ,
'sm' : '640px' ,
'md' : '768px' ,
'lg' : '1024px' ,
'xl' : '1280px' ,
'2xl' : '1536px'
}
def generate_z_index_scale (self) -> Dict:
"""Generate z-index scale"""
return {
'hide' : - 1 ,
'base' : 0 ,
'dropdown' : 1000 ,
'sticky' : 1020 ,
'overlay' : 1030 ,
'modal' : 1040 ,
'popover' : 1050 ,
'tooltip' : 1060 ,
'notification' : 1070
}
def export_tokens (self, tokens: Dict, format: str = 'json' ) -> str :
"""Export tokens in various formats"""
if format == 'json' :
return json.dumps(tokens, indent = 2 )
elif format == 'css' :
return self ._export_as_css(tokens)
elif format == 'scss' :
return self ._export_as_scss(tokens)
else :
return json.dumps(tokens, indent = 2 )
def _export_as_css (self, tokens: Dict) -> str :
"""Export as CSS variables"""
css = [ ':root {' ]
def flatten_dict (obj, prefix = '' ):
for key, value in obj.items():
if isinstance (value, dict ):
flatten_dict(value, f ' { prefix } - { key } ' if prefix else key)
else :
css.append( f ' -- { prefix } - { key } : { value } ;' )
flatten_dict(tokens)
css.append( '}' )
return ' \n ' .join(css)
def _hex_to_rgb (self, hex_color: str ) -> Tuple[ int , int , int ]:
"""Convert hex to RGB"""
hex_color = hex_color.lstrip( '#' )
return tuple ( int (hex_color[i:i + 2 ], 16 ) for i in ( 0 , 2 , 4 ))
def _rgb_to_hex (self, rgb: List[ int ]) -> str :
"""Convert RGB to hex"""
return '# { :02x }{ :02x }{ :02x } ' .format( * rgb)
def _adjust_hue (self, hex_color: str , degrees: int ) -> str :
"""Adjust hue of color"""
rgb = self ._hex_to_rgb(hex_color)
h, s, v = colorsys.rgb_to_hsv( * [c / 255 for c in rgb])
h = (h + degrees / 360 ) % 1
new_rgb = colorsys.hsv_to_rgb(h, s, v)
return self ._rgb_to_hex([ int (c * 255 ) for c in new_rgb])
def main ():
import sys
import argparse
parser = argparse.ArgumentParser(
description = "Design Token Generator - Creates consistent design system tokens for colors, typography, spacing, and more."
)
parser.add_argument(
"brand_color" , nargs = "?" , default = "#0066CC" ,
help = "Hex brand color (default: #0066CC)"
)
parser.add_argument(
"--style" , choices = [ "modern" , "classic" , "playful" ], default = "modern" ,
help = "Design style (default: modern)"
)
parser.add_argument(
"--format" , choices = [ "json" , "css" , "scss" , "summary" ], default = "json" ,
dest = "output_format" ,
help = "Output format (default: json)"
)
args = parser.parse_args()
generator = DesignTokenGenerator()
tokens = generator.generate_complete_system(args.brand_color, args.style)
if args.output_format == 'summary' :
print ( "=" * 60 )
print ( "DESIGN SYSTEM TOKENS" )
print ( "=" * 60 )
print ( f " \n Style: { args.style } " )
print ( f " Brand Color: { args.brand_color } " )
print ( " \n Generated Tokens:" )
print ( f " - Colors: {len (tokens[ 'colors' ]) } palettes" )
print ( f " - Typography: {len (tokens[ 'typography' ]) } categories" )
print ( f " - Spacing: {len (tokens[ 'spacing' ]) } values" )
print ( f " - Shadows: {len (tokens[ 'shadows' ]) } styles" )
print ( f " - Breakpoints: {len (tokens[ 'breakpoints' ]) } sizes" )
print ( " \n Export formats available: json, css, scss" )
else :
print (generator.export_tokens(tokens, args.output_format))
if __name__ == "__main__" :
main()