---
name: Graphite
tagline: Near-black developer canvas — Matter type, near-white ink, one clean blue, 8px CTAs.
updated_at: 2026-05-28T23:12:23.528Z
published_at: 2026-05-28T23:12:23.528Z
author: webdesignhot
source_url: https://graphite.dev
spec: webdesignhot/0.1
quality: curated
featured: false
categories: [dev-tools, saas]
tags: [dark, minimal, sans, developer, code-review]
preview_swatch: ['#070707', '#3b82f6', '#60a5fa']
description: 'Graphite renders its marketing site like the IDE its customers live in — a near-black `#070707` canvas, near-white `#fafafa` ink, and the Matter typeface set tight at a 60px/500 hero. The chromatic budget is a single clean blue `#3b82f6`, reserved for links, focus, and the rare emphasis; the dominant CTAs stay dark `#262626` with an 8px radius, so the blue never has to fight the page. It is developer-technical in register — Linear-adjacent restraint, built for engineers who read diffs all day.'


# Canonical 8-role aliases (bg / text / brand / border / accent / muted / surface / danger).
# Maps role names to this entry's actual token names so role-aware
# downstream tools resolve `theme.background` → entry's `bg`, etc.
# Auto-generated by scripts/add-aliases.mjs — do not edit manually;
# regenerate after changing color token names.
aliases:
  background: bg
  foreground: text
  primary: brand
  primary-foreground: on-brand
  accent: accent
  border: border
  ring: brand
  muted: text-secondary
colors:
  # Page grounds
  bg: '#070707'                  # canvas — near-black (lab 2.75), not pure #000
  bg-level-1: '#0f0f0f'          # first elevation tier (cards, panels)
  bg-level-2: '#171717'          # second elevation (hover, banners, emphasized)
  bg-level-3: '#1f1f1f'          # third tier — popovers, raised tooltips
  bg-overlay: 'rgba(7,7,7,0.72)' # modal scrim
  # Surfaces & containers
  surface: '#0f0f0f'
  surface-strong: '#171717'
  surface-tinted-brand: 'rgba(59,130,246,0.08)'  # brand-tinted callout wash
  # Text
  text: '#fafafa'                # body copy, headlines (lab 98.26)
  text-strong: '#ffffff'         # display, max contrast
  text-secondary: '#d4d4d4'      # supporting copy
  text-tertiary: '#a3a3a3'       # metadata, captions
  text-quaternary: '#737373'     # placeholder, faint helpers
  text-disabled: '#525252'
  # Brand & accent — one clean blue
  brand: '#3b82f6'               # Graphite blue — links, focus, emphasis
  brand-hover: '#60a5fa'         # active states / hover lift
  brand-press: '#2f6fed'
  brand-soft: 'rgba(59,130,246,0.16)'  # tinted backdrop
  accent: '#60a5fa'              # brighter blue for active glow
  link: '#60a5fa'                # link copy on dark
  link-hover: '#93c5fd'
  # Borders
  border: '#1f1f1f'              # default 1px hairline
  border-strong: '#2e2e2e'       # emphasized
  border-subtle: 'rgba(255,255,255,0.06)'  # near-invisible
  border-brand: '#3b82f6'
  # CTA-dark (the signature primary — observed live, 8px radius)
  cta-fill: '#262626'            # dark neutral pill button
  cta-fill-hover: '#2e2e2e'
  cta-fill-press: '#1f1f1f'
  cta-text: '#fafafa'
  # Semantic
  success: '#22c55e'
  success-bg: 'rgba(34,197,94,0.12)'
  warning: '#f59e0b'
  warning-bg: 'rgba(245,158,11,0.12)'
  danger: '#ef4444'
  danger-bg: 'rgba(239,68,68,0.12)'
  info: '#3b82f6'
  info-bg: 'rgba(59,130,246,0.12)'
  on-brand: '#ffffff'

typography:
  display:
    family: 'matterFont, "Matter", system-ui, -apple-system, sans-serif'
    weights: [500, 600, 700]
  body:
    family: 'matterFont, "Matter", system-ui, -apple-system, sans-serif'
    weights: [400, 500, 600]
  mono:
    family: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace'
    weights: [400, 500]
  scale:
    display-hero:    { size: 72, weight: 500, lineHeight: 1.0,  tracking: '-0.03em',  family: display }
    display-lg:      { size: 60, weight: 500, lineHeight: 1.05, tracking: '-0.025em', family: display }
    h1:              { size: 60, weight: 500, lineHeight: 1.05, tracking: '-0.022em', family: display }
    h2:              { size: 40, weight: 500, lineHeight: 1.1,  tracking: '-0.018em', family: display }
    h3:              { size: 28, weight: 500, lineHeight: 1.2,  tracking: '-0.012em', family: display }
    h4:              { size: 20, weight: 600, lineHeight: 1.3,  tracking: '-0.005em', family: display }
    eyebrow:         { size: 13, weight: 500, lineHeight: 1.4,  tracking: '0.04em',   family: body, transform: uppercase }
    body-lg:         { size: 18, weight: 400, lineHeight: 1.55, tracking: '0',        family: body }
    body:            { size: 16, weight: 400, lineHeight: 1.55, tracking: '0',        family: body }
    body-sm:         { size: 14, weight: 400, lineHeight: 1.5,  tracking: '0',        family: body }
    body-emphasis:   { size: 16, weight: 500, lineHeight: 1.55, tracking: '0',        family: body }
    label:           { size: 13, weight: 500, lineHeight: 1.4,  tracking: '0',        family: body }
    caption:         { size: 12, weight: 500, lineHeight: 1.4,  tracking: '0.02em',   family: body }
    code-inline:     { size: 14, weight: 400, lineHeight: 1.5,  tracking: '0',        family: mono }
    code-block:      { size: 13, weight: 400, lineHeight: 1.6,  tracking: '0',        family: mono }
    button:          { size: 14, weight: 500, lineHeight: 1,    tracking: '0',        family: body }
    button-large:    { size: 16, weight: 500, lineHeight: 1,    tracking: '0',        family: body }

