@zevra/ui 0.35.0 → 0.36.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.
Files changed (104) hide show
  1. package/DECISIONS.md +264 -208
  2. package/README.md +21 -21
  3. package/demo/app.html +6 -6
  4. package/demo/index.html +3 -3
  5. package/dist/actions.d.ts +8 -8
  6. package/dist/actions.d.ts.map +1 -1
  7. package/dist/actions.js +1 -1
  8. package/dist/actions.js.map +1 -1
  9. package/dist/catalogue.d.ts +2 -2
  10. package/dist/catalogue.js +67 -67
  11. package/dist/catalogue.js.map +1 -1
  12. package/dist/content.d.ts +23 -23
  13. package/dist/content.d.ts.map +1 -1
  14. package/dist/content.js +16 -16
  15. package/dist/content.js.map +1 -1
  16. package/dist/css-inline.d.ts +1 -1
  17. package/dist/css-inline.d.ts.map +1 -1
  18. package/dist/css-inline.js +4 -4
  19. package/dist/css-inline.js.map +1 -1
  20. package/dist/data-table.d.ts +1 -1
  21. package/dist/data.d.ts +7 -7
  22. package/dist/data.js +5 -5
  23. package/dist/email-tokens.js +1 -1
  24. package/dist/email.d.ts +6 -6
  25. package/dist/email.js +8 -8
  26. package/dist/email.js.map +1 -1
  27. package/dist/feedback.d.ts +10 -10
  28. package/dist/feedback.d.ts.map +1 -1
  29. package/dist/feedback.js +3 -3
  30. package/dist/forms.d.ts +12 -12
  31. package/dist/forms.js +5 -5
  32. package/dist/glyph-data.d.ts +2 -2
  33. package/dist/glyph-data.js +3 -3
  34. package/dist/glyph-urls.js +1 -1
  35. package/dist/glyphes.d.ts +2 -2
  36. package/dist/glyphes.js +4 -4
  37. package/dist/icon-data.d.ts +1 -1
  38. package/dist/icon-data.js +2 -2
  39. package/dist/icon.d.ts +5 -5
  40. package/dist/icon.js +1 -1
  41. package/dist/index.js +4 -4
  42. package/dist/layout.d.ts +21 -21
  43. package/dist/layout.d.ts.map +1 -1
  44. package/dist/layout.js +15 -15
  45. package/dist/layout.js.map +1 -1
  46. package/dist/navigation.d.ts +16 -16
  47. package/dist/navigation.d.ts.map +1 -1
  48. package/dist/navigation.js +9 -9
  49. package/dist/navigation.js.map +1 -1
  50. package/dist/overlays.d.ts +6 -6
  51. package/dist/overlays.d.ts.map +1 -1
  52. package/dist/overlays.js +5 -5
  53. package/dist/select-menu.d.ts +1 -1
  54. package/dist/select-menu.js +2 -2
  55. package/dist/surfaces.d.ts +8 -8
  56. package/dist/surfaces.d.ts.map +1 -1
  57. package/dist/surfaces.js +6 -6
  58. package/dist/surfaces.js.map +1 -1
  59. package/dist/typography.d.ts +4 -4
  60. package/dist/typography.d.ts.map +1 -1
  61. package/dist/typography.js +3 -3
  62. package/dist/typography.js.map +1 -1
  63. package/icons/index.json +1 -1
  64. package/package.json +2 -2
  65. package/react/actions.tsx +9 -9
  66. package/react/catalogue.tsx +68 -68
  67. package/react/content.tsx +28 -28
  68. package/react/css-inline.ts +4 -4
  69. package/react/data-table.tsx +3 -3
  70. package/react/data.tsx +9 -9
  71. package/react/email-tokens.ts +1 -1
  72. package/react/email.ts +10 -10
  73. package/react/feedback.tsx +12 -12
  74. package/react/forms.tsx +15 -15
  75. package/react/glyph-data.ts +3 -3
  76. package/react/glyph-urls.ts +1 -1
  77. package/react/glyphes.ts +4 -4
  78. package/react/icon-data.ts +2 -2
  79. package/react/icon.tsx +6 -6
  80. package/react/index.ts +4 -4
  81. package/react/layout.tsx +22 -22
  82. package/react/navigation.tsx +18 -18
  83. package/react/overlays.tsx +9 -9
  84. package/react/select-menu.tsx +3 -3
  85. package/react/surfaces.tsx +10 -10
  86. package/react/typography.tsx +6 -6
  87. package/src/base.css +10 -10
  88. package/src/components.css +49 -49
  89. package/src/data.css +41 -41
  90. package/src/feedback.css +55 -55
  91. package/src/fonts.css +2 -2
  92. package/src/forms.css +50 -50
  93. package/src/icons.css +10 -10
  94. package/src/index.css +1 -1
  95. package/src/layout.css +27 -27
  96. package/src/motion.css +16 -16
  97. package/src/motion.js +4 -4
  98. package/src/nav.js +5 -5
  99. package/src/navigation.css +62 -62
  100. package/src/overlays.css +14 -14
  101. package/src/rail.js +6 -6
  102. package/src/surfaces.css +11 -11
  103. package/src/tokens.css +14 -14
  104. package/tokens/index.js +8 -8
