ui-theme

|

higashi-kota/drawing-explorer1 installsMITSynced Aug 22

Works with

Claude CodeCursorCodex CLIGitHub CopilotGemini CLI
---
name: ui-theme
description: |
license: MIT
---

# UI Theme Skill

## Architecture Overview

```
design-tokens/                   # Design token source of truth
├── src/
│   ├── build.ts                 # Style Dictionary build script (TypeScript)
│   └── tokens/                  # Token definitions (JSON)
│       ├── colors/
│       │   ├── base.json        # Color palette (gray, blue, cyan, etc.)
│       │   └── semantic.json    # Semantic color aliases
│       ├── spacing/index.json
│       ├── typography/index.json
│       ├── radius/index.json
│       ├── shadow/index.json
│       └── animation/index.json
└── dist/
    ├── tokens.css               # Plain CSS variables (:root)
    └── tailwind-theme.css       # Tailwind CSS v4 @theme block
```

## Design Token Workflow

### 1. Define Tokens in JSON

Tokens are defined using Style Dictionary format:

```json
// colors/base.json - Raw color values
{
  "color": {
    "base": {
      "gray": {
        "50": { "value": "#f8fafc" },
        "500": { "value": "#64748b" },
        "900": { "value": "#0f172a" }
      },
      "cyan": {
        "500": { "value": "#06b6d4" },
        "600": { "value": "#0891b2" }
      }
    }
  }
}

// colors/semantic.json - Semantic aliases
{
  "color": {
    "semantic": {
      "background": { "value": "{color.base.gray.50}" },
      "foreground": { "value": "{color.base.gray.900}" },
      "primary": { "value": "{color.base.cyan.600}" },
      "primary-hover": { "value": "{color.base.cyan.700}" }
    }
  }
}
```

### 2. Build Tokens

Run the Style Dictionary build script to generate CSS output:

```bash
pnpm build  # Runs: tsx src/build.ts
```

Output generates:
- `dist/tokens.css` - Plain `:root { --color-primary: #0891b2; }`
- `dist/tailwind-theme.css` - Tailwind v4 `@theme { --color-primary: #0891b2; }`

### 3. Import in Application

```css
/* Import generated theme */
@import "design-tokens/tailwind-theme.css";

/* Global base styles (html, body, scrollbar, etc.) */
```

### 4. Use in Components

```tsx
// Tailwind utility classes work with tokens
<div className="bg-background text-foreground border-border" />

// Or CSS variables directly
<div style={{ backgroundColor: 'var(--color-primary)' }} />
```

## Style Dictionary Configuration

### Custom Format for Tailwind CSS v4

The build script registers a custom format that outputs `@theme` blocks:

```typescript
import StyleDictionary from "style-dictionary"
import type { FormatFn } from "style-dictionary/types"

const tailwindThemeFormat: FormatFn = ({ dictionary }) => {
  // Groups tokens by category (color, spacing, font, etc.)
  // Outputs @theme block with simplified names:
  //   color-semantic-primary → --color-primary
  //   color-base-gray-500 → --color-gray-500
  return `@import "tailwindcss";

@theme {
  --color-primary: #0891b2;
  --spacing-4: 1rem;
  ...
}`;
};

StyleDictionary.registerFormat({
  name: "css/tailwind-theme",
  format: tailwindThemeFormat,
});
```

### Adding New Tokens

1. Add token to appropriate JSON file in `src/tokens/`
2. Run build command
3. Token is automatically available as CSS variable and Tailwind utility

## Design Methodology

### 1. Define Design Direction

Before implementing, establish a clear aesthetic direction:

- **Purpose**: What problem does this UI solve? Who uses it?
- **Tone**: Professional/Industrial, Playful, Minimal, Editorial, etc.
- **Color Philosophy**: Choose a hue family (e.g., cool slate ~260, warm gray ~45)
- **Differentiation**: What makes this design memorable?

### 2. Color System

Define colors in base tokens then create semantic aliases:

```json
// Base colors - Raw palette values
{
  "color": {
    "base": {
      "gray": {
        "50": { "value": "#f8fafc" },
        "100": { "value": "#f1f5f9" },
        "200": { "value": "#e2e8f0" },
        "500": { "value": "#64748b" },
        "600": { "value": "#475569" },
        "900": { "value": "#0f172a" }
      },
      "cyan": {
        "500": { "value": "#06b6d4" },
        "600": { "value": "#0891b2" },
        "700": { "value": "#0e7490" }
      }
    }
  }
}

// Semantic colors - UI-specific aliases
{
  "color": {
    "semantic": {
      "background": { "value": "{color.base.gray.50}" },
      "foreground": { "value": "{color.base.gray.900}" },
      "muted": { "value": "{color.base.gray.100}" },
      "muted-foreground": { "value": "{color.base.gray.500}" },
      "primary": { "value": "{color.base.cyan.600}" },
      "primary-foreground": { "value": "{color.base.white}" },
      "primary-hover": { "value": "{color.base.cyan.700}" },
      "border": { "value": "{color.base.gray.200}" },
      "ring": { "value": "{color.base.cyan.600}" },
      "ring-offset": { "value": "{color.base.white}" }
    }
  }
}
```

### 3. Token Categories

| Category | File | Variables |
|----------|------|-----------|
| Colors | `colors/base.json`, `colors/semantic.json` | `--color-*` |
| Spacing | `spacing/index.json` | `--spacing-*` |
| Typography | `typography/index.json` | `--font-*` |
| Border Radius | `radius/index.json` | `--radius-*` |
| Shadows | `shadow/index.json` | `--shadow-*` |
| Animation | `animation/index.json` | `--duration-*`, `--easing-*` |

## Typography

```css
@theme {
  --font-sans: "Inter", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", monospace;

  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
}
```

