imitation
← all crawls

Vercel: Build and deploy the best web experiences with the AI Cloud

https://vercel.com/

Vercel gives developers the frameworks, workflows, and infrastructure to build a faster, more personalized web.

vercel.com screenshot

Visuals

Colors

Primary
#0068d6
Accent
#bd2864
Background
#ffffff
Surface
#fafafa
Text Primary
#171717
Text Secondary
#4d4d4d

Typography

Aa
Display
Geist
64px / w700
Aa
Heading
Geist
32px / w600
Aa
Body
Geist
12px / w400
Aa
Label
Geist
12px / w500
Aa
Mono
Geist Mono
13px / w400

Spacing

Xs
3px
Sm
4px
Md
6px
Lg
10px
Xl
12px

Radius

Sm
4px
Md
8px
Lg
100px
Pill
9999px

Shadows

Sm
Md
Lg

Mode

Light mode
Background
Sample text on canvas
Bg#ffffff
Text#171717
Muted#4d4d4d

Motion

Levelsubtle
Duration150ms
Easingease-in-out

Stack

Frameworktailwind
Iconscustom

Full Palette · 26 tokens

Brand
accent
#bd2864
primary
#0068d6
primary-active
#044a9c
primary-hover
#0557b5
Surface
canvas
#ffffff
surface-dark
#171717
surface-elevated
#ebf5ff
surface-soft
#fafafa
surface-strong
#ebebeb
Text
body
#4d4d4d
ink
#171717
muted
#666666
muted-soft
#7d7d7d
muted-weaker
#8f8f8f
on-dark
#ffffff
on-primary
#ffffff
Hairlines & Borders
border-pink
#e5484d
border-strong
#52aeff
border-teal
#45dec5
hairline
#ebebeb
hairline-soft
#eaeaea
Semantic
error
#e5484d
info-bg
#cce6ff
link
#0068d6
link-active
#0557b6
success
#45dec5

Typography Roles · 15

body-lg
Aa
16px / w400
body-md
Aa
12px / w400
body-sm
Aa
11px / w400
button
Aa
14px / w500
button-sm
Aa
13px / w500
caption
Aa
11px / w400
display-lg
Aa
48px / w600
display-md
Aa
32px / w600
display-xl
Aa
64px / w700
label
Aa
12px / w500
mono
Aa
13px / w400
mono-sm
Aa
12px / w400
title-lg
Aa
20px / w600
title-md
Aa
14px / w500
title-sm
Aa
13px / w500

Components · 33

announcement-bar
backgroundColor{colors.canvas}
padding{spacing.md} {spacing.xl}
textColor{colors.body}
typography{typography.body-md}
avatar
backgroundColor{colors.surface-strong}
rounded{rounded.full}
size32px
textColor{colors.muted}
button-dark-solid
backgroundColor{colors.ink}
padding6px 14px
rounded{rounded.pill}
textColor{colors.on-dark}
typography{typography.button-sm}
button-ghost
backgroundColortransparent
padding8px 12px
rounded{rounded.pill}
textColor{colors.body}
typography{typography.button}
button-ghost-hover
backgroundColor{colors.surface-soft}
rounded{rounded.pill}
textColor{colors.ink}
button-primary
backgroundColor{colors.surface-dark}
padding10px 20px
rounded{rounded.pill}
textColor{colors.on-dark}
typography{typography.button}
button-primary-active
backgroundColor#2a2a2a
rounded{rounded.pill}
textColor{colors.on-dark}
button-primary-hover
backgroundColor#000000
rounded{rounded.pill}
textColor{colors.on-dark}
button-secondary
backgroundColor{colors.canvas}
padding10px 20px
rounded{rounded.pill}
textColor{colors.ink}
typography{typography.button}
button-secondary-bordered
backgroundColor{colors.canvas}
padding6px 12px
rounded{rounded.DEFAULT}
textColor{colors.ink}
typography{typography.button-sm}
button-secondary-hover
backgroundColor{colors.surface-soft}
rounded{rounded.pill}
textColor{colors.ink}
card-bordered
backgroundColor{colors.canvas}
padding{spacing.lg} {spacing.xl}
rounded{rounded.DEFAULT}
textColor{colors.body}
typography{typography.body-md}
card-default
backgroundColor{colors.canvas}
padding{spacing.lg}
rounded{rounded.DEFAULT}
textColor{colors.ink}
typography{typography.body-md}
card-elevated
backgroundColor{colors.canvas}
padding{spacing.base} {spacing.xl}
rounded{rounded.DEFAULT}
textColor{colors.ink}
typography{typography.body-md}
code-inline
backgroundColor{colors.surface-soft}
padding1px 6px
rounded{rounded.sm}
textColor{colors.ink}
typography{typography.mono-sm}
cta-badge
backgroundColor{colors.info-bg}
padding4px 10px
rounded{rounded.pill}
textColor{colors.primary}
typography{typography.label}
cta-badge-inline
backgroundColor{colors.surface-dark}
padding6px 14px
rounded{rounded.pill}
textColor{colors.on-dark}
typography{typography.label}
divider
backgroundColortransparent
height1px
textColor{colors.hairline}
footer
backgroundColor{colors.canvas}
padding{spacing.section} {spacing.xl}
textColor{colors.muted}
typography{typography.caption}
hero-band
backgroundColor{colors.canvas}
padding{spacing.section-xl} {spacing.xl}
textColor{colors.ink}
typography{typography.display-lg}
hero-cta-container
backgroundColortransparent
textColor{colors.body}
typography{typography.body-md}
hero-headline
backgroundColortransparent
textColor{colors.ink}
typography{typography.display-lg}
hero-subhead
backgroundColortransparent
textColor{colors.body}
typography{typography.body-lg}
icon-button
backgroundColortransparent
rounded{rounded.DEFAULT}
size32px
textColor{colors.muted}
link-muted
backgroundColortransparent
textColor{colors.muted}
typography{typography.body-md}
link-primary
backgroundColortransparent
textColor{colors.link}
typography{typography.body-md}
logo-mark
backgroundColortransparent
textColor{colors.ink}
typography{typography.title-lg}
nav-trigger
backgroundColortransparent
padding8px 12px
rounded{rounded.pill}
textColor{colors.body}
typography{typography.button}
nav-trigger-hover
backgroundColor{colors.surface-soft}
rounded{rounded.pill}
textColor{colors.ink}
tag
backgroundColor{colors.surface-soft}
padding2px 8px
rounded{rounded.sm}
textColor{colors.muted}
typography{typography.caption}
text-input
backgroundColor{colors.canvas}
height36px
padding8px 12px
rounded{rounded.DEFAULT}
textColor{colors.ink}
typography{typography.body-md}
text-input-focus
backgroundColor{colors.canvas}
rounded{rounded.DEFAULT}
textColor{colors.ink}
top-nav
backgroundColor{colors.canvas}
height64px
textColor{colors.body}
typography{typography.button}

