Qure UI

Typography

The sixteen named text styles, as Tailwind utilities.

The design system names its text styles rather than numbering them, and each name carries four things at once: size, leading, weight and tracking. They are declared as Tailwind font-size theme keys, so one utility applies the whole style.

<h2 className="text-heading">Findings</h2>
<p className="text-body-base">Right upper lobe nodule, 8mm, spiculated margins.</p>
<span className="text-label-emphasis text-muted-foreground">ACC-482913</span>

Prefer these to text-sm font-medium. The pair happens to be right today and drifts the moment the scale moves; text-body-small cannot.

The scale

text-title-hero48/56 Bold, −2%

Title Hero — CT chest, ACC-482913

text-title-page32/40 Bold, −2%

Title Page — CT chest, ACC-482913

text-subtitle24/28 Regular

Subtitle — CT chest, ACC-482913

text-heading20/32 Medium, −2%

Heading — CT chest, ACC-482913

text-subheading16/20 Regular

Subheading — CT chest, ACC-482913

text-body-base16/24 Regular

Body — CT chest, ACC-482913

text-body-emphasis16/24 Medium

Body Emphasis — CT chest, ACC-482913

text-body-strong16/24 SemiBold

Body Strong — CT chest, ACC-482913

text-body-small14/20 Regular

Body Small — CT chest, ACC-482913

text-body-small-strong14/20 SemiBold

Body Small Strong — CT chest, ACC-482913

text-label-base12/16 Regular

Label — CT chest, ACC-482913

text-label-emphasis12/16 Medium

Label Emphasis — CT chest, ACC-482913

text-label-strong12/16 SemiBold

Label Strong — CT chest, ACC-482913

text-label-caps uppercase12/16 Regular, +8%, uppercase

Label Caps — CT chest, ACC-482913

text-label-small10/12 Regular

Label Small — CT chest, ACC-482913

text-label-small-strong10/12 SemiBold

Label Small Strong — CT chest, ACC-482913

const styles = [  { cls: 'text-title-hero', name: 'Title Hero', spec: '48/56 Bold, −2%' },  { cls: 'text-title-page', name: 'Title Page', spec: '32/40 Bold, −2%' },  { cls: 'text-subtitle', name: 'Subtitle', spec: '24/28 Regular' },  { cls: 'text-heading', name: 'Heading', spec: '20/32 Medium, −2%' },  { cls: 'text-subheading', name: 'Subheading', spec: '16/20 Regular' },  { cls: 'text-body-base', name: 'Body', spec: '16/24 Regular' },  { cls: 'text-body-emphasis', name: 'Body Emphasis', spec: '16/24 Medium' },  { cls: 'text-body-strong', name: 'Body Strong', spec: '16/24 SemiBold' },  { cls: 'text-body-small', name: 'Body Small', spec: '14/20 Regular' },  { cls: 'text-body-small-strong', name: 'Body Small Strong', spec: '14/20 SemiBold' },  { cls: 'text-label-base', name: 'Label', spec: '12/16 Regular' },  { cls: 'text-label-emphasis', name: 'Label Emphasis', spec: '12/16 Medium' },  { cls: 'text-label-strong', name: 'Label Strong', spec: '12/16 SemiBold' },  { cls: 'text-label-caps uppercase', name: 'Label Caps', spec: '12/16 Regular, +8%, uppercase' },  { cls: 'text-label-small', name: 'Label Small', spec: '10/12 Regular' },  { cls: 'text-label-small-strong', name: 'Label Small Strong', spec: '10/12 SemiBold' },]/** * Every named style, at its own size. The specimen is a clinical sentence * rather than "The quick brown fox" — the scale has to survive accession * numbers and units, which is where a type scale usually shows its seams. */export default function TypographyScale() {  return (    <div className="flex w-full flex-col gap-6">      {styles.map(style => (        <div key={style.cls} className="flex flex-col gap-1">          <div className="text-label-base text-muted-foreground flex flex-wrap items-baseline gap-x-3">            <code>{style.cls}</code>            <span>{style.spec}</span>          </div>          <p className={style.cls}>{style.name} — CT chest, ACC-482913</p>        </div>      ))}    </div>  )}

The three that are not keys

body-italic, body-link and label-link differ from their base style by one property that a font-size key cannot carry, so they are a utility plus a modifier:

StyleWrite
Body Italictext-body-base italic
Body Linktext-body-base underline
Label Linktext-label-base underline

text-transform is in the same position, which is why Label Caps is text-label-caps uppercase — the key carries the 8% tracking that makes capitals legible, and uppercase does the rest. Do not uppercase a Body or Heading style by hand: they have no tracking to spare and set solid.

Choosing one

The hierarchy nests, and skipping a level is usually a mistake:

Title Hero        a hero banner, once per product
Title Page        the primary page heading
  Subtitle        alongside or beneath a Title Page
    Heading       a section within a page
    Subheading    a sub-section label
      Body        default prose
      Body Small  supporting and meta content
        Label     UI labels, tags, timestamps
        Label Small  micro labels and footnotes

A few rules worth stating:

  • Title styles do not go inside cards or panels. Use Heading. A card with a Title Page in it is competing with the page it sits on.
  • 14px is the floor for reading-length content. 12px Label is for a word or two — a tag, a timestamp, a column header — not a sentence somebody has to get through.
  • Weight carries meaning. Regular is body, Medium is emphasis and heading hierarchy, SemiBold is strong emphasis and table column headers, Bold is display titles only.
  • Do not signal a link with colour alone. Body Link is underlined for that reason.

Where the numbers come from

The same Figma file as the colour tokens, corroborated twice: the SDS config the qtrack app ships and the Figma export agree on every style. Where they differed — Label Caps at weight 400 or 500 — the export wins, being the only one of the two that carries exact numbers rather than a summary.

The scale lives in registry/styles/theme-qure.css, declared as Tailwind font-size theme keys so that one utility carries size, leading, weight and tracking together.

The typeface

IBM Plex Sans, loaded through next/font so the page does not depend on fonts.googleapis.com being reachable.

--font-sans: var(--font-ibm-plex-sans), system-ui, -apple-system, sans-serif;

The token export disagrees with itself here, and it is worth knowing which way to resolve it. --font-family-sans is a bare "Inter", while --body-font-family, --heading-font-family and every --title-*-font-family in the same file route through --ibm-plex-sans. Three other sources settle it: the Figma export's own --font-sans, its "IBM Plex Sans throughout" header, and the qtrack app, which ships Plex. --font-family-sans is a leftover — do not reference it.

On this page