Foundations
Typography
39 typography tokens. The base theme sets text in the system UI font, so a new project starts with nothing to download; a brand swaps the family and keeps the scale. The fluid sizes below change with your window.
Type scale
Tokens first, then components
Getting started
Component library
Foundations
Install the package
Props
Body text is sized for reading, so long passages stay comfortable without zooming in.
Save changes
Supporting text and table cells
Email address
Updated 30 September 2026
Tokens
Families
The base theme uses the system UI font for text, so nothing is downloaded, and JetBrains Mono for code.
| Token | Value |
|---|---|
--font-family-base | -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif |
--font-family-heading | -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif |
--font-family-mono | 'JetBrains Mono', monospace |
Sizes
Display and H1 to H3 have fluid versions that scale with the viewport. Everything from H4 down is fixed.
| Token | Value |
|---|---|
--font-size-body | 18px |
--font-size-control | 16px |
--font-size-small | 14px |
--font-size-caption | 12px |
--font-size-h1 | 64px |
--font-size-display | clamp(2rem, 0.75rem + 5vw, 5rem) |
--font-size-h1-fluid | clamp(1.75rem, 0.75rem + 4vw, 4rem) |
--font-size-h2 | 48px |
--font-size-h2-fluid | clamp(1.625rem, 1rem + 2.5vw, 3rem) |
--font-size-h3 | 32px |
--font-size-h3-fluid | clamp(1.5rem, 1rem + 2vw, 2.5rem) |
--font-size-h4 | 24px |
--font-size-h5 | 20px |
Weights
Weights by role. Title is the bold one, for small titles in card and dialog headers (decisions/0010 in the library).
| Token | Value |
|---|---|
--font-weight-body | 400 |
--font-weight-heading | 600 |
--font-weight-label | 500 |
--font-weight-display | 600 |
--font-weight-title | 700 |
--font-weight-control | 500 |
Line heights
Fixed line heights sit on a 4px grid. Display and heading use a ratio, so they follow the fluid sizes.
| Token | Value |
|---|---|
--line-height-display | 1.125 |
--line-height-body | 28px |
--line-height-control | 24px |
--line-height-small | 20px |
--line-height-caption | 16px |
--line-height-h1 | 80px |
--line-height-h2 | 60px |
--line-height-h3 | 40px |
--line-height-h4 | 32px |
--line-height-h5 | 24px |
--line-height-heading | 1.25 |
--line-height-label | 16px |
Letter spacing
Tighter for headings, slightly open for labels, wide for uppercase.
| Token | Value |
|---|---|
--letter-spacing-heading | -0.02em |
--letter-spacing-subheading | -0.01em |
--letter-spacing-body | 0 |
--letter-spacing-label | 0.01em |
--letter-spacing-wide | 0.08em |
Usage
import { Heading } from '@amezquita/design-system/components/primitives/Heading'
// Visual size and document level are separate:
// a page title that looks like H2 but is the page's <h1>.
<Heading level={2} as="h1">Account settings</Heading>
/* In CSS, take size, weight and line-height as a set. */
.caption {
font-size: var(--font-size-caption);
font-weight: var(--font-weight-label);
line-height: var(--line-height-caption);
}Do and don’t
Do
- Use
Headingfor headings, and setaswhen the outline level and the visual size differ. - Take size, weight and line height from the same step.
- Keep running text at body size and within
--size-container-text.
Don’t
- Hardcode a line height. The linter rejects it in component CSS.
- Skip heading levels to get a smaller look. Change
level, keep the outline. - Set a font family in a component. A brand sets it once, in its tokens.