package/src/feedback.css CHANGED
@@ -1,19 +1,19 @@
1
- /* Zevra UI — retours d'état : bandeaux, étiquettes, pastilles, absence,
2
- * travail en cours, curseur de flux — et, depuis le 25/08/2026, la roue,
1
+ /* Zevra UI (retours d'état : bandeaux, étiquettes, pastilles, absence,
2
+ * travail en cours, curseur de flux) et, depuis le 25/08/2026, la roue,
3
3
  * le squelette et l'infobulle, longtemps refusés et enfin arbitrés.
4
4
  *
5
5
  * Dépend de tokens.css et de base.css (reset, fonte de corps, focus clavier
6
6
  * global). Indépendant des autres modules.
7
7
  *
8
8
  * Tokens réellement employés ici, tous vérifiés dans tokens.css :
9
- * couleurs — --ink, --ink-2, --muted, --label, --line, --hairline, --white,
9
+ * couleurs (--ink, --ink-2, --muted, --label, --line, --hairline, --white,
10
10
  * --accent, --accent-line, --accent-soft,
11
11
  * --ok, --ok-soft, --ok-line,
12
12
  * --warn, --warn-soft, --warn-line, --warn-ink,
13
13
  * --err, --err-soft, --err-line ;
14
- * typo — --font-display, --font-mono, --app, --app-sm,
14
+ * typo) --font-display, --font-mono, --app, --app-sm,
15
15
  * --app-h2, --mono, --mono-sm ;
16
- * ombre — --shadow-menu (l'infobulle, qui flotte comme le menu).
16
+ * ombre) --shadow-menu (l'infobulle, qui flotte comme le menu).
17
17
  * Aucun autre. Il n'existe PAS de --ink-3…--ink-7, pas de --line-soft, pas de
18
18
  * --line-firm, pas d'échelles --text-* ni --mono-xs/--mono-2xs : une version
19
19
  * antérieure de cet en-tête les déclarait en dépendance, ce qui rendait le
@@ -27,11 +27,11 @@
27
27
  * avec les modules de vitrine : Mémoire est écrite mobile-first et bascule à
28
28
  * `lg` (1024px), alors que la charte ne connaît qu'UN point de rupture, à
29
29
  * 768px. Les valeurs desktop sont donc posées en base et les valeurs mobiles
30
- * regroupées en fin de fichier — le rendu desktop est identique au relevé, le
30
+ * regroupées en fin de fichier : le rendu desktop est identique au relevé, le
31
31
  * rendu mobile arrive 256px plus tôt. C'est délibéré : deux ruptures dans un
32
32
  * système qui en annonce une seule est une dette qui se paie sur chaque app.
33
33
  *
34
- * ÉCHELLE DE TEXTE — la production emploie des demi-pixels (11,5 / 12,5 /
34
+ * ÉCHELLE DE TEXTE : la production emploie des demi-pixels (11,5 / 12,5 /
35
35
  * 13,5) que le paquet a rationalisés en trois paliers (12 / 13 / 14). Le
36
36
  * rabattement retenu ici conserve les ÉCARTS du relevé plutôt que la valeur
37
37
  * absolue : 11,5 et 12,5 → --app-sm (12), 13,5 → --app (13), 14 → --app-lg.
@@ -41,7 +41,7 @@
41
41
  *
42
42
  * Presque rien ici n'est interactif : pas de bouton de fermeture, pas de
43
43
  * champ. Les états [disabled] / [aria-invalid] n'ont aucune cible dans ce
44
- * module — ils appartiennent aux boutons (components.css) et aux champs
44
+ * module : ils appartiennent aux boutons (components.css) et aux champs
45
45
  * (forms.css). Le focus clavier global de base.css suffit au bandeau qu'on
46
46
  * rend focusable pour l'annoncer. Seule exception, arbitrée le 25/08/2026 :
47
47
  * l'infobulle, qui se montre par nature au survol et au focus de sa cible.
@@ -70,7 +70,7 @@
70
70
  * nom de fichier à rallonge, identifiant, chemin. Sans coupure, il pousse
71
71
  * la page en défilement horizontal. */
