.claude/skills/shadcn-theming/SKILL.md
shadcn/ui theme customization for NextSpark applications. Covers tweakcn.com integration, CSS variable format, color space conversion, and theme initialization. Use this skill when initializing or customizing the design system for a theme.
npx skillsauth add NextSpark-js/nextspark shadcn-themingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Patterns for customizing shadcn/ui themes in NextSpark using CSS variables and the tweakcn.com editor.
THE THEME IS THE SINGLE SOURCE OF TRUTH FOR DESIGN TOKENS.
All visual customization happens in the theme's globals.css. No inline colors, no hardcoded values.
themes/{THEME}/styles/globals.css → BUILD → core/theme-styles.css → App
THEME CSS STRUCTURE:
themes/{THEME}/styles/
├── globals.css # CSS variables (THE DESIGN SYSTEM)
│ ├── :root # Light mode tokens
│ ├── .dark # Dark mode tokens
│ └── @theme inline # Tailwind v4 mappings
│
└── components.css # Component-specific styles (optional)
BUILD OUTPUT:
└── core/theme-styles.css # Auto-generated (DO NOT EDIT)
Navigate to: https://tweakcn.com/editor/theme
The editor provides:
Base Colors:
Component Colors:
Design Tokens:
Click "Copy CSS" or "Export" to get:
:root {
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--primary: oklch(0.55 0.2 250);
--primary-foreground: oklch(0.985 0 0);
/* ... all variables */
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
/* ... dark mode overrides */
}
:root {
/* === SURFACE COLORS === */
--background: oklch(L C H); /* Page background */
--foreground: oklch(L C H); /* Primary text */
--card: oklch(L C H); /* Card surfaces */
--card-foreground: oklch(L C H); /* Card text */
--popover: oklch(L C H); /* Dropdown/popover bg */
--popover-foreground: oklch(L C H);
/* === INTERACTIVE COLORS === */
--primary: oklch(L C H); /* Primary buttons, links */
--primary-foreground: oklch(L C H); /* Text on primary */
--secondary: oklch(L C H); /* Secondary buttons */
--secondary-foreground: oklch(L C H);
--accent: oklch(L C H); /* Hover highlights */
--accent-foreground: oklch(L C H);
/* === STATE COLORS === */
--muted: oklch(L C H); /* Muted backgrounds */
--muted-foreground: oklch(L C H); /* Placeholder text */
--destructive: oklch(L C H); /* Error/danger */
--destructive-foreground: oklch(L C H);
/* === BORDER & INPUT === */
--border: oklch(L C H); /* Border color */
--input: oklch(L C H); /* Input border */
--ring: oklch(L C H); /* Focus ring */
/* === CHART COLORS === */
--chart-1: oklch(L C H);
--chart-2: oklch(L C H);
--chart-3: oklch(L C H);
--chart-4: oklch(L C H);
--chart-5: oklch(L C H);
/* === SIDEBAR (if dashboard) === */
--sidebar: oklch(L C H);
--sidebar-foreground: oklch(L C H);
--sidebar-primary: oklch(L C H);
--sidebar-primary-foreground: oklch(L C H);
--sidebar-accent: oklch(L C H);
--sidebar-accent-foreground: oklch(L C H);
--sidebar-border: oklch(L C H);
--sidebar-ring: oklch(L C H);
/* === TYPOGRAPHY === */
--font-sans: ui-sans-serif, system-ui, ...;
--font-serif: ui-serif, Georgia, ...;
--font-mono: ui-monospace, SFMono-Regular, ...;
/* === DESIGN TOKENS === */
--radius: 0.625rem; /* Base border radius */
--spacing: 0.25rem; /* Base spacing unit */
/* === SHADOWS === */
--shadow-2xs: ...;
--shadow-xs: ...;
--shadow-sm: ...;
--shadow: ...;
--shadow-md: ...;
--shadow-lg: ...;
--shadow-xl: ...;
--shadow-2xl: ...;
}
.dark {
/* Only override colors that change in dark mode */
/* Typically invert backgrounds/foregrounds */
--background: oklch(0.145 0 0); /* Dark bg */
--foreground: oklch(0.985 0 0); /* Light text */
--card: oklch(0.205 0 0); /* Slightly lighter */
--card-foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0 0); /* Often lighter in dark mode */
--primary-foreground: oklch(0.205 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--border: oklch(0.275 0 0);
--input: oklch(0.325 0 0);
/* Destructive typically stays similar hue but adjusted */
--destructive: oklch(0.704 0.191 22);
/* Chart colors usually stay the same */
}
REQUIRED: Map CSS variables to Tailwind for class-based styling.
@theme inline {
/* Colors */
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
/* Typography */
--font-sans: var(--font-sans);
--font-mono: var(--font-mono);
--font-serif: var(--font-serif);
/* Radius */
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
/* Shadows */
--shadow-2xs: var(--shadow-2xs);
--shadow-xs: var(--shadow-xs);
--shadow-sm: var(--shadow-sm);
--shadow: var(--shadow);
--shadow-md: var(--shadow-md);
--shadow-lg: var(--shadow-lg);
--shadow-xl: var(--shadow-xl);
--shadow-2xl: var(--shadow-2xl);
}
shadcn/ui uses OKLCH color space for perceptually uniform colors.
oklch(Lightness Chroma Hue)
- Lightness: 0-1 (0 = black, 1 = white)
- Chroma: 0-0.4 (0 = gray, higher = more saturated)
- Hue: 0-360 (color angle on color wheel)
| Color | OKLCH | Notes |
|-------|-------|-------|
| White | oklch(1 0 0) | L=1, no chroma |
| Black | oklch(0 0 0) | L=0 |
| Pure Gray | oklch(0.5 0 0) | Mid gray, no chroma |
| Blue Primary | oklch(0.55 0.2 250) | Typical blue |
| Red Destructive | oklch(0.577 0.245 27) | shadcn default red |
| Green Success | oklch(0.6 0.2 145) | Typical green |
| Orange Warning | oklch(0.7 0.2 65) | Typical orange |
Use online converters or JavaScript:
// Using culori library
import { oklch, formatCss } from 'culori'
const hex = '#137fec'
const oklchColor = oklch(hex)
// { mode: 'oklch', l: 0.55, c: 0.2, h: 250 }
const cssValue = `oklch(${oklchColor.l.toFixed(4)} ${oklchColor.c.toFixed(4)} ${oklchColor.h?.toFixed(4) || 0})`
// "oklch(0.5500 0.2000 250.0000)"
# 1. Customize at tweakcn.com/editor/theme
# 2. Copy the CSS export
# 3. Run the command with the CSS file
/theme:design-system path/to/exported-theme.css
The command will:
@theme inline mappings if neededglobals.csspnpm theme:buildUse how-to:customize-theme command with a mock folder:
# Extract DS from a mock design
how-to:customize-theme --from-mock path/to/mock/folder
The process will:
design-system skill for patternsglobals.csspnpm theme:buildAfter modifying globals.css:
# Rebuild theme CSS
pnpm theme:build
# Or with watch mode
pnpm theme:build --watch
What Build Does:
NEXT_PUBLIC_ACTIVE_THEME from .envthemes/{THEME}/styles/globals.css + components.csscore/theme-styles.csspublic/theme/Before finalizing theme customization:
:root.dark@theme inline section present with all mappings--radius uses rem unitspnpm theme:build runs without errors:root {
/* Brand blue as primary */
--primary: oklch(0.55 0.2 250); /* #137fec equivalent */
--primary-foreground: oklch(0.985 0 0); /* White text on blue */
/* Brand blue tint for secondary */
--secondary: oklch(0.95 0.03 250); /* Very light blue */
--secondary-foreground: oklch(0.25 0 0); /* Dark text */
/* Brand blue for accent */
--accent: oklch(0.92 0.05 250); /* Light blue hover */
--accent-foreground: oklch(0.25 0 0);
}
.dark {
/* Keep brand color vibrant in dark mode */
--primary: oklch(0.65 0.2 250); /* Slightly lighter */
--primary-foreground: oklch(0.1 0 0); /* Dark text on light primary */
/* Muted versions for backgrounds */
--secondary: oklch(0.25 0.03 250); /* Dark blue-gray */
--secondary-foreground: oklch(0.95 0 0); /* Light text */
}
/* ❌ NEVER: Use HEX or HSL in globals.css */
--primary: #137fec;
--primary: hsl(210, 100%, 50%);
/* ✅ CORRECT: Use OKLCH */
--primary: oklch(0.55 0.2 250);
/* ❌ NEVER: Skip dark mode */
/* (Will look terrible in dark mode) */
/* ✅ CORRECT: Define complete dark mode */
.dark {
--background: oklch(0.145 0 0);
/* ... all overrides */
}
/* ❌ NEVER: Skip @theme inline */
/* (Tailwind classes won't work) */
/* ✅ CORRECT: Include complete mapping */
@theme inline {
--color-background: var(--background);
/* ... all mappings */
}
/* ❌ NEVER: Edit core/theme-styles.css */
/* (Will be overwritten on next build) */
/* ✅ CORRECT: Edit themes/{THEME}/styles/globals.css */
tailwind-theming - Tailwind CSS patterns and buildSectionClassesdesign-system - Token mapping from mocksshadcn-components - Component usage patternsdevelopment
Zod validation patterns for this Next.js application. Covers schema definition, API validation, form integration, error formatting, and type inference. Use this skill when implementing validation for APIs, forms, or entity schemas.
development
Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".
testing
Test coverage metrics and registry system for this Next.js application. Covers FEATURE_REGISTRY, FLOW_REGISTRY, TAGS_REGISTRY, and coverage metrics interpretation. Use this skill when evaluating test coverage, identifying gaps, or planning testing priorities.
development
TanStack Query (React Query) patterns for data fetching in this Next.js application. Covers useQuery, useMutation, optimistic updates, cache invalidation, and anti-patterns. Use this skill when implementing data fetching or state management with server data.