Use when generating and applying professional color themes, typography systems, and design tokens for applications. Create consistent visual identities across platforms.
"Generate and apply professional color themes, typography systems, and design tok"
When creating a new visual theme or color palette
When defining design tokens for a design system
When rebranding an application
When ensuring visual consistency across platforms
When NOT to Use
For implementing existing designs (use frontend-ui-design)
For logo design (use image generation skills)
For content creation (use content skills)
Overview
Generate professional design systems including color palettes, typography scales, spacing systems, and design tokens. Supports CSS custom properties, Tailwind config, and design token JSON.
Generate a full color scale from a single hex primary using HSL interpolation for light→dark variants (simplified HSL demo — for OKLCH-based perceptual uniformity use the colour or culori libraries listed below):
from typing import Dict, List, Tuple
def hex_to_rgb(hex_color: str) -> Tuple[int, int, int]:
"""Convert #RRGGBB to (R, G, B) integer tuple."""
h = hex_color.lstrip("#")
return tuple(int(h[i:i+2], 16) for i in (0, 2, 4))
def rgb_to_hsl(r: int, g: int, b: int) -> Tuple[float, float, float]:
"""Convert RGB 0-255 to HSL 0-360 / 0-1 / 0-1."""
r, g, b = r / 255, g / 255, b / 255
mx, mn = max(r, g, b), min(r, g, b)
l = (mx + mn) / 2
if mx == mn:
return 0, 0, l
d = mx - mn
s = d / (2 - mx - mn) if l > 0.5 else d / (mx + mn)
if mx == r:
h = (g - b) / d + (6 if g < b else 0)
elif mx == g:
h = (b - r) / d + 2
else:
h = (r - g) / d + 4
return h * 60, s, l
def hsl_to_hex(h: float, s: float, l: float) -> str:
"""Convert HSL to #RRGGBB."""
c = (1 - abs(2 * l - 1)) * s
hp = h / 60
x = c * (1 - abs(hp % 2 - 1))
m = l - c / 2
if hp < 1:
r, g, b = c, x, 0
elif hp < 2:
r, g, b = x, c, 0
elif hp < 3:
r, g, b = 0, c, x
elif hp < 4:
r, g, b = 0, x, c
elif hp < 5:
r, g, b = x, 0, c
else:
r, g, b = c, 0, x
return "#{:02x}{:02x}{:02x}".format(
round((r + m) * 255), round((g + m) * 255), round((b + m) * 255)
)
def generate_scale(primary: str, steps: List[int] = None) -> Dict[str, str]:
"""Generate a 50-900 color scale from one primary hex.
Light shades (50-400) blend toward white; dark shades (600-900)
blend toward black; 500 is the reference.
"""
if steps is None:
steps = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900]
h, s, l = rgb_to_hsl(*hex_to_rgb(primary))
scale = {}
target_luminances = {
50: 0.95, 100: 0.85, 200: 0.75, 300: 0.65, 400: 0.55,
500: l,
600: 0.35, 700: 0.25, 800: 0.15, 900: 0.08,
}
for step in steps:
t = target_luminances.get(step, l)
scale[str(step)] = hsl_to_hex(h, max(0, min(1, s)), max(0, min(1, t)))
return scale
# Example: generate palette from #3b82f6 (Tailwind blue-500)
primary = "#3b82f6"
scale = generate_scale(primary)
for step, color in scale.items():
print(f" --color-primary-{step}: {color};")
# Dark-mode invert: shift lightness toward black, reduce saturation
dark_scale = generate_scale("#60a5fa")
dark_scale["50"] = "#1e3a8a" # override for deeper dark background
Production-ready palette libraries:
[palette] — Extract color palettes from images (k-means clustering)
[colour] — Advanced color science (perceptual deltas, gamut mapping)
pip install colour-science # advanced color science
pip install palettable # predefined color palettes
pip install wcag-contrast-ratio # accessibility ratio checks
pip install Pillow # image-based palette extraction
Node.js environment:
npm install chroma-js # color manipulation (OKLCH, HSL, contrast)
npm install color # CSS color string parsing
npm install culori # color conversion + interpolation
npm install @radix-ui/colors # radix color scales reference
Figma token sync (optional):
npm install style-dictionary # Amazon Style Dictionary — compile design tokens
npx token-transformer # convert Figma Tokens to Style-Dictionary format
For production theme pipelines, use Style Dictionary to compile tokens into platform-specific outputs (CSS, iOS, Android, React Native) from a single JSON source.
Common Issues & Troubleshooting
Problem
Solution
Color scale looks muddy / low saturation
Reduce the saturation multiplier for mid-range steps (200-400). Perceptual spacing via OKLCH color space produces cleaner ramps. Try culori with lch() interpolation
WCAG AA contrast fails on primary-500 buttons
Shift the button color toward the darker end of the scale (use primary-600 or primary-700 for text on white backgrounds). Check ratio with wcag-contrast-ratio library
Dark-mode tokens produce washed-out colors
Dark mode needs lower saturation, not just inverted lightness. Reduce saturation by 15-30% for mid-tones and boost the lighter end (50-200) to ensure contrast on dark backgrounds
Typography scale looks uneven
Minor second (1.067) for dense UIs, major third (1.25) for editorial. Scale base size from 16px and verify each step: h1 = base * ratio^3, h2 = base * ratio^2, h3 = base * ratio
Generated palette has too many/too few shades
Target 10-step (50-900) for brands, 6-step (100-700) for neutral grays. Merge extremes (50+100, 800+900) when the palette feels redundant
Spacing tokens feel arbitrary
Use a modular scale: space(n) = base * n where base = 4px (tight) or 8px (generous). Every distance should be a multiple of the base unit
Figma tokens won't import
Convert to W3C Design Tokens format using style-dictionary or token-transformer. Some tools expect $value / $type keys instead of plain values
Monetization
Theme Marketplace
Create and sell premium themes as digital products:
Tailwind UI kits — Full application themes with color palettes, typography, components ($49-149/sale). List on Tailwind UI, ThemeForest, or Gumroad
Figma Design System — Complete token-based design systems with light/dark mode, component library, and documentation ($79-199/sale)
Brand-in-a-box — Generate brand identity packages (logo + palette + typography + tokens) and sell on a micro-site. Target startups that need instant branding ($199-499/package)
Subscription palette feed — Weekly or monthly curated color palettes with code exports (CSS/JSON/Tailwind) on a membership platform ($9-29/month)
Design System Service
Offer custom design system consulting as a service:
Design system audit — Review existing UI for inconsistencies, document token gaps, produce a migration plan ($500-2,000/engagement)
Custom theme generation — Build a complete production theme from brand guidelines: colors, typography, spacing, components, dark mode ($1,000-5,000)
Token integration — Wire the theme into their codebase (CSS custom properties, Tailwind, styled-components) with CI/CD token publishing ($2,000-8,000)
Multi-brand white-label — Architecture for SaaS platforms needing per-tenant themes (brand colors, logo, fonts) with runtime token switching ($5,000-15,000)
Automated Add-ons
WCAG accessibility scanner for themes — SaaS that crawls any CSS file and reports contrast failures ($49/month)
Theme snapshot service — Generate before/after screenshots of an app with different themes for client pitches (per-project)
Token diff pipeline — CI plugin that fails builds when design tokens change unexpectedly, with approval workflow (open-source with paid enterprise tier)
Process
Define primitives — Lock in the brand primary hex. Choose neutral undertone (warm/cool/true gray). Pick font superfamily (e.g. Inter for UI + Merriweather for headings). Set the base space unit (4px or 8px).
Map semantic roles — Assign token names to functional roles: --color-bg, --color-text, --color-border, --color-accent. Decide which roles are theme-aware (swap in dark mode) and which are invariant.
Generate palette scale — Run the Python or JS palette generator from the primary, producing 10-step (50-900) scales for each role color. Verify each step with wcag-contrast-ratio against expected backgrounds.
Create variant recipes — Define interaction states: hover → adjust lightness by ±8%, active → ±12%, disabled → opacity 0.38 + desaturate. Store as functions in design tokens, not hardcoded values.
Export targets — Compile tokens to CSS custom properties for web, JSON for style-dictionary, Tailwind config for utility-first, and Figma tokens for designers. Dark mode is a separate export pass with inverted values.
Version & publish — Token breaking changes must be communicated via semver. Publish to npm as @company/design-tokens or to a design token CDN endpoint for runtime fetching.
Verification
Every semantic role has a token assignment (bg, text, border, accent, success, error, warning, info)
WCAG AA contrast ratio ≥4.5:1 for body text, ≥3:1 for large text (18px+ bold or 24px+ regular) on all role-appropriate backgrounds
Dark-mode tokens verified: minimum contrast ratio maintained, not just inverted (saturation may need adjustment)
Spacing scale is a strict multiple of the base unit — no orphan distances
Token export produces files for every target (CSS, JSON, Tailwind, Figma) that parse without errors
Dark mode toggles cleanly (swap data-theme attribute) with no un-themed flash
Token changes are versioned: bump MAJOR on breaking role renames, MINOR on new roles, PATCH on color value tweaks
1---2name: theme-factory3description: Use when generating and applying professional color themes, typography systems, and design tokens for applications. Create consistent visual identities across platforms.4license: Apache-2.05---678# Theme Factory910## When to Use11**Trigger phrases:**12- "theme factory"13- "Generate and apply professional color themes, typography systems, and design tok"141516- When creating a new visual theme or color palette17- When defining design tokens for a design system18- When rebranding an application19- When ensuring visual consistency across platforms2021## When NOT to Use2223- For implementing existing designs (use `frontend-ui-design`)24- For logo design (use image generation skills)25- For content creation (use content skills)2627## Overview2829Generate professional design systems including color palettes, typography scales, spacing systems, and design tokens. Supports CSS custom properties, Tailwind config, and design token JSON.3031## Workflow32331. **Define brand** — Primary color, mood, audience342. **Generate palette** — Primary, secondary, accent, neutral, semantic colors353. **Define typography** — Font stack, scale, line heights, weights364. **Create tokens** — Design token JSON for cross-platform use375. **Export** — CSS variables, Tailwind config, Figma tokens3839## Anti-Rationalization Table4041| Rationalization | Reality |42|---|---|43| "I will pick colors by eye" | Systematic color theory ensures accessibility and harmony |44| "One font is enough" | A type scale (headings, body, caption) creates visual hierarchy |45| "Hardcode colors in components" | Design tokens enable theme switching and dark mode |4647## Code Example (CSS Custom Properties)4849```css50:root {51 --color-primary-50: #eff6ff;52 --color-primary-500: #3b82f6;53 --color-primary-900: #1e3a8a;54 --font-family-sans: 'Inter', system-ui, sans-serif;55 --font-size-xs: 0.75rem;56 --font-size-base: 1rem;57 --font-size-2xl: 1.5rem;58 --space-1: 0.25rem;59 --space-4: 1rem;60 --space-8: 2rem;6162 [data-theme="dark"] {63 --color-primary-500: #60a5fa;64 --color-bg: #0f172a;65 --color-text: #f8fafc;66 }67}68```6970## Code Example (Python) — Color Palette Generation7172Generate a full color scale from a single hex primary using HSL interpolation for light→dark variants (simplified HSL demo — for OKLCH-based perceptual uniformity use the `colour` or `culori` libraries listed below):7374```python75from typing import Dict, List, Tuple767778def hex_to_rgb(hex_color: str) -> Tuple[int, int, int]:79 """Convert #RRGGBB to (R, G, B) integer tuple."""80 h = hex_color.lstrip("#")81 return tuple(int(h[i:i+2], 16) for i in (0, 2, 4))828384def rgb_to_hsl(r: int, g: int, b: int) -> Tuple[float, float, float]:85 """Convert RGB 0-255 to HSL 0-360 / 0-1 / 0-1."""86 r, g, b = r / 255, g / 255, b / 25587 mx, mn = max(r, g, b), min(r, g, b)88 l = (mx + mn) / 289 if mx == mn:90 return 0, 0, l91 d = mx - mn92 s = d / (2 - mx - mn) if l > 0.5 else d / (mx + mn)93 if mx == r:94 h = (g - b) / d + (6 if g < b else 0)95 elif mx == g:96 h = (b - r) / d + 297 else:98 h = (r - g) / d + 499 return h * 60, s, l100101102def hsl_to_hex(h: float, s: float, l: float) -> str:103 """Convert HSL to #RRGGBB."""104 c = (1 - abs(2 * l - 1)) * s105 hp = h / 60106 x = c * (1 - abs(hp % 2 - 1))107 m = l - c / 2108 if hp < 1:109 r, g, b = c, x, 0110 elif hp < 2:111 r, g, b = x, c, 0112 elif hp < 3:113 r, g, b = 0, c, x114 elif hp < 4:115 r, g, b = 0, x, c116 elif hp < 5:117 r, g, b = x, 0, c118 else:119 r, g, b = c, 0, x120 return "#{:02x}{:02x}{:02x}".format(121 round((r + m) * 255), round((g + m) * 255), round((b + m) * 255)122 )123124125def generate_scale(primary: str, steps: List[int] = None) -> Dict[str, str]:126 """Generate a 50-900 color scale from one primary hex.127128 Light shades (50-400) blend toward white; dark shades (600-900)129 blend toward black; 500 is the reference.130 """131 if steps is None:132 steps = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900]133 h, s, l = rgb_to_hsl(*hex_to_rgb(primary))134 scale = {}135 target_luminances = {136 50: 0.95, 100: 0.85, 200: 0.75, 300: 0.65, 400: 0.55,137 500: l,138 600: 0.35, 700: 0.25, 800: 0.15, 900: 0.08,139 }140 for step in steps:141 t = target_luminances.get(step, l)142 scale[str(step)] = hsl_to_hex(h, max(0, min(1, s)), max(0, min(1, t)))143 return scale144145146# Example: generate palette from #3b82f6 (Tailwind blue-500)147primary = "#3b82f6"148scale = generate_scale(primary)149for step, color in scale.items():150 print(f" --color-primary-{step}: {color};")151152# Dark-mode invert: shift lightness toward black, reduce saturation153dark_scale = generate_scale("#60a5fa")154dark_scale["50"] = "#1e3a8a" # override for deeper dark background155```156157**Production-ready palette libraries:**158159- [palette] — Extract color palettes from images (k-means clustering)160- [colour] — Advanced color science (perceptual deltas, gamut mapping)161- [wcag-contrast-ratio] — Check accessibility ratios programmatically162163## Code Example (JavaScript) — Design Token → CSS Variables164165Generate theme CSS and Tailwind config from a design-token JSON object, including dark-mode inversion and TypeScript types:166167```javascript168/**169 * Generate CSS custom properties string from a token tree.170 * Flattens nested keys into `--category-key-subkey` variable names.171 */172function tokensToCSS(tokens, { prefix = "", theme = "light" } = {}) {173 const lines = [];174 for (const [key, value] of Object.entries(tokens)) {175 const varName = prefix ? `${prefix}-${key}` : key;176 if (typeof value === "object" && value !== null && !Array.isArray(value)) {177 lines.push(tokensToCSS(value, { prefix: varName, theme }));178 } else {179 lines.push(` --${varName}: ${value};`);180 }181 }182 return lines.join("\n");183}184185/**186 * Invert a light palette for dark mode by swapping light/dark steps.187 * dark[50] -> light[900], dark[100] -> light[800], etc.188 */189function invertPalette(tokens) {190 const inverted = JSON.parse(JSON.stringify(tokens));191 for (const [cat, scale] of Object.entries(tokens)) {192 if (typeof scale !== "object") continue;193 inverted[cat] = {};194 for (const [step, color] of Object.entries(scale)) {195 const num = parseInt(step, 10);196 const invertedStep = isNaN(num) ? step : String(1000 - num);197 inverted[cat][invertedStep] = color;198 }199 }200 return inverted;201}202203// ---- Example ----204const tokens = {205 color: {206 primary: { 50: "#eff6ff", 500: "#3b82f6", 900: "#1e3a8a" },207 neutral: { 50: "#fafafa", 500: "#737373", 900: "#171717" },208 },209 font: {210 family: { sans: "'Inter', system-ui, sans-serif" },211 size: { xs: "0.75rem", base: "1rem", xl: "1.5rem" },212 },213 space: { 1: "0.25rem", 4: "1rem", 8: "2rem" },214};215216const lightCSS = `:root {\n${tokensToCSS(tokens)}\n}`;217console.log(lightCSS);218219const darkTokens = invertPalette(tokens);220const darkCSS = `[data-theme="dark"] {\n${tokensToCSS(darkTokens)}\n}`;221console.log(darkCSS);222223// ---- Tailwind v3/v4 config export ----224function tokensToTailwind(tokens) {225 const tw = { theme: { extend: {} } };226 for (const [cat, values] of Object.entries(tokens)) {227 if (cat === "font" && values.family) {228 tw.theme.extend.fontFamily = { sans: values.family.sans.split(",").map(s => s.trim()) };229 }230 if (cat === "space") {231 tw.theme.extend.spacing = Object.fromEntries(232 Object.entries(values).map(([k, v]) => [k, v])233 );234 }235 }236 return tw;237}238// Usage: write tailwind.config.js with module.exports = tokensToTailwind(tokens)239```240241## Setup & Configuration242243**Python environment:**244```bash245pip install colour-science # advanced color science246pip install palettable # predefined color palettes247pip install wcag-contrast-ratio # accessibility ratio checks248pip install Pillow # image-based palette extraction249```250251**Node.js environment:**252```bash253npm install chroma-js # color manipulation (OKLCH, HSL, contrast)254npm install color # CSS color string parsing255npm install culori # color conversion + interpolation256npm install @radix-ui/colors # radix color scales reference257```258259**Figma token sync (optional):**260```bash261npm install style-dictionary # Amazon Style Dictionary — compile design tokens262npx token-transformer # convert Figma Tokens to Style-Dictionary format263```264265For production theme pipelines, use [Style Dictionary](https://amzn.github.io/style-dictionary/) to compile tokens into platform-specific outputs (CSS, iOS, Android, React Native) from a single JSON source.266267## Common Issues & Troubleshooting268269| Problem | Solution |270|---|---|271| Color scale looks muddy / low saturation | Reduce the saturation multiplier for mid-range steps (200-400). Perceptual spacing via OKLCH color space produces cleaner ramps. Try `culori` with `lch()` interpolation |272| WCAG AA contrast fails on primary-500 buttons | Shift the button color toward the darker end of the scale (use primary-600 or primary-700 for text on white backgrounds). Check ratio with `wcag-contrast-ratio` library |273| Dark-mode tokens produce washed-out colors | Dark mode needs lower saturation, not just inverted lightness. Reduce saturation by 15-30% for mid-tones and boost the lighter end (50-200) to ensure contrast on dark backgrounds |274| Typography scale looks uneven | Minor second (1.067) for dense UIs, major third (1.25) for editorial. Scale base size from 16px and verify each step: `h1 = base * ratio^3`, `h2 = base * ratio^2`, `h3 = base * ratio` |275| Generated palette has too many/too few shades | Target 10-step (50-900) for brands, 6-step (100-700) for neutral grays. Merge extremes (50+100, 800+900) when the palette feels redundant |276| Spacing tokens feel arbitrary | Use a modular scale: `space(n) = base * n` where `base = 4px` (tight) or `8px` (generous). Every distance should be a multiple of the base unit |277| Figma tokens won't import | Convert to W3C Design Tokens format using `style-dictionary` or `token-transformer`. Some tools expect `$value` / `$type` keys instead of plain values |278279## Monetization280281### Theme Marketplace282Create and sell premium themes as digital products:283284- **Tailwind UI kits** — Full application themes with color palettes, typography, components ($49-149/sale). List on Tailwind UI, ThemeForest, or Gumroad285- **Figma Design System** — Complete token-based design systems with light/dark mode, component library, and documentation ($79-199/sale)286- **Brand-in-a-box** — Generate brand identity packages (logo + palette + typography + tokens) and sell on a micro-site. Target startups that need instant branding ($199-499/package)287- **Subscription palette feed** — Weekly or monthly curated color palettes with code exports (CSS/JSON/Tailwind) on a membership platform ($9-29/month)288289### Design System Service290Offer custom design system consulting as a service:291292- **Design system audit** — Review existing UI for inconsistencies, document token gaps, produce a migration plan ($500-2,000/engagement)293- **Custom theme generation** — Build a complete production theme from brand guidelines: colors, typography, spacing, components, dark mode ($1,000-5,000)294- **Token integration** — Wire the theme into their codebase (CSS custom properties, Tailwind, styled-components) with CI/CD token publishing ($2,000-8,000)295- **Multi-brand white-label** — Architecture for SaaS platforms needing per-tenant themes (brand colors, logo, fonts) with runtime token switching ($5,000-15,000)296297### Automated Add-ons298- **WCAG accessibility scanner for themes** — SaaS that crawls any CSS file and reports contrast failures ($49/month)299- **Theme snapshot service** — Generate before/after screenshots of an app with different themes for client pitches (per-project)300- **Token diff pipeline** — CI plugin that fails builds when design tokens change unexpectedly, with approval workflow (open-source with paid enterprise tier)301302## Process3033041. **Define primitives** — Lock in the brand primary hex. Choose neutral undertone (warm/cool/true gray). Pick font superfamily (e.g. Inter for UI + Merriweather for headings). Set the base space unit (4px or 8px).3052. **Map semantic roles** — Assign token names to functional roles: `--color-bg`, `--color-text`, `--color-border`, `--color-accent`. Decide which roles are theme-aware (swap in dark mode) and which are invariant.3063. **Generate palette scale** — Run the Python or JS palette generator from the primary, producing 10-step (50-900) scales for each role color. Verify each step with `wcag-contrast-ratio` against expected backgrounds.3074. **Create variant recipes** — Define interaction states: `hover` → adjust lightness by ±8%, `active` → ±12%, `disabled` → opacity 0.38 + desaturate. Store as functions in design tokens, not hardcoded values.3085. **Export targets** — Compile tokens to CSS custom properties for web, JSON for style-dictionary, Tailwind config for utility-first, and Figma tokens for designers. Dark mode is a separate export pass with inverted values.3096. **Version & publish** — Token breaking changes must be communicated via semver. Publish to npm as `@company/design-tokens` or to a design token CDN endpoint for runtime fetching.310311## Verification312313- [ ] Every semantic role has a token assignment (bg, text, border, accent, success, error, warning, info)314- [ ] WCAG AA contrast ratio ≥4.5:1 for body text, ≥3:1 for large text (18px+ bold or 24px+ regular) on all role-appropriate backgrounds315- [ ] Dark-mode tokens verified: minimum contrast ratio maintained, not just inverted (saturation may need adjustment)316- [ ] Typography scale covers at least: display, h1, h2, h3, body, caption, overline, code317- [ ] Spacing scale is a strict multiple of the base unit — no orphan distances318- [ ] Token export produces files for every target (CSS, JSON, Tailwind, Figma) that parse without errors319- [ ] Dark mode toggles cleanly (swap `data-theme` attribute) with no un-themed flash320- [ ] Token changes are versioned: bump MAJOR on breaking role renames, MINOR on new roles, PATCH on color value tweaks
Run npx skillmds add oyi77/theme-factory in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Use when generating and applying professional color themes, typography systems, and design tokens for applications. Create consistent visual identities across platforms. It is listed under Design & Media on SkillMD.
This skill has not completed SkillMD's automated safety review yet. Capability flags: makes network calls, reads secrets. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free. This skill is licensed under Apache-2.
oyi77 (@oyi77) published this skill. Their other Agent Skills are listed on their SkillMD profile.