72
72
  overflow-wrap: break-word;
73
- /* Angle vif, comme au relevé — et, depuis le 25/08/2026, comme tout le
73
+ /* Angle vif, comme au relevé, et, depuis le 25/08/2026, comme tout le
74
74
  * paquet : l'arbitrage DA « angle vif partout » (DECISIONS.md) a ramené
75
75
  * les quatre tokens de rayon à 0. La contradiction longtemps signalée ici
76
76
  * (un bouton arrondi au milieu de blocs vifs dans l'écran vide) est
@@ -78,7 +78,7 @@
78
78
  border-radius: 0;
79
79
  }
80
80
 
81
- /* Information — le seul ton relevé en bandeau de bas de page (garanties,
81
+ /* Information : le seul ton relevé en bandeau de bas de page (garanties,
82
82
  * explication d'un écran). */
83
83
  .zv-alert--info {
84
84
  border-color: var(--accent-line);
@@ -86,7 +86,7 @@
86
86
  color: var(--accent);
87
87
  }
88
88
 
89
- /* Avertissement — le texte est --warn-ink, JAMAIS --warn : l'ambre plein
89
+ /* Avertissement, le texte est --warn-ink, JAMAIS --warn : l'ambre plein
90
90
  * sur fond ambre atténué passe sous le seuil de contraste. C'est la seule
91
91
  * famille asymétrique du système, et l'erreur la plus facile à commettre. */
92
92
  .zv-alert--warn {
@@ -95,7 +95,7 @@
95
95
  color: var(--warn-ink);
96
96
  }
97
97
 
98
- /* Erreur — à porter avec role="alert" côté balisage, sinon le message
98
+ /* Erreur, à porter avec role="alert" côté balisage, sinon le message
99
99
  * apparaît sans être annoncé aux lecteurs d'écran : c'est précisément le
100
100
  * seul contenu de l'écran qu'on ne peut pas se permettre de rater. */
101
101
  .zv-alert--err {
@@ -104,7 +104,7 @@
104
104
  color: var(--err);
105
105
  }
106
106
 
107
- /* Succès — RELEVÉ, pleine largeur, deux fois : reset-password-card.tsx:90 et
107
+ /* Succès, RELEVÉ, pleine largeur, deux fois : reset-password-card.tsx:90 et
108
108
  * forgot-password-card.tsx:60, en `border-ok-line bg-ok-soft px-3 py-[10px]
109
109
  * text-[13.5px]/[1.6] font-medium text-ok`. (Une version antérieure de ce
110
110
  * commentaire le disait « extrapolé » : c'était faux, les deux écrans de
@@ -117,20 +117,20 @@
117
117
  }
118
118
 
119
119
  /* Variante « aveu d'ignorance » : ce que le système n'a PAS trouvé. Le
120
- * pointillé sans fond dit qu'il n'y a rien derrière — un fond plein ferait
120
+ * pointillé sans fond dit qu'il n'y a rien derrière : un fond plein ferait
121
121
  * lire une réponse là où il n'y en a pas. Avec la zone de dépôt, c'est le
122
122
  * seul pointillé de toute la couche applicative : le garder rare, c'est ce
123
123
  * qui lui laisse son sens.
124
124
  *
125
125
  * ⚠️ DEUX PERTES DE TEINTE, assumées et signalées plutôt que glissées :
126
126
  * 1. le texte est `#6E6A61` en production (chat-client.tsx:265), un gris
127
- * CHAUD — le seul du fil de réponse. Le paquet n'a pas de neutre chaud :
127
+ * CHAUD : le seul du fil de réponse. Le paquet n'a pas de neutre chaud :
128
128
  * --muted (#5a637a) est bleuté. Le rabattement est arrêté, mais il
129
129
  * REFROIDIT ce texte, et il le range sous le même token que les gris
130
130
  * froids du relevé (#6B7488 du pager, du bouton d'icône). Deux familles
131
131
  * de teinte finissent donc sur --muted : c'est une fusion, pas une
132
132
  * nuance. Le jour où la DA veut retrouver ce chaud, il faut un token
133
- * dédié dans tokens.css — pas une valeur en dur ici.
133
+ * dédié dans tokens.css : pas une valeur en dur ici.
134
134
  * 2. le filet est `#C9CEDD` en production, un gris froid neutre ; --accent-line
135
135
  * (#c9d6f5) est le seul filet du paquet à cette clarté, mais il est
136
136
  * légèrement indigo. Écart perceptible sur un pointillé large. */
