@juxtui/ui 0.2.0 → 0.3.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 (37) hide show
  1. package/README.md +1 -1
  2. package/dist/components/aspect-ratio/JAspectRatio.vue.d.ts +18 -0
  3. package/dist/components/avatar/JAvatar.vue.d.ts +1 -1
  4. package/dist/components/avatar-group/JAvatarGroup.vue.d.ts +19 -0
  5. package/dist/components/banner/JBanner.vue.d.ts +30 -0
  6. package/dist/components/breadcrumb/JBreadcrumb.vue.d.ts +29 -0
  7. package/dist/components/card/JCard.vue.d.ts +1 -1
  8. package/dist/components/collapsible/JCollapsible.vue.d.ts +28 -0
  9. package/dist/components/command-palette/JCommandPalette.vue.d.ts +1 -1
  10. package/dist/components/dropdown-menu/JDropdownMenu.vue.d.ts +1 -1
  11. package/dist/components/empty-state/JEmptyState.vue.d.ts +23 -0
  12. package/dist/components/field/JFieldShell.vue.d.ts +1 -1
  13. package/dist/components/pagination/JPagination.vue.d.ts +25 -0
  14. package/dist/components/primitives/JSlot.d.ts +1 -1
  15. package/dist/components/rating/JRating.vue.d.ts +27 -0
  16. package/dist/components/slider/JSlider.vue.d.ts +31 -0
  17. package/dist/components/stat/JStat.vue.d.ts +22 -0
  18. package/dist/components/tag/JTag.vue.d.ts +28 -0
  19. package/dist/components/timeline/JTimeline.vue.d.ts +12 -0
  20. package/dist/components/timeline/JTimelineItem.vue.d.ts +24 -0
  21. package/dist/components/toast/JToaster.vue.d.ts +1 -1
  22. package/dist/components/toggle-group/JToggleGroup.vue.d.ts +33 -0
  23. package/dist/components/toggle-group/JToggleGroupItem.vue.d.ts +19 -0
  24. package/dist/components/toggle-group/context.d.ts +9 -0
  25. package/dist/components/visually-hidden/JVisuallyHidden.vue.d.ts +19 -0
  26. package/dist/components.d.ts +16 -0
  27. package/dist/composables/useModal.d.ts +1 -1
  28. package/dist/composables/useToast.d.ts +1 -1
  29. package/dist/icons.d.ts +4 -0
  30. package/dist/index.d.ts +16 -0
  31. package/dist/index.js +1161 -196
  32. package/dist/index.js.map +1 -1
  33. package/dist/nuxt.js +17 -1
  34. package/dist/nuxt.js.map +1 -1
  35. package/dist/style.css +1526 -548
  36. package/dist/tokens.css +5 -5
  37. package/package.json +1 -1
package/dist/style.css CHANGED
@@ -4,7 +4,7 @@
4
4
  /*
5
5
  * Juxt's component styles live in the `juxt` cascade layer. The order below
6
6
  * puts it above CSS resets (Tailwind's `base`) and below utilities, so a
7
- * class like `hidden` or `w-full` on a component always wins — and any
7
+ * class like `hidden` or `w-full` on a component always wins | and any
8
8
  * unlayered CSS of your own does too. Without Tailwind the extra names are
9
9
  * simply empty layers.
10
10
  */
@@ -13,7 +13,7 @@
13
13
  * Juxt design tokens
14
14
  *
15
15
  * One source of truth for colour, space, radius, type, elevation, motion and
16
- * layering. Components never hardcode these values — they read them here.
16
+ * layering. Components never hardcode these values | they read them here.
17
17
  *
18
18
  * Light is the default. Dark applies under `.dark` or `[data-theme="dark"]`
19
19
  * on any ancestor (usually <html>).
@@ -44,7 +44,7 @@
44
44
  --juxt-fg-muted: #71717a;
45
45
  --juxt-fg-disabled: #a1a1aa;
46
46
 
47
- /* Ink — the inverted neutral used by primary actions */
47
+ /* Ink | the inverted neutral used by primary actions */
48
48
  --juxt-ink: #09090b;
49
49
  --juxt-ink-hover: #27272a;
50
50
  --juxt-ink-fg: #fafafa;
@@ -84,7 +84,7 @@
84
84
  --juxt-success-soft: var(--juxt-accent-soft);
85
85
  --juxt-success-border: var(--juxt-accent-border);
86
86
 
87
- /* Elevation — borders do most of the work, shadows only lift */
87
+ /* Elevation | borders do most of the work, shadows only lift */
88
88
  --juxt-shadow-xs: 0 1px 1px rgb(9 9 11 / 0.04);
89
89
  --juxt-shadow-sm: 0 1px 2px rgb(9 9 11 / 0.05), 0 1px 1px rgb(9 9 11 / 0.03);
90
90
  --juxt-shadow-md: 0 4px 12px -2px rgb(9 9 11 / 0.08), 0 2px 4px -2px rgb(9 9 11 / 0.05);
@@ -186,7 +186,7 @@
186
186
  --juxt-tracking-tight: -0.011em;
187
187
  --juxt-tracking-tighter: -0.022em;
188
188
 
189
- /* Space — a 4px grid */
189
+ /* Space | a 4px grid */
190
190
  --juxt-space-0-5: 0.125rem; /* 2 */
191
191
  --juxt-space-1: 0.25rem; /* 4 */
192
192
  --juxt-space-1-5: 0.375rem; /* 6 */
@@ -239,7 +239,7 @@
239
239
 
240
240
  @media (prefers-reduced-motion: reduce) {
241
241
  :root {
242
- /* Things still fade — they just stop travelling. */
242
+ /* Things still fade | they just stop travelling. */
243
243
  --juxt-motion-shift: 0px;
244
244
  --juxt-motion-scale: 1;
245
245
  --juxt-duration-slow: 140ms;
@@ -462,211 +462,235 @@
462
462
  }
463
463
  }
464
464
 
465
+ @layer theme, base, juxt, components, utilities;
465
466
  @layer juxt {
466
- .j-accordion {
467
- display: flex;
468
- flex-direction: column;
467
+ .j-accordion {
468
+ display: flex;
469
+ flex-direction: column;
469
470
  font-family: var(--juxt-font-sans);
470
471
  }
471
- }
472
+ }
472
473
 
