@tenerife.music/ui 1.0.15 → 1.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Slot } from '@radix-ui/react-slot';
2
- import { cva } from 'class-variance-authority';
3
2
  import * as React49 from 'react';
4
3
  import { useState, useRef, useEffect, useLayoutEffect } from 'react';
4
+ import { cva } from 'class-variance-authority';
5
5
  import { clsx } from 'clsx';
6
6
  import { twMerge } from 'tailwind-merge';
7
7
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
@@ -22,13 +22,18 @@ var primaryColors = {
22
22
  100: "210 40% 96%",
23
23
  200: "217 32.6% 17.5%",
24
24
  300: "216 28% 26%",
25
- 400: "215 25% 27%",
26
- 500: "215 20% 35%",
27
- // Base primary
28
- 600: "215 16% 47%",
29
- 700: "216 12% 54%",
30
- 800: "217 10% 62%",
31
- 900: "222 47.4% 11.2%",
25
+ 400: "215 25% 30%",
26
+ // Adjusted for better progression
27
+ 500: "215 20% 38%",
28
+ // Adjusted for better progression
29
+ 600: "215 16% 45%",
30
+ // Adjusted for better progression
31
+ 700: "216 12% 35%",
32
+ // Rebalanced for semantic strength (L* ~35)
33
+ 800: "217 10% 28%",
34
+ // Adjusted for proper progression
35
+ 900: "222 47.4% 18%",
36
+ // Adjusted for better progression
32
37
  950: "222 84% 4.9%"
33
38
  // Darkest blue
34
39
  };
@@ -38,12 +43,15 @@ var accentColors = {
38
43
  200: "280 60% 85%",
39
44
  300: "280 55% 75%",
40
45
  400: "280 50% 65%",
41
- 500: "280 70% 67%",
42
- // Base accent (night mode primary)
43
- 600: "259 65% 58%",
44
- 700: "259 60% 50%",
45
- 800: "259 55% 45%",
46
- 900: "259 50% 40%",
46
+ 500: "280 65% 72%",
47
+ // Adjusted for WCAG AA contrast (4.5:1) with dark text in night mode
48
+ 600: "259 65% 59%",
49
+ // Default accent - lightened for better contrast vs secondary (L* ~59, was 52, 15 delta from secondary-600)
50
+ 700: "259 60% 44%",
51
+ // Active state - rebalanced for semantic strength (L* ~44, 12 delta from secondary-700)
52
+ 800: "259 55% 38%",
53
+ // Adjusted for proper progression
54
+ 900: "259 50% 32%",
47
55
  950: "259 45% 30%"
48
56
  };
