- fg
#F7F8F8- bg
#000000- APCA Lc
- -103
- Use
- background on foreground
Linear
The rarest kind of product marketing page — one that earns trust through restraint rather than spectacle. Linear's landing is the lodestar of the post-Jira developer-tool renaissance; this is the reference to keep open in the next tab while you build.

Editorial disclaimer
This entry documents observable design-language patterns for educational transfer and AI-agent briefing. Screenshots and trademarks are property of their respective owners. AI2 Design is not affiliated with or endorsed by the featured brand. Inspiration here is about language and rhythm - do not reproduce brand identity, logo, product copy, or proprietary features.
Fair Use & Gallery PolicyCopy the full design language into your agent
A typed, paste-ready design system brief - philosophy, tokens, rules, techniques, and fitness checks. Drop it into Claude, Cursor, v0 or any coding agent and it builds in Linear’s language, not just a screenshot.
Dark-first typographic precision at 2px spatial resolution. The canvas is near-black; Inter Variable carries voice, weight, and rhythm across a custom 400 / 510 / 590 stepped ladder; large headings pull in with negative px tracking (-1.056 to -1.408px) to feel bound. Elevation is delivered through inset 1px borders, not drop shadows. Accent colors are used homeopathically — cyan and pink as ~3-4% radial glimmers, never as fills. Discipline over decoration, density over display.
Use this capture as a design language transfer brief for my project. Adopt the palette (dark-first near-black background + near-white foreground + homeopathic cyan/pink accents), typographic rhythm (Inter Variable with custom 400/510/590 weight ladder, negative px tracking on display), 2px-base spacing scale, border-first elevation (inset 1px shadows), cubic-bezier(0.25, 0.46, 0.45, 0.94) motion curve, and image-lazy-by-default strategy across every page and component I ship. Treat this as my project's constitution — any new component I author should pass as if crafted in the same studio. Apply the language, not the source brand's specific copy or identity. When I ask you to build a page or component, enforce these rules by default, and call out any decision that deviates.
- Layout
- Grid
- Content width
- Bounded
- Framing
- Flat
- Grid strength
- Strong
Dark-first canvas — #0f1011 primary background paired with #23252a panel and #f7f8f8 near-white foreground doing 92% of the surface work. Secondary text descends through cool grays: #62666d → #8a8f98 → #d0d6e0 for progressive de-emphasis. Accent palette is cyan (#55cdff) + pink (#f79ce0) + a thin green (#00ff05), appearing almost exclusively as radial glimmers and 90deg linear highlights at single-digit opacity — not as fills.
- Near-white #f7f8f8 text (weight 400) handling ~2491 measured surface occurrences — dominant reading layer
- Background pair #0f1011 (body) + #23252a (panel), maintaining 4.5+ contrast with #f7f8f8 foreground
- Cool gray descender #62666d / #8a8f98 / #d0d6e0 for captions, metadata, de-emphasized labels
- Cyan #55cdff and pink #f79ce0 used only inside gradients and as focus/highlight accents — surface area < 2%
- Semantic green #00ff05 reserved for critical positive state (a measured 20 occurrences, never decorative)
Gradients (paste-ready)
radial-gradient(50% 50%, rgba(255, 255, 255, 0.04) 0px, rgba(255, 255, 255, 0) 90%) linear-gradient(90deg, transparent 0px, color(srgb 0.129 0.702 1)) radial-gradient(52.53% 57.5% at 50% 100%, rgba(8, 9, 10, 0) 0px, rgba(8, 9, 10, 1))
- Primary family: Inter Variable (self-hosted, preloaded from /fonts/InterVariable.woff2). Monospace fallback: Berkeley Mono for code, tabular numerics.
- Weight ladder: 400 (reading) / 510 (UI labels + dense controls) / 590 (bold emphasis). Do not substitute 500 or 600 — the 510/590 stepping is the signature.
- Display tracking in px, not em: -0.165px on 15-18px body, -1.056px on 48px headings, -1.408px on 64px hero — constant optical correction at every size.
- Heading line-height is unitless 1.0 at 48-64px (display sits tight); 1.4-1.5 on body 13-16px; 1.3 on small UI labels 12px.
- Tabular numerals mandatory on aligned columns: `font-variant-numeric: tabular-nums`. Berkeley Mono handles code/kbd automatically.
- No italic for emphasis — Inter Variable carries through weight shift. Italic reserved for quoted editorial content.
- Paragraph max 45-55 ch at body 15-16px; dense tables may run to 65 ch at 13px with line-height 1.5.
- 2px base unit (not 4px). Scale: 2 / 4 / 6 / 8 / 10 / 12 / 14 / 16 / 19 / 22 / 24 / 26 — micro-density is the signature.
- Container max-width 1436px (wider than the Tailwind 1280 default). Secondary bounded rails at 368 / 440 / 480 px for narrow content clusters.
- Section vertical rhythm: 64-96px on desktop, 40-64px on mobile — driven by page depth, not section count.
- Card padding: 16-24px on desktop, 12-16px on mobile. Always pick from scale values; no magic numbers.
- Gutter values for flex/grid: 4 / 8 / 12 / 16 / 24 px — the 19 and 22 variants only appear for optical correction inside dense forms.
- Primary elevation is inset 1px border shadow — e.g. `box-shadow: rgb(35, 37, 42) 0 0 0 1px inset`. Use this before reaching for drop shadow.
- Drop shadows exist but are near-invisible: opacity 0.03-0.4, blur 1.2-12px, zero spread. Never a bloom, never a halo.
- Layering depth is delivered through border weight + background-shift (bg → bg-secondary), not through stacked shadow.
- Focus state uses a second inset ring at the accent color — never an outer glow.
Techniques
Inset-1px border as surface delimiter
Cards default to `box-shadow: rgb(35, 37, 42) 0 0 0 1px inset` (or `rgba(0, 0, 0, 0.2) 0 0 0 1px` on light panels). Hover adds a 2px inset in the accent color. Never switch to drop-shadow for hover — stay inside the surface.
Radial glimmer on dark sections
Feature sections receive a `radial-gradient(50% 50%, rgba(255,255,255,0.04), rgba(255,255,255,0) 90%)` overlay to break monotony — <5% opacity, no hard edges, purely atmospheric.
- Radius scale is granular: 2 / 4 / 6 / 7 / 8 / 12 / 16 / 20. The 6/7 pair exists for subtle optical pairing (button inside input).
- Buttons default to 8px radius, chips 6px, cards 12px, modals 16-20px, pills `rounded-full` for indicator badges only.
- Icons are stroke-based at 1.5-2px weight; no filled or duotone variants.
- Tap targets minimum 40×40px on desktop, 44×44 on touch — per observed button min-height pattern.
button-primary- backgroundColor
- #f7f8f8
- textColor
- #0f1011
- radius
- 8px
- padding
- 8px 14px
- border
- 1px solid transparent
- boxShadow
- none
- fontWeight
- 510
- fontSize
- 13px
- lineHeight
- 16.8px
Tailwind
inline-flex min-h-[32px] items-center gap-1.5 rounded-[8px] bg-[#f7f8f8] px-3.5 py-2 text-[13px] font-medium text-[#0f1011] transition-colors duration-[160ms] ease-[cubic-bezier(0.25,0.46,0.45,0.94)] hover:opacity-90 focus-visible:outline-none focus-visible:shadow-[rgb(85,205,255)_0_0_0_2px_inset]
button-secondary- backgroundColor
- transparent
- textColor
- #f7f8f8
- radius
- 8px
- padding
- 8px 14px
- border
- none
- boxShadow
- rgb(35, 37, 42) 0 0 0 1px inset
- fontWeight
- 510
- fontSize
- 13px
Tailwind
inline-flex min-h-[32px] items-center gap-1.5 rounded-[8px] bg-transparent px-3.5 py-2 text-[13px] font-medium text-[#f7f8f8] shadow-[rgb(35,37,42)_0_0_0_1px_inset] transition-colors duration-[160ms] ease-[cubic-bezier(0.25,0.46,0.45,0.94)] hover:shadow-[rgb(98,102,109)_0_0_0_1px_inset] focus-visible:outline-none focus-visible:shadow-[rgb(85,205,255)_0_0_0_2px_inset]
card-surface- backgroundColor
- #0f1011
- textColor
- #f7f8f8
- radius
- 12px
- padding
- 22px 24px
- border
- none
- boxShadow
- rgb(35, 37, 42) 0 0 0 1px inset
Tailwind
rounded-[12px] bg-[#0f1011] p-[22px] text-[#f7f8f8] shadow-[rgb(35,37,42)_0_0_0_1px_inset] transition-shadow duration-[160ms] ease-[cubic-bezier(0.25,0.46,0.45,0.94)] hover:shadow-[rgb(98,102,109)_0_0_0_1px_inset]
input-field- backgroundColor
- #0f1011
- textColor
- #f7f8f8
- radius
- 6px
- padding
- 6px 10px
- border
- none
- boxShadow
- rgb(35, 37, 42) 0 0 0 1px inset
- fontWeight
- 400
- fontSize
- 13px
- lineHeight
- 19.5px
- letterSpacing
- -0.165px
Tailwind
w-full rounded-[6px] bg-[#0f1011] px-2.5 py-1.5 text-[13px] leading-[19.5px] tracking-[-0.165px] text-[#f7f8f8] shadow-[rgb(35,37,42)_0_0_0_1px_inset] placeholder:text-[#62666d] focus-visible:outline-none focus-visible:shadow-[rgb(85,205,255)_0_0_0_2px_inset]
link-inline- color
- inherit
- textDecoration
- underline
- textDecorationColor
- #62666d
- textDecorationThickness
- 1px
- textUnderlineOffset
- 2px
- transition
- text-decoration-color 160ms cubic-bezier(0.25, 0.46, 0.45, 0.94)
Tailwind
underline decoration-[#62666d] decoration-[1px] underline-offset-2 transition-[text-decoration-color] duration-[160ms] ease-[cubic-bezier(0.25,0.46,0.45,0.94)] hover:decoration-[#f7f8f8] focus-visible:outline-none focus-visible:decoration-[#55cdff]
Easings
cubic-bezier(0.25, 0.46, 0.45, 0.94)cubic-bezier(0.66, 0, 0, 1)ease-outeasesteps(1)Scroll patterns
- Intersection-triggered opacity + translateY reveals at 0.4s on cubic-bezier(0.25, 0.46, 0.45, 0.94)
- Long-duration ambient transitions captured at 1.6 / 2.8 / 3.2 s on slower curves (cubic-bezier(0.66, 0, 0, 1) and ease-out) — used sparingly for atmospheric beats
- Stagger 40-80 ms between grouped cards
- No parallax beyond 2% translateY — subtle depth, never theatrical
- Primary easing: cubic-bezier(0.25, 0.46, 0.45, 0.94) — an ease-out quad variant that anchors most interactive transitions.
- Supporting easings: cubic-bezier(0.66, 0, 0, 1) for slower scroll choreography; ease-out / ease for legacy CSS-keyword transitions; steps(1) for non-interpolated state flips on toggles or counters.
- Five durations captured: 0.16s (primary state change), 0.4s (reveals + scroll choreography), 1.6 / 2.8 / 3.2 s (long-duration ambient). Most interactive transitions sit on 0.16s; the longer tier is reserved for atmospheric beats, never for affordance.
- `filter` and `transform` are first-class animated properties — the primary cubic-bezier applied to both simultaneously produces the signature Linear feel.
- useReducedMotion mandatory: all animations collapse to opacity-only or disable.
- Spring animations forbidden — deterministic cubic-bezier or steps(1) only.
- No loop animations except explicit loaders.
- Segmented controls for binary/ternary choices (pricing toggle, doc version switcher) — not toggle switches.
- Accordion: single-open for FAQ; multi-open only for deeply nested documentation.
- Tooltips reveal on hover + focus with 400ms delay, dismiss instantly on blur.
- Modals for destructive confirmations; drawers for mobile-only expansions; never nested modals.
- Form validation: inline below field on blur; submit disabled until pristine validation passes.
- Empty states: 10px caption icon + one-line 13px copy + primary 510-weight action link. No illustrations.
- Loading states: skeleton shimmer for content; inline spinner for buttons. No full-page overlays.
Desktop-first because the audience is technical teams on wide displays (Linear's container extends to 1436px, 12% wider than the generic 1280 default). Mobile adapts the same language without reinventing it — no hamburger-revealed alternate architecture. The page is the page, just reflowed into the narrower rail.
- Breakpoints: sm 640 / md 768 / lg 1024 / xl 1280 / 2xl 1536 — standard Tailwind ladder.
- Container max-width scales through 368 → 440 → 480 → 1436 px for bounded content at each tier.
- Hide-on-mobile is banned — if a control exists on desktop, it must reach mobile via reflow.
- Tap target minimum 44×44 on touch; 40×40 on pointer devices.
- Typography scales proportionally: hero 64 → 48 → 32, headings drop ~25% per tier while tracking compensates (less negative at smaller sizes).
- focus-visible: inset 2px accent-color shadow (replaces default ring). Mandatory on every interactive element.
- All interactive elements reachable via Tab key in logical reading order; never rely on hover to expose actions.
- Color contrast: #f7f8f8 on #0f1011 = ~18:1 (AAA); secondary text #62666d on #0f1011 = ~4.9:1 (AA). Never drop below 4.5:1 for body text.
- ARIA labels on icon-only buttons; aria-expanded on collapsible regions; aria-live='polite' on toast and status updates.
- Motion respects prefers-reduced-motion — animations reduce to opacity-only or disable entirely.
- Tap targets minimum 44×44 on touch; 40×40 on pointer.
- Screen reader-only content uses `sr-only`; never `display:none` for meaningful context.
- Form errors announced via aria-describedby on the associated input; never color-only signaling.
Motion library is not directly observable in the extract (chunk-name regex miss), but the motion profile (filter/transform transitions at 160ms on cubic-bezier(0.25, 0.46, 0.45, 0.94)) matches Framer Motion defaults. Next/Image (or a Next-equivalent) handles images with 94% lazy-loading; the hero at 6304×3520 is the only eager candidate. Icons stroke-based, 1.5-2px weight.
- Framer Motion `motion.div` with `whileInView` + `viewport={{ once: true, margin: '-10%' }}` for scroll reveals
- Transitions use `ease: [0.25, 0.46, 0.45, 0.94]` and `duration: 0.16` (or 0.1 / 0.4) — constants only
- useReducedMotion guard wraps every animation primitive — no exceptions
- Next/Image with `sizes` attribute always set; `priority` only on LCP candidate (hero)
- No canvas, no WebGL, no Lottie — static-first, animated-discreet
- Apply inset focus shadow (`box-shadow: <accent> 0 0 0 2px inset`) on every interactive element — replaces generic ring.
- Use `tabular-nums` on aligned numerics; reach for Berkeley Mono (or a mono fallback) for code and kbd inline.
- Reference observable tokens — accent color surface area stays under ~2% of total page.
- Break body text at 45-55 ch; dense tables may extend to 65 ch at 13px.
- Reach for inset 1px border shadows before any drop shadow.
- Pass every page through useReducedMotion before shipping.
- Default to the primary cubic-bezier(0.25, 0.46, 0.45, 0.94) for interactive transitions; reach for cubic-bezier(0.66, 0, 0, 1) only for slower scroll choreography.
- Never coarsen the spacing floor — Linear's granular 2 px floor under a 4 / 8 px dominant rhythm is the density signature; jumping straight to a 4-only or 8-only grid erases the optical micro-corrections.
- Never substitute 500 or 600 font weights for 510 / 590 — the stepped ladder is what separates this from generic Inter usage.
- Never use drop shadows > 0.4 opacity or > 12px blur.
- Never introduce a secondary display font. One variable family + one mono is the boundary.
- Never animate `height: auto` — use measured transforms or scaleY.
- Never invent durations outside the captured set {0.16, 0.4, 1.6, 2.8, 3.2}s; never introduce a sixth easing beyond {cubic-bezier(0.25, 0.46, 0.45, 0.94), cubic-bezier(0.66, 0, 0, 1), ease-out, ease, steps(1)}.
- Never use em for tracking — the px-based scale (-0.165 / -1.056 / -1.408) is an optical constant, not layout-relative.
- Tailwind v4 @theme inline only — no runtime style concatenation, no CSS-in-JS.
- Spacing base 2px, scale 2/4/6/8/10/12/14/16/19/22/24/26.
- Container max 1436px — do not exceed.
- Single font family + mono fallback: Inter Variable + Berkeley Mono.
- Weight ladder strictly 400 / 510 / 590.
- Motion: five captured durations (0.16 / 0.4 / 1.6 / 2.8 / 3.2 s) and five easings (cubic-bezier(0.25, 0.46, 0.45, 0.94) primary, cubic-bezier(0.66, 0, 0, 1) secondary, ease-out, ease, steps(1)). No springs.
- Radius scale: 2 / 4 / 6 / 7 / 8 / 12 / 16 / 20 px.
- Container width: no page exceeds 1436px wide.
- Spacing grep: no values outside the 2/4/6/8/10/12/14/16/19/22/24/26 ladder.
- Font weight grep: only 400, 510, 590 appear — no 500, 600, 700.
- Transition grep: `transition-timing-function` values draw from {cubic-bezier(0.25, 0.46, 0.45, 0.94), cubic-bezier(0.66, 0, 0, 1), ease-out, ease, steps(1)}; the primary cubic-bezier(0.25, 0.46, 0.45, 0.94) carries most interactive transitions.
- Transition duration grep: values draw from {0.16s, 0.4s, 1.6s, 2.8s, 3.2s}; longer values reserved for atmospheric beats only.
- Shadow audit: every elevation uses an inset 1px shadow first; drop shadows ≤ 0.4 opacity.
- Image audit: loading='lazy' on every non-LCP image; priority only on hero.
- Tracking audit: display-size text uses px-based negative tracking (-0.165 / -1.056 / -1.408), not em.
- Contrast audit: body text on darkest background ≥ 4.5:1 (WCAG AA).
Design tokens
Observed token system
Color, type, spacing, gradients, and stacking order captured from the live page and rendered here as living, paste-ready previews.
Inspector
Observable layers
Structure, breakpoints, motion, fonts, and images captured from the live page and kept paste-ready alongside the tokens.
Depth-first walk of the meaningful sections. 11 nodes across 6 levels, shallow to deep by color.
- body1
- div (×2)2
- Section
- div3
- div1
- Header1
- Nav
- Main1
- div1
- Section (×7)
- Footer
Accessibility
Contrast matrix
276 combinations - 94 pass AA - 58 pass AAA. Each pair is previewed with its real foreground on background; APCA Lc sits alongside the WCAG 2.1 ratio for draft WCAG 3 awareness.
- fg
#000000- bg
#F7F8F8- APCA Lc
- +102
- Use
- foreground on background
- fg
#F7F8F8- bg
#0F1011- APCA Lc
- -103
- Use
- background on foreground
- fg
#0F1011- bg
#F7F8F8- APCA Lc
- +101
- Use
- foreground on background
- fg
#00FF05- bg
#000000- APCA Lc
- -86
- Use
- accent on foreground
- fg
#000000- bg
#00FF05- APCA Lc
- +87
- Use
- foreground on accent
- fg
#F7F8F8- bg
#23252A- APCA Lc
- -100
- Use
- background on foreground
- fg
#23252A- bg
#F7F8F8- APCA Lc
- +98
- Use
- foreground on background
- fg
#D0D6E0- bg
#000000- APCA Lc
- -81
- Use
- foreground on foreground
Images
Image strategy
Observable image posture - total count, lazy-loading ratio, and format mix. The hero image is measured above the fold.
- unknown29 · 94%
- png2 · 6%
Hero image
https://linear.app/cdn-cgi/imagedelivery/fO02fVwohEs9s9UHFwon6A/c7fa8f5f-d439-4329-6a65-de549b51e300/f=auto,dpr=2,q=95,fit=scale-down,metadata=none- Format
- UNKNOWN
- Dimensions
- 6304x3520
- Loading
- lazy
- srcset
- no
- Industry
- saas
- Industry
- productivity
- Theme
- Dark
- Added
- 2026-04-01
FAQ
Questions people ask about Linear
3questionsAnswers are pulled from the curator verdict and design brief - the same text your AI agent sees when it paste-reads this page.
Compare this with



