design-system

zzoohub's avatarfrom zzoohub

Modern design token systems and headless component architecture. Covers W3C DTCG tokens, multi-tier hierarchy, headless/styled separation, compound components, and accessibility. Use when building design systems for web or React Native.

⭐0stars🔀0forks📁View on GitHub🕐Updated Jan 10, 2026

When & Why to Use This Skill

This Claude skill provides a comprehensive framework for building scalable design systems using W3C DTCG-compliant tokens and headless component architecture. It bridges the gap between design and implementation by offering structured guidance on multi-tier token hierarchies, accessibility standards, and cross-platform UI development for Web and React Native, ensuring high maintainability and consistent user experiences.

Use Cases

  • Architecting a multi-tier design token system (Primitive, Semantic, Component) to enable seamless theme switching, dark mode support, and brand updates.
  • Developing headless UI components that decouple logic and accessibility from visual styles, ensuring consistent behavior across different platforms like Web and React Native.
  • Ensuring WCAG compliance by implementing standardized accessibility requirements for color contrast, focus indicators, and touch target sizes.
  • Standardizing component libraries through composition patterns and polymorphic components to reduce code duplication and improve developer experience.
namedesign-system
description|
Use whenimplementing design-system, building UI components, defining tokens, creating themed interfaces.
Do not use forUX decisions (use ux-design), business logic, data fetching.
Workflowux-design (what/why) → this skill (tokens, components) → nextjs/expo-react-native (integration).

Design System

Token Architecture

Multi-Tier Hierarchy

Tier 1: Primitive     →  Raw values, no meaning
Tier 2: Semantic      →  Intent/purpose ← USE THIS
Tier 3: Component     →  (Optional) Component-specific overrides
color.blue.500              (primitive) - NEVER use directly
    ↓
color.interactive.primary   (semantic) ← use this in components
    ↓
button.bg.primary           (component, optional)

Rule: Components only reference Semantic tokens. Never Primitive.

Why 3 Tiers?

Change What to update Impact
Brand refresh Tier 1 (Primitive) All semantics auto-update
Dark mode Tier 2 (Semantic) Components unchanged
One-off exception Tier 3 (Component) Isolated change

Semantic Token Categories

Category Purpose Examples
color.bg.* Backgrounds primary, secondary, inverse
color.text.* Typography primary, secondary, link
color.interactive.* Actions primary, primaryHover, primaryActive
color.border.* Borders default, strong, focus
color.status.* Feedback error, success, warning
spacing.component.* Inside components xs, sm, md, lg, xl
spacing.layout.* Between sections xs, sm, md, lg, xl

Component Architecture

Headless + Styled Separation

┌──────────────────────────────────────┐
│  Headless Layer                      │
│  Behavior + A11y + Keyboard          │
│  No styles, reusable across brands   │
└──────────────────────────────────────┘
                 ↓
┌──────────────────────────────────────┐
│  Styled Layer                        │
│  Headless + Tokens = UI Component    │
└──────────────────────────────────────┘

Rule: Headless handles behavior. Styled handles appearance. Never mix.

Why Separate?

Change What to update Other layer
Keyboard navigation fix Headless hook Styled unchanged
Brand color change Styled component Headless unchanged
New accessibility requirement Headless hook Styled unchanged

File Structure

src/shared/ui/
├── tokens/          # primitive, semantic, themes
├── headless/        # useButton, useToggle, useDialog
├── styled/          # Button, Toggle, Dialog (uses headless)
├── primitives/      # Box, Text, Stack
└── patterns/        # FormField, ConfirmDialog

Preferred Patterns

Pattern Preferred Avoid Why
Props variant="primary" size="lg" primary large (booleans) Explicit, mutually exclusive
Composition <Card><Card.Header> <Card showHeader headerTitle=""> Flexible, readable
Polymorphic <Box as="section"> Separate <Section> component Semantic HTML, less components
State Headless hook + Styled Mixed logic/styles Separation of concerns

Rule: Variant props over booleans. Composition over configuration.


Platform Output

Web (CSS Custom Properties)

:root {
  --color-bg-primary: #ffffff;
  --color-text-primary: #0f172a;
  --color-interactive-primary: #2563eb;
}

[data-theme="dark"] {
  --color-bg-primary: #0f172a;
  --color-text-primary: #f9fafb;
}

React Native (TypeScript)

export const tokens = {
  color: {
    bg: { primary: '#ffffff', secondary: '#f9fafb' },
    text: { primary: '#0f172a', secondary: '#475569' },
    interactive: { primary: '#2563eb' },
  },
  spacing: {
    component: { xs: 4, sm: 8, md: 12, lg: 16, xl: 24 },
  },
} as const;

Accessibility Requirements

Requirement Value Non-negotiable
Text contrast 4.5:1 minimum ✅
UI component contrast 3:1 minimum ✅
Focus indicator 2px+ visible outline ✅
Touch targets 44×44pt minimum ✅

Rule: Color is never the only indicator. Always pair with icon, text, or pattern.

Focus States

:focus-visible {
  outline: 2px solid var(--color-border-focus);
  outline-offset: 2px;
}

:focus:not(:focus-visible) {
  outline: none;
}

Reduced Motion

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

Quick Checklist

Tokens

  • No hardcoded values in components (colors, spacing, etc.)
  • Using Semantic tokens, not Primitive
  • Dark theme remaps Semantic tokens only

Components

  • Headless hook for behavior + a11y
  • Styled component uses tokens only
  • Using variant / size / colorScheme props (not booleans)
  • All states defined: default, hover, focus, active, disabled, loading

Accessibility

  • Color not sole indicator
  • Focus visible (2px+ outline)
  • Touch targets 44pt+
  • Reduced motion respected
  • ARIA attributes correct