radius:
  micro: 2
  sm: 4
  md: 8
  lg: 12
  xl: 16
  pill: 9999

spacing:
  base: 4
  scale: [0, 4, 8, 12, 16, 24, 32, 48, 64, 96]

layout:
  page-width: 1280
  prose-width: 720
  header-height: 64
  section-y: 96
  gutter: 24
  grid-columns: 12

components:
  button-primary:
    backgroundColor: '#262626'
    textColor: '#fafafa'
    rounded: md
    padding: '10px 16px'
    height: 40
    font: '14px Matter, weight 500'
    hover: 'bg #2e2e2e'
    active: 'bg #1f1f1f'
    focus: 'ring 2px #3b82f6 offset 2px on bg'
    use: 'log-in / get-started — dark neutral, observed live at 8px radius'
  button-brand:
    backgroundColor: '#3b82f6'
    textColor: '#ffffff'
    rounded: md
    padding: '10px 16px'
    use: 'rare — used only when emphasis must be brand-coded (sign-up, beta)'
    hover: 'bg #60a5fa'
  button-ghost:
    backgroundColor: transparent
    textColor: '#d4d4d4'
    border: '1px solid #1f1f1f'
    rounded: md
    padding: '10px 16px'
    height: 40
    hover: 'bg rgba(255,255,255,0.05); text #fafafa; border #2e2e2e'
    use: 'secondary nav, "Read the docs"'
  button-icon:
    backgroundColor: transparent
    textColor: '#a3a3a3'
    rounded: md
    size: '32 × 32'
    hover: 'bg #171717; text #fafafa'
    use: 'header utility — search, theme, account'
  card:
    backgroundColor: '#0f0f0f'
    border: '1px solid #1f1f1f'
    rounded: lg
    padding: 24
    shadow: none
    hover: 'border #2e2e2e; bg #171717'
    use: 'feature blocks, doc cards — never shadowed'
  card-hero:
    backgroundColor: '#0f0f0f'
    border: '1px solid #1f1f1f'
    rounded: xl
    padding: 48
    use: 'product-screenshot frames, feature splits'
  input:
    backgroundColor: '#0f0f0f'
    textColor: '#fafafa'
    placeholderColor: '#737373'
    border: '1px solid #1f1f1f'
    rounded: md
    height: 40
    padding: '8px 12px'
    focus: 'border #3b82f6; ring rgba(59,130,246,0.32) 0 0 0 3px'
    font: '14px Matter 400'
    use: 'compact dense — matches in-product surfaces'
  pill-status:
    backgroundColor: 'rgba(59,130,246,0.12)'
    textColor: '#60a5fa'
    border: '1px solid rgba(59,130,246,0.22)'
    rounded: pill
    padding: '2px 10px'
    font: '12px Matter 500'
    use: 'status: merged / approved / changes-requested — semantic colour swap'
  navbar:
    backgroundColor: 'rgba(7,7,7,0.72)'
    backdrop-filter: 'blur(12px) saturate(180%)'
    border-bottom: '1px solid #1f1f1f'
    height: 64
    use: 'sticky top — no shadow on scroll, just border edge'
  tooltip:
    backgroundColor: '#1f1f1f'
    textColor: '#fafafa'
    border: '1px solid #2e2e2e'
    rounded: md
    font: '12px Matter 500'
    shadow: '0 8px 24px rgba(0,0,0,0.5)'

motion:
  ease-standard: 'cubic-bezier(0.4, 0, 0.2, 1)'
  ease-emphasized: 'cubic-bezier(0.2, 0, 0, 1)'
  ease-out: 'cubic-bezier(0, 0, 0.2, 1)'
  duration-fast: 150
  duration-standard: 240
  duration-slow: 320
  hover-button: 'bg shift over 150ms ease-out; no transform'
  hover-card: 'border #2e2e2e transition over 240ms; no transform'
  page-transition: 'opacity 200ms ease-standard; no slide'
  scroll-fade: 'opacity 0 → 1 over 320ms with translateY(8px) → 0'
  reduced-motion: 'respects prefers-reduced-motion: reduce — transitions to opacity-only, transform disabled'

breakpoints:
  mobile: 640
  tablet: 1024
  desktop: 1280
  wide: 1536

shadows:
  none: 'none'
  ambient: '0 1px 2px rgba(0,0,0,0.5)'
  popover: '0 8px 24px rgba(0,0,0,0.5)'
  modal: '0 24px 48px rgba(0,0,0,0.6)'
  ring-focus: '0 0 0 3px rgba(59,130,246,0.32)'

accessibility:
  contrast-text-on-bg: 19.3              # #fafafa on #070707 — AAA
  contrast-secondary-on-bg: 13.6         # #d4d4d4 on #070707 — AAA
  contrast-brand-on-bg: 5.5              # #3b82f6 on #070707 — AA
  contrast-cta-text: 14.5                # #fafafa on #262626 — AAA
  focus-ring: '3px solid rgba(59,130,246,0.32) offset 2px'
  reduced-motion-honored: true
  keyboard-nav: 'visible focus on every interactive; skip-to-content link before header'
  aria-patterns: 'dialog uses role=dialog + aria-modal=true; popover uses role=dialog + aria-labelledby; status pills use aria-live=polite'

