Linear-Quality Design System
Build UI with the craft of Linear, Vercel, and Resend. Great UI is restraint, not addition.
The best details are invisible — felt, not seen.
Color System
Design a derived color system, not a palette of hardcoded values.
- Define 3 foundation variables: base color, accent color, contrast level.
- Derive all surfaces, text, icons, borders from these via opacity operations.
- Use perceptually uniform color space (LCH/OKLCH) so colors at same lightness look equally light.
- Hierarchy through opacity and weight, not hue. Monochrome-first.
- Color ONLY for semantic meaning: error (red), success (green), active/selected, brand accent.
- No decorative color. No habitual colored icons — make them
muted-foreground.
- Limit brand color leakage into chrome. The frame should feel neutral and timeless.
- No hardcoded hex anywhere. CSS variables / design tokens only.
Surface & Elevation
Layer surfaces with subtle background shifts, not heavy shadows.
- Define clear elevation hierarchy:
background → card/raised → popover → dialog/modal.
- Each level is a slight shade shift (via opacity on base), not a different color.
- Dark mode: shadows become subtle borders or glows. Replace
shadow-md with border border-border/50.
- Borders: semi-transparent at low opacity (
border-border/40), never solid opaque lines.
- Backdrop blur on floating elements:
backdrop-blur-sm on overlays, popovers, command palette.
- Support high-contrast mode via the contrast variable — accessibility built into the system.
-webkit-font-smoothing: antialiased globally.
Motion & Animation
Motion is ~30% of why premium UI feels premium. transition-colors duration-150 is the floor.
- Micro-transitions: color/opacity changes use
duration-150 ease-out.
- Layout transitions: panels, drawers, sidebars use
duration-200 ease-in-out.
- Entrances: modals/dialogs use spring-based easing — slight overshoot, then settle.
Framer Motion:
type: "spring", stiffness: 400, damping: 30. CSS: cubic-bezier(0.34, 1.56, 0.64, 1).
- List stagger: items entering a list animate in with 30-50ms stagger between each.
- Skeleton shimmer: animated gradient sweep matching content shape, not a static gray box.
- Toasts: slide in from consistent anchor (bottom-right), slide out on dismiss.
- Number animations: counters animate between values, don't jump.
- Exit animations: elements leaving should animate out (opacity + slight translate), not vanish.
- Never add artificial delays. Motion should feel instant-but-smooth, not slow.
Layout Architecture
The structural patterns that make an app feel like a tool, not a website.
- Three-column layout: collapsible sidebar (240-280px) + main content + optional detail panel.
- Resizable panels: drag handles between columns. Show handle on hover, store width preference.
- Sticky headers: compress or transform on scroll. Never duplicate content in header and body.
- Sheet/drawer vs modal: use sheets for contextual detail (stays in flow), modals for focused tasks
(blocks flow). Sheets slide from right, modals center with backdrop.
- Command palette:
Cmd+K overlay that floats above layout. Fuzzy search, categorized results,
recent items, keyboard-navigable. This is primary navigation for power users.
- Split views: side-by-side content for comparison or detail-alongside-list.
Keyboard-First Design
A Linear-quality app is faster with keyboard than mouse.
- Command palette (
Cmd+K): search commands, navigate, execute actions. Must exist.
- Single-key shortcuts:
C to create, S for status, etc. Show in tooltips and context menus.
- List navigation:
j/k or arrow keys to move through items, Enter to open.
- Multi-select:
Shift+Click range select, Cmd+Click toggle individual.
- Focus management: after dialog close, focus returns to trigger. After create, focus new item.
- Shortcuts in UI: display keyboard shortcut hints in tooltips, context menus, and command palette
results. This teaches users the shortcuts naturally.
- Escape to dismiss: every overlay, modal, popover, command palette closes on
Escape.
Progressive Disclosure
Resting state is minimal. Complexity reveals on interaction.
- Row actions: edit, delete, options menu — visible only on row
:hover.
- Metadata: timestamps, secondary badges — shown on hover where non-essential at rest.
- Toolbars: bulk action bars appear on selection, not permanently.
- Contextual menus: right-click surfaces full action set. Include keyboard shortcuts in menu items.
- Sub-menu safe areas: triangle hit area between cursor and sub-menu so diagonal mouse movement
doesn't close the menu (the Linear pattern — ~40 lines of code, invisible to user, felt as smoothness).
- If it's not primary content or primary action, it should not be visible at rest.
Information Density
Dense yet clean. Chrome is sparse, content is dense.
- Tight line-heights in lists and tables (1.25-1.4, not Tailwind default 1.5).
- Compact inline metadata: status dot + avatar + priority icon + label, all in one row.
- Tabular numbers:
font-variant-numeric: tabular-nums on all number columns so digits align.
- Monospace: IDs, branch names, code, technical strings in
font-mono text-xs.
- Right-align numbers in table columns.
- Density trade-off: reduce chrome spacing (sidebar padding, header height) to give content room.
Content area can be dense; navigation frame stays spacious.
Buttons & Actions
- AT MOST one
variant="default" (primary) button per page/modal/card.
- All other actions: secondary, outline, or ghost — pick by visual weight.
- Destructive:
variant="destructive" + confirmation dialog before execution.
- Consistent button height per context. Never mix sizes in the same view.
- Cursor
pointer on everything clickable.
Interactivity & Micro-interactions
- Every clickable element: distinct
hover: state (color/opacity) + active: state (pressed).
- No bare
<div onClick> without visual hover feedback.
- Focusable elements:
focus-visible:ring-2 ring-ring.
- Drag handles: appear on hover, hidden at rest.
- Copy-to-clipboard: brief "Copied!" feedback (tooltip or inline text swap, 1.5s).
- Optimistic updates: UI changes instantly on action, server catches up async.
- Smart menu positioning: menus stay in viewport, flip direction when near edges.
- Input debounce: search/filter inputs debounce 200-300ms, show subtle loading indicator.
Typography
- Each view: one dominant heading, one focal point. No competing visual weights.
- Chrome recedes, content advances — high-contrast text against quieter frame.
- Design system tokens only. No arbitrary font sizes or weights.
- Display font for headings (e.g. Inter Display, Geist) for expression. Regular weight for body.
- Letter-spacing: slightly tighter on large headings (
tracking-tight), default on body.
Truncation
- Single-line:
truncate + min-w-0 on flex parent and span.
- Multi-line:
line-clamp-{n} with deliberate max.
- Text never overflows. Every string is bounded. Never
break-all.
States
- Loading:
<Skeleton> matching real layout shape + shimmer animation. Never spinner in content.
- Empty: title + one-line description + single CTA. Never blank.
- Error: human-readable message + what to do next.
- Disabled:
opacity-50 cursor-not-allowed. Never remove the element.
Tables & Data Display
- Full row highlight on hover (subtle background change).
- Right-aligned numbers, left-aligned text.
- Sortable columns with subtle indicator (chevron icon).
- Horizontally scrollable with frozen first column on overflow.
- Row actions on hover (progressive disclosure).
- Alternating row backgrounds at very low opacity (optional,
even:bg-muted/30).
Components
- shadcn/ui only. Never reimplement Dialog, Tooltip, Dropdown, Select, Tabs, Badge, Card, Skeleton.
- Lucide icons only. No emojis. No decorative AI icons (sparkles, wands, stars).
- Icon-only buttons: MUST wrap in
<Tooltip> with short label. No exceptions.
- Consistent icon size per density (16px dense, 18-20px standard). Don't mix arbitrarily.
- Consistent border radius throughout — never deviate from system radius.
Spacing
- 4px base scale. No arbitrary values (
mt-[13px] is a violation).
- No orphaned elements. Everything on a layout grid.
- Remove borders/dividers replaceable by spacing alone.
- Generous whitespace — empty space IS the design.
Polish
- No
console.log in UI components.
- No
z-[9999] — use defined z-index scale.
- No
!important overrides.
- No hardcoded colors — all through CSS variables.
Escape closes every overlay.
- URL updates on tab/section change for shareability.
- Responsive: sidebar collapses to icon-only or drawer on mobile. Panels stack vertically.
Audit Output Format
For each issue:
- File path + line
- What's wrong (one sentence)
- The fix
Group by: Color/Surface → Motion → Layout → Keyboard → Progressive Disclosure →
Density → Interactivity → Typography → States → Tables → Polish
Rank: broken interactions > missing keyboard support > missing states > motion gaps > visual inconsistency > polish.
End with: what still needs human design judgment that code alone cannot fix.
1---2name: linear-design3description: Build and audit Linear/Vercel/Notion-quality UI. Covers color systems, motion, progressive disclosure, keyboard-first design, layout architecture, surface elevation, information density, micro-interactions, and state handling. Use when building UI components, reviewing design quality, creating pages, or when the user asks for a design review.4---56# Linear-Quality Design System78Build UI with the craft of Linear, Vercel, and Resend. Great UI is restraint, not addition.9The best details are invisible — felt, not seen.1011## Color System1213Design a **derived color system**, not a palette of hardcoded values.1415- Define 3 foundation variables: **base color**, **accent color**, **contrast level**.16- Derive all surfaces, text, icons, borders from these via opacity operations.17- Use perceptually uniform color space (LCH/OKLCH) so colors at same lightness look equally light.18- Hierarchy through **opacity and weight**, not hue. Monochrome-first.19- Color ONLY for semantic meaning: error (red), success (green), active/selected, brand accent.20- No decorative color. No habitual colored icons — make them `muted-foreground`.21- Limit brand color leakage into chrome. The frame should feel neutral and timeless.22- No hardcoded hex anywhere. CSS variables / design tokens only.2324## Surface & Elevation2526Layer surfaces with subtle background shifts, not heavy shadows.2728- Define clear elevation hierarchy: `background` → `card/raised` → `popover` → `dialog/modal`.29- Each level is a slight shade shift (via opacity on base), not a different color.30- **Dark mode**: shadows become subtle borders or glows. Replace `shadow-md` with `border border-border/50`.31- **Borders**: semi-transparent at low opacity (`border-border/40`), never solid opaque lines.32- **Backdrop blur** on floating elements: `backdrop-blur-sm` on overlays, popovers, command palette.33- Support high-contrast mode via the contrast variable — accessibility built into the system.34- `-webkit-font-smoothing: antialiased` globally.3536## Motion & Animation3738Motion is ~30% of why premium UI feels premium. `transition-colors duration-150` is the floor.3940- **Micro-transitions**: color/opacity changes use `duration-150 ease-out`.41- **Layout transitions**: panels, drawers, sidebars use `duration-200 ease-in-out`.42- **Entrances**: modals/dialogs use spring-based easing — slight overshoot, then settle.43 Framer Motion: `type: "spring", stiffness: 400, damping: 30`. CSS: `cubic-bezier(0.34, 1.56, 0.64, 1)`.44- **List stagger**: items entering a list animate in with 30-50ms stagger between each.45- **Skeleton shimmer**: animated gradient sweep matching content shape, not a static gray box.46- **Toasts**: slide in from consistent anchor (bottom-right), slide out on dismiss.47- **Number animations**: counters animate between values, don't jump.48- **Exit animations**: elements leaving should animate out (opacity + slight translate), not vanish.49- Never add artificial delays. Motion should feel instant-but-smooth, not slow.5051## Layout Architecture5253The structural patterns that make an app feel like a tool, not a website.5455- **Three-column layout**: collapsible sidebar (240-280px) + main content + optional detail panel.56- **Resizable panels**: drag handles between columns. Show handle on hover, store width preference.57- **Sticky headers**: compress or transform on scroll. Never duplicate content in header and body.58- **Sheet/drawer vs modal**: use sheets for contextual detail (stays in flow), modals for focused tasks59 (blocks flow). Sheets slide from right, modals center with backdrop.60- **Command palette**: `Cmd+K` overlay that floats above layout. Fuzzy search, categorized results,61 recent items, keyboard-navigable. This is primary navigation for power users.62- **Split views**: side-by-side content for comparison or detail-alongside-list.6364## Keyboard-First Design6566A Linear-quality app is faster with keyboard than mouse.6768- **Command palette** (`Cmd+K`): search commands, navigate, execute actions. Must exist.69- **Single-key shortcuts**: `C` to create, `S` for status, etc. Show in tooltips and context menus.70- **List navigation**: `j/k` or arrow keys to move through items, `Enter` to open.71- **Multi-select**: `Shift+Click` range select, `Cmd+Click` toggle individual.72- **Focus management**: after dialog close, focus returns to trigger. After create, focus new item.73- **Shortcuts in UI**: display keyboard shortcut hints in tooltips, context menus, and command palette74 results. This teaches users the shortcuts naturally.75- **Escape to dismiss**: every overlay, modal, popover, command palette closes on `Escape`.7677## Progressive Disclosure7879Resting state is minimal. Complexity reveals on interaction.8081- **Row actions**: edit, delete, options menu — visible only on row `:hover`.82- **Metadata**: timestamps, secondary badges — shown on hover where non-essential at rest.83- **Toolbars**: bulk action bars appear on selection, not permanently.84- **Contextual menus**: right-click surfaces full action set. Include keyboard shortcuts in menu items.85- **Sub-menu safe areas**: triangle hit area between cursor and sub-menu so diagonal mouse movement86 doesn't close the menu (the Linear pattern — ~40 lines of code, invisible to user, felt as smoothness).87- If it's not primary content or primary action, it should not be visible at rest.8889## Information Density9091Dense yet clean. Chrome is sparse, content is dense.9293- **Tight line-heights** in lists and tables (1.25-1.4, not Tailwind default 1.5).94- **Compact inline metadata**: status dot + avatar + priority icon + label, all in one row.95- **Tabular numbers**: `font-variant-numeric: tabular-nums` on all number columns so digits align.96- **Monospace**: IDs, branch names, code, technical strings in `font-mono text-xs`.97- **Right-align numbers** in table columns.98- **Density trade-off**: reduce chrome spacing (sidebar padding, header height) to give content room.99 Content area can be dense; navigation frame stays spacious.100101## Buttons & Actions102103- AT MOST one `variant="default"` (primary) button per page/modal/card.104- All other actions: secondary, outline, or ghost — pick by visual weight.105- Destructive: `variant="destructive"` + confirmation dialog before execution.106- Consistent button height per context. Never mix sizes in the same view.107- Cursor `pointer` on everything clickable.108109## Interactivity & Micro-interactions110111- Every clickable element: distinct `hover:` state (color/opacity) + `active:` state (pressed).112- No bare `<div onClick>` without visual hover feedback.113- Focusable elements: `focus-visible:ring-2 ring-ring`.114- **Drag handles**: appear on hover, hidden at rest.115- **Copy-to-clipboard**: brief "Copied!" feedback (tooltip or inline text swap, 1.5s).116- **Optimistic updates**: UI changes instantly on action, server catches up async.117- **Smart menu positioning**: menus stay in viewport, flip direction when near edges.118- **Input debounce**: search/filter inputs debounce 200-300ms, show subtle loading indicator.119120## Typography121122- Each view: one dominant heading, one focal point. No competing visual weights.123- Chrome recedes, content advances — high-contrast text against quieter frame.124- Design system tokens only. No arbitrary font sizes or weights.125- **Display font for headings** (e.g. Inter Display, Geist) for expression. Regular weight for body.126- **Letter-spacing**: slightly tighter on large headings (`tracking-tight`), default on body.127128## Truncation129130- Single-line: `truncate` + `min-w-0` on flex parent and span.131- Multi-line: `line-clamp-{n}` with deliberate max.132- Text never overflows. Every string is bounded. Never `break-all`.133134## States135136- **Loading**: `<Skeleton>` matching real layout shape + shimmer animation. Never spinner in content.137- **Empty**: title + one-line description + single CTA. Never blank.138- **Error**: human-readable message + what to do next.139- **Disabled**: `opacity-50 cursor-not-allowed`. Never remove the element.140141## Tables & Data Display142143- Full row highlight on hover (subtle background change).144- Right-aligned numbers, left-aligned text.145- Sortable columns with subtle indicator (chevron icon).146- Horizontally scrollable with frozen first column on overflow.147- Row actions on hover (progressive disclosure).148- Alternating row backgrounds at very low opacity (optional, `even:bg-muted/30`).149150## Components151152- shadcn/ui only. Never reimplement Dialog, Tooltip, Dropdown, Select, Tabs, Badge, Card, Skeleton.153- Lucide icons only. No emojis. No decorative AI icons (sparkles, wands, stars).154- Icon-only buttons: MUST wrap in `<Tooltip>` with short label. No exceptions.155- Consistent icon size per density (16px dense, 18-20px standard). Don't mix arbitrarily.156- Consistent border radius throughout — never deviate from system radius.157158## Spacing159160- 4px base scale. No arbitrary values (`mt-[13px]` is a violation).161- No orphaned elements. Everything on a layout grid.162- Remove borders/dividers replaceable by spacing alone.163- Generous whitespace — empty space IS the design.164165## Polish166167- No `console.log` in UI components.168- No `z-[9999]` — use defined z-index scale.169- No `!important` overrides.170- No hardcoded colors — all through CSS variables.171- `Escape` closes every overlay.172- URL updates on tab/section change for shareability.173- Responsive: sidebar collapses to icon-only or drawer on mobile. Panels stack vertically.174175## Audit Output Format176177For each issue:1781. File path + line1792. What's wrong (one sentence)1803. The fix181182Group by: **Color/Surface** → **Motion** → **Layout** → **Keyboard** → **Progressive Disclosure** →183**Density** → **Interactivity** → **Typography** → **States** → **Tables** → **Polish**184185Rank: broken interactions > missing keyboard support > missing states > motion gaps > visual inconsistency > polish.186187End with: what still needs human design judgment that code alone cannot fix.