@zevra/ui 0.34.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 +293 -203
  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 +93 -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
@@ -1,4 +1,4 @@
1
- /* Zevra UI — composants : boutons, badges, cartes, encarts
1
+ /* Zevra UI, composants : boutons, badges, cartes, encarts
2
2
  * Dépend de tokens.css et base.css.
3
3
  *
4
4
  * Les cinq maquettes ne divergent jamais sur l'intention, souvent sur le
@@ -12,7 +12,7 @@
12
12
  * s'il est répété. Les actions secondaires prennent la variante fantôme.
13
13
  *
14
14
  * Hauteur 48px : Main.html, Mobile.html et le prototype s'accordent.
15
- * DesignSystem.html pose 46px — planche isolée, écartée. */
15
+ * DesignSystem.html pose 46px : planche isolée, écartée. */
16
16
 
17
17
  .zv-btn,
18
18
  .zv-btn--ghost,
@@ -31,7 +31,7 @@
31
31
  text-decoration: none;
32
32
  border: 0;
33
33
  cursor: pointer;
34
- /* La courbe maison, 160 ms — coupée globalement par prefers-reduced-motion
34
+ /* La courbe maison, 160 ms : coupée globalement par prefers-reduced-motion
35
35
  * (base.css). Le fond en dégradé du bouton plein ne s'interpole pas : lui
36
36
  * seul bascule sans fondu, l'écart est trop faible pour se voir. */
37
37
  transition:
@@ -46,15 +46,15 @@
46
46
  * `zv-btn`, `zv-btn--ghost`, `zv-btn--ink` et `zv-btn--danger` sont quatre
47
47
  * classes AUTONOMES et mutuellement exclusives : le socle commun ci-dessus
48
48
  * les groupe dans un même sélecteur, ce qui leur donne exactement l'air
49
- * d'une base et de ses modificateurs. `Button` n'en rend jamais qu'une —
49
+ * d'une base et de ses modificateurs. `Button` n'en rend jamais qu'une :
50
50
  * mais une app qui écrit ses classes à la main lit du BEM et compose les
51
51
  * deux. C'est arrivé (mcp-factory, 0.19.0), et le résultat était vicieux :
52
52
  * `.zv-btn:hover` (0,2,0) l'emportait sur `.zv-btn--ghost` (0,1,0), d'où un
53
- * fond indigo sous un texte encre — illisible, et seulement AU SURVOL, donc
53
+ * fond indigo sous un texte encre, illisible, et seulement AU SURVOL, donc
54
54
  * invisible en relecture comme en capture.
55
55
  *
56
56
  * Le `:not(:where(…))` dit ce que le système voulait déjà dire : ces quatre
57
- * classes s'excluent. `:where()` a une spécificité NULLE — la garde ne
57
+ * classes s'excluent. `:where()` a une spécificité NULLE : la garde ne
58
58
  * change donc aucun arbitrage existant, et une app qui surcharge `.zv-btn`
59
59
  * continue de gagner exactement comme avant.
60
60
  *
@@ -64,7 +64,7 @@
64
64
  /* Le sommet du dégradé. RELEVÉ dans Main.html à #2b2bb4, mais DÉRIVÉ de
65
65
  * --accent depuis la 0.19.0 : la déclaration étant portée par le bouton
66
66
  * lui-même, une redéfinition de marque héritée d'un conteneur ne
67
- * l'atteignait pas — un cabinet en marque blanche obtenait un dégradé
67
+ * l'atteignait pas, un cabinet en marque blanche obtenait un dégradé
68
68
  * allant de l'indigo Zevra à SA couleur. Pour la charte par défaut,
69
69
  * l'écart avec la valeur relevée est d'un point de bleu, invisible.
70
70
  * Les états de survol le dérivent ensuite par color-mix. */
@@ -102,10 +102,10 @@
102
102
 
