Reseed
All demos

Live demo · cached extraction

linear.app

https://linear.app
Originally extracted in 61.4s
Minimal SaaS·Restrained & Technical·extracted in 61.4s

Color is information, not decoration — the only saturated hue in the chrome is indigo, and it only appears when something has status.

The pitch

I built this for people who live inside their tools eight hours a day, not for first-time visitors who need to be sold. That's why headlines run at 510 weight, not 600 or 700 — bold reads as marketing, and Linear isn't marketing, it's infrastructure. The page sits on near-black #08090a with surfaces only one or two steps up (#0f1011, #1c1c1f), because every saturated pixel needs to mean something — the indigo #5e6ad2 is reserved for status dots and the 'In Progress' chip, never for decoration. We rejected drop shadows entirely in the chrome; elevation comes from 1px borders in #23252a and subtle background shifts, which is harder to get right but stays out of the way when you're scanning 145 issues. Inter Variable at 16px body, Berkeley Mono for code tokens like `vehicle_state` — the mono isn't decorative, it's signaling 'this is a literal value.' The trade-off I accept: a cold visitor on the marketing site gets none of the warmth or visual hooks a conversion-optimized landing page would offer, and we lose some of them in the first three seconds.

Signature move

Headlines at 510 font-weight — heavier than regular, lighter than bold — giving the product presence without the marketing-deck loudness that 600+ weights carry.

When to use it

Reach for it

Building a developer or operator tool where users return daily, density matters more than first-impression delight, and chrome should disappear behind the work.

Wrong fit

Shipping a marketing site that needs to convert cold traffic, or a consumer product where warmth and personality drive trust — the restraint reads as indifference.

What gets written

The files dropped into your repo

design-system.md17.6 KB
---
name: linear.app
description: "I built this for people who live inside their tools eight hours a day, not for first-time visitors who need to be sold. That's why headlines run at 510 weight, not 600 or 700 — bold reads as marketing, and Linear isn't marketing, it's infrastructure. The page sits on near-black #08090a with surfaces only one or two steps up (#0f1011, #1c1c1f), because every saturated pixel needs to mean something — the indigo #5e6ad2 is reserved for status dots and the 'In Progress' chip, never for decoration. We rejected drop shadows entirely in the chrome; elevation comes from 1px borders in #23252a and subtle background shifts, which is harder to get right but stays out of the way when you're scanning 145 issues. Inter Variable at 16px body, Berkeley Mono for code tokens like `vehicle_state` — the mono isn't decorative, it's signaling 'this is a literal value.' The trade-off I accept: a cold visitor on the marketing site gets none of the warmth or visual hooks a conversion-optimized landing page would offer, and we lose some of them in the first three seconds."

colors:
  primary: "#5e6ad2"
  background: "#08090a"
  surface: "#0f1011"
  surface-2: "#1c1c1f"
  fg: "#f7f8f8"
  fg-muted: "#8a8f98"
  border: "#23252a"
  neutral-1: "#62666d"

typography:
  sans: Inter Variable
  mono: Berkeley Mono
  weights: [400, 510, 590]
  scale:
    page-hero:
      size: 64px
      lineHeight: 64px
      classes: text-6xl font-medium tracking-tight
    page-hero-2:
      size: 48px
      lineHeight: 48px
      classes: text-5xl font-medium tracking-tight
    section-header:
      size: 24px
      lineHeight: 32px
      classes: text-2xl font-semibold
    subsection-header:
      size: 20px
      lineHeight: 26px
      classes: text-xl font-semibold
    body:
      size: 16px
      lineHeight: 24px
      classes: text-base
    caption-secondary:
      size: 15px
      lineHeight: 24px
      classes: text-sm font-medium

rounded:
  button: 6px
  card: 8px

spacing:
  container: max-w-6xl mx-auto px-6
  section: py-20

components:
  button-primary:
    background: "{colors.primary}"
    text: "{colors.background}"
    rounded: "{rounded.button}"
    padding: 8px 12px
  button-secondary:
    background: "{colors.surface}"
    text: "{colors.fg}"
    border: "1px solid {colors.border}"
    rounded: "{rounded.button}"
    padding: 8px 12px
  card:
    background: "{colors.surface}"
    border: "1px solid {colors.border}"
    rounded: "{rounded.card}"
    padding: 24px
  input:
    background: "{colors.surface}"
    text: "{colors.fg}"
    placeholder: "{colors.fg-muted}"
    border: "1px solid {colors.border}"
    rounded: "{rounded.input}"
    padding: 8px 10px
