Skip to main content

Design System

Every primitive earns a visible job: structure the page, label a state, carry an action, or make data readable on mobile.

01

Button

Primary commands use verb-plus-object copy, visible focus, and a minimum 44px tap target.

Variants (md)
Sizes (primary)
States (primary)
Dark (on bg-ink)

02

Links

InlineLink is for sentence-level destinations. EyebrowLink is a quiet section CTA. Both must describe the destination.

Read the design-system standard before creating local UI.

Component library audit →

Dark sections use accessible inline links without relying on color alone.

Return to style index →

03

Chip

Passive chips describe. Interactive chips link — enforces 44px tap.

Passive tones
brandneutralinksuccesswarningdanger
Interactive (min-h-44)

04

Semantic labels

Badge reports generic status. Pill names trigger taxonomy. Callout explains consequence in text, not color alone.

Badge variants
neutralinfovalidatedat riskblocked
Pill taxonomy
painjobfrictionsignaldefault

Design decision

Use label text that still works when color is unavailable.

Audit gate

If a status needs a legend to decode, rewrite the label before changing color.

05

Card

Surface primitive. Variants × padding × interactive.

Default

bg-surface border-edge, non-interactive.

Muted

bg-surface-muted — subdued card on white.

Accent

bg-surface-accent border-brand/20.

Dark

bg-ink — inverted card on any surface.

Interactive (to)

Hover lifts, focus rings, no underline.

Interactive (prop)

interactive={true} without href/to.

Paddings
p-4
p-6
p-6 md:p-8

06

Prose

Measure-enforced long-form wrapper. Three sizes.

Small

Small prose. Used for sidebar explanations or footnotes. Max 65ch measure.

Links render in brand. Strong pushes weight without color shift.

Medium (default)

Default body prose. The workhorse. 16px base, 1.625 line-height, 65ch measure.

Two paragraphs here test the inter-paragraph rhythm. Check descenders and ascenders read cleanly.

Large

Large prose. For hero intros and primary content that needs weight. 18px base.

07

SectionHeader

Section openers carry scan order: short label, literal heading, and one explanatory lede.

Default — center, h2

Centered heading

The landing-page default. max-w-xl, mx-auto.

align=left, as=h1

Left-aligned H1

For sub-pages where the SectionHeader IS the page title.

Dark

Inverted colors

dark prop flips all tokens for bg-ink sections.

08

Eyebrow

Mono uppercase label. The atom that signals what's about to be said.

tone=accent (default)

Section label

Another label

tone=subtle

When

So I get

dark=true, tone=accent

Section label

as=span (inline)

Text with inline eyebrow inside prose.

09

Rhythm

Vertical stack with a fixed-token gap. Replaces ad-hoc space-y-*.

tight (12px)

Label + value pair

Same idea, close together

Third line, still tight

base (24px)

Sibling block A

Sibling block B

Sibling block C

loose (48px)

Distinct concept A

Distinct concept B

10

Stat

Mono number + label. bare (default) or card variant. Replaces StatCard.

variant=bare (default)

$25.8K

M12 Cumulative

Base case

M4

Break-even

Base case

$800

Monthly Burn

variant=card

$25.8K

M12 Cumulative

Base case

M4

Break-even

$800

Monthly Burn

Fixed costs

dark=true

94%

Uptime

30-day rolling

12ms

p95 latency

align=left

$0

Starting cash

Bootstrapped

11

Divider

Thin rule with optional eyebrow caption. Segments without nesting a Section.

Plain rule

With caption
Labelled section break
dark=true

12

TightFive

Miller minus two enforced. Show 5, fold the rest.

as=col gap=base (5-item ceiling)
Wallet
Identity
Reputation
Incentive
Governance
as=grid gap=base
First
Second
Third
Fourth
Fifth
as=row gap=tight
DreamerEngineerCoachBuilderInvestor

13

DataListTable

Tables become readable cards on mobile, then regain cross-row comparison on desktop.

  • Need
    Action
    Primitive
    Button
  • Need
    Status
    Primitive
    Badge / Pill
  • Need
    Evidence
    Primitive
    DataListTable

14

CopyablePrompt

A prompt block turns reading into doing. Its copy must be self-contained and its controls must be keyboard reachable.

Put this to work

Audit one component before reuse

Design auditor

Copy this prompt. Paste into Claude, ChatGPT, or any AI assistant. The page context is already loaded — send it and get analysis tailored to your role.

Audit this component before I reuse it.

Component:
Page job:
Reader state:
Check contrast, 44px targets, keyboard focus, mobile reflow, and link/button copy.
Name the single change that would most improve legibility.