@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/react/catalogue.tsx
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
// Catalogue
|
|
3
|
+
// Catalogue : la planche de tous les composants, avec un exemple rendu et le
|
|
4
4
|
// code qui le produit.
|
|
5
5
|
//
|
|
6
6
|
// Il est PUBLIÉ avec le paquet, pas cantonné aux tests, et c'est délibéré :
|
|
7
7
|
// · la page « Design system » de l'admin le rend tel quel, donc la
|
|
8
|
-
// documentation ne peut pas dériver des composants
|
|
8
|
+
// documentation ne peut pas dériver des composants : c'est le même code ;
|
|
9
9
|
// · tests/react.test.js le rend en HTML et vérifie que chaque classe émise
|
|
10
10
|
// existe dans le CSS. Un composant absent du catalogue n'est pas couvert :
|
|
11
11
|
// c'est le rappel le plus efficace qu'on ait trouvé pour le tenir complet.
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
} from './forms.js'
|
|
39
39
|
import { ICONES, Icon, IconButton, IconTile, NOMS_ICONES } from './icon.js'
|
|
40
40
|
// Les glyphes sont INLINÉS (data-URI) : le catalogue est rendu hors du dépôt
|
|
41
|
-
//
|
|
41
|
+
// - planche, kit de canvas, page d'admin) où un chemin d'image ne résout pas.
|
|
42
42
|
import {
|
|
43
43
|
ACCROCHES_PRODUITS, ADRESSES_PRODUITS, APPS, GLYPHES, MOT_ZEVRA, NOMS_PRODUITS,
|
|
44
44
|
} from './glyphes.js'
|
|
@@ -66,7 +66,7 @@ import {
|
|
|
66
66
|
} from './typography.js'
|
|
67
67
|
|
|
68
68
|
export interface Exemple {
|
|
69
|
-
/** Identifiant stable
|
|
69
|
+
/** Identifiant stable : sert d'ancre dans la page de consultation. */
|
|
70
70
|
id: string
|
|
71
71
|
nom: string
|
|
72
72
|
/** Ce que le composant fait, et surtout quand NE PAS l'employer. */
|
|
@@ -341,7 +341,7 @@ function DemoPopover() {
|
|
|
341
341
|
}
|
|
342
342
|
|
|
343
343
|
/** La barre de vitrine dans ses deux états. Rendue au REPOS : survoler le
|
|
344
|
-
* lanceur ou la pastille déplie le panneau, comme sur un vrai site
|
|
344
|
+
* lanceur ou la pastille déplie le panneau, comme sur un vrai site, c'est
|
|
345
345
|
* du CSS, il n'y a rien à hydrater. La réserve sous chaque barre existe pour
|
|
346
346
|
* que le panneau ait la place de s'ouvrir sans être coupé. */
|
|
347
347
|
function DemoNav() {
|
|
@@ -447,7 +447,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
447
447
|
id: 'headings',
|
|
448
448
|
nom: 'Titres',
|
|
449
449
|
resume:
|
|
450
|
-
'Six paliers. Une page n’a qu’un <h1>, mais peut avoir plusieurs blocs à sa taille
|
|
450
|
+
'Six paliers. Une page n’a qu’un <h1>, mais peut avoir plusieurs blocs à sa taille : passer « as » plutôt que de casser le plan du document.',
|
|
451
451
|
code: `<H1>La recherche juridique, sourcée</H1>
|
|
452
452
|
<H2 as="h3">Ce que voit votre équipe</H2>
|
|
453
453
|
<H3>Indexation continue</H3>
|
|
@@ -465,7 +465,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
465
465
|
id: 'display',
|
|
466
466
|
nom: 'Display',
|
|
467
467
|
resume:
|
|
468
|
-
'Chiffre ou mot posé pour sa présence, HORS de la hiérarchie des titres
|
|
468
|
+
'Chiffre ou mot posé pour sa présence, HORS de la hiérarchie des titres : annoncé comme titre de section, il pollue le plan du document.',
|
|
469
469
|
code: `<Display>4 812</Display>`,
|
|
470
470
|
rendu: <Display>4 812</Display>,
|
|
471
471
|
},
|
|
@@ -494,7 +494,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
494
494
|
id: 'kicker',
|
|
495
495
|
nom: 'Kicker et filet',
|
|
496
496
|
resume:
|
|
497
|
-
'Le filet de spectre 56×2 devant un sur-titre. PREMIER des trois emplois autorisés du spectre
|
|
497
|
+
'Le filet de spectre 56×2 devant un sur-titre. PREMIER des trois emplois autorisés du spectre : jamais en fond, jamais en texte.',
|
|
498
498
|
code: `<Kicker>Méthode</Kicker>
|
|
499
499
|
<Kicker variante="stack">Sécurité</Kicker>
|
|
500
500
|
<Spec petit />`,
|
|
@@ -552,7 +552,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
552
552
|
couche: 'commun',
|
|
553
553
|
css: 'components.css',
|
|
554
554
|
resume:
|
|
555
|
-
"Quatre variantes, et UNE SEULE pleine par page
|
|
555
|
+
"Quatre variantes, et UNE SEULE pleine par page, « danger » comprise, la règle compte les aplats, pas les couleurs : c'est ce qui fait que l'action principale se voit. Un écran à deux boutons pleins n'en a plus aucun.",
|
|
556
556
|
exemples: [
|
|
557
557
|
{
|
|
558
558
|
id: 'boutons',
|
|
@@ -596,7 +596,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
596
596
|
id: 'etats',
|
|
597
597
|
nom: 'États',
|
|
598
598
|
resume:
|
|
599
|
-
'« danger » COMPTE comme le bouton plein de la page
|
|
599
|
+
'« danger » COMPTE comme le bouton plein de la page : la règle compte les aplats, pas les couleurs ; à réserver à la confirmation destructive. « occupe » pose aria-busy et aria-disabled et AVALE le clic sans sortir le bouton du parcours clavier : le LIBELLÉ doit changer avec lui, l’estompement seul ne dit pas ce qu’on attend. Survol et appui sont dans le CSS, rien à câbler.',
|
|
600
600
|
code: `<Button variante="danger">Supprimer définitivement</Button>
|
|
601
601
|
<Button occupe>Connexion…</Button>
|
|
602
602
|
<Button variante="fantome" disabled>Envoyer</Button>`,
|
|
@@ -614,7 +614,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
614
614
|
id: 'boutons-icones',
|
|
615
615
|
nom: 'Boutons à icône',
|
|
616
616
|
resume:
|
|
617
|
-
'L’icône vient du jeu (16 px) et hérite de la couleur du libellé
|
|
617
|
+
'L’icône vient du jeu (16 px) et hérite de la couleur du libellé : en prop, jamais recopiée à la main. « carre » est l’action à icône SEULE : aria-label OBLIGATOIRE, écrit pour l’ACTION. Ne pas confondre avec IconButton (chrome nu, 40 px) ni ChromeButton (croix bordée) : le carré est une action, il en a le poids.',
|
|
618
618
|
code: `<Button icone="telecharger">Télécharger le rapport</Button>
|
|
619
619
|
<Button variante="fantome" iconeApres="chevron-droit">Étape suivante</Button>
|
|
620
620
|
<Button carre variante="encre" icone="envoyer" aria-label="Envoyer le message" />`,
|
|
@@ -696,7 +696,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
696
696
|
id: 'select',
|
|
697
697
|
nom: 'Sélection',
|
|
698
698
|
resume:
|
|
699
|
-
'Liste DESSINÉE jusqu’au bout
|
|
699
|
+
'Liste DESSINÉE jusqu’au bout : c’est le motif par défaut depuis le 25/08. Le <select> natif ne peut pas être habillé : sa liste est peinte par le système, et sort en menu noir sur un macOS en mode sombre. Clavier, annonce et recherche à la frappe sont réimplémentés ici.',
|
|
700
700
|
code: `<Field label="RÔLE" htmlFor="role">
|
|
701
701
|
<SelectMenu id="role" valeur={role} onChange={setRole} options={[
|
|
702
702
|
{ valeur: 'admin', label: 'Administrateur' },
|
|
@@ -742,7 +742,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
742
742
|
id: 'recherche',
|
|
743
743
|
nom: 'Recherche',
|
|
744
744
|
resume:
|
|
745
|
-
'Cadre + loupe + champ nu. Deux marquages au clavier (l’anneau du champ ET le filet du cadre) :
|
|
745
|
+
'Cadre + loupe + champ nu. Deux marquages au clavier (l’anneau du champ ET le filet du cadre) : assumé, supprimer l’un rend le champ invisible, l’autre prive la souris de retour.',
|
|
746
746
|
code: `<Search placeholder="Rechercher un document…" />`,
|
|
747
747
|
rendu: (
|
|
748
748
|
<div style={{ maxWidth: 380 }}>
|
|
@@ -822,7 +822,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
822
822
|
id: 'curseur',
|
|
823
823
|
nom: 'Curseur',
|
|
824
824
|
resume:
|
|
825
|
-
'Natif habillé : clavier, bornes et annonce viennent du navigateur ; le remplissage suit la valeur en contrôlé. Toujours un intitulé ET la valeur affichée en clair
|
|
825
|
+
'Natif habillé : clavier, bornes et annonce viennent du navigateur ; le remplissage suit la valeur en contrôlé. Toujours un intitulé ET la valeur affichée en clair : un curseur seul ne dit ni ce qu’il règle, ni sur combien. Pas de spectre sur la piste : ce n’est pas une barre de progression.',
|
|
826
826
|
code: `<Field label="SOURCES INTERROGÉES" htmlFor="prof" help={\`\${sources} sources sur 17\`}>
|
|
827
827
|
<Range id="prof" min={1} max={17} value={sources} onChange={…} />
|
|
828
828
|
</Field>`,
|
|
@@ -852,7 +852,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
852
852
|
id: 'mot-de-passe',
|
|
853
853
|
nom: 'Mot de passe',
|
|
854
854
|
resume:
|
|
855
|
-
'Le seul champ où l’on tape sans voir ce qu’on écrit : sur un mot de passe long saisi au clavier d’un téléphone, la bascule évite l’échec silencieux. L’état est tenu par l’appelant, et le libellé du bouton change
|
|
855
|
+
'Le seul champ où l’on tape sans voir ce qu’on écrit : sur un mot de passe long saisi au clavier d’un téléphone, la bascule évite l’échec silencieux. L’état est tenu par l’appelant, et le libellé du bouton change : une icône seule ne dit pas ce qui va se passer.',
|
|
856
856
|
code: `const [visible, setVisible] = useState(false)
|
|
857
857
|
|
|
858
858
|
<Field label="MOT DE PASSE" htmlFor="mdp">
|
|
@@ -871,7 +871,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
871
871
|
couche: 'applicatif',
|
|
872
872
|
css: 'feedback.css',
|
|
873
873
|
resume:
|
|
874
|
-
"Rien n'y crie : le bandeau porte le ton, la pastille l'état, la phrase le travail. La roue, le squelette et l'infobulle
|
|
874
|
+
"Rien n'y crie : le bandeau porte le ton, la pastille l'état, la phrase le travail. La roue, le squelette et l'infobulle, longtemps refusés faute de relevé, sont arbitrés depuis le 25/08/2026 (DECISIONS.md), chacun avec son périmètre écrit ; « Loading », qui nomme ce qu'on attend, reste le motif d'attente par défaut.",
|
|
875
875
|
exemples: [
|
|
876
876
|
{
|
|
877
877
|
id: 'alertes',
|
|
@@ -968,7 +968,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
968
968
|
id: 'roue',
|
|
969
969
|
nom: 'Roue',
|
|
970
970
|
resume:
|
|
971
|
-
'Attente COURTE et LOCALE : un bouton, une cellule, un panneau sans la place d’une phrase. Pour l’attente d’un écran, « Loading » reste le motif
|
|
971
|
+
'Attente COURTE et LOCALE : un bouton, une cellule, un panneau sans la place d’une phrase. Pour l’attente d’un écran, « Loading » reste le motif : la phrase dit sur quoi et sur combien. Sans label, la roue est décorative et masquée aux lecteurs d’écran.',
|
|
972
972
|
code: `<Spinner label="Vérification du dépôt…" />
|
|
973
973
|
<Spinner grand />`,
|
|
974
974
|
rendu: (
|
|
@@ -982,7 +982,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
982
982
|
id: 'squelette',
|
|
983
983
|
nom: 'Squelette',
|
|
984
984
|
resume:
|
|
985
|
-
'Il ANNONCE une structure connue
|
|
985
|
+
'Il ANNONCE une structure connue : la carte, la ligne qui va venir ; pour un contenu de forme inconnue, c’est « Loading ». La géométrie vient de l’appelant : un squelette qui invente ses dimensions ne ressemble jamais au contenu. C’est la zone qui charge qui porte aria-busy, pas chaque os.',
|
|
986
986
|
code: `<div aria-busy="true">
|
|
987
987
|
<Skeleton texte largeur="60%" />
|
|
988
988
|
<Skeleton texte />
|
|
@@ -1000,7 +1000,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1000
1000
|
id: 'infobulle',
|
|
1001
1001
|
nom: 'Infobulle',
|
|
1002
1002
|
resume:
|
|
1003
|
-
'Un COMPLÉMENT dispensable
|
|
1003
|
+
'Un COMPLÉMENT dispensable, un raccourci, une date exacte, une unité : une commande n’a pas le droit d’y cacher son nom, et le tactile ne survole pas. Liage aria-describedby EXPLICITE (id), comme le htmlFor de Field : pas de useId, le rendu serveur reste possible. Apparition retardée de 300 ms, disparition immédiate, Échap la ferme.',
|
|
1004
1004
|
code: `<Tooltip id="th-date" contenu="Déposé le 12/08/2026 à 14 h 02">
|
|
1005
1005
|
<Button variante="fantome" compact aria-describedby="th-date">12 août</Button>
|
|
1006
1006
|
</Tooltip>`,
|
|
@@ -1029,7 +1029,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1029
1029
|
id: 'page-erreur',
|
|
1030
1030
|
nom: 'Page d’erreur',
|
|
1031
1031
|
resume:
|
|
1032
|
-
'404, 403, 410, 500. ⚠️ Le glyphe est DÉCORATIF par défaut (glypheAlt=""), et le mot « Erreur » se passe en prop : la 0.32.0 posait alt="Zevra" et « Erreur » en dur, si bien que la 404 de Mémoire annonçait « Zevra » au lecteur d’écran et affichait « Erreur 404 » sous /en/. Le composant ne porte AUCUN texte : une plaisanterie câblée dans un design system part dans les sept apps, dans une seule langue, et n’en revient jamais. La copie ci-dessous est la RÉFÉRENCE, à copier et à adapter. Elle plaisante en vocabulaire juridique
|
|
1032
|
+
'404, 403, 410, 500. ⚠️ Le glyphe est DÉCORATIF par défaut (glypheAlt=""), et le mot « Erreur » se passe en prop : la 0.32.0 posait alt="Zevra" et « Erreur » en dur, si bien que la 404 de Mémoire annonçait « Zevra » au lecteur d’écran et affichait « Erreur 404 » sous /en/. Le composant ne porte AUCUN texte : une plaisanterie câblée dans un design system part dans les sept apps, dans une seule langue, et n’en revient jamais. La copie ci-dessous est la RÉFÉRENCE, à copier et à adapter. Elle plaisante en vocabulaire juridique (un mot juste employé de travers, pas une blague sur un ton qu’Encre & Papier n’a pas) et l’ordre est fixe : le titre dit la panne en clair, l’esprit vient ensuite et se dédit lui-même. Une page d’erreur qui fait rire avant d’informer est ratée.',
|
|
1033
1033
|
code: `<PageErreur
|
|
1034
1034
|
code="404"
|
|
1035
1035
|
libelle="Erreur" {/* le mot est À VOUS : « Error » sous /en/ */}
|
|
@@ -1157,7 +1157,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1157
1157
|
id: 'preuve',
|
|
1158
1158
|
nom: 'Aperçu d’interface',
|
|
1159
1159
|
resume:
|
|
1160
|
-
'⚠️ RÈGLE DE CHARTE : toujours de VRAIES données réalistes, jamais de lorem
|
|
1160
|
+
'⚠️ RÈGLE DE CHARTE : toujours de VRAIES données réalistes, jamais de lorem, c’est ce bloc qui porte la crédibilité de la page.',
|
|
1161
1161
|
code: `<UiPreview question="Quelle est la durée de préavis ?"
|
|
1162
1162
|
sources="12 sources" puces={<SrcRow>…</SrcRow>}>
|
|
1163
1163
|
Trois mois pour les cadres…
|
|
@@ -1260,7 +1260,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1260
1260
|
id: 'page-legale',
|
|
1261
1261
|
nom: 'Page légale',
|
|
1262
1262
|
resume:
|
|
1263
|
-
'La FORME d’un document contractuel ; le TEXTE vit dans @zevra/legal, versionné et archivé
|
|
1263
|
+
'La FORME d’un document contractuel ; le TEXTE vit dans @zevra/legal, versionné et archivé : le design system ne dépend pas du contenu, sinon corriger une clause deviendrait une livraison de charte. La version est AFFICHÉE : c’est ce que l’utilisateur cite quand il conteste. ⚠️ Jamais de « voir plus » sur un contrat : ce qu’on accepte se lit en entier là où on l’accepte. Le sommaire se pose à côté, avec « Rail ».',
|
|
1264
1264
|
code: `import { enVigueur } from '@zevra/legal'
|
|
1265
1265
|
|
|
1266
1266
|
<LegalPage document={enVigueur('mentions-legales')} />`,
|
|
@@ -1306,12 +1306,12 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1306
1306
|
id: 'citation',
|
|
1307
1307
|
nom: 'Citation client',
|
|
1308
1308
|
resume:
|
|
1309
|
-
'⚠️ RÈGLE DE CHARTE : jamais de fausse citation. Tant qu’un verbatim n’a pas été recueilli, ce bloc reste EN RÉSERVE
|
|
1310
|
-
code: `<Band><Quote auteur="
|
|
1309
|
+
'⚠️ RÈGLE DE CHARTE : jamais de fausse citation. Tant qu’un verbatim n’a pas été recueilli, ce bloc reste EN RÉSERVE : un placeholder crédible finit toujours par partir en production.',
|
|
1310
|
+
code: `<Band><Quote auteur=": Nom, cabinet">Verbatim réel uniquement.</Quote></Band>`,
|
|
1311
1311
|
surSombre: true,
|
|
1312
1312
|
rendu: (
|
|
1313
1313
|
<Band>
|
|
1314
|
-
<Quote auteur="
|
|
1314
|
+
<Quote auteur=": en attente d’un verbatim recueilli">
|
|
1315
1315
|
Ce bloc reste en réserve tant qu’aucune citation réelle n’a été
|
|
1316
1316
|
recueillie.
|
|
1317
1317
|
</Quote>
|
|
@@ -1375,7 +1375,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1375
1375
|
id: 'tableau-prose',
|
|
1376
1376
|
nom: 'Tableau de prose',
|
|
1377
1377
|
resume:
|
|
1378
|
-
'Les cellules reviennent à la ligne au lieu de tronquer. ⚠️ Dès qu’une cellule porte une PHRASE et non une donnée
|
|
1378
|
+
'Les cellules reviennent à la ligne au lieu de tronquer. ⚠️ Dès qu’une cellule porte une PHRASE et non une donnée (une clause, un fondement juridique, une durée et son motif), tronquer ne raccourcit pas : ça cache, et le lecteur n’a aucun moyen de savoir qu’il manque quelque chose. La troncature reste juste pour une ligne de données, qui se balaye du regard.',
|
|
1379
1379
|
code: `<Table prose gabarit="minmax(0,1fr) minmax(0,2fr)">
|
|
1380
1380
|
<TableHead><Cell>Donnée</Cell><Cell>Durée et fondement</Cell></TableHead>
|
|
1381
1381
|
<Row>
|
|
@@ -1466,7 +1466,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1466
1466
|
id: 'meta',
|
|
1467
1467
|
nom: 'Métadonnées',
|
|
1468
1468
|
resume:
|
|
1469
|
-
'Second registre mono, en BAS DE CASSE : taille, date, latence. Ni capitales ni interlettrage
|
|
1469
|
+
'Second registre mono, en BAS DE CASSE : taille, date, latence. Ni capitales ni interlettrage : c’est ce qui le distingue de « Mono », et une date en capitales espacées devient illisible.',
|
|
1470
1470
|
code: `<MetaRow><Meta>12 mars 2026</Meta><Meta taille="sm">1,2 s</Meta></MetaRow>`,
|
|
1471
1471
|
rendu: (
|
|
1472
1472
|
<MetaRow>
|
|
@@ -1500,7 +1500,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1500
1500
|
id: 'avatar-chip',
|
|
1501
1501
|
nom: 'Pastilles et catégories',
|
|
1502
1502
|
resume:
|
|
1503
|
-
'Avatar CARRÉ, jamais rond : le rond est un usage de réseau social. ⚠️ Sa teinte dit la NATURE de l’entité
|
|
1503
|
+
'Avatar CARRÉ, jamais rond : le rond est un usage de réseau social. ⚠️ Sa teinte dit la NATURE de l’entité : la changer, c’est changer le sens.',
|
|
1504
1504
|
code: `<Avatar ton="accent">MD</Avatar>
|
|
1505
1505
|
<ChipRow><Chip>Droit social</Chip><Chip variante="outline">2024</Chip></ChipRow>`,
|
|
1506
1506
|
rendu: (
|
|
@@ -1552,7 +1552,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1552
1552
|
id: 'depliant',
|
|
1553
1553
|
nom: 'Rangée dépliante',
|
|
1554
1554
|
resume:
|
|
1555
|
-
'<details> NATIF : clavier, annonce et état viennent du navigateur, aucun JavaScript. Le pliage APPLICATIF
|
|
1555
|
+
'<details> NATIF : clavier, annonce et état viennent du navigateur, aucun JavaScript. Le pliage APPLICATIF : options avancées, détail d’une ligne de journal ; la FAQ (contenu) reste celui de la vitrine. Plusieurs rangées se posent bord à bord, le filet mitoyen tombe seul.',
|
|
1556
1556
|
code: `<Fold titre="Options avancées">…</Fold>
|
|
1557
1557
|
<Fold titre="Journal d'indexation" ouvert>…</Fold>`,
|
|
1558
1558
|
rendu: (
|
|
@@ -1572,7 +1572,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1572
1572
|
id: 'code',
|
|
1573
1573
|
nom: 'Code et raccourcis',
|
|
1574
1574
|
resume:
|
|
1575
|
-
'La chasse fixe RÉELLE (--font-code) : --font-mono est proportionnelle et n’aligne pas du code, tabular-nums n’aligne que les chiffres. Aucune coloration syntaxique
|
|
1575
|
+
'La chasse fixe RÉELLE (--font-code) : --font-mono est proportionnelle et n’aligne pas du code, tabular-nums n’aligne que les chiffres. Aucune coloration syntaxique : elle imposerait une palette que la charte n’a pas. « ⌘K » fait DEUX touches, donc deux Kbd.',
|
|
1576
1576
|
code: `<Body>Lancer <Code>pnpm build</Code>, puis <Kbd>⌘</Kbd> <Kbd>K</Kbd>.</Body>
|
|
1577
1577
|
<CodeBlock>claude mcp add --transport http zevra-design …</CodeBlock>`,
|
|
1578
1578
|
rendu: (
|
|
@@ -1596,13 +1596,13 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1596
1596
|
couche: 'applicatif',
|
|
1597
1597
|
css: 'navigation.css',
|
|
1598
1598
|
resume:
|
|
1599
|
-
"Rien n'a d'état propre : l'entrée courante, la page courante et l'item sélectionné viennent de l'appelant
|
|
1599
|
+
"Rien n'a d'état propre : l'entrée courante, la page courante et l'item sélectionné viennent de l'appelant, c'est ce qui permet à une colonne de navigation Next de rester rendue au serveur.",
|
|
1600
1600
|
exemples: [
|
|
1601
1601
|
{
|
|
1602
1602
|
id: 'sidebar',
|
|
1603
1603
|
nom: 'Colonne latérale',
|
|
1604
1604
|
resume:
|
|
1605
|
-
'Une colonne, un filet, rien d’autre. « courant » pose aria-current="page" en plus de la classe : sans lui, l’entrée courante est marquée pour l’œil et muette au lecteur d’écran. « num » accepte un rang mono OU un glyphe (le ⚙ du relevé), sur la même colonne de 16 px
|
|
1605
|
+
'Une colonne, un filet, rien d’autre. « courant » pose aria-current="page" en plus de la classe : sans lui, l’entrée courante est marquée pour l’œil et muette au lecteur d’écran. « num » accepte un rang mono OU un glyphe (le ⚙ du relevé), sur la même colonne de 16 px : jamais les deux.',
|
|
1606
1606
|
code: `<Sidebar>
|
|
1607
1607
|
<SidebarHead>…</SidebarHead>
|
|
1608
1608
|
<SideGroup titre="Espace">
|
|
@@ -1644,7 +1644,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1644
1644
|
id: 'topbar',
|
|
1645
1645
|
nom: 'Barre supérieure',
|
|
1646
1646
|
resume:
|
|
1647
|
-
'⚠️ Elle REMPLACE la colonne sous le point de rupture : masquée au-dessus, elle n’apparaît que dans le bloc mobile du CSS. Ne jamais la conditionner en JavaScript
|
|
1647
|
+
'⚠️ Elle REMPLACE la colonne sous le point de rupture : masquée au-dessus, elle n’apparaît que dans le bloc mobile du CSS. Ne jamais la conditionner en JavaScript : le serveur ne connaît pas la largeur de l’écran.',
|
|
1648
1648
|
code: `<Topbar>
|
|
1649
1649
|
<TopbarBurger aria-label="Ouvrir la navigation">☰</TopbarBurger>
|
|
1650
1650
|
<TopbarLogo><img src="/logo.svg" alt="" /></TopbarLogo>
|
|
@@ -1660,7 +1660,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1660
1660
|
id: 'crumbs',
|
|
1661
1661
|
nom: 'Fil d’Ariane',
|
|
1662
1662
|
resume:
|
|
1663
|
-
'⚠️ Le fil ENTIER est cliquable
|
|
1663
|
+
'⚠️ Le fil ENTIER est cliquable : c’est un seul nœud, pas une liste de liens. Le DERNIER segment est plus sombre : c’est celui qu’on lit, le reste n’est qu’un chemin.',
|
|
1664
1664
|
code: `<Crumbs href="/dossiers/2024" segments={['Dossiers', '2024', 'Duflot']} />`,
|
|
1665
1665
|
rendu: <Crumbs href="#" segments={['Dossiers', '2024', 'Duflot & Associés']} />,
|
|
1666
1666
|
},
|
|
@@ -1668,7 +1668,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1668
1668
|
id: 'onglets',
|
|
1669
1669
|
nom: 'Onglets en puces',
|
|
1670
1670
|
resume:
|
|
1671
|
-
'La rangée de puces, grammaire d’état de Seg
|
|
1671
|
+
'La rangée de puces, grammaire d’état de Seg : le motif des FILTRES, qui restreignent une collection. Ce composant n’ajoute que l’ARIA. Pour les VUES d’un même objet, prendre la variante soulignée.',
|
|
1672
1672
|
code: `<Tabs actif={actif} onChange={setActif} onglets={[
|
|
1673
1673
|
{ id: 'apercu', label: 'Aperçu' },
|
|
1674
1674
|
{ id: 'sources', label: 'Sources', compte: 12 },
|
|
@@ -1679,7 +1679,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1679
1679
|
id: 'onglets-soulignes',
|
|
1680
1680
|
nom: 'Onglets soulignés',
|
|
1681
1681
|
resume:
|
|
1682
|
-
'L’arbitrage longtemps en attente, tranché le 25/08/2026 : trait actif de 2 px
|
|
1682
|
+
'L’arbitrage longtemps en attente, tranché le 25/08/2026 : trait actif de 2 px, l’épaisseur des filets dessinés du système, en accent, PAS en spectre (un quatrième emploi n’existe pas). Pour les VUES d’un même objet (Aperçu / Sources) ; pour filtrer, les puces.',
|
|
1683
1683
|
code: `<Tabs variante="soulignes" actif={actif} onChange={setActif} onglets={[
|
|
1684
1684
|
{ id: 'apercu', label: 'Aperçu' },
|
|
1685
1685
|
{ id: 'sources', label: 'Sources', compte: 12 },
|
|
@@ -1690,7 +1690,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1690
1690
|
id: 'popover',
|
|
1691
1691
|
nom: 'Popover',
|
|
1692
1692
|
resume:
|
|
1693
|
-
'Surface ancrée LIBRE
|
|
1693
|
+
'Surface ancrée LIBRE (aide contextuelle, mini-formulaire de filtre) dans la même ancre que le menu (SelectAnchor). Ce n’est PAS une infobulle : le popover s’ouvre au CLIC et peut porter de l’interactif. Fermeture par clic extérieur et Échap : à l’appelant, comme pour le menu.',
|
|
1694
1694
|
code: `<SelectAnchor>
|
|
1695
1695
|
<Button variante="fantome" compact aria-expanded={ouvert} onClick={…}>Colonnes affichées</Button>
|
|
1696
1696
|
{ouvert && <Popover>…</Popover>}
|
|
@@ -1776,7 +1776,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1776
1776
|
couche: 'commun',
|
|
1777
1777
|
css: 'overlays.css',
|
|
1778
1778
|
resume:
|
|
1779
|
-
"Le seul module marqué « use client ». Tout ce qui vit ici vole le regard à la page : il faut Échap, un piège de focus et un verrou de défilement
|
|
1779
|
+
"Le seul module marqué « use client ». Tout ce qui vit ici vole le regard à la page : il faut Échap, un piège de focus et un verrou de défilement, rien de cela ne s'écrit en CSS. Le hook « useOverlay » est exporté pour les enrobages maison.",
|
|
1780
1780
|
exemples: [
|
|
1781
1781
|
{
|
|
1782
1782
|
id: 'tiroir',
|
|
@@ -1793,7 +1793,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1793
1793
|
id: 'modale',
|
|
1794
1794
|
nom: 'Modale',
|
|
1795
1795
|
resume:
|
|
1796
|
-
'Fermée, elle n’est pas rendue du tout : son contenu
|
|
1796
|
+
'Fermée, elle n’est pas rendue du tout : son contenu (un formulaire, le plus souvent) ne doit pas rester dans le DOM à l’état fantôme. « danger » met l’avertissement dans le filet HAUT, pas dans un fond rouge qui rendrait le texte pénible à lire.',
|
|
1797
1797
|
code: `<Modal ouvert={ouvert} onClose={…} titre="Supprimer" danger
|
|
1798
1798
|
pied={<ButtonRow>…</ButtonRow>}>
|
|
1799
1799
|
…
|
|
@@ -1804,7 +1804,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1804
1804
|
id: 'toast',
|
|
1805
1805
|
nom: 'Notification',
|
|
1806
1806
|
resume:
|
|
1807
|
-
'⚠️ Ne remplace PAS « Alert » : une erreur de formulaire se dit à côté du champ, jamais dans un coin qui disparaît. Réserver à ce qui est vrai APRÈS COUP
|
|
1807
|
+
'⚠️ Ne remplace PAS « Alert » : une erreur de formulaire se dit à côté du champ, jamais dans un coin qui disparaît. Réserver à ce qui est vrai APRÈS COUP : « copié », « enregistré », « envoyé ».',
|
|
1808
1808
|
code: `<Toasts>
|
|
1809
1809
|
<Toast ton="ok">Lien copié.</Toast>
|
|
1810
1810
|
</Toasts>`,
|
|
@@ -1825,13 +1825,13 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1825
1825
|
couche: 'commun',
|
|
1826
1826
|
css: 'icons.css',
|
|
1827
1827
|
resume:
|
|
1828
|
-
"55 icônes TRACÉES, jamais pleines : trait 2, grille de 24, BOUTS FRANCS et jonctions vives
|
|
1828
|
+
"55 icônes TRACÉES, jamais pleines : trait 2, grille de 24, BOUTS FRANCS et jonctions vives, le trait carré de la charte, points d'encre carrés compris. Elles héritent de la couleur du texte : c'est ce qui leur permet de fonctionner sur papier comme sur la bande manifeste sans déclinaison. Le tracé est inliné : rien à résoudre côté bundler, rien à autoriser côté CSP.",
|
|
1829
1829
|
exemples: [
|
|
1830
1830
|
{
|
|
1831
1831
|
id: 'jeu',
|
|
1832
1832
|
nom: 'Le jeu complet',
|
|
1833
1833
|
resume:
|
|
1834
|
-
'Sans « titre », l’icône est DÉCORATIVE et masquée aux lecteurs d’écran
|
|
1834
|
+
'Sans « titre », l’icône est DÉCORATIVE et masquée aux lecteurs d’écran, le bon défaut : accolée à un libellé qui la répète, elle crée une annonce double.',
|
|
1835
1835
|
code: `<Icon nom="recherche" />
|
|
1836
1836
|
<Icon nom="document" taille="lg" />
|
|
1837
1837
|
<Icon nom="alerte" titre="Alerte" />`,
|
|
@@ -1873,7 +1873,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1873
1873
|
id: 'tuile',
|
|
1874
1874
|
nom: 'Tuile d’icône',
|
|
1875
1875
|
resume:
|
|
1876
|
-
'La pastille carrée devant un argument de la vitrine
|
|
1876
|
+
'La pastille carrée devant un argument de la vitrine : liste de garanties, grille d’atouts. DÉCORATIVE par défaut : c’est le libellé voisin qui nomme, un titre ne se pose que si elle est seule. UNE par argument, jamais en décor isolé : une tuile sans libellé est un rébus.',
|
|
1877
1877
|
code: `<IconTile nom="bouclier-verifie" />
|
|
1878
1878
|
<IconTile nom="balance" />`,
|
|
1879
1879
|
rendu: (
|
|
@@ -1881,7 +1881,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1881
1881
|
{(
|
|
1882
1882
|
[
|
|
1883
1883
|
['bouclier-verifie', 'Hébergement souverain', 'Infrastructure dédiée, en France.'],
|
|
1884
|
-
['balance', 'Sources officielles', 'BOSS, Judilibre, KALI
|
|
1884
|
+
['balance', 'Sources officielles', 'BOSS, Judilibre, KALI : datées et citées.'],
|
|
1885
1885
|
['cadenas', 'Zéro réutilisation', 'Vos pièces n’entraînent aucun modèle.'],
|
|
1886
1886
|
] as const
|
|
1887
1887
|
).map(([nom, titre, texte]) => (
|
|
@@ -1905,13 +1905,13 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1905
1905
|
couche: 'vitrine',
|
|
1906
1906
|
css: 'components.css',
|
|
1907
1907
|
resume:
|
|
1908
|
-
"Quatre façons de poser du contenu SANS carte. Ils existent pour une règle de composition de la DA (24/08/2026) : jamais deux blocs de même forme qui se suivent, 80 % de formes différentes par page
|
|
1908
|
+
"Quatre façons de poser du contenu SANS carte. Ils existent pour une règle de composition de la DA (24/08/2026) : jamais deux blocs de même forme qui se suivent, 80 % de formes différentes par page, les grilles de cartes redeviennent un choix, pas un réflexe.",
|
|
1909
1909
|
exemples: [
|
|
1910
1910
|
{
|
|
1911
1911
|
id: 'rows',
|
|
1912
1912
|
nom: 'Rangées à filets',
|
|
1913
1913
|
resume:
|
|
1914
|
-
'Libellé fort + contenu, un trait fin entre chaque rangée. Pour les listes où l’ALIGNEMENT fait la lecture (profils rencontrés, prestations, caractéristiques)
|
|
1914
|
+
'Libellé fort + contenu, un trait fin entre chaque rangée. Pour les listes où l’ALIGNEMENT fait la lecture (profils rencontrés, prestations, caractéristiques) : là où des cartes casseraient la comparaison.',
|
|
1915
1915
|
code: `<Rows>
|
|
1916
1916
|
<RowsItem cle="Directions juridiques">Structurer la connaissance interne…</RowsItem>
|
|
1917
1917
|
<RowsItem cle="Cabinets d’avocats">Retrouver la jurisprudence du cabinet…</RowsItem>
|
|
@@ -1953,7 +1953,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1953
1953
|
<IndexItem num="02">
|
|
1954
1954
|
<CardTitle>Indexation</CardTitle>
|
|
1955
1955
|
<Body taille="dense">
|
|
1956
|
-
Le corpus est océrisé, anonymisé et indexé
|
|
1956
|
+
Le corpus est océrisé, anonymisé et indexé : comptez une semaine pour
|
|
1957
1957
|
10 000 pièces.
|
|
1958
1958
|
</Body>
|
|
1959
1959
|
</IndexItem>
|
|
@@ -1964,7 +1964,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1964
1964
|
id: 'flow',
|
|
1965
1965
|
nom: 'Déroulé vertical',
|
|
1966
1966
|
resume:
|
|
1967
|
-
'La déclinaison verticale de « Steps », pour les méthodes qui se lisent comme un récit. Les points reprennent les couleurs des points de méthode
|
|
1967
|
+
'La déclinaison verticale de « Steps », pour les méthodes qui se lisent comme un récit. Les points reprennent les couleurs des points de méthode : l’un des trois emplois autorisés du spectre.',
|
|
1968
1968
|
code: `<Flow>
|
|
1969
1969
|
<FlowStep><CardTitle>Déposer</CardTitle>…</FlowStep>
|
|
1970
1970
|
<FlowStep teinte="violet"><CardTitle>Interroger</CardTitle>…</FlowStep>
|
|
@@ -1991,7 +1991,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
1991
1991
|
id: 'callout',
|
|
1992
1992
|
nom: 'Encart d’appel',
|
|
1993
1993
|
resume:
|
|
1994
|
-
'Une bande sur accent-soft, un titre, une action : l’offre transverse qui doit se voir sans crier (remise, renvoi vers une autre page). L’action passe en enfant
|
|
1994
|
+
'Une bande sur accent-soft, un titre, une action : l’offre transverse qui doit se voir sans crier (remise, renvoi vers une autre page). L’action passe en enfant : elle se range à droite et tombe sous le titre sur mobile.',
|
|
1995
1995
|
code: `<Callout titre="Formation Campus incluse la première année">
|
|
1996
1996
|
<ButtonLink href="/campus" variante="fantome">Découvrir Campus</ButtonLink>
|
|
1997
1997
|
</Callout>`,
|
|
@@ -2034,7 +2034,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
2034
2034
|
id: 'grille',
|
|
2035
2035
|
nom: 'Grilles',
|
|
2036
2036
|
resume:
|
|
2037
|
-
'⚠️ Seules les portées 3, 4, 6, 8 et 9 existent : ce sont les découpes employées par la vitrine. En ajouter une revient à ajouter une mise en page
|
|
2037
|
+
'⚠️ Seules les portées 3, 4, 6, 8 et 9 existent : ce sont les découpes employées par la vitrine. En ajouter une revient à ajouter une mise en page : c’est une décision de DA, pas une utilité.',
|
|
2038
2038
|
code: `<Grid12>
|
|
2039
2039
|
<Col span={8}>…</Col>
|
|
2040
2040
|
<Col span={4}>…</Col>
|
|
@@ -2069,7 +2069,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
2069
2069
|
id: 'sections',
|
|
2070
2070
|
nom: 'Sections',
|
|
2071
2071
|
resume:
|
|
2072
|
-
'Le bloc « aside » tombe SOUS le titre en dessous du point de rupture
|
|
2072
|
+
'Le bloc « aside » tombe SOUS le titre en dessous du point de rupture : c’est le CSS qui le fait, pas une condition de rendu.',
|
|
2073
2073
|
code: `<SectionHead aside={<LinkArrow href="/methode">Tout voir</LinkArrow>}>
|
|
2074
2074
|
<Kicker>Méthode</Kicker>
|
|
2075
2075
|
<H2>Trois étapes, rien de plus</H2>
|
|
@@ -2088,7 +2088,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
2088
2088
|
{
|
|
2089
2089
|
id: 'sheet-section',
|
|
2090
2090
|
nom: 'Section de document',
|
|
2091
|
-
resume: 'Un intitulé mono, un filet, du corps
|
|
2091
|
+
resume: 'Un intitulé mono, un filet, du corps : pour un document long.',
|
|
2092
2092
|
code: `<SheetSection titre="ENGAGEMENTS">…</SheetSection>`,
|
|
2093
2093
|
rendu: (
|
|
2094
2094
|
<SheetSection titre="ENGAGEMENTS">
|
|
@@ -2103,7 +2103,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
2103
2103
|
id: 'nav-vitrine',
|
|
2104
2104
|
nom: 'Navigation',
|
|
2105
2105
|
resume:
|
|
2106
|
-
'LA barre du site, dans ses deux états
|
|
2106
|
+
'LA barre du site, dans ses deux états, c’est le design de landing.zevra.tech, et il fait référence : une app qui compose sa propre barre finit par ne plus ressembler aux autres. Deux zones, et la distinction n’est pas cosmétique : « NavLinks » porte ce qui TOMBE dans le tiroir sous le point de rupture (familles, langues, appel à l’action) ; « NavActions » porte ce qui RESTE à toutes les largeurs, lanceur, compte, burger. Un compte placé dans NavLinks s’évanouit sur téléphone, et l’on ne peut plus se connecter. ⚠️ Le lanceur ET le compte sont là dans les deux états : les produits sont publics, et une barre où l’on ne peut pas se connecter est une barre où l’on ne revient pas. Seul le contenu du compte change. Survoler une famille, le lanceur ou la pastille pour déplier : c’est du CSS, il n’y a rien à hydrater. « zv-nav--riche » bascule vers le tiroir à 1150px, où une barre de cette densité déborde (mesuré), et non à 768.',
|
|
2107
2107
|
code: `<Nav className="zv-nav--riche">
|
|
2108
2108
|
<NavLogo>
|
|
2109
2109
|
<Lockup capitale={15}>
|
|
@@ -2135,7 +2135,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
2135
2135
|
{/* APPS = les produits QUI ONT UNE ADRESSE, pas les sept glyphes :
|
|
2136
2136
|
une tuile qui mène à rien promet un produit et fait tomber le
|
|
2137
2137
|
visiteur. Plume et Supernovia y entreront le jour où ils ouvrent,
|
|
2138
|
-
par une ligne dans logos/index.json
|
|
2138
|
+
par une ligne dans logos/index.json : sans toucher aux apps. */}
|
|
2139
2139
|
<Lanceur> {/* titre="Applications" par défaut, filet de spectre */}
|
|
2140
2140
|
<LanceurGroupe>Suite Zevra</LanceurGroupe>
|
|
2141
2141
|
<LanceurApps>
|
|
@@ -2159,7 +2159,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
2159
2159
|
id: 'lockup',
|
|
2160
2160
|
nom: 'Lockup',
|
|
2161
2161
|
resume:
|
|
2162
|
-
'La marque et le mot. Tout se pilote par « capitale », qui EST la hauteur de capitale : la marque vaut 2,86 fois cette valeur et l’écart 0,64, proportions relevées au pixel sur l’original. Sous 11 px, poser « marqueSeule »
|
|
2162
|
+
'La marque et le mot. Tout se pilote par « capitale », qui EST la hauteur de capitale : la marque vaut 2,86 fois cette valeur et l’écart 0,64, proportions relevées au pixel sur l’original. Sous 11 px, poser « marqueSeule » : le mot ne se lit plus, quelle que soit sa netteté, et c’est la marque qui identifie.',
|
|
2163
2163
|
code: `<Lockup capitale={15}>
|
|
2164
2164
|
<LockupMark src={GLYPHES.zevra} />
|
|
2165
2165
|
<LockupWord src={MOT_ZEVRA} alt="Zevra" />
|
|
@@ -2175,7 +2175,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
2175
2175
|
id: 'tiroir-groupe',
|
|
2176
2176
|
nom: 'Tiroir groupé',
|
|
2177
2177
|
resume:
|
|
2178
|
-
'Quand la barre porte des familles, les aplatir en une liste unique rend le tiroir illisible : un label capitale par famille, ses entrées en dessous. Le sélecteur de langue s’y pose en pied, détaché par un filet. L’ouverture et la fermeture viennent de « @zevra/ui/nav.js »
|
|
2178
|
+
'Quand la barre porte des familles, les aplatir en une liste unique rend le tiroir illisible : un label capitale par famille, ses entrées en dessous. Le sélecteur de langue s’y pose en pied, détaché par un filet. L’ouverture et la fermeture viennent de « @zevra/ui/nav.js » : le tiroir doit vivre EN DEHORS du chrome flouté, qui devient sinon son bloc conteneur.',
|
|
2179
2179
|
code: `<NavDrawer>
|
|
2180
2180
|
<NavDrawerGroup>Services</NavDrawerGroup>
|
|
2181
2181
|
<NavDrawerLink href="/audit" className="zv-nav-drawer__link--sous">Audit</NavDrawerLink>
|
|
@@ -2209,7 +2209,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
2209
2209
|
id: 'rail',
|
|
2210
2210
|
nom: 'Rail de lecture',
|
|
2211
2211
|
resume:
|
|
2212
|
-
'La table des matières d’une page longue, posée sur le côté. Elle NAVIGUE (chaque entrée est une ancre) et elle SUIT
|
|
2212
|
+
'La table des matières d’une page longue, posée sur le côté. Elle NAVIGUE (chaque entrée est une ancre) et elle SUIT : importer « @zevra/ui/rail.js » pour que l’entrée courante s’allume ; sans lui le rail navigue toujours, il ne suit plus. Le module lit la POSITION plutôt que d’observer les intersections : les ancres d’un rail sont souvent des points de 1 px en tête de section, qu’un défilement rapide fait manquer à un IntersectionObserver réduit à sa bande centrale. ⚠️ Il disparaît sous le point de rupture : un rail fixe sur un téléphone se pose sur la lecture.',
|
|
2213
2213
|
code: `<Rail aria-label="Sections">
|
|
2214
2214
|
<RailItem href="#intro" courant>Intro</RailItem>
|
|
2215
2215
|
<RailItem href="#methode">Méthode</RailItem>
|
|
@@ -2335,14 +2335,14 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
2335
2335
|
id: 'bandeau',
|
|
2336
2336
|
nom: 'Bandeau d’annonce',
|
|
2337
2337
|
resume:
|
|
2338
|
-
'La bande AU-DESSUS de la barre de navigation : annonce de version, information réglementaire. UN SEUL par page, et jamais pour du marketing permanent
|
|
2338
|
+
'La bande AU-DESSUS de la barre de navigation : annonce de version, information réglementaire. UN SEUL par page, et jamais pour du marketing permanent : un bandeau qui ne part pas devient un bourrelet de chrome. Le lien s’y souligne : sur un fond déjà indigo, la couleur seule ne le distingue plus.',
|
|
2339
2339
|
code: `<Banner>
|
|
2340
|
-
La charte évolue
|
|
2340
|
+
La charte évolue : le journal des livraisons est en ligne.{' '}
|
|
2341
2341
|
<a href="/journal">Ce qui change</a>
|
|
2342
2342
|
</Banner>`,
|
|
2343
2343
|
rendu: (
|
|
2344
2344
|
<Banner>
|
|
2345
|
-
La charte évolue
|
|
2345
|
+
La charte évolue : le journal des livraisons est en ligne.{' '}
|
|
2346
2346
|
<a href="#">Ce qui change</a>
|
|
2347
2347
|
</Banner>
|
|
2348
2348
|
),
|
|
@@ -2351,7 +2351,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
2351
2351
|
id: 'carrousel',
|
|
2352
2352
|
nom: 'Carrousel',
|
|
2353
2353
|
resume:
|
|
2354
|
-
'Défilement natif scroll-snap, AUCUN JavaScript : pas de flèches, pas de points ; le conteneur prend le focus, et son label est OBLIGATOIRE
|
|
2354
|
+
'Défilement natif scroll-snap, AUCUN JavaScript : pas de flèches, pas de points ; le conteneur prend le focus, et son label est OBLIGATOIRE, une région qui défile sans nom est une énigme au lecteur d’écran. Un carrousel reste un aveu d’espace : la règle de variété lui préfère une grille tant que le contenu tient.',
|
|
2355
2355
|
code: `<Carousel label="La suite Zevra">
|
|
2356
2356
|
<CarouselItem style={{ width: 260 }}>
|
|
2357
2357
|
<Card>…</Card>
|
|
@@ -2386,7 +2386,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
2386
2386
|
id: 'media',
|
|
2387
2387
|
nom: 'Cadre média',
|
|
2388
2388
|
resume:
|
|
2389
|
-
'Le rapport vit sur le CADRE, jamais sur l’image : posé sur un enfant de grille aligné au centre, il ne se résout pas et la colonne s’effondre à zéro. Le cadre ne charge ni ne décode rien
|
|
2389
|
+
'Le rapport vit sur le CADRE, jamais sur l’image : posé sur un enfant de grille aligné au centre, il ne se résout pas et la colonne s’effondre à zéro. Le cadre ne charge ni ne décode rien : pour masquer le temps de décodage, composer Spinner par-dessus.',
|
|
2390
2390
|
code: `<Media ratio="16-9">
|
|
2391
2391
|
<MediaImg src={couverture} alt="" />
|
|
2392
2392
|
<MediaVoile />
|
|
@@ -2416,13 +2416,13 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
2416
2416
|
couche: 'vitrine',
|
|
2417
2417
|
css: 'surfaces.css + motion.css',
|
|
2418
2418
|
resume:
|
|
2419
|
-
"Ce qui distingue une page Zevra d'une page blanche bien composée. ⚠️ Tout y est DÉCORATIF : posé en absolu derrière le contenu, sans capter le pointeur, masqué aux lecteurs d'écran
|
|
2419
|
+
"Ce qui distingue une page Zevra d'une page blanche bien composée. ⚠️ Tout y est DÉCORATIF : posé en absolu derrière le contenu, sans capter le pointeur, masqué aux lecteurs d'écran, et suppose un parent « position: relative; overflow: hidden ».",
|
|
2420
2420
|
exemples: [
|
|
2421
2421
|
{
|
|
2422
2422
|
id: 'bande',
|
|
2423
2423
|
nom: 'Bande manifeste',
|
|
2424
2424
|
resume:
|
|
2425
|
-
'⚠️ LA surface sombre du système. Les surfaces sombres se font avec elle et --accent-on-dark, JAMAIS en inversant les neutres. La bande ne porte AUCUNE gouttière propre : c’est la page qui la donne
|
|
2425
|
+
'⚠️ LA surface sombre du système. Les surfaces sombres se font avec elle et --accent-on-dark, JAMAIS en inversant les neutres. La bande ne porte AUCUNE gouttière propre : c’est la page qui la donne, poser un Gutter dedans, sinon le contenu colle au bord.',
|
|
2426
2426
|
code: `<Band lueur filigrane={<Glyph variante="watermark">…</Glyph>}>
|
|
2427
2427
|
<Gutter>
|
|
2428
2428
|
<Kicker surSombre>Souveraineté</Kicker>
|
|
@@ -2451,7 +2451,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
2451
2451
|
id: 'panneau-navy',
|
|
2452
2452
|
nom: 'Panneau sombre',
|
|
2453
2453
|
resume:
|
|
2454
|
-
'Plus petit qu’une bande : une carte, un encart. « TextOnDark » repeint un texte isolé
|
|
2454
|
+
'Plus petit qu’une bande : une carte, un encart. « TextOnDark » repeint un texte isolé : « Band » le fait déjà pour son contenu courant, l’ajouter dedans ne sert à rien.',
|
|
2455
2455
|
code: `<PanelNavy><TextOnDark>…</TextOnDark></PanelNavy>`,
|
|
2456
2456
|
surSombre: true,
|
|
2457
2457
|
rendu: (
|
|
@@ -2467,7 +2467,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
2467
2467
|
id: 'halo',
|
|
2468
2468
|
nom: 'Halo, sol, voile',
|
|
2469
2469
|
resume:
|
|
2470
|
-
'Le violet et le cyan du spectre, très dilués. Ce n’est PAS un emploi du spectre en aplat : c’est une lumière
|
|
2470
|
+
'Le violet et le cyan du spectre, très dilués. Ce n’est PAS un emploi du spectre en aplat : c’est une lumière, elle ne compte pas dans les trois emplois autorisés.',
|
|
2471
2471
|
code: `<section style={{ position: 'relative', overflow: 'hidden' }}>
|
|
2472
2472
|
<Halo place="hero" />
|
|
2473
2473
|
<GridFloor />
|
|
@@ -2533,7 +2533,7 @@ export const CATALOGUE: GroupeCatalogue[] = [
|
|
|
2533
2533
|
id: 'format-social',
|
|
2534
2534
|
nom: 'Formats sociaux',
|
|
2535
2535
|
resume:
|
|
2536
|
-
'Planches d’EXPORT
|
|
2536
|
+
'Planches d’EXPORT (paysage 1200×630 (OpenGraph, lien LinkedIn), carré 1080 (post), story 1080×1920) FIGÉES en pixels : on les capture, on ne les publie pas en HTML, et elles ignorent le point de rupture. Un visuel social EST une publication : jamais de faux chiffre ni de fausse citation. Rendue ici à l’échelle 0,35.',
|
|
2537
2537
|
code: `<SocialFrame manifeste pied={<><Mono ton="on-dark">ZEVRA</Mono><Mono ton="on-dark">zevra.tech</Mono></>}>
|
|
2538
2538
|
<Kicker surSombre><Mono ton="on-dark">Manifeste · Article 1ᵉʳ</Mono></Kicker>
|
|
2539
2539
|
<Heading taille="h2" as="p">
|
|
@@ -2572,7 +2572,7 @@ function Heading2Cta() {
|
|
|
2572
2572
|
return <Heading taille="h2-cta">Voir Zevra sur vos propres pièces.</Heading>
|
|
2573
2573
|
}
|
|
2574
2574
|
|
|
2575
|
-
/** Tous les exemples à plat
|
|
2575
|
+
/** Tous les exemples à plat : pratique pour une recherche ou un test. */
|
|
2576
2576
|
export const EXEMPLES: (Exemple & { groupe: string })[] = CATALOGUE.flatMap((g) =>
|
|
2577
2577
|
g.exemples.map((e) => ({ ...e, groupe: g.id })),
|
|
2578
2578
|
)
|