bruv-ui 0.2.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 (44) hide show
  1. package/dist/area-chart.d.ts +84 -0
  2. package/dist/area-chart.js +2002 -0
  3. package/dist/area-chart.js.map +1 -0
  4. package/dist/bar-chart.d.ts +80 -0
  5. package/dist/bar-chart.js +2251 -0
  6. package/dist/bar-chart.js.map +1 -0
  7. package/dist/chart-background-BK77UXhl.d.ts +9 -0
  8. package/dist/chart-brush-BoxY9aDm.d.ts +72 -0
  9. package/dist/chart-dot-8H287EDv.d.ts +17 -0
  10. package/dist/chart-legend-Dv9pqes-.d.ts +16 -0
  11. package/dist/chart-tooltip-DajpzJRy.d.ts +68 -0
  12. package/dist/charts.d.ts +17 -0
  13. package/dist/charts.js +5097 -0
  14. package/dist/charts.js.map +1 -0
  15. package/dist/composed-chart.d.ts +93 -0
  16. package/dist/composed-chart.js +2338 -0
  17. package/dist/composed-chart.js.map +1 -0
  18. package/dist/form-dK_DJRTw.d.ts +43 -0
  19. package/dist/form-rhf.d.ts +26 -0
  20. package/dist/form-rhf.js +268 -0
  21. package/dist/form-rhf.js.map +1 -0
  22. package/dist/index.d.ts +2881 -0
  23. package/dist/index.js +9368 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/line-chart.d.ts +81 -0
  26. package/dist/line-chart.js +1879 -0
  27. package/dist/line-chart.js.map +1 -0
  28. package/dist/pie-chart.d.ts +64 -0
  29. package/dist/pie-chart.js +1094 -0
  30. package/dist/pie-chart.js.map +1 -0
  31. package/dist/radar-chart.d.ts +67 -0
  32. package/dist/radar-chart.js +1318 -0
  33. package/dist/radar-chart.js.map +1 -0
  34. package/dist/radial-chart.d.ts +56 -0
  35. package/dist/radial-chart.js +1051 -0
  36. package/dist/radial-chart.js.map +1 -0
  37. package/dist/sankey-chart.d.ts +58 -0
  38. package/dist/sankey-chart.js +1179 -0
  39. package/dist/sankey-chart.js.map +1 -0
  40. package/package.json +135 -0
  41. package/src/scales.css +288 -0
  42. package/src/shiki.css +37 -0
  43. package/src/styles.css +23 -0
  44. package/src/theme.css +659 -0
