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