Typography
The type scale, weights, and families Propel ships — and the utilities that apply them.
Propel ships one type scale, applied through composite utilities. A single class sets font size, line height, letter spacing, and weight together, so a piece of text can’t end up with the size of one style and the leading of another.
<p class="text-body-sm-medium">Save changes</p>
Every name is text-<step>-<weight>: pick the step by the job the text does, then the weight by how
much emphasis it needs. There are 51 styles across three tiers — headings for
section titles, body for text meant to be read, and captions for text that labels something.
Propel replaces Tailwind’s type scale rather than adding to it. The theme resets --text-*,
--font-*, --font-weight-*, and --tracking-* to initial before declaring its own, so
Tailwind’s defaults such as text-sm, font-mono, and font-normal generate no CSS at all and
fail silently, inheriting whatever was set further up the tree. The
substitutions below list what to use instead.
Headings
Six steps from 32px down to 16px, all on a tight 1.2 leading (1.3 at h6). Pick the step by the level of the section, not by the size you want.
Composable primitives
Heading 1 — One per page — the page title. Nothing above it.
Weights: regular, medium, semibold, bold
- utility
- text-h1-semibold
- font-size
- 2rem / 32px
- line-height
- 1.2
- letter-spacing
- 0em
Composable primitives
Heading 2 — A major section of a page.
Weights: regular, medium, semibold, bold
- utility
- text-h2-semibold
- font-size
- 1.75rem / 28px
- line-height
- 1.2
- letter-spacing
- 0em
Composable primitives
Heading 3 — A subsection. The largest step most product UI needs.
Weights: regular, medium, semibold, bold
- utility
- text-h3-semibold
- font-size
- 1.5rem / 24px
- line-height
- 1.2
- letter-spacing
- 0em
Composable primitives
Heading 4 — Dialog and drawer titles, panel headers.
Weights: regular, medium, semibold, bold
- utility
- text-h4-semibold
- font-size
- 1.25rem / 20px
- line-height
- 1.2
- letter-spacing
- 0em
Composable primitives
Heading 5 — A heading inside an already-dense region.
Weights: regular, medium, semibold, bold
- utility
- text-h5-semibold
- font-size
- 1.125rem / 18px
- line-height
- 1.2
- letter-spacing
- 0em
Composable primitives
Heading 6 — Card and group titles. Leading opens to 1.3 — it sits close to body size.
Weights: regular, medium, semibold, bold
- utility
- text-h6-semibold
- font-size
- 1rem / 16px
- line-height
- 1.3
- letter-spacing
- 0em
Body
Three steps on a roomy 1.54 leading, tuned for reading more than one line. Body SM is the workhorse of product UI.
Behavior comes from Base UI; the look comes from Propel's tokens.
Body MD — Long-form prose and page intros. Cap the measure at 65–75 characters.
Weights: regular, medium, semibold, bold
- utility
- text-body-md-regular
- font-size
- 1rem / 16px
- line-height
- 1.54
- letter-spacing
- 0em
Behavior comes from Base UI; the look comes from Propel's tokens.
Body SM — The default for interface text — controls, menu rows, table cells, descriptions. Reach here first.
Weights: regular, medium, semibold, bold
- utility
- text-body-sm-regular
- font-size
- 0.875rem / 14px
- line-height
- 1.54
- letter-spacing
- 0em
Behavior comes from Base UI; the look comes from Propel's tokens.
Body XS — Dense interface text that still runs to multiple lines — sidebars, compact lists.
Weights: regular, medium, semibold, bold
- utility
- text-body-xs-regular
- font-size
- 0.8125rem / 13px
- line-height
- 1.54
- letter-spacing
- 0em
Captions
Four steps at 1.2 leading for text that labels something rather than being read as prose. The bottom two open their tracking to 0.01em to stay legible.
Updated 2 hours ago
Caption MD — Field labels, badge text, section eyebrows, metadata rows.
Weights: regular, medium, semibold, bold
- utility
- text-caption-md-medium
- font-size
- 0.75rem / 12px
- line-height
- 1.2
- letter-spacing
- 0em
Updated 2 hours ago
Caption SM — Secondary metadata and helper text under a control.
Weights: regular, medium, semibold, bold
- utility
- text-caption-sm-medium
- font-size
- 0.6875rem / 11px
- line-height
- 1.2
- letter-spacing
- 0em
Updated 2 hours ago
Caption XS — Counters and chips where space is genuinely scarce.
Weights: regular, medium, semibold, bold
- utility
- text-caption-xs-medium
- font-size
- 0.625rem / 10px
- line-height
- 1.2
- letter-spacing
- 0.01em
Updated 2 hours ago
Caption 2XS — The floor of the scale — numeric badges only. Never a sentence, and never the only carrier of a meaning.
Weights: regular, medium, semibold
- utility
- text-caption-2xs-medium
- font-size
- 0.5625rem / 9px
- line-height
- 1.2
- letter-spacing
- 0.01em
Weights
Text styles use four of the six declared weights. Propel’s regular is 450 rather than the usual 400, because Inter Variable reads slightly light at 400 for interface text, so the whole scale sits half a step up.
The quick brown fox jumps
regular · 450
The quick brown fox jumps
medium · 500
The quick brown fox jumps
semibold · 600
The quick brown fox jumps
bold · 700
light and heavy are declared as primitives but no text style uses them; reach for one only when
a composite genuinely can’t express what you need.
Font families
Two faces do all the work: Inter for the interface, IBM Plex Mono for anything read character by character. Propel names them but bundles no font files — see Installation for self-hosting, or let the stacks fall back to the system fonts.
The composite styles set size, leading, tracking, and weight — never the family. Set the family
once at the root and let it inherit; font-code is the only one worth repeating locally.
Every text style
The complete index. Sizes are shown at the 16px root the scale is authored against.
Font size
The composites are built from a numeric size scale, named for the pixel value at a 16px root, so
text-14 is 0.875rem. It is the primitive layer, not a shortcut: a step sets font-size alone,
so text using one opts out of the leading, tracking and weight a real text style carries and
inherits whatever is around it instead. Reach for a composite every time — propel/no-raw-font-size
makes a bare step an error in the library, and the same rule runs over this site.
Letter spacing
Tracking is deliberately near zero, since Inter needs no dramatic tightening at interface sizes.
Every text style uses tracking-default except the two smallest captions, which open to a literal
0.01em.
Substitutions for Tailwind’s defaults
Propel’s reset removes these; each has a direct replacement.
leading-* is the exception. Propel doesn’t reset it, so Tailwind’s line-height utilities still
work, though they are rarely needed since every text style brings its own.
Guidelines
A heading token does not set the element. Choose <h1> through <h6> from the document’s real
structure, because screen reader users navigate by heading level, then apply whichever step the
design calls for. A card title inside a page section is often <h3 class="text-h6-semibold">, and
that is correct.
Don’t restate what a composite already sets. Stacking leading-*, font-*, or tracking-* on top
of text-body-md-regular fights the pairing the token exists to guarantee, and which declaration
wins comes down to Tailwind’s utility ordering rather than the order the classes are written. A
design needing a different combination needs a different step.
Cap long-form text at 65–75 characters per line and leave it at text-body-md-regular. The 1.54
leading on the body tier is what makes multi-line text comfortable, while the caption tier’s 1.2
leading is for single lines, so a paragraph set in a caption style reads as cramped.
Text below text-caption-md-* is for labels and counters rather than content a reader must not
miss. Pair the 9px and 10px steps with color, icon, or position instead of letting size carry the
meaning alone.