
# Échelle typographique

La section typographique d'une charte de marque est une échelle : le titre d'ouverture, puis les niveaux de titre, puis le texte courant, puis les mentions. Chaque barreau est un triplet solidaire — une taille, l'interlignage qui va avec, et la graisse dans laquelle il est composé. `design.typeScale` est l'endroit où vit cette échelle.

```yaml
design:
  typeScale:
    h1:
      size: '3rem'
      lineHeight: 1.1
      weight: 700
      letterSpacing: '-0.02em'
    body:
      size: '1rem'
      lineHeight: 1.6
    caption:
      size: '0.8125rem'
      lineHeight: 1.4
```

Tous les niveaux sont optionnels. Une application qui ne déclare que `h1` et `body` possède une échelle réelle, quoique courte : la clé est faite pour être adoptée un barreau à la fois.

## Les douze niveaux

L'ensemble est fermé, et l'ordre ci-dessous est celui dans lequel l'échelle est publiée — du plus grand au plus petit — quel que soit l'ordre dans lequel vous avez écrit les clés.

| Niveau      | Ce que c'est                                                          |
| ----------- | --------------------------------------------------------------------- |
| `display`   | La taille d'ouverture de page, unique, au-dessus de `h1`.             |
| `h1`        | Titre de page. Un seul par page.                                      |
| `h2`        | Titre de section.                                                     |
| `h3`        | Titre de sous-section.                                                |
| `h4`        | Titre de quatrième niveau.                                            |
| `h5`        | Titre de cinquième niveau.                                            |
| `h6`        | Titre de sixième niveau.                                              |
| `lead`      | Le chapô qui ouvre une page, composé plus grand que le texte courant. |
| `body`      | Le texte courant. Le niveau auquel tous les autres se mesurent.       |
| `bodySmall` | Texte courant secondaire : aide contextuelle, tableaux denses.        |
| `caption`   | Libellés, horodatages, notes de bas de page.                          |
| `overline`  | Le petit surtitre espacé placé au-dessus d'un titre.                  |

Un nom de niveau hors de cette liste est refusé nommément à la validation : `h7` est signalé comme clé inconnue plutôt qu'ignoré en silence. `h1` à `h6` reprennent délibérément les noms que le [composant `text`](/fr/docs/content-components) émet déjà dans `element:` : un niveau devient ainsi quelque chose à quoi un moteur de rendu peut se rattacher, et non une chaîne qu'il doit deviner.

## Ce que contient un niveau

| Membre          | Type     | Remarques                                                                          |
| --------------- | -------- | ---------------------------------------------------------------------------------- |
| `size`          | `string` | **Obligatoire.** Un nombre suivi de `px` ou `rem` — `'3rem'`, `'14px'`.            |
| `lineHeight`    | `number` | Un **rapport sans unité** : `1.5`, et non `'1.5'` ni `'24px'`.                     |
| `weight`        | `number` | De 100 à 900, la même échelle que celle de `theme.fonts`.                          |
| `letterSpacing` | `string` | Un nombre suivi de `px`, `rem` ou `em` — `'-0.02em'`.                              |
| `font`          | `string` | Le nom d'une police déclarée dans `design.theme.fonts` — `'title'`, pas `'Inter'`. |

`size` est le seul membre obligatoire : un niveau qui ne déclare qu'une taille est un état réel et courant — l'interlignage et la graisse sont hérités. À l'inverse, un niveau qui déclare un interlignage sans taille ne nomme aucune taille et ne peut pas s'afficher.

`font` désigne un rôle de police plutôt qu'une famille pour que le lien survive à un réglage : un niveau portant `font: title` suit la police de titre partout où vous la modifiez, alors qu'un `'Inter'` écrit en dur est une copie qui se périme sans le dire. Le nom est vérifié contre les polices que vous avez déclarées : un nom introuvable est donc refusé, plutôt qu'émis sous forme de variable orpheline.

```yaml
design:
  theme:
    fonts:
      title:
        family: Inter
        fallback: 'system-ui, sans-serif'
  typeScale:
    display:
      size: '4.5rem'
      lineHeight: 1.05
      weight: 800
      font: title
```

## Ce qui est émis

Chaque niveau déclaré devient un jeton typographique Tailwind : une propriété personnalisée pour la taille, et un modificateur par membre optionnel.

```css
:root {
  --text-h1: 3rem;
  --text-h1--line-height: 1.1;
  --text-h1--font-weight: 700;
  --text-h1--letter-spacing: -0.02em;
  --text-h1--font-family: var(--font-title);
}
```

Les variables atteignent `:root` sans condition : n'importe quoi peut donc lire `var(--text-h1)`. L'**utilitaire** `text-h1` correspondant, lui, est généré comme tout utilitaire Tailwind — lorsque le nom de classe apparaît dans un `className` que l'analyse au moment de la compilation peut voir :

