@24vlh/vds 0.1.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.
Files changed (65) hide show
  1. package/LICENSE.txt +201 -0
  2. package/README.md +147 -0
  3. package/dist/components/accordion.css +170 -0
  4. package/dist/components/accordion.min.css +1 -0
  5. package/dist/components/authoring.css +332 -0
  6. package/dist/components/authoring.min.css +1 -0
  7. package/dist/components/buttons.css +683 -0
  8. package/dist/components/buttons.min.css +1 -0
  9. package/dist/components/charts.css +502 -0
  10. package/dist/components/charts.min.css +1 -0
  11. package/dist/components/command.css +521 -0
  12. package/dist/components/command.min.css +1 -0
  13. package/dist/components/content-blocks.css +944 -0
  14. package/dist/components/content-blocks.min.css +1 -0
  15. package/dist/components/doc-block.css +782 -0
  16. package/dist/components/doc-block.min.css +1 -0
  17. package/dist/components/feedback.css +657 -0
  18. package/dist/components/feedback.min.css +1 -0
  19. package/dist/components/flows.css +1101 -0
  20. package/dist/components/flows.min.css +1 -0
  21. package/dist/components/forms-advanced.css +462 -0
  22. package/dist/components/forms-advanced.min.css +1 -0
  23. package/dist/components/forms.css +1831 -0
  24. package/dist/components/forms.min.css +1 -0
  25. package/dist/components/header-footer.css +348 -0
  26. package/dist/components/header-footer.min.css +1 -0
  27. package/dist/components/hero.css +498 -0
  28. package/dist/components/hero.min.css +1 -0
  29. package/dist/components/icons.css +937 -0
  30. package/dist/components/icons.min.css +1 -0
  31. package/dist/components/navigation.css +900 -0
  32. package/dist/components/navigation.min.css +1 -0
  33. package/dist/components/overlays.css +498 -0
  34. package/dist/components/overlays.min.css +1 -0
  35. package/dist/components/sections.css +450 -0
  36. package/dist/components/sections.min.css +1 -0
  37. package/dist/components/skeleton.css +385 -0
  38. package/dist/components/skeleton.min.css +1 -0
  39. package/dist/components/tables.css +591 -0
  40. package/dist/components/tables.min.css +1 -0
  41. package/dist/components/tabs.css +307 -0
  42. package/dist/components/tabs.min.css +1 -0
  43. package/dist/components/toasts.css +421 -0
  44. package/dist/components/toasts.min.css +1 -0
  45. package/dist/components/tooltips-popovers.css +447 -0
  46. package/dist/components/tooltips-popovers.min.css +1 -0
  47. package/dist/components/typography.css +250 -0
  48. package/dist/components/typography.min.css +1 -0
  49. package/dist/components/utilities.css +3434 -0
  50. package/dist/components/utilities.min.css +1 -0
  51. package/dist/core.css +866 -0
  52. package/dist/core.min.css +1 -0
  53. package/dist/identity.css +266 -0
  54. package/dist/identity.min.css +1 -0
  55. package/dist/themes/carbon.css +658 -0
  56. package/dist/themes/carbon.min.css +1 -0
  57. package/dist/themes/graphite.css +658 -0
  58. package/dist/themes/graphite.min.css +1 -0
  59. package/dist/themes/navy.css +657 -0
  60. package/dist/themes/navy.min.css +1 -0
  61. package/dist/themes/slate.css +659 -0
  62. package/dist/themes/slate.min.css +1 -0
  63. package/dist/vds.css +20313 -0
  64. package/dist/vds.min.css +1 -0
  65. package/package.json +64 -0
