marcus/marcus-skills · Archived

linear-design-patterns

Linear-inspired design system patterns for building keyboard-first, high-density, dark-first web applications. Use when (1) building a new design system or design tokens inspired by Linear's aesthetic, (2) implementing keyboard-first navigation with command palettes and vim-style shortcuts, (3) designing admin tools, developer tools, or SaaS UIs that prioritize speed and information density, (4) choosing color systems, typography, animation, or feedback patterns for professional/engineering-foc…

First seen Mar 13, 2026

Installation

$ npx skills add marcus/marcus-skills --skill linear-design-patterns

Summary

  • Linear-inspired design system patterns for building keyboard-first, high-density, dark-first web applications.
  • Use when (1) building a new design system or design tokens inspired by Linear's aesthetic, (2) implementing keyboard-first navigation with command palettes and vim-style shortcuts, (3) designing admin tools, developer tools, or SaaS UIs that prioritize speed and information density, (4) choosing color systems, typography, animation, or feedback patterns for professional/engineering-focused apps, (5) user mentions Linear, Linear-style, or asks for a clean/minimal/keyboard-first design approach.

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from marcus/marcus-skills.

npx skills add marcus/marcus-skills

Browse all from marcus/marcus-skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 2
Default branch main
Open issues 1
Status Archived

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 11,867 B
  • docs SUMMARY.md 639 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

Linear Design Patterns

Apply Linear's design philosophy to web applications. Covers color, typography, layout, keyboard interaction, animation, feedback, and visual polish.

Quick Decision Guide

Decision Linear's Answer
Light or dark default? Dark-first
Color space? LCH (perceptually uniform)
How many theme variables? 3: base, accent, contrast
Font? Inter + Inter Display for headings
Spacing base unit? 4px
Animation duration? ~200ms, ease-out
Confirm or undo? Undo (except irreversible)
Loading spinners? No — optimistic updates
Feedback location? Inline, next to the action
Keyboard support? Full app control, mouse optional
Command palette? Yes, Cmd+K, fuzzy search, context-aware
Navigation shortcuts? g then letter (vim-style)
Information density? High density, low clutter
Chrome/decoration? Minimal — content over chrome
Content surface shape? Sharp edges — no border-radius on data panels
Panel separation? 1px border lines, not gaps or shadows
When to elevate? Only floating overlays (modals, dropdowns, popovers)

Core Principles

  1. Keyboard-first, mouse-optional — every click action has a key equivalent
  2. Dark-first — dark mode is default, light mode is the variant
  3. Speed is a feature — 100ms interaction target, optimistic updates, no spinners
  4. Color restraint — near-monochrome, color only for status/accent
  5. High density, low clutter — pack information in through alignment, not cramming
  6. Be gentle — everything comfortable, natural, expected, no surprises

⚠️ Common Agent Mistakes — READ THIS FIRST

Agents consistently fail at this design system in the same ways. If you catch yourself doing any of these, stop and fix it immediately.

Mistake #1: Containers within containers

The most common failure. Agents instinctively wrap content in .card > .card-body > .card-content or .panel > .panel-inner. Never do this. The layout is a flat grid. Visual grouping comes from background colors, borders, and spacing — not from nesting.

This applies equally to conversational surfaces. Chat turns, activity feeds, and timeline rows should usually be rendered as flush rows inside a pane, using row padding, alternating tints, and subtle dividers. Do not put each turn inside its own floating card inside the conversation panel. The same rule applies to toolbars and filter rails. Do not place a bordered filter bar inside a bordered header surface. The header is already the surface. Put the controls directly on it.

WRONG:

<div class="stats-row">
  <div class="stat-card">
    <div class="stat-body">
      <h3>Total Requests</h3>
      <p>537,784</p>
    </div>
  </div>
</div>

RIGHT:

<div class="metric-grid">
  <div class="metric-cell">
    <span class="metric-label">Total Requests</span>
    <span class="metric-value">537,784</span>
  </div>
</div>

RIGHT for conversation rows:

<div class="conversation-pane">
  <div class="message-row user">...</div>
  <div class="message-row agent">...</div>
</div>

Mistake #2: box-shadow on data surfaces

Shadows are ONLY for floating overlays (modals, dropdowns, popovers). Never on tables, cards, panels, grids, or any data surface. Use 1px border lines instead.

Mistake #3: border-radius on data surfaces

Data grids, table rows, list items, content sections — all get border-radius: 0. Rounded corners are ONLY for interactive elements (buttons, pills, badges, inputs) and floating overlays.

Mistake #4: max-width containers that don't fill the viewport

Content should span the full width of its area. No max-width: 800px; margin: 0 auto on page content. The grid fills the space.

Mistake #5: Using traditional table markup for non-tabular data

Comments, blog posts, activity feeds — these are conversational/content, not spreadsheet data. Render them as styled row lists, not <table> elements. Use tables only when the data is genuinely columnar.

Mistake #7: Tinted header regions styled as cards

Header regions with background tints must be flush (edge-to-edge, no border-radius, no outer margin). They are NOT cards — they're just colored zones within a panel. Use a border-bottom: 1px solid in the tint color for separation. Never add border-top, border-radius, or outer margin to a tinted header region.

/* ✅ Correct */
.panel-header {
  background: rgba(163, 113, 247, 0.05);
  border-bottom: 1px solid rgba(163, 113, 247, 0.2);
  border-radius: 0;
  margin: 0;
  padding: var(--space-3); /* inner padding is fine */
}

