---
version: alpha
name: Uniswap
description: A bright white DeFi canvas where Basel grotesque headlines sit dead-center over a field of soft pastel token orbs, and a single electric hot-magenta pixel carries every primary action — protocol-grade finance that reads as friendly and weightless rather than intimidating.

colors:
  # Surface / canvas
  background: "#ffffff"
  surface: "#fafafa"           # the swap card body, muted panel fills
  surface-pink: "#ffeefb"      # the soft pink "Get started" footer chip

  # Ink / text
  ink: "#131313"               # near-black headings and primary body
  ink-soft: "#222222"          # secondary body, dark UI labels
  ink-muted: "#7d7d7d"         # captions, input placeholders, helper rows
  on-dark: "#ffffff"           # text on the magenta CTA and dark chips

  # Brand accent — the singular Uniswap hot magenta
  primary: "#ff37c7"           # primary CTA, the "Select token" pill, Connect button
  primary-hover: "#f50db4"     # pressed / hover magenta
  primary-soft: "#fad8f8"      # decorative pink tints, soft accent fills
  on-primary: "#ffffff"

  # Pastel ecosystem orbs (the floating background token field)
  orb-violet: "#8251fb"        # Privy/wallet violet, decorative orb
  orb-teal: "#00c3a0"          # mint token orb
  orb-sky: "#2abdff"           # sky-blue token orb
  orb-orange: "#ff4d00"        # warm orange token orb

  # Semantic
  success: "#0c8911"           # positive price / confirmation green
  error: "#e10f0f"             # negative price / error red

  # Borders
  border: "#ededed"            # hairline dividers, card edges
  border-strong: "#dcdcdc"     # input outlines, stronger separators

  # Shadow tint (opaque approximation for the elevation table)
  shadow-soft: "#131313"       # was rgba(19,19,19,0.04) — Google format requires hex

typography:
  display-hero:
    fontFamily: "Basel, -apple-system, system-ui, Segoe UI, Roboto, Helvetica, Arial, sans-serif"
    fontSize: 64px
    fontWeight: 485
    lineHeight: 1.19
    letterSpacing: -1.28px
  display:
    fontFamily: "Basel, -apple-system, system-ui, Segoe UI, Roboto, Helvetica, Arial, sans-serif"
    fontSize: 52px
    fontWeight: 485
    lineHeight: 1.15
    letterSpacing: -1.04px
  heading:
    fontFamily: "Basel, -apple-system, system-ui, Segoe UI, Roboto, Helvetica, Arial, sans-serif"
    fontSize: 36px
    fontWeight: 485
    lineHeight: 1.2
    letterSpacing: -0.36px
  heading-sub:
    fontFamily: "Basel, -apple-system, system-ui, Segoe UI, Roboto, Helvetica, Arial, sans-serif"
    fontSize: 24px
    fontWeight: 535
    lineHeight: 1.2
    letterSpacing: -0.24px
  body-large:
    fontFamily: "Basel, -apple-system, system-ui, Segoe UI, Roboto, Helvetica, Arial, sans-serif"
    fontSize: 18px
    fontWeight: 485
    lineHeight: 1.33
    letterSpacing: 0px
  body:
    fontFamily: "Basel, -apple-system, system-ui, Segoe UI, Roboto, Helvetica, Arial, sans-serif"
    fontSize: 16px
    fontWeight: 485
    lineHeight: 1.5
    letterSpacing: 0px
  body-strong:
    fontFamily: "Basel, -apple-system, system-ui, Segoe UI, Roboto, Helvetica, Arial, sans-serif"
    fontSize: 16px
    fontWeight: 535
    lineHeight: 1.3
    letterSpacing: 0px
  link:
    fontFamily: "Basel, -apple-system, system-ui, Segoe UI, Roboto, Helvetica, Arial, sans-serif"
    fontSize: 16px
    fontWeight: 500
    lineHeight: 1.3
    letterSpacing: 0px
  caption:
    fontFamily: "Basel, -apple-system, system-ui, Segoe UI, Roboto, Helvetica, Arial, sans-serif"
    fontSize: 14px
    fontWeight: 485
    lineHeight: 1.3
    letterSpacing: 0px
  caption-strong:
    fontFamily: "Basel, -apple-system, system-ui, Segoe UI, Roboto, Helvetica, Arial, sans-serif"
    fontSize: 12px
    fontWeight: 535
    lineHeight: 1.33
    letterSpacing: 0px

