# Vercel Design System

> High-contrast monochrome precision anchored by Geist sans-serif, punctuated by a single electric blue accent.

**Source:** https://vercel.com | **Captured:** 2026-06-06 | **Pages analyzed:** 3
**Brand layer:** parent | **Related brands:** None

## TL;DR
Vercel's visual identity is a masterclass in developer-centric minimalism. The system operates on a stark monochrome foundation of `#fafafa` (Canvas) and `#171717` (Ink), creating a high-contrast environment that mimics a premium IDE. Typography is exclusively **Geist**, utilizing tight negative letter-spacing (`-2.88px` at display sizes) to create a dense, authoritative "stamped" look. While the core is achromatic, a specific electric blue (`#0072f5`) is reserved for primary success states and critical CTAs. The layout is structured by a rigorous grid, often visible through 1px dividers (`#ebebeb`) and subtle inset shadows that suggest depth without traditional elevation.

## Signature DNA
1. **The Geist Display Stamp** (Geist 600 at 48px with -2.88px letter-spacing. This extreme tracking creates the signature "Vercel" headline look seen on the homepage and pricing heroes.)
2. **Achromatic Hierarchy** (The interface uses shades of gray—`#171717`, `#4d4d4d`, `#7d7d7d`—to establish importance, reserving `#0072f5` blue strictly for functional "Success" or "Primary" actions.)
3. **Pill-Geometry Controls** (Interactive elements are almost universally rounded to `9999px`, creating a soft, tactile contrast against the sharp 1px grid lines of the layout.)

## Family Map
| Sub-brand | Primary color | Graphics motif | Inherits | Overrides |
| :--- | :--- | :--- | :--- | :--- |
| Vercel (Parent) | #0072f5 | Monochrome Grid | N/A | N/A |

## Colors
### Foundation
| Token | Hex | Role | Occurrences | Confidence | Source |
| :--- | :--- | :--- | :--- | :--- | :--- |
| `{colors.canvas}` | #fafafa | Page background, primary surface | 149 | 1.0 | Computed Style |
| `{colors.ink}` | #171717 | Primary text, dark button background | 854 | 0.8 | Computed Style |
| `{colors.border}` | #ebebeb | 1px section dividers, card outlines | 27 | 1.0 | `--accents-2` |
| `{colors.text-muted}` | #4d4d4d | Secondary body text, descriptions | 205 | 0.8 | Computed Style |
| `{colors.text-ghost}` | #7d7d7d | Captions, tertiary labels | 20 | 0.8 | Computed Style |

### Accent
| Token | Hex | Role | Occurrences | Confidence | Source |
| :--- | :--- | :--- | :--- | :--- | :--- |
| `{colors.primary}` | #0072f5 | Primary CTA background, success state | 3 | 1.0 | `--geist-success` |
| `{colors.link}` | #0068d6 | Inline text links | 23 | 0.8 | Computed Style |
| `{colors.violet}` | #7820bc | Decorative only (pricing feature) | 3 | 0.6 | Computed Style |
| `{colors.gold}` | #a35200 | Decorative only (warning/alert) | 4 | 0.6 | Computed Style |

## Typography
### Fonts
| Family | Weights observed | Role | Open-source substitute | License |
| :--- | :--- | :--- | :--- | :--- |
| Geist | 400, 500, 600 | Display, Heading, Body | Inter | Proprietary (Vercel) |
| Geist Mono | 400, 500, 600 | Code, Technical labels | JetBrains Mono | Proprietary (Vercel) |

### Scale
| Token | Size | Line height | Letter spacing | Weight | Use | Evidence selector |
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
| `{type.display-lg}` | 48px | 56px | -2.88px | 600 | Main Hero | `h3.text-heading-40` |
| `{type.display-md}` | 40px | 48px | -2.4px | 600 | Section Hero | `h2.intro-module__title` |
| `{type.heading-lg}` | 32px | 40px | -1.28px | 600 | Section Head | `h3.text-heading-24` |
| `{type.heading-md}` | 24px | 32px | -0.96px | 600 | Card Titles | `h3.text-heading-20` |
| `{type.body-lg}` | 20px | 36px | normal | 400 | Intro Paragraphs | `p.text-gray-900` |
| `{type.body-md}` | 16px | 24px | normal | 400 | Default Body | `div.stack` |
| `{type.body-sm}` | 14px | 20px | normal | 500 | Button Labels | `a.button-module__base` |
| `{type.mono-sm}` | 13px | 20px | normal | 500 | Code Snippets | `li.h-5.w-full` |

### Principles
1. **Tighten for Impact:** As font size increases, letter-spacing must decrease aggressively (up to -6% of font size).
2. **Medium for Interaction:** Use weight 500 for all interactive labels (buttons, nav links) to distinguish from weight 400 body prose.
3. **Mono for Metadata:** Use Geist Mono for technical data, code, and versioning strings, never for primary narrative.

## Spacing
**Base unit:** 4px
| Token | Value | Occurrences |
| :--- | :--- | :--- |
| `{space.1}` | 4px | 100 |
| `{space.2}` | 8px | 16 |
| `{space.4}` | 16px | 41 |
| `{space.6}` | 24px | 48 |
| `{space.12}` | 48px | 19 |

