---
version: alpha
name: Dub
description: "Hairline-ruled white paper, lit by three candy-bright product marks"
colors:
  on-surface-variant: "#737373"
  on-surface: "#0A0A0A"
  surface: "#FFFFFF"
  outline: "#D4D4D4"
  primary: "#FB923C"
  recessed: "#FAFAFA"
  tint: "#F5F5F5"
  hairline: "#E5E5E5"
  faint: "#A3A3A3"
  body: "#525252"
  body-strong: "#262626"
  heading-ink: "#171717"
  action-black: "#000000"
  partners-purple: "#C084FC"
  analytics-green: "#4ADE80"
  spectrum-glow: "#3A8BFD"
typography:
  display:
    fontFamily: Satoshi
    fontSize: 48px
    fontWeight: 500
    lineHeight: 48px
    letterSpacing: 0em
  heading-l:
    fontFamily: Inter
    fontSize: 40px
    fontWeight: 400
    lineHeight: 40px
    letterSpacing: 0em
  heading-m:
    fontFamily: Inter
    fontSize: 36px
    fontWeight: 400
    lineHeight: 40px
    letterSpacing: 0em
  heading-s:
    fontFamily: Inter
    fontSize: 30px
    fontWeight: 400
    lineHeight: 36px
    letterSpacing: -0.6px
  pull-quote:
    fontFamily: Inter
    fontSize: 30px
    fontWeight: 400
    lineHeight: 41.25px
    letterSpacing: 0em
  quote:
    fontFamily: Inter
    fontSize: 24px
    fontWeight: 400
    lineHeight: 32px
    letterSpacing: 0em
  lead:
    fontFamily: Inter
    fontSize: 18px
    fontWeight: 400
    lineHeight: 28px
    letterSpacing: 0em
  body:
    fontFamily: Inter
    fontSize: 16px
    fontWeight: 400
    lineHeight: 24px
    letterSpacing: 0em
  default:
    fontFamily: Inter
    fontSize: 14px
    fontWeight: 400
    lineHeight: 20px
    letterSpacing: 0em
  label:
    fontFamily: Inter
    fontSize: 12px
    fontWeight: 400
    lineHeight: 16px
    letterSpacing: 0em
  micro:
    fontFamily: Inter
    fontSize: 10px
    fontWeight: 400
    lineHeight: 15px
    letterSpacing: 0em
  nano:
    fontFamily: Inter
    fontSize: 8px
    fontWeight: 400
    lineHeight: 8px
    letterSpacing: 0em
rounded:
  progress-bar-micro-swatch: 2px
  product-chip: 4px
  inline-metric-row-small-badge: 6px
  buttons-nav-items-most-surfaces: 8px
  trial-pill-bordered-thumbnail: 10px
  nested-icon-plate: 11px
  cards-story-tiles-demo-frame: 12px
  feature-frame: 16px
  device-top-edge: 16px
  avatars-pips-toggles: 9999px
spacing:
  2xs: 2px
  xs: 4px
  sm: 6px
  md: 8px
  lg: 10px
  xl: 12px
  2xl: 14px
  3xl: 16px
  4xl: 24px
  5xl: 32px
  section-sm: 48px
  section: 56px
  section-md: 64px
  section-lg: 80px
  section-xl: 96px
---
# Dub — Style Reference

> Hairline-ruled white paper, lit by three candy-bright product marks

**Theme:** light

White paper ruled by a single 1px hairline in `#E5E5E5`, which draws the vertical column rules, the section borders, the table rows and the edge of nearly every control — one line weight doing the structural work most systems hand to shadows. Colour is rationed to a product taxonomy: four 16px chips at radius 4px, orange `#FB923C`, purple `#C084FC`, green `#4ADE80` and neutral `#A3A3A3`, the three saturated ones each carrying a 900-level glyph, and the inline "Learn more" link under each band takes that family's darker ink, so the accent tells you which product you are reading about. Type runs two registers with no middle ground — Satoshi at 500 at every measured heading size, 30px to 48px, with leading pulled down to the size itself, Inter at 400 and 500 for body and controls, 600 and 700 for bylines and table headers, running 8px to 30px at a body ratio of 1.43 (20px on 14px) — so scale, not weight, carries hierarchy. Neutrals descend from `#0A0A0A` ink through `#737373` copy to `#FAFAFA` bands, and a black `#000000` fill marks the control a view is asking you to press. The rhythm is a 1080px column inside a full-bleed grid, sections breathing at 64–96px, with product screenshots rendered as live components rather than flat images.

## Tokens — Colors