dark-mode: native        # Graphite is dark-first; marketing surface ships near-black only

lineage:
  summary: 'Graphite draws from the dark-canvas dev-tool lineage — Linear, Vercel, GitHub''s diff surfaces — and from the IDE itself. The near-black ground, near-white ink, single restrained blue, and 8px-radius dark CTAs are the vocabulary of a tool whose customers read code reviews all day. It rejects marketing softening: no gradient hero, no glow, just the product shown in its own native chrome.'
  influences:
    - { name: Linear, role: 'Dark-canvas product-as-marketing discipline; restrained single-accent palette', url: 'https://linear.app' }
    - { name: Vercel, role: 'Near-black dev-tool surface and Geist-family sans typography lineage', url: 'https://vercel.com' }
    - { name: GitHub, role: 'Code-review and diff surface conventions that Graphite reframes for the AI age', url: 'https://github.com' }
    - { name: Tailwind CSS Palette, role: 'Blue-500/600 and neutral scale this system samples for its accent and tiers', url: 'https://tailwindcss.com/docs/customizing-colors' }
    - { name: Matter (Displaay Type Foundry), role: 'The geometric grotesque set tight at the 60px/500 hero — Graphite''s type voice', url: 'https://displaay.net/typeface/matter/matter/' }
---

## 1. Visual Theme & Atmosphere

Graphite is a code-review tool dressed as the editor its users already
trust. The marketing site is rendered on a near-black `#070707` canvas
(lab `2.75`, a hair off pure `#000` to keep type from crunching) with
near-white `#fafafa` ink, the Matter typeface set tight, and a single
clean blue `#3b82f6` held in reserve. The atmosphere is the IDE at
night: nothing decorative, no gradient orbs, no marketing glow — just
the product shown in its own native chrome. If you build software for
a living, the page reads as familiar before you've parsed a word.

What separates it from softer dev-tool sites is conviction about the
canvas. Most tools lighten their dark themes for marketing — bigger
margins, lifted text, friendly illustration. Graphite refuses. The
near-black holds across the whole page; section breaks are tonal
lifts (`#0f0f0f`, `#171717`), not new colours. The hero is a 60px
Matter headline at weight `500` — firm but not bold — over a single
line of supporting copy and one dark CTA. The screenshot of the
review surface does the persuading.

The chromatic budget is deliberately one blue. `#3b82f6` carries
links, focus rings, the active state of a tab, and the rare
brand-coded button — and that's the whole accent story. Because the
dominant CTAs are dark neutral `#262626` at an 8px radius (observed
live), the blue never competes with itself. One eye-anchor per
screen, one accent in the system. The restraint is the brand: it
signals a tool made by engineers who distrust ornament.

The register is developer-technical — Linear-adjacent. Copy is
declarative and present-tense; geometry is rectilinear at 8px, not
pill; depth is carried by tone and hairline borders, not shadows.
The mood is a workstation that respects your attention: dense where
it counts, quiet everywhere else.

**Key Characteristics**
- Near-black `#070707` ground (lab `2.75`, warm-leaning, never `#000`)
- Near-white `#fafafa` ink (lab `98.26`), never pure `#ffffff` for body
- Matter typeface (`matterFont`) — hero at 60px / weight `500`, tight tracking
- One clean blue `#3b82f6` — links, focus, rare emphasis; never the default CTA
- Dark-neutral CTAs `#262626` at **8px radius** (the live-observed signature)
- 8px is the working radius — rectilinear, not pill (contrast with Linear)
- Tonal layering for depth (`#070707` → `#0f0f0f` → `#171717` → `#1f1f1f`)
- No drop shadows on cards; hairline borders + tonal lift do the work
- Single eye-anchor per screen; the product screenshot is the hero
- Marketing surface ships dark-first — no light variant on the website

## 2. Color Palette & Roles

### Canvas (Primary)

- **bg** `#070707` — page canvas, near-black (lab `2.75`), the whole site lives here
- **bg-level-1** `#0f0f0f` — first elevation: cards, panels, section lifts
- **bg-level-2** `#171717` — second elevation: hover, banner strips, emphasized blocks
- **bg-level-3** `#1f1f1f` — third tier: popovers, tooltips, raised menus
- **bg-overlay** `rgba(7,7,7,0.72)` — modal scrim over the canvas

### Text

- **text** `#fafafa` — body copy and headlines (lab `98.26`), default ink
- **text-strong** `#ffffff` — display / max-contrast moments only
- **text-secondary** `#d4d4d4` — supporting copy, sub-headers
- **text-tertiary** `#a3a3a3` — captions, metadata, helper lines
- **text-quaternary** `#737373` — placeholders, faint helpers
- **text-disabled** `#525252` — disabled labels

### Brand

- **brand** `#3b82f6` — Graphite blue: links, focus, active tab, rare emphasis
- **brand-hover** `#60a5fa` — hover / active glow, brighter step
- **brand-press** `#2f6fed` — pressed state on branded controls
- **brand-soft** `rgba(59,130,246,0.16)` — tinted callout backdrop
- **accent** `#60a5fa` — brighter blue used for active glow and links
- **link** `#60a5fa` — link copy on dark; **link-hover** `#93c5fd`

### CTA (the live signature)

- **cta-fill** `#262626` — dark-neutral primary button (observed live, 8px radius)
- **cta-fill-hover** `#2e2e2e` — hover lift
- **cta-fill-press** `#1f1f1f` — pressed
- **cta-text** `#fafafa` — ink on the dark CTA