## Border radius
| Token | Value | Use | Evidence |
| :--- | :--- | :--- | :--- |
| `{radius.sharp}` | 0px | Section containers, layout blocks | 1018 occurrences |
| `{radius.sm}` | 6px | Inner cards, small UI elements | Card component |
| `{radius.md}` | 8px | Form controls, inputs | `role: control` |
| `{radius.pill}` | 9999px | Buttons, badges, tags | 42 occurrences |

## Elevation
| Level | Value | Use | Evidence |
| :--- | :--- | :--- | :--- |
| `{shadow.border}` | `rgba(0, 0, 0, 0.08) 0px 0px 0px 1px` | Card outlines | pricing page cards |
| `{shadow.soft}` | `rgba(0, 0, 0, 0.04) 0px 2px 2px 0px` | Hovered surfaces | `occurrences: 11` |

## Components
### Tier 1: Foundational
#### Rounded Button (Primary)
**Role:** Main call to action
**Pages observed:** Homepage, About
**Spec:** Background: `#171717` / Text: `#ffffff` / Radius: `9999px` / Padding: `0px 14px` / Typography: `Geist 500 16px`
**States observed:** Default | Hover: captured | Active: captured

#### Rounded Button (Secondary/Ghost)
**Role:** Secondary actions, navigation
**Pages observed:** Homepage, Pricing
**Spec:** Background: `#ffffff` / Text: `#171717` / Border: `#ebebeb` / Radius: `9999px` / Padding: `0px 10px` / Shadow: `{shadow.border}`
**States observed:** Default | Hover: captured

### Tier 2: Patterns
#### Feature Card
**Role:** Displaying product capabilities
**Pages observed:** Homepage
**Spec:** Background: `#ffffff` / Border: `1px #ebebeb` / Radius: `6px` / Padding: `16px` / Shadow: `{shadow.soft}`
**States observed:** Default | Hover: captured

#### Pill Badge
**Role:** Status indicators, tags
**Pages observed:** Pricing
**Spec:** Background: `transparent` / Text: `#171717` / Border: `1px #ebebeb` / Radius: `9999px` / Padding: `4px 8px`
**States observed:** Default

### Tier 3: Surface-specific
#### Pricing Tier Card
**Role:** Plan selection
**Pages observed:** Pricing
**Spec:** Background: `#fafafa` / Text: `#171717` / Border: `1px #ebebeb` / Radius: `0px` / Padding: `24px`
**States observed:** Default

#### Code Block
**Role:** Technical documentation snippets
**Pages observed:** Homepage
**Spec:** Background: `#ffffff` / Text: `#171717` / Font: `Geist Mono` / Radius: `6px` / Border: `1px #ebebeb`
**States observed:** Default

## Layout
| Property | Value |
| :--- | :--- |
| Max Width | 1200px (approx) |
| Section Gap | 90px |
| Column Grid | 12-column desktop |

## Responsive
| Breakpoint | Width | Key changes |
| :--- | :--- | :--- |
| Mobile | 390px | Display type scales from 48px to 32px; padding reduces to 16px. |
| Desktop | 1440px | Full 12-column grid; 90px section spacing. |

## Do's
- Use `#171717` for primary text to maintain high contrast against `#fafafa`.
- Apply negative letter-spacing to Geist headers (at least -1px for sizes > 24px).
- Use `9999px` border-radius for all interactive buttons.
- Reserve `#0072f5` for "Success" or "Primary" functional moments only.
- Use 1px `#ebebeb` borders to define layout structure instead of heavy shadows.

## Don'ts
- **Wrong:** Using `#0072f5` for a sub-brand's primary logo. **Right:** Use the sub-brand's specific token. **Reason:** `#0072f5` is the Vercel parent success/primary token.
- **Wrong:** Using standard letter-spacing for large Geist headlines. **Right:** Tighten to at least -2px. **Reason:** Geist display requires negative tracking for its signature look.
- **Wrong:** Mixing sharp and rounded buttons. **Right:** Use `9999px` for all buttons. **Reason:** Consistency in interactive geometry is a core brand signal.

## Quick start

```css
/* CSS Variables */
:root {
  --ds-background: #fafafa;
  --ds-foreground: #171717;
  --ds-accent: #0072f5;
  --ds-border: #ebebeb;
  --font-geist: "Geist", sans-serif;
  --font-geist-mono: "Geist Mono", monospace;
}
```

```javascript
// Tailwind v4 @theme
@theme {
  --color-canvas: #fafafa;
  --color-ink: #171717;
  --color-primary: #0072f5;
  --font-sans: "Geist";
  --font-mono: "Geist Mono";
  --radius-pill: 9999px;
}
```

## Agent prompt examples
- "Create a primary CTA button using Vercel's Ink color (#171717) with white text, Geist 500 font, and a full pill radius."
- "Design a feature card with a 1px #ebebeb border, 6px radius, and a subtle #0000000a shadow on a #fafafa background."
- "Generate a Geist display headline at 48px with -2.88px letter-spacing and weight 600."

## Known gaps
- Hover and Active states for tertiary buttons were not fully captured in the automated run.
- Dark mode tokens were present in CSS variables but not rendered on the analyzed pages.
- Complex animation timings for the "AI Cloud" hero graphic were not captured.

## Provenance
| Page sampled | URL | Viewport | Capture time |
| :--- | :--- | :--- | :--- |
| Homepage | https://vercel.com | 1440x900 | 2026-06-06 |
| Pricing | https://vercel.com/pricing | 1440x900 | 2026-06-06 |
| About | https://vercel.com/about | 1440x900 | 2026-06-06 |
