@codenhub/styles 0.0.2

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.
@@ -0,0 +1,657 @@
1
+ @import "tailwindcss";
2
+ @import "./theme.css";
3
+
4
+ @keyframes codenhub-skeleton {
5
+ 0% {
6
+ background-position: 200% 0;
7
+ }
8
+
9
+ 100% {
10
+ background-position: -200% 0;
11
+ }
12
+ }
13
+
14
+ @layer components {
15
+ .sect {
16
+ @apply flex flex-col items-center justify-center gap-[clamp(2rem,5vw,4rem)] px-(--layout-gutter) py-(--layout-section-block);
17
+ }
18
+
19
+ .sect-container,
20
+ .sect-inn {
21
+ @apply mx-auto flex w-full flex-col gap-[clamp(1.5rem,4vw,3rem)];
22
+
23
+ max-width: var(--container-max);
24
+
25
+ &.narrow {
26
+ max-width: var(--container-narrow);
27
+ }
28
+
29
+ &.wide {
30
+ max-width: var(--container-wide);
31
+ }
32
+
33
+ &.left {
34
+ @apply items-start;
35
+ }
36
+
37
+ &.right {
38
+ @apply items-end;
39
+ }
40
+
41
+ &.center {
42
+ @apply items-center;
43
+ }
44
+ }
45
+
46
+ .stack {
47
+ @apply flex flex-col gap-(--layout-stack-gap);
48
+
49
+ &.tight {
50
+ --layout-stack-gap: 0.5rem;
51
+ }
52
+
53
+ &.loose {
54
+ --layout-stack-gap: 1.5rem;
55
+ }
56
+ }
57
+
58
+ .cluster {
59
+ @apply flex flex-wrap items-center gap-(--layout-cluster-gap);
60
+
61
+ &.between {
62
+ @apply justify-between;
63
+ }
64
+ }
65
+
66
+ .auto-grid {
67
+ @apply grid gap-(--layout-stack-gap);
68
+
69
+ grid-template-columns: repeat(auto-fit, minmax(min(var(--layout-grid-min), 100%), 1fr));
70
+ }
71
+
72
+ .card,
73
+ .panel {
74
+ --surface-bg: var(--color-background);
75
+ --surface-border: var(--color-border);
76
+ --surface-border-hover: var(--color-border-hover);
77
+ --surface-radius: var(--radius-surface);
78
+ --surface-elevation: var(--elevation-low);
79
+
80
+ @apply text-text flex flex-col gap-4 rounded-(--surface-radius) border border-(--surface-border) bg-(--surface-bg) p-[clamp(1rem,3vw,2rem)] shadow-(--surface-elevation) transition-[border-color,box-shadow,transform] duration-(--motion-duration-normal) ease-(--motion-ease);
81
+
82
+ &.interactive {
83
+ @apply cursor-pointer;
84
+
85
+ &:hover {
86
+ transform: translateY(-1px);
87
+ border-color: var(--surface-border-hover);
88
+ }
89
+ }
90
+
91
+ &[data-state="open"] {
92
+ transform: translateY(-1px);
93
+ border-color: var(--surface-border-hover);
94
+ }
95
+ }
96
+
97
+ .card {
98
+ --surface-bg: var(--color-background);
99
+ }
100
+
101
+ .panel {
102
+ --surface-bg: var(--color-foreground);
103
+ }
104
+
105
+ .btn {
106
+ --button-color: var(--color-primary);
107
+ --button-contrast: var(--color-primary-contrast);
108
+ --button-hover: var(--color-primary-hover);
109
+ --button-subtle: var(--color-primary-subtle);
110
+ --button-strong: var(--color-primary-strong);
111
+ --button-bg: var(--button-color);
112
+ --button-fg: var(--button-contrast);
113
+ --button-border: var(--button-bg);
114
+ --button-hover-bg: var(--button-hover);
115
+ --button-hover-fg: var(--button-fg);
116
+ --button-hover-border: var(--button-hover-bg);
117
+ --button-text: var(--button-strong);
118
+ --button-soft-bg: var(--button-subtle);
119
+ --button-subtle-hover-bg: color-mix(in srgb, var(--button-soft-bg) 80%, transparent);
120
+ --button-soft-hover-bg: color-mix(in srgb, var(--button-soft-bg) 84%, var(--button-text));
121
+ --button-spinner: var(--button-fg);
122
+
123
+ @apply relative inline-flex min-h-(--control-height,2.5rem) w-fit items-center justify-center gap-2 rounded-(--radius-control) border border-(--button-border) bg-(--button-bg) px-4 py-2 font-semibold whitespace-nowrap text-(--button-fg) no-underline transition-[background-color,border-color,color,opacity,transform] duration-(--motion-duration-fast) ease-(--motion-ease) select-none;
124
+
125
+ &.primary {
126
+ --button-color: var(--color-primary);
127
+ --button-contrast: var(--color-primary-contrast);
128
+ --button-hover: var(--color-primary-hover);
129
+ --button-subtle: var(--color-primary-subtle);
130
+ --button-strong: var(--color-primary-strong);
131
+ }
132
+
133
+ &.secondary {
134
+ --button-color: var(--color-accent);
135
+ --button-contrast: var(--color-accent-contrast);
136
+ --button-hover: var(--color-accent-hover);
137
+ --button-subtle: var(--color-accent-subtle);
138
+ --button-strong: var(--color-accent-strong);
139
+ }
140
+
141
+ &.success {
142
+ --button-color: var(--color-success);
143
+ --button-contrast: var(--color-success-contrast);
144
+ --button-hover: var(--color-success-hover);
145
+ --button-subtle: var(--color-success-subtle);
146
+ --button-strong: var(--color-success-strong);
147
+ }
148
+
149
+ &.warning {
150
+ --button-color: var(--color-warning);
151
+ --button-contrast: var(--color-warning-contrast);
152
+ --button-hover: var(--color-warning-hover);
153
+ --button-subtle: var(--color-warning-subtle);
154
+ --button-strong: var(--color-warning-strong);
155
+ }
156
+
157
+ &.destructive,
158
+ &.danger,
159
+ &.error {
160
+ --button-color: var(--color-destructive);
161
+ --button-contrast: var(--color-destructive-contrast);
162
+ --button-hover: var(--color-destructive-hover);
163
+ --button-subtle: var(--color-destructive-subtle);
164
+ --button-strong: var(--color-destructive-strong);
165
+ }
166
+
167
+ &.info {
168
+ --button-color: var(--color-info);
169
+ --button-contrast: var(--color-info-contrast);
170
+ --button-hover: var(--color-info-hover);
171
+ --button-subtle: var(--color-info-subtle);
172
+ --button-strong: var(--color-info-strong);
173
+ }
174
+
175
+ &.out {
176
+ --button-spinner: var(--button-text);
177
+
178
+ @apply border-2 border-(--button-color) bg-transparent text-(--button-color);
179
+
180
+ &:not(:disabled, .disabled, [aria-disabled="true"], [data-disabled]):hover {
181
+ @apply border-(--button-color) bg-(--button-subtle) text-(--button-color);
182
+ }
183
+
184
+ &.fill {
185
+ &:not(:disabled, .disabled, [aria-disabled="true"], [data-disabled]):hover {
186
+ @apply border-(--button-color) bg-(--button-color) text-(--button-contrast);
187
+ }
188
+ }
189
+ }
190
+
191
+ &.ghost {
192
+ --button-spinner: var(--button-text);
193
+
194
+ @apply border-transparent bg-transparent text-(--button-text);
195
+
196
+ &:not(:disabled, .disabled, [aria-disabled="true"], [data-disabled]):hover {
197
+ @apply border-transparent bg-(--button-subtle-hover-bg) text-(--button-text);
198
+ }
199
+ }
200
+
201
+ &.soft {
202
+ --button-spinner: var(--button-text);
203
+
204
+ @apply border-transparent bg-(--button-soft-bg) text-(--button-text);
205
+
206
+ &:not(:disabled, .disabled, [aria-disabled="true"], [data-disabled]):hover {
207
+ @apply border-transparent bg-(--button-soft-hover-bg) text-(--button-text);
208
+ }
209
+ }
210
+
211
+ &.sm {
212
+ @apply min-h-8 px-3 py-1 text-sm;
213
+ }
214
+
215
+ &.lg {
216
+ @apply min-h-12 px-5 py-2.5 text-[1.0625rem];
217
+ }
218
+
219
+ &.icon {
220
+ @apply aspect-square min-w-(--control-height,2.5rem) p-2;
221
+
222
+ aspect-ratio: 1;
223
+ }
224
+
225
+ &.pill {
226
+ @apply rounded-full;
227
+ }
228
+
229
+ &:not(:disabled, .disabled, [aria-disabled="true"], [data-disabled]):hover {
230
+ &:not(.out, .ghost, .soft) {
231
+ @apply border-(--button-hover-border) bg-(--button-hover-bg) text-(--button-hover-fg);
232
+ }
233
+ }
234
+
235
+ &:disabled,
236
+ &.disabled,
237
+ &[aria-disabled="true"],
238
+ &[data-disabled] {
239
+ @apply cursor-not-allowed;
240
+
241
+ opacity: 0.58;
242
+ }
243
+
244
+ &.loading {
245
+ @apply pointer-events-none text-transparent! transition-[opacity,transform];
246
+
247
+ &::after {
248
+ @apply absolute top-[calc(50%+var(--border-width))] left-[calc(50%+var(--border-width))] block size-4 -translate-1/2 rounded-full bg-(--button-spinner);
249
+
250
+ content: "";
251
+ mask-image: url('data:image/svg+xml;utf8,<svg stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>.spinner_V8m1{transform-origin:center;animation:spinner_zKoa 2s linear infinite}.spinner_V8m1 circle{stroke-linecap:round;animation:spinner_YpZS 1.5s ease-in-out infinite}@keyframes spinner_zKoa{100%{transform:rotate(360deg)}}@keyframes spinner_YpZS{0%{stroke-dasharray:0 150;stroke-dashoffset:0}47.5%{stroke-dasharray:42 150;stroke-dashoffset:-16}95%,100%{stroke-dasharray:42 150;stroke-dashoffset:-59}}</style><g class="spinner_V8m1"><circle cx="12" cy="12" r="9.5" fill="none" stroke-width="3"></circle></g></svg>');
252
+ -webkit-mask-image: url('data:image/svg+xml;utf8,<svg stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>.spinner_V8m1{transform-origin:center;animation:spinner_zKoa 2s linear infinite}.spinner_V8m1 circle{stroke-linecap:round;animation:spinner_YpZS 1.5s ease-in-out infinite}@keyframes spinner_zKoa{100%{transform:rotate(360deg)}}@keyframes spinner_YpZS{0%{stroke-dasharray:0 150;stroke-dashoffset:0}47.5%{stroke-dasharray:42 150;stroke-dashoffset:-16}95%,100%{stroke-dasharray:42 150;stroke-dashoffset:-59}}</style><g class="spinner_V8m1"><circle cx="12" cy="12" r="9.5" fill="none" stroke-width="3"></circle></g></svg>');
253
+ mask-size: contain;
254
+ -webkit-mask-size: contain;
255
+ }
256
+ }
257
+ }
258
+
259
+ .field {
260
+ @apply flex w-full flex-col gap-1.5;
261
+
262
+ .label {
263
+ @apply text-text text-sm font-semibold;
264
+ }
265
+
266
+ .hint {
267
+ @apply text-text-secondary text-[0.8125rem];
268
+ }
269
+
270
+ .error:not(.btn),
271
+ &-error {
272
+ @apply text-destructive text-[0.8125rem] font-medium;
273
+ }
274
+ }
275
+
276
+ .ipt,
277
+ .textarea,
278
+ .select {
279
+ --control-bg: var(--color-background);
280
+ --control-border: var(--color-border);
281
+ --control-border-active: var(--color-primary);
282
+ --control-fg: var(--color-text);
283
+ --control-placeholder: var(--color-text-secondary);
284
+
285
+ @apply min-h-(--control-height,2.5rem) w-full rounded-(--radius-control) border border-(--control-border) bg-(--control-bg) px-3 py-2 text-(--control-fg) transition-[border-color,box-shadow,color,opacity] duration-(--motion-duration-fast) ease-(--motion-ease);
286
+
287
+ &::placeholder {
288
+ color: var(--control-placeholder);
289
+ }
290
+
291
+ &:focus {
292
+ @apply outline-none;
293
+ }
294
+
295
+ &:focus-visible {
296
+ border-color: var(--control-border-active);
297
+ box-shadow: 0 0 0 var(--focus-ring-width) var(--focus-ring);
298
+ }
299
+
300
+ &[aria-invalid="true"] {
301
+ --control-border: var(--color-destructive);
302
+ --control-border-active: var(--color-destructive);
303
+ }
304
+
305
+ &:disabled,
306
+ &[aria-disabled="true"],
307
+ &[data-disabled] {
308
+ @apply cursor-not-allowed;
309
+
310
+ opacity: 0.58;
311
+ }
312
+ }
313
+
314
+ .textarea {
315
+ @apply min-h-28 resize-y;
316
+ }
317
+
318
+ .select {
319
+ appearance: none;
320
+ }
321
+
322
+ input[type="checkbox"].checkbox {
323
+ --control-color: var(--color-primary);
324
+ --control-contrast: var(--color-primary-contrast);
325
+
326
+ @apply inline-grid size-4 cursor-pointer appearance-none place-content-center rounded-sm border border-(--color-border) bg-(--color-background) transition-[background-color,border-color,box-shadow] duration-(--motion-duration-normal) ease-(--motion-ease);
327
+
328
+ &:hover {
329
+ @apply border-(--color-border-hover);
330
+ }
331
+
332
+ &:focus {
333
+ @apply outline-none;
334
+ }
335
+
336
+ &:focus-visible {
337
+ border-color: var(--control-color);
338
+ box-shadow: 0 0 0 var(--focus-ring-width) var(--focus-ring);
339
+ }
340
+
341
+ &::after {
342
+ @apply block size-3 opacity-0 transition-opacity duration-(--motion-duration-normal) ease-(--motion-ease);
343
+
344
+ background-color: var(--control-contrast);
345
+ content: "";
346
+ mask-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>');
347
+ -webkit-mask-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>');
348
+ mask-size: contain;
349
+ -webkit-mask-size: contain;
350
+ }
351
+
352
+ &:checked {
353
+ border-color: var(--control-color);
354
+ background-color: var(--control-color);
355
+
356
+ &::after {
357
+ @apply opacity-100;
358
+ }
359
+ }
360
+
361
+ &.success {
362
+ --control-color: var(--color-success);
363
+ --control-contrast: var(--color-success-contrast);
364
+ }
365
+
366
+ &.warning {
367
+ --control-color: var(--color-warning);
368
+ --control-contrast: var(--color-warning-contrast);
369
+ }
370
+
371
+ &.destructive,
372
+ &.danger,
373
+ &.error {
374
+ --control-color: var(--color-destructive);
375
+ --control-contrast: var(--color-destructive-contrast);
376
+ }
377
+
378
+ &.info {
379
+ --control-color: var(--color-info);
380
+ --control-contrast: var(--color-info-contrast);
381
+ }
382
+
383
+ &[aria-invalid="true"] {
384
+ @apply border-(--color-destructive);
385
+ }
386
+
387
+ &:disabled,
388
+ &[aria-disabled="true"],
389
+ &[data-disabled] {
390
+ @apply cursor-not-allowed opacity-[0.58];
391
+ }
392
+ }
393
+
394
+ input[type="checkbox"].switch {
395
+ --control-color: var(--color-primary);
396
+ --control-contrast: var(--color-primary-contrast);
397
+
398
+ @apply relative h-4.5 w-9 cursor-pointer appearance-none rounded-full bg-(--color-surface) transition-[background-color,box-shadow] duration-(--motion-duration-normal) ease-(--motion-ease);
399
+
400
+ &::after {
401
+ @apply absolute top-0.5 left-0.5 size-3.5 rounded-full bg-(--color-text-secondary) transition-[transform,translate,background-color] duration-(--motion-duration-normal) ease-(--motion-ease);
402
+
403
+ content: "";
404
+ }
405
+
406
+ &:hover {
407
+ @apply border-(--color-border-hover);
408
+ }
409
+
410
+ &:focus {
411
+ @apply outline-none;
412
+ }
413
+
414
+ &:focus-visible {
415
+ border-color: var(--control-color);
416
+ box-shadow: 0 0 0 var(--focus-ring-width) var(--focus-ring);
417
+ }
418
+
419
+ &:checked {
420
+ border-color: var(--control-color);
421
+ background-color: var(--control-color);
422
+
423
+ &::after {
424
+ @apply translate-x-4.5;
425
+
426
+ background-color: var(--control-contrast);
427
+ }
428
+ }
429
+
430
+ &.success {
431
+ --control-color: var(--color-success);
432
+ --control-contrast: var(--color-success-contrast);
433
+ }
434
+
435
+ &.warning {
436
+ --control-color: var(--color-warning);
437
+ --control-contrast: var(--color-warning-contrast);
438
+ }
439
+
440
+ &.destructive,
441
+ &.danger,
442
+ &.error {
443
+ --control-color: var(--color-destructive);
444
+ --control-contrast: var(--color-destructive-contrast);
445
+ }
446
+
447
+ &.info {
448
+ --control-color: var(--color-info);
449
+ --control-contrast: var(--color-info-contrast);
450
+ }
451
+
452
+ &[aria-invalid="true"] {
453
+ @apply border-(--color-destructive);
454
+ }
455
+
456
+ &:disabled,
457
+ &[aria-disabled="true"],
458
+ &[data-disabled] {
459
+ @apply cursor-not-allowed opacity-[0.58];
460
+ }
461
+ }
462
+
463
+ .alert,
464
+ .toast,
465
+ .badge,
466
+ .banner {
467
+ --feedback-color: var(--color-info);
468
+ --feedback-surface: color-mix(in srgb, var(--feedback-color) 12%, var(--color-background));
469
+ --feedback-border: color-mix(in srgb, var(--feedback-color) 42%, var(--color-border));
470
+
471
+ @apply border border-(--feedback-border) text-(--feedback-color);
472
+
473
+ &.success {
474
+ --feedback-color: var(--color-success);
475
+ }
476
+
477
+ &.warning {
478
+ --feedback-color: var(--color-warning);
479
+ }
480
+
481
+ &.destructive,
482
+ &.danger,
483
+ &.error {
484
+ --feedback-color: var(--color-destructive);
485
+ }
486
+
487
+ &.info {
488
+ --feedback-color: var(--color-info);
489
+ }
490
+ }
491
+
492
+ .alert,
493
+ .toast,
494
+ .banner {
495
+ @apply flex gap-3 p-4;
496
+ }
497
+
498
+ .alert {
499
+ @apply rounded-(--radius-surface) bg-(--feedback-surface);
500
+ }
501
+
502
+ .toast {
503
+ @apply fixed top-4 right-4 z-(--z-toast) max-w-[min(24rem,calc(100vw-2rem))] rounded-(--radius-overlay) bg-[color-mix(in_srgb,var(--color-background)_92%,var(--feedback-color))] shadow-(--elevation-overlay);
504
+ }
505
+
506
+ .banner {
507
+ @apply rounded-none border-x-0 bg-(--feedback-surface);
508
+ }
509
+
510
+ .badge {
511
+ @apply inline-flex min-h-6 w-fit items-center gap-1 rounded-full bg-(--feedback-surface) px-2.5 text-xs font-bold;
512
+ }
513
+
514
+ .spinner {
515
+ @apply bg-text inline-block size-6 rounded-full [&.lg]:size-8 [&.sm]:size-4;
516
+
517
+ content: "";
518
+ mask-image: url('data:image/svg+xml;utf8,<svg stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>.spinner_V8m1{transform-origin:center;animation:spinner_zKoa 2s linear infinite}.spinner_V8m1 circle{stroke-linecap:round;animation:spinner_YpZS 1.5s ease-in-out infinite}@keyframes spinner_zKoa{100%{transform:rotate(360deg)}}@keyframes spinner_YpZS{0%{stroke-dasharray:0 150;stroke-dashoffset:0}47.5%{stroke-dasharray:42 150;stroke-dashoffset:-16}95%,100%{stroke-dasharray:42 150;stroke-dashoffset:-59}}</style><g class="spinner_V8m1"><circle cx="12" cy="12" r="9.5" fill="none" stroke-width="3"></circle></g></svg>');
519
+ -webkit-mask-image: url('data:image/svg+xml;utf8,<svg stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>.spinner_V8m1{transform-origin:center;animation:spinner_zKoa 2s linear infinite}.spinner_V8m1 circle{stroke-linecap:round;animation:spinner_YpZS 1.5s ease-in-out infinite}@keyframes spinner_zKoa{100%{transform:rotate(360deg)}}@keyframes spinner_YpZS{0%{stroke-dasharray:0 150;stroke-dashoffset:0}47.5%{stroke-dasharray:42 150;stroke-dashoffset:-16}95%,100%{stroke-dasharray:42 150;stroke-dashoffset:-59}}</style><g class="spinner_V8m1"><circle cx="12" cy="12" r="9.5" fill="none" stroke-width="3"></circle></g></svg>');
520
+ mask-size: contain;
521
+ -webkit-mask-size: contain;
522
+ }
523
+
524
+ .skeleton {
525
+ @apply min-h-4 w-full rounded-(--radius-control);
526
+
527
+ animation: codenhub-skeleton var(--motion-duration-slow) linear infinite;
528
+ background: linear-gradient(90deg, var(--color-surface), var(--color-foreground), var(--color-surface));
529
+ background-size: 200% 100%;
530
+ }
531
+
532
+ .progress {
533
+ --progress-color: var(--color-primary);
534
+ --progress-surface: var(--color-surface);
535
+
536
+ @apply h-2.5 w-full overflow-hidden rounded-full bg-(--progress-surface);
537
+
538
+ > * {
539
+ @apply block h-full transition-[width] duration-(--motion-duration-slow) ease-(--motion-ease);
540
+
541
+ background-color: var(--progress-color);
542
+ width: var(--progress-value, 0%);
543
+ }
544
+
545
+ &.success {
546
+ --progress-color: var(--color-success);
547
+ --progress-surface: color-mix(var(--color-success-subtle) 60%, transparent);
548
+ }
549
+
550
+ &.warning {
551
+ --progress-color: var(--color-warning);
552
+ --progress-surface: color-mix(var(--color-warning-subtle) 60%, transparent);
553
+ }
554
+
555
+ &.destructive,
556
+ &.danger,
557
+ &.error {
558
+ --progress-color: var(--color-destructive);
559
+ --progress-surface: color-mix(var(--color-destructive-subtle) 60%, transparent);
560
+ }
561
+
562
+ &.info {
563
+ --progress-color: var(--color-info);
564
+ --progress-surface: color-mix(var(--color-info-subtle) 60%, transparent);
565
+ }
566
+ }
567
+
568
+ .empty-state {
569
+ @apply text-text-secondary flex flex-col items-center gap-3 p-[clamp(2rem,8vw,5rem)] text-center;
570
+ }
571
+
572
+ .tooltip {
573
+ --tooltip-bg: var(--color-surface);
574
+ --tooltip-fg: var(--color-text);
575
+ --tooltip-gap: 0.5rem;
576
+ --tooltip-top: calc(var(--tooltip-gap) * -1);
577
+ --tooltip-right: auto;
578
+ --tooltip-bottom: auto;
579
+ --tooltip-left: 50%;
580
+ --tooltip-origin: bottom;
581
+ --tooltip-transform: translate(-50%, -100%);
582
+
583
+ @apply relative;
584
+
585
+ &.icon {
586
+ @apply bg-surface text-text inline-flex size-5 cursor-default items-center justify-center rounded-full text-sm font-bold;
587
+ }
588
+
589
+ &[data-tooltip-position="bottom"] {
590
+ --tooltip-top: auto;
591
+ --tooltip-bottom: calc(var(--tooltip-gap) * -1);
592
+ --tooltip-origin: top;
593
+ --tooltip-transform: translate(-50%, 100%);
594
+ }
595
+
596
+ &[data-tooltip-position="left"] {
597
+ --tooltip-top: 50%;
598
+ --tooltip-left: calc(var(--tooltip-gap) * -1);
599
+ --tooltip-origin: right;
600
+ --tooltip-transform: translate(-100%, -50%);
601
+ }
602
+
603
+ &[data-tooltip-position="right"] {
604
+ --tooltip-top: 50%;
605
+ --tooltip-left: auto;
606
+ --tooltip-right: calc(var(--tooltip-gap) * -1);
607
+ --tooltip-origin: left;
608
+ --tooltip-transform: translate(100%, -50%);
609
+ }
610
+
611
+ &::after {
612
+ @apply pointer-events-none absolute z-(--z-popover) w-max max-w-72 rounded-(--radius-control) bg-(--tooltip-bg) px-2.5 py-2 text-sm font-normal whitespace-normal text-(--tooltip-fg) opacity-0 shadow-(--elevation-high) transition-[opacity,transform] duration-(--motion-duration-normal) ease-(--motion-ease);
613
+ content: attr(data-tooltip);
614
+ left: var(--tooltip-left);
615
+ right: var(--tooltip-right);
616
+ top: var(--tooltip-top);
617
+ bottom: var(--tooltip-bottom);
618
+ transform: var(--tooltip-transform) scale(0);
619
+ transform-origin: var(--tooltip-origin);
620
+ }
621
+
622
+ &:hover::after,
623
+ &:focus-visible::after,
624
+ &[data-state="open"]::after {
625
+ opacity: 1;
626
+ transform: var(--tooltip-transform) scale(1);
627
+ }
628
+ }
629
+
630
+ [aria-current="page"] {
631
+ @apply text-primary font-bold;
632
+ }
633
+
634
+ @media (width < 40rem) {
635
+ .sect {
636
+ @apply items-stretch;
637
+ }
638
+
639
+ .toast {
640
+ @apply right-4 left-4 max-w-none;
641
+ }
642
+ }
643
+
644
+ @media (forced-colors: active) {
645
+ .btn,
646
+ .ipt,
647
+ .textarea,
648
+ .select,
649
+ .card,
650
+ .panel,
651
+ .alert,
652
+ .toast,
653
+ .badge {
654
+ border-color: CanvasText;
655
+ }
656
+ }
657
+ }