‹ 首页

design-tokens

@darkroomengineering · 收录于 昨天 · 上游提交 昨天

Generate OR consolidate design tokens — type scales, color palettes, spacing systems, dark-mode derivations with WCAG checks (generate); or audit-and-reduce an over-grown Tailwind v4 token set with identical render (consolidate). Outputs CSS/Tailwind. Triggers "design tokens", "type scale", "color palette", "theme setup", "reduce tokens", "dedupe tokens", "too many tokens", "consolidate tokens".

适合你,如果你需要创建或优化设计系统中的令牌集

/ 通过 npx 安装 校验哈希
npx oh-my-skill add darkroomengineering/cc-settings/design-tokens
/ 通过 bash 安装
curl -fsSL https://oh-my-skill.com/install.sh | bash -s -- darkroomengineering/cc-settings/design-tokens
/ 已经装过?验证本机副本,不用重装
npx oh-my-skill verify darkroomengineering/cc-settings/design-tokens
安装目标可用 --agent / --scope 或 --to 明确指定;省略时只会在唯一已存在的 agent 目录上自动选择,零命中或多命中会停止并提示。content_hash 缺失或不一致均拒装。
40GitHub stars
~3.3K上下文体积 · 单文件
索引托管

怎么用

商店整理自技能原文 · 版本 fa04efc · 表述以原文为准
它做什么

Claude 会根据你的需求生成或整合设计令牌,包括字体大小、颜色、间距、暗黑模式等,并确保符合 WCAG 无障碍标准,最后输出 CSS 或 Tailwind 代码。

什么时候触发

当你提到“设计令牌”、“调色板”、“字体比例”、“主题设置”、“减少令牌”等关键词,或者要求设置设计系统时触发。

装好后可以这样说
Claude 会生成颜色令牌并检查对比度。
Claude 会审核并合并重复或近似的令牌。
Claude 会输出字体大小令牌。
技能原文 SKILL.md作者撰写 · MIT · fa04efc

Design Tokens

When to Use
  • User is setting up a new project's design system
  • User asks for a type scale, color palette, or spacing system
  • User needs WCAG-compliant color combinations
  • User wants dark mode colors derived from a light palette
  • User asks for "design tokens" or "theme setup"
  • Building a Tailwind config or CSS custom properties
Core Philosophy
  • Math over taste. Scales should follow ratios, not arbitrary values.
  • Accessibility by default. Every text/background combo must pass WCAG AA.
  • Systematic. Every value should be derivable from a base + ratio.
  • Portable. Output as CSS custom properties, Tailwind config, or JSON tokens.

Type Scale Generation
The Formula
fontSize = baseFontSize x ratio^step
Recommended Ratios

| Ratio | Name | Value | Best for | |-------|------|-------|----------| | Minor Second | 1.067 | Tight, minimal difference | Dense UI, dashboards | | Major Second | 1.125 | Subtle progression | Apps, data-heavy interfaces | | Minor Third | 1.200 | Balanced, versatile | Most websites, SaaS | | Major Third | 1.250 | Clear hierarchy | Marketing sites, blogs | | Perfect Fourth | 1.333 | Strong contrast | Editorial, landing pages | | Augmented Fourth | 1.414 | Dramatic | Bold designs, portfolios | | Perfect Fifth | 1.500 | Very dramatic | Hero-heavy designs |

Generating the Scale

Given a base size (typically 16px) and a ratio:

Step -2: 16 / ratio^2 = xs
Step -1: 16 / ratio   = sm
Step  0: 16           = base
Step  1: 16 x ratio   = lg
Step  2: 16 x ratio^2 = xl
Step  3: 16 x ratio^3 = 2xl
Step  4: 16 x ratio^4 = 3xl
Step  5: 16 x ratio^5 = 4xl
Step  6: 16 x ratio^6 = 5xl

Round to nearest 0.5px or convert to rem (/ 16).

Line Height Rules

| Font Size | Line Height | Use | |-----------|-------------|-----| | <= 14px | 1.6-1.7 | Small text, captions | | 16-20px | 1.5-1.6 | Body text | | 20-32px | 1.3-1.4 | Subheadings | | 32-48px | 1.1-1.2 | Headings | | 48px+ | 1.0-1.1 | Display/hero text |

