---
title: Typography
description: One variable family used in earnest — Bricolage Grotesque, axes opsz 12–96 and weight 200–800.
---

## One family, three axes

Nibiru uses **Bricolage Grotesque** (free, Google Fonts) for every piece of text. The trick is that it's a **variable font** with two meaningful axes:

- **Optical size (`opsz`, 12–96)** — display sizes get characterful, narrowed, slightly squarer; body sizes get calmer and more open.
- **Weight (`wght`, 200–800)** — full range available.
- **Italic** — true italic, not slanted.

So a single font file gives us a display face *and* a body face. No need to load extra fonts.

```css
font-family: 'Bricolage Grotesque', system-ui, sans-serif;
font-variation-settings: 'opsz' 96, 'wght' 600;   /* display */
font-variation-settings: 'opsz' 14, 'wght' 400;   /* body */
```

Code uses **JetBrains Mono** because it's quietly excellent at code and pairs well.

## Variation presets (the building blocks)

| Token | Variation | Use |
|---|---|---|
| `--nibiru-fv-display-hero`   | `'opsz' 96, 'wght' 600` | Hero H1 |
| `--nibiru-fv-display-large`  | `'opsz' 64, 'wght' 600` | H2 |
| `--nibiru-fv-display-medium` | `'opsz' 36, 'wght' 600` | H3 |
| `--nibiru-fv-heading-small`  | `'opsz' 18, 'wght' 600` | H4 |
| `--nibiru-fv-lead`           | `'opsz' 24, 'wght' 400` | Lead paragraph |
| `--nibiru-fv-body`           | `'opsz' 14, 'wght' 400` | Body |
| `--nibiru-fv-body-bold`      | `'opsz' 14, 'wght' 600` | Strong |
| `--nibiru-fv-label`          | `'opsz' 12, 'wght' 600` | Labels, eyebrow |

## Type scale

| Token | Size | Use |
|---|---|---|
| `--nibiru-text-xs`   | 0.72rem | Eyebrow / labels |
| `--nibiru-text-sm`   | 0.85rem | Captions |
| `--nibiru-text-md`   | 0.92rem | UI controls, sidebar |
| `--nibiru-text-base` | 1.00rem | Body |
| `--nibiru-text-lg`   | 1.18rem | Lead paragraph |
| `--nibiru-text-xl`   | 1.45rem | Section intros |
| `--nibiru-text-2xl`  | 2.00rem | H3 |
| `--nibiru-text-3xl`  | 2.60rem | H2 |
| `--nibiru-text-hero` | clamp(2.6rem, 1.8rem + 4vw, 4.8rem) | H1, hero |

## Tracking

Tracking tightens as size grows — that's how you keep a hero feeling dense and a body feeling open.

| Token | Value | Use |
|---|---|---|
| `--nibiru-tracking-display` | −0.04em | Hero / H1 |
| `--nibiru-tracking-heading` | −0.025em | H2, H3 |
| `--nibiru-tracking-body`    | −0.005em | Body |
| `--nibiru-tracking-label`   | 0.10em | Uppercase labels |
| `--nibiru-tracking-eyebrow` | 0.22em | Hero eyebrow, section numbers |

## A hero, written out

```css
h1.atelier-hero__title {
  font-family: var(--nibiru-font-display);
  font-variation-settings: var(--nibiru-fv-display-hero);
  font-size:        var(--nibiru-text-hero);
  letter-spacing:   var(--nibiru-tracking-display);
  line-height:      0.96;
  color:            var(--nibiru-ink);
  max-width:        16ch;
}

h1.atelier-hero__title em {
  font-style: normal;
  color: var(--nibiru-iris-deep);
  position: relative;
}
h1.atelier-hero__title em::after {
  content: '';
  position: absolute;
  inset: auto 0 0.05em 0;
  height: 0.18em;
  background: var(--nibiru-aurum);
  opacity: 0.3;
  z-index: -1;
}
```

That's a hero. The italic word gets a single gold-leaf underline. Nothing else needs decoration.

## A body, written out

```css
body, .prose p {
  font-family: var(--nibiru-font-text);
  font-variation-settings: var(--nibiru-fv-body);
  font-size: var(--nibiru-text-base);
  line-height: 1.7;
  letter-spacing: var(--nibiru-tracking-body);
  color: var(--nibiru-ink);
}
```

## Don't

- Don't use Bricolage Grotesque at the same OPSZ for hero and body — that wastes its variable axis.
- Don't bold body text below `wght: 600`. Below 600 it doesn't read as bold.
- Don't track display text positively. Tighten as size grows.
- Don't use Bricolage Italic for whole sentences — use it for single words inside a heading. The "*Impress.*" trick on the splash page is the reference.
