@zevra/ui 0.1.0 → 0.2.1

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 CHANGED
@@ -128,6 +128,62 @@ le composant plutôt qu'ajouté au token.
128
128
 
129
129
  ---
130
130
 
131
+ ## La couche applicative (relevé Mémoire)
132
+
133
+ Les composants d'interface sont relevés dans l'application Mémoire, en
134
+ production, qui emploie les mêmes tokens de charte. Trois arbitrages de fond
135
+ ont été rendus :
136
+
137
+ **Les neutres.** Mémoire emploie six niveaux de gris là où la charte en a
138
+ trois, et deux d'entre eux — #6B7488 et #727C93 — **échouent au contraste AA**
139
+ sur texte normal (4,34 et 3,87), alors qu'ils portent justement le texte mono
140
+ de 10,5px : latences, horodatages, compteurs. Les adopter aurait gravé une
141
+ régression d'accessibilité. Ils se rabattent sur `--muted` (5,55). Un seul
142
+ niveau intermédiaire est ajouté, `--ink-2` (#4a5468, contraste 7,05).
143
+
144
+ **L'échelle de texte.** Le relevé compte huit paliers répartis dans 5,5px,
145
+ avec des demi-pixels et des écarts d'un pixel — de l'entropie d'utilitaires,
146
+ pas une échelle dessinée. Ils se regroupent en trois paliers de texte
147
+ (`--app-lg`, `--app`, `--app-sm`) et trois de labels (`--mono-lg`, `--mono`,
148
+ `--mono-sm`).
149
+
150
+ **Les filets et surfaces.** Cinq « nouveaux » tokens étaient des doublons
151
+ imperceptibles de tokens existants — écart RVB de 1,4 à 6,8, sous le seuil de
152
+ perception. `--line-inner` → `--hairline`, `--line-soft` → `--line`,
153
+ `--row-hover` / `--paper-hover` / `--paper-warm` → `--panel`.
154
+
155
+ Au total, 32 tokens proposés se réduisent à 14.
156
+
157
+ ### Écarts assumés au relevé
158
+
159
+ **La barre supérieure.** La production pose `top: 53px` pour une barre de
160
+ 52px, en supposant que son filet s'ajoute à la hauteur. Il ne s'y ajoute
161
+ pas : `box-sizing: border-box` le peint à l'intérieur. Ce pixel n'empilait
162
+ rien, il ouvrait une couture — et la feuille portant son propre filet haut,
163
+ le trait apparaissait doublé. Corrigé : la feuille se cale à ras, sans filet
164
+ propre.
165
+
166
+ **L'alignement des colonnes de chiffres.** Le relevé s'appuyait sur
167
+ `--font-mono` pour aligner les nombres. Or `--font-mono` vaut Space Grotesk,
168
+ qui n'est **pas à chasse fixe** : l'alignement n'aurait jamais tenu. Remplacé
169
+ par `font-variant-numeric: tabular-nums`, qui aligne les chiffres dans
170
+ n'importe quelle police.
171
+
172
+ **Le gris chaud.** `#6E6A61`, seule teinte chaude du relevé, se rabat sur
173
+ `--muted`. La nuance de température disparaît ; elle n'était reconductible
174
+ nulle part ailleurs.
175
+
176
+ ### Ce que le relevé ne donnait pas
177
+
178
+ Aucun `<textarea>`, aucune case à cocher, aucun bouton radio n'existe dans
179
+ Mémoire : le composeur du chat est un `<input>`, et toute sélection passe par
180
+ des puces de filtre ou un interrupteur. Ces trois contrôles sont livrés,
181
+ dérivés strictement de `.zv-input`, et signalés comme tels dans le CSS.
182
+
183
+ Aucun jeu d'onglets non plus : une rangée d'onglets se construit avec
184
+ `.zv-seg-group` et `.zv-seg`. Un onglet **souligné** reste à faire — il
185
+ suppose d'arbitrer la couleur et l'épaisseur du trait actif.
186
+
131
187
  ## Écarté du paquet
132
188
 
133
189
  Ce que le relevé recense mais que le paquet ne livre pas, faute d'usage hors
package/README.md CHANGED
@@ -31,6 +31,11 @@ pnpm add @zevra/ui
31
31
  @import "@zevra/ui/layout.css"; /* conteneurs, grilles, sections, chrome */
32
32
  @import "@zevra/ui/surfaces.css"; /* halos, sols, voiles, manifeste */
33
33
  @import "@zevra/ui/motion.css"; /* les neuf animations autorisées */
34
+ @import "@zevra/ui/icons.css"; /* dimensionnement des icônes */
35
+ @import "@zevra/ui/forms.css"; /* champs, selects, interrupteurs, dépôt */
36
+ @import "@zevra/ui/feedback.css"; /* alertes, badges, états, chargement */
37
+ @import "@zevra/ui/navigation.css"; /* menus, barre, fil d'Ariane, pagination */
38
+ @import "@zevra/ui/data.css"; /* tableaux, listes, clé-valeur, avatars */
34
39
  ```
35
40
 
36
41
  L'ordre compte : les tokens d'abord, le socle ensuite. Toutes les classes sont
@@ -44,6 +49,24 @@ unique à 768px reprend les valeurs mobiles du relevé.
44
49
  Chaque valeur vient des maquettes de la passation. Là où deux planches se
45
50
  contredisaient, l'arbitrage est écrit dans [DECISIONS.md](DECISIONS.md).
46
51
 
52
+ ## Deux couches
53
+
54
+ Le paquet en porte deux, et elles ne servent pas au même usage.
55
+
56
+ La **couche vitrine** — `base`, `components`, `layout`, `surfaces`, `motion` —
57
+ compose une page qui se lit : hero, sections, manifeste, cartes produit.
58
+
59
+ La **couche applicative** — `forms`, `feedback`, `navigation`, `data`, `icons` —
60
+ compose une interface qui s'opère : champs, alertes, menus, tableaux. Elle
61
+ est plus dense, et dispose de son échelle propre (`--app`, `--mono`).
62
+
63
+ Une app n'a aucune raison de charger les deux. Seuls `tokens.css` et
64
+ `base.css` sont communs.
65
+
66
+ Le tableau est **à base de grille**, pas de `<table>` : le gabarit de
67
+ colonnes se pose en `--zv-cols` sur le conteneur, et sous 768px la rangée
68
+ s'effondre en carte, chaque valeur reprenant son intitulé.
69
+
47
70
  ## Le mouvement
48
71
 
49
72
  Neuf animations, pas une de plus, sous le préfixe `zv-anim-`. Sept sont
@@ -172,6 +195,9 @@ ci-dessus fonctionne telle quelle.
172
195
  l'index régénéré.
173
196
  5. Publier une version : `npm version <patch|minor|major>` puis `npm publish`.
174
197
 
198
+ `demo/index.html` exerce la couche vitrine, `demo/app.html` la couche
199
+ applicative. Aucune des deux n'est publiée dans le paquet.
200
+
175
201
  `reference/` conserve les maquettes HTML, le prototype animé et les fichiers
176
202
  d'origine de la passation. Ce dossier n'est **pas publié** dans le paquet : il
177
203
  sert d'archive et de référence visuelle, pas de dépendance.
package/demo/app.html ADDED
@@ -0,0 +1,233 @@
1
+ <!doctype html>
2
+ <html lang="fr">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>Zevra UI — couche applicative</title>
7
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
8
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Outfit:wght@200;300;400;500;600&family=Public+Sans:wght@400;500;600&family=Space+Grotesk:wght@500;600;700&display=swap">
9
+ <link rel="stylesheet" href="../src/index.css">
10
+ <style>
11
+ /* Propre à la planche — n'appartient pas au système. */
12
+ body { padding: 0; }
13
+ .d-wrap { max-width: 1180px; margin: 0 auto; padding: 32px 24px 80px; }
14
+ .d-sec { margin-top: 44px; }
15
+ .d-sec > h2 { margin: 0 0 4px; }
16
+ .d-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-start; margin-top: 16px; }
17
+ .d-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); margin-top: 16px; }
18
+ .d-box { border: 1px dashed var(--accent-line); padding: 14px; background: var(--white); }
19
+ </style>
20
+ </head>
21
+ <body>
22
+
23
+ <div class="d-wrap">
24
+ <span class="zv-kicker"><span class="zv-spec" aria-hidden="true"></span><span class="zv-mono">Couche applicative</span></span>
25
+ <h1 class="zv-h2 zv-h2--sm" style="margin-top:18px">Ce qu'une interface exige <span class="zv-em">et qu'une vitrine ignore.</span></h1>
26
+ <p class="zv-note" style="margin-top:10px">Chaque composant relevé dans Mémoire, posé une fois. Les cadres pointillés isolent un composant de son voisin.</p>
27
+
28
+ <!-- FORMULAIRES -->
29
+ <section class="d-sec">
30
+ <span class="zv-kicker"><span class="zv-spec" aria-hidden="true"></span><span class="zv-mono">01 · Formulaires</span></span>
31
+ <div class="d-grid">
32
+ <div class="d-box">
33
+ <label class="zv-field">
34
+ <span class="zv-field__head">
35
+ <span class="zv-field__label">Adresse e-mail</span>
36
+ <a class="zv-link" href="#" style="font-size:var(--app-sm)">Aide</a>
37
+ </span>
38
+ <input class="zv-input" type="email" placeholder="prenom@cabinet.fr">
39
+ <span class="zv-field__help">Utilisée pour la connexion et les alertes.</span>
40
+ </label>
41
+ </div>
42
+ <div class="d-box">
43
+ <label class="zv-field zv-field--err">
44
+ <span class="zv-field__label">Identifiant d'organisation</span>
45
+ <input class="zv-input zv-input--mono" value="karila-2024" aria-invalid="true">
46
+ <span class="zv-field__err">Cet identifiant est déjà pris.</span>
47
+ </label>
48
+ </div>
49
+ <div class="d-box">
50
+ <label class="zv-field">
51
+ <span class="zv-field__label">Rôle</span>
52
+ <select class="zv-input zv-input--select">
53
+ <option>Membre</option><option>Administrateur</option><option>Lecture seule</option>
54
+ </select>
55
+ </label>
56
+ </div>
57
+ <div class="d-box">
58
+ <label class="zv-field">
59
+ <span class="zv-field__label">Note interne</span>
60
+ <textarea class="zv-textarea" placeholder="Contexte du dossier…"></textarea>
61
+ </label>
62
+ </div>
63
+ </div>
64
+
65
+ <div class="d-row">
66
+ <span class="zv-search"><svg class="zv-search__icon" viewBox="0 0 13 13" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><circle cx="5.5" cy="5.5" r="4"/><line x1="8.6" y1="8.6" x2="12" y2="12"/></svg><input class="zv-search__input" placeholder="Rechercher un document…"></span>
67
+ </div>
68
+
69
+ <div class="d-row">
70
+ <span class="zv-seg-group">
71
+ <button class="zv-seg zv-seg--on">Tous <span class="zv-seg__count">128</span></button>
72
+ <button class="zv-seg">Consultations <span class="zv-seg__count">41</span></button>
73
+ <button class="zv-seg">Actes <span class="zv-seg__count">63</span></button>
74
+ <button class="zv-seg zv-seg--mono">PDF</button>
75
+ </span>
76
+ </div>
77
+
78
+ <div class="d-row">
79
+ <span class="zv-select-anchor">
80
+ <button class="zv-select">Périmètre : <strong>Toute la base</strong><span class="zv-select__chevron">▾</span></button>
81
+ </span>
82
+ <label class="zv-switch-hit"><span class="zv-switch zv-switch--on"><span class="zv-switch__knob"></span></span><span class="zv-switch__text zv-switch__text--on">Indexation automatique</span></label>
83
+ <label class="zv-switch-hit"><span class="zv-switch"><span class="zv-switch__knob"></span></span><span class="zv-switch__text">Notifications</span></label>
84
+ </div>
85
+
86
+ <div class="d-row">
87
+ <label class="zv-switch-hit"><input class="zv-check-box" type="checkbox" checked><span class="zv-switch__text">J'accepte les conditions</span></label>
88
+ <label class="zv-switch-hit"><input class="zv-radio" type="radio" name="r" checked><span class="zv-switch__text">Mensuel</span></label>
89
+ <label class="zv-switch-hit"><input class="zv-radio" type="radio" name="r"><span class="zv-switch__text">Annuel</span></label>
90
+ </div>
91
+
92
+ <div class="zv-drop" style="margin-top:16px">
93
+ <span class="zv-drop__title">Déposer des documents</span>
94
+ <span class="zv-drop__hint">Glissez vos fichiers ici, ou <span class="zv-drop__browse">parcourez votre disque</span>.</span>
95
+ <span class="zv-drop__spec">PDF, DOCX — 40 Mo maximum</span>
96
+ </div>
97
+ </section>
98
+
99
+ <!-- RETOURS -->
100
+ <section class="d-sec">
101
+ <span class="zv-kicker"><span class="zv-spec" aria-hidden="true"></span><span class="zv-mono">02 · Retours</span></span>
102
+ <div class="d-row" style="flex-direction:column;align-items:stretch">
103
+ <div class="zv-alert zv-alert--info">L'indexation reprendra automatiquement à la reconnexion.</div>
104
+ <div class="zv-alert zv-alert--ok">Douze documents importés, tous indexés.</div>
105
+ <div class="zv-alert zv-alert--warn">Trois documents scannés attendent la reconnaissance de texte.</div>
106
+ <div class="zv-alert zv-alert--err">Impossible de joindre le service d'indexation. Réessayez dans un instant.</div>
107
+ <div class="zv-alert zv-alert--dash">Réponse construite à partir de vos documents, sans recours à un modèle externe.</div>
108
+ </div>
109
+
110
+ <div class="d-row">
111
+ <span class="zv-badge zv-badge--ok">Indexé</span>
112
+ <span class="zv-badge zv-badge--warn">OCR en cours</span>
113
+ <span class="zv-badge zv-badge--err">Échec</span>
114
+ <span class="zv-badge zv-badge--accent">Nouveau</span>
115
+ <span class="zv-badge zv-badge--neutre">Brouillon</span>
116
+ <span class="zv-badge zv-badge--micro">v2</span>
117
+ <span class="zv-badge zv-badge--dot"><span class="zv-dot zv-dot--ok"></span>En ligne</span>
118
+ </div>
119
+
120
+ <div class="d-row">
121
+ <span class="zv-status"><span class="zv-dot zv-dot--indexe"></span><span class="zv-status__label">Indexé</span></span>
122
+ <span class="zv-status"><span class="zv-dot zv-dot--indexation"></span><span class="zv-status__label">Indexation…</span></span>
123
+ <span class="zv-status"><span class="zv-dot zv-dot--ocr"></span><span class="zv-status__label">Reconnaissance de texte</span></span>
124
+ <span class="zv-status"><span class="zv-dot zv-dot--erreur"></span><span class="zv-status__label">Erreur</span></span>
125
+ <span class="zv-status"><span class="zv-dot zv-dot--recu"></span><span class="zv-status__label">Reçu</span></span>
126
+ <span class="zv-loading">Chargement…</span>
127
+ </div>
128
+
129
+ <div class="zv-empty" style="margin-top:16px">
130
+ <div class="zv-empty__title">Aucun document</div>
131
+ <div class="zv-empty__text">Déposez vos premiers actes pour que Mémoire puisse les interroger.</div>
132
+ <a class="zv-btn zv-btn--sm zv-empty__action" href="#">Importer</a>
133
+ </div>
134
+ </section>
135
+
136
+ <!-- NAVIGATION -->
137
+ <section class="d-sec">
138
+ <span class="zv-kicker"><span class="zv-spec" aria-hidden="true"></span><span class="zv-mono">03 · Navigation</span></span>
139
+
140
+ <div class="d-box" style="margin-top:16px;padding:0">
141
+ <div class="zv-topbar">
142
+ <button class="zv-topbar__burger zv-icon-btn" aria-label="Ouvrir le menu"><svg class="zv-icon"><use href="../icons/sprite.svg#zv-menu"/></svg></button>
143
+ <span class="zv-topbar__title">Bibliothèque</span>
144
+ </div>
145
+ </div>
146
+
147
+ <div class="d-grid">
148
+ <div class="d-box" style="padding:0">
149
+ <nav class="zv-sidebar" style="height:auto">
150
+ <div class="zv-sidebar__head"><span class="zv-mono zv-mono--micro">Cabinet Karila</span></div>
151
+ <div class="zv-sidegroup">
152
+ <span class="zv-sidegroup__title">Travail</span>
153
+ <a class="zv-sidelink zv-sidelink--on" href="#"><svg class="zv-icon zv-icon--sm"><use href="../icons/sprite.svg#zv-recherche"/></svg>Recherche</a>
154
+ <a class="zv-sidelink" href="#"><svg class="zv-icon zv-icon--sm"><use href="../icons/sprite.svg#zv-dossier"/></svg>Bibliothèque <span class="zv-sidelink__num">128</span></a>
155
+ <a class="zv-sidelink" href="#"><svg class="zv-icon zv-icon--sm"><use href="../icons/sprite.svg#zv-equipe"/></svg>Répertoire</a>
156
+ </div>
157
+ </nav>
158
+ </div>
159
+ <div class="d-box">
160
+ <span class="zv-crumbs"><a class="zv-crumbs__seg" href="#">Bibliothèque</a><span class="zv-crumbs__sep">/</span><a class="zv-crumbs__seg" href="#">Actes</a><span class="zv-crumbs__sep">/</span><span class="zv-crumbs__seg">Cession de parts</span></span>
161
+ <div class="zv-menu" style="position:static;margin-top:16px">
162
+ <button class="zv-menu__item zv-menu__item--on">Toute la base</button>
163
+ <button class="zv-menu__item">Consultations</button>
164
+ <button class="zv-menu__item">Actes signés</button>
165
+ </div>
166
+ <div class="zv-pager" style="margin-top:16px">
167
+ <button class="zv-pager__arrow" aria-label="Page précédente">‹</button>
168
+ <span class="zv-pager__rank">1 – 25 sur 128</span>
169
+ <button class="zv-pager__arrow" aria-label="Page suivante">›</button>
170
+ </div>
171
+ </div>
172
+ </div>
173
+ </section>
174
+
175
+ <!-- DONNÉES -->
176
+ <section class="d-sec">
177
+ <span class="zv-kicker"><span class="zv-spec" aria-hidden="true"></span><span class="zv-mono">04 · Données</span></span>
178
+
179
+ <!-- Le tableau est à base de GRILLE, pas de <table> : c'est ainsi qu'il
180
+ est relevé, et le gabarit de colonnes se pose sur le conteneur. -->
181
+ <div class="zv-table" style="margin-top:16px;--zv-cols:minmax(180px,1.4fr) 108px 132px 84px 104px">
182
+ <div class="zv-table__head">
183
+ <span>Document</span>
184
+ <span>Nature</span>
185
+ <span>Statut</span>
186
+ <span>Taille</span>
187
+ <span>Indexé le</span>
188
+ </div>
189
+ <div class="zv-row">
190
+ <span class="zv-cell zv-cell--name"><span class="zv-filetype zv-filetype--pdf">PDF</span><span class="zv-trunc">Cession de parts — SCI Beaumont</span></span>
191
+ <span class="zv-cell">Acte</span>
192
+ <span class="zv-cell"><span class="zv-status"><span class="zv-dot zv-dot--indexe"></span><span class="zv-status__label">Indexé</span></span></span>
193
+ <span class="zv-cell zv-cell--num"><span class="zv-cell__label">Taille</span>2,4 Mo</span>
194
+ <span class="zv-cell zv-cell--num">12/08/2026</span>
195
+ </div>
196
+ <div class="zv-row">
197
+ <span class="zv-cell zv-cell--name"><span class="zv-filetype zv-filetype--docx">DOCX</span><span class="zv-trunc">Consultation — garantie autonome</span></span>
198
+ <span class="zv-cell">Consultation</span>
199
+ <span class="zv-cell"><span class="zv-status"><span class="zv-dot zv-dot--ocr"></span><span class="zv-status__label">OCR</span></span></span>
200
+ <span class="zv-cell zv-cell--num"><span class="zv-cell__label">Taille</span>840 Ko</span>
201
+ <span class="zv-cell zv-cell--num">11/08/2026</span>
202
+ </div>
203
+ <div class="zv-pager zv-pager--foot">
204
+ <button class="zv-pager__arrow" aria-label="Page précédente">‹</button>
205
+ <span class="zv-pager__rank">1 – 25 sur 128</span>
206
+ <button class="zv-pager__arrow" aria-label="Page suivante">›</button>
207
+ </div>
208
+ </div>
209
+
210
+ <div class="d-grid">
211
+ <div class="d-box">
212
+ <div class="zv-kv zv-kv--grid">
213
+ <div class="zv-kv__row"><span class="zv-kv__key">Nature</span><span class="zv-kv__val">Acte de cession</span></div>
214
+ <div class="zv-kv__row"><span class="zv-kv__key">Pages</span><span class="zv-kv__val">14</span></div>
215
+ <div class="zv-kv__row"><span class="zv-kv__key">Signé le</span><span class="zv-kv__val">04/07/2026</span></div>
216
+ </div>
217
+ </div>
218
+ <div class="d-box">
219
+ <div class="zv-list">
220
+ <div class="zv-list__row"><span class="zv-avatar zv-avatar--accent">MK</span><span class="zv-list__main"><span class="zv-list__name">Maître Karila</span><span class="zv-meta">Associé · 4 dossiers</span></span></div>
221
+ <div class="zv-list__row"><span class="zv-avatar zv-avatar--soft">CL</span><span class="zv-list__main"><span class="zv-list__name">Clesame</span><span class="zv-meta zv-meta--quiet">Client · 12 documents</span></span></div>
222
+ </div>
223
+ </div>
224
+ <div class="d-box">
225
+ <span class="zv-chip-row"><span class="zv-chip">Garantie</span><span class="zv-chip zv-chip--outline">Cession</span><span class="zv-chip zv-chip--mono">40 %</span></span>
226
+ <p class="zv-cite-row" style="margin-top:14px"><span class="zv-cite">p. 12</span> Garantie autonome plafonnée à 40 % du prix de cession.</p>
227
+ </div>
228
+ </div>
229
+ </section>
230
+
231
+ </div>
232
+ </body>
233
+ </html>
@@ -0,0 +1,242 @@
1
+ <!doctype html>
2
+ <html lang="fr">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>Zevra UI — planche de vérification</title>
7
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
8
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Outfit:wght@200;300;400;500;600&family=Public+Sans:wght@400;600&family=Space+Grotesk:wght@500;600;700&display=swap">
9
+ <link rel="stylesheet" href="../src/index.css">
10
+ <style>
11
+ /* Propre à la planche : elle n'appartient pas au système. */
12
+ .demo-sec { padding-top: 72px; }
13
+ .demo-sec > h2 { margin: 0 0 6px; }
14
+ .demo-row { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; margin-top: 20px; }
15
+ .demo-row > * { min-width: 240px; }
16
+ .demo-note { margin-top: 4px; }
17
+ </style>
18
+ </head>
19
+ <body>
20
+ <div class="zv-page">
21
+
22
+ <!-- Chrome -->
23
+ <nav class="zv-nav zv-gutter">
24
+ <span class="zv-display" style="font-size:21px;font-weight:600;letter-spacing:0.22em;text-transform:uppercase">Zevra</span>
25
+ <a class="zv-btn zv-btn--sm zv-only-mobile" href="#">Réserver</a>
26
+ <span class="zv-nav__links zv-only-desktop">
27
+ <a class="zv-navlink" href="#">Produits</a>
28
+ <a class="zv-navlink" href="#">Méthode</a>
29
+ <a class="zv-navlink zv-navlink--quiet" href="#">Se connecter</a>
30
+ <a class="zv-btn zv-btn--sm" href="#">Réserver 30 min</a>
31
+ </span>
32
+ </nav>
33
+
34
+ <!-- Hero -->
35
+ <header class="zv-hero zv-gutter--wide">
36
+ <span class="zv-halo zv-halo--hero zv-anim-breathe" aria-hidden="true"></span>
37
+ <span class="zv-kicker zv-kicker--center">
38
+ <span class="zv-spec" aria-hidden="true"></span>
39
+ <span class="zv-mono">Planche de vérification</span>
40
+ </span>
41
+ <h1 class="zv-h1">Un système pour des outils <span class="zv-em">qui refusent de louer leur intelligence.</span></h1>
42
+ <p class="zv-lead">Cette page n'existe que pour regarder le paquet fonctionner : chaque composant y est posé une fois, dans son contexte.</p>
43
+ <span class="zv-tagline">Votre savoir, interrogeable en une phrase</span>
44
+ <span class="zv-btn-row">
45
+ <a class="zv-btn" href="#">Action principale</a>
46
+ <a class="zv-btn--ghost" href="#">Action secondaire</a>
47
+ </span>
48
+ </header>
49
+
50
+ <!-- Typographie -->
51
+ <section class="zv-gutter demo-sec">
52
+ <span class="zv-kicker"><span class="zv-spec" aria-hidden="true"></span><span class="zv-mono">01 · Typographie</span></span>
53
+ <div class="zv-grid-12" style="margin-top:28px">
54
+ <div class="zv-col-8">
55
+ <h2 class="zv-h2">Titre de section <span class="zv-em">en deux temps.</span></h2>
56
+ <p class="zv-lead demo-note">Chapô — 18px, gris, interligne 1.6.</p>
57
+ <p class="zv-body demo-note">Corps de texte à 15px. Un <strong>mot fort</strong> passe en encre.</p>
58
+ <p class="zv-body zv-body--dense demo-note">Variante dense à 13px, pour les légendes de carte.</p>
59
+ <p class="zv-rule demo-note">Texte de règle à 14px, celui des planches de documentation.</p>
60
+ </div>
61
+ <div class="zv-col-4">
62
+ <p class="zv-body zv-body--lg">Colonne d'accompagnement à 16px, alignée sur le bas du titre.</p>
63
+ </div>
64
+ </div>
65
+ </section>
66
+
67
+ <!-- Boutons et badges -->
68
+ <section class="zv-gutter demo-sec">
69
+ <span class="zv-kicker"><span class="zv-spec" aria-hidden="true"></span><span class="zv-mono">02 · Boutons et badges</span></span>
70
+ <div class="demo-row">
71
+ <a class="zv-btn" href="#">Bouton plein</a>
72
+ <a class="zv-btn--ghost" href="#">Fantôme</a>
73
+ <a class="zv-btn--ink" href="#">Encre</a>
74
+ <a class="zv-btn zv-btn--sm" href="#">Compact</a>
75
+ <button class="zv-btn" disabled>Désactivé</button>
76
+ <a class="zv-link-arrow" href="#">Lien fléché
77
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14"/><path d="M13 6l6 6-6 6"/></svg>
78
+ </a>
79
+ </div>
80
+ <div class="demo-row">
81
+ <span class="zv-pill">Pièce 01 · Connaissance</span>
82
+ <span class="zv-src-row">
83
+ <span class="zv-src">BOSS</span><span class="zv-src">Judilibre</span><span class="zv-src">KALI</span><span class="zv-src zv-src--quiet">+ 11</span>
84
+ </span>
85
+ <span class="zv-tag zv-tag--ok">Validé</span>
86
+ <span class="zv-tag zv-tag--err">Interdit</span>
87
+ </div>
88
+ <p class="zv-ent-text demo-row" style="display:block">Par acte du <span class="zv-ent">DATE_1</span>, la société <span class="zv-ent">SOCIÉTÉ_1</span> a cédé à <span class="zv-ent">PERSONNE_1</span> l'intégralité des parts.</p>
89
+ <div class="zv-progress" style="margin-top:24px"><span class="zv-progress__fill" style="width:38%"></span></div>
90
+ </section>
91
+
92
+ <!-- Cartes -->
93
+ <section class="zv-gutter demo-sec">
94
+ <span class="zv-kicker"><span class="zv-spec" aria-hidden="true"></span><span class="zv-mono">03 · Cartes et encarts</span></span>
95
+ <div class="zv-grid-3" style="margin-top:28px">
96
+ <article class="zv-card zv-card--pad-lg" style="display:flex;flex-direction:column;gap:18px;min-height:300px">
97
+ <span class="zv-mono zv-mono--label">Recherche</span>
98
+ <h3 class="zv-card-title">Une carte produit, avec sa preuve en bas.</h3>
99
+ <div class="zv-inset zv-inset--bottom">Réponse sourcée sur <span class="zv-inset__key">14 décisions</span>.</div>
100
+ </article>
101
+ <article class="zv-card zv-card--pad-lg" style="display:flex;flex-direction:column;gap:18px;min-height:300px">
102
+ <span class="zv-mono zv-mono--label">Rédaction</span>
103
+ <h3 class="zv-card-title">Encart de document, plus aéré.</h3>
104
+ <div class="zv-inset zv-inset--quiet zv-inset--bottom">Extrait de l'acte, restitué tel quel dans le fil du dossier.</div>
105
+ </article>
106
+ <article class="zv-card zv-card--pad-lg" style="display:flex;flex-direction:column;gap:18px;min-height:300px">
107
+ <span class="zv-mono zv-mono--label">Mesure</span>
108
+ <h3 class="zv-card-title">Statistiques de pied de carte.</h3>
109
+ <div class="zv-ministat zv-inset--bottom">
110
+ <div class="zv-ministat__item"><span class="zv-mono zv-mono--micro">Sources</span><span class="zv-ministat__value">1 240</span></div>
111
+ <div class="zv-ministat__item"><span class="zv-mono zv-mono--micro">Délai</span><span class="zv-ministat__value">1,8 s</span></div>
112
+ </div>
113
+ </article>
114
+ </div>
115
+ <div class="demo-row" style="align-items:stretch">
116
+ <div class="zv-card zv-card--ok zv-card--pad" style="flex:1"><span class="zv-tag zv-tag--ok">Oui</span><p class="zv-body zv-body--dense" style="margin-top:8px">Carte d'état validé.</p></div>
117
+ <div class="zv-card zv-card--err zv-card--pad" style="flex:1"><span class="zv-tag zv-tag--err">Non</span><p class="zv-body zv-body--dense" style="margin-top:8px">Carte d'état refusé.</p></div>
118
+ <div class="zv-stat-card"><span class="zv-mono zv-mono--micro">Cabinets</span><span class="zv-stat-card__value">38</span><span class="zv-body zv-body--dense">équipés cette année</span></div>
119
+ </div>
120
+ </section>
121
+
122
+ <!-- Surfaces -->
123
+ <section class="demo-sec">
124
+ <div class="zv-gutter">
125
+ <span class="zv-kicker"><span class="zv-spec" aria-hidden="true"></span><span class="zv-mono">04 · Surfaces</span></span>
126
+ </div>
127
+ <div style="position:relative;overflow:hidden;height:280px;margin-top:24px">
128
+ <span class="zv-grid-floor" aria-hidden="true"></span>
129
+ <span class="zv-fade" aria-hidden="true"></span>
130
+ <div class="zv-glass zv-gutter" style="position:relative;max-width:520px;margin:48px auto 0;padding-top:28px;padding-bottom:28px">
131
+ <span class="zv-mono zv-mono--label">Carte verre</span>
132
+ <p class="zv-body" style="margin-top:10px">Posée devant un sol quadrillé, avec son voile de fondu.</p>
133
+ </div>
134
+ </div>
135
+ </section>
136
+
137
+ <!-- Manifeste -->
138
+ <section class="zv-band" style="margin-top:64px">
139
+ <span class="zv-band__glow" aria-hidden="true"></span>
140
+ <div class="zv-band__content zv-gutter">
141
+ <span class="zv-kicker"><span class="zv-spec zv-spec--on-dark" aria-hidden="true"></span><span class="zv-mono zv-mono--on-dark">05 · Manifeste</span></span>
142
+ <h2 class="zv-h2" style="margin-top:24px;max-width:900px">La seule surface sombre du système, <span class="zv-em zv-em--on-dark">et elle ne s'obtient pas en inversant les neutres.</span></h2>
143
+ <p class="zv-body" style="margin-top:20px;max-width:560px">Les labels passent en indigo clair, les filets en blanc à 18 %.</p>
144
+ <div class="zv-stats" style="margin-top:40px">
145
+ <div class="zv-stat"><span class="zv-stat__value">5</span><span class="zv-mono zv-mono--micro zv-mono--on-dark">produits</span></div>
146
+ <div class="zv-stat"><span class="zv-stat__value">40</span><span class="zv-mono zv-mono--micro zv-mono--on-dark">logos</span></div>
147
+ <div class="zv-stat"><span class="zv-stat__value">32</span><span class="zv-mono zv-mono--micro zv-mono--on-dark">tokens</span></div>
148
+ </div>
149
+ </div>
150
+ </section>
151
+
152
+ <!-- Méthode -->
153
+ <section class="zv-gutter demo-sec">
154
+ <span class="zv-kicker"><span class="zv-spec" aria-hidden="true"></span><span class="zv-mono">06 · Méthode</span></span>
155
+ <div class="zv-steps" style="margin-top:36px">
156
+ <span class="zv-steps__rail" aria-hidden="true"></span>
157
+ <span class="zv-steps__progress" style="width:38%" aria-hidden="true"></span>
158
+ <div class="zv-step"><span class="zv-step__dot" aria-hidden="true"></span><span class="zv-mono zv-mono--label">Étape 01</span><h3 class="zv-card-title">Relever</h3><p class="zv-rule">Les valeurs viennent des maquettes, pas de l'intuition.</p></div>
159
+ <div class="zv-step"><span class="zv-step__dot zv-step__dot--violet" aria-hidden="true"></span><span class="zv-mono zv-mono--label">Étape 02</span><h3 class="zv-card-title">Arbitrer</h3><p class="zv-rule">Chaque désaccord est écrit, jamais tranché en silence.</p></div>
160
+ <div class="zv-step"><span class="zv-step__dot zv-step__dot--cyan" aria-hidden="true"></span><span class="zv-mono zv-mono--label">Étape 03</span><h3 class="zv-card-title">Verrouiller</h3><p class="zv-rule">Un test échoue si les deux sources divergent.</p></div>
161
+ </div>
162
+ </section>
163
+
164
+ <!-- Blocs de landing -->
165
+ <section class="zv-gutter demo-sec">
166
+ <span class="zv-kicker"><span class="zv-spec zv-anim-filet" aria-hidden="true"></span><span class="zv-mono">07 · Blocs de landing</span></span>
167
+ <h2 class="zv-h2 zv-h2--sm zv-anim-rise" style="margin-top:20px">Un titre de landing, <span class="zv-em">d'un cran plus court.</span></h2>
168
+ <div class="zv-grid-3" style="margin-top:28px;align-items:start">
169
+
170
+ <div class="zv-price zv-price--featured">
171
+ <span class="zv-pill">Early adopter</span>
172
+ <span class="zv-price__amount">1 250 € <span class="zv-price__unit">HT · 1re année</span></span>
173
+ <span class="zv-price__note">Puis 2 900 € HT plein tarif.</span>
174
+ <span class="zv-note" style="display:flex;align-items:center;gap:8px;margin-top:4px">
175
+ <span class="zv-check" aria-hidden="true"><svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg></span>
176
+ Mise en service incluse
177
+ </span>
178
+ </div>
179
+
180
+ <div class="zv-quote">
181
+ <span class="zv-spec zv-spec--on-dark" aria-hidden="true"></span>
182
+ <span class="zv-quote__text">« [Citation client à recueillir.] »</span>
183
+ <span class="zv-mono zv-mono--micro zv-mono--on-dark">[Nom, cabinet]</span>
184
+ </div>
185
+
186
+ <div class="zv-ui-preview">
187
+ <span class="zv-ui-preview__q">
188
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="M20 20l-3.5-3.5"/></svg>
189
+ Quelle clause de garantie depuis 2021 ?
190
+ </span>
191
+ <span class="zv-divider" aria-hidden="true"></span>
192
+ <span class="zv-ui-preview__a">Garantie autonome plafonnée à 40 %… <span class="zv-ui-preview__count">3 sources</span></span>
193
+ <span class="zv-src-row"><span class="zv-src">Consultation</span><span class="zv-src">Protocole</span></span>
194
+ </div>
195
+
196
+ </div>
197
+
198
+ <div class="zv-card" style="margin-top:24px;overflow:hidden">
199
+ <div class="zv-faq">
200
+ <div class="zv-faq__q">Où sont hébergées nos données ?
201
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg>
202
+ </div>
203
+ <div class="zv-faq__a">En France, sur infrastructure OVHcloud, dans un réseau privé cloisonné.</div>
204
+ </div>
205
+ </div>
206
+
207
+ <div class="zv-card" style="margin-top:24px">
208
+ <div class="zv-proof-bar">
209
+ <span class="zv-mono zv-mono--micro">Ils bâtissent avec nous</span>
210
+ <span class="zv-proof-bar__names"><span>Karila</span><span>Orange</span><span>Clesame</span><span>Beside Avocats</span><span>Dairia</span><span>BL-NK</span></span>
211
+ </div>
212
+ </div>
213
+ </section>
214
+
215
+ <!-- CTA -->
216
+ <section class="zv-cta zv-gutter--wide">
217
+ <span class="zv-halo zv-halo--cta" aria-hidden="true"></span>
218
+ <span class="zv-kicker zv-kicker--center"><span class="zv-spec" aria-hidden="true"></span><span class="zv-mono">Fin de planche</span></span>
219
+ <h2 class="zv-h2 zv-h2--cta">Le titre de CTA prend <span class="zv-em">un cran de plus.</span></h2>
220
+ <a class="zv-btn" href="#">Action finale</a>
221
+ </section>
222
+
223
+ <footer class="zv-footer zv-inset-x">
224
+ <div class="zv-footer__brand">
225
+ <span class="zv-spec zv-spec--sm" aria-hidden="true"></span>
226
+ <p class="zv-body zv-body--dense">Zevra UI — design system « Encre &amp; Papier ».</p>
227
+ <span class="zv-mono zv-mono--micro">Planche de vérification, hors paquet</span>
228
+ </div>
229
+ <div class="zv-footer__cols">
230
+ <div><span class="zv-mono zv-mono--micro zv-mono--ink" style="display:block">Modules</span><a class="zv-link" href="#">tokens</a><br><a class="zv-link" href="#">base</a><br><a class="zv-link" href="#">components</a></div>
231
+ <div><span class="zv-mono zv-mono--micro zv-mono--ink" style="display:block">Suite</span><a class="zv-link" href="#">layout</a><br><a class="zv-link" href="#">surfaces</a></div>
232
+ </div>
233
+ </footer>
234
+
235
+ <div class="zv-footer-mini">
236
+ <span class="zv-mono zv-mono--micro">Zevra · Legaltech souveraine · France</span>
237
+ <span class="zv-spec" style="width:32px" aria-hidden="true"></span>
238
+ </div>
239
+
240
+ </div>
241
+ </body>
242
+ </html>