@starterlib/tokens 0.8.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -20,8 +20,8 @@ pnpm add @starterlib/tokens
20
20
  ```
21
21
 
22
22
  Elle pose les variables `--st-*` sur `:root`, le theme sombre sous
23
- `[data-theme='sombre']` et sous `prefers-color-scheme: dark`, et reduit les
24
- durees sous `prefers-reduced-motion`. `color-scheme` suit le theme effectif :
23
+ `[data-theme='sombre']` et sous `prefers-color-scheme: dark`, et eteint le
24
+ mouvement sous `prefers-reduced-motion` (voir « Mouvement »). `color-scheme` suit le theme effectif :
25
25
  les controles natifs, les barres de defilement et le remplissage automatique
26
26
  restent dans le bon theme meme quand l'utilisateur force un theme contraire a
27
27
  son systeme.
@@ -35,6 +35,45 @@ Elle obeit aussi a la PERSONNE, pas seulement au theme :
35
35
  hauteur que `st-app-shell` mesure sur son en-tete collant, pour qu'un arret de
36
36
  tabulation ne remonte jamais dessous (WCAG 2.4.11). Sans coquille, zero.
37
37
 
38
+ Elle publie aussi les classes qu'un gabarit d'APPLICATION ecrit lui-meme (lot 156) :
39
+
40
+ - `.st-vh` — un texte pour les seuls lecteurs d'ecran
41
+ (`<span class="st-vh">, 5 non lus</span>`), masque a l'oeil et garde dans le nom
42
+ accessible ; `.st-vh-focalisable` le montre quand il recoit le focus (un lien d'evitement).
43
+ Emise dans la portee d'un composant, la classe n'atteignait jamais un element ecrit par
44
+ l'appelant : le texte s'affichait en clair ;
45
+ - `.st-hors-impression`, `.st-impression-seulement` — ce qui ne s'imprime pas, et l'inverse ;
46
+ - `.st-formulaire` — le rythme vertical d'un formulaire, porte par le conteneur.
47
+
48
+ ## Mouvement
49
+
50
+ Une table FERMEE (01 §6, D9, D24), emise en variables :
51
+
52
+ | Famille | Jetons | Sous mouvement reduit |
53
+ | -------------------- | ------------------------------------------------------------------------- | --------------------- |
54
+ | `--st-duree-*` | `instantane` 0, `rapide` 120, `normale` 200, `lente` 320, `longue` 480 ms | 0 ms |
55
+ | `--st-courbe-*` | `standard`, `entrant`, `sortant` (plus `linear`) | — |
56
+ | `--st-deplacement-*` | `court` 0.25rem, `moyen` 0.5rem, `long` 1rem | 0 |
57
+ | `--st-cadence-*` | `vive` 900, `normale` 1400, `respiration` 1600 ms | **conservees** |
58
+ | `--st-cadence-min` | 600 ms, plancher d'une boucle d'attente | — |
59
+
60
+ - Une entree est une opacite PLUS un deplacement, jamais une echelle ; une sortie est
61
+ un fondu. Le fondu d'une couche lit `--st-duree-normale` : il n'y a pas de reglage
62
+ de fondu (D8).
63
+ - Trois voies eteignent le mouvement, toutes dans la feuille : la preference du
64
+ systeme (sauf `data-mouvement="complet"` sur `<html>`), l'attribut
65
+ `data-mouvement="reduit"` (pose par `StMouvement` de `@starterlib/core`), et le gel
66
+ d'une image `data-gel` (pose le temps d'un rendu au changement de theme ou de
67
+ langue). Une feuille de composant n'ecrit donc JAMAIS
68
+ `@media (prefers-reduced-motion)` autour d'une transition : elle lit les jetons.
69
+ - Les cadences ne s'eteignent jamais : sous mouvement reduit, une boucle d'attente
70
+ passe de la rotation a la respiration (mixin `sous-mouvement-reduit` du partiel
71
+ `ruptures`), elle ne se fige pas.
72
+ - Les DELAIS et les TENUES (200 ms avant un chargement, 400 ms minimum une fois
73
+ montre, 2 s de confirmation...) ne sont pas du mouvement : ils vivent en TypeScript
74
+ seulement, dans `rythme` (`rythme.delai.*`, `rythme.tenue.*`, D3), jamais emis,
75
+ jamais mis a zero.
76
+
38
77
  ## Points de rupture
39
78
 
40
79
  Un partiel Sass, engendre comme la feuille, et la meme echelle en TypeScript :
@@ -68,16 +107,118 @@ Le theme se force par attribut, et l'attribut l'emporte dans les deux sens :
68
107
  <html data-theme="sombre"></html>
69
108
  ```
