PREDICT uses two typefaces and one size scale. Good type does most of the work in a health interface: it makes the result, the range, and what to do next easy to find.

Typefaces

Neue Montreal is the brand typeface, used for everything from headlines to buttons. Geist Mono is for codes, IDs, tokens, and numbers that need to line up.

Neue Montrealfont-sans

Aa

ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789 .,:;!?()&@%+−×÷=

  • Biological age 45Light 300
    Large display text only.
  • Biological age 45Regular 400
    Body text and descriptions.
  • Biological age 45Medium 500
    Headings, labels, and buttons.
  • Biological age 45Bold 700
    Rare emphasis, such as a key number.
Geist Monofont-mono

Aa

ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789 ·−+=%

Sample ID
PRD-20481
Token
--status-normal
Z-score
+2.71
Unit
mg·dL⁻¹
FontClassWeightsLoaded in
Neue Montrealfont-sans (the default)300, 400, 500, 700apps/design/src/lib/fonts.ts, as --font-montreal
Geist Monofont-monoVariableapp/layout.tsx, from Google Fonts, as --font-mono
  • Neue Montreal is loaded in four weights only. font-semibold (600) has no file, so it renders as Bold. Use font-medium or font-bold so you get what you see in code.
  • font-sans is set on html, so you rarely need to write it.

Type scale

Ten sizes, from 72px down to 14px. Type in the box to try your own text.

text-heading-7272px · 4.5rem
Understand your biologyHero headlines on marketing pages.
text-heading-6464px · 4rem
Understand your biologyHero headlines.
text-heading-5656px · 3.5rem
Understand your biologyHero headlines on smaller screens.
text-heading-4848px · 3rem
Understand your biologyPage titles on landing pages.
text-heading-4040px · 2.5rem
Understand your biologyLarge section titles.
text-heading-3232px · 2rem
Understand your biologyh1. Page titles in the app.
text-heading-2424px · 1.5rem
Understand your biologyh2. Section titles.
text-heading-2020px · 1.25rem
Understand your biologyh3. Sub-sections and large cards.
text-heading-1616px · 1rem
Understand your biologyh4 and p. Body text.
text-heading-1414px · 0.875rem
Understand your biologysmall. Captions and metadata.

The tokens are defined in packages/ui/src/styles/typo.css and work like any Tailwind size: text-heading-32, md:text-heading-48.

TokenSizeRemDefault for
text-heading-7272px4.5rem—
text-heading-6464px4rem—
text-heading-5656px3.5rem—
text-heading-4848px3rem—
text-heading-4040px2.5rem—
text-heading-3232px2remh1
text-heading-2424px1.5remh2
text-heading-2020px1.25remh3
text-heading-1616px1remh4, p
text-heading-1414px0.875remsmall

The tokens set the font size only. Line height is inherited (1.5 by default), which is too loose for large headings. Add leading-tight (1.25) or leading-none to headings of 32px and up.

For interface text below 14px, use Tailwind's sizes: text-xs (12px) for captions and labels, and text-sm (14px) for compact body text in cards and tables.

Semantic defaults

typo.css styles plain HTML elements, so content looks right without classes.

ExampleElementStyle

Your October results

h1text-heading-32

Your October results

h2text-heading-24

Your October results

h3text-heading-20 font-medium

Your October results

h4text-heading-16

Your October results

ptext-heading-16 text-muted-foreground
Your October resultssmalltext-heading-14 text-muted-foreground
  • Every p is 16px and muted. Inside components, set the size and colour you need, such as text-sm text-foreground. Classes win over the defaults.
  • These defaults are in @layer base, so any utility class overrides them.
  • In docs pages, the MDX components add spacing on top, such as a top margin on headings.

Hierarchy

A report header built from the scale. One clear title, a muted line of context, and the result as the largest thing in its section.

Report

Your October results

Collected 12 Oct 2026 · 40 biomarkers

Inflammation

hs-CRP is above the healthy range. A recent cold or hard training can raise it.

3.5mg·L⁻¹

Healthy range 0.2–3.0 mg·L⁻¹

Text styles

The combinations used across PREDICT. Reuse them instead of inventing new ones.

RoleClassesExample
Hero titletext-4xl md:text-6xl font-medium tracking-tightThe home page headline
Page titletext-heading-32 leading-tight font-medium tracking-tight"Your October results"
Section titletext-heading-20 font-medium"Inflammation"
Card titletext-sm font-medium"Bio clock"
Overlinetext-xs font-medium tracking-[0.18em] uppercase text-muted-foreground"DESIGN SYSTEM"
Bodytext-sm or text-base, text-muted-foreground for descriptionsCard descriptions
Captiontext-xs text-muted-foreground"Healthy range 0.2–3.0"
Resultfont-mono tabular-nums with a large size"3.5"
Code and tokensfont-mono text-xs--primary

Details

Weight

  • Medium (500) for headings, labels, and buttons.
  • Regular (400) for body text.
  • Light (300) only for very large display text.
  • Bold (700) for rare emphasis, such as one key number. Never for whole paragraphs.

Letter spacing

  • Add tracking-tight to headings of 24px and up. Large type looks loose at the default spacing.
  • Leave body text at the default.
  • Uppercase overlines need extra space: tracking-[0.18em].

Line length

Keep paragraphs to about 65 characters a line with max-w-2xl. Long lines are hard to follow, especially in dense medical text.

Numbers

Use tabular-nums wherever numbers sit in columns or update live, so digits line up and don't shift.

LDL-C
185.5
HDL-C
35.7
TG
111.1
Proportional (default)
LDL-C
185.5
HDL-C
35.7
TG
111.1
tabular-nums
  • Write units with a middle dot and superscript minus: mg·dL⁻¹, mL·min⁻¹·1.73 m⁻². Put a space between the number and the unit.
  • Use an en dash for ranges, with no spaces: 0.2–3.0.
  • Use a real minus sign (−) for negative Z-scores in display text.

Case and punctuation

  • Use sentence case for headings, buttons, and labels: "Book a test", not "Book A Test".
  • Use uppercase only for short overlines.
  • Avoid exclamation marks. Results can be worrying; keep the tone calm.

Implementation

FileWhat it holds
packages/ui/src/styles/typo.cssThe text-heading-* scale and the semantic HTML defaults.
packages/ui/src/styles/globals.cssImports typo.css and maps font-sans to Neue Montreal.
apps/design/src/lib/fonts.tsLoads Neue Montreal from local files.
apps/design/src/app/layout.tsxLoads Geist Mono and adds both font variables to html.

To add a size, add it to the @theme block in typo.css:

Then use it as text-heading-28. Each app that uses @workspace/ui must load Neue Montreal and set --font-montreal itself, as apps/design does.