| Name | Value | Token | Role |
|------|-------|-------|------|
| Canvas | `#FFFFFF` | `--color-canvas` | Page ground and the fill of table cells, panels and floating controls; the theme's base. |
| Recessed | `#FAFAFA` | `--color-recessed` | One luminance step down: alternating bands, and the resting fill of `.group.relative.block.h-full` story cards. |
| Tint | `#F5F5F5` | `--color-tint` | Fill of the `.flex.h-52.flex-col.justify-between` pricing card and the `"Case Study"` pip; the quietest ground, for cards that read inset. |
| Hairline | `#E5E5E5` | `--color-hairline` | The structural line — column rules, section borders, table rows, control outlines. It carries the elevation this system withholds from shadows. |
| Divider Ink | `#D4D4D4` | `--color-divider` | Separator glyphs and dimmed inline text in the plan tables; mostly a text grey — text 42 against fill 2 and border 13 — but also the system's second border ink, drawn on `.group.flex.divide-neutral-300.rounded-full` and `.relative.size-full.overflow-hidden.rounded-t-lg`. |
| Faint | `#A3A3A3` | `--color-faint` | Supporting captions under dark bands; the lowest-contrast ink that still reads. |
| Muted | `#737373` | `--color-muted` | Default copy colour for links, list items and secondary paragraphs; the third-most-painted ink, after `#0A0A0A` (text 1537) and `#262626` (text 350), at text 229. |
| Body | `#525252` | `--color-body` | Lead paragraphs and eyebrow labels; the step where copy turns deliberate. |
| Body Strong | `#262626` | `--color-body-strong` | Emphasis, table headers, the secondary button's label; the strongest ink that is not a heading. |
| Heading Ink | `#171717` | `--color-heading` | Seventeen of the twenty-one measured Satoshi heading elements, and the fill of the inverted band — `"Compare plans"` paints `#0A0A0A`, and the three headlines on the inverted band paint `#FAFAFA`. |
| Ink | `#0A0A0A` | `--color-ink` | The inherited document text colour: all 1537 of its observations are text, none of them a fill. |
| Action Black | `#000000` | `--color-action` | Filled button and matching border, carried by `"Sign up"` and `"Start for free"`; in the controls census it fills no tertiary or inline link. |
| Links Orange | `#FB923C` | `--color-links` | Dub Links chip fill, glyph ink `#7C2D12`, inline link ink `#EA580C`; editorial signal for the links product, and no control in the controls census fills with it. |
| Partners Purple | `#C084FC` | `--color-partners` | Dub Partners chip fill, glyph ink `#581C87`, inline link ink `#7C3AED`; the `"Best Value"` pip is a neighbouring violet, not this hue: `"Best Value" .w-fit.whitespace-nowrap.rounded-full.px-2` fills `#DDD6FE` with `#4C1D95` ink, 2 elements on p3. |
| Analytics Green | `#4ADE80` | `--color-analytics` | Dub Analytics chip fill, glyph ink `#14532D`, inline link ink `#16A34A`; the same green reads as `"Verified"` on `#DCFCE7`. |
| Spectrum Glow | `#3A8BFD → #855AFC → #FF0000 → #EAB308` | `--gradient-glow` | The conic wash on `.absolute.-inset-[40px].bg-[conic-gradient(…)]`, 2 elements on p1 and p2; a second conic layer, `.pointer-events-none.absolute.bottom-0.left-1/2` (1 element, p1), runs `#FF0000 → #EAB308 → #5CFF80 → #00FFF9`. Decorative light; no text row in the census takes a stop from either. |

## Tokens — Typography

### Satoshi — the display face, set at weight 500 at every measured heading size, 30px to 48px, with leading collapsed to the size itself · `--font-display`
- **Substitute:** Cabinet Grotesk, General Sans, Switzer
- **Weights:** 500, 700 — every measured heading row, from `"Turn clicks into revenue"` to `"Compare plans"`, paints 500; the one 700 row is `"# direct-dub-support" .font-display.text-base.font-bold.leading-tight` in `#4B5563` on p4, whose size the type census does not carry
- **Sizes:** 30px, 36px, 40px, 48px
- **Line height:** 36px at 30px, 40px at 36px and 40px, 48px or 55.2px at 48px — a ratio between 1.00 and 1.20
- **Letter spacing:** normal on every measured display row except the 30px `h2` on the customers page, which paints −0.6px
- **Role:** The display face.

### Inter — the interface face, carrying body, labels, controls and micro-copy from 8px to 30px · `--font-default`
- **Substitute:** Geist, SF Pro Text, system-ui
- **Weights:** 400, 500, 600, 700
- **Sizes:** 8px, 10px, 12px, 14px, 16px, 18px, 24px, 30px
- **Line height:** 8px at 8px, 15px at 10px, 16px at 12px, 20px at 14px, 24px at 16px, 28px at 18px, 32px at 24px, 41.25px at 30px
- **Letter spacing:** normal on every measured row
- **Role:** The interface face.

### GeistMono — numerals and technical metadata, where figures must align in a column · `--font-mono`
- **Substitute:** JetBrains Mono, IBM Plex Mono, ui-monospace
- **Weights:** 400, 500
- **Sizes:** not measured — the type census carries no GeistMono row
- **Line height:** not measured
- **Letter spacing:** not measured
- **Role:** The counters ride `.font-mono.text-2xl.font-medium.text-orange-600` in `#EA580C`.

### Rowan — a single editorial voice, reserved for the long testimonial on the inverted panel · `--font-serif`
- **Substitute:** Freight Display Pro, Spectral, Newsreader
- **Weights:** 300
- **Sizes:** not measured — the type census carries no Rowan row
- **Line height:** not measured
- **Letter spacing:** not measured
- **Role:** A serif at light weight breaks a page otherwise set in grotesques.

### Type Scale

| Role | Size | Line Height | Letter Spacing | Token |
|------|------|-------------|----------------|-------|
| Display | 48px | 48px / 55.2px | normal | `--text-display` |
| Heading L | 40px | 40px | normal | `--text-heading-lg` |
| Heading M | 36px | 40px | normal | `--text-heading-md` |
| Heading S | 30px | 36px | −0.6px | `--text-heading-sm` |
| Pull Quote | 30px | 41.25px | normal | `--text-quote-lg` |
| Quote | 24px | 32px | normal | `--text-quote` |
| Lead | 18px | 28px | normal | `--text-lead` |
| Body | 16px | 24px | normal | `--text-body` |
| Default | 14px | 20px | normal | `--text-default` |
| Label | 12px | 16px | normal | `--text-label` |
| Micro | 10px | 15px | normal | `--text-micro` |
| Nano | 8px | 8px | normal | `--text-nano` |