70
109
 
110
+ Chaque couleur est UNE declaration `light-dark(clair, sombre)` : le theme effectif
111
+ est porte par `color-scheme`, que `:root`, `prefers-color-scheme` et l'attribut
112
+ posent. L'attribut vaut donc aussi sur un **ilot** : une carte `data-theme="sombre"`
113
+ dans une page claire rend ses couleurs sombres, sans classe ni variable de plus.
114
+
115
+ ```html
116
+ <section data-theme="sombre">…</section>
117
+ ```
118
+
119
+ La densite se regle de meme, par attribut, sur la page ou sur une zone :
120
+
121
+ ```html
122
+ <main data-densite="compacte">…</main>
123
+ <!-- confortable (defaut) | compacte | dense -->
124
+ ```
125
+
126
+ Elle regle la hauteur des commandes (44, 36 ou 32 px), les rembourrages et
127
+ l'interligne des lignes de tableau ; sous `pointer: coarse`, la cible tactile ne
128
+ descend jamais sous 44 px.
129
+
130
+ ## Polices
131
+
132
+ Inter et JetBrains Mono, **auto-hebergees** (SIL OFL 1.1) : aucune adresse tierce,
133
+ `font-src 'self'` suffit.
134
+
135
+ ```css
136
+ @import '@starterlib/tokens/styles/polices.css';
137
+ ```
138
+
139
+ ```html
140
+ <link
141
+ rel="preload"
142
+ href="/polices/inter-latin-wght-normal.woff2"
143
+ as="font"
144
+ type="font/woff2"
145
+ crossorigin
146
+ />
147
+ ```
148
+
149
+ `font-display: optional` et un repli METRISE (memes hauteur de ligne et chasse
150
+ moyenne, calcules sur le fichier livre) : la page ne saute pas quand la police
151
+ arrive. Recette complete, budget et correspondance avec les planches :
152
+ [docs/recettes/police.md](../../docs/recettes/police.md).
153
+
154
+ ## Styles typographiques
155
+
156
+ Des styles composites (taille, interligne, graisse, approche, chiffres ; jamais de
157
+ couleur), par un seul mixin engendre :
158
+
159
+ ```scss
160
+ @use '@starterlib/tokens/styles/typographie' as typo;
161
+
162
+ h2 {
163
+ @include typo.style('titre-2');
164
+ }
165
+ // un nom inconnu echoue a la compilation
166
+ ```
167
+
168
+ `stylesTypographiques` donne la meme table en TypeScript. Les tailles vont de `2xs`
169
+ (reserve aux capitales) a `6xl`, chacune avec son interligne ; les chiffres passent
170
+ par deux contrats (`--st-chiffres-alignes`, `--st-chiffres-references`).
171
+
172
+ ⚠️ **Un nom diverge entre le TypeScript et la feuille** : les piles de polices s'appellent
173
+ `typographie.famille.base` et `typographie.famille.mono` en TypeScript, et `--st-police-base` et
174
+ `--st-police-mono` dans la feuille (et `police.base`, `police.mono` dans le fichier DTCG). La feuille
175
+ nomme ce que l'ecran charge ; le TypeScript garde le vocabulaire de l'echelle typographique.
176
+
71
177
  ## API TypeScript
72
178
 
73
179
  ```ts
74
- import { themes, contraste, echelles } from '@starterlib/tokens';
180
+ import { themeClair, themeSombre, primitives, rapportDeContraste, apca } from '@starterlib/tokens';
75
181
  ```
76
182
 