/* ❌ Wrong — looks like a floating card */
.panel-header {
  background: rgba(163, 113, 247, 0.05);
  border-top: 2px solid #a371f7;
  border-radius: var(--radius-md);
  margin: 0 0 var(--space-3) 0;
}

Mistake #6: Bland pages with no color differentiation

Color restraint doesn't mean no color. Use the status color system actively:

  • Badges with colored dots for status (green=success, amber=warning, red=error)
  • Subtle background tints for status rows (e.g., rgba(229, 166, 62, 0.05) for pending items)
  • Accent color for active states, links, primary actions
  • Typography hierarchy (size, weight, opacity) creates visual interest without decoration

Concrete Patterns

Metric Grid

.metric-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-bottom: 1px solid var(--color-border-strong);
}
.metric-cell {
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  border-right: 1px solid var(--color-border-strong);
}
.metric-cell:last-child { border-right: none; }

Status Badge with Dot

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 1px var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  font-weight: var(--font-medium);
}
.badge-dot {
  width: 6px;
  height: 6px;
  border-radius: var(--radius-full);
}
.badge-success { background: var(--color-success-bg-subtle); color: var(--color-success); }
.badge-warning { background: var(--color-warning-bg-subtle); color: var(--color-warning); }
.badge-error { background: var(--color-error-bg-subtle); color: var(--color-error); }

Button System

.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border-radius: var(--radius-sm);
  font-weight: var(--font-medium);
  cursor: pointer;
  transition: all var(--duration-fast);
  white-space: nowrap;
}
.btn-primary { background: var(--color-accent-default); color: var(--color-on-accent); }
.btn-secondary { background: var(--color-bg-tertiary); color: var(--color-text-primary); border: 1px solid var(--color-border-default); }
.btn-ghost { color: var(--color-text-secondary); }
.btn-ghost:hover { background: var(--color-bg-tertiary); color: var(--color-text-primary); }

Filter Controls

Filter toggles are low-contrast, border-only controls designed for high-density filtering layouts. They differ from primary buttons by using no background fill and promoting the border as the primary visual indicator.

Container:

.filter-bar {
  display: flex;
  gap: var(--space-1);
  align-items: center;
}

Individual toggle:

.filter-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  background: none;
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-sm); /* Square, NOT rounded */
  color: var(--color-text-secondary);
  font-size: var(--text-xs);
  font-weight: var(--font-medium);
  cursor: pointer;
  transition: all var(--duration-fast);
}
.filter-toggle:hover {
  border-color: var(--color-border-strong);
  color: var(--color-text-primary);
}
.filter-toggle.active {
  border-color: var(--color-accent-default);
  color: var(--color-accent-default);
}

Key points:

  • Default state: subtle border, no background, secondary text color
  • Hover state: stronger border, promoted text color, still no background
  • Active state: accent color on border and text only — no background fill
  • Use square borders (var(--radius-sm)) NOT rounded (var(--radius-full))
  • Prefer icons (from @marcus/roc) over emoji for filter labels
  • Reference implementation: Perch's frontend/src/lib/styles/filters.css

Slide-in Detail Panel

.detail-panel {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  width: 480px;
  background: var(--color-bg-secondary);
  border-left: 1px solid var(--color-border-strong);
  z-index: 51;
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 300ms cubic-bezier(0.16, 1, 0.3, 1);
  box-shadow: var(--shadow-lg); /* OK — this is a floating overlay */
}
.detail-panel.open { transform: translateX(0); }

Content Row (for lists, feeds, comments)

.content-row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-3);
  border-bottom: 1px solid var(--color-border-default);
  cursor: pointer;
  transition: background var(--duration-fast);
}
.content-row:hover { background: var(--color-bg-tertiary); }

Sidebar Navigation

.sidebar {
  background: var(--color-bg-inset);
  border-right: 1px solid var(--color-border-strong);
  display: flex;
  flex-direction: column;
}
.nav-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md); /* OK — interactive element */
  color: var(--color-text-secondary);
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
}
.nav-item.active {
  background: var(--color-bg-tertiary);
  color: var(--color-text-primary);
}
.nav-item.active::before {
  content: '';
  position: absolute;
  left: 0; top: 50%;
  transform: translateY(-50%);
  width: 3px; height: 16px;
  background: var(--color-accent-default);
  border-radius: var(--radius-full);
}

Implementation

For full design system details covering color, typography, layout, navigation, interaction, animation, feedback, and visual polish patterns, see [references/linear-design-system.md](references/linear-design-system.md).

Key sections:

  • A. Color & Theming — LCH color space, 3-variable themes, dark-first
  • B. Typography — Inter family, hierarchy through weight/size only
  • C. Layout & Navigation — inverted-L, list/detail split, collapsible sidebar
  • D. Surface Architecture — flush tiled grids, sharp edges on data, border hierarchy, elevation only for overlays
  • E. Information Density — in-place editing, contextual menus
  • F. Interaction & Speed — optimistic updates, command palette, keyboard shortcuts
  • G. Motion & Animation — 200ms, purposeful micro-interactions only
  • H. Feedback — inline over toasts, undo over confirmation
  • I. Visual Polish — tight alignment, subtle gradients, "be gentle"
  • J. Progressive Disclosure — works out of the box, natural language filters, universal URLs