package/src/theme.css ADDED
@@ -0,0 +1,659 @@
1
+ /*
2
+ * ═══════════════════════════════════════════════════════════════
3
+ * Semantic Color Tokens
4
+ *
5
+ * Maps raw scale steps (from scales.css) to meaningful names.
6
+ * All tokens are explicitly scoped to their Tailwind namespace:
7
+ * --background-color-* → generates bg-* only
8
+ * --text-color-* → generates text-* only
9
+ * --border-color-* → generates border-* only
10
+ * --ring-color-* → generates ring-* only
11
+ *
12
+ * Raw scales (--color-bruv-mauve-*, --color-bruv-red-*, etc.)
13
+ * remain in the --color-* namespace for direct use in gradients
14
+ * and other edge cases at the component level.
15
+ *
16
+ * All tokens are prefixed with `bruv-` to avoid collisions
17
+ * when imported alongside other design systems.
18
+ * ═══════════════════════════════════════════════════════════════
19
+ */
20
+
21
+ :root {
22
+ /* ── Shadow border tint: black in light, white in dark ── */
23
+ --bruv-border-tint: 0 0 0;
24
+ /* ── Button top highlight opacity ── */
25
+ --bruv-button-highlight-alpha: 0.4;
26
+ }
27
+
28
+ [data-theme="dark"] {
29
+ color-scheme: dark;
30
+ --bruv-border-tint: 1 0 0;
31
+ --bruv-button-highlight-alpha: 0.12;
32
+ }
33
+
34
+ @theme {
35
+ /*
36
+ * ═══════════════════════════════════════
37
+ * TYPOGRAPHY — Geist (sans) + Hack (mono)
38
+ *
39
+ * Font families resolve through Tailwind's
40
+ * font-bruv-sans / font-bruv-mono utilities.
41
+ *
42
+ * 4 sizes: sm (12px), base (14px default),
43
+ * lg (18px headings), xl (24px page titles).
44
+ * 2 weights: font-medium (default), font-semibold.
45
+ *
46
+ * All tokens prefixed with `bruv-` to avoid
47
+ * collisions with Tailwind built-ins.
48
+ * ═══════════════════════════════════════
49
+ */
50
+ --font-bruv-sans:
51
+ "Geist Variable", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",
52
+ "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
53
+ --font-bruv-mono:
54
+ "Hack", ui-monospace, "SFMono-Regular", "Menlo", "Monaco", "Consolas",
55
+ "Liberation Mono", "Courier New", monospace;
56
+
57
+ /* Size scale — 12 (sm) / 14 (base / body) / 18 (lg) / 24 (xl) */
58
+ --text-bruv-sm: 0.75rem; /* 12px */
59
+ --text-bruv-sm--line-height: 1rem; /* 16px */
60
+ --text-bruv-base: 0.875rem; /* 14px — body default */
61
+ --text-bruv-base--line-height: 1.25rem; /* 20px */
62
+ --text-bruv-lg: 1.125rem; /* 18px */
63
+ --text-bruv-lg--line-height: 1.75rem; /* 28px */
64
+ --text-bruv-xl: 1.5rem; /* 24px */
65
+ --text-bruv-xl--line-height: 2rem; /* 32px */
66
+
67
+ --radius-bruv: 0.375rem;
68
+ --radius-bruv-sm: calc(var(--radius-bruv) - 2px);
69
+ --radius-bruv-md: var(--radius-bruv);
70
+ --radius-bruv-lg: calc(var(--radius-bruv) + 2px);
71
+ --radius-bruv-xl: calc(var(--radius-bruv) + 4px);
72
+
73
+ /*
74
+ * ═══════════════════════════════════════
75
+ * BACKGROUNDS — 3 spatial layers
76
+ *
77
+ * bruv-base-0: page shell / surround (deepest)
78
+ * bruv-base-1: main content area
79
+ * bruv-base-2: elevated cards, panels, popovers
80
+ * ═══════════════════════════════════════
81
+ */
82
+ --background-color-bruv-base-0: var(--color-bruv-mauve-4);
83
+ --background-color-bruv-base-1: var(--color-bruv-mauve-2);
84
+ --background-color-bruv-base-2: var(--color-bruv-mauve-1);
85
+
86
+ /*
87
+ * ═══════════════════════════════════════
88
+ * INTERACTIVE — Alpha-based hover/highlight
89
+ *
90
+ * Works on any background layer because it's
91
+ * a semi-transparent overlay, not a fixed color.
92
+ * ═══════════════════════════════════════
93
+ */
94
+ --background-color-bruv-subtle: oklch(var(--bruv-border-tint) / 0.06);
95
+
96
+ /*
97
+ * ═══════════════════════════════════════
98
+ * TEXT — 3 hierarchy levels
99
+ * ═══════════════════════════════════════
100
+ */
101
+ --text-color-bruv-primary: var(--color-bruv-mauve-12);
102
+ --text-color-bruv-secondary: var(--color-bruv-mauve-11);
103
+ --text-color-bruv-tertiary: var(--color-bruv-mauve-9);
104
+
105
+ /*
106
+ * ═══════════════════════════════════════
107
+ * FILL — matching bg tokens for use with
108
+ * SVG fill/stroke and divider backgrounds
109
+ * ═══════════════════════════════════════
110
+ */
111
+ --background-color-bruv-neutral: var(--color-bruv-mauve-5);
112
+ --background-color-bruv-tertiary: var(--color-bruv-mauve-9);
113
+
114
+ /*
115
+ * ═══════════════════════════════════════
116
+ * BORDERS — 2 levels
117
+ * ═══════════════════════════════════════
118
+ */
119
+ --border-color-bruv-neutral: var(--color-bruv-mauve-5);
120
+ --border-color-bruv-neutral-strong: var(--color-bruv-mauve-7);
121
+
122
+ --ring-color-bruv-neutral: var(--color-bruv-mauve-5);
123
+ --ring-color-bruv-focus: var(--color-bruv-accent-9);
124
+
125
+ /*
126
+ * ═══════════════════════════════════════
127
+ * ACCENT — Bruv brand periwinkle
128
+ * ═══════════════════════════════════════
129
+ */
130
+ --background-color-bruv-accent: var(--color-bruv-accent-9);
131
+ --background-color-bruv-accent-subtle: var(--color-bruv-accent-3);
132
+ --background-color-bruv-accent-strong: var(--color-bruv-accent-10);
133
+ --background-color-bruv-accent-on: oklch(0.99 0 0);
134
+ --text-color-bruv-accent: var(--color-bruv-accent-11);
135
+ --text-color-bruv-accent-on: oklch(0.99 0 0);
136
+ --border-color-bruv-accent: var(--color-bruv-accent-8);
137
+
138
+ /*
139
+ * ═══════════════════════════════════════
140
+ * DANGER — Radix red scale
141
+ * ═══════════════════════════════════════
142
+ */
143
+ --background-color-bruv-danger: var(--color-bruv-red-10);
144
+ --background-color-bruv-danger-subtle: var(--color-bruv-red-3);
145
+ --background-color-bruv-danger-strong: var(--color-bruv-red-11);
146
+ --background-color-bruv-danger-on: oklch(0.99 0 0);
147
+ --text-color-bruv-danger: var(--color-bruv-red-11);
148
+ --text-color-bruv-danger-on: oklch(0.99 0 0);
149
+ --border-color-bruv-danger: var(--color-bruv-red-11);
150
+
151
+ /*
152
+ * ═══════════════════════════════════════
153
+ * WARN — Radix amber scale
154
+ * ═══════════════════════════════════════
155
+ */
156
+ --background-color-bruv-warn: var(--color-bruv-amber-9);
157
+ --background-color-bruv-warn-subtle: var(--color-bruv-amber-3);
158
+ --background-color-bruv-warn-strong: var(--color-bruv-amber-10);
159
+ --background-color-bruv-warn-on: oklch(0.15 0 0);
160
+ --text-color-bruv-warn: var(--color-bruv-amber-11);
161
+ --text-color-bruv-warn-on: oklch(0.15 0 0);
162
+ --border-color-bruv-warn: var(--color-bruv-amber-8);
163
+
164
+ /*
165
+ * ═══════════════════════════════════════
166
+ * SUCCESS — secondary (mint) scale
167
+ * ═══════════════════════════════════════
168
+ */
169
+ --background-color-bruv-success: var(--color-bruv-secondary-9);
170
+ --background-color-bruv-success-subtle: var(--color-bruv-secondary-3);
171
+ --background-color-bruv-success-strong: var(--color-bruv-secondary-10);
172
+ --background-color-bruv-success-on: oklch(0.99 0 0);
173
+ --text-color-bruv-success: var(--color-bruv-secondary-11);
174
+ --text-color-bruv-success-on: oklch(0.99 0 0);
175
+ --border-color-bruv-success: var(--color-bruv-secondary-8);
176
+
177
+ /*
178
+ * ═══════════════════════════════════════
179
+ * SHADOWS
180
+ * ═══════════════════════════════════════
181
+ */
182
+ --inset-shadow-bruv-border: inset 0 0 0 1px
183
+ oklch(var(--bruv-border-tint) / 0.06);
184
+ --inset-shadow-bruv-button: inset 0 1px 0 0
185
+ oklch(1 0 0 / var(--bruv-button-highlight-alpha));
186
+ --inset-shadow-bruv-primary:
187
+ inset 0 1px 0 0 oklch(1 0 0 / 0.15), inset 0 -1px 0 0 oklch(0 0 0 / 0.15);
188
+
189
+ /*
190
+ * ═══════════════════════════════════════
191
+ * INVERSE — Flipped contrast pair
192
+ *
193
+ * bg-bruv-inverse: near-black in light, near-white in dark
194
+ * text-bruv-inverse: near-white in light, near-black in dark
195
+ *
196
+ * Pulled slightly from the extremes so the inset-shadow-bruv-primary
197
+ * top highlight and bottom shadow are both visible.
198
+ * ═══════════════════════════════════════
199
+ */
200
+ --background-color-bruv-inverse: oklch(0.28 0.005 305);
201
+ --text-color-bruv-inverse: var(--color-bruv-mauve-1);
202
+
203
+ /*
204
+ * ═══════════════════════════════════════
205
+ * SPECIAL
206
+ * ═══════════════════════════════════════
207
+ */
208
+ --background-color-bruv-overlay: oklch(0 0 0 / 0.4);
209
+
210
+ --color-bruv-chart-grid: var(--color-bruv-mauve-5);
211
+ --color-bruv-chart-axis: var(--color-bruv-mauve-9);
212
+ --color-bruv-chart-cursor: var(--color-bruv-mauve-7);
213
+
214
+ /**
215
+ * Easing Functions
216
+ */
217
+ --ease-bruv-in-quad: cubic-bezier(0.55, 0.085, 0.68, 0.53);
218
+ --ease-bruv-in-cubic: cubic-bezier(0.55, 0.055, 0.675, 0.19);
219
+ --ease-bruv-in-quart: cubic-bezier(0.895, 0.03, 0.685, 0.22);
220
+ --ease-bruv-in-quint: cubic-bezier(0.755, 0.05, 0.855, 0.06);
221
+ --ease-bruv-in-expo: cubic-bezier(0.95, 0.05, 0.795, 0.035);
222
+ --ease-bruv-in-circ: cubic-bezier(0.6, 0.04, 0.98, 0.335);
223
+
224
+ --ease-bruv-out-quad: cubic-bezier(0.25, 0.46, 0.45, 0.94);
225
+ --ease-bruv-out-cubic: cubic-bezier(0.215, 0.61, 0.355, 1);
226
+ --ease-bruv-out-quart: cubic-bezier(0.165, 0.84, 0.44, 1);
227
+ --ease-bruv-out-quint: cubic-bezier(0.23, 1, 0.32, 1);
228
+ --ease-bruv-out-expo: cubic-bezier(0.19, 1, 0.22, 1);
229
+ --ease-bruv-out-circ: cubic-bezier(0.075, 0.82, 0.165, 1);
230
+
231
+ --ease-bruv-in-out-quad: cubic-bezier(0.455, 0.03, 0.515, 0.955);
232
+ --ease-bruv-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1);
233
+ --ease-bruv-in-out-quart: cubic-bezier(0.77, 0, 0.175, 1);
234
+ --ease-bruv-in-out-quint: cubic-bezier(0.86, 0, 0.07, 1);
235
+ --ease-bruv-in-out-expo: cubic-bezier(1, 0, 0, 1);
236
+ --ease-bruv-in-out-circ: cubic-bezier(0.785, 0.135, 0.15, 0.86);
237
+
238
+ /**
239
+ * Animations
240
+ */
241
+ --animate-bruv-dot-cycle: bruv-dot-cycle 1.2s steps(1) infinite;
242
+ --animate-bruv-select-in: bruv-select-in 200ms var(--ease-bruv-out-expo);
243
+ --animate-bruv-select-out: bruv-select-out 150ms var(--ease-bruv-in-quad);
244
+ --animate-bruv-shimmer: bruv-shimmer 2s infinite linear;
245
+ --animate-bruv-shake: bruv-shake 400ms var(--ease-bruv-out-cubic);
246
+ }
247
+
248
+ /*
249
+ * ═══════════════════════════════════════════════════════════════
250
+ * DARK MODE SEMANTIC OVERRIDES
251
+ * ═══════════════════════════════════════════════════════════════
252
+ */
253
+ [data-theme="dark"] {
254
+ /* Backgrounds: lighter = more elevated in dark mode too */
255
+ --background-color-bruv-base-0: var(--color-bruv-mauve-1);
256
+ --background-color-bruv-base-1: var(--color-bruv-mauve-2);
257
+ --background-color-bruv-base-2: var(--color-bruv-mauve-3);
258
+
259
+ /* Neutral strong: more visible border in dark mode */
260
+ --border-color-bruv-neutral-strong: var(--color-bruv-mauve-7);
261
+
262
+ /* Accent */
263
+ --background-color-bruv-accent: var(--color-bruv-accent-9);
264
+ --background-color-bruv-accent-strong: var(--color-bruv-accent-8);
265
+ --ring-color-bruv-focus: var(--color-bruv-accent-9);
266
+
267
+ /* Danger */
268
+ --background-color-bruv-danger: var(--color-bruv-red-9);
269
+ --background-color-bruv-danger-strong: var(--color-bruv-red-8);
270
+ --border-color-bruv-danger: var(--color-bruv-red-7);
271
+
272
+ /* Warning */
273
+ --background-color-bruv-warn: var(--color-bruv-amber-9);
274
+ --background-color-bruv-warn-strong: var(--color-bruv-amber-10);
275
+
276
+ /* Inverse: pulled back from pure white so highlights/shadows are visible */
277
+ --background-color-bruv-inverse: oklch(0.9 0.005 305);
278
+
279
+ /* Success */
280
+ --background-color-bruv-success: var(--color-bruv-secondary-9);
281
+ --background-color-bruv-success-strong: var(--color-bruv-secondary-10);
282
+
283
+ --color-bruv-chart-grid: var(--color-bruv-mauve-6);
284
+ --color-bruv-chart-axis: var(--color-bruv-mauve-11);
285
+ --color-bruv-chart-cursor: var(--color-bruv-mauve-8);
286
+ }
287
+
288
+ /*
289
+ * ═══════════════════════════════════════════════════════════════
290
+ * KEYFRAMES
291
+ * ═══════════════════════════════════════════════════════════════
292
+ */
293
+ @keyframes braille-snake {
294
+ 0% {
295
+ content: "⣾";
296
+ }
297
+ 6.25% {
298
+ content: "⣽";
299
+ }
300
+ 12.5% {
301
+ content: "⣻";
302
+ }
303
+ 18.75% {
304
+ content: "⢿";
305
+ }
306
+ 25% {
307
+ content: "⡿";
308
+ }
309
+ 31.25% {
310
+ content: "⣟";
311
+ }
312
+ 37.5% {
313
+ content: "⣯";
314
+ }
315
+ 43.75% {
316
+ content: "⣷";
317
+ }
318
+ 50% {
319
+ content: "⣾";
320
+ }
321
+ 56.25% {
322
+ content: "⣽";
323
+ }
324
+ 62.5% {
325
+ content: "⣻";
326
+ }
327
+ 68.75% {
328
+ content: "⢿";
329
+ }
330
+ 75% {
331
+ content: "⡿";
332
+ }
333
+ 81.25% {
334
+ content: "⣟";
335
+ }
336
+ 87.5% {
337
+ content: "⣯";
338
+ }
339
+ 93.75% {
340
+ content: "⣷";
341
+ }
342
+ 100% {
343
+ content: "⣾";
344
+ }
345
+ }
346
+
347
+ @keyframes bruv-dot-cycle {
348
+ 0% {
349
+ content: ".";
350
+ }
351
+ 33% {
352
+ content: "..";
353
+ }
354
+ 66% {
355
+ content: "...";
356
+ }
357
+ 100% {
358
+ content: ".";
359
+ }
360
+ }
361
+
362
+ @keyframes bruv-select-in {
363
+ from {
364
+ opacity: 0;
365
+ transform: scale(0.7);
366
+ }
367
+ to {
368
+ opacity: 1;
369
+ transform: scale(1);
370
+ }
371
+ }
372
+
373
+ @keyframes bruv-select-out {
374
+ from {
375
+ opacity: 1;
376
+ transform: scale(1);
377
+ }
378
+ to {
379
+ opacity: 0;
380
+ transform: scale(0.7);
381
+ }
382
+ }
383
+
384
+ @keyframes bruv-shimmer {
385
+ 0% {
386
+ background-position: 200% 0;
387
+ }
388
+ 100% {
389
+ background-position: -200% 0;
390
+ }
391
+ }
392
+
393
+ @keyframes slide-in-from-right {
394
+ from {
395
+ opacity: 0;
396
+ transform: translateX(6px);
397
+ }
398
+ }
399
+
400
+ @keyframes slide-in-from-left {
401
+ from {
402
+ opacity: 0;
403
+ transform: translateX(-6px);
404
+ }
405
+ }
406
+
407
+ @keyframes slide-in-from-bottom {
408
+ from {
409
+ opacity: 0;
410
+ transform: translateY(6px);
411
+ }
412
+ }
413
+
414
+ @keyframes slide-in-from-top {
415
+ from {
416
+ opacity: 0;
417
+ transform: translateY(-6px);
418
+ }
419
+ }
420
+
421
+ @keyframes slide-out-to-right {
422
+ to {
423
+ opacity: 0;
424
+ transform: translateX(6px);
425
+ }
426
+ }
427
+
428
+ @keyframes slide-out-to-left {
429
+ to {
430
+ opacity: 0;
431
+ transform: translateX(-6px);
432
+ }
433
+ }
434
+
435
+ @keyframes slide-out-to-bottom {
436
+ to {
437
+ opacity: 0;
438
+ transform: translateY(6px);
439
+ }
440
+ }
441
+
442
+ @keyframes slide-out-to-top {
443
+ to {
444
+ opacity: 0;
445
+ transform: translateY(-6px);
446
+ }
447
+ }
448
+
449
+ @keyframes check-pop {
450
+ from {
451
+ opacity: 0;
452
+ transform: scale(0.8);
453
+ }
454
+ to {
455
+ opacity: 1;
456
+ transform: scale(1);
457
+ }
458
+ }
459
+
460
+ @keyframes bruv-shake {
461
+ 0%,
462
+ 100% {
463
+ transform: translateX(0);
464
+ }
465
+ 20% {
466
+ transform: translateX(-6px);
467
+ }
468
+ 40% {
469
+ transform: translateX(5px);
470
+ }
471
+ 60% {
472
+ transform: translateX(-3px);
473
+ }
474
+ 80% {
475
+ transform: translateX(2px);
476
+ }
477
+ }
478
+
479
+ @keyframes check-out {
480
+ from {
481
+ opacity: 1;
482
+ transform: scale(1);
483
+ }
484
+ to {
485
+ opacity: 0;
486
+ transform: scale(0.8);
487
+ }
488
+ }
489
+
490
+ /*
491
+ * ═══════════════════════════════════════════════════════════════
492
+ * TOAST — Stacking, animation, and swipe styles
493
+ *
494
+ * Matches Sonner's DOM structure: <section> (ARIA) > <ol> (fixed
495
+ * positioned toaster) > <li> (absolute positioned toasts).
496
+ *
497
+ * All dynamic values flow through CSS custom properties set by JS:
498
+ * ol: --gap, --front-toast-height, --toast-width
499
+ * li: --index, --toasts-before, --z-index, --offset,
500
+ * --initial-height, --swipe-amount
501
+ * ═══════════════════════════════════════════════════════════════
502
+ */
503
+
504
+ /* ── Toast base ── */
505
+ .bruv-toast {
506
+ z-index: var(--z-index);
507
+ transition:
508
+ transform 400ms,
509
+ opacity 400ms,
510
+ height 400ms;
511
+ }
512
+
513
+ /* Content fades in/out for collapsed non-front toasts */
514
+ .bruv-toast > * {
515
+ transition: opacity 400ms;
516
+ }
517
+
518
+ /* ── Lift direction ── */
519
+ .bruv-toast[data-y-position="bottom"] {
520
+ --lift: -1;
521
+ }
522
+ .bruv-toast[data-y-position="top"] {
523
+ --lift: 1;
524
+ }
525
+
526
+ /* ── Initial state: off-screen ── */
527
+ .bruv-toast:not([data-mounted="true"]) {
528
+ opacity: 0;
529
+ }
530
+ .bruv-toast[data-y-position="bottom"]:not([data-mounted="true"]) {
531
+ transform: translateY(100%);
532
+ }
533
+ .bruv-toast[data-y-position="top"]:not([data-mounted="true"]) {
534
+ transform: translateY(-100%);
535
+ }
536
+
537
+ /* ── Mounted: animate in ── */
538
+ .bruv-toast[data-mounted="true"] {
539
+ opacity: 1;
540
+ }
541
+
542
+ /* ── Collapsed stack (not expanded) ── */
543
+ .bruv-toast[data-expanded="false"][data-front="true"][data-mounted="true"] {
544
+ transform: translateY(0);
545
+ }
546
+ .bruv-toast[data-expanded="false"][data-front="false"][data-mounted="true"] {
547
+ height: var(--front-toast-height);
548
+ overflow: hidden;
549
+ transform: translateY(calc(var(--lift) * var(--gap) * var(--toasts-before)))
550
+ scale(calc(1 - var(--toasts-before) * 0.03));
551
+ }
552
+ .bruv-toast[data-expanded="false"][data-front="false"][data-mounted="true"]
553
+ > * {
554
+ opacity: 0;
555
+ }
556
+
557
+ /* ── Expanded stack (hover) ── */
558
+ .bruv-toast[data-expanded="true"][data-mounted="true"] {
559
+ height: var(--initial-height);
560
+ transform: translateY(calc(var(--lift) * var(--offset)));
561
+ }
562
+ .bruv-toast[data-expanded="true"][data-mounted="true"] > * {
563
+ opacity: 1;
564
+ }
565
+
566
+ /* ── Gap bridge (prevents mouseout between toasts) ── */
567
+ .bruv-toast[data-expanded="true"]::after {
568
+ content: "";
569
+ position: absolute;
570
+ left: 0;
571
+ width: 100%;
572
+ height: calc(var(--gap) + 1px);
573
+ }
574
+ .bruv-toast[data-y-position="bottom"][data-expanded="true"]::after {
575
+ bottom: 100%;
576
+ }
577
+ .bruv-toast[data-y-position="top"][data-expanded="true"]::after {
578
+ top: 100%;
579
+ }
580
+
581
+ /* ── Hidden toasts beyond visible limit ── */
582
+ .bruv-toast[data-visible="false"] {
583
+ opacity: 0 !important;
584
+ pointer-events: none !important;
585
+ }
586
+
587
+ /* ── Removed: exit animation ── */
588
+ .bruv-toast[data-removed="true"][data-front="true"][data-swipe-out="false"] {
589
+ transform: translateY(calc(var(--lift) * -100%));
590
+ opacity: 0;
591
+ }
592
+ .bruv-toast[data-removed="true"][data-front="false"][data-swipe-out="false"][data-expanded="true"] {
593
+ transform: translateY(
594
+ calc(var(--lift) * var(--offset) + var(--lift) * -100%)
595
+ );
596
+ opacity: 0;
597
+ }
598
+ .bruv-toast[data-removed="true"][data-front="false"][data-swipe-out="false"][data-expanded="false"] {
599
+ transform: translateY(40%);
600
+ opacity: 0;
601
+ transition:
602
+ transform 500ms,
603
+ opacity 200ms;
604
+ }
605
+
606
+ /* ── Swiping (drag in progress) ── */
607
+ .bruv-toast[data-swiping="true"] {
608
+ transform: translateY(calc(var(--lift) * var(--offset)))
609
+ translateX(var(--swipe-amount, 0px));
610
+ transition: none;
611
+ user-select: none;
612
+ }
613
+
614
+ /* ── Swipe out ── */
615
+ .bruv-toast[data-swipe-out="true"] {
616
+ animation: bruv-toast-swipe-out 200ms ease-out forwards;
617
+ }
618
+
619
+ @keyframes bruv-toast-swipe-out {
620
+ from {
621
+ transform: translateY(calc(var(--lift) * var(--offset)))
622
+ translateX(var(--swipe-amount, 0px));
623
+ opacity: 1;
624
+ }
625
+ to {
626
+ transform: translateY(calc(var(--lift) * var(--offset)))
627
+ translateX(
628
+ calc(var(--swipe-amount, 0px) + 100% * sign(var(--swipe-amount, 1px)))
629
+ );
630
+ opacity: 0;
631
+ }
632
+ }
633
+
634
+ /* ── Promise toast: icon crossfade on state change ── */
635
+ .bruv-toast[data-promise-state="success"] .bruv-toast-icon > *,
636
+ .bruv-toast[data-promise-state="error"] .bruv-toast-icon > * {
637
+ animation: bruv-toast-icon-in 300ms ease forwards;
638
+ }
639
+
640
+ @keyframes bruv-toast-icon-in {
641
+ from {
642
+ opacity: 0;
643
+ transform: scale(0.6);
644
+ }
645
+ to {
646
+ opacity: 1;
647
+ transform: scale(1);
648
+ }
649
+ }
650
+
651
+ /* ── Reduced motion ── */
652
+ @media (prefers-reduced-motion) {
653
+ .bruv-toast,
654
+ .bruv-toast > *,
655
+ .bruv-toast .bruv-toast-icon > * {
656
+ transition: none !important;
657
+ animation: none !important;
658
+ }
659
+ }