Propel

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.

UtilityValueStylesUsed for
font-light300none
font-regular45013Body copy and long-form prose. Propel's true body weight.
font-medium50013UI labels, buttons, table headers — emphasis without a heading.
font-semibold60013Headings and section titles.
font-bold70012The strongest emphasis a text style carries.
font-heavy800none

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.

UtilityFaceUsed for
font-bodyInter VariableEverything that isn't code. The default — set once on the page, rarely restated.
font-headingInter VariableHeadings. Declared separately so the two can diverge later; today it resolves to the same stack as font-body.
font-codeIBM Plex MonoCode, API identifiers, and any value meant to be read character by character.

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.

UtilitySizeLine heightWeightLetter spacing
text-h1-regular2rem / 32px1.24500em
text-h1-medium2rem / 32px1.25000em
text-h1-semibold2rem / 32px1.26000em
text-h1-bold2rem / 32px1.27000em
text-h2-regular1.75rem / 28px1.24500em
text-h2-medium1.75rem / 28px1.25000em
text-h2-semibold1.75rem / 28px1.26000em
text-h2-bold1.75rem / 28px1.27000em
text-h3-regular1.5rem / 24px1.24500em
text-h3-medium1.5rem / 24px1.25000em
text-h3-semibold1.5rem / 24px1.26000em
text-h3-bold1.5rem / 24px1.27000em
text-h4-regular1.25rem / 20px1.24500em
text-h4-medium1.25rem / 20px1.25000em
text-h4-semibold1.25rem / 20px1.26000em
text-h4-bold1.25rem / 20px1.27000em
text-h5-regular1.125rem / 18px1.24500em
text-h5-medium1.125rem / 18px1.25000em
text-h5-semibold1.125rem / 18px1.26000em
text-h5-bold1.125rem / 18px1.27000em
text-h6-regular1rem / 16px1.34500em
text-h6-medium1rem / 16px1.35000em
text-h6-semibold1rem / 16px1.36000em
text-h6-bold1rem / 16px1.37000em
text-body-md-regular1rem / 16px1.544500em
text-body-md-medium1rem / 16px1.545000em
text-body-md-semibold1rem / 16px1.546000em
text-body-md-bold1rem / 16px1.547000em
text-body-sm-regular0.875rem / 14px1.544500em
text-body-sm-medium0.875rem / 14px1.545000em
text-body-sm-semibold0.875rem / 14px1.546000em
text-body-sm-bold0.875rem / 14px1.547000em
text-body-xs-regular0.8125rem / 13px1.544500em
text-body-xs-medium0.8125rem / 13px1.545000em
text-body-xs-semibold0.8125rem / 13px1.546000em
text-body-xs-bold0.8125rem / 13px1.547000em
text-caption-md-regular0.75rem / 12px1.24500em
text-caption-md-medium0.75rem / 12px1.25000em
text-caption-md-semibold0.75rem / 12px1.26000em
text-caption-md-bold0.75rem / 12px1.27000em
text-caption-sm-regular0.6875rem / 11px1.24500em
text-caption-sm-medium0.6875rem / 11px1.25000em
text-caption-sm-semibold0.6875rem / 11px1.26000em
text-caption-sm-bold0.6875rem / 11px1.27000em
text-caption-xs-regular0.625rem / 10px1.24500.01em
text-caption-xs-medium0.625rem / 10px1.25000.01em
text-caption-xs-semibold0.625rem / 10px1.26000.01em
text-caption-xs-bold0.625rem / 10px1.27000.01em
text-caption-2xs-regular0.5625rem / 9px1.24500.01em
text-caption-2xs-medium0.5625rem / 9px1.25000.01em
text-caption-2xs-semibold0.5625rem / 9px1.26000.01em

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.

UtilityrempxNote
text-90.5625rem9px
text-100.625rem10px
text-110.6875rem11px
text-120.75rem12px
text-130.8125rem13px
text-140.875rem14px
text-161rem16px
text-181.125rem18px
text-201.25rem20px
text-241.5rem24px
text-281.75rem28px
text-322rem32px
text-402.5rem40pxDeclared, but no text style uses this step.

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.

UtilityValueStyles
tracking-extra-tight-0.004emnone
tracking-tight-0.002emnone
tracking-default0em44
tracking-wide0.002emnone

Substitutions for Tailwind’s defaults

Propel’s reset removes these; each has a direct replacement.

Tailwind defaultPropel equivalentNote
text-xs … text-9xltext-body-sm-regular, text-14The whole t-shirt scale is removed. Use a composite style, or a numeric step for a one-off.
font-sansfont-bodyfont-heading is declared separately and currently resolves to the same stack.
font-monofont-code
font-normalfont-regularPropel's regular is 450, not 400. font-thin, font-extrabold, and font-black are also gone.
tracking-normaltracking-defaulttracking-tight survives the reset but is redeclared at -0.002em, not Tailwind's -0.025em.

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.