---
title: "Fonts"
description: "Font family tokens, the fallback stack every family carries, and weight names."
requested_language: fr
language: en
translation_notice: "This page isn't translated yet"
url: https://docs.systhema.app/fr/next/design/fonts
version: unreleased (main)
docs_index: https://docs.systhema.app/fr/next/llms.txt
---
> This page isn't translated yet. Showing English.


Font tokens in the `font` collection set each text style's family and weight. Two root families, the default body and heading families, are referenced by every other font token. This page covers the value format both need.

## Fallback stacks

A `fontFamily` token is emitted into CSS **verbatim** — `font.default.body.fontFamily` becomes `--font-default-body-font-family`, and every other font token in the system (`font.h1`, `font.button.primary`, `font.chip`, …) references one of the two roots:

```text
font.default.body.fontFamily     →  --font-default-body-font-family
font.default.heading.fontFamily  →  --font-default-heading-font-family
```

So the value must be a complete CSS `font-family` list, not a bare family name. Webfonts load with `font-display: swap` (what `next/font` uses by default), which means the browser paints once **before** the face arrives. With a bare `"Geist"` there is nothing to paint with, so it falls back to its built-in serif — a visible Times New Roman flash on every cold load, worst on headings. Systhema's own defaults therefore ship a stack:

```json
{
  "font": {
    "default": {
      "body": {
        "fontFamily": {
          "$type": "string",
          "$value": "Geist, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
        }
      }
    }
  }
}
```

When you swap in your own family, keep the tail and match the **category** of the face you picked — a serif brand font needs a serif tail, a mono needs a mono tail:

| Brand font is… | Tail to append                                                               |
| -------------- | ---------------------------------------------------------------------------- |
| sans           | `system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif` |
| serif          | `Georgia, 'Times New Roman', Times, serif`                                   |
| mono           | `ui-monospace, SFMono-Regular, Menlo, Consolas, monospace`                   |

Multi-word names go in quotes (`'Segoe UI'`); the Tailwind bridge reads the first entry as the family key, so `font-geist` still resolves the whole stack.

`systhema upgrade` back-propagates the stack onto projects still running the stock `Geist` default. A project that already customised the family is **never** rewritten — you own the tail from then on.

The [Figma plugin](https://docs.systhema.app/fr/next/design/figma/export.md#font-families-carry-a-css-fallback-stack) appends the same stack on export.

## Weight names

A `fontWeight` token may be a number (`700`) or the style name the family itself uses (`Bold`, `SemiBold`, `Extra Bold`). Names are resolved to the numeric CSS weight, and the separator is irrelevant — closed-up, spaced, hyphenated and underscored spellings of the same name all resolve identically, and an appended `Italic` sets `font-style` without changing the weight:

| Token value                                 | `font-weight` |
| ------------------------------------------- | ------------- |
| `Thin` / `Hairline`                         | `100`         |
| `ExtraLight` / `Extra Light` / `UltraLight` | `200`         |
| `Light`                                     | `300`         |
| `Regular` / `Normal` / `Book`               | `400`         |
| `Medium`                                    | `500`         |
| `SemiBold` / `Semi Bold` / `DemiBold`       | `600`         |
| `Bold`                                      | `700`         |
| `ExtraBold` / `Extra-Bold` / `UltraBold`    | `800`         |
| `Black` / `Heavy`                           | `900`         |
| `ExtraBlack` / `Ultra Black`                | `950`         |
| `750` (any bare number)                     | `750`         |

A token reference (`{font.h1.fontWeight}`) is passed through untouched, and anything unrecognised falls back to `400`.
