ca-grow-ops-manager/docs/DESIGN-SYSTEM-LINEAR.md
fullsizemalt 71e58dd4c7
Some checks are pending
Deploy to Production / deploy (push) Waiting to run
Test / backend-test (push) Waiting to run
Test / frontend-test (push) Waiting to run
feat: Linear-inspired UI redesign with Space Grotesk headlines
- 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
2025-12-12 14:29:47 -08:00

368 lines
8.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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