@@ -0,0 +1,683 @@
1
+ /************************************************************
2
+ * VLAH DESIGN SYSTEM (VDS) - Buttons
3
+ *
4
+ * Responsibilities:
5
+ * - Provide a fully tokenised, theme-respecting button engine
6
+ * - Define consistent sizing, spacing, radii, and layout primitives
7
+ * - Expose semantic (primary/secondary), status (success/warning/info/danger),
8
+ * outline, ghost, soft, subtle, and link variants
9
+ * - Support interactive states: hover, active, pressed, selected, disabled,
10
+ * and loading (pure CSS spinner)
11
+ * - Maintain predictable focus, accessibility, and reduced-motion behaviour
12
+ *
13
+ * System Notes:
14
+ * - Pure CSS; no JS needed for pressed, disabled, or loading patterns
15
+ * - Strictly token-driven: all color, motion, and border values originate from
16
+ * primitives + active theme (Carbon, Graphite, Navy, Slate, Titanium)
17
+ * - Suitable for <button>, <a>, and role="button" elements with full ARIA support
18
+ ************************************************************/
19
+
20
+ /* ---------------------------------------------------------
21
+ 1. BASE BUTTON
22
+ --------------------------------------------------------- */
23
+
24
+ .button {
25
+ display: inline-flex;
26
+ align-items: center;
27
+ justify-content: center;
28
+ gap: var(--space-2);
29
+ padding-top: var(--space-2_5);
30
+ padding-bottom: var(--space-2_5);
31
+ padding-left: var(--space-5);
32
+ padding-right: var(--space-5);
33
+ border-radius: var(--radius-md);
34
+ border-width: var(--border-width);
35
+ border-style: solid;
36
+ font-family: inherit;
37
+ font-size: var(--text-sm);
38
+ font-weight: var(--font-weight-medium);
39
+ line-height: var(--line-height-xl-tight);
40
+ background: var(--color-surface);
41
+ border-color: var(--color-border-subtle);
42
+ color: var(--color-text);
43
+ cursor: pointer;
44
+ -webkit-text-decoration: none;
45
+ text-decoration: none;
46
+ white-space: normal;
47
+ -webkit-user-select: none;
48
+ -moz-user-select: none;
49
+ user-select: none;
50
+ transition: background-color var(--transition-normal), border-color var(--transition-normal), color var(--transition-normal), box-shadow var(--transition-normal), transform var(--transition-fast);
51
+ }
52
+
53
+ .button:focus-visible {
54
+ outline: none;
55
+ box-shadow: 0 0 0 1px var(--color-surface),
56
+ 0 0 0 3px var(--focus-ring-color, var(--color-accent-soft));
57
+ }
58
+
59
+ .button:hover:not(:disabled):not([aria-disabled="true"]) {
60
+ background: var(--color-surface-subtle, var(--color-muted-bg));
61
+ }
62
+
63
+ .button:active:not(:disabled):not([aria-disabled="true"]) {
64
+ transform: translateY(1px);
65
+ background: var(--color-surface-subtle, var(--color-muted-bg));
66
+ border-color: var(--color-border-strong, var(--color-border-subtle));
67
+ }
68
+
69
+ .button:disabled,
70
+ .button[aria-disabled="true"] {
71
+ opacity: 0.6;
72
+ cursor: not-allowed;
73
+ box-shadow: none;
74
+ transform: none;
75
+ background-color: var(--color-surface-subtle);
76
+ color: var(--color-text-muted);
77
+ border-color: var(--color-border-subtle);
78
+ }
79
+
80
+ .button--selected,
81
+ .button[aria-pressed="true"] {
82
+ box-shadow: 0 0 0 1px var(--color-surface),
83
+ 0 0 0 3px var(--focus-ring-color, var(--color-accent-soft));
84
+ }
85
+
86
+ /* ---------------------------------------------------------
87
+ 2. SIZE SCALE
88
+ --------------------------------------------------------- */
89
+
90
+ .button--sm {
91
+ padding-top: var(--space-1_5);
92
+ padding-bottom: var(--space-1_5);
93
+ padding-left: var(--space-3);
94
+ padding-right: var(--space-3);
95
+ }
96
+
97
+ .button--md {
98
+ padding-top: var(--space-2_5);
99
+ padding-bottom: var(--space-2_5);
100
+ padding-left: var(--space-5);
101
+ padding-right: var(--space-5);
102
+ }
103
+
104
+ .button--lg {
105
+ padding-top: var(--space-3_5);
106
+ padding-bottom: var(--space-3_5);
107
+ padding-left: var(--space-7);
108
+ padding-right: var(--space-7);
109
+ }
110
+
111
+ .button--nowrap {
112
+ white-space: nowrap;
113
+ }
114
+
115
+ /* ---------------------------------------------------------
116
+ 3. LAYOUT MODIFIERS
117
+ --------------------------------------------------------- */
118
+
119
+ .button--block {
120
+ display: flex;
121
+ width: 100%;
122
+ align-items: center;
123
+ justify-content: center;
124
+ }
125
+
126
+ .button--full-height {
127
+ height: 100%;
128
+ }
129
+
130
+ .button--icon {
131
+ padding: var(--space-2);
132
+ min-width: var(--space-8);
133
+ min-height: var(--space-8);
134
+ border-radius: var(--radius-full);
135
+ }
136
+
137
+ .button__icon {
138
+ flex-shrink: 0;
139
+ display: inline-flex;
140
+ align-items: center;
141
+ justify-content: center;
142
+ }
143
+
144
+ .button__icon--left {
145
+ margin-right: var(--space-2);
146
+ }
147
+
148
+ .button__icon--right {
149
+ margin-left: var(--space-2);
150
+ }
151
+
152
+ /* ---------------------------------------------------------
153
+ 4. NEUTRAL / SEMANTIC VARIANTS
154
+ --------------------------------------------------------- */
155
+
156
+ .button--primary {
157
+ background: var(--color-accent);
158
+ border-color: var(--color-accent-strong);
159
+ color: var(--color-on-accent);
160
+ }
161
+
162
+ .button--primary:hover:not(:disabled):not([aria-disabled="true"]) {
163
+ background: var(--color-accent-strong);
164
+ border-color: var(--color-accent-strong);
165
+ }
166
+
167
+ .button--primary:active:not(:disabled):not([aria-disabled="true"]) {
168
+ background: var(--color-accent-strong);
169
+ border-color: var(--color-accent-strong);
170
+ }
171
+
172
+ .button--primary:focus-visible {
173
+ box-shadow: 0 0 0 1px var(--color-accent-strong),
174
+ 0 0 0 3px var(--focus-ring-color, var(--color-accent-soft));
175
+ }
176
+
177
+ .button--primary:active:focus-visible {
178
+ box-shadow: 0 0 0 1px var(--color-accent-strong),
179
+ 0 0 0 3px var(--focus-ring-color, var(--color-accent-soft));
180
+ }
181
+
182
+ .button--secondary {
183
+ background: var(--color-surface);
184
+ border-color: var(--color-border-subtle);
185
+ color: var(--color-text);
186
+ }
187
+
188
+ .button--secondary:hover:not(:disabled):not([aria-disabled="true"]) {
189
+ background: var(--color-surface-subtle, var(--color-muted-bg));
190
+ border-color: var(--color-border-subtle);
191
+ }
192
+
193
+ .button--secondary:active:not(:disabled):not([aria-disabled="true"]) {
194
+ background: var(--color-surface-subtle, var(--color-muted-bg));
195
+ border-color: var(--color-border-strong, var(--color-border-subtle));
196
+ }
197
+
198
+ .button--secondary:focus-visible {
199
+ box-shadow: 0 0 0 1px var(--color-surface),
200
+ 0 0 0 3px var(--focus-ring-color, var(--color-accent-soft));
201
+ }
202
+
203
+ .button--soft {
204
+ background-color: var(--color-surface-subtle);
205
+ border-color: var(--button-soft-border, var(--color-border-subtle));
206
+ color: var(--button-soft-text, var(--color-text));
207
+ }
208
+
209
+ .button--soft:hover:not(:disabled):not([aria-disabled="true"]) {
210
+ background: var(--color-accent-soft-hover, var(--color-accent-soft));
211
+ border-color: var(--button-soft-border-hover, var(--color-border-strong));
212
+ }
213
+
214
+ .button--soft:active:not(:disabled):not([aria-disabled="true"]) {
215
+ background: var(--color-accent-soft-hover, var(--color-accent-soft));
216
+ border-color: transparent;
217
+ }
218
+
219
+ .button--soft:focus-visible {
220
+ box-shadow: 0 0 0 1px var(--color-accent-soft),
221
+ 0 0 0 3px var(--focus-ring-color, var(--color-accent-soft));
222
+ }
223
+
224
+ .button--ghost {
225
+ background: transparent;
226
+ border-color: transparent;
227
+ color: var(--color-text);
228
+ }
229
+
230
+ .button--ghost:hover:not(:disabled):not([aria-disabled="true"]) {
231
+ background: var(--color-muted-bg);
232
+ border-color: transparent;
233
+ }
234
+
235
+ .button--ghost:active:not(:disabled):not([aria-disabled="true"]) {
236
+ background: var(--color-muted-bg);
237
+ border-color: transparent;
238
+ }
239
+
240
+ .button--ghost:focus-visible {
241
+ box-shadow: 0 0 0 1px var(--color-muted-bg),
242
+ 0 0 0 3px var(--focus-ring-color, var(--color-accent-soft));
243
+ }
244
+
245
+ .button--subtle {
246
+ background: transparent;
247
+ border-color: transparent;
248
+ color: var(--color-text-muted);
249
+ }
250
+
251
+ .button--subtle:hover:not(:disabled):not([aria-disabled="true"]) {
252
+ background: var(--color-muted-bg);
253
+ color: var(--color-text);
254
+ }
255
+
256
+ .button--subtle:active:not(:disabled):not([aria-disabled="true"]) {
257
+ background: var(--color-muted-bg);
258
+ color: var(--color-text);
259
+ }
260
+
261
+ .button--subtle:focus-visible {
262
+ box-shadow: 0 0 0 1px var(--color-muted-bg),
263
+ 0 0 0 3px var(--focus-ring-color, var(--color-accent-soft));
264
+ }
265
+
266
+ /* ---------------------------------------------------------
267
+ 5. STATUS VARIANTS (SOLID)
268
+ --------------------------------------------------------- */
269
+
270
+ .button--success {
271
+ background: var(--color-success);
272
+ border-color: var(--color-success-strong);
273
+ color: var(--color-on-success);
274
+ }
275
+
276
+ .button--success:hover:not(:disabled):not([aria-disabled="true"]) {
277
+ background-color: var(--success-soft-surface-strong, var(--color-success-soft-hover));
278
+ border-color: var(--color-success-strong);
279
+ color: var(--success-soft-on);
280
+ }
281
+
282
+ .button--success:active:not(:disabled):not([aria-disabled="true"]) {
283
+ background: var(--color-success-strong);
284
+ border-color: var(--color-success-strong);
285
+ }
286
+
287
+ .button--success:focus-visible {
288
+ box-shadow: 0 0 0 1px var(--color-success-strong),
289
+ 0 0 0 3px var(--focus-ring-color, var(--color-success-soft));
290
+ }
291
+
292
+ .button--warning {
293
+ background: var(--color-warning);
294
+ border-color: var(--color-warning-strong);
295
+ color: var(--color-on-warning);
296
+ }
297
+
298
+ .button--warning:hover:not(:disabled):not([aria-disabled="true"]) {
299
+ background-color: var(--warning-soft-surface-strong, var(--color-warning-soft-hover));
300
+ border-color: var(--color-warning-strong);
301
+ color: var(--warning-soft-on);
302
+ }
303
+
304
+ .button--warning:active:not(:disabled):not([aria-disabled="true"]) {
305
+ background: var(--color-warning-strong);
306
+ border-color: var(--color-warning-strong);
307
+ }
308
+
309
+ .button--warning:focus-visible {
310
+ box-shadow: 0 0 0 1px var(--color-warning-strong),
311
+ 0 0 0 3px var(--focus-ring-color, var(--color-warning-soft));
312
+ }
313
+
314
+ .button--info {
315
+ background: var(--color-info);
316
+ border-color: var(--color-info-strong);
317
+ color: var(--color-on-info);
318
+ }
319
+
320
+ .button--info:hover:not(:disabled):not([aria-disabled="true"]) {
321
+ background-color: var(--info-soft-surface-strong, var(--color-info-soft-hover));
322
+ border-color: var(--color-info-strong);
323
+ color: var(--info-soft-on);
324
+ }
325
+
326
+ .button--info:active:not(:disabled):not([aria-disabled="true"]) {
327
+ background: var(--color-info-strong);
328
+ border-color: var(--color-info-strong);
329
+ }
330
+
331
+ .button--info:focus-visible {
332
+ box-shadow: 0 0 0 1px var(--color-info-strong),
333
+ 0 0 0 3px var(--focus-ring-color, var(--color-info-soft));
334
+ }
335
+
336
+ .button--danger {
337
+ background: var(--color-danger);
338
+ border-color: var(--color-danger-strong);
339
+ color: var(--color-on-danger);
340
+ }
341
+
342
+ .button--danger:hover:not(:disabled):not([aria-disabled="true"]) {
343
+ background-color: var(--danger-soft-surface-strong, var(--color-danger-soft-hover));
344
+ border-color: var(--color-danger-strong);
345
+ color: var(--danger-soft-on);
346
+ }
347
+
348
+ .button--danger:active:not(:disabled):not([aria-disabled="true"]) {
349
+ background: var(--color-danger-strong);
350
+ border-color: var(--color-danger-strong);
351
+ }
352
+
353
+ .button--danger:focus-visible {
354
+ box-shadow: 0 0 0 1px var(--color-danger-strong),
355
+ 0 0 0 3px var(--focus-ring-color, var(--color-danger-soft));
356
+ }
357
+
358
+ /* ---------------------------------------------------------
359
+ 6. OUTLINE VARIANTS
360
+ --------------------------------------------------------- */
361
+
362
+ .button--outline {
363
+ background: transparent;
364
+ border-color: var(--color-border-subtle);
365
+ color: var(--color-text);
366
+ }
367
+
368
+ .button--outline:hover:not(:disabled):not([aria-disabled="true"]) {
369
+ background: var(--color-surface-subtle, var(--color-muted-bg));
370
+ border-color: var(--color-border-strong, var(--color-border-subtle));
371
+ }
372
+
373
+ .button--outline:active:not(:disabled):not([aria-disabled="true"]) {
374
+ background: var(--color-surface-subtle, var(--color-muted-bg));
375
+ border-color: var(--color-border-strong, var(--color-border-subtle));
376
+ }
377
+
378
+ .button--outline:focus-visible {
379
+ box-shadow: 0 0 0 1px var(--color-border-strong, var(--color-border-subtle)),
380
+ 0 0 0 3px var(--focus-ring-color, var(--color-accent-soft));
381
+ }
382
+
383
+ .button--outline-accent {
384
+ background: transparent;
385
+ border-color: var(--color-accent);
386
+ color: var(--color-accent);
387
+ }
388
+
389
+ .button--outline-accent:hover:not(:disabled):not([aria-disabled="true"]) {
390
+ background-color: var(--button-outline-accent-hover-bg);
391
+ border-color: var(--button-outline-accent-hover-border, var(--color-accent-strong));
392
+ }
393
+
394
+ .button--outline-accent:active:not(:disabled):not([aria-disabled="true"]) {
395
+ background: var(--color-accent-soft);
396
+ border-color: var(--color-accent-strong);
397
+ }
398
+
399
+ .button--outline-accent:focus-visible {
400
+ box-shadow: 0 0 0 1px var(--color-accent-strong),
401
+ 0 0 0 3px var(--focus-ring-color, var(--color-accent-soft));
402
+ }
403
+
404
+ .button--outline-danger {
405
+ background: transparent;
406
+ border-color: var(--color-danger);
407
+ color: var(--color-danger);
408
+ }
409
+
410
+ .button--outline-danger:hover:not(:disabled):not([aria-disabled="true"]) {
411
+ background-color: var(--button-outline-danger-hover-bg);
412
+ border-color: var(--button-outline-danger-hover-border, var(--color-danger-strong));
413
+ }
414
+
415
+ .button--outline-danger:active:not(:disabled):not([aria-disabled="true"]) {
416
+ background: var(--color-danger-soft);
417
+ border-color: var(--color-danger-strong);
418
+ }
419
+
420
+ .button--outline-danger:focus-visible {
421
+ box-shadow: 0 0 0 1px var(--color-danger-strong),
422
+ 0 0 0 3px var(--focus-ring-color, var(--color-danger-soft));
423
+ }
424
+
425
+ .button--outline-success {
426
+ background: transparent;
427
+ border-color: var(--color-success);
428
+ color: var(--color-success);
429
+ }
430
+
431
+ .button--outline-success:hover:not(:disabled):not([aria-disabled="true"]) {
432
+ background-color: var(--button-outline-success-hover-bg);
433
+ border-color: var(--button-outline-success-hover-border, var(--color-success-strong));
434
+ }
435
+
436
+ .button--outline-success:active:not(:disabled):not([aria-disabled="true"]) {
437
+ background: var(--color-success-soft);
438
+ border-color: var(--color-success-strong);
439
+ }
440
+
441
+ .button--outline-success:focus-visible {
442
+ box-shadow: 0 0 0 1px var(--color-success-strong),
443
+ 0 0 0 3px var(--focus-ring-color, var(--color-success-soft));
444
+ }
445
+
446
+ .button--outline-warning {
447
+ background: transparent;
448
+ border-color: var(--color-warning);
449
+ color: var(--color-warning);
450
+ }
451
+
452
+ .button--outline-warning:hover:not(:disabled):not([aria-disabled="true"]) {
453
+ background-color: var(--button-outline-warning-hover-bg);
454
+ border-color: var(--button-outline-warning-hover-border, var(--color-warning-strong));
455
+ }
456
+
457
+ .button--outline-warning:active:not(:disabled):not([aria-disabled="true"]) {
458
+ background: var(--color-warning-soft);
459
+ border-color: var(--color-warning-strong);
460
+ }
461
+
462
+ .button--outline-warning:focus-visible {
463
+ box-shadow: 0 0 0 1px var(--color-warning-strong),
464
+ 0 0 0 3px var(--focus-ring-color, var(--color-warning-soft));
465
+ }
466
+
467
+ .button--outline-info {
468
+ background: transparent;
469
+ border-color: var(--color-info);
470
+ color: var(--color-info);
471
+ }
472
+
473
+ .button--outline-info:hover:not(:disabled):not([aria-disabled="true"]) {
474
+ background-color: var(--button-outline-info-hover-bg);
475
+ border-color: var(--button-outline-info-hover-border, var(--color-info-strong));
476
+ }
477
+
478
+ .button--outline-info:active:not(:disabled):not([aria-disabled="true"]) {
479
+ background: var(--color-info-soft);
480
+ border-color: var(--color-info-strong);
481
+ }
482
+
483
+ .button--outline-info:focus-visible {
484
+ box-shadow: 0 0 0 1px var(--color-info-strong),
485
+ 0 0 0 3px var(--focus-ring-color, var(--color-info-soft));
486
+ }
487
+
488
+ /* ---------------------------------------------------------
489
+ 7. LINK BUTTON
490
+ --------------------------------------------------------- */
491
+
492
+ .button--link {
493
+ background: transparent;
494
+ border-color: transparent;
495
+ color: var(--color-accent);
496
+ padding-left: 0;
497
+ padding-right: 0;
498
+ padding-top: 0;
499
+ padding-bottom: 0;
500
+ font-weight: 500;
501
+ }
502
+
503
+ .button--link:hover:not(:disabled):not([aria-disabled="true"]) {
504
+ -webkit-text-decoration: underline;
505
+ text-decoration: underline;
506
+ background: transparent;
507
+ }
508
+
509
+ .button--link:active:not(:disabled):not([aria-disabled="true"]) {
510
+ -webkit-text-decoration: underline;
511
+ text-decoration: underline;
512
+ background: transparent;
513
+ }
514
+
515
+ .button--link:focus-visible {
516
+ -webkit-text-decoration: underline;
517
+ text-decoration: underline;
518
+ box-shadow: 0 0 0 1px transparent,
519
+ 0 0 0 3px var(--focus-ring-color, var(--color-accent-soft));
520
+ }
521
+
522
+ .button--link:disabled,
523
+ .button--link[aria-disabled="true"] {
524
+ opacity: 0.6;
525
+ cursor: not-allowed;
526
+ -webkit-text-decoration: none;
527
+ text-decoration: none;
528
+ }
529
+
530
+ /* ---------------------------------------------------------
531
+ 8. LOADING STATE
532
+ --------------------------------------------------------- */
533
+
534
+ .button--loading {
535
+ position: relative;
536
+ pointer-events: none;
537
+ }
538
+
539
+ .button--loading > * {
540
+ visibility: hidden;
541
+ }
542
+
543
+ .button--loading::after {
544
+ content: "";
545
+ position: absolute;
546
+ top: 0;
547
+ right: 0;
548
+ bottom: 0;
549
+ left: 0;
550
+ margin: auto;
551
+ width: 1em;
552
+ height: 1em;
553
+ border-radius: 50%;
554
+ border: 2px solid currentColor;
555
+ border-top-color: transparent;
556
+ animation: button-spinner 0.8s linear infinite;
557
+ }
558
+
559
+ .button--loading:focus-visible {
560
+ box-shadow: 0 0 0 1px var(--color-surface),
561
+ 0 0 0 3px var(--focus-ring-color, var(--color-accent-soft));
562
+ }
563
+
564
+ @keyframes button-spinner {
565
+ to {
566
+ transform: rotate(360deg);
567
+ }
568
+ }
569
+
570
+ /* ---------------------------------------------------------
571
+ 9. REDUCED MOTION
572
+ --------------------------------------------------------- */
573
+
574
+ @media (prefers-reduced-motion: reduce) {
575
+ .button {
576
+ transition: none;
577
+ }
578
+
579
+ .button--loading::after {
580
+ animation: none;
581
+ border-top-color: currentColor;
582
+ }
583
+ }
584
+
585
+ /* ---------------------------------------------------------
586
+ 10. HELPERS
587
+ --------------------------------------------------------- */
588
+
589
+ .button--contrast-hover:hover:not(:disabled):not([aria-disabled="true"]) {
590
+ background: rgba(0, 0, 0, 0.12);
591
+ border-color: currentColor;
592
+ }
593
+
594
+ /* ---------------------------------------------------------
595
+ 11. LINK RESETS
596
+ --------------------------------------------------------- */
597
+
598
+ a.button,
599
+ a.button:hover,
600
+ a.button:focus,
601
+ a.button:active {
602
+ color: inherit;
603
+ -webkit-text-decoration: none;
604
+ text-decoration: none;
605
+ }
606
+
607
+ a.button[aria-disabled="true"],
608
+ a.button[aria-disabled="true"]:hover,
609
+ a.button[aria-disabled="true"]:focus,
610
+ a.button[aria-disabled="true"]:active {
611
+ pointer-events: none;
612
+ color: var(--color-text-muted);
613
+ -webkit-text-decoration: none;
614
+ text-decoration: none;
615
+ }
616
+
617
+ a.button--primary,
618
+ a.button--primary:hover,
619
+ a.button--primary:focus,
620
+ a.button--primary:active {
621
+ color: var(--color-on-accent);
622
+ }
623
+
624
+ a.button--secondary,
625
+ a.button--secondary:hover,
626
+ a.button--secondary:focus,
627
+ a.button--secondary:active {
628
+ color: var(--color-accent-strong);
629
+ }
630
+
631
+ a.button--ghost,
632
+ a.button--ghost:hover,
633
+ a.button--ghost:focus,
634
+ a.button--ghost:active {
635
+ color: var(--color-accent-soft);
636
+ }
637
+
638
+ a.button--subtle,
639
+ a.button--subtle:hover,
640
+ a.button--subtle:focus,
641
+ a.button--subtle:active {
642
+ color: var(--color-text);
643
+ }
644
+
645
+ a.button--neutral,
646
+ a.button--neutral:hover,
647
+ a.button--neutral:focus,
648
+ a.button--neutral:active {
649
+ color: var(--color-text-on-soft);
650
+ }
651
+
652
+ a.button--danger,
653
+ a.button--danger:hover,
654
+ a.button--danger:focus,
655
+ a.button--danger:active {
656
+ color: var(--color-on-danger);
657
+ }
658
+
659
+ a.button--warning,
660
+ a.button--warning:hover,
661
+ a.button--warning:focus,
662
+ a.button--warning:active {
663
+ color: var(--color-on-warning);
664
+ }
665
+
666
+ a.button--success,
667
+ a.button--success:hover,
668
+ a.button--success:focus,
669
+ a.button--success:active {
670
+ color: var(--color-on-success);
671
+ }
672
+
673
+ a.button--info,
674
+ a.button--info:hover,
675
+ a.button--info:focus,
676
+ a.button--info:active {
677
+ color: var(--color-on-info);
678
+ }
679
+
680
+ a.button:hover {
681
+ -webkit-text-decoration: none;
682
+ text-decoration: none;
683
+ }
@@ -0,0 +1 @@
1
+ .button{align-items:center;background:var(--color-surface);border-color:var(--color-border-subtle);border-radius:var(--radius-md);border-style:solid;border-width:var(--border-width);color:var(--color-text);cursor:pointer;display:inline-flex;font-family:inherit;font-size:var(--text-sm);font-weight:var(--font-weight-medium);gap:var(--space-2);justify-content:center;line-height:var(--line-height-xl-tight);padding:var(--space-2_5) var(--space-5);-webkit-text-decoration:none;text-decoration:none;transition:background-color var(--transition-normal),border-color var(--transition-normal),color var(--transition-normal),box-shadow var(--transition-normal),transform var(--transition-fast);-webkit-user-select:none;-moz-user-select:none;user-select:none;white-space:normal}.button:focus-visible{box-shadow:0 0 0 1px var(--color-surface),0 0 0 3px var(--focus-ring-color,var(--color-accent-soft));outline:none}.button:active:not(:disabled):not([aria-disabled=true]),.button:hover:not(:disabled):not([aria-disabled=true]){background:var(--color-surface-subtle,var(--color-muted-bg))}.button:active:not(:disabled):not([aria-disabled=true]){border-color:var(--color-border-strong,var(--color-border-subtle));transform:translateY(1px)}.button:disabled,.button[aria-disabled=true]{background-color:var(--color-surface-subtle);border-color:var(--color-border-subtle);box-shadow:none;color:var(--color-text-muted);cursor:not-allowed;opacity:.6;transform:none}.button--selected,.button[aria-pressed=true]{box-shadow:0 0 0 1px var(--color-surface),0 0 0 3px var(--focus-ring-color,var(--color-accent-soft))}.button--sm{padding:var(--space-1_5) var(--space-3)}.button--md{padding:var(--space-2_5) var(--space-5)}.button--lg{padding:var(--space-3_5) var(--space-7)}.button--nowrap{white-space:nowrap}.button--block{align-items:center;display:flex;justify-content:center;width:100%}.button--full-height{height:100%}.button--icon{border-radius:var(--radius-full);min-height:var(--space-8);min-width:var(--space-8);padding:var(--space-2)}.button__icon{align-items:center;display:inline-flex;flex-shrink:0;justify-content:center}.button__icon--left{margin-right:var(--space-2)}.button__icon--right{margin-left:var(--space-2)}.button--primary{background:var(--color-accent);border-color:var(--color-accent-strong);color:var(--color-on-accent)}.button--primary:active:not(:disabled):not([aria-disabled=true]),.button--primary:hover:not(:disabled):not([aria-disabled=true]){background:var(--color-accent-strong);border-color:var(--color-accent-strong)}.button--primary:focus-visible{box-shadow:0 0 0 1px var(--color-accent-strong),0 0 0 3px var(--focus-ring-color,var(--color-accent-soft))}.button--primary:active:focus-visible{box-shadow:0 0 0 1px var(--color-accent-strong),0 0 0 3px var(--focus-ring-color,var(--color-accent-soft))}.button--secondary{background:var(--color-surface);border-color:var(--color-border-subtle);color:var(--color-text)}.button--secondary:hover:not(:disabled):not([aria-disabled=true]){background:var(--color-surface-subtle,var(--color-muted-bg));border-color:var(--color-border-subtle)}.button--secondary:active:not(:disabled):not([aria-disabled=true]){background:var(--color-surface-subtle,var(--color-muted-bg));border-color:var(--color-border-strong,var(--color-border-subtle))}.button--secondary:focus-visible{box-shadow:0 0 0 1px var(--color-surface),0 0 0 3px var(--focus-ring-color,var(--color-accent-soft))}.button--soft{background-color:var(--color-surface-subtle);border-color:var(--button-soft-border,var(--color-border-subtle));color:var(--button-soft-text,var(--color-text))}.button--soft:hover:not(:disabled):not([aria-disabled=true]){background:var(--color-accent-soft-hover,var(--color-accent-soft));border-color:var(--button-soft-border-hover,var(--color-border-strong))}.button--soft:active:not(:disabled):not([aria-disabled=true]){background:var(--color-accent-soft-hover,var(--color-accent-soft));border-color:transparent}.button--soft:focus-visible{box-shadow:0 0 0 1px var(--color-accent-soft),0 0 0 3px var(--focus-ring-color,var(--color-accent-soft))}.button--ghost{background:transparent;border-color:transparent;color:var(--color-text)}.button--ghost:active:not(:disabled):not([aria-disabled=true]),.button--ghost:hover:not(:disabled):not([aria-disabled=true]){background:var(--color-muted-bg);border-color:transparent}.button--ghost:focus-visible{box-shadow:0 0 0 1px var(--color-muted-bg),0 0 0 3px var(--focus-ring-color,var(--color-accent-soft))}.button--subtle{background:transparent;border-color:transparent;color:var(--color-text-muted)}.button--subtle:active:not(:disabled):not([aria-disabled=true]),.button--subtle:hover:not(:disabled):not([aria-disabled=true]){background:var(--color-muted-bg);color:var(--color-text)}.button--subtle:focus-visible{box-shadow:0 0 0 1px var(--color-muted-bg),0 0 0 3px var(--focus-ring-color,var(--color-accent-soft))}.button--success{background:var(--color-success);border-color:var(--color-success-strong);color:var(--color-on-success)}.button--success:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--success-soft-surface-strong,var(--color-success-soft-hover));border-color:var(--color-success-strong);color:var(--success-soft-on)}.button--success:active:not(:disabled):not([aria-disabled=true]){background:var(--color-success-strong);border-color:var(--color-success-strong)}.button--success:focus-visible{box-shadow:0 0 0 1px var(--color-success-strong),0 0 0 3px var(--focus-ring-color,var(--color-success-soft))}.button--warning{background:var(--color-warning);border-color:var(--color-warning-strong);color:var(--color-on-warning)}.button--warning:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--warning-soft-surface-strong,var(--color-warning-soft-hover));border-color:var(--color-warning-strong);color:var(--warning-soft-on)}.button--warning:active:not(:disabled):not([aria-disabled=true]){background:var(--color-warning-strong);border-color:var(--color-warning-strong)}.button--warning:focus-visible{box-shadow:0 0 0 1px var(--color-warning-strong),0 0 0 3px var(--focus-ring-color,var(--color-warning-soft))}.button--info{background:var(--color-info);border-color:var(--color-info-strong);color:var(--color-on-info)}.button--info:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--info-soft-surface-strong,var(--color-info-soft-hover));border-color:var(--color-info-strong);color:var(--info-soft-on)}.button--info:active:not(:disabled):not([aria-disabled=true]){background:var(--color-info-strong);border-color:var(--color-info-strong)}.button--info:focus-visible{box-shadow:0 0 0 1px var(--color-info-strong),0 0 0 3px var(--focus-ring-color,var(--color-info-soft))}.button--danger{background:var(--color-danger);border-color:var(--color-danger-strong);color:var(--color-on-danger)}.button--danger:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--danger-soft-surface-strong,var(--color-danger-soft-hover));border-color:var(--color-danger-strong);color:var(--danger-soft-on)}.button--danger:active:not(:disabled):not([aria-disabled=true]){background:var(--color-danger-strong);border-color:var(--color-danger-strong)}.button--danger:focus-visible{box-shadow:0 0 0 1px var(--color-danger-strong),0 0 0 3px var(--focus-ring-color,var(--color-danger-soft))}.button--outline{background:transparent;border-color:var(--color-border-subtle);color:var(--color-text)}.button--outline:active:not(:disabled):not([aria-disabled=true]),.button--outline:hover:not(:disabled):not([aria-disabled=true]){background:var(--color-surface-subtle,var(--color-muted-bg));border-color:var(--color-border-strong,var(--color-border-subtle))}.button--outline:focus-visible{box-shadow:0 0 0 1px var(--color-border-strong,var(--color-border-subtle)),0 0 0 3px var(--focus-ring-color,var(--color-accent-soft))}.button--outline-accent{background:transparent;border-color:var(--color-accent);color:var(--color-accent)}.button--outline-accent:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--button-outline-accent-hover-bg);border-color:var(--button-outline-accent-hover-border,var(--color-accent-strong))}.button--outline-accent:active:not(:disabled):not([aria-disabled=true]){background:var(--color-accent-soft);border-color:var(--color-accent-strong)}.button--outline-accent:focus-visible{box-shadow:0 0 0 1px var(--color-accent-strong),0 0 0 3px var(--focus-ring-color,var(--color-accent-soft))}.button--outline-danger{background:transparent;border-color:var(--color-danger);color:var(--color-danger)}.button--outline-danger:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--button-outline-danger-hover-bg);border-color:var(--button-outline-danger-hover-border,var(--color-danger-strong))}.button--outline-danger:active:not(:disabled):not([aria-disabled=true]){background:var(--color-danger-soft);border-color:var(--color-danger-strong)}.button--outline-danger:focus-visible{box-shadow:0 0 0 1px var(--color-danger-strong),0 0 0 3px var(--focus-ring-color,var(--color-danger-soft))}.button--outline-success{background:transparent;border-color:var(--color-success);color:var(--color-success)}.button--outline-success:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--button-outline-success-hover-bg);border-color:var(--button-outline-success-hover-border,var(--color-success-strong))}.button--outline-success:active:not(:disabled):not([aria-disabled=true]){background:var(--color-success-soft);border-color:var(--color-success-strong)}.button--outline-success:focus-visible{box-shadow:0 0 0 1px var(--color-success-strong),0 0 0 3px var(--focus-ring-color,var(--color-success-soft))}.button--outline-warning{background:transparent;border-color:var(--color-warning);color:var(--color-warning)}.button--outline-warning:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--button-outline-warning-hover-bg);border-color:var(--button-outline-warning-hover-border,var(--color-warning-strong))}.button--outline-warning:active:not(:disabled):not([aria-disabled=true]){background:var(--color-warning-soft);border-color:var(--color-warning-strong)}.button--outline-warning:focus-visible{box-shadow:0 0 0 1px var(--color-warning-strong),0 0 0 3px var(--focus-ring-color,var(--color-warning-soft))}.button--outline-info{background:transparent;border-color:var(--color-info);color:var(--color-info)}.button--outline-info:hover:not(:disabled):not([aria-disabled=true]){background-color:var(--button-outline-info-hover-bg);border-color:var(--button-outline-info-hover-border,var(--color-info-strong))}.button--outline-info:active:not(:disabled):not([aria-disabled=true]){background:var(--color-info-soft);border-color:var(--color-info-strong)}.button--outline-info:focus-visible{box-shadow:0 0 0 1px var(--color-info-strong),0 0 0 3px var(--focus-ring-color,var(--color-info-soft))}.button--link{background:transparent;border-color:transparent;color:var(--color-accent);font-weight:500;padding:0}.button--link:active:not(:disabled):not([aria-disabled=true]),.button--link:hover:not(:disabled):not([aria-disabled=true]){background:transparent;-webkit-text-decoration:underline;text-decoration:underline}.button--link:focus-visible{box-shadow:0 0 0 1px transparent,0 0 0 3px var(--focus-ring-color,var(--color-accent-soft));-webkit-text-decoration:underline;text-decoration:underline}.button--link:disabled,.button--link[aria-disabled=true]{cursor:not-allowed;opacity:.6;-webkit-text-decoration:none;text-decoration:none}.button--loading{pointer-events:none;position:relative}.button--loading>*{visibility:hidden}.button--loading:after{animation:button-spinner .8s linear infinite;border:2px solid;border-radius:50%;border-top:2px solid transparent;bottom:0;content:"";height:1em;left:0;margin:auto;position:absolute;right:0;top:0;width:1em}.button--loading:focus-visible{box-shadow:0 0 0 1px var(--color-surface),0 0 0 3px var(--focus-ring-color,var(--color-accent-soft))}@keyframes button-spinner{to{transform:rotate(1turn)}}@media (prefers-reduced-motion:reduce){.button{transition:none}.button--loading:after{animation:none;border-top-color:currentColor}}.button--contrast-hover:hover:not(:disabled):not([aria-disabled=true]){background:rgba(0,0,0,.12);border-color:currentColor}a.button,a.button:active,a.button:focus,a.button:hover{color:inherit;-webkit-text-decoration:none;text-decoration:none}a.button[aria-disabled=true],a.button[aria-disabled=true]:active,a.button[aria-disabled=true]:focus,a.button[aria-disabled=true]:hover{color:var(--color-text-muted);pointer-events:none;-webkit-text-decoration:none;text-decoration:none}a.button--primary,a.button--primary:active,a.button--primary:focus,a.button--primary:hover{color:var(--color-on-accent)}a.button--secondary,a.button--secondary:active,a.button--secondary:focus,a.button--secondary:hover{color:var(--color-accent-strong)}a.button--ghost,a.button--ghost:active,a.button--ghost:focus,a.button--ghost:hover{color:var(--color-accent-soft)}a.button--subtle,a.button--subtle:active,a.button--subtle:focus,a.button--subtle:hover{color:var(--color-text)}a.button--neutral,a.button--neutral:active,a.button--neutral:focus,a.button--neutral:hover{color:var(--color-text-on-soft)}a.button--danger,a.button--danger:active,a.button--danger:focus,a.button--danger:hover{color:var(--color-on-danger)}a.button--warning,a.button--warning:active,a.button--warning:focus,a.button--warning:hover{color:var(--color-on-warning)}a.button--success,a.button--success:active,a.button--success:focus,a.button--success:hover{color:var(--color-on-success)}a.button--info,a.button--info:active,a.button--info:focus,a.button--info:hover{color:var(--color-on-info)}a.button:hover{-webkit-text-decoration:none;text-decoration:none}