## Tokens — Spacing & Shapes

**Base unit:** 4px   **Density:** comfortable

### Spacing Scale

| Name | Value | Token |
|------|-------|-------|
| 2xs | 2px | `--spacing-2xs` |
| xs | 4px | `--spacing-xs` |
| sm | 6px | `--spacing-sm` |
| md | 8px | `--spacing-md` |
| lg | 10px | `--spacing-lg` |
| xl | 12px | `--spacing-xl` |
| 2xl | 14px | `--spacing-2xl` |
| 3xl | 16px | `--spacing-3xl` |
| 4xl | 24px | `--spacing-4xl` |
| 5xl | 32px | `--spacing-5xl` |
| section-sm | 48px | `--spacing-section-sm` |
| section | 56px | `--spacing-section` |
| section-md | 64px | `--spacing-section-md` |
| section-lg | 80px | `--spacing-section-lg` |
| section-xl | 96px | `--spacing-section-xl` |

### Border Radius

| Element | Value |
|---------|-------|
| Progress bar, micro swatch | 2px |
| Product chip | 4px |
| Inline metric row, small badge | 6px |
| Buttons, nav items, most surfaces | 8px |
| Trial pill, bordered thumbnail | 10px |
| Nested icon plate | 11px |
| Cards, story tiles, demo frame | 12px |
| Feature frame | 16px |
| Device top edge | 16px 16px 0px 0px |
| Avatars, pips, toggles | 9999px |

### Shadows

| Name | Value | Token |
|------|-------|-------|
| Control | `rgba(0, 0, 0, 0.05) 0px 1px 2px 0px` | `--shadow-control` |
| Raised | `rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.1) 0px 2px 4px -2px` | `--shadow-raised` |
| Inset | `rgba(0, 0, 0, 0.2) 0px 2px 6px 0px inset` | `--shadow-inset` |
| Ring | `rgb(255, 255, 255) 0px 0px 0px 0px, rgba(229, 229, 229, 0.7) 0px 0px 0px 1px` | `--shadow-ring` |
| Float | `rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.1) 0px 4px 6px -4px` | `--shadow-float` |
| Ring + Lift | `rgba(0, 0, 0, 0.06) 0px 0px 0px 1px, rgba(0, 0, 0, 0.06) 0px 1px 2px -1px, rgba(0, 0, 0, 0.04) 0px 2px 4px 0px` | `--shadow-ring-lift` |
| Hairline Ring | `rgba(0, 0, 0, 0.02) 0px 0px 0px 1px, rgba(0, 0, 0, 0.08) 0px 1px 3px 0px` | `--shadow-hairline-ring` |
| Flat Ring | `rgba(0, 0, 0, 0.06) 0px 0px 0px 1px` | `--shadow-flat-ring` |
| Inverted Ring | `rgba(255, 255, 255, 0.1) 0px 0px 0px 1px inset` | `--shadow-inverted-ring` |
| Soft Drop | `rgba(0, 0, 0, 0.07) 0px 4px 12px 0px` | `--shadow-soft-drop` |

### Layout

- **Page max-width:** a 1080px content column (`.relative.z-0.mx-auto.max-w-grid-width`, bordered 1px `#E5E5E5`) inside a full-bleed 1920px band (`.grid-section.relative.overflow-clip.px-4`); demo frames narrow to an 800px measure.
- **Section gap:** 80px is the most-counted vertical section padding, 64px and 56px close behind, 96px on the widest bands; one hero block reaches 160px.
- **Card padding:** 24px 20px on the pricing card, 16px 20px on a table cell, 32px 16px on an integration cell, 20px 16px on a borderless panel.
- **Element gap:** 8px by a wide margin, 4px icon-to-label, 12px and 16px for list and grid rows, 32px for the widest split rows.
- **Horizontal inset:** 48px on the widest blocks, 64px on two.

## Components

### Primary Button

**Role:** The single filled action in a view — sign up, start free, contact us.

The nav version, `"Sign up" .transition-all.border-black.bg-black.text-content-inverted`, paints fill `#000000`, ink `#FFFFFF`, Inter 14px/400, padding 0px 16px, radius 8px, a matching 1px `#000000` border and no shadow. The in-page version, `"Start for free" .mx-auto.max-w-fit.whitespace-nowrap.border`, keeps fill, border and radius, steps weight to 500, pads 8px 20px and adds `rgba(0, 0, 0, 0.05) 0px 1px 2px 0px`. The border matching the fill is the tell: the black control uses the same outlined chassis as every other button with the fill swapped in, so only one member of a row shouts.

### Secondary Button

**Role:** The companion action beside a primary — log in, get a demo, explore a product area.

`"Log in" .transition-all.border-border-subtle.bg-bg-default.text-content-emphasis` paints fill `#FFFFFF`, ink `#171717`, Inter 14px/400, padding 0px 16px, radius 8px, border 1px `#E5E5E5`, shadow none. The page-body sibling `"Get a demo" .mx-auto.max-w-fit.whitespace-nowrap.border` holds the same fill, radius and border, moves the ink to `#262626` at 14px/500, pads 8px 20px and lifts on `rgba(0, 0, 0, 0.05) 0px 1px 2px 0px`. A third, `"Explore Links" .max-w-fit.whitespace-nowrap.border.px-5`, matches that geometry with `#171717` ink in a 119–168×38px box. The secondary is legible by its edge, so the edge is never softened.

