- Complete UI refactor with charcoal/bone color palette - Add Space Grotesk font for headlines, Inter for body - Update all 24+ pages with new design system - Add LinearPrimitives reusable components - Improve dark mode support throughout - Add subtle micro-animations and transitions
368 lines
8.7 KiB
Markdown
368 lines
8.7 KiB
Markdown
# Linear-Inspired Design System
|
||
|
||
**Version**: 2.0.0
|
||
**Date**: 2025-12-12
|
||
**Status**: 🚀 Implementing
|
||
|
||
---
|
||
|
||
## 🎯 Design Philosophy
|
||
|
||
Inspired by Linear, our design prioritizes:
|
||
|
||
1. **Speed Over Spectacle** - UI should feel instant
|
||
2. **Keyboard-First** - Power users can navigate without a mouse
|
||
3. **Clarity Over Decoration** - Every element serves a purpose
|
||
4. **Minimalist Density** - More information, less noise
|
||
5. **Subtle Motion** - Micro-animations guide, never distract
|
||
|
||
---
|
||
|
||
## 🎨 Color Palette
|
||
|
||
### Core Colors (Charcoal & Bone)
|
||
|
||
```css
|
||
/* Light Mode ("Bone") */
|
||
--color-bg-primary: #FFFFFF; /* Pure white */
|
||
--color-bg-secondary: #FAFAFA; /* Off-white */
|
||
--color-bg-tertiary: #F5F5F5; /* Light gray */
|
||
--color-bg-elevated: #FFFFFF; /* Cards, modals */
|
||
|
||
--color-text-primary: #171717; /* Near black */
|
||
--color-text-secondary: #525252; /* Dark gray */
|
||
--color-text-tertiary: #A3A3A3; /* Mid gray */
|
||
--color-text-quaternary: #D4D4D4; /* Light gray (disabled) */
|
||
|
||
--color-border-default: #E5E5E5; /* Subtle border */
|
||
--color-border-subtle: #F5F5F5; /* Very subtle */
|
||
--color-border-strong: #D4D4D4; /* Emphasis */
|
||
|
||
/* Dark Mode ("Charcoal") */
|
||
--color-bg-primary: #0A0A0A; /* Near black */
|
||
--color-bg-secondary: #171717; /* Charcoal */
|
||
--color-bg-tertiary: #262626; /* Dark gray */
|
||
--color-bg-elevated: #1F1F1F; /* Cards, modals */
|
||
|
||
--color-text-primary: #FAFAFA; /* Off-white */
|
||
--color-text-secondary: #A3A3A3; /* Mid gray */
|
||
--color-text-tertiary: #737373; /* Dark gray */
|
||
--color-text-quaternary: #525252; /* Darker gray (disabled) */
|
||
|
||
--color-border-default: #262626; /* Subtle border */
|
||
--color-border-subtle: #1F1F1F; /* Very subtle */
|
||
--color-border-strong: #404040; /* Emphasis */
|
||
```
|
||
|
||
### Accent Colors (Minimal, Purposeful)
|
||
|
||
```css
|
||
/* Accent - Desaturated Blue (Linear-style) */
|
||
--color-accent: #5E6AD2; /* Primary accent */
|
||
--color-accent-hover: #6E7AE2; /* Hover state */
|
||
--color-accent-muted: rgba(94, 106, 210, 0.15);
|
||
|
||
/* Status Colors (Desaturated) */
|
||
--color-success: #22C55E; /* Green - success */
|
||
--color-success-muted: rgba(34, 197, 94, 0.15);
|
||
|
||
--color-warning: #EAB308; /* Yellow - warning */
|
||
--color-warning-muted: rgba(234, 179, 8, 0.15);
|
||
|
||
--color-error: #EF4444; /* Red - error */
|
||
--color-error-muted: rgba(239, 68, 68, 0.15);
|
||
|
||
--color-info: #5E6AD2; /* Same as accent */
|
||
--color-info-muted: rgba(94, 106, 210, 0.15);
|
||
```
|
||
|
||
### Semantic Mapping
|
||
|
||
| Usage | Light Mode | Dark Mode |
|
||
|-------|------------|-----------|
|
||
| Page background | `#FFFFFF` | `#0A0A0A` |
|
||
| Card background | `#FFFFFF` | `#171717` |
|
||
| Sidebar background | `#FAFAFA` | `#0F0F0F` |
|
||
| Primary text | `#171717` | `#FAFAFA` |
|
||
| Secondary text | `#525252` | `#A3A3A3` |
|
||
| Borders | `#E5E5E5` | `#262626` |
|
||
| Focus ring | `#5E6AD2` | `#5E6AD2` |
|
||
|
||
---
|
||
|
||
## 📝 Typography
|
||
|
||
### Font Stack
|
||
|
||
```css
|
||
--font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||
--font-mono: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
|
||
```
|
||
|
||
### Type Scale
|
||
|
||
| Name | Size | Weight | Line Height | Usage |
|
||
|------|------|--------|-------------|-------|
|
||
| `xs` | 11px | 400 | 1.4 | Labels, metadata |
|
||
| `sm` | 13px | 400 | 1.5 | Secondary text |
|
||
| `base` | 14px | 400 | 1.6 | Body text |
|
||
| `lg` | 16px | 500 | 1.5 | Subheadings |
|
||
| `xl` | 18px | 600 | 1.4 | Headings |
|
||
| `2xl` | 24px | 600 | 1.3 | Page titles |
|
||
| `3xl` | 30px | 700 | 1.2 | Hero text |
|
||
|
||
### Letter Spacing
|
||
|
||
```css
|
||
--tracking-tight: -0.02em; /* Headings */
|
||
--tracking-normal: -0.01em; /* Body */
|
||
--tracking-wide: 0.02em; /* All caps labels */
|
||
```
|
||
|
||
---
|
||
|
||
## 📐 Spacing & Layout
|
||
|
||
### Spacing Scale
|
||
|
||
```css
|
||
--space-0: 0;
|
||
--space-1: 4px;
|
||
--space-2: 8px;
|
||
--space-3: 12px;
|
||
--space-4: 16px;
|
||
--space-5: 20px;
|
||
--space-6: 24px;
|
||
--space-8: 32px;
|
||
--space-10: 40px;
|
||
--space-12: 48px;
|
||
--space-16: 64px;
|
||
```
|
||
|
||
### Border Radius
|
||
|
||
```css
|
||
--radius-sm: 4px; /* Buttons, inputs */
|
||
--radius-md: 6px; /* Cards */
|
||
--radius-lg: 8px; /* Modals */
|
||
--radius-xl: 12px; /* Large cards */
|
||
--radius-full: 9999px; /* Pills, avatars */
|
||
```
|
||
|
||
---
|
||
|
||
## ✨ Micro-Animations
|
||
|
||
### Timing Functions
|
||
|
||
```css
|
||
/* Linear's signature easing */
|
||
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
|
||
--ease-in-out-expo: cubic-bezier(0.87, 0, 0.13, 1);
|
||
--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
|
||
```
|
||
|
||
### Animation Durations
|
||
|
||
```css
|
||
--duration-instant: 50ms; /* Color changes */
|
||
--duration-fast: 100ms; /* Hover states */
|
||
--duration-normal: 150ms; /* Most transitions */
|
||
--duration-slow: 250ms; /* Modals, drawers */
|
||
--duration-slower: 400ms; /* Page transitions */
|
||
```
|
||
|
||
### Standard Transitions
|
||
|
||
```css
|
||
/* Hover state */
|
||
.interactive {
|
||
transition:
|
||
background-color var(--duration-fast) var(--ease-out-expo),
|
||
color var(--duration-fast) var(--ease-out-expo),
|
||
border-color var(--duration-fast) var(--ease-out-expo),
|
||
transform var(--duration-normal) var(--ease-spring);
|
||
}
|
||
|
||
/* Subtle press effect */
|
||
.interactive:active {
|
||
transform: scale(0.98);
|
||
}
|
||
|
||
/* Focus ring animation */
|
||
.focus-ring:focus-visible {
|
||
box-shadow: 0 0 0 2px var(--color-accent);
|
||
transition: box-shadow var(--duration-normal) var(--ease-out-expo);
|
||
}
|
||
```
|
||
|
||
### Component-Specific Animations
|
||
|
||
```css
|
||
/* Button hover glow */
|
||
@keyframes button-glow {
|
||
0% { box-shadow: 0 0 0 0 rgba(94, 106, 210, 0.4); }
|
||
100% { box-shadow: 0 0 0 4px rgba(94, 106, 210, 0); }
|
||
}
|
||
|
||
/* Card hover lift */
|
||
@keyframes card-lift {
|
||
0% { transform: translateY(0); }
|
||
100% { transform: translateY(-2px); }
|
||
}
|
||
|
||
/* Fade in */
|
||
@keyframes fade-in {
|
||
from { opacity: 0; }
|
||
to { opacity: 1; }
|
||
}
|
||
|
||
/* Slide up */
|
||
@keyframes slide-up {
|
||
from { opacity: 0; transform: translateY(8px); }
|
||
to { opacity: 1; transform: translateY(0); }
|
||
}
|
||
|
||
/* Scale in */
|
||
@keyframes scale-in {
|
||
from { opacity: 0; transform: scale(0.95); }
|
||
to { opacity: 1; transform: scale(1); }
|
||
}
|
||
|
||
/* Progress bar shimmer */
|
||
@keyframes shimmer {
|
||
0% { background-position: -200% 0; }
|
||
100% { background-position: 200% 0; }
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🧱 Component Patterns
|
||
|
||
### Buttons
|
||
|
||
```css
|
||
/* Base button */
|
||
.btn {
|
||
height: 32px;
|
||
padding: 0 12px;
|
||
font-size: 13px;
|
||
font-weight: 500;
|
||
border-radius: var(--radius-sm);
|
||
transition: all var(--duration-fast) var(--ease-out-expo);
|
||
}
|
||
|
||
/* Primary (accent) */
|
||
.btn-primary {
|
||
background: var(--color-accent);
|
||
color: white;
|
||
}
|
||
.btn-primary:hover {
|
||
background: var(--color-accent-hover);
|
||
}
|
||
|
||
/* Secondary (ghost) */
|
||
.btn-secondary {
|
||
background: transparent;
|
||
color: var(--color-text-secondary);
|
||
border: 1px solid var(--color-border-default);
|
||
}
|
||
.btn-secondary:hover {
|
||
background: var(--color-bg-tertiary);
|
||
color: var(--color-text-primary);
|
||
}
|
||
```
|
||
|
||
### Cards
|
||
|
||
```css
|
||
.card {
|
||
background: var(--color-bg-elevated);
|
||
border: 1px solid var(--color-border-subtle);
|
||
border-radius: var(--radius-md);
|
||
transition: border-color var(--duration-fast) var(--ease-out-expo);
|
||
}
|
||
.card:hover {
|
||
border-color: var(--color-border-default);
|
||
}
|
||
```
|
||
|
||
### Inputs
|
||
|
||
```css
|
||
.input {
|
||
height: 36px;
|
||
padding: 0 12px;
|
||
font-size: 14px;
|
||
background: var(--color-bg-primary);
|
||
border: 1px solid var(--color-border-default);
|
||
border-radius: var(--radius-sm);
|
||
transition: all var(--duration-fast) var(--ease-out-expo);
|
||
}
|
||
.input:focus {
|
||
border-color: var(--color-accent);
|
||
box-shadow: 0 0 0 3px var(--color-accent-muted);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 📱 Responsive Breakpoints
|
||
|
||
```css
|
||
--breakpoint-sm: 640px;
|
||
--breakpoint-md: 768px;
|
||
--breakpoint-lg: 1024px;
|
||
--breakpoint-xl: 1280px;
|
||
--breakpoint-2xl: 1536px;
|
||
```
|
||
|
||
---
|
||
|
||
## 🌙 Dark Mode Strategy
|
||
|
||
- **Default**: Follow system preference (`prefers-color-scheme`)
|
||
- **Toggle**: Available in settings
|
||
- **Persistence**: localStorage key `theme`
|
||
- **Transition**: Smooth 150ms color transition on toggle
|
||
|
||
---
|
||
|
||
## ♿ Accessibility
|
||
|
||
- **Focus visible**: All interactive elements have visible focus ring
|
||
- **Contrast**: Minimum 4.5:1 for text, 3:1 for large text/graphics
|
||
- **Motion**: Respect `prefers-reduced-motion`
|
||
- **Touch targets**: Minimum 44×44px
|
||
- **Keyboard**: Full keyboard navigation support
|
||
|
||
---
|
||
|
||
## 🚀 Implementation Priority
|
||
|
||
1. **Phase 1: Colors & Typography** (2-3 hours)
|
||
- Update `tailwind.config.js` with new color tokens
|
||
- Update `index.css` with new font imports
|
||
- Create CSS custom properties
|
||
|
||
2. **Phase 2: Core Components** (3-4 hours)
|
||
- Update Button component
|
||
- Update Card component
|
||
- Update Input component
|
||
- Update focus states
|
||
|
||
3. **Phase 3: Layouts** (2-3 hours)
|
||
- Update Sidebar
|
||
- Update PageHeader
|
||
- Update Navigation
|
||
|
||
4. **Phase 4: Micro-Animations** (2-3 hours)
|
||
- Add hover transitions
|
||
- Add press effects
|
||
- Add page transitions
|
||
|
||
5. **Phase 5: Polish** (2-3 hours)
|
||
- Dark mode refinement
|
||
- Accessibility audit
|
||
- Performance check
|