Typo­graphy

Our typography sits at the heart of our design system. Good typography is vital to readability, design and the success of our content.

This page covers the design system. For implementation details, see Tokens (type scale + token names), CSS (where the rules live), and Utilities (type scale helpers).

Fonts

Our font is Bely, designed by French designer Roxane Gataud and published by TypeTogether. The font is both classical and modern, weighty and playful, with good readability and a striking display style which we use for page and section headings. Gataud designed Bely before graduating from Amiens.

Bold and Bely Italic are used, sparingly, for emphasis.

We have both a desktop and a web licence for Bely, which is also available through Adobe Fonts.

Courier New is a monospaced font reserved for code.

Bely Display

The quick brown fox jumps over the lazy dog.

Bely

Jinxed wizards pluck ivy from the big quilt.

Bely Bold

Amazingly few discotheques provide jukeboxes.

Bely Italic

Pack my box with five dozen liquor jugs.

Courier New

How vexingly quick daft zebras jump!

Website typography

On our website, typography is driven by CSS custom properties in design-tokens.css and global element styles in global.css.

Core tokens

:root {
  --base-font-size: 24px;
  --text-multiplier: 1;
  --heading-line-height: 1.2em;
  --body-line-height: 1.4em;

  --font-body: 'Bely', serif;
  --font-heading: 'Bely', serif;
  --font-heading-display: 'Bely display', serif;
  --font-mono: 'Courier New', monospace;
}

Responsive sizing is handled by adjusting --text-multiplier at multiple breakpoints. Most text on the site scales automatically through that token.

Type scale and weights

Heading sizes are derived from --base-font-size and --text-multiplier. Font weights are defined as tokens for consistency across components.

:root {
  /* Font sizes */
  --font-size-xs: 12px;
  --font-size-sm: 14px;
  --font-size-base: var(--base-font-size);
  --font-size-h3: calc(1.5em * var(--text-multiplier));
  --font-size-h2: calc(2.8em * var(--text-multiplier));
  --font-size-h1: calc(3.5em * var(--text-multiplier));

  /* Font weights */
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
}

Headings

H1 heading

Bely display is used for our h1 page headings and some important section headings too.

H2 heading

We follow a strictly hierarchical heading structure, making h2s an especially important level.

H3 heading

H3 is used infrequently for subheadings.

H4 heading

H4 is there to be used in extremis.

Forcing the display face

Headings use --font-heading, except h1 which uses the display face (--font-heading-display).

Display heading

Use .display-heading when you want to use Bely Display on headings other than h1. We do this with h2s on prominent sections on multi-section pages.

Scaling up for emphasis

Intro text with .large

Intro text with .larger

<h1>Page heading (h1)</h1>
<h2>Section heading (h2)</h2>
<h3>Subheading (h3)</h3>

<h2 class="display-heading">Use .display-heading to force display font</h2>

<p class="intro large">Use .large / .larger to scale typography up</p>

Body copy

Body copy is made up of paragraphs, lists and quotes. It inherits font-family: var(--font-body), uses --line-height-normal, and scales with --text-multiplier.

Bold is semantic (<strong>) and italic uses the italic face.

Keep paragraphs short, with one idea per paragraph.

Line spacing

Default line spacing is controlled by --line-height-normal (body copy) and --heading-line-height (headings). We also have a line-height scale (--line-height-tight to --line-height-loose) for deliberate overrides.

Snug line spacing (--line-height-snug). Useful for compact UI labels and short snippets, but avoid for long reading.

Relaxed line spacing (--line-height-relaxed). Useful for highly legible reading experiences, but can feel slow.

:root {
  /* Defaults */
  --heading-line-height: 1.2em;
  --body-line-height: 1.4em;

  /* Line-height scale */
  --line-height-tight: 1;
  --line-height-snug: 1.2;
  --line-height-normal: 1.4;
  --line-height-relaxed: 1.7;
  --line-height-loose: 1.8;
}

.tight {
  line-height: var(--line-height-snug);
}

.loose {
  line-height: var(--line-height-relaxed);
}

Text utilities

This is .intro.

This is .small.

Typographic marks

We use an en dash () for number ranges (e.g. 1–10) and as a parenthetical dash (e.g. content – not layout). We don’t use em dashes ().

We use curly quotes: single (‘ ’) and double (“ ”), including curly apostrophes (’). We use double quotes in the first instance and single quotes inside those to denote quoted quotes.

We don’t use the Oxford comma: apples, pears and oranges.

If you’re writing in Markdown/MDX, our Smartypants setup will usually convert straight quotes and double hyphens automatically. If you’re writing in HTML, type the characters directly.

Inline links are standardly fire, with a sunshine underline on hover. We adjust link colours depending on background.

Linked section heading

Headings use a slightly thinner underline on hover than body links.

<p>
  <a href="#">Inline link</a> inside a paragraph.
</p>

<h2><a href="#">Linked section heading</a></h2>

Lists

  • List items inherit body type and line-height.
  • Use for short, scannable points.
  1. Ordered lists are the same, but numbered.
  2. Use for sequences.
<ul>
  <li>List items inherit body type and line-height.</li>
  <li>Use for short lists and checklists.</li>
</ul>

<ol>
  <li>Ordered lists are styled the same way.</li>
  <li>Use for sequences.</li>
</ol>

Blockquotes

Few people set out to produce content that bores, confuses, and irritates users, yet the web is filled with fluffy, purposeless, and annoying content.

Erin Kissane
<blockquote>
  <p>Few people set out to produce content that bores, confuses, and irritates users, yet the web is filled with fluffy, purposeless, and annoying content.</p>
  <cite>Erin Kissane</cite>
</blockquote>

Code

Inline code: --text-multiplier.

const hello = 'world';
console.log(hello);
<p>Inline code uses <code>&lt;code&gt;</code>.</p>

<pre><code>const hello = 'world';
console.log(hello);
</code></pre>