### Nav Item

**Role:** A top-level destination in the sticky header.

`"Product" .relative.group/item.flex.items-center` paints no fill, ink `#404040`, Inter 14px/500/20px, padding 0px 12px, radius 8px, no border and no shadow, in a 93–111×32px box. The selected state is the same class on an anchor, `"Customers" .relative.group/item.flex.items-center`, filling `rgba(23, 23, 23, 0.05)` with ink, type, padding, radius, border and shadow identical; the anchor's box measures 71–97×32px against the button's 93–111×32px — a 5% wash of the heading ink rather than a new colour. The button variant `"Solutions" .relative.group/item.flex.items-center` paints that tint in a 102×32px box. Ink at `#404040` rather than the page's `#0A0A0A` keeps the header a half-step quieter than the content below.

### Product Mark Chip

**Role:** The glyph that names which product a section, footer link or price row belongs to.

`.flex.size-4.items-center.justify-center` paints a 16×16px box at radius 4px with a 1px `rgba(0, 0, 0, 0.05)` border and no shadow, in one of four fills: `#FB923C` for links, `#C084FC` for partners, `#4ADE80` for analytics and `#A3A3A3` for Dub API. The glyph inside takes the 900-level ink of the same hue — `#7C2D12`, `#581C87`, `#14532D` — which keeps a 16px mark readable at a fraction of a line height. The near-invisible black border at 5% stops the saturated fill bleeding into white paper, and is why the chips read as objects rather than emoji.

### Section Eyebrow

**Role:** The small label above a section headline that names the product line.

The label is Inter 12px/500/16px in `#525252`, carried on `"Dub Links" .text-xs.font-medium.text-neutral-600`, sitting beside its product chip on the same baseline. It takes the body ink rather than the accent, so the chip alone carries colour, and at 12px against a 48px Satoshi headline it is a quarter of the display size, so the pair reads as one unit instead of two competing lines.

### Feature Triad Column

**Role:** The three-up detail strip under each product band, one column active and two dimmed.

Columns are divided by `.absolute.-left-px.top-0.h-full` — a 1px, 132–152px tall rule filled `#E5E5E5`, no radius, no shadow — set flush to the column's left edge so the divider doubles as an active-state marker. The closing link is `"Learn more" .mt-3.5.inline-flex.items-center.text-sm` at Inter 14px/500/20px, resting in `#737373` and taking its product's ink when active: `#EA580C` under links, `#16A34A` under analytics, `#7C3AED` under partners. That swap on a single 14px link is the system's most economical use of accent — the column stays neutral and one word tells you where you are.

### Pricing Plan Card

**Role:** A plan summary — name, price, description, trial action.

`.flex.h-52.flex-col.justify-between` paints fill `#F5F5F5`, padding 24px 20px, radius 12px, no border, and `rgb(255, 255, 255) 0px 0px 0px 0px, rgba(229, 229, 229, 0.7) 0px 0px 0px 1px`. The ring replaces a border: at 70% opacity of the hairline it reads fractionally lighter than a solid `#E5E5E5` edge, so three cards separate without a heavy cage. The unit label beside the price is `"per month" .text-sm.font-medium.text-neutral-900/50` in `rgba(23, 23, 23, 0.5)` — half-opacity ink instead of a second grey. The price figure itself is not measured: no census row carries it.

### Plan Comparison Row

**Role:** One feature line in the plan comparison table, repeated across three plan columns.

`.flex.items-center.gap-2.border-b` paints fill `#FFFFFF`, Inter 14px/400/20px, padding 16px 20px, radius 0px, a 1px `#E5E5E5` border and no shadow, in a 359×53px cell. The same class appears again with **border none** in a 359×52px cell, where a group of sub-items should read as one block. Rounded cells would fight the 1080px column rules the table hangs from, so the radius vocabulary stops at the table edge. Headers set Inter 14px/700/20px in `#262626`, the heaviest weight the interface face paints.

### Customer Story Card

**Role:** A tile in the customer grid that opens a case study.

`.group.relative.block.h-full` paints fill `#FAFAFA`, ink `#0A0A0A`, Inter 16px/400/24px, zero padding, radius 12px, no border and no shadow, in a 335×140px box. The affordance is a separate 24×24px square, `.absolute.right-2.top-2.flex`, filled `rgba(23, 23, 23, 0.05)` at radius 8px with 12px/500/16px type and 0px 6px padding, pinned top-right. A card with no border and no shadow, one luminance step below white, is how this system says "clickable" without adding a line; the corner square is the only chrome, and it sits on the tile rather than around it.

### Dark CTA Band

**Role:** The full-width closing block that asks for the signup.

`.relative.bg-neutral-900.px-4` fills `#171717` with 0px 16px padding, no radius, no border and no shadow. The headline runs Satoshi 48px/500/48px in `#FAFAFA` — the recessed grey used as inverted ink, not pure white, so the band reads as a tonal inversion rather than a second palette. Paired controls are `"Start for free" .flex.h-10.items-center.justify-center`, filled `#FFFFFF` with `#171717` ink, 14px/500, padding 0px 20px, radius 8px, border 1px `#E5E5E5`; and `"Get a demo" .flex.h-10.items-center.justify-center`, filled `rgba(255, 255, 255, 0.2)` with `#FFFFFF` ink, same type, padding and radius, no border. The ghost at 20% white is the inverted twin of the white-with-hairline secondary, resolved with opacity because a hairline would disappear here.

