@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/dist/catalogue.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
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.
|
|
@@ -21,7 +21,7 @@ import { Alert, Badge, Caret, Dot, Empty, Loading, Progress, Skeleton, Spinner,
|
|
|
21
21
|
import { Checkbox, Drop, Field, Input, InputAffix, InputPassword, Radio, Range, Search, Seg, SegGroup, Select, SelectAnchor, SelectTrigger, Switch, Textarea, } from './forms.js';
|
|
22
22
|
import { ICONES, Icon, IconButton, IconTile, NOMS_ICONES } from './icon.js';
|
|
23
23
|
// Les glyphes sont INLINÉS (data-URI) : le catalogue est rendu hors du dépôt
|
|
24
|
-
//
|
|
24
|
+
// - planche, kit de canvas, page d'admin) où un chemin d'image ne résout pas.
|
|
25
25
|
import { ACCROCHES_PRODUITS, ADRESSES_PRODUITS, APPS, GLYPHES, MOT_ZEVRA, NOMS_PRODUITS, } from './glyphes.js';
|
|
26
26
|
import { Banner, CTA, Carousel, CarouselItem, Col, Compte, CompteLien, Footer, FooterMini, Grid, Grid12, Lanceur, LanceurApp, LanceurApps, LanceurGroupe, NavActions, Gutter, Hero, Langue, Langues, Lockup, LockupMark, LockupWord, Nav, NavDrawer, NavDrawerGroup, NavDrawerLink, NavDropdown, NavDropdownButton, NavDropdownMenu, NavDropdownSep, NavLink, NavLinks, NavLogo, ProofBar, Rail, RailItem, SectionHead, SectionRule, SheetSection, Stat, Stats, Step, Steps, } from './layout.js';
|
|
27
27
|
import { ChromeButton, CitePanel, Crumbs, Menu, MenuItem, Pager, PagerArrow, PagerRank, PagerStep, Popover, Scroll, SideGroup, SideLink, Sidebar, SidebarFoot, SidebarHead, Tabs, Topbar, TopbarTitle, } from './navigation.js';
|
|
@@ -106,7 +106,7 @@ function DemoPopover() {
|
|
|
106
106
|
return (_jsxs(SelectAnchor, { children: [_jsx(Button, { variante: "fantome", compact: true, "aria-expanded": ouvert, onClick: () => setOuvert(!ouvert), children: "Colonnes affich\u00E9es" }), ouvert && (_jsx(Popover, { children: _jsx("div", { style: { display: 'grid', gap: 8 }, children: ['Nom', 'Taille', 'Statut'].map((c) => (_jsxs("label", { style: { display: 'flex', gap: 8, alignItems: 'center' }, children: [_jsx(Checkbox, { defaultChecked: c !== 'Taille' }), _jsx("span", { className: "zv-body zv-body--dense", children: c })] }, c))) }) }))] }));
|
|
107
107
|
}
|
|
108
108
|
/** La barre de vitrine dans ses deux états. Rendue au REPOS : survoler le
|
|
109
|
-
* lanceur ou la pastille déplie le panneau, comme sur un vrai site
|
|
109
|
+
* lanceur ou la pastille déplie le panneau, comme sur un vrai site, c'est
|
|
110
110
|
* du CSS, il n'y a rien à hydrater. La réserve sous chaque barre existe pour
|
|
111
111
|
* que le panneau ait la place de s'ouvrir sans être coupé. */
|
|
112
112
|
function DemoNav() {
|
|
@@ -125,7 +125,7 @@ export const CATALOGUE = [
|
|
|
125
125
|
{
|
|
126
126
|
id: 'headings',
|
|
127
127
|
nom: 'Titres',
|
|
128
|
-
resume: 'Six paliers. Une page n’a qu’un <h1>, mais peut avoir plusieurs blocs à sa taille
|
|
128
|
+
resume: '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.',
|
|
129
129
|
code: `<H1>La recherche juridique, sourcée</H1>
|
|
130
130
|
<H2 as="h3">Ce que voit votre équipe</H2>
|
|
131
131
|
<H3>Indexation continue</H3>
|
|
@@ -135,7 +135,7 @@ export const CATALOGUE = [
|
|
|
135
135
|
{
|
|
136
136
|
id: 'display',
|
|
137
137
|
nom: 'Display',
|
|
138
|
-
resume: 'Chiffre ou mot posé pour sa présence, HORS de la hiérarchie des titres
|
|
138
|
+
resume: '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.',
|
|
139
139
|
code: `<Display>4 812</Display>`,
|
|
140
140
|
rendu: _jsx(Display, { children: "4 812" }),
|
|
141
141
|
},
|
|
@@ -152,7 +152,7 @@ export const CATALOGUE = [
|
|
|
152
152
|
{
|
|
153
153
|
id: 'kicker',
|
|
154
154
|
nom: 'Kicker et filet',
|
|
155
|
-
resume: 'Le filet de spectre 56×2 devant un sur-titre. PREMIER des trois emplois autorisés du spectre
|
|
155
|
+
resume: 'Le filet de spectre 56×2 devant un sur-titre. PREMIER des trois emplois autorisés du spectre : jamais en fond, jamais en texte.',
|
|
156
156
|
code: `<Kicker>Méthode</Kicker>
|
|
157
157
|
<Kicker variante="stack">Sécurité</Kicker>
|
|
158
158
|
<Spec petit />`,
|
|
@@ -184,7 +184,7 @@ export const CATALOGUE = [
|
|
|
184
184
|
nom: 'Actions',
|
|
185
185
|
couche: 'commun',
|
|
186
186
|
css: 'components.css',
|
|
187
|
-
resume: "Quatre variantes, et UNE SEULE pleine par page
|
|
187
|
+
resume: "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.",
|
|
188
188
|
exemples: [
|
|
189
189
|
{
|
|
190
190
|
id: 'boutons',
|
|
@@ -209,7 +209,7 @@ export const CATALOGUE = [
|
|
|
209
209
|
{
|
|
210
210
|
id: 'etats',
|
|
211
211
|
nom: 'États',
|
|
212
|
-
resume: '« danger » COMPTE comme le bouton plein de la page
|
|
212
|
+
resume: '« 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.',
|
|
213
213
|
code: `<Button variante="danger">Supprimer définitivement</Button>
|
|
214
214
|
<Button occupe>Connexion…</Button>
|
|
215
215
|
<Button variante="fantome" disabled>Envoyer</Button>`,
|
|
@@ -218,7 +218,7 @@ export const CATALOGUE = [
|
|
|
218
218
|
{
|
|
219
219
|
id: 'boutons-icones',
|
|
220
220
|
nom: 'Boutons à icône',
|
|
221
|
-
resume: 'L’icône vient du jeu (16 px) et hérite de la couleur du libellé
|
|
221
|
+
resume: '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.',
|
|
222
222
|
code: `<Button icone="telecharger">Télécharger le rapport</Button>
|
|
223
223
|
<Button variante="fantome" iconeApres="chevron-droit">Étape suivante</Button>
|
|
224
224
|
<Button carre variante="encre" icone="envoyer" aria-label="Envoyer le message" />`,
|
|
@@ -260,7 +260,7 @@ export const CATALOGUE = [
|
|
|
260
260
|
{
|
|
261
261
|
id: 'select',
|
|
262
262
|
nom: 'Sélection',
|
|
263
|
-
resume: 'Liste DESSINÉE jusqu’au bout
|
|
263
|
+
resume: '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.',
|
|
264
264
|
code: `<Field label="RÔLE" htmlFor="role">
|
|
265
265
|
<SelectMenu id="role" valeur={role} onChange={setRole} options={[
|
|
266
266
|
{ valeur: 'admin', label: 'Administrateur' },
|
|
@@ -289,7 +289,7 @@ export const CATALOGUE = [
|
|
|
289
289
|
{
|
|
290
290
|
id: 'recherche',
|
|
291
291
|
nom: 'Recherche',
|
|
292
|
-
resume: 'Cadre + loupe + champ nu. Deux marquages au clavier (l’anneau du champ ET le filet du cadre) :
|
|
292
|
+
resume: '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.',
|
|
293
293
|
code: `<Search placeholder="Rechercher un document…" />`,
|
|
294
294
|
rendu: (_jsx("div", { style: { maxWidth: 380 }, children: _jsx(Search, { placeholder: "Rechercher un document\u2026" }) })),
|
|
295
295
|
},
|
|
@@ -326,7 +326,7 @@ export const CATALOGUE = [
|
|
|
326
326
|
{
|
|
327
327
|
id: 'curseur',
|
|
328
328
|
nom: 'Curseur',
|
|
329
|
-
resume: '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
|
|
329
|
+
resume: '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.',
|
|
330
330
|
code: `<Field label="SOURCES INTERROGÉES" htmlFor="prof" help={\`\${sources} sources sur 17\`}>
|
|
331
331
|
<Range id="prof" min={1} max={17} value={sources} onChange={…} />
|
|
332
332
|
</Field>`,
|
|
@@ -353,7 +353,7 @@ export const CATALOGUE = [
|
|
|
353
353
|
{
|
|
354
354
|
id: 'mot-de-passe',
|
|
355
355
|
nom: 'Mot de passe',
|
|
356
|
-
resume: '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
|
|
356
|
+
resume: '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.',
|
|
357
357
|
code: `const [visible, setVisible] = useState(false)
|
|
358
358
|
|
|
359
359
|
<Field label="MOT DE PASSE" htmlFor="mdp">
|
|
@@ -370,7 +370,7 @@ export const CATALOGUE = [
|
|
|
370
370
|
nom: 'Retours',
|
|
371
371
|
couche: 'applicatif',
|
|
372
372
|
css: 'feedback.css',
|
|
373
|
-
resume: "Rien n'y crie : le bandeau porte le ton, la pastille l'état, la phrase le travail. La roue, le squelette et l'infobulle
|
|
373
|
+
resume: "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.",
|
|
374
374
|
exemples: [
|
|
375
375
|
{
|
|
376
376
|
id: 'alertes',
|
|
@@ -421,7 +421,7 @@ export const CATALOGUE = [
|
|
|
421
421
|
{
|
|
422
422
|
id: 'roue',
|
|
423
423
|
nom: 'Roue',
|
|
424
|
-
resume: '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
|
|
424
|
+
resume: '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.',
|
|
425
425
|
code: `<Spinner label="Vérification du dépôt…" />
|
|
426
426
|
<Spinner grand />`,
|
|
427
427
|
rendu: (_jsxs("div", { style: { display: 'flex', gap: 16, alignItems: 'center' }, children: [_jsx(Spinner, { label: "V\u00E9rification du d\u00E9p\u00F4t\u2026" }), _jsx(Spinner, { grand: true })] })),
|
|
@@ -429,7 +429,7 @@ export const CATALOGUE = [
|
|
|
429
429
|
{
|
|
430
430
|
id: 'squelette',
|
|
431
431
|
nom: 'Squelette',
|
|
432
|
-
resume: 'Il ANNONCE une structure connue
|
|
432
|
+
resume: '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.',
|
|
433
433
|
code: `<div aria-busy="true">
|
|
434
434
|
<Skeleton texte largeur="60%" />
|
|
435
435
|
<Skeleton texte />
|
|
@@ -440,7 +440,7 @@ export const CATALOGUE = [
|
|
|
440
440
|
{
|
|
441
441
|
id: 'infobulle',
|
|
442
442
|
nom: 'Infobulle',
|
|
443
|
-
resume: 'Un COMPLÉMENT dispensable
|
|
443
|
+
resume: '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.',
|
|
444
444
|
code: `<Tooltip id="th-date" contenu="Déposé le 12/08/2026 à 14 h 02">
|
|
445
445
|
<Button variante="fantome" compact aria-describedby="th-date">12 août</Button>
|
|
446
446
|
</Tooltip>`,
|
|
@@ -458,7 +458,7 @@ export const CATALOGUE = [
|
|
|
458
458
|
{
|
|
459
459
|
id: 'page-erreur',
|
|
460
460
|
nom: 'Page d’erreur',
|
|
461
|
-
resume: '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
|
|
461
|
+
resume: '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.',
|
|
462
462
|
code: `<PageErreur
|
|
463
463
|
code="404"
|
|
464
464
|
libelle="Erreur" {/* le mot est À VOUS : « Error » sous /en/ */}
|
|
@@ -513,7 +513,7 @@ export const CATALOGUE = [
|
|
|
513
513
|
{
|
|
514
514
|
id: 'preuve',
|
|
515
515
|
nom: 'Aperçu d’interface',
|
|
516
|
-
resume: '⚠️ RÈGLE DE CHARTE : toujours de VRAIES données réalistes, jamais de lorem
|
|
516
|
+
resume: '⚠️ 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.',
|
|
517
517
|
code: `<UiPreview question="Quelle est la durée de préavis ?"
|
|
518
518
|
sources="12 sources" puces={<SrcRow>…</SrcRow>}>
|
|
519
519
|
Trois mois pour les cadres…
|
|
@@ -560,7 +560,7 @@ export const CATALOGUE = [
|
|
|
560
560
|
{
|
|
561
561
|
id: 'page-legale',
|
|
562
562
|
nom: 'Page légale',
|
|
563
|
-
resume: 'La FORME d’un document contractuel ; le TEXTE vit dans @zevra/legal, versionné et archivé
|
|
563
|
+
resume: '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 ».',
|
|
564
564
|
code: `import { enVigueur } from '@zevra/legal'
|
|
565
565
|
|
|
566
566
|
<LegalPage document={enVigueur('mentions-legales')} />`,
|
|
@@ -600,10 +600,10 @@ export const CATALOGUE = [
|
|
|
600
600
|
{
|
|
601
601
|
id: 'citation',
|
|
602
602
|
nom: 'Citation client',
|
|
603
|
-
resume: '⚠️ RÈGLE DE CHARTE : jamais de fausse citation. Tant qu’un verbatim n’a pas été recueilli, ce bloc reste EN RÉSERVE
|
|
604
|
-
code: `<Band><Quote auteur="
|
|
603
|
+
resume: '⚠️ 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.',
|
|
604
|
+
code: `<Band><Quote auteur=": Nom, cabinet">Verbatim réel uniquement.</Quote></Band>`,
|
|
605
605
|
surSombre: true,
|
|
606
|
-
rendu: (_jsx(Band, { children: _jsx(Quote, { auteur: "
|
|
606
|
+
rendu: (_jsx(Band, { children: _jsx(Quote, { auteur: ": en attente d\u2019un verbatim recueilli", children: "Ce bloc reste en r\u00E9serve tant qu\u2019aucune citation r\u00E9elle n\u2019a \u00E9t\u00E9 recueillie." }) })),
|
|
607
607
|
},
|
|
608
608
|
],
|
|
609
609
|
},
|
|
@@ -637,7 +637,7 @@ export const CATALOGUE = [
|
|
|
637
637
|
{
|
|
638
638
|
id: 'tableau-prose',
|
|
639
639
|
nom: 'Tableau de prose',
|
|
640
|
-
resume: 'Les cellules reviennent à la ligne au lieu de tronquer. ⚠️ Dès qu’une cellule porte une PHRASE et non une donnée
|
|
640
|
+
resume: '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.',
|
|
641
641
|
code: `<Table prose gabarit="minmax(0,1fr) minmax(0,2fr)">
|
|
642
642
|
<TableHead><Cell>Donnée</Cell><Cell>Durée et fondement</Cell></TableHead>
|
|
643
643
|
<Row>
|
|
@@ -672,7 +672,7 @@ export const CATALOGUE = [
|
|
|
672
672
|
{
|
|
673
673
|
id: 'meta',
|
|
674
674
|
nom: 'Métadonnées',
|
|
675
|
-
resume: 'Second registre mono, en BAS DE CASSE : taille, date, latence. Ni capitales ni interlettrage
|
|
675
|
+
resume: '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.',
|
|
676
676
|
code: `<MetaRow><Meta>12 mars 2026</Meta><Meta taille="sm">1,2 s</Meta></MetaRow>`,
|
|
677
677
|
rendu: (_jsxs(MetaRow, { children: [_jsx(Meta, { taille: "md", children: "12 mars 2026" }), _jsx(Meta, { children: "14:07:22" }), _jsx(Meta, { taille: "sm", children: "1,24 s" }), _jsx(Meta, { discret: true, children: "2,4 Mo" })] })),
|
|
678
678
|
},
|
|
@@ -689,7 +689,7 @@ export const CATALOGUE = [
|
|
|
689
689
|
{
|
|
690
690
|
id: 'avatar-chip',
|
|
691
691
|
nom: 'Pastilles et catégories',
|
|
692
|
-
resume: 'Avatar CARRÉ, jamais rond : le rond est un usage de réseau social. ⚠️ Sa teinte dit la NATURE de l’entité
|
|
692
|
+
resume: '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.',
|
|
693
693
|
code: `<Avatar ton="accent">MD</Avatar>
|
|
694
694
|
<ChipRow><Chip>Droit social</Chip><Chip variante="outline">2024</Chip></ChipRow>`,
|
|
695
695
|
rendu: (_jsxs("div", { style: { display: 'grid', gap: 12 }, children: [_jsxs("div", { style: { display: 'flex', gap: 8 }, children: [_jsx(Avatar, { ton: "accent", children: "MD" }), _jsx(Avatar, { ton: "ink", children: "JL" }), _jsx(Avatar, { ton: "soft", children: "AB" }), _jsx(Avatar, { ton: "soft", petit: true, children: "ZV" })] }), _jsxs(ChipRow, { children: [_jsx(Chip, { children: "Droit social" }), _jsx(Chip, { children: "Convention collective" }), _jsx(Chip, { variante: "mono", children: "2024-114" }), _jsx(Chip, { variante: "outline", children: "Archiv\u00E9" })] })] })),
|
|
@@ -711,7 +711,7 @@ export const CATALOGUE = [
|
|
|
711
711
|
{
|
|
712
712
|
id: 'depliant',
|
|
713
713
|
nom: 'Rangée dépliante',
|
|
714
|
-
resume: '<details> NATIF : clavier, annonce et état viennent du navigateur, aucun JavaScript. Le pliage APPLICATIF
|
|
714
|
+
resume: '<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.',
|
|
715
715
|
code: `<Fold titre="Options avancées">…</Fold>
|
|
716
716
|
<Fold titre="Journal d'indexation" ouvert>…</Fold>`,
|
|
717
717
|
rendu: (_jsxs("div", { style: { maxWidth: 420 }, children: [_jsx(Fold, { titre: "Options avanc\u00E9es", children: "P\u00E9rim\u00E8tre, profondeur et sources exclues se r\u00E8glent par dossier, jamais par requ\u00EAte." }), _jsx(Fold, { titre: "Journal d\u2019indexation", ouvert: true, children: "Re\u00E7u, OCR, indexation : chaque \u00E9tape est dat\u00E9e, et l\u2019\u00E9chec d\u2019une page n\u2019interrompt pas les suivantes." })] })),
|
|
@@ -719,7 +719,7 @@ export const CATALOGUE = [
|
|
|
719
719
|
{
|
|
720
720
|
id: 'code',
|
|
721
721
|
nom: 'Code et raccourcis',
|
|
722
|
-
resume: '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
|
|
722
|
+
resume: '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.',
|
|
723
723
|
code: `<Body>Lancer <Code>pnpm build</Code>, puis <Kbd>⌘</Kbd> <Kbd>K</Kbd>.</Body>
|
|
724
724
|
<CodeBlock>claude mcp add --transport http zevra-design …</CodeBlock>`,
|
|
725
725
|
rendu: (_jsxs("div", { style: { display: 'grid', gap: 12, maxWidth: 520 }, children: [_jsxs(Body, { taille: "dense", children: ["Lancer ", _jsx(Code, { children: "pnpm build" }), ", puis ouvrir la recherche avec ", _jsx(Kbd, { children: "\u2318" }), ' ', _jsx(Kbd, { children: "K" }), "."] }), _jsx(CodeBlock, { children: 'claude mcp add --transport http zevra-design \\\n https://mcp.design.zevra.tech/mcp --scope user' })] })),
|
|
@@ -731,12 +731,12 @@ export const CATALOGUE = [
|
|
|
731
731
|
nom: 'Navigation',
|
|
732
732
|
couche: 'applicatif',
|
|
733
733
|
css: 'navigation.css',
|
|
734
|
-
resume: "Rien n'a d'état propre : l'entrée courante, la page courante et l'item sélectionné viennent de l'appelant
|
|
734
|
+
resume: "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.",
|
|
735
735
|
exemples: [
|
|
736
736
|
{
|
|
737
737
|
id: 'sidebar',
|
|
738
738
|
nom: 'Colonne latérale',
|
|
739
|
-
resume: '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
|
|
739
|
+
resume: '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.',
|
|
740
740
|
code: `<Sidebar>
|
|
741
741
|
<SidebarHead>…</SidebarHead>
|
|
742
742
|
<SideGroup titre="Espace">
|
|
@@ -752,7 +752,7 @@ export const CATALOGUE = [
|
|
|
752
752
|
{
|
|
753
753
|
id: 'topbar',
|
|
754
754
|
nom: 'Barre supérieure',
|
|
755
|
-
resume: '⚠️ 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
|
|
755
|
+
resume: '⚠️ 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.',
|
|
756
756
|
code: `<Topbar>
|
|
757
757
|
<TopbarBurger aria-label="Ouvrir la navigation">☰</TopbarBurger>
|
|
758
758
|
<TopbarLogo><img src="/logo.svg" alt="" /></TopbarLogo>
|
|
@@ -763,14 +763,14 @@ export const CATALOGUE = [
|
|
|
763
763
|
{
|
|
764
764
|
id: 'crumbs',
|
|
765
765
|
nom: 'Fil d’Ariane',
|
|
766
|
-
resume: '⚠️ Le fil ENTIER est cliquable
|
|
766
|
+
resume: '⚠️ 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.',
|
|
767
767
|
code: `<Crumbs href="/dossiers/2024" segments={['Dossiers', '2024', 'Duflot']} />`,
|
|
768
768
|
rendu: _jsx(Crumbs, { href: "#", segments: ['Dossiers', '2024', 'Duflot & Associés'] }),
|
|
769
769
|
},
|
|
770
770
|
{
|
|
771
771
|
id: 'onglets',
|
|
772
772
|
nom: 'Onglets en puces',
|
|
773
|
-
resume: 'La rangée de puces, grammaire d’état de Seg
|
|
773
|
+
resume: '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.',
|
|
774
774
|
code: `<Tabs actif={actif} onChange={setActif} onglets={[
|
|
775
775
|
{ id: 'apercu', label: 'Aperçu' },
|
|
776
776
|
{ id: 'sources', label: 'Sources', compte: 12 },
|
|
@@ -780,7 +780,7 @@ export const CATALOGUE = [
|
|
|
780
780
|
{
|
|
781
781
|
id: 'onglets-soulignes',
|
|
782
782
|
nom: 'Onglets soulignés',
|
|
783
|
-
resume: 'L’arbitrage longtemps en attente, tranché le 25/08/2026 : trait actif de 2 px
|
|
783
|
+
resume: '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.',
|
|
784
784
|
code: `<Tabs variante="soulignes" actif={actif} onChange={setActif} onglets={[
|
|
785
785
|
{ id: 'apercu', label: 'Aperçu' },
|
|
786
786
|
{ id: 'sources', label: 'Sources', compte: 12 },
|
|
@@ -790,7 +790,7 @@ export const CATALOGUE = [
|
|
|
790
790
|
{
|
|
791
791
|
id: 'popover',
|
|
792
792
|
nom: 'Popover',
|
|
793
|
-
resume: 'Surface ancrée LIBRE
|
|
793
|
+
resume: '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.',
|
|
794
794
|
code: `<SelectAnchor>
|
|
795
795
|
<Button variante="fantome" compact aria-expanded={ouvert} onClick={…}>Colonnes affichées</Button>
|
|
796
796
|
{ouvert && <Popover>…</Popover>}
|
|
@@ -838,7 +838,7 @@ export const CATALOGUE = [
|
|
|
838
838
|
nom: 'Enrobages',
|
|
839
839
|
couche: 'commun',
|
|
840
840
|
css: 'overlays.css',
|
|
841
|
-
resume: "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
|
|
841
|
+
resume: "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.",
|
|
842
842
|
exemples: [
|
|
843
843
|
{
|
|
844
844
|
id: 'tiroir',
|
|
@@ -853,7 +853,7 @@ export const CATALOGUE = [
|
|
|
853
853
|
{
|
|
854
854
|
id: 'modale',
|
|
855
855
|
nom: 'Modale',
|
|
856
|
-
resume: 'Fermée, elle n’est pas rendue du tout : son contenu
|
|
856
|
+
resume: '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.',
|
|
857
857
|
code: `<Modal ouvert={ouvert} onClose={…} titre="Supprimer" danger
|
|
858
858
|
pied={<ButtonRow>…</ButtonRow>}>
|
|
859
859
|
…
|
|
@@ -863,7 +863,7 @@ export const CATALOGUE = [
|
|
|
863
863
|
{
|
|
864
864
|
id: 'toast',
|
|
865
865
|
nom: 'Notification',
|
|
866
|
-
resume: '⚠️ 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
|
|
866
|
+
resume: '⚠️ 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é ».',
|
|
867
867
|
code: `<Toasts>
|
|
868
868
|
<Toast ton="ok">Lien copié.</Toast>
|
|
869
869
|
</Toasts>`,
|
|
@@ -876,12 +876,12 @@ export const CATALOGUE = [
|
|
|
876
876
|
nom: 'Icônes',
|
|
877
877
|
couche: 'commun',
|
|
878
878
|
css: 'icons.css',
|
|
879
|
-
resume: "55 icônes TRACÉES, jamais pleines : trait 2, grille de 24, BOUTS FRANCS et jonctions vives
|
|
879
|
+
resume: "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.",
|
|
880
880
|
exemples: [
|
|
881
881
|
{
|
|
882
882
|
id: 'jeu',
|
|
883
883
|
nom: 'Le jeu complet',
|
|
884
|
-
resume: 'Sans « titre », l’icône est DÉCORATIVE et masquée aux lecteurs d’écran
|
|
884
|
+
resume: '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.',
|
|
885
885
|
code: `<Icon nom="recherche" />
|
|
886
886
|
<Icon nom="document" taille="lg" />
|
|
887
887
|
<Icon nom="alerte" titre="Alerte" />`,
|
|
@@ -898,12 +898,12 @@ export const CATALOGUE = [
|
|
|
898
898
|
{
|
|
899
899
|
id: 'tuile',
|
|
900
900
|
nom: 'Tuile d’icône',
|
|
901
|
-
resume: 'La pastille carrée devant un argument de la vitrine
|
|
901
|
+
resume: '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.',
|
|
902
902
|
code: `<IconTile nom="bouclier-verifie" />
|
|
903
903
|
<IconTile nom="balance" />`,
|
|
904
904
|
rendu: (_jsx("div", { style: { display: 'grid', gap: 14, maxWidth: 380 }, children: [
|
|
905
905
|
['bouclier-verifie', 'Hébergement souverain', 'Infrastructure dédiée, en France.'],
|
|
906
|
-
['balance', 'Sources officielles', 'BOSS, Judilibre, KALI
|
|
906
|
+
['balance', 'Sources officielles', 'BOSS, Judilibre, KALI : datées et citées.'],
|
|
907
907
|
['cadenas', 'Zéro réutilisation', 'Vos pièces n’entraînent aucun modèle.'],
|
|
908
908
|
].map(([nom, titre, texte]) => (_jsxs("div", { style: { display: 'flex', gap: 14, alignItems: 'flex-start' }, children: [_jsx(IconTile, { nom: nom }), _jsxs("div", { children: [_jsx(CardTitle, { as: "p", children: titre }), _jsx(Body, { taille: "dense", children: texte })] })] }, nom))) })),
|
|
909
909
|
},
|
|
@@ -914,12 +914,12 @@ export const CATALOGUE = [
|
|
|
914
914
|
nom: 'Blocs éditoriaux',
|
|
915
915
|
couche: 'vitrine',
|
|
916
916
|
css: 'components.css',
|
|
917
|
-
resume: "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
|
|
917
|
+
resume: "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.",
|
|
918
918
|
exemples: [
|
|
919
919
|
{
|
|
920
920
|
id: 'rows',
|
|
921
921
|
nom: 'Rangées à filets',
|
|
922
|
-
resume: '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)
|
|
922
|
+
resume: '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.',
|
|
923
923
|
code: `<Rows>
|
|
924
924
|
<RowsItem cle="Directions juridiques">Structurer la connaissance interne…</RowsItem>
|
|
925
925
|
<RowsItem cle="Cabinets d’avocats">Retrouver la jurisprudence du cabinet…</RowsItem>
|
|
@@ -936,12 +936,12 @@ export const CATALOGUE = [
|
|
|
936
936
|
</IndexList>
|
|
937
937
|
|
|
938
938
|
<IndexList cols>…</IndexList>`,
|
|
939
|
-
rendu: (_jsxs(IndexList, { children: [_jsxs(IndexItem, { num: "01", children: [_jsx(CardTitle, { children: "Cadrage" }), _jsx(Body, { taille: "dense", children: "Deux ateliers pour d\u00E9limiter le corpus et les usages prioritaires." })] }), _jsxs(IndexItem, { num: "02", children: [_jsx(CardTitle, { children: "Indexation" }), _jsx(Body, { taille: "dense", children: "Le corpus est oc\u00E9ris\u00E9, anonymis\u00E9 et index\u00E9
|
|
939
|
+
rendu: (_jsxs(IndexList, { children: [_jsxs(IndexItem, { num: "01", children: [_jsx(CardTitle, { children: "Cadrage" }), _jsx(Body, { taille: "dense", children: "Deux ateliers pour d\u00E9limiter le corpus et les usages prioritaires." })] }), _jsxs(IndexItem, { num: "02", children: [_jsx(CardTitle, { children: "Indexation" }), _jsx(Body, { taille: "dense", children: "Le corpus est oc\u00E9ris\u00E9, anonymis\u00E9 et index\u00E9 : comptez une semaine pour 10 000 pi\u00E8ces." })] })] })),
|
|
940
940
|
},
|
|
941
941
|
{
|
|
942
942
|
id: 'flow',
|
|
943
943
|
nom: 'Déroulé vertical',
|
|
944
|
-
resume: '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
|
|
944
|
+
resume: '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.',
|
|
945
945
|
code: `<Flow>
|
|
946
946
|
<FlowStep><CardTitle>Déposer</CardTitle>…</FlowStep>
|
|
947
947
|
<FlowStep teinte="violet"><CardTitle>Interroger</CardTitle>…</FlowStep>
|
|
@@ -952,7 +952,7 @@ export const CATALOGUE = [
|
|
|
952
952
|
{
|
|
953
953
|
id: 'callout',
|
|
954
954
|
nom: 'Encart d’appel',
|
|
955
|
-
resume: '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
|
|
955
|
+
resume: '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.',
|
|
956
956
|
code: `<Callout titre="Formation Campus incluse la première année">
|
|
957
957
|
<ButtonLink href="/campus" variante="fantome">Découvrir Campus</ButtonLink>
|
|
958
958
|
</Callout>`,
|
|
@@ -981,7 +981,7 @@ export const CATALOGUE = [
|
|
|
981
981
|
{
|
|
982
982
|
id: 'grille',
|
|
983
983
|
nom: 'Grilles',
|
|
984
|
-
resume: '⚠️ 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
|
|
984
|
+
resume: '⚠️ 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é.',
|
|
985
985
|
code: `<Grid12>
|
|
986
986
|
<Col span={8}>…</Col>
|
|
987
987
|
<Col span={4}>…</Col>
|
|
@@ -993,7 +993,7 @@ export const CATALOGUE = [
|
|
|
993
993
|
{
|
|
994
994
|
id: 'sections',
|
|
995
995
|
nom: 'Sections',
|
|
996
|
-
resume: 'Le bloc « aside » tombe SOUS le titre en dessous du point de rupture
|
|
996
|
+
resume: '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.',
|
|
997
997
|
code: `<SectionHead aside={<LinkArrow href="/methode">Tout voir</LinkArrow>}>
|
|
998
998
|
<Kicker>Méthode</Kicker>
|
|
999
999
|
<H2>Trois étapes, rien de plus</H2>
|
|
@@ -1004,14 +1004,14 @@ export const CATALOGUE = [
|
|
|
1004
1004
|
{
|
|
1005
1005
|
id: 'sheet-section',
|
|
1006
1006
|
nom: 'Section de document',
|
|
1007
|
-
resume: 'Un intitulé mono, un filet, du corps
|
|
1007
|
+
resume: 'Un intitulé mono, un filet, du corps : pour un document long.',
|
|
1008
1008
|
code: `<SheetSection titre="ENGAGEMENTS">…</SheetSection>`,
|
|
1009
1009
|
rendu: (_jsx(SheetSection, { titre: "ENGAGEMENTS", children: _jsx(Body, { taille: "dense", children: "Les donn\u00E9es restent h\u00E9berg\u00E9es en France et ne sont jamais vers\u00E9es \u00E0 un entra\u00EEnement." }) })),
|
|
1010
1010
|
},
|
|
1011
1011
|
{
|
|
1012
1012
|
id: 'nav-vitrine',
|
|
1013
1013
|
nom: 'Navigation',
|
|
1014
|
-
resume: 'LA barre du site, dans ses deux états
|
|
1014
|
+
resume: '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.',
|
|
1015
1015
|
code: `<Nav className="zv-nav--riche">
|
|
1016
1016
|
<NavLogo>
|
|
1017
1017
|
<Lockup capitale={15}>
|
|
@@ -1043,7 +1043,7 @@ export const CATALOGUE = [
|
|
|
1043
1043
|
{/* APPS = les produits QUI ONT UNE ADRESSE, pas les sept glyphes :
|
|
1044
1044
|
une tuile qui mène à rien promet un produit et fait tomber le
|
|
1045
1045
|
visiteur. Plume et Supernovia y entreront le jour où ils ouvrent,
|
|
1046
|
-
par une ligne dans logos/index.json
|
|
1046
|
+
par une ligne dans logos/index.json : sans toucher aux apps. */}
|
|
1047
1047
|
<Lanceur> {/* titre="Applications" par défaut, filet de spectre */}
|
|
1048
1048
|
<LanceurGroupe>Suite Zevra</LanceurGroupe>
|
|
1049
1049
|
<LanceurApps>
|
|
@@ -1066,7 +1066,7 @@ export const CATALOGUE = [
|
|
|
1066
1066
|
{
|
|
1067
1067
|
id: 'lockup',
|
|
1068
1068
|
nom: 'Lockup',
|
|
1069
|
-
resume: '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 »
|
|
1069
|
+
resume: '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.',
|
|
1070
1070
|
code: `<Lockup capitale={15}>
|
|
1071
1071
|
<LockupMark src={GLYPHES.zevra} />
|
|
1072
1072
|
<LockupWord src={MOT_ZEVRA} alt="Zevra" />
|
|
@@ -1076,7 +1076,7 @@ export const CATALOGUE = [
|
|
|
1076
1076
|
{
|
|
1077
1077
|
id: 'tiroir-groupe',
|
|
1078
1078
|
nom: 'Tiroir groupé',
|
|
1079
|
-
resume: '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 »
|
|
1079
|
+
resume: '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.',
|
|
1080
1080
|
code: `<NavDrawer>
|
|
1081
1081
|
<NavDrawerGroup>Services</NavDrawerGroup>
|
|
1082
1082
|
<NavDrawerLink href="/audit" className="zv-nav-drawer__link--sous">Audit</NavDrawerLink>
|
|
@@ -1087,7 +1087,7 @@ export const CATALOGUE = [
|
|
|
1087
1087
|
{
|
|
1088
1088
|
id: 'rail',
|
|
1089
1089
|
nom: 'Rail de lecture',
|
|
1090
|
-
resume: '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
|
|
1090
|
+
resume: '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.',
|
|
1091
1091
|
code: `<Rail aria-label="Sections">
|
|
1092
1092
|
<RailItem href="#intro" courant>Intro</RailItem>
|
|
1093
1093
|
<RailItem href="#methode">Méthode</RailItem>
|
|
@@ -1148,17 +1148,17 @@ export const CATALOGUE = [
|
|
|
1148
1148
|
{
|
|
1149
1149
|
id: 'bandeau',
|
|
1150
1150
|
nom: 'Bandeau d’annonce',
|
|
1151
|
-
resume: '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
|
|
1151
|
+
resume: '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.',
|
|
1152
1152
|
code: `<Banner>
|
|
1153
|
-
La charte évolue
|
|
1153
|
+
La charte évolue : le journal des livraisons est en ligne.{' '}
|
|
1154
1154
|
<a href="/journal">Ce qui change</a>
|
|
1155
1155
|
</Banner>`,
|
|
1156
|
-
rendu: (_jsxs(Banner, { children: ["La charte \u00E9volue
|
|
1156
|
+
rendu: (_jsxs(Banner, { children: ["La charte \u00E9volue : le journal des livraisons est en ligne.", ' ', _jsx("a", { href: "#", children: "Ce qui change" })] })),
|
|
1157
1157
|
},
|
|
1158
1158
|
{
|
|
1159
1159
|
id: 'carrousel',
|
|
1160
1160
|
nom: 'Carrousel',
|
|
1161
|
-
resume: 'Défilement natif scroll-snap, AUCUN JavaScript : pas de flèches, pas de points ; le conteneur prend le focus, et son label est OBLIGATOIRE
|
|
1161
|
+
resume: '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.',
|
|
1162
1162
|
code: `<Carousel label="La suite Zevra">
|
|
1163
1163
|
<CarouselItem style={{ width: 260 }}>
|
|
1164
1164
|
<Card>…</Card>
|
|
@@ -1175,7 +1175,7 @@ export const CATALOGUE = [
|
|
|
1175
1175
|
{
|
|
1176
1176
|
id: 'media',
|
|
1177
1177
|
nom: 'Cadre média',
|
|
1178
|
-
resume: '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
|
|
1178
|
+
resume: '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.',
|
|
1179
1179
|
code: `<Media ratio="16-9">
|
|
1180
1180
|
<MediaImg src={couverture} alt="" />
|
|
1181
1181
|
<MediaVoile />
|
|
@@ -1195,12 +1195,12 @@ export const CATALOGUE = [
|
|
|
1195
1195
|
nom: 'Surfaces',
|
|
1196
1196
|
couche: 'vitrine',
|
|
1197
1197
|
css: 'surfaces.css + motion.css',
|
|
1198
|
-
resume: "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
|
|
1198
|
+
resume: "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 ».",
|
|
1199
1199
|
exemples: [
|
|
1200
1200
|
{
|
|
1201
1201
|
id: 'bande',
|
|
1202
1202
|
nom: 'Bande manifeste',
|
|
1203
|
-
resume: '⚠️ 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
|
|
1203
|
+
resume: '⚠️ 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.',
|
|
1204
1204
|
code: `<Band lueur filigrane={<Glyph variante="watermark">…</Glyph>}>
|
|
1205
1205
|
<Gutter>
|
|
1206
1206
|
<Kicker surSombre>Souveraineté</Kicker>
|
|
@@ -1213,7 +1213,7 @@ export const CATALOGUE = [
|
|
|
1213
1213
|
{
|
|
1214
1214
|
id: 'panneau-navy',
|
|
1215
1215
|
nom: 'Panneau sombre',
|
|
1216
|
-
resume: 'Plus petit qu’une bande : une carte, un encart. « TextOnDark » repeint un texte isolé
|
|
1216
|
+
resume: '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.',
|
|
1217
1217
|
code: `<PanelNavy><TextOnDark>…</TextOnDark></PanelNavy>`,
|
|
1218
1218
|
surSombre: true,
|
|
1219
1219
|
rendu: (_jsx(PanelNavy, { children: _jsxs(TextOnDark, { children: [_jsx(Mono, { ton: "on-dark", children: "CHIFFREMENT" }), _jsx(Body, { children: "AES-256 au repos, TLS 1.3 en transit." })] }) })),
|
|
@@ -1221,7 +1221,7 @@ export const CATALOGUE = [
|
|
|
1221
1221
|
{
|
|
1222
1222
|
id: 'halo',
|
|
1223
1223
|
nom: 'Halo, sol, voile',
|
|
1224
|
-
resume: '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
|
|
1224
|
+
resume: '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.',
|
|
1225
1225
|
code: `<section style={{ position: 'relative', overflow: 'hidden' }}>
|
|
1226
1226
|
<Halo place="hero" />
|
|
1227
1227
|
<GridFloor />
|
|
@@ -1256,7 +1256,7 @@ export const CATALOGUE = [
|
|
|
1256
1256
|
{
|
|
1257
1257
|
id: 'format-social',
|
|
1258
1258
|
nom: 'Formats sociaux',
|
|
1259
|
-
resume: 'Planches d’EXPORT
|
|
1259
|
+
resume: '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.',
|
|
1260
1260
|
code: `<SocialFrame manifeste pied={<><Mono ton="on-dark">ZEVRA</Mono><Mono ton="on-dark">zevra.tech</Mono></>}>
|
|
1261
1261
|
<Kicker surSombre><Mono ton="on-dark">Manifeste · Article 1ᵉʳ</Mono></Kicker>
|
|
1262
1262
|
<Heading taille="h2" as="p">
|
|
@@ -1271,6 +1271,6 @@ export const CATALOGUE = [
|
|
|
1271
1271
|
function Heading2Cta() {
|
|
1272
1272
|
return _jsx(Heading, { taille: "h2-cta", children: "Voir Zevra sur vos propres pi\u00E8ces." });
|
|
1273
1273
|
}
|
|
1274
|
-
/** Tous les exemples à plat
|
|
1274
|
+
/** Tous les exemples à plat : pratique pour une recherche ou un test. */
|
|
1275
1275
|
export const EXEMPLES = CATALOGUE.flatMap((g) => g.exemples.map((e) => ({ ...e, groupe: g.id })));
|
|
1276
1276
|
//# sourceMappingURL=catalogue.js.map
|