design.md

Vercel Design System

Overview

Vercel's visual identity is built on an almost aggressively minimal foundation—a pure {colors.canvas} background, near-black {colors.ink} type set in the proprietary Geist family, and exactly one brand voltage color ({colors.primary}) deployed with surgical restraint. The system reads as confident and developer-native: it assumes its audience respects precision over ornament, speed over flourish, and clarity over persuasion. Where many SaaS landing pages lean into gradients and glassmorphism, Vercel lets flat surfaces and sharp type carry the message, reserving its visual energy for the signature gradient illustration zone beneath the hero headline.

Brand voltage lives almost exclusively in interactive elements: the primary CTA buttons are inverted ({colors.surface-dark} backgrounds with white text), while informational badges use the pale {colors.info-bg} wash with {colors.primary} text. The single exception is the "Events" callout badge in the announcement strip, which signals urgency through the blue-on-blue treatment. Navigation triggers are ghost buttons—transparent with {colors.body} text—that gain a {colors.surface-soft} background on hover, creating a subtle "pressable" affordance without committing to borders or shadows.

The defining typographic move is weight as hierarchy: headlines sit at font-weight: 600 (never 700+ except at {typography.display-xl} scale), body copy at font-weight: 400, and labels at font-weight: 500. The system never uses bold as emphasis within running text; instead, it relies on size contrast (48px vs. 16px) and letter-spacing compression ({typography.display-lg} carries -0.05em) to create visual distinction. The Geist typeface itself is a geometric sans with extremely tight spacing characteristics, which the design leans into rather than fighting against.

Shape language splits cleanly between two idioms: navigation elements, buttons, and badges use {rounded.pill} (9999px border-radius) to feel friendly and approachable, while content cards, inputs, and structural containers default to {rounded.DEFAULT} (6px)—just enough softness to avoid feeling brutalist, but not so much that they read as toy-like. Avatars go fully circular ({rounded.full}), and the signature decorative elements in the illustration zone use geometric primitives (triangles, circles) with no rounding at all.