### Partner Payout Row

**Role:** A single row inside the rendered product surface — avatar, name, amount.

`.-mt-px.flex.h-10.items-center` paints fill `#FFFFFF`, Inter 10px/400/15px, padding 0px 8px, radius 6px, border 1px `#E5E5E5`, no shadow, in a 384×40px box. The negative top margin makes a stack read as a table: adjacent rows overlap their hairlines by 1px, so the divider between two rows stays 1px rather than doubling to 2px. At 10px the names sit below reading size on purpose — the screenshot is composed from real components at reduced scale, which is why its edges stay crisp where a flattened image would blur.

### Status Badge

**Role:** A state pip inside the product surface — verified, pending, new event.

`.flex.items-center.gap-1.rounded-md` paints fill `#DCFCE7`, padding 6px 8px, radius 6px, no border and no shadow; its label takes `#16A34A`. The negative twin fills `#FEE2E2` with `#DC2626` ink on the same geometry, and the outlined variant `"New Event" .rounded-lg.border.px-2.py-1` sets `#166534` ink on `#DCFCE7` behind a 1px `#BBF7D0` border. Radius 6px rather than a pill: the badges sit inside the link row `.flex.items-center.justify-between.gap-8` — fill `#FFFFFF`, padding 20px 16px, radius 12px, 3 on p1 — where a fully rounded shape would read as a button. Fill and ink come from the same hue family, not a grey chip with a coloured dot.

## Do's and Don'ts

### Do

- Build structure from the 1px `#E5E5E5` hairline first. It borders `.grid-section.relative.overflow-clip.px-4`, the 1080px `.relative.z-0.mx-auto.max-w-grid-width` column and the `.flex.items-center.gap-2.border-b` table cell; reach for a shadow only after the line has failed.
- Keep the button chassis constant and change only the fill: `"Log in" .transition-all.border-border-subtle.bg-bg-default.text-content-emphasis` and `"Sign up" .transition-all.border-black.bg-black.text-content-inverted` share padding 0px 16px, radius 8px, a 1px border and a 14px label, and differ only in `#FFFFFF` against `#000000`.
- Let the product chip carry the colour and the copy stay neutral. `#FB923C`, `#C084FC` and `#4ADE80` name a product; `#EA580C`, `#7C3AED` and `#16A34A` echo it on `"Learn more" .mt-3.5.inline-flex.items-center.text-sm`.
- Set display type in Satoshi 500 with line height at or near the size: `"Turn clicks into revenue" .mt-5.text-center.font-display.text-4xl` paints 48px on 55.2px, `"It starts with a link" .mt-3.max-w-lg.text-pretty.font-display` 48px on 48px, `"Built to scale" .font-display.text-3xl.font-medium.text-neutral-900` 36px on 40px.
- Use `#FAFAFA` and `#F5F5F5` as steps down from the `#FFFFFF` canvas. Surfaces here recede rather than float.
- Invert with `#171717` and set the headline in `#FAFAFA`, not `#FFFFFF`, so the dark band stays tonal.
- Pad sections at 64–96px and keep content in the 1080px column, letting the band run full-bleed behind it.

### Don't

- Don't paint `#0A0A0A` as a background.
- Don't put an accent hue on a filled control. Every fill in the controls census is a neutral or a white/ink translucency — `#000000`, `#FFFFFF`, `#FAFAFA`, `#F5F5F5`, `#171717`, `rgba(255, 255, 255, 0.2)`, `rgba(23, 23, 23, 0.05)` — and no chip hue among them.
- Don't add a heavier shadow where a hairline will do. The standard control shadow is `rgba(0, 0, 0, 0.05) 0px 1px 2px 0px` at 31 elements, and `.flex.h-52.flex-col.justify-between` replaces its border with a ring rather than deepening.
- Don't round the comparison table. `.flex.items-center.gap-2.border-b` paints radius 0px, and square cells let the table sit flush inside the ruled column.
- Don't set display type in a bold weight. Every measured Satoshi heading paints 500, from `"Turn clicks into revenue"` at 48px to `"Built to scale"` at 36px.
- Don't add letter-spacing to headlines. The display row that paints tracking is `"Why modern companies choose Dub to power their g"` at −0.6px; the rest measure normal.
- Don't let the spectrum gradient touch type; it is carried on `.absolute.-inset-[40px].bg-[conic-gradient(…)]`, a decorative layer.

## Surfaces

| Level | Name | Value | Purpose |
|-------|------|-------|---------|
| 0 | Canvas | `#FFFFFF` | Page ground; fill of panels, table cells and floating rows. |
| 1 | Recessed | `#FAFAFA` | Alternating bands; resting fill of customer story tiles. |
| 2 | Tint | `#F5F5F5` | Pricing cards, toggle tracks, the `"Case Study"` pip. |
| 3 | Line | `#E5E5E5` | The edge between surfaces; also the fill of 1px rules and divider bars. |
| 4 | Inverted | `#171717` | The closing band and the dark link card, with `#FAFAFA` as its ink. |

## Elevation