474
+ @layer theme, base, juxt, components, utilities;
473
475
  @layer juxt {
474
- .j-accordion__item {
476
+ .j-accordion__item {
475
477
  border-bottom: 1px solid var(--juxt-border-subtle);
476
478
  }
477
- .dark .j-accordion__item,
478
- [data-theme='dark'] .j-accordion__item {
479
+ .dark .j-accordion__item,
480
+ [data-theme='dark'] .j-accordion__item {
479
481
  border-bottom-color: var(--juxt-border);
480
482
  }
481
- .j-accordion__heading {
482
- margin: 0;
483
+ .j-accordion__heading {
484
+ margin: 0;
483
485
  font: inherit;
484
486
  }
485
- .j-accordion__trigger {
486
- display: flex;
487
- align-items: center;
488
- justify-content: space-between;
489
- gap: var(--juxt-space-4);
490
- width: 100%;
491
- min-height: 3rem;
492
- padding: var(--juxt-space-3) 0;
493
- border: 0;
494
- border-radius: var(--juxt-radius-xs);
495
- background: transparent;
496
- color: var(--juxt-fg);
497
- font: inherit;
498
- font-size: var(--juxt-text-md);
499
- font-weight: var(--juxt-weight-medium);
500
- letter-spacing: var(--juxt-tracking-tight);
501
- text-align: left;
502
- cursor: pointer;
503
- outline: 2px solid transparent;
504
- outline-offset: 0;
505
- -webkit-tap-highlight-color: transparent;
506
- transition:
507
- color var(--juxt-duration-fast) var(--juxt-ease-standard),
508
- outline-color var(--juxt-duration-fast) var(--juxt-ease-out),
487
+ .j-accordion__trigger {
488
+ display: flex;
489
+ align-items: center;
490
+ justify-content: space-between;
491
+ gap: var(--juxt-space-4);
492
+ width: 100%;
493
+ min-height: 3rem;
494
+ padding: var(--juxt-space-3) 0;
495
+ border: 0;
496
+ border-radius: var(--juxt-radius-xs);
497
+ background: transparent;
498
+ color: var(--juxt-fg);
499
+ font: inherit;
500
+ font-size: var(--juxt-text-md);
501
+ font-weight: var(--juxt-weight-medium);
502
+ letter-spacing: var(--juxt-tracking-tight);
503
+ text-align: left;
504
+ cursor: pointer;
505
+ outline: 2px solid transparent;
506
+ outline-offset: 0;
507
+ -webkit-tap-highlight-color: transparent;
508
+ transition:
509
+ color var(--juxt-duration-fast) var(--juxt-ease-standard),
510
+ outline-color var(--juxt-duration-fast) var(--juxt-ease-out),
509
511
  outline-offset var(--juxt-duration-fast) var(--juxt-ease-out);
510
512
  }
511
- .j-accordion__trigger:focus-visible {
512
- outline-color: var(--juxt-ring);
513
+ .j-accordion__trigger:focus-visible {
514
+ outline-color: var(--juxt-ring);
513
515
  outline-offset: 2px;
514
516
  }
515
- .j-accordion__trigger:disabled {
516
- color: var(--juxt-fg-disabled);
517
+ .j-accordion__trigger:disabled {
518
+ color: var(--juxt-fg-disabled);
517
519
  cursor: not-allowed;
518
520
  }
519
- .j-accordion__chevron {
520
- flex: none;
521
- width: 1rem;
522
- height: 1rem;
523
- color: var(--juxt-fg-muted);
524
- transition:
525
- transform var(--juxt-duration-normal) var(--juxt-ease-out),
521
+ .j-accordion__chevron {
522
+ flex: none;
523
+ width: 1rem;
524
+ height: 1rem;
525
+ color: var(--juxt-fg-muted);
526
+ transition:
527
+ transform var(--juxt-duration-normal) var(--juxt-ease-out),
526
528
  color var(--juxt-duration-fast) var(--juxt-ease-standard);
527
529
  }
528
- .j-accordion__trigger:hover:not(:disabled) .j-accordion__chevron {
530
+ .j-accordion__trigger:hover:not(:disabled) .j-accordion__chevron {
529
531
  color: var(--juxt-fg);
530
532
  }
531
- .j-accordion__item[data-state='open'] .j-accordion__chevron {
533
+ .j-accordion__item[data-state='open'] .j-accordion__chevron {
532
534
  transform: rotate(180deg);
533
- }
534
-
535
- /* Height follows content via grid rows — no measuring, no magic numbers. */
536
- .j-accordion__panel {
537
- display: grid;
538
- grid-template-rows: 0fr;
535
+ }
536
+
537
+ /* Height follows content via grid rows | no measuring, no magic numbers. */
538
+ .j-accordion__panel {
539
+ display: grid;
540
+ grid-template-rows: 0fr;
539
541
  transition: grid-template-rows var(--juxt-duration-slow) var(--juxt-ease-out);
540
542
  }
541
- .j-accordion__item[data-state='open'] .j-accordion__panel {
543
+ .j-accordion__item[data-state='open'] .j-accordion__panel {
542
544
  grid-template-rows: 1fr;
543
545
  }
544
- .j-accordion__panel-inner {
545
- min-height: 0;
546
+ .j-accordion__panel-inner {
547
+ min-height: 0;
546
548
  overflow: hidden;
547
549
  }
548
- .j-accordion__content {
549
- padding-bottom: var(--juxt-space-4);
550
- color: var(--juxt-fg-secondary);
551
- font-size: var(--juxt-text-md);
552
- line-height: var(--juxt-leading-normal);
553
- opacity: 0;
550
+ .j-accordion__content {
551
+ padding-bottom: var(--juxt-space-4);
552
+ color: var(--juxt-fg-secondary);
553
+ font-size: var(--juxt-text-md);
554
+ line-height: var(--juxt-leading-normal);
555
+ opacity: 0;
554
556
  transition: opacity var(--juxt-duration-fast) var(--juxt-ease-standard);
555
557
  }
556
- .j-accordion__item[data-state='open'] .j-accordion__content {
557
- opacity: 1;
558
+ .j-accordion__item[data-state='open'] .j-accordion__content {
559
+ opacity: 1;
558
560
  transition-delay: 60ms;
559
561
  }
560
562
  @media (prefers-reduced-motion: reduce) {
561
- .j-accordion__panel,
562
- .j-accordion__chevron {
563
+ .j-accordion__panel,
564
+ .j-accordion__chevron {
563
565
  transition: none;
564
566
  }
565
567
  }
566
- }
568
+ }
567
569
 
568
- @layer juxt {
569
- /*
570
- * Alerts stay on the page's surface. Colour lives in the icon and a hairline
571
- * of the border — enough to be noticed, never enough to shout.
570
+ @layer theme, base, juxt, components, utilities;
571
+ @layer juxt {
572
+ /*
573
+ * Alerts stay on the page's surface. Colour lives in the icon and a hairline
574
+ * of the border | enough to be noticed, never enough to shout.
572
575
  */
573
- .j-alert {
574
- --j-alert-accent: var(--juxt-fg-muted);
575
- --j-alert-border: var(--juxt-border);
576
-
577
- position: relative;
578
- display: flex;
579
- align-items: flex-start;
580
- gap: var(--juxt-space-3);
581
- padding: var(--juxt-space-3) var(--juxt-space-4);
582
- border: 1px solid var(--j-alert-border);
583
- border-radius: var(--juxt-radius-md);
584
- background: var(--juxt-surface);
585
- color: var(--juxt-fg);
576
+ .j-alert {
577
+ --j-alert-accent: var(--juxt-fg-muted);
578
+ --j-alert-border: var(--juxt-border);
579
+
580
+ position: relative;
581
+ display: flex;
582
+ align-items: flex-start;
583
+ gap: var(--juxt-space-3);
584
+ padding: var(--juxt-space-3) var(--juxt-space-4);
585
+ border: 1px solid var(--j-alert-border);
586
+ border-radius: var(--juxt-radius-md);
587
+ background: var(--juxt-surface);
588
+ color: var(--juxt-fg);
586
589
  font-family: var(--juxt-font-sans);
587
590
  }
588
- .j-alert--info {
591
+ .j-alert--info {
589
592
  --j-alert-accent: var(--juxt-info-text);
590
593
  }
591
- .j-alert--success {
594
+ .j-alert--success {
592
595
  --j-alert-accent: var(--juxt-success-text);
593
596
  }
594
- .j-alert--warning {
595
- --j-alert-accent: var(--juxt-warning-text);
597
+ .j-alert--warning {
598
+ --j-alert-accent: var(--juxt-warning-text);
596
599
  --j-alert-border: var(--juxt-warning-border);
597
600
  }
598
- .j-alert--destructive {
599
- --j-alert-accent: var(--juxt-danger-text);
601
+ .j-alert--destructive {
602
+ --j-alert-accent: var(--juxt-danger-text);
600
603
  --j-alert-border: var(--juxt-danger-border);
601
604
  }
602
- .j-alert__icon {
603
- display: grid;
604
- flex: none;
605
- place-items: center;
606
- height: 1.25rem;
605
+ .j-alert__icon {
606
+ display: grid;
607
+ flex: none;
608
+ place-items: center;
609
+ height: 1.25rem;
607
610
  color: var(--j-alert-accent);
608
611
  }
609
- .j-alert__icon > svg {
610
- width: 1rem;
612
+ .j-alert__icon > svg {
613
+ width: 1rem;
611
614
  height: 1rem;
612
615
  }
613
- .j-alert__body {
614
- display: flex;
615
- flex: 1;
616
- flex-direction: column;
617
- gap: var(--juxt-space-0-5);
616
+ .j-alert__body {
617
+ display: flex;
618
+ flex: 1;
619
+ flex-direction: column;
620
+ gap: var(--juxt-space-0-5);
618
621
  min-width: 0;
619
622
  }
620
- .j-alert__title {
621
- margin: 0;
622
- font-size: var(--juxt-text-md);
623
- font-weight: var(--juxt-weight-medium);
624
- line-height: 1.25rem;
623
+ .j-alert__title {
624
+ margin: 0;
625
+ font-size: var(--juxt-text-md);
626
+ font-weight: var(--juxt-weight-medium);
627
+ line-height: 1.25rem;
625
628
  letter-spacing: var(--juxt-tracking-tight);
626
629
  }
627
- .j-alert__description {
628
- color: var(--juxt-fg-secondary);
629
- font-size: var(--juxt-text-sm);
630
+ .j-alert__description {
631
+ color: var(--juxt-fg-secondary);
632
+ font-size: var(--juxt-text-sm);
630
633
  line-height: var(--juxt-leading-normal);
631
634
  }
632
- .j-alert__description > p {
635
+ .j-alert__description > p {
633
636
  margin: 0;
634
637
  }
635
- .j-alert__actions {
636
- display: flex;
637
- flex-wrap: wrap;
638
- gap: var(--juxt-space-2);
638
+ .j-alert__actions {
639
+ display: flex;
640
+ flex-wrap: wrap;
641
+ gap: var(--juxt-space-2);
639
642
  margin-top: var(--juxt-space-2);
640
643
  }
641
- .j-alert:has(.j-alert__close) {
644
+ .j-alert:has(.j-alert__close) {
642
645
  padding-right: var(--juxt-space-10);
643
646
  }
644
- .j-alert__close {
645
- position: absolute;
646
- top: var(--juxt-space-2-5);
647
- right: var(--juxt-space-2-5);
648
- display: grid;
649
- place-items: center;
650
- width: 1.5rem;
651
- height: 1.5rem;
652
- padding: 0;
653
- border: 0;
654
- border-radius: var(--juxt-radius-xs);
655
- background: transparent;
656
- color: var(--juxt-fg-muted);
657
- cursor: pointer;
647
+ .j-alert__close {
648
+ position: absolute;
649
+ top: var(--juxt-space-2-5);
650
+ right: var(--juxt-space-2-5);
651
+ display: grid;
652
+ place-items: center;
653
+ width: 1.5rem;
654
+ height: 1.5rem;
655
+ padding: 0;
656
+ border: 0;
657
+ border-radius: var(--juxt-radius-xs);
658
+ background: transparent;
659
+ color: var(--juxt-fg-muted);
660
+ cursor: pointer;
658
661
  transition-property: background-color, color, outline-color, outline-offset;
659
662
  }
660
- .j-alert__close:hover {
661
- background: var(--juxt-surface-hover);
663
+ .j-alert__close:hover {
664
+ background: var(--juxt-surface-hover);
662
665
  color: var(--juxt-fg);
663
666
  }
664
- .j-alert__close > svg {
665
- width: 0.875rem;
667
+ .j-alert__close > svg {
668
+ width: 0.875rem;
666
669
  height: 0.875rem;
667
670
  }
671
+ }
672
+
673
+ @layer theme, base, juxt, components, utilities;
674
+ @layer juxt {
675
+ .j-aspect-ratio {
676
+ position: relative;
677
+ width: 100%;
678
+ aspect-ratio: var(--j-aspect-ratio, 16 / 9);
679
+ }
680
+ .j-aspect-ratio__content {
681
+ position: absolute;
682
+ inset: 0;
683
+ overflow: hidden;
684
+ }
685
+ .j-aspect-ratio__content > :where(img, video, iframe, canvas) {
686
+ display: block;
687
+ width: 100%;
688
+ height: 100%;
689
+ object-fit: cover;
668
690
  }
691
+ }
669
692
 
693
+ @layer theme, base, juxt, components, utilities;
670
694
  @layer juxt {
671
695
  .j-avatar {
672
696
  --j-avatar-size: 2rem;
@@ -779,9 +803,65 @@
779
803
  }
780
804
  }
781
805
 
806
+ @layer theme, base, juxt, components, utilities;
807
+ @layer juxt {
808
+ .j-avatar-group {
809
+ --j-avatar-group-overlap: 0.5em;
810
+
811
+ display: inline-flex;
812
+ align-items: center;
813
+ font-family: var(--juxt-font-sans);
814
+ }
815
+ .j-avatar-group__item {
816
+ position: relative;
817
+ display: inline-flex;
818
+ flex: none;
819
+ border-radius: var(--juxt-radius-full);
820
+ box-shadow: 0 0 0 2px var(--juxt-bg);
821
+ }
822
+ .j-avatar-group__item:not(:first-child) {
823
+ margin-left: calc(var(--j-avatar-group-overlap) * -1);
824
+ }
825
+ .j-avatar-group__overflow {
826
+ display: grid;
827
+ place-items: center;
828
+ width: 2rem;
829
+ height: 2rem;
830
+ background: var(--juxt-surface-active);
831
+ color: var(--juxt-fg-secondary);
832
+ font-size: var(--juxt-text-xs);
833
+ font-weight: var(--juxt-weight-medium);
834
+ font-variant-numeric: tabular-nums;
835
+ }
836
+ .j-avatar-group--xs .j-avatar-group__overflow {
837
+ width: 1.25rem;
838
+ height: 1.25rem;
839
+ font-size: var(--juxt-text-2xs);
840
+ }
841
+ .j-avatar-group--sm .j-avatar-group__overflow {
842
+ width: 1.5rem;
843
+ height: 1.5rem;
844
+ font-size: 0.625rem;
845
+ }
846
+ .j-avatar-group--lg .j-avatar-group__overflow {
847
+ width: 2.5rem;
848
+ height: 2.5rem;
849
+ font-size: var(--juxt-text-sm);
850
+ }
851
+ .j-avatar-group--xl .j-avatar-group__overflow {
852
+ width: 3.5rem;
853
+ height: 3.5rem;
854
+ font-size: var(--juxt-text-lg);
855
+ }
856
+ .j-avatar-group__overflow--square {
857
+ border-radius: 22%;
858
+ }
859
+ }
860
+
861
+ @layer theme, base, juxt, components, utilities;
782
862
  @layer juxt {
783
863
  /*
784
- * Badges are small, square-shouldered labels — closer to a stamp than a pill.
864
+ * Badges are small, square-shouldered labels | closer to a stamp than a pill.
785
865
  * No borders: a quiet tint and the text colour carry the meaning.
786
866
  */
787
867
  .j-badge {
@@ -828,7 +908,7 @@
828
908
  --j-badge-marker: var(--juxt-danger);
829
909
  }
830
910
 
831
- /* Accent is the only solid badge — reserve it for the thing that matters. */
911
+ /* Accent is the only solid badge | reserve it for the thing that matters. */
832
912
  .j-badge--accent {
833
913
  --j-badge-fg: var(--juxt-accent-fg);
834
914
  --j-badge-bg: var(--juxt-accent-strong);
@@ -862,74 +942,230 @@
862
942
  }
863
943
  }
864
944
 
865
- @layer juxt {
866
- .j-button {
867
- --j-button-height: var(--juxt-control-md);
868
- --j-button-px: var(--juxt-space-3);
869
- --j-button-gap: var(--juxt-space-1-5);
870
- --j-button-font: var(--juxt-text-md);
871
- --j-button-radius: var(--juxt-radius-sm);
945
+ @layer theme, base, juxt, components, utilities;
946
+ @layer juxt {
947
+ /*
948
+ * Banners run edge-to-edge across a page or section, unlike JAlert which sits
949
+ * inline in a card or form. A flat tinted surface and a left accent bar
950
+ * distinguish them from the bordered, neutral surface of an alert.
951
+ */
952
+ .j-banner {
953
+ --j-banner-accent: var(--juxt-fg-muted);
954
+ --j-banner-bg: var(--juxt-surface-sunken);
872
955
 
873
956
  position: relative;
874
- display: inline-flex;
957
+ display: flex;
875
958
  align-items: center;
876
- justify-content: center;
877
- height: var(--j-button-height);
878
- padding: 0 var(--j-button-px);
879
- border: 1px solid transparent;
880
- border-radius: var(--j-button-radius);
881
- font-family: var(--juxt-font-sans);
882
- font-size: var(--j-button-font);
883
- font-weight: var(--juxt-weight-medium);
884
- line-height: 1;
885
- letter-spacing: var(--juxt-tracking-tight);
886
- white-space: nowrap;
887
- text-decoration: none;
888
- cursor: pointer;
889
- user-select: none;
890
- -webkit-tap-highlight-color: transparent;
891
- touch-action: manipulation;
892
- transition-property: background-color, border-color, color, box-shadow, transform, outline-color, outline-offset;
893
- transition-duration: var(--juxt-duration-fast);
894
- transition-timing-function: var(--juxt-ease-standard);
895
- }
896
-
897
- /* Pressed: a short, physical dip. Released slower than pressed. */
898
- .j-button:active:not([aria-disabled='true'], :disabled) {
899
- transform: scale(0.97);
900
- transition-duration: var(--juxt-duration-instant);
901
- }
902
- @media (prefers-reduced-motion: reduce) {
903
- .j-button:active:not([aria-disabled='true'], :disabled) {
904
- transform: none;
959
+ gap: var(--juxt-space-3);
960
+ padding: var(--juxt-space-3) var(--juxt-space-5);
961
+ border-left: 3px solid var(--j-banner-accent);
962
+ background: var(--j-banner-bg);
963
+ color: var(--juxt-fg);
964
+ font-family: var(--juxt-font-sans);
905
965
  }
966
+ .j-banner--info {
967
+ --j-banner-accent: var(--juxt-info);
968
+ --j-banner-bg: var(--juxt-info-soft);
906
969
  }
907
- .j-button__content {
908
- display: inline-flex;
909
- align-items: center;
910
- gap: var(--j-button-gap);
911
- transition:
912
- opacity var(--juxt-duration-fast) var(--juxt-ease-standard),
913
- transform var(--juxt-duration-normal) var(--juxt-ease-out);
970
+ .j-banner--success {
971
+ --j-banner-accent: var(--juxt-success);
972
+ --j-banner-bg: var(--juxt-success-soft);
914
973
  }
915
- .j-button__icon {
916
- display: inline-flex;
917
- margin-inline: -0.125rem;
918
- opacity: 0.85;
974
+ .j-banner--warning {
975
+ --j-banner-accent: var(--juxt-warning);
976
+ --j-banner-bg: var(--juxt-warning-soft);
919
977
  }
920
- .j-button__icon > svg {
921
- width: 1em;
922
- height: 1em;
978
+ .j-banner--destructive {
979
+ --j-banner-accent: var(--juxt-danger);
980
+ --j-banner-bg: var(--juxt-danger-soft);
923
981
  }
924
- .j-button.is-loading {
925
- cursor: progress;
982
+ .j-banner__icon {
983
+ display: grid;
984
+ flex: none;
985
+ place-items: center;
986
+ height: 1.25rem;
987
+ color: var(--j-banner-accent);
926
988
  }
927
- .j-button.is-loading .j-button__content {
928
- opacity: 0;
929
- transform: scale(0.96);
989
+ .j-banner__icon > svg {
990
+ width: 1rem;
991
+ height: 1rem;
930
992
  }
931
- .j-button__spinner {
932
- position: absolute;
993
+ .j-banner__body {
994
+ display: flex;
995
+ flex: 1;
996
+ flex-wrap: wrap;
997
+ align-items: baseline;
998
+ gap: var(--juxt-space-1) var(--juxt-space-2);
999
+ min-width: 0;
1000
+ }
1001
+ .j-banner__title {
1002
+ margin: 0;
1003
+ color: var(--juxt-fg);
1004
+ font-size: var(--juxt-text-md);
1005
+ font-weight: var(--juxt-weight-medium);
1006
+ letter-spacing: var(--juxt-tracking-tight);
1007
+ }
1008
+ .j-banner__description {
1009
+ color: var(--juxt-fg-secondary);
1010
+ font-size: var(--juxt-text-sm);
1011
+ line-height: var(--juxt-leading-normal);
1012
+ }
1013
+ .j-banner__description > p {
1014
+ margin: 0;
1015
+ }
1016
+ .j-banner__actions {
1017
+ display: flex;
1018
+ flex: none;
1019
+ flex-wrap: wrap;
1020
+ gap: var(--juxt-space-2);
1021
+ }
1022
+ .j-banner__close {
1023
+ display: grid;
1024
+ flex: none;
1025
+ place-items: center;
1026
+ width: 1.5rem;
1027
+ height: 1.5rem;
1028
+ padding: 0;
1029
+ border: 0;
1030
+ border-radius: var(--juxt-radius-xs);
1031
+ background: transparent;
1032
+ color: var(--juxt-fg-muted);
1033
+ cursor: pointer;
1034
+ transition-property: background-color, color, outline-color, outline-offset;
1035
+ }
1036
+ .j-banner__close:hover {
1037
+ background: var(--juxt-surface-hover);
1038
+ color: var(--juxt-fg);
1039
+ }
1040
+ .j-banner__close > svg {
1041
+ width: 0.875rem;
1042
+ height: 0.875rem;
1043
+ }
1044
+ }
1045
+
1046
+ @layer theme, base, juxt, components, utilities;
1047
+ @layer juxt {
1048
+ .j-breadcrumb {
1049
+ font-family: var(--juxt-font-sans);
1050
+ }
1051
+ .j-breadcrumb__list {
1052
+ display: flex;
1053
+ flex-wrap: wrap;
1054
+ align-items: center;
1055
+ gap: var(--juxt-space-1-5);
1056
+ margin: 0;
1057
+ padding: 0;
1058
+ list-style: none;
1059
+ }
1060
+ .j-breadcrumb__item {
1061
+ display: flex;
1062
+ align-items: center;
1063
+ gap: var(--juxt-space-1-5);
1064
+ color: var(--juxt-fg-muted);
1065
+ font-size: var(--juxt-text-sm);
1066
+ line-height: var(--juxt-leading-snug);
1067
+ }
1068
+ .j-breadcrumb__item:not(:first-child)::before {
1069
+ content: '';
1070
+ display: inline-block;
1071
+ width: 0.3125rem;
1072
+ height: 0.3125rem;
1073
+ margin-right: var(--juxt-space-1-5);
1074
+ border-top: 1.5px solid var(--juxt-fg-disabled);
1075
+ border-right: 1.5px solid var(--juxt-fg-disabled);
1076
+ transform: rotate(45deg);
1077
+ }
1078
+ .j-breadcrumb__link {
1079
+ border-radius: var(--juxt-radius-xs);
1080
+ color: var(--juxt-fg-muted);
1081
+ text-decoration: none;
1082
+ transition: color var(--juxt-duration-fast) var(--juxt-ease-standard);
1083
+ }
1084
+ .j-breadcrumb__link:hover {
1085
+ color: var(--juxt-fg);
1086
+ text-decoration: underline;
1087
+ text-underline-offset: 2px;
1088
+ }
1089
+ .j-breadcrumb__current {
1090
+ color: var(--juxt-fg);
1091
+ font-weight: var(--juxt-weight-medium);
1092
+ letter-spacing: var(--juxt-tracking-tight);
1093
+ }
1094
+ .j-breadcrumb__ellipsis {
1095
+ color: var(--juxt-fg-disabled);
1096
+ user-select: none;
1097
+ }
1098
+ }
1099
+
1100
+ @layer theme, base, juxt, components, utilities;
1101
+ @layer juxt {
1102
+ .j-button {
1103
+ --j-button-height: var(--juxt-control-md);
1104
+ --j-button-px: var(--juxt-space-3);
1105
+ --j-button-gap: var(--juxt-space-1-5);
1106
+ --j-button-font: var(--juxt-text-md);
1107
+ --j-button-radius: var(--juxt-radius-sm);
1108
+
1109
+ position: relative;
1110
+ display: inline-flex;
1111
+ align-items: center;
1112
+ justify-content: center;
1113
+ height: var(--j-button-height);
1114
+ padding: 0 var(--j-button-px);
1115
+ border: 1px solid transparent;
1116
+ border-radius: var(--j-button-radius);
1117
+ font-family: var(--juxt-font-sans);
1118
+ font-size: var(--j-button-font);
1119
+ font-weight: var(--juxt-weight-medium);
1120
+ line-height: 1;
1121
+ letter-spacing: var(--juxt-tracking-tight);
1122
+ white-space: nowrap;
1123
+ text-decoration: none;
1124
+ cursor: pointer;
1125
+ user-select: none;
1126
+ -webkit-tap-highlight-color: transparent;
1127
+ touch-action: manipulation;
1128
+ transition-property: background-color, border-color, color, box-shadow, transform, outline-color, outline-offset;
1129
+ transition-duration: var(--juxt-duration-fast);
1130
+ transition-timing-function: var(--juxt-ease-standard);
1131
+ }
1132
+
1133
+ /* Pressed: a short, physical dip. Released slower than pressed. */
1134
+ .j-button:active:not([aria-disabled='true'], :disabled) {
1135
+ transform: scale(0.97);
1136
+ transition-duration: var(--juxt-duration-instant);
1137
+ }
1138
+ @media (prefers-reduced-motion: reduce) {
1139
+ .j-button:active:not([aria-disabled='true'], :disabled) {
1140
+ transform: none;
1141
+ }
1142
+ }
1143
+ .j-button__content {
1144
+ display: inline-flex;
1145
+ align-items: center;
1146
+ gap: var(--j-button-gap);
1147
+ transition:
1148
+ opacity var(--juxt-duration-fast) var(--juxt-ease-standard),
1149
+ transform var(--juxt-duration-normal) var(--juxt-ease-out);
1150
+ }
1151
+ .j-button__icon {
1152
+ display: inline-flex;
1153
+ margin-inline: -0.125rem;
1154
+ opacity: 0.85;
1155
+ }
1156
+ .j-button__icon > svg {
1157
+ width: 1em;
1158
+ height: 1em;
1159
+ }
1160
+ .j-button.is-loading {
1161
+ cursor: progress;
1162
+ }
1163
+ .j-button.is-loading .j-button__content {
1164
+ opacity: 0;
1165
+ transform: scale(0.96);
1166
+ }
1167
+ .j-button__spinner {
1168
+ position: absolute;
933
1169
  inset: 0;
934
1170
  display: grid;
935
1171
  place-items: center;
@@ -1049,6 +1285,7 @@
1049
1285
  }
1050
1286
  }
1051
1287
 
1288
+ @layer theme, base, juxt, components, utilities;
1052
1289
  @layer juxt {
1053
1290
  .j-card {
1054
1291
  --j-card-p: var(--juxt-space-5);
@@ -1141,6 +1378,7 @@
1141
1378
  }
1142
1379
  }
1143
1380
 
1381
+ @layer theme, base, juxt, components, utilities;
1144
1382
  @layer juxt {
1145
1383
  .j-checkbox {
1146
1384
  --j-checkbox-size: 1rem;
@@ -1281,6 +1519,79 @@
1281
1519
  }
1282
1520
  }
1283
1521
 
1522
+ @layer theme, base, juxt, components, utilities;
1523
+ @layer juxt {
1524
+ .j-collapsible {
1525
+ font-family: var(--juxt-font-sans);
1526
+ }
1527
+ .j-collapsible__trigger {
1528
+ display: inline-flex;
1529
+ align-items: center;
1530
+ gap: var(--juxt-space-1-5);
1531
+ padding: var(--juxt-space-1) 0;
1532
+ border: 0;
1533
+ border-radius: var(--juxt-radius-xs);
1534
+ background: transparent;
1535
+ color: var(--juxt-fg);
1536
+ font: inherit;
1537
+ font-size: var(--juxt-text-md);
1538
+ font-weight: var(--juxt-weight-medium);
1539
+ letter-spacing: var(--juxt-tracking-tight);
1540
+ cursor: pointer;
1541
+ outline: 2px solid transparent;
1542
+ outline-offset: 2px;
1543
+ -webkit-tap-highlight-color: transparent;
1544
+ transition:
1545
+ color var(--juxt-duration-fast) var(--juxt-ease-standard),
1546
+ outline-color var(--juxt-duration-fast) var(--juxt-ease-out);
1547
+ }
1548
+ .j-collapsible__trigger:disabled {
1549
+ color: var(--juxt-fg-disabled);
1550
+ cursor: not-allowed;
1551
+ }
1552
+ .j-collapsible__chevron {
1553
+ flex: none;
1554
+ width: 1rem;
1555
+ height: 1rem;
1556
+ color: var(--juxt-fg-muted);
1557
+ transition: transform var(--juxt-duration-normal) var(--juxt-ease-out);
1558
+ }
1559
+ .j-collapsible[data-state='open'] .j-collapsible__chevron {
1560
+ transform: rotate(180deg);
1561
+ }
1562
+ .j-collapsible__panel {
1563
+ display: grid;
1564
+ grid-template-rows: 0fr;
1565
+ transition: grid-template-rows var(--juxt-duration-slow) var(--juxt-ease-out);
1566
+ }
1567
+ .j-collapsible[data-state='open'] .j-collapsible__panel {
1568
+ grid-template-rows: 1fr;
1569
+ }
1570
+ .j-collapsible__panel-inner {
1571
+ min-height: 0;
1572
+ overflow: hidden;
1573
+ }
1574
+ .j-collapsible__content {
1575
+ padding-top: var(--juxt-space-2);
1576
+ color: var(--juxt-fg-secondary);
1577
+ font-size: var(--juxt-text-md);
1578
+ line-height: var(--juxt-leading-normal);
1579
+ opacity: 0;
1580
+ transition: opacity var(--juxt-duration-fast) var(--juxt-ease-standard);
1581
+ }
1582
+ .j-collapsible[data-state='open'] .j-collapsible__content {
1583
+ opacity: 1;
1584
+ transition-delay: 60ms;
1585
+ }
1586
+ @media (prefers-reduced-motion: reduce) {
1587
+ .j-collapsible__panel,
1588
+ .j-collapsible__chevron {
1589
+ transition: none;
1590
+ }
1591
+ }
1592
+ }
1593
+
1594
+ @layer theme, base, juxt, components, utilities;
1284
1595
  @layer juxt {
1285
1596
  .j-command__overlay {
1286
1597
  position: fixed;
@@ -1597,6 +1908,7 @@ to {
1597
1908
  }
1598
1909
  }
1599
1910
 
1911
+ @layer theme, base, juxt, components, utilities;
1600
1912
  @layer juxt {
1601
1913
  .j-dialog__overlay {
1602
1914
  position: fixed;
@@ -1766,6 +2078,7 @@ to {
1766
2078
  }
1767
2079
  }
1768
2080
 
2081
+ @layer theme, base, juxt, components, utilities;
1769
2082
  @layer juxt {
1770
2083
  .j-menu {
1771
2084
  z-index: var(--juxt-z-popover);
@@ -1871,6 +2184,74 @@ to {
1871
2184
  }
1872
2185
  }
1873
2186
 
2187
+ @layer theme, base, juxt, components, utilities;
2188
+ @layer juxt {
2189
+ .j-empty-state {
2190
+ display: flex;
2191
+ flex-direction: column;
2192
+ align-items: center;
2193
+ max-width: 24rem;
2194
+ margin: 0 auto;
2195
+ padding: var(--juxt-space-8) var(--juxt-space-4);
2196
+ text-align: center;
2197
+ font-family: var(--juxt-font-sans);
2198
+ }
2199
+ .j-empty-state--sm {
2200
+ max-width: 18rem;
2201
+ padding: var(--juxt-space-6) var(--juxt-space-3);
2202
+ }
2203
+ .j-empty-state--lg {
2204
+ max-width: 28rem;
2205
+ padding: var(--juxt-space-12) var(--juxt-space-4);
2206
+ }
2207
+ .j-empty-state__icon {
2208
+ display: grid;
2209
+ place-items: center;
2210
+ width: 2.75rem;
2211
+ height: 2.75rem;
2212
+ margin-bottom: var(--juxt-space-4);
2213
+ border-radius: var(--juxt-radius-full);
2214
+ background: var(--juxt-surface-sunken);
2215
+ color: var(--juxt-fg-muted);
2216
+ }
2217
+ .j-empty-state--lg .j-empty-state__icon {
2218
+ width: 3.5rem;
2219
+ height: 3.5rem;
2220
+ }
2221
+ .j-empty-state__icon > svg {
2222
+ width: 1.25rem;
2223
+ height: 1.25rem;
2224
+ }
2225
+ .j-empty-state--lg .j-empty-state__icon > svg {
2226
+ width: 1.5rem;
2227
+ height: 1.5rem;
2228
+ }
2229
+ .j-empty-state__title {
2230
+ margin: 0;
2231
+ color: var(--juxt-fg);
2232
+ font-size: var(--juxt-text-lg);
2233
+ font-weight: var(--juxt-weight-semibold);
2234
+ letter-spacing: var(--juxt-tracking-tight);
2235
+ }
2236
+ .j-empty-state__description {
2237
+ margin-top: var(--juxt-space-1-5);
2238
+ color: var(--juxt-fg-muted);
2239
+ font-size: var(--juxt-text-sm);
2240
+ line-height: var(--juxt-leading-normal);
2241
+ }
2242
+ .j-empty-state__description > p {
2243
+ margin: 0;
2244
+ }
2245
+ .j-empty-state__actions {
2246
+ display: flex;
2247
+ flex-wrap: wrap;
2248
+ justify-content: center;
2249
+ gap: var(--juxt-space-2);
2250
+ margin-top: var(--juxt-space-5);
2251
+ }
2252
+ }
2253
+
2254
+ @layer theme, base, juxt, components, utilities;
1874
2255
  @layer juxt {
1875
2256
  .j-field {
1876
2257
  display: flex;
@@ -1929,6 +2310,7 @@ to {
1929
2310
  }
1930
2311
  }
1931
2312
 
2313
+ @layer theme, base, juxt, components, utilities;
1932
2314
  @layer juxt {
1933
2315
  .j-input__native {
1934
2316
  flex: 1;
@@ -1955,280 +2337,432 @@ to {
1955
2337
  }
1956
2338
  }
1957
2339
 
2340
+ @layer theme, base, juxt, components, utilities;
1958
2341
  @layer juxt {
1959
- .j-kbd-group {
1960
- display: inline-flex;
1961
- gap: 3px;
2342
+ .j-kbd-group {
2343
+ display: inline-flex;
2344
+ gap: 3px;
1962
2345
  vertical-align: middle;
1963
2346
  }
1964
- .j-kbd-group--sm .j-kbd,
1965
- .j-kbd--sm {
1966
- min-width: 1.0625rem;
1967
- height: 1.0625rem;
2347
+ .j-kbd-group--sm .j-kbd,
2348
+ .j-kbd--sm {
2349
+ min-width: 1.0625rem;
2350
+ height: 1.0625rem;
1968
2351
  font-size: 0.625rem;
1969
2352
  }
1970
- }
1971
-
1972
- @layer juxt {
1973
- .j-popover {
1974
- z-index: var(--juxt-z-popover);
1975
- box-sizing: border-box;
1976
- max-width: calc(100vw - 16px);
1977
- max-height: var(--j-available-height, 32rem);
1978
- padding: var(--juxt-space-4);
1979
- overflow: auto;
1980
- outline: none;
1981
- font-size: var(--juxt-text-md);
1982
- line-height: var(--juxt-leading-normal);
1983
- }
1984
- }
2353
+ }
1985
2354
 
2355
+ @layer theme, base, juxt, components, utilities;
1986
2356
  @layer juxt {
1987
- .j-progress {
1988
- --j-progress-height: 0.375rem;
1989
- --j-progress-fill: var(--juxt-accent);
1990
-
1991
- display: flex;
1992
- flex-direction: column;
1993
- gap: var(--juxt-space-2);
1994
- width: 100%;
2357
+ .j-pagination {
2358
+ --j-pagination-size: var(--juxt-control-md);
2359
+
2360
+ display: flex;
2361
+ align-items: center;
2362
+ gap: var(--juxt-space-1);
1995
2363
  font-family: var(--juxt-font-sans);
1996
2364
  }
1997
- .j-progress--sm {
2365
+ .j-pagination--sm {
2366
+ --j-pagination-size: var(--juxt-control-sm);
2367
+ }
2368
+ .j-pagination__list {
2369
+ display: flex;
2370
+ align-items: center;
2371
+ gap: var(--juxt-space-1);
2372
+ margin: 0;
2373
+ padding: 0;
2374
+ list-style: none;
2375
+ }
2376
+ .j-pagination__nav,
2377
+ .j-pagination__page {
2378
+ display: grid;
2379
+ flex: none;
2380
+ place-items: center;
2381
+ width: var(--j-pagination-size);
2382
+ height: var(--j-pagination-size);
2383
+ border: 1px solid transparent;
2384
+ border-radius: var(--juxt-radius-sm);
2385
+ background: transparent;
2386
+ color: var(--juxt-fg-secondary);
2387
+ font-family: inherit;
2388
+ font-size: var(--juxt-text-sm);
2389
+ font-weight: var(--juxt-weight-medium);
2390
+ font-variant-numeric: tabular-nums;
2391
+ cursor: pointer;
2392
+ transition:
2393
+ background-color var(--juxt-duration-fast) var(--juxt-ease-standard),
2394
+ border-color var(--juxt-duration-fast) var(--juxt-ease-standard),
2395
+ color var(--juxt-duration-fast) var(--juxt-ease-standard);
2396
+ }
2397
+ .j-pagination__nav > svg {
2398
+ width: 1rem;
2399
+ height: 1rem;
2400
+ }
2401
+ .j-pagination__nav:hover:not(:disabled),
2402
+ .j-pagination__page:hover:not(:disabled) {
2403
+ background: var(--juxt-surface-hover);
2404
+ color: var(--juxt-fg);
2405
+ }
2406
+ .j-pagination__nav:disabled {
2407
+ color: var(--juxt-fg-disabled);
2408
+ cursor: not-allowed;
2409
+ }
2410
+ .j-pagination__page.is-current {
2411
+ border-color: var(--juxt-border);
2412
+ background: var(--juxt-surface-active);
2413
+ color: var(--juxt-fg);
2414
+ }
2415
+ .j-pagination__page:disabled {
2416
+ color: var(--juxt-fg-disabled);
2417
+ cursor: not-allowed;
2418
+ }
2419
+ .j-pagination__ellipsis {
2420
+ display: grid;
2421
+ place-items: center;
2422
+ width: var(--j-pagination-size);
2423
+ height: var(--j-pagination-size);
2424
+ color: var(--juxt-fg-disabled);
2425
+ }
2426
+ .j-pagination__ellipsis > svg {
2427
+ width: 1rem;
2428
+ height: 1rem;
2429
+ }
2430
+ }
2431
+
2432
+ @layer theme, base, juxt, components, utilities;
2433
+ @layer juxt {
2434
+ .j-popover {
2435
+ z-index: var(--juxt-z-popover);
2436
+ box-sizing: border-box;
2437
+ max-width: calc(100vw - 16px);
2438
+ max-height: var(--j-available-height, 32rem);
2439
+ padding: var(--juxt-space-4);
2440
+ overflow: auto;
2441
+ outline: none;
2442
+ font-size: var(--juxt-text-md);
2443
+ line-height: var(--juxt-leading-normal);
2444
+ }
2445
+ }
2446
+
2447
+ @layer theme, base, juxt, components, utilities;
2448
+ @layer juxt {
2449
+ .j-progress {
2450
+ --j-progress-height: 0.375rem;
2451
+ --j-progress-fill: var(--juxt-accent);
2452
+
2453
+ display: flex;
2454
+ flex-direction: column;
2455
+ gap: var(--juxt-space-2);
2456
+ width: 100%;
2457
+ font-family: var(--juxt-font-sans);
2458
+ }
2459
+ .j-progress--sm {
1998
2460
  --j-progress-height: 0.25rem;
1999
2461
  }
2000
- .j-progress--neutral {
2462
+ .j-progress--neutral {
2001
2463
  --j-progress-fill: var(--juxt-fg);
2002
2464
  }
2003
- .j-progress__header {
2004
- display: flex;
2005
- align-items: baseline;
2006
- justify-content: space-between;
2007
- gap: var(--juxt-space-3);
2465
+ .j-progress__header {
2466
+ display: flex;
2467
+ align-items: baseline;
2468
+ justify-content: space-between;
2469
+ gap: var(--juxt-space-3);
2008
2470
  font-size: var(--juxt-text-sm);
2009
2471
  }
2010
- .j-progress__label {
2011
- color: var(--juxt-fg);
2012
- font-weight: var(--juxt-weight-medium);
2472
+ .j-progress__label {
2473
+ color: var(--juxt-fg);
2474
+ font-weight: var(--juxt-weight-medium);
2013
2475
  letter-spacing: var(--juxt-tracking-tight);
2014
2476
  }
2015
- .j-progress__value {
2016
- color: var(--juxt-fg-muted);
2477
+ .j-progress__value {
2478
+ color: var(--juxt-fg-muted);
2017
2479
  font-variant-numeric: tabular-nums;
2018
2480
  }
2019
- .j-progress__track {
2020
- position: relative;
2021
- height: var(--j-progress-height);
2022
- overflow: hidden;
2023
- border-radius: var(--juxt-radius-full);
2481
+ .j-progress__track {
2482
+ position: relative;
2483
+ height: var(--j-progress-height);
2484
+ overflow: hidden;
2485
+ border-radius: var(--juxt-radius-full);
2024
2486
  background: var(--juxt-surface-active);
2025
- }
2026
-
2487
+ }
2488
+
2027
2489
  /* Width changes are transforms, so updates glide without reflow. */
2028
- .j-progress__fill {
2029
- position: absolute;
2030
- inset: 0;
2031
- border-radius: inherit;
2032
- background: var(--j-progress-fill);
2033
- transform: scaleX(0);
2034
- transform-origin: left;
2490
+ .j-progress__fill {
2491
+ position: absolute;
2492
+ inset: 0;
2493
+ border-radius: inherit;
2494
+ background: var(--j-progress-fill);
2495
+ transform: scaleX(0);
2496
+ transform-origin: left;
2035
2497
  transition: transform var(--juxt-duration-slow) var(--juxt-ease-out);
2036
2498
  }
2037
- .j-progress.is-indeterminate .j-progress__fill {
2038
- width: 40%;
2039
- transform: none;
2499
+ .j-progress.is-indeterminate .j-progress__fill {
2500
+ width: 40%;
2501
+ transform: none;
2040
2502
  animation: j-progress-indeterminate 1.4s var(--juxt-ease-standard) infinite;
2041
2503
  }
2042
2504
  @keyframes j-progress-indeterminate {
2043
- from {
2505
+ from {
2044
2506
  transform: translateX(-100%);
2045
2507
  }
2046
- to {
2508
+ to {
2047
2509
  transform: translateX(250%);
2048
2510
  }
2049
2511
  }
2050
2512
  @media (prefers-reduced-motion: reduce) {
2051
- .j-progress.is-indeterminate .j-progress__fill {
2052
- width: 100%;
2513
+ .j-progress.is-indeterminate .j-progress__fill {
2514
+ width: 100%;
2053
2515
  animation: j-progress-pulse 1.6s ease-in-out infinite;
2054
2516
  }
2055
2517
  @keyframes j-progress-pulse {
2056
- 50% {
2518
+ 50% {
2057
2519
  opacity: 0.35;
2058
2520
  }
2059
2521
  }
2060
2522
  }
2061
- }
2523
+ }
2062
2524
 
2525
+ @layer theme, base, juxt, components, utilities;
2063
2526
  @layer juxt {
2064
- .j-radio {
2065
- --j-radio-size: 1rem;
2066
-
2067
- display: inline-flex;
2068
- align-items: flex-start;
2069
- gap: var(--juxt-space-2-5);
2527
+ .j-radio {
2528
+ --j-radio-size: 1rem;
2529
+
2530
+ display: inline-flex;
2531
+ align-items: flex-start;
2532
+ gap: var(--juxt-space-2-5);
2070
2533
  font-family: var(--juxt-font-sans);
2071
2534
  }
2072
- .j-radio__control {
2073
- position: relative;
2074
- display: inline-flex;
2075
- flex: none;
2535
+ .j-radio__control {
2536
+ position: relative;
2537
+ display: inline-flex;
2538
+ flex: none;
2076
2539
  margin-top: calc((var(--juxt-text-md) * var(--juxt-leading-snug) - var(--j-radio-size)) / 2);
2077
2540
  }
2078
- .j-radio__input {
2079
- position: absolute;
2080
- inset: -4px;
2081
- z-index: 1;
2082
- width: calc(100% + 8px);
2083
- height: calc(100% + 8px);
2084
- margin: 0;
2085
- opacity: 0;
2541
+ .j-radio__input {
2542
+ position: absolute;
2543
+ inset: -4px;
2544
+ z-index: 1;
2545
+ width: calc(100% + 8px);
2546
+ height: calc(100% + 8px);
2547
+ margin: 0;
2548
+ opacity: 0;
2086
2549
  cursor: pointer;
2087
2550
  }
2088
- .j-radio__input:disabled {
2551
+ .j-radio__input:disabled {
2089
2552
  cursor: not-allowed;
2090
2553
  }
2091
- .j-radio__circle {
2092
- position: relative;
2093
- display: block;
2094
- width: var(--j-radio-size);
2095
- height: var(--j-radio-size);
2096
- border: 1px solid var(--juxt-border-strong);
2097
- border-radius: var(--juxt-radius-full);
2098
- background: var(--juxt-surface);
2099
- box-shadow: var(--juxt-shadow-xs);
2100
- outline: 2px solid transparent;
2101
- outline-offset: 0;
2102
- transition:
2103
- background-color var(--juxt-duration-fast) var(--juxt-ease-standard),
2104
- border-color var(--juxt-duration-fast) var(--juxt-ease-standard),
2105
- transform var(--juxt-duration-fast) var(--juxt-ease-out),
2106
- outline-color var(--juxt-duration-fast) var(--juxt-ease-out),
2554
+ .j-radio__circle {
2555
+ position: relative;
2556
+ display: block;
2557
+ width: var(--j-radio-size);
2558
+ height: var(--j-radio-size);
2559
+ border: 1px solid var(--juxt-border-strong);
2560
+ border-radius: var(--juxt-radius-full);
2561
+ background: var(--juxt-surface);
2562
+ box-shadow: var(--juxt-shadow-xs);
2563
+ outline: 2px solid transparent;
2564
+ outline-offset: 0;
2565
+ transition:
2566
+ background-color var(--juxt-duration-fast) var(--juxt-ease-standard),
2567
+ border-color var(--juxt-duration-fast) var(--juxt-ease-standard),
2568
+ transform var(--juxt-duration-fast) var(--juxt-ease-out),
2569
+ outline-color var(--juxt-duration-fast) var(--juxt-ease-out),
2107
2570
  outline-offset var(--juxt-duration-fast) var(--juxt-ease-out);
2108
- }
2109
-
2571
+ }
2572
+
2110
2573
  /* The inner dot grows out of the centre once the fill lands. */
2111
- .j-radio__circle::after {
2112
- content: '';
2113
- position: absolute;
2114
- inset: 0;
2115
- margin: auto;
2116
- width: 0.375rem;
2117
- height: 0.375rem;
2118
- border-radius: var(--juxt-radius-full);
2119
- background: var(--juxt-accent-fg);
2120
- opacity: 0;
2121
- transform: scale(0.3);
2122
- transition:
2123
- opacity var(--juxt-duration-instant) var(--juxt-ease-standard),
2574
+ .j-radio__circle::after {
2575
+ content: '';
2576
+ position: absolute;
2577
+ inset: 0;
2578
+ margin: auto;
2579
+ width: 0.375rem;
2580
+ height: 0.375rem;
2581
+ border-radius: var(--juxt-radius-full);
2582
+ background: var(--juxt-accent-fg);
2583
+ opacity: 0;
2584
+ transform: scale(0.3);
2585
+ transition:
2586
+ opacity var(--juxt-duration-instant) var(--juxt-ease-standard),
2124
2587
  transform var(--juxt-duration-normal) var(--juxt-ease-out);
2125
2588
  }
2126
- .j-radio__input:hover:not(:disabled) + .j-radio__circle {
2589
+ .j-radio__input:hover:not(:disabled) + .j-radio__circle {
2127
2590
  border-color: var(--juxt-fg-muted);
2128
2591
  }
2129
- .j-radio__input:active:not(:disabled) + .j-radio__circle {
2592
+ .j-radio__input:active:not(:disabled) + .j-radio__circle {
2130
2593
  transform: scale(0.9);
2131
2594
  }
2132
- .j-radio__input:focus-visible + .j-radio__circle {
2133
- outline-color: var(--juxt-ring);
2595
+ .j-radio__input:focus-visible + .j-radio__circle {
2596
+ outline-color: var(--juxt-ring);
2134
2597
  outline-offset: 2px;
2135
2598
  }
2136
- .j-radio[data-state='checked'] .j-radio__circle {
2137
- border-color: var(--juxt-accent);
2599
+ .j-radio[data-state='checked'] .j-radio__circle {
2600
+ border-color: var(--juxt-accent);
2138
2601
  background: var(--juxt-accent);
2139
2602
  }
2140
- .j-radio[data-state='checked'] .j-radio__input:hover:not(:disabled) + .j-radio__circle {
2141
- border-color: var(--juxt-accent-hover);
2603
+ .j-radio[data-state='checked'] .j-radio__input:hover:not(:disabled) + .j-radio__circle {
2604
+ border-color: var(--juxt-accent-hover);
2142
2605
  background: var(--juxt-accent-hover);
2143
2606
  }
2144
- .j-radio[data-state='checked'] .j-radio__circle::after {
2145
- opacity: 1;
2146
- transform: none;
2607
+ .j-radio[data-state='checked'] .j-radio__circle::after {
2608
+ opacity: 1;
2609
+ transform: none;
2147
2610
  transition-delay: 30ms;
2148
2611
  }
2149
- .j-radio-group.is-invalid .j-radio:not([data-state='checked']) .j-radio__circle {
2612
+ .j-radio-group.is-invalid .j-radio:not([data-state='checked']) .j-radio__circle {
2150
2613
  border-color: var(--juxt-danger-border);
2151
2614
  }
2152
2615
  @media (prefers-reduced-motion: reduce) {
2153
- .j-radio__input:active:not(:disabled) + .j-radio__circle {
2616
+ .j-radio__input:active:not(:disabled) + .j-radio__circle {
2154
2617
  transform: none;
2155
2618
  }
2156
2619
  }
2157
- .j-radio__text {
2158
- display: flex;
2159
- flex-direction: column;
2160
- gap: var(--juxt-space-0-5);
2620
+ .j-radio__text {
2621
+ display: flex;
2622
+ flex-direction: column;
2623
+ gap: var(--juxt-space-0-5);
2161
2624
  min-width: 0;
2162
2625
  }
2163
- .j-radio__label {
2164
- color: var(--juxt-fg);
2165
- font-size: var(--juxt-text-md);
2166
- line-height: var(--juxt-leading-snug);
2167
- letter-spacing: var(--juxt-tracking-tight);
2168
- cursor: pointer;
2626
+ .j-radio__label {
2627
+ color: var(--juxt-fg);
2628
+ font-size: var(--juxt-text-md);
2629
+ line-height: var(--juxt-leading-snug);
2630
+ letter-spacing: var(--juxt-tracking-tight);
2631
+ cursor: pointer;
2169
2632
  user-select: none;
2170
2633
  }
2171
- .j-radio__description {
2172
- color: var(--juxt-fg-muted);
2173
- font-size: var(--juxt-text-sm);
2634
+ .j-radio__description {
2635
+ color: var(--juxt-fg-muted);
2636
+ font-size: var(--juxt-text-sm);
2174
2637
  line-height: var(--juxt-leading-normal);
2175
2638
  }
2176
- .j-radio.is-disabled .j-radio__circle {
2177
- opacity: 0.5;
2639
+ .j-radio.is-disabled .j-radio__circle {
2640
+ opacity: 0.5;
2178
2641
  box-shadow: none;
2179
2642
  }
2180
- .j-radio.is-disabled .j-radio__label {
2181
- color: var(--juxt-fg-muted);
2643
+ .j-radio.is-disabled .j-radio__label {
2644
+ color: var(--juxt-fg-muted);
2182
2645
  cursor: not-allowed;
2183
2646
  }
2184
- }
2647
+ }
2185
2648
 
2649
+ @layer theme, base, juxt, components, utilities;
2186
2650
  @layer juxt {
2187
- .j-radio-group {
2188
- display: flex;
2189
- flex-direction: column;
2190
- gap: var(--juxt-space-1-5);
2191
- min-width: 0;
2192
- margin: 0;
2193
- padding: 0;
2194
- border: 0;
2651
+ .j-radio-group {
2652
+ display: flex;
2653
+ flex-direction: column;
2654
+ gap: var(--juxt-space-1-5);
2655
+ min-width: 0;
2656
+ margin: 0;
2657
+ padding: 0;
2658
+ border: 0;
2195
2659
  font-family: var(--juxt-font-sans);
2196
2660
  }
2197
- .j-radio-group__legend {
2198
- display: inline-flex;
2199
- gap: var(--juxt-space-0-5);
2200
- margin-bottom: var(--juxt-space-1-5);
2201
- padding: 0;
2202
- color: var(--juxt-fg);
2203
- font-size: var(--juxt-text-sm);
2204
- font-weight: var(--juxt-weight-medium);
2205
- line-height: var(--juxt-leading-snug);
2661
+ .j-radio-group__legend {
2662
+ display: inline-flex;
2663
+ gap: var(--juxt-space-0-5);
2664
+ margin-bottom: var(--juxt-space-1-5);
2665
+ padding: 0;
2666
+ color: var(--juxt-fg);
2667
+ font-size: var(--juxt-text-sm);
2668
+ font-weight: var(--juxt-weight-medium);
2669
+ line-height: var(--juxt-leading-snug);
2206
2670
  letter-spacing: var(--juxt-tracking-tight);
2207
2671
  }
2208
- .j-radio-group__description,
2209
- .j-radio-group__error {
2210
- margin: calc(var(--juxt-space-1) * -1) 0 var(--juxt-space-1-5);
2211
- color: var(--juxt-fg-muted);
2212
- font-size: var(--juxt-text-xs);
2672
+ .j-radio-group__description,
2673
+ .j-radio-group__error {
2674
+ margin: calc(var(--juxt-space-1) * -1) 0 var(--juxt-space-1-5);
2675
+ color: var(--juxt-fg-muted);
2676
+ font-size: var(--juxt-text-xs);
2213
2677
  line-height: var(--juxt-leading-normal);
2214
2678
  }
2215
- .j-radio-group__error {
2216
- margin: var(--juxt-space-1) 0 0;
2679
+ .j-radio-group__error {
2680
+ margin: var(--juxt-space-1) 0 0;
2217
2681
  color: var(--juxt-danger-text);
2218
2682
  }
2219
- .j-radio-group__items {
2683
+ .j-radio-group__items {
2220
2684
  display: flex;
2221
2685
  }
2222
- .j-radio-group__items--vertical {
2223
- flex-direction: column;
2686
+ .j-radio-group__items--vertical {
2687
+ flex-direction: column;
2224
2688
  gap: var(--juxt-space-3);
2225
2689
  }
2226
- .j-radio-group__items--horizontal {
2227
- flex-wrap: wrap;
2690
+ .j-radio-group__items--horizontal {
2691
+ flex-wrap: wrap;
2228
2692
  gap: var(--juxt-space-3) var(--juxt-space-6);
2229
2693
  }
2694
+ }
2695
+
2696
+ @layer theme, base, juxt, components, utilities;
2697
+ @layer juxt {
2698
+ .j-rating {
2699
+ --j-rating-size: 1.25rem;
2700
+
2701
+ display: inline-flex;
2702
+ align-items: center;
2703
+ gap: var(--juxt-space-0-5);
2704
+ font-family: var(--juxt-font-sans);
2705
+ }
2706
+ .j-rating--sm {
2707
+ --j-rating-size: 1rem;
2708
+ }
2709
+ .j-rating--lg {
2710
+ --j-rating-size: 1.5rem;
2711
+ }
2712
+ .j-rating__star,
2713
+ .j-rating__button {
2714
+ position: relative;
2715
+ display: inline-flex;
2716
+ flex: none;
2717
+ width: var(--j-rating-size);
2718
+ height: var(--j-rating-size);
2719
+ padding: 0;
2720
+ border: 0;
2721
+ background: transparent;
2722
+ color: var(--juxt-fg-disabled);
2723
+ cursor: default;
2724
+ }
2725
+ .j-rating__button {
2726
+ border-radius: var(--juxt-radius-xs);
2727
+ cursor: pointer;
2728
+ transition: transform var(--juxt-duration-fast) var(--juxt-ease-out);
2729
+ }
2730
+ .j-rating__button:hover:not(:disabled) {
2731
+ transform: scale(1.1);
2732
+ }
2733
+ .j-rating__button:disabled {
2734
+ cursor: not-allowed;
2735
+ }
2736
+ .j-rating.is-disabled .j-rating__button {
2737
+ opacity: 0.5;
2738
+ }
2739
+ .j-rating__star-bg,
2740
+ .j-rating__star-fill > svg {
2741
+ position: absolute;
2742
+ inset: 0;
2743
+ width: 100%;
2744
+ height: 100%;
2745
+ fill: currentColor;
2746
+ stroke: none;
2747
+ }
2748
+ .j-rating__star-fill {
2749
+ position: absolute;
2750
+ inset: 0;
2751
+ overflow: hidden;
2752
+ color: var(--juxt-warning);
2753
+ transition: width var(--juxt-duration-fast) var(--juxt-ease-out);
2754
+ }
2755
+ @media (prefers-reduced-motion: reduce) {
2756
+ .j-rating__button:hover:not(:disabled) {
2757
+ transform: none;
2758
+ }
2759
+ .j-rating__star-fill {
2760
+ transition: none;
2761
+ }
2230
2762
  }
2763
+ }
2231
2764
 
2765
+ @layer theme, base, juxt, components, utilities;
2232
2766
  @layer juxt {
2233
2767
  .j-select__trigger {
2234
2768
  width: 100%;
@@ -2340,284 +2874,443 @@ to {
2340
2874
  }
2341
2875
  }
2342
2876
 
2877
+ @layer theme, base, juxt, components, utilities;
2343
2878
  @layer juxt {
2344
- .j-separator {
2345
- flex: none;
2879
+ .j-separator {
2880
+ flex: none;
2346
2881
  background: var(--juxt-border-subtle);
2347
2882
  }
2348
- .dark .j-separator,
2349
- [data-theme='dark'] .j-separator {
2883
+ .dark .j-separator,
2884
+ [data-theme='dark'] .j-separator {
2350
2885
  background: var(--juxt-border);
2351
2886
  }
2352
- .j-separator--horizontal {
2353
- width: 100%;
2887
+ .j-separator--horizontal {
2888
+ width: 100%;
2354
2889
  height: 1px;
2355
2890
  }
2356
- .j-separator--vertical {
2357
- align-self: stretch;
2358
- width: 1px;
2891
+ .j-separator--vertical {
2892
+ align-self: stretch;
2893
+ width: 1px;
2359
2894
  min-height: 1rem;
2360
2895
  }
2361
- .j-separator--labelled {
2362
- display: flex;
2363
- align-items: center;
2364
- gap: var(--juxt-space-3);
2365
- height: auto;
2366
- background: none !important;
2367
- color: var(--juxt-fg-muted);
2368
- font-family: var(--juxt-font-sans);
2896
+ .j-separator--labelled {
2897
+ display: flex;
2898
+ align-items: center;
2899
+ gap: var(--juxt-space-3);
2900
+ height: auto;
2901
+ background: none !important;
2902
+ color: var(--juxt-fg-muted);
2903
+ font-family: var(--juxt-font-sans);
2369
2904
  font-size: var(--juxt-text-xs);
2370
2905
  }
2371
- .j-separator--labelled::before,
2372
- .j-separator--labelled::after {
2373
- content: '';
2374
- flex: 1;
2375
- height: 1px;
2906
+ .j-separator--labelled::before,
2907
+ .j-separator--labelled::after {
2908
+ content: '';
2909
+ flex: 1;
2910
+ height: 1px;
2376
2911
  background: var(--juxt-border-subtle);
2377
2912
  }
2378
- .dark .j-separator--labelled::before,
2379
- .dark .j-separator--labelled::after,
2380
- [data-theme='dark'] .j-separator--labelled::before,
2381
- [data-theme='dark'] .j-separator--labelled::after {
2913
+ .dark .j-separator--labelled::before,
2914
+ .dark .j-separator--labelled::after,
2915
+ [data-theme='dark'] .j-separator--labelled::before,
2916
+ [data-theme='dark'] .j-separator--labelled::after {
2382
2917
  background: var(--juxt-border);
2383
2918
  }
2384
- .j-separator__label {
2919
+ .j-separator__label {
2385
2920
  flex: none;
2386
2921
  }
2387
- }
2922
+ }
2388
2923
 
2924
+ @layer theme, base, juxt, components, utilities;
2389
2925
  @layer juxt {
2390
- .j-sheet__overlay {
2391
- position: fixed;
2392
- inset: 0;
2393
- z-index: var(--juxt-z-overlay);
2926
+ .j-sheet__overlay {
2927
+ position: fixed;
2928
+ inset: 0;
2929
+ z-index: var(--juxt-z-overlay);
2394
2930
  background: var(--juxt-overlay);
2395
2931
  }
2396
- .j-sheet__positioner {
2397
- position: fixed;
2398
- inset: 0;
2399
- z-index: var(--juxt-z-modal);
2400
- display: flex;
2932
+ .j-sheet__positioner {
2933
+ position: fixed;
2934
+ inset: 0;
2935
+ z-index: var(--juxt-z-modal);
2936
+ display: flex;
2401
2937
  padding: var(--juxt-space-2);
2402
2938
  }
2403
- .j-sheet__positioner--right {
2939
+ .j-sheet__positioner--right {
2404
2940
  justify-content: flex-end;
2405
2941
  }
2406
- .j-sheet__positioner--left {
2942
+ .j-sheet__positioner--left {
2407
2943
  justify-content: flex-start;
2408
2944
  }
2409
- .j-sheet__positioner--bottom {
2410
- align-items: flex-end;
2945
+ .j-sheet__positioner--bottom {
2946
+ align-items: flex-end;
2411
2947
  padding-bottom: max(var(--juxt-space-2), env(safe-area-inset-bottom));
2412
- }
2413
-
2414
- /* A floating panel with a small inset from the edges — calmer than edge-to-edge. */
2415
- .j-sheet {
2416
- position: relative;
2417
- display: flex;
2418
- flex-direction: column;
2419
- width: 100%;
2420
- border: 1px solid var(--juxt-border);
2421
- border-radius: var(--juxt-radius-lg);
2422
- background: var(--juxt-surface-raised);
2423
- box-shadow: var(--juxt-shadow-lg);
2424
- color: var(--juxt-fg);
2425
- font-family: var(--juxt-font-sans);
2948
+ }
2949
+
2950
+ /* A floating panel with a small inset from the edges | calmer than edge-to-edge. */
2951
+ .j-sheet {
2952
+ position: relative;
2953
+ display: flex;
2954
+ flex-direction: column;
2955
+ width: 100%;
2956
+ border: 1px solid var(--juxt-border);
2957
+ border-radius: var(--juxt-radius-lg);
2958
+ background: var(--juxt-surface-raised);
2959
+ box-shadow: var(--juxt-shadow-lg);
2960
+ color: var(--juxt-fg);
2961
+ font-family: var(--juxt-font-sans);
2426
2962
  outline: none;
2427
2963
  }
2428
- .j-sheet--right,
2429
- .j-sheet--left {
2964
+ .j-sheet--right,
2965
+ .j-sheet--left {
2430
2966
  height: 100%;
2431
2967
  }
2432
- .j-sheet--right.j-sheet--sm,
2433
- .j-sheet--left.j-sheet--sm {
2968
+ .j-sheet--right.j-sheet--sm,
2969
+ .j-sheet--left.j-sheet--sm {
2434
2970
  max-width: 20rem;
2435
2971
  }
2436
- .j-sheet--right.j-sheet--md,
2437
- .j-sheet--left.j-sheet--md {
2972
+ .j-sheet--right.j-sheet--md,
2973
+ .j-sheet--left.j-sheet--md {
2438
2974
  max-width: 25rem;
2439
2975
  }
2440
- .j-sheet--right.j-sheet--lg,
2441
- .j-sheet--left.j-sheet--lg {
2976
+ .j-sheet--right.j-sheet--lg,
2977
+ .j-sheet--left.j-sheet--lg {
2442
2978
  max-width: 35rem;
2443
2979
  }
2444
- .j-sheet--bottom.j-sheet--sm {
2980
+ .j-sheet--bottom.j-sheet--sm {
2445
2981
  max-height: 20rem;
2446
2982
  }
2447
- .j-sheet--bottom.j-sheet--md {
2983
+ .j-sheet--bottom.j-sheet--md {
2448
2984
  max-height: 25rem;
2449
2985
  }
2450
- .j-sheet--bottom.j-sheet--lg {
2986
+ .j-sheet--bottom.j-sheet--lg {
2451
2987
  max-height: min(35rem, calc(100dvh - var(--juxt-space-12)));
2452
2988
  }
2453
- .j-sheet__header {
2454
- display: flex;
2455
- flex-direction: column;
2456
- gap: var(--juxt-space-1-5);
2457
- padding: var(--juxt-space-5) var(--juxt-space-12) var(--juxt-space-4) var(--juxt-space-5);
2989
+ .j-sheet__header {
2990
+ display: flex;
2991
+ flex-direction: column;
2992
+ gap: var(--juxt-space-1-5);
2993
+ padding: var(--juxt-space-5) var(--juxt-space-12) var(--juxt-space-4) var(--juxt-space-5);
2458
2994
  border-bottom: 1px solid var(--juxt-border-subtle);
2459
2995
  }
2460
- .dark .j-sheet__header,
2461
- [data-theme='dark'] .j-sheet__header {
2996
+ .dark .j-sheet__header,
2997
+ [data-theme='dark'] .j-sheet__header {
2462
2998
  border-bottom-color: var(--juxt-border);
2463
2999
  }
2464
- .j-sheet__title {
2465
- margin: 0;
2466
- font-size: var(--juxt-text-lg);
2467
- font-weight: var(--juxt-weight-semibold);
2468
- line-height: var(--juxt-leading-snug);
3000
+ .j-sheet__title {
3001
+ margin: 0;
3002
+ font-size: var(--juxt-text-lg);
3003
+ font-weight: var(--juxt-weight-semibold);
3004
+ line-height: var(--juxt-leading-snug);
2469
3005
  letter-spacing: var(--juxt-tracking-tight);
2470
3006
  }
2471
- .j-sheet__description {
2472
- margin: 0;
2473
- color: var(--juxt-fg-secondary);
2474
- font-size: var(--juxt-text-md);
3007
+ .j-sheet__description {
3008
+ margin: 0;
3009
+ color: var(--juxt-fg-secondary);
3010
+ font-size: var(--juxt-text-md);
2475
3011
  line-height: var(--juxt-leading-normal);
2476
3012
  }
2477
- .j-sheet__body {
2478
- flex: 1;
2479
- min-height: 0;
2480
- padding: var(--juxt-space-5);
2481
- overflow-y: auto;
2482
- overscroll-behavior: contain;
2483
- color: var(--juxt-fg-secondary);
2484
- font-size: var(--juxt-text-md);
3013
+ .j-sheet__body {
3014
+ flex: 1;
3015
+ min-height: 0;
3016
+ padding: var(--juxt-space-5);
3017
+ overflow-y: auto;
3018
+ overscroll-behavior: contain;
3019
+ color: var(--juxt-fg-secondary);
3020
+ font-size: var(--juxt-text-md);
2485
3021
  line-height: var(--juxt-leading-normal);
2486
3022
  }
2487
- .j-sheet__footer {
2488
- display: flex;
2489
- justify-content: flex-end;
2490
- gap: var(--juxt-space-2);
2491
- padding: var(--juxt-space-4) var(--juxt-space-5);
3023
+ .j-sheet__footer {
3024
+ display: flex;
3025
+ justify-content: flex-end;
3026
+ gap: var(--juxt-space-2);
3027
+ padding: var(--juxt-space-4) var(--juxt-space-5);
2492
3028
  border-top: 1px solid var(--juxt-border-subtle);
2493
3029
  }
2494
- .dark .j-sheet__footer,
2495
- [data-theme='dark'] .j-sheet__footer {
3030
+ .dark .j-sheet__footer,
3031
+ [data-theme='dark'] .j-sheet__footer {
2496
3032
  border-top-color: var(--juxt-border);
2497
3033
  }
2498
- .j-sheet__close {
2499
- position: absolute;
2500
- top: var(--juxt-space-3);
2501
- right: var(--juxt-space-3);
2502
- display: grid;
2503
- place-items: center;
2504
- width: var(--juxt-control-sm);
2505
- height: var(--juxt-control-sm);
2506
- padding: 0;
2507
- border: 0;
2508
- border-radius: var(--juxt-radius-sm);
2509
- background: transparent;
2510
- color: var(--juxt-fg-muted);
2511
- cursor: pointer;
3034
+ .j-sheet__close {
3035
+ position: absolute;
3036
+ top: var(--juxt-space-3);
3037
+ right: var(--juxt-space-3);
3038
+ display: grid;
3039
+ place-items: center;
3040
+ width: var(--juxt-control-sm);
3041
+ height: var(--juxt-control-sm);
3042
+ padding: 0;
3043
+ border: 0;
3044
+ border-radius: var(--juxt-radius-sm);
3045
+ background: transparent;
3046
+ color: var(--juxt-fg-muted);
3047
+ cursor: pointer;
2512
3048
  transition-property: background-color, color, outline-color, outline-offset;
2513
3049
  }
2514
- .j-sheet__close:hover {
2515
- background: var(--juxt-surface-hover);
3050
+ .j-sheet__close:hover {
3051
+ background: var(--juxt-surface-hover);
2516
3052
  color: var(--juxt-fg);
2517
3053
  }
2518
- .j-sheet__close > svg {
2519
- width: 1rem;
3054
+ .j-sheet__close > svg {
3055
+ width: 1rem;
2520
3056
  height: 1rem;
2521
3057
  }
2522
- .j-sheet.is-nudging {
3058
+ .j-sheet.is-nudging {
2523
3059
  animation: j-sheet-nudge 220ms var(--juxt-ease-out);
2524
3060
  }
2525
3061
  @keyframes j-sheet-nudge {
2526
- 40% {
3062
+ 40% {
2527
3063
  transform: scale(1.006);
2528
3064
  }
2529
- }
2530
-
3065
+ }
3066
+
2531
3067
  /* Motion: the backdrop fades; the sheet slides in from its edge. */
2532
- .j-sheet-overlay-enter-active {
3068
+ .j-sheet-overlay-enter-active {
2533
3069
  transition: opacity var(--juxt-duration-normal) var(--juxt-ease-out);
2534
3070
  }
2535
- .j-sheet-overlay-leave-active {
3071
+ .j-sheet-overlay-leave-active {
2536
3072
  transition: opacity var(--juxt-duration-fast) var(--juxt-ease-in);
2537
3073
  }
2538
- .j-sheet-overlay-enter-from,
2539
- .j-sheet-overlay-leave-to {
3074
+ .j-sheet-overlay-enter-from,
3075
+ .j-sheet-overlay-leave-to {
2540
3076
  opacity: 0;
2541
3077
  }
2542
- .j-sheet-enter-active .j-sheet {
3078
+ .j-sheet-enter-active .j-sheet {
2543
3079
  transition: transform 280ms var(--juxt-ease-out);
2544
3080
  }
2545
- .j-sheet-leave-active .j-sheet {
3081
+ .j-sheet-leave-active .j-sheet {
2546
3082
  transition: transform var(--juxt-duration-normal) var(--juxt-ease-in);
2547
3083
  }
2548
- .j-sheet-enter-from .j-sheet--right,
2549
- .j-sheet-leave-to .j-sheet--right {
3084
+ .j-sheet-enter-from .j-sheet--right,
3085
+ .j-sheet-leave-to .j-sheet--right {
2550
3086
  transform: translateX(calc(100% + var(--juxt-space-4)));
2551
3087
  }
2552
- .j-sheet-enter-from .j-sheet--left,
2553
- .j-sheet-leave-to .j-sheet--left {
3088
+ .j-sheet-enter-from .j-sheet--left,
3089
+ .j-sheet-leave-to .j-sheet--left {
2554
3090
  transform: translateX(calc(-100% - var(--juxt-space-4)));
2555
3091
  }
2556
- .j-sheet-enter-from .j-sheet--bottom,
2557
- .j-sheet-leave-to .j-sheet--bottom {
3092
+ .j-sheet-enter-from .j-sheet--bottom,
3093
+ .j-sheet-leave-to .j-sheet--bottom {
2558
3094
  transform: translateY(calc(100% + var(--juxt-space-4)));
3095
+ }
3096
+
3097
+ /* Reduced motion: the sheet fades in place instead of travelling. */
3098
+ @media (prefers-reduced-motion: reduce) {
3099
+ .j-sheet-enter-active .j-sheet,
3100
+ .j-sheet-leave-active .j-sheet {
3101
+ transition: opacity var(--juxt-duration-normal) var(--juxt-ease-standard);
3102
+ }
3103
+ .j-sheet-enter-from .j-sheet,
3104
+ .j-sheet-leave-to .j-sheet {
3105
+ opacity: 0;
3106
+ transform: none !important;
3107
+ }
3108
+ }
3109
+ }
3110
+
3111
+ @layer theme, base, juxt, components, utilities;
3112
+ @layer juxt {
3113
+ .j-skeleton {
3114
+ display: block;
3115
+ width: 100%;
3116
+ height: 1rem;
3117
+ border-radius: var(--juxt-radius-sm);
3118
+ background: var(--juxt-surface-active);
3119
+ animation: j-skeleton-pulse 1.8s var(--juxt-ease-standard) infinite;
3120
+ }
3121
+ .j-skeleton--circle {
3122
+ width: 2rem;
3123
+ height: 2rem;
3124
+ border-radius: var(--juxt-radius-full);
3125
+ }
3126
+ .j-skeleton--text {
3127
+ height: 0.75rem;
3128
+ border-radius: var(--juxt-radius-xs);
3129
+ }
3130
+ .j-skeleton-lines {
3131
+ display: flex;
3132
+ flex-direction: column;
3133
+ gap: var(--juxt-space-2);
3134
+ width: 100%;
3135
+ }
3136
+
3137
+ /* A slow breath, not a shimmer | loading shouldn't compete for attention. */
3138
+ @keyframes j-skeleton-pulse {
3139
+ 50% {
3140
+ opacity: 0.5;
3141
+ }
3142
+ }
3143
+ @media (prefers-reduced-motion: reduce) {
3144
+ .j-skeleton {
3145
+ animation: none;
3146
+ }
3147
+ }
3148
+ }
3149
+
3150
+ @layer theme, base, juxt, components, utilities;
3151
+ @layer juxt {
3152
+ .j-slider {
3153
+ --j-slider-track: 0.25rem;
3154
+ --j-slider-thumb: 1rem;
3155
+
3156
+ display: flex;
3157
+ align-items: center;
3158
+ width: 100%;
3159
+ padding: calc(var(--j-slider-thumb) / 2) 0;
3160
+ font-family: var(--juxt-font-sans);
3161
+ touch-action: none;
3162
+ }
3163
+ .j-slider--sm {
3164
+ --j-slider-track: 0.1875rem;
3165
+ --j-slider-thumb: 0.875rem;
3166
+ }
3167
+ .j-slider__track {
3168
+ position: relative;
3169
+ width: 100%;
3170
+ height: var(--j-slider-track);
3171
+ border-radius: var(--juxt-radius-full);
3172
+ background: var(--juxt-surface-active);
3173
+ cursor: pointer;
3174
+ }
3175
+ .j-slider.is-disabled .j-slider__track {
3176
+ cursor: not-allowed;
3177
+ opacity: 0.5;
3178
+ }
3179
+ .j-slider__range {
3180
+ position: absolute;
3181
+ top: 0;
3182
+ bottom: 0;
3183
+ border-radius: var(--juxt-radius-full);
3184
+ background: var(--juxt-accent);
3185
+ }
3186
+ .j-slider__thumb {
3187
+ position: absolute;
3188
+ top: 50%;
3189
+ width: var(--j-slider-thumb);
3190
+ height: var(--j-slider-thumb);
3191
+ border-radius: var(--juxt-radius-full);
3192
+ background: var(--juxt-surface);
3193
+ box-shadow: 0 0 0 1px var(--juxt-border-strong), var(--juxt-shadow-sm);
3194
+ cursor: grab;
3195
+ transform: translate(-50%, -50%);
3196
+ transition:
3197
+ box-shadow var(--juxt-duration-fast) var(--juxt-ease-out),
3198
+ left var(--juxt-duration-fast) var(--juxt-ease-out);
3199
+ }
3200
+ .j-slider__thumb.is-dragging {
3201
+ cursor: grabbing;
3202
+ transition: none;
3203
+ }
3204
+ .j-slider__thumb:hover {
3205
+ box-shadow: 0 0 0 1px var(--juxt-accent), var(--juxt-shadow-sm);
3206
+ }
3207
+ .j-slider__thumb:focus-visible {
3208
+ outline-color: var(--juxt-ring);
3209
+ outline-offset: 3px;
3210
+ }
3211
+ .j-slider.is-disabled .j-slider__thumb {
3212
+ cursor: not-allowed;
3213
+ }
3214
+ .j-slider__bubble {
3215
+ position: absolute;
3216
+ bottom: calc(100% + var(--juxt-space-2));
3217
+ left: 50%;
3218
+ padding: var(--juxt-space-0-5) var(--juxt-space-1-5);
3219
+ border-radius: var(--juxt-radius-xs);
3220
+ background: var(--juxt-tooltip-bg);
3221
+ color: var(--juxt-tooltip-fg);
3222
+ font-size: var(--juxt-text-2xs);
3223
+ font-weight: var(--juxt-weight-medium);
3224
+ font-variant-numeric: tabular-nums;
3225
+ white-space: nowrap;
3226
+ pointer-events: none;
3227
+ transform: translateX(-50%);
2559
3228
  }
2560
-
2561
- /* Reduced motion: the sheet fades in place instead of travelling. */
2562
3229
  @media (prefers-reduced-motion: reduce) {
2563
- .j-sheet-enter-active .j-sheet,
2564
- .j-sheet-leave-active .j-sheet {
2565
- transition: opacity var(--juxt-duration-normal) var(--juxt-ease-standard);
2566
- }
2567
- .j-sheet-enter-from .j-sheet,
2568
- .j-sheet-leave-to .j-sheet {
2569
- opacity: 0;
2570
- transform: none !important;
3230
+ .j-slider__thumb {
3231
+ transition: none;
2571
3232
  }
2572
3233
  }
3234
+ }
3235
+
3236
+ @layer theme, base, juxt, components, utilities;
3237
+ @layer juxt {
3238
+ .j-spinner-wrap {
3239
+ display: inline-flex;
3240
+ color: var(--juxt-fg-muted);
3241
+ vertical-align: middle;
2573
3242
  }
3243
+ }
2574
3244
 
3245
+ @layer theme, base, juxt, components, utilities;
2575
3246
  @layer juxt {
2576
- .j-skeleton {
2577
- display: block;
2578
- width: 100%;
2579
- height: 1rem;
2580
- border-radius: var(--juxt-radius-sm);
2581
- background: var(--juxt-surface-active);
2582
- animation: j-skeleton-pulse 1.8s var(--juxt-ease-standard) infinite;
3247
+ .j-stat {
3248
+ display: flex;
3249
+ flex-direction: column;
3250
+ gap: var(--juxt-space-1-5);
3251
+ font-family: var(--juxt-font-sans);
2583
3252
  }
2584
- .j-skeleton--circle {
2585
- width: 2rem;
2586
- height: 2rem;
2587
- border-radius: var(--juxt-radius-full);
3253
+ .j-stat__header {
3254
+ display: flex;
3255
+ align-items: center;
3256
+ gap: var(--juxt-space-1-5);
2588
3257
  }
2589
- .j-skeleton--text {
2590
- height: 0.75rem;
2591
- border-radius: var(--juxt-radius-xs);
3258
+ .j-stat__icon {
3259
+ display: grid;
3260
+ place-items: center;
3261
+ color: var(--juxt-fg-muted);
2592
3262
  }
2593
- .j-skeleton-lines {
2594
- display: flex;
2595
- flex-direction: column;
2596
- gap: var(--juxt-space-2);
2597
- width: 100%;
3263
+ .j-stat__icon > svg {
3264
+ width: 0.875rem;
3265
+ height: 0.875rem;
2598
3266
  }
2599
-
2600
- /* A slow breath, not a shimmer — loading shouldn't compete for attention. */
2601
- @keyframes j-skeleton-pulse {
2602
- 50% {
2603
- opacity: 0.5;
3267
+ .j-stat__label {
3268
+ color: var(--juxt-fg-muted);
3269
+ font-size: var(--juxt-text-sm);
3270
+ font-weight: var(--juxt-weight-medium);
3271
+ letter-spacing: var(--juxt-tracking-tight);
2604
3272
  }
3273
+ .j-stat__row {
3274
+ display: flex;
3275
+ align-items: baseline;
3276
+ gap: var(--juxt-space-2);
2605
3277
  }
2606
- @media (prefers-reduced-motion: reduce) {
2607
- .j-skeleton {
2608
- animation: none;
3278
+ .j-stat__value {
3279
+ color: var(--juxt-fg);
3280
+ font-size: var(--juxt-text-3xl);
3281
+ font-weight: var(--juxt-weight-semibold);
3282
+ line-height: var(--juxt-leading-tight);
3283
+ letter-spacing: var(--juxt-tracking-tighter);
3284
+ font-variant-numeric: tabular-nums;
2609
3285
  }
3286
+ .j-stat__delta {
3287
+ display: inline-flex;
3288
+ align-items: center;
3289
+ gap: 0.125rem;
3290
+ color: var(--juxt-fg-muted);
3291
+ font-size: var(--juxt-text-sm);
3292
+ font-weight: var(--juxt-weight-medium);
3293
+ font-variant-numeric: tabular-nums;
2610
3294
  }
3295
+ .j-stat__delta > svg {
3296
+ width: 0.875rem;
3297
+ height: 0.875rem;
2611
3298
  }
2612
-
2613
- @layer juxt {
2614
- .j-spinner-wrap {
2615
- display: inline-flex;
2616
- color: var(--juxt-fg-muted);
2617
- vertical-align: middle;
3299
+ .j-stat__delta--up {
3300
+ color: var(--juxt-success-text);
3301
+ }
3302
+ .j-stat__delta--down {
3303
+ color: var(--juxt-danger-text);
2618
3304
  }
3305
+ .j-stat__description {
3306
+ margin: 0;
3307
+ color: var(--juxt-fg-muted);
3308
+ font-size: var(--juxt-text-xs);
3309
+ line-height: var(--juxt-leading-normal);
2619
3310
  }
3311
+ }
2620
3312
 
3313
+ @layer theme, base, juxt, components, utilities;
2621
3314
  @layer juxt {
2622
3315
  .j-switch {
2623
3316
  --j-switch-w: 2rem;
@@ -2728,6 +3421,7 @@ to {
2728
3421
  }
2729
3422
  }
2730
3423
 
3424
+ @layer theme, base, juxt, components, utilities;
2731
3425
  @layer juxt {
2732
3426
  .j-tabs {
2733
3427
  --j-tab-height: var(--juxt-control-md);
@@ -2882,6 +3576,110 @@ from {
2882
3576
  }
2883
3577
  }
2884
3578
 
3579
+ @layer theme, base, juxt, components, utilities;
3580
+ @layer juxt {
3581
+ /*
3582
+ * Tags are pills, not stamps | fully rounded and carrying their own remove
3583
+ * affordance, which is what sets them apart from the static JBadge.
3584
+ */
3585
+ .j-tag {
3586
+ --j-tag-fg: var(--juxt-fg-secondary);
3587
+ --j-tag-bg: var(--juxt-surface-active);
3588
+
3589
+ display: inline-flex;
3590
+ flex: none;
3591
+ align-items: center;
3592
+ gap: 0.3125rem;
3593
+ height: 1.375rem;
3594
+ padding: 0 var(--juxt-space-1) 0 var(--juxt-space-2-5);
3595
+ border-radius: var(--juxt-radius-full);
3596
+ background: var(--j-tag-bg);
3597
+ color: var(--j-tag-fg);
3598
+ font-family: var(--juxt-font-sans);
3599
+ font-size: var(--juxt-text-xs);
3600
+ font-weight: var(--juxt-weight-medium);
3601
+ line-height: 1;
3602
+ white-space: nowrap;
3603
+ }
3604
+ .j-tag--sm {
3605
+ height: 1.125rem;
3606
+ padding: 0 0.1875rem 0 var(--juxt-space-2);
3607
+ font-size: var(--juxt-text-2xs);
3608
+ }
3609
+ .j-tag--success {
3610
+ --j-tag-fg: var(--juxt-success-text);
3611
+ --j-tag-bg: var(--juxt-success-soft);
3612
+ }
3613
+ .j-tag--warning {
3614
+ --j-tag-fg: var(--juxt-warning-text);
3615
+ --j-tag-bg: var(--juxt-warning-soft);
3616
+ }
3617
+ .j-tag--destructive {
3618
+ --j-tag-fg: var(--juxt-danger-text);
3619
+ --j-tag-bg: var(--juxt-danger-soft);
3620
+ }
3621
+ .j-tag--accent {
3622
+ --j-tag-fg: var(--juxt-accent-fg);
3623
+ --j-tag-bg: var(--juxt-accent-strong);
3624
+ }
3625
+ .j-tag__icon {
3626
+ display: inline-flex;
3627
+ margin-left: -0.0625rem;
3628
+ }
3629
+ .j-tag__icon > svg {
3630
+ width: 0.75rem;
3631
+ height: 0.75rem;
3632
+ }
3633
+ .j-tag__label {
3634
+ overflow: hidden;
3635
+ text-overflow: ellipsis;
3636
+ }
3637
+ .j-tag__remove {
3638
+ display: grid;
3639
+ flex: none;
3640
+ place-items: center;
3641
+ width: 1.125rem;
3642
+ height: 1.125rem;
3643
+ padding: 0;
3644
+ border: 0;
3645
+ border-radius: var(--juxt-radius-full);
3646
+ background: transparent;
3647
+ color: inherit;
3648
+ cursor: pointer;
3649
+ opacity: 0.7;
3650
+ transition:
3651
+ background-color var(--juxt-duration-fast) var(--juxt-ease-standard),
3652
+ opacity var(--juxt-duration-fast) var(--juxt-ease-standard);
3653
+ }
3654
+ .j-tag--sm .j-tag__remove {
3655
+ width: 0.875rem;
3656
+ height: 0.875rem;
3657
+ }
3658
+ .j-tag__remove:hover:not(:disabled) {
3659
+ background: rgb(0 0 0 / 0.08);
3660
+ opacity: 1;
3661
+ }
3662
+ .dark .j-tag__remove:hover:not(:disabled),
3663
+ [data-theme='dark'] .j-tag__remove:hover:not(:disabled) {
3664
+ background: rgb(255 255 255 / 0.12);
3665
+ }
3666
+ .j-tag__remove > svg {
3667
+ width: 0.625rem;
3668
+ height: 0.625rem;
3669
+ }
3670
+ .j-tag--sm .j-tag__remove > svg {
3671
+ width: 0.5rem;
3672
+ height: 0.5rem;
3673
+ }
3674
+ .j-tag.is-disabled {
3675
+ opacity: 0.5;
3676
+ }
3677
+ .j-tag__remove:disabled {
3678
+ cursor: not-allowed;
3679
+ }
3680
+ }
3681
+
3682
+ @layer theme, base, juxt, components, utilities;
2885
3683
  @layer juxt {
2886
3684
  .j-textarea {
2887
3685
  align-items: stretch;
@@ -2917,6 +3715,102 @@ from {
2917
3715
  }
2918
3716
  }
2919
3717
 
3718
+ @layer theme, base, juxt, components, utilities;
3719
+ @layer juxt {
3720
+ .j-timeline {
3721
+ display: flex;
3722
+ flex-direction: column;
3723
+ margin: 0;
3724
+ padding: 0;
3725
+ list-style: none;
3726
+ font-family: var(--juxt-font-sans);
3727
+ }
3728
+ }
3729
+
3730
+ @layer theme, base, juxt, components, utilities;
3731
+ @layer juxt {
3732
+ .j-timeline-item {
3733
+ position: relative;
3734
+ display: flex;
3735
+ gap: var(--juxt-space-3);
3736
+ padding-bottom: var(--juxt-space-5);
3737
+ }
3738
+ .j-timeline-item:last-child {
3739
+ padding-bottom: 0;
3740
+ }
3741
+ .j-timeline-item__rail {
3742
+ position: relative;
3743
+ display: flex;
3744
+ flex: none;
3745
+ justify-content: center;
3746
+ width: 1rem;
3747
+ }
3748
+ .j-timeline-item__rail::before {
3749
+ content: '';
3750
+ position: absolute;
3751
+ top: 1rem;
3752
+ bottom: calc(var(--juxt-space-5) * -1);
3753
+ width: 1px;
3754
+ background: var(--juxt-border);
3755
+ }
3756
+ .j-timeline-item:last-child .j-timeline-item__rail::before {
3757
+ display: none;
3758
+ }
3759
+ .j-timeline-item__marker {
3760
+ z-index: 1;
3761
+ display: grid;
3762
+ place-items: center;
3763
+ width: 0.625rem;
3764
+ height: 0.625rem;
3765
+ margin-top: 0.25rem;
3766
+ border: 2px solid var(--juxt-surface);
3767
+ border-radius: var(--juxt-radius-full);
3768
+ background: var(--juxt-fg-disabled);
3769
+ box-shadow: 0 0 0 1px var(--juxt-border);
3770
+ }
3771
+ .j-timeline-item--complete .j-timeline-item__marker {
3772
+ background: var(--juxt-accent);
3773
+ box-shadow: none;
3774
+ }
3775
+ .j-timeline-item--current .j-timeline-item__marker {
3776
+ background: var(--juxt-surface);
3777
+ box-shadow: 0 0 0 2px var(--juxt-accent);
3778
+ }
3779
+ .j-timeline-item__content {
3780
+ flex: 1;
3781
+ min-width: 0;
3782
+ padding-bottom: var(--juxt-space-0-5);
3783
+ }
3784
+ .j-timeline-item__header {
3785
+ display: flex;
3786
+ flex-wrap: wrap;
3787
+ align-items: baseline;
3788
+ gap: var(--juxt-space-2);
3789
+ }
3790
+ .j-timeline-item__title {
3791
+ margin: 0;
3792
+ color: var(--juxt-fg);
3793
+ font-size: var(--juxt-text-md);
3794
+ font-weight: var(--juxt-weight-medium);
3795
+ letter-spacing: var(--juxt-tracking-tight);
3796
+ }
3797
+ .j-timeline-item--upcoming .j-timeline-item__title {
3798
+ color: var(--juxt-fg-muted);
3799
+ }
3800
+ .j-timeline-item__time {
3801
+ color: var(--juxt-fg-muted);
3802
+ font-size: var(--juxt-text-xs);
3803
+ font-variant-numeric: tabular-nums;
3804
+ }
3805
+ .j-timeline-item__body {
3806
+ margin-top: var(--juxt-space-0-5);
3807
+ color: var(--juxt-fg-secondary);
3808
+ font-size: var(--juxt-text-sm);
3809
+ line-height: var(--juxt-leading-normal);
3810
+ }
3811
+ }
3812
+
3813
+ @layer theme, base, juxt, components, utilities;
2920
3814
  @layer juxt {
2921
3815
  .j-toaster {
2922
3816
  --j-toast-width: 22.5rem;
@@ -3171,6 +4065,78 @@ to {
3171
4065
  }
3172
4066
  }
3173
4067
 
4068
+ @layer theme, base, juxt, components, utilities;
4069
+ @layer juxt {
4070
+ .j-toggle-group {
4071
+ --j-toggle-height: var(--juxt-control-md);
4072
+
4073
+ display: inline-flex;
4074
+ align-items: center;
4075
+ gap: 2px;
4076
+ padding: 2px;
4077
+ border-radius: var(--juxt-radius-md);
4078
+ background: var(--juxt-surface-sunken);
4079
+ box-shadow: inset 0 0 0 1px var(--juxt-border-subtle);
4080
+ font-family: var(--juxt-font-sans);
4081
+ }
4082
+ .j-toggle-group--sm {
4083
+ --j-toggle-height: var(--juxt-control-sm);
4084
+ }
4085
+ .j-toggle-group.is-disabled {
4086
+ opacity: 0.6;
4087
+ }
4088
+ }
4089
+
4090
+ @layer theme, base, juxt, components, utilities;
4091
+ @layer juxt {
4092
+ .j-toggle-group__item {
4093
+ display: inline-flex;
4094
+ align-items: center;
4095
+ justify-content: center;
4096
+ gap: var(--juxt-space-1-5);
4097
+ height: var(--j-toggle-height, var(--juxt-control-md));
4098
+ padding: 0 var(--juxt-space-3);
4099
+ border: 0;
4100
+ border-radius: var(--juxt-radius-sm);
4101
+ background: transparent;
4102
+ color: var(--juxt-fg-secondary);
4103
+ font: inherit;
4104
+ font-size: var(--juxt-text-sm);
4105
+ font-weight: var(--juxt-weight-medium);
4106
+ letter-spacing: var(--juxt-tracking-tight);
4107
+ white-space: nowrap;
4108
+ cursor: pointer;
4109
+ outline: 2px solid transparent;
4110
+ outline-offset: 0;
4111
+ -webkit-tap-highlight-color: transparent;
4112
+ transition:
4113
+ background-color var(--juxt-duration-fast) var(--juxt-ease-standard),
4114
+ color var(--juxt-duration-fast) var(--juxt-ease-standard),
4115
+ box-shadow var(--juxt-duration-fast) var(--juxt-ease-standard);
4116
+ }
4117
+ .j-toggle-group__item > svg {
4118
+ width: 1rem;
4119
+ height: 1rem;
4120
+ }
4121
+ .j-toggle-group__item:hover:not(:disabled) {
4122
+ color: var(--juxt-fg);
4123
+ }
4124
+ .j-toggle-group__item.is-selected {
4125
+ background: var(--juxt-surface);
4126
+ box-shadow: var(--juxt-shadow-sm);
4127
+ color: var(--juxt-fg);
4128
+ }
4129
+ .dark .j-toggle-group__item.is-selected,
4130
+ [data-theme='dark'] .j-toggle-group__item.is-selected {
4131
+ background: var(--juxt-surface-active);
4132
+ }
4133
+ .j-toggle-group__item:disabled {
4134
+ color: var(--juxt-fg-disabled);
4135
+ cursor: not-allowed;
4136
+ }
4137
+ }
4138
+
4139
+ @layer theme, base, juxt, components, utilities;
3174
4140
  @layer juxt {
3175
4141
  .j-tooltip {
3176
4142
  z-index: var(--juxt-z-tooltip);
@@ -3217,4 +4183,16 @@ to {
3217
4183
  );
3218
4184
  }
3219
4185
  }
4186
+
4187
+ @layer theme, base, juxt, components, utilities;
4188
+ @layer juxt {
4189
+ /*
4190
+ * Visual hiding is handled entirely by the shared `.j-sr-only` utility in
4191
+ * base.css | this component just gives it a typed, composable wrapper so it
4192
+ * can be used as `<JVisuallyHidden as="label">…</JVisuallyHidden>`.
4193
+ */
4194
+ .j-visually-hidden {
4195
+ display: block;
4196
+ }
4197
+ }
3220
4198
  /*$vite$:1*/