Key Characteristics:

  • Pure {colors.canvas} baseline with {colors.surface-soft} (#fafafa) for alternating band depth
  • Near-black {colors.ink} (#171717) for all headlines; never pure #000000
  • Single brand color {colors.primary} (#0068d6) reserved for links, badges, and focus states
  • Inverted CTAs using {colors.surface-dark} background with {colors.on-dark} text
  • Pill-shaped ({rounded.pill}) navigation and action elements; slightly-rounded ({rounded.DEFAULT}) content containers
  • Geist font family at weights 400/500/600/700 only—no light (300) faces in production
  • Tight negative letter-spacing on display sizes (-0.05em at 48px, -0.04em at 32px)
  • Shadow system capped at {extensions.shadows.lg}—never dramatic elevation, always grounded
  • Monospaced {typography.mono} (Geist Mono) for all code references and technical annotations

Colors

Brand & Accent

  • Primary ({colors.primary} — #0068d6): The sole brand voltage color—electric blue used for links, informational badges, active states, and the "Request to join" CTA badge background tint.
  • Primary Hover ({colors.primary-hover} — #0557b5): Darkened primary shade applied on link hover and interactive element hover states.
  • Primary Active ({colors.primary-active} — #044a9c): Further darkened state for pressed/focused interactions.
  • Accent ({colors.accent} — #bd2864): Magenta-pink used sparingly for decorative gradient zones in hero illustrations and occasional semantic highlights.

Surface

  • Canvas ({colors.canvas} — #ffffff): The absolute baseline—page background, card surfaces, button backgrounds in secondary/ghost variants.
  • Surface Soft ({colors.surface-soft} — #fafafa): One-step-off-white used for alternating content bands, hover fills on ghost buttons, and tag backgrounds.
  • Surface Strong ({colors.surface-strong} — #ebebeb): Medium gray surface for disabled-looking elements, input borders at rest, and subtle dividers.
  • Surface Elevated ({colors.surface-elevated} — #ebf5ff): Very pale blue tint reserved for info-callout backgrounds and selected/hover states on list items.
  • Surface Dark ({colors.surface-dark} — #171717): Near-black used as solid fill for primary CTA buttons ("Start Deploying", "Sign Up") and inline dark badges like "Request to join".

Text

  • Ink ({colors.ink} — #171717): Near-black—the darkest text color in the system, reserved exclusively for headlines (h1–h3) and highest-emphasis UI labels.
  • Body ({colors.body} — #4d4d4d): Mid-gray used for paragraph text, navigation items, and standard body copy throughout the page.
  • Muted ({colors.muted} — #666666): Softer gray for secondary descriptions, metadata timestamps, and placeholder text.
  • Muted Soft ({colors.muted-soft} — #7d7d7d): Even lighter gray for tertiary information—footnotes, helper text below form fields.
  • Muted Weaker ({colors.muted-weaker} — #8f8f8f): Faintest gray for disabled states and truly optional chrome.
  • On Primary ({colors.on-primary} — #ffffff): White text rendered atop {colors.primary} or {colors.surface-dark} backgrounds.
  • On Dark ({colors.on-dark} — #ffffff): White text for any dark-surface element (primary buttons, dark badges).

Hairlines & Borders

  • Hairline ({colors.hairline} — #ebebeb): Default border/divider color—used for card outlines, input borders at rest, and horizontal rules.
  • Hairline Soft ({colors.hairline-soft} — #eaeaea): Subtlest visible border, nearly indistinguishable from {colors.surface-strong} but semantically distinct for inner borders.
  • Border Strong ({colors.border-strong} — #52aeff): Bright blue border for focused inputs, active ring highlights, and selected-state indicators.
  • Border Pink ({colors.border-pink} — #e5484d): Error-red border for validation states and destructive action boundaries.
  • Border Teal ({colors.border-teal} — #45dec5): Success-teal border for positive confirmation states and completed-step indicators.

Semantic

  • Error ({colors.error} — #e5484d): Red for error messages, failed-state indicators, and destructive action text.
  • Success ({colors.success} — #45dec5): Teal-green for success confirmations, status checks, and positive feedback.
  • Link ({colors.link} — #0068d6): Alias for {colors.primary}—inline hyperlinks within prose and navigation anchor text.
  • Link Active ({colors.link-active} — #0557b6): Visited or active-link state, slightly darker than default link.
  • Info Background ({colors.info-bg} — #cce6ff): Pale blue wash behind informational badges (like the "Events" tag in the announcement bar).

Typography

Font Family

The entire system runs on Geist, Vercel's proprietary geometric sans-serif typeface, served as variable-weight WOFF2 from their CDN with font-display: swap. The font stack includes comprehensive emoji fallbacks ("Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol") and degrades gracefully to Arial then system-ui for environments where Geist fails to load. A secondary face, Geist Mono, handles all code snippets, terminal references, and technical annotations—it shares the same x-height and cap-height proportions as Geist but with monospaced glyphs and tabular figures. The font-face declarations reveal Geist supports weight range 100–900 via variable font axes, though the production system only exercises 400, 500, 600, and 700 in practice.

Hierarchy

| Token | Size | Weight | Line Height | Letter Spacing | Use | |---|---|---|---|---|---| | {typography.display-xl} | 64px | 700 | 1.05 | -0.03em | Epic-scale headlines (rare, marketing moments) | | {typography.display-lg} | 48px | 600 | 1 | -0.05em | Hero h1, major section openers | | {typography.display-md} | 32px | 600 | 1.25 | -0.04em | Feature section headings, h2 equivalents | | {typography.title-lg} | 20px | 600 | 1.35 | -0.02em | Card titles, sidebar headings | | {typography.title-md} | 14px | 500 | 1.43 | -0.02em | Navigation labels, small section headers | | {typography.title-sm} | 13px | 500 | 1.38 | -0.01em | Table headers, filter labels | | {typography.body-lg} | 16px | 400 | 1.55 | 0 | Hero subhead paragraphs, lead-in copy | | {typography.body-md} | 12px | 400 | 1.33 | 0 | Standard body text, descriptions | | {typography.body-sm} | 11px | 400 | 1.45 | 0 | Fine print, legal footers, metadata | | {typography.caption} | 11px | 400 | 1.36 | 0 | Timestamps, helper text, disabled labels | | {typography.button} | 14px | 500 | 1.25 | 0 | Button labels, CTA text | | {typography.button-sm} | 13px | 500 | 1.23 | 0 | Small button labels ("Ask AI") | | {typography.label} | 12px | 500 | 1.33 | 0 | Badge text, tag contents | | {typography.mono} | 13px | 400 | 1.54 | 0 | Inline code, command-line references | | {typography.mono-sm} | 12px | 400 | 1.33 | 0 | Small code blocks, keyboard shortcuts |

Principles

The typography system trusts size and weight over decoration to establish hierarchy. You will find zero instances of underlined headlines, italicized emphasis blocks, or uppercase treatments for headings—every distinction comes from stepping up in the size scale (12px → 14px → 20px → 32px → 48px) and bumping weight (400 → 500 → 600 → 700). Letter-spacing compression is applied aggressively at larger sizes: {typography.display-lg} sits at -0.05em (-2.4px absolute), which visually tightens the headline without reducing legibility. This is a deliberate counteraction to Geist's naturally wide character advance widths at display sizes.

Color also carries hierarchy: {colors.ink} (#171717) appears only in headline contexts, while {colors.body} (#4d4d4d) handles everything else. This means a reader can instantly distinguish heading from body by darkness alone, even if the size delta were smaller than it is. The mono face (Geist Mono) is reserved strictly for technical content—package names, command strings, file paths—and never used for UI chrome like button labels or navigation items.

Note on Font Substitutes

Geist is not available on Google Fonts. For prototyping or open-source reimplementation, the closest match is Inter (Rasmus Andersson), available at fonts.google.com. Inter shares Geist's tall x-height, geometric skeleton, and excellent screen rendering at small sizes. Set your CSS variables as follows:

:root {
  --font-sans: 'Inter', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, "Fira Code", monospace;
}

For Geist Mono substitutes, JetBrains Mono or Fira Code provide the closest visual match with similar tabular figure support.

Layout

Spacing System

  • Base unit: 2px (the {spacing.xxs} token). Most internal gaps derive from multiples of this value.
  • Tokens: {spacing.xxxs} (1px — hairline dividers, inset shadows), {spacing.xxs} (2px — micro-gaps inside tags), {spacing.xs} (3px — icon-to-text gap in buttons), {spacing.sm} (4px — compact padding), {spacing.md} (6px — standard gap), {spacing.base} (8px — comfortable gap), {spacing.lg} (10px — button vertical padding), {spacing.xl} (12px — card padding, input padding), {spacing.2xl} (14px — loose button padding), {spacing.3xl} (16px — section gutters), {spacing.4xl} (24px — inter-block spacing), {spacing.5xl} (32px — major section breaks), {spacing.section} (48px — vertical band padding), {spacing.section-xl} (80px — hero/top-section breathing room).
  • Section padding (vertical): {spacing.section-xl} — applied to the hero band and major content sections.
  • Card internal padding: {spacing.xl} (12px) horizontally, {spacing.lg} (10px) vertically for tight cards; {spacing.xl} all-around for standard cards.
  • Gutters: Page-level horizontal gutter is {spacing.3xl} (16px) on mobile, scaling to 24px at desktop per container max-width constraints.

Grid & Container

  • Max content width: 1440px (derived from the main and header container widths in extracted data). Content centers within viewport beyond this.
  • Density choice: Editorial-airy — the hero uses roughly 60% of viewport width for the text column, leaving substantial whitespace on either side. This is not a marketplace-dense grid; it's a narrative layout where each section gets room to breathe.
  • Desktop grid behavior: The main content area operates as a fluid centered column within the 1440px constraint. No explicit 12-column or 6-column CSS Grid was detected—the layout uses flexbox with max-width containers and auto margins. An interesting structural detail: the DOM reveals a sticky right-rail aside (w-[400px]) that may serve as a reservation/sales rail on authenticated or enterprise views, though it's empty in this public landing snapshot.
  • Hero column split: Text content (headline + subhead + CTA pair) occupies the left ~55% of the hero band; the gradient illustration occupies the remaining space below and slightly overlapping.

Whitespace Philosophy

The system practices generous asymmetric whitespace: vertical rhythm is loose (80px between major bands), but horizontal density within a component is tighter (12px card padding, 8px gaps between sibling buttons). This creates a feeling of spaciousness at the macro level while keeping individual interaction clusters compact enough for efficient scanning. The hero subhead has significant bottom margin before the CTA pair—roughly 32px—ensuring the call-to-action doesn't crowd the value proposition.

Header Architecture

┌──────────────────────────────────────────────────────────────────────────────┐
│ [▲ Vercel]   [Products ▾] [Resources ▾] [Solutions▾] [Enterprise][Pricing]     │
│                                              [Ask AI][Log In][Sign Up]       │
│ ──────────────────────────────────────────────────────────────────────────── │
│  max-width: 1440px, height: 64px, padding: 0 24px                           │
└──────────────────────────────────────────────────────────────────────────────┘

Navigation items use pill-shaped ({rounded.pill}) trigger buttons with transparent backgrounds. The "Sign Up" button is the only persistent primary CTA in the header, rendered as {component.button-dark-solid} (dark background, white text, pill shape).

Hero Section

┌──────────────────────────────────────────────────────────────────────────────┐
│                                                                              │
│   [Events] Ship 26 is coming to 5 cities        [Request to join ▸]         │
│ ──────────────────────────────────────────────────────────────────────────── │
│                                                                              │
│            Build and deploy on the AI Cloud.                                │
│                                                                              │
│          Vercel provides the developer tools and                            │
│          cloud infrastructure to build, scale,                              │
│          and secure a faster, more personalized web.                        │
│                                                                              │
│              [▲ Start Deploying]    [Get a Demo]                            │
│                                                                              │
│                         ╲                                                    │
│                          △  (gradient illustration zone)                     │
│                         ╱                                                    │
│                                                                              │
└──────────────────────────────────────────────────────────────────────────────┘

The announcement bar sits above the hero headline with a light {colors.info-bg} badge for "Events" and an inline dark {component.cta-badge-inline} for the "Request to join" CTA. The headline is set in {typography.display-lg} (48px/600 weight) with aggressive letter-spacing compression. Below the subhead, two CTAs appear side-by-side with ~12px gap: {component.button-primary} (dark filled, "Start Deploying") and {component.button-secondary} (white outlined, "Get a Demo"). The gradient illustration zone begins below the CTA row, featuring a triangular geometric primitive overlaid on a warm-cool radial gradient wash.

Announcement Strip

A thin horizontal band (roughly 40px tall) positioned between the sticky header and hero content. Contains an inline notification with a pill-shaped {component.cta-badge} (blue-tinted background) for categorical labeling, followed by plain text in {typography.body-md}, terminated by a dark {component.cta-badge-inline} CTA. Background is {colors.canvas} with no border separator—visual separation comes from spacing alone.

Elevation & Depth

| Level | Treatment | Use | |---|---|---| | 0 (Flat) | No shadow, {colors.canvas} background | Base page surface, static cards | | 1 (Hairline) | {extensions.shadows.border-only} — 1px rgba(0,0,0,0.08) border | Bordered cards, input fields at rest, secondary buttons | | 2 (Soft) | {extensions.shadows.sm} — 0px 2px 2px rgba(0,0,0,0.04) | Hovered cards, dropdown menus, tooltip containers | | 3 (Raised) | {extensions.shadows.md} — composite border + soft drop + white inset | Elevated panels, modals, sticky nav on scroll | | 4 (Floating) | {extensions.shadows.lg} — multi-layer with spread blur | Persistent overlays, drag surfaces, preview panes |

The elevation philosophy is grounded, not floating. Even the deepest shadow ({extensions.shadows.lg}) produces only an 8px blur spread—nothing approaches the 24px+ drops common in Material Design or Apple HIG. Shadows are neutral-toned (no blue or warm tint), and the system prefers color-block separation (alternating {colors.canvas} / {colors.surface-soft} bands) over shadow-cast depth for sectional hierarchy. Borders are favored over shadows for most interactive elements: notice that {component.button-secondary-bordered} uses a 1px {colors.hairline} border rather than any drop shadow.

Decorative Depth

The hero illustration zone introduces the only non-flat depth treatment: a radial gradient wash blending warm yellows/oranges on the left through magenta center to cyan/teal on the right, overlaid with fine parallel-line hatching patterns that create a subtle moiré/interference effect. A stark black-outlined triangle (the Vercel logo primitive) floats atop this gradient, creating focal-point contrast. This is purely illustrative—not a UI surface—and should be treated as imagery, not a component token.

Shapes

Border Radius Scale

| Token | Value | Use | |---|---|---| | {rounded.none} | 0px | Code blocks, table cells, hard-edged decorative elements | | {rounded.sm} | 4px | Tags, inline code snippets, small badges | | {rounded.DEFAULT} | 6px | Cards, inputs, bordered buttons, content containers | | {rounded.md} | 8px | Larger cards, modal panels, image thumbnails | | {rounded.lg} | 100px | Very loose rounding—rarely used, possibly legacy | | {rounded.xl} | 50% | Semi-circle shapes (pill alternatives) | | {rounded.pill} | 9999px | Buttons, nav triggers, badges, CTAs | | {rounded.full} | 9999px | Avatars, circular icon containers |

The dominant radius in the system is pill ({rounded.pill}) for anything interactive and clickable, and default ({rounded.DEFAULT}) for anything containing or presenting content. This binary split creates clear visual grammar: round = action, squarish = information.

Photography Geometry

No photography is present in the hero screenshot—the illustration is vector-gradient artwork. Based on Vercel's broader design language (inferable from the DOM classes referencing avatars and image containers), images would be treated with {rounded.DEFAULT} (6px) corners for screenshots/demo previews, {rounded.full} for user avatars, and no rounding for product/logomark imagery. Aspect ratios favor 16:9 for demo captures and 1:1 for team/member photos.

Components

No hover states documented. Hover behavior is unreliable to extract from a single screenshot. State variants live as separate entries in the components: frontmatter (e.g. {component.button-primary-active}, {component.text-input-focus}); add hover styling at implementation time per your stack's conventions.

Buttons

{component.top-nav} — The fixed/sticky header container spanning full viewport width. Background {colors.canvas}, text defaults to {colors.body}, height locked at 64px. Internal layout uses flexbox with logo left, nav-center cluster, utilities right. Has a subtle bottom border or shadow on scroll (not captured in static screenshot). Contains {component.nav-trigger} items, {component.logo-mark}, {component.button-secondary-bordered} (Ask AI), {component.button-ghost} (Log In), and {component.button-dark-solid} (Sign Up).

{component.nav-trigger} — Transparent-background pill button for "Products", "Resources", "Solutions" etc. Text in {typography.button} at {colors.body} color, {rounded.pill} geometry, padding 8px 12px. On hover transitions to {component.nav-trigger-hover} with {colors.surface-soft} background and {colors.ink} text. Includes chevron-down indicator (not captured as text node).

{component.button-primary} — The primary conversion CTA, exemplified by "Start Deploying". Solid {colors.surface-dark} background, {colors.on-dark} text, {typography.button} sizing, {rounded.pill} shape, padding 10px 20px. Includes a leading triangle icon (the Vercel mark) inline with text. Active variant {component.button-primary-active} darkens background to #2a2a2a.

{component.button-secondary} — The outlined/gost counterpart to primary, shown as "Get a Demo". {colors.canvas} background with implicit 1px {colors.hairline} border (carried by shadow/border property outside YAML schema), {colors.ink} text, same {rounded.pill} and padding dimensions as primary. Hover variant {component.button-secondary-hover} fills background with {colors.surface-soft}.

{component.button-secondary-bordered} — Smaller bordered variant used for "Ask AI" in the header. {colors.canvas} background, 1px {colors.hairline} border, {typography.button-sm} text, {rounded.DEFAULT} (6px, notably not pill here—this distinguishes utility actions from primary CTAs), tight padding 6px 12px.

{component.button-dark-solid} — Compact dark-filled button for "Sign Up". {colors.ink} background, {colors.on-dark} text, {typography.button-sm}, {rounded.pill}, 6px 14px padding. Visually subordinate to {component.button-primary} but more prominent than ghost actions.

{component.button-ghost} — Transparent button for "Log In". No background, {colors.body} text, {typography.button}, {rounded.pill}, 8px 12px padding. Hover fills with {colors.surface-soft} per {component.button-ghost-hover}.

{component.cta-badge} — Informational pill badge like "Events" in the announcement bar. {colors.info-bg} background, {colors.primary} text, {typography.label} sizing, {rounded.pill}, 4px 10px padding. Used for categorical labeling alongside free text.

{component.cta-badge-inline} — Action-oriented dark badge like "Request to join". {colors.surface-dark} background, {colors.on-dark} text, {typography.label}, {rounded.pill}, 6px 14px padding. Functions as a mini-CTA within text flow, includes trailing chevron indicator.

Cards & Containers

{component.hero-band} — The full-width hero section container. {colors.canvas} background, padding {spacing.section-xl} vertically and {spacing.xl} horizontally. Centers its child content within the 1440px max-width constraint. Houses {component.hero-headline}, {component.hero-subhead}, {component.hero-cta-container}, and the gradient illustration.

{component.card-default} — Standard content card. {colors.canvas} background, no visible border or shadow at rest (flat), {rounded.DEFAULT}, {spacing.lg} padding. Would be used for feature summaries, testimonial blocks, or pricing-tier displays lower on page (inferred from typical Vercel page architecture).

{component.card-elevated} — Card with subtle elevation. Same surface and text tokens as {component.card-default} but carries {extensions.shadows.sm} or {extensions.shadows.border-only} for lift. Padding slightly looser at {spacing.base} horizontal.

{component.card-bordered} — Card with visible border outline. Uses 1px {colors.hairline} border (outside YAML schema), {rounded.DEFAULT}, generous {spacing.lg}/{spacing.xl} padding. Used when card must be clearly demarcated from surrounding content without shadow depth.

{component.footer} — Page footer container. {colors.canvas} background (may alternate to {colors.surface-soft} on deeper pages), {colors.muted} text, {typography.caption} sizing, {spacing.section} vertical padding. Typically contains multi-column link groups, legal text, and social icons (not visible in above-fold screenshot).

{component.announcement-bar} — Thin horizontal notification strip between header and hero. {colors.canvas} background, {typography.body-md} text, {spacing.md}/{spacing.xl} padding. Contains mixed inline elements: {component.cta-badge}, free text, and {component.cta-badge-inline}.

Inputs & Forms

{component.text-input} — Standard text input field. {colors.canvas} background, 1px {colors.hairline} border, {colors.ink} text, {typography.body-md}, {rounded.DEFAULT}, 8px 12px internal padding, 36px height. Focus state {component.text-input-focus} swaps border to {colors.border-strong} (bright blue) per the elevation table.

Navigation & Links

{component.link-primary} — Inline hyperlink. Transparent background, {colors.link} text color, {typography.body-md}. No underline decoration (Vercel style omits underlines except on explicit hover/focus). Active state shifts to {colors.link-active}.

{component.link-muted} — De-emphasized link for secondary navigation or footer links. {colors.muted} text, same typography as primary link.

{component.logo-mark} — The Vercel wordmark (leftmost in header). Transparent background, {colors.ink} text, {typography.title-lg} (approximately 18-20px, weight 600 inferred from mark prominence). Accompanied by the triangle SVG icon (not a text element).

{component.divider} — Horizontal rule element. 1px height, {colors.hairline} background color, full-width within parent container. Used sparingly—prefers whitespace separation over drawn lines.

Sub-System Components

{component.tag} — Taxonomy or category label. {colors.surface-soft} background, {colors.muted} text, {typography.caption}, {rounded.sm}, 2px 8px padding. Smaller and more rectangular than badges—used for filtering UI or metadata tagging.

{component.avatar} — User profile image placeholder. {colors.surface-strong} background (gray circle until image loads), {colors.muted} initial/text if present, {rounded.full}, 32px default size. Would contain <img> in populated state.

{component.icon-button} — Square/minimal button holding only an icon. Transparent background, {colors.muted} icon color, {rounded.DEFAULT}, 32×32px. Used for settings toggles, dismiss actions, or auxiliary controls.

{component.code-inline} — Inline code or technical reference. {colors.surface-soft} background, {colors.ink} monospace text, {typography.mono-sm}, {rounded.sm}, 1px 6px horizontal padding. Distinguishes technical terms from prose.

Do's and Don'ts

Do

  • Do reserve {colors.ink} (#171717) exclusively for headlines and h1–h3 elements—body copy must always use {colors.body} (#4d4d4d) or lighter.
  • Do apply {rounded.pill} to all clickable action elements (buttons, nav triggers, badges) and {rounded.default} (6px) to all content-containing surfaces (cards, inputs, panels).
  • Do use {typography.display-lg} with its -0.05em letter-spacing for hero headlines—never reset to letter-spacing: normal at display sizes.
  • Do place primary CTAs as filled dark buttons ({component.button-primary}) with white text, keeping secondary actions as outlined or ghost ({component.button-secondary}).
  • Do maintain 80px+ vertical padding ({spacing.section-xl}) between major page sections—Vercel's aesthetic demands breathing room.
  • Do render all code references in {typography.mono} (Geist Mono) with {component.code-inline} styling (light gray background, tiny border-radius).
  • Do use shadow level 2 or below for most elevated surfaces—reserve {extensions.shadows.lg} for true overlay modals only.
  • Do keep button height at 36–40px minimum for primary/secondary variants to ensure touch-friendly targets.
  • Do employ alternating band backgrounds ({colors.canvas}{colors.surface-soft}) for section separation rather than heavy dividers or shadows.
  • Do include the triangle icon (Vercel mark) inline before "Start Deploying"—it's part of the button's visual identity, not separable decoration.

Don'ts

  • Don't use pure black (#000000) for any text—always use {colors.ink} (#171717) as the darkest tone; pure black is too harsh for this system's voice.
  • Don't apply bold (700+) weight to body text or labels—the system caps non-display text at weight 500 ({typography.label}) or 400 ({typography.body-md}).
  • Don't add gradients to button backgrounds or card surfaces—the only gradient in the system is the hero illustration zone; all UI chrome is flat-color.
  • Don't use underlined links in body prose—Vercel's convention is color-only link indication ( {colors.link} ) with underline appearing only on hover/focus.
  • Don't exceed 6px border-radius on content cards—larger rounding (8px+) is rare and reserved for specific modal/image containers; don't promote it to default.
  • Don't mix font families within a text block—Geist handles everything except explicit code (which uses Geist Mono); never introduce a serif or alternate sans.
  • Don't place more than two CTAs side-by-side in a hero—the pattern is strictly primary + secondary; additional actions belong in a dropdown or below-fold.
  • Don't apply box-shadow to navigation triggers—they remain flat/ghost at all states, using only background-color transitions.
  • Don't use the primary blue ({colors.primary}) as a solid fill for large areas—it's reserved for text, borders, and small accents; large blue fields don't exist in this palette.
  • Don't omit the negative letter-spacing on display typography—it's essential to the tightened, modern look of headlines; removing it makes Geist look unexpectedly wide and airy.

Motion & Animation

Transition Tokens

/* Core transition presets extracted from computed styles */
--transition-fast: color 0.09s, background 0.09s;
--transition-base: color 0.15s ease-in-out;
--transition-complex: border-color 0.15s, background 0.15s, color 0.15s, transform 0.15s, box-shadow 0.15s;
--transition-shadow: box-shadow 0.2s, background-color 0.2s;
--transform-rotate: rotate 0.2s;
--fade-opacity: opacity 0.4s cubic-bezier(0.33, 0.12, 0.15, 1);

Keyframe Animations

  • fadeIn — Generic opacity 0→1 entrance for dialogs, tooltips, and overlay panels.
  • fadeOut — Opacity 1→0 exit paired with fadeIn for modal lifecycle.
  • xsDisappear/smDisappear/mdDisappear/lgDisappear — Responsive grid-item exit animations triggered at breakpoint changes.
  • spin — Continuous 360° rotation for loading spinner indicators.
  • drawAndErase/drawAndEraseFirst/drawAndEraseSecond/drawAndEraseThird — SVG stroke-dashoffset animations for the avatar/icon drawing effect (likely the Vercel triangle or user avatar rings).
  • flicker — Rapid opacity toggle for "booting" or terminal-style status effects.
  • dots — Pulsing ellipsis animation for loading/processing indicators.
  • fade-in — Scroll-triggered content entrance (campaign events list and general content modules).

Interaction Patterns

  • Hover lifts on cards: Bordered/elevated cards gain {extensions.shadows.sm} on hover with a 150ms color/shadow transition.
  • Background-fill on ghost buttons: Nav triggers and ghost buttons transition from transparent to {colors.surface-soft} on hover (~90ms timing).
  • Focus rings on inputs: Text inputs swap border from {colors.hairline} to {colors.border-strong} (bright blue) on focus, with possible subtle shadow enhancement.
  • Dropdown reveals: Navigation menu dropdowns animate in with fade + slight Y-offset (implied by dialog fadeIn keyframe).
  • Scroll-triggered fades: Content sections below the fold fade in as they enter the viewport (using Intersection Observer + content-module__fadeIn).
  • Avatar drawing animation: User avatars or icon marks "draw themselves" via sequential stroke animations on mount.
  • Tooltip fade: Tooltips use 150ms opacity transition with a cubic-bezier easing for smooth appearance.
  • Spinner rotation: Loading states show a continuously rotating SVG element at moderate speed.

Imagery Style

  • Illustration-led hero: The dominant visual is a custom vector-gradient illustration featuring a radial warm-to-cool color field (yellow-orange → magenta → cyan-teal) with fine parallel-line hatching texture creating subtle optical depth.
  • Geometric primitives: The Vercel triangle (black stroke, white or transparent fill) serves as the central focal point overlaid on the gradient field—this is brand imagery, not decorative abstraction.
  • No photography: The above-fold area contains zero photographic imagery; the entire visual weight is carried by type and vector art.
  • Gradient as atmosphere: The gradient isn't a button or card fill—it's a background atmospheric element occupying the lower 40% of the hero band, suggesting creativity/AI capability without depicting literal screens or dashboards.
  • Line-art texture: Subtle hatching/parallel lines create a sense of digital precision and "constructed" quality, aligning with the developer-tool positioning.
  • High contrast foreground: All UI elements (text, buttons) sit on flat {colors.canvas}—imagery never competes with readability by serving as a text backdrop.
  • Brand color presence: The gradient includes hints of {colors.primary}-adjacent blues and {colors.accent}-adjacent pinks, subtly reinforcing the palette without explicit color-token usage.
  • Bottom-weighted composition: Visual mass concentrates in the lower half of the hero, balancing the headline/subhead/CTA stack in the upper half.
  • Scalable vector format: Implied SVG or CSS-gradient implementation for crisp rendering at all viewport sizes and pixel densities.
  • Animation potential: The gradient zone likely supports subtle parallax or color-shift animation on scroll (inferred from the complexity of the keyframe inventory including draw/erase cycles).

Icon System

  • Library: Custom SVG icons (no detected third-party library—TailwindLikely framework with inline SVG components).
  • Specific icons observed:
    • Triangle (Vercel logo mark) — appears inline before "Start Deploying" CTA text and as the standalone hero illustration focal point.
    • Chevron down (▾) — suffix on navigation triggers (Products, Resources, Solutions).
    • Chevron right (›) — suffix on "Request to join" badge indicating external/navigation action.
  • Treatment: Icons use currentColor inheritance, matching their parent element's textColor. Stroke-based for line icons (chevrons), fill-based for the logo triangle. Size is typically 16px–20px inline with text, scaling to 120px+ for the hero illustration mark.
  • Alignment: Icons are vertically centered with adjacent text using flexbox alignment, with 6px–8px gap (matching {spacing.md}/{spacing.base}) between icon glyph and text label.
  • Weight consistency: All icons share consistent stroke width (likely 1.5px–2px for line icons), maintaining uniform visual weight across the icon vocabulary.

Recommended Frontend Stack

- Framework:      Next.js (App Router) — Vercel's own framework, evident from RSC payload markers in DOM
- Styling:        Tailwind CSS v4 (utility-first, detected tailwind-* class prefixes throughout)
- Fonts:          Self-hosted Geist + Geist Mono via @font-face WOFF2 variables; fall back to Inter/Geist from vercel.com CDN
- Animation:      CSS transitions + keyframes (vanilla, JS-triggered via Intersection Observer)
- Icons:          Custom SVG components (inline, currentColor-based)
- Component lib:  Custom atomic components (Radix-like patterns implied by dialog/grid module naming)

Responsive Behavior

Breakpoints

| Name | Width | Key Changes | |---|---|---| | Mobile | < 640px | Single-column layout, collapsed nav to hamburger, hero headline scales to ~32px, CTA buttons stack vertically | | Tablet | 640px – 1023px | Two-column grid emerges, nav remains collapsed or simplified, hero illustration reduces width share | | Desktop | 1024px – 1439px | Full header nav visible, hero text + illustration side-by-side, 1440px max-width container active | | Wide | ≥ 1440px | Container maxes at 1440px with auto centering, right-rail aside (400px) may appear on authenticated views |

Touch Targets

  • {component.button-primary}: ~40px height × variable width (padding 10px 20px) — exceeds 44px WCAG AAA target comfortably.
  • {component.button-secondary-bordered} ("Ask AI"): ~34px height × ~70px width — marginally below 44px recommendation; consider increasing padding to 8px 14px for touch.
  • {component.nav-trigger}: ~36px height × variable width — adequate for tap targets; pill shape aids perceived clickability.
  • {component.text-input}: 36px height — meets 44px minimum only with padding inclusion; ensure total hit-area (including border) reaches 44px.

Collapsing Strategy

  • Navigation: At tablet and below, the Products/Resources/Solutions/Solutions/Enterprise/Pricing links collapse into a hamburger menu (or "More") trigger. "Ask AI", "Log In", and "Sign Up" persist as visible buttons or move into the menu panel.
  • Hero columns: On mobile, the hero headline, subhead, and CTA stack to single-column full-width. The gradient illustration moves below the CTA block or reduces to a smaller decorative accent.
  • CTA pairing: The "Start Deploying" + "Get a Demo" side-by-side arrangement stacks vertically on mobile with ~12px gap, primary button on top.
  • Announcement bar: May truncate or hide on smallest viewports to preserve hero real estate; "Events" badge likely persists but descriptive text may clip with ellipsis.
  • Right-rail aside: The 400px-wide sticky aside detected in the DOM collapses to hidden/off-canvas at all breakpoints except possibly widescreen desktop (1440px+).

Image Behavior

  • Hero gradient illustration: Scales proportionally with viewport width, maintaining aspect ratio roughly 16:9 or wider. On mobile, it compresses vertically and may reduce opacity or shift to a background-position treatment behind text content rather than sitting as a discrete block.
  • Logo mark (triangle in hero): Maintains relative position within the gradient field; scales down proportionally, likely never dropping below 60px visible size to preserve brand recognition.
  • Avatars (if present lower on page): Maintain 32px diameter at all breakpoints; grid layouts simply show fewer columns.

Iteration Guide

  1. Build a landing page closely mimicking this design system using Next.js with App Router and Tailwind CSS v4. Initialize your project with the Geist font loaded via next/font or self-hosted @font-face declarations matching the fontFaces array above.

  2. Extract every color, font-size, font-weight, border-radius, spacing, and shadow value directly from the YAML frontmatter using the {section.token} reference paths. Never hard-code a hex, pixel value, or font stack that has a defined token—for example, always write backgroundColor: "{colors.surface-dark}" never backgroundColor: "#171717" in your component implementations.

  3. Implement state variants (-hover, -active, -focus, -disabled) as separate component entries or conditional className logic following your framework's conventions. The spec documents Default and Active/Pressed states explicitly; infer hover from the pattern (background-color shift to {colors.surface-soft}, shadow enhancement).

  4. When adding a new component, classify it into one of these subsystems first: Buttons (clickable actions), Cards (content containers), Inputs (form controls), Navigation (wayfinding), or Sub-System (badges, tags, avatars). Each subsystem shares consistent padding, radius, and elevation rules.

  5. Ensure every {token.path} reference in your codebase resolves to a token actually defined in frontmatter. Run npx @google/design.md lint DESIGN.md after any edits—broken-ref, contrast-ratio, and orphaned-tokens warnings will catch missing definitions or unused tokens automatically.

  6. Match the weight-as-hierarchy principle: reach for size increases before weight increases when establishing typographic emphasis. Headlines should be 600 weight maximum unless exceeding 48px (where 700 becomes acceptable). Body text stays 400; labels stay 500.

  7. Replicate the binary radius grammar: anything you can click gets {rounded.pill}; anything you read gets {rounded.DEFAULT} (6px). Resist introducing intermediate radius values not present in the scale.

  8. Preserve the motion timing from the extensions: 90ms for fast color transitions, 150ms for complex property transitions, 200ms for shadow/structural changes. Use ease-in-out or the specified cubic-bezier curves rather than default ease or linear.

  9. When implementing the hero illustration zone, treat it as an <img> or CSS-background layer rather than a component—it sits outside the token system. Use a gradient SVG or CSS radial-gradient approximation with the yellow→magenta→cyan-teal color stops observed.

  10. For font setup, define these CSS custom properties in your :root or tailwind config to map to the actual font files:

    :root {
      --font-sans: 'Geist', Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
      --font-mono: 'Geist Mono', ui-monospace, SFMono-Regular, "Roboto Mono", Menlo, Monaco, monospace;
    }
    

    If Geist WOFF2 files are unavailable, substitute 'Inter', ui-sans-serif, system-ui for --font-sans and 'JetBrains Mono', ui-monospace, monospace for --font-mono.

Known Gaps

  • Hover state styling: Per the no-hover policy, exact hover background colors, shadow elevations, and transform offsets for buttons, cards, and links are documented only as separate active/pressed variants or inferred from transition properties. Implementation teams must synthesize hover states from the active-variant patterns.
  • Loading skeletons / pending states: No spinner or skeleton markup was extractable beyond the spinner-module__gyz83a__spin keyframe name and booting-module flicker/dots animations. Exact skeleton gradient colors and pulse timings require implementation judgment.
  • Form validation states beyond focus: Only {component.text-input-focus} (border color change) is documented. Error state (red border + error message), disabled state (opacity reduction + cursor restriction), and success state (teal border) follow from the semantic color tokens but lack explicit component entries.
  • Authenticated-only flows: Dashboard surfaces, project grids, deployment logs, and settings panels are entirely absent from the public landing page. These likely introduce new surface colors (darker canvases for IDE-like interfaces), denser spacing tokens, and additional component types (table rows, tabs, breadcrumbs).
  • Sub-brand palettes: Vercel Enterprise, Vercel AI SDK, and V0 (their AI tool) may have distinct accent color treatments or logo variations not represented in the core landing palette.
  • Pixel-exact gradient values: The hero illustration gradient uses approximate color sampling (yellow-orange, magenta, cyan-teal). The exact hex stops, radial center point coordinates, and hatching-pattern parameters would require access to the source SVG/CSS or designer assets.
  • Right-rail aside contents: The DOM reveals a 400px-wide sticky aside element with class suggesting a sales/reservation rail, but its contents are empty in the unauthenticated public view. Its internal components (calendar picker, contact form, chat widget) are unknown.
  • Dark mode token mapping: While extensions.mode: "light" is confirmed, no dark-mode color inverses (e.g., canvas → #171717, ink → #fafafa) were extractable from the single screenshot. A complete dark-theme implementation requires systematic inversion of the surface/ink pairs.
  • Internationalization / RTL layout: No bidi-awareness or RTL-specific spacing adjustments (margin flips, icon mirroring) were detectable in the LTR-only source. RTL deployment would require auditing all padding/margin directional values.