---
title: "Typography"
description: "The three type families, the sixteen-step scale, and the rules for using them."
url: https://ui.clinia.dev/docs/typography
---
# Typography

## Type families

Three licensed families are available in the Clinia design:

| Utility | Family | Use |
|---|---|---|
| `font-display` | NaN Serf B | Headlines, display text |
| `font-sans` | CircularXX | UI, body text |
| `font-mono` | CircularXX Mono | Code, tokens |

- **Display** (`font-display`, NaN Serf B) - Used by default for headlines, hero copy, and every step in the Display and Title scale.
- **Sans** (`font-sans`, CircularXX) - The default for the rest of the text sections, including body copy, labels, buttons, form fields, navigation.
- **Mono** (`font-mono`, CircularXX Mono) - The default for eyebrow labels and code.

  ex: Eyebrow label

## Scale

Sixteen font sizes covering hero text, down to a 10px eyebrow. Each group (Display, Title, Body and Eyebrow) has its own job and family, so sizes overlap between groups.

**Display** (`font-display`): Marketing heroes and campaign headlines.

| Step | Class | Size |
|---|---|---|
| Display XL | `text-display-xl` | 6rem |
| Display L | `text-display-l` | 5.5rem |
| Display M | `text-display-m` | 4.5rem |
| Display S | `text-display-s` | 3.5rem |

**Title** (`font-display`): Headings, H1 to H4: page, section, subsection, card.

| Step | Class | Size |
|---|---|---|
| Title XL | `text-title-xl` | 5rem |
| Title L | `text-title-l` | 4rem |
| Title M | `text-title-m` | 2.5rem |
| Title S | `text-title-s` | 2rem |
| Title XS | `text-title-xs` | 1.5rem |

**Body** (`font-sans`): Running text and UI: paragraphs, labels, buttons, fields.

| Step | Class | Size |
|---|---|---|
| Body XL | `text-body-xl` | 2rem |
| Body L | `text-body-l` | 1.5rem |
| Body M | `text-body-m` | 1rem |
| Body S | `text-body-s` | 0.875rem |
| Body XS | `text-body-xs` | 0.75rem |

**Eyebrow** (`font-mono uppercase tracking-widest`): Section labels above a heading.

| Step | Class | Size |
|---|---|---|
| Eyebrow L | `text-eyebrow-l` | 1rem |
| Eyebrow S | `text-eyebrow-s` | 0.625rem |

## Sizes off the scale

An app moving to Clinia UI maps each size it uses to a step, as in the table. Sizes under 16px move up a pixel or two, which makes those screens less dense. Sizes from 17 to 19px move down to `body-m` (16px), and headings from 20 to 28px land on `title-xs` (24px) from either side. Compare each screen before and after.

| Size in the app | Step |
|---|---|
| 9 to 10px | `eyebrow-s` for an eyebrow label (mono, uppercase), otherwise `body-xs` |
| 11 to 12px | `body-xs` |
| 13 to 14px | `body-s` |
| 15 to 19px | `body-m` |
| 20 to 28px, headings | `title-xs` |
| Larger headings | The nearest Title step |

Tailwind's `text-xs`, `text-sm` and `text-base` are allowed. They're the same sizes as `body-xs`, `body-s` and `body-m`, and the components use them. They also set Tailwind's line height, which the scale steps leave to the surrounding text.

## Headings

Showcases how headings (H1 to H6) map onto the allowed size scale. H1 to H4 use NaN Serf B, H5 and H6 use CircularXX Medium.

| Heading | Classes | Size |
|---|---|---|
| H1 | `font-display text-title-l tracking-tight` | 4rem |
| H2 | `font-display text-title-m tracking-tight` | 2.5rem |
| H3 | `font-display text-title-s tracking-tight` | 2rem |
| H4 | `font-display text-title-xs` | 1.5rem |
| H5 | `font-sans text-body-m font-medium` | 1rem |
| H6 | `font-sans text-body-s font-medium` | 0.875rem |

## Weights

Five weights across the three families, to keep the range tight: CircularXX has three, CircularXX Mono and NaN Serf B have one each.

| Family | Weight | Class |
|---|---|---|
| CircularXX | Book 400 | `font-sans font-normal` |
| CircularXX | Regular 450 | `font-sans font-[450]` |
| CircularXX | Medium 500 | `font-sans font-medium` |
| CircularXX Mono | Regular 400 | `font-mono font-normal` |
| NaN Serf B | Book 400 | `font-display font-normal` |

## Italic

Only CircularXX has italics, in Book 400 and Medium 500. NaN Serf B and CircularXX Mono have none, so `italic` on them does not render.

_Live example: see the web page._

Headlines carry no emphasis on a single word. NaN Serf B has one weight and no italic, so an `<em>` or a `<strong>` in a display line renders like the rest of it, with no warning. Write the line so it doesn't need one, and drop the tag.

## Links

Links keep the text colour, in Medium, and carry a thin `accent` underline (Trust, `#95795C`) set a little below the text. Trust sits on the underline only. A hovered link dims slightly, and a focused one shows the focus ring.

- Keep the underline at the font's own thickness. A thicker or text-coloured underline makes a paragraph of links read as bold.
- Never set link text in Trust: at body size it measures 4.06:1 on white, under AA.
- A heading's anchor link stays plain: the heading is already the link.

_Live example: see the web page._

For the container widths and rhythm that type sits inside, see [Containers](https://ui.clinia.dev/docs/containers). For type space and case per surface, see [App getting started](https://ui.clinia.dev/docs/app/getting-started) and [Marketing getting started](https://ui.clinia.dev/docs/marketing/getting-started).

## Build reference

### Link styles

On an element, the classes Clinia's docs use:

```tsx
<a className="font-medium text-foreground underline decoration-accent underline-offset-4 rounded-xs hover:opacity-80 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2">
```

In CSS, for prose a framework styles, such as Fumadocs' typography plugin:

| Property | Value |
|---|---|
| `color` | `var(--foreground)` |
| `font-weight` | `500` |
| `text-decoration-line` | `underline` |
| `text-decoration-color` | `var(--accent)` |
| `text-decoration-thickness` | `auto` |
| `text-underline-offset` | `4px` |
| `opacity` on hover | `0.8` |

Exclude links inside headings, which frameworks use as section anchors.