77
- - `themes.clair` et `themes.sombre` : couleurs semantiques.
78
- - `echelles` : espacement, typographie, rayons, ombres, durees, plans.
183
+ - `themeClair` et `themeSombre` : les couleurs semantiques, chacune une `CouleurHex`
184
+ (`#${string}`) : `primaire: 'bleu'` ne compile pas (lot 158) ; `ombres`, `voile`.
185
+ - `primitives`, `definitionsDesPrimitives` : les rampes, ENGENDREES en OKLCH
186
+ (`oklchVersHex`, `hexVersOklch`), jamais recopiees.
187
+ - `espacement`, `typographie`, `rayon`, `epaisseur`, `largeur`, `hauteurDeCommande`,
188
+ `densite`, `focus`, `plan`, `duree`, `courbe`, `deplacement`, `cadence`,
189
+ `cadenceMinimale` : les echelles ; `mouvementReduit` et `mouvementGele` : ce que
190
+ la feuille met a zero.
191
+ - `rythme` (`delai`, `tenue`) : les delais et tenues que les composants lisent en
192
+ TypeScript (D3).
193
+ - `stylesTypographiques`, `policesDuSocle` : typographie et polices.
79
194
  - `RUPTURES` : les points de rupture en px, en rem et en requete de media.
80
- - `contraste(a, b)` : rapport WCAG, employe par les tests du depot.
195
+ - `rapportDeContraste(a, b)` (WCAG), `apca(texte, fond)` (Lc, APCA 0.0.98G-4g),
196
+ `composer(premierPlan, fond)` : employes par les tests du depot.
197
+ - `rolesDesPrimitives()` : quel role porte quel pas (le nuancier le lit).
198
+ - `jetonsDtcg()` : les jetons au format DTCG (ci-dessous).
199
+
200
+ ## Format DTCG
201
+
202
+ `styles/starter-tokens.tokens.json` porte les jetons au format du W3C Design Tokens Community Group
203
+ (« Design Tokens Format Module », version stable 2025.10), pour un outil de design ou un autre
204
+ moteur de rendu qui ne lit pas le TypeScript :
205
+
206
+ ```ts
207
+ import jetons from '@starterlib/tokens/styles/starter-tokens.tokens.json' with { type: 'json' };
208
+ ```
209
+
210
+ | Groupe | Contenu | `$type` |
211
+ | -------------------------- | ----------------------------------- | ------------ |
212
+ | `couleur.clair`, `.sombre` | les couleurs semantiques des themes | `color` |
213
+ | `espacement`, `rayon` | les echelles, en `{ value, unit }` | `dimension` |
214
+ | `taille`, `interligne` | l'echelle typographique | `dimension` |
215
+ | `graisse` | 400, 500, 600, 700 | `fontWeight` |
216
+ | `police` | les piles de polices, en listes | `fontFamily` |
217
+ | `duree` | les durees du mouvement, en ms | `duration` |
218
+
219
+ Une couleur s'ecrit en sRGB (`colorSpace`, `components` de 0 a 1) avec son `hex` en repli. Les
220
+ ombres, les courbes, les cadences et les derogations (contraste renforce, impression, mouvement
221
+ reduit) n'y sont pas : ce sont des regles de la feuille, pas des valeurs a recopier ailleurs.
81
222
 
82
223
  ## Niveau 3 — reglages de composant
83
224
 
@@ -97,17 +238,17 @@ style. Elles sont listees en commentaire en tete de la feuille engendree, et dan
97
238
  }