---

# Design System — inspired by linear.app

> **Color is information, not decoration — the only saturated hue in the chrome is indigo, and it only appears when something has status.**

I built this for people who live inside their tools eight hours a day, not for first-time visitors who need to be sold. That's why headlines run at 510 weight, not 600 or 700 — bold reads as marketing, and Linear isn't marketing, it's infrastructure. The page sits on near-black #08090a with surfaces only one or two steps up (#0f1011, #1c1c1f), because every saturated pixel needs to mean something — the indigo #5e6ad2 is reserved for status dots and the 'In Progress' chip, never for decoration. We rejected drop shadows entirely in the chrome; elevation comes from 1px borders in #23252a and subtle background shifts, which is harder to get right but stays out of the way when you're scanning 145 issues. Inter Variable at 16px body, Berkeley Mono for code tokens like `vehicle_state` — the mono isn't decorative, it's signaling 'this is a literal value.' The trade-off I accept: a cold visitor on the marketing site gets none of the warmth or visual hooks a conversion-optimized landing page would offer, and we lose some of them in the first three seconds.

**Signature move.** Headlines at 510 font-weight — heavier than regular, lighter than bold — giving the product presence without the marketing-deck loudness that 600+ weights carry.

**Use this when.** Building a developer or operator tool where users return daily, density matters more than first-impression delight, and chrome should disappear behind the work.
**Avoid when.** Shipping a marketing site that needs to convert cold traffic, or a consumer product where warmth and personality drive trust — the restraint reads as indifference.

When in doubt: less. Restraint reads as confidence.

## Rules

- **Color**: Use only tokens from `tailwind.config.ts` theme.colors. Never hardcode hex values, hsl(), or arbitrary `bg-[#...]` classes.
- **Spacing**: Use Tailwind's default scale. Avoid arbitrary values like `p-[18px]` unless matching a fixed asset.
- **Type weights**: Only `font-normal`, `font-medium`, `font-semibold`. Do not introduce other weights.
- **Radius**: Buttons and inputs use `rounded-md`. Cards use `rounded-lg`. Avatars use `rounded-full`. Nothing else.
- **Borders before shadows**: Use `border border-border` for elevation. Reserve `shadow-sm` for floating menus only.
- **Motion**: Hover transitions are `transition-colors duration-150`. Never animate layout. Never use `duration-500` or longer for UI feedback.
- **Container**: Page content sits in `max-w-6xl mx-auto px-6`. Sections use `py-20`.
- **Icons**: Use `lucide-react` at `size-4` (default) or `size-5` (emphasis). No emoji in UI.

## Tokens

### Color (defined in `tailwind.config.ts`)

| Token | Value | Use for |
|---|---|---|
| `bg-primary` | `#5e6ad2` | Primary brand color |
| `bg-background` | `#08090a` | Page background |
| `bg-surface` | `#0f1011` | Surface background, elevated above page |
| `bg-surface-2` | `#1c1c1f` | Elevated hover state |
| `text-fg` | `#f7f8f8` | Primary text, headings |
| `text-fg-muted` | `#8a8f98` | Secondary text, muted content |
| `border-border` | `#23252a` | Borders, dividers |
| `bg-neutral-1` | `#62666d` | Tertiary text, placeholders |

### Type scale

| Class | Size / line-height | Use for |
|---|---|---|
| `text-6xl font-medium tracking-tight` | 64px / 64px | Page hero |
| `text-5xl font-medium tracking-tight` | 48px / 48px | Page hero |
| `text-2xl font-semibold` | 24px / 32px | Section header |
| `text-xl font-semibold` | 20px / 26px | Subsection header |
| `text-base` | 16px / 24px | Body |
| `text-sm font-medium` | 15px / 24px | Caption / secondary |

### Font families

- **Sans**: Inter Variable. Class: `font-sans`.
- **Mono**: Berkeley Mono. Class: `font-mono`. Code only.


## Components

### Button

