Pigment

2.1 Typography

One scale, everywhere. text-xs is the floor: a layout that needs smaller text needs fewer columns.

Faces

SpecimenTokenValue
Handofffont-sansInter — Default for all text
0x4f2a…9c1b · 1,284,391 · 12.500000font-monoDM Mono — Hashes, IDs, raw numeric values, code

Figures

Numeric columns align because they are set in DM Mono; Inter has no tabular figures.

Default figures0123456789
Inherited from the page0123456789

Size

SpecimenTokenValue
The order shipped at 2:22pmtext-xl28px / 36px — Display — a short code read across two devices
The order shipped at 2:22pmtext-lg20px / 26px — Page headers
The order shipped at 2:22pmtext-md16px / 22px — Section headers
The order shipped at 2:22pmtext-base14px / 20px — Body default
The order shipped at 2:22pmtext-sm12px / 16px — Dense content
The order shipped at 2:22pmtext-xs11px / 15px — Component labels and secondary metadata

Leading

text-xl · 28px/36px

The order shipped at 2:22pm and the invoice settled 12.50 USDC against a spend cap of 500.00. Three approvals were still open when the run finished, and the journal recorded every one of them.

text-lg · 20px/26px

The order shipped at 2:22pm and the invoice settled 12.50 USDC against a spend cap of 500.00. Three approvals were still open when the run finished, and the journal recorded every one of them.

text-md · 16px/22px

The order shipped at 2:22pm and the invoice settled 12.50 USDC against a spend cap of 500.00. Three approvals were still open when the run finished, and the journal recorded every one of them.

text-base · 14px/20px

The order shipped at 2:22pm and the invoice settled 12.50 USDC against a spend cap of 500.00. Three approvals were still open when the run finished, and the journal recorded every one of them.

text-sm · 12px/16px

The order shipped at 2:22pm and the invoice settled 12.50 USDC against a spend cap of 500.00. Three approvals were still open when the run finished, and the journal recorded every one of them.

text-xs · 11px/15px

The order shipped at 2:22pm and the invoice settled 12.50 USDC against a spend cap of 500.00. Three approvals were still open when the run finished, and the journal recorded every one of them.

Solid leading (§2.1B)

Line height equal to the size, for text centred inside a fixed-height control such as a button label.

text-xl-solid · 28px
Approve access
text-lg-solid · 20px
Approve access
text-md-solid · 16px
Approve access
text-base-solid · 14px
Approve access
text-sm-solid · 12px
Approve access
text-xs-solid · 11px
Approve access

Weight

SpecimenTokenValue
The order shipped at 2:22pmweight-normal400 — Body, table cells, values
The order shipped at 2:22pmweight-medium500 — Table header labels, keys, active states
The order shipped at 2:22pmweight-semibold600 — All headers

Inline links (§2.1D rule 1)

A link is marked by its dotted underline, never by hue — this one is text-link, which equals text-primary on purpose.

2.2 Borders

Weight carries meaning, not decoration. A non-solid border carries its meaning in its line style, so it is always border-width-light.

SpecimenTokenValue
border-width-heavy3px — Marks the start of a structure
border-width-medium2px — Separates a table header from its rows
border-width-light1px — Separates peers
border-style-dotted1px dash 3px gap — Square dots — the dots are square, not round. Separators between table rows. Borders underneath section headers.
border-style-dashed3px dash 3px gap — Borders for callouts and code blocks.

A callout is marked by its dashed border, not by hue — there is no status-info token.

2.3 Color

Neutral from black to white; hue appears only in status. Showing the light values.

2.3A Surface

surface-raised matches surface-page — raised components separate by shadow, never by fill. surface-sticky exists for occlusion, not elevation.

surface-page#FFFFFF
surface-raised#FFFFFF
surface-sunken#F5F5F5
surface-overlay#FFFFFF
surface-hover#F5F5F5
surface-active#EBEBEB
surface-selected#F0F0F0
surface-sticky#FAFAFA
surface-disabled#F5F5F5
surface-scrim#000000 @ 40%
surface-skeleton#EDEDED
shadow-color#000000 @ 8%

2.3B Text

Contrast is measured against surface-page in the matching theme.

text-primary#0A0A0A · 19.9:1
text-secondary#8A8A8A · 3.5:1
text-placeholder#B8B8B8 · 2.0:1
text-disabled#C7C7C7 · 1.7:1
text-inverse#FFFFFF · —
text-link#0A0A0A · 19.9:1

2.3C Border

border-color-subtle#E5E5E5
border-color-default#D4D4D4
border-color-strong#171717
border-color-selected#0A0A0A
border-color-focus#0A0A0A
border-color-disabled#EBEBEB

2.3D Action

action-primary-bg#171717
action-primary-bg-hover#2E2E2E
action-primary-bg-active#000000
action-primary-fg#FFFFFF
action-secondary-bg#FFFFFF
action-secondary-bg-hover#F5F5F5
action-secondary-fg#171717
action-secondary-border#D4D4D4
action-ghost-bgtransparent
action-ghost-bg-hover#F5F5F5
action-ghost-fg#171717

2.3E Status

The only chromatic tokens in the system. Hue is never the only carrier — every status pairs its color with an icon or a label.

status-success-fg#1A7F4B
status-success-bg#ECF6F0
status-success-border#B8DEC8
status-warning-fg#9A6700
status-warning-bg#FDF6E7
status-warning-border#E8D5A3
status-error-fg#B42318
status-error-bg#FDF0EF
status-error-border#EFC5C1
status-neutral-fg#8A8A8A
status-neutral-bg#F5F5F5
status-neutral-border#E5E5E5

