# Foundations **The building blocks of our design system**: OKLCH colors, typography scale, spacing tokens, shadows, and border radius. Master these fundamentals to build consistent, accessible interfaces. --- ## Table of Contents 1. [Technology Stack](#technology-stack) 2. [Color System (OKLCH)](#color-system-oklch) 3. [Typography](#typography) 4. [Spacing Scale](#spacing-scale) 5. [Shadows](#shadows) 6. [Border Radius](#border-radius) 7. [Quick Reference](#quick-reference) --- ## Technology Stack ### Core Technologies - **Framework**: Next.js 16 + React 19 - **Styling**: Tailwind CSS 4 (CSS-first configuration) - **Components**: shadcn/ui (New York style) - **Color Space**: OKLCH (perceptually uniform) - **Icons**: lucide-react - **Fonts**: Geist Sans + Geist Mono ### Design Principles 1. **🎨 Semantic First** - Use `bg-primary`, not `bg-blue-500` 2. **♿ Accessible by Default** - WCAG AA compliance minimum (4.5:1 contrast) 3. **📐 Consistent Spacing** - Multiples of 4px (0.25rem base unit) 4. **🧩 Compose, Don't Create** - Use shadcn/ui primitives 5. **🌗 Dark Mode Ready** - All components work in light/dark 6. **⚡ Pareto Efficient** - 80% of needs with 20% of patterns --- --- > [!NOTE] > **Branding vs. Design System**: These foundations implement the visual identity defined in the **[Branding Guidelines](../branding/README.md)**. Refer to that document for the "why" behind these choices. ## Color System (OKLCH) ### Why OKLCH? We use **OKLCH** (Oklab LCH) color space for: - ✅ **Perceptual uniformity** - Colors look consistent across light/dark modes - ✅ **Better accessibility** - Predictable contrast ratios - ✅ **Vibrant colors** - More saturated without sacrificing legibility - ✅ **Future-proof** - CSS native support (vs HSL/RGB) **Learn more**: [oklch.com](https://oklch.com) --- ### Semantic Color Tokens All colors follow the **background/foreground** convention: - `background` - The background color - `foreground` - The text color that goes on that background **This ensures accessible contrast automatically.** --- ### Primary Colors **Purpose**: Main brand color, CTAs, primary actions ```css /* Light & Dark Mode */ --primary: oklch(0.6231 0.188 259.8145) /* Blue */ --primary-foreground: oklch(1 0 0) /* White text */; ``` **Usage**: ```tsx // Primary button (most common) // Primary link Learn more // Primary badge New ``` **When to use**: - ✅ Call-to-action buttons - ✅ Primary links - ✅ Active states in navigation - ✅ Important badges/tags **When NOT to use**: - ❌ Large background areas (too intense) - ❌ Body text (use `text-foreground`) - ❌ Disabled states (use `muted`) --- ### Secondary Colors **Purpose**: Secondary actions, less prominent UI elements ```css /* Light Mode */ --secondary: oklch(0.967 0.0029 264.5419) /* Light gray-blue */ --secondary-foreground: oklch(0.1529 0 0) /* Dark text */ /* Dark Mode */ --secondary: oklch(0.2686 0 0) /* Dark gray */ --secondary-foreground: oklch(0.9823 0 0) /* Light text */; ``` **Usage**: ```tsx // Secondary button // Secondary badge Draft // Muted background area
Less important information
``` --- ### Muted Colors **Purpose**: Backgrounds for disabled states, subtle UI elements ```css /* Light Mode */ --muted: oklch(0.9846 0.0017 247.8389) --muted-foreground: oklch(0.4667 0.0043 264.4327) /* Dark Mode */ --muted: oklch(0.2393 0 0) --muted-foreground: oklch(0.6588 0.0043 264.4327); ``` **Usage**: ```tsx // Disabled button // Secondary/helper text

This action cannot be undone

// Skeleton loader // TabsList background Tab 1 ``` **Common use cases**: - Disabled button backgrounds - Placeholder/skeleton loaders - TabsList backgrounds - Switch backgrounds (unchecked state) - Helper text, captions, timestamps --- ### Accent Colors **Purpose**: Hover states, focus indicators, highlights ```css /* Light Mode */ --accent: oklch(0.9514 0.025 236.8242) --accent-foreground: oklch(0.1529 0 0) /* Dark Mode */ --accent: oklch(0.3791 0.1378 265.5222) --accent-foreground: oklch(0.9823 0 0); ``` **Usage**: ```tsx // Dropdown menu item hover Edit // Highlighted section
Featured content
``` **Common use cases**: - Dropdown menu item hover states - Command palette hover states - Highlighted sections - Subtle emphasis backgrounds --- ### Destructive Colors **Purpose**: Error states, delete actions, warnings ```css /* Light & Dark Mode */ --destructive: oklch(0.6368 0.2078 25.3313) /* Red */ --destructive-foreground: oklch(1 0 0) /* White text */; ``` **Usage**: ````tsx // Delete button --- ### Success & Warning Colors **Purpose**: Success states and warning alerts ```css /* Light & Dark Mode */ --success: oklch(0.6231 0.188 145) /* Green */ --success-foreground: oklch(1 0 0) /* White text */ --warning: oklch(0.75 0.15 85) /* Yellow/Orange */ --warning-foreground: oklch(0.1529 0 0) /* Dark text */ ```` **Usage**: ```tsx // Success badge Completed // Warning alert
Warning: This action is irreversible.
``` // Error alert Error Something went wrong. Please try again. // Form error text

{errors.email?.message}

// Destructive badge Critical ```` **When to use**: - ✅ Delete/remove actions - ✅ Error messages - ✅ Validation errors - ✅ Critical warnings --- ### Card & Popover Colors **Purpose**: Elevated surfaces (cards, popovers, dropdowns) ```css /* Light Mode */ --card: oklch(1 0 0) /* White */ --card-foreground: oklch(0.1529 0 0) /* Dark text */ --popover: oklch(1 0 0) /* White */ --popover-foreground: oklch(0.1529 0 0) /* Dark text */ /* Dark Mode */ --card: oklch(0.2686 0 0) /* Dark gray */ --card-foreground: oklch(0.9823 0 0) /* Light text */ --popover: oklch(0.2686 0 0) /* Dark gray */ --popover-foreground: oklch(0.9823 0 0) /* Light text */; ```` **Usage**: ```tsx // Card (uses card colors by default) Card Title Card content // Popover Open Popover content ``` --- ### Border & Input Colors **Purpose**: Borders, input field borders, dividers ```css /* Light Mode */ --border: oklch(0.9276 0.0058 264.5313) --input: oklch(0.9276 0.0058 264.5313) /* Dark Mode */ --border: oklch(0.3715 0 0) --input: oklch(0.3715 0 0); ``` **Usage**: ```tsx // Input border // Card with border Content // Separator // Custom border
Content
``` --- ### Focus Ring **Purpose**: Focus indicators for keyboard navigation ```css /* Light & Dark Mode */ --ring: oklch(0.6231 0.188 259.8145) /* Primary blue */; ``` **Usage**: ```tsx // Button with focus ring (automatic) // Custom focusable element
Focusable content
``` **Accessibility note**: Focus rings are critical for keyboard navigation. Never remove them with `outline: none` without providing an alternative. --- ### Chart Colors **Purpose**: Data visualization with harmonious color palette ```css --chart-1: oklch(0.6231 0.188 259.8145) /* Blue */ --chart-2: oklch(0.5461 0.2152 262.8809) /* Purple-blue */ --chart-3: oklch(0.4882 0.2172 264.3763) /* Deep purple */ --chart-4: oklch(0.4244 0.1809 265.6377) /* Violet */ --chart-5: oklch(0.3791 0.1378 265.5222) /* Deep violet */; ``` **Usage**: ```tsx // In chart components const COLORS = [ 'hsl(var(--chart-1))', 'hsl(var(--chart-2))', 'hsl(var(--chart-3))', 'hsl(var(--chart-4))', 'hsl(var(--chart-5))', ]; ``` --- ### Color Decision Tree ``` What's the purpose? │ ├─ Main action/CTA? → PRIMARY ├─ Secondary action? → SECONDARY ├─ Error/delete? → DESTRUCTIVE ├─ Hover state? → ACCENT ├─ Disabled/subtle? → MUTED ├─ Card/elevated surface? → CARD ├─ Border/divider? → BORDER └─ Focus indicator? → RING ``` --- ### Color Usage Guidelines #### ✅ DO ```tsx // Use semantic tokens
CTA

Error message

Subtle background
// Use accent for hover
Hover me
// Test contrast // Primary on white: 4.5:1 ✅ // Destructive on white: 4.5:1 ✅ ``` #### ❌ DON'T ```tsx // Don't use arbitrary colors
Bad
// Don't mix color spaces
Bad
// Don't use primary for large areas
Too intense
// Don't override foreground without checking contrast
Low contrast!
``` --- ## Typography ### Font Families ```css --font-sans: Geist Sans, system-ui, -apple-system, sans-serif --font-mono: Geist Mono, ui-monospace, monospace --font-serif: ui-serif, Georgia, serif; ``` **Usage**: ```tsx // Sans serif (default)
Body text
// Monospace (code) const example = true; // Serif (rarely used)
Quote
``` --- ### Type Scale | Size | Class | rem | px | Use Case | | ---- | ----------- | -------- | ----- | ---------------------------- | | 9xl | `text-9xl` | 8rem | 128px | Hero text (rare) | | 8xl | `text-8xl` | 6rem | 96px | Hero text (rare) | | 7xl | `text-7xl` | 4.5rem | 72px | Hero text (rare) | | 6xl | `text-6xl` | 3.75rem | 60px | Hero text (rare) | | 5xl | `text-5xl` | 3rem | 48px | Landing page H1 | | 4xl | `text-4xl` | 2.25rem | 36px | Page H1 | | 3xl | `text-3xl` | 1.875rem | 30px | **Page titles** | | 2xl | `text-2xl` | 1.5rem | 24px | **Section headings** | | xl | `text-xl` | 1.25rem | 20px | **Card titles** | | lg | `text-lg` | 1.125rem | 18px | **Subheadings** | | base | `text-base` | 1rem | 16px | **Body text (default)** | | sm | `text-sm` | 0.875rem | 14px | **Secondary text, captions** | | xs | `text-xs` | 0.75rem | 12px | **Labels, helper text** | **Bold = most commonly used** --- ### Font Weights | Weight | Class | Numeric | Use Case | | -------- | --------------- | ------- | ------------------------ | | Bold | `font-bold` | 700 | **Headings, emphasis** | | Semibold | `font-semibold` | 600 | **Subheadings, buttons** | | Medium | `font-medium` | 500 | **Labels, menu items** | | Normal | `font-normal` | 400 | **Body text (default)** | | Light | `font-light` | 300 | De-emphasized text | **Bold = most commonly used** --- ### Typography Patterns #### Page Title ```tsx

Page Title

``` #### Section Heading ```tsx

Section Heading

``` #### Card Title ```tsx Card Title ``` #### Body Text ```tsx

Regular paragraph text uses the default text-base size.

``` #### Secondary Text ```tsx

Helper text, timestamps, captions

``` #### Label ```tsx ``` --- ### Line Height | Class | Value | Use Case | | ----------------- | ----- | ----------------------- | | `leading-none` | 1 | Headings (rare) | | `leading-tight` | 1.25 | **Headings** | | `leading-snug` | 1.375 | Dense text | | `leading-normal` | 1.5 | **Body text (default)** | | `leading-relaxed` | 1.625 | Comfortable reading | | `leading-loose` | 2 | Very relaxed (rare) | **Usage**: ```tsx // Heading