- **Primary**: `bg-primary text-background px-3 h-8 rounded-md text-sm font-medium hover:opacity-90 transition-colors`
- **Secondary**: `bg-surface text-fg border border-border px-3 h-8 rounded-md text-sm font-medium hover:bg-opacity-80`
- **Ghost**: `text-fg-muted px-3 h-8 rounded-md text-sm hover:bg-surface hover:text-fg`
- **Sizes**: only `h-8` (default) and `h-7 text-xs` (compact).

### Card

`bg-surface border border-border rounded-lg p-6`

Cards never have shadows in this design. Hover state: slightly lighter border.

### Input

`bg-surface border border-border rounded-md h-8 px-2.5 text-sm text-fg placeholder:text-fg-muted focus:outline-none focus:border-primary`

### Section

```html
<section class="py-20">
  <div class="max-w-6xl mx-auto px-6">
    ...
  </div>
</section>
```


## Anti-patterns — this design does NOT use

- **Drop shadows.** Depth comes from borders and surface tints. Never `shadow-md`, `shadow-lg`, etc.
- **Gradients.** All fills are solid. No `bg-gradient-*`.
- **Multiple accent colors.** There is one accent (`primary`). No success-green, warning-yellow, etc., unless explicitly building a status indicator.
- **Heavy font weights.** The maximum weight in this design is `font-semibold` (600).
- **Light font weights.** This design does not use `font-light` or `font-thin` for UI text.
- **Pill-shaped buttons (rounded-full).** Buttons use `rounded-md`. `rounded-full` is reserved for avatars and badges.
- **Decorative animations.** No fade-in-on-scroll, parallax, or entrance animations on page load. Motion is reserved for hover/focus feedback.
- **Emoji in UI.** Use `lucide-react` icons. Never emoji in buttons, headings, or interface chrome.
- **Centered body text.** Long-form content is left-aligned. Centering is reserved for hero headlines and short CTA blocks.
- **Multiple type families on one screen.** Sans for everything except code blocks (mono).
- **Arbitrary Tailwind values.** Avoid `text-[15px]`, `p-[13px]`, `bg-[#abc]` — these break the system. If a value is missing from the theme, add it to `tailwind.config.ts` first.


## Slop to avoid

Patterns AI coding agents reach for that produce visibly AI-generated UI. Avoid all of these. Items marked **avoided here** are choices the source design explicitly makes — preserve them when generating new screens.

- **Purple-to-pink gradient hero**
  The default LLM hero — every AI starter looks like this. Reads as 'made by ChatGPT' on sight.
  - ✗ `bg-gradient-to-br from-purple-600 to-pink-500`
  - ✓ Solid brand color with one accent. Reserve gradients for illustration, not chrome.
- **Glassmorphism card (frosted blur)**
  backdrop-blur + low-opacity white was a 2021 trend. AI agents pile it on every modal and card.
  - ✗ `bg-white/10 backdrop-blur-md border border-white/20`
  - ✓ Solid surface color with a 1px border. If you need elevation, raise the surface.
- **Stacked drop shadows on every surface** — _avoided here_
  shadow-md on cards, shadow-lg on modals, shadow-xl on hover — depth performed instead of designed.
  - ✗ `shadow-md hover:shadow-xl`
  - ✓ Pick one: borders OR shadows for elevation, never both. Reserve shadow for floating menus.
- **Gradient text on headlines**
  bg-clip-text on every H1 — distracts from the message and ages instantly.
  - ✗ `bg-gradient-to-r from-blue-500 to-purple-500 bg-clip-text text-transparent`
  - ✓ Solid foreground color. If the headline needs emphasis, use weight or size.
- **Pill-shaped buttons everywhere** — _avoided here_
  rounded-full is the consumer-app default. On a B2B/dev tool it reads as derivative.
  - ✗ `rounded-full px-6 py-3`
  - ✓ Match the radius vocabulary of the design — usually 4-8px on dev tools, 12-16px on consumer.
- **Inter or Geist as the default 'modern' font**
  Every AI-generated UI uses Inter. It's not wrong, it's just the same answer everyone gets.
  - ✗ `font-family: "Inter", sans-serif;`
  - ✓ If you don't have a brand font, use the system stack. If you do, use it. Don't reach for Inter as a 'safe' default.