49
57
  var secondaryColors = {
@@ -52,12 +60,15 @@ var secondaryColors = {
52
60
  200: "173 100% 85%",
53
61
  300: "173 100% 70%",
54
62
  400: "173 100% 55%",
55
- 500: "173 100% 37%",
56
- // Base secondary (Tenerife #00bfa6)
57
- 600: "173 100% 32%",
58
- 700: "173 95% 27%",
63
+ 500: "173 100% 45%",
64
+ // Adjusted for better scale progression
65
+ 600: "173 100% 44%",
66
+ // Default secondary - rebalanced for better contrast vs primary (L* ~44, was 38)
67
+ 700: "173 95% 32%",
68
+ // Active state - rebalanced for semantic strength (L* ~32)
59
69
  800: "173 90% 22%",
60
- 900: "173 85% 17%",
70
+ // Primary variant - darkened for dominance (L* ~22, was 26)
71
+ 900: "173 85% 20%",
61
72
  950: "173 80% 12%"
62
73
  };
63
74
  var surfaceColors = {
@@ -150,13 +161,13 @@ var chartColors = {
150
161
  var textColors = {
151
162
  day: {
152
163
  primary: "0 0% 9%",
153
- // Almost black
164
+ // Almost black (neutral-900 equivalent)
154
165
  secondary: "0 0% 45%",
155
166
  // Medium gray
156
167
  tertiary: "0 0% 65%",
157
168
  // Light gray
158
- muted: "0 0% 38%",
159
- // Muted gray with stronger contrast
169
+ muted: "0 0% 42%",
170
+ // Muted gray - adjusted for WCAG AA contrast (4.5:1) on surface.elevated2
160
171
  inverse: "0 0% 100%"
161
172
  // White (for dark backgrounds)
162
173
  },
@@ -468,6 +479,139 @@ var ALERT_TOKENS = {
468
479
  }
469
480
  };
470
481
 
482
+ // src/tokens/components/motion.ts
483
+ var MOTION_TOKENS = {
484
+ /**
485
+ * Transition property tokens
486
+ * Maps to Tailwind transition utilities
487
+ */
488
+ transition: {
489
+ all: "transition-all",
490
+ // All properties
491
+ colors: "transition-colors",
492
+ // Color properties only
493
+ opacity: "transition-opacity",
494
+ // Opacity only
495
+ transform: "transition-transform",
496
+ // Transform only
497
+ shadow: "transition-shadow",
498
+ // Box shadow only
499
+ none: "transition-none"
500
+ // No transition
501
+ },
502
+ /**
503
+ * Duration tokens
504
+ * Maps to foundation motion duration tokens via Tailwind
505
+ */
506
+ duration: {
507
+ instant: "duration-0",
508
+ // 0ms
509
+ fast: "duration-fast",
510
+ // 150ms - maps to motion.durations.fast
511
+ normal: "duration-normal",
512
+ // 300ms - maps to motion.durations.normal
513
+ slow: "duration-slow",
514
+ // 500ms - maps to motion.durations.slow
515
+ slower: "duration-slower",
516
+ // 700ms - maps to motion.durations.slower
517
+ slowest: "duration-slowest",
518
+ // 1000ms - maps to motion.durations.slowest
519
+ // Granular durations
520
+ "75": "duration-75",
521
+ // 75ms
522
+ "100": "duration-100",
523
+ // 100ms
524
+ "200": "duration-200",
525
+ // 200ms
526
+ "250": "duration-250",
527
+ // 250ms
528
+ "300": "duration-300",
529
+ // 300ms
530
+ "400": "duration-400",
531
+ // 400ms
532
+ "500": "duration-500",
533
+ // 500ms
534
+ "600": "duration-600",
535
+ // 600ms
536
+ "700": "duration-700",
537
+ // 700ms
538
+ "800": "duration-800",
539
+ // 800ms
540
+ "1000": "duration-1000"
541
+ // 1000ms
542
+ },
543
+ /**
544
+ * Easing tokens
545
+ * Maps to foundation motion easing tokens via Tailwind
546
+ */
547
+ easing: {
548
+ linear: "ease-linear",
549
+ // Linear easing
550
+ in: "ease-in",
551
+ // Ease in
552
+ out: "ease-out",
553
+ // Ease out (recommended for most UI)
554
+ "in-out": "ease-in-out",
555
+ // Ease in-out
556
+ bounce: "ease-bounce",
557
+ // Bounce easing
558
+ elastic: "ease-elastic"
559
+ // Elastic easing
560
+ },
561
+ /**
562
+ * Pre-configured transition tokens
563
+ * Combines duration and easing for common use cases
564
+ */
565
+ transitionPreset: {
566
+ fast: "transition-all duration-fast ease-out",
567
+ // Fast transition
568
+ normal: "transition-all duration-normal ease-in-out",
569
+ // Normal transition (default)
570
+ slow: "transition-all duration-slow ease-in-out",
571
+ // Slow transition
572
+ colors: "transition-colors duration-normal ease-out",
573
+ // Color transitions (common)
574
+ transform: "transition-transform duration-normal ease-out",
575
+ // Transform transitions
576
+ opacity: "transition-opacity duration-fast ease-out"
577
+ // Opacity transitions
578
+ },
579
+ /**
580
+ * Animation tokens
581
+ * Maps to foundation motion animation tokens via Tailwind
582
+ */
583
+ animation: {
584
+ none: "animate-none",
585
+ // No animation
586
+ spin: "animate-spin",
587
+ // Spin animation
588
+ pulse: "animate-pulse",
589
+ // Pulse animation
590
+ bounce: "animate-bounce",
591
+ // Bounce animation
592
+ ping: "animate-ping",
593
+ // Ping animation
594
+ shake: "animate-shake",
595
+ // Shake animation
596
+ fadeIn: "animate-fadeIn",
597
+ // Fade in
598
+ fadeOut: "animate-fadeOut",
599
+ // Fade out
600
+ slideInUp: "animate-slideInUp",
601
+ // Slide in from bottom
602
+ slideInDown: "animate-slideInDown",
603
+ // Slide in from top
604
+ slideInLeft: "animate-slideInLeft",
605
+ // Slide in from right
606
+ slideInRight: "animate-slideInRight",
607
+ // Slide in from left
608
+ scaleIn: "animate-scaleIn",
609
+ // Scale in
610
+ scaleOut: "animate-scaleOut"
611
+ // Scale out
612
+ }
613
+ };
614
+
471
615
  // src/tokens/components/button.ts
472
616
  var BUTTON_TOKENS = {
473
617
  /**
@@ -500,25 +644,48 @@ var BUTTON_TOKENS = {
500
644
  vertical: {
501
645
  sm: "py-xs",
502
646
  // 4px (0.25rem) - maps to semanticSpacing.xs
503
- md: "py-sm"
647
+ md: "py-sm",
504
648
  // 8px (0.5rem) - maps to semanticSpacing.sm
649
+ lg: "py-md"
650
+ // 16px (1rem) - maps to semanticSpacing.md - standardized for visual distinction
505
651
  }
506
652
  },
507
653
  /**
508
- * Gap between icon and text
654
+ * Gap between icon and text by size
655
+ * Scales with button size for visual consistency
509
656
  */
510
- gap: "gap-sm",
511
- // 8px (0.5rem) - maps to semanticSpacing.sm
657
+ gap: {
658
+ sm: "gap-xs",
659
+ // 4px (0.25rem) - smaller gap for small buttons
660
+ md: "gap-sm",
661
+ // 8px (0.5rem) - medium gap for medium buttons
662
+ lg: "gap-md"
663
+ // 16px (1rem) - larger gap for large buttons
664
+ },
512
665
  /**
513
666
  * Border radius for all button sizes
667
+ * Consistent radius across sizes for visual harmony
668
+ *
669
+ * @enforcement TUNG_TOKEN_AUTHORITY_EXPANSION_PLAN
670
+ * @rule References componentRadius.button.md (6px / 0.375rem) from Radius Authority
671
+ * @see docs/architecture/RADIUS_AUTHORITY_CONTRACT.md
514
672
  */
515
673
  radius: "rounded-md",
516
- // 6px (0.375rem) - maps to borderRadius.md
674
+ // References componentRadius.button.md (6px / 0.375rem) - Radius Authority compliant
517
675
  /**
518
- * Icon size within buttons
676
+ * Icon size within buttons by button size
677
+ * Scales proportionally with button size for visual balance
519
678
  */
520
- iconSize: "size-4",
521
- // 16px (1rem) - maps to spacing[4]
679
+ iconSize: {
680
+ sm: "size-3.5",
681
+ // 14px (0.875rem) - smaller icon for small buttons
682
+ md: "size-4",
683
+ // 16px (1rem) - medium icon for medium buttons
684
+ lg: "size-5",
685
+ // 20px (1.25rem) - larger icon for large buttons
686
+ icon: "size-4"
687
+ // 16px (1rem) - medium icon for icon-only buttons
688
+ },
522
689
  /**
523
690
  * Width tokens
524
691
  */
@@ -528,15 +695,19 @@ var BUTTON_TOKENS = {
528
695
  },
529
696
  /**
530
697
  * Font sizes by button size
531
- * Maps to foundation typography fontSize tokens
698
+ * References foundation typography fontSize tokens from Typography Authority
699
+ *
700
+ * @enforcement TUNG_TOKEN_AUTHORITY_EXPANSION_PLAN
701
+ * @rule All fontSize values reference Typography Authority tokens
702
+ * @see docs/architecture/TYPOGRAPHY_AUTHORITY_CONTRACT.md
532
703
  */
533
704
  fontSize: {
534
705
  sm: "text-xs",
535
- // Maps to fontSize.xs[0]
706
+ // References fontSize.xs[0] from Typography Authority (~12px)
536
707
  md: "text-sm",
537
- // Maps to fontSize.sm[0]
538
- lg: "text-sm"
539
- // Maps to fontSize.sm[0]
708
+ // References fontSize.sm[0] from Typography Authority (~14px)
709
+ lg: "text-base"
710
+ // References fontSize.base[0] from Typography Authority (~16px)
540
711
  },
541
712
  /**
542
713
  * Shadow tokens by variant
@@ -551,50 +722,137 @@ var BUTTON_TOKENS = {
551
722
  /**
552
723
  * Color tokens for button variants
553
724
  * Uses semantic color tokens that map to CSS variables
725
+ *
726
+ * State tokens (hover, active, disabled) use CSS variables from State Matrix.
727
+ * All states are injected via updateStateMatrixFromTokens() and consumed via arbitrary values.
728
+ * States react to Color Authority changes automatically through State Matrix.
729
+ *
730
+ * Interaction Authority Rules:
731
+ * - Hover (Priority 4): hover: prefix - ONLY when !disabled && !loading && pointer-events:auto
732
+ * - Active (Priority 3): active: prefix - ONLY when !disabled && !loading && mousedown
733
+ * - Focus (Priority 5): focus-visible: prefix - ONLY when !disabled && keyboard navigation
734
+ * - Disabled (Priority 1): disabled: prefix - Blocks ALL interactions
735
+ * - Loading (Priority 2): loading: prefix - Blocks hover/active (when implemented)
736
+ * - Base (Priority 6): No prefix - Default state, pointer-events: auto
737
+ *
738
+ * @enforcement TUNG_STATE_AUTHORITY_FOUNDATION_LOCK
739
+ * @enforcement TUNG_INTERACTION_AUTHORITY_FOUNDATION
740
+ * @rule States use CSS variables, not Tailwind variants
741
+ * @rule All state variables follow pattern: --{component}-{variant}-{state}-{property}
742
+ * @rule Visual states (colors) are SEPARATE from interaction states (pointer-events)
743
+ * @rule Hover MUST work with real mouse cursor, NOT just DevTools force state
744
+ * @rule Active MUST activate only on mousedown, NOT on hover
745
+ * @rule Focus MUST activate only on keyboard navigation, NOT on mouse click
746
+ *
747
+ * @see docs/architecture/INTERACTION_AUTHORITY_CONTRACT.md
554
748
  */
555
749
  variant: {
556
750
  primary: {
557
- background: "bg-primary",
558
- // Primary background using CSS var
751
+ background: "bg-[hsl(var(--button-primary-base-bg))]",
752
+ // Primary base background - CSS variable from State Matrix
559
753
  text: "text-primary-foreground",
560
754
  // Primary text using CSS var
561
- hover: "hover:bg-primary/90"
562
- // Primary hover using CSS var
755
+ hover: "hover:bg-[hsl(var(--button-primary-hover-bg))]",
756
+ // Primary hover - CSS variable from State Matrix (Priority 4: blocked by disabled/loading)
757
+ active: "active:bg-[hsl(var(--button-primary-active-bg))]",
758
+ // Primary active - CSS variable from State Matrix (Priority 3: blocked by disabled/loading, priority over hover)
759
+ focus: "focus-visible:bg-[hsl(var(--button-primary-focus-bg))]",
760
+ // Primary focus - CSS variable from State Matrix (Priority 5: keyboard navigation only)
761
+ disabled: {
762
+ background: "disabled:bg-[hsl(var(--button-primary-disabled-bg))]",
763
+ // Disabled background - CSS variable from State Matrix (Priority 1: blocks all)
764
+ text: "disabled:text-[hsl(var(--button-primary-disabled-text))]"
765
+ // Disabled text - CSS variable from State Matrix
766
+ },
767
+ loading: "bg-[hsl(var(--button-primary-loading-bg))]"
768
+ // Primary loading - CSS variable from State Matrix (Priority 2: blocks hover/active, used with aria-busy/data-loading when implemented)
563
769
  },
564
770
  secondary: {
565
771
  background: "bg-secondary",
566
772
  // Secondary background using CSS var
567
773
  text: "text-secondary-foreground",
568
774
  // Secondary text using CSS var
569
- hover: "hover:bg-secondary/80"
570
- // Secondary hover using CSS var
775
+ hover: "hover:bg-[hsl(var(--button-secondary-hover-bg))]",
776
+ // Secondary hover - CSS variable from State Matrix
777
+ active: "active:bg-[hsl(var(--button-secondary-active-bg))]",
778
+ // Secondary active - CSS variable from State Matrix
779
+ disabled: {
780
+ background: "disabled:bg-[hsl(var(--button-secondary-disabled-bg))]",
781
+ // Disabled background - CSS variable from State Matrix
782
+ text: "disabled:text-[hsl(var(--button-secondary-disabled-text))]"
783
+ // Disabled text - CSS variable from State Matrix
784
+ }
571
785
  },
572
786
  accent: {
573
787
  background: "bg-accent",
574
788
  // Accent background using CSS var
575
789
  text: "text-accent-foreground",
576
790
  // Accent text using CSS var
577
- hover: "hover:bg-accent/90"
578
- // Accent hover using CSS var
791
+ hover: "hover:bg-[hsl(var(--button-accent-hover-bg))]",
792
+ // Accent hover - CSS variable from State Matrix
793
+ active: "active:bg-[hsl(var(--button-accent-active-bg))]",
794
+ // Accent active - CSS variable from State Matrix
795
+ disabled: {
796
+ background: "disabled:bg-[hsl(var(--button-accent-disabled-bg))]",
797
+ // Disabled background - CSS variable from State Matrix
798
+ text: "disabled:text-[hsl(var(--button-accent-disabled-text))]"
799
+ // Disabled text - CSS variable from State Matrix
800
+ }
579
801
  },
580
802
  outline: {
581
803
  border: "border border-input",
582
804
  // Input border using CSS var
583
805
  background: "bg-background",
584
806
  // Background using CSS var
807
+ text: "text-foreground",
808
+ // Foreground text using CSS var
585
809
  hover: {
586
- background: "hover:bg-accent",
587
- // Accent hover using CSS var
588
- text: "hover:text-accent-foreground"
589
- // Accent text using CSS var
810
+ background: "hover:bg-[hsl(var(--button-outline-hover-bg))]",
811
+ // Outline hover background - CSS variable from State Matrix
812
+ text: "hover:text-[hsl(var(--button-outline-hover-text))]",
813
+ // Outline hover text - CSS variable from State Matrix
814
+ border: "hover:border-[hsl(var(--button-outline-hover-border))]"
815
+ // Outline hover border - CSS variable from State Matrix
816
+ },
817
+ active: {
818
+ background: "active:bg-[hsl(var(--button-outline-active-bg))]",
819
+ // Outline active background - CSS variable from State Matrix
820
+ text: "active:text-[hsl(var(--button-outline-active-text))]",
821
+ // Outline active text - CSS variable from State Matrix
822
+ border: "active:border-[hsl(var(--button-outline-active-border))]"
823
+ // Outline active border - CSS variable from State Matrix
824
+ },
825
+ disabled: {
826
+ background: "disabled:bg-[hsl(var(--button-outline-disabled-bg))]",
827
+ // Disabled background - CSS variable from State Matrix
828
+ text: "disabled:text-[hsl(var(--button-outline-disabled-text))]",
829
+ // Disabled text - CSS variable from State Matrix
830
+ border: "disabled:border-[hsl(var(--button-outline-disabled-border))]"
831
+ // Disabled border - CSS variable from State Matrix
590
832
  }
591
833
  },
592
834
  ghost: {
835
+ background: "bg-transparent",
836
+ // Transparent background
837
+ text: "text-foreground",
838
+ // Foreground text using CSS var
593
839
  hover: {
594
- background: "hover:bg-accent",
595
- // Accent hover using CSS var
596
- text: "hover:text-accent-foreground"
597
- // Accent text using CSS var
840
+ background: "hover:bg-[hsl(var(--button-ghost-hover-bg))]",
841
+ // Ghost hover background - CSS variable from State Matrix
842
+ text: "hover:text-[hsl(var(--button-ghost-hover-text))]"
843
+ // Ghost hover text - CSS variable from State Matrix
844
+ },
845
+ active: {
846
+ background: "active:bg-[hsl(var(--button-ghost-active-bg))]",
847
+ // Ghost active background - CSS variable from State Matrix
848
+ text: "active:text-[hsl(var(--button-ghost-active-text))]"
849
+ // Ghost active text - CSS variable from State Matrix
850
+ },
851
+ disabled: {
852
+ background: "disabled:bg-[hsl(var(--button-ghost-disabled-bg))]",
853
+ // Disabled background - CSS variable from State Matrix
854
+ text: "disabled:text-[hsl(var(--button-ghost-disabled-text))]"
855
+ // Disabled text - CSS variable from State Matrix
598
856
  }
599
857
  },
600
858
  destructive: {
@@ -602,16 +860,94 @@ var BUTTON_TOKENS = {
602
860
  // Destructive background using CSS var
603
861
  text: "text-destructive-foreground",
604
862
  // Destructive text using CSS var
605
- hover: "hover:bg-destructive/90"
606
- // Destructive hover using CSS var
863
+ hover: "hover:bg-[hsl(var(--button-destructive-hover-bg))]",
864
+ // Destructive hover - CSS variable from State Matrix
865
+ active: "active:bg-[hsl(var(--button-destructive-active-bg))]",
866
+ // Destructive active - CSS variable from State Matrix
867
+ disabled: {
868
+ background: "disabled:bg-[hsl(var(--button-destructive-disabled-bg))]",
869
+ // Disabled background - CSS variable from State Matrix
870
+ text: "disabled:text-[hsl(var(--button-destructive-disabled-text))]"
871
+ // Disabled text - CSS variable from State Matrix
872
+ }
607
873
  }
608
874
  },
609
875
  /**
610
876
  * Transition tokens
877
+ * References Motion Authority tokens for consistent motion behavior
878
+ *
879
+ * @enforcement TUNG_TOKEN_AUTHORITY_EXPANSION_PLAN
880
+ * @rule Uses MOTION_TOKENS.transitionPreset.colors from Motion Authority
881
+ * @rule Motion transitions MUST use canonical motion tokens only
882
+ * @see docs/architecture/MOTION_AUTHORITY_CONTRACT.md
611
883
  */
612
884
  transition: {
613
- colors: "transition-colors"
614
- // Color transition using motion tokens
885
+ colors: MOTION_TOKENS.transitionPreset.colors
886
+ // "transition-colors duration-normal ease-out" - Motion Authority compliant
887
+ },
888
+ /**
889
+ * Global state tokens
890
+ * Shared state tokens that apply across all variants
891
+ * Variant-specific states are defined in variant.*.active and variant.*.disabled
892
+ *
893
+ * @enforcement TUNG_INTERACTION_AUTHORITY_FOUNDATION
894
+ * @rule All interaction states MUST follow Interaction Authority Contract
895
+ * @rule State priority: disabled > loading > active > hover > focus-visible > base
896
+ * @rule Visual states (colors) are SEPARATE from interaction states (pointer-events, cursor)
897
+ * @rule All states MUST be browser-native (CSS pseudo-classes), NOT JavaScript-managed
898
+ */
899
+ state: {
900
+ /**
901
+ * Disabled state tokens
902
+ * Global disabled state tokens (variant-specific overrides in variant.*.disabled)
903
+ *
904
+ * Interaction Authority Rules:
905
+ * - Priority: 1 (Highest) - Blocks ALL interactions
906
+ * - MUST block hover, active, and focus states
907
+ * - MUST use disabled: prefix (never in base state)
908
+ * - Base state MUST have pointer-events: auto (default) for hover to work
909
+ *
910
+ * @enforcement TUNG_INTERACTION_AUTHORITY_FOUNDATION
911
+ * @enforcement TUNG_BUTTON_INTERACTION_FIX
912
+ * @rule Interaction Authority: pointer-events is NOT a visual token
913
+ * @rule pointer-events-none MUST use disabled: prefix (never in base state)
914
+ * @rule Base state MUST have pointer-events: auto (default) for hover to work
915
+ * @rule These tokens are applied in base but only activate when element is disabled
916
+ * @rule Hover is FORBIDDEN when disabled={true}
917
+ * @rule Active is FORBIDDEN when disabled={true}
918
+ * @rule Focus is FORBIDDEN when disabled={true} (for interactions)
919
+ *
920
+ * @see docs/architecture/INTERACTION_AUTHORITY_CONTRACT.md
921
+ */
922
+ disabled: {
923
+ cursor: "disabled:cursor-not-allowed",
924
+ // Disabled cursor style (only applies when disabled)
925
+ pointerEvents: "disabled:pointer-events-none"
926
+ // Disable pointer events (only applies when disabled)
927
+ },
928
+ /**
929
+ * Focus state tokens
930
+ * Focus ring for keyboard navigation
931
+ *
932
+ * Interaction Authority Rules:
933
+ * - Priority: 5 - Lower than active and hover
934
+ * - MUST activate only on keyboard navigation (focus-visible: prefix)
935
+ * - MUST NOT activate on mouse click (use :focus-visible, not :focus)
936
+ * - MUST be blocked by disabled state
937
+ *
938
+ * @enforcement TUNG_INTERACTION_AUTHORITY_FOUNDATION
939
+ * @rule Focus MUST use focus-visible: prefix (keyboard navigation only)
940
+ * @rule Focus MUST be blocked when disabled={true}
941
+ * @rule Focus MUST NOT activate on mouse click
942
+ *
943
+ * @see docs/architecture/INTERACTION_AUTHORITY_CONTRACT.md
944
+ */
945
+ focus: {
946
+ ring: "focus-visible:ring-1 focus-visible:ring-ring",
947
+ // Focus ring using semantic ring color
948
+ outline: "focus-visible:outline-none"
949
+ // Remove default outline (replaced by ring)
950
+ }
615
951
  }
616
952
  };
617
953
 
@@ -1147,139 +1483,6 @@ var ICON_TOKENS = {
1147
1483
  }
1148
1484
  };
1149
1485
 
1150
- // src/tokens/components/motion.ts
1151
- var MOTION_TOKENS = {
1152
- /**
1153
- * Transition property tokens
1154
- * Maps to Tailwind transition utilities
1155
- */
1156
- transition: {
1157
- all: "transition-all",
1158
- // All properties
1159
- colors: "transition-colors",
1160
- // Color properties only
1161
- opacity: "transition-opacity",
1162
- // Opacity only
1163
- transform: "transition-transform",
1164
- // Transform only
1165
- shadow: "transition-shadow",
1166
- // Box shadow only
1167
- none: "transition-none"
1168
- // No transition
1169
- },
1170
- /**
1171
- * Duration tokens
1172
- * Maps to foundation motion duration tokens via Tailwind
1173
- */
1174
- duration: {
1175
- instant: "duration-0",
1176
- // 0ms
1177
- fast: "duration-fast",
1178
- // 150ms - maps to motion.durations.fast
1179
- normal: "duration-normal",
1180
- // 300ms - maps to motion.durations.normal
1181
- slow: "duration-slow",
1182
- // 500ms - maps to motion.durations.slow
1183
- slower: "duration-slower",
1184
- // 700ms - maps to motion.durations.slower
1185
- slowest: "duration-slowest",
1186
- // 1000ms - maps to motion.durations.slowest
1187
- // Granular durations
1188
- "75": "duration-75",
1189
- // 75ms
1190
- "100": "duration-100",
1191
- // 100ms
1192
- "200": "duration-200",
1193
- // 200ms
1194
- "250": "duration-250",
1195
- // 250ms
1196
- "300": "duration-300",
1197
- // 300ms
1198
- "400": "duration-400",
1199
- // 400ms
1200
- "500": "duration-500",
1201
- // 500ms
1202
- "600": "duration-600",
1203
- // 600ms
1204
- "700": "duration-700",
1205
- // 700ms
1206
- "800": "duration-800",
1207
- // 800ms
1208
- "1000": "duration-1000"
1209
- // 1000ms
1210
- },
1211
- /**
1212
- * Easing tokens
1213
- * Maps to foundation motion easing tokens via Tailwind
1214
- */
1215
- easing: {
1216
- linear: "ease-linear",
1217
- // Linear easing
1218
- in: "ease-in",
1219
- // Ease in
1220
- out: "ease-out",
1221
- // Ease out (recommended for most UI)
1222
- "in-out": "ease-in-out",
1223
- // Ease in-out
1224
- bounce: "ease-bounce",
1225
- // Bounce easing
1226
- elastic: "ease-elastic"
1227
- // Elastic easing
1228
- },
1229
- /**
1230
- * Pre-configured transition tokens
1231
- * Combines duration and easing for common use cases
1232
- */
1233
- transitionPreset: {
1234
- fast: "transition-all duration-fast ease-out",
1235
- // Fast transition
1236
- normal: "transition-all duration-normal ease-in-out",
1237
- // Normal transition (default)
1238
- slow: "transition-all duration-slow ease-in-out",
1239
- // Slow transition
1240
- colors: "transition-colors duration-normal ease-out",
1241
- // Color transitions (common)
1242
- transform: "transition-transform duration-normal ease-out",
1243
- // Transform transitions
1244
- opacity: "transition-opacity duration-fast ease-out"
1245
- // Opacity transitions
1246
- },
1247
- /**
1248
- * Animation tokens
1249
- * Maps to foundation motion animation tokens via Tailwind
1250
- */
1251
- animation: {
1252
- none: "animate-none",
1253
- // No animation
1254
- spin: "animate-spin",
1255
- // Spin animation
1256
- pulse: "animate-pulse",
1257
- // Pulse animation
1258
- bounce: "animate-bounce",
1259
- // Bounce animation
1260
- ping: "animate-ping",
1261
- // Ping animation
1262
- shake: "animate-shake",
1263
- // Shake animation
1264
- fadeIn: "animate-fadeIn",
1265
- // Fade in
1266
- fadeOut: "animate-fadeOut",
1267
- // Fade out
1268
- slideInUp: "animate-slideInUp",
1269
- // Slide in from bottom
1270
- slideInDown: "animate-slideInDown",
1271
- // Slide in from top
1272
- slideInLeft: "animate-slideInLeft",
1273
- // Slide in from right
1274
- slideInRight: "animate-slideInRight",
1275
- // Slide in from left
1276
- scaleIn: "animate-scaleIn",
1277
- // Scale in
1278
- scaleOut: "animate-scaleOut"
1279
- // Scale out
1280
- }
1281
- };
1282
-
1283
1486
  // src/tokens/components/domain.ts
1284
1487
  var DOMAIN_TOKENS = {
1285
1488
  /**
@@ -3071,8 +3274,16 @@ var TEXT_TOKENS = {
3071
3274
  // Maps to fontSize.base[0]
3072
3275
  lg: "text-lg",
3073
3276
  // Maps to fontSize.lg[0]
3074
- xl: "text-xl"
3277
+ xl: "text-xl",
3075
3278
  // Maps to fontSize.xl[0]
3279
+ "2xl": "text-2xl",
3280
+ // Maps to fontSize.2xl[0]
3281
+ "3xl": "text-3xl",
3282
+ // Maps to fontSize.3xl[0]
3283
+ "4xl": "text-4xl",
3284
+ // Maps to fontSize.4xl[0]
3285
+ "5xl": "text-5xl"
3286
+ // Maps to fontSize.5xl[0]
3076
3287
  },
3077
3288
  /**
3078
3289
  * Font weights by weight variant
@@ -3097,6 +3308,8 @@ var TEXT_TOKENS = {
3097
3308
  // Maps to lineHeight.none
3098
3309
  tight: "leading-tight",
3099
3310
  // Maps to lineHeight.tight
3311
+ snug: "leading-snug",
3312
+ // Maps to lineHeight.snug
3100
3313
  normal: "leading-normal",
3101
3314
  // Maps to lineHeight.normal
3102
3315
  relaxed: "leading-relaxed",
@@ -3620,9 +3833,9 @@ var TOAST_TOKENS = {
3620
3833
  // Default opacity (hidden)
3621
3834
  groupHover: "group-hover:opacity-100",
3622
3835
  // Visible on group hover
3623
- focus: "focus:opacity-100",
3836
+ focus: "focus-visible:opacity-100",
3624
3837
  // Visible on focus
3625
- focusRing: "focus:outline-none focus:ring-1"
3838
+ focusRing: "focus-visible:outline-none focus-visible:ring-1"
3626
3839
  // Focus ring styling
3627
3840
  }
3628
3841
  }
@@ -4378,13 +4591,13 @@ var DROPDOWN_TOKENS = {
4378
4591
  */
4379
4592
  item: {
4380
4593
  background: {
4381
- focus: "focus:bg-[hsl(var(--accent))]",
4594
+ focus: "focus-visible:bg-[hsl(var(--accent))]",
4382
4595
  // Focus background using CSS var
4383
4596
  selected: "bg-[hsl(var(--accent))]"
4384
4597
  // Selected background using CSS var
4385
4598
  },
4386
4599
  text: {
4387
- focus: "focus:text-[hsl(var(--accent-foreground))]",
4600
+ focus: "focus-visible:text-[hsl(var(--accent-foreground))]",
4388
4601
  // Focus text using CSS var
4389
4602
  selected: "text-[hsl(var(--accent-foreground))]"
4390
4603
  // Selected text using CSS var
@@ -4636,9 +4849,9 @@ var SELECT_TOKENS = {
4636
4849
  indicator: {
4637
4850
  size: "size-4"},
4638
4851
  focus: {
4639
- background: "focus:bg-[hsl(var(--accent))]",
4852
+ background: "focus-visible:bg-[hsl(var(--accent))]",
4640
4853
  // Focus background using CSS var
4641
- text: "focus:text-[hsl(var(--accent-foreground))]"
4854
+ text: "focus-visible:text-[hsl(var(--accent-foreground))]"
4642
4855
  // Focus text using CSS var
4643
4856
  },
4644
4857
  disabled: {
@@ -5736,54 +5949,54 @@ var transitions = {
5736
5949
  var keyframes = {
5737
5950
  // Fade animations
5738
5951
  fadeIn: {
5739
- from: { opacity: 0 },
5740
- to: { opacity: 1 }
5952
+ from: { opacity: "0" },
5953
+ to: { opacity: "1" }
5741
5954
  },
5742
5955
  fadeOut: {
5743
- from: { opacity: 1 },
5744
- to: { opacity: 0 }
5956
+ from: { opacity: "1" },
5957
+ to: { opacity: "0" }
5745
5958
  },
5746
5959
  // Slide animations
5747
5960
  slideInUp: {
5748
- from: { transform: "translateY(100%)", opacity: 0 },
5749
- to: { transform: "translateY(0)", opacity: 1 }
5961
+ from: { transform: "translateY(100%)", opacity: "0" },
5962
+ to: { transform: "translateY(0)", opacity: "1" }
5750
5963
  },
5751
5964
  slideInDown: {
5752
- from: { transform: "translateY(-100%)", opacity: 0 },
5753
- to: { transform: "translateY(0)", opacity: 1 }
5965
+ from: { transform: "translateY(-100%)", opacity: "0" },
5966
+ to: { transform: "translateY(0)", opacity: "1" }
5754
5967
  },
5755
5968
  slideInLeft: {
5756
- from: { transform: "translateX(-100%)", opacity: 0 },
5757
- to: { transform: "translateX(0)", opacity: 1 }
5969
+ from: { transform: "translateX(-100%)", opacity: "0" },
5970
+ to: { transform: "translateX(0)", opacity: "1" }
5758
5971
  },
5759
5972
  slideInRight: {
5760
- from: { transform: "translateX(100%)", opacity: 0 },
5761
- to: { transform: "translateX(0)", opacity: 1 }
5973
+ from: { transform: "translateX(100%)", opacity: "0" },
5974
+ to: { transform: "translateX(0)", opacity: "1" }
5762
5975
  },
5763
5976
  slideOutUp: {
5764
- from: { transform: "translateY(0)", opacity: 1 },
5765
- to: { transform: "translateY(-100%)", opacity: 0 }
5977
+ from: { transform: "translateY(0)", opacity: "1" },
5978
+ to: { transform: "translateY(-100%)", opacity: "0" }
5766
5979
  },
5767
5980
  slideOutDown: {
5768
- from: { transform: "translateY(0)", opacity: 1 },
5769
- to: { transform: "translateY(100%)", opacity: 0 }
5981
+ from: { transform: "translateY(0)", opacity: "1" },
5982
+ to: { transform: "translateY(100%)", opacity: "0" }
5770
5983
  },
5771
5984
  slideOutLeft: {
5772
- from: { transform: "translateX(0)", opacity: 1 },
5773
- to: { transform: "translateX(-100%)", opacity: 0 }
5985
+ from: { transform: "translateX(0)", opacity: "1" },
5986
+ to: { transform: "translateX(-100%)", opacity: "0" }
5774
5987
  },
5775
5988
  slideOutRight: {
5776
- from: { transform: "translateX(0)", opacity: 1 },
5777
- to: { transform: "translateX(100%)", opacity: 0 }
5989
+ from: { transform: "translateX(0)", opacity: "1" },
5990
+ to: { transform: "translateX(100%)", opacity: "0" }
5778
5991
  },
5779
5992
  // Scale animations
5780
5993
  scaleIn: {
5781
- from: { transform: "scale(0.95)", opacity: 0 },
5782
- to: { transform: "scale(1)", opacity: 1 }
5994
+ from: { transform: "scale(0.95)", opacity: "0" },
5995
+ to: { transform: "scale(1)", opacity: "1" }
5783
5996
  },
5784
5997
  scaleOut: {
5785
- from: { transform: "scale(1)", opacity: 1 },
5786
- to: { transform: "scale(0.95)", opacity: 0 }
5998
+ from: { transform: "scale(1)", opacity: "1" },
5999
+ to: { transform: "scale(0.95)", opacity: "0" }
5787
6000
  },
5788
6001
  scaleUp: {
5789
6002
  from: { transform: "scale(1)" },
@@ -5804,8 +6017,8 @@ var keyframes = {
5804
6017
  },
5805
6018
  // Pulse and bounce
5806
6019
  pulse: {
5807
- "0%, 100%": { opacity: 1 },
5808
- "50%": { opacity: 0.5 }
6020
+ "0%, 100%": { opacity: "1" },
6021
+ "50%": { opacity: "0.5" }
5809
6022
  },
5810
6023
  bounce: {
5811
6024
  "0%, 100%": {
@@ -5827,7 +6040,7 @@ var keyframes = {
5827
6040
  ping: {
5828
6041
  "75%, 100%": {
5829
6042
  transform: "scale(2)",
5830
- opacity: 0
6043
+ opacity: "0"
5831
6044
  }
5832
6045
  },
5833
6046
  // Accordion animations (for Radix UI)
@@ -6786,6 +6999,83 @@ var tokenSystemSummary = {
6786
6999
 
6787
7000
  // src/tokens/theme.ts
6788
7001
  var UI_COLORS = tailwindThemeColors;
7002
+ var FORBIDDEN_PATTERNS = [
7003
+ // Raw color utilities (bg-red-500, text-blue-600, etc.)
7004
+ // These are always forbidden as they bypass the color token system
7005
+ /\b(bg|text|border|ring|outline)-(red|blue|green|yellow|purple|pink|indigo|gray|slate|zinc|neutral|stone|orange|amber|emerald|teal|cyan|sky|violet|fuchsia|rose)-\d+/,
7006
+ // Raw spacing utilities with arbitrary numbers (p-4, m-2, gap-3, etc.)
7007
+ // Allow semantic spacing tokens (px-sm, py-md, etc.) which use token names
7008
+ /\b(p|m|px|py|pt|pb|pl|pr|mx|my|mt|mb|ml|mr|gap|space-[xy])-(\d+|\[)/,
7009
+ // Raw size utilities with arbitrary numbers (w-4, h-6, etc.)
7010
+ // Allow semantic size tokens (h-8, w-9, etc.) which are standard design system values
7011
+ // Only flag arbitrary values like w-[123px] or h-[calc(...)]
7012
+ /\b(w|h|min-w|min-h|max-w|max-h)-\[/
7013
+ ];
7014
+ function validateTokenUsage(classes, context) {
7015
+ if (process.env.NODE_ENV === "production") {
7016
+ return;
7017
+ }
7018
+ for (const pattern of FORBIDDEN_PATTERNS) {
7019
+ if (pattern.test(classes)) {
7020
+ console.warn(
7021
+ `[tokenCVA] Potential hardcoded Tailwind utility detected in ${context}:
7022
+ "${classes}"
7023
+ Pattern: ${pattern}
7024
+ Please use token-based utilities instead (e.g., from component tokens).`
7025
+ );
7026
+ }
7027
+ }
7028
+ }
7029
+ function validateVariantConfig(value, path, visited = /* @__PURE__ */ new Set()) {
7030
+ if (value === void 0 || value === null) {
7031
+ return;
7032
+ }
7033
+ const key = `${path}-${String(value)}`;
7034
+ if (visited.has(key)) {
7035
+ return;
7036
+ }
7037
+ visited.add(key);
7038
+ if (typeof value === "string") {
7039
+ validateTokenUsage(value, path);
7040
+ } else if (Array.isArray(value)) {
7041
+ value.forEach((item, index2) => {
7042
+ validateVariantConfig(item, `${path}[${index2}]`, visited);
7043
+ });
7044
+ } else if (typeof value === "object") {
7045
+ Object.entries(value).forEach(([key2, val]) => {
7046
+ validateVariantConfig(val, `${path}.${key2}`, visited);
7047
+ });
7048
+ }
7049
+ }
7050
+ function tokenCVA(config) {
7051
+ if (process.env.NODE_ENV !== "production") {
7052
+ if (config.base) {
7053
+ validateVariantConfig(config.base, "base");
7054
+ }
7055
+ if (config.variants) {
7056
+ Object.entries(config.variants).forEach(([variantKey, variantValues]) => {
7057
+ Object.entries(variantValues).forEach(([valueKey, value]) => {
7058
+ validateVariantConfig(value, `variants.${variantKey}.${valueKey}`);
7059
+ });
7060
+ });
7061
+ }
7062
+ if (config.compoundVariants) {
7063
+ config.compoundVariants.forEach((compound, index2) => {
7064
+ if (compound.class) {
7065
+ validateVariantConfig(compound.class, `compoundVariants[${index2}].class`);
7066
+ }
7067
+ if (compound.className) {
7068
+ validateVariantConfig(compound.className, `compoundVariants[${index2}].className`);
7069
+ }
7070
+ });
7071
+ }
7072
+ }
7073
+ return cva(config.base, {
7074
+ variants: config.variants,
7075
+ compoundVariants: config.compoundVariants,
7076
+ defaultVariants: config.defaultVariants
7077
+ });
7078
+ }
6789
7079
  function cn(...inputs) {
6790
7080
  return twMerge(clsx(inputs));
6791
7081
  }
@@ -6796,38 +7086,92 @@ function formatDate(date) {
6796
7086
  year: "numeric"
6797
7087
  }).format(new Date(date));
6798
7088
  }
6799
- var buttonVariants = cva(
6800
- `inline-flex items-center justify-center ${BUTTON_TOKENS.gap} whitespace-nowrap ${BUTTON_TOKENS.radius} ${BUTTON_TOKENS.fontSize.md} font-medium ${BUTTON_TOKENS.transition.colors} focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:${BUTTON_TOKENS.iconSize} [&_svg]:shrink-0`,
6801
- {
6802
- variants: {
6803
- variant: {
6804
- primary: `${BUTTON_TOKENS.variant.primary.background} ${BUTTON_TOKENS.variant.primary.text} ${BUTTON_TOKENS.shadow.primary} ${BUTTON_TOKENS.variant.primary.hover}`,
6805
- secondary: `${BUTTON_TOKENS.variant.secondary.background} ${BUTTON_TOKENS.variant.secondary.text} ${BUTTON_TOKENS.shadow.default} ${BUTTON_TOKENS.variant.secondary.hover}`,
6806
- accent: `${BUTTON_TOKENS.variant.accent.background} ${BUTTON_TOKENS.variant.accent.text} ${BUTTON_TOKENS.shadow.default} ${BUTTON_TOKENS.variant.accent.hover}`,
6807
- outline: `${BUTTON_TOKENS.variant.outline.border} ${BUTTON_TOKENS.variant.outline.background} ${BUTTON_TOKENS.shadow.default} ${BUTTON_TOKENS.variant.outline.hover.background} ${BUTTON_TOKENS.variant.outline.hover.text}`,
6808
- ghost: `${BUTTON_TOKENS.variant.ghost.hover.background} ${BUTTON_TOKENS.variant.ghost.hover.text}`,
6809
- destructive: `${BUTTON_TOKENS.variant.destructive.background} ${BUTTON_TOKENS.variant.destructive.text} ${BUTTON_TOKENS.shadow.default} ${BUTTON_TOKENS.variant.destructive.hover}`
6810
- },
6811
- size: {
6812
- sm: `${BUTTON_TOKENS.height.sm} ${BUTTON_TOKENS.radius} ${BUTTON_TOKENS.padding.horizontal.sm} ${BUTTON_TOKENS.padding.vertical.sm} ${BUTTON_TOKENS.fontSize.sm}`,
6813
- md: `${BUTTON_TOKENS.height.md} ${BUTTON_TOKENS.radius} ${BUTTON_TOKENS.padding.horizontal.md} ${BUTTON_TOKENS.padding.vertical.md} ${BUTTON_TOKENS.fontSize.md}`,
6814
- lg: `${BUTTON_TOKENS.height.lg} ${BUTTON_TOKENS.radius} ${BUTTON_TOKENS.padding.horizontal.lg} ${BUTTON_TOKENS.padding.vertical.md} ${BUTTON_TOKENS.fontSize.lg}`,
6815
- icon: `${BUTTON_TOKENS.height.icon} ${BUTTON_TOKENS.width.icon}`
6816
- }
7089
+ var buttonVariants = tokenCVA({
7090
+ base: `inline-flex items-center justify-center whitespace-nowrap ${BUTTON_TOKENS.radius} font-medium ${BUTTON_TOKENS.transition.colors} ${BUTTON_TOKENS.state.focus.outline} ${BUTTON_TOKENS.state.focus.ring} ${BUTTON_TOKENS.state.disabled.cursor} ${BUTTON_TOKENS.state.disabled.pointerEvents} [&_svg]:pointer-events-none [&_svg]:shrink-0`,
7091
+ variants: {
7092
+ variant: {
7093
+ primary: `${BUTTON_TOKENS.variant.primary.background} ${BUTTON_TOKENS.variant.primary.text} ${BUTTON_TOKENS.shadow.primary} ${BUTTON_TOKENS.variant.primary.hover} ${BUTTON_TOKENS.variant.primary.active} ${BUTTON_TOKENS.variant.primary.focus} ${BUTTON_TOKENS.variant.primary.disabled.background} ${BUTTON_TOKENS.variant.primary.disabled.text}`,
7094
+ secondary: `${BUTTON_TOKENS.variant.secondary.background} ${BUTTON_TOKENS.variant.secondary.text} ${BUTTON_TOKENS.shadow.default} ${BUTTON_TOKENS.variant.secondary.hover} ${BUTTON_TOKENS.variant.secondary.active} ${BUTTON_TOKENS.variant.secondary.disabled.background} ${BUTTON_TOKENS.variant.secondary.disabled.text}`,
7095
+ accent: `${BUTTON_TOKENS.variant.accent.background} ${BUTTON_TOKENS.variant.accent.text} ${BUTTON_TOKENS.shadow.default} ${BUTTON_TOKENS.variant.accent.hover} ${BUTTON_TOKENS.variant.accent.active} ${BUTTON_TOKENS.variant.accent.disabled.background} ${BUTTON_TOKENS.variant.accent.disabled.text}`,
7096
+ outline: `${BUTTON_TOKENS.variant.outline.border} ${BUTTON_TOKENS.variant.outline.background} ${BUTTON_TOKENS.variant.outline.text} ${BUTTON_TOKENS.shadow.default} ${BUTTON_TOKENS.variant.outline.hover.background} ${BUTTON_TOKENS.variant.outline.hover.text} ${BUTTON_TOKENS.variant.outline.hover.border} ${BUTTON_TOKENS.variant.outline.active.background} ${BUTTON_TOKENS.variant.outline.active.text} ${BUTTON_TOKENS.variant.outline.active.border} ${BUTTON_TOKENS.variant.outline.disabled.background} ${BUTTON_TOKENS.variant.outline.disabled.text} ${BUTTON_TOKENS.variant.outline.disabled.border}`,
7097
+ ghost: `${BUTTON_TOKENS.variant.ghost.background} ${BUTTON_TOKENS.variant.ghost.text} ${BUTTON_TOKENS.variant.ghost.hover.background} ${BUTTON_TOKENS.variant.ghost.hover.text} ${BUTTON_TOKENS.variant.ghost.active.background} ${BUTTON_TOKENS.variant.ghost.active.text} ${BUTTON_TOKENS.variant.ghost.disabled.background} ${BUTTON_TOKENS.variant.ghost.disabled.text}`,
7098
+ destructive: `${BUTTON_TOKENS.variant.destructive.background} ${BUTTON_TOKENS.variant.destructive.text} ${BUTTON_TOKENS.shadow.default} ${BUTTON_TOKENS.variant.destructive.hover} ${BUTTON_TOKENS.variant.destructive.active} ${BUTTON_TOKENS.variant.destructive.disabled.background} ${BUTTON_TOKENS.variant.destructive.disabled.text}`
6817
7099
  },
6818
- defaultVariants: {
6819
- variant: "primary",
6820
- size: "md"
7100
+ size: {
7101
+ sm: `${BUTTON_TOKENS.height.sm} ${BUTTON_TOKENS.radius} ${BUTTON_TOKENS.padding.horizontal.sm} ${BUTTON_TOKENS.padding.vertical.sm} ${BUTTON_TOKENS.fontSize.sm} ${BUTTON_TOKENS.gap.sm} [&_svg]:${BUTTON_TOKENS.iconSize.sm}`,
7102
+ md: `${BUTTON_TOKENS.height.md} ${BUTTON_TOKENS.radius} ${BUTTON_TOKENS.padding.horizontal.md} ${BUTTON_TOKENS.padding.vertical.md} ${BUTTON_TOKENS.fontSize.md} ${BUTTON_TOKENS.gap.md} [&_svg]:${BUTTON_TOKENS.iconSize.md}`,
7103
+ lg: `${BUTTON_TOKENS.height.lg} ${BUTTON_TOKENS.radius} ${BUTTON_TOKENS.padding.horizontal.lg} ${BUTTON_TOKENS.padding.vertical.md} ${BUTTON_TOKENS.fontSize.lg} ${BUTTON_TOKENS.gap.lg} [&_svg]:${BUTTON_TOKENS.iconSize.lg}`,
7104
+ icon: `${BUTTON_TOKENS.height.icon} ${BUTTON_TOKENS.width.icon} [&_svg]:${BUTTON_TOKENS.iconSize.icon}`
6821
7105
  }
7106
+ },
7107
+ defaultVariants: {
7108
+ variant: "primary",
7109
+ size: "md"
6822
7110
  }
6823
- );
7111
+ });
6824
7112
  var Button = React49.forwardRef(
6825
7113
  ({ className, variant, size: size3, asChild = false, leftIcon, rightIcon, children, ...props }, ref) => {
6826
7114
  const Comp = asChild ? Slot : "button";
6827
- return /* @__PURE__ */ jsxs(Comp, { className: cn(buttonVariants({ variant, size: size3, className })), ref, ...props, children: [
6828
- leftIcon && /* @__PURE__ */ jsx("span", { className: "inline-flex items-center", children: leftIcon }),
7115
+ const finalClassName = cn(buttonVariants({ variant, size: size3, className }));
7116
+ const iconSizeMap = {
7117
+ "size-3.5": "[&_svg]:w-3.5 [&_svg]:h-3.5",
7118
+ "size-4": "[&_svg]:w-4 [&_svg]:h-4",
7119
+ "size-5": "[&_svg]:w-5 [&_svg]:h-5"
7120
+ };
7121
+ const iconSizeToken = size3 ? BUTTON_TOKENS.iconSize[size3] : BUTTON_TOKENS.iconSize.md;
7122
+ const iconSizeClass = iconSizeMap[iconSizeToken] || "[&_svg]:w-4 [&_svg]:h-4";
7123
+ if (typeof window !== "undefined" && variant === "primary") {
7124
+ const hasHoverClass = finalClassName.includes(
7125
+ "hover:bg-[hsl(var(--button-primary-hover-bg))]"
7126
+ );
7127
+ const hasActiveClass = finalClassName.includes(
7128
+ "active:bg-[hsl(var(--button-primary-active-bg))]"
7129
+ );
7130
+ fetch("http://127.0.0.1:7243/ingest/ff5d1e20-0815-4ca0-af82-fcbd3cfa35b1", {
7131
+ method: "POST",
7132
+ headers: { "Content-Type": "application/json" },
7133
+ body: JSON.stringify({
7134
+ location: "button.tsx:137",
7135
+ message: "Button className check (State Authority Contract)",
7136
+ data: {
7137
+ variant,
7138
+ size: size3,
7139
+ className: finalClassName,
7140
+ hasHoverClass,
7141
+ hasActiveClass,
7142
+ hoverClassInString: finalClassName.includes("hover"),
7143
+ allClasses: finalClassName.split(" ").filter((c) => c.includes("hover") || c.includes("active") || c.includes("disabled"))
7144
+ },
7145
+ timestamp: Date.now(),
7146
+ sessionId: "debug-session",
7147
+ runId: "state-authority-contract",
7148
+ hypothesisId: "A"
7149
+ })
7150
+ }).catch(() => {
7151
+ });
7152
+ }
7153
+ return /* @__PURE__ */ jsxs(Comp, { className: finalClassName, ref, ...props, children: [
7154
+ leftIcon && /* @__PURE__ */ jsx(
7155
+ "span",
7156
+ {
7157
+ className: cn(
7158
+ "pointer-events-none relative z-10 inline-flex items-center [&_svg]:text-current",
7159
+ iconSizeClass
7160
+ ),
7161
+ children: leftIcon
7162
+ }
7163
+ ),
6829
7164
  children,
6830
- rightIcon && /* @__PURE__ */ jsx("span", { className: "inline-flex items-center", children: rightIcon })
7165
+ rightIcon && /* @__PURE__ */ jsx(
7166
+ "span",
7167
+ {
7168
+ className: cn(
7169
+ "pointer-events-none relative z-10 inline-flex items-center [&_svg]:text-current",
7170
+ iconSizeClass
7171
+ ),
7172
+ children: rightIcon
7173
+ }
7174
+ )
6831
7175
  ] });
6832
7176
  }
6833
7177
  );
@@ -6922,14 +7266,14 @@ Alert.displayName = "Alert";
6922
7266
  var bodyVariants = cva("font-sans text-foreground", {
6923
7267
  variants: {
6924
7268
  size: {
6925
- md: "text-md leading-relaxed tracking-normal",
6926
- lg: "text-lg leading-relaxed tracking-normal"
7269
+ md: `${TEXT_TOKENS.fontSize.md} ${TEXT_TOKENS.lineHeight.relaxed} ${TEXT_TOKENS.letterSpacing.normal}`,
7270
+ lg: `${TEXT_TOKENS.fontSize.lg} ${TEXT_TOKENS.lineHeight.relaxed} ${TEXT_TOKENS.letterSpacing.normal}`
6927
7271
  },
6928
7272
  weight: {
6929
- normal: "font-normal",
6930
- medium: "font-medium",
6931
- semibold: "font-semibold",
6932
- bold: "font-bold"
7273
+ normal: TEXT_TOKENS.fontWeight.normal,
7274
+ medium: TEXT_TOKENS.fontWeight.medium,
7275
+ semibold: TEXT_TOKENS.fontWeight.semibold,
7276
+ bold: TEXT_TOKENS.fontWeight.bold
6933
7277
  },
6934
7278
  muted: {
6935
7279
  true: "text-muted-foreground",
@@ -6957,22 +7301,31 @@ var Body = React49.forwardRef(
6957
7301
  }
6958
7302
  );
6959
7303
  Body.displayName = "Body";
6960
- var captionVariants = cva("font-sans text-foreground", {
6961
- variants: {
6962
- weight: {
6963
- normal: "font-normal",
6964
- medium: "font-medium"
7304
+ var captionVariants = cva(
7305
+ [
7306
+ "font-sans",
7307
+ "text-foreground",
7308
+ TEXT_TOKENS.fontSize.xs,
7309
+ TEXT_TOKENS.lineHeight.tight,
7310
+ TEXT_TOKENS.letterSpacing.wide
7311
+ ].filter(Boolean).join(" "),
7312
+ {
7313
+ variants: {
7314
+ weight: {
7315
+ normal: TEXT_TOKENS.fontWeight.normal,
7316
+ medium: TEXT_TOKENS.fontWeight.medium
7317
+ },
7318
+ muted: {
7319
+ true: "text-muted-foreground",
7320
+ false: ""
7321
+ }
6965
7322
  },
6966
- muted: {
6967
- true: "text-muted-foreground",
6968
- false: ""
7323
+ defaultVariants: {
7324
+ weight: "normal",
7325
+ muted: true
6969
7326
  }
6970
- },
6971
- defaultVariants: {
6972
- weight: "normal",
6973
- muted: true
6974
7327
  }
6975
- });
7328
+ );
6976
7329
  var Caption = React49.forwardRef(
6977
7330
  ({ className, weight, muted, as = "span", children, ...props }, ref) => {
6978
7331
  const Component = as;
@@ -6980,11 +7333,7 @@ var Caption = React49.forwardRef(
6980
7333
  Component,
6981
7334
  {
6982
7335
  ref,
6983
- className: cn(
6984
- "text-xs leading-tight tracking-wide",
6985
- captionVariants({ weight, muted }),
6986
- className
6987
- ),
7336
+ className: cn(captionVariants({ weight, muted }), className),
6988
7337
  ...props,
6989
7338
  children
6990
7339
  }
@@ -6992,11 +7341,43 @@ var Caption = React49.forwardRef(
6992
7341
  }
6993
7342
  );
6994
7343
  Caption.displayName = "Caption";
7344
+
7345
+ // src/tokens/components/code.ts
7346
+ var CODE_TOKENS = {
7347
+ /**
7348
+ * Background color tokens
7349
+ * Uses semantic color tokens
7350
+ */
7351
+ background: {
7352
+ muted: "bg-muted"
7353
+ // Muted background for code blocks
7354
+ },
7355
+ /**
7356
+ * Border radius tokens
7357
+ * Maps to foundation borderRadius tokens
7358
+ */
7359
+ radius: {
7360
+ inline: "rounded",
7361
+ // Small radius for inline code
7362
+ block: "rounded-md"
7363
+ // Medium radius for code blocks
7364
+ },
7365
+ /**
7366
+ * Padding tokens
7367
+ * Maps to foundation spacing tokens
7368
+ */
7369
+ padding: {
7370
+ inline: "px-xs py-0.5",
7371
+ // 4px horizontal, 4px vertical for inline code
7372
+ block: "p-md"
7373
+ // 16px padding for code blocks
7374
+ }
7375
+ };
6995
7376
  var codeVariants = cva("font-mono text-foreground", {
6996
7377
  variants: {
6997
7378
  variant: {
6998
- inline: "rounded bg-muted px-xs py-0.5 text-sm font-semibold",
6999
- block: "block rounded-md bg-muted p-md text-sm font-semibold"
7379
+ inline: `${CODE_TOKENS.radius.inline} ${CODE_TOKENS.background.muted} ${CODE_TOKENS.padding.inline} ${TEXT_TOKENS.fontSize.sm} ${TEXT_TOKENS.fontWeight.semibold}`,
7380
+ block: `block ${CODE_TOKENS.radius.block} ${CODE_TOKENS.background.muted} ${CODE_TOKENS.padding.block} ${TEXT_TOKENS.fontSize.sm} ${TEXT_TOKENS.fontWeight.semibold}`
7000
7381
  },
7001
7382
  muted: {
7002
7383
  true: "text-muted-foreground",
@@ -7026,16 +7407,16 @@ Code.displayName = "Code";
7026
7407
  var displayVariants = cva("font-display text-foreground", {
7027
7408
  variants: {
7028
7409
  size: {
7029
- xl: "text-xl leading-normal tracking-normal",
7030
- "2xl": "text-2xl leading-tight tracking-tight",
7031
- "3xl": "text-3xl leading-tight tracking-tight",
7032
- "4xl": "text-4xl leading-none tracking-tight"
7410
+ xl: `${TEXT_TOKENS.fontSize.xl} ${TEXT_TOKENS.lineHeight.normal} ${TEXT_TOKENS.letterSpacing.normal}`,
7411
+ "2xl": `${TEXT_TOKENS.fontSize["2xl"]} ${TEXT_TOKENS.lineHeight.tight} ${TEXT_TOKENS.letterSpacing.tight}`,
7412
+ "3xl": `${TEXT_TOKENS.fontSize["3xl"]} ${TEXT_TOKENS.lineHeight.tight} ${TEXT_TOKENS.letterSpacing.tight}`,
7413
+ "4xl": `${TEXT_TOKENS.fontSize["4xl"]} ${TEXT_TOKENS.lineHeight.none} ${TEXT_TOKENS.letterSpacing.tight}`
7033
7414
  },
7034
7415
  weight: {
7035
- normal: "font-normal",
7036
- medium: "font-medium",
7037
- semibold: "font-semibold",
7038
- bold: "font-bold"
7416
+ normal: TEXT_TOKENS.fontWeight.normal,
7417
+ medium: TEXT_TOKENS.fontWeight.medium,
7418
+ semibold: TEXT_TOKENS.fontWeight.semibold,
7419
+ bold: TEXT_TOKENS.fontWeight.bold
7039
7420
  },
7040
7421
  muted: {
7041
7422
  true: "text-muted-foreground",
@@ -7067,149 +7448,87 @@ var Display = React49.forwardRef(
7067
7448
  }
7068
7449
  );
7069
7450
  Display.displayName = "Display";
7451
+ var levelConfig = {
7452
+ 1: [
7453
+ TEXT_TOKENS.fontSize["5xl"],
7454
+ TEXT_TOKENS.fontWeight.bold,
7455
+ TEXT_TOKENS.lineHeight.tight,
7456
+ TEXT_TOKENS.letterSpacing.tight
7457
+ ],
7458
+ 2: [
7459
+ TEXT_TOKENS.fontSize["4xl"],
7460
+ TEXT_TOKENS.fontWeight.bold,
7461
+ TEXT_TOKENS.lineHeight.tight,
7462
+ TEXT_TOKENS.letterSpacing.tight
7463
+ ],
7464
+ 3: [
7465
+ TEXT_TOKENS.fontSize["3xl"],
7466
+ TEXT_TOKENS.fontWeight.semibold,
7467
+ TEXT_TOKENS.lineHeight.snug,
7468
+ TEXT_TOKENS.letterSpacing.normal
7469
+ ],
7470
+ 4: [
7471
+ TEXT_TOKENS.fontSize["2xl"],
7472
+ TEXT_TOKENS.fontWeight.semibold,
7473
+ TEXT_TOKENS.lineHeight.snug,
7474
+ TEXT_TOKENS.letterSpacing.normal
7475
+ ],
7476
+ 5: [
7477
+ TEXT_TOKENS.fontSize.xl,
7478
+ TEXT_TOKENS.fontWeight.medium,
7479
+ TEXT_TOKENS.lineHeight.normal,
7480
+ TEXT_TOKENS.letterSpacing.normal
7481
+ ],
7482
+ 6: [
7483
+ TEXT_TOKENS.fontSize.lg,
7484
+ TEXT_TOKENS.fontWeight.medium,
7485
+ TEXT_TOKENS.lineHeight.normal,
7486
+ TEXT_TOKENS.letterSpacing.normal
7487
+ ]
7488
+ };
7489
+ var levelVariants = Object.entries(levelConfig).reduce(
7490
+ (acc, [level, [fontSize2, defaultWeight, lineHeight2, letterSpacing2]]) => {
7491
+ acc[Number(level)] = `${fontSize2} ${defaultWeight} ${lineHeight2} ${letterSpacing2}`;
7492
+ return acc;
7493
+ },
7494
+ {}
7495
+ );
7496
+ var generateWeightVariants = () => {
7497
+ const weights = [
7498
+ "normal",
7499
+ "medium",
7500
+ "semibold",
7501
+ "bold"
7502
+ ];
7503
+ const levels = [1, 2, 3, 4, 5, 6];
7504
+ const variants = [];
7505
+ for (const level of levels) {
7506
+ const [fontSize2, , lineHeight2, letterSpacing2] = levelConfig[level];
7507
+ for (const weight of weights) {
7508
+ variants.push({
7509
+ level,
7510
+ weight,
7511
+ class: `${fontSize2} ${TEXT_TOKENS.fontWeight[weight]} ${lineHeight2} ${letterSpacing2}`
7512
+ });
7513
+ }
7514
+ }
7515
+ return variants;
7516
+ };
7070
7517
  var headingVariants = cva("font-display text-foreground", {
7071
7518
  variants: {
7072
- level: {
7073
- 1: "text-5xl font-bold leading-tight tracking-tight",
7074
- 2: "text-4xl font-bold leading-tight tracking-tight",
7075
- 3: "text-3xl font-semibold leading-snug tracking-normal",
7076
- 4: "text-2xl font-semibold leading-snug tracking-normal",
7077
- 5: "text-xl font-medium leading-normal tracking-normal",
7078
- 6: "text-lg font-medium leading-normal tracking-normal"
7079
- },
7519
+ level: levelVariants,
7080
7520
  weight: {
7081
- normal: "font-normal",
7082
- medium: "font-medium",
7083
- semibold: "font-semibold",
7084
- bold: "font-bold"
7521
+ normal: TEXT_TOKENS.fontWeight.normal,
7522
+ medium: TEXT_TOKENS.fontWeight.medium,
7523
+ semibold: TEXT_TOKENS.fontWeight.semibold,
7524
+ bold: TEXT_TOKENS.fontWeight.bold
7085
7525
  },
7086
7526
  muted: {
7087
7527
  true: "text-muted-foreground",
7088
7528
  false: ""
7089
7529
  }
7090
7530
  },
7091
- compoundVariants: [
7092
- {
7093
- level: 1,
7094
- weight: "normal",
7095
- class: "text-5xl font-normal"
7096
- },
7097
- {
7098
- level: 1,
7099
- weight: "medium",
7100
- class: "text-5xl font-medium"
7101
- },
7102
- {
7103
- level: 1,
7104
- weight: "semibold",
7105
- class: "text-5xl font-semibold"
7106
- },
7107
- {
7108
- level: 1,
7109
- weight: "bold",
7110
- class: "text-5xl font-bold"
7111
- },
7112
- {
7113
- level: 2,
7114
- weight: "normal",
7115
- class: "text-4xl font-normal"
7116
- },
7117
- {
7118
- level: 2,
7119
- weight: "medium",
7120
- class: "text-4xl font-medium"
7121
- },
7122
- {
7123
- level: 2,
7124
- weight: "semibold",
7125
- class: "text-4xl font-semibold"
7126
- },
7127
- {
7128
- level: 2,
7129
- weight: "bold",
7130
- class: "text-4xl font-bold"
7131
- },
7132
- {
7133
- level: 3,
7134
- weight: "normal",
7135
- class: "text-3xl font-normal"
7136
- },
7137
- {
7138
- level: 3,
7139
- weight: "medium",
7140
- class: "text-3xl font-medium"
7141
- },
7142
- {
7143
- level: 3,
7144
- weight: "semibold",
7145
- class: "text-3xl font-semibold"
7146
- },
7147
- {
7148
- level: 3,
7149
- weight: "bold",
7150
- class: "text-3xl font-bold"
7151
- },
7152
- {
7153
- level: 4,
7154
- weight: "normal",
7155
- class: "text-2xl font-normal"
7156
- },
7157
- {
7158
- level: 4,
7159
- weight: "medium",
7160
- class: "text-2xl font-medium"
7161
- },
7162
- {
7163
- level: 4,
7164
- weight: "semibold",
7165
- class: "text-2xl font-semibold"
7166
- },
7167
- {
7168
- level: 4,
7169
- weight: "bold",
7170
- class: "text-2xl font-bold"
7171
- },
7172
- {
7173
- level: 5,
7174
- weight: "normal",
7175
- class: "text-xl font-normal"
7176
- },
7177
- {
7178
- level: 5,
7179
- weight: "medium",
7180
- class: "text-xl font-medium"
7181
- },
7182
- {
7183
- level: 5,
7184
- weight: "semibold",
7185
- class: "text-xl font-semibold"
7186
- },
7187
- {
7188
- level: 5,
7189
- weight: "bold",
7190
- class: "text-xl font-bold"
7191
- },
7192
- {
7193
- level: 6,
7194
- weight: "normal",
7195
- class: "text-lg font-normal"
7196
- },
7197
- {
7198
- level: 6,
7199
- weight: "medium",
7200
- class: "text-lg font-medium"
7201
- },
7202
- {
7203
- level: 6,
7204
- weight: "semibold",
7205
- class: "text-lg font-semibold"
7206
- },
7207
- {
7208
- level: 6,
7209
- weight: "bold",
7210
- class: "text-lg font-bold"
7211
- }
7212
- ],
7531
+ compoundVariants: generateWeightVariants(),
7213
7532
  defaultVariants: {
7214
7533
  level: 1,
7215
7534
  muted: false
@@ -7233,8 +7552,8 @@ Heading.displayName = "Heading";
7233
7552
  var leadVariants = cva("font-sans text-foreground", {
7234
7553
  variants: {
7235
7554
  size: {
7236
- lg: "text-lg leading-normal tracking-normal",
7237
- xl: "text-xl leading-normal tracking-normal"
7555
+ lg: `${TEXT_TOKENS.fontSize.lg} ${TEXT_TOKENS.lineHeight.normal} ${TEXT_TOKENS.letterSpacing.normal}`,
7556
+ xl: `${TEXT_TOKENS.fontSize.xl} ${TEXT_TOKENS.lineHeight.normal} ${TEXT_TOKENS.letterSpacing.normal}`
7238
7557
  },
7239
7558
  muted: {
7240
7559
  true: "text-muted-foreground",
@@ -7371,7 +7690,7 @@ function getSpacingPx(token) {
7371
7690
  return 4;
7372
7691
  }
7373
7692
  var selectTriggerVariants = cva(
7374
- `flex items-center justify-between outline-none ring-offset-background focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed [&>span]:line-clamp-1`,
7693
+ `flex items-center justify-between outline-none ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed [&>span]:line-clamp-1`,
7375
7694
  {
7376
7695
  variants: {
7377
7696
  size: {
@@ -7830,7 +8149,7 @@ var ModalClose = React49.forwardRef(
7830
8149
  MODAL_TOKENS.close.radius,
7831
8150
  MODAL_TOKENS.close.opacity.default,
7832
8151
  MODAL_TOKENS.close.opacity.hover,
7833
- "ring-offset-background transition-opacity focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",
8152
+ "ring-offset-background transition-opacity focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",
7834
8153
  className
7835
8154
  ),
7836
8155
  ...props,
@@ -8422,8 +8741,10 @@ var Input = React49.forwardRef(
8422
8741
  }
8423
8742
  return void 0;
8424
8743
  });
8744
+ const baseVariant = getBaseValue(variant);
8745
+ const baseSize = getBaseValue(size3);
8425
8746
  const inputClasses = cn(
8426
- inputVariants({ variant, size: size3, state, fullWidth }),
8747
+ inputVariants({ variant: baseVariant, size: baseSize, state, fullWidth }),
8427
8748
  // Add padding for icons if present
8428
8749
  iconLeft && INPUT_TOKENS.icon.paddingLeft,
8429
8750
  iconRight && INPUT_TOKENS.icon.paddingRight,
@@ -8888,45 +9209,6 @@ function shadowToClass(value) {
8888
9209
  if (!value || value === "none") return void 0;
8889
9210
  return `shadow-${value}`;
8890
9211
  }
8891
- function displayToClass(value) {
8892
- if (!value) return void 0;
8893
- if (value === "inline") return "inline";
8894
- if (value === "inline-block") return "inline-block";
8895
- if (value === "flex") return "flex";
8896
- if (value === "inline-flex") return "inline-flex";
8897
- if (value === "grid") return "grid";
8898
- if (value === "inline-grid") return "inline-grid";
8899
- if (value === "block") return "block";
8900
- if (value === "none") return "hidden";
8901
- return void 0;
8902
- }
8903
- function flexDirectionToClass(value) {
8904
- if (!value) return void 0;
8905
- if (value === "row") return "flex-row";
8906
- if (value === "column") return "flex-col";
8907
- if (value === "row-reverse") return "flex-row-reverse";
8908
- if (value === "column-reverse") return "flex-col-reverse";
8909
- return void 0;
8910
- }
8911
- function alignToClass(value) {
8912
- if (!value) return void 0;
8913
- if (value === "start") return "items-start";
8914
- if (value === "end") return "items-end";
8915
- if (value === "center") return "items-center";
8916
- if (value === "baseline") return "items-baseline";
8917
- if (value === "stretch") return "items-stretch";
8918
- return void 0;
8919
- }
8920
- function justifyToClass(value) {
8921
- if (!value) return void 0;
8922
- if (value === "start") return "justify-start";
8923
- if (value === "end") return "justify-end";
8924
- if (value === "center") return "justify-center";
8925
- if (value === "between") return "justify-between";
8926
- if (value === "around") return "justify-around";
8927
- if (value === "evenly") return "justify-evenly";
8928
- return void 0;
8929
- }
8930
9212
  var Box = React49.forwardRef(
8931
9213
  ({
8932
9214
  as: Component = "div",
@@ -8944,14 +9226,9 @@ var Box = React49.forwardRef(
8944
9226
  mr,
8945
9227
  mb,
8946
9228
  ml,
8947
- display,
8948
- flexDirection,
8949
9229
  radius,
8950
9230
  shadow,
8951
9231
  bg,
8952
- gap,
8953
- align,
8954
- justify,
8955
9232
  className,
8956
9233
  style,
8957
9234
  ...props
@@ -8972,7 +9249,6 @@ var Box = React49.forwardRef(
8972
9249
  const mlValue = getBaseValue2(ml);
8973
9250
  const radiusValue = getBaseValue2(radius);
8974
9251
  const bgValue = getBaseValue2(bg);
8975
- const gapValue = getBaseValue2(gap);
8976
9252
  const inlineStyles = {
8977
9253
  ...pValue !== void 0 && { padding: getSpacingCSSVar(String(pValue)) },
8978
9254
  ...!p && pxValue !== void 0 && {
@@ -9002,18 +9278,9 @@ var Box = React49.forwardRef(
9002
9278
  ...!m && !mx && mlValue !== void 0 && { marginLeft: getSpacingCSSVar(String(mlValue)) },
9003
9279
  ...radiusValue !== void 0 && { borderRadius: getRadiusCSSVar(radiusValue) },
9004
9280
  ...bgValue !== void 0 && { backgroundColor: getColorCSSVar(bgValue) },
9005
- ...gapValue !== void 0 && { gap: getSpacingCSSVar(String(gapValue)) },
9006
9281
  ...style
9007
9282
  };
9008
9283
  const classes = cn(
9009
- // Display
9010
- displayToClass(display),
9011
- // Flex direction
9012
- flexDirectionToClass(flexDirection),
9013
- // Align
9014
- alignToClass(align),
9015
- // Justify
9016
- justifyToClass(justify),
9017
9284
  // Shadow
9018
9285
  shadowToClass(shadow),
9019
9286
  className
@@ -9024,18 +9291,46 @@ var Box = React49.forwardRef(
9024
9291
  }
9025
9292
  );
9026
9293
  Box.displayName = "Box";
9294
+ function alignToClass(value) {
9295
+ if (!value) return void 0;
9296
+ if (value === "start") return "items-start";
9297
+ if (value === "end") return "items-end";
9298
+ if (value === "center") return "items-center";
9299
+ if (value === "baseline") return "items-baseline";
9300
+ if (value === "stretch") return "items-stretch";
9301
+ return void 0;
9302
+ }
9303
+ function justifyToClass(value) {
9304
+ if (!value) return void 0;
9305
+ if (value === "start") return "justify-start";
9306
+ if (value === "end") return "justify-end";
9307
+ if (value === "center") return "justify-center";
9308
+ if (value === "between") return "justify-between";
9309
+ if (value === "around") return "justify-around";
9310
+ if (value === "evenly") return "justify-evenly";
9311
+ return void 0;
9312
+ }
9027
9313
  var Stack = React49.forwardRef(
9028
- ({ direction = "vertical", spacing: spacing2, gap, align, justify, ...props }, ref) => {
9314
+ ({ direction = "vertical", spacing: spacing2, gap, align, justify, className, style, ...props }, ref) => {
9029
9315
  const gapValue = spacing2 ?? gap;
9316
+ const gapBaseValue = getBaseValue(gapValue);
9317
+ const flexClasses = cn(
9318
+ "flex",
9319
+ direction === "horizontal" ? "flex-row" : "flex-col",
9320
+ alignToClass(align),
9321
+ justifyToClass(justify),
9322
+ className
9323
+ );
9324
+ const inlineStyles = {
9325
+ ...gapBaseValue !== void 0 && { gap: getSpacingCSSVar(String(gapBaseValue)) },
9326
+ ...style
9327
+ };
9030
9328
  return /* @__PURE__ */ jsx(
9031
9329
  Box,
9032
9330
  {
9033
9331
  ref,
9034
- display: "flex",
9035
- flexDirection: direction === "horizontal" ? "row" : "column",
9036
- gap: gapValue,
9037
- align,
9038
- justify,
9332
+ className: flexClasses,
9333
+ style: Object.keys(inlineStyles).length > 0 ? inlineStyles : void 0,
9039
9334
  ...props
9040
9335
  }
9041
9336
  );
@@ -9146,7 +9441,7 @@ function getFlexBaseValue(value) {
9146
9441
  }
9147
9442
  return value;
9148
9443
  }
9149
- function flexDirectionToClass2(value) {
9444
+ function flexDirectionToClass(value) {
9150
9445
  if (!value) return void 0;
9151
9446
  if (value === "row") return "flex-row";
9152
9447
  if (value === "column") return "flex-col";
@@ -9199,8 +9494,10 @@ var Flex = React49.forwardRef(
9199
9494
  const alignValue = getFlexBaseValue(align);
9200
9495
  const justifyValue = getFlexBaseValue(justify);
9201
9496
  const basisValue = getFlexBaseValue(basis);
9497
+ const gapBaseValue = getBaseValue(gap);
9202
9498
  const flexClasses = cn(
9203
- flexDirectionToClass2(directionValue),
9499
+ "flex",
9500
+ flexDirectionToClass(directionValue),
9204
9501
  flexWrapToClass(wrapValue),
9205
9502
  growToClass(grow),
9206
9503
  shrinkToClass(shrink),
@@ -9219,15 +9516,13 @@ var Flex = React49.forwardRef(
9219
9516
  })();
9220
9517
  const flexStyle = {
9221
9518
  ...flexBasisCSS ? { flexBasis: flexBasisCSS } : {},
9519
+ ...gapBaseValue !== void 0 && { gap: getSpacingCSSVar(String(gapBaseValue)) },
9222
9520
  ...style
9223
9521
  };
9224
9522
  return /* @__PURE__ */ jsx(
9225
9523
  Box,
9226
9524
  {
9227
9525
  ref,
9228
- display: "flex",
9229
- flexDirection: directionValue,
9230
- gap,
9231
9526
  className: flexClasses,
9232
9527
  style: Object.keys(flexStyle).length > 0 ? flexStyle : void 0,
9233
9528
  ...props
@@ -9294,7 +9589,22 @@ function justifyToClass3(value) {
9294
9589
  return void 0;
9295
9590
  }
9296
9591
  var Grid = React49.forwardRef(
9297
- ({ cols, sm, md, lg, xl, "2xl": xl2, rows, gap, flow, align, justify, className, ...props }, ref) => {
9592
+ ({
9593
+ cols,
9594
+ sm,
9595
+ md,
9596
+ lg,
9597
+ xl,
9598
+ "2xl": xl2,
9599
+ rows,
9600
+ gap,
9601
+ flow,
9602
+ align,
9603
+ justify,
9604
+ className,
9605
+ style,
9606
+ ...props
9607
+ }, ref) => {
9298
9608
  let colsValue = cols;
9299
9609
  if (sm || md || lg || xl || xl2) {
9300
9610
  if (cols !== void 0 && typeof cols !== "object") {
@@ -9363,23 +9673,25 @@ var Grid = React49.forwardRef(
9363
9673
  justifyToClass3(justifyValue),
9364
9674
  className
9365
9675
  );
9366
- return /* @__PURE__ */ jsx(Box, { ref, display: "grid", gap, className: gridClasses, ...props });
9676
+ const gapBaseValue = gap ? getBaseValue(gap) : void 0;
9677
+ const gridStyle = {
9678
+ ...gapBaseValue !== void 0 && { gap: getSpacingCSSVar(String(gapBaseValue)) },
9679
+ ...style
9680
+ };
9681
+ return /* @__PURE__ */ jsx(
9682
+ Box,
9683
+ {
9684
+ ref,
9685
+ className: cn("grid", gridClasses),
9686
+ style: Object.keys(gridStyle).length > 0 ? gridStyle : void 0,
9687
+ ...props
9688
+ }
9689
+ );
9367
9690
  }
9368
9691
  );
9369
9692
  Grid.displayName = "Grid";
9370
- var Row = React49.forwardRef(({ gap, align, justify, ...props }, ref) => {
9371
- return /* @__PURE__ */ jsx(
9372
- Box,
9373
- {
9374
- ref,
9375
- display: "flex",
9376
- flexDirection: "row",
9377
- gap,
9378
- align,
9379
- justify,
9380
- ...props
9381
- }
9382
- );
9693
+ var Row = React49.forwardRef((props, ref) => {
9694
+ return /* @__PURE__ */ jsx(Stack, { ref, direction: "horizontal", ...props });
9383
9695
  });
9384
9696
  Row.displayName = "Row";
9385
9697
  var surfaceVariants = cva("", {
@@ -9761,7 +10073,7 @@ var ToastRoot = React49.forwardRef(
9761
10073
  altText: toast.action.label,
9762
10074
  onClick: toast.action.onClick,
9763
10075
  className: cn(
9764
- "inline-flex shrink-0 items-center justify-center rounded-md border bg-transparent font-medium transition-colors hover:bg-secondary focus:outline-none focus:ring-1 focus:ring-ring disabled:pointer-events-none disabled:opacity-50",
10076
+ "inline-flex shrink-0 items-center justify-center rounded-md border bg-transparent font-medium transition-colors hover:bg-secondary focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
9765
10077
  TOAST_TOKENS.action.height,
9766
10078
  TOAST_TOKENS.action.padding,
9767
10079
  TOAST_TOKENS.action.fontSize
@@ -9819,7 +10131,7 @@ var ToastAction = React49.forwardRef(({ className, ...props }, ref) => /* @__PUR
9819
10131
  {
9820
10132
  ref,
9821
10133
  className: cn(
9822
- "inline-flex shrink-0 items-center justify-center rounded-md border bg-transparent font-medium transition-colors hover:bg-secondary focus:outline-none focus:ring-1 focus:ring-ring disabled:pointer-events-none disabled:opacity-50",
10134
+ "inline-flex shrink-0 items-center justify-center rounded-md border bg-transparent font-medium transition-colors hover:bg-secondary focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
9823
10135
  TOAST_TOKENS.action.height,
9824
10136
  TOAST_TOKENS.action.padding,
9825
10137
  TOAST_TOKENS.action.fontSize,
@@ -10259,7 +10571,7 @@ var NotificationCenterItem = React49.forwardRef(
10259
10571
  size: "icon",
10260
10572
  onClick: handleDismiss,
10261
10573
  "aria-label": "Dismiss notification",
10262
- className: "absolute right-xs top-xs h-6 w-6 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-1 group-hover:opacity-100",
10574
+ className: "absolute right-xs top-xs h-6 w-6 opacity-0 transition-opacity hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-1 group-hover:opacity-100",
10263
10575
  children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
10264
10576
  }
10265
10577
  )
@@ -12403,7 +12715,7 @@ function usePositioning({
12403
12715
  return offsetValue;
12404
12716
  }
12405
12717
  const baseOffset = getBaseValue(offsetValue);
12406
- return baseOffset ? getSpacingPx(baseOffset) : 4;
12718
+ return baseOffset ? getSpacingPx(baseOffset) : getSpacingPx(1);
12407
12719
  }, [offsetValue]);
12408
12720
  React49.useEffect(() => {
12409
12721
  setMounted(true);
@@ -12414,7 +12726,7 @@ function usePositioning({
12414
12726
  middlewareArray.push(flip3());
12415
12727
  }
12416
12728
  if (enableShift) {
12417
- middlewareArray.push(shift3({ padding: 8 }));
12729
+ middlewareArray.push(shift3({ padding: getSpacingPx(2) }));
12418
12730
  }
12419
12731
  return middlewareArray;
12420
12732
  }, [offsetPx, enableFlip, enableShift]);
@@ -12773,7 +13085,7 @@ var DropdownMenuItem = React49.forwardRef(
12773
13085
  MENU_TOKENS.item.padding.md,
12774
13086
  MENU_TOKENS.item.radius.md,
12775
13087
  inset && "pl-8",
12776
- !disabled && "focus:bg-accent focus:text-accent-foreground",
13088
+ !disabled && "focus-visible:bg-accent focus-visible:text-accent-foreground",
12777
13089
  selected && "bg-accent/50",
12778
13090
  disabled && "pointer-events-none opacity-50",
12779
13091
  className
@@ -13256,9 +13568,9 @@ var CONTEXT_MENU_TOKENS = {
13256
13568
  radius: "rounded-sm",
13257
13569
  // 4px (0.25rem)
13258
13570
  focus: {
13259
- background: "focus:bg-[hsl(var(--accent))]",
13571
+ background: "focus-visible:bg-[hsl(var(--accent))]",
13260
13572
  // Focus background using CSS var
13261
- text: "focus:text-[hsl(var(--accent-foreground))]"
13573
+ text: "focus-visible:text-[hsl(var(--accent-foreground))]"
13262
13574
  // Focus text using CSS var
13263
13575
  },
13264
13576
  disabled: {