Rule of thumb: As font size increases, line height decreases.

Letter Spacing Rules

| Size | Letter Spacing | Why | |------|---------------|-----| | Small text (<=14px) | 0.01-0.02em | Slightly open for readability | | Body text | 0em (normal) | Don't touch it | | Subheadings | -0.01em | Slightly tighten | | Headings | -0.02em to -0.03em | Tighten as size grows | | Display text | -0.03em to -0.05em | Tight tracking at large sizes |

Font Weight Pairing

| Role | Weight | Tailwind | |------|--------|----------| | Body | 400 (Regular) | font-normal | | Body emphasis | 500 (Medium) | font-medium | | Subheading | 600 (Semibold) | font-semibold | | Heading | 700 (Bold) | font-bold | | Display | 800 (Extrabold) | font-extrabold |

Output Example (CSS Custom Properties)
:root {
  --font-size-xs: 0.694rem;    /* 11.1px */
  --font-size-sm: 0.833rem;    /* 13.3px */
  --font-size-base: 1rem;      /* 16px */
  --font-size-lg: 1.2rem;      /* 19.2px */
  --font-size-xl: 1.44rem;     /* 23px */
  --font-size-2xl: 1.728rem;   /* 27.6px */
  --font-size-3xl: 2.074rem;   /* 33.2px */
  --font-size-4xl: 2.488rem;   /* 39.8px */
  --font-size-5xl: 2.986rem;   /* 47.8px */
}

Color Palette Generation
Step 1: Choose Base Colors

Every palette needs:

| Token | Purpose | Example | |-------|---------|---------| | primary | Main brand color, CTAs | Blue, purple, etc. | | neutral | Text, borders, backgrounds | Gray (warm/cool/pure) | | success | Positive states | Green | | warning | Caution states | Amber/yellow | | error | Destructive states | Red | | info | Informational | Blue (can overlap primary) |

Step 2: Generate Shade Scale (50-950)

For each base color, generate a 10-step shade scale. The base color is typically the 500 step.

Method: HSL manipulation

Starting from the base HSL:

| Step | Lightness Adjustment | Saturation Adjustment | |------|---------------------|----------------------| | 50 | +45% | -30% | | 100 | +38% | -25% | | 200 | +28% | -15% | | 300 | +18% | -5% | | 400 | +8% | 0% | | 500 | 0% (base) | 0% (base) | | 600 | -8% | +5% | | 700 | -18% | +5% | | 800 | -28% | 0% | | 900 | -38% | -10% | | 950 | -45% | -20% |

Clamp all values: lightness 0-100%, saturation 0-100%.

Step 3: Semantic Token Mapping

Map shade steps to semantic roles:

/* Light mode */
--color-bg: var(--neutral-50);
--color-bg-subtle: var(--neutral-100);
--color-bg-muted: var(--neutral-200);
--color-border: var(--neutral-200);
--color-border-strong: var(--neutral-300);
--color-text-muted: var(--neutral-500);
--color-text-subtle: var(--neutral-600);
--color-text: var(--neutral-900);
--color-text-heading: var(--neutral-950);

--color-primary: var(--primary-600);
--color-primary-hover: var(--primary-700);
--color-primary-bg: var(--primary-50);
--color-primary-text: white;

WCAG Contrast Checking
The Formula

Contrast ratio = (L1 + 0.05) / (L2 + 0.05)

Where L1 = lighter relative luminance, L2 = darker.

Relative Luminance
For each channel (R, G, B):
  sRGB = channel / 255
  linear = sRGB <= 0.04045 ? sRGB / 12.92 : ((sRGB + 0.055) / 1.055) ^ 2.4

L = 0.2126 x R_linear + 0.7152 x G_linear + 0.0722 x B_linear
WCAG Requirements

| Level | Body text | Large text (18pt+/14pt+ bold) | Non-text UI | |---|---|---|---| | AA | 4.5:1 | 3:1 | 3:1 | | AAA | 7:1 | 4.5:1 | — |

Canonical copy: ~/.claude/rules/accessibility.md.