spacing:
  xs: 4px
  sm: 8px
  md: 12px
  lg: 16px
  xl: 18px
  2xl: 24px
  3xl: 32px
  4xl: 48px
  5xl: 72px

rounded:
  sm: 8px
  md: 12px
  lg: 16px
  xl: 20px
  2xl: 32px
  pill: 9999px

components:
  button-primary:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
    typography: "{typography.body-strong}"
    rounded: "{rounded.pill}"
    padding: 12px 20px
  button-primary-hover:
    backgroundColor: "{colors.primary-hover}"
    textColor: "{colors.on-primary}"

  button-secondary:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.ink}"
    typography: "{typography.body-strong}"
    rounded: "{rounded.pill}"
    padding: 12px 20px
  button-secondary-hover:
    backgroundColor: "{colors.border}"
    textColor: "{colors.ink}"

  button-soft:
    backgroundColor: "{colors.surface-pink}"
    textColor: "{colors.primary-hover}"
    typography: "{typography.body-strong}"
    rounded: "{rounded.lg}"
    padding: 12px 20px

  token-pill:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
    typography: "{typography.body-strong}"
    rounded: "{rounded.pill}"
    padding: 8px 12px

  card:
    backgroundColor: "{colors.background}"
    textColor: "{colors.ink}"
    rounded: "{rounded.2xl}"
    padding: 24px
  card-swap:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.ink}"
    rounded: "{rounded.xl}"
    padding: 16px

  input:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.ink}"
    typography: "{typography.body}"
    rounded: "{rounded.lg}"
    padding: 12px 16px
  input-focus:
    backgroundColor: "{colors.background}"
    textColor: "{colors.ink}"

  search:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.ink-muted}"
    typography: "{typography.body}"
    rounded: "{rounded.pill}"
    padding: 8px 16px

  nav-bar:
    backgroundColor: "{colors.background}"
    textColor: "{colors.ink}"
    typography: "{typography.link}"
    padding: 16px 24px

  nav-link:
    textColor: "{colors.ink}"
    typography: "{typography.link}"
    padding: 8px 12px

  badge:
    backgroundColor: "{colors.primary-soft}"
    textColor: "{colors.primary-hover}"
    typography: "{typography.caption-strong}"
    rounded: "{rounded.pill}"
    padding: 4px 10px

  badge-success:
    backgroundColor: "{colors.surface}"
    textColor: "{colors.success}"
    typography: "{typography.caption-strong}"
    rounded: "{rounded.pill}"
    padding: 4px 10px
---

# Uniswap Design System

## Overview

Uniswap's site takes the most intimidating product category on the internet — a decentralized crypto exchange — and renders it as something that looks like it could be a friendly consumer app. The canvas is pure, bright white (`{colors.background}`), and the entire hero is built around a single dead-center declaration: "Swap anytime, anywhere." set in **Basel**, the brand's custom grotesque, at `{typography.display-hero}` in near-black (`{colors.ink}`). There is no gradient wash, no chart-heavy dashboard screenshot, no jargon. The page wants to feel weightless, and it largely succeeds — the swap card floats in the middle of the screen like an object you could pick up.

