Skip to content
Docs

Typography

Two typefaces: Geist for interface text and JetBrains Mono for code, IDs, shortcuts and numbers in tables. Content text is 14px, and the scale is tuned around it.

Typefaces

Geist is the interface font. JetBrains Mono is for code, IDs, shortcuts and numbers in tables.

UseStackToken
InterfaceGeist, ui-sans-serif, system-ui, sans-seriffont-family-sans
Code'JetBrains Mono', ui-monospace, monospacefont-family-mono

The quick brown fox jumps over the lazy dog. 0123456789

The quick brown fox jumps over the lazy dog. 0123456789

Both are licensed under the SIL Open Font License 1.1.

Type roles

A role sets size, weight and leading together. Use a role for headings and body text, never one role's size with another's weight.

Heading 1

Heading 2

Heading 3

Body text, 14px, for paragraphs and table cells.

Heading 1

Heading 2

Heading 3

Body text, 14px, for paragraphs and table cells.

RoleSizeWeightLeading
heading-132px5001.2
heading-224px5001.25
heading-318px5001.3
body14px4001.5

UI sizes

Small interface text uses the font-size-* steps, so labels and captions stay in the same scale as the roles.

TokenSizeUse for
font-size-xs12pxBadges, tokens, captions and timestamps.
font-size-sm13pxSecondary text next to a primary line: descriptions, helper and error text, and sm controls.
font-size-md14pxBody copy, input values, table cells, and default (md) and lg controls.
font-size-lg16pxHeadings and xl controls.
font-size-xl18pxLarger headings.
font-size-input14pxInputs, selects and textareas. 16px on touch screens, so iOS Safari does not zoom the page on focus.

Rules

Four rules from the design skill, each with one thing to write and one to avoid.

Headings use sentence case

Capitalize only the first word and proper nouns. Product and feature names keep the casing their owner uses. Title Case and uppercase make headings slower to read and louder than the content under them.

// Do
<h2 className="text-heading-3">Billing history</h2>
// Avoid
<h2 className="text-heading-3">Billing History</h2>
<h2 className="text-heading-3 uppercase">Billing history</h2>

Never change letter spacing

No tracking-* classes and no letter-spacing in CSS. Geist and JetBrains Mono are already spaced for the sizes in the scale; tightening or loosening them is how generated UI starts to look generated.

// Do
<span className="text-xs font-medium text-text-secondary">Last 30 days</span>
// Avoid
<span className="text-xs font-medium tracking-wide uppercase text-text-secondary">Last 30 days</span>

No bold

The scale has regular (400), medium (500) and semibold (600). There is no 700, and font-bold does nothing in a Werewolf project.

  • Headings: the weight comes with the role (text-heading-1 to -3 set it). Don't add a weight class on top.
  • Emphasis inside text, labels, button text: font-medium.
  • font-semibold only when medium can't separate a label from medium text right next to it.
// Do
<p className="text-body">Payment failed. <span className="font-medium">Update your card</span> to keep access.</p>
// Avoid
<p className="text-body">Payment failed. <b>Update your card</b> to keep access.</p>

Inline code is 0.9em

Mono text sitting inside a sans sentence looks bigger than the words around it at the same size. Use code-inline: it sets the mono family at 0.9em, so it follows whatever size the sentence is.

// Do
<p className="text-body">Run <code className="code-inline">npm run build</code> again.</p>
// Avoid
<p className="text-body">Run <code className="font-mono">npm run build</code> again.</p>