Install
$ agentstack add skill-darkroomengineering-cc-settings-design-tokens ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
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 | |-----------|-------------|-----| | = 4.5:1 | Body text (= 3:1 | >= 18px regular or >= 14px bold | | AAA Normal Text | >= 7:1 | Enhanced accessibility | | AA UI Components | >= 3:1 | Borders, icons, focus rings |
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:
text(900) onbg(50) -> must be >= 4.5:1text-muted(500) onbg(50) -> must be >= 4.5:1primary(600) onwhite-> must be >= 4.5:1primary-textonprimary(600) -> must be >= 4.5:1border(200) onbg(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 (50950, 100900, 200800). Text shades flip similarly. Middle shades (400-600) shift by ~1-2 steps.
Primary Color in Dark Mode
- Use a lighter step:
primary-400orprimary-500instead ofprimary-600 - Reduce saturation slightly for dark backgrounds (avoids eye strain)
- Verify contrast against
neutral-900orneutral-950background
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:
- Audit, don't edit. Parse
globals.cssinto blocks (@theme inline,:root,.dark, every scoped block). Count tokens. - 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/.mdxexceptglobals.css), OR it's referenced inside another live token's value. Iterate to a fixed point. - 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 remainingvar()ref — those tokens MUST stay. - Build a rename map as data (
old → new, orDELETE) 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. - Verify after every pass:
bun run typecheck(ortsgo --noEmit) ·biome check --write·bun run build. All green before "done". (pnpm monorepos:pnpm … --filterand the realapps//app/globals.csspath.)
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
transparentin 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_SOURCEmap naming which source token's value the merged token takes. - Name-collision check. Before collapsing a color to name
X, grep for--background-image-Xandbg-Xusage — a new--color-Xalias 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
- Ask: What's the project? (marketing site, SaaS app, dashboard?)
- Type scale: Pick ratio based on project type -> generate scale
- Colors: Get brand color -> generate shade scales for primary + neutral + semantic
- Verify contrast: Check all text/bg combos against WCAG AA
- Spacing: Use base-4 scale (match Tailwind)
- Dark mode: Derive from light palette using inversion pattern
- 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
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: darkroomengineering
- Source: darkroomengineering/cc-settings
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.