The signature move is the field of **soft pastel token orbs** scattered across the background — blurred circular gradients in violet (`{colors.orb-violet}`), mint (`{colors.orb-teal}`), sky (`{colors.orb-sky}`), and warm orange (`{colors.orb-orange}`). They evoke the hundreds of tokens tradable on the protocol without naming a single one, and because they are heavily blurred and low-contrast, they add color and motion without ever competing with the centered content. It is the rare crypto site that uses color to feel *playful* rather than to scream "volatility." The orbs are decoration, never chrome.

Then there's the discipline around the one true accent. Uniswap's hot magenta (`{colors.primary}`) is electric, almost neon, and it is rationed with real intent. It fills the "Connect" button in the top-right, the "Select token" pill inside the swap card, and the primary CTA — and almost nothing else. Everything interactive that matters wears magenta; everything else stays black-and-white. Buttons and the wallet pill are fully pill-shaped (`{rounded.pill}`), reinforcing the soft, rounded, approachable tone, while the swap card itself uses a generous 32px radius (`{rounded.2xl}`). The result is finance that reads as a clean, modern web app — confident enough to put one swap card on a white page and trust it to carry the whole message.

**Key Characteristics:**
- Pure white canvas (`{colors.background}`) — bright, light-first, zero dark mode on the marketing site
- **Basel** custom grotesque for everything, at the unusual variable weight 485 (`{typography.display-hero}`) — a hair lighter than a true 500
- Dead-center hero composition: one headline, one floating swap card, nothing else competing
- A field of **blurred pastel token orbs** (`{colors.orb-violet}`, `{colors.orb-teal}`, `{colors.orb-sky}`, `{colors.orb-orange}`) as ambient background decoration
- Single electric hot-magenta accent (`{colors.primary}`) rationed to the CTA, the token pill, and the Connect button
- Fully pill-shaped buttons and the wallet pill (`{rounded.pill}`) — soft and approachable, never sharp
- Large 32px radius on the swap card (`{rounded.2xl}`) — the product object reads as rounded and liftable
- Soft pink footer chip (`{colors.surface-pink}`) for the "Get started" prompt — accent without full saturation
- Restrained shadows: the swap card sits on a barely-there soft cast, the page is otherwise flat
- Tight negative tracking on display type (-1.28px at 64px) for a dense, confident headline
- Semantic green (`{colors.success}`) and red (`{colors.error}`) reserved strictly for price movement
- Hairline borders (`{colors.border}`) handle structural separation on the page chrome

## Colors

### Surface & Canvas
- **White** (`{colors.background}`): The dominant canvas. Nearly the entire site sits on pure white.
- **Off-White** (`{colors.surface}`): The swap card body and muted input fills — a barely-there shift from white.
- **Soft Pink** (`{colors.surface-pink}`): The gentle pink chip behind the "Get started" footer prompt — magenta diluted to a tint.

### Ink / Text
- **Near-Black** (`{colors.ink}`): Headings and primary body. The dominant text color.
- **Soft Black** (`{colors.ink-soft}`): Secondary body and darker UI labels.
- **Muted Gray** (`{colors.ink-muted}`): Captions, input placeholders, and low-emphasis helper rows.
- **White on Dark** (`{colors.on-dark}`): Text on the magenta CTA and any dark chips.

### Brand Accent
- **Hot Magenta** (`{colors.primary}`): The singular brand color — the Connect button, the "Select token" pill, and the primary CTA. Rationed to preserve its charge.
- **Magenta Pressed** (`{colors.primary-hover}`): Hover and pressed state for magenta surfaces; also used as text on soft-pink fills.
- **Soft Magenta** (`{colors.primary-soft}`): Light pink tint for decorative accents and badge fills.

### Ecosystem Orbs
- **Violet / Mint / Sky / Orange** (`{colors.orb-violet}`, `{colors.orb-teal}`, `{colors.orb-sky}`, `{colors.orb-orange}`): The blurred pastel token orbs floating in the background. Decorative only — never used for text or interactive chrome.

### Semantic
- **Green / Red** (`{colors.success}`, `{colors.error}`): Reserved exclusively for positive and negative price movement and confirmation/error states.

