Typography
Geist Variable + Geist Mono Variable. Scale maps to Tailwind defaults — no custom type tokens. Weight and color carry hierarchy, not aggressive size jumps.
Type scale
10 steps
Display
48 / 56 / -0.04em
Pack my box with five dozen liquor jugs.
Heading 1
36 / 44 / -0.03em
Pack my box with five dozen liquor jugs.
Heading 2
30 / 38 / -0.025em
Pack my box with five dozen liquor jugs.
Heading 3
24 / 32 / -0.02em
Pack my box with five dozen liquor jugs.
Heading 4
20 / 28 / -0.015em
Pack my box with five dozen liquor jugs.
Body L
18 / 28
Pack my box with five dozen liquor jugs.
Body
16 / 24
Pack my box with five dozen liquor jugs.
Body S
14 / 20
Pack my box with five dozen liquor jugs.
Caption
12 / 16
Pack my box with five dozen liquor jugs.
Overline
11 / 16 · mono
Pack my box with five dozen liquor jugs.
Composed hierarchy
specimen
The scale read as a real text block — how Display, headings, body, and caption stack on a single surface. Spacing and color do most of the work; size jumps stay restrained.
Release notes
Designing with intent
A short standfirst that sits below the headline — set at Body L in muted-foreground to separate it from the body without another size jump.
Weight over size
Body copy stays at Regular 400 with relaxed leading. Hierarchy is carried by weight and color rather than escalating type sizes, so a dense interface still reads as one calm system. Inline emphasis uses Semibold, never a larger size.
Caption — supporting metadata, set at Caption 12px in muted-foreground.
Weights — Geist Variable
3 of 7 in production
Geist ships the full variable range, but bloom-nx production type uses only three weights. Off-policy weights are dimmed below.
Weight policy
400 / 500 / 600
Three sanctioned weights, one role each. 700+ is not used unless a design explicitly specs it — per DESIGN.md §3 / Design Direction. Heavier weights muddy a calm systems UI and break the weight-over-size hierarchy.
Body copy, paragraphs, long-form reading.
UI labels, control text, field labels, section captions.
Display, headings, emphasis. Hierarchy is driven by weight + color, not size jumps.
Numerics
tabular vs proportional
bloom-nx is a fintech system — prices, balances, and tables need digits that line up. tabular-nums gives every figure an equal advance width so
columns align vertically; proportional figures (the default) optimize the look of inline prose
but drift in a column. Use tabular-nums for any stacked numbers;
leave prose proportional.
Tabular
tabular-nums
Proportional
default
Watch the decimal points line up on the left, the proportional ones on the right wander. The mono face (Geist Mono) is tabular by construction — reach for it on numeric-dense tables and timestamps.
Mono — Geist Mono Variable
code · metadata · figures
const bloom = {
primary: '#5f34ec',
motion: 'var(--motion-duration-fast)',
radius: '0.875rem'
}