All references

Design reference

Linear

A dark-only product interface where separation is drawn with light rather than shadow — every raised surface is an inset white hairline at three to five percent. Inter Variable runs on non-integer weights (510, 590, 680) with cv01/ss03 enabled, body copy sits in tertiary grey rather than white, and one indigo carries the brand while a near-white pill carries the action. Editorial pages swap the display face to a serif.

39 colors · 17 type steps · 10 components · analyzed: homepage, pricing, and the /method editorial surface, plus the header and footer chrome shared across all three


Colors

bg-marketing#010102
bg-primary#08090a
bg-level-1#0f1011
bg-level-2#141516
bg-level-3#191a1b
bg-secondary#1c1c1f
bg-tertiary#232326
bg-quaternary#28282c
bg-translucent#ffffff0d
header-bg#0b0b0bcc
text-primary#f7f8f8
text-secondary#d0d6e0
text-tertiary#8a8f98
text-quaternary#62666d

Typography

Inter Variable · Tiempos Headline · Berkeley Mono

title-972px · w590 · lh 1 · ls -0.022em
Linear
title-864px · w590 · lh 1.06 · ls -0.022em
Linear
title-756px · w510 · lh 1.1 · ls -0.022em
Linear
title-648px · w590 · lh 1 · ls -0.022em
Linear
title-editorial48px · w400 · lh 1 · ls 0em
Linear
title-540px · w590 · lh 1.1 · ls -0.022em
Linear
title-432px · w510 · lh 1.125 · ls -0.022em
Linear
title-324px · w590 · lh 1.33 · ls -0.012em
Linear
title-220px · w590 · lh 1.33 · ls -0.012em
Linear
title-117px · w590 · lh 1.4 · ls -0.012em
Linear
text-large17px · w400 · lh 1.6 · ls 0em
Linear
text-regular15px · w400 · lh 1.6 · ls -0.011em
Linear
text-small14px · w400 · lh 1.5 · ls -0.013em
Linear
text-mini13px · w400 · lh 1.5 · ls -0.01em
Linear
code13px · w400 · lh 1.5 · ls 0em
Linear
text-micro12px · w400 · lh 1.4 · ls 0em
Linear
text-tiny10px · w400 · lh 1.5 · ls -0.015em
Linear

Overview

Linear's marketing site is a dark product surface, not a dark marketing page. The canvas is {colors.bg-primary} (#08090a) — very close to black but never black — and hero sections go one step darker still on {colors.bg-marketing} (#010102). Everything above the canvas is separated not by a drop shadow but by an inset white hairline at three to five percent: the raised card, the panel, the input all read as lifted because a single pixel of light traces their edge.