## Animation Tokens

```css
@theme {
  --duration-instant: 50ms;
  --duration-fast: 100ms;
  --duration-normal: 150ms;
  --duration-slow: 250ms;

  --easing-default: cubic-bezier(0.4, 0, 0.2, 1);
  --easing-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}
```

## Modern Color Features

### OKLCH Color Space (Recommended)

Perceptually uniform color space for predictable color manipulation:

```css
@theme {
  /* OKLCH: lightness (0-100%), chroma (0-0.4), hue (0-360) */
  --color-primary: oklch(55% 0.2 240);        /* Vibrant blue */
  --color-primary-light: oklch(75% 0.15 240);
  --color-primary-dark: oklch(35% 0.2 240);

  /* Consistent gray scale */
  --color-gray-50: oklch(97% 0.005 240);
  --color-gray-100: oklch(93% 0.005 240);
  --color-gray-500: oklch(55% 0.005 240);
  --color-gray-900: oklch(15% 0.005 240);
}
```

**Benefits:**
- Consistent perceived brightness across hues
- Predictable lightness modifications
- Better for accessibility contrast calculations
- Wider gamut support (P3 displays)

### color-mix() Function

Generate color variations dynamically:

```css
.button {
  --base: var(--color-primary);

  background: var(--base);

  &:hover {
    /* Mix with white for lighter */
    background: color-mix(in oklch, var(--base), white 20%);
  }

  &:active {
    /* Mix with black for darker */
    background: color-mix(in oklch, var(--base), black 20%);
  }
}

/* Semi-transparent variations */
.overlay {
  background: color-mix(in oklch, var(--color-primary) 50%, transparent);
}
```

### @property for Animated Variables

Enable CSS variable animations:

```css
@property --gradient-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

@property --glow-opacity {
  syntax: "<number>";
  initial-value: 0;
  inherits: false;
}

.animated-border {
  background: conic-gradient(
    from var(--gradient-angle),
    var(--color-primary),
    var(--color-secondary),
    var(--color-primary)
  );
  animation: spin 3s linear infinite;
}

@keyframes spin {
  to { --gradient-angle: 360deg; }
}
```

### light-dark() for Theme Switching

Single-declaration dark mode:

```css
:root {
  color-scheme: light dark;
}

.card {
  background: light-dark(var(--color-gray-50), var(--color-gray-900));
  color: light-dark(var(--color-gray-900), var(--color-gray-50));
  border-color: light-dark(var(--color-gray-200), var(--color-gray-700));
}
```

## Dark Mode Strategy

### CSS-Only Approach

```css
/* Semantic tokens with light-dark() */
:root {
  color-scheme: light dark;

  --background: light-dark(oklch(98% 0 0), oklch(12% 0 0));
  --foreground: light-dark(oklch(12% 0 0), oklch(98% 0 0));
  --muted: light-dark(oklch(95% 0 0), oklch(20% 0 0));
  --border: light-dark(oklch(90% 0 0), oklch(25% 0 0));
}
```

### Token-Based Approach (Style Dictionary)

```json
// tokens/colors/semantic-light.json
{
  "color": {
    "semantic": {
      "background": { "value": "{color.base.gray.50}" },
      "foreground": { "value": "{color.base.gray.900}" }
    }
  }
}

// tokens/colors/semantic-dark.json
{
  "color": {
    "semantic": {
      "background": { "value": "{color.base.gray.900}" },
      "foreground": { "value": "{color.base.gray.50}" }
    }
  }
}
```

## A11y Checklist

- [ ] Contrast ratios: 4.5:1 text, 3:1 UI components
- [ ] Focus visible: 2px+ ring on all interactive elements
- [ ] Touch targets: min 24x24 CSS pixels
- [ ] Reduced motion: respect `prefers-reduced-motion`

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

## References

- [Style Dictionary Documentation](https://amzn.github.io/style-dictionary/)
- [Tailwind CSS v4 Theme](https://tailwindcss.com/docs/theme)
- [Design Tokens W3C](https://www.w3.org/community/design-tokens/)

More Design Systems skills

stitch-design-taste

leonxlnx/taste-skill

Semantic Design System Skill for Google Stitch. Generates agent-friendly DESIGN.md files that enforce premium, anti-generic UI standards — strict typography, calibrated color, asymmetric layouts, perpetual micro-motion, and hardware-accelerated performance.

265.6k

figma

heygen-com/hyperframes

Import Figma content into a HyperFrames composition — rendered assets, brand tokens, components, storyboard sections → reconstructed motion (frames read as states, not slides) (REST/CLI), connector-assisted motion when available, and shaders from a connector or native export. Use when the user pastes a figma.com link or asks to bring a Figma design, frame, logo, brand, or animation into a video/composition.

101.8k

image

coreyhaines31/marketingskills

When the user wants to create, generate, edit, or optimize images for marketing — blog heroes, social graphics, product mockups, profile banners, listing visuals, or brand assets. Also use when the user mentions 'AI image generation,' 'generate an image,' 'create a graphic,' 'product mockup,' 'hero image,' 'social media graphic,' 'banner image,' 'cover photo,' 'profile banner,' 'listing screenshot,' 'Flux,' 'Flux Kontext,' 'Midjourney,' 'DALL-E,' 'GPT Image,' 'ChatGPT Images,' 'Ideogram,' 'Gemini image,' 'Nano Banana,' 'Recraft,' 'Stable Diffusion,' 'Canva,' 'Figma,' 'image optimization,' 'compress images,' 'WebP,' or 'OG image.' Use this for general-purpose marketing image creation and optimization. For paid ad image creative and platform-specific ad specs, see ad-creative. For video production, see video.

62.9k

← All Design Systems skills

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY