- Introduce FastNext Design System based on `shadcn/ui` and `Tailwind CSS 4`. - Detail semantic color tokens using the OKLCH color space for better accessibility. - Define typography, spacing, shadows, and border radius standards. - Provide component usage guidelines for consistent and accessible design. - Outline responsive design, performance, and accessibility best practices. - Add dark mode implementation strategy and tooling references. - Include a version history for change tracking and future updates.
16 KiB
FastNext Template Design System
Version: 1.0 Last Updated: November 2, 2025 Theme: Modern Minimal (via tweakcn.com) Status: Production Ready
Table of Contents
- Overview
- Color System
- Typography
- Spacing & Layout
- Shadows
- Border Radius
- Components
- Dark Mode
- Accessibility
- Best Practices
Overview
This design system is built on shadcn/ui component library with Tailwind CSS 4, using the OKLCH color space for superior perceptual uniformity and accessibility.
Technology Stack
- Framework: Next.js 15 + React 19
- Styling: Tailwind CSS 4 (CSS-first configuration)
- Components: shadcn/ui (New York style)
- Color Space: OKLCH
- Icons: lucide-react
- Fonts: Geist Sans + Geist Mono
Design Principles
- Minimal & Clean - Simple, uncluttered interfaces
- Accessible First - WCAG AA compliance minimum
- Consistent - Predictable patterns across the application
- Performant - Optimized for speed and efficiency
- Responsive - Mobile-first approach
Color System
Our color system uses OKLCH (Oklab LCH) color space for:
- Perceptual uniformity across light and dark modes
- Better accessibility with predictable contrast
- More vibrant colors without sacrificing legibility
Semantic Color Tokens
All colors follow the background/foreground convention:
background- The background colorforeground- The text color on that background
Primary Colors
Purpose: Main brand color, CTAs, primary actions
Light: --primary: oklch(0.6231 0.1880 259.8145) /* Blue */
Dark: --primary: oklch(0.6231 0.1880 259.8145) /* Same blue */
Usage:
<Button>Primary Action</Button>
<a href="#" className="text-primary">Link</a>
Secondary Colors
Purpose: Secondary actions, less prominent UI elements
Light: --secondary: oklch(0.9670 0.0029 264.5419) /* Light gray-blue */
Dark: --secondary: oklch(0.2686 0 0) /* Dark gray */
Muted Colors
Purpose: Backgrounds for disabled states, subtle UI elements
Light: --muted: oklch(0.9846 0.0017 247.8389)
Dark: --muted: oklch(0.2393 0 0)
Usage:
- Disabled button backgrounds
- Skeleton loaders
- TabsList backgrounds
- Switch backgrounds (unchecked)
Accent Colors
Purpose: Hover states, focus indicators, highlights
Light: --accent: oklch(0.9514 0.0250 236.8242)
Dark: --accent: oklch(0.3791 0.1378 265.5222)
Usage:
<DropdownMenuItem className="focus:bg-accent">Item</DropdownMenuItem>
Destructive Colors
Purpose: Error states, delete actions, warnings
Light: --destructive: oklch(0.6368 0.2078 25.3313) /* Red */
Dark: --destructive: oklch(0.6368 0.2078 25.3313) /* Same red */
Usage:
<Button variant="destructive">Delete</Button>
<Alert variant="destructive">Error message</Alert>
Card & Popover
Purpose: Elevated surfaces (cards, popovers, dropdowns)
Light: --card: oklch(1.0000 0 0) /* White */
Dark: --card: oklch(0.2686 0 0) /* Dark gray */
Light: --popover: oklch(1.0000 0 0) /* White */
Dark: --popover: oklch(0.2686 0 0) /* Dark gray */
Border & Input
Purpose: Borders, input field borders
Light: --border: oklch(0.9276 0.0058 264.5313)
Dark: --border: oklch(0.3715 0 0)
Light: --input: oklch(0.9276 0.0058 264.5313)
Dark: --input: oklch(0.3715 0 0)
Focus Ring
Purpose: Focus indicators for keyboard navigation
Light: --ring: oklch(0.6231 0.1880 259.8145) /* Primary blue */
Dark: --ring: oklch(0.6231 0.1880 259.8145)
Chart Colors
For data visualization, we provide 5 harmonious chart colors:
--chart-1: oklch(0.6231 0.1880 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 */
Color Usage Guidelines
DO:
- ✅ Use semantic tokens (
bg-primary,text-destructive) - ✅ Test color combinations with contrast checkers
- ✅ Use
mutedfor subtle backgrounds - ✅ Use
accentfor hover states
DON'T:
- ❌ Use arbitrary color values (
bg-blue-500) - ❌ Mix OKLCH with RGB/HSL in the same context
- ❌ Use
primaryfor large background areas - ❌ Override foreground colors without checking contrast
Typography
Font Families
--font-sans: Geist Sans, system-ui, -apple-system, sans-serif
--font-mono: Geist Mono, ui-monospace, monospace
--font-serif: ui-serif, Georgia, serif
Usage:
<div className="font-sans">Body text</div>
<code className="font-mono">const example = true;</code>
Type Scale
Tailwind CSS provides a comprehensive type scale. We use:
| Size | Class | Use Case |
|---|---|---|
| 3xl | text-3xl |
Page titles |
| 2xl | text-2xl |
Section headings |
| xl | text-xl |
Card titles |
| lg | text-lg |
Subheadings |
| base | text-base |
Body text (default) |
| sm | text-sm |
Secondary text, captions |
| xs | text-xs |
Labels, helper text |
Font Weights
| Weight | Class | Use Case |
|---|---|---|
| 700 | font-bold |
Headings, emphasis |
| 600 | font-semibold |
Subheadings, buttons |
| 500 | font-medium |
Labels, menu items |
| 400 | font-normal |
Body text (default) |
| 300 | font-light |
De-emphasized text |
Typography Guidelines
DO:
- ✅ Use
text-foregroundfor body text - ✅ Use
text-muted-foregroundfor secondary text - ✅ Maintain consistent heading hierarchy (h1 → h2 → h3)
- ✅ Limit line length to 60-80 characters for readability
DON'T:
- ❌ Use more than 3 font sizes on a single page
- ❌ Use custom colors without checking contrast
- ❌ Skip heading levels (h1 → h3)
- ❌ Use
font-boldexcessively
Line Height:
- Headings:
leading-tight(1.25) - Body:
leading-normal(1.5) - default - Dense UI:
leading-relaxed(1.625)
Spacing & Layout
Spacing Scale
Tailwind uses a 0.25rem (4px) base unit:
--spacing: 0.25rem;
| Token | Value | Pixels | Use Case |
|---|---|---|---|
0 |
0 | 0px | No spacing |
px |
1px | 1px | Borders, dividers |
0.5 |
0.125rem | 2px | Tight spacing |
1 |
0.25rem | 4px | Icon gaps |
2 |
0.5rem | 8px | Small gaps |
3 |
0.75rem | 12px | Component padding |
4 |
1rem | 16px | Standard spacing |
6 |
1.5rem | 24px | Section spacing |
8 |
2rem | 32px | Large gaps |
12 |
3rem | 48px | Section dividers |
16 |
4rem | 64px | Page sections |
Container & Max Width
<div className="container mx-auto px-4">
{/* Responsive container with horizontal padding */}
</div>
<div className="max-w-2xl mx-auto">
{/* Constrained width for readability */}
</div>
Max Width Scale:
max-w-sm- 384px - Small cardsmax-w-md- 448px - Formsmax-w-lg- 512px - Modalsmax-w-2xl- 672px - Article contentmax-w-4xl- 896px - Wide layoutsmax-w-7xl- 1280px - Full page width
Layout Guidelines
DO:
- ✅ Use multiples of 4 for spacing (4, 8, 12, 16, 24, 32...)
- ✅ Use
gap-utilities for flex/grid spacing - ✅ Use
space-y-for vertical stacks - ✅ Use
containerfor page-level constraints
DON'T:
- ❌ Use arbitrary values like
p-[13px] - ❌ Mix padding and margin inconsistently
- ❌ Forget responsive spacing (
sm:p-6 lg:p-8)
Shadows
Professional shadow system for depth and elevation:
--shadow-xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05)
--shadow-sm: 0 1px 3px 0px hsl(0 0% 0% / 0.10), 0 1px 2px -1px hsl(0 0% 0% / 0.10)
--shadow: 0 1px 3px 0px hsl(0 0% 0% / 0.10), 0 1px 2px -1px hsl(0 0% 0% / 0.10)
--shadow-md: 0 1px 3px 0px hsl(0 0% 0% / 0.10), 0 2px 4px -1px hsl(0 0% 0% / 0.10)
--shadow-lg: 0 1px 3px 0px hsl(0 0% 0% / 0.10), 0 4px 6px -1px hsl(0 0% 0% / 0.10)
--shadow-xl: 0 1px 3px 0px hsl(0 0% 0% / 0.10), 0 8px 10px -1px hsl(0 0% 0% / 0.10)
--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 |
Usage:
<Card className="shadow-sm">Card content</Card>
<DropdownMenu className="shadow-md">Menu</DropdownMenu>
<Dialog className="shadow-xl">Modal</Dialog>
Border Radius
Consistent rounded corners across the application:
--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 Usage
| Token | Value | Use Case |
|---|---|---|
rounded-sm |
2px | Small elements, tags |
rounded-md |
4px | Inputs, small buttons |
rounded-lg |
6px | Cards, buttons (default) |
rounded-xl |
10px | Large cards, modals |
rounded-full |
9999px | Pills, avatars, icon buttons |
Usage:
<Button className="rounded-lg">Default Button</Button>
<Avatar className="rounded-full" />
<Badge className="rounded-sm">Tag</Badge>
Components
shadcn/ui Component Library
We use shadcn/ui components (New York style) with CSS variables for theming.
Installed Components:
alert- Alerts and notificationsavatar- User avatarsbadge- Tags and labelsbutton- Buttons (primary, secondary, outline, ghost, destructive)card- Content cardscheckbox- Checkboxesdialog- Modals and dialogsdropdown-menu- Context menus, dropdownsinput- Text inputslabel- Form labelspopover- Tooltips, popoversselect- Select dropdownsseparator- Horizontal/vertical dividerssheet- Side panelsskeleton- Loading skeletonstable- Data tablestabs- Tabbed interfacestextarea- Multi-line inputs
Component Variants
Button Variants
<Button variant="default">Primary Button</Button>
<Button variant="secondary">Secondary Button</Button>
<Button variant="outline">Outline Button</Button>
<Button variant="ghost">Ghost Button</Button>
<Button variant="destructive">Delete</Button>
<Button variant="link">Link Button</Button>
Button Sizes
<Button size="sm">Small</Button>
<Button size="default">Default</Button>
<Button size="lg">Large</Button>
<Button size="icon"><Icon /></Button>
Component Guidelines
DO:
- ✅ Use semantic variant names (
destructive, notred) - ✅ Compose components from shadcn/ui primitives
- ✅ Follow the background/foreground convention
- ✅ Add
aria-labelfor icon-only buttons
DON'T:
- ❌ Create custom variants without documenting them
- ❌ Override component styles with arbitrary classes
- ❌ Mix component libraries (stick to shadcn/ui)
Dark Mode
Dark mode is implemented using CSS classes (.dark) with automatic OS preference detection.
Dark Mode Strategy
- CSS Variables: All colors have light and dark variants
- Class Toggle:
.darkclass on<html>element - Persistent: User preference stored in localStorage
- Smooth Transition: Optional transitions between modes
Implementation
// Toggle dark mode
<Button onClick={() => document.documentElement.classList.toggle('dark')}>
Toggle Theme
</Button>
// Check current mode
const isDark = document.documentElement.classList.contains('dark');
Dark Mode Guidelines
DO:
- ✅ Test all components in both light and dark modes
- ✅ Use semantic color tokens (not hardcoded colors)
- ✅ Maintain WCAG AA contrast in both modes
- ✅ Provide a theme toggle in settings
DON'T:
- ❌ Use absolute colors like
bg-whiteorbg-black - ❌ Assume users only use one mode
- ❌ Forget to test shadow visibility in dark mode
Accessibility
We follow WCAG 2.1 Level AA as the minimum standard.
Color Contrast
All text must meet minimum contrast ratios:
- Normal text (< 18px): 4.5:1 minimum
- Large text (≥ 18px or ≥ 14px bold): 3:1 minimum
- UI components: 3:1 minimum
Tools:
- WebAIM Contrast Checker
- Chrome DevTools Accessibility panel
- Browser extensions (axe, WAVE)
Keyboard Navigation
Requirements:
- ✅ All interactive elements focusable via Tab
- ✅ Visible focus indicators (
:focus-visible) - ✅ Logical tab order
- ✅ Escape key closes modals/dropdowns
- ✅ Arrow keys for navigation within components
Screen Readers
Requirements:
- ✅ Semantic HTML (headings, lists, nav, main, etc.)
- ✅
aria-labelfor icon-only buttons - ✅
aria-describedbyfor form errors - ✅
roleattributes where needed - ✅ Live regions for dynamic updates
Focus Management
// Proper focus indicator
<Button className="focus-visible:ring-2 focus-visible:ring-ring">
Action
</Button>
// Skip to main content link
<a href="#main" className="sr-only focus:not-sr-only">
Skip to main content
</a>
Accessibility Checklist
- Color contrast meets WCAG AA (4.5:1 for text)
- All interactive elements keyboard accessible
- Focus indicators visible
- Images have
alttext - Forms have labels
- Error messages associated with inputs
- ARIA attributes used correctly
- Tested with screen reader (NVDA, JAWS, VoiceOver)
Best Practices
Naming Conventions
DO:
// ✅ Descriptive, semantic names
<Button variant="destructive">Delete</Button>
<div className="bg-card text-card-foreground">Content</div>
DON'T:
// ❌ Generic, non-semantic names
<Button className="bg-red-500">Delete</Button>
<div className="bg-white text-black">Content</div>
Component Structure
DO:
// ✅ Compose with shadcn/ui primitives
<Card>
<CardHeader>
<CardTitle>Title</CardTitle>
</CardHeader>
<CardContent>Content</CardContent>
</Card>
DON'T:
// ❌ Create custom components for everything
<CustomCard title="Title">Content</CustomCard>
Responsive Design
DO:
// ✅ Mobile-first responsive utilities
<div className="p-4 sm:p-6 lg:p-8">
<h1 className="text-2xl sm:text-3xl lg:text-4xl">Title</h1>
</div>
DON'T:
// ❌ Desktop-first or no responsive design
<div className="p-8">
<h1 className="text-4xl">Title</h1>
</div>
Performance
DO:
- ✅ Use CSS variables for theming (no runtime JS)
- ✅ Minimize custom CSS (use Tailwind utilities)
- ✅ Lazy load components when appropriate
- ✅ Optimize images with Next.js Image component
DON'T:
- ❌ Inline styles everywhere
- ❌ Large custom CSS files
- ❌ Unoptimized images
- ❌ Excessive animation/transitions
Code Organization
src/components/
├── ui/ # shadcn/ui components (don't edit)
├── auth/ # Authentication components
├── layout/ # Layout components (Header, Footer)
└── settings/ # Feature-specific components
Documentation
DO:
- ✅ Document custom variants in this file
- ✅ Add JSDoc comments to complex components
- ✅ Include usage examples
- ✅ Update this document when making changes
Version History
| Version | Date | Changes |
|---|---|---|
| 1.0 | Nov 2, 2025 | Initial design system with Modern Minimal theme |
Resources
- shadcn/ui Documentation
- Tailwind CSS 4 Documentation
- OKLCH Color Space
- WCAG 2.1 Guidelines
- Theme Generator
For questions or suggestions, refer to this document and the official documentation.