Forme DS

Introduction

Doctrine

Le Design System n'est pas une bibliothèque d'options : c'est une ligne. Une seule façon de construire l'interface, la même pour Admin, AI, Space et Frame. Ces principes expliquent pourquoi le DS est structuré ainsi — et ce que tu t'engages à respecter en l'adoptant.

Astryx est le socle, Forme est la couche

Chaque composant de @forme-ch/ui enrobe son équivalent Astryx sous l'API Forme. Astryx apporte le comportement et l'accessibilité — gestion du focus, clavier, rôles ARIA, fermeture des overlays. Forme apporte l'identité : la charte, le vocabulaire, les tokens. On hérite du premier, on impose le second par-dessus. Quand une convention Forme historique diverge du comportement natif d'Astryx, Astryx l'emporte : on ne recode pas une a11y que le socle fournit déjà.

Source unique

Un composant existe à un seul endroit : le paquet. On ne duplique jamais un Button dans une app, on ne recrée pas un menu maison parce que le DS « ne fait pas encore » ce qu'il faut. Si une lacune existe, on fait évoluer le paquet — et toutes les surfaces en profitent d'un coup. Une app ne contient pas de composant d'UI ; elle en consomme.

Accessibilité d'abord — l'API label

L'accessibilité n'est pas une option qu'on active à la fin. Elle est câblée dans le contrat des composants : là où un nom accessible est requis, l'API l'exige. Le label est aligné sur Astryx — il garantit un nom accessible découplé du visuel. Un bouton icône seule ne peut pas exister sans son label ; le composant l'impose, ce n'est pas au développeur d'y penser.

// Le nom accessible est garanti, même sans texte visible.
<IconButton label="Fermer" icon={<XIcon />} variant="ghost" />

Les tokens sont la seule source de couleur, de typo et de rayon

Aucune valeur littérale dans le code d'une app. Pas de #hex en dur, pas de 15px hors échelle, pas de rayon en pixels. On référence un token — défini une seule fois dans @forme-ch/design-system. C'est ce qui garantit le thème sombre (chaque token s'adapte via light-dark()), la cohérence entre apps, et la maintenabilité : changer une valeur au centre la change partout.

/* Oui : un token. */
.bloc { color: var(--color-text-primary); background: var(--color-background-card); }

/* Non : une valeur en dur — invisible en thème sombre, hors ligne. */
.bloc { color: #111; background: #fff; }

Parité inter-apps

Admin, AI, Space et Frame partagent les mêmes composants et les mêmes tokens. Un SideNavItem a la même hauteur, le même rayon, la même typo des deux côtés — parce que c'est le même code. La parité n'est pas un objectif qu'on vise, c'est une conséquence mécanique de la source unique. Voir Parité inter-apps.

On n'écrit pas de CSS de composant dans les apps

C'est le corollaire de tout ce qui précède, et la règle la plus facile à enfreindre. Une app ne contient pas de CSS qui redessine un composant, ni de style inline qui contourne une lacune du socle (un padding pour bricoler un bouton carré, une border-left décorative pour teinter un bloc). Ces bricolages divergent, se dupliquent, et cassent la parité. La bonne réponse à une lacune n'est jamais du CSS d'app — c'est une amélioration du paquet.

En une phrase. On améliore le paquet, jamais l'app. Chaque composant vient de @forme-ch/ui, chaque valeur vient d'un token, chaque nom accessible est garanti par l'API — et les quatre surfaces restent identiques sans effort.