2.3F Delta

One axis for any signed change — money, lines, bytes. Separate from status on purpose: money out is not an error.

delta-increase-fg#1A7F4B
delta-increase-bg#ECF6F0
delta-decrease-fg#B42318
delta-decrease-bg#FDF0EF
delta-unchanged-fg#8A8A8A

2.3G Diff

Lighter than the delta backgrounds — they tint whole lines, not badges.

diff-added-bg#F2F9F5
diff-added-marker#1A7F4B
diff-removed-bg#FDF6F5
diff-removed-marker#B42318
diff-conflict-bg#FDF6E7
diff-conflict-marker#9A6700
diff-context-fg#8A8A8A

2.3H Focus and selection

focus-ring#0A0A0A
focus-ring-offset#FFFFFF
selection-bg#E5E5E5
selection-fg#0A0A0A

2.3I Value

Not an alias of text-secondary — tuned against numeric columns.

value-padding#C7C7C7

2.4 Spacing

Base unit is 4px. space-2xs is the only half-step, and it exists for components rendered inside other components.

SpecimenTokenValue
space-2xs2px — Chips. Small buttons. Icon to label at small size.
space-xs4px — Table and list cell padding. Icon to label.
space-sm8px — Gap between related controls.
space-md12px — Button padding. Input padding.
space-lg16px — Padding inside a component. Gap between components.
space-xl24px — Gap between sections on a page.

2.5 Radii · 2.6 Elevation

Sharp corners on records — tables, lists, code. Rounded on everything the interface invented — controls, containers, overlays.

SpecimenTokenValue
rounded-xs2px — Marks smaller than a control: checkbox, skeleton block
rounded-sm4px — Controls: buttons, inputs, chips
rounded-md6px — Containers and overlays: cards, menus, dialogs, drawers

A data-bearing component.

shd-diffuse2px x-offset 2px y-offset 8px blur shadow-color

A menu, a tooltip, a dialog — the shadow says it left the plane.

shd-overlay0 4px 14px shadow-color-strong — Anything that sits on top of the plane
surface-scrimblack @ 40% — Raised only by a dialog

2.7 Layout

Six columns with space-md gutters, at every breakpoint — density comes from what fills the columns.

Six columns, space-md gutters

Column count, and whether navigation is a column or a trigger, are the only two things a breakpoint changes.

Breakpoints

BreakpointWidthGridNavigation
wide≥ 1024px6 columnsColumn, visible
medium640–1023px6 columnsCollapsed to trigger
narrow< 640px2 columnsCollapsed to trigger

Row height: 24px, text only

ConversationStatusAmount
0x1a2b…9f4cSettled12.500000
0x77c1…0e28Blocked4.125000

The dimmed digits are value-padding — the eye stops at the last digit that carries information.

Row height: 30px, any cell holds a control or a chip

ConversationTagsAmount
0x1a2b…9f4cpayment12.500000
0x77c1…0e28memory write4.125000

The height is chosen once per table and applies to every row in it.

2.12 Size

Sizes are not spacing — never substitute one axis for the other.

SpecimenTokenValue
size-row-text24px — Table and list row holding only text.
size-row-control30px — Table and list row holding a control or chip.
size-frame-cell16px — Avatar frame inline in a cell or chip.
size-frame-header24px — Avatar frame in a header or the nav.
size-box16px — Checkbox and radio box, default.
size-box-small12px — Checkbox and radio box, small.

2.8 Icons

Phosphor Icons, two weights: regular, and fill for selection. Icon size tracks the text it sits with, never the container.

SpecimenTokenValue
Copy conversation IDicon-default · regular16px — Alongside text-base and text-md
Copy conversation IDicon-default · fillSelected and active states only — an icon never fills on hover.
Settledicon-small · regular12px — Alongside text-sm, inside table cells
Settledicon-small · fillThe icon equivalent of surface-selected.

The status vocabulary (§3.10)

Status renders as an outline icon plus its label — the icon carries the hue, the label carries the meaning.

SpecimenTokenValue
Successstatus-success-fgCheck circle — Success
Failurestatus-error-fgX circle — Failure
Warningstatus-warning-fgWarning circle — Warning
Blockedstatus-error-fgCircle with slash — Blocked
In progressstatus-neutral-fgDashed circle — In progress
Pausedstatus-neutral-fgPause circle — Paused

2.9 Motion

Motion is reserved for state the reader caused. Data never animates in; it appears. Under a reduced-motion preference these transitions are removed, not shortened.

SpecimenTokenValue
duration-fast · ease-standard200ms — Hover, focus, selection
duration-base · ease-standard180ms — Overlay entry and exit
ease-standardcubic-bezier(.2, 0, 0, 1) — Everything that moves

2.10 Layering · 2.11 Focus

Two tiers: everything in the document flow shares one low band, and every overlay uses the browser's top layer, which stacks by the order things opened rather than by number.

layer-base · 0
layer-raised · 1
layer-sticky · 2
TierTokenValueUse
In-flowlayer-base0Page content
In-flowlayer-raised1Elevated data components
In-flowlayer-sticky2Sticky table and page headers
Top——Dialog, menu, tooltip, toast

A z-index above 2 anywhere in the system is a bug. Overlays carry no z-index at all.

The focus ring

Tab into the buttons — the ring is focus-ring-width in focus-ring, held off the control by focus-ring-gap. A click draws no ring: keyboard only.