### Borders

- **border** `#1f1f1f` — default 1px hairline
- **border-strong** `#2e2e2e` — emphasized rule / hover border
- **border-subtle** `rgba(255,255,255,0.06)` — barely-visible separators
- **border-brand** `#3b82f6` — active input outline

### Surface

- **surface** `#0f0f0f` — default card
- **surface-strong** `#171717` — emphasized panel
- **surface-tinted-brand** `rgba(59,130,246,0.08)` — brand-coded callout wash

### Shadow

Shadows are *almost never used on cards.* When they appear (popovers,
modals), they are pure-neutral black, multi-layer:

- **shadow-popover** `0 8px 24px rgba(0,0,0,0.5)`
- **shadow-modal** `0 24px 48px rgba(0,0,0,0.6)`
- **shadow-ambient** `0 1px 2px rgba(0,0,0,0.5)` — subtle sticky-header lift

### Semantic

- **success** `#22c55e` + **success-bg** `rgba(34,197,94,0.12)` — merged / approved
- **warning** `#f59e0b` + **warning-bg** `rgba(245,158,11,0.12)` — pending / stale
- **danger** `#ef4444` + **danger-bg** `rgba(239,68,68,0.12)` — failing / blocked
- **info** `#3b82f6` + **info-bg** `rgba(59,130,246,0.12)` — uses the brand blue

Status pills follow one pattern: tinted bg + tinted border (~22% alpha)
+ tinted text at full saturation.

## 3. Typography Rules

### Font Family

- **Primary (display + body)**: `matterFont` — the Matter typeface
  (Displaay Type Foundry), a geometric grotesque, with `"Matter"`,
  `system-ui`, `-apple-system`, `sans-serif` fallback chain
- **Mono**: `ui-monospace`, `SFMono-Regular`, `"SF Mono"`, `Menlo`,
  `monospace` — for inline code, diffs, and code blocks
- **Live-observed**: hero h1 renders at **60px / weight 500**, body at
  **16px / weight 400** — both in `matterFont`. The headline weight is
  `500` (firm, not bold), which is the system's whole voice.

### Hierarchy

| Role | Font | Size | Weight | Line Height | Tracking | Notes |
|---|---|---|---|---|---|---|
| display-hero | Matter | 72 | 500 | 1.0 | -0.03em | Largest landing splash |
| display-lg | Matter | 60 | 500 | 1.05 | -0.025em | Section heroes |
| h1 | Matter | 60 | 500 | 1.05 | -0.022em | Page title (live: 60/500) |
| h2 | Matter | 40 | 500 | 1.1 | -0.018em | Major sections |
| h3 | Matter | 28 | 500 | 1.2 | -0.012em | Sub-sections |
| h4 | Matter | 20 | 600 | 1.3 | -0.005em | Card titles |
| eyebrow | Matter | 13 | 500 | 1.4 | 0.04em uppercase | Section markers |
| body-lg | Matter | 18 | 400 | 1.55 | 0 | Hero subhead |
| body | Matter | 16 | 400 | 1.55 | 0 | Default body (live: 16/400) |
| body-emphasis | Matter | 16 | 500 | 1.55 | 0 | Inline emphasis |
| body-sm | Matter | 14 | 400 | 1.5 | 0 | Footnotes, dense copy |
| label | Matter | 13 | 500 | 1.4 | 0 | Form labels |
| caption | Matter | 12 | 500 | 1.4 | 0.02em | Metadata |
| code-inline | Mono | 14 | 400 | 1.5 | 0 | Inline code |
| code-block | Mono | 13 | 400 | 1.6 | 0 | Diffs, code blocks |
| button | Matter | 14 | 500 | 1 | 0 | Default button |
| button-large | Matter | 16 | 500 | 1 | 0 | Hero CTA |

### Principles

- **Weight 500 is the headline voice.** The hero renders at `500`, not
  `700`. Hierarchy is carried by size and tight tracking, not bold —
  `700` is reserved for the rare wordmark or code emphasis.
- **Tracking tightens with size.** The 60px h1 sits near `-0.022em`;
  the 72px hero tightens to `-0.03em`. Display type must feel
  engineered, not bloated. Body stays at `0`.
- **Matter is the brand vocabulary.** The geometric grotesque reads as
  technical and modern without GitHub-mono or Inter-default fatigue.
  Treat `matterFont` as load-bearing; the `system-ui` fallback is a
  graceful but visible downgrade.
- **Mono is for the diff.** Code, file paths, and review snippets use
  the mono stack. It signals the product's domain on a marketing page
  without illustration.
- **Body never goes pure white.** `#fafafa` (lab `98.26`) is the ink;
  `#ffffff` is held for display-only max-contrast moments.
- **Reading width caps at ~720px** even when the page is 1280. Long
  copy is always constrained inside the wider frame.

## 4. Component Stylings

### Buttons (4 variants)

**Primary (the live signature — dark neutral)**
- Background: `#262626`
- Text: `#fafafa` at 14/500
- Padding: `10px 16px`, Height: 40
- Radius: **8 (md)** — observed live on the Log-in CTA
- Border: none
- Hover: bg `#2e2e2e`
- Active: bg `#1f1f1f`
- Focus: `ring 2px #3b82f6 offset 2px`
- Use: log-in, get-started — the dominant action on most screens

**Brand (rare)**
- Background: `#3b82f6`
- Text: `#ffffff` at 14/500
- Radius: 8 (md)
- Hover: bg `#60a5fa`
- Use: only when the action must read as brand-coded — sign-up, beta
  enrolment. Most pages use the dark primary instead.