Hairline first, shadow second. `#E5E5E5` at 1px is the primary separator across all four pages, and most surfaces stop there. When a shadow appears it is `rgba(0, 0, 0, 0.05) 0px 1px 2px 0px` — a 1px offset, 2px blur, enough to imply a raised control and nothing more. Nine further values appear. Three belong to demo art: `rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.1) 0px 2px 4px -2px` on the floating home tiles, `rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.1) 0px 4px 6px -4px` on the pill above the demo frame, and `rgba(0, 0, 0, 0.2) 0px 2px 6px 0px inset` pressing an icon plate into its gradient. The rest are chrome: the ring on `.flex.h-52.flex-col.justify-between`, `rgba(0, 0, 0, 0.02) 0px 0px 0px 1px, rgba(0, 0, 0, 0.08) 0px 1px 3px 0px` on `.border-border-subtle.absolute.left-0.top-0`, `rgba(0, 0, 0, 0.06) 0px 0px 0px 1px` on `.relative.flex.min-h-[560px].flex-col`, `rgba(0, 0, 0, 0.07) 0px 4px 12px 0px` on `.flex.w-full.items-center.justify-start`, and the three-layer ring-lift on the control `"Start your free trial" .flex.h-7.items-center.justify-center`. On the inverted band the logic flips to `rgba(255, 255, 255, 0.1) 0px 0px 0px 1px inset`.

## Imagery

Four modes, each in its lane. Product UI is rendered as live components at reduced scale — 40px rows on `#FFFFFF` with 1px `#E5E5E5` borders, 8px avatars, 4px progress bars — so screenshots share the page's token vocabulary instead of sitting on it as flat pictures. Customer proof is video stills in 12px-radius cards, the featured one full-bleed with white overlay type at Inter 18px/500/28px and a white pill button lower left. Wordmarks are partner logos in their own brand colours on white — tile `p1-01` carries twilio in red, the perplexity mark in teal and the Raycast mark in red beside black SUPERHUMAN and Vercel. Decoration is limited to a dotted-sphere globe in faint grey and the conic wash, `#3A8BFD → #855AFC → #FF0000 → #EAB308`, behind the dark band. Line icons are 16px, single-weight, in the ink beside them.

## Layout

Bands run edge to edge; content does not. Every section is a full-bleed `.grid-section.relative.overflow-clip.px-4` at 1920px with a 1px `#E5E5E5` border, and inside it a 1080px column, `.relative.z-0.mx-auto.max-w-grid-width`, also hairline-bordered. The result is a pair of vertical rules running the page's full height, visible in the margin of every screen — the system's most recognisable structural signature. The header is sticky, nav items 32px tall at 12px side padding and 8px radius, 8px between the log-in and sign-up controls, with a 16px 16px 0px 0px top-rounded frame at the viewport edge. Footers run a five-column link grid on `.flex.flex-col.mt-2.5.gap-3.5` at 14px row gaps, product links carrying their chips inline.

## Typography Voice

Two registers, no middle. Satoshi appears at 30px and above, at weight 500, leading pulled to or below 1.2 — 48px on 48px is the extreme, stacking a two-line headline with almost no gutter so it reads as one dense mass. Inter appears at 18px and below, with two quote exceptions at 24px and 30px, and its leading opens the other way — 20px on 14px, 28px on 18px — so body copy breathes where the headline compresses. The band between 18px and 30px is thinly populated — the type census carries a single row there, the 24px pull quote on `"“What you all have built is fantastic. I've used" .text-pretty.bg-gradient-to-b.from-black/60.to-black` (8 elements, p1 p3 p4) — which keeps the editorial jump from headline to text abrupt. Two guest voices break the grotesque: GeistMono for counted figures, so digits align in a column and a nine-digit number reads as data; and Rowan at 300 for the long testimonial on the inverted panel, the only serif here. Tracking is normal nearly everywhere — the one measured exception is a 30px headline at −0.6px — so the face's own fitting does the work.

## Agent Prompt Guide

## Quick Color Reference

- background: `#FFFFFF`
- text: `#0A0A0A`
- surface: `#FAFAFA`
- border: `#E5E5E5`
- accent: `#FB923C`
- primary action: `#000000`

## Example Component Prompts

1. **Primary Button**: Build a button with a `#000000` fill, `#FFFFFF` label in Inter 14px weight 500, 8px 20px padding, 8px border radius, a 1px `#000000` border matching the fill, and `rgba(0, 0, 0, 0.05) 0px 1px 2px 0px` shadow. Beside it, a secondary with `#FFFFFF` fill, `#262626` label, identical type, padding and radius, and a 1px `#E5E5E5` border.
2. **Pricing Plan Card**: Build a plan card on `.flex.h-52.flex-col.justify-between`, filled `#F5F5F5` with 24px top and 20px side padding, 12px radius, no border, and `rgb(255, 255, 255) 0px 0px 0px 0px, rgba(229, 229, 229, 0.7) 0px 0px 0px 1px` in place of a border. Plan name and price are not measured — no census row carries either face or figure. Set the unit label in `rgba(23, 23, 23, 0.5)` on `"per month" .text-sm.font-medium.text-neutral-900/50`, and the trial button full width at 8px radius.
3. **Product Mark Chip with Eyebrow**: Build a 16×16px square at 4px radius filled `#FB923C` with a 1px `rgba(0, 0, 0, 0.05)` border and a `#7C2D12` glyph inside, set beside a label in Inter 12px weight 500, line height 16px, colour `#525252`. Repeat with `#C084FC` / `#581C87` and `#4ADE80` / `#14532D`.
4. **Dark CTA Band**: Build a full-bleed section filled `#171717` with 16px side padding and no radius. Centre a Satoshi 48px weight 500 headline at 48px line height in `#FAFAFA`, then two 40px-tall buttons at 8px radius with 20px side padding: one filled `#FFFFFF` with `#171717` label and 1px `#E5E5E5` border, one filled `rgba(255, 255, 255, 0.2)` with `#FFFFFF` label and no border.
5. **Ruled Section Grid**: Build a full-bleed 1920px band with a 1px `#E5E5E5` border containing a centred 1080px column, also bordered 1px `#E5E5E5`, so two vertical hairlines run the full height. Pad the section 80px top and bottom, gutter 48px, place content in an 800px inner measure, and use 8px as the default flex gap.