@@ -143,11 +143,11 @@
143
143
  color: var(--muted);
144
144
  }
145
145
 
146
- /* Gabarit compact (`px-3 py-[9px]`) — relevé quatre fois : login-card:207,
146
+ /* Gabarit compact (`px-3 py-[9px]`), relevé quatre fois : login-card:207,
147
147
  * bibliotheque-client:210, branding-card:219, billing-card:164. Deux d'entre
148
148
  * eux sont des alertes de PAGE, pas de panneau : ce gabarit n'est donc pas
149
149
  * « le bandeau dans un cadre », c'est simplement le bandeau resserré. La
150
- * carte de suppression (delete-org-card:39) n'a aucun bandeau — l'histoire
150
+ * carte de suppression (delete-org-card:39) n'a aucun bandeau : l'histoire
151
151
  * qui justifiait ces valeurs dans une version antérieure était inventée, les
152
152
  * valeurs, elles, sont bonnes. */
153
153
  .zv-alert--sm {
@@ -157,7 +157,7 @@
157
157
  /* Gabarit ample : le message d'incident qui REMPLACE une réponse attendue
158
158
  * (GPU en charge). Il occupe la place du contenu manquant, d'où le corps plus
159
159
  * grand. Source chat-client.tsx:308 : `px-4 py-[14px] text-[13.5px]/[1.6]
160
- * lg:px-5 lg:py-4` — le padding change au seuil, la TAILLE non (13,5px des
160
+ * lg:px-5 lg:py-4`, le padding change au seuil, la TAILLE non (13,5px des
161
161
  * deux côtés). D'où l'absence de font-size dans le bloc mobile. */
162
162
  .zv-alert--lg {
163
163
  padding: 16px 20px;
@@ -168,7 +168,7 @@
168
168
  /* ⚠️ DEUX ARBITRAGES de couleur portés ici, pas glissés sous le tapis :
169
169
  * 1. le filet vert est écrit `border-ok/30` en production (un color-mix à
170
170
  * 30 %) alors que --ok-line existe dans le paquet et n'y sert jamais.
171
- * Retenu : --ok-line. Le rendu diffère — le color-mix laissait
171
+ * Retenu : --ok-line. Le rendu diffère : le color-mix laissait
172
172
  * transparaître --ok-soft, le token est un vert franc.
173
173
  * 2. l'ambre de production est #FFF6E3 / #EBD9AE (teintes écrites en dur
174
174
  * dans deux tables), le token du paquet #faf3e2 / #ebdcb4. Retenu : les
@@ -177,7 +177,7 @@
177
177
  /* ─── Étiquettes d'état ─────────────────────────────────────────────────
178
178
  * Rôle d'une entité, niveau d'un log, état d'un service, issue d'un envoi :
179
179
  * un seul objet, trois gabarits, cinq tons. Le mono en petit corps est ce
180
- * qui les distingue d'un texte — une étiquette se lit d'un coup d'œil, elle
180
+ * qui les distingue d'un texte : une étiquette se lit d'un coup d'œil, elle
181
181
  * ne se lit pas en phrase.
182
182
  *
183
183
  * Pas de text-transform : les libellés sont écrits en capitales à la source.
@@ -206,7 +206,7 @@
206
206
  /* Un état ne se coupe jamais en deux lignes : « EN CHARGE » sur deux
207
207
  * lignes se lit comme deux états. */
208
208
  white-space: nowrap;
209
- border-radius: 0; /* angle vif — relevé, et arbitré depuis (25/08/2026) */
209
+ border-radius: 0; /* angle vif : relevé, et arbitré depuis (25/08/2026) */
210
210
  }
211
211
 
212
212
  /* Gabarit micro : niveau de log en tête de ligne, badge de la coque. À
@@ -231,7 +231,7 @@
231
231
  letter-spacing: 0.06em;
232
232
  }
233
233
 
234
- /* Tons — triplets relevés tels quels dans les tables de teintes. */
234
+ /* Tons : triplets relevés tels quels dans les tables de teintes. */
235
235
 
236
236
  /* Neutre : `border-line bg-hairline text-[#4A5468]` (repertoire-client:25).
237
237
  * Le filet est bien --line, pas un filet adouci : une version antérieure y
@@ -283,7 +283,7 @@
283
283
  .zv-dot {
284
284
  width: 6px;
285
285
  height: 6px;
286
- /* Sans flex: none la pastille s'écrase quand le libellé voisin est long —
286
+ /* Sans flex: none la pastille s'écrase quand le libellé voisin est long :
287
287
  * elle devient un ovale, et l'état n'est plus lisible. */
288
288
  flex: none;
289
289
  border-radius: 9999px;
@@ -331,7 +331,7 @@
331
331
  }
