Styleguide
A comprehensive design system for building consistent, accessible, and beautiful user interfaces. Built with React, Tailwind CSS, and Base UI.
Foundations
Colors, typography, spacing, and core visual elements
Components
Reusable UI components with multiple variants and states
Guidelines
Accessibility standards, theming, and best practices
Quick Start
Install the UI package and start building
npm install @repo/ui
import { Button, Card, Badge } from "@repo/ui";
export default function Page() {
return (
<Card>
<Badge variant="accent">New</Badge>
<h1>Welcome</h1>
<Button>Get Started</Button>
</Card>
);
}Colors
A semantic color system with light and dark mode support. Colors are defined as CSS custom properties for easy theming.
Background & Surface
Base colors for layouts and containers
Background
--color-bg
Page background
Surface
--color-surface
Card backgrounds
Surface 2
--color-surface-2
Nested elements
Text
Text colors for hierarchy
Text
--color-text
Primary text
Text Secondary
--color-text-secondary
Secondary text
Text Muted
--color-text-muted
Placeholder, disabled
Border
Border and divider colors
Border
--color-border
Default borders
Border Strong
--color-border-strong
Emphasized borders
Brand
Primary and accent colors
Primary
--color-primary
Primary actions
Accent
--color-accent
Highlights, links
Accent Subtle
--color-accent-subtle
Accent backgrounds
Semantic
Status and feedback colors
Success
--color-success
Success Subtle
--color-success-subtle
Warning
--color-warning
Warning Subtle
--color-warning-subtle
Danger
--color-danger
Danger Subtle
--color-danger-subtle
Info
--color-info
Info Subtle
--color-info-subtle
Usage
/* Use CSS variables directly */
.my-element {
background: var(--color-surface);
color: var(--color-text);
border: 1px solid var(--color-border);
}
/* Or with Tailwind arbitrary values */
<div className="bg-[var(--color-surface)] text-[var(--color-text)]">
Content
</div>Typography
A type scale designed for clarity and hierarchy. Uses Inter for UI text and a monospace font for code.
Type Scale
Predefined text styles for consistent hierarchy
Display
Heading 1
Heading 2
Heading 3
Heading 4
Body large text for introductions and emphasis
Body text for paragraphs and general content
Small body text for captions and metadata
/EYEBROW LABEL
Font Families
Sans (UI)
Inter, system-ui, sans-serif
Mono (Code)
Geist Mono, JetBrains Mono, monospace
Guidelines
• Keep line length between 60-90 characters for readability
• Use heading hierarchy consistently (don't skip levels)
• Reserve ALL CAPS for short labels and eyebrows only
• Use monospace font for code, technical values, and IDs
Spacing
An 8px-based spacing scale for consistent layouts. Use these values for margins, padding, and gaps.
Spacing Scale
Based on 8px increments for visual rhythm
space-0space-1space-2space-3space-4space-6space-8space-10space-12space-16space-20space-24Usage Examples
// Tailwind classes
<div className="p-4 m-6 gap-3">
<div className="space-y-4">
<p>Vertical spacing</p>
</div>
</div>
// CSS variables
.element {
padding: var(--space-4);
margin: var(--space-6);
gap: var(--space-3);
}Elevation
Shadow levels for creating depth and visual hierarchy. Use sparingly for a clean, flat aesthetic.
Level 0
Default state, use borders
Level 1
Dropdowns, tooltips
--shadow-smLevel 2
Modals, dialogs
--shadow-mdBorder Radius
Consistent corner rounding for UI elements. Smaller radii for inputs and buttons, larger for cards.
None
0px
Small
4px
Medium
8px
Large
12px
XL
16px
Full
9999px
Usage Guidelines
• None/Small (0-4px): Terminal elements, code blocks
• Medium (8px): Buttons, inputs, badges
• Large (12px): Cards, modals, containers
• Full: Avatars, pills, circular buttons
Motion
Animation timing and easing for smooth, purposeful interactions. Motion should provide feedback, not decoration.
Duration
Timing for different interaction types
Fast
Hover, focus states
120msDefault
Most transitions
200msSlow
Complex animations
300msEasing
Curves for natural movement
Default
cubic-bezier(0.2, 0, 0, 1)Exit
cubic-bezier(0.4, 0, 1, 1)Spring
cubic-bezier(0.34, 1.56, 0.64, 1)Reduced Motion
All animations respect the prefers-reduced-motion media query. When reduced motion is preferred, animations are disabled or significantly reduced.
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}Icons
Using Lucide React icons for consistent, accessible iconography.
Icon Sizes
Standard sizes for different contexts
16px
Inline
20px
Default
24px
Large
32px
Hero
Common Icons
Form Inputs
Text inputs, labels, and form controls for user data entry.
Input Variants
This field is required
Usage
import { Input } from "@repo/ui/input";
import { Label } from "@repo/ui/label";
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input
id="email"
type="email"
placeholder="you@example.com"
icon={<Mail className="h-4 w-4" />}
/>
</div>
// Error state
<Input error placeholder="Invalid" />
<Label error>Error message</Label>Cards
Container components for grouping related content.
Default Card
Standard card with border
Use for static content grouping.
Interactive Card
Hover for effect
Use for clickable cards and links.
Ghost Card
No background
Use for subtle content grouping.
Badges
Small labels for status, categories, and counts.
Variants
Sizes
Use Cases
Dialogs
Modal dialogs for focused interactions and confirmations.
Features
• Focus trap keeps keyboard navigation inside the dialog
• Escape key closes the dialog
• Click outside to dismiss (backdrop click)
• Animated entrance and exit
• Scroll lock on body when open
• Accessible with proper ARIA attributes
Code Blocks
Syntax-highlighted code display with copy functionality.
Inline Code
Use npm install to install packages. Import components like import { Button } from "@repo/ui".
Code Block with Language
interface User {
id: string;
email: string;
name: string;
}
async function getUser(id: string): Promise<User> {
const response = await fetch(`/api/users/${id}`);
return response.json();
}Code Block with Filename
export function Button({ children, onClick }) {
return (
<button
onClick={onClick}
className="px-4 py-2 rounded-lg bg-primary"
>
{children}
</button>
);
}Terminal
Terminal-style display for command-line output and examples.
$ npm create blah-app@latest my-app
Creating a new application...
Installing dependencies...
✓ Project created successfully!
$ cd my-app
$ npm run dev
Starting development server...
→ Local: http://localhost:3000
Feedback
Components for communicating status, errors, and information to users.
Alert Messages
Information
This is an informational message for the user.
Success
Your changes have been saved successfully.
Warning
Please review your input before continuing.
Error
Something went wrong. Please try again.
Accessibility
Guidelines for building inclusive and accessible interfaces.
Keyboard Navigation
• All interactive elements are focusable
• Tab order follows visual layout
• Focus indicators are always visible
• Dialogs trap focus when open
• Escape key closes overlays
Color Contrast
• Body text meets WCAG AA (4.5:1)
• Large text meets WCAG AA (3:1)
• Interactive elements have sufficient contrast
• Focus rings are clearly visible
Screen Readers
• Semantic HTML elements used throughout
• ARIA labels for icon-only buttons
• Live regions for dynamic content
• Proper heading hierarchy
Motion
• Respects prefers-reduced-motion
• No essential information conveyed by motion alone
• Animations are subtle and purposeful
Focus Ring
All focusable elements display a visible focus ring when navigated via keyboard.
Theming
Light and dark mode support with CSS custom properties.
Theme Toggle
Switch between light and dark modes
Click to toggle theme. Preference is saved to localStorage.
Implementation
// Theme is controlled via data-theme attribute on <html>
<html data-theme="dark">
// Or use system preference (default)
<html> // No data-theme = follows system
// Toggle theme with JavaScript
function toggleTheme() {
const current = document.documentElement.getAttribute('data-theme');
const next = current === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', next);
localStorage.setItem('theme', next);
}CSS Variables
All colors are defined as CSS custom properties
:root {
--color-bg: #FFFFFF;
--color-text: #111111;
--color-accent: #F5A623;
}
[data-theme="dark"] {
--color-bg: #0B0B0B;
--color-text: #F2F2F2;
--color-accent: #F5A623;
}