## Similar Brands

- **Vercel** — the same white-paper-and-hairline discipline, with a black filled primary as the loudest control.
- **Linear** — a comparable two-register type system, a tightly-led display face far above a calm interface face with nothing between.
- **Stripe** — shares the habit of rendering product UI as real components in the marketing page rather than flattened screenshots.
- **Resend** — the same restraint of one accent hue as editorial credit against a neutral ramp.
- **Raycast** — a kindred use of small saturated glyph chips as the colour in a monochrome interface.

## Quick Start

### CSS Custom Properties

```css
:root {
  /* Colors */
  --color-canvas: #FFFFFF;
  --color-recessed: #FAFAFA;
  --color-tint: #F5F5F5;
  --color-hairline: #E5E5E5;
  --color-divider: #D4D4D4;
  --color-faint: #A3A3A3;
  --color-muted: #737373;
  --color-body: #525252;
  --color-body-strong: #262626;
  --color-heading: #171717;
  --color-ink: #0A0A0A;
  --color-action: #000000;
  --color-links: #FB923C;
  --color-links-glyph: #7C2D12;
  --color-links-link: #EA580C;
  --color-partners: #C084FC;
  --color-partners-glyph: #581C87;
  --color-partners-link: #7C3AED;
  --color-analytics: #4ADE80;
  --color-analytics-glyph: #14532D;
  --color-analytics-link: #16A34A;
  --color-success-bg: #DCFCE7;
  --color-success-border: #BBF7D0;
  --color-success-ink: #166534;
  --color-danger-bg: #FEE2E2;
  --color-danger-ink: #DC2626;
  --color-info-bg: #DBEAFE;
  --color-info-border: #BFDBFE;
  --color-info-ink: #2563EB;
  --color-best-value-bg: #DDD6FE;
  --color-best-value-ink: #4C1D95;
  --color-wash-ink: rgba(23, 23, 23, 0.05);
  --color-ink-half: rgba(23, 23, 23, 0.5);
  --color-ghost-fill: rgba(255, 255, 255, 0.2);
  --color-chip-border: rgba(0, 0, 0, 0.05);
  --gradient-glow: conic-gradient(#3A8BFD, #855AFC, #FF0000, #EAB308, #5CFF80, #00FFF9);

  /* Typography — Families */
  --font-display: 'Satoshi', 'Cabinet Grotesk', ui-sans-serif, system-ui, sans-serif;
  --font-default: 'Inter', 'Geist', ui-sans-serif, system-ui, sans-serif;
  --font-mono: 'GeistMono', 'JetBrains Mono', ui-monospace, monospace;
  --font-serif: 'Rowan', 'Spectral', ui-serif, Georgia, serif;

  /* Typography — Scale */
  --text-display: 48px;      --leading-display: 48px;
  --text-heading-lg: 40px;   --leading-heading-lg: 40px;
  --text-heading-md: 36px;   --leading-heading-md: 40px;
  --text-heading-sm: 30px;   --leading-heading-sm: 36px;
  --text-quote-lg: 30px;     --leading-quote-lg: 41.25px;
  --text-quote: 24px;        --leading-quote: 32px;
  --text-lead: 18px;         --leading-lead: 28px;
  --text-body: 16px;         --leading-body: 24px;
  --text-default: 14px;      --leading-default: 20px;
  --text-label: 12px;        --leading-label: 16px;
  --text-micro: 10px;        --leading-micro: 15px;
  --text-nano: 8px;          --leading-nano: 8px;
  --tracking-heading-sm: -0.6px;

  /* Spacing */
  --spacing-2xs: 2px;
  --spacing-xs: 4px;
  --spacing-sm: 6px;
  --spacing-md: 8px;
  --spacing-lg: 10px;
  --spacing-xl: 12px;
  --spacing-2xl: 14px;
  --spacing-3xl: 16px;
  --spacing-4xl: 24px;
  --spacing-5xl: 32px;
  --spacing-section-sm: 48px;
  --spacing-section: 56px;
  --spacing-section-md: 64px;
  --spacing-section-lg: 80px;
  --spacing-section-xl: 96px;
  --grid-width: 1080px;
  --measure-width: 800px;

  /* Border Radius */
  --radius-2xs: 2px;
  --radius-xs: 4px;
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 10px;
  --radius-plate: 11px;
  --radius-card: 12px;
  --radius-frame: 16px;
  --radius-device: 16px 16px 0px 0px;
  --radius-pill: 9999px;

  /* Shadows */
  --shadow-control: rgba(0, 0, 0, 0.05) 0px 1px 2px 0px;
  --shadow-raised: rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.1) 0px 2px 4px -2px;
  --shadow-inset: rgba(0, 0, 0, 0.2) 0px 2px 6px 0px inset;
  --shadow-ring: rgb(255, 255, 255) 0px 0px 0px 0px, rgba(229, 229, 229, 0.7) 0px 0px 0px 1px;
  --shadow-float: rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.1) 0px 4px 6px -4px;
  --shadow-ring-lift: rgba(0, 0, 0, 0.06) 0px 0px 0px 1px, rgba(0, 0, 0, 0.06) 0px 1px 2px -1px, rgba(0, 0, 0, 0.04) 0px 2px 4px 0px;
  --shadow-hairline-ring: rgba(0, 0, 0, 0.02) 0px 0px 0px 1px, rgba(0, 0, 0, 0.08) 0px 1px 3px 0px;
  --shadow-flat-ring: rgba(0, 0, 0, 0.06) 0px 0px 0px 1px;
  --shadow-inverted-ring: rgba(255, 255, 255, 0.1) 0px 0px 0px 1px inset;
  --shadow-soft-drop: rgba(0, 0, 0, 0.07) 0px 4px 12px 0px;
}
```