### Borders & Shadow Tint
- **Hairline** (`{colors.border}`): Card edges and dividers.
- **Strong Border** (`{colors.border-strong}`): Input outlines and stronger separators.
- **Shadow Soft** (`{colors.shadow-soft}`): Opaque stand-in for the card's soft drop shadow (the original was rgba — flattened for the Google spec).

## Typography

### Font Family
- **Primary**: `Basel`, Uniswap's custom grotesque, with fallbacks `-apple-system, system-ui, Segoe UI, Roboto, Helvetica, Arial`. It carries every line on the site — display, body, labels, and buttons alike.
- **Weight strategy**: Basel ships as a variable font and the site leans on two slightly non-standard weights — **485** for most display and body text and **535** for emphasis. Both sit just shy of the conventional 500/600, giving the whole page a soft, even, near-uniform weight.
- **Tracking**: large display sizes use negative tracking (-1.28px at 64px); body and small text sit near zero.

### Hierarchy

The full type scale lives in the `typography:` token block. Reference tokens directly.

| Token | Use |
|---|---|
| `display-hero` | 64px / 485 / -1.28px — the marquee "Swap anytime, anywhere." headline |
| `display` | 52px / 485 / -1.04px — large section titles |
| `heading` | 36px / 485 — section headings |
| `heading-sub` | 24px / 535 — sub-section headings and emphasized rows |
| `body-large` | 18px / 485 — lead paragraphs |
| `body` | 16px / 485 — standard body and inputs |
| `body-strong` | 16px / 535 — button labels and emphasized body |
| `link` | 16px / 500 — nav links |
| `caption` | 14px / 485 — metadata, helper text |
| `caption-strong` | 12px / 535 — badge labels, dense pills |

### Principles
- **One typeface, everywhere**: Basel does all the work. There is no secondary serif or mono — the uniformity is the point.
- **Weight 485 as the default**: the site's calling card is that near-medium weight that reads softer than 500 but heavier than 400.
- **Tighten the big, relax the small**: heavy negative tracking on display; near-zero on body.

## Layout

### Spacing System
The full scale is in the `spacing:` token block. Base unit: 8px, with a 4px sub-step for tight component internals and an 18px step the brand favors for card padding. The page reads airy — the hero is mostly whitespace with one card in the middle.

### Grid & Container
- Max content width: ~1200px, centered, but the hero deliberately uses far less — a single centered column
- Signature pattern: a centered headline above a centered, floating swap card, with everything else (the orb field) pushed to the background
- Below the fold, content moves into standard centered marketing rows

### Whitespace Philosophy
- **Center and float**: the composition is built around a single object in the middle of an open white field
- **Decoration lives behind, never beside**: the orbs occupy the margins and background, leaving the center clean
- **The swap card is the hero**: it gets the most visual weight (fill contrast + soft shadow) on the page

## Elevation & Depth

| Level | Treatment | Use |
|---|---|---|
| Flat (Level 0) | No shadow, hairline `{colors.border}` only | Page chrome, nav, most content |
| Subtle (Level 1) | `0 2px 5px -2px` at ~3% ink | Resting buttons, small chips |
| Card (Level 2) | `0 6px 12px -3px` + `0 2px 5px -2px` (`{colors.shadow-soft}`) | The floating swap card — the signature elevation |
| Focus Ring | `0 0 0 3.6px` at ~24% accent or success | Focused inputs and active swap fields |

**Shadow Philosophy**: Uniswap's shadows are soft, diffuse, and reserved. The page is almost entirely flat — separation comes from fill changes and hairline borders. The one place real elevation is spent is the swap card, where a gentle two-layer drop shadow lets it read as a physical object floating over the pastel orb field. Nothing else on the page competes for that lifted quality.

## Shapes

The full radius scale is in the `rounded:` token block.