98
239
  ```
99
240
 
100
- | Reglage | Defaut | Pour |
101
- | ----------------------------- | -------------------------- | ------------------------------------------ |
102
- | `--st-commande-hauteur` | `--st-cible-tactile-min` | hauteur minimale des boutons et des champs |
103
- | `--st-commande-rayon` | `--st-rayon-md` | identite de marque |
104
- | `--st-surface-rayon` | `--st-rayon-md` | carte, dialogue, menu, popover |
105
- | `--st-tableau-cellule-bloc` | `--st-espacement-3` | densite verticale d'un tableau |
106
- | `--st-tableau-cellule-ligne` | `--st-espacement-3` | densite horizontale |
107
- | `--st-tableau-largeur-case` | `3rem` | colonne des cases a cocher |
108
- | `--st-calendrier-jour-taille` | `--st-cible-tactile-min` | calendrier dense |
109
- | `--st-anim-chargement` | propre a chaque indicateur | rythme d'un indicateur d'activite |
110
- | `--st-anim-respiration` | `1600ms` | rythme sous mouvement reduit |
241
+ | Reglage | Defaut | Pour |
242
+ | ----------------------------- | --------------------------------------------- | --------------------------------------------------------------- |
243
+ | `--st-commande-hauteur` | `--st-cible-tactile-min` | hauteur minimale des boutons et des champs |
244
+ | `--st-commande-rayon` | `--st-rayon-md` | identite de marque |
245
+ | `--st-surface-rayon` | `--st-rayon-md` | carte, dialogue, menu, popover |
246
+ | `--st-tableau-cellule-bloc` | `--st-espacement-3` | densite verticale d'un tableau |
247
+ | `--st-tableau-cellule-ligne` | `--st-espacement-3` | densite horizontale |
248
+ | `--st-tableau-largeur-case` | `3rem` | colonne des cases a cocher |
249
+ | `--st-calendrier-jour-taille` | `--st-cible-tactile-min` | calendrier dense |
250
+ | `--st-anim-chargement` | `--st-cadence-vive` ou `--st-cadence-normale` | rythme d'un indicateur d'activite (plancher `--st-cadence-min`) |
251
+ | `--st-anim-respiration` | `--st-cadence-respiration` | rythme sous mouvement reduit (plancher `--st-cadence-min`) |
111
252
 
112
253
  ⚠️ **Le socle ne les DECLARE jamais** : il les lit au point d'usage, avec un
113
254
  repli. Une declaration sur l'hote d'un composant l'emporterait sur la valeur
@@ -124,12 +265,30 @@ calendrier reste au-dessus de la cible minimale, quoi qu'on pose.
124
265
 
125
266
  ## Garde de non-derive
126
267
 
127
- Le CSS est **engendre**, jamais ecrit a la main — la feuille comme le partiel
128
- des ruptures. `pnpm tokens:css:check` echoue si un fichier livre ne correspond
129
- plus aux jetons TypeScript — meme principe que le controle de contrat cote
130
- backend.
268
+ Le CSS est **engendre**, jamais ecrit a la main — la feuille, les partiels des
269
+ ruptures et de la typographie, la feuille des polices, et le fichier DTCG. Les outils lisent les
270
+ jetons sur leurs SOURCES (`tools/jetons-sources.mjs`, Node 24 retire les types a l'import) : ni
271
+ `ng build` prealable, ni course avec `dist/` (`rm -rf dist && pnpm tokens:css:check` reste vert,
272
+ lot 158). `pnpm tokens:css:check`
273
+ echoue si un fichier livre ne correspond plus aux jetons TypeScript — meme
274
+ principe que le controle de contrat cote backend —, si une metrique de police
275
+ declaree n'est plus celle du fichier livre (`tools/verifier-police.mjs`), ou si
276
+ le nuancier de la planche 11 corrige par le registre ne correspond plus au moteur
277
+ (`tools/ecarts-du-nuancier.mjs`).
131
278
 
132
279
  ## Accessibilite
133
280
 
134
- 25 paires semantiques sont verifiees en AA dans les deux themes par les tests du
135
- paquet. Toute exemption porte une raison ecrite et reste perceptible.
281
+ Les tests du paquet verifient, dans les deux themes :
282
+
283
+ - chaque paire de `pairesDeContraste` en AA (4,5:1 pour le texte, 3:1 pour les
284
+ filets et les indicateurs), avec son score APCA ; chaque exemption
285
+ (`exemptesDeContraste`) et chaque paire exclue (`pairesExclues`) porte sa raison
286
+ ecrite ;
287
+ - l'ecart perceptible entre surfaces voisines (repos, survol, actif, conteneurs) ;
288
+ - l'anneau de focus sur chaque surface de `surfacesDuFocus` : l'anneau OU le lisere
289
+ tient 3:1 ;
290
+ - les alias de `prefers-contrast: more` et les couleurs systeme de
291
+ `forced-colors`.
292
+
293
+ Aucun compte n'est ecrit a la main ici : `node tools/compter-jetons.mjs` les donne
294
+ depuis le paquet construit (D14).