The type system is unusually precise. Inter Variable runs on non-integer weights — 510 for medium and 590 for semibold rather than the conventional 500 and 600 — with cv01 and ss03 enabled and the optical-size axis left on auto. Nine title steps and six text steps are published as tokens, and negative tracking tightens from −0.012em on the small titles to −0.022em from 32px upward. Body copy sits in {colors.text-tertiary} (#8a8f98), not in the primary near-white; on this site white is reserved for headlines and the things you can act on.

Colour is disciplined to the point of austerity. One indigo, {colors.brand} (#5e6ad2), carries the brand; {colors.accent} (#7170ff) and {colors.link} (#828fff) are its two lighter siblings for interactive text. The primary call to action is not brand-coloured at all — it is a near-white pill, {colors.action-bg} (#e5e5e6), which on this canvas is the loudest thing available. Editorial surfaces such as /method break the system in exactly one deliberate place: the display face swaps from Inter to a serif, {typography.title-editorial}.

Key Characteristics:

  • Dark-only. There is no light theme; color-scheme: dark is set on the root and no light token set is published.
  • Elevation is drawn with light: inset 0 0 0 1px rgba(255,255,255,.03) rather than a cast shadow.
  • Non-integer weights — 300 / 400 / 510 / 590 / 680 — exploiting the Inter Variable axis.
  • Body copy is {colors.text-tertiary}; primary near-white is reserved for headlines and actions.
  • The primary action is a near-white pill, not the brand indigo.
  • {rounded.rounded} dominates: 14 of 18 rounded elements on the pricing surface are full pills.
  • Four background levels plus three border levels give depth without a single gradient.
  • One easing everywhere: cubic-bezier(.25, .46, .45, .94) at 0.1s and 0.16s.
  • The serif display face appears only on editorial pages — the one sanctioned exception.

Colors

Source pages analyzed: homepage, pricing, and the /method editorial surface, plus the header and footer chrome shared across all three.

Brand & Accent

  • Brand Indigo ({colors.brand} — #5e6ad2): The brand mark and brand-filled surfaces. Notably not the primary CTA colour.
  • Accent ({colors.accent} — #7170ff): A lighter indigo for interactive accents and highlights.
  • Link ({colors.link} — #828fff): Inline links, lighter again so it holds contrast as small text on the dark canvas. Pressed goes to {colors.link-hover} (pure white).
  • Accent Tint ({colors.accent-tint} — #18182f): The faintest indigo wash, for selected or highlighted rows.
  • Action ({colors.action-bg} — #e5e5e6): The primary button. A near-white pill is the highest-contrast object available on this canvas, so Linear spends its loudest value on the action rather than on the brand.

Surface

Four descending levels plus a marketing floor, all within a nine-value range of near-black:

  • Marketing ({colors.bg-marketing} — #010102): Hero sections. One step below the app canvas.
  • Primary ({colors.bg-primary} — #08090a): The page. Never pure black.
  • Level 1 ({colors.bg-level-1} — #0f1011): Panels and raised cards.
  • Level 2 ({colors.bg-level-2} — #141516) / Level 3 ({colors.bg-level-3} — #191a1b): Nested surfaces.
  • Secondary ({colors.bg-secondary} — #1c1c1f) through Quaternary ({colors.bg-quaternary} — #28282c): Controls, chips, inputs.
  • Translucent ({colors.bg-translucent} — rgba(255,255,255,.05)): The pressed state of a ghost control — light added, never a darker fill.
  • Header ({colors.header-bg} — #0b0b0bcc): 80% opaque over a 20px backdrop blur.

Text

  • Primary ({colors.text-primary} — #f7f8f8): Headlines and interactive labels. An off-white, never #fff.
  • Secondary ({colors.text-secondary} — #d0d6e0): Sub-headings and emphasised body. Faintly blue.
  • Tertiary ({colors.text-tertiary} — #8a8f98): Default body copy, and the resting colour of nav items.
  • Quaternary ({colors.text-quaternary} — #62666d): Disabled and the quietest metadata.

Hairlines & Borders

Two parallel ramps serve different jobs. border- are opaque and used on controls; line- are darker and used as structural rules between regions.

  • Border ({colors.border-primary} — #23252a, {colors.border-secondary} — #34343a, {colors.border-tertiary} — #3e3e44)
  • Translucent ({colors.border-translucent} — rgba(255,255,255,.05), {colors.border-translucent-strong} — rgba(255,255,255,.08)): The preferred edge, because it holds its relationship to whatever sits behind it.
  • Line ({colors.line-primary} — #37393a down to {colors.line-tertiary} — #18191a): Dividers.

Semantic

{colors.red} #eb5757 · {colors.green} #27a644 · {colors.yellow} #f0bf00 · {colors.orange} #fc7840 · {colors.teal} #00b8cc. Status only; they never appear as chrome.

Brand Gradient

No gradient tokens. Depth comes from the four background levels and the inset hairline. What reads as a glow in hero imagery is artwork, not CSS.

Typography

Font Family

  • Inter Variable — the interface and display face, loaded with font-feature-settings: "cv01", "ss03" and font-variation-settings: "opsz" auto. cv01 gives the single-storey lowercase g; ss03 adjusts the curved-r pairs. Both are on everywhere and are part of the site's fingerprint.
  • Tiempos Headline — serif, display only, and only on editorial surfaces (/method). See {typography.title-editorial}.
  • Berkeley Mono — code and technical labels.

Weights

300 light · 400 normal · 510 medium · 590 semibold · 680 bold.

The 510 and 590 are the tell. A variable axis makes any value available, and Linear uses that to sit slightly below the conventional 500/600 stops — enough to read as lighter and more precise at display sizes without losing structure.

Hierarchy

TokenSizeWeightLine HeightLetter SpacingUse
{typography.title-9}72px5901-0.022emLargest display step
{typography.title-8}64px5901.06-0.022emDisplay
{typography.title-7}56px5101.1-0.022emHomepage hero — note the lighter 510
{typography.title-6}48px5901-0.022emSection display
{typography.title-editorial}48px40010Serif. Editorial page headline only
{typography.title-5}40px5901.1-0.022emSection headline
{typography.title-4}32px5101.125-0.022emSub-section headline, usually in {colors.text-tertiary}
{typography.title-3}24px5901.33-0.012emCard headline
{typography.title-2}20px5901.33-0.012emFeature heading
{typography.title-1}17px5901.4-0.012emSmallest title step
{typography.text-large}17px4001.60Editorial body
{typography.text-regular}15px4001.6-0.011emDefault body
{typography.text-small}14px4001.5-0.013emSecondary copy
{typography.text-mini}13px4001.5-0.01emNav items, button labels
{typography.text-micro}12px4001.40Metadata
{typography.text-tiny}10px4001.5-0.015emBadges

Principles

  • Tracking tightens with size, in two bands. Titles up to 24px carry −0.012em; from 32px upward it jumps to −0.022em and stays there. Text steps run −0.011em to −0.015em, with 12px and 17px at zero.
  • Line-height inverts with size. 1 to 1.125 across the display range, 1.5 to 1.6 for text.
  • The hero is lighter than the ladder suggests. {typography.title-7} is published at 590 but the homepage h1 renders at 510 — the largest type gets the lightest treatment.
  • Section headings are often tertiary grey, not white. Hierarchy comes from size and colour together.
  • Editorial pages swap the face, not the system. Only the display step changes; body, spacing and colour stay identical.

Note on Font Substitutes

Inter is free (Google Fonts, variable) — use the real thing and keep the feature settings:

font-family: "Inter Variable", "Inter", system-ui, sans-serif;
font-feature-settings: "cv01", "ss03";
font-variation-settings: "opsz" auto;

Without cv01/ss03 the face is recognisably not Linear. Tiempos Headline is licensed from Klim; the closest free substitutes are Newsreader or Source Serif 4 at weight 400 — both need roughly −0.01em tracking added to match Tiempos' tighter fit. Berkeley Mono is commercial; JetBrains Mono is the nearest free equivalent.

Layout

Spacing System

  • Base unit: 4px, working scale 4 · 8 · 12 · 16 · 24 · 28 · 32 · 48 · 64.
  • Tokens: {spacing.xs} 4px · {spacing.sm} 8px · {spacing.md} 12px · {spacing.lg} 16px · {spacing.xl} 24px · {spacing.outer} 28px · {spacing.inset} 32px · {spacing.page-block} 48px · {spacing.section} 64px.
  • Button padding is 0 {spacing.md} on a fixed 32px height — controls are sized by height, not by vertical padding.

Grid & Container

ContextMax widthInset
Marketing pages1400px (calc(1344px + 28px * 2))28px
Documentation / app pages1024px24px
Prose column624px published; 410px measured on /method—

The grid is 8 columns, not 12 — narrower than the usual marketing grid and part of why the layout reads as a product rather than a brochure.

Whitespace Philosophy

Whitespace here is tight by marketing standards and generous by product standards, which is exactly the impression intended. Sections do not use large fixed vertical padding; they are separated by a change of background level or a line-* rule. The prose column is unusually narrow — around 410px on the editorial pages — which forces short measure and gives long-form pages the density of documentation rather than of a blog.

Elevation & Depth

LevelTreatmentUse
FlatBackground level change onlySections, page regions
Hairlineinset 0 0 0 1px rgba(255,255,255,.03)The default raised surface — 6 of 11 shadowed elements on the pricing page
Border1px rgba(255,255,255,.05)Controls, cards, inputs
Low0 2px 4px rgba(0,0,0,.1)Slightly lifted controls
Medium0 4px 24px rgba(0,0,0,.2)Popovers, menus
High0 7px 32px rgba(0,0,0,.35)Dialogs, command menu

Shadow philosophy. On a near-black canvas a cast shadow is invisible, so Linear inverts the technique: elevation is drawn with light. A raised surface gets one pixel of white at 3% inset along its edge; a stronger one gets 5%. Dark shadows exist in the token set and appear only under genuinely floating layers — popovers, dialogs — where they separate a surface from the content scrolling beneath it. Never reach for a dark shadow to raise a card.

Decorative Depth

  • Background levels ({colors.bg-primary} → {colors.bg-level-3}) do most of the work.
  • Backdrop blur appears once, on the header: 20px behind an 80%-opaque fill.
  • No gradients.

Shapes

Border Radius Scale

TokenValueUse
{rounded.none}0pxFull-bleed sections
{rounded.xs}4pxBadges, the smallest chips
{rounded.sm}6pxInline code, editor blocks
{rounded.md}8pxCompact controls, inline card imagery
{rounded.lg}12pxCards and panels
{rounded.xl} – {rounded.xxxl}16 / 24 / 32pxLarge containers and media frames
{rounded.rounded}9999pxAll buttons, nav items and chips
{rounded.circle}50%Avatars, icon buttons

The grammar is two-tier: pills mean interactive, 12px means container. On the pricing surface 14 of 18 rounded elements are pills, which is why the page reads as a control panel.

Media Geometry

Product screenshots sit on {component.surface-raised} at {rounded.lg} with the inset hairline, so the artwork appears inset into the page rather than laid on top of it.

Components

Top Navigation

header — 72px, sticky, {colors.header-bg} (#0b0b0b at 80%) over a 20px backdrop blur. Nav items are {component.button-ghost}: pill, 32px tall, {typography.text-mini} at {colors.text-tertiary}, transitioning colour and background over 0.1s. The right cluster pairs a ghost "Log in" with the near-white {component.button-action} "Sign up".

Buttons

All buttons are {rounded.rounded} and 32px tall, sized by height with 0 {spacing.md} inline padding.

button-action — The primary. {colors.action-bg} (#e5e5e6) fill, {colors.action-text} (#08090a) label, 1px border in the same value, {typography.text-mini} at weight 510. Pressed brightens the fill to {colors.action-bg-hover} (#ffffff). Transition: border 0.16s, background-color 0.16s on cubic-bezier(.25,.46,.45,.94).

button-ghost — Transparent with {colors.text-tertiary} label. Pressed adds {colors.bg-translucent} — light is added, never a darker fill. Transition 0.1s.

button-brand — {colors.brand} fill with white label, for brand moments rather than for the main conversion path.

Cards & Containers

surface-raised — {colors.bg-level-1}, {rounded.lg}, edge drawn with inset 0 0 0 1px rgba(255,255,255,.03). The default card.

surface-overlay — {colors.bg-secondary} with the stronger {colors.border-translucent-strong} edge and {colors.overlay} behind it, for menus and dialogs. This is where the dark medium/high shadows are permitted.

Inputs & Forms

Inputs follow {component.surface-overlay}: a {colors.bg-secondary} fill, a translucent white border and {rounded.md}. Validation and error states were not surfaced on the analyzed pages — see ## Known Gaps.

footer — {colors.bg-primary}, links in {typography.text-small} at {colors.text-primary} weight 400. Column headings use {colors.text-tertiary}. No background change from the page; a line-* rule separates it.

Do's and Don'ts

Do

  • Build on {colors.bg-primary} and lift surfaces with inset 0 0 0 1px rgba(255,255,255,.03).
  • Set body copy in {colors.text-tertiary} and reserve {colors.text-primary} for headlines and actions.
  • Use the non-integer weights: 510 for medium, 590 for semibold.
  • Keep font-feature-settings: "cv01", "ss03" on Inter — without them the face is not Linear.
  • Give every button {rounded.rounded} and a fixed 32px height.
  • Make the primary action the near-white pill, not the brand indigo.
  • Animate with cubic-bezier(.25, .46, .45, .94) at 0.1s for colour and 0.16s for anything structural.
  • Switch to {typography.title-editorial} only on long-form editorial pages.

Don't

  • Don't add a light theme; this system publishes no light token set.
  • Don't raise a card with a dark drop shadow — dark shadows belong to floating layers only.
  • Don't use pure black or pure white as a surface or as body text.
  • Don't make the brand indigo the primary CTA; it is a brand colour, not an action colour.
  • Don't round a container to a pill or a button to 12px — the two-tier grammar is the signal.
  • Don't widen the prose column past ~624px; the narrow measure is part of the voice.
  • Don't use the semantic colours as chrome — they carry status only.

Responsive Behavior

Breakpoints

The system is fluid rather than step-based: containers are min()-capped and the grid holds at 8 columns. The published constants are the marketing cap (1400px), the app cap (1024px), the prose cap (624px) and the page inline padding (24px, opening to 28–32px on wide viewports).

Touch Targets

--min-tap-size: 44px is published, but controls render at 32px on desktop — the token governs touch contexts, where the hit area is expanded around the same visual pill.

Collapsing Strategy

  • Header: the nav collapses behind a trigger at mobile; the 72px height and the action pill persist.
  • Type: the title ladder steps down through its published sizes rather than by media query per element.
  • Prose: the narrow column is already mobile-width, so long-form pages barely reflow.

Image Behavior

Product artwork keeps its {rounded.lg} frame and inset hairline at every width.

Iteration Guide

  1. Work on one component at a time, addressed by its YAML key ({component.surface-raised}, {component.button-action}).
  2. Variants live as their own components: entries with an -active suffix.
  3. Use {token.refs} everywhere; never inline a hex once a token exists.
  4. Document default and active/pressed states only — never hover.
  5. The two rules that define this language: elevation is drawn with light, not shadow, and body copy is tertiary grey. Break either and it stops being Linear.
  6. Before adding chrome for emphasis, change the background level instead.
  7. Weights are 510 and 590, not 500 and 600. The difference is visible at display sizes.

Known Gaps

  • No light theme exists to document. The root sets color-scheme: dark and publishes no light token set; this is a single-theme system.
  • Form validation and error states were not surfaced. The analyzed pages contained no form with visible validation; input styling is inferred from the overlay surface tokens.
  • The in-app product UI was not analyzed. These findings come from the marketing surfaces; the application itself may extend the system.
  • 54 of 77 stylesheets are cross-origin and could not be read as rules. Values here were resolved off the live root element instead, which yields computed values but not the authoring conditions behind them.
  • Spacing is derived. Linear publishes layout constants (page insets, container caps) but no numbered spacing scale; the scale here is the dominant measured set.
  • The full easing set is published but only one is used. Twenty-two Penner curves exist as tokens; only ease-out-quad was observed in effect on the analyzed pages.