| Token | Value | Use |
|---|---|---|
| `sm` | 8px | Small chips, token icons |
| `md` | 12px | Buttons-as-rectangles, mid containers |
| `lg` | 16px | Inputs, the soft "Get started" chip |
| `xl` | 20px | Sub-cards, the inner swap rows |
| `2xl` | 32px | The swap card — the signature large radius |
| `pill` | 9999px | The Connect button, the token pill, primary CTAs, search |

The system is soft and rounded throughout. Interactive elements that carry the brand — the Connect button, the token pill, the primary CTA — are fully pill-shaped, while the swap card uses a generous 32px corner. There are effectively no sharp corners anywhere.

## Components

The complete component spec lives in the `components:` token block.

### Buttons
- **`button-primary`** — Hot magenta (`{colors.primary}`) fill, white text, fully pill-shaped. The main CTA and the Connect button. Hover deepens to `{colors.primary-hover}`.
- **`button-secondary`** — Off-white (`{colors.surface}`) fill, near-black text, pill-shaped. The neutral action. Hover fills `{colors.border}`.
- **`button-soft`** — Soft pink (`{colors.surface-pink}`) fill, magenta text. The gentle "Get started" prompt — accent at low saturation.
- **`token-pill`** — The "Select token" pill inside the swap card: magenta fill, white text, pill radius, compact padding.

### Cards
- **`card`** — White surface, 32px radius (`{rounded.2xl}`), soft shadow. The signature swap container.
- **`card-swap`** — The inner Sell/Buy rows: off-white fill, 20px radius, tighter padding.

### Inputs
- **`input`** — Off-white fill, `{colors.border-strong}` outline, 16px radius. **`input-focus`** swaps to a white fill with a soft accent focus ring.
- **`search`** — The top-bar token search: off-white pill, muted placeholder, pill radius.

### Navigation
- **`nav-bar`** — White, hairline bottom border, Basel links. **`nav-link`** sits at weight 500 with comfortable padding.

### Badges
- **`badge`** — Soft-magenta fill, magenta text, pill radius. **`badge-success`** uses green text on off-white for positive states.

## Do's and Don'ts

### Do
- Keep the canvas pure white (`{colors.background}`) and the hero composition dead-center
- Use the **pastel orb field** (`{colors.orb-violet}`, `{colors.orb-teal}`, `{colors.orb-sky}`, `{colors.orb-orange}`) as blurred, low-contrast background decoration only
- Ration hot magenta (`{colors.primary}`) to the Connect button, the token pill, and the primary CTA
- Set everything in **Basel** at weight 485, stepping up to 535 for emphasis
- Make the primary CTA, Connect button, and token pill fully pill-shaped (`{rounded.pill}`)
- Give the swap card a generous 32px radius (`{rounded.2xl}`) and a soft, single floating shadow
- Reserve green (`{colors.success}`) and red (`{colors.error}`) strictly for price movement
- Keep the page flat — fill changes and hairlines do the structural work, not shadows

### Don't
- Don't darken the marketing canvas — Uniswap's site is committedly bright white
- Don't bring the orbs to the foreground or use their colors for text or buttons — they are background decoration
- Don't over-deploy magenta; if it's filling more than the CTA, the pill, and Connect, you've diluted it
- Don't introduce a second typeface — Basel carries everything, including labels and buttons
- Don't use sharp or small radii on primary interactive elements — they are pills, and the swap card is 32px
- Don't reach for heavy bold weights — the brand's softness comes from the 485/535 pairing
- Don't scatter shadows across the page — elevation is reserved for the one swap card

---

## Responsive Behavior

### Breakpoints
*(The site exposes a dense set of stops; the table below groups them into the standard tiers the layout behaves to.)*

| Name | Width | Key Changes |
|---|---|---|
| Mobile | <640px | Single column; hero text scales 64px → ~36px; nav collapses to a menu; the swap card goes near full-width; the "Get the app" / Connect buttons compress |
| Tablet | 640–1023px | Hero stays centered; orb field thins out; section rows begin to use two columns |
| Desktop | 1024–1279px | Full layout; centered hero with the floating swap card and the full orb field |
| Large | ≥1280px | Max ~1200px container, centered; generous vertical padding |