### Tailwind v4

```css
@theme {
  --color-canvas: #FFFFFF;
  --color-recessed: #FAFAFA;
  --color-tint: #F5F5F5;
  --color-hairline: #E5E5E5;
  --color-divider: #D4D4D4;
  --color-faint: #A3A3A3;
  --color-muted: #737373;
  --color-body: #525252;
  --color-body-strong: #262626;
  --color-heading: #171717;
  --color-ink: #0A0A0A;
  --color-action: #000000;
  --color-links: #FB923C;
  --color-links-glyph: #7C2D12;
  --color-links-link: #EA580C;
  --color-partners: #C084FC;
  --color-partners-glyph: #581C87;
  --color-partners-link: #7C3AED;
  --color-analytics: #4ADE80;
  --color-analytics-glyph: #14532D;
  --color-analytics-link: #16A34A;
  --color-success-bg: #DCFCE7;
  --color-success-border: #BBF7D0;
  --color-success-ink: #166534;
  --color-danger-bg: #FEE2E2;
  --color-danger-ink: #DC2626;
  --color-info-bg: #DBEAFE;
  --color-info-border: #BFDBFE;
  --color-info-ink: #2563EB;
  --color-best-value-bg: #DDD6FE;
  --color-best-value-ink: #4C1D95;
  --color-wash-ink: rgba(23, 23, 23, 0.05);
  --color-ink-half: rgba(23, 23, 23, 0.5);
  --color-ghost-fill: rgba(255, 255, 255, 0.2);
  --color-chip-border: rgba(0, 0, 0, 0.05);

  --font-display: 'Satoshi', 'Cabinet Grotesk', ui-sans-serif, system-ui, sans-serif;
  --font-default: 'Inter', 'Geist', ui-sans-serif, system-ui, sans-serif;
  --font-mono: 'GeistMono', 'JetBrains Mono', ui-monospace, monospace;
  --font-serif: 'Rowan', 'Spectral', ui-serif, Georgia, serif;

  --text-display: 48px;
  --text-display--line-height: 48px;
  --text-heading-lg: 40px;
  --text-heading-lg--line-height: 40px;
  --text-heading-md: 36px;
  --text-heading-md--line-height: 40px;
  --text-heading-sm: 30px;
  --text-heading-sm--line-height: 36px;
  --text-heading-sm--letter-spacing: -0.6px;
  --text-quote-lg: 30px;
  --text-quote-lg--line-height: 41.25px;
  --text-quote: 24px;
  --text-quote--line-height: 32px;
  --text-lead: 18px;
  --text-lead--line-height: 28px;
  --text-body: 16px;
  --text-body--line-height: 24px;
  --text-default: 14px;
  --text-default--line-height: 20px;
  --text-label: 12px;
  --text-label--line-height: 16px;
  --text-micro: 10px;
  --text-micro--line-height: 15px;
  --text-nano: 8px;
  --text-nano--line-height: 8px;

  --spacing-2xs: 2px;
  --spacing-xs: 4px;
  --spacing-sm: 6px;
  --spacing-md: 8px;
  --spacing-lg: 10px;
  --spacing-xl: 12px;
  --spacing-2xl: 14px;
  --spacing-3xl: 16px;
  --spacing-4xl: 24px;
  --spacing-5xl: 32px;
  --spacing-section-sm: 48px;
  --spacing-section: 56px;
  --spacing-section-md: 64px;
  --spacing-section-lg: 80px;
  --spacing-section-xl: 96px;

  --radius-2xs: 2px;
  --radius-xs: 4px;
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 10px;
  --radius-plate: 11px;
  --radius-card: 12px;
  --radius-frame: 16px;
  --radius-pill: 9999px;

  --shadow-control: rgba(0, 0, 0, 0.05) 0px 1px 2px 0px;
  --shadow-raised: rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.1) 0px 2px 4px -2px;
  --shadow-inset: rgba(0, 0, 0, 0.2) 0px 2px 6px 0px inset;
  --shadow-ring: rgb(255, 255, 255) 0px 0px 0px 0px, rgba(229, 229, 229, 0.7) 0px 0px 0px 1px;
  --shadow-float: rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.1) 0px 4px 6px -4px;
  --shadow-ring-lift: rgba(0, 0, 0, 0.06) 0px 0px 0px 1px, rgba(0, 0, 0, 0.06) 0px 1px 2px -1px, rgba(0, 0, 0, 0.04) 0px 2px 4px 0px;
  --shadow-hairline-ring: rgba(0, 0, 0, 0.02) 0px 0px 0px 1px, rgba(0, 0, 0, 0.08) 0px 1px 3px 0px;
  --shadow-flat-ring: rgba(0, 0, 0, 0.06) 0px 0px 0px 1px;
  --shadow-inverted-ring: rgba(255, 255, 255, 0.1) 0px 0px 0px 1px inset;
  --shadow-soft-drop: rgba(0, 0, 0, 0.07) 0px 4px 12px 0px;
}
```
