@starterlib/tokens 0.9.1 → 0.10.0

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.
@@ -0,0 +1,1123 @@
1
+ /**
2
+ * Moteur OKLCH, sans dependance.
3
+ *
4
+ * Une rampe de couleurs ne se raisonne pas en hexadecimal : deux gris de meme
5
+ * « code » n'ont pas la meme clarte percue, et deux statuts au meme pas n'ont
6
+ * pas le meme contraste. En OKLCH, la clarte `l` est perceptuelle : deux pas de
7
+ * meme `l` tiennent le meme contraste sur une meme surface, quelle que soit leur
8
+ * teinte. C'est ce qui permet d'engendrer six familles chromatiques par une
9
+ * seule table de clartes (`primitives.ts`).
10
+ *
11
+ * Le moteur ne fait que convertir. L'hexadecimal reste ce que consomment la
12
+ * feuille engendree et le calcul de contraste : une couleur OKLCH est une
13
+ * DEFINITION, le hex est DERIVE.
14
+ *
15
+ * Matrices : OKLab de Bjorn Ottosson (2020), sur sRGB D65.
16
+ */
17
+ /** Une couleur en OKLCH : clarte 0..1, chroma >= 0, teinte en degres 0..360. */
18
+ export interface Oklch {
19
+ readonly l: number;
20
+ readonly c: number;
21
+ readonly h: number;
22
+ }
23
+ /** Resultat d'une conversion vers sRGB : le hex, et si la chroma a du etre rabattue. */
24
+ /**
25
+ * Une couleur hexadecimale sRGB (`#rrggbb`) : la seule forme qu'un jeton de couleur accepte (lot 158).
26
+ * `primaire: 'bleu'` ne compile plus : chaque champ de `JetonsDeCouleur` est une `CouleurHex`.
27
+ */
28
+ export type CouleurHex = `#${string}`;
29
+ export interface ConversionSrgb {
30
+ readonly hex: CouleurHex;
31
+ readonly rabattue: boolean;
32
+ /** Chroma effectivement rendue (egale a la chroma demandee sauf rabattement). */
33
+ readonly chroma: number;
34
+ }
35
+ /**
36
+ * OKLCH vers sRGB, avec RABATTEMENT de chroma : une couleur hors du gamut sRGB
37
+ * garde sa clarte et sa teinte, et perd la chroma qu'aucun ecran sRGB ne rend.
38
+ * Couper un canal a la place changerait la clarte, donc le contraste, sans le
39
+ * dire. Le rabattement est signale (`rabattue`) pour que les tests le voient.
40
+ */
41
+ export declare function oklchVersSrgb(couleur: Oklch): ConversionSrgb;
42
+ /** OKLCH vers hex sRGB (`#rrggbb`), chroma rabattue dans le gamut si besoin. */
43
+ export declare function oklchVersHex(couleur: Oklch): CouleurHex;
44
+ /**
45
+ * Hex sRGB vers OKLCH. Un gris a une chroma nulle et une teinte sans objet :
46
+ * elle vaut alors 0, par convention.
47
+ */
48
+ export declare function hexVersOklch(hex: string): Oklch;
49
+ /** Ecriture CSS d'une couleur OKLCH, pour la documentation et le banc. */
50
+ export declare function oklchEnCss({ l, c, h }: Oklch): string;
51
+ /**
52
+ * Niveau 1 — primitives. Palette brute, sans intention d'usage.
53
+ *
54
+ * ⚠️ Aucun composant ne consomme ce niveau : il passe par le niveau semantique
55
+ * (`theme.ts`), sinon un changement de nuance se propage a l'aveugle. La regle
56
+ * est outillee : `no-restricted-imports` refuse `primitives` dans `packages/ui`.
57
+ * Le niveau reste exporte, parce qu'une SPA peut construire une echelle de
58
+ * donnees (graphique sequentiel, carte de chaleur) sur une rampe.
59
+ *
60
+ * Chaque couleur est DEFINIE en OKLCH et son hexadecimal est DERIVE par le
61
+ * moteur (`oklch.ts`). Les six familles chromatiques partagent une seule table de
62
+ * clartes : un `succes 600` et un `danger 600` ont la meme clarte, donc le meme
63
+ * contraste sur une meme surface (01 §2, principe P3). Une famille se definit par
64
+ * deux nombres, sa teinte et sa chroma maximale.
65
+ *
66
+ * Les rampes de la planche 11 de Claude Design ne sont PAS reprises ici : 11 de
67
+ * ses 13 neutres et 7 de ses 11 bleus y sont faux, avec des clartes CIELAB
68
+ * presentees comme OKLCH (audit Claude Design §3.6). Le moteur reste la source ;
69
+ * les valeurs claires SEMANTIQUES du rendu (D17) vivent dans `theme.ts`.
70
+ */
71
+ /** Pas des rampes chromatiques, du plus clair au plus sombre. */
72
+ export declare const PAS_DE_RAMPE: readonly [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];
73
+ export type PasDeRampe = (typeof PAS_DE_RAMPE)[number];
74
+ /** Pas de la rampe neutre : ceux des rampes, plus 0 (le blanc) et 150 (le creux). */
75
+ export declare const PAS_NEUTRES: readonly [0, 50, 100, 150, 200, 300, 400, 500, 600, 700, 800, 900, 950];
76
+ export type PasNeutre = (typeof PAS_NEUTRES)[number];
77
+ /** Rangs de la palette categorielle. */
78
+ export declare const RANGS_DE_SERIE: readonly [1, 2, 3, 4, 5, 6];
79
+ export type RangDeSerie = (typeof RANGS_DE_SERIE)[number];
80
+ /** Clarte OKLCH de chaque pas, commune aux six familles chromatiques. */
81
+ export declare const L_PAS: Readonly<Record<PasDeRampe, number>>;
82
+ /** Part de la chroma maximale de la famille, par pas : la couleur culmine au pas 600. */
83
+ export declare const C_PAS: Readonly<Record<PasDeRampe, number>>;
84
+ export type NomDeFamille = 'bleu' | 'azur' | 'or' | 'vert' | 'ambre' | 'rouge';
85
+ export interface FamilleChromatique {
86
+ /** Teinte OKLCH, en degres. */
87
+ readonly teinte: number;
88
+ /** Chroma du pas le plus sature (600). */
89
+ readonly chromaMax: number;
90
+ /** Seule derogation a la table des clartes, ecrite et testee. */
91
+ readonly exception?: Partial<Record<PasDeRampe, number>>;
92
+ /** A quoi sert la famille. */
93
+ readonly vocation: string;
94
+ }
95
+ export declare const FAMILLES: Readonly<Record<NomDeFamille, FamilleChromatique>>;
96
+ /** Une primitive : sa definition OKLCH, son hex derive, et si le gamut l'a rabattue. */
97
+ export interface DefinitionDePrimitive {
98
+ readonly oklch: Oklch;
99
+ readonly hex: CouleurHex;
100
+ readonly rabattue: boolean;
101
+ }
102
+ /** Definition OKLCH d'un pas d'une famille chromatique. */
103
+ export declare function definitionDuPas(famille: NomDeFamille, pas: PasDeRampe): Oklch;
104
+ /** Les 85 primitives avec leur definition : ce que le nuancier du banc affiche. */
105
+ export declare const definitionsDesPrimitives: {
106
+ readonly neutre: Readonly<Record<0 | 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950 | 150, DefinitionDePrimitive>>;
107
+ readonly bleu: Readonly<Record<50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950, DefinitionDePrimitive>>;
108
+ readonly azur: Readonly<Record<50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950, DefinitionDePrimitive>>;
109
+ readonly or: Readonly<Record<50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950, DefinitionDePrimitive>>;
110
+ readonly vert: Readonly<Record<50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950, DefinitionDePrimitive>>;
111
+ readonly ambre: Readonly<Record<50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950, DefinitionDePrimitive>>;
112
+ readonly rouge: Readonly<Record<50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950, DefinitionDePrimitive>>;
113
+ readonly serie: Readonly<Record<3 | 1 | 2 | 4 | 5 | 6, DefinitionDePrimitive>>;
114
+ };
115
+ export type NomDeRampe = keyof typeof definitionsDesPrimitives;
116
+ /** Les primitives en hexadecimal : la forme que le theme et la feuille consomment. */
117
+ export declare const primitives: {
118
+ readonly neutre: Readonly<Record<0 | 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950 | 150, `#${string}`>>;
119
+ readonly bleu: Readonly<Record<50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950, `#${string}`>>;
120
+ readonly azur: Readonly<Record<50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950, `#${string}`>>;
121
+ readonly or: Readonly<Record<50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950, `#${string}`>>;
122
+ readonly vert: Readonly<Record<50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950, `#${string}`>>;
123
+ readonly ambre: Readonly<Record<50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950, `#${string}`>>;
124
+ readonly rouge: Readonly<Record<50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950, `#${string}`>>;
125
+ readonly serie: Readonly<Record<3 | 1 | 2 | 4 | 5 | 6, `#${string}`>>;
126
+ };
127
+ /**
128
+ * Echelles non chromatiques. Elles ne changent pas entre le theme clair et le
129
+ * theme sombre : une distance ni une graisse ne dependent de la luminosite. Les
130
+ * ombres, elles, dependent du theme : elles vivent dans `theme.ts`.
131
+ */
132
+ /**
133
+ * Pas de 4 px, plus trois demi-pas et le quart de pas `demi` (2 px).
134
+ *
135
+ * Les demi-pas (`1-5` = 6 px, `2-5` = 10 px, `3-5` = 14 px) sont ceux que les
136
+ * planches de Claude Design RENDENT (D21) : le padding de 14 px des champs, l'ecart
137
+ * de 6 px d'une pastille. Les arrondir a la grille de 4 decalerait tout de 2 px, et
138
+ * la garde de conformite (G1) le verrait. Une valeur hors echelle reste un defaut.
139
+ */
140
+ export declare const espacement: {
141
+ readonly '0': "0";
142
+ readonly '1': "0.25rem";
143
+ readonly '2': "0.5rem";
144
+ readonly '3': "0.75rem";
145
+ readonly '4': "1rem";
146
+ readonly '5': "1.25rem";
147
+ readonly '6': "1.5rem";
148
+ readonly '8': "2rem";
149
+ readonly '10': "2.5rem";
150
+ readonly '12': "3rem";
151
+ readonly '16': "4rem";
152
+ readonly '20': "5rem";
153
+ readonly '24': "6rem";
154
+ readonly demi: "0.125rem";
155
+ readonly '1-5': "0.375rem";
156
+ readonly '2-5': "0.625rem";
157
+ readonly '3-5': "0.875rem";
158
+ };
159
+ /**
160
+ * Rayons. Correspondance ecrite (01 §5.2) : commande = `md`, carte = `lg`,
161
+ * surface flottante = `md`, dialogue = `lg`, badge = `sm`, case = `xs`,
162
+ * pastille et avatar = `pleine`. Les planches rendent 4 / 8 / 12 / pleine.
163
+ */
164
+ export declare const rayon: {
165
+ readonly none: "0";
166
+ readonly xs: "0.125rem";
167
+ readonly sm: "0.25rem";
168
+ readonly md: "0.5rem";
169
+ readonly lg: "0.75rem";
170
+ readonly xl: "1rem";
171
+ readonly pleine: "9999px";
172
+ };
173
+ /** Cles de l'echelle typographique, de la plus petite a la plus grande. */
174
+ export declare const CLES_DE_TAILLE: readonly ["2xs", "xs", "sm", "md", "lg", "xl", "2xl", "3xl", "4xl", "5xl", "6xl"];
175
+ export type CleDeTaille = (typeof CLES_DE_TAILLE)[number];
176
+ /**
177
+ * Typographie (D18, D19). Echelle alignee sur le rendu de Claude Design : onze
178
+ * tailles, chacune avec SON interligne en rem — deux composants qui posent la
179
+ * meme taille ont la meme ligne.
180
+ *
181
+ * ⚠️ `2xs` (11 px) est RESERVE aux micro-libelles en capitales (`micro-capitales`,
182
+ * `surtitre`) : c'est le plancher absolu du socle, un texte de 9 ou 10 px est
183
+ * refuse (ecart EA-32). `xs` (12 px) est le plancher d'un texte courant.
184
+ */
185
+ export declare const typographie: {
186
+ readonly famille: {
187
+ readonly base: "'Inter Variable', 'Inter Repli', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif";
188
+ readonly mono: "'JetBrains Mono Variable', 'JetBrains Mono Repli', ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace";
189
+ };
190
+ readonly taille: {
191
+ readonly '2xs': "0.6875rem";
192
+ readonly xs: "0.75rem";
193
+ readonly sm: "0.875rem";
194
+ readonly md: "1rem";
195
+ readonly lg: "1.125rem";
196
+ readonly xl: "1.25rem";
197
+ readonly '2xl': "1.5rem";
198
+ readonly '3xl': "2rem";
199
+ readonly '4xl': "2.5rem";
200
+ readonly '5xl': "3rem";
201
+ readonly '6xl': "3.5rem";
202
+ };
203
+ readonly interligne: {
204
+ readonly '2xs': "0.875rem";
205
+ readonly xs: "1rem";
206
+ readonly sm: "1.25rem";
207
+ readonly md: "1.5rem";
208
+ readonly lg: "1.75rem";
209
+ readonly xl: "1.75rem";
210
+ readonly '2xl': "2rem";
211
+ readonly '3xl': "2.5rem";
212
+ readonly '4xl': "3rem";
213
+ readonly '5xl': "3.5rem";
214
+ readonly '6xl': "4rem";
215
+ };
216
+ readonly graisse: {
217
+ readonly normale: "400";
218
+ readonly moyenne: "500";
219
+ readonly semi: "600";
220
+ readonly grasse: "700";
221
+ };
222
+ /**
223
+ * Interlettrage des TEXTES. Les titres ont en plus une approche negative par
224
+ * taille, portee par leur style composite (`styles/_typographie.scss`) : elle
225
+ * n'est pas un reglage, elle suit la taille.
226
+ */
227
+ readonly interlettrage: {
228
+ readonly serre: "-0.01em";
229
+ readonly normal: "normal";
230
+ readonly large: "0.02em";
231
+ readonly capitales: "0.05em";
232
+ readonly etiquette: "0.04em";
233
+ readonly surtitre: "0.1em";
234
+ };
235
+ /**
236
+ * Approche des TITRES, par taille : negative, et d'autant plus serree que le corps
237
+ * grandit (DESIGN.md, echelle D18). Un jeton par taille employee par un titre :
238
+ * ecrite dans le partiel en litteral, elle echappait a la garde « aucun
239
+ * letter-spacing en dur » et a l'impression.
240
+ */
241
+ readonly approche: {
242
+ readonly lg: "-0.005em";
243
+ readonly xl: "-0.01em";
244
+ readonly '2xl': "-0.015em";
245
+ readonly '3xl': "-0.02em";
246
+ readonly '4xl': "-0.025em";
247
+ readonly '6xl': "-0.03em";
248
+ };
249
+ /**
250
+ * Deux contrats de chiffres (01 §4.4). `alignes` : tout ce qui s'aligne en
251
+ * colonne (montant, date, compteur, minuteur). `references` : tout ce qui se
252
+ * recopie ou se dicte (IBAN, code, telephone) — le zero y est barre.
253
+ */
254
+ readonly chiffres: {
255
+ readonly alignes: "tabular-nums lining-nums";
256
+ readonly references: "tabular-nums lining-nums slashed-zero";
257
+ };
258
+ };
259
+ /**
260
+ * Durees de transition (01 §6, D9) : la table est FERMEE. Au-dela de 250 ms une
261
+ * commande parait lente ; `lente` et `longue` sont reservees aux grandes surfaces
262
+ * (tiroir, feuille inferieure, entree de page). Ni `eclair` ni `ample` (D9, D24) :
263
+ * l'appui lit `rapide`, la feuille inferieure lit `lente` ou `longue`.
264
+ *
265
+ * ⚠️ Toute duree non nulle passe a ZERO sous mouvement reduit, et sous le gel
266
+ * d'une image (changement de theme ou de langue) : la feuille de jetons tranche,
267
+ * aucune feuille de composant n'ecrit `@media (prefers-reduced-motion)` autour
268
+ * d'une transition. Une duree ajoutee plus tard entre dans cette table ET dans le
269
+ * bloc de mise a zero — qui est engendre depuis elle.
270
+ *
271
+ * Le fondu d'une couche lit `normale` (D8) : il n'y a pas de reglage de fondu.
272
+ */
273
+ export declare const duree: {
274
+ readonly instantane: "0ms";
275
+ readonly rapide: "120ms";
276
+ readonly normale: "200ms";
277
+ readonly lente: "320ms";
278
+ readonly longue: "480ms";
279
+ };
280
+ /**
281
+ * Distances d'entree (01 §6) : d'ou arrive ce qui apparait. Une entree est une
282
+ * opacite PLUS un deplacement, jamais une echelle (D9) : c'est le seul motif que
283
+ * le mouvement reduit sait eteindre sans rien casser — distance a zero, la couche
284
+ * apparait en place.
285
+ *
286
+ * - `court` : menu, popover, liste deroulante (4 px, a peine le temps de le voir) ;
287
+ * - `moyen` : message ephemere, banniere (8 px) ;
288
+ * - `long` : tiroir partiel, page (16 px).
289
+ */
290
+ export declare const deplacement: {
291
+ readonly court: "0.25rem";
292
+ readonly moyen: "0.5rem";
293
+ readonly long: "1rem";
294
+ };
295
+ /**
296
+ * Cadences des boucles d'attente (01 §6, D24) : rotation de l'indicateur (`vive`),
297
+ * pulsation du squelette et va-et-vient de la progression (`normale`), respiration
298
+ * qui remplace le mouvement (`respiration`).
299
+ *
300
+ * ⚠️ **Hors de l'echelle des durees, et c'est le point.** `--st-duree-*` passe a
301
+ * zero sous mouvement reduit : un indicateur d'activite cable dessus se figerait,
302
+ * et l'ecran passerait pour bloque. Les cadences ne passent JAMAIS a zero ; les
303
+ * feuilles les lisent par `--st-anim-chargement` et `--st-anim-respiration`, deux
304
+ * reglages dont le repli est une cadence.
305
+ */
306
+ export declare const cadence: {
307
+ readonly vive: "900ms";
308
+ readonly normale: "1400ms";
309
+ readonly respiration: "1600ms";
310
+ };
311
+ /**
312
+ * Plancher d'une cadence (01 §6, regle 4) : une application peut RALENTIR une
313
+ * boucle d'attente, jamais l'eteindre ni la rendre frenetique. Les indicateurs
314
+ * lisent `max(<reglage>, var(--st-cadence-min))` : un `0ms` pose a la racine est
315
+ * refuse, et une boucle sous 600 ms clignoterait plus qu'elle n'informe.
316
+ */
317
+ export declare const cadenceMinimale = "600ms";
318
+ export declare const courbe: {
319
+ readonly standard: "cubic-bezier(0.2, 0, 0, 1)";
320
+ readonly entrant: "cubic-bezier(0, 0, 0, 1)";
321
+ readonly sortant: "cubic-bezier(0.3, 0, 1, 1)";
322
+ };
323
+ /**
324
+ * Plans d'empilement, reduits a ce qui s'applique vraiment (01 §5.5). Le CDK
325
+ * empile menus, popovers, infobulles, tiroirs et dialogues par l'ORDRE du DOM dans
326
+ * son conteneur, qui lit `superposition` : un plan par surface ne pilotait rien.
327
+ * Un `z-index` ecrit a la main dans un composant est un defaut.
328
+ */
329
+ export declare const plan: {
330
+ readonly base: "0";
331
+ readonly contenuEleve: "10";
332
+ readonly entete: "100";
333
+ readonly superposition: "300";
334
+ readonly notification: "600";
335
+ readonly evitement: "700";
336
+ };
337
+ /** Cible tactile minimale. Sous 44 px, l'echec de pointage devient courant. */
338
+ export declare const cibleTactileMinimale = "44px";
339
+ /**
340
+ * Cible de pointage minimale (WCAG 2.5.8, niveau AA). C'est un PLANCHER, pas un
341
+ * confort : la cible tactile reste la regle pour ce qui se touche.
342
+ */
343
+ export declare const cibleMinimale = "24px";
344
+ /**
345
+ * Epaisseurs de trait. `fine` separe, `moyenne` signale, `forte` designe (marqueur
346
+ * de selection de 3 px). `intermediaire` (1,5 px) est le filet des cases a cocher
347
+ * et `epaisse` (4 px) le connecteur du stepper, tous deux rendus par les planches
348
+ * (D21). `capillaire` est emise a part : 1 px, et un vrai pixel d'ecran (0,5 px) sur
349
+ * les dalles haute densite.
350
+ */
351
+ export declare const epaisseur: {
352
+ readonly fine: "1px";
353
+ readonly intermediaire: "1.5px";
354
+ readonly moyenne: "2px";
355
+ readonly forte: "3px";
356
+ readonly epaisse: "4px";
357
+ };
358
+ /** Filet d'un pixel d'ecran : `1px`, `0.5px` a 2 dppx, `1px` sous contraste force et a l'impression. */
359
+ export declare const epaisseurCapillaire: {
360
+ readonly base: "1px";
361
+ readonly hauteDensite: "0.5px";
362
+ };
363
+ /**
364
+ * Largeurs de mise en page (D2, D21). Deux mesures de lecture (`etroite`,
365
+ * `normale`, en `ch`), puis les largeurs d'objets reels : la page (90rem, le
366
+ * contenu de la planche 6), la navigation et son rail replie, la carte
367
+ * d'authentification (450 px, planche 8), les trois dialogues, le tiroir, le menu, la
368
+ * couche, trois largeurs de champ a cles ordonnees et la colonne de texte d'une ligne de reglage.
369
+ */
370
+ export declare const largeur: {
371
+ readonly etroite: "45ch";
372
+ readonly normale: "70ch";
373
+ readonly page: "90rem";
374
+ readonly navigation: "16rem";
375
+ readonly rail: "4.5rem";
376
+ readonly 'carte-auth': "28.125rem";
377
+ readonly 'dialogue-sm': "24rem";
378
+ readonly 'dialogue-md': "32rem";
379
+ readonly 'dialogue-lg': "48rem";
380
+ readonly tiroir: "28rem";
381
+ readonly menu: "12rem";
382
+ readonly couche: "28rem";
383
+ readonly 'champ-sm': "8rem";
384
+ readonly 'champ-md': "12rem";
385
+ readonly 'champ-lg': "16rem";
386
+ readonly colonne: "18rem";
387
+ };
388
+ /**
389
+ * Hauteurs de commande (D4) : pas de `xs`, le plancher est 32 px au pointeur fin
390
+ * et 44 px au doigt. `--st-hauteur-commande-defaut` suit la densite.
391
+ */
392
+ export declare const hauteurDeCommande: {
393
+ readonly sm: "2rem";
394
+ readonly md: "2.25rem";
395
+ readonly lg: "2.5rem";
396
+ readonly xl: "2.75rem";
397
+ readonly '2xl': "3.25rem";
398
+ };
399
+ /** Les trois densites (01 §5.6, D10, D29). `confortable` est le defaut, sans attribut. */
400
+ export declare const MODES_DE_DENSITE: readonly ["confortable", "dense", "compacte"];
401
+ export type ModeDeDensite = (typeof MODES_DE_DENSITE)[number];
402
+ /**
403
+ * Variables de densite, par mode. Une densite est un MODE, pas quatre reglages :
404
+ * la hauteur de commande, la respiration des cellules, la taille du texte des
405
+ * listes, la case de calendrier et la hauteur de ligne de liste derivent ensemble.
406
+ * En compacte, le texte descend a 12 px et jamais moins (D10 amende).
407
+ */
408
+ export declare const densite: Readonly<Record<ModeDeDensite, Readonly<Record<string, string>>>>;
409
+ /**
410
+ * Focus a deux voies (01 §3.3) : anneau exterieur + lisere qui le detache d'un
411
+ * fond colore. Sous `prefers-contrast: more`, l'anneau passe a `forte` (3 px).
412
+ */
413
+ export declare const focus: {
414
+ readonly epaisseur: "var(--st-epaisseur-moyenne)";
415
+ readonly decalage: "var(--st-epaisseur-moyenne)";
416
+ readonly lisere: "var(--st-epaisseur-moyenne)";
417
+ };
418
+ /**
419
+ * Calcul de contraste : WCAG 2.x (la norme opposable) et APCA (la perception).
420
+ * Il vit dans les jetons, et non dans les tests, parce qu'une SPA peut avoir a
421
+ * verifier une couleur fournie a l'execution (theme d'un client, statut colore
422
+ * par une donnee).
423
+ *
424
+ * WCAG decide ; APCA informe. Une paire peut tenir 4,5:1 et fatiguer l'oeil
425
+ * (texte fin gris sur gris clair) : le temoin APCA le signale sans faire echouer
426
+ * la garde, parce qu'APCA n'est pas une norme (WCAG 3 est un brouillon).
427
+ */
428
+ export interface Rvb {
429
+ readonly r: number;
430
+ readonly g: number;
431
+ readonly b: number;
432
+ }
433
+ /** Couleur avec son opacite, entre 0 (transparente) et 1 (opaque). */
434
+ export interface Rvba extends Rvb {
435
+ readonly a: number;
436
+ }
437
+ /**
438
+ * Lit `#rgb`, `#rrggbb`, `rgb(...)` et `rgba(...)` (les deux ecritures). Leve
439
+ * sur toute autre forme : une couleur illisible ne doit pas se transformer en
440
+ * noir par defaut.
441
+ */
442
+ export declare function lireCouleur(texte: string): Rvba;
443
+ /**
444
+ * Couleur OPAQUE, en composantes. Une couleur translucide leve : son contraste
445
+ * depend du fond sur lequel elle se pose, il faut d'abord la `composer()`.
446
+ */
447
+ export declare function versRvb(couleur: string): Rvb;
448
+ /**
449
+ * Pose une couleur (translucide ou non) sur un fond opaque, comme le moteur de
450
+ * rendu : `rgb(0 0 0 / 0.2)` sur `#ffffff` donne `#cccccc`. C'est ce qui rend
451
+ * mesurable une ombre, un voile ou un filet teinte.
452
+ */
453
+ export declare function composer(premierPlan: string, fond: string): string;
454
+ /** Luminance relative WCAG, entre 0 (noir) et 1 (blanc). */
455
+ export declare function luminanceRelative(couleur: string | Rvb): number;
456
+ /** Rapport de contraste, entre 1 et 21. L'ordre des arguments est indifferent. */
457
+ export declare function rapportDeContraste(a: string | Rvb, b: string | Rvb): number;
458
+ export type NiveauContraste = 'AA' | 'AAA';
459
+ export type NatureDuTexte = 'courant' | 'grand' | 'composant';
460
+ /**
461
+ * Seuils WCAG. `composant` couvre les bordures, icones et limites de champ :
462
+ * la norme 1.4.11 leur demande 3:1, pas 4.5:1.
463
+ */
464
+ export declare function seuilExige(niveau: NiveauContraste, nature: NatureDuTexte): number;
465
+ export declare function respecteLeContraste(premierPlan: string, arrierePlan: string, niveau?: NiveauContraste, nature?: NatureDuTexte): boolean;
466
+ /**
467
+ * Contraste perceptuel APCA, en Lc. Le signe dit la polarite : positif pour un
468
+ * texte sombre sur fond clair, negatif pour un texte clair sur fond sombre.
469
+ * Reperes : 106,0 (noir sur blanc), -107,9 (blanc sur noir), 75,6 (`#1234b0` sur
470
+ * `#e9e4d0`). L'ORDRE des arguments compte, contrairement a WCAG.
471
+ *
472
+ * Seuils d'usage (01 §3.2, jamais bloquants) : 75 pour un texte courant, 60
473
+ * pour 18 px et plus, 15 pour un filet.
474
+ */
475
+ export declare function apca(texte: string, fond: string): number;
476
+ /**
477
+ * Niveau 2 — jetons semantiques. C'est le SEUL niveau que les composants
478
+ * consomment. Le nom dit le role, jamais la couleur : `danger` reste `danger`
479
+ * si la charte passe du rouge a l'orange.
480
+ *
481
+ * Noms, structure, derivation sombre et statuts : `docs/design-cible/01` §3.
482
+ * Valeurs CLAIRES : celles du rendu de Claude Design (decision D17, ADR 0005),
483
+ * bouton principal en systeme A (`primaire #003181`, survol `#1948a5`).
484
+ */
485
+ export interface JetonsDeCouleur {
486
+ readonly fond: CouleurHex;
487
+ readonly surface: CouleurHex;
488
+ readonly surfaceElevee: CouleurHex;
489
+ readonly surfaceEnfoncee: CouleurHex;
490
+ readonly surfaceConteneurBas: CouleurHex;
491
+ readonly surfaceConteneurHaut: CouleurHex;
492
+ readonly surfaceSurvol: CouleurHex;
493
+ readonly surfaceSurvolElevee: CouleurHex;
494
+ readonly surfaceCouranteElevee: CouleurHex;
495
+ readonly surfaceActive: CouleurHex;
496
+ readonly surfaceSelection: CouleurHex;
497
+ readonly surfaceInverse: CouleurHex;
498
+ readonly surfaceMarque: CouleurHex;
499
+ readonly texte: CouleurHex;
500
+ readonly texteDiscret: CouleurHex;
501
+ readonly texteAttenue: CouleurHex;
502
+ readonly texteDesactive: CouleurHex;
503
+ readonly texteInverse: CouleurHex;
504
+ readonly textePrimaire: CouleurHex;
505
+ readonly texteSurMarque: CouleurHex;
506
+ readonly texteSurMarqueDiscret: CouleurHex;
507
+ readonly bordure: CouleurHex;
508
+ readonly bordureForte: CouleurHex;
509
+ readonly bordureSelection: CouleurHex;
510
+ readonly anneauFocus: CouleurHex;
511
+ readonly lisereFocus: CouleurHex;
512
+ readonly selection: CouleurHex;
513
+ readonly surSelection: CouleurHex;
514
+ readonly primaire: CouleurHex;
515
+ readonly primaireSurvol: CouleurHex;
516
+ readonly primaireActif: CouleurHex;
517
+ readonly surPrimaire: CouleurHex;
518
+ readonly primaireDiscret: CouleurHex;
519
+ readonly surPrimaireDiscret: CouleurHex;
520
+ readonly primaireAttenue: CouleurHex;
521
+ readonly surPrimaireAttenue: CouleurHex;
522
+ readonly accent: CouleurHex;
523
+ readonly accentSurvol: CouleurHex;
524
+ readonly surAccent: CouleurHex;
525
+ readonly accentDiscret: CouleurHex;
526
+ readonly surAccentDiscret: CouleurHex;
527
+ readonly information: CouleurHex;
528
+ readonly surInformation: CouleurHex;
529
+ readonly informationDiscret: CouleurHex;
530
+ readonly surInformationDiscret: CouleurHex;
531
+ readonly succes: CouleurHex;
532
+ readonly surSucces: CouleurHex;
533
+ readonly succesDiscret: CouleurHex;
534
+ readonly surSuccesDiscret: CouleurHex;
535
+ readonly avertissement: CouleurHex;
536
+ readonly surAvertissement: CouleurHex;
537
+ readonly avertissementDiscret: CouleurHex;
538
+ readonly surAvertissementDiscret: CouleurHex;
539
+ readonly danger: CouleurHex;
540
+ readonly dangerSurvol: CouleurHex;
541
+ readonly dangerActif: CouleurHex;
542
+ readonly surDanger: CouleurHex;
543
+ readonly dangerDiscret: CouleurHex;
544
+ readonly surDangerDiscret: CouleurHex;
545
+ readonly dangerDiscretCourant: CouleurHex;
546
+ readonly positif: CouleurHex;
547
+ readonly negatif: CouleurHex;
548
+ }
549
+ export type NomDeJeton = keyof JetonsDeCouleur;
550
+ export type NomDeTheme = 'clair' | 'sombre';
551
+ export declare const themeClair: JetonsDeCouleur;
552
+ /**
553
+ * Derivation du sombre (01 §3.1, ecrite et testee) : les surfaces montent vers
554
+ * l'encre, le texte descend vers le clair, les accents passent au pas 300 (lisible
555
+ * sur encre a 9:1), les `*Discret` au pas 900 et leurs `sur*` au pas 100, le survol
556
+ * d'un accent s'eclaircit. Ne change pas : `bordureForte` (3:1 sur les deux).
557
+ */
558
+ export declare const themeSombre: JetonsDeCouleur;
559
+ export declare const themes: Readonly<Record<NomDeTheme, JetonsDeCouleur>>;
560
+ /**
561
+ * Les paires que le contraste doit tenir, dans les DEUX themes. Elles sont
562
+ * declarees ici, et non dans le test, pour qu'un jeton ajoute sans sa paire saute
563
+ * aux yeux : le test verifie aussi que chaque couleur de premier plan est couverte.
564
+ * Aucun compte n'est ecrit nulle part : il se lit sur `pairesDeContraste.length`.
565
+ *
566
+ * ⚠️ La nature se declare selon l'USAGE le plus exigeant, jamais selon la vocation
567
+ * premiere de la couleur : `succes` est aussi du TEXTE (`st-inline-message`), il se
568
+ * mesure donc a 4,5:1 et non a 3:1 (audit de la vague 2, UX-7).
569
+ */
570
+ export interface PaireDeContraste {
571
+ readonly premierPlan: NomDeJeton;
572
+ readonly arrierePlan: NomDeJeton;
573
+ readonly nature: NatureDuTexte;
574
+ }
575
+ export declare const pairesDeContraste: readonly PaireDeContraste[];
576
+ /**
577
+ * Jetons volontairement HORS du controle de contraste, avec leur raison.
578
+ * Une exemption non ecrite est un oubli ; ecrite, elle se discute.
579
+ */
580
+ export interface Exemption {
581
+ readonly jeton: NomDeJeton;
582
+ readonly raison: string;
583
+ }
584
+ export declare const exemptesDeContraste: readonly Exemption[];
585
+ /**
586
+ * Paires qu'on pourrait croire permises et qui NE LE SONT PAS : elles echouent dans
587
+ * au moins un theme, et la regle d'usage est ecrite a la place. Le test verifie
588
+ * qu'elles echouent vraiment — une exclusion qui passe doit redevenir une paire.
589
+ */
590
+ export interface PaireExclue {
591
+ readonly premierPlan: NomDeJeton;
592
+ readonly arrierePlan: NomDeJeton;
593
+ readonly raison: string;
594
+ }
595
+ export declare const pairesExclues: readonly PaireExclue[];
596
+ /** Seuil de perceptibilite des jetons exemptes : ils n'ont pas de minimum
597
+ * normatif, mais un separateur invisible ne separe rien. */
598
+ export declare const SEUIL_DE_PERCEPTIBILITE = 1.2;
599
+ /**
600
+ * Ecarts de SURFACE qui doivent rester perceptibles (01 §3.4, remesure sur les
601
+ * valeurs du rendu). Les minimums suivent le rendu de D17 : `surfaceActive` sur
602
+ * `surfaceSurvol` vaut 1,11:1 en clair (#dde3ee sur #e9eefa), la ou `01` visait
603
+ * 1,25 ; l'enfonce se lit aussi par le curseur et la transition.
604
+ */
605
+ export interface EcartDeSurface {
606
+ readonly devant: NomDeJeton;
607
+ readonly derriere: NomDeJeton;
608
+ readonly minimum: number;
609
+ readonly pourquoi: string;
610
+ }
611
+ export declare const ecartsDeSurface: readonly EcartDeSurface[];
612
+ /**
613
+ * Focus a deux voies (01 §3.3) : sur chaque surface ou un focus peut se poser,
614
+ * l'anneau OU son lisere tient 3:1. Un anneau d'une seule couleur ne le peut pas
615
+ * (1,94:1 sur `primaire`) : le lisere est donc la regle PAR DEFAUT de `_focus.scss`.
616
+ */
617
+ export declare const surfacesDuFocus: readonly NomDeJeton[];
618
+ /** Les cinq couches d'elevation (01 §5.4), du papier pose au dialogue. */
619
+ export declare const COUCHES: readonly ["repos", "survol", "surelevee", "flottante", "modale"];
620
+ export type NomDeCouche = (typeof COUCHES)[number];
621
+ /** Une couche d'ombre : sa geometrie, et sa couleur dans chaque theme. */
622
+ export interface CoucheDOmbre {
623
+ readonly geometrie: string;
624
+ readonly couleur: Readonly<Record<NomDeTheme, string>>;
625
+ }
626
+ /**
627
+ * Ombres de couche : celles que les planches RENDENT (valeurs du rendu, D17).
628
+ * Repos, survol, surelevee et flottante sont les ombres noires a 5-10 % des
629
+ * planches 2 a 16 ; modale est l'ombre teintee d'encre de la planche 5, identique
630
+ * a `01` §5.4. Le seul modele sombre au pixel (planche 6.3) pose les MEMES ombres
631
+ * qu'en clair : en sombre, l'elevation se lit d'abord par la surface qui s'eclaircit
632
+ * et par le filet (01 P4), l'ombre ne fait que la confirmer.
633
+ */
634
+ export declare const ombres: Readonly<Record<NomDeCouche, readonly CoucheDOmbre[]>>;
635
+ /** Voile pose derriere un dialogue ou un tiroir (planche 5, 01 §5.4). */
636
+ export declare const voile: Readonly<Record<NomDeTheme, string>>;
637
+ /** Teinte des ombres internes des composants (ombre de defilement d'un tableau). */
638
+ export declare const couleurDOmbre: Readonly<Record<NomDeTheme, string>>;
639
+ /** L'ombre d'une couche, telle qu'un theme la rend. */
640
+ export declare function ombreDuTheme(couche: NomDeCouche, theme: NomDeTheme): string;
641
+ /**
642
+ * Pour chaque primitive employee par un theme, les jetons qui la lisent :
643
+ * `bleu.700 -> clair: bordureSelection, primaireSurvol`. ENGENDRE depuis les
644
+ * themes, et non ecrit a cote : le nuancier du banc l'affiche, et une valeur
645
+ * recopiee a la main finirait par mentir (la planche 11 en est la preuve).
646
+ */
647
+ export declare function rolesDesPrimitives(): ReadonlyMap<string, readonly string[]>;
648
+ /**
649
+ * Styles typographiques composites (01 §4.3, D5, D15, D18) : une composition
650
+ * GARANTIE de taille, interligne, graisse, interlettrage et chiffres. Deux titres
651
+ * de page, l'un dans une carte et l'autre dans un dialogue, ne peuvent plus
652
+ * diverger d'un demi-point.
653
+ *
654
+ * Une seule notation, `@include st.style('titre-2')` (D15), dans le partiel Sass
655
+ * ENGENDRE `styles/_typographie.scss`. Aucun nom Material 3 (`headline-sm`,
656
+ * `label-md`) : la correspondance avec les planches de Claude Design est ecrite
657
+ * dans la recette `docs/recettes/police.md`, pas dans le socle.
658
+ *
659
+ * ⚠️ Un style ne pose JAMAIS de couleur : la couleur est un role semantique, le
660
+ * style une forme. Il ne pose la famille que pour la chasse fixe.
661
+ */
662
+ type Graisse = keyof typeof typographie.graisse;
663
+ type Interlettrage = keyof typeof typographie.interlettrage;
664
+ export interface StyleComposite {
665
+ readonly taille: CleDeTaille;
666
+ /**
667
+ * Interligne d'une autre cle que la taille : une EXCEPTION ecrite. La seule est
668
+ * `titre-4`, 18/24 (D18), la ou l'interligne de `lg` vaut 28.
669
+ */
670
+ readonly interligne?: CleDeTaille;
671
+ readonly graisse: Graisse;
672
+ /**
673
+ * Nom d'interlettrage du theme, ou `approche` : l'approche negative d'un titre, lue
674
+ * dans `typographie.approche` a la cle de sa TAILLE (jamais un litteral en em).
675
+ */
676
+ readonly interlettrage: Interlettrage | 'approche';
677
+ readonly chiffres?: keyof typeof typographie.chiffres;
678
+ readonly famille?: 'mono';
679
+ /** Micro-libelles en capitales : la casse fait partie de la forme. */
680
+ readonly capitales?: true;
681
+ readonly usage: string;
682
+ }
683
+ /** Les styles du socle. L'ordre est celui de la documentation. */
684
+ export declare const stylesTypographiques: {
685
+ readonly corps: {
686
+ readonly taille: "md";
687
+ readonly graisse: "normale";
688
+ readonly interlettrage: "normal";
689
+ readonly usage: "texte courant";
690
+ };
691
+ readonly 'corps-petit': {
692
+ readonly taille: "sm";
693
+ readonly graisse: "normale";
694
+ readonly interlettrage: "normal";
695
+ readonly usage: "texte secondaire";
696
+ };
697
+ readonly 'corps-fort': {
698
+ readonly taille: "md";
699
+ readonly graisse: "semi";
700
+ readonly interlettrage: "normal";
701
+ readonly usage: "intitule de ligne, valeur secondaire (D5)";
702
+ };
703
+ readonly 'corps-grand': {
704
+ readonly taille: "lg";
705
+ readonly graisse: "normale";
706
+ readonly interlettrage: "normal";
707
+ readonly usage: "texte d introduction, mention juridique (18/28, DESIGN.md body-lg)";
708
+ };
709
+ readonly legende: {
710
+ readonly taille: "xs";
711
+ readonly graisse: "moyenne";
712
+ readonly interlettrage: "large";
713
+ readonly usage: "legende, etiquette de badge";
714
+ };
715
+ readonly libelle: {
716
+ readonly taille: "sm";
717
+ readonly graisse: "moyenne";
718
+ readonly interlettrage: "normal";
719
+ readonly usage: "libelle de champ, onglet (D18 : 14/500)";
720
+ };
721
+ readonly commande: {
722
+ readonly taille: "sm";
723
+ readonly graisse: "semi";
724
+ readonly interlettrage: "normal";
725
+ readonly usage: "libelle de bouton de 44 px (14/20 600, majorite des planches)";
726
+ };
727
+ readonly etiquette: {
728
+ readonly taille: "xs";
729
+ readonly graisse: "semi";
730
+ readonly interlettrage: "etiquette";
731
+ readonly usage: "en-tete de colonne, etiquette de statut (12/16 600, DESIGN.md label-md)";
732
+ };
733
+ readonly 'micro-capitales': {
734
+ readonly taille: "2xs";
735
+ readonly graisse: "semi";
736
+ readonly interlettrage: "capitales";
737
+ readonly capitales: true;
738
+ readonly usage: "en-tete de colonne, terme de liste, statut en capitales (seul lecteur de 2xs)";
739
+ };
740
+ readonly surtitre: {
741
+ readonly taille: "2xs";
742
+ readonly graisse: "semi";
743
+ readonly interlettrage: "surtitre";
744
+ readonly capitales: true;
745
+ readonly usage: "surtitre de page ou de section, en capitales espacees";
746
+ };
747
+ readonly 'titre-4': {
748
+ readonly taille: "lg";
749
+ readonly interligne: "md";
750
+ readonly graisse: "semi";
751
+ readonly interlettrage: "approche";
752
+ readonly usage: "intertitre, titre de dialogue et de carte (18/24)";
753
+ };
754
+ readonly 'titre-3': {
755
+ readonly taille: "xl";
756
+ readonly graisse: "semi";
757
+ readonly interlettrage: "approche";
758
+ readonly usage: "titre de section";
759
+ };
760
+ readonly 'titre-2': {
761
+ readonly taille: "2xl";
762
+ readonly graisse: "semi";
763
+ readonly interlettrage: "approche";
764
+ readonly usage: "titre de bloc majeur";
765
+ };
766
+ readonly 'titre-1': {
767
+ readonly taille: "3xl";
768
+ readonly graisse: "semi";
769
+ readonly interlettrage: "approche";
770
+ readonly usage: "titre de page (h1 de 32 px, D18)";
771
+ };
772
+ readonly affichage: {
773
+ readonly taille: "4xl";
774
+ readonly graisse: "semi";
775
+ readonly interlettrage: "approche";
776
+ readonly usage: "annonce, titre d ecran de marque";
777
+ };
778
+ readonly 'affichage-grand': {
779
+ readonly taille: "6xl";
780
+ readonly graisse: "semi";
781
+ readonly interlettrage: "approche";
782
+ readonly usage: "grand chiffre de tableau de bord (56/64, DESIGN.md display-lg)";
783
+ };
784
+ readonly 'chiffre-cle': {
785
+ readonly taille: "3xl";
786
+ readonly graisse: "semi";
787
+ readonly interlettrage: "approche";
788
+ readonly chiffres: "alignes";
789
+ readonly usage: "valeur de st-stat";
790
+ };
791
+ readonly montant: {
792
+ readonly taille: "md";
793
+ readonly graisse: "moyenne";
794
+ readonly interlettrage: "normal";
795
+ readonly chiffres: "alignes";
796
+ readonly usage: "st-money, cellule numerique";
797
+ };
798
+ readonly 'montant-hero': {
799
+ readonly taille: "4xl";
800
+ readonly graisse: "semi";
801
+ readonly interlettrage: "approche";
802
+ readonly chiffres: "alignes";
803
+ readonly usage: "solde de compte (40/48, planche 2)";
804
+ };
805
+ readonly reference: {
806
+ readonly taille: "sm";
807
+ readonly graisse: "normale";
808
+ readonly interlettrage: "large";
809
+ readonly chiffres: "references";
810
+ readonly famille: "mono";
811
+ readonly usage: "IBAN, identifiant, reference de virement";
812
+ };
813
+ readonly code: {
814
+ readonly taille: "sm";
815
+ readonly graisse: "normale";
816
+ readonly interlettrage: "normal";
817
+ readonly chiffres: "references";
818
+ readonly famille: "mono";
819
+ readonly usage: "st-code";
820
+ };
821
+ };
822
+ export type NomDeStyle = keyof typeof stylesTypographiques;
823
+ /** La valeur (en em ou `normal`) de l'interlettrage d'un style, resolue dans l'echelle. */
824
+ export declare function interlettrageDuStyle(nom: NomDeStyle): string;
825
+ /** Les declarations d'un style, telles que le partiel les ecrit. */
826
+ export declare function declarationsDuStyle(nom: NomDeStyle): readonly string[];
827
+ /**
828
+ * Le partiel Sass `_typographie.scss`, ENGENDRE comme la feuille de jetons et
829
+ * garde par `pnpm tokens:css:check`. Un nom inconnu echoue a la COMPILATION
830
+ * (`@error`) : une faute de frappe ne laisse pas un titre sans style.
831
+ *
832
+ * ```scss
833
+ * @use '@starterlib/tokens/styles/typographie' as typo;
834
+ * h2 { @include typo.style('titre-2'); }
835
+ * ```
836
+ */
837
+ export declare function partielDeTypographie(): string;
838
+ /**
839
+ * Polices du socle (D19) : Inter Variable et JetBrains Mono Variable, AUTO-HEBERGEES
840
+ * (licence SIL OFL 1.1, fichiers copies depuis `@fontsource-variable/*` aux versions
841
+ * epinglees). Aucune adresse tierce : `font-src 'self'` suffit sous CSP stricte, et
842
+ * aucune adresse IP ne part chez un fournisseur de polices.
843
+ *
844
+ * La feuille `styles/polices.css` est ENGENDREE d'ici et livree a part : elle
845
+ * n'est importee par aucune autre feuille du socle. Le banc et la coquille la
846
+ * chargent par defaut ; une SPA l'ajoute par la recette `docs/recettes/police.md`.
847
+ *
848
+ * `font-display: optional` : la police n'est employee que si elle est deja la
849
+ * (cache, ou prechargee dans la fenetre de blocage d'une centaine de millisecondes) ;
850
+ * sinon le REPLI METRISE s'affiche et la page ne bouge plus. Le repli est une
851
+ * police locale dont les surcharges (`size-adjust`, `ascent-override`...) sont
852
+ * CALCULEES sur les metriques du fichier livre : meme hauteur de ligne, meme
853
+ * chasse moyenne, aucun decalage de mise en page. `tools/verifier-police.mjs`
854
+ * relit les fichiers et echoue si une metrique ci-dessous a derive.
855
+ */
856
+ /** Metriques d'une police, en unites de sa grille (`unitesParEm`). */
857
+ export interface MetriquesDePolice {
858
+ readonly unitesParEm: number;
859
+ readonly ascendante: number;
860
+ /** Positive : la profondeur sous la ligne de base. */
861
+ readonly descendante: number;
862
+ readonly interligneAjoute: number;
863
+ /**
864
+ * Chasse moyenne ponderee par la frequence des lettres d'un texte courant
865
+ * (espace compris), a la maniere de Capsize : c'est elle qui regle `size-adjust`.
866
+ */
867
+ readonly chasseMoyenne: number;
868
+ }
869
+ export interface FichierDePolice {
870
+ /** Nom du fichier sous `styles/polices/`. */
871
+ readonly fichier: string;
872
+ readonly unicodeRange: string;
873
+ /** Le seul fichier que le premier ecran peint : c'est lui qu'on precharge. */
874
+ readonly aPrecharger: boolean;
875
+ }
876
+ export interface PoliceDuSocle {
877
+ readonly famille: string;
878
+ readonly graisses: string;
879
+ readonly paquet: string;
880
+ readonly fichiers: readonly FichierDePolice[];
881
+ readonly metriques: MetriquesDePolice;
882
+ readonly repli: {
883
+ readonly famille: string;
884
+ /** Polices locales aux metriques IDENTIQUES entre elles (clones metriques). */
885
+ readonly locales: readonly string[];
886
+ readonly metriques: MetriquesDePolice;
887
+ };
888
+ }
889
+ export declare const policesDuSocle: readonly PoliceDuSocle[];
890
+ /** Surcharges du repli, en pourcentage, arrondies au centieme. */
891
+ export interface SurchargesDuRepli {
892
+ readonly sizeAdjust: string;
893
+ readonly ascentOverride: string;
894
+ readonly descentOverride: string;
895
+ readonly lineGapOverride: string;
896
+ }
897
+ /**
898
+ * Le calcul de Capsize : le repli est agrandi pour que sa chasse moyenne egale
899
+ * celle de la police, puis ses ascendante, descendante et interligne sont ramenes
900
+ * a ceux de la police, divises par ce meme agrandissement.
901
+ */
902
+ export declare function surchargesDuRepli(police: PoliceDuSocle): SurchargesDuRepli;
903
+ /** Les fichiers a precharger par l'hote, dans l'ordre. */
904
+ export declare function fichiersAPrecharger(): readonly string[];
905
+ /**
906
+ * La feuille `styles/polices.css`. Les adresses sont RELATIVES a la feuille
907
+ * (`./polices/…`) : l'outil de construction de l'hote les reecrit et les sert de
908
+ * sa propre origine.
909
+ */
910
+ export declare function feuilleDesPolices(): string;
911
+ /**
912
+ * Niveau 3 — jetons de composant. Les quelques reglages qu'une application peut
913
+ * poser sans forker une feuille de style.
914
+ *
915
+ * ⚠️ **Un jeton de composant est une PROMESSE PUBLIQUE.** Il se tient aussi
916
+ * longtemps que le composant existe : le catalogue reste donc court (moins de
917
+ * quinze entrees, 01 §8 et D8), et chaque entree repond a un besoin reel —
918
+ * densite, identite de marque, rythme d'attente. Tout le reste passe par le
919
+ * niveau semantique, ou n'a pas a etre ouvert.
920
+ *
921
+ * ⚠️ **Ils ne sont PAS declares sur l'hote du composant, et c'est le coeur du
922
+ * mecanisme.** Une valeur declaree sur `:host` l'emporte sur celle qu'un ancetre
923
+ * herite : l'application poserait son reglage a la racine, et le composant
924
+ * continuerait d'afficher le sien. Les feuilles du socle les lisent donc au
925
+ * POINT D'USAGE, avec un repli :
926
+ *
927
+ * ```scss
928
+ * min-block-size: var(--st-commande-hauteur, var(--st-hauteur-commande-defaut));
929
+ * ```
930
+ *
931
+ * L'application, elle, les pose ou elle veut — a la racine, sur une zone, sur
932
+ * une instance :
933
+ *
934
+ * ```css
935
+ * .tableau-dense { --st-tableau-cellule-bloc: var(--st-espacement-1); }
936
+ * ```
937
+ *
938
+ * ⚠️ **Aucune couleur ici.** Une couleur se change au niveau semantique, sinon
939
+ * le meme bleu a deux sources de verite, et les paires de contraste verifiees ne
940
+ * garantissent plus rien. `--st-carte-fond` a ete retire pour cette raison (0.9).
941
+ *
942
+ * Une variable interne pilotee par une entree — `--st-icone-taille`,
943
+ * `--st-avatar-taille` — n'est pas un jeton de composant : elle est declaree sur
944
+ * l'hote, elle n'est pas dans ce catalogue, et elle peut changer sans preavis
945
+ * (liste : `variablesInternes`).
946
+ */
947
+ export interface JetonDeComposant {
948
+ /** Nom complet de la propriete CSS, prefixe compris. */
949
+ readonly nom: string;
950
+ /** Ce que le socle emploie quand l'application ne pose rien. */
951
+ readonly repli: string;
952
+ /** A quoi il sert, et pour qui. */
953
+ readonly role: string;
954
+ /** Les composants qui le lisent (verifie par la garde des feuilles). */
955
+ readonly lecteurs: readonly string[];
956
+ }
957
+ export declare const jetonsDeComposant: readonly JetonDeComposant[];
958
+ /**
959
+ * Contrats d'HOTE (D7, D16) : poses par un composant sur la page pour qu'une
960
+ * autre feuille les lise. Ils ne sont ni des jetons de la feuille, ni des
961
+ * reglages d'application.
962
+ */
963
+ export declare const contratsDHote: readonly string[];
964
+ /**
965
+ * Variables internes legitimes (D13) : declarees sur l'hote du composant qui les
966
+ * lit, pilotees par ses entrees, hors catalogue et sans promesse.
967
+ */
968
+ export declare const variablesInternes: readonly string[];
969
+ /** Vrai si la propriete fait partie du catalogue public. */
970
+ export declare function estJetonDeComposant(nom: string): boolean;
971
+ /**
972
+ * Les proprietes CSS personnalisees sont ENGENDREES depuis les jetons
973
+ * TypeScript, jamais ecrites a la main en parallele. Deux sources de verite
974
+ * pour une meme couleur finissent toujours par diverger ; ici la derive est
975
+ * impossible, et la CI verifie que le fichier livre correspond au code.
976
+ *
977
+ * ⚠️ **Une seule declaration par couleur**, en `light-dark(clair, sombre)`. Le
978
+ * theme ne recopie plus trente couleurs dans quatre blocs qui se battent a la
979
+ * specificite : il pose `color-scheme`, et chaque couleur se resout d'elle-meme
980
+ * la ou elle est EMPLOYEE. C'est ce qui rend possibles les ILOTS de theme : un
981
+ * conteneur `[data-theme='sombre']` dans une page claire rend ses descendants en
982
+ * sombre, avec les memes jetons (carte sombre de la planche 6.3).
983
+ * Plancher navigateur : `light-dark()` est Baseline 2024 (Chrome 123, Safari 17.5,
984
+ * Firefox 120) — voir `docs/matrice-compatibilite.md`.
985
+ */
986
+ export declare const PREFIXE = "--st";
987
+ export declare function enKebab(valeur: string): string;
988
+ export declare function nomDeCouleur(jeton: NomDeJeton): string;
989
+ /** Jetons invariants : ils ne dependent pas du theme. */
990
+ export declare function cssDesEchelles(): string;
991
+ /** Couleurs, ombres et voile : une declaration chacun, en `light-dark()`. */
992
+ export declare function cssDuTheme(): string;
993
+ /**
994
+ * Mouvement reduit (01 §6, 03 P5) : toute duree non nulle ET tout deplacement a zero.
995
+ * Une couche apparait alors en place et d'un coup, sans qu'aucun composant sache
996
+ * qu'il est sous mouvement reduit : il consomme les jetons, la feuille tranche.
997
+ *
998
+ * ⚠️ **Les cadences n'y figurent pas, et c'est voulu** : une boucle d'attente
999
+ * figee ferait croire a un ecran bloque. Sous mouvement reduit, les indicateurs
1000
+ * passent de la rotation a la respiration (une pulsation d'opacite), par le mixin
1001
+ * `sous-mouvement-reduit` du partiel `ruptures`.
1002
+ *
1003
+ * `0rem` et non `0` : un deplacement se lit dans `calc(-1 * var(...))`, et un zero
1004
+ * sans unite y deviendrait un nombre, que `translate` refuse.
1005
+ */
1006
+ export declare const mouvementReduit: Readonly<Record<string, string>>;
1007
+ /**
1008
+ * Gel d'une image (03 §2.6 d) : au changement de theme ou de langue, `StTheme` et
1009
+ * `StLangue` posent `data-gel` sur `<html>` jusqu'au rendu suivant. Toutes les
1010
+ * durees a zero : cent vingt millisecondes de boutons en retard sur un fond deja
1011
+ * change se liraient comme un defaut. Aucun `!important`, aucun
1012
+ * `* { transition: none }` : chaque transition lit les jetons, geler les jetons gele
1013
+ * tout — et les boucles d'attente, sur leurs cadences, continuent.
1014
+ */
1015
+ export declare const mouvementGele: Readonly<Record<string, string>>;
1016
+ /**
1017
+ * `prefers-contrast: more` (01 §7.1) : chaque jeton prend la valeur d'un jeton plus
1018
+ * contraste DU MEME THEME. Chaque niveau monte d'un cran, et la hierarchie reste :
1019
+ * le texte attenue devient le texte discret, pas le texte.
1020
+ *
1021
+ * ⚠️ La valeur est ecrite en `light-dark()` et non en `var()` : des alias en chaine
1022
+ * (`attenue -> discret -> texte`) se resolvent l'un par l'autre sur le meme element,
1023
+ * et tout le texte finirait au niveau 1.
1024
+ *
1025
+ * Le creux (`surfaceEnfoncee`) ne bascule PAS vers la surface active, contrairement a
1026
+ * `01` : un filet de champ y tombait a 2,93:1 (#7e848b sur #dde3ee). Le filet fort
1027
+ * monte a la place au niveau du texte discret (7,29 et 5,10:1 sur la surface active).
1028
+ */
1029
+ export declare const aliasDeContrasteRenforceParJeton: Readonly<Partial<Record<NomDeJeton, NomDeJeton>>>;
1030
+ /**
1031
+ * Encres de statut FONCEES d'un pas sous `prefers-contrast: more`, par theme.
1032
+ *
1033
+ * ⚠️ Le survol y devient la surface active (`surfaceSurvol -> surfaceActive`), plus
1034
+ * sombre en clair : `succes` y tombait a 4,37:1 et `avertissement` a 4,45:1, sous le
1035
+ * seuil que le mode est cense renforcer (revue E2-E5, 103 paires parcourues a travers
1036
+ * la table). Les encres du pas 700 — celles de l'impression — tiennent 5,98 et
1037
+ * 6,49:1 ; le sombre garde ses valeurs, deja au-dessus.
1038
+ */
1039
+ export declare const encresDeContrasteRenforce: Readonly<Partial<Record<NomDeJeton, Readonly<Record<NomDeTheme, string>>>>>;
1040
+ /**
1041
+ * Le theme tel que `prefers-contrast: more` le rend : chaque alias resolu dans le
1042
+ * theme, puis les encres foncees. C'est ce que les paires de contraste doivent tenir
1043
+ * sous ce mode, et ce que la garde parcourt.
1044
+ */
1045
+ export declare function themeSousContrasteRenforce(theme: NomDeTheme): JetonsDeCouleur;
1046
+ /** Les alias de `prefers-contrast: more`, tels que la feuille les ecrit. */
1047
+ export declare const aliasDeContrasteRenforce: Readonly<Record<string, string>>;
1048
+ /**
1049
+ * `forced-colors: active` : les jetons dont la couleur systeme vaut dans TOUS leurs
1050
+ * emplois (01 §7.2). Chromium GARDE une couleur systeme posee par l'auteur (il ne
1051
+ * force que les autres) et peint une plaque `Canvas` derriere chaque texte : un
1052
+ * alias est donc une decision, pas une documentation.
1053
+ *
1054
+ * ⚠️ **Aucun alias pour les encres posees sur un aplat** (`surPrimaire`, `surDanger`,
1055
+ * `surSucces`...). Envoyees vers `Canvas`, elles rendaient le libelle du bouton
1056
+ * primaire, du bouton danger et les chiffres d'une pastille INVISIBLES : texte
1057
+ * `Canvas` sur la plaque `Canvas` (revue E2-E5, banc sous contraste force). Sans
1058
+ * alias, le navigateur les force lui-meme (`CanvasText`, `ButtonText`), lisibles sur
1059
+ * la plaque. Les aplats (`primaire`, `danger`...) gardent une couleur systeme de
1060
+ * PREMIER PLAN : une barre de progression ou un point de statut, qui n'ont pas de
1061
+ * texte, restent visibles sur `Canvas`.
1062
+ *
1063
+ * ⚠️ **`surfaceSelection` va vers `Canvas`, pas vers `Highlight`** : une ligne
1064
+ * choisie (tableau, arbre, lien courant) garde son texte `CanvasText` ou `LinkText`,
1065
+ * qui tombait sous 2:1 sur `Highlight`. La selection se lit par le filet
1066
+ * `bordureSelection` (`Highlight`), par `aria-selected` et par la coche ; un
1067
+ * composant qui veut l'aplat le pose lui-meme, en paire `Highlight`/`HighlightText`
1068
+ * sous `forced-color-adjust: none` (jour choisi, segment, ligne d'arbre).
1069
+ */
1070
+ export declare const couleursSysteme: Readonly<Record<string, readonly NomDeJeton[]>>;
1071
+ /**
1072
+ * Les encres posees sur un aplat plein : jamais aliasees sous contraste force (voir
1073
+ * `couleursSysteme`). Exportees pour que la garde le verifie.
1074
+ */
1075
+ export declare const encresDAplat: readonly NomDeJeton[];
1076
+ /**
1077
+ * Impression (01 §7.3) : le theme clair, avec des derogations d'ENCRE. Un filet a
1078
+ * 1,4:1 disparait sur une imprimante laser ; un aplat de statut ne s'imprime pas,
1079
+ * l'icone et le texte portent le statut. Une derogation d'encre ne peut que FONCER
1080
+ * (clarte OKLCH inferieure ou egale a l'ecran) ; seuls les fonds passent au blanc.
1081
+ */
1082
+ export declare const derogationsDImpression: Readonly<Partial<Record<NomDeJeton, string>>>;
1083
+ /** Tailles en points a l'impression : le rem y vaut 12 pt, l'echelle se resserre. */
1084
+ export declare const taillesDImpression: Readonly<Record<keyof typeof typographie.taille, string>>;
1085
+ /**
1086
+ * Feuille complete.
1087
+ *
1088
+ * Ordre et specificite : TOUTES les regles de theme et de derogation portent la
1089
+ * meme specificite (0,1,0) — `:root` et `[data-theme…]` — et l'emportent par
1090
+ * l'ORDRE. Plus aucune derogation ne se bat contre un selecteur de theme a
1091
+ * (0,2,0) : il n'y en a plus.
1092
+ *
1093
+ * ⚠️ `color-scheme` suit le theme EFFECTIF, il n'est pas pose une fois pour
1094
+ * toutes a `light dark` : ce dernier laisse le navigateur decider seul, si bien
1095
+ * qu'un theme clair force sur un systeme sombre gardait des barres de
1096
+ * defilement, des champs natifs et un remplissage automatique sombres.
1097
+ */
1098
+ export declare function feuilleDeJetons(): string;
1099
+ /** Nombre de jetons de couleur semantiques : le compte vient du code, jamais d'une prose. */
1100
+ export declare function nombreDeJetonsDeCouleur(jetons?: JetonsDeCouleur): number;
1101
+ /**
1102
+ * Les jetons au format du W3C Design Tokens Community Group (DTCG, « Design Tokens Format Module »,
1103
+ * version stable 2025.10) : `styles/starter-tokens.tokens.json`, ENGENDRE comme la feuille CSS et
1104
+ * garde par le meme `tools/generer-css.mjs --verifier` (lot 158). C'est la forme qu'un outil de
1105
+ * design ou un autre moteur de rendu lit sans connaitre le TypeScript du socle.
1106
+ *
1107
+ * Ce qui part, et dans quel type DTCG :
1108
+ *
1109
+ * | Groupe | Source | `$type` |
1110
+ * | -------------------------- | ------------------------------ | ------------ |
1111
+ * | `couleur.clair`, `.sombre` | `themeClair`, `themeSombre` | `color` |
1112
+ * | `espacement`, `rayon` | echelles | `dimension` |
1113
+ * | `taille`, `interligne` | `typographie` | `dimension` |
1114
+ * | `graisse` | `typographie.graisse` | `fontWeight` |
1115
+ * | `police` | `typographie.famille` | `fontFamily` |
1116
+ * | `duree` | `duree` | `duration` |
1117
+ *
1118
+ * Ce qui ne part pas : les ombres, courbes, cadences et derogations (contraste renforce, impression,
1119
+ * mouvement reduit) sont des REGLES de la feuille, pas des valeurs a recopier ailleurs.
1120
+ */
1121
+ export declare function jetonsDtcg(): string;
1122
+
1123
+ export {};