332
332
 
333
333
  /* ─── Statut en clair ───────────────────────────────────────────────────
334
- * Pastille + libellé, sans cadre — contrairement à l'étiquette. Le cadre
334
+ * Pastille + libellé, sans cadre : contrairement à l'étiquette. Le cadre
335
335
  * est réservé à ce qui classe (rôle, niveau) ; le statut, lui, se lit dans
336
336
  * le fil de la ligne. Le message d'erreur REMPLACE le libellé quand il y en
337
337
  * a un : l'utilisateur veut lire la cause, pas le mot « Erreur ».
@@ -342,7 +342,7 @@
342
342
  * sur ce span. Autrement dit : le libellé tronque, et il tronque SOUS le
343
343
  * seuil, là où min-width vaut 0 ; au-dessus, la colonne reprend sa largeur
344
344
  * naturelle. Le fichier est desktop-first, donc `min-width: auto` est ici et
345
- * `min-width: 0` dans le bloc mobile — l'inverse exact de ce qu'une version
345
+ * `min-width: 0` dans le bloc mobile : l'inverse exact de ce qu'une version
346
346
  * antérieure de ce module posait, qui faisait passer le libellé à la ligne
347
347
  * sur téléphone et décalait la pastille de 5px vers le bas. Rien de tout
348
348
  * cela n'existe en production. */
@@ -352,7 +352,7 @@
352
352
  align-items: center;
353
353
  gap: 6px;
354
354
  /* Valeur initiale, écrite pour être lue : au-dessus du seuil la colonne
355
- * n'est pas contrainte, le libellé la pousse — c'est le `lg:min-w-[auto]`
355
+ * n'est pas contrainte, le libellé la pousse, c'est le `lg:min-w-[auto]`
356
356
  * du relevé. La troncature n'opère réellement que sous le seuil. */
357
357
  min-width: auto;
358
358
  font-size: var(--app-sm); /* 11,5px relevé → palier 12 */
@@ -370,10 +370,10 @@
370
370
 
371
371
  /* ─── Absence ───────────────────────────────────────────────────────────
372
372
  * DEUX objets distincts, à ne surtout pas fusionner :
373
- * — la ligne d'absence, quand un filtre ne ramène rien : la collection
373
+ * - la ligne d'absence, quand un filtre ne ramène rien : la collection
374
374
  * existe, seul le filtre est trop étroit. Elle vit DANS le cadre, à la
375
375
  * place des lignes, pour que l'en-tête de tableau reste visible ;
376
- * — l'écran d'absence, quand la collection est vide : il remplace le
376
+ * - l'écran d'absence, quand la collection est vide : il remplace le
377
377
  * tableau entier, porte un titre et l'action qui la remplira.
378
378
  * Les confondre donne soit un écran de bienvenue affiché à chaque filtre
379
379
  * trop strict, soit une collection vide qui n'offre aucune porte de sortie. */
@@ -383,7 +383,7 @@
383
383
  * `px-[18px] py-8` (import-client:263), `py-5` seul (logs-client:234).
384
384
  * Retenue : la seule qui soit écrite telle quelle, 26px sur les quatre
385
385
  * côtés. Une version antérieure posait « 26px 14px », c'est-à-dire le
386
- * vertical de la première recomposé avec l'horizontal de la deuxième — une
386
+ * vertical de la première recomposé avec l'horizontal de la deuxième : une
387
387
  * paire plausible qui n'existe dans aucune source. */