### Touch Targets
- Pill buttons and the token pill run comfortably tall (~40px) for thumbs
- The token search and swap inputs use generous vertical padding

### Collapsing Strategy
- **Navigation**: full horizontal nav (Trade, Explore, Pool, Portfolio) → menu toggle on mobile; the magenta Connect button persists
- **Hero**: the centered swap card stays centered and goes near full-width
- **Type**: display drops from 64px toward ~36px while keeping proportional negative tracking
- **Orbs**: the background orb field reduces in count and blur on smaller screens

### Image Behavior
- The "images" are decorative pastel orbs and token glyphs that reflow / thin out as background elements rather than fixed art

---

## Agent Prompt Guide

### Quick Color Reference
- Background: White (`{colors.background}`)
- Text: Near-Black (`{colors.ink}`)
- Brand accent: Hot Magenta (`{colors.primary}`)
- Secondary text: Muted Gray (`{colors.ink-muted}`)
- Border: Hairline (`{colors.border}`)
- Primary CTA: Hot Magenta (`{colors.primary}`), fully pill-shaped

### Example Component Prompts

- "Create a centered hero on white (`{colors.background}`) with a 64px near-black (`{colors.ink}`) headline in Basel at weight 485, letter-spacing -1.28px, and behind it a field of large blurred pastel orbs in `{colors.orb-violet}`, `{colors.orb-teal}`, `{colors.orb-sky}` and `{colors.orb-orange}` at low opacity"
- "Build the swap card: white (`{colors.background}`) surface, `{rounded.2xl}` (32px) radius, soft single drop shadow (`{colors.shadow-soft}`), containing two off-white inner rows (`{colors.surface}`, `{rounded.xl}`) labeled Sell and Buy, with a magenta (`{colors.primary}`) pill-shaped 'Select token' button"
- "Create the primary button: hot magenta (`{colors.primary}`) fill, white text, Basel weight 535, fully pill-shaped (`{rounded.pill}`), 12px 20px padding, hover deepens to `{colors.primary-hover}`"
- "Build a soft prompt chip: soft-pink (`{colors.surface-pink}`) fill, magenta (`{colors.primary-hover}`) text, `{rounded.lg}` radius — the 'Get started' footer pattern"
- "Design the top nav: white (`{colors.background}`) bar with Basel links at weight 500, a pill-shaped off-white (`{colors.surface}`) token search in the center, and a magenta (`{colors.primary}`) pill 'Connect' button on the right"
- "Render a price badge: off-white (`{colors.surface}`) fill, green (`{colors.success}`) text for a positive change, pill radius, Basel weight 535 at 12px"

### Iteration Guide

1. Start on pure white (`{colors.background}`) with a centered composition. If you reached for a dark or tinted background, stop — Uniswap is bright white.
2. Add the pastel orb field behind the content, heavily blurred and low-contrast. Orbs never come forward.
3. Magenta (`{colors.primary}`) is rationed: Connect button, token pill, primary CTA only. If it's anywhere else, pull it back.
4. Set everything in Basel at weight 485, stepping to 535 for emphasis. No second typeface.
5. Make primary interactive elements fully pill-shaped (`{rounded.pill}`); give the swap card a 32px corner (`{rounded.2xl}`).
6. Keep the page flat — separate with fills and hairlines. Spend the one real shadow on the swap card.
7. Reserve green (`{colors.success}`) and red (`{colors.error}`) strictly for price movement, never for general accent.

---

## Attribution

Independent design analysis from [Design Swatches](https://designmd.santiagoalonso.com) by [Santiago Alonso](https://santiagoalonso.com). Based on publicly observable interface patterns. Not affiliated with or endorsed by Uniswap. Brand names and trademarks belong to their respective owners.