Tight line height for headings

// Body (default)

Normal line height for readability

``` --- ### Typography Guidelines #### ✅ DO ```tsx // Use semantic foreground colors

Body text

Secondary text

// Maintain heading hierarchy

Page Title

Section

Subsection

// Limit line length for readability

60-80 characters per line is optimal

// Use responsive type sizes

Responsive Title

``` #### ❌ DON'T ```tsx // Don't use too many sizes on one page

Too small

Still small

Base

Large

Larger

// ^ Pick 2-3 sizes max // Don't skip heading levels

Page

Section

// ❌ Skipped h2 // Don't use custom colors without contrast check

Low contrast

// Don't overuse bold

Every word bold

``` --- ## Spacing Scale Tailwind uses a **0.25rem (4px) base unit**: ```css --spacing: 0.25rem; ``` **All spacing should be multiples of 4px** for consistency. ### Spacing Tokens | Token | rem | Pixels | Use Case | | ----- | -------- | ------ | ---------------------------------- | | `0` | 0 | 0px | No spacing | | `px` | - | 1px | Borders, dividers | | `0.5` | 0.125rem | 2px | Very tight | | `1` | 0.25rem | 4px | Icon gaps | | `2` | 0.5rem | 8px | **Tight spacing** (label → input) | | `3` | 0.75rem | 12px | Component padding | | `4` | 1rem | 16px | **Standard spacing** (form fields) | | `5` | 1.25rem | 20px | Medium spacing | | `6` | 1.5rem | 24px | **Section spacing** (cards) | | `8` | 2rem | 32px | **Large gaps** | | `10` | 2.5rem | 40px | Very large gaps | | `12` | 3rem | 48px | **Section dividers** | | `16` | 4rem | 64px | **Page sections** | | `20` | 5rem | 80px | Extra large | | `24` | 6rem | 96px | Huge spacing | **Bold = most commonly used** --- ### Container & Max Width ```tsx // Responsive container with horizontal padding
Content
// Constrained width for readability
Article content
``` ### Max Width Scale | Class | Pixels | Use Case | | ----------- | ------ | ------------------- | | `max-w-xs` | 320px | Tiny cards | | `max-w-sm` | 384px | Small cards | | `max-w-md` | 448px | **Forms** | | `max-w-lg` | 512px | **Modals** | | `max-w-xl` | 576px | Medium content | | `max-w-2xl` | 672px | **Article content** | | `max-w-3xl` | 768px | Documentation | | `max-w-4xl` | 896px | **Wide layouts** | | `max-w-5xl` | 1024px | Extra wide | | `max-w-6xl` | 1152px | Very wide | | `max-w-7xl` | 1280px | **Full page width** | **Bold = most commonly used** --- ### Spacing Guidelines #### ✅ DO ```tsx // Use multiples of 4
Content
// Use gap for flex/grid
// Use space-y for stacks
// Use responsive spacing
Responsive padding
``` #### ❌ DON'T ```tsx // Don't use arbitrary values
Bad
// Don't mix methods inconsistently
Inconsistent
Inconsistent
// Don't forget responsive spacing
Too much padding on mobile
``` **See [Spacing Philosophy](./04-spacing-philosophy.md) for detailed spacing strategy.** --- ## Shadows Professional shadow system for depth and elevation: ```css --shadow-xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05) --shadow-sm: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1) --shadow: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1) --shadow-md: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 2px 4px -1px hsl(0 0% 0% / 0.1) --shadow-lg: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 4px 6px -1px hsl(0 0% 0% / 0.1) --shadow-xl: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 8px 10px -1px hsl(0 0% 0% / 0.1) --shadow-2xl: 0 1px 3px 0px hsl(0 0% 0% / 0.25); ``` ### Shadow Usage | Elevation | Class | Use Case | | --------- | ------------ | -------------------------------- | | Base | No shadow | Buttons, inline elements | | Low | `shadow-sm` | **Cards, panels** | | Medium | `shadow-md` | **Dropdowns, tooltips** | | High | `shadow-lg` | **Modals, popovers** | | Highest | `shadow-xl` | Notifications, floating elements | | Maximum | `shadow-2xl` | Dialogs (rare) | **Usage**: ```tsx // Card with subtle shadow Card content // Dropdown with medium shadow Menu items // Modal with high shadow Modal content // Floating notification
Notification
``` **Dark mode note**: Shadows are less visible in dark mode. Test both modes. --- ## Border Radius Consistent rounded corners across the application: ```css --radius: 0.375rem; /* 6px - base */ --radius-sm: calc(var(--radius) - 4px) /* 2px */ --radius-md: calc(var(--radius) - 2px) /* 4px */ --radius-lg: var(--radius) /* 6px */ --radius-xl: calc(var(--radius) + 4px) /* 10px */; ``` ### Border Radius Scale | Token | Class | Pixels | Use Case | | ------ | -------------- | ------ | -------------------------------- | | None | `rounded-none` | 0px | Square elements | | Small | `rounded-sm` | 2px | **Tags, small badges** | | Medium | `rounded-md` | 4px | **Inputs, small buttons** | | Large | `rounded-lg` | 6px | **Cards, buttons (default)** | | XL | `rounded-xl` | 10px | **Large cards, modals** | | 2XL | `rounded-2xl` | 16px | Hero sections | | 3XL | `rounded-3xl` | 24px | Very rounded | | Full | `rounded-full` | 9999px | **Pills, avatars, icon buttons** | **Bold = most commonly used** ### Usage Examples ```tsx // Button (default) // Input field // Card Large card // Avatar // Badge/Tag Small tag // Pill button ``` ### Directional Radius ```tsx // Top corners only
Top rounded
// Bottom corners only
Bottom rounded
// Left corners only
Left rounded
// Right corners only
Right rounded
// Individual corners
Top-left and bottom-right
``` --- ## Quick Reference ### Most Used Tokens **Colors**: - `bg-primary text-primary-foreground` - CTAs - `bg-destructive text-destructive-foreground` - Delete/errors - `bg-muted text-muted-foreground` - Disabled/subtle - `text-foreground` - Body text - `text-muted-foreground` - Secondary text - `border-border` - Borders **Typography**: - `text-3xl font-bold` - Page titles - `text-2xl font-semibold` - Section headings - `text-xl font-semibold` - Card titles - `text-base` - Body text - `text-sm text-muted-foreground` - Secondary text **Spacing**: - `p-4` - Standard padding (16px) - `p-6` - Card padding (24px) - `gap-4` - Standard gap (16px) - `gap-6` - Section gap (24px) - `space-y-4` - Form field spacing (16px) - `space-y-6` - Section spacing (24px) **Shadows & Radius**: - `shadow-sm` - Cards - `shadow-md` - Dropdowns - `shadow-lg` - Modals - `rounded-lg` - Buttons, cards (6px) - `rounded-full` - Avatars, pills --- ## Next Steps - **Quick Start**: [5-minute crash course](./00-quick-start.md) - **Components**: [shadcn/ui component guide](./02-components.md) - **Layouts**: [Layout patterns](./03-layouts.md) - **Spacing**: [Spacing philosophy](./04-spacing-philosophy.md) - **Reference**: [Quick lookup tables](./99-reference.md) --- **Related Documentation:** - [Quick Start](./00-quick-start.md) - Essential patterns - [Components](./02-components.md) - shadcn/ui library - [Spacing Philosophy](./04-spacing-philosophy.md) - Margin vs padding strategy - [Accessibility](./07-accessibility.md) - WCAG compliance **External Resources:** - [OKLCH Color Picker](https://oklch.com) - [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/) - [Tailwind CSS Documentation](https://tailwindcss.com/docs) **Last Updated**: November 2, 2025