103
103
  /* ─── États de survol et d'appui ────────────────────────────────────────
104
104
  * HORS RELEVÉ (25/08/2026, voir DECISIONS.md) : aucune maquette n'a d'état
105
- * hover — elles sont figées. Le survol ASSOMBRIT, l'appui assombrit
105
+ * hover, elles sont figées. Le survol ASSOMBRIT, l'appui assombrit
106
106
  * davantage et rassoit le bouton (l'ombre tombe, le liseré s'éteint).
107
- * Les teintes sont DÉRIVÉES par color-mix — l'idiome du voile
108
- * (overlays.css) — des couleurs que le bouton porte déjà : le sommet de
107
+ * Les teintes sont DÉRIVÉES par color-mix, l'idiome du voile
108
+ * (overlays.css), des couleurs que le bouton porte déjà : le sommet de
109
109
  * dégradé relevé (--zv-btn-haut, sans token) et --accent-deep. Aucune
110
110
  * teinte nouvelle n'entre. Aucun déplacement : les entrées du système
111
111
  * montent au défilement, un bouton qui saute au survol raconterait autre
@@ -139,7 +139,7 @@
139
139
  }
140
140
 
141
141
  /* Un aplat d'encre ne peut pas s'assombrir visiblement : il s'ÉCLAIRCIT au
142
- * survol, et l'appui revient à l'encre pleine — plus sombre que le survol,
142
+ * survol, et l'appui revient à l'encre pleine, plus sombre que le survol,
143
143
  * c'est ce qui fait lire l'enfoncement. */
144
144
  .zv-btn--ink:hover {
145
145
  background: color-mix(in oklab, var(--ink) 82%, var(--white));
@@ -157,7 +157,7 @@
157
157
  background: color-mix(in oklab, var(--err) 72%, var(--ink));
158
158
  }
159
159
 
160
- /* Variante compacte : barres de navigation. L'ombre tombe — un bouton de
160
+ /* Variante compacte : barres de navigation. L'ombre tombe : un bouton de
161
161
  * chrome ne décolle pas de la page. */