Quick Reference (Neutral on White #FFFFFF)

| Shade | Approx Contrast | Passes | |-------|-----------------|--------| | 300 | ~2.5:1 | Decorative only | | 400 | ~3.5:1 | Large text, UI | | 500 | ~4.5:1 | AA body text | | 600 | ~6:1 | AA comfortable | | 700 | ~8:1 | AAA body text |

Checking Contrast Programmatically

When generating palettes, always verify:

  1. text (900) on bg (50) -> must be >= 4.5:1
  2. text-muted (500) on bg (50) -> must be >= 4.5:1
  3. primary (600) on white -> must be >= 4.5:1
  4. primary-text on primary (600) -> must be >= 4.5:1
  5. border (200) on bg (50) -> must be >= 3:1

If a combo fails, adjust the darker color one step darker until it passes.


Spacing System
Base-4 Scale (Recommended)

Everything is a multiple of 4px. Predictable, consistent, works with most font sizes.

:root {
  --space-0: 0px;
  --space-0.5: 2px;
  --space-1: 4px;
  --space-1.5: 6px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;
  --space-20: 80px;
  --space-24: 96px;
  --space-32: 128px;
}

This matches Tailwind's default scale exactly.

Spacing Usage Guide

| Context | Spacing | Values | |---------|---------|--------| | Inline icon gap | space-1 to space-2 | 4-8px | | Button padding | space-2 x space-4 | 8px 16px | | Card padding | space-4 to space-6 | 16-24px | | Section gap (between elements) | space-6 to space-8 | 24-32px | | Section padding (container) | space-12 to space-16 | 48-64px | | Page section vertical rhythm | space-16 to space-24 | 64-96px |

The Container Width Scale

| Token | Width | Use | |-------|-------|-----| | sm | 640px | Narrow content (auth forms) | | md | 768px | Blog posts, documentation | | lg | 1024px | App layouts | | xl | 1280px | Wide layouts | | 2xl | 1536px | Full-width dashboards |


Dark Mode Derivation
The Inversion Pattern

Don't manually pick dark mode colors. Derive them systematically:

Light mode          ->  Dark mode
neutral-50  (bg)    ->  neutral-950 (bg)
neutral-100 (bg-subtle) -> neutral-900 (bg-subtle)
neutral-200 (border) -> neutral-800 (border)
neutral-300 (border-strong) -> neutral-700 (border-strong)
neutral-500 (text-muted) -> neutral-400 (text-muted)
neutral-600 (text-subtle) -> neutral-300 (text-subtle)
neutral-900 (text)  ->  neutral-50  (text)
neutral-950 (heading) -> neutral-50 (heading)

The rule: Background shades flip (50<->950, 100<->900, 200<->800). Text shades flip similarly. Middle shades (400-600) shift by ~1-2 steps.

Primary Color in Dark Mode
  • Use a lighter step: primary-400 or primary-500 instead of primary-600
  • Reduce saturation slightly for dark backgrounds (avoids eye strain)
  • Verify contrast against neutral-900 or neutral-950 background
Semantic Tokens for Dark Mode
/* Light */
:root {
  --color-bg: var(--neutral-50);
  --color-text: var(--neutral-900);
  --color-primary: var(--primary-600);
}

/* Dark */
.dark {
  --color-bg: var(--neutral-950);
  --color-text: var(--neutral-50);
  --color-primary: var(--primary-400);
}

Components reference semantic tokens, never raw shades. Switching themes means swapping the token mapping.


Consolidation (reducing an over-grown token set)

The inverse of generation: a globals.css has accreted too many near-duplicate tokens. Goal — fewer tokens, identical render. (Method adapted from millionco/skills, MIT.)

REQUIRED order — audit first, edit never-first:

  1. Audit, don't edit. Parse globals.css into blocks (@theme inline, :root, .dark, every scoped block). Count tokens.
  2. Compute the LIVE set transitively. A token is live if its suffix appears as a Tailwind class anywhere, OR it's referenced as var(--name) anywhere (scan every .ts/.tsx/.css/.mdx except globals.css), OR it's referenced inside another live token's value. Iterate to a fixed point.
  3. Count globals.css's own utility classes. A var(--…) inside a .x { … } block (outside :root/.dark/@theme inline) is a hard dependency. Strip the theme blocks from the text first, then collect every remaining var() ref — those tokens MUST stay.
  4. Build a rename map as data (old → new, or DELETE) and apply it to globals.css AND the codebase in ONE codegen pass. Never hand-edit class names across files — the next run reverts hand-fixes.
  5. Verify after every pass: bun run typecheck (or tsgo --noEmit) · biome check --write · bun run build. All green before "done". (pnpm monorepos: pnpm … --filter <app> and the real apps/<app>/app/globals.css path.)

Two levers, in order: (1) dead deletion — zero code usage + zero intra-globals demand → safe; (2) value-similar collapse — rename --a → --b only when the values are within ~5% in BOTH light and dark. Realistic reduction is 50–60%, not 70%.

Do NOT inline tokens into Tailwind arbitrary values (px-[17px], shadow-[#000_0px_1px]). That relocates noise — named tokens carry intent, arbitrary values destroy it. If asked for a bigger number, push back: fewer named tokens beats the same noise in className strings.

Collapse-safety checks (the bugs that bite):

  • Scoped overrides stay. A token set in .dashboard { --x: … } is load-bearing; deleting it silently breaks the scoped override.
  • Same-side rule. Diff a token's light vs dark value. If both sit on the same side of L=0.5 (an always-light or always-dark surface — dropdowns, tooltips), it CANNOT collapse into a flipping token like --foreground/--icon.
  • Transparent-in-one-mode stays. A token that's transparent in one mode and concrete in the other is intentionally see-through; don't merge it with an always-opaque token.
  • Canonical value must win. When N tokens collapse to one name, parse-order "first-write-wins" picks the wrong color. Keep an explicit CANONICAL_SOURCE map naming which source token's value the merged token takes.
  • Name-collision check. Before collapsing a color to name X, grep for --background-image-X and bg-X usage — a new --color-X alias can paint a background-color over a gradient.

Output Formats
CSS Custom Properties
:root {
  /* Type */
  --font-size-base: 1rem;
  --font-size-lg: 1.2rem;
  /* Colors */
  --color-primary-500: hsl(220, 80%, 50%);
  /* Spacing */
  --space-4: 1rem;
}
Tailwind Config
module.exports = {
  theme: {
    extend: {
      fontSize: {
        'xs': '0.694rem',
        'sm': '0.833rem',
        'base': '1rem',
        'lg': '1.2rem',
        'xl': '1.44rem',
      },
      colors: {
        primary: {
          50: 'hsl(220, 50%, 95%)',
          500: 'hsl(220, 80%, 50%)',
          900: 'hsl(220, 60%, 15%)',
        },
      },
    },
  },
}
JSON Design Tokens (W3C Format)
{
  "color": {
    "primary": {
      "500": { "$value": "hsl(220, 80%, 50%)", "$type": "color" }
    }
  },
  "fontSize": {
    "base": { "$value": "1rem", "$type": "dimension" }
  }
}

Step-by-Step: Full Design Token Setup
  1. Ask: What's the project? (marketing site, SaaS app, dashboard?)
  2. Type scale: Pick ratio based on project type -> generate scale
  3. Colors: Get brand color -> generate shade scales for primary + neutral + semantic
  4. Verify contrast: Check all text/bg combos against WCAG AA
  5. Spacing: Use base-4 scale (match Tailwind)
  6. Dark mode: Derive from light palette using inversion pattern
  7. Output: Generate CSS custom properties and/or Tailwind config
Examples
Example 1: "Set up design tokens for a SaaS dashboard"
  • Type: Minor Third (1.2) ratio, 16px base -- clear hierarchy without being dramatic
  • Colors: Generate from brand blue, warm gray neutral
  • Spacing: Base-4 (Tailwind default)
  • Dark mode: Full derivation
Example 2: "I need a color palette from this brand color: #6366F1"
  • Parse HSL: ~239 deg, 84%, 67%
  • Generate 50-950 scale using the shade generation method
  • Map semantic tokens
  • Verify WCAG contrast for all text/bg combos
  • Output as CSS + Tailwind config
Example 3: "Create a type scale for a blog"
  • Ratio: Major Third (1.25) -- strong hierarchy for editorial content
  • Base: 18px (slightly larger for long-form reading)
  • Generate scale with line-height and letter-spacing for each step
按 MIT 许可原样转载,未经改动 · 在 GitHub 查看 →

评论

登录即可评论;带「已验证安装」的,是发布者名下有本店的安装或持有记录。