```yaml
pages:
  - path: /
    components:
      - type: text
        element: h1
        props:
          className: text-h1
        content: Charte
```

Appliquer l'utilitaire fixe la taille de police et y intègre l'interlignage, la graisse, l'approche et la police en une seule classe. C'est tout l'intérêt de la clé : un niveau utilisable, et non une variable que personne ne peut atteindre.

## Pourquoi ces unités et pas d'autres

Chaque contrainte suit le type [W3C Design Tokens](https://www.designtokens.org/tr/drafts/format/) vers lequel le niveau est sérialisé, car une valeur que l'export ne peut pas porter fidèlement est une valeur que la charte ne peut pas publier.

- **`size` accepte `px` ou `rem`, et rien d'autre.** Ce sont les deux unités qu'autorise une `dimension` DTCG. Un `clamp(1rem, 2vw, 3rem)` fluide est refusé plutôt qu'accepté en silence : la typographie fluide est une technique de mise en page destinée à l'élément qui en a besoin, tandis qu'une échelle typographique est une suite de barreaux fixes et citables — « notre h1 fait 3rem » est exactement le genre de phrase qu'une charte existe pour rendre vraie. Passez par une classe utilitaire sur cet élément.
- **`lineHeight` est un nombre, pas une chaîne.** DTCG le type comme un nombre, et la bonne pratique va dans le même sens indépendamment : un rapport survit à un changement de taille, alors qu'un interlignage figé à `24px` devient faux sans prévenir dès que le niveau est réglé autrement.
- **`letterSpacing` accepte en plus `em`, ce que DTCG ne fait pas.** `-0.02em` est la valeur d'approche idiomatique dans à peu près toutes les échelles typographiques jamais écrites, et la refuser pour satisfaire un format de sérialisation reviendrait à laisser le format dicter le design. Elle est honorée telle quelle dans le navigateur, et signalée dans la liste `unmappable` de l'export à son chemin de configuration exact — vous voyez ainsi que Sovrium l'a bien rendue et n'a pas pu la porter dans le document de jetons.

## Ce que cette clé remplace

`design.typeScale` remplace trois champs de `theme.fonts.*` qui passent la validation puis n'atteignent rien :

| Champ remplacé             | Ce qu'il faisait réellement                                                                                                                   |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `theme.fonts.*.lineHeight` | Rien du tout. Aucune propriété personnalisée n'a jamais été émise pour ce champ.                                                              |
| `theme.fonts.*.size`       | N'atteignait que l'ancien moteur de rendu de section `hero`, sous forme de taille en ligne. Jamais une variable CSS.                          |
| `theme.fonts.*.weights`    | Seul `weights[0]` était lu, par ce même moteur. Jamais une règle `@font-face` : les entrées suivantes ne chargeaient aucun fichier de police. |

**Remplacés, et non dépréciés** — la nuance mérite d'être tenue. « Déprécié » signifie _ceci fonctionnait et va disparaître_ ; ces trois champs n'ont jamais fonctionné. Ils continuent d'être décodés jusqu'à la prochaine version majeure, aux côtés de l'alias `theme` de premier niveau, parce que les refuser maintenant arrêterait une application qui démarre sans rien changer au rendu. `sovrium validate` affiche un avis `Superseded:` nommant chaque chemin déclaré, et se termine avec le code `0`.

Aucune conversion automatique n'est faite pour vous. Les formes diffèrent réellement — `typeScale` est par **niveau** là où `theme.fonts` est par **police**, son `lineHeight` est un rapport là où l'ancien était une chaîne libre, et il prend une seule `weight` là où l'ancien prenait un tableau. Toute traduction automatique devrait donc deviner quelle police correspond à quel barreau. Sovrium le dit plutôt que de le deviner.

## Dans l'export

`sovrium design-system` et les deux points d'accès d'export publient l'échelle sous forme de section **Type scale**, dans l'ordre canonique ci-dessus. Dans le document DTCG, chaque niveau est un jeton composite `typography` ; les valeurs `letterSpacing` exprimées en `em` sont listées sous `unmappable`, pour la raison donnée plus haut.

## Pages associées

- [Système de design](/fr/docs/design) — la clé `design` à laquelle ceci appartient, et l'export.
- [Typographie](/fr/docs/theme-typography) — `theme.fonts`, les polices dans lesquelles un niveau est composé.
- [Aperçu du thème et couleurs](/fr/docs/theme) — les autres catégories de jetons.
- [Composants de contenu](/fr/docs/content-components) — le composant `text` auquel un niveau s'applique.
- [Console du système de design](/fr/docs/design-system-console) — l'échelle dessinée à ses tailles réelles.