**Ghost**
- Background: transparent
- Text: `#d4d4d4` at 14/500
- Border: `1px solid #1f1f1f`
- Radius: 8 (md)
- Hover: bg `rgba(255,255,255,0.05)`; text `#fafafa`; border `#2e2e2e`
- Use: secondary nav, "Read the docs"

**Icon**
- Background: transparent → `#171717` on hover
- Text: `#a3a3a3` → `#fafafa` on hover
- Size: 32 × 32, Radius: 8 (md)
- Use: header utilities — search, theme toggle, account

### Cards (2 variants)

**Standard card**
- Background: `#0f0f0f`, Border: `1px solid #1f1f1f`, Radius: 12 (lg)
- Padding: 24, Shadow: none
- Hover: border `#2e2e2e`, bg `#171717`
- Use: feature blocks, doc cards

**Hero card**
- Background: `#0f0f0f`, Border: `1px solid #1f1f1f`, Radius: 16 (xl)
- Padding: 48
- Use: product-screenshot frames, feature splits

### Inputs / Forms

**Text input**
- Background: `#0f0f0f`, Border: `1px solid #1f1f1f`, Radius: 8 (md)
- Height: 40, Padding: `8px 12px`
- Font: `14px Matter 400`
- Placeholder: `#737373`
- Focus: border `#3b82f6`; ring `rgba(59,130,246,0.32) 0 0 0 3px`
- Disabled: bg `#070707`, text `#525252`

**Select** — same shell as input + a chevron icon at 12px in `#a3a3a3`;
the popover follows tooltip styling.

**Checkbox / Radio** — 16 × 16, `1px solid #2e2e2e`, 4px radius
(checkbox) or 9999 (radio); checked fill is brand `#3b82f6`.

### Badges, Tags, Pills

**Status pill** — pill radius, tinted bg + tinted border at ~22% alpha
+ tinted text at full saturation. Maps to review states: merged
(success `#22c55e`), approved (brand `#3b82f6`), changes-requested
(warning `#f59e0b`), failing (danger `#ef4444`).

**Tag** — neutral variant: `#171717` bg, `#2e2e2e` border, `#d4d4d4`
text. Used for repo / category labels.

### Navigation

**Top nav**: 64px tall, `rgba(7,7,7,0.72)` bg with `backdrop-filter:
blur(12px) saturate(180%)`, 1px bottom border `#1f1f1f`. Sticky on
scroll — no shadow added, just the border edge. (Note: the live audit
also caught a `Cursor Cloud Agents` banner strip at `#171717` — that
is announcement noise, not part of the nav system.)

**Footer**: dark with low-contrast `#737373` text on `#070707`; 1px
top border `#1f1f1f`.

**Side nav (docs)**: tonal column at `bg-level-1` with `#1f1f1f` rule
on the right; active item gets `bg-level-2` + 2px brand left border.

### Tooltips & Popovers

Tooltip: `#1f1f1f` bg, `#2e2e2e` border, 8 radius, `12px Matter 500`
text, 6 × 10 padding. Shadow `0 8px 24px rgba(0,0,0,0.5)`.

Popover (menu, combobox): `#1f1f1f` bg with the same border and shadow,
8 radius, max-width 320, list items use 6/8 padding.

### Modals

Centered overlay on `rgba(7,7,7,0.72)` scrim with backdrop blur.
Dialog box at `#171717`, 12 radius, 24 padding, 1px `#2e2e2e` border,
shadow `0 24px 48px rgba(0,0,0,0.6)`. Title at h3 500, body 16/400,
action row pinned to the footer with the primary CTA on the right.

## 5. Layout Principles

### Spacing System

- **Base unit**: 4px
- **Scale**: `[0, 4, 8, 12, 16, 24, 32, 48, 64, 96]`
- Small steps (4, 8) handle in-component spacing; big jumps (64, 96)
  handle section rhythm. Density is product-grade: 8px between form
  rows, 4px between an icon and its label, 16–24px between cards.
- The marketing page inherits the product's tight interior spacing
  while keeping generous section gutters.

### Grid & Container

- **Page width**: 1280px max
- **Prose width**: 720px — multi-paragraph copy is capped here within
  the 1280 frame
- **Gutter**: 24px
- **Grid**: 12 columns on tablet+, single column on mobile
- Hero: full-bleed near-black bg + centred 1280 content; the product
  screenshot lives inside its own hero card, not full-bleed
- Feature grid: asymmetric splits (copy vs. screenshot) when one side
  deserves visual primacy

### Whitespace Philosophy

Graphite is dense by product DNA but generous on marketing rhythm.
Sections breathe at ~96px vertical gutters; *within* sections the
density tightens to product values (8–24px). Macro-relaxed,
micro-tight — the same tempo the IDE uses.

### Section Cadence

The site stays on `#070707` throughout. Section breaks are tonal —
`bg-level-1` panels stand against the canvas rather than introducing
new colours. The exception is the occasional `bg-level-2` band
(customer quote, announcement strip) that lifts for one viewport and
returns to canvas.

## 6. Shapes & Radius Scale

| Tier | px | Use |
|---|---|---|
| Micro | 2 | Decorative corners, inline accents |
| Standard (sm) | 4 | Tags, micro-pills, checkboxes |
| Comfortable (md) | **8** | **Buttons, inputs, icon buttons — the working radius** |
| Relaxed (lg) | 12 | Cards, panel containers, modals |
| Featured (xl) | 16 | Hero cards, product-screenshot frames |
| Pill | 9999 | Status pills, avatar mode only |

