@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.
- package/DECISIONS.md +264 -208
- package/README.md +21 -21
- package/demo/app.html +6 -6
- package/demo/index.html +3 -3
- package/dist/actions.d.ts +8 -8
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +1 -1
- package/dist/actions.js.map +1 -1
- package/dist/catalogue.d.ts +2 -2
- package/dist/catalogue.js +67 -67
- package/dist/catalogue.js.map +1 -1
- package/dist/content.d.ts +23 -23
- package/dist/content.d.ts.map +1 -1
- package/dist/content.js +16 -16
- package/dist/content.js.map +1 -1
- package/dist/css-inline.d.ts +1 -1
- package/dist/css-inline.d.ts.map +1 -1
- package/dist/css-inline.js +4 -4
- package/dist/css-inline.js.map +1 -1
- package/dist/data-table.d.ts +1 -1
- package/dist/data.d.ts +7 -7
- package/dist/data.js +5 -5
- package/dist/email-tokens.js +1 -1
- package/dist/email.d.ts +6 -6
- package/dist/email.js +8 -8
- package/dist/email.js.map +1 -1
- package/dist/feedback.d.ts +10 -10
- package/dist/feedback.d.ts.map +1 -1
- package/dist/feedback.js +3 -3
- package/dist/forms.d.ts +12 -12
- package/dist/forms.js +5 -5
- package/dist/glyph-data.d.ts +2 -2
- package/dist/glyph-data.js +3 -3
- package/dist/glyph-urls.js +1 -1
- package/dist/glyphes.d.ts +2 -2
- package/dist/glyphes.js +4 -4
- package/dist/icon-data.d.ts +1 -1
- package/dist/icon-data.js +2 -2
- package/dist/icon.d.ts +5 -5
- package/dist/icon.js +1 -1
- package/dist/index.js +4 -4
- package/dist/layout.d.ts +21 -21
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +15 -15
- package/dist/layout.js.map +1 -1
- package/dist/navigation.d.ts +16 -16
- package/dist/navigation.d.ts.map +1 -1
- package/dist/navigation.js +9 -9
- package/dist/navigation.js.map +1 -1
- package/dist/overlays.d.ts +6 -6
- package/dist/overlays.d.ts.map +1 -1
- package/dist/overlays.js +5 -5
- package/dist/select-menu.d.ts +1 -1
- package/dist/select-menu.js +2 -2
- package/dist/surfaces.d.ts +8 -8
- package/dist/surfaces.d.ts.map +1 -1
- package/dist/surfaces.js +6 -6
- package/dist/surfaces.js.map +1 -1
- package/dist/typography.d.ts +4 -4
- package/dist/typography.d.ts.map +1 -1
- package/dist/typography.js +3 -3
- package/dist/typography.js.map +1 -1
- package/icons/index.json +1 -1
- package/package.json +2 -2
- package/react/actions.tsx +9 -9
- package/react/catalogue.tsx +68 -68
- package/react/content.tsx +28 -28
- package/react/css-inline.ts +4 -4
- package/react/data-table.tsx +3 -3
- package/react/data.tsx +9 -9
- package/react/email-tokens.ts +1 -1
- package/react/email.ts +10 -10
- package/react/feedback.tsx +12 -12
- package/react/forms.tsx +15 -15
- package/react/glyph-data.ts +3 -3
- package/react/glyph-urls.ts +1 -1
- package/react/glyphes.ts +4 -4
- package/react/icon-data.ts +2 -2
- package/react/icon.tsx +6 -6
- package/react/index.ts +4 -4
- package/react/layout.tsx +22 -22
- package/react/navigation.tsx +18 -18
- package/react/overlays.tsx +9 -9
- package/react/select-menu.tsx +3 -3
- package/react/surfaces.tsx +10 -10
- package/react/typography.tsx +6 -6
- package/src/base.css +10 -10
- package/src/components.css +49 -49
- package/src/data.css +41 -41
- package/src/feedback.css +55 -55
- package/src/fonts.css +2 -2
- package/src/forms.css +50 -50
- package/src/icons.css +10 -10
- package/src/index.css +1 -1
- package/src/layout.css +27 -27
- package/src/motion.css +16 -16
- package/src/motion.js +4 -4
- package/src/nav.js +5 -5
- package/src/navigation.css +62 -62
- package/src/overlays.css +14 -14
- package/src/rail.js +6 -6
- package/src/surfaces.css +11 -11
- package/src/tokens.css +14 -14
- package/tokens/index.js +8 -8
package/src/forms.css
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
/* Zevra UI
|
|
2
|
-
* case/radio, interrupteur, puces de filtre, zone de dépôt
|
|
1
|
+
/* Zevra UI (formulaires : champ, recherche, zone de texte, sélection,
|
|
2
|
+
* case/radio, interrupteur, puces de filtre, zone de dépôt) et, depuis le
|
|
3
3
|
* 25/08/2026 (hors relevé, voir DECISIONS.md) : le champ à affixe et le
|
|
4
4
|
* curseur.
|
|
5
5
|
*
|
|
6
6
|
* DÉPEND de tokens.css (toutes les valeurs) et de base.css (reset
|
|
7
7
|
* box-sizing, anneau :focus-visible). RIEN D'AUTRE : ce module ne lit ni
|
|
8
|
-
* layout.css, ni components.css, ni motion.css. C'est volontaire
|
|
8
|
+
* layout.css, ni components.css, ni motion.css. C'est volontaire : une app
|
|
9
9
|
* purement applicative n'a aucune raison de charger la mise en page de la
|
|
10
10
|
* vitrine.
|
|
11
11
|
*
|
|
12
12
|
* Ce qu'il NE porte PAS :
|
|
13
|
-
* · le menu déroulé par .zv-select
|
|
13
|
+
* · le menu déroulé par .zv-select (il appartient à navigation.css
|
|
14
14
|
* (.zv-menu) ; ce module pose l'ancre (.zv-select-anchor) et le
|
|
15
15
|
* déclencheur, rien de plus ;
|
|
16
|
-
* · le bouton d'envoi d'un formulaire
|
|
17
|
-
* · l'alerte de bloc (role="alert")
|
|
16
|
+
* · le bouton d'envoi d'un formulaire) c'est .zv-btn (components.css) ;
|
|
17
|
+
* · l'alerte de bloc (role="alert")) module de retours.
|
|
18
18
|
*
|
|
19
19
|
* PROVENANCE. Relevé dans l'application Mémoire (production, mêmes tokens de
|
|
20
20
|
* charte) sur six écrans : /connexion, /chat, /repertoire, /bibliotheque,
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
color: var(--muted);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
/* Le message d'erreur AU NIVEAU DU CHAMP existe
|
|
92
|
+
/* Le message d'erreur AU NIVEAU DU CHAMP existe : une seule fois dans toute
|
|
93
93
|
* l'application, hors des six écrans du relevé initial
|
|
94
94
|
* (add-member-form.tsx:94). Ses valeurs propres (taille, graisse, écart)
|
|
95
95
|
* n'ont PAS été relevées : celles ci-dessous sont dérivées du reste du
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
|
|
130
130
|
/* Relevé (`focus:border-accent-line`) : c'est :focus et non :focus-visible,
|
|
131
131
|
* la bordure réagit donc aussi à la souris. L'anneau clavier de base.css
|
|
132
|
-
* s'y AJOUTE
|
|
132
|
+
* s'y AJOUTE : on ne reprend PAS le `input { outline: none }` de la prod,
|
|
133
133
|
* qui laissait l'application inutilisable au clavier. */
|
|
134
134
|
.zv-input:focus {
|
|
135
135
|
border-color: var(--accent-line);
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
|
|
144
144
|
/* <select> NATIF, habillé comme le champ. C'est le motif de sélection
|
|
145
145
|
* accessible de l'application, relevé deux fois (add-member-form.tsx:82,
|
|
146
|
-
* billing-card.tsx:135) avec exactement les valeurs de .zv-input
|
|
146
|
+
* billing-card.tsx:135) avec exactement les valeurs de .zv-input :
|
|
147
147
|
* `border-line bg-white px-3 py-[9px] text-[13px] text-ink`. D'où un simple
|
|
148
148
|
* modificateur : tout est déjà là.
|
|
149
149
|
*
|
|
@@ -151,7 +151,7 @@
|
|
|
151
151
|
* la liste native et son annonce viennent du navigateur. La remplacer
|
|
152
152
|
* imposerait de redessiner tout cela, et le relevé ne le fait pas non plus.
|
|
153
153
|
* À ne pas confondre avec .zv-select, qui est un déclencheur de menu maison
|
|
154
|
-
*
|
|
154
|
+
* - voir plus bas. */
|
|
155
155
|
.zv-input--select {
|
|
156
156
|
cursor: pointer;
|
|
157
157
|
}
|
|
@@ -203,15 +203,15 @@
|
|
|
203
203
|
* à l'intérieur du cadre, en plus de ce filet. On le garde tel quel plutôt
|
|
204
204
|
* que de trancher l'un des deux :
|
|
205
205
|
* · supprimer l'anneau (outline:none) rendrait le champ nu invisible au
|
|
206
|
-
* clavier
|
|
206
|
+
* clavier, c'est exactement la faute de la production ;
|
|
207
207
|
* · supprimer ce filet priverait la souris de tout retour, alors que le
|
|
208
208
|
* relevé lui en donne un sur les champs bordés.
|
|
209
209
|
* La redondance coûte moins cher que l'une ou l'autre perte. */
|
|
210
|
-
/* ⚠️ REPRIS le 25/08/2026
|
|
210
|
+
/* ⚠️ REPRIS le 25/08/2026 : la DA jugeait la prise de focus « boff ». Elle
|
|
211
211
|
* l'était : le cadre passait à --accent-line, un filet si pâle qu'à côté de
|
|
212
212
|
* l'anneau du champ intérieur il ne se voyait pas. Trois corrections :
|
|
213
213
|
* · le filet passe à --accent PLEIN, pas à sa version diluée ;
|
|
214
|
-
* · un halo --accent-soft de 3px double le trait
|
|
214
|
+
* · un halo --accent-soft de 3px double le trait, c'est lui qui rend le
|
|
215
215
|
* retour visible du coin de l'œil, sans déplacer un pixel de la mise en
|
|
216
216
|
* page (box-shadow ne prend pas de place) ;
|
|
217
217
|
* · la loupe s'allume avec le cadre : elle cesse d'être une invite grise
|
|
@@ -220,7 +220,7 @@
|
|
|
220
220
|
* L'anneau :focus-visible du champ INTÉRIEUR est neutralisé ici, et
|
|
221
221
|
* seulement ici : le cadre le remplace, et il le remplace pour la souris
|
|
222
222
|
* comme pour le clavier. C'est ce qui lève la double marque assumée jusque-là
|
|
223
|
-
*
|
|
223
|
+
* - un seul objet à l'écran, un seul retour. Le champ nu reste parfaitement
|
|
224
224
|
* repérable au clavier, puisque c'est le cadre entier qui s'allume. */
|
|
225
225
|
.zv-search:focus-within {
|
|
226
226
|
border-color: var(--accent);
|
|
@@ -240,7 +240,7 @@
|
|
|
240
240
|
width: 13px;
|
|
241
241
|
height: 13px;
|
|
242
242
|
/* Même gris que le placeholder : la loupe est une invite, pas une donnée.
|
|
243
|
-
* Elle s'allume avec le cadre
|
|
243
|
+
* Elle s'allume avec le cadre : voir :focus-within plus bas. */
|
|
244
244
|
stroke: var(--label);
|
|
245
245
|
transition: stroke 140ms cubic-bezier(0.2, 0.7, 0.2, 1);
|
|
246
246
|
}
|
|
@@ -263,7 +263,7 @@
|
|
|
263
263
|
/* ─── Champ à affixe ────────────────────────────────────────────────────
|
|
264
264
|
* HORS RELEVÉ (25/08/2026, voir DECISIONS.md). « 30 », seul dans un champ,
|
|
265
265
|
* ne dit pas s'il s'agit de jours ou d'euros. La grammaire est celle de
|
|
266
|
-
* .zv-search
|
|
266
|
+
* .zv-search, le seul cadre-à-champ-nu du relevé : cadre --line, champ nu
|
|
267
267
|
* dedans, allumage :focus-within identique. L'affixe est en mono --label,
|
|
268
268
|
* comme les libellés de déclencheur : une unité est un libellé, pas une
|
|
269
269
|
* donnée. */
|
|
@@ -286,7 +286,7 @@
|
|
|
286
286
|
}
|
|
287
287
|
|
|
288
288
|
/* Même prise de focus que le cadre de recherche : filet --accent plein,
|
|
289
|
-
* halo --accent-soft
|
|
289
|
+
* halo --accent-soft, et l'anneau du champ intérieur est remplacé par le
|
|
290
290
|
* cadre, pour la souris comme pour le clavier. */
|
|
291
291
|
.zv-affix:focus-within {
|
|
292
292
|
border-color: var(--accent);
|
|
@@ -319,7 +319,7 @@
|
|
|
319
319
|
* DÉCISION, PAS UN RELEVÉ : il n'existe AUCUN <textarea> dans l'application,
|
|
320
320
|
* sur aucun des huit écrans ouverts. Le composeur du chat est un <input> où
|
|
321
321
|
* Entrée envoie (chat-client.tsx:365). Le bloc ci-dessous est dérivé mot à
|
|
322
|
-
* mot de .zv-input ; seules min-height et resize s'y ajoutent
|
|
322
|
+
* mot de .zv-input ; seules min-height et resize s'y ajoutent : sans elles
|
|
323
323
|
* le champ se rend sur une ligne et le composant n'existe pas. min-height
|
|
324
324
|
* est la SEULE valeur de ce module sans aucune source, dans aucun écran.
|
|
325
325
|
*
|
|
@@ -329,7 +329,7 @@
|
|
|
329
329
|
.zv-textarea {
|
|
330
330
|
width: 100%;
|
|
331
331
|
min-width: 0;
|
|
332
|
-
min-height: 96px; /* sans source
|
|
332
|
+
min-height: 96px; /* sans source : voir ci-dessus */
|
|
333
333
|
border: 1px solid var(--line);
|
|
334
334
|
border-radius: 0;
|
|
335
335
|
background: var(--white);
|
|
@@ -357,7 +357,7 @@
|
|
|
357
357
|
* <select> : c'est un bouton qui ouvre .zv-menu (navigation.css). Pour un
|
|
358
358
|
* vrai choix dans une liste, préférer .zv-input--select, qui est natif.
|
|
359
359
|
*
|
|
360
|
-
* ANCRAGE
|
|
360
|
+
* ANCRAGE : arbitrage à consigner dans DECISIONS.md, les deux modules ne
|
|
361
361
|
* disent pas la même chose. Le relevé donne raison à celui-ci : c'est
|
|
362
362
|
* l'ENVELOPPE qui porte position:relative (`relative inline-block
|
|
363
363
|
* max-w-full`), pas le déclencheur. Ancrer le menu sur .zv-select
|
|
@@ -390,7 +390,7 @@
|
|
|
390
390
|
* l'affichage de la liste » (DA, sur pièces).
|
|
391
391
|
*
|
|
392
392
|
* Le <select> natif (.zv-input--select) reste dans le paquet et garde son
|
|
393
|
-
* usage
|
|
393
|
+
* usage, mais il ne peut PAS être habillé : la liste déroulée est peinte
|
|
394
394
|
* par le système, pas par la page. Sur un macOS en mode sombre, elle sort
|
|
395
395
|
* en menu noir au milieu d'une interface claire. Aucun CSS ne corrige cela,
|
|
396
396
|
* c'est une limite du contrôle.
|
|
@@ -398,7 +398,7 @@
|
|
|
398
398
|
* D'où ce déclencheur, qui a l'apparence exacte d'un champ et ouvre le
|
|
399
399
|
* .zv-menu du paquet. Ce qu'il COÛTE, et qu'il faut assumer en le
|
|
400
400
|
* choisissant : le clavier, l'annonce et la liste native sont à réimplémenter
|
|
401
|
-
*
|
|
401
|
+
* - c'est fait dans le composant React (SelectMenu), pas dans ce fichier.
|
|
402
402
|
* Un gabarit qui pose ces classes à la main sans ce travail livre un select
|
|
403
403
|
* inutilisable au clavier. Dans ce cas, prendre le natif. */
|
|
404
404
|
.zv-input--trigger {
|
|
@@ -466,7 +466,7 @@
|
|
|
466
466
|
/* ─── Case à cocher et bouton radio ─────────────────────────────────────
|
|
467
467
|
* DÉRIVÉS INTÉGRALEMENT, ET ILS DOIVENT ÊTRE LUS COMME TELS : il n'existe
|
|
468
468
|
* zéro <input type="checkbox"> et zéro <input type="radio"> dans toute
|
|
469
|
-
* l'application
|
|
469
|
+
* l'application, la sélection s'y fait toujours par .zv-seg ou .zv-switch.
|
|
470
470
|
* Le bloc ci-dessous réemploie la grammaire déjà en production (carré au
|
|
471
471
|
* filet --line sur --white, coché en aplat --accent, rond des pastilles)
|
|
472
472
|
* sans introduire de valeur de charte nouvelle ; ses DIMENSIONS, elles
|
|
@@ -474,7 +474,7 @@
|
|
|
474
474
|
* source. Le jour où un vrai écran en pose, c'est lui qui tranche.
|
|
475
475
|
*
|
|
476
476
|
* ⚠️ .zv-check est DÉJÀ PRIS par la pastille de validation
|
|
477
|
-
* (components.css:482)
|
|
477
|
+
* (components.css:482) : d'où .zv-check-box.
|
|
478
478
|
*
|
|
479
479
|
* Contrôles natifs volontairement conservés (appearance:none seulement) : le
|
|
480
480
|
* clavier, :focus-visible, [disabled] et l'annonce au lecteur d'écran
|
|
@@ -516,7 +516,7 @@
|
|
|
516
516
|
|
|
517
517
|
/* Le point du radio est creusé dans l'aplat par un anneau blanc interne :
|
|
518
518
|
* un pseudo-élément sur un <input> n'est pas fiable d'un moteur à l'autre.
|
|
519
|
-
* Ce box-shadow est une géométrie, pas une ombre de charte
|
|
519
|
+
* Ce box-shadow est une géométrie, pas une ombre de charte : d'où l'absence
|
|
520
520
|
* de token. */
|
|
521
521
|
.zv-radio:checked {
|
|
522
522
|
border-color: var(--accent);
|
|
@@ -530,11 +530,11 @@
|
|
|
530
530
|
*
|
|
531
531
|
* ⚠️ RABATTEMENT VISIBLE : la piste éteinte était un gris ferme (#C9CEDD),
|
|
532
532
|
* rabattu sur --accent-line, qui est bleuté. L'état éteint prend donc une
|
|
533
|
-
* teinte indigo très pâle. La distinction éteint/allumé tient quand même
|
|
533
|
+
* teinte indigo très pâle. La distinction éteint/allumé tient quand même :
|
|
534
534
|
* elle est portée par l'aplat plein et par le libellé accolé, pas par cette
|
|
535
535
|
* nuance-là. */
|
|
536
536
|
|
|
537
|
-
/* ⚠️ REDESSINÉ le 25/08/2026
|
|
537
|
+
/* ⚠️ REDESSINÉ le 25/08/2026, la DA a tranché « switch horrible » sur
|
|
538
538
|
* pièces, et elle avait raison sur trois points :
|
|
539
539
|
* · 28×16 avec un bouton rond de 12, c'est un jouet posé au milieu de
|
|
540
540
|
* contrôles carrés de 16px de haut ; la ligne de réglage n'avait aucune
|
|
@@ -557,7 +557,7 @@
|
|
|
557
557
|
background: var(--white);
|
|
558
558
|
/* La courbe est celle du paquet (motion.css, `--zv-easing`), recopiée en
|
|
559
559
|
* clair : forms.css ne dépend pas de motion.css et n'a pas à en dépendre
|
|
560
|
-
* pour une transition de couleur. Ce n'est PAS `ease`
|
|
560
|
+
* pour une transition de couleur. Ce n'est PAS `ease` : le défaut d'un
|
|
561
561
|
* framework tiers n'a rien à faire dans le système. */
|
|
562
562
|
transition:
|
|
563
563
|
background-color 150ms cubic-bezier(0.2, 0.7, 0.2, 1),
|
|
@@ -579,7 +579,7 @@
|
|
|
579
579
|
}
|
|
580
580
|
|
|
581
581
|
/* Bouton CARRÉ : le rond ici n'est pas une forme porteuse de sens (ce que
|
|
582
|
-
* sont la pastille d'état ou le radio), c'était un style
|
|
582
|
+
* sont la pastille d'état ou le radio), c'était un style, il tombe avec les
|
|
583
583
|
* autres rayons. Éteint il est gris comme un contrôle inactif, allumé il
|
|
584
584
|
* passe en blanc sur l'aplat indigo. */
|
|
585
585
|
.zv-switch__knob {
|
|
@@ -607,7 +607,7 @@
|
|
|
607
607
|
/* La source place la gouttière de 7px sur une enveloppe PARENTE, et
|
|
608
608
|
* n'entoure que la piste de sa zone tactile (logs-client.tsx:267-273).
|
|
609
609
|
* Elle est ramenée ici : cette classe enveloppe le contrôle ET son
|
|
610
|
-
* libellé, ce qui rend le texte cliquable
|
|
610
|
+
* libellé, ce qui rend le texte cliquable, un <label> qui n'entoure que
|
|
611
611
|
* l'interrupteur laisse une cible de 28px là où il en faut 40. Sans la
|
|
612
612
|
* gouttière, le libellé vient coller à la piste. */
|
|
613
613
|
align-items: center;
|
|
@@ -632,16 +632,16 @@
|
|
|
632
632
|
* HORS RELEVÉ (25/08/2026, voir DECISIONS.md). Aucune source ; dérivé de
|
|
633
633
|
* l'interrupteur redessiné : bouton CARRÉ de 14 px (la taille exacte du
|
|
634
634
|
* bouton du switch), --accent, --accent-deep au survol. La piste fait 3 px
|
|
635
|
-
*
|
|
635
|
+
* - la hauteur de .zv-progress, en --line, remplie en --accent jusqu'au
|
|
636
636
|
* curseur. PAS le spectre : la barre de progression est l'un des trois
|
|
637
637
|
* emplois autorisés, le curseur n'en est pas un.
|
|
638
638
|
*
|
|
639
639
|
* Le remplissage est peint par le FOND de l'input (un dégradé à arrêt
|
|
640
|
-
* franc), position portée par --zv-range-pos que la façade React calcule
|
|
640
|
+
* franc), position portée par --zv-range-pos que la façade React calcule :
|
|
641
641
|
* une géométrie, comme la largeur de Progress, pas une valeur de charte.
|
|
642
642
|
* Sans elle, la piste s'affiche remplie à moitié : poser la variable, ou
|
|
643
643
|
* assumer le repli. Le bouton, lui, passe par les pseudo-éléments de
|
|
644
|
-
* chaque moteur
|
|
644
|
+
* chaque moteur : c'est le seul contrôle du paquet qui l'exige. */
|
|
645
645
|
|
|
646
646
|
.zv-range {
|
|
647
647
|
--zv-range-pos: 50%;
|
|
@@ -706,25 +706,25 @@
|
|
|
706
706
|
* 143-180, repertoire-client.tsx:79-94, logs-client.tsx:193-207).
|
|
707
707
|
*
|
|
708
708
|
* ⚠️ LA SOURCE DIVERGE, ET C'EST TRANCHÉ ICI :
|
|
709
|
-
* · gouttière du groupe
|
|
709
|
+
* · gouttière du groupe, bibliothèque 5px, répertoire et logs 6px. On
|
|
710
710
|
* retient 6px : deux écrans sur trois, et c'est la valeur de .zv-tabs
|
|
711
711
|
* (navigation.css), qui héberge les mêmes puces. Deux conteneurs des
|
|
712
712
|
* mêmes puces avec deux écarts différents, c'est un défaut, pas une
|
|
713
713
|
* nuance.
|
|
714
|
-
* · taille et densité
|
|
714
|
+
* · taille et densité : bibliothèque descend à 11px/4-9px au-dessus du
|
|
715
715
|
* seuil, le répertoire reste à 11px/8-12px partout, en graisse 600. On
|
|
716
716
|
* retient la puce DENSE de la bibliothèque au-dessus du seuil, et la
|
|
717
717
|
* graisse 500 (la 600 est réservée à l'état sélectionné, sinon
|
|
718
718
|
* sélectionné et non sélectionné ne se distinguent plus que par la
|
|
719
719
|
* couleur).
|
|
720
|
-
* · corps
|
|
720
|
+
* · corps, 11 et 12px se rabattent tous les deux sur --app-sm (12px) :
|
|
721
721
|
* l'écart d'un pixel entre les deux écrans disparaît, et la variante
|
|
722
722
|
* mobile de la bibliothèque avec lui. C'est le prix de l'échelle
|
|
723
723
|
* rationalisée, assumé.
|
|
724
724
|
*
|
|
725
725
|
* ⚠️ L'état sélectionné n'est porté par AUCUN aria-pressed en production :
|
|
726
726
|
* il est invisible pour un lecteur d'écran. Le paquet impose <button
|
|
727
|
-
* aria-pressed="true|false">
|
|
727
|
+
* aria-pressed="true|false"> : et le style suit l'attribut autant que la
|
|
728
728
|
* classe, pour que le balisage correct ne coûte rien. */
|
|
729
729
|
|
|
730
730
|
.zv-seg-group {
|
|
@@ -760,7 +760,7 @@
|
|
|
760
760
|
|
|
761
761
|
/* La rangée de puces vit souvent dans un rail qui défile horizontalement
|
|
762
762
|
* (.zv-tabs--rail, navigation.css). L'anneau de base.css y serait rogné aux
|
|
763
|
-
* deux bords. On ne le REDÉFINIT pas
|
|
763
|
+
* deux bords. On ne le REDÉFINIT pas : on déplace seulement son tracé à
|
|
764
764
|
* l'intérieur de la puce, où rien ne le coupe. */
|
|
765
765
|
.zv-seg:focus-visible {
|
|
766
766
|
outline-offset: -2px;
|
|
@@ -778,7 +778,7 @@
|
|
|
778
778
|
}
|
|
779
779
|
|
|
780
780
|
/* Sélection PLEINE (répertoire, logs) : OPT-IN, à poser explicitement, et
|
|
781
|
-
* BORNÉE
|
|
781
|
+
* BORNÉE, un seul groupe plein par page, jamais sur une page qui porte
|
|
782
782
|
* déjà un bouton plein. Une page de filtres à plusieurs groupes (la
|
|
783
783
|
* bibliothèque en a deux) afficherait sinon autant d'aplats indigo que de
|
|
784
784
|
* groupes, simultanément : c'est le seul mécanisme du paquet capable de
|
|
@@ -817,7 +817,7 @@
|
|
|
817
817
|
* tabindex="0" (l'anneau de base.css suit alors tout seul).
|
|
818
818
|
*
|
|
819
819
|
* L'icône est un SVG du balisage (import-client.tsx:159-166) : viewBox
|
|
820
|
-
* 0 0 30 30, fill="none", stroke="var(--accent)", stroke-width="1.5"
|
|
820
|
+
* 0 0 30 30, fill="none", stroke="var(--accent)", stroke-width="1.5",
|
|
821
821
|
* relevée en stroke-linecap="round", REPRISE au trait carré le 25/08/2026
|
|
822
822
|
* comme tout ce qui trace (DECISIONS.md, « Le trait carré ») :
|
|
823
823
|
* <line x1="15" y1="4" x2="15" y2="18"/>
|
|
@@ -842,7 +842,7 @@
|
|
|
842
842
|
*
|
|
843
843
|
* ⚠️ RABATTEMENT VISIBLE : le fond de survol du relevé (#FDFDFF) tombe sur
|
|
844
844
|
* --panel, à peine distinct du --white de repos. Le fond ne SIGNALE donc
|
|
845
|
-
* plus rien
|
|
845
|
+
* plus rien : le retour visuel repose entièrement sur le filet qui passe à
|
|
846
846
|
* --accent. Ne pas le supprimer en croyant que le fond compense. */
|
|
847
847
|
.zv-drop:hover,
|
|
848
848
|
.zv-drop.is-dragging {
|
|
@@ -850,7 +850,7 @@
|
|
|
850
850
|
background: var(--panel);
|
|
851
851
|
}
|
|
852
852
|
|
|
853
|
-
/* Stockage indisponible : la zone reste visible mais inerte
|
|
853
|
+
/* Stockage indisponible : la zone reste visible mais inerte, la masquer
|
|
854
854
|
* ferait croire à une page cassée. */
|
|
855
855
|
.zv-drop--disabled {
|
|
856
856
|
cursor: not-allowed;
|
|
@@ -864,7 +864,7 @@
|
|
|
864
864
|
background: var(--panel);
|
|
865
865
|
}
|
|
866
866
|
|
|
867
|
-
/* 15px : c'est une phrase, pas un libellé d'interface
|
|
867
|
+
/* 15px : c'est une phrase, pas un libellé d'interface, d'où le palier de
|
|
868
868
|
* corps de texte (--body) plutôt que l'échelle applicative, qui s'arrête à
|
|
869
869
|
* 14px. */
|
|
870
870
|
.zv-drop__title {
|
|
@@ -908,7 +908,7 @@
|
|
|
908
908
|
* paquet a par ailleurs une vignette de format (.zv-filetype, data.css) et
|
|
909
909
|
* les deux se liraient comme un seul bloc.
|
|
910
910
|
*
|
|
911
|
-
* Conséquence du retrait du flux : l'input n'est PAS focusable
|
|
911
|
+
* Conséquence du retrait du flux : l'input n'est PAS focusable, d'où le
|
|
912
912
|
* role/tabindex exigés sur .zv-drop ci-dessus. Remettre value='' après
|
|
913
913
|
* chaque sélection, sinon redéposer le même fichier ne déclenche rien. */
|
|
914
914
|
.zv-drop__input {
|
|
@@ -946,7 +946,7 @@
|
|
|
946
946
|
}
|
|
947
947
|
|
|
948
948
|
/* Champ en erreur : seul le filet change. Un fond rouge sur un champ à
|
|
949
|
-
* remplir rendrait la saisie illisible
|
|
949
|
+
* remplir rendrait la saisie illisible : l'aplat --err-soft reste réservé au
|
|
950
950
|
* bandeau d'alerte. Le sélecteur suit l'attribut autant que la classe :
|
|
951
951
|
* aria-invalid est ce qui rend l'erreur audible, il ne doit rien coûter. */
|
|
952
952
|
.zv-field--err .zv-input,
|
|
@@ -987,7 +987,7 @@
|
|
|
987
987
|
/* 44px, pas --tap (40px) : c'est la valeur des formulaires de connexion et
|
|
988
988
|
* du pavé d'import, les deux seuls endroits où l'on saisit au doigt.
|
|
989
989
|
* 16px : en dessous, Safari iOS zoome à la mise au point du champ et
|
|
990
|
-
* décale toute la page
|
|
990
|
+
* décale toute la page, ce n'est pas un choix typographique, aucun token
|
|
991
991
|
* n'a à porter cette valeur. */
|
|
992
992
|
.zv-input,
|
|
993
993
|
.zv-textarea {
|
|
@@ -1003,7 +1003,7 @@
|
|
|
1003
1003
|
|
|
1004
1004
|
/* Le champ nu et celui d'un cadre à affixe. 16px et non --app-lg (14px) :
|
|
1005
1005
|
* la règle des 16px ci-dessus vaut pour TOUT champ qu'on saisit au doigt,
|
|
1006
|
-
* et ces deux-là
|
|
1006
|
+
* et ces deux-là (le composeur, le sous-domaine d'organisation) sont
|
|
1007
1007
|
* parmi les plus saisis d'une application. Sous 16, Safari iOS zoome à la
|
|
1008
1008
|
* mise au point et décale la page. */
|
|
1009
1009
|
.zv-input--bare,
|
|
@@ -1087,7 +1087,7 @@
|
|
|
1087
1087
|
|
|
1088
1088
|
/* ─── Champ mot de passe ────────────────────────────────────────────────
|
|
1089
1089
|
* HORS RELEVÉ (27/08/2026, 0.18.0). Aucune des planches ne montre d'écran de
|
|
1090
|
-
* connexion, et le système n'avait donc rien pour ce champ
|
|
1090
|
+
* connexion, et le système n'avait donc rien pour ce champ : alors que tous
|
|
1091
1091
|
* les produits en ont un, et que la saisie masquée est le seul endroit de
|
|
1092
1092
|
* l'interface où l'on tape sans voir ce qu'on écrit.
|
|
1093
1093
|
*
|
|
@@ -1096,8 +1096,8 @@
|
|
|
1096
1096
|
*
|
|
1097
1097
|
* ⚠️ Le bouton est un vrai <button type="button"> : posé sur un <span>, il
|
|
1098
1098
|
* n'est ni atteignable au clavier ni annoncé, et il envoie le formulaire dès
|
|
1099
|
-
* qu'on oublie le type. Son libellé change avec l'état
|
|
1100
|
-
* « Masquer
|
|
1099
|
+
* qu'on oublie le type. Son libellé change avec l'état, « Afficher » /
|
|
1100
|
+
* « Masquer », parce qu'une icône seule ne dit pas ce qui va se passer. */
|
|
1101
1101
|
|
|
1102
1102
|
.zv-affix__btn {
|
|
1103
1103
|
display: inline-flex;
|
package/src/icons.css
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
/* Zevra UI
|
|
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
4
|
* Les icônes sont TRACÉES, jamais pleines : trait à l'épaisseur 2, sur une
|
|
5
|
-
* grille de 24, à BOUTS FRANCS et JONCTIONS VIVES
|
|
5
|
+
* grille de 24, à BOUTS FRANCS et JONCTIONS VIVES, le trait carré de la
|
|
6
6
|
* charte, arbitré le 25/08/2026 (DECISIONS.md, « Le trait carré ») : les
|
|
7
7
|
* bouts arrondis étaient le dialecte des bibliothèques génériques, pas le
|
|
8
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
|
|
9
|
+
* héritent de la couleur du texte : c'est ce qui leur permet de fonctionner
|
|
10
10
|
* sur papier comme sur la bande manifeste sans qu'on ait à les décliner.
|
|
11
11
|
*
|
|
12
12
|
* Deux façons de les poser :
|
|
13
13
|
*
|
|
14
14
|
* <svg class="zv-icon"><use href="…/icons/sprite.svg#zv-recherche"/></svg>
|
|
15
15
|
*
|
|
16
|
-
* ou, là où les ressources distantes sont interdites
|
|
17
|
-
* Design
|
|
16
|
+
* ou, là où les ressources distantes sont interdites, un canvas Claude
|
|
17
|
+
* Design, en collant le corps de l'icône depuis icons/index.json.
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
.zv-icon {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
width: 16px;
|
|
23
23
|
height: 16px;
|
|
24
24
|
/* `flex: none` évite l'écrasement quand l'icône est posée à côté d'un
|
|
25
|
-
* libellé long dans un conteneur flex
|
|
25
|
+
* libellé long dans un conteneur flex : le cas le plus fréquent, et la
|
|
26
26
|
* déformation la plus visible. */
|
|
27
27
|
flex: none;
|
|
28
28
|
vertical-align: middle;
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
/* `square` garde l'emprise optique du rond (le bout dépasse d'une
|
|
33
33
|
* demi-épaisseur, comme lui) : la silhouette change sans qu'un seul
|
|
34
34
|
* tracé soit redessiné. Les angles très aigus retombent d'eux-mêmes en
|
|
35
|
-
* biseau (miter-limit par défaut)
|
|
35
|
+
* biseau (miter-limit par défaut) : rien à régler. */
|
|
36
36
|
stroke-linecap: square;
|
|
37
37
|
stroke-linejoin: miter;
|
|
38
38
|
}
|
|
@@ -84,11 +84,11 @@
|
|
|
84
84
|
/* Désactivé. C'était la SEULE classe interactive du module sans cet état :
|
|
85
85
|
* .zv-btn, .zv-chrome-btn, .zv-menu__item, .zv-pager__arrow, .zv-range et
|
|
86
86
|
* les champs en ont tous un. Sans lui, un bouton fermé se rendait comme un
|
|
87
|
-
* bouton actif
|
|
87
|
+
* bouton actif, curseur main compris, et s'allumait au survol comme s'il
|
|
88
88
|
* allait agir.
|
|
89
89
|
* ⚠️ Le survol est neutralisé EXPLICITEMENT : `:hover` s'applique encore à
|
|
90
90
|
* un bouton désactivé, et l'application ne peut pas le rattraper depuis une
|
|
91
|
-
* couche d'utilitaires
|
|
91
|
+
* couche d'utilitaires, ce module n'est pas layered. */
|
|
92
92
|
.zv-icon-btn[disabled],
|
|
93
93
|
.zv-icon-btn[aria-disabled='true'] {
|
|
94
94
|
opacity: 0.5;
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
|
|
110
110
|
/* ─── Tuile d'icône ─────────────────────────────────────────────────────
|
|
111
111
|
* HORS RELEVÉ (25/08/2026, voir DECISIONS.md). La pastille carrée qui
|
|
112
|
-
* porte une icône devant un argument de la vitrine
|
|
112
|
+
* porte une icône devant un argument de la vitrine : liste de garanties,
|
|
113
113
|
* grille d'atouts. Carrée par NATURE, pas par style : c'est une tuile.
|
|
114
114
|
* Une par argument, jamais en décor isolé ; c'est le libellé voisin qui
|
|
115
115
|
* nomme, la tuile est décorative par défaut. */
|
package/src/index.css
CHANGED
package/src/layout.css
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
/* Zevra UI
|
|
1
|
+
/* Zevra UI, mise en page : conteneurs, grilles, sections, chrome
|
|
2
2
|
* Dépend de tokens.css et base.css. Ne pose ni reset ni fond de page :
|
|
3
3
|
* c'est le rôle de base.css.
|
|
4
4
|
*
|
|
5
5
|
* ⚠️ Les maquettes sont des rendus FIGÉS (1440px pour les planches, 390px
|
|
6
6
|
* pour Mobile.html). Les reproduire en `width: 1440px` donnerait un
|
|
7
|
-
* débordement horizontal garanti sur téléphone
|
|
7
|
+
* débordement horizontal garanti sur téléphone : ce que les règles du projet
|
|
8
8
|
* interdisent explicitement. Les conteneurs sont donc fluides et plafonnés,
|
|
9
9
|
* ce qui rend le rendu identique au-delà de 1440px et utilisable en dessous.
|
|
10
10
|
*/
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
/* ─── Gouttières ────────────────────────────────────────────────────────
|
|
24
24
|
* Trois retraits relevés, et un seul mécanisme pour les poser : ces
|
|
25
25
|
* utilitaires. Les blocs ci-dessous ne portent QUE leur rythme vertical,
|
|
26
|
-
* jamais leur retrait horizontal
|
|
26
|
+
* jamais leur retrait horizontal : sans quoi poser un utilitaire par-dessus
|
|
27
27
|
* un bloc écraserait son padding vertical (shorthand contre longhand). */
|
|
28
28
|
|
|
29
29
|
.zv-gutter {
|
|
@@ -234,7 +234,7 @@
|
|
|
234
234
|
* zone apparaît (`.zv-nav__actions` : lanceur, compte), space-between
|
|
235
235
|
* centrait les liens et ouvrait un trou entre l'appel à l'action et le
|
|
236
236
|
* compte. Deux apps composant la même barre se rendaient alors
|
|
237
|
-
* différemment selon qu'elles avaient ou non la zone de droite
|
|
237
|
+
* différemment selon qu'elles avaient ou non la zone de droite : c'est le
|
|
238
238
|
* défaut rapporté depuis Campus et Mémoire.
|
|
239
239
|
*
|
|
240
240
|
* La marge automatique absorbe l'espace libre AVANT que space-between ne
|
|
@@ -255,7 +255,7 @@
|
|
|
255
255
|
* Le lanceur et le compte, à droite. Elle ne fait PAS partie de
|
|
256
256
|
* `.zv-nav__links` et c'est tout l'intérêt : cette rangée-là disparaît sous
|
|
257
257
|
* le point de rupture (et sous 1150px pour `.zv-nav--riche`), remplacée par
|
|
258
|
-
* le burger. Le compte, lui, doit rester
|
|
258
|
+
* le burger. Le compte, lui, doit rester : sinon on ne peut plus se
|
|
259
259
|
* connecter depuis un téléphone, et c'est la première chose qu'on y fait.
|
|
260
260
|
*
|
|
261
261
|
* Elle se pose APRÈS `.zv-nav__links` dans le balisage, et avant le burger. */
|
|
@@ -310,7 +310,7 @@
|
|
|
310
310
|
fill: none;
|
|
311
311
|
stroke: currentColor;
|
|
312
312
|
stroke-width: 2;
|
|
313
|
-
/* Bouts francs
|
|
313
|
+
/* Bouts francs : le trait carré du jeu d'icônes (25/08/2026). Le burger
|
|
314
314
|
* applicatif, relevé « extrémités franches », y était déjà. */
|
|
315
315
|
stroke-linecap: square;
|
|
316
316
|
}
|
|
@@ -354,7 +354,7 @@
|
|
|
354
354
|
/* ─── Sélecteur de langue ───────────────────────────────────────────────
|
|
355
355
|
* Des initiales au registre mono, pas un menu : trois langues se lisent
|
|
356
356
|
* d'un coup d'œil, et un menu pour trois entrées coûte un clic pour rien.
|
|
357
|
-
* Une page qui n'existe que dans une langue ne le pose pas
|
|
357
|
+
* Une page qui n'existe que dans une langue ne le pose pas : il vaut mieux
|
|
358
358
|
* pas de sélecteur qu'un sélecteur qui mène à des 404. */
|
|
359
359
|
|
|
360
360
|
.zv-langues {
|
|
@@ -411,14 +411,14 @@
|
|
|
411
411
|
* s'y fonde au défilement.
|
|
412
412
|
*
|
|
413
413
|
* Deux usages, une seule classe. Il est LA BARRE quand il porte directement
|
|
414
|
-
* ses pièces ; il l'ENVELOPPE quand il contient une .zv-nav
|
|
414
|
+
* ses pièces ; il l'ENVELOPPE quand il contient une .zv-nav : c'est la forme
|
|
415
415
|
* qu'impose une nav complète, dont les menus déroulants et le tiroir ont
|
|
416
416
|
* besoin d'un conteneur à eux. Le `:has` bascule tout seul, plutôt que de
|
|
417
417
|
* demander un modificateur qu'on oublierait.
|
|
418
418
|
*
|
|
419
419
|
* ⚠️ backdrop-filter fait de ce bloc le containing block de TOUT descendant
|
|
420
420
|
* en position fixe. Le tiroir (fixe lui aussi) doit donc vivre EN DEHORS,
|
|
421
|
-
* en frère
|
|
421
|
+
* en frère : dedans, il serait rogné par la hauteur de la barre.
|
|
422
422
|
*
|
|
423
423
|
* Le voile venait en rgba littéral, c'est-à-dire hors token : --paper
|
|
424
424
|
* repeint, la barre serait restée sur l'ancienne couleur. */
|
|
@@ -436,7 +436,7 @@
|
|
|
436
436
|
/* Le voile est PLEIN derrière la barre, et il se dégrade EN DESSOUS d'elle
|
|
437
437
|
* (::after). Il était auparavant dégradé sur toute sa hauteur : à sa base
|
|
438
438
|
* il ne restait donc presque rien, et un titre de 38 ou 56px qui passait
|
|
439
|
-
* dessous se retrouvait COUPÉ EN DEUX
|
|
439
|
+
* dessous se retrouvait COUPÉ EN DEUX, moitié voilée, moitié nette, avec
|
|
440
440
|
* les entrées de nav posées sur ses lettres. Deux textes superposés, aucun
|
|
441
441
|
* lisible. Signalé en recette sur mcp-factory.
|
|
442
442
|
* Le dégradé n'est pas perdu : il vit sous la barre, là où il adoucit le
|
|
@@ -445,7 +445,7 @@
|
|
|
445
445
|
* L'OPACITÉ, elle, est retombée de 92 à 72 %. À 92 la barre était un
|
|
446
446
|
* bandeau blanc : ce qui passait dessous n'était plus qu'un fantôme, et
|
|
447
447
|
* le flou ne servait à rien puisqu'il n'y avait rien à voir au travers.
|
|
448
|
-
* C'est du verre qu'on veut, pas un cache
|
|
448
|
+
* C'est du verre qu'on veut, pas un cache : le rendu de
|
|
449
449
|
* landing.zevra.tech, qui fait toujours référence. À 72 avec un flou de
|
|
450
450
|
* 14, le contenu transparaît franchement ET les entrées de nav restent
|
|
451
451
|
* nettes. Comparé à l'écran sur un titre passant sous la barre, à 92, 72
|
|
@@ -455,20 +455,20 @@
|
|
|
455
455
|
* les deux vont ensemble. C'est le flou qui fait le verre ; l'opacité ne
|
|
456
456
|
* fait que doser ce qu'on en voit. */
|
|
457
457
|
background: color-mix(in srgb, var(--paper) 72%, transparent);
|
|
458
|
-
/* ⚠️ LE PRÉFIXÉ D'ABORD. Lightning CSS
|
|
459
|
-
* donc celui de toutes nos applications Next
|
|
458
|
+
/* ⚠️ LE PRÉFIXÉ D'ABORD. Lightning CSS (le compilateur de Tailwind v4,
|
|
459
|
+
* donc celui de toutes nos applications Next) SUPPRIME `backdrop-filter`
|
|
460
460
|
* non préfixé quand il précède la forme `-webkit-`. Or Firefox ne connaît
|
|
461
461
|
* QUE la forme non préfixée : la barre y perdait son flou. Reproduit avec
|
|
462
462
|
* la chaîne exacte des apps, dans les deux ordres. L'ordre est donc une
|
|
463
463
|
* contrainte, pas un style.
|
|
464
464
|
*
|
|
465
465
|
* Le voile, lui, reste en `color-mix` : le compilateur le traite
|
|
466
|
-
* CORRECTEMENT
|
|
466
|
+
* CORRECTEMENT, il émet un repli opaque puis la vraie valeur sous
|
|
467
467
|
* `@supports`, ce qu'on lit dans les bundles livrés. Une note antérieure
|
|
468
468
|
* affirmait qu'il le « réduisait » ; elle prenait le repli pour le
|
|
469
469
|
* résultat. Ne pas « corriger » vers `rgb(from …)` : cette syntaxe sort du
|
|
470
470
|
* compilateur NUE, sans repli, et un navigateur qui l'ignore n'a alors
|
|
471
|
-
* plus AUCUN fond sous une barre fixe
|
|
471
|
+
* plus AUCUN fond sous une barre fixe, 3,5 % d'usage qui voyaient le
|
|
472
472
|
* voile correctement et ne verraient plus rien. */
|
|
473
473
|
-webkit-backdrop-filter: blur(14px);
|
|
474
474
|
backdrop-filter: blur(14px);
|
|
@@ -477,7 +477,7 @@
|
|
|
477
477
|
/* La frange de dégradé, posée SOUS la barre. `pointer-events: none` : elle
|
|
478
478
|
* couvre le haut du contenu, elle ne doit rien intercepter. */
|
|
479
479
|
/* Le prolongement du voile SOUS la barre : il éteint le verre au lieu de
|
|
480
|
-
* le couper net. Son sommet doit valoir EXACTEMENT l'opacité de la barre
|
|
480
|
+
* le couper net. Son sommet doit valoir EXACTEMENT l'opacité de la barre :
|
|
481
481
|
* sinon la jointure fait une marche, d'autant plus visible que la barre est
|
|
482
482
|
* translucide. Les deux valeurs bougent donc ensemble. */
|
|
483
483
|
.zv-header::after {
|
|
@@ -656,13 +656,13 @@
|
|
|
656
656
|
* script et un arbitrage de dessin), pas de points. Le clavier passe par le
|
|
657
657
|
* focus du conteneur, que la façade rend focalisable.
|
|
658
658
|
*
|
|
659
|
-
* La barre de défilement tombe
|
|
659
|
+
* La barre de défilement tombe : le rail visible transformerait la vitrine
|
|
660
660
|
* en fenêtre d'application. C'est un MASQUAGE, pas l'habillage que
|
|
661
661
|
* navigation.css refuse : aucune dimension inventée.
|
|
662
662
|
*
|
|
663
663
|
* ⚠️ Un carrousel reste un aveu d'espace : la règle de variété lui préfère
|
|
664
664
|
* une grille tant que le contenu tient. La largeur des éléments vient du
|
|
665
|
-
* consommateur
|
|
665
|
+
* consommateur : un carrousel qui la fixerait déciderait de la mise en page
|
|
666
666
|
* à la place de la grille. */
|
|
667
667
|
|
|
668
668
|
.zv-carousel {
|
|
@@ -715,15 +715,15 @@
|
|
|
715
715
|
/* ─── Bascule d'affichage ───────────────────────────────────────────────
|
|
716
716
|
* HORS RELEVÉ : utilitaires mécaniques, pas des décisions de charte. Ils
|
|
717
717
|
* existent parce que les maquettes desktop et mobile ne montrent PAS les
|
|
718
|
-
* mêmes éléments de navigation
|
|
719
|
-
* menu burger
|
|
718
|
+
* mêmes éléments de navigation, les liens de nav desktop deviennent un
|
|
719
|
+
* menu burger, et que sans eux chaque app réinvente la même règle. */
|
|
720
720
|
|
|
721
721
|
/* Chaque utilitaire MASQUE dans la plage où l'élément n'a pas sa place, et ne
|
|
722
722
|
* dit RIEN dans l'autre.
|
|
723
723
|
*
|
|
724
724
|
* La version précédente posait `display: none` par défaut puis
|
|
725
725
|
* `display: revert` au-dessus du seuil. C'était faux : `revert` revient au
|
|
726
|
-
* défaut du NAVIGATEUR
|
|
726
|
+
* défaut du NAVIGATEUR, `inline` pour un span, et écrasait donc le
|
|
727
727
|
* `display: flex` que l'élément tenait de sa propre classe. Une rangée de
|
|
728
728
|
* liens de navigation perdait sa gouttière et ses libellés se collaient.
|
|
729
729
|
*
|
|
@@ -826,7 +826,7 @@
|
|
|
826
826
|
|
|
827
827
|
/* Les liens de navigation desktop n'ont pas d'équivalent mobile au
|
|
828
828
|
* relevé : Mobile.html les remplace par un menu burger. Ils ne sont pas
|
|
829
|
-
* masqués d'office
|
|
829
|
+
* masqués d'office, cela casserait les pages sans burger, mais
|
|
830
830
|
* .zv-only-desktop est là pour le faire en une classe. */
|
|
831
831
|
|
|
832
832
|
.zv-steps__rail,
|
|
@@ -893,11 +893,11 @@
|
|
|
893
893
|
* La table des matières d'une page longue, posée sur le côté : un libellé,
|
|
894
894
|
* un point, et le point courant qui s'allume. Elle NAVIGUE (chaque entrée
|
|
895
895
|
* est une ancre) et elle SUIT (le module rail.js marque la section en
|
|
896
|
-
* cours)
|
|
896
|
+
* cours) : les deux, sinon ce n'est qu'un décor qui occupe la marge.
|
|
897
897
|
*
|
|
898
898
|
* ⚠️ Elle demande de la place à côté du texte. Sous le point de rupture
|
|
899
899
|
* elle disparaît : un rail fixe sur un téléphone se pose sur la lecture.
|
|
900
|
-
* Au-dessus, c'est la mesure de la page qui décide
|
|
900
|
+
* Au-dessus, c'est la mesure de la page qui décide : une page dont le
|
|
901
901
|
* contenu court d'un bord à l'autre jusqu'à 1100px gagnera à relever le
|
|
902
902
|
* seuil chez elle.
|
|
903
903
|
*
|
|
@@ -978,7 +978,7 @@
|
|
|
978
978
|
}
|
|
979
979
|
|
|
980
980
|
/* L'entrée courante, posée par rail.js. Le halo du point est le seul
|
|
981
|
-
* signal dont une navigation discrète a besoin
|
|
981
|
+
* signal dont une navigation discrète a besoin : pas de fond, pas de
|
|
982
982
|
* filet. */
|
|
983
983
|
.zv-rail__item--on {
|
|
984
984
|
color: var(--accent-deep);
|
|
@@ -992,8 +992,8 @@
|
|
|
992
992
|
/* ─── Le seuil d'une nav riche ──────────────────────────────────────────
|
|
993
993
|
*
|
|
994
994
|
* La bascule vers le tiroir est à 767px, réglée sur la nav de référence :
|
|
995
|
-
* quatre liens simples. Une nav qui porte l'architecture d'un site
|
|
996
|
-
* familles à menu, un sélecteur de langue, un appel à l'action
|
|
995
|
+
* quatre liens simples. Une nav qui porte l'architecture d'un site (cinq
|
|
996
|
+
* familles à menu, un sélecteur de langue, un appel à l'action) déborde
|
|
997
997
|
* bien avant. Mesuré : entre 768 et 1150px, le logo passe SOUS la première
|
|
998
998
|
* entrée.
|
|
999
999
|
*
|