
# Densité

À quel point une ligne de tableau est-elle serrée ? Avant `design.density`, la réponse était `py-[5px]`, écrit dans quelques recettes internes à Sovrium et accessible nulle part depuis une configuration. La densité n'était pas un jeton ; c'était un littéral qui se trouvait être le même dans plusieurs fichiers.

`design.density` la rend déclarable. Une échelle, trois crans, cinq nombres chacun :

```yaml
design:
  density:
    steps:
      compact: { rowY: 5px, controlH: 36px, buttonH: 28px, gap: 7px, text: 11px }
      cozy: { rowY: 8px, controlH: 40px, buttonH: 32px, gap: 10px, text: 13px }
      roomy: { rowY: 14px, controlH: 44px, buttonH: 36px, gap: 16px, text: 14px }
```

Ce sont les valeurs livrées. Les recopier ne change rien, ce qui fait du bloc ci-dessus un bon point de départ : modifiez un nombre et voyez exactement ce qu'il déplace.

## Les cinq nombres

| Champ      | Ce qu'il fixe                                                      | Propriété personnalisée  |
| ---------- | ------------------------------------------------------------------ | ------------------------ |
| `rowY`     | Le rembourrage vertical d'une ligne et d'une cellule d'en-tête     | `--sv-density-row-y`     |
| `controlH` | La hauteur d'un contrôle de saisie — champ texte, liste déroulante | `--sv-density-control-h` |
| `buttonH`  | La hauteur d'un petit bouton — une action de barre d'outils        | `--sv-density-button-h`  |
| `gap`      | La gouttière interne des petits éléments — puces, badges           | `--sv-density-gap`       |
| `text`     | La taille du texte secondaire, dans une cellule                    | `--sv-density-text`      |

`controlH` et `buttonH` n'ont fait qu'un jusqu'à ce qu'ils fassent deux, et la raison mérite
une phrase. Un champ et un petit bouton tiennent tous deux sur une ligne, mais on ne leur
demande pas la même chose : un champ est un endroit où l'on écrit, et il lui faut la place
d'un curseur, d'un jambage et d'une cible confortable ; un petit bouton est une étiquette
entourée d'un cadre, et il doit se fondre dans une barre d'outils. Avec une clé unique, on ne
pouvait pas donner de l'air au champ sans gonfler chaque bouton à côté. L'échelle livrée les
sépare de 8px à chaque cran — champs 36 / 40 / 44, boutons 28 / 32 / 36 — et le champ du cran
`roomy` tombe exactement sur la cible renforcée de 44px décrite dans `floors` plus bas.

Chaque valeur est un **nombre suivi de `px` ou `rem`**. Rien d'autre ne se décode — ni pourcentage, ni `clamp()`, ni nombre sans unité. Un cran est un nombre fixe et citable ; une valeur fluide est une autre fonctionnalité portant le même nom.

Les cinq champs sont requis sur chaque cran, et les trois crans sont requis. Les noms de crans forment un ensemble **fermé** : `cosy` là où vous vouliez `cozy` est refusé au démarrage, en nommant la clé. Une échelle à laquelle il manque un barreau n'est pas une échelle — une surface retomberait en silence sur un cran non voulu, et rien ne le dirait.

## Les trois crans, et celui que vous obtenez

`compact` est le défaut. Pas seulement parce qu'il vient en premier : c'est le cran émis sur `:root`, donc toute surface s'affiche en `compact` tant que rien n'a explicitement demandé un autre cran.

```css
:root {
  --sv-density-row-y: 5px; /* compact */
}
[data-density='cozy'] {
  --sv-density-row-y: 8px;
}
[data-density='roomy'] {
  --sv-density-row-y: 14px;
}
```

Ancrer `compact` à la racine est délibéré. Ses nombres **sont** les littéraux que les recettes codaient en dur : un auteur qui déclare une échelle — même recopiée telle quelle depuis le bloc ci-dessus — retrouve exactement ce qu'il avait. Y ancrer `cozy` aurait silencieusement desserré tous les tableaux existants dès que quiconque aurait déclaré une densité.

## Ce qui bouge aujourd'hui, et ce qui ne bouge pas

Déclarer une échelle change réellement le rembourrage rendu. Trois des cinq propriétés sont lues par des recettes livrées :

