- fg
#FFFFFF- bg
#000000- APCA Lc
- -108
- Use
- background on foreground
Vercel
The platform landing that doubles as the reference implementation of its own stack — Vercel treats marketing as a living engineering brief. A Geist family trinity (sans, mono, and five decorative pixel cuts) carries the entire typographic personality. Accents come from a Radix-derived semantic palette used like confidence indicators rather than decoration. Elevation runs on a ring-plus-inset shadow grammar that makes every card feel printed. Gradients appear only as 50%-stop solid-colour dot-fill pattern backgrounds, and 96 CSS custom properties are exposed in the cascade as a public token surface.

Editorial disclaimer
This entry documents observable design-language patterns for educational transfer and AI-agent briefing. Screenshots and trademarks are property of their respective owners. AI2 Design is not affiliated with or endorsed by the featured brand. Inspiration here is about language and rhythm - do not reproduce brand identity, logo, product copy, or proprietary features.
Fair Use & Gallery PolicyCopy the full design language into your agent
A typed, paste-ready design system brief - philosophy, tokens, rules, techniques, and fitness checks. Drop it into Claude, Cursor, v0 or any coding agent and it builds in Vercel’s language, not just a screenshot.
Light-first engineering-as-aesthetic platform landing. Pure white #ffffff canvas. Near-black #171717 primary text doing the dominant reading (measured 1908 occurrences), with a six-stop grey descender ladder (#4d4d4d / #666666 / #808080 / #a8a8a8 / #ebebeb) handling secondary, tertiary and border roles. Typography carries the entire identity: Geist Variable (sans) for voice, Geist Mono for code and tabular proof, Geist Pixel in five decorative cuts (Circle / Grid / Line / Square / Triangle) for craft punctuation. Accents come from a Radix-derived semantic palette (cyan / magenta / red / teal / orange / green) applied like state indicators, never as fills. Elevation is a ring-plus-inset grammar — 1px outer hairline with a 1px inset highlight — that makes every card feel printed rather than floated. Gradients are used only as 50%-stop solid-colour dot-fill pattern backgrounds. Motion splits into three channels: 0.1-0.15s snap chroma for input feedback, cubic-bezier(0.33, 0.12, 0.15, 1) opacity reveals, and 0.2s ease transforms.
Use this capture as a design language transfer brief for my project. Adopt the palette (light-first #ffffff canvas + #171717 primary text + six-stop grey descender ladder + Radix-derived semantic accents used as state indicators), typographic system (Geist Variable as primary sans, Geist Mono for code and tabular data, Geist Pixel reserved for sparse decorative punctuation), 2px base spacing scale with peaks at 2 / 6 / 8 / 12, single 1080px content rail, ring-plus-inset shadow grammar (1px outer hairline plus 1px inset highlight), 50%-stop solid-colour gradient as flat pattern fill, 96-variable open CSS token surface, border-radius double-peak at 4 / 6 px with 64px for large feature cards and 100px pill for indicators, and three-channel motion (0.1-0.15s snap chroma for input, cubic-bezier(0.33, 0.12, 0.15, 1) for opacity reveals, 0.2s ease for transform). Treat this as my project's constitution — every new component should pass as if crafted in the same studio. Apply the language, not the source brand's copy or identity. When I ask you to build a page or component, enforce these rules by default, and call out any decision that deviates.
- Layout
- Grid
- Content width
- Bounded
- Framing
- Flat
- Grid strength
- Strong
Light-first canvas — pure #ffffff background paired with #171717 near-black primary text doing the dominant reading layer (measured 1908 occurrences). Six-stop grey descender ladder: #4d4d4d (secondary body) → #666666 (muted text) → #808080 (placeholder) → #a8a8a8 (borders) → #ebebeb (light borders / strokes) → #000000 (accent border). Accent palette is Radix-derived semantic — cyan #52aeff, magenta #bd2864, red #e5484d, teal #45dec5, orange #ffb224, green #297a3a — each colour tied to a role (state, category, emphasis) rather than used as decoration. Surface area of accent colour stays below 3% of the viewport.
- Primary reading pair: #171717 near-black text on #ffffff background (measured 1888 + 138 occurrences — dominant surface)
- Secondary descender ladder: #4d4d4d (ready-to-read) → #666666 (muted) → #808080 (placeholder / disabled) — for progressive de-emphasis
- Border grey stops: #a8a8a8 (emphasised stroke), #ebebeb (default hairline) — the ring that does the elevation work
- Semantic accent cyan #52aeff for informational state, magenta #bd2864 for editorial emphasis
- Semantic accent red #e5484d for destructive state, teal #45dec5 for fresh state, orange #ffb224 for warning, green #297a3a for success
Gradients (paste-ready)
linear-gradient(rgb(235, 235, 235), rgb(235, 235, 235) 50%, rgba(0, 0, 0, 0) 0px, rgba(0, 0, 0, 0)) linear-gradient(rgb(212, 238, 247), rgb(212, 238, 247) 50%, rgba(0, 0, 0, 0) 0px, rgba(0, 0, 0, 0)) linear-gradient(rgb(255, 232, 224), rgb(255, 232, 224) 50%, rgba(0, 0, 0, 0) 0px, rgba(0, 0, 0, 0))
- Primary family: Geist Variable (self-hosted, preloaded from /vc-ap-vercel-marketing/_next/static/media/*.woff2). The family is deployed alongside Geist Mono for code and five Geist Pixel cuts (Circle, Grid, Line, Square, Triangle) for decorative punctuation.
- Do not introduce a second foundry. The Geist trinity carries every register — voice, proof, craft. Mixing in Inter, SF Pro or any display serif breaks the identity immediately.
- Observed size ladder: 12 / 13 / 14 / 16 / 18 / 24 / 48 px. Display hero at 48/48 with letter-spacing -2.4px. Display sub at 24/32 with letter-spacing -0.96px. Body at 14-16 with line-height 20-24.
- Letter-spacing is px, not em: negative at display (-2.4px at 48, -0.96px at 24) to produce optical tightness; normal at body. Never invent intermediate tracking values.
- Geist Mono reserved for code, kbd, tabular numerics, version strings, hashes, deploy IDs. Body 13-16px with line-height 20px. Never use Mono as a display substitute.
- Geist Pixel is decorative only — reserve each of the five cuts (Circle / Grid / Line / Square / Triangle) for specific craft moments (pattern tiles, feature dividers, visual emphasis). Pasted on running text it is costume.
- Paragraph max 55-65 ch at body 14-16px — echoes the 1080px rail when wrapped in the main container.
- 2px base unit. Observed scale: 2 / 4 / 6 / 8 / 10 / 12 / 14 / 16 / 18 / 20 / 24 / 32 px, dominated by 2 (freq 361) / 12 (301) / 8 (277) / 6 (204).
- Flex gaps: 8px (freq 73), 6px (69), 12px (43), 4px (15), 16px (13). Keep gutters in multiples of 2.
- Container: single 1080px primary rail (maxWidthPx 1080, freq 6). Do not break the rail except for full-bleed feature strips or hero-scale assets.
- Card padding scale: 12 / 16 / 20 / 24 px, aligned to gutter steps.
- Section vertical rhythm: 32 / 48 / 64 px desktop; 24 / 32 / 48 px mobile.
- Default cards: shadow-xs three-layer ring + subtle drop + inset highlight — 'rgba(0,0,0,0.08) 0px 0px 0px 1px, rgba(0,0,0,0.04) 0px 2px 2px 0px, rgb(250,250,250) 0px 0px 0px 1px inset'. The inset highlight is the signature — it makes the card feel printed rather than floated.
- Emphasised cards: shadow-lg 'rgba(0,0,0,0.08) 0px 0px 0px 1px, rgb(250,250,250) 0px 0px 0px 1px' — simpler ring + inset without the drop. Use when the card should feel set into the page rather than raised.
- Dividers / inset outline: shadow-outline 'rgb(234,234,234) 0px -1px 0px 0px inset' — a single inset hairline on the bottom edge, used under header rows and section tops.
- Inner shadow for pressed / input state: 'rgba(0,0,0,0.04) 0px 1px 2px 0px' — the only inner-drop shadow in the grammar.
- Do not substitute a large blur drop-shadow for any of these — the identity breaks the instant cards start to float.
Techniques
Ring + inset highlight card
Every primary card uses a 1px outer ring (rgba(0,0,0,0.08)) plus a 1px inset highlight (rgb(250,250,250)) to feel printed. The combination produces a card that reads as set into the surface while still being visually separated.
Inset bottom divider
Section dividers use 'rgb(234,234,234) 0px -1px 0px 0px inset' — a single inset hairline rather than a border, so the divider aligns to pixel grid without adding layout height.
- Double-peak base: 4px (freq 41) and 6px (freq 45) cover most surfaces. Buttons and inline inputs use 6, chips and badges use 4.
- Large cards / feature blocks use 12px; extra-large feature cards and pattern tiles use 64px (freq 6) — the distinctive 3xl.
- Full pill (100px radius, freq 11) reserved for indicator badges, hover dots, and tag-sized controls.
- Do not use radii between 12 and 64 — the gap is intentional. Anything in-between reads as indecisive.
- Border widths: 1px default; 2px only for focus emphasis or active-state outlines.
ring-inset-card- backgroundColor
- #ffffff
- textColor
- #171717
- radius
- 12px
- padding
- 20px
- border
- none
- boxShadow
- rgba(0, 0, 0, 0.08) 0px 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 2px 2px 0px, rgb(250, 250, 250) 0px 0px 0px 1px inset
- fontFamily
- Geist Variable, ui-sans-serif
Tailwind
rounded-xl bg-white p-5 text-[#171717] shadow-[rgba(0,0,0,0.08)_0px_0px_0px_1px,rgba(0,0,0,0.04)_0px_2px_2px_0px,rgb(250,250,250)_0px_0px_0px_1px_inset]
dot-fill-feature-tile- backgroundColor
- #ffffff
- backgroundImage
- linear-gradient(rgb(212, 238, 247), rgb(212, 238, 247) 50%, rgba(0, 0, 0, 0) 0px, rgba(0, 0, 0, 0))
- radius
- 64px
- padding
- 32px
- textColor
- #171717
- border
- 1px solid #ebebeb
Tailwind
rounded-[64px] border border-[#ebebeb] p-8 text-[#171717] bg-[linear-gradient(rgb(212,238,247),rgb(212,238,247)_50%,rgba(0,0,0,0)_0px,rgba(0,0,0,0))]
snap-chroma-button- backgroundColor
- #171717
- textColor
- #ffffff
- radius
- 6px
- padding
- 8px 14px
- border
- none
- boxShadow
- rgba(0, 0, 0, 0.04) 0px 2px 2px 0px
- fontFamily
- Geist Variable
- fontSize
- 14px
- fontWeight
- 500
- transition
- color 0.1s ease, background 0.15s ease-in-out
Tailwind
inline-flex min-h-[36px] items-center gap-1.5 rounded-md bg-[#171717] px-3.5 py-2 text-[14px] font-medium text-white shadow-[rgba(0,0,0,0.04)_0px_2px_2px_0px] transition-[color,background] duration-100 ease-in-out hover:bg-[#4d4d4d]
pill-state-indicator- backgroundColor
- #52aeff
- textColor
- #ffffff
- radius
- 100px
- padding
- 2px 8px
- border
- none
- fontFamily
- Geist Mono
- fontSize
- 12px
- fontWeight
- 500
Tailwind
inline-flex items-center rounded-full bg-[#52aeff] px-2 py-0.5 font-mono text-[12px] font-medium text-white
link-inline- color
- #0070f3
- textDecoration
- none
- textUnderlineOffset
- 3px
- textDecorationThickness
- 1px
- transition
- color 100ms ease, text-decoration-color 100ms ease
Tailwind
text-[#0070f3] no-underline underline-offset-[3px] transition-colors duration-100 ease-[cubic-bezier(0.33,0.12,0.15,1)] hover:underline hover:decoration-[#0070f3] focus-visible:outline-none focus-visible:underline focus-visible:decoration-[#0070f3]
Easings
easeease-in-outcubic-bezier(0.33, 0.12, 0.15, 1)cubic-bezier(0.4, 0, 0.2, 1)cubic-bezier(0.39, 0.18, 0.17, 0.99)Scroll patterns
- Opacity fade with cubic-bezier(0.33, 0.12, 0.15, 1) over 0.4s for below-the-fold sections
- No parallax. Transform limited to 0.2s ease reveals.
- Three-channel motion rule: chroma is snap (0.1-0.15s ease), transform is swift (0.2s ease), opacity is theatrical (0.4s cubic-bezier(0.33, 0.12, 0.15, 1)).
- Easing palette captured: ease + ease-in-out CSS keywords plus three custom cubic-bezier curves — cubic-bezier(0.33, 0.12, 0.15, 1) for opacity reveals, cubic-bezier(0.4, 0, 0.2, 1) and cubic-bezier(0.39, 0.18, 0.17, 0.99) for supporting state transitions. Do not substitute spring or bounce easings.
- Hover feedback MUST land under 150ms — that is the tempo signature.
- Opacity reveals use the custom cubic-bezier only. Swapping to ease-in-out flattens the identity.
- Respect prefers-reduced-motion — disable cubic-bezier reveals and collapse chroma transitions to 0ms.
- Hover states escalate through the grey ladder — #171717 → #4d4d4d on text, border thickens from #ebebeb to #a8a8a8 on cards. Elevation stays constant; only chroma shifts.
- Active / pressed state uses the inner drop-shadow 'rgba(0,0,0,0.04) 0px 1px 2px 0px' instead of a translate.
- Focus rings use a 2px solid ring in the semantic accent cyan #52aeff for form fields, #171717 for primary controls.
- Status badges use the pill + Geist Mono combination with semantic colour — red for error, green for healthy, orange for warning, cyan for informational.
- Tooltips open under 150ms with chroma-only animation — never translate, never fade in.
Desktop-first because the audience is developers on wide displays. The 1080px rail is the primary anchor at every size — mobile reflows into a single narrow column without re-architecting the layout. Thirty measured media queries confirm per-breakpoint adjustments rather than fluid guessing.
- Breakpoints: sm 640 / md 768 / lg 1024 / xl 1280 / 2xl 1536 — standard Tailwind ladder.
- The 1080px rail holds from lg upwards. Below lg, content reflows to a single 16-24px gutter column.
- Typography scales proportionally — 48/48 hero drops to 32/36, 24/32 sub drops to 20/28. Letter-spacing compensates (less negative at smaller sizes).
- Tap targets minimum 40×40 on pointer; 44×44 on touch.
- Hide-on-mobile is banned — controls reflow, they do not disappear.
- Primary reading pair #171717 on #ffffff = 16:1 (AAA). Secondary #4d4d4d on white = 8.7:1 (AAA). Muted #666666 = 5.7:1 (AA).
- Semantic accents must pair with text at AA minimum — cyan #52aeff on #ffffff fails for normal text; use as background-plus-icon only, or thicken text to 18px bold.
- Focus rings mandatory: 2px solid #52aeff for form fields, 2px solid #171717 for primary controls, offset 2px.
- Do not rely on colour alone for state — pair every Radix semantic colour with an icon or label.
- prefers-reduced-motion must disable cubic-bezier opacity reveals and collapse chroma transitions to 0ms.
- Geist Pixel must not be used for critical reading content — it is decorative.
- Tap targets minimum 44×44 on touch, 40×40 on pointer.
Self-hosted variable woff2 font delivery — 8 files preloaded (Geist, Geist Mono, Geist Pixel Circle / Grid / Line / Square / Triangle) from Vercel's /_next/static/media/ pipeline with 38 @font-face declarations in the CSSOM. Palette mapped to Radix Colors semantic scale (the 10 / 11 / 12 numbering on accent colour names matches Radix step conventions). 96 CSS custom properties exposed in the cascade — the token surface is deliberately public.
- Preload each Geist woff2 with <link rel='preload' as='font' type='font/woff2' crossorigin>
- Adopt Radix Colors or a compatible semantic palette for accents; do not invent arbitrary colours
- Expose design tokens as CSS custom properties — let the cascade be legible
- No runtime motion library required — all motion rides on CSS transitions. If a spring is desired, port to Framer Motion with an explicit cubic-bezier equivalent
- Icons stroke-based at 1.5-2px weight; Geist Pixel is reserved for decorative punctuation only
- Use Geist Variable + Geist Mono as the entire typographic backbone.
- Hold a pure-white canvas and let grey descender do the reading work.
- Apply accent colour as confidence — state, category, emphasis — never as surface paint.
- Use ring + inset shadow for every card that needs to feel set into the page.
- Reach for 50%-stop solid-colour gradients when feature tiles need pattern ink.
- Keep hover chroma under 150ms for snap feedback.
- Expose your token surface publicly — CSS custom properties in the cascade are a brand signal.
- Do not import a second type foundry. Geist trinity only.
- Do not use Geist Pixel on running text — it is craft punctuation, not a display font.
- Do not substitute large-blur drop shadows for the ring-plus-inset grammar.
- Do not fill card surfaces with accent colour — below 3% of viewport is the rule.
- Do not break the 1080px content rail for regular text sections.
- Do not invent motion durations outside 0.09 / 0.1 / 0.15 / 0.2 / 0.4 seconds.
- Do not use spring or bounce easings — ease, ease-in-out, and the single cubic-bezier(0.33, 0.12, 0.15, 1) only.
- Typography must render with variable-weight Geist — static weight substitutes break the family trinity.
- All shadows must honour the observed rgba stacks exactly; fabricated opacities collapse the elevation grammar.
- Accents must pass AA contrast against the surface they sit on; demote to grey if they do not.
- Breakpoints stay within Tailwind-standard 640 / 768 / 1024 / 1280 / 1536; respect 30-entry media-query discipline per component.
- Motion durations are quantised — only the five values listed are valid.
- Does every card use shadow-xs (ring + drop + inset) or shadow-lg (ring + inset) — and never a raw drop shadow?
- Is accent colour usage below 3% of viewport, with every accent tied to a semantic role?
- Do feature tiles use 50%-stop solid-colour gradients (linear-gradient(rgb X, rgb X 50%, transparent)) rather than diffuse gradients?
- Is every hover chroma transition 0.1-0.15s ease, and every opacity reveal 0.4s cubic-bezier(0.33, 0.12, 0.15, 1)?
- Does typography use Geist Variable by default, Geist Mono for code, and Geist Pixel only as decorative punctuation?
- Does the page expose CSS custom properties in the cascade (at least 40+ visible), and do rounded corners follow the 4/6/12/64/100 radius grammar?
Design tokens
Observed token system
Color, type, spacing, gradients, and stacking order captured from the live page and rendered here as living, paste-ready previews.
Inspector
Observable layers
Structure, breakpoints, motion, fonts, and images captured from the live page and kept paste-ready alongside the tokens.
Depth-first walk of the meaningful sections. 10 nodes across 5 levels, shallow to deep by color.
- body2
- a
- div (×4)2
- div3
- div1
- Header
- Main
- Footer1
- Nav
- Aside
Accessibility
Contrast matrix
276 combinations - 78 pass AA - 34 pass AAA. Each pair is previewed with its real foreground on background; APCA Lc sits alongside the WCAG 2.1 ratio for draft WCAG 3 awareness.
- fg
#000000- bg
#FFFFFF- APCA Lc
- +106
- Use
- foreground on background
- fg
#171717- bg
#FFFFFF- APCA Lc
- +105
- Use
- foreground on background
- fg
#FFFFFF- bg
#171717- APCA Lc
- -107
- Use
- background on foreground
- fg
#000000- bg
#EBEBEB- APCA Lc
- +94
- Use
- foreground on background
- fg
#EBEBEB- bg
#000000- APCA Lc
- -95
- Use
- background on foreground
- fg
#000000- bg
#CCE6FF- APCA Lc
- +89
- Use
- foreground on accent
- fg
#CCE6FF- bg
#000000- APCA Lc
- -90
- Use
- accent on foreground
- fg
#171717- bg
#EBEBEB- APCA Lc
- +93
- Use
- foreground on background
Images
Image strategy
Observable image posture - total count, lazy-loading ratio, and format mix. The hero image is measured above the fold.
- svg49 · 100%
Hero image
https://vercel.com/vc-ap-vercel-marketing/_next/static/media/leonardo-ai-light.33rurcgq77tyi.svg?dpl=dpl_53dNajPAEgXXNCKBoLEtJvLR1AUh- Format
- SVG
- Dimensions
- 355x38
- Loading
- eager
- srcset
- no
- Industry
- developer-tools
- Industry
- saas
- Industry
- ai
- Theme
- Light + Dark
- Added
- 2026-04-23
FAQ
Questions people ask about Vercel
3questionsAnswers are pulled from the curator verdict and design brief - the same text your AI agent sees when it paste-reads this page.
Compare this with



