The typefaces, text sizes and named text styles that every component sets its words in.
Type scale
Display XL
typography.display-xl56 to 88 px · weight 400 · line height 1Display LG
typography.display-lg48 to 72 px · weight 400 · line height 1Heading XL
typography.heading-xl40 to 56 px · weight 400 · line height 1.2Heading LG
typography.heading-lg32 to 48 px · weight 400 · line height 1.2Heading MD
typography.heading-md28 to 40 px · weight 400 · line height 1.2Heading SM
typography.heading-sm24 to 32 px · weight 400 · line height 1.2Heading XS
typography.heading-xs20 to 28 px · weight 400 · line height 1.2Heading 2XS
typography.heading-2xs18 to 24 px · weight 400 · line height 1.2Subtitle
typography.subtitle20 px · weight 400 · line height 1.4Body LG
typography.body-lg20 px · weight 400 · line height 1.5Body MD
typography.body-md16 px · weight 400 · line height 1.5Body SM
typography.body-sm14 px · weight 400 · line height 1.5Body XS
typography.body-xs12 px · weight 400 · line height 1.5Label LG
typography.label-lg16 px · weight 500 · line height 1.4Label MD
typography.label-md14 px · weight 500 · line height 1.4Label SM
typography.label-sm12 px · weight 500 · line height 1.4Field SM
typography.field-sm16 px on a phone, 14 on a desktop · weight 400 · line height 1.5Code SM
typography.code-sm12 px · weight 400 · line height 1.5Code MD
typography.code-md14 px · weight 400 · line height 1.6
Guidelines
Purpose
The vocabulary of text: which faces exist, which sizes exist, and the named presets that combine face, size, weight, line height, letter spacing and case into a role such as page title, body copy or control label. Components consume presets. They do not compose text from raw values.
How it is structured
Three groups, stacked.
At the bottom, the typographic primitives: the font families — a display face for headings, a body face for reading, and a monospace face for code and keys — plus runs of sizes, weights and letter-spacing steps. These are ingredients and reach nothing directly.
In the middle, the text sizes: a semantic run of named sizes for display, heading, body and label roles. This is the only layer that changes with the viewport, and it is the layer the presets read their size from.
On top, the presets: display registers and heading levels, each with a light version, body sizes with their medium, semibold and bold versions, label sizes, a small field size and code sizes. Each preset is one composite token. Labels are set in the body face at a medium weight, in sentence case. A preset set in capitals carries the case out of the composite as a setting the component applies, because the token standard's text recipe has no slot for it.
The shape follows role families — display, heading, body, label — with headings independent of the HTML heading level a page chooses.
Tabular figures, digits of equal width for columns, counters and timers, are a CSS setting on the component that needs them, not a token.
Tiers
Text keeps its full line box, in Figma and in the components: nothing is trimmed to the cap height. The space between two texts is the gap between their boxes plus each line's own leading, so the text spacing tokens are set for untrimmed text, and a stack of text in the browser measures the same as its Figma frame.
Font families, sizes, weights and letter-spacing steps are primitives and do not reach CSS as custom properties, for the same reason primitive colors do not: the text ramp compresses at narrow widths, and a component reading a raw size would be blind to that. Semantic text sizes and the presets are what reach CSS. A preset becomes one custom property per part — family, size, weight, line height, letter spacing and text transform — because no single CSS property carries all of them without losing some.
Context behavior
Text size follows the viewport and involves no choice. Below the switch width the text sizes take their minimum values; at and above it, the display and heading sizes step up, some by more than one step, while body and label sizes stay put. The switch width is itself a token, documented under Breakpoints, so the boundary is a design decision held in the token source rather than a number in a stylesheet.
Line heights are ratios, so they scale with the size on their own. Letter spacing is a fixed length, so it does not; the display and heading presets use no tracking, and only the smaller labels carry a little.
Theme and density do not touch typography.
Usage rules
Do
- Consume a preset by referencing all of its parts together. Longhand properties are always safe; the label presets additionally need their text transform applied.
- Match the preset to the role, not the size. A card title is the preset that card titles use; if it needs to be bigger, that is a different preset, not a size override.
- Choose the HTML heading level from document structure and the preset from appearance. They are independent (TYP-001).
- Use the label presets for every uppercase moment. Uppercase outside the label register is not part of the system.
- Let text reflow and grow. Components must survive 200% text scaling and the guideline's text-spacing overrides without clipping (TYP-002, TYP-003).
Don't
- Write a font family, size, weight, line height or letter spacing in component CSS. The conformance checker rejects it.
- Apply uppercase to a body or display preset.
- Override one part of a preset with another preset's part. Mixing a heading's size with a body face is a new preset, and new presets are decided in Figma.
- Use a viewport media query on text inside a component. The text sizes already follow the viewport; a component that wants a different size at a different width wants a different preset.
- Leave any of the three faces unloaded. Each family names backups after it, a stand-in face sized to match and then the system's own font, so a page drawn before its face arrives keeps its layout. But the backups only stand in; they are not the system's type.
- Use a display preset more than once on a page, or in a product screen. Display presets are for one moment on a marketing or brand page; product screens stop at the largest heading.
Tokens
106 tokens in 8 groups. Open a group to see its tokens. The button beside a CSS name copies it, ready to paste; open a row for what the token is for and which components read it.
Font family
| Token | CSS |
|---|---|
display | Not in CSS |
Typeface for display text and headings: Funnel Display.
| |
body | Not in CSS |
Typeface for body text and labels: Geist.
| |
mono | Not in CSS |
Typeface for code and keys: Geist Mono.
| |
Font size
| Token | Value | Picture | CSS |
|---|---|---|---|
12 | 12px | Not in CSS | |
Raw font size, 12 px. Text styles read it through Semantic Typography; never bind it directly.
| |||
14 | 14px | Not in CSS | |
Raw font size, 14 px. Text styles read it through Semantic Typography; never bind it directly.
| |||
16 | 16px | Not in CSS | |
Raw font size, 16 px. Text styles read it through Semantic Typography; never bind it directly.
| |||
18 | 18px | Not in CSS | |
Raw font size, 18 px. Text styles read it through Semantic Typography; never bind it directly.
| |||
20 | 20px | Not in CSS | |
Raw font size, 20 px. Text styles read it through Semantic Typography; never bind it directly.
| |||
24 | 24px | Not in CSS | |
Raw font size, 24 px. Text styles read it through Semantic Typography; never bind it directly.
| |||
28 | 28px | Not in CSS | |
Raw font size, 28 px. Text styles read it through Semantic Typography; never bind it directly.
| |||
32 | 32px | Not in CSS | |
Raw font size, 32 px. Text styles read it through Semantic Typography; never bind it directly.
| |||
40 | 40px | Not in CSS | |
Raw font size, 40 px. Text styles read it through Semantic Typography; never bind it directly.
| |||
48 | 48px | Not in CSS | |
Raw font size, 48 px. Text styles read it through Semantic Typography; never bind it directly.
| |||
56 | 56px | Not in CSS | |
Raw font size, 56 px. Text styles read it through Semantic Typography; never bind it directly.
| |||
64 | 64px | Not in CSS | |
Raw font size, 64 px. Text styles read it through Semantic Typography; never bind it directly.
| |||
72 | 72px | Not in CSS | |
Raw font size, 72 px. Text styles read it through Semantic Typography; never bind it directly.
| |||
88 | 88px | Not in CSS | |
Raw font size, 88 px. Text styles read it through Semantic Typography; never bind it directly.
| |||
Font weight
| Token | Value | Picture | CSS |
|---|---|---|---|
light | 300 | The quick brown fox | Not in CSS |
Font weight: light (300).
| |||
regular | 400 | The quick brown fox | Not in CSS |
Font weight: regular (400).
| |||
medium | 500 | The quick brown fox | Not in CSS |
Font weight: medium (500).
| |||
semibold | 600 | The quick brown fox | Not in CSS |
Font weight: semibold (600).
| |||
Font letter spacing
| Token | Value | Picture | CSS |
|---|---|---|---|
none | 0px | Not in CSS | |
Letter spacing: none.
| |||
loose | 0.5px | Not in CSS | |
Letter spacing: loose.
| |||
Text styles
| Style | Specimen | Size | Weight | Line height | CSS |
|---|---|---|---|---|---|
display-xl | 56 to 88 px | 400 | 1 | --smbk-typography-display-xl-* | |
| |||||
display-lg | 48 to 72 px | 400 | 1 | --smbk-typography-display-lg-* | |
| |||||
heading-xl | 40 to 56 px | 400 | 1.2 | --smbk-typography-heading-xl-* | |
| |||||
heading-lg | 32 to 48 px | 400 | 1.2 | --smbk-typography-heading-lg-* | |
| |||||
heading-md | 28 to 40 px | 400 | 1.2 | --smbk-typography-heading-md-* | |
| |||||
heading-sm | 24 to 32 px | 400 | 1.2 | --smbk-typography-heading-sm-* | |
| |||||
heading-xs | 20 to 28 px | 400 | 1.2 | --smbk-typography-heading-xs-* | |
| |||||
heading-2xs | 18 to 24 px | 400 | 1.2 | --smbk-typography-heading-2xs-* | |
| |||||
subtitle | 20 px | 400 | 1.4 | --smbk-typography-subtitle-* | |
Subtitle: a short heading set in body text, such as the error summary’s title. Body LG’s size with closer lines.
| |||||
body-lg | 20 px | 400 | 1.5 | --smbk-typography-body-lg-* | |
| |||||
body-md | 16 px | 400 | 1.5 | --smbk-typography-body-md-* | |
| |||||
body-sm | 14 px | 400 | 1.5 | --smbk-typography-body-sm-* | |
| |||||
body-xs | 12 px | 400 | 1.5 | --smbk-typography-body-xs-* | |
| |||||
label-lg | 16 px | 500 | 1.4 | --smbk-typography-label-lg-* | |
Label LG: labels on controls and short UI text (buttons, chips, tabs, menu headings). Geist Medium, sentence case. Code and keys use Code SM and Code MD.
| |||||
label-md | 14 px | 500 | 1.4 | --smbk-typography-label-md-* | |
Label MD: labels on controls and short UI text (buttons, chips, tabs, menu headings). Geist Medium, sentence case. Code and keys use Code SM and Code MD.
| |||||
label-sm | 12 px | 500 | 1.4 | --smbk-typography-label-sm-* | |
Label SM: labels on controls and short UI text (buttons, chips, tabs, menu headings). Geist Medium, sentence case. Code and keys use Code SM and Code MD.
| |||||
display-xl-light | 56 to 88 px | 300 | 1 | --smbk-typography-display-xl-light-* | |
Display XL in Funnel Display Light, for large display and heading text where a lighter weight reads better.
| |||||
display-lg-light | 48 to 72 px | 300 | 1 | --smbk-typography-display-lg-light-* | |
Display LG in Funnel Display Light, for large display and heading text where a lighter weight reads better.
| |||||
heading-xl-light | 40 to 56 px | 300 | 1.2 | --smbk-typography-heading-xl-light-* | |
Heading XL in Funnel Display Light, for large display and heading text where a lighter weight reads better.
| |||||
heading-lg-light | 32 to 48 px | 300 | 1.2 | --smbk-typography-heading-lg-light-* | |
Heading LG in Funnel Display Light, for large display and heading text where a lighter weight reads better.
| |||||
heading-md-light | 28 to 40 px | 300 | 1.2 | --smbk-typography-heading-md-light-* | |
Heading MD in Funnel Display Light, for large display and heading text where a lighter weight reads better.
| |||||
heading-sm-light | 24 to 32 px | 300 | 1.2 | --smbk-typography-heading-sm-light-* | |
Heading SM in Funnel Display Light, for large display and heading text where a lighter weight reads better.
| |||||
heading-xs-light | 20 to 28 px | 300 | 1.2 | --smbk-typography-heading-xs-light-* | |
Heading XS in Funnel Display Light, for large display and heading text where a lighter weight reads better.
| |||||
heading-2xs-light | 18 to 24 px | 300 | 1.2 | --smbk-typography-heading-2xs-light-* | |
Heading 2XS in Funnel Display Light, for large display and heading text where a lighter weight reads better.
| |||||
field-sm | 16 px on a phone, 14 on a desktop | 400 | 1.5 | --smbk-typography-field-sm-* | |
Field SM: the text inside a small field. 14 on a desktop, 16 on a phone, so iPhones do not zoom in (answer 11).
| |||||
code-sm | 12 px | 400 | 1.5 | --smbk-typography-code-sm-* | |
Code SM: keys (Kbd) and short code in a line of text. Geist Mono.
| |||||
code-md | 14 px | 400 | 1.6 | --smbk-typography-code-md-* | |
Code MD: the code block and larger keys. Geist Mono with its own line height, 160%, so lines of code read apart.
| |||||
body-md-medium | 16 px | 500 | 1.5 | --smbk-typography-body-md-medium-* | |
Body MD one weight step bolder, for the current item, so the current item is not shown by colour alone.
| |||||
body-sm-medium | 14 px | 500 | 1.5 | --smbk-typography-body-sm-medium-* | |
Body SM one weight step bolder, for the current item, so the current item is not shown by colour alone.
| |||||
body-lg-bold | 20 px | 700 | 1.5 | --smbk-typography-body-lg-bold-* | |
Body LG in bold: a title over body text.
| |||||
heading-2xs-bold | 18 to 24 px | 700 | 1.2 | --smbk-typography-heading-2xs-bold-* | |
Heading 2XS in bold: drawer and modal titles.
| |||||
body-md-bold | 16 px | 700 | 1.5 | --smbk-typography-body-md-bold-* | |
Body MD in bold. Kept for the sites built on the system; the system's own components use semibold for button labels.
| |||||
body-sm-bold | 14 px | 700 | 1.5 | --smbk-typography-body-sm-bold-* | |
Body SM in bold. Kept for the sites built on the system; the system's own components use semibold for small button labels.
| |||||
body-md-semibold | 16 px | 600 | 1.5 | --smbk-typography-body-md-semibold-* | |
Body MD in semibold: button labels.
| |||||
body-sm-semibold | 14 px | 600 | 1.5 | --smbk-typography-body-sm-semibold-* | |
Body SM in semibold: small button labels.
| |||||
body-lg-light | 20 px | 300 | 1.5 | --smbk-typography-body-lg-light-* | |
Body LG in light: a section's or an opener's lede, where Figma sets Geist Light.
| |||||
Font weight
| Token | Value | Picture | CSS |
|---|---|---|---|
bold | 700 | The quick brown fox | Not in CSS |
Figma's primitives stop at semibold, but its components set titles and button labels in Geist Bold. It lives here rather than in Figma.
| |||
Font fallback
| Token | CSS |
|---|---|
| Body12 | |
stack | Not in CSS |
What follows Geist in every text style that names it: its stand-in face, then the system's own.
| |
local | Not in CSS |
The fonts already on the reader's device that the stand-in face draws with: Arial, or Helvetica where Arial is missing.
| |
size-adjust | Not in CSS |
How much the stand-in face scales Arial so its regular weight is as wide as Geist's: the two measured over the design system's own prose, with each font's kerning, as a browser sets it.
| |
ascent | Not in CSS |
Geist's height above the baseline, as a share of the stand-in face's scaled size.
| |
descent | Not in CSS |
Geist's depth below the baseline, as a share of the stand-in face's scaled size.
| |
line-gap | Not in CSS |
Geist's extra room between lines, as a share of the stand-in face's scaled size.
| |
light.size-adjust | Not in CSS |
How much the stand-in face scales Arial so it is as wide as Geist Light, measured as the regular one is.
| |
medium.size-adjust | Not in CSS |
How much the stand-in face scales Arial so it is as wide as Geist Medium, measured as the regular one is.
| |
semibold.local | Not in CSS |
Arial's bold face, or Helvetica's, so the stand-in's letters are shaped as heavy as Geist Semibold's.
| |
semibold.size-adjust | Not in CSS |
How much the stand-in face scales Arial Bold so it is as wide as Geist Semibold, measured as the regular one is.
| |
bold.local | Not in CSS |
Arial's bold face, or Helvetica's, so the stand-in's letters are shaped as heavy as Geist Bold's.
| |
bold.size-adjust | Not in CSS |
How much the stand-in face scales Arial Bold so it is as wide as Geist Bold, measured as the regular one is.
| |
| Display12 | |
stack | Not in CSS |
What follows Funnel Display in every text style that names it: its stand-in face, then the system's own.
| |
local | Not in CSS |
The fonts already on the reader's device that the stand-in face draws with: Arial, or Helvetica where Arial is missing.
| |
size-adjust | Not in CSS |
How much the stand-in face scales Arial so its regular weight is as wide as Funnel Display's: the two measured over the design system's own prose, with each font's kerning, as a browser sets it.
| |
ascent | Not in CSS |
Funnel Display's height above the baseline, as a share of the stand-in face's scaled size.
| |
descent | Not in CSS |
Funnel Display's depth below the baseline, as a share of the stand-in face's scaled size.
| |
line-gap | Not in CSS |
Funnel Display's extra room between lines, as a share of the stand-in face's scaled size.
| |
light.size-adjust | Not in CSS |
How much the stand-in face scales Arial so it is as wide as Funnel Display Light, measured as the regular one is.
| |
medium.size-adjust | Not in CSS |
How much the stand-in face scales Arial so it is as wide as Funnel Display Medium, measured as the regular one is.
| |
semibold.local | Not in CSS |
Arial's bold face, or Helvetica's, so the stand-in's letters are shaped as heavy as Funnel Display Semibold's.
| |
semibold.size-adjust | Not in CSS |
How much the stand-in face scales Arial Bold so it is as wide as Funnel Display Semibold, measured as the regular one is.
| |
bold.local | Not in CSS |
Arial's bold face, or Helvetica's, so the stand-in's letters are shaped as heavy as Funnel Display Bold's.
| |
bold.size-adjust | Not in CSS |
How much the stand-in face scales Arial Bold so it is as wide as Funnel Display Bold, measured as the regular one is.
| |
| Mono6 | |
stack | Not in CSS |
What follows Geist Mono in every text style that names it: its stand-in face, then the system's own.
| |
local | Not in CSS |
The fonts already on the reader's device that the stand-in face draws with: Courier New, or Courier where it is missing.
| |
size-adjust | Not in CSS |
How much the stand-in face scales Courier New so its average letter is as wide as Geist Mono's.
| |
ascent | Not in CSS |
Geist Mono's height above the baseline, as a share of the stand-in face's scaled size.
| |
descent | Not in CSS |
Geist Mono's depth below the baseline, as a share of the stand-in face's scaled size.
| |
line-gap | Not in CSS |
Geist Mono's extra room between lines, as a share of the stand-in face's scaled size.
| |
Text sizes
| Token | Phone | Desktop | CSS |
|---|---|---|---|
display-xl | 56px | 88px | --smbk-text-display-xl |
Font size for Display XL, phone (min) and desktop (max).
| |||
display-lg | 48px | 72px | --smbk-text-display-lg |
Font size for Display LG, phone (min) and desktop (max).
| |||
heading-xl | 40px | 56px | --smbk-text-heading-xl |
Font size for Heading XL, phone (min) and desktop (max).
| |||
heading-lg | 32px | 48px | --smbk-text-heading-lg |
Font size for Heading LG, phone (min) and desktop (max).
| |||
heading-md | 28px | 40px | --smbk-text-heading-md |
Font size for Heading MD, phone (min) and desktop (max).
| |||
heading-sm | 24px | 32px | --smbk-text-heading-sm |
Font size for Heading SM, phone (min) and desktop (max).
| |||
heading-xs | 20px | 28px | --smbk-text-heading-xs |
Font size for Heading XS, phone (min) and desktop (max).
| |||
heading-2xs | 18px | 24px | --smbk-text-heading-2xs |
Font size for Heading 2XS, phone (min) and desktop (max); 18 on a phone so each step has its own size.
| |||
body-lg | 20px | 20px | --smbk-text-body-lg |
Font size for Body LG, phone (min) and desktop (max).
| |||
body-md | 16px | 16px | --smbk-text-body-md |
Font size for Body MD, phone (min) and desktop (max). Fields use it: it never goes below 16 on a phone.
| |||
body-sm | 14px | 14px | --smbk-text-body-sm |
Font size for Body SM, phone (min) and desktop (max).
| |||
body-xs | 12px | 12px | --smbk-text-body-xs |
Font size for Body XS, phone (min) and desktop (max).
| |||
label-lg | 16px | 16px | --smbk-text-label-lg |
Font size for Label LG, phone (min) and desktop (max).
| |||
label-md | 14px | 14px | --smbk-text-label-md |
Font size for Label MD, phone (min) and desktop (max).
| |||
label-sm | 12px | 12px | --smbk-text-label-sm |
Font size for Label SM, phone (min) and desktop (max).
| |||
field-sm | 16px | 14px | --smbk-text-field-sm |
Font size for the text inside a small field (input, select, search field): 14 on a desktop, 16 on a phone, because iPhones zoom into a field with text under 16.
| |||