Token System Guide
Token System Guide
This guide explains how to use the theme’s design token system effectively, covering both shadcn/ui tokens and our semantic tokens.
Token Architecture
The token system is organized into several key areas:
-
Base Tokens (
src/styles/tokens/
)colors.ts
: HSL color values and opacity levelstypography.ts
: Font families, sizes, and scalesradius.ts
: Border radius valuestheme.ts
: Theme configuration and variable generation
-
Semantic Tokens (CSS Variables)
- Generated from base tokens
- Theme-aware (light/dark)
- Accessible through CSS variables
-
Component Tokens (shadcn/ui)
- Built on semantic tokens
- Component-specific variants
- Consistent across theme changes
When to Use What
1. Direct Tailwind Classes
Use for:
- One-off styles that don’t need theming
- Layout properties (margin, padding, grid, flex)
- Responsive design
- Animation and transitions
// ✅ Good: Layout and spacing
<div className="mt-4 grid gap-6 md:grid-cols-2">
// ✅ Good: One-off styles
<span className="inline-block rotate-90">
// ❌ Bad: Theme-dependent styles
<div className="bg-slate-900 text-white">
2. Semantic Tokens
Use for:
- Theme-aware styles
- Brand colors
- Typography
- Spacing patterns
// ✅ Good: Theme-aware background
<div className="bg-background text-foreground">
// ✅ Good: Semantic colors
<div className="border-border bg-card">
// ❌ Bad: Hard-coded colors
<div className="bg-[#242424]">
3. Component Tokens
Use for:
- shadcn/ui components
- Custom components that follow shadcn/ui patterns
- Consistent interactive elements
// ✅ Good: Component variants
<Button variant="secondary" size="sm">
// ✅ Good: Custom component using shadcn tokens
<Card className="bg-card text-card-foreground">
// ❌ Bad: Mixed token systems
<Button className="bg-background hover:bg-slate-100">
Color System
Our color system uses HSL values for better theme handling:
/* Base Colors */
--slate: 0 0% 14%; /* #242424 */
--cream: 20 20% 93%; /* #EFE8E8 */
--red: 0 84% 60%; /* Accent */
/* Semantic Colors */
--background: hsl(var(--cream));
--foreground: hsl(var(--slate));
--border: hsl(var(--slate) / var(--border-opacity));
Using Colors
// ✅ Good: Semantic color usage
<div className="bg-background text-foreground">
<div className="border-border/20"> {/* Using opacity */}
// ❌ Bad: Direct HSL values
<div className="bg-[hsl(0,0%,14%)]">
Typography System
Typography tokens are available for consistent text styling:
// ✅ Good: Font family tokens
<p className="font-sans">
<code className="font-mono">
// ✅ Good: Font size scale
<h1 className="text-4xl">
<p className="text-sm text-muted-foreground">
// ❌ Bad: Custom sizes
<p className="text-[14px]">
Component Variants
When creating custom components, follow the shadcn/ui pattern:
// ✅ Good: Consistent variant pattern
const Card = ({
variant = "default",
size = "default",
className,
...props
}) => {
return (
<div
className={cn(
"bg-card text-card-foreground",
variants[variant],
sizes[size],
className
)}
{...props}
/>
);
};
Best Practices
-
Consistency First
- Use semantic tokens for theme-aware styles
- Use Tailwind for layout and one-off styles
- Follow shadcn/ui patterns for components
-
Accessibility
- Use semantic color combinations
- Maintain WCAG contrast ratios
- Test in both light and dark themes
-
Maintainability
- Don’t mix token systems
- Document custom values
- Use type-safe token imports
-
Performance
- Prefer CSS variables over JavaScript
- Use Tailwind’s JIT for custom values
- Minimize runtime theme calculations
Type Safety
The token system is fully typed:
import type { ColorTokens } from '@/types';
// ✅ Good: Type-safe token usage
const theme: ColorTokens = {
background: `hsl(var(--cream))`,
foreground: `hsl(var(--slate))`,
};
// ✅ Good: Variant types
type ButtonVariant = "default" | "secondary" | "ghost";
// ❌ Bad: Untyped values
const colors = {
primary: "#242424", // Use HSL and types
};
Common Patterns
1. Opacity Variants
// ✅ Good: Using opacity tokens
<div className="border-border/20">
<p className="text-foreground/60">
// ❌ Bad: Arbitrary opacity
<div className="border-border/[0.15]">
2. Interactive States
// ✅ Good: State handling
<button className="bg-primary hover:bg-primary/90 active:bg-primary/80">
// ❌ Bad: Inconsistent states
<button className="hover:opacity-50">
3. Dark Mode
// ✅ Good: Theme-aware styles
<div className="bg-background dark:bg-background">
// ❌ Bad: Manual dark mode
<div className="bg-white dark:bg-slate-900">
Migration Guide
When updating existing components:
- Replace hard-coded colors with semantic tokens
- Update typography to use the scale
- Refactor variants to match shadcn/ui patterns
- Test in both themes
- Verify accessibility
Further Reading
design-system
documentation