- **Decorative emoji in headings and buttons**
  "🚀 Launch your app" — emoji as decoration is the visual equivalent of comic sans for AI output.
  - ✗ `<button>🚀 Get started</button>`
  - ✓ Use icon components (lucide, heroicons). Reserve emoji for user-generated content.
- **Generic testimonial cards with stock-photo avatars**
  Three round avatars, three star ratings, three made-up quotes — the AI 'social proof' template.
  - ✗ `<Avatar src="/photo-1.jpg" /> "Game-changer for our team!" — Sarah, CEO`
  - ✓ Real testimonials with real attribution, or omit the section entirely.
- **3D-tilted feature cards on hover**
  perspective(1000px) rotateX/rotateY hover effects — 2023 SaaS-template default.
  - ✗ `hover:transform hover:rotate-1 hover:scale-105 transition-all`
  - ✓ Subtle border-color or background-color change on hover. Static layouts read as confident.
- **Green-checkmark feature lists**
  Every AI pricing page has the same ✓ ✓ ✓ list. Becomes wallpaper.
  - ✗ `<li><CheckCircle className="text-green-500" /> Unlimited projects</li>`
  - ✓ If the list is short, write prose. If it's long, use a comparison table.
- **Center-aligned long-form content**
  AI defaults to text-align:center for everything. Long-form reads as ad copy when centered.
  - ✗ `<div class="text-center max-w-3xl mx-auto">{long paragraph}</div>`
  - ✓ Center hero headlines and short CTA blocks only. Body content is left-aligned.
- **Vague aspirational hero headline**
  "Build the future of your business" — meaningless because it would fit any product.
  - ✗ `<h1>Empower your team to do their best work</h1>`
  - ✓ Name the user, the action, and the outcome. If you swap your product name and the headline still works, rewrite it.
- **Bento grid with mixed card sizes**
  The Apple-pages-imitator layout. Used as an excuse not to decide what's important.
  - ✗ `Grid of 6 cards, 2 large + 4 small, each with a different feature.`
  - ✓ Linear list of features in priority order. If you must use a grid, make all cards equal weight.
- **Animated mesh-gradient background**
  The 'I learned about CSS conic-gradient last week' look. Distracts from content, kills perf.
  - ✗ `Animated SVG mesh or conic-gradient with @keyframes rotation`
  - ✓ Static background. If the page needs energy, get it from typography or content density.
- **Auto-playing hero video loop**
  10MB MP4 of generic abstract footage. Page LCP cratered, brand value zero.
  - ✗ `<video autoplay loop muted><source src='/abstract-tech.mp4' /></video>`
  - ✓ Static image, animated SVG, or a real product screenshot.
- **Translucent navigation with backdrop-blur**
  Apple did it once. Now every AI agent puts blur(12px) on every nav.
  - ✗ `fixed top-0 bg-white/80 backdrop-blur-md`
  - ✓ Solid nav background. If you must, add a 1px bottom border on scroll.