388
388
  .zv-empty {
389
389
  padding: 26px;
@@ -445,7 +445,7 @@
445
445
  font-family: var(--font-mono);
446
446
  font-size: var(--app-sm);
447
447
  font-weight: 500;
448
- /* #727C93 au relevé — un gris froid, rabattu sur --muted comme les autres
448
+ /* #727C93 au relevé : un gris froid, rabattu sur --muted comme les autres
449
449
  * neutres secondaires. Le token porte donc plusieurs gris du relevé : la
450
450
  * hiérarchie interne des gris de Mémoire (#6B7488 / #727C93) n'existe plus
451
451
  * dans le paquet, elle échouait de toute façon au seuil AA. */
@@ -463,12 +463,12 @@
463
463
  * pouls est l'invention la plus tentante de tout le relevé. Les boucles de
464
464
  * ce module (roue, squelette) disent une ATTENTE ; la pastille dit un
465
465
  * ÉTAT, et un état ne bat pas. Ne pas confondre `.zv-dot` avec
466
- * `.zv-anim-dot-active` de motion.css — ce dernier anime un point de
466
+ * `.zv-anim-dot-active` de motion.css : ce dernier anime un point de
467
467
  * méthode de la vitrine, pas un état. */
468
468
 
469
469
  /* ─── Curseur de flux ───────────────────────────────────────────────────
470
470
  * Bloc collé à la fin du texte en cours de diffusion, sur le dernier
471
- * message seulement. Il dit « la réponse n'est pas finie » — sans lui, une
471
+ * message seulement. Il dit « la réponse n'est pas finie » : sans lui, une
472
472
  * réponse coupée à mi-phrase se lit comme une réponse complète et fausse. */
473
473
 
474
474
  .zv-caret {
@@ -481,9 +481,9 @@
481
481
  * en fin de ligne justifiée. STATIQUE là encore, aucun clignotement.
482
482
  *
483
483
  * Le flux interrompu, lui, n'a AUCUN style : c'est la phrase
484
- * « [Flux interrompu — la réponse est incomplète.] » ajoutée au corps du
484
+ * « [Flux interrompu, la réponse est incomplète.] » ajoutée au corps du
485
485
  * message, rendue par white-space: pre-wrap. La réponse partielle est
486
- * conservée, jamais effacée — on n'efface pas ce que l'utilisateur a déjà lu. */
486
+ * conservée, jamais effacée : on n'efface pas ce que l'utilisateur a déjà lu. */
487
487
 
488
488
  /* ─── Retour d'attente : ce que fait Mémoire, et ce qu'elle ne fait pas ──
489
489
  * Le retour d'attente de cette application est TEXTUEL, et c'est cohérent
@@ -500,11 +500,11 @@
500
500
  *
501
501
  * ─── Roue, squelette, infobulle : les manques, comblés ──────────────────
502
502
  * Longtemps REFUSÉS ici même, faute de matière première dans les cinq
503
- * écrans relevés — un système ment moins en affichant un trou qu'une valeur
503
+ * écrans relevés, un système ment moins en affichant un trou qu'une valeur
504
504
  * plausible. Tranchés le 25/08/2026 (DECISIONS.md, « les manques comblés »)
505
505
  * en reprenant TELLES QUELLES les contraintes que ce module posait pour ce
506
- * jour-là : pas de dégradé spectre — donc un squelette en --hairline, pas
507
- * un balayage spectral — et une infobulle en petit panneau blanc, filet
506
+ * jour-là : pas de dégradé spectre (donc un squelette en --hairline, pas
507
+ * un balayage spectral) et une infobulle en petit panneau blanc, filet
508
508
  * --line, ombre --shadow-menu, texte --app-sm / --ink-2, la seule
509
509
  * combinaison déjà présente ailleurs dans le système. Les trois blocs
510
510
  * suivent ; ce qui restait à inventer (durées, amplitudes) est dit sur
@@ -518,7 +518,7 @@
518
518
  *
519
519
  * Géométrie empruntée, rien d'inventé sauf la durée : 16 px (la taille de
520
520
  * .zv-icon), trait de 2 (l'épaisseur du jeu d'icônes), piste --accent-line,
521
- * secteur --accent. 0,8 s linéaire — une rotation qui accélère se lit comme
521
+ * secteur --accent. 0,8 s linéaire : une rotation qui accélère se lit comme
522
522
  * un à-coup. prefers-reduced-motion (base.css) la FIGE : l'anneau
523
523
  * interrompu reste lisible immobile, c'est pour cela que le secteur est un
524
524
  * quart et pas une moitié. */
@@ -537,15 +537,15 @@
537
537
  border: 2px solid var(--accent-line);
538
538
  border-top-color: var(--accent);
539
539
  /* Rond de FORME, pas de style : c'est le cercle qui fait lire la
540
- * rotation — même dérogation que la pastille d'état. */
540
+ * rotation, même dérogation que la pastille d'état. */
541
541
  border-radius: 9999px;
542
542
  /* `rotate` et non `transform` : la propriété indépendante compose avec un
543
- * éventuel transform de placement — la leçon des boucles de motion.css. */
543
+ * éventuel transform de placement, la leçon des boucles de motion.css. */
544
544
  animation: zv-spin 0.8s linear infinite;
545
545
  }
546
546
 
547
547
  /* En tête d'un panneau ou d'un écran d'attente : la roue seule, plus
548
- * grande. Le trait ne grossit pas — même compensation optique que les
548
+ * grande. Le trait ne grossit pas : même compensation optique que les
549
549
  * icônes. */
550
550
  .zv-spinner--lg {
551
551
  width: 24px;
@@ -553,11 +553,11 @@
553
553
  }
554
554
 
555
555
  /* ─── Squelette ─────────────────────────────────────────────────────────
556
- * L'aplat --hairline exigé — pas de balayage spectral, pas de dégradé de
556
+ * L'aplat --hairline exigé : pas de balayage spectral, pas de dégradé de
557
557
  * gris que la charte n'a pas. La pulsation est une OPACITÉ (1 → 0,55), pas
558
558
  * une couleur : elle dit « en chargement » sans introduire de teinte.
559
559
  * 1,8 s en ease-in-out, la respiration de zv-breathe plutôt que la courbe
560
- * d'entrée — c'est une boucle, pas un mouvement.
560
+ * d'entrée : c'est une boucle, pas un mouvement.
561
561
  *
562
562
  * La géométrie vient du CONSOMMATEUR (largeur et hauteur en style, comme la
563
563
  * largeur de Progress) : un squelette qui invente ses dimensions ne
@@ -565,7 +565,7 @@
565
565
  * une hauteur d'un cadratin, pour mimer une ligne du texte courant.
566
566
  *
567
567
  * ⚠️ Un squelette ANNONCE une structure : ne jamais en poser un pour un
568
- * contenu dont la forme est inconnue — c'est .zv-loading qui dit ce cas. */
568
+ * contenu dont la forme est inconnue, c'est .zv-loading qui dit ce cas. */
569
569
 
570
570
  @keyframes zv-skeleton {
571
571
  0%,
@@ -590,20 +590,20 @@
590
590
  /* ─── Infobulle ─────────────────────────────────────────────────────────
591
591
  * La combinaison imposée par l'arbitrage : panneau blanc, filet --line,
592
592
  * ombre --shadow-menu, texte --app-sm / --ink-2. Posée AU-DESSUS de la
593
- * cible, centrée, à 6 px — au-dessus parce que le pointeur vient d'en bas
593
+ * cible, centrée, à 6 px : au-dessus parce que le pointeur vient d'en bas
594
594
  * et la masquerait en dessous.
595
595
  *
596
596
  * Elle se montre au survol et au focus de l'enveloppe (.zv-tooltip-hit),
597
- * avec un retard de 300 ms à l'APPARITION seulement — sans lui, traverser
597
+ * avec un retard de 300 ms à l'APPARITION seulement : sans lui, traverser
598
598
  * une rangée d'icônes fait clignoter une infobulle par icône. La
599
599
  * disparition, elle, est immédiate.
600
600
  *
601
601
  * Le masquage est `visibility` ET opacité, à dessein (WCAG 1.4.13) :
602
- * · cachée en visibility:hidden, la bulle ne capte pas le pointeur — pas
602
+ * · cachée en visibility:hidden, la bulle ne capte pas le pointeur (pas
603
603
  * de zone de survol fantôme au-dessus de chaque cible ;
604
604
  * · visible, elle EST survolable : descendante de l'enveloppe, le
605
605
  * pointeur peut la traverser sans la fermer ;
606
- * · Échap la ferme — la façade pose --off jusqu'au blur, seul
606
+ * · Échap la ferme) la façade pose --off jusqu'au blur, seul
607
607
  * comportement qui demande une ligne de script.
608
608
  *
609
609
  * ⚠️ Réservée à un COMPLÉMENT dispensable (un raccourci, une date exacte,
@@ -669,7 +669,7 @@
669
669
  /* ─── Mobile ────────────────────────────────────────────────────────────
670
670
  * Un seul point de rupture, 768px, comme dans tous les modules du paquet.
671
671
  * Ce bloc ne contient QUE des bascules attestées dans la source (variantes
672
- * `lg:` de Mémoire, lues en sens inverse) — pas une seule règle de confort
672
+ * `lg:` de Mémoire, lues en sens inverse) : pas une seule règle de confort
673
673
  * ajoutée en chemin. */
674
674
 
675
675
  @media (max-width: 767px) {
@@ -682,8 +682,8 @@
682
682
  font-size: var(--app);
683
683
  }
684
684
 
685
- /* Le bandeau pointillé fait l'inverse — `text-[13px]` en desktop,
686
- * `text-[12.5px]` sous le seuil — et resserre sa gouttière : 16px de
685
+ /* Le bandeau pointillé fait l'inverse (`text-[13px]` en desktop,
686
+ * `text-[12.5px]` sous le seuil) et resserre sa gouttière : 16px de
687
687
  * chaque côté sur 375px déjà bordés par le padding de page, c'est la
688
688
  * moitié de la largeur perdue en marges. Déclaré APRÈS .zv-alert pour
689
689
  * l'emporter à spécificité égale. */
@@ -703,7 +703,7 @@
703
703
 
704
704
  /* C'est ici, et seulement ici, que la troncature du statut opère : le
705
705
  * `min-w-0` de la source vaut sous le seuil, et sans lui l'ellipse ne se
706
- * déclenche pas dans une cellule flex ou grid — le libellé pousse la
706
+ * déclenche pas dans une cellule flex ou grid, le libellé pousse la
707
707
  * colonne. C'est la cause n° 1 de débordement horizontal des tableaux. */
708
708
  .zv-status {
709
709
  min-width: 0;
@@ -711,7 +711,7 @@
711
711
 
712
712
  /* Même garde-fou que le menu et le popover : plafonnée à l'écran, la
713
713
  * bulle ne pousse jamais la page en défilement horizontal. Le centrage
714
- * sur une cible collée au bord peut encore la décaler — limite connue,
714
+ * sur une cible collée au bord peut encore la décaler : limite connue,
715
715
  * une variante d'ancrage latéral s'arbitrera si le cas se présente. */
716
716
  .zv-tooltip {
717
717
  max-width: calc(100vw - 40px);
@@ -720,7 +720,7 @@
720
720
  /* ⚠️ NON RELEVÉ : aucune variante `lg:` sur le padding de l'écran vide.
721
721
  * Ce resserrement est une décision de portage, prise parce que 32px de
722
722
  * gouttière sur 375px laissent 311px de contenu à un bloc qui porte un
723
- * titre et un bouton. Si la DA la refuse, c'est cette règle qui saute —
723
+ * titre et un bouton. Si la DA la refuse, c'est cette règle qui saute :
724
724
  * pas le reste du bloc. */
725
725
  .zv-empty--page {
726
726
  padding: 40px 20px;
package/src/fonts.css CHANGED
@@ -1,4 +1,4 @@
1
- /* Zevra — chargement des trois familles de la DA.
1
+ /* Zevra : chargement des trois familles de la DA.
2
2
  *
3
3
  * Import SÉPARÉ du reste : une @import CSS bloque le rendu le temps d'un
4
4
  * aller-retour réseau. En production, préférez la balise <link> en tête de
@@ -6,7 +6,7 @@
6
6
  * fichier existe pour les prototypes, les maquettes et les canvas de design,
7
7
  * où la simplicité prime sur la milliseconde.
8
8
  *
9
- * Graisses volontairement restreintes à ce que la DA utilise réellement —
9
+ * Graisses volontairement restreintes à ce que la DA utilise réellement,
10
10
  * charger la famille entière alourdirait la page sans rien apporter :
11
11
  * Outfit 200-600 (titres en 300, wordmarks en 600)
12
12
  * Public Sans 400/600 (texte courant)