@zevra/ui 0.10.0 → 0.11.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.
package/react/data.tsx CHANGED
@@ -334,8 +334,8 @@ export function Fold({ titre, ouvert, className, children, ...reste }: FoldProps
334
334
  fill="none"
335
335
  stroke="currentColor"
336
336
  strokeWidth="2"
337
- strokeLinecap="round"
338
- strokeLinejoin="round"
337
+ strokeLinecap="square"
338
+ strokeLinejoin="miter"
339
339
  aria-hidden="true"
340
340
  >
341
341
  <path d="M6.67 9.33 L12 14.67 L17.33 9.33" />
package/react/forms.tsx CHANGED
@@ -359,7 +359,7 @@ export function Drop({
359
359
  fill="none"
360
360
  stroke="var(--accent)"
361
361
  strokeWidth="1.5"
362
- strokeLinecap="round"
362
+ strokeLinecap="square"
363
363
  aria-hidden="true"
364
364
  >
365
365
  <line x1="15" y1="4" x2="15" y2="18" />
@@ -61,24 +61,24 @@ export type IconId =
61
61
  export const CORPS: Record<IconId, string> = {
62
62
  'accueil': "<path d=\"M4 10.67 L12 4 L20 10.67 V20 H4 Z\" /><path d=\"M9.33 20 V13.33 H14.67 V20\" />",
63
63
  'activite': "<path d=\"M3.33 12 H8 L10.67 5.33 L14 18.67 L16 12 H20.67\" />",
64
- 'aide': "<circle cx=\"12\" cy=\"12\" r=\"8.67\" /><path d=\"M9.33 9.33 A2.67 2.67 0 0 1 14.53 10.13 C14.53 11.87 12 12.27 12 14\" /><circle cx=\"12\" cy=\"17.07\" r=\"0.8\" fill=\"currentColor\" stroke=\"none\" />",
64
+ 'aide': "<circle cx=\"12\" cy=\"12\" r=\"8.67\" /><path d=\"M9.33 9.33 A2.67 2.67 0 0 1 14.53 10.13 C14.53 11.87 12 12.27 12 14\" /><rect x=\"11.2\" y=\"16.27\" width=\"1.6\" height=\"1.6\" fill=\"currentColor\" stroke=\"none\" />",
65
65
  'app-couches': "<path d=\"M12 2.67 L20 6.67 L12 10.67 L4 6.67 Z\" /><path d=\"M4 12 L12 16 L20 12\" /><path d=\"M4 17.33 L12 21.33 L20 17.33\" />",
66
- 'archiver': "<rect x=\"3.33\" y=\"4\" width=\"17.33\" height=\"4.67\" rx=\"1.07\" /><path d=\"M5.33 8.67 V18.93 A1.07 1.07 0 0 0 6.4 20 H17.6 A1.07 1.07 0 0 0 18.67 18.93 V8.67\" /><path d=\"M9.33 12.67 H14.67\" />",
67
- 'attention': "<path d=\"M10.67 3.87 L2.53 17.87 A1.55 1.55 0 0 0 3.87 20.19 H20.13 A1.55 1.55 0 0 0 21.47 17.87 L13.33 3.87 A1.54 1.54 0 0 0 10.67 3.87 Z\" /><path d=\"M12 9.33 V13.33\" /><circle cx=\"12\" cy=\"16.53\" r=\"0.8\" fill=\"currentColor\" stroke=\"none\" />",
66
+ 'archiver': "<rect x=\"3.33\" y=\"4\" width=\"17.33\" height=\"4.67\" /><path d=\"M5.33 8.67 V18.93 A1.07 1.07 0 0 0 6.4 20 H17.6 A1.07 1.07 0 0 0 18.67 18.93 V8.67\" /><path d=\"M9.33 12.67 H14.67\" />",
67
+ 'attention': "<path d=\"M10.67 3.87 L2.53 17.87 A1.55 1.55 0 0 0 3.87 20.19 H20.13 A1.55 1.55 0 0 0 21.47 17.87 L13.33 3.87 A1.54 1.54 0 0 0 10.67 3.87 Z\" /><path d=\"M12 9.33 V13.33\" /><rect x=\"11.2\" y=\"15.73\" width=\"1.6\" height=\"1.6\" fill=\"currentColor\" stroke=\"none\" />",
68
68
  'balance': "<path d=\"M12 3.33 V20.67\" /><path d=\"M8.67 20.67 H15.33\" /><path d=\"M5.33 6 H18.67\" /><path d=\"M6.67 6 L3.33 13.33\" /><path d=\"M6.67 6 L10 13.33\" /><path d=\"M3.33 13.33 A3.33 3.33 0 0 0 10 13.33\" /><path d=\"M17.33 6 L14 13.33\" /><path d=\"M17.33 6 L20.67 13.33\" /><path d=\"M14 13.33 A3.33 3.33 0 0 0 20.67 13.33\" />",
69
69
  'base-de-donnees': "<ellipse cx=\"12\" cy=\"6\" rx=\"7.33\" ry=\"2.67\" /><path d=\"M4.67 6 V12 C4.67 13.47 7.87 14.67 12 14.67 C16.13 14.67 19.33 13.47 19.33 12 V6\" /><path d=\"M4.67 12 V18 C4.67 19.47 7.87 20.67 12 20.67 C16.13 20.67 19.33 19.47 19.33 18 V12\" />",
70
70
  'bouclier-verifie': "<path d=\"M12 2.67 L20 6 V12 C20 16.67 16.67 19.73 12 21.33 C7.33 19.73 4 16.67 4 12 V6 Z\" /><path d=\"M8.67 12 L11.07 14.4 L15.33 10\" />",
71
- 'cadenas': "<rect x=\"4.67\" y=\"10.67\" width=\"14.67\" height=\"9.33\" rx=\"1.6\" /><path d=\"M8 10.67 V7.33 A4 4 0 0 1 16 7.33 V10.67\" /><circle cx=\"12\" cy=\"15.33\" r=\"1.33\" />",
71
+ 'cadenas': "<rect x=\"4.67\" y=\"10.67\" width=\"14.67\" height=\"9.33\" /><path d=\"M8 10.67 V7.33 A4 4 0 0 1 16 7.33 V10.67\" /><circle cx=\"12\" cy=\"15.33\" r=\"1.33\" />",
72
72
  'cadrer': "<path d=\"M4 8 V4 H8\" /><path d=\"M20 8 V4 H16\" /><path d=\"M4 16 V20 H8\" /><path d=\"M20 16 V20 H16\" />",
73
- 'calendrier': "<rect x=\"3.33\" y=\"4.67\" width=\"17.33\" height=\"16\" rx=\"1.33\" /><path d=\"M3.33 9.33 H20.67\" /><path d=\"M8 2.67 V6.67\" /><path d=\"M16 2.67 V6.67\" />",
73
+ 'calendrier': "<rect x=\"3.33\" y=\"4.67\" width=\"17.33\" height=\"16\" /><path d=\"M3.33 9.33 H20.67\" /><path d=\"M8 2.67 V6.67\" /><path d=\"M16 2.67 V6.67\" />",
74
74
  'chevron-bas': "<path d=\"M6.67 9.33 L12 14.67 L17.33 9.33\" />",
75
75
  'chevron-droit': "<path d=\"M9.33 4 L17.33 12 L9.33 20\" />",
76
76
  'chevron-gauche': "<path d=\"M14.67 4 L6.67 12 L14.67 20\" />",
77
77
  'chevron-haut': "<path d=\"M6.67 14.67 L12 9.33 L17.33 14.67\" />",
78
78
  'coche': "<path d=\"M5 12.4 L9.4 16.8 L19 6.8\" />",
79
- 'copier': "<rect x=\"4\" y=\"4\" width=\"12\" height=\"12\" rx=\"1.6\" /><path d=\"M8 16 V18.93 A1.07 1.07 0 0 0 9.07 20 H18.93 A1.07 1.07 0 0 0 20 18.93 V9.07 A1.07 1.07 0 0 0 18.93 8 H16\" />",
79
+ 'copier': "<rect x=\"4\" y=\"4\" width=\"12\" height=\"12\" /><path d=\"M8 16 V18.93 A1.07 1.07 0 0 0 9.07 20 H18.93 A1.07 1.07 0 0 0 20 18.93 V9.07 A1.07 1.07 0 0 0 18.93 8 H16\" />",
80
80
  'corbeille': "<path d=\"M4 6.67 H20\" /><path d=\"M9.33 6.67 V4.67 A1.33 1.33 0 0 1 10.67 3.33 H13.33 A1.33 1.33 0 0 1 14.67 4.67 V6.67\" /><path d=\"M6 6.67 L6.93 18.93 A1.33 1.33 0 0 0 8.27 20 H15.73 A1.33 1.33 0 0 0 17.07 18.93 L18 6.67\" /><path d=\"M10 10.67 V16.67\" /><path d=\"M14 10.67 V16.67\" />",
81
- 'courriel': "<rect x=\"2.67\" y=\"5.33\" width=\"18.67\" height=\"13.33\" rx=\"1.33\" /><path d=\"M2.67 7.33 L12 13.33 L21.33 7.33\" />",
81
+ 'courriel': "<rect x=\"2.67\" y=\"5.33\" width=\"18.67\" height=\"13.33\" /><path d=\"M2.67 7.33 L12 13.33 L21.33 7.33\" />",
82
82
  'cube': "<path d=\"M3.33 8 L12 4 L20.67 8 V16 L12 20 L3.33 16 Z\" /><path d=\"M3.33 8 L12 12 L20.67 8\" /><path d=\"M12 12 V20\" />",
83
83
  'deconnexion': "<path d=\"M14.67 4 H5.33 V20 H14.67\" /><path d=\"M10.67 12 H20\" /><path d=\"M16.67 8 L20.67 12 L16.67 16\" />",
84
84
  'depot-fichier': "<path d=\"M12 3.2 V14.4\" /><polyline points=\"7.6,10 12,14.4 16.4,10\" /><path d=\"M4 16.8 v2.4 a1.6 1.6 0 0 0 1.6 1.6 h12.8 a1.6 1.6 0 0 0 1.6-1.6 v-2.4\" />",
@@ -96,8 +96,8 @@ export const CORPS: Record<IconId, string> = {
96
96
  'globe': "<circle cx=\"12\" cy=\"12\" r=\"8.67\" /><path d=\"M3.33 12 H20.67\" /><path d=\"M12 3.33 C14.22 5.64 15.47 8.71 15.47 12 C15.47 15.29 14.22 18.36 12 20.67 C9.78 18.36 8.53 15.29 8.53 12 C8.53 8.71 9.78 5.64 12 3.33 Z\" />",
97
97
  'graphique': "<path d=\"M4 4 V20 H20\" /><path d=\"M8.67 20 V12.67\" /><path d=\"M12.67 20 V8\" /><path d=\"M16.67 20 V15.33\" />",
98
98
  'horloge': "<circle cx=\"12\" cy=\"12\" r=\"8\" /><path d=\"M12 6.67 V12 L15.33 14\" />",
99
- 'imprimante': "<path d=\"M6.67 8 V3.33 H17.33 V8\" /><path d=\"M6.67 17.33 H4.67 A1.33 1.33 0 0 1 3.33 16 V10.67 A1.33 1.33 0 0 1 4.67 9.33 H19.33 A1.33 1.33 0 0 1 20.67 10.67 V16 A1.33 1.33 0 0 1 19.33 17.33 H17.33\" /><rect x=\"6.67\" y=\"13.33\" width=\"10.67\" height=\"7.33\" rx=\"0.8\" />",
100
- 'info': "<circle cx=\"12\" cy=\"12\" r=\"8.67\" /><path d=\"M12 11.33 V16\" /><circle cx=\"12\" cy=\"8\" r=\"0.8\" fill=\"currentColor\" stroke=\"none\" />",
99
+ 'imprimante': "<path d=\"M6.67 8 V3.33 H17.33 V8\" /><path d=\"M6.67 17.33 H4.67 A1.33 1.33 0 0 1 3.33 16 V10.67 A1.33 1.33 0 0 1 4.67 9.33 H19.33 A1.33 1.33 0 0 1 20.67 10.67 V16 A1.33 1.33 0 0 1 19.33 17.33 H17.33\" /><rect x=\"6.67\" y=\"13.33\" width=\"10.67\" height=\"7.33\" />",
100
+ 'info': "<circle cx=\"12\" cy=\"12\" r=\"8.67\" /><path d=\"M12 11.33 V16\" /><rect x=\"11.2\" y=\"7.2\" width=\"1.6\" height=\"1.6\" fill=\"currentColor\" stroke=\"none\" />",
101
101
  'lien-externe': "<path d=\"M10.67 4 H4 V20 H20 V13.33\" /><path d=\"M14.67 4 H20 V9.33\" /><path d=\"M20 4 L12 12\" />",
102
102
  'livre-ouvert': "<path d=\"M2.67 5.33 C5.33 4.67 7.78 4.89 12 6.67 C16.22 4.89 18.67 4.67 21.33 5.33 V18 C18.67 17.33 16.22 17.56 12 19.33 C7.78 17.56 5.33 17.33 2.67 18 Z\" /><path d=\"M12 6.67 V19.33\" />",
103
103
  'menu': "<path d=\"M0 5.33 H24\" /><path d=\"M0 12 H24\" /><path d=\"M0 18.67 H24\" />",
@@ -105,14 +105,14 @@ export const CORPS: Record<IconId, string> = {
105
105
  'oeil': "<path d=\"M2 12 C5.33 6.67 8.67 4.67 12 4.67 C15.33 4.67 18.67 6.67 22 12 C18.67 17.33 15.33 19.33 12 19.33 C8.67 19.33 5.33 17.33 2 12 Z\" /><circle cx=\"12\" cy=\"12\" r=\"2.67\" />",
106
106
  'plus': "<path d=\"M12 4 V20\" /><path d=\"M4 12 H20\" />",
107
107
  'recherche': "<circle cx=\"10.67\" cy=\"10.67\" r=\"6\" /><path d=\"M15.33 15.33 L20 20\" />",
108
- 'registre': "<rect x=\"3.33\" y=\"5.33\" width=\"17.33\" height=\"5.33\" rx=\"1.33\" /><rect x=\"3.33\" y=\"13.33\" width=\"17.33\" height=\"5.33\" rx=\"1.33\" /><circle cx=\"6.67\" cy=\"8\" r=\"0.8\" fill=\"currentColor\" stroke=\"none\" /><circle cx=\"6.67\" cy=\"16\" r=\"0.8\" fill=\"currentColor\" stroke=\"none\" />",
108
+ 'registre': "<rect x=\"3.33\" y=\"5.33\" width=\"17.33\" height=\"5.33\" /><rect x=\"3.33\" y=\"13.33\" width=\"17.33\" height=\"5.33\" /><rect x=\"5.87\" y=\"7.2\" width=\"1.6\" height=\"1.6\" fill=\"currentColor\" stroke=\"none\" /><rect x=\"5.87\" y=\"15.2\" width=\"1.6\" height=\"1.6\" fill=\"currentColor\" stroke=\"none\" />",
109
109
  'reglages': "<circle cx=\"12\" cy=\"12\" r=\"2.93\" /><path d=\"M12 2 V4.67 M12 19.33 V22 M2 12 H4.67 M19.33 12 H22 M4.8 4.8 L6.67 6.67 M17.33 17.33 L19.2 19.2 M19.2 4.8 L17.33 6.67 M6.67 17.33 L4.8 19.2\" />",
110
110
  'reseau': "<circle cx=\"12\" cy=\"12\" r=\"8\" /><path d=\"M4 12 H20\" /><path d=\"M12 4 C14.67 8 14.67 16 12 20\" /><path d=\"M12 4 C9.33 8 9.33 16 12 20\" />",
111
111
  'taches': "<path d=\"M4.67 6.67 L6.67 8.67 L10 5.33\" /><path d=\"M4.67 16 L6.67 18 L10 14.67\" /><path d=\"M13.33 7.33 H20\" /><path d=\"M13.33 16.67 H20\" />",
112
112
  'telecharger': "<path d=\"M12 3.33 V15.33\" /><polyline points=\"6.67,10 12,15.33 17.33,10\" /><path d=\"M4.67 20.67 H19.33\" />",
113
113
  'telephone': "<path d=\"M20.67 16.93 V19.33 A1.6 1.6 0 0 1 18.93 20.93 C16.13 20.67 13.47 19.67 11.2 18.13 C9.09 16.71 7.29 14.91 5.87 12.8 C4.33 10.52 3.33 7.85 3.07 5.05 A1.6 1.6 0 0 1 4.67 3.33 H7.07 A1.6 1.6 0 0 1 8.67 4.71 C8.79 5.83 9.04 6.93 9.4 7.97 A1.6 1.6 0 0 1 9.04 9.65 L8 10.69 C9.32 13.01 11.03 14.71 13.33 16 L14.37 14.96 A1.6 1.6 0 0 1 16.05 14.6 C17.09 14.96 18.19 15.21 19.31 15.33 A1.6 1.6 0 0 1 20.67 16.93 Z\" />",
114
114
  'tri': "<path d=\"M8 4 V20\" /><path d=\"M4.67 7.33 L8 4 L11.33 7.33\" /><path d=\"M16 20 V4\" /><path d=\"M12.67 16.67 L16 20 L19.33 16.67\" />",
115
- 'trois-points': "<circle cx=\"5.33\" cy=\"12\" r=\"1.33\" fill=\"currentColor\" stroke=\"none\" /><circle cx=\"12\" cy=\"12\" r=\"1.33\" fill=\"currentColor\" stroke=\"none\" /><circle cx=\"18.67\" cy=\"12\" r=\"1.33\" fill=\"currentColor\" stroke=\"none\" />",
115
+ 'trois-points': "<rect x=\"4\" y=\"10.67\" width=\"2.66\" height=\"2.66\" fill=\"currentColor\" stroke=\"none\" /><rect x=\"10.67\" y=\"10.67\" width=\"2.66\" height=\"2.66\" fill=\"currentColor\" stroke=\"none\" /><rect x=\"17.34\" y=\"10.67\" width=\"2.66\" height=\"2.66\" fill=\"currentColor\" stroke=\"none\" />",
116
116
  'utilisateur': "<circle cx=\"12\" cy=\"8\" r=\"3.33\" /><path d=\"M5.33 20 C5.33 15.33 8.33 13.33 12 13.33 C15.67 13.33 18.67 15.33 18.67 20\" />",
117
117
  }
118
118
 
package/react/icon.tsx CHANGED
@@ -5,7 +5,7 @@
5
5
  // autoriser côté CSP. L'icône hérite de la couleur du texte : elle fonctionne
6
6
  // sur papier comme sur la bande manifeste sans déclinaison.
7
7
 
8
- import type { ButtonHTMLAttributes, ReactNode, SVGAttributes } from 'react'
8
+ import type { ButtonHTMLAttributes, HTMLAttributes, ReactNode, SVGAttributes } from 'react'
9
9
  import { cx } from './cx.js'
10
10
  import { CORPS, NOMS, type IconId } from './icon-data.js'
11
11
 
@@ -82,3 +82,25 @@ export function IconButton({
82
82
  </button>
83
83
  )
84
84
  }
85
+
86
+ /* ─── Tuile d'icône ────────────────────────────────────────────────── */
87
+
88
+ export interface IconTileProps
89
+ extends Omit<HTMLAttributes<HTMLSpanElement>, 'className'> {
90
+ nom: IconId
91
+ /** Titre accessible. Sans lui la tuile est DÉCORATIVE — le bon défaut :
92
+ * elle accompagne un libellé qui la nomme déjà. */
93
+ titre?: string
94
+ className?: string
95
+ }
96
+
97
+ /** La pastille carrée qui porte une icône devant un argument de la vitrine
98
+ * (liste de garanties, grille d'atouts). UNE par argument, jamais en décor
99
+ * isolé : une tuile sans libellé voisin est un rébus. */
100
+ export function IconTile({ nom, titre, className, ...reste }: IconTileProps) {
101
+ return (
102
+ <span className={cx('zv-icon-tile', className)} {...reste}>
103
+ <Icon nom={nom} titre={titre} />
104
+ </span>
105
+ )
106
+ }
@@ -146,6 +146,22 @@
146
146
  width: 100%;
147
147
  }
148
148
 
149
+ /* Bouton d'action à icône SEULE : l'envoi d'un composeur, l'action unique
150
+ * d'une barre. HORS RELEVÉ (25/08/2026, voir DECISIONS.md). Le libellé
151
+ * accessible est OBLIGATOIRE (aria-label), et s'écrit pour l'ACTION.
152
+ * Ne pas confondre : .zv-icon-btn est le chrome nu (40 px, sans cadre),
153
+ * .zv-chrome-btn la croix bordée (26 px) — le carré est une action, il en
154
+ * a le poids et l'aplat. */
155
+ .zv-btn--carre {
156
+ width: 48px;
157
+ padding: 0;
158
+ }
159
+
160
+ .zv-btn--sm.zv-btn--carre {
161
+ width: 40px;
162
+ padding: 0;
163
+ }
164
+
149
165
  .zv-btn[disabled],
150
166
  .zv-btn--ghost[disabled],
151
167
  .zv-btn--ink[disabled],
@@ -224,7 +240,8 @@
224
240
  /* ─── Lien fléché ───────────────────────────────────────────────────────
225
241
  * Le SVG fait 15×15 : quatre occurrences dans Main.html contre une seule
226
242
  * à 16px dans DesignSystem.html. Tracés : M5 12h14 et M13 6l6 6-6 6, sur
227
- * un viewBox 0 0 24 24, stroke currentColor, épaisseur 2, bouts arrondis. */
243
+ * un viewBox 0 0 24 24 — au trait carré depuis le 25/08/2026, comme tout
244
+ * le jeu d'icônes (DECISIONS.md, « Le trait carré »). */
228
245
 
229
246
  /* ⚠️ REPRIS le 25/08/2026 — la DA le jugeait « pas ouf ». Le diagnostic :
230
247
  * c'était un lien bleu avec un chevron collé, sans rien qui le distingue
@@ -281,6 +298,16 @@
281
298
  width: 15px;
282
299
  height: 15px;
283
300
  flex: none;
301
+ /* ⚠️ CORRIGÉ le 25/08/2026 : le trait n'avait JAMAIS été déclaré — ni
302
+ * fill:none ni stroke —, la flèche se rendait en triangle PLEIN noir (le
303
+ * fût, d'aire nulle, disparaissait) au lieu du tracé que le commentaire
304
+ * d'en-tête promettait depuis le premier jour. Posé au trait carré, avec
305
+ * le reste du jeu. */
306
+ fill: none;
307
+ stroke: currentColor;
308
+ stroke-width: 2;
309
+ stroke-linecap: square;
310
+ stroke-linejoin: miter;
284
311
  transition: transform 220ms cubic-bezier(0.2, 0.7, 0.2, 1);
285
312
  }
286
313
 
@@ -890,6 +917,12 @@
890
917
  font-size: 13px;
891
918
  }
892
919
 
920
+ /* Le carré compact suit la hauteur compacte mobile. */
921
+ .zv-btn--sm.zv-btn--carre {
922
+ width: 36px;
923
+ padding: 0;
924
+ }
925
+
893
926
  .zv-pill {
894
927
  height: 26px;
895
928
  padding: 0 12px;
package/src/forms.css CHANGED
@@ -503,11 +503,12 @@
503
503
  }
504
504
 
505
505
  /* Le blanc du glyphe est écrit en clair (%23fff) : une data-URI ne lit pas
506
- * les variables CSS. Valeur strictement égale à --white. */
506
+ * les variables CSS. Valeur strictement égale à --white. La coche est au
507
+ * trait carré depuis le 25/08/2026, comme tout ce qui trace. */
507
508
  .zv-check-box:checked {
508
509
  border-color: var(--accent);
509
510
  background-color: var(--accent);
510
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23fff' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='2.5,6.5 5,9 9.5,3.5'/%3E%3C/svg%3E");
511
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23fff' stroke-width='1.5' stroke-linecap='square' stroke-linejoin='miter'%3E%3Cpolyline points='2.5,6.5 5,9 9.5,3.5'/%3E%3C/svg%3E");
511
512
  background-position: center;
512
513
  background-repeat: no-repeat;
513
514
  background-size: 12px 12px;
@@ -816,9 +817,9 @@
816
817
  * tabindex="0" (l'anneau de base.css suit alors tout seul).
817
818
  *
818
819
  * L'icône est un SVG du balisage (import-client.tsx:159-166) : viewBox
819
- * 0 0 30 30, fill="none", stroke="var(--accent)", stroke-width="1.5",
820
- * stroke-linecap="round" — et PAS de stroke-linejoin, le tracé n'a qu'un
821
- * angle franc et la source ne le pose pas :
820
+ * 0 0 30 30, fill="none", stroke="var(--accent)", stroke-width="1.5" —
821
+ * relevée en stroke-linecap="round", REPRISE au trait carré le 25/08/2026
822
+ * comme tout ce qui trace (DECISIONS.md, « Le trait carré ») :
822
823
  * <line x1="15" y1="4" x2="15" y2="18"/>
823
824
  * <polyline points="9.5,12.5 15,18 20.5,12.5"/>
824
825
  * <path d="M5 21 v3 a2 2 0 0 0 2 2 h16 a2 2 0 0 0 2-2 v-3"/> */
package/src/icons.css CHANGED
@@ -1,10 +1,13 @@
1
1
  /* Zevra UI — icônes
2
2
  * Dépend de tokens.css. Le jeu lui-même vit dans icons/ (index + sprite).
3
3
  *
4
- * Les icônes sont TRACÉES, jamais pleines : trait à l'épaisseur 2, bouts et
5
- * jonctions arrondis, sur une grille de 24. Elles héritent de la couleur du
6
- * texte — c'est ce qui leur permet de fonctionner sur papier comme sur la
7
- * bande manifeste sans qu'on ait à les décliner.
4
+ * Les icônes sont TRACÉES, jamais pleines : trait à l'épaisseur 2, sur une
5
+ * grille de 24, à BOUTS FRANCS et JONCTIONS VIVES — le trait carré de la
6
+ * charte, arbitré le 25/08/2026 (DECISIONS.md, « Le trait carré ») : les
7
+ * bouts arrondis étaient le dialecte des bibliothèques génériques, pas le
8
+ * nôtre. Le réglage vit ici, les 55 tracés le suivent d'un coup. Elles
9
+ * héritent de la couleur du texte — c'est ce qui leur permet de fonctionner
10
+ * sur papier comme sur la bande manifeste sans qu'on ait à les décliner.
8
11
  *
9
12
  * Deux façons de les poser :
10
13
  *
@@ -26,8 +29,12 @@
26
29
  fill: none;
27
30
  stroke: currentColor;
28
31
  stroke-width: 2;
29
- stroke-linecap: round;
30
- stroke-linejoin: round;
32
+ /* `square` garde l'emprise optique du rond (le bout dépasse d'une
33
+ * demi-épaisseur, comme lui) : la silhouette change sans qu'un seul
34
+ * tracé soit redessiné. Les angles très aigus retombent d'eux-mêmes en
35
+ * biseau (miter-limit par défaut) — rien à régler. */
36
+ stroke-linecap: square;
37
+ stroke-linejoin: miter;
31
38
  }
32
39
 
33
40
  /* Accolée à du texte dense : métadonnée, puce de source, cellule. */
@@ -79,3 +86,21 @@
79
86
  .zv-icon--quiet {
80
87
  color: var(--label);
81
88
  }
89
+
90
+ /* ─── Tuile d'icône ─────────────────────────────────────────────────────
91
+ * HORS RELEVÉ (25/08/2026, voir DECISIONS.md). La pastille carrée qui
92
+ * porte une icône devant un argument de la vitrine — liste de garanties,
93
+ * grille d'atouts. Carrée par NATURE, pas par style : c'est une tuile.
94
+ * Une par argument, jamais en décor isolé ; c'est le libellé voisin qui
95
+ * nomme, la tuile est décorative par défaut. */
96
+ .zv-icon-tile {
97
+ display: inline-flex;
98
+ align-items: center;
99
+ justify-content: center;
100
+ width: 40px;
101
+ height: 40px;
102
+ flex: none;
103
+ border: 1px solid var(--accent-line);
104
+ background: var(--accent-soft);
105
+ color: var(--accent);
106
+ }
package/src/layout.css CHANGED
@@ -263,7 +263,9 @@
263
263
  fill: none;
264
264
  stroke: currentColor;
265
265
  stroke-width: 2;
266
- stroke-linecap: round;
266
+ /* Bouts francs — le trait carré du jeu d'icônes (25/08/2026). Le burger
267
+ * applicatif, relevé « extrémités franches », y était déjà. */
268
+ stroke-linecap: square;
267
269
  }
268
270
 
269
271
  /* Le tiroir de la vitrine : liens empilés, respiration généreuse. Le panneau