@agence-zef/astro 0.3.1 → 0.5.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/styles.css ADDED
@@ -0,0 +1,468 @@
1
+ /*
2
+ * Habillage facultatif des composants de @agence-zef/astro : champs de formulaire (Form,
3
+ * AccountForm, Checkout, panier, Field / Input / Select / Checkbox), boutons, Dialog,
4
+ * Accordion, Popover, popups et bandeau cookies.
5
+ *
6
+ * - Importé une fois (`import "@agence-zef/astro/styles.css"` dans le gabarit).
7
+ * - Toutes les règles sont en `:where()` : aucune priorité, la moindre règle du site passe devant.
8
+ * - Tout se règle par les variables `--zef-*` ci-dessous, à redéfinir dans `:root` du site
9
+ * (ex. `--zef-accent: var(--color-accent)`).
10
+ */
11
+
12
+ :where(:root) {
13
+ --zef-font: inherit;
14
+ --zef-text: currentColor;
15
+ --zef-muted: color-mix(in srgb, currentColor 62%, transparent);
16
+ --zef-surface: #fff;
17
+ --zef-surface-muted: color-mix(in srgb, currentColor 5%, transparent);
18
+ --zef-border: color-mix(in srgb, currentColor 18%, transparent);
19
+ --zef-border-strong: color-mix(in srgb, currentColor 35%, transparent);
20
+ --zef-accent: #18181b;
21
+ --zef-on-accent: #fff;
22
+ --zef-danger: #c62828;
23
+ --zef-success: #2e7d32;
24
+ --zef-focus: 0 0 0 3px color-mix(in srgb, var(--zef-accent) 30%, transparent);
25
+ --zef-radius: 0.5rem;
26
+ --zef-radius-small: 0.25rem;
27
+ --zef-gap: 1rem;
28
+ --zef-input-height: 2.75rem;
29
+ --zef-input-padding: 0.75rem;
30
+ --zef-shadow: 0 12px 40px rgb(0 0 0 / 0.16);
31
+ --zef-backdrop: rgb(0 0 0 / 0.45);
32
+ --zef-dialog-width: 32rem;
33
+ --zef-popover-width: 18rem;
34
+ --zef-duration: 0.2s;
35
+ }
36
+
37
+ /* ---------- Formulaires ---------- */
38
+
39
+ :where(.zef-account, .zef-checkout fieldset, .zef-cart-add) {
40
+ display: flex;
41
+ flex-direction: column;
42
+ gap: var(--zef-gap);
43
+ font-family: var(--zef-font);
44
+ }
45
+ /* Formulaire du CMS : champs en pleine largeur ou en demi-largeur (`data-width="half"`). */
46
+ :where(.zef-form) {
47
+ display: flex;
48
+ flex-wrap: wrap;
49
+ gap: var(--zef-gap);
50
+ font-family: var(--zef-font);
51
+ }
52
+ :where(.zef-form) > :where(*) {
53
+ flex: 1 1 100%;
54
+ }
55
+ /* Champs masqués (logique conditionnelle, erreurs vides) : `hidden` l'emporte sur `display`. */
56
+ :where(.zef-form, .zef-account, .zef-checkout, .zef-cart, .zef-cart-add, .zef-field)
57
+ :where([hidden]) {
58
+ /* biome-ignore lint/complexity/noImportantStyles: `hidden` doit gagner sur tout `display` du site. */
59
+ display: none !important;
60
+ }
61
+ :where(.zef-checkout fieldset) {
62
+ margin: 0;
63
+ padding: 0;
64
+ border: 0;
65
+ }
66
+ :where(.zef-checkout legend, .zef-form legend, .zef-account legend) {
67
+ margin-bottom: 0.5rem;
68
+ padding: 0;
69
+ font-weight: 600;
70
+ }
71
+
72
+ /* Champ : libellé au-dessus du contrôle. */
73
+ :where(.zef-field, .zef-form__field, .zef-account__field, .zef-checkout fieldset > label) {
74
+ display: flex;
75
+ flex-direction: column;
76
+ gap: 0.375rem;
77
+ min-width: 0;
78
+ }
79
+ :where(
80
+ .zef-label,
81
+ .zef-form__label,
82
+ .zef-account__field > label:not(:has(input[type="checkbox"])),
83
+ .zef-checkout fieldset > label
84
+ ) {
85
+ font-weight: 600;
86
+ font-size: 0.9375rem;
87
+ }
88
+ :where(.zef-required) {
89
+ color: var(--zef-danger);
90
+ }
91
+ :where(.zef-form__field[data-width="half"]) {
92
+ flex: 1 1 calc(50% - var(--zef-gap) / 2);
93
+ }
94
+
95
+ /* Zones de saisie et listes. */
96
+ :where(
97
+ .zef-input,
98
+ .zef-select,
99
+ :is(.zef-form, .zef-account, .zef-checkout, .zef-cart, .zef-cart-add, .zef-subscriptions)
100
+ :is(
101
+ input:not(
102
+ [type="checkbox"],
103
+ [type="radio"],
104
+ [type="hidden"],
105
+ [type="file"],
106
+ [type="submit"],
107
+ [type="button"]
108
+ ),
109
+ select,
110
+ textarea
111
+ )
112
+ ) {
113
+ box-sizing: border-box;
114
+ width: 100%;
115
+ min-height: var(--zef-input-height);
116
+ padding: 0 var(--zef-input-padding);
117
+ border: 1px solid var(--zef-border-strong);
118
+ border-radius: var(--zef-radius);
119
+ background: var(--zef-surface);
120
+ color: inherit;
121
+ font: inherit;
122
+ transition:
123
+ border-color var(--zef-duration),
124
+ box-shadow var(--zef-duration);
125
+ }
126
+ :where(textarea.zef-input, :is(.zef-form, .zef-account, .zef-cart-add) textarea) {
127
+ min-height: 7.5rem;
128
+ padding-block: var(--zef-input-padding);
129
+ resize: vertical;
130
+ }
131
+ :where(
132
+ .zef-input,
133
+ .zef-select,
134
+ :is(.zef-form, .zef-account, .zef-checkout, .zef-cart, .zef-cart-add, .zef-subscriptions)
135
+ :is(input, select, textarea)
136
+ ):focus-visible {
137
+ border-color: var(--zef-accent);
138
+ outline: none;
139
+ box-shadow: var(--zef-focus);
140
+ }
141
+ :where(
142
+ .zef-input[aria-invalid="true"],
143
+ .zef-select[aria-invalid="true"],
144
+ [data-invalid] :is(input, select, textarea)
145
+ ) {
146
+ border-color: var(--zef-danger);
147
+ }
148
+ :where(
149
+ .zef-input,
150
+ .zef-select,
151
+ :is(.zef-form, .zef-account, .zef-checkout) :is(input, select, textarea)
152
+ ):disabled {
153
+ opacity: 0.55;
154
+ cursor: not-allowed;
155
+ }
156
+ :where(.zef-form input[type="file"]) {
157
+ font: inherit;
158
+ }
159
+
160
+ /* Cases à cocher et boutons radio. */
161
+ :where(
162
+ .zef-check,
163
+ .zef-form__check,
164
+ .zef-account label:has(> input[type="checkbox"]),
165
+ .zef-checkout label:has(> input:is([type="checkbox"], [type="radio"])),
166
+ .zef-cart-add label:has(> input[type="radio"])
167
+ ) {
168
+ display: flex;
169
+ align-items: flex-start;
170
+ gap: 0.625rem;
171
+ font-weight: 400;
172
+ cursor: pointer;
173
+ }
174
+ :where(.zef-check, .zef-form__check, .zef-account, .zef-checkout, .zef-cart-add, .zef-cookies)
175
+ :where(input[type="checkbox"], input[type="radio"]) {
176
+ flex-shrink: 0;
177
+ width: 1.125rem;
178
+ height: 1.125rem;
179
+ margin: 0.125rem 0 0;
180
+ accent-color: var(--zef-accent);
181
+ }
182
+ :where(.zef-form__choices) {
183
+ display: flex;
184
+ flex-direction: column;
185
+ gap: 0.5rem;
186
+ margin: 0;
187
+ padding: 0;
188
+ border: 0;
189
+ }
190
+
191
+ /* Aide, erreurs, messages. */
192
+ :where(.zef-help, .zef-account__help, .zef-account__optional, .zef-checkout__optional) {
193
+ color: var(--zef-muted);
194
+ font-size: 0.875rem;
195
+ font-weight: 400;
196
+ }
197
+ :where(.zef-error, .zef-form__error, .zef-account__error, .zef-checkout__error, .zef-cart__error) {
198
+ margin: 0;
199
+ color: var(--zef-danger);
200
+ font-size: 0.875rem;
201
+ }
202
+ :where(.zef-form__status, .zef-account__notice, .zef-checkout__notice, .zef-cart__warning) {
203
+ margin: 0;
204
+ padding: 0.75rem 1rem;
205
+ border-radius: var(--zef-radius);
206
+ background: var(--zef-surface-muted);
207
+ }
208
+ :where(.zef-account__success, .zef-cart__success, .zef-subscriptions__success, .zef-form__done) {
209
+ color: var(--zef-success);
210
+ }
211
+
212
+ /* ---------- Boutons ---------- */
213
+
214
+ :where(
215
+ .zef-button,
216
+ .zef-form__submit,
217
+ .zef-account__submit,
218
+ .zef-checkout__submit,
219
+ .zef-cart__checkout,
220
+ .zef-cart-add button[type="submit"],
221
+ .zef-subscriptions__cancel
222
+ ) {
223
+ display: inline-flex;
224
+ align-items: center;
225
+ justify-content: center;
226
+ gap: 0.5rem;
227
+ min-height: var(--zef-input-height);
228
+ padding: 0 1.25rem;
229
+ border: 1px solid var(--zef-accent);
230
+ border-radius: var(--zef-radius);
231
+ background: var(--zef-accent);
232
+ color: var(--zef-on-accent);
233
+ font: inherit;
234
+ font-weight: 600;
235
+ text-decoration: none;
236
+ cursor: pointer;
237
+ transition:
238
+ filter var(--zef-duration),
239
+ opacity var(--zef-duration);
240
+ }
241
+ :where(.zef-button[data-variant="secondary"], .zef-subscriptions__cancel) {
242
+ background: transparent;
243
+ color: var(--zef-accent);
244
+ }
245
+ :where(
246
+ .zef-button,
247
+ .zef-form__submit,
248
+ .zef-account__submit,
249
+ .zef-checkout__submit,
250
+ .zef-cart__checkout
251
+ ):hover {
252
+ filter: brightness(1.12);
253
+ }
254
+ :where(.zef-button, .zef-form__submit, .zef-account__submit, .zef-checkout__submit):focus-visible {
255
+ outline: none;
256
+ box-shadow: var(--zef-focus);
257
+ }
258
+ :where(.zef-button, .zef-form__submit, .zef-account__submit, .zef-checkout__submit):disabled {
259
+ opacity: 0.55;
260
+ cursor: progress;
261
+ }
262
+ :where(.zef-form__submit, .zef-account__submit) {
263
+ align-self: flex-start;
264
+ }
265
+
266
+ /* ---------- Dialog et popups ---------- */
267
+
268
+ :where(.zef-dialog, .zef-popup) {
269
+ box-sizing: border-box;
270
+ width: min(var(--zef-dialog-width), calc(100vw - 2rem));
271
+ max-height: calc(100dvh - 2rem);
272
+ padding: 0;
273
+ border: 0;
274
+ border-radius: calc(var(--zef-radius) * 1.5);
275
+ background: var(--zef-surface);
276
+ color: inherit;
277
+ box-shadow: var(--zef-shadow);
278
+ overflow: auto;
279
+ }
280
+ :where(.zef-dialog, .zef-popup)::backdrop {
281
+ background: var(--zef-backdrop);
282
+ }
283
+ :where(.zef-dialog__panel) {
284
+ position: relative;
285
+ padding: 2rem;
286
+ }
287
+ :where(.zef-dialog__close, .zef-popup__close) {
288
+ position: absolute;
289
+ top: 0.75rem;
290
+ right: 0.75rem;
291
+ display: grid;
292
+ place-items: center;
293
+ width: 2.25rem;
294
+ height: 2.25rem;
295
+ padding: 0;
296
+ border: 0;
297
+ border-radius: 999px;
298
+ background: transparent;
299
+ color: inherit;
300
+ cursor: pointer;
301
+ }
302
+ :where(.zef-dialog__close, .zef-popup__close):hover {
303
+ background: var(--zef-surface-muted);
304
+ }
305
+ @media (prefers-reduced-motion: no-preference) {
306
+ :where(.zef-dialog[open], .zef-popup[open]) {
307
+ animation: zef-dialog-in var(--zef-duration) cubic-bezier(0.16, 1, 0.3, 1);
308
+ }
309
+ :where(.zef-dialog[open])::backdrop {
310
+ animation: zef-fade-in var(--zef-duration) ease-out;
311
+ }
312
+ :where(.zef-dialog[data-closing]) {
313
+ animation: zef-dialog-out calc(var(--zef-duration) * 0.75) ease-in forwards;
314
+ }
315
+ :where(.zef-dialog[data-closing])::backdrop {
316
+ animation: zef-fade-out calc(var(--zef-duration) * 0.75) ease-in forwards;
317
+ }
318
+ }
319
+ @keyframes zef-dialog-in {
320
+ from {
321
+ opacity: 0;
322
+ transform: translateY(0.5rem) scale(0.98);
323
+ }
324
+ }
325
+ @keyframes zef-dialog-out {
326
+ to {
327
+ opacity: 0;
328
+ transform: translateY(0.5rem) scale(0.98);
329
+ }
330
+ }
331
+ @keyframes zef-fade-in {
332
+ from {
333
+ opacity: 0;
334
+ }
335
+ }
336
+ @keyframes zef-fade-out {
337
+ to {
338
+ opacity: 0;
339
+ }
340
+ }
341
+
342
+ /* ---------- Accordéon ---------- */
343
+
344
+ :where(.zef-accordion) {
345
+ display: flex;
346
+ flex-direction: column;
347
+ border-top: 1px solid var(--zef-border);
348
+ }
349
+ :where(.zef-accordion__item) {
350
+ border-bottom: 1px solid var(--zef-border);
351
+ /* Hauteur animée (navigateurs récents) ; sinon ouverture instantanée. */
352
+ interpolate-size: allow-keywords;
353
+ }
354
+ :where(.zef-accordion__summary) {
355
+ display: flex;
356
+ align-items: center;
357
+ justify-content: space-between;
358
+ gap: 1rem;
359
+ padding: 1.125rem 0;
360
+ font-weight: 600;
361
+ list-style: none;
362
+ cursor: pointer;
363
+ }
364
+ :where(.zef-accordion__summary)::-webkit-details-marker {
365
+ display: none;
366
+ }
367
+ :where(.zef-accordion__summary)::after {
368
+ content: "";
369
+ flex-shrink: 0;
370
+ width: 0.5rem;
371
+ height: 0.5rem;
372
+ margin-right: 0.25rem;
373
+ border-right: 1.5px solid currentColor;
374
+ border-bottom: 1.5px solid currentColor;
375
+ transform: translateY(-25%) rotate(45deg);
376
+ transition: transform var(--zef-duration);
377
+ }
378
+ :where(.zef-accordion__item[open] > .zef-accordion__summary)::after {
379
+ transform: translateY(25%) rotate(-135deg);
380
+ }
381
+ :where(.zef-accordion__summary):focus-visible {
382
+ outline: none;
383
+ box-shadow: var(--zef-focus);
384
+ border-radius: var(--zef-radius-small);
385
+ }
386
+ :where(.zef-accordion__content) {
387
+ padding-bottom: 1.25rem;
388
+ color: var(--zef-muted);
389
+ }
390
+ :where(.zef-accordion__content) > :first-child {
391
+ margin-top: 0;
392
+ }
393
+ :where(.zef-accordion__content) > :last-child {
394
+ margin-bottom: 0;
395
+ }
396
+ @media (prefers-reduced-motion: no-preference) {
397
+ :where(.zef-accordion__item)::details-content {
398
+ block-size: 0;
399
+ overflow: hidden;
400
+ transition:
401
+ block-size var(--zef-duration) ease,
402
+ content-visibility var(--zef-duration) allow-discrete;
403
+ }
404
+ :where(.zef-accordion__item[open])::details-content {
405
+ block-size: auto;
406
+ }
407
+ }
408
+
409
+ /* ---------- Popover ---------- */
410
+
411
+ :where(.zef-popover) {
412
+ box-sizing: border-box;
413
+ width: min(var(--zef-popover-width), calc(100vw - 2rem));
414
+ margin: 0;
415
+ padding: 1rem;
416
+ border: 1px solid var(--zef-border);
417
+ border-radius: var(--zef-radius);
418
+ background: var(--zef-surface);
419
+ color: inherit;
420
+ box-shadow: var(--zef-shadow);
421
+ /* Positionnement d'ancre : sous le bouton qui l'ouvre, retourné s'il manque de place. */
422
+ position-area: block-end span-inline-end;
423
+ position-try-fallbacks: flip-block, flip-inline;
424
+ margin-block: 0.375rem;
425
+ }
426
+ :where(.zef-popover[data-placement="top"]) {
427
+ position-area: block-start span-inline-end;
428
+ }
429
+ :where(.zef-popover[data-placement="right"]) {
430
+ position-area: inline-end span-block-end;
431
+ margin: 0 0.375rem;
432
+ }
433
+ :where(.zef-popover[data-placement="left"]) {
434
+ position-area: inline-start span-block-end;
435
+ margin: 0 0.375rem;
436
+ }
437
+ @supports not (position-area: block-end) {
438
+ :where(.zef-popover) {
439
+ margin: auto;
440
+ }
441
+ }
442
+ @media (prefers-reduced-motion: no-preference) {
443
+ :where(.zef-popover) {
444
+ transition:
445
+ opacity var(--zef-duration),
446
+ transform var(--zef-duration),
447
+ overlay var(--zef-duration) allow-discrete,
448
+ display var(--zef-duration) allow-discrete;
449
+ opacity: 0;
450
+ transform: translateY(-0.25rem);
451
+ }
452
+ :where(.zef-popover:popover-open) {
453
+ opacity: 1;
454
+ transform: none;
455
+ }
456
+ @starting-style {
457
+ :where(.zef-popover:popover-open) {
458
+ opacity: 0;
459
+ transform: translateY(-0.25rem);
460
+ }
461
+ }
462
+ }
463
+
464
+ @media (max-width: 40rem) {
465
+ :where(.zef-form__field[data-width="half"]) {
466
+ flex-basis: 100%;
467
+ }
468
+ }