162
162
  .zv-btn--sm {
163
163
  height: 40px;
@@ -174,7 +174,7 @@
174
174
  * d'une barre. HORS RELEVÉ (25/08/2026, voir DECISIONS.md). Le libellé
175
175
  * accessible est OBLIGATOIRE (aria-label), et s'écrit pour l'ACTION.
176
176
  * Ne pas confondre : .zv-icon-btn est le chrome nu (40 px, sans cadre),
177
- * .zv-chrome-btn la croix bordée (26 px) — le carré est une action, il en
177
+ * .zv-chrome-btn la croix bordée (26 px), le carré est une action, il en
178
178
  * a le poids et l'aplat. */
179
179
  .zv-btn--carre {
180
180
  width: 48px;
@@ -190,14 +190,14 @@
190
190
  .zv-btn--ghost[disabled],
191
191
  .zv-btn--ink[disabled],
192
192
  .zv-btn--danger[disabled] {
193
- /* HORS RELEVÉ — aucune maquette ne montre de bouton désactivé. Traitement
193
+ /* HORS RELEVÉ : aucune maquette ne montre de bouton désactivé. Traitement
194
194
  * minimal et neutre plutôt qu'une couleur inventée. */
195
195
  opacity: 0.5;
196
196
  cursor: not-allowed;
197
197
  box-shadow: none;
198
198
  }
199
199
 
200
- /* Ni le survol ni l'appui ne doivent rattraper un bouton inerte —
200
+ /* Ni le survol ni l'appui ne doivent rattraper un bouton inerte,
201
201
  * désactivé OU occupé (dont le clic est avalé par la façade) : sans ces
202
202
  * règles, les états ci-dessus repeignent le fond et le bouton a l'air
203
203
  * actif. Même précaution que les contrôles désactivés de forms.css. */
@@ -206,7 +206,7 @@
206
206
  background: linear-gradient(180deg, var(--zv-btn-haut) 0%, var(--accent-deep) 100%);
207
207
  }
208
208
 
209
- /* Occupé mais pas désactivé, le bouton plein garde son ombre à l'appui —
209
+ /* Occupé mais pas désactivé, le bouton plein garde son ombre à l'appui :
210
210
  * un enfoncement qui ne déclenche rien serait un mensonge de rendu. Le
211
211
  * compact, lui, n'a pas d'ombre à garder. */
212
212
  .zv-btn:not(.zv-btn--sm)[aria-busy='true']:active {
@@ -231,12 +231,12 @@
231
231
  background: var(--err);
232
232
  }
233
233
 
234
- /* Attente : le motif de Mémoire (feedback.css le documente) — le LIBELLÉ
234
+ /* Attente : le motif de Mémoire (feedback.css le documente), le LIBELLÉ
235
235
  * change (« Connexion… ») pendant que le bouton s'estompe, en
236
236
  * `cursor-wait; opacity: .7`, valeurs relevées reprises telles quelles.
237
237
  * Codé sur [aria-busy], l'attribut qui rend l'attente audible : le
238
238
  * balisage correct ne coûte rien. La façade React l'expose en prop
239
- * `occupe` — qui pose aria-disabled et AVALE le clic plutôt que de poser
239
+ * `occupe` : qui pose aria-disabled et AVALE le clic plutôt que de poser
240
240
  * `disabled`, pour que le bouton reste dans le parcours clavier pendant
241
241
  * que l'attente s'annonce (voir DECISIONS.md). Déclaré APRÈS [disabled]
242
242
  * pour l'emporter à spécificité égale quand les deux se combinent. */
@@ -264,10 +264,10 @@
264
264
  /* ─── Lien fléché ───────────────────────────────────────────────────────
265
265
  * Le SVG fait 15×15 : quatre occurrences dans Main.html contre une seule
266
266
  * à 16px dans DesignSystem.html. Tracés : M5 12h14 et M13 6l6 6-6 6, sur
267
- * un viewBox 0 0 24 24 — au trait carré depuis le 25/08/2026, comme tout
267
+ * un viewBox 0 0 24 24, au trait carré depuis le 25/08/2026, comme tout
268
268
  * le jeu d'icônes (DECISIONS.md, « Le trait carré »). */
269
269
 
270
- /* ⚠️ REPRIS le 25/08/2026 — la DA le jugeait « pas ouf ». Le diagnostic :
270
+ /* ⚠️ REPRIS le 25/08/2026 : la DA le jugeait « pas ouf ». Le diagnostic :
271
271
  * c'était un lien bleu avec un chevron collé, sans rien qui le distingue
272
272
  * d'un lien de texte, et sans aucune récompense au survol. Le mouvement du
273
273
  * paquet est réservé à la vitrine et piloté au défilement ; il n'y avait
@@ -275,12 +275,12 @@
275
275
  *
276
276
  * Trois ajouts, tous dessinés dans les tokens existants :
277
277
  * · un FILET qui se déploie sous le libellé au survol, de gauche à droite
278
- * (scaleX sur une origine gauche) — pas un `text-decoration`, qui ne
278
+ * (scaleX sur une origine gauche), pas un `text-decoration`, qui ne
279
279
  * s'anime pas et coupe les jambages ;
280
280
  * · la flèche avance de 4px, ce qui donne au lien sa direction ;
281
281
  * · le libellé passe en --accent-deep.
282
282
  * Le tout est repeint en une seule transition, donc coupé net par
283
- * prefers-reduced-motion (base.css) — l'état final reste lisible sans. */
283
+ * prefers-reduced-motion (base.css) : l'état final reste lisible sans. */
284
284
 
285
285
  .zv-link-arrow {
286
286
  position: relative;
@@ -322,8 +322,8 @@
322
322
  width: 15px;
323
323
  height: 15px;
324
324
  flex: none;
325
- /* ⚠️ CORRIGÉ le 25/08/2026 : le trait n'avait JAMAIS été déclaré — ni
326
- * fill:none ni stroke —, la flèche se rendait en triangle PLEIN noir (le
325
+ /* ⚠️ CORRIGÉ le 25/08/2026 : le trait n'avait JAMAIS été déclaré, ni
326
+ * fill:none ni stroke, la flèche se rendait en triangle PLEIN noir (le
327
327
  * fût, d'aire nulle, disparaissait) au lieu du tracé que le commentaire
328
328
  * d'en-tête promettait depuis le premier jour. Posé au trait carré, avec
329
329
  * le reste du jeu. */
@@ -341,7 +341,7 @@
341
341
  }
342
342
 
343
343
  /* Sur la bande manifeste : le filet suit `currentColor`, il n'y a donc rien
344
- * à redéclarer — c'est tout l'intérêt de l'avoir posé en currentColor. */
344
+ * à redéclarer, c'est tout l'intérêt de l'avoir posé en currentColor. */
345
345
  .zv-link-arrow--on-dark {
346
346
  color: var(--white);
347
347
  }
@@ -600,7 +600,7 @@
600
600
 
601
601
  /* ─── Carte de tarif ────────────────────────────────────────────────────
602
602
  * Trois par page au maximum. La formule recommandée se signale par le
603
- * bandeau indigo et sa pastille — pas par une couleur de fond. */
603
+ * bandeau indigo et sa pastille : pas par une couleur de fond. */
604
604
 
605
605
  .zv-price {
606
606
  background: var(--white);
@@ -638,7 +638,7 @@
638
638
 
639
639
  /* Le filet, comme `.zv-fold` : sans lui, la FAQ est un aplat blanc posé sur
640
640
  * le papier, sans début ni fin. Toutes les autres surfaces blanches de la
641
- * vitrine — carte, encart, tarif — en portent un ; celle-ci faisait tache. */
641
+ * vitrine (carte, encart, tarif) en portent un ; celle-ci faisait tache. */
642
642
  .zv-faq {
643
643
  background: var(--white);
644
644
  border: 1px solid var(--line);
@@ -677,7 +677,7 @@
677
677
  /* Une FAQ de vitrine veut ses questions dans le PLAN DU DOCUMENT : c'est ce
678
678
  * que lisent les moteurs, et ce que parcourt un lecteur d'écran qui saute de
679
679
  * titre en titre. On accepte donc un `<h2>`/`<h3>`/`<h4>` comme question,
680
- * et on lui retire ce que le navigateur lui met — taille, graisse, marges —
680
+ * et on lui retire ce que le navigateur lui met (taille, graisse, marges)
681
681
  * pour qu'il se rende comme le reste des questions. Le niveau reste au
682
682
  * balisage, l'apparence au système. */
683
683
  .zv-faq__q > :is(h2, h3, h4) {
@@ -715,7 +715,7 @@
715
715
  /* ─── Aperçu d'interface ────────────────────────────────────────────────
716
716
  * La preuve produit : une question, une réponse, ses sources.
717
717
  * ⚠️ Règle de la passation : toujours de vraies données réalistes, jamais
718
- * de lorem — c'est ce bloc qui porte la crédibilité de la page. */
718
+ * de lorem, c'est ce bloc qui porte la crédibilité de la page. */
719
719
 
720
720
  .zv-ui-preview {
721
721
  background: var(--white);
@@ -807,7 +807,7 @@
807
807
 
808
808
 
809
809
  /* ─── Blocs éditoriaux ──────────────────────────────────────────────────
810
- * HORS RELEVÉ — ajoutés le 24/08/2026 à la demande de la DA (règle de
810
+ * HORS RELEVÉ, ajoutés le 24/08/2026 à la demande de la DA (règle de
811
811
  * variété : jamais deux blocs de même forme qui se suivent, 80 % de formes
812
812
  * différentes par page). Quatre façons de poser du contenu SANS carte,
813
813
  * pour que les grilles de cartes redeviennent un choix et non un réflexe.
@@ -842,7 +842,7 @@
842
842
  .zv-rows__val {
843
843
  flex: 1;
844
844
  min-width: 260px;
845
- /* C'est le corps de texte du paquet — le token, pas sa valeur recopiée. */
845
+ /* C'est le corps de texte du paquet : le token, pas sa valeur recopiée. */
846
846
  font-size: var(--body);
847
847
  line-height: 1.6;
848
848
  color: var(--muted);
@@ -885,7 +885,7 @@
885
885
  }
886
886
 
887
887
  /* Variante en colonnes : les mêmes entrées numérotées, posées en grille
888
- * de trois, sans filets — l'espace fait la séparation. */
888
+ * de trois, sans filets, l'espace fait la séparation. */
889
889
  .zv-index--cols {
890
890
  display: grid;
891
891
  grid-template-columns: repeat(3, minmax(0, 1fr));
@@ -984,7 +984,7 @@
984
984
  @media (max-width: 767px) {
985
985
 
986
986
  /* Le `min-width: 260px` de la valeur ne tient pas sous le seuil : dans une
987
- * carte de 215px — un écran de 320px — elle débordait de 45px. La CLÉ
987
+ * carte de 215px, un écran de 320px, elle débordait de 45px. La CLÉ
988
988
  * était déjà libérée (flex-basis 100%), il manquait la valeur. */
989
989
  .zv-rows__val {
990
990
  min-width: 0;
@@ -1059,13 +1059,13 @@
1059
1059
  * Le mot est donc un SVG (`logos/svg/<produit>-wordmark.svg`), à
1060
1060
  * `currentColor` : net à toute taille, et il prend enfin les nuances encre
1061
1061
  * / navy / blanc que le registre des logos décrit. La marque reste le PNG
1062
- * couleur du paquet — c'est un dégradé, il ne se recolore pas.
1062
+ * couleur du paquet : c'est un dégradé, il ne se recolore pas.
1063
1063
  *
1064
1064
  * ⚠️ Ces tracés sont RELEVÉS sur le lockup bitmap d'origine, faute de son
1065
1065
  * fichier vectoriel. Ils sont fidèles à 0,1 % en largeur et nettement plus
1066
1066
  * lisibles que le bitmap partout où le site les pose, mais ils portent les
1067
1067
  * approximations du relevé : réservés à l'ÉCRAN, jusqu'à 120px de capitale.
1068
- * Au-delà — grand format, impression — exiger le fichier d'origine.
1068
+ * Au-delà (grand format, impression) exiger le fichier d'origine.
1069
1069
  *
1070
1070
  * Les proportions viennent du lockup, mesurées au pixel : la marque vaut
1071
1071
  * 2,86 fois la capitale, l'écart entre les deux 0,64 fois, et les deux
@@ -1097,7 +1097,7 @@
1097
1097
 
1098
1098
  /* Le seuil de lisibilité. Sous 11px de capitale, le mot ne se lit plus :
1099
1099
  * ce n'est plus une question de netteté mais de taille, et aucun fichier
1100
- * n'y changera rien. On montre la marque, seule — c'est elle qui identifie.
1100
+ * n'y changera rien. On montre la marque, seule : c'est elle qui identifie.
1101
1101
  * Poser cette classe, ou masquer .zv-lockup__word sous un point de rupture
1102
1102
  * quand la barre se resserre. */
1103
1103
  .zv-lockup--marque-seule {
@@ -1110,13 +1110,13 @@
1110
1110
 
1111
1111
  /* ─── Cadre média ───────────────────────────────────────────────────────
1112
1112
  * HORS RELEVÉ (27/08/2026, 0.18.0). Aucune des dix planches ne montre
1113
- * d'image de contenu — elles sont composées, pas photographiées. Le manque
1113
+ * d'image de contenu : elles sont composées, pas photographiées. Le manque
1114
1114
  * était pourtant total : pas un `aspect-ratio`, pas un `object-fit` dans le
1115
1115
  * paquet, et quatre réécritures du même cadre chez un seul consommateur.
1116
1116
  *
1117
1117
  * ⚠️ Le rapport vit sur le CADRE, jamais sur l'image. Posé sur un enfant de
1118
1118
  * grille aligné au centre, il ne se résout pas et la colonne s'effondre à
1119
- * zéro — c'est un correctif de production, pas une précaution théorique.
1119
+ * zéro : c'est un correctif de production, pas une précaution théorique.
1120
1120
  *
1121
1121
  * Le fond est posé et non laissé transparent : une image qui tarde, échoue
1122
1122
  * ou porte de la transparence laisserait voir la surface du dessous, soit un
@@ -1164,7 +1164,7 @@
1164
1164
  display: block;
1165
1165
  }
1166
1166
 
1167
- /* Le cas inverse — un logo, un schéma, une pièce qu'on ne peut pas rogner.
1167
+ /* Le cas inverse : un logo, un schéma, une pièce qu'on ne peut pas rogner.
1168
1168
  * Le papier passe derrière : il restera du vide, autant qu'il soit choisi. */
1169
1169
  .zv-media--contient {
1170
1170
  background: var(--paper);
@@ -1175,7 +1175,7 @@
1175
1175
  }
1176
1176
 
1177
1177
  /* Le coin d'un cadre : durée d'une vidéo, nombre de pages, mention de
1178
- * réserve. Encre diluée et non un gris opaque — le fond d'image est
1178
+ * réserve. Encre diluée et non un gris opaque : le fond d'image est
1179
1179
  * imprévisible, et l'encre de charte s'y pose sans jurer. */
1180
1180
  .zv-media__coin {
1181
1181
  position: absolute;
@@ -1206,7 +1206,7 @@
1206
1206
 
1207
1207
  /* Voile de lecture : un titre posé SUR une image n'est lisible qu'au-dessus
1208
1208
  * d'un dégradé. Il part du bas, là où le texte se pose, et n'assombrit pas
1209
- * le sujet. Il ne capte pas le pointeur — le cadre reste cliquable. */
1209
+ * le sujet. Il ne capte pas le pointeur : le cadre reste cliquable. */
1210
1210
  .zv-media__voile {
1211
1211
  position: absolute;
1212
1212
  inset: 0;
@@ -1221,7 +1221,7 @@
1221
1221
 
1222
1222
  /* ─── Page légale ───────────────────────────────────────────────────────
1223
1223
  * HORS RELEVÉ (27/08/2026, voir DECISIONS.md). La forme d'un document
1224
- * contractuel — CGVU, mentions légales, DPA. Le TEXTE, lui, n'est pas ici :
1224
+ * contractuel : CGVU, mentions légales, DPA. Le TEXTE, lui, n'est pas ici :
1225
1225
  * il vit dans @zevra/legal, versionné et archivé. Ce module ne porte que la
1226
1226
  * mise en page ; c'est ce qui permet au même texte de s'afficher sur la
1227
1227
  * vitrine et dans une application sans exister en deux exemplaires.
@@ -1237,7 +1237,7 @@
1237
1237
  gap: 48px;
1238
1238
  /* La MESURE, et c'est la seule règle qui compte vraiment pour un contrat :
1239
1239
  * au-delà d'environ 80 signes par ligne, l'œil perd le début de la ligne
1240
- * suivante — sur un texte qu'on lit déjà à reculons, c'est rédhibitoire. */
1240
+ * suivante, sur un texte qu'on lit déjà à reculons, c'est rédhibitoire. */
1241
1241
  max-width: 72ch;
1242
1242
  }
1243
1243
 
@@ -1332,7 +1332,7 @@
1332
1332
 
1333
1333
  /* Encart d'accompagnement d'une clause : la reformulation en langage courant
1334
1334
  * (« En clair ») ou le point à ne pas manquer. Il COMMENTE la clause et ne
1335
- * la remplace pas — d'où une surface d'accompagnement, et non l'aplat d'une
1335
+ * la remplace pas : d'où une surface d'accompagnement, et non l'aplat d'une
1336
1336
  * alerte, qui annoncerait un incident.
1337
1337
  * Il vit ici et non dans feedback.css : une page légale de vitrine n'a pas à
1338
1338
  * charger la couche applicative pour afficher une glose. */
@@ -1369,7 +1369,7 @@
1369
1369
  * Une page entière, pas un encart : 404, 403, 410, 500, maintenance. Elle
1370
1370
  * est ICI et non dans feedback.css parce que la landing Astro en a besoin
1371
1371
  * autant que les apps Next, et que components.css est le seul module que
1372
- * les deux couches chargent réellement — c'est lui qui porte le bouton.
1372
+ * les deux couches chargent réellement : c'est lui qui porte le bouton.
1373
1373
  *
1374
1374
  * ⚠️ Le bloc ne pose AUCUN texte et n'embarque AUCUNE image. Le glyphe
1375
1375
  * arrive en propriété (`@zevra/ui/glyphes`), la copie vient de l'app. Une
@@ -1382,7 +1382,7 @@
1382
1382
  align-items: center;
1383
1383
  justify-content: center;
1384
1384
  /* 70vh et non 100 : la page garde sa barre de navigation au-dessus et son
1385
- * pied en dessous — une erreur n'est pas une raison de perdre la sortie. */
1385
+ * pied en dessous, une erreur n'est pas une raison de perdre la sortie. */
1386
1386
  min-height: 70vh;
1387
1387
  padding: 72px 24px;
1388
1388
  text-align: center;
@@ -1396,7 +1396,7 @@
1396
1396
  object-fit: contain;
1397
1397
  }
1398
1398
 
1399
- /* Le kicker, avec le filet de spectre — PREMIER de ses trois emplois
1399
+ /* Le kicker, avec le filet de spectre : PREMIER de ses trois emplois
1400
1400
  * autorisés. C'est là que le code d'erreur se dit, en mono comme toutes les
1401
1401
  * métadonnées du système. */
1402
1402
  .zv-errpage__kicker {
@@ -1438,7 +1438,7 @@
1438
1438
  }
1439
1439
 
1440
1440
  /* La cote de l'incident : le code et le chemin demandé. Ce n'est pas un
1441
- * ornement — elle donne au visiteur de quoi signaler la panne et au support
1441
+ * ornement : elle donne au visiteur de quoi signaler la panne et au support
1442
1442
  * de quoi la retrouver. Sa forme est celle d'une référence de dossier, ce
1443
1443
  * qui est la seule illustration dont cette maison ait besoin. */
1444
1444
  .zv-errpage__ref {
@@ -1446,7 +1446,7 @@
1446
1446
  padding-top: 14px;
1447
1447
  /* --line et NON --hairline : le cheveu (#eef1f8) est plus CLAIR que le
1448
1448
  * papier (#f5f6fa), donc invisible dès que la page ne repose pas sur du
1449
- * blanc — et une page d'erreur repose sur le papier. Vu au navigateur ; le
1449
+ * blanc, et une page d'erreur repose sur le papier. Vu au navigateur ; le
1450
1450
  * trait était bien là, et ne se voyait pas. */
1451
1451
  border-top: 1px solid var(--line);
1452
1452
  min-width: 220px;