- **Arbitrary Tailwind values everywhere**
  p-[13px], text-[15px], bg-[#f3e1c4] — the design system was abandoned line-by-line.
  - ✗ `px-[13px] text-[15px] bg-[#f3e1c4]`
  - ✓ Use scale tokens. If a value is missing, add it to the theme first.
- **Untouched shadcn slate/zinc default palette**
  The 'I installed shadcn and never theme'd it' look. Looks like every AI-generated app.
  - ✗ `Using the default `--primary: 222.2 47.4% 11.2%` and `--background: 0 0% 100%` from shadcn init.`
  - ✓ Replace the default tokens with your brand palette before shipping.
- **py-32 / py-48 between every section**
  Vertical whitespace as a substitute for content. The page scrolls forever, says nothing.
  - ✗ `py-32 (everywhere)`
  - ✓ Match the rhythm of your content. py-16 to py-24 is usually plenty.
- **One icon per word in headings**
  AI agents add lucide icons next to every nav link, button, and bullet — visual noise.
  - ✗ `<Button><Sparkles /> Try it free</Button>`
  - ✓ Reserve icons for nav and actions where the icon adds meaning the word doesn't.
- **Neumorphism (soft 3D embossed) buttons**
  Two opposing shadows on every button to fake 3D. Accessibility nightmare and looks dated.
  - ✗ `shadow-[inset_2px_2px_5px_#bbb,_-3px_-3px_5px_#fff]`
  - ✓ Flat or border-only. Save 3D for actual physical product mockups.
- **Auto-scrolling logo marquee for 'social proof'**
  12 customer logos sliding across the page. Reads as 'we copied Stripe's homepage'.
  - ✗ `Animate-x infinite scroll of grayscale customer logos`
  - ✓ Static grid of 4-6 real customer logos, no animation.
- **Dark mode = invert all the colors** — _avoided here_
  Pure-black bg with white text and the same brand color at full saturation — eye-fatigue mode.
  - ✗ `html.dark { background: #000; color: #fff; }`
  - ✓ Real dark mode uses near-black (not pure), softened text (not pure white), and desaturated accents.
- **Framer-template-style: hero / features / pricing / testimonials / cta / footer**
  The same six sections in the same order on every AI-generated landing page.
  - ✗ `Hero → Features → Pricing → Testimonials → CTA → Footer with no variation.`
  - ✓ Decide what your page actually needs to convince the reader. Skip sections that don't earn their space.
- **Bootstrap-default status colors (red/yellow/green/blue)**
  #ff0000 #ffcc00 #00cc00 #0066ff — the 'I didn't theme my status palette' tell.
  - ✗ `text-red-500 text-yellow-500 text-green-500 text-blue-500`
  - ✓ Tint your status colors toward your brand palette. Desaturate them on dark mode.
- **Mixing a serif "elegant" headline with a sans body for "contrast"** — _avoided here_
  Editorial type pairing applied to a SaaS landing — reads as a Squarespace template.
  - ✗ `<h1 class="font-serif">Reimagine work</h1><p class="font-sans">…</p>`
  - ✓ One typographic voice. If you want hierarchy, use weight and size, not family.
- **Fade-in/slide-up on every section as the user scrolls**
  data-aos='fade-up' on every block. The user can't read until they wait for the animation.
  - ✗ `Every <section> has an entrance animation triggered by IntersectionObserver.`
  - ✓ Static layouts. Reserve motion for actual interactions (hover, focus, modal open).
- **12-column footer with 60+ links**
  Copying SaaS-megacorp footers without their actual content depth. Empty links for 'Product / Solutions / Resources'.
  - ✗ `<footer> with 6 columns × 10 links each, 80% leading to empty pages.`
  - ✓ List the pages you actually have. A 4-link footer is fine.
- **Stat blocks with made-up percentages**
  "99% faster", "10× more efficient", "3× ROI" — round numbers no real customer cited.
  - ✗ `<div>99%</div><div>faster deploys</div>`
  - ✓ Real metrics with real attribution, or skip the section.
- **"Eyebrow" + "Big Claim" + "Subtitle" pattern on every section**
  The mandatory three-line section opener. Recognizable as AI output from the silhouette alone.
  - ✗ `<small>WHY US</small><h2>Built for teams</h2><p>The platform that scales…</p>`
  - ✓ One headline that earns its space. Drop the eyebrow unless it's load-bearing taxonomy.

_Slop catalog is shipped as `slop.json` for programmatic access. Catalog concept popularized by [Impeccable](https://impeccable.style/)._

## Visual reference

Open `.reseed/design-reference.html` in a browser to see every token and
component rendered. Use it to verify visual decisions before committing.

Source: extracted from <https://linear.app> on 2026-05-07.
Re-extract with `npx reseed-cli update`.
CLAUDE.mdappended on init
Same snippet works for AGENTS.md, .cursor/rules

When you run npx reseed-cli init https://linear.app, Reseed appends this block to your existing CLAUDE.md (or AGENTS.md, or creates one if absent) so your AI editor automatically picks up the rules:

## Design system

This project's design language is documented in [.reseed/design-system.md](.reseed/design-system.md). When generating UI, follow the rules and tokens defined there. Open `.reseed/design-reference.html` for a visual reference.

The generated .reseed/design-system.md is the load-bearing file — Cursor, Claude Code, and Windsurf read it transitively from the pointer above on every prompt.

Drop this into your codebase

One command writes all four files into your repo.

$npx reseed-cli init https://linear.app