The **8px (md)** corner is the system's signature — confirmed live on
the primary CTA. Graphite is rectilinear, not pill-driven: where
Linear rounds CTAs to full pills, Graphite keeps them at 8px, which
reads more like an IDE control. The pill (9999) is reserved for status
indicators and avatars, never the action buttons.

There is essentially no `0px`-radius element except 1px hairline
section rules. Compound radii appear only in modal headers (`12 12 0 0`
to lock to the body) and pinned tab strips (`8 8 0 0`).

## 7. Depth & Elevation

| Level | Treatment | Use |
|---|---|---|
| 0 | flat — `#070707` only | page canvas |
| 1 | `#0f0f0f` + 1px `#1f1f1f` border | cards, panels |
| 2 | `#171717` + 1px `#2e2e2e` border | hover, banners, emphasized |
| 3 | `#1f1f1f` + ambient shadow `0 1px 2px rgba(0,0,0,0.5)` | sticky header |
| 4 | `#1f1f1f` + popover shadow `0 8px 24px rgba(0,0,0,0.5)` | tooltips, menus, popovers |
| 5 | `#171717` + modal shadow `0 24px 48px rgba(0,0,0,0.6)` + scrim | modals, dialogs |

### Shadow Philosophy

Graphite uses **tonal stacking** as its default depth language. Each
elevation step lifts lightness a few points — barely perceptible
alone, readable as a stack. Borders pick up where tone is too subtle:
`#1f1f1f` → `#2e2e2e` is the two-step border ladder.

Drop shadows are **floating UI only**: popovers, tooltips, modals,
toasts. Cards never carry shadows; the hairline border plus the tonal
lift do all the work. Shadows are pure-neutral black (no tint),
multi-layer when deep. The result reads as solid surfaces on a solid
ground, not floating glass.

## 8. Interaction & Motion

### Easing curves

- **ease-standard**: `cubic-bezier(0.4, 0, 0.2, 1)` — default for
  hover and state transitions
- **ease-emphasized**: `cubic-bezier(0.2, 0, 0, 1)` — page enters,
  modal slide-in
- **ease-out**: `cubic-bezier(0, 0, 0.2, 1)` — settling motions

### Duration buckets

- **fast**: 150ms — button hover, focus ring, state changes
- **standard**: 240ms — card hover, popover open
- **slow**: 320ms — modal enter, scroll-fade

### Per-component micro-states

- **Button hover**: bg lift (`#262626 → #2e2e2e`) over 150ms ease-out;
  *no transform* — the dark CTA stays planted
- **Button active**: bg press to `#1f1f1f` over 150ms
- **Card hover**: border transition `#1f1f1f → #2e2e2e` + bg lift
  `#0f0f0f → #171717` over 240ms ease-standard; *no transform*
- **Link hover**: colour shift `#60a5fa → #93c5fd` only, 150ms; no
  underline grow
- **Popover open**: opacity 0 → 1 + scale 0.98 → 1 over 240ms
  ease-emphasized
- **Modal enter**: scrim fade 320ms + dialog slide from `translateY(8px)`
  to 0 over 320ms ease-emphasized

### Page transitions

Marketing page changes are full opacity 0 → 1 over 200ms — no slide.
Scroll-fade for in-view content uses opacity + 8px `translateY` → 0
over 320ms.

### Reduced motion

Respects `prefers-reduced-motion: reduce`. All transforms disabled,
all transitions reduced to opacity-only at the same durations. The
sticky-header backdrop blur stays on (it is not motion).

## 9. Accessibility & A11y

### Contrast pairs (computed from live tokens)

- **#fafafa on #070707 (text on bg)**: **19.3** — AAA at all sizes
- **#d4d4d4 on #070707 (secondary on bg)**: 13.6 — AAA
- **#a3a3a3 on #070707 (tertiary on bg)**: 8.0 — AAA at body sizes
- **#737373 on #070707 (quaternary on bg)**: 4.2 — AA Large only; use
  for non-essential helpers
- **#fafafa on #262626 (CTA text on dark fill)**: 14.5 — AAA
- **#3b82f6 on #070707 (brand on bg)**: 5.5 — AA for text and icons
- **#60a5fa on #070707 (link on bg)**: 7.9 — AAA
- **#ffffff on #3b82f6 (text on brand button)**: 3.7 — AA Large /
  UI-component contrast only; keep brand-button label at 14px+ 500

### Focus indicators

Every interactive element ships a focus ring: `3px solid
rgba(59,130,246,0.32)` with 2px offset on the dark canvas — box-shadow
ring, not outline, so it composites cleanly over borders. Inputs get
the solid `#3b82f6` border on focus plus the ring.

### ARIA patterns

- **Combobox** (search): `role=combobox` + `aria-expanded` +
  `aria-controls` + `aria-activedescendant`
- **Dialog**: `role=dialog` + `aria-modal=true` + `aria-labelledby`
  pointing to the title node
- **Status pills**: `aria-live=polite` for in-page state changes;
  state included in the accessible name (e.g., `aria-label="Status: merged"`)

### Keyboard nav

A skip-to-content link appears on first Tab focus (confirmed live).
Tab order: skip link → header logo → nav links → header CTA → hero CTA
→ in-page sections → footer. All buttons and links are keyboard
reachable; focus is always visible.

### Screen reader hints

- Icon-only buttons carry `aria-label` (e.g., `aria-label="Search"`)
- Decorative icons get `aria-hidden=true`
- Diff and code regions use `role=region` with a descriptive label

### Reduced motion

Honoured globally; see §8. Auto-playing demo loops respect the same
query and freeze on the first frame.