- **`rowY`** — les cellules d'en-tête et les lignes d'une [`table`](/fr/docs/data-components), lié ou statique.
- **`text`** — les petites affordances dans une cellule : aperçu JSON, puce de tableau, code en ligne, code couleur, légende de code-barres, paire de coordonnées.
- **`gap`** — la gouttière interne d'un badge, et le décor qui réutilise la mise en page du badge.

**`controlH` et `buttonH` sont émises, et rien ne les lit pour l'instant.** Les deux propriétés personnalisées existent et portent vos valeurs ; aucune recette ne les consomme. Déclarez-les — le schéma exige les deux — mais n'attendez pas qu'un champ ou un bouton change de hauteur pour autant. C'est écrit ici plutôt que laissé à redécouvrir comme un bug.

:::callout
**À ne pas confondre avec le contrôle de densité de la `table`.** La barre d'outils d'une `table` peut exposer un bouton `density` qui laisse un _lecteur_ changer la hauteur des lignes pour lui-même, et cette préférence lui appartient, propre à chaque lecteur. `design.density` est l'échelle applicative à partir de laquelle ces surfaces sont dessinées. L'un est un choix d'exécution fait par qui regarde ; l'autre est une décision de design prise par qui a écrit la configuration.
:::

## `byZone` — déclaré, pas encore câblé

`byZone` attribue un cran à une [zone](/fr/docs/design), pour qu'une surface produit soit plus serrée qu'une surface marketing :

```yaml
design:
  zones:
    - { pattern: '/app/*', zone: product, accentBudget: product }
    - { pattern: 'everything else', zone: marketing, accentBudget: public }
  density:
    steps:
      compact: { rowY: 5px, controlH: 36px, buttonH: 28px, gap: 7px, text: 11px }
      cozy: { rowY: 8px, controlH: 40px, buttonH: 32px, gap: 10px, text: 13px }
      roomy: { rowY: 14px, controlH: 44px, buttonH: 36px, gap: 16px, text: 14px }
    byZone:
      product: compact
      marketing: roomy
```

Cela se décode, et c'est validé : un nom de zone que `design.zones` ne déclare pas est refusé au démarrage, avec la liste des zones qui existent.

**Cela ne change encore rien.** Rien n'écrit l'attribut `[data-density]` sur un élément rendu : les blocs `cozy` et `roomy` sont émis et jamais appariés. C'est pourquoi les trois crans sont émis quoi qu'en dise `byZone` — cela fait du travail restant un câblage plutôt qu'un changement de feuille de style, et cela signifie qu'une échelle déclarée aujourd'hui commencera à s'appliquer sans que vous ayez à la réécrire.

## `floors` — une garantie qu'on peut redire, pas déplacer

```yaml
design:
  density:
    floors:
      controlH: 24
      hit: 44
```

Deux nombres, et **seulement** ces deux valeurs se décodent. Un plancher plus bas est refusé, un plancher plus haut aussi. Déclarer la clé redit une garantie que le moteur tient déjà ; l'omettre est identique en tout point. Elle existe pour que les nombres soient lisibles dans une configuration et pas seulement dans le code source, et il est honnête de dire que rien ne relit la clé.

## Ce que coûte une déclaration

Sovrium peut servir une feuille de style précompilée, indépendante de l'application, aux applications qui n'ont rien personnalisé. Déclarer `design.density` sort votre application de ce chemin : l'échelle doit être compilée, car servir le fichier prégénéré laisserait tous les tableaux sur le cran `compact` de la plateforme alors que votre configuration dit autre chose.

C'est un coût à la première requête, pas à chaque requête, et c'est le même compromis que toute personnalisation de `design`.

## Pages associées

- [Système de design](/fr/docs/design) — la clé `design` sous laquelle vit la densité, et où les zones sont déclarées.
- [Styles de composants](/fr/docs/design-components) — restyler un type de composant moteur dans toute l'application.
- [Espacements et surfaces](/fr/docs/theme-spacing) — l'échelle d'espacement applicative à côté de laquelle la densité se range.
- [Composants de données](/fr/docs/data-components) — la barre d'outils de la `table` et son contrôle de densité par lecteur.
- [Console du système de design](/fr/docs/design-system-console) — où les jetons résolus sont dessinés à leurs valeurs rendues.
