@zevra/ui 0.1.0 → 0.2.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/DECISIONS.md +56 -0
- package/README.md +26 -0
- package/icons/index.json +210 -0
- package/icons/sprite.svg +36 -0
- package/package.json +9 -2
- package/src/components.css +2 -3
- package/src/data.css +742 -0
- package/src/feedback.css +566 -0
- package/src/forms.css +815 -0
- package/src/icons.css +81 -0
- package/src/index.css +5 -0
- package/src/navigation.css +814 -0
- package/src/tokens.css +57 -1
- package/tokens/index.js +27 -1
package/src/data.css
ADDED
|
@@ -0,0 +1,742 @@
|
|
|
1
|
+
/* Zevra UI — données : tableaux, listes, cellules, métadonnées, citations
|
|
2
|
+
*
|
|
3
|
+
* CE QUE PORTE LE MODULE
|
|
4
|
+
* le cadre de tableau et sa grille (.zv-table, .zv-table__head, .zv-row),
|
|
5
|
+
* les trois registres de cellule, le dégroupage mobile (.zv-unwrap), la
|
|
6
|
+
* liste sans colonnes, la métadonnée mono, le couple clé-valeur, la
|
|
7
|
+
* pastille d'initiales, les deux utilitaires de troncature, l'étiquette de
|
|
8
|
+
* catégorie, la puce de citation et la vignette de format.
|
|
9
|
+
*
|
|
10
|
+
* DÉPENDANCES
|
|
11
|
+
* tokens.css — pour les seules variables qui y sont déclarées ;
|
|
12
|
+
* base.css — reset (box-sizing), body, et le :focus-visible global, dont
|
|
13
|
+
* ce module ne redéfinit ni la couleur ni l'épaisseur.
|
|
14
|
+
* Ni le reset, ni body, ni :root ne sont reposés ici.
|
|
15
|
+
*
|
|
16
|
+
* CE QUE LE MODULE NE PORTE PAS
|
|
17
|
+
* la pagination (.zv-pager--foot, navigation.css) : le pied de tableau et
|
|
18
|
+
* le pied de pagination sont LE MÊME nœud dans la source (un seul
|
|
19
|
+
* conteneur flex, compteur à gauche, flèches à droite). La version de ce
|
|
20
|
+
* module a été supprimée, elle faisait doublon — les emboîter donnait deux
|
|
21
|
+
* space-between imbriqués et 24px de padding vertical.
|
|
22
|
+
* Aucun contrôle de formulaire non plus : [disabled] et [aria-invalid]
|
|
23
|
+
* n'ont pas d'objet ici, ils vivent dans forms.css.
|
|
24
|
+
*
|
|
25
|
+
* ÉCHELLES — comment lire les tailles ci-dessous
|
|
26
|
+
* La source emploie des demi-pixels (9,5 / 10,5 / 11,5) que le paquet ne
|
|
27
|
+
* nomme pas. Deux rabattements, appliqués systématiquement :
|
|
28
|
+
* — registre TEXTE : plancher --app-sm (12px). Les paliers 10,5 et 11,5
|
|
29
|
+
* relevés y remontent ; c'est une décision, pas un relevé.
|
|
30
|
+
* — micro-labels et glyphes (label de colonne, initiales, vignette) :
|
|
31
|
+
* l'échelle mono (--mono-lg 11 / --mono 10 / --mono-sm 9), employée là
|
|
32
|
+
* comme MESURE, la famille restant celle que la règle déclare.
|
|
33
|
+
* ⚠️ Toutes les tailles et tous les interlettrages mono de la source ont
|
|
34
|
+
* été mesurés sur Menlo (chasse fixe). Le paquet rend la mono en Space
|
|
35
|
+
* Grotesk, de largeur et de hauteur d'x différentes : ces valeurs ne sont
|
|
36
|
+
* donc plus des relevés, ce sont des transpositions à revérifier à l'œil.
|
|
37
|
+
*
|
|
38
|
+
* ÉTATS
|
|
39
|
+
* Le seul état interactif de la source est le survol (.zv-row, .zv-cite).
|
|
40
|
+
* Ni sélection, ni ligne active, ni tri : c'est dit à chaque endroit
|
|
41
|
+
* concerné plutôt que comblé par une valeur inventée.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
/* ─── Cadre de tableau ──────────────────────────────────────────────────
|
|
45
|
+
* Le tableau scrolle DANS son cadre : sans ce confinement, une colonne trop
|
|
46
|
+
* large fait scroller la page entière et le rail de navigation part avec.
|
|
47
|
+
* Angle vif et sans ombre : un tableau est une surface de travail, pas une
|
|
48
|
+
* carte éditoriale. Aucun rayon n'est posé — la valeur par défaut est déjà 0,
|
|
49
|
+
* il n'y a rien à annuler tant qu'on ne compose pas .zv-table avec .zv-card
|
|
50
|
+
* (ce que ce module déconseille : ce sont deux intentions différentes). */
|
|
51
|
+
|
|
52
|
+
.zv-table {
|
|
53
|
+
overflow-x: auto;
|
|
54
|
+
border: 1px solid var(--line);
|
|
55
|
+
background: var(--white);
|
|
56
|
+
|
|
57
|
+
/* --zv-cols est un PARAMÈTRE de grille, pas un token de marque : il n'a
|
|
58
|
+
* rien à faire dans tokens.css et n'y est pas. Il est déclaré ici, sur la
|
|
59
|
+
* classe qui l'expose, avec une valeur de repli ; l'appelant l'écrase en
|
|
60
|
+
* style inline sur ce même élément (le style inline l'emporte), et les
|
|
61
|
+
* enfants en héritent. Une seule déclaration pour l'en-tête ET les lignes :
|
|
62
|
+
* recopié aux deux endroits, on l'oublie à l'un des deux et les intitulés
|
|
63
|
+
* se décalent des valeurs sans que rien ne casse visiblement.
|
|
64
|
+
*
|
|
65
|
+
* Repli à une colonne souple bornée à 0 : sans gabarit, la rangée se
|
|
66
|
+
* dégrade en pile dont les cellules tronquent, au lieu de pousser le cadre.
|
|
67
|
+
*
|
|
68
|
+
* Gabarits relevés, à reprendre tels quels :
|
|
69
|
+
* bibliothèque : 26px minmax(150px, 1fr) 78px 92px 170px 128px
|
|
70
|
+
* répertoire : minmax(190px, 1.4fr) 108px 118px minmax(150px, 1fr) 74px 96px
|
|
71
|
+
* Les colonnes souples sont en minmax(0|150px, …) : sans borne basse à 0 ou
|
|
72
|
+
* sans min-width sur la cellule, la troncature ne se déclenche jamais. */
|
|
73
|
+
--zv-cols: minmax(0, 1fr);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.zv-table__head {
|
|
77
|
+
display: grid;
|
|
78
|
+
/* Le repli est répété dans le var() : .zv-table__head et .zv-row servent
|
|
79
|
+
* aussi hors de .zv-table (rangée seule dans une carte), où rien ne
|
|
80
|
+
* déclarerait le paramètre. */
|
|
81
|
+
grid-template-columns: var(--zv-cols, minmax(0, 1fr));
|
|
82
|
+
align-items: center;
|
|
83
|
+
gap: 10px;
|
|
84
|
+
/* Filet plein (--line) contre le cheveu (--hairline) des lignes : c'est le
|
|
85
|
+
* seul repère qui sépare les intitulés des données, il doit être plus
|
|
86
|
+
* marqué qu'une séparation de lignes. */
|
|
87
|
+
border-bottom: 1px solid var(--line);
|
|
88
|
+
background: var(--panel);
|
|
89
|
+
padding: 9px 14px;
|
|
90
|
+
font-family: var(--font-mono);
|
|
91
|
+
font-size: var(--mono);
|
|
92
|
+
font-weight: 600;
|
|
93
|
+
/* 0,14em et non les 0,2em de .zv-mono : c'est l'interlettrage que le paquet
|
|
94
|
+
* emploie déjà pour les capitales denses (.zv-tag, .zv-src). À 0,2em, six
|
|
95
|
+
* intitulés de colonne ne tiennent plus dans leurs pistes. */
|
|
96
|
+
letter-spacing: 0.14em;
|
|
97
|
+
text-transform: uppercase;
|
|
98
|
+
color: var(--label);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* En-tête d'un tableau posé DANS une carte : la carte porte déjà son filet,
|
|
102
|
+
* un second trait au-dessus ferait doublon. */
|
|
103
|
+
.zv-table__head--inset {
|
|
104
|
+
border-bottom: 0;
|
|
105
|
+
padding: 7px 10px;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* ⚠️ Aucun tri : les intitulés sont inertes, sans indicateur ni gestionnaire.
|
|
109
|
+
* Rien dans la source ne dit ce que trierait un clic ni comment se marque la
|
|
110
|
+
* colonne active — un en-tête triable serait une décision, pas un style. */
|
|
111
|
+
|
|
112
|
+
/* ─── Ligne de données ─────────────────────────────────────────────────
|
|
113
|
+
* Une seule écriture de balisage pour deux mises en page : grille au-dessus
|
|
114
|
+
* du seuil, carte empilée en dessous (voir .zv-unwrap et le bloc responsive).
|
|
115
|
+
* Aucun zébrage nulle part dans la source — le survol est le seul repère de
|
|
116
|
+
* ligne, ce qui laisse le fond blanc porter la lecture. */
|
|
117
|
+
|
|
118
|
+
.zv-row {
|
|
119
|
+
display: grid;
|
|
120
|
+
grid-template-columns: var(--zv-cols, minmax(0, 1fr));
|
|
121
|
+
align-items: center;
|
|
122
|
+
gap: 10px;
|
|
123
|
+
padding: 10px 14px;
|
|
124
|
+
border-bottom: 1px solid var(--hairline);
|
|
125
|
+
text-decoration: none;
|
|
126
|
+
cursor: pointer;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* La dernière ligne colle au cadre : son filet doublerait le trait de bordure
|
|
130
|
+
* et épaissirait le bas du tableau. C'est déjà ce que fait la source côté
|
|
131
|
+
* bibliothèque et côté import (`last:border-b-0`) ; seul le répertoire garde
|
|
132
|
+
* le filet. Le module tranche pour le retrait — ce n'est donc pas une
|
|
133
|
+
* correction contre la production, c'est l'alignement sur sa majorité. */
|
|
134
|
+
.zv-row:last-child {
|
|
135
|
+
border-bottom: 0;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.zv-row:hover {
|
|
139
|
+
/* --panel sur --white : l'écart est faible (2 %), c'est le seul fond de
|
|
140
|
+
* survol dont dispose un système clair sans introduire un troisième gris.
|
|
141
|
+
* Ne pas y accrocher un signal qui doit être vu de loin. */
|
|
142
|
+
background: var(--panel);
|
|
143
|
+
/* La ligne est un lien : sans cette annulation, le survol souligne d'un
|
|
144
|
+
* coup tout le contenu de la rangée. */
|
|
145
|
+
text-decoration: none;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/* Le cadre du tableau est en overflow auto : un contour de focus posé à
|
|
149
|
+
* l'extérieur de la ligne y serait rogné sur les bords. On le rentre.
|
|
150
|
+
* (La couleur et l'épaisseur restent celles de base.css.) */
|
|
151
|
+
.zv-row:focus-visible {
|
|
152
|
+
outline-offset: -2px;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/* ⚠️ Ni état sélectionné, ni :focus-within, ni ligne active : la source n'en
|
|
156
|
+
* contient aucun, et les inventer ferait apparaître un fond de plus dans un
|
|
157
|
+
* système qui n'en a que deux (blanc, survol). */
|
|
158
|
+
|
|
159
|
+
/* ─── Cellules ─────────────────────────────────────────────────────────
|
|
160
|
+
* Trois registres seulement : le texte courant, le nombre, et l'intitulé qui
|
|
161
|
+
* remplace l'en-tête quand celui-ci disparaît. */
|
|
162
|
+
|
|
163
|
+
.zv-cell {
|
|
164
|
+
/* Sans min-width: 0, une cellule de grille ne descend pas sous la largeur
|
|
165
|
+
* de son contenu : la troncature ne se déclenche pas et la ligne pousse le
|
|
166
|
+
* tableau au lieu de couper. C'est la panne la plus fréquente ici. */
|
|
167
|
+
min-width: 0;
|
|
168
|
+
overflow: hidden;
|
|
169
|
+
text-overflow: ellipsis;
|
|
170
|
+
white-space: nowrap;
|
|
171
|
+
font-size: var(--app-sm);
|
|
172
|
+
color: var(--ink-2);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/* Cellule d'identité (nom de document, nom d'entité) : c'est elle qu'on lit
|
|
176
|
+
* en premier, elle monte d'un cran en taille, en graisse et en contraste.
|
|
177
|
+
* Sans cette variante, .zv-cell rendrait le titre au même poids que ses
|
|
178
|
+
* métadonnées et la ligne perdrait son point d'entrée. */
|
|
179
|
+
.zv-cell--name {
|
|
180
|
+
font-size: var(--app);
|
|
181
|
+
font-weight: 500;
|
|
182
|
+
color: var(--ink);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/* Nombres et dates, alignés à droite.
|
|
186
|
+
*
|
|
187
|
+
* ⚠️ CORRECTION DE FOND. La version précédente comptait sur --font-mono pour
|
|
188
|
+
* aligner les colonnes de chiffres. Dans la source, --font-mono valait
|
|
189
|
+
* `ui-monospace, Menlo` — une vraie chasse fixe. Dans CE paquet, --font-mono
|
|
190
|
+
* vaut « Space Grotesk », une grotesque PROPORTIONNELLE : le 1 y est plus
|
|
191
|
+
* étroit que le 8, les unités ne tombent pas les unes sous les autres et
|
|
192
|
+
* l'alignement annoncé n'existe pas.
|
|
193
|
+
*
|
|
194
|
+
* Ce qui aligne réellement, c'est font-variant-numeric: tabular-nums : la
|
|
195
|
+
* fonte sert alors ses chiffres à chasse égale, quelle que soit sa famille.
|
|
196
|
+
* La famille mono est conservée ici pour le REGISTRE (valeur technique), pas
|
|
197
|
+
* pour l'alignement — les deux ne sont plus confondus. */
|
|
198
|
+
.zv-cell--num {
|
|
199
|
+
/* Sans effet dans la grille ; utile sous 768px, où la cellule se retrouve
|
|
200
|
+
* enfant d'un .zv-unwrap devenu flex et ne doit pas se laisser comprimer. */
|
|
201
|
+
flex: none;
|
|
202
|
+
text-align: right;
|
|
203
|
+
font-family: var(--font-mono);
|
|
204
|
+
font-size: var(--mono-lg);
|
|
205
|
+
font-weight: 500;
|
|
206
|
+
font-variant-numeric: tabular-nums;
|
|
207
|
+
white-space: nowrap;
|
|
208
|
+
color: var(--muted);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* Intitulé porté par la valeur : quand la ligne devient une carte, l'en-tête
|
|
212
|
+
* de colonnes n'existe plus et « 12 » ne veut plus rien dire. Il disparaît
|
|
213
|
+
* dès que la colonne reprend son titre (bloc responsive). */
|
|
214
|
+
.zv-cell__label {
|
|
215
|
+
display: none;
|
|
216
|
+
font-family: var(--font-mono);
|
|
217
|
+
font-size: var(--mono);
|
|
218
|
+
font-weight: 600;
|
|
219
|
+
letter-spacing: 0.14em;
|
|
220
|
+
text-transform: uppercase;
|
|
221
|
+
color: var(--label);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* Même logique pour l'unité en clair — « 42 docs » en carte, « 42 » en
|
|
225
|
+
* tableau. Reste INLINE : elle appartient à la valeur, pas à sa ligne. */
|
|
226
|
+
.zv-cell__unit {
|
|
227
|
+
display: none;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/* ─── Dégroupage ───────────────────────────────────────────────────────
|
|
231
|
+
* La primitive structurelle du module : un groupe qui rassemble deux ou trois
|
|
232
|
+
* cellules pour l'empilement mobile, puis s'efface (display: contents) et
|
|
233
|
+
* rend ses enfants DIRECTEMENT à la grille du tableau. C'est ce qui permet
|
|
234
|
+
* d'écrire le balisage une seule fois pour deux mises en page — sans lui, il
|
|
235
|
+
* faudrait dupliquer la rangée et les deux copies divergeraient.
|
|
236
|
+
*
|
|
237
|
+
* Quatre enveloppes de ce type dans la source, sur trois écrans indépendants :
|
|
238
|
+
* c'est une primitive, pas une astuce locale.
|
|
239
|
+
*
|
|
240
|
+
* ⚠️ Ce que .zv-unwrap NE fait PAS : la fiche client emploie le mouvement
|
|
241
|
+
* inverse (`contents` sur mobile, flex au-dessus du seuil) pour défaire ses
|
|
242
|
+
* colonnes en pile ordonnée. Cette classe-ci pose `contents` en base : elle
|
|
243
|
+
* ne peut pas exprimer ce cas, et le prétendre serait faux. */
|
|
244
|
+
|
|
245
|
+
.zv-unwrap {
|
|
246
|
+
display: contents;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/* ─── Liste sans colonnes ──────────────────────────────────────────────
|
|
250
|
+
* Même cadre que le tableau, mais rien à aligner : pas d'en-tête, pas de
|
|
251
|
+
* gabarit. Sert dès que les rangées n'ont pas de colonnes comparables. */
|
|
252
|
+
|
|
253
|
+
.zv-list {
|
|
254
|
+
border: 1px solid var(--line);
|
|
255
|
+
background: var(--white);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.zv-list__row {
|
|
259
|
+
display: flex;
|
|
260
|
+
align-items: center;
|
|
261
|
+
gap: 16px;
|
|
262
|
+
padding: 13px 18px;
|
|
263
|
+
border-bottom: 1px solid var(--hairline);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.zv-list__row:last-child {
|
|
267
|
+
border-bottom: 0;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/* Rangée « envoi en cours ».
|
|
271
|
+
* ⚠️ La source porte ici un papier CHAUD (#FDFCF8) : une température, pas un
|
|
272
|
+
* accent. Le paquet n'a pas de fond chaud, et le plus proche (--panel) est à
|
|
273
|
+
* 2 % du blanc de la liste : ce fond est, en pratique, INVISIBLE. Il est
|
|
274
|
+
* conservé comme rappel discret, mais le signal « quelque chose est en train
|
|
275
|
+
* de se passer » doit être porté par la jauge (.zv-progress) ou par le
|
|
276
|
+
* libellé de la rangée — surtout pas par ce fond. */
|
|
277
|
+
.zv-list__row--upload {
|
|
278
|
+
background: var(--panel);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.zv-list__main {
|
|
282
|
+
/* Colonne, et non bloc : le nom surmonte sa métadonnée. Sans direction
|
|
283
|
+
* explicite, les deux se suivaient sur une même ligne et la ligne de
|
|
284
|
+
* liste se lisait comme une phrase. */
|
|
285
|
+
display: flex;
|
|
286
|
+
flex-direction: column;
|
|
287
|
+
gap: 2px;
|
|
288
|
+
min-width: 0;
|
|
289
|
+
flex: 1 1 0%;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.zv-list__name {
|
|
293
|
+
overflow: hidden;
|
|
294
|
+
text-overflow: ellipsis;
|
|
295
|
+
white-space: nowrap;
|
|
296
|
+
font-size: var(--app);
|
|
297
|
+
font-weight: 500;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/* ⚠️ Aucun état interactif dans la source : ni survol de rangée, ni sélection,
|
|
301
|
+
* ni focus. Une liste de fichiers n'y est pas cliquable — si elle le devient,
|
|
302
|
+
* c'est .zv-row qu'il faut employer, pas cette rangée-ci. */
|
|
303
|
+
|
|
304
|
+
/* ─── Métadonnée mono ──────────────────────────────────────────────────
|
|
305
|
+
* Second registre mono du système, en BAS DE CASSE : taille de fichier, date,
|
|
306
|
+
* horodatage, compteur, latence. Ni capitales ni interlettrage — c'est
|
|
307
|
+
* exactement ce qui le distingue de .zv-tag et .zv-mono (capitales,
|
|
308
|
+
* 0,14–0,2em) : une date ou un nom de fichier passés en capitales espacées
|
|
309
|
+
* deviennent illisibles et s'alignent mal.
|
|
310
|
+
*
|
|
311
|
+
* tabular-nums pour la même raison qu'en .zv-cell--num : Space Grotesk est
|
|
312
|
+
* proportionnelle, et une colonne d'horodatages y danse d'une ligne à
|
|
313
|
+
* l'autre sans cette propriété. */
|
|
314
|
+
|
|
315
|
+
.zv-meta {
|
|
316
|
+
font-family: var(--font-mono);
|
|
317
|
+
font-size: var(--mono);
|
|
318
|
+
font-weight: 500;
|
|
319
|
+
font-variant-numeric: tabular-nums;
|
|
320
|
+
color: var(--muted);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/* La source échelonne 10,5 / 10 / 11px. Les deux premiers se rabattent sur le
|
|
324
|
+
* même palier du paquet (--mono, 10px) : la variante basse est re-fondée sur
|
|
325
|
+
* --mono-sm (9px, plancher du paquet) pour garder un écart perceptible.
|
|
326
|
+
* C'est une décision assumée, pas une mesure. */
|
|
327
|
+
.zv-meta--sm {
|
|
328
|
+
font-size: var(--mono-sm);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.zv-meta--md {
|
|
332
|
+
font-size: var(--mono-lg);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/* Métadonnée de second plan (taille d'un fichier en cours d'envoi, compteur
|
|
336
|
+
* d'en-tête) : elle recule d'un cran pour ne pas concurrencer le nom. */
|
|
337
|
+
.zv-meta--quiet {
|
|
338
|
+
color: var(--label);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/* Plusieurs métadonnées sur une même ligne : le retour à la ligne est autorisé
|
|
342
|
+
* dès l'origine, une date et une taille ne tiennent pas côte à côte à 320px. */
|
|
343
|
+
.zv-meta-row {
|
|
344
|
+
display: flex;
|
|
345
|
+
flex-wrap: wrap;
|
|
346
|
+
align-items: center;
|
|
347
|
+
column-gap: 10px;
|
|
348
|
+
row-gap: 4px;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/* ─── Clé-valeur ───────────────────────────────────────────────────────
|
|
352
|
+
* ⚠️ RÔLES REMIS DANS LE SENS DE LA SOURCE. La version précédente mettait la
|
|
353
|
+
* mono à droite et la césure à gauche ; la fiche client fait l'inverse : la
|
|
354
|
+
* CLÉ est en mono, en accent, et se coupe ; la VALEUR est en texte courant,
|
|
355
|
+
* en gris de label, et ne se coupe jamais. Inverser les deux change ce que
|
|
356
|
+
* l'œil balaie en premier dans une colonne de métadonnées. */
|
|
357
|
+
|
|
358
|
+
.zv-kv {
|
|
359
|
+
display: flex;
|
|
360
|
+
flex-direction: column;
|
|
361
|
+
gap: 8px;
|
|
362
|
+
font-size: var(--app-sm);
|
|
363
|
+
font-weight: 500;
|
|
364
|
+
color: var(--ink-2);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
.zv-kv__row {
|
|
368
|
+
display: flex;
|
|
369
|
+
justify-content: space-between;
|
|
370
|
+
gap: 10px;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
.zv-kv__key {
|
|
374
|
+
/* Une clé longue doit se couper plutôt que pousser la valeur hors de la
|
|
375
|
+
* carte : ici on préfère la césure à la troncature, un libellé amputé de sa
|
|
376
|
+
* fin ne se devine pas. */
|
|
377
|
+
min-width: 0;
|
|
378
|
+
overflow-wrap: break-word;
|
|
379
|
+
font-family: var(--font-mono);
|
|
380
|
+
font-size: var(--mono-lg);
|
|
381
|
+
font-weight: 500;
|
|
382
|
+
/* L'accent, parce que la clé est le point d'entrée de la ligne. Les alias
|
|
383
|
+
* sémantiques de citation (--cite-ink & co.) n'existent pas dans ce paquet :
|
|
384
|
+
* c'est --accent, directement. */
|
|
385
|
+
color: var(--accent);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
.zv-kv__val {
|
|
389
|
+
white-space: nowrap;
|
|
390
|
+
font-variant-numeric: tabular-nums;
|
|
391
|
+
color: var(--label);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/* Variante en pied de carte : le filet supérieur détache le récapitulatif du
|
|
395
|
+
* contenu qu'il résume. Valeurs de la fiche client (mt 12 / pt 10 / corps
|
|
396
|
+
* 11px / graisse 400). Le corps 11px n'a pas de palier texte dans le paquet,
|
|
397
|
+
* dont l'échelle s'arrête à --app-sm (12px) : rabattu, et dit. */
|
|
398
|
+
.zv-kv--foot {
|
|
399
|
+
margin-top: 12px;
|
|
400
|
+
border-top: 1px solid var(--hairline);
|
|
401
|
+
padding-top: 10px;
|
|
402
|
+
font-size: var(--app-sm);
|
|
403
|
+
font-weight: 400;
|
|
404
|
+
color: var(--muted);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/* Variante en grille (métadonnées d'une source citée) : deux colonnes des DEUX
|
|
408
|
+
* côtés du seuil — ce sont quatre valeurs courtes, les empiler ferait une
|
|
409
|
+
* colonne inutilement longue. Le libellé passe au-dessus de la valeur. */
|
|
410
|
+
.zv-kv--grid {
|
|
411
|
+
display: grid;
|
|
412
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
413
|
+
column-gap: 14px;
|
|
414
|
+
row-gap: 8px;
|
|
415
|
+
font-size: var(--app-sm);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
.zv-kv--grid .zv-kv__row {
|
|
419
|
+
display: block;
|
|
420
|
+
min-width: 0;
|
|
421
|
+
overflow-wrap: break-word;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/* En grille, la clé redevient un label de colonne : capitales, plus petit,
|
|
425
|
+
* gris de label — et non plus l'accent de la variante en ligne. */
|
|
426
|
+
.zv-kv--grid .zv-kv__key {
|
|
427
|
+
display: block;
|
|
428
|
+
margin-bottom: 2px;
|
|
429
|
+
font-size: var(--mono-sm);
|
|
430
|
+
font-weight: 600;
|
|
431
|
+
letter-spacing: 0.14em;
|
|
432
|
+
text-transform: uppercase;
|
|
433
|
+
color: var(--label);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/* La valeur peut se couper ici : dans une case de 50 % de largeur, un
|
|
437
|
+
* nowrap déborderait de sa colonne. */
|
|
438
|
+
.zv-kv--grid .zv-kv__val {
|
|
439
|
+
white-space: normal;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/* ─── Pastille d'initiales ─────────────────────────────────────────────
|
|
443
|
+
* CARRÉE, jamais ronde : le rond est un usage de réseau social, l'encre et le
|
|
444
|
+
* papier posent des blocs. La teinte dit la NATURE de l'entité, elle n'est pas
|
|
445
|
+
* décorative — la changer, c'est changer le sens.
|
|
446
|
+
*
|
|
447
|
+
* 9,5px dans la source. Le paquet ne descend sous 12px que sur son échelle
|
|
448
|
+
* mono : --mono-sm (9px) est employé ici comme MESURE, la pastille restant
|
|
449
|
+
* rendue dans la famille de texte héritée. */
|
|
450
|
+
|
|
451
|
+
.zv-avatar {
|
|
452
|
+
display: flex;
|
|
453
|
+
width: 26px;
|
|
454
|
+
height: 26px;
|
|
455
|
+
flex: none;
|
|
456
|
+
align-items: center;
|
|
457
|
+
justify-content: center;
|
|
458
|
+
font-size: var(--mono-sm);
|
|
459
|
+
font-weight: 600;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/* Puce d'organisation, dans le chrome : une taille en dessous pour ne pas
|
|
463
|
+
* peser plus que le nom qu'elle accompagne. */
|
|
464
|
+
.zv-avatar--sm {
|
|
465
|
+
width: 22px;
|
|
466
|
+
height: 22px;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
.zv-avatar--accent {
|
|
470
|
+
background: var(--accent);
|
|
471
|
+
color: var(--white);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
.zv-avatar--ink {
|
|
475
|
+
background: var(--ink-2);
|
|
476
|
+
color: var(--white);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/* Défaut (société, confrère) : sans aplat, pour que les pastilles pleines
|
|
480
|
+
* restent l'exception et gardent leur valeur de signal. */
|
|
481
|
+
.zv-avatar--soft {
|
|
482
|
+
border: 1px solid var(--line);
|
|
483
|
+
background: var(--hairline);
|
|
484
|
+
color: var(--ink-2);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/* Règles d'initiales, à respecter côté appelant. Il y en a DEUX, et les
|
|
488
|
+
* confondre change le rendu :
|
|
489
|
+
* — .zv-avatar (26px, entité du répertoire) : préfixes « M. | Me | SARL |
|
|
490
|
+
* SCI | SA » retirés, découpe sur [espace ou &], AUCUN repli ;
|
|
491
|
+
* — .zv-avatar--sm (22px, organisation dans le chrome) : deux mots au plus,
|
|
492
|
+
* mots-outils écartés (« cabinet », « étude », « office », « selarl »,
|
|
493
|
+
* « scp », « et », « de », « du », « des », « la », « le », « les »),
|
|
494
|
+
* repli sur « · » quand rien ne sort — sans ce repli, une pastille vide
|
|
495
|
+
* passe pour un défaut d'affichage.
|
|
496
|
+
* Prescrire la seconde pour la première change les initiales du répertoire. */
|
|
497
|
+
|
|
498
|
+
/* ─── Troncature ───────────────────────────────────────────────────────
|
|
499
|
+
* Deux comportements, jamais interchangeables : couper, ou revenir à la ligne. */
|
|
500
|
+
|
|
501
|
+
/* Couper : réservé à ce qui reste identifiable amputé (titres, noms d'entité)
|
|
502
|
+
* ET à ce qui est récupérable ailleurs. ⚠️ Ne marche QUE si le parent porte
|
|
503
|
+
* min-width: 0 (ou si la colonne est en minmax(0, 1fr)) : sans cela, la boîte
|
|
504
|
+
* ne descend pas sous son contenu, rien n'est coupé et la grille est poussée.
|
|
505
|
+
* Livré seul, c'est un utilitaire qui ne marche pas. */
|
|
506
|
+
.zv-trunc {
|
|
507
|
+
min-width: 0;
|
|
508
|
+
overflow: hidden;
|
|
509
|
+
text-overflow: ellipsis;
|
|
510
|
+
white-space: nowrap;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/* Revenir à la ligne : tout ce qui ne se devine pas coupé — adresses e-mail,
|
|
514
|
+
* noms de fichiers, jetons, messages d'erreur. Perdre la fin d'un message
|
|
515
|
+
* d'erreur, c'est perdre l'incident. */
|
|
516
|
+
.zv-break {
|
|
517
|
+
min-width: 0;
|
|
518
|
+
overflow-wrap: break-word;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/* ─── Étiquette de catégorie ───────────────────────────────────────────
|
|
522
|
+
* Étiquette NON porteuse d'alerte : nature d'entité, matière, mot-clé. À ne
|
|
523
|
+
* pas confondre avec le badge d'état (feedback.css), qui porte une couleur
|
|
524
|
+
* sémantique, ni avec .zv-tag (components.css : mono capitales, sans fond) qui est
|
|
525
|
+
* un kicker éditorial. Le fond hairline suffit : une catégorie n'a pas à
|
|
526
|
+
* crier.
|
|
527
|
+
*
|
|
528
|
+
* 10,5 puis 11px dans la source : deux micro-labels, rabattus sur --mono et
|
|
529
|
+
* --mono-lg pris comme mesures (la famille reste celle du texte). */
|
|
530
|
+
|
|
531
|
+
.zv-chip {
|
|
532
|
+
display: inline-block;
|
|
533
|
+
background: var(--hairline);
|
|
534
|
+
padding: 3px 9px;
|
|
535
|
+
font-size: var(--mono);
|
|
536
|
+
font-weight: 600;
|
|
537
|
+
color: var(--ink-2);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/* Valeur technique dans une étiquette (date normalisée, référence) : la mono
|
|
541
|
+
* sans capitales, comme .zv-meta. */
|
|
542
|
+
.zv-chip--mono {
|
|
543
|
+
font-family: var(--font-mono);
|
|
544
|
+
font-variant-numeric: tabular-nums;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/* Variante à contour : employée quand les étiquettes sont posées sur une carte
|
|
548
|
+
* blanche, où le fond hairline ne se détacherait plus assez. */
|
|
549
|
+
.zv-chip--outline {
|
|
550
|
+
border: 1px solid var(--line);
|
|
551
|
+
background: none;
|
|
552
|
+
padding: 4px 10px;
|
|
553
|
+
font-size: var(--mono-lg);
|
|
554
|
+
font-weight: 500;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
.zv-chip-row {
|
|
558
|
+
display: flex;
|
|
559
|
+
flex-wrap: nowrap;
|
|
560
|
+
gap: 6px;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/* ─── Citation ─────────────────────────────────────────────────────────
|
|
564
|
+
* Référence cliquable, insérée dans le fil du texte ou groupée en pied de
|
|
565
|
+
* réponse ; elle ouvre la feuille de source. Fond, filet et encre sont ceux
|
|
566
|
+
* de l'accent (--accent-soft / --accent-line / --accent) : le paquet ne
|
|
567
|
+
* déclare pas d'alias sémantique de citation, et en inventer un ferait un
|
|
568
|
+
* token de plus qu'aucun test n'accepterait. */
|
|
569
|
+
|
|
570
|
+
.zv-cite {
|
|
571
|
+
display: inline-flex;
|
|
572
|
+
align-items: center;
|
|
573
|
+
gap: 5px;
|
|
574
|
+
max-width: 100%;
|
|
575
|
+
border: 1px solid var(--accent-line);
|
|
576
|
+
background: var(--accent-soft);
|
|
577
|
+
color: var(--accent);
|
|
578
|
+
padding: 2px 8px;
|
|
579
|
+
/* La puce est insérée au fil d'un paragraphe : sans ce recalage elle pend
|
|
580
|
+
* sous la ligne de base et hache l'interligne. */
|
|
581
|
+
vertical-align: 1px;
|
|
582
|
+
font-family: var(--font-mono);
|
|
583
|
+
font-size: var(--mono-lg);
|
|
584
|
+
font-weight: 500;
|
|
585
|
+
font-variant-numeric: tabular-nums;
|
|
586
|
+
/* nowrap l'emporte tant qu'on est au-dessus du seuil ; overflow-wrap est
|
|
587
|
+
* posé d'avance pour le passage en white-space: normal du bloc mobile. */
|
|
588
|
+
overflow-wrap: break-word;
|
|
589
|
+
white-space: nowrap;
|
|
590
|
+
cursor: pointer;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
.zv-cite:hover {
|
|
594
|
+
border-color: var(--accent);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
.zv-cite-row {
|
|
598
|
+
display: flex;
|
|
599
|
+
flex-wrap: wrap;
|
|
600
|
+
gap: 6px;
|
|
601
|
+
margin-top: 10px;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/* ⚠️ Aucun état « source déjà ouverte » : la puce ne se marque pas quand sa
|
|
605
|
+
* feuille est affichée, on ne sait pas laquelle on lit dès qu'il y en a
|
|
606
|
+
* plusieurs. À trancher, pas à combler au hasard.
|
|
607
|
+
* ⚠️ En production c'est un <span onClick> : inatteignable au clavier. Le
|
|
608
|
+
* rendre focusable côté appelant (<button>) suffit à lui donner le contour de
|
|
609
|
+
* base.css — c'est la correction à faire, pas un style à ajouter ici.
|
|
610
|
+
* ⚠️ Recoupe .zv-src (components.css : mono capitales, fond blanc, filet
|
|
611
|
+
* --accent-line, rayon 4px) : même rôle éditorial, aucune valeur commune. La
|
|
612
|
+
* version applicative est remplie et à angle vif. Fusion ou dédoublement
|
|
613
|
+
* assumé : à arbitrer, ce module ne tranche pas seul. */
|
|
614
|
+
|
|
615
|
+
/* ─── Vignette de format ───────────────────────────────────────────────
|
|
616
|
+
* ⚠️ HORS CHARTE, ET ASSUMÉ : --fmt-pdf et --fmt-docx sont le rouge Acrobat
|
|
617
|
+
* et le bleu Word, pas --err ni --accent. Deux relevés indépendants les codent
|
|
618
|
+
* à l'identique — c'est une intention (reconnaître le format d'un coup d'œil),
|
|
619
|
+
* pas une dérive ; tokens.css les déclare et n'en autorise pas d'autre usage.
|
|
620
|
+
* ⚠️ La source pose 7,5px, sous le plancher du paquet (--mono-sm, 9px).
|
|
621
|
+
* Rabattu sur ce plancher : la vignette grossit d'un pixel et demi, ce qui
|
|
622
|
+
* n'est PAS le relevé — à revoir à l'œil sur une rangée dense. Réservé à deux
|
|
623
|
+
* ou quatre caractères en capitales, jamais à du texte.
|
|
624
|
+
* L'interlettrage reste à 0,06em et non aux 0,14em du reste des capitales :
|
|
625
|
+
* sur quatre caractères dans 30px de large, 0,14em déborde de la vignette.
|
|
626
|
+
* Règle de choix relevée : DOCX si le type MIME contient « word », PDF sinon. */
|
|
627
|
+
|
|
628
|
+
.zv-filetype {
|
|
629
|
+
flex: none;
|
|
630
|
+
padding: 2px 5px;
|
|
631
|
+
text-align: center;
|
|
632
|
+
font-family: var(--font-mono);
|
|
633
|
+
font-size: var(--mono-sm);
|
|
634
|
+
font-weight: 700;
|
|
635
|
+
letter-spacing: 0.06em;
|
|
636
|
+
color: var(--white);
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
.zv-filetype--pdf {
|
|
640
|
+
background: var(--fmt-pdf);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
.zv-filetype--docx {
|
|
644
|
+
background: var(--fmt-docx);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/* ─── Sous 768px ───────────────────────────────────────────────────────
|
|
648
|
+
* Point de rupture unique de la charte. Les lignes cessent d'être des lignes :
|
|
649
|
+
* une grille de six colonnes à 375px produit six colonnes illisibles, ou un
|
|
650
|
+
* débordement horizontal de la page. Le balisage, lui, ne change pas — c'est
|
|
651
|
+
* .zv-unwrap qui rend l'inversion possible.
|
|
652
|
+
*
|
|
653
|
+
* ⚠️ La source coupe à 1024px (lg de Tailwind), pas à 768 : entre les deux,
|
|
654
|
+
* l'application affichera des cartes là où la source affiche encore un
|
|
655
|
+
* tableau. C'est la charte qui tranche, mais les gabarits de colonnes ont été
|
|
656
|
+
* réglés pour 1024 et méritent une vérification à 800px. */
|
|
657
|
+
|
|
658
|
+
@media (max-width: 767px) {
|
|
659
|
+
/* Des intitulés de colonnes sans colonnes ne veulent rien dire : ce sont les
|
|
660
|
+
* valeurs qui reprennent leur étiquette (.zv-cell__label). */
|
|
661
|
+
.zv-table__head {
|
|
662
|
+
display: none;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/* stretch, pas flex-start : c'est ce que fait la source (aucun items-* au
|
|
666
|
+
* répertoire, items-stretch à l'import). Avec flex-start, tout enfant
|
|
667
|
+
* direct qui n'est pas une enveloppe se rétracte à sa largeur de contenu. */
|
|
668
|
+
.zv-row {
|
|
669
|
+
display: flex;
|
|
670
|
+
flex-direction: column;
|
|
671
|
+
align-items: stretch;
|
|
672
|
+
gap: 7px;
|
|
673
|
+
padding-block: 12px;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/* Le groupe redevient une boîte : ses deux ou trois cellules tiennent sur
|
|
677
|
+
* une même ligne au lieu de s'empiler chacune sur la sienne.
|
|
678
|
+
* flex-wrap: wrap n'est pas optionnel — deux des quatre enveloppes de la
|
|
679
|
+
* source passent à la ligne, et sans lui la rangée taille + date + statut
|
|
680
|
+
* déborde de la carte à 320px, c'est-à-dire exactement le défaut que le
|
|
681
|
+
* passage en carte devait supprimer.
|
|
682
|
+
* ⚠️ La gouttière est arbitrée : la source en emploie trois (6, 10, 12px).
|
|
683
|
+
* 10px est la valeur médiane et la plus fréquente, pas une mesure unique. */
|
|
684
|
+
.zv-unwrap {
|
|
685
|
+
display: flex;
|
|
686
|
+
flex-wrap: wrap;
|
|
687
|
+
align-items: center;
|
|
688
|
+
column-gap: 10px;
|
|
689
|
+
row-gap: 4px;
|
|
690
|
+
min-width: 0;
|
|
691
|
+
width: 100%;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
.zv-cell__label {
|
|
695
|
+
display: inline-block;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
/* La source ne pose PAS de marge sur l'étiquette : elle rend la CELLULE
|
|
699
|
+
* flex, intitulé à gauche et valeur à droite
|
|
700
|
+
* (tableau-de-bord/page.tsx:120). Sans cela, « TAILLE » vient se coller à
|
|
701
|
+
* « 2,4 Mo » et les deux se lisent comme un seul mot.
|
|
702
|
+
* `:has()` cible les seules cellules qui portent une étiquette — les
|
|
703
|
+
* autres gardent leur flux. */
|
|
704
|
+
.zv-cell:has(.zv-cell__label) {
|
|
705
|
+
display: flex;
|
|
706
|
+
align-items: center;
|
|
707
|
+
justify-content: space-between;
|
|
708
|
+
gap: 12px;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
/* Inline, et pas inline-block : « 42 docs » doit rester un seul mot visuel
|
|
712
|
+
* collé à sa valeur. */
|
|
713
|
+
.zv-cell__unit {
|
|
714
|
+
display: inline;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
.zv-list__row {
|
|
718
|
+
flex-direction: column;
|
|
719
|
+
align-items: stretch;
|
|
720
|
+
gap: 8px;
|
|
721
|
+
padding: 12px 14px;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
/* Clé et valeur empilées : côte à côte à 320px, elles se chevauchent dès que
|
|
725
|
+
* le libellé dépasse trois mots. */
|
|
726
|
+
.zv-kv__row {
|
|
727
|
+
flex-direction: column;
|
|
728
|
+
gap: 2px;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
/* Un libellé long ne tient pas sur une ligne à cette largeur : les
|
|
732
|
+
* étiquettes passent en plusieurs rangées plutôt que de déborder. */
|
|
733
|
+
.zv-chip-row {
|
|
734
|
+
flex-wrap: wrap;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
/* Une référence complète ne tient pas en une ligne sur un écran de 320px :
|
|
738
|
+
* sans césure autorisée, la puce déborde de sa colonne. */
|
|
739
|
+
.zv-cite {
|
|
740
|
+
white-space: normal;
|
|
741
|
+
}
|
|
742
|
+
}
|