## 10. Responsive Behavior

| Breakpoint | px | Layout |
|---|---|---|
| mobile | < 640 | single-column, 16px gutter, h1 → 36px |
| tablet | 640–1023 | 2-column on splits, 20px gutter, h1 → 44px |
| desktop | 1024–1279 | full 12-col grid, h1 → 56px |
| wide | ≥ 1280 | page caps at 1280, h1 at 60px — refuses to over-stretch |

### Touch targets

Minimum 44 × 44 on mobile (buttons grow vertical padding from 10 to
12; icon buttons grow to 40 × 40). All keep the 8px radius —
fingerprint matches desktop.

### Collapsing strategy

- Header collapses to a hamburger at ≤ 768
- Feature grids switch from asymmetric splits to single-column stacks
  at ≤ 768
- Comparison tables become card lists at ≤ 640
- Sticky docs sidebar becomes a top sheet on mobile

### Image behavior

Product screenshots use `aspect-ratio: 16 / 10` and `object-fit: cover`
with `loading=lazy`. SVG illustrations are inline and respect
`currentColor`. Screenshot corners match their parent hero card (16px),
no radius mismatch.

### Container queries

Used in hero-card variants where the screenshot frame switches from
landscape to portrait based on container width below ~480px.

## 11. Content & Voice

### Tone

Direct, technical, present-tense. Graphite writes like an engineer
leaving review comments: declarative, specific, allergic to hype. The
title itself sets the register — "Code review for the age of AI."
Sentences are short; metaphors are rare and mechanical when used.

### Microcopy patterns

- **Button verbs**: "Log in", "Get started", "Read the docs", "Start
  reviewing" — short, imperative, present-tense. Never "Click here" or
  "Learn more about our…".
- **Errors**: format `<noun> couldn't be <verbed>. <one-sentence
  reason>.` Example: "Review couldn't be submitted. You're offline."
- **Success confirmations**: terse, no exclamation marks. Example:
  "Branch merged."
- **Progress**: `Syncing…` rather than `Please wait…`

### Empty states

Empty review queues show a short headline (e.g., "No open reviews"),
one line of orientation, and a single CTA. No illustration, no upbeat
encouragement.

### CTA verb conventions

Observed verb ladder, by frequency:
1. **Get started** — top-of-page hero CTA
2. **Log in** — utility nav (the live-sampled dark CTA)
3. **Read the docs** — developer-facing pages
4. **Book a demo** — enterprise surfaces

Graphite avoids "Sign up free" / "Free trial" in the verb — the
free-tier fact lives in copy below the CTA, not in the button label.

## 12. Dark Mode & Theming

Graphite is **dark-first by design**. The marketing site ships
near-black only — the dark canvas *is* the brand identity, the same
surface the review product runs on. Inverting it would break
recognition with the engineering audience it targets.

If a downstream system needs to derive a light variant from these
tokens (e.g., for a light-mode docs portal):

```yaml
colors-light:
  bg: '#ffffff'
  bg-level-1: '#fafafa'
  bg-level-2: '#f4f4f5'
  text: '#070707'
  text-secondary: '#404040'
  text-tertiary: '#737373'
  brand: '#2563eb'                 # darken the blue for white-bg contrast
  border: '#e5e5e5'
  cta-fill: '#171717'              # dark CTA stays dark, near-black on white
  cta-text: '#fafafa'
```

But Graphite's own marketing surface stays near-black. This is
intentional.

## 13. Lineage & Influences

Graphite's marketing surface is engineered as a continuation of the
review product, not a separate brand layer. The lineage runs through
three strands: dark-canvas dev-tool design (Linear, Vercel), the
code-review and diff conventions of GitHub that Graphite reframes "for
the age of AI," and the Bay-Area discipline of a single restrained
accent over a near-black ground. What it inherits is the refusal to
soften the canvas for marketing — to treat the website as a view into
the tool. What it adds is the specific Matter type voice (60px / weight
`500`) and the dark-neutral 8px CTA, which reads as an IDE control
rather than a marketing pill.

What it rejects: Stripe-class chromatic gradients, glassy chrome, and
playful illustration. The system has no mascot, no gradient mark, no
decorative element. Where Linear pills its CTAs, Graphite keeps them
rectilinear at 8px; where most tools spend a second accent colour,
Graphite spends exactly one blue. The blue is punctuation, never the
page.

**Influences:**
- **Linear** — Dark-canvas product-as-marketing discipline and the
  single-accent restraint Graphite mirrors
  ([linear.app](https://linear.app))
- **Vercel** — Near-black dev-tool surface and the Geist-family sans
  typography lineage that sets the register
  ([vercel.com](https://vercel.com))
- **GitHub** — The code-review and diff surface conventions Graphite
  reframes for AI-assisted review ([github.com](https://github.com))
- **Tailwind CSS palette** — The blue-500/600 accent and neutral tiers
  this system samples ([tailwindcss.com](https://tailwindcss.com/docs/customizing-colors))
- **Matter (Displaay Type Foundry)** — The geometric grotesque set
  tight at the 60px/500 hero; Graphite's type voice
  ([displaay.net](https://displaay.net/typeface/matter/matter/))

## 14. Do's and Don'ts

### Do

- Use the near-black `#070707` ground across the whole surface — let
  section breaks be tonal lifts, not new colours.
- Keep `#fafafa` as body ink; reserve pure `#ffffff` for display-only
  max-contrast moments.
- Set headlines in Matter at weight `500` — firm, not bold. Carry
  hierarchy with size and tracking.
- Tighten tracking as type scales up (`-0.022em` at 60px), keep body
  at `0`.
- Make the dominant CTA dark-neutral `#262626` at **8px radius** — the
  live-observed signature.
- Treat the blue `#3b82f6` as accent-only: links, focus, the rare
  brand-coded button — one accent in the system.
- Use tonal layering (`#070707` → `#0f0f0f` → `#171717` → `#1f1f1f`)
  for depth; lift cards a tonal step on hover.
- Keep buttons and inputs rectilinear at 8px — Graphite is not
  pill-driven.
- Use hairline `#1f1f1f` borders, stepping to `#2e2e2e` on
  hover/emphasis, instead of card shadows.
- Render code, diffs, and file paths in the mono stack to signal the
  product's domain without illustration.
- Honour `prefers-reduced-motion` — switch all transforms to
  opacity-only.

### Don't

- Use pure `#000` for the canvas or `#ffffff` for body — both are off
  by design (`#070707`, `#fafafa`).
- Make the blue a default CTA fill. The primary action is dark
  `#262626`; the blue is punctuation.
- Round CTAs to full pills (9999). That's Linear's move — Graphite
  keeps action buttons at 8px.
- Introduce a second saturated accent. The chromatic budget is one
  blue plus the semantic four.
- Add drop shadows on cards. Use tonal layering and hairline borders.
- Soften the dark canvas for marketing — the product is dark, the site
  is dark.
- Set headlines at weight `700`. The system's voice is `500`.
- Treat the `Cursor Cloud Agents` banner or the skip-to-content link
  as design tokens — the live audit flagged both as noise, not CTAs.
- Centre H1s — Graphite's headlines are left-aligned.
- Let the page stretch past 1280, or reading copy past ~720px.

## 15. Agent Prompt Guide

### Quick Color Reference

```
bg:           #070707
bg-level-1:   #0f0f0f
bg-level-2:   #171717
text:         #fafafa
text-muted:   #a3a3a3
brand:        #3b82f6
accent:       #60a5fa
link:         #60a5fa
border:       #1f1f1f
cta-fill:     #262626
cta-text:     #fafafa
success:      #22c55e
danger:       #ef4444
```

### Example Component Prompts

1. **Hero**: "Create a hero section on `#070707` background with a
   left-aligned 60px Matter headline at weight 500 and `-0.022em`
   tracking, subhead at 18px/400 in `#fafafa`, reading copy capped at
   720px, with a single primary CTA: a dark `#262626` button, 8px
   radius, `#fafafa` text reading 'Get started'."

2. **Card**: "Design a feature card with `#0f0f0f` background, 1px
   `#1f1f1f` border, 12px radius, 24px padding, no shadow. Title at
   20px Matter 600, body at 16px/400 in `#d4d4d4`. On hover, transition
   the border to `#2e2e2e` and bg to `#171717` over 240ms."

3. **Primary CTA**: "Create a dark primary button: 8px radius, `#262626`
   background, `#fafafa` text at 14px Matter weight 500, padding
   `10px 16px`, height 40. Hover: bg `#2e2e2e`; no transform. Focus:
   `0 0 0 3px rgba(59,130,246,0.32)` ring with 2px offset."

4. **Status pill**: "Render a status pill with pill radius (9999),
   `rgba(59,130,246,0.12)` background, `rgba(59,130,246,0.22)` border,
   `#60a5fa` text at 12px Matter 500, 2px × 10px padding. Vary the
   colour to map to merged (success `#22c55e`) / approved (brand
   `#3b82f6`) / failing (danger `#ef4444`)."

5. **Sticky nav**: "Make a 64px-tall sticky nav with `rgba(7,7,7,0.72)`
   background, `backdrop-filter: blur(12px) saturate(180%)`, 1px bottom
   border `#1f1f1f`. Logo left, nav links centre, dark `#262626` 8px
   'Log in' CTA right; on scroll the border edge stays — no shadow."

6. **Input**: "Build a text input with `#0f0f0f` background, 1px
   `#1f1f1f` border, 8px radius, 40px height, `8px 12px` padding, 14px
   Matter 400 text in `#fafafa`, placeholder `#737373`. On focus,
   border `#3b82f6` plus a `0 0 0 3px rgba(59,130,246,0.32)` ring."

### Iteration Guide

1. **Near-black, not pure black.** If your `bg` reads as `#000`,
   soften to `#070707` (lab `2.75`). The hair of warmth keeps Matter
   from crunching.
2. **The CTA is dark, not blue.** If your primary action is
   brand-coloured, you've missed the central move. Make it dark
   neutral `#262626` at 8px; the blue goes on links, focus, and the
   rare brand button only.
3. **8px, not pill.** If the CTAs are full pills, you've drifted toward
   Linear. Graphite's action buttons are rectilinear at 8px — IDE
   controls, not marketing pills.
4. **Matter at 500.** Headlines are weight `500`, not `700`. If the
   type feels heavy, drop the weight before adjusting size; firmness,
   not boldness, is the voice.
5. **One blue.** If a second saturated accent has crept in, remove it.
   The chromatic budget is one blue plus the semantic four — nothing
   else competes.
6. **No card shadows.** If a card needs depth, lift its bg one tonal
   step (`#0f0f0f → #171717`) and tighten its border. Shadows belong to
   floating UI only.
7. **Ink stays `#fafafa`.** Pure `#ffffff` body copy looks harsh on the
   near-black ground; reserve it for display-only max-contrast.
8. **Reduced motion always.** Honour `prefers-reduced-motion` on every
   transition. Graphite's motion is restrained even at full — reduced
   should feel nearly identical.
