taste-skill / Style guides / Dub style
How to build a UI in the Dub style
Dub (dub.co) reads as Modern Link Attribution & Crisp Satoshi/Geist Minimalist — Airy #FAFAFA canvas with #FFFFFF analytics cards, #E5E5E5 1px borders, geometric Satoshi 48px display headings, GeistMono shortlinks, and high-contrast #000000 8px-radius primary buttons. This guide turns its extracted computed styles into an implementation kit: a live preview, the exact palette and type scale, real button and card recipes, the rules to avoid, and drop-in CSS variables, Tailwind config and a Cursor / Claude Code SKILL.md snippet.
Source: computed styles extracted from
https://dub.co on 2026-10-26 by the taste-skill extractor. Brand fonts may be proprietary; previews fall back to Inter / system fonts. Dub is a trademark of its owner; this page documents publicly visible styling for reference and is not affiliated with Dub.Live preview with Dub tokens
Dub style · light
Ship the product, not the pixels.
Preview text rendered with the extracted Dub canvas, text, muted and accent tokens.
Card on extracted card recipe
Accent link: #000000 · border
#E5E5E5Color palette (light mode)
| Role | Value | Tailwind | Usage |
|---|---|---|---|
| canvasBg | #FAFAFA | bg-[#FAFAFA] | Primary Dub page canvas |
| surfaceElevated | #FFFFFF | bg-white | Primary elevated card & bento surface |
| surfaceSecondary | #262626 | bg-[#262626] | Secondary interactive container / hover fill |
| borderPrimary | #E5E5E5 | border-[#E5E5E5] | Primary structural divider (1px solid #E5E5E5) |
| borderSecondary | #D4D4D4 | border-[#D4D4D4] | Secondary nested module or pill border |
| textPrimary | #171717 | text-[#171717] | Hero H1, section H2 & high-contrast foreground |
| textMuted | #737373 | text-[#737373] | Lead paragraphs, descriptions & muted labels |
| accentPrimary | #000000 | bg-black | Primary interactive CTA & brand highlight (8px) |
| accentSecondary | #F5F5F5 | text-[#F5F5F5] | Secondary badge, syntax or telemetry highlight |
Typography
Heading Satoshi · body Inter / Satoshi · mono GeistMono
| Level | Computed spec |
|---|---|
| Hero H1 | 48px | line-height 55.2px (leading-[1.15]) | letter-spacing 0px (tracking-[0em]) | weight 500 (font-[500]) | color #171717 (text-[#171717]) | font satoshi |
| Section H2 (Primary) | 48px | line-height 48px (leading-[1]) | letter-spacing 0px (tracking-[0em]) | weight 500 (font-[500]) | color #171717 (text-[#171717]) | font satoshi |
| Card / Feature H3 | 16px | line-height 24px (leading-[1.5]) | letter-spacing 0px (tracking-[0em]) | weight 500 (font-[500]) | color #0A0A0A (text-[#0A0A0A]) | font Inter |
| Body Copy (Paragraph) | 20px | line-height 28px (leading-[1.4]) | letter-spacing 0px (tracking-[0em]) | weight 400 (font-[400]) | color #525252 (text-[#525252]) | font Inter |
| Monospace / Code Block | 14px | line-height 20px (leading-[1.43]) | letter-spacing 0px (tracking-[0em]) | weight 400 (font-[400]) | color #24292E (text-[#24292E]) | font GeistMono |
Spacing, radius, depth and motion
| Token family | Most frequent values (count on page) |
|---|---|
| Border radius | 12px ×59 · 8px ×34 · 6px ×17 · 2px ×8 · 4px ×5 · 20px 20px 0px 0px ×3 |
| Box shadow | rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 1px 2px 0px ×8 · rgb(255, 255, 255) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 0px 0px 4px, rgba(0, 0, 0, 0) 0px 0px 0px 0px ×1 · rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0.09) 0px 20px 20px 0px ×1 |
| Grid / flex gap | 8px ×56 · 4px ×20 · 16px ×15 · 6px ×10 · 2px ×9 · 12px ×6 |
| Container max-width | 1080px ×6 · 800px ×5 · 672px ×2 · 1024px ×1 |
| Section vertical padding | 80px / 40px ×2 · 64px / 80px ×1 · 160px / 128px ×1 · 48px / 0px ×1 |
| Easing | cubic-bezier(0.4, 0, 0.2, 1) ×76 |
| Duration | 0.15s ×40 · 0.3s ×13 · 0.2s ×12 · 0.5s ×9 |
Component recipes
Buttons (9 distinct)
| Rendered | Height | Padding | Radius | Background / Text | Border | Font |
|---|---|---|---|---|---|---|
| Sign up | 32px | 0px 16px | 8px | #000000#FFFFFF | 1px solid #000000 | 14px / 400 |
| Start for free | 38px | 8px 20px | 8px | #000000#FFFFFF | 1px solid #000000 | 14px / 500 |
| Start for free | 40px | 0px 20px | 8px | #FFFFFF#171717 | 1px solid #E5E5E5 | 14px / 500 |
| Log in | 32px | 0px 16px | 8px | #FFFFFF#171717 | 1px solid #E5E5E5 | 14px / 400 |
| Get a demo | 38px | 8px 20px | 8px | #FFFFFF#262626 | 1px solid #E5E5E5 | 14px / 500 |
Cards (7 distinct)
| # | Background | Border | Radius | Padding | Shadow |
|---|---|---|---|---|---|
| 1 | transparent | 1px solid #E5E5E5 | 20px 20px 0px 0px | 12px 12px | none |
| 2 | #FFFFFF | 1px solid #D4D4D4 | 12px 12px 0px 0px | 0px 0px | none |
| 3 | transparent | 1px solid #E5E5E5 | 8px | 0px 0px | none |
| 4 | #FFFFFF | 1px solid #E5E5E5 | 8px | 0px 0px | none |
Rules: what never to do in the Dub style
- NEVER substitute generic uncalibrated gray backgrounds for Dub’s exact
#FAFAFAcanvas and#FFFFFFsurface pairing. - NEVER replace
Satoshidisplay typography or ignore its signature scale (48px / 1.15 (w500)). - NEVER use thick opaque borders that clash with
#E5E5E5(1px solid #E5E5E5). - NEVER deviate from the signature button geometry (
8px) or introduce off-brand saturated gradients. - NEVER use default browser monospace when rendering code or telemetry—always pair with
GeistMono.
Copy-paste kit
CSS variables
:root {
/* Dub style — extracted from dub.co by taste-skill */
--canvas: #FAFAFA;
--surface: #FFFFFF;
--text: #171717;
--text-muted: #737373;
--accent: #000000;
--border: #E5E5E5;
--font-heading: Satoshi, Inter, system-ui, -apple-system, sans-serif;
--font-body: 'Inter / Satoshi', Inter, system-ui, -apple-system, sans-serif;
--font-mono: 'GeistMono', 'JetBrains Mono', ui-monospace, monospace;
--h1-size: 48px;
--h1-tracking: 0em;
--h1-weight: 500;
--radius-button: 8px;
--radius-common: 12px;
--shadow-common: rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 1px 2px 0px;
--ease: cubic-bezier(0.4, 0, 0.2, 1);
--duration: 0.15s;
}tailwind.config.js
// tailwind.config.js — Dub style tokens (taste-skill)
module.exports = {
theme: {
extend: {
colors: {
canvas: "#FAFAFA",
surface: "#FFFFFF",
ink: "#171717",
muted: "#737373",
accent: "#000000",
line: "#E5E5E5",
},
fontFamily: {
heading: ["Satoshi", 'Inter', 'system-ui', 'sans-serif'],
sans: ["Inter / Satoshi", 'Inter', 'system-ui', 'sans-serif'],
mono: ["GeistMono", 'ui-monospace', 'monospace'],
},
fontSize: { display: ["48px", { letterSpacing: "0em", fontWeight: "500" }] },
borderRadius: { button: "8px", card: "12px" },
boxShadow: { brand: "rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 1px 2px 0px" },
transitionTimingFunction: { brand: "cubic-bezier(0.4, 0, 0.2, 1)" },
},
},
};.cursor/skills/dub-style/SKILL.md
--- name: dub-style description: Build UI in the Dub visual style (Modern Link Attribution & Crisp Satoshi/Geist Minimalist). Use when the user asks for a Dub-like look. --- # Dub Style — Quick Rules (source: dub.co, extracted by taste-skill) ## Tokens - canvasBg: #FAFAFA — Primary Dub page canvas - surfaceElevated: #FFFFFF — Primary elevated card & bento surface - surfaceSecondary: #262626 — Secondary interactive container / hover fill - borderPrimary: #E5E5E5 — Primary structural divider (1px solid #E5E5E5) - borderSecondary: #D4D4D4 — Secondary nested module or pill border - textPrimary: #171717 — Hero H1, section H2 & high-contrast foreground - textMuted: #737373 — Lead paragraphs, descriptions & muted labels - accentPrimary: #000000 — Primary interactive CTA & brand highlight (8px) - accentSecondary: #F5F5F5 — Secondary badge, syntax or telemetry highlight ## Typography - Heading font: Satoshi; body: Inter / Satoshi; mono: GeistMono - Hero H1: 48px | line-height 55.2px (leading-[1.15]) | letter-spacing 0px (tracking-[0em]) | weight 500 (font-[500]) | color #171717 (text-[#171717]) | font satoshi - Section H2 (Primary): 48px | line-height 48px (leading-[1]) | letter-spacing 0px (tracking-[0em]) | weight 500 (font-[500]) | color #171717 (text-[#171717]) | font satoshi - Card / Feature H3: 16px | line-height 24px (leading-[1.5]) | letter-spacing 0px (tracking-[0em]) | weight 500 (font-[500]) | color #0A0A0A (text-[#0A0A0A]) | font Inter - Body Copy (Paragraph): 20px | line-height 28px (leading-[1.4]) | letter-spacing 0px (tracking-[0em]) | weight 400 (font-[400]) | color #525252 (text-[#525252]) | font Inter ## Components - Primary button: height 32px, padding 0px 16px, radius 8px, bg #000000, text #FFFFFF, 14px / 400 - Card: bg transparent, border 1px solid #E5E5E5, radius 20px 20px 0px 0px, padding 12px 12px ## Never - NEVER substitute generic uncalibrated gray backgrounds for Dub’s exact #FAFAFA canvas and #FFFFFF surface pairing. - NEVER replace Satoshi display typography or ignore its signature scale (48px / 1.15 (w500)). - NEVER use thick opaque borders that clash with #E5E5E5 (1px solid #E5E5E5). - NEVER deviate from the signature button geometry (8px) or introduce off-brand saturated gradients. - NEVER use default browser monospace when rendering code or telemetry—always pair with GeistMono. Full 120-line spec: https://taste-skill.pages.dev/taste/dub/
Or install the full spec
npx taste-skill add dub
Related
Dub full token specDub ButtonsDub CardsDub Pricing TableDub vs PostHogLinear vs DubCal.com vs DubDub vs Loops
Similar styles
Get all 30 full SKILL.md specs (Cursor / Claude Code / Codex ready) plus the Pro growth skills.
See taste-skill Pro →