@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.
@@ -7,13 +7,18 @@ var primaryColors = {
7
7
  100: "210 40% 96%",
8
8
  200: "217 32.6% 17.5%",
9
9
  300: "216 28% 26%",
10
- 400: "215 25% 27%",
11
- 500: "215 20% 35%",
12
- // Base primary
13
- 600: "215 16% 47%",
14
- 700: "216 12% 54%",
15
- 800: "217 10% 62%",
16
- 900: "222 47.4% 11.2%",
10
+ 400: "215 25% 30%",
11
+ // Adjusted for better progression
12
+ 500: "215 20% 38%",
13
+ // Adjusted for better progression
14
+ 600: "215 16% 45%",
15
+ // Adjusted for better progression
16
+ 700: "216 12% 35%",
17
+ // Rebalanced for semantic strength (L* ~35)
18
+ 800: "217 10% 28%",
19
+ // Adjusted for proper progression
20
+ 900: "222 47.4% 18%",
21
+ // Adjusted for better progression
17
22
  950: "222 84% 4.9%"
18
23
  // Darkest blue
19
24
  };
@@ -23,12 +28,15 @@ var accentColors = {
23
28
  200: "280 60% 85%",
24
29
  300: "280 55% 75%",
25
30
  400: "280 50% 65%",
26
- 500: "280 70% 67%",
27
- // Base accent (night mode primary)
28
- 600: "259 65% 58%",
29
- 700: "259 60% 50%",
30
- 800: "259 55% 45%",
31
- 900: "259 50% 40%",
31
+ 500: "280 65% 72%",
32
+ // Adjusted for WCAG AA contrast (4.5:1) with dark text in night mode
33
+ 600: "259 65% 59%",
34
+ // Default accent - lightened for better contrast vs secondary (L* ~59, was 52, 15 delta from secondary-600)
35
+ 700: "259 60% 44%",
36
+ // Active state - rebalanced for semantic strength (L* ~44, 12 delta from secondary-700)
37
+ 800: "259 55% 38%",
38
+ // Adjusted for proper progression
39
+ 900: "259 50% 32%",
32
40
  950: "259 45% 30%"
33
41
  };
34
42
  var secondaryColors = {
@@ -37,12 +45,15 @@ var secondaryColors = {
37
45
  200: "173 100% 85%",
38
46
  300: "173 100% 70%",
39
47
  400: "173 100% 55%",
40
- 500: "173 100% 37%",
41
- // Base secondary (Tenerife #00bfa6)
42
- 600: "173 100% 32%",
43
- 700: "173 95% 27%",
48
+ 500: "173 100% 45%",
49
+ // Adjusted for better scale progression
50
+ 600: "173 100% 44%",
51
+ // Default secondary - rebalanced for better contrast vs primary (L* ~44, was 38)
52
+ 700: "173 95% 32%",
53
+ // Active state - rebalanced for semantic strength (L* ~32)
44
54
  800: "173 90% 22%",
45
- 900: "173 85% 17%",
55
+ // Primary variant - darkened for dominance (L* ~22, was 26)
56
+ 900: "173 85% 20%",
46
57
  950: "173 80% 12%"
47
58
  };
48
59
  var surfaceColors = {
@@ -135,13 +146,13 @@ var chartColors = {
135
146
  var textColors = {
136
147
  day: {
137
148
  primary: "0 0% 9%",
138
- // Almost black
149
+ // Almost black (neutral-900 equivalent)
139
150
  secondary: "0 0% 45%",
140
151
  // Medium gray
141
152
  tertiary: "0 0% 65%",
142
153
  // Light gray
143
- muted: "0 0% 38%",
144
- // Muted gray with stronger contrast
154
+ muted: "0 0% 42%",
155
+ // Muted gray - adjusted for WCAG AA contrast (4.5:1) on surface.elevated2
145
156
  inverse: "0 0% 100%"
146
157
  // White (for dark backgrounds)
147
158
  },
@@ -453,6 +464,139 @@ var ALERT_TOKENS = {
453
464
  }
454
465
  };
455
466
 
467
+ // src/tokens/components/motion.ts
468
+ var MOTION_TOKENS = {
469
+ /**
470
+ * Transition property tokens
471
+ * Maps to Tailwind transition utilities
472
+ */
473
+ transition: {
474
+ all: "transition-all",
475
+ // All properties
476
+ colors: "transition-colors",
477
+ // Color properties only
478
+ opacity: "transition-opacity",
479
+ // Opacity only
480
+ transform: "transition-transform",
481
+ // Transform only
482
+ shadow: "transition-shadow",
483
+ // Box shadow only
484
+ none: "transition-none"
485
+ // No transition
486
+ },
487
+ /**
488
+ * Duration tokens
489
+ * Maps to foundation motion duration tokens via Tailwind
490
+ */
491
+ duration: {
492
+ instant: "duration-0",
493
+ // 0ms
494
+ fast: "duration-fast",
495
+ // 150ms - maps to motion.durations.fast
496
+ normal: "duration-normal",
497
+ // 300ms - maps to motion.durations.normal
498
+ slow: "duration-slow",
499
+ // 500ms - maps to motion.durations.slow
500
+ slower: "duration-slower",
501
+ // 700ms - maps to motion.durations.slower
502
+ slowest: "duration-slowest",
503
+ // 1000ms - maps to motion.durations.slowest
504
+ // Granular durations
505
+ "75": "duration-75",
506
+ // 75ms
507
+ "100": "duration-100",
508
+ // 100ms
509
+ "200": "duration-200",
510
+ // 200ms
511
+ "250": "duration-250",
512
+ // 250ms
513
+ "300": "duration-300",
514
+ // 300ms
515
+ "400": "duration-400",
516
+ // 400ms
517
+ "500": "duration-500",
518
+ // 500ms
519
+ "600": "duration-600",
520
+ // 600ms
521
+ "700": "duration-700",
522
+ // 700ms
523
+ "800": "duration-800",
524
+ // 800ms
525
+ "1000": "duration-1000"
526
+ // 1000ms
527
+ },
528
+ /**
529
+ * Easing tokens
530
+ * Maps to foundation motion easing tokens via Tailwind
531
+ */
532
+ easing: {
533
+ linear: "ease-linear",
534
+ // Linear easing
535
+ in: "ease-in",
536
+ // Ease in
537
+ out: "ease-out",
538
+ // Ease out (recommended for most UI)
539
+ "in-out": "ease-in-out",
540
+ // Ease in-out
541
+ bounce: "ease-bounce",
542
+ // Bounce easing
543
+ elastic: "ease-elastic"
544
+ // Elastic easing
545
+ },
546
+ /**
547
+ * Pre-configured transition tokens
548
+ * Combines duration and easing for common use cases
549
+ */
550
+ transitionPreset: {
551
+ fast: "transition-all duration-fast ease-out",
552
+ // Fast transition
553
+ normal: "transition-all duration-normal ease-in-out",
554
+ // Normal transition (default)
555
+ slow: "transition-all duration-slow ease-in-out",
556
+ // Slow transition
557
+ colors: "transition-colors duration-normal ease-out",
558
+ // Color transitions (common)
559
+ transform: "transition-transform duration-normal ease-out",
560
+ // Transform transitions
561
+ opacity: "transition-opacity duration-fast ease-out"
562
+ // Opacity transitions
563
+ },
564
+ /**
565
+ * Animation tokens
566
+ * Maps to foundation motion animation tokens via Tailwind
567
+ */
568
+ animation: {
569
+ none: "animate-none",
570
+ // No animation
571
+ spin: "animate-spin",
572
+ // Spin animation
573
+ pulse: "animate-pulse",
574
+ // Pulse animation
575
+ bounce: "animate-bounce",
576
+ // Bounce animation
577
+ ping: "animate-ping",
578
+ // Ping animation
579
+ shake: "animate-shake",
580
+ // Shake animation
581
+ fadeIn: "animate-fadeIn",
582
+ // Fade in
583
+ fadeOut: "animate-fadeOut",
584
+ // Fade out
585
+ slideInUp: "animate-slideInUp",
586
+ // Slide in from bottom
587
+ slideInDown: "animate-slideInDown",
588
+ // Slide in from top
589
+ slideInLeft: "animate-slideInLeft",
590
+ // Slide in from right
591
+ slideInRight: "animate-slideInRight",
592
+ // Slide in from left
593
+ scaleIn: "animate-scaleIn",
594
+ // Scale in
595
+ scaleOut: "animate-scaleOut"
596
+ // Scale out
597
+ }
598
+ };
599
+
456
600
  // src/tokens/components/button.ts
457
601
  var BUTTON_TOKENS = {
458
602
  /**
@@ -485,25 +629,48 @@ var BUTTON_TOKENS = {
485
629
  vertical: {
486
630
  sm: "py-xs",
487
631
  // 4px (0.25rem) - maps to semanticSpacing.xs
488
- md: "py-sm"
632
+ md: "py-sm",
489
633
  // 8px (0.5rem) - maps to semanticSpacing.sm
634
+ lg: "py-md"
635
+ // 16px (1rem) - maps to semanticSpacing.md - standardized for visual distinction
490
636
  }
491
637
  },
492
638
  /**
493
- * Gap between icon and text
639
+ * Gap between icon and text by size
640
+ * Scales with button size for visual consistency
494
641
  */
495
- gap: "gap-sm",
496
- // 8px (0.5rem) - maps to semanticSpacing.sm
642
+ gap: {
643
+ sm: "gap-xs",
644
+ // 4px (0.25rem) - smaller gap for small buttons
645
+ md: "gap-sm",
646
+ // 8px (0.5rem) - medium gap for medium buttons
647
+ lg: "gap-md"
648
+ // 16px (1rem) - larger gap for large buttons
649
+ },
497
650
  /**
498
651
  * Border radius for all button sizes
652
+ * Consistent radius across sizes for visual harmony
653
+ *
654
+ * @enforcement TUNG_TOKEN_AUTHORITY_EXPANSION_PLAN
655
+ * @rule References componentRadius.button.md (6px / 0.375rem) from Radius Authority
656
+ * @see docs/architecture/RADIUS_AUTHORITY_CONTRACT.md
499
657
  */
500
658
  radius: "rounded-md",
501
- // 6px (0.375rem) - maps to borderRadius.md
659
+ // References componentRadius.button.md (6px / 0.375rem) - Radius Authority compliant
502
660
  /**
503
- * Icon size within buttons
661
+ * Icon size within buttons by button size
662
+ * Scales proportionally with button size for visual balance
504
663
  */
505
- iconSize: "size-4",
506
- // 16px (1rem) - maps to spacing[4]
664
+ iconSize: {
665
+ sm: "size-3.5",
666
+ // 14px (0.875rem) - smaller icon for small buttons
667
+ md: "size-4",
668
+ // 16px (1rem) - medium icon for medium buttons
669
+ lg: "size-5",
670
+ // 20px (1.25rem) - larger icon for large buttons
671
+ icon: "size-4"
672
+ // 16px (1rem) - medium icon for icon-only buttons
673
+ },
507
674
  /**
508
675
  * Width tokens
509
676
  */
@@ -513,15 +680,19 @@ var BUTTON_TOKENS = {
513
680
  },
514
681
  /**
515
682
  * Font sizes by button size
516
- * Maps to foundation typography fontSize tokens
683
+ * References foundation typography fontSize tokens from Typography Authority
684
+ *
685
+ * @enforcement TUNG_TOKEN_AUTHORITY_EXPANSION_PLAN
686
+ * @rule All fontSize values reference Typography Authority tokens
687
+ * @see docs/architecture/TYPOGRAPHY_AUTHORITY_CONTRACT.md
517
688
  */
518
689
  fontSize: {
519
690
  sm: "text-xs",
520
- // Maps to fontSize.xs[0]
691
+ // References fontSize.xs[0] from Typography Authority (~12px)
521
692
  md: "text-sm",
522
- // Maps to fontSize.sm[0]
523
- lg: "text-sm"
524
- // Maps to fontSize.sm[0]
693
+ // References fontSize.sm[0] from Typography Authority (~14px)
694
+ lg: "text-base"
695
+ // References fontSize.base[0] from Typography Authority (~16px)
525
696
  },
526
697
  /**
527
698
  * Shadow tokens by variant
@@ -536,50 +707,137 @@ var BUTTON_TOKENS = {
536
707
  /**
537
708
  * Color tokens for button variants
538
709
  * Uses semantic color tokens that map to CSS variables
710
+ *
711
+ * State tokens (hover, active, disabled) use CSS variables from State Matrix.
712
+ * All states are injected via updateStateMatrixFromTokens() and consumed via arbitrary values.
713
+ * States react to Color Authority changes automatically through State Matrix.
714
+ *
715
+ * Interaction Authority Rules:
716
+ * - Hover (Priority 4): hover: prefix - ONLY when !disabled && !loading && pointer-events:auto
717
+ * - Active (Priority 3): active: prefix - ONLY when !disabled && !loading && mousedown
718
+ * - Focus (Priority 5): focus-visible: prefix - ONLY when !disabled && keyboard navigation
719
+ * - Disabled (Priority 1): disabled: prefix - Blocks ALL interactions
720
+ * - Loading (Priority 2): loading: prefix - Blocks hover/active (when implemented)
721
+ * - Base (Priority 6): No prefix - Default state, pointer-events: auto
722
+ *
723
+ * @enforcement TUNG_STATE_AUTHORITY_FOUNDATION_LOCK
724
+ * @enforcement TUNG_INTERACTION_AUTHORITY_FOUNDATION
725
+ * @rule States use CSS variables, not Tailwind variants
726
+ * @rule All state variables follow pattern: --{component}-{variant}-{state}-{property}
727
+ * @rule Visual states (colors) are SEPARATE from interaction states (pointer-events)
728
+ * @rule Hover MUST work with real mouse cursor, NOT just DevTools force state
729
+ * @rule Active MUST activate only on mousedown, NOT on hover
730
+ * @rule Focus MUST activate only on keyboard navigation, NOT on mouse click
731
+ *
732
+ * @see docs/architecture/INTERACTION_AUTHORITY_CONTRACT.md
539
733
  */
540
734
  variant: {
541
735
  primary: {
542
- background: "bg-primary",
543
- // Primary background using CSS var
736
+ background: "bg-[hsl(var(--button-primary-base-bg))]",
737
+ // Primary base background - CSS variable from State Matrix
544
738
  text: "text-primary-foreground",
545
739
  // Primary text using CSS var
546
- hover: "hover:bg-primary/90"
547
- // Primary hover using CSS var
740
+ hover: "hover:bg-[hsl(var(--button-primary-hover-bg))]",
741
+ // Primary hover - CSS variable from State Matrix (Priority 4: blocked by disabled/loading)
742
+ active: "active:bg-[hsl(var(--button-primary-active-bg))]",
743
+ // Primary active - CSS variable from State Matrix (Priority 3: blocked by disabled/loading, priority over hover)
744
+ focus: "focus-visible:bg-[hsl(var(--button-primary-focus-bg))]",
745
+ // Primary focus - CSS variable from State Matrix (Priority 5: keyboard navigation only)
746
+ disabled: {
747
+ background: "disabled:bg-[hsl(var(--button-primary-disabled-bg))]",
748
+ // Disabled background - CSS variable from State Matrix (Priority 1: blocks all)
749
+ text: "disabled:text-[hsl(var(--button-primary-disabled-text))]"
750
+ // Disabled text - CSS variable from State Matrix
751
+ },
752
+ loading: "bg-[hsl(var(--button-primary-loading-bg))]"
753
+ // Primary loading - CSS variable from State Matrix (Priority 2: blocks hover/active, used with aria-busy/data-loading when implemented)
548
754
  },
549
755
  secondary: {
550
756
  background: "bg-secondary",
551
757
  // Secondary background using CSS var
552
758
  text: "text-secondary-foreground",
553
759
  // Secondary text using CSS var
554
- hover: "hover:bg-secondary/80"
555
- // Secondary hover using CSS var
760
+ hover: "hover:bg-[hsl(var(--button-secondary-hover-bg))]",
761
+ // Secondary hover - CSS variable from State Matrix
762
+ active: "active:bg-[hsl(var(--button-secondary-active-bg))]",
763
+ // Secondary active - CSS variable from State Matrix
764
+ disabled: {
765
+ background: "disabled:bg-[hsl(var(--button-secondary-disabled-bg))]",
766
+ // Disabled background - CSS variable from State Matrix
767
+ text: "disabled:text-[hsl(var(--button-secondary-disabled-text))]"
768
+ // Disabled text - CSS variable from State Matrix
769
+ }
556
770
  },
557
771
  accent: {
558
772
  background: "bg-accent",
559
773
  // Accent background using CSS var
560
774
  text: "text-accent-foreground",
561
775
  // Accent text using CSS var
562
- hover: "hover:bg-accent/90"
563
- // Accent hover using CSS var
776
+ hover: "hover:bg-[hsl(var(--button-accent-hover-bg))]",
777
+ // Accent hover - CSS variable from State Matrix
778
+ active: "active:bg-[hsl(var(--button-accent-active-bg))]",
779
+ // Accent active - CSS variable from State Matrix
780
+ disabled: {
781
+ background: "disabled:bg-[hsl(var(--button-accent-disabled-bg))]",
782
+ // Disabled background - CSS variable from State Matrix
783
+ text: "disabled:text-[hsl(var(--button-accent-disabled-text))]"
784
+ // Disabled text - CSS variable from State Matrix
785
+ }
564
786
  },
565
787
  outline: {
566
788
  border: "border border-input",
567
789
  // Input border using CSS var
568
790
  background: "bg-background",
569
791
  // Background using CSS var
792
+ text: "text-foreground",
793
+ // Foreground text using CSS var
570
794
  hover: {
571
- background: "hover:bg-accent",
572
- // Accent hover using CSS var
573
- text: "hover:text-accent-foreground"
574
- // Accent text using CSS var
795
+ background: "hover:bg-[hsl(var(--button-outline-hover-bg))]",
796
+ // Outline hover background - CSS variable from State Matrix
797
+ text: "hover:text-[hsl(var(--button-outline-hover-text))]",
798
+ // Outline hover text - CSS variable from State Matrix
799
+ border: "hover:border-[hsl(var(--button-outline-hover-border))]"
800
+ // Outline hover border - CSS variable from State Matrix
801
+ },
802
+ active: {
803
+ background: "active:bg-[hsl(var(--button-outline-active-bg))]",
804
+ // Outline active background - CSS variable from State Matrix
805
+ text: "active:text-[hsl(var(--button-outline-active-text))]",
806
+ // Outline active text - CSS variable from State Matrix
807
+ border: "active:border-[hsl(var(--button-outline-active-border))]"
808
+ // Outline active border - CSS variable from State Matrix
809
+ },
810
+ disabled: {
811
+ background: "disabled:bg-[hsl(var(--button-outline-disabled-bg))]",
812
+ // Disabled background - CSS variable from State Matrix
813
+ text: "disabled:text-[hsl(var(--button-outline-disabled-text))]",
814
+ // Disabled text - CSS variable from State Matrix
815
+ border: "disabled:border-[hsl(var(--button-outline-disabled-border))]"
816
+ // Disabled border - CSS variable from State Matrix
575
817
  }
576
818
  },
577
819
  ghost: {
820
+ background: "bg-transparent",
821
+ // Transparent background
822
+ text: "text-foreground",
823
+ // Foreground text using CSS var
578
824
  hover: {
579
- background: "hover:bg-accent",
580
- // Accent hover using CSS var
581
- text: "hover:text-accent-foreground"
582
- // Accent text using CSS var
825
+ background: "hover:bg-[hsl(var(--button-ghost-hover-bg))]",
826
+ // Ghost hover background - CSS variable from State Matrix
827
+ text: "hover:text-[hsl(var(--button-ghost-hover-text))]"
828
+ // Ghost hover text - CSS variable from State Matrix
829
+ },
830
+ active: {
831
+ background: "active:bg-[hsl(var(--button-ghost-active-bg))]",
832
+ // Ghost active background - CSS variable from State Matrix
833
+ text: "active:text-[hsl(var(--button-ghost-active-text))]"
834
+ // Ghost active text - CSS variable from State Matrix
835
+ },
836
+ disabled: {
837
+ background: "disabled:bg-[hsl(var(--button-ghost-disabled-bg))]",
838
+ // Disabled background - CSS variable from State Matrix
839
+ text: "disabled:text-[hsl(var(--button-ghost-disabled-text))]"
840
+ // Disabled text - CSS variable from State Matrix
583
841
  }
584
842
  },
585
843
  destructive: {
@@ -587,16 +845,94 @@ var BUTTON_TOKENS = {
587
845
  // Destructive background using CSS var
588
846
  text: "text-destructive-foreground",
589
847
  // Destructive text using CSS var
590
- hover: "hover:bg-destructive/90"
591
- // Destructive hover using CSS var
848
+ hover: "hover:bg-[hsl(var(--button-destructive-hover-bg))]",
849
+ // Destructive hover - CSS variable from State Matrix
850
+ active: "active:bg-[hsl(var(--button-destructive-active-bg))]",
851
+ // Destructive active - CSS variable from State Matrix
852
+ disabled: {
853
+ background: "disabled:bg-[hsl(var(--button-destructive-disabled-bg))]",
854
+ // Disabled background - CSS variable from State Matrix
855
+ text: "disabled:text-[hsl(var(--button-destructive-disabled-text))]"
856
+ // Disabled text - CSS variable from State Matrix
857
+ }
592
858
  }
593
859
  },
594
860
  /**
595
861
  * Transition tokens
862
+ * References Motion Authority tokens for consistent motion behavior
863
+ *
864
+ * @enforcement TUNG_TOKEN_AUTHORITY_EXPANSION_PLAN
865
+ * @rule Uses MOTION_TOKENS.transitionPreset.colors from Motion Authority
866
+ * @rule Motion transitions MUST use canonical motion tokens only
867
+ * @see docs/architecture/MOTION_AUTHORITY_CONTRACT.md
596
868
  */
597
869
  transition: {
598
- colors: "transition-colors"
599
- // Color transition using motion tokens
870
+ colors: MOTION_TOKENS.transitionPreset.colors
871
+ // "transition-colors duration-normal ease-out" - Motion Authority compliant
872
+ },
873
+ /**
874
+ * Global state tokens
875
+ * Shared state tokens that apply across all variants
876
+ * Variant-specific states are defined in variant.*.active and variant.*.disabled
877
+ *
878
+ * @enforcement TUNG_INTERACTION_AUTHORITY_FOUNDATION
879
+ * @rule All interaction states MUST follow Interaction Authority Contract
880
+ * @rule State priority: disabled > loading > active > hover > focus-visible > base
881
+ * @rule Visual states (colors) are SEPARATE from interaction states (pointer-events, cursor)
882
+ * @rule All states MUST be browser-native (CSS pseudo-classes), NOT JavaScript-managed
883
+ */
884
+ state: {
885
+ /**
886
+ * Disabled state tokens
887
+ * Global disabled state tokens (variant-specific overrides in variant.*.disabled)
888
+ *
889
+ * Interaction Authority Rules:
890
+ * - Priority: 1 (Highest) - Blocks ALL interactions
891
+ * - MUST block hover, active, and focus states
892
+ * - MUST use disabled: prefix (never in base state)
893
+ * - Base state MUST have pointer-events: auto (default) for hover to work
894
+ *
895
+ * @enforcement TUNG_INTERACTION_AUTHORITY_FOUNDATION
896
+ * @enforcement TUNG_BUTTON_INTERACTION_FIX
897
+ * @rule Interaction Authority: pointer-events is NOT a visual token
898
+ * @rule pointer-events-none MUST use disabled: prefix (never in base state)
899
+ * @rule Base state MUST have pointer-events: auto (default) for hover to work
900
+ * @rule These tokens are applied in base but only activate when element is disabled
901
+ * @rule Hover is FORBIDDEN when disabled={true}
902
+ * @rule Active is FORBIDDEN when disabled={true}
903
+ * @rule Focus is FORBIDDEN when disabled={true} (for interactions)
904
+ *
905
+ * @see docs/architecture/INTERACTION_AUTHORITY_CONTRACT.md
906
+ */
907
+ disabled: {
908
+ cursor: "disabled:cursor-not-allowed",
909
+ // Disabled cursor style (only applies when disabled)
910
+ pointerEvents: "disabled:pointer-events-none"
911
+ // Disable pointer events (only applies when disabled)
912
+ },
913
+ /**
914
+ * Focus state tokens
915
+ * Focus ring for keyboard navigation
916
+ *
917
+ * Interaction Authority Rules:
918
+ * - Priority: 5 - Lower than active and hover
919
+ * - MUST activate only on keyboard navigation (focus-visible: prefix)
920
+ * - MUST NOT activate on mouse click (use :focus-visible, not :focus)
921
+ * - MUST be blocked by disabled state
922
+ *
923
+ * @enforcement TUNG_INTERACTION_AUTHORITY_FOUNDATION
924
+ * @rule Focus MUST use focus-visible: prefix (keyboard navigation only)
925
+ * @rule Focus MUST be blocked when disabled={true}
926
+ * @rule Focus MUST NOT activate on mouse click
927
+ *
928
+ * @see docs/architecture/INTERACTION_AUTHORITY_CONTRACT.md
929
+ */
930
+ focus: {
931
+ ring: "focus-visible:ring-1 focus-visible:ring-ring",
932
+ // Focus ring using semantic ring color
933
+ outline: "focus-visible:outline-none"
934
+ // Remove default outline (replaced by ring)
935
+ }
600
936
  }
601
937
  };
602
938
 
@@ -1132,139 +1468,6 @@ var ICON_TOKENS = {
1132
1468
  }
1133
1469
  };
1134
1470
 
1135
- // src/tokens/components/motion.ts
1136
- var MOTION_TOKENS = {
1137
- /**
1138
- * Transition property tokens
1139
- * Maps to Tailwind transition utilities
1140
- */
1141
- transition: {
1142
- all: "transition-all",
1143
- // All properties
1144
- colors: "transition-colors",
1145
- // Color properties only
1146
- opacity: "transition-opacity",
1147
- // Opacity only
1148
- transform: "transition-transform",
1149
- // Transform only
1150
- shadow: "transition-shadow",
1151
- // Box shadow only
1152
- none: "transition-none"
1153
- // No transition
1154
- },
1155
- /**
1156
- * Duration tokens
1157
- * Maps to foundation motion duration tokens via Tailwind
1158
- */
1159
- duration: {
1160
- instant: "duration-0",
1161
- // 0ms
1162
- fast: "duration-fast",
1163
- // 150ms - maps to motion.durations.fast
1164
- normal: "duration-normal",
1165
- // 300ms - maps to motion.durations.normal
1166
- slow: "duration-slow",
1167
- // 500ms - maps to motion.durations.slow
1168
- slower: "duration-slower",
1169
- // 700ms - maps to motion.durations.slower
1170
- slowest: "duration-slowest",
1171
- // 1000ms - maps to motion.durations.slowest
1172
- // Granular durations
1173
- "75": "duration-75",
1174
- // 75ms
1175
- "100": "duration-100",
1176
- // 100ms
1177
- "200": "duration-200",
1178
- // 200ms
1179
- "250": "duration-250",
1180
- // 250ms
1181
- "300": "duration-300",
1182
- // 300ms
1183
- "400": "duration-400",
1184
- // 400ms
1185
- "500": "duration-500",
1186
- // 500ms
1187
- "600": "duration-600",
1188
- // 600ms
1189
- "700": "duration-700",
1190
- // 700ms
1191
- "800": "duration-800",
1192
- // 800ms
1193
- "1000": "duration-1000"
1194
- // 1000ms
1195
- },
1196
- /**
1197
- * Easing tokens
1198
- * Maps to foundation motion easing tokens via Tailwind
1199
- */
1200
- easing: {
1201
- linear: "ease-linear",
1202
- // Linear easing
1203
- in: "ease-in",
1204
- // Ease in
1205
- out: "ease-out",
1206
- // Ease out (recommended for most UI)
1207
- "in-out": "ease-in-out",
1208
- // Ease in-out
1209
- bounce: "ease-bounce",
1210
- // Bounce easing
1211
- elastic: "ease-elastic"
1212
- // Elastic easing
1213
- },
1214
- /**
1215
- * Pre-configured transition tokens
1216
- * Combines duration and easing for common use cases
1217
- */
1218
- transitionPreset: {
1219
- fast: "transition-all duration-fast ease-out",
1220
- // Fast transition
1221
- normal: "transition-all duration-normal ease-in-out",
1222
- // Normal transition (default)
1223
- slow: "transition-all duration-slow ease-in-out",
1224
- // Slow transition
1225
- colors: "transition-colors duration-normal ease-out",
1226
- // Color transitions (common)
1227
- transform: "transition-transform duration-normal ease-out",
1228
- // Transform transitions
1229
- opacity: "transition-opacity duration-fast ease-out"
1230
- // Opacity transitions
1231
- },
1232
- /**
1233
- * Animation tokens
1234
- * Maps to foundation motion animation tokens via Tailwind
1235
- */
1236
- animation: {
1237
- none: "animate-none",
1238
- // No animation
1239
- spin: "animate-spin",
1240
- // Spin animation
1241
- pulse: "animate-pulse",
1242
- // Pulse animation
1243
- bounce: "animate-bounce",
1244
- // Bounce animation
1245
- ping: "animate-ping",
1246
- // Ping animation
1247
- shake: "animate-shake",
1248
- // Shake animation
1249
- fadeIn: "animate-fadeIn",
1250
- // Fade in
1251
- fadeOut: "animate-fadeOut",
1252
- // Fade out
1253
- slideInUp: "animate-slideInUp",
1254
- // Slide in from bottom
1255
- slideInDown: "animate-slideInDown",
1256
- // Slide in from top
1257
- slideInLeft: "animate-slideInLeft",
1258
- // Slide in from right
1259
- slideInRight: "animate-slideInRight",
1260
- // Slide in from left
1261
- scaleIn: "animate-scaleIn",
1262
- // Scale in
1263
- scaleOut: "animate-scaleOut"
1264
- // Scale out
1265
- }
1266
- };
1267
-
1268
1471
  // src/tokens/components/domain.ts
1269
1472
  var DOMAIN_TOKENS = {
1270
1473
  /**
@@ -2874,8 +3077,16 @@ var TEXT_TOKENS = {
2874
3077
  // Maps to fontSize.base[0]
2875
3078
  lg: "text-lg",
2876
3079
  // Maps to fontSize.lg[0]
2877
- xl: "text-xl"
3080
+ xl: "text-xl",
2878
3081
  // Maps to fontSize.xl[0]
3082
+ "2xl": "text-2xl",
3083
+ // Maps to fontSize.2xl[0]
3084
+ "3xl": "text-3xl",
3085
+ // Maps to fontSize.3xl[0]
3086
+ "4xl": "text-4xl",
3087
+ // Maps to fontSize.4xl[0]
3088
+ "5xl": "text-5xl"
3089
+ // Maps to fontSize.5xl[0]
2879
3090
  },
2880
3091
  /**
2881
3092
  * Font weights by weight variant
@@ -2900,6 +3111,8 @@ var TEXT_TOKENS = {
2900
3111
  // Maps to lineHeight.none
2901
3112
  tight: "leading-tight",
2902
3113
  // Maps to lineHeight.tight
3114
+ snug: "leading-snug",
3115
+ // Maps to lineHeight.snug
2903
3116
  normal: "leading-normal",
2904
3117
  // Maps to lineHeight.normal
2905
3118
  relaxed: "leading-relaxed",
@@ -3423,9 +3636,9 @@ var TOAST_TOKENS = {
3423
3636
  // Default opacity (hidden)
3424
3637
  groupHover: "group-hover:opacity-100",
3425
3638
  // Visible on group hover
3426
- focus: "focus:opacity-100",
3639
+ focus: "focus-visible:opacity-100",
3427
3640
  // Visible on focus
3428
- focusRing: "focus:outline-none focus:ring-1"
3641
+ focusRing: "focus-visible:outline-none focus-visible:ring-1"
3429
3642
  // Focus ring styling
3430
3643
  }
3431
3644
  }
@@ -4181,13 +4394,13 @@ var DROPDOWN_TOKENS = {
4181
4394
  */
4182
4395
  item: {
4183
4396
  background: {
4184
- focus: "focus:bg-[hsl(var(--accent))]",
4397
+ focus: "focus-visible:bg-[hsl(var(--accent))]",
4185
4398
  // Focus background using CSS var
4186
4399
  selected: "bg-[hsl(var(--accent))]"
4187
4400
  // Selected background using CSS var
4188
4401
  },
4189
4402
  text: {
4190
- focus: "focus:text-[hsl(var(--accent-foreground))]",
4403
+ focus: "focus-visible:text-[hsl(var(--accent-foreground))]",
4191
4404
  // Focus text using CSS var
4192
4405
  selected: "text-[hsl(var(--accent-foreground))]"
4193
4406
  // Selected text using CSS var
@@ -4445,9 +4658,9 @@ var SELECT_TOKENS = {
4445
4658
  // 8px (0.5rem) from left
4446
4659
  },
4447
4660
  focus: {
4448
- background: "focus:bg-[hsl(var(--accent))]",
4661
+ background: "focus-visible:bg-[hsl(var(--accent))]",
4449
4662
  // Focus background using CSS var
4450
- text: "focus:text-[hsl(var(--accent-foreground))]"
4663
+ text: "focus-visible:text-[hsl(var(--accent-foreground))]"
4451
4664
  // Focus text using CSS var
4452
4665
  },
4453
4666
  selected: {
@@ -5037,54 +5250,54 @@ var transitions = {
5037
5250
  var keyframes = {
5038
5251
  // Fade animations
5039
5252
  fadeIn: {
5040
- from: { opacity: 0 },
5041
- to: { opacity: 1 }
5253
+ from: { opacity: "0" },
5254
+ to: { opacity: "1" }
5042
5255
  },
5043
5256
  fadeOut: {
5044
- from: { opacity: 1 },
5045
- to: { opacity: 0 }
5257
+ from: { opacity: "1" },
5258
+ to: { opacity: "0" }
5046
5259
  },
5047
5260
  // Slide animations
5048
5261
  slideInUp: {
5049
- from: { transform: "translateY(100%)", opacity: 0 },
5050
- to: { transform: "translateY(0)", opacity: 1 }
5262
+ from: { transform: "translateY(100%)", opacity: "0" },
5263
+ to: { transform: "translateY(0)", opacity: "1" }
5051
5264
  },
5052
5265
  slideInDown: {
5053
- from: { transform: "translateY(-100%)", opacity: 0 },
5054
- to: { transform: "translateY(0)", opacity: 1 }
5266
+ from: { transform: "translateY(-100%)", opacity: "0" },
5267
+ to: { transform: "translateY(0)", opacity: "1" }
5055
5268
  },
5056
5269
  slideInLeft: {
5057
- from: { transform: "translateX(-100%)", opacity: 0 },
5058
- to: { transform: "translateX(0)", opacity: 1 }
5270
+ from: { transform: "translateX(-100%)", opacity: "0" },
5271
+ to: { transform: "translateX(0)", opacity: "1" }
5059
5272
  },
5060
5273
  slideInRight: {
5061
- from: { transform: "translateX(100%)", opacity: 0 },
5062
- to: { transform: "translateX(0)", opacity: 1 }
5274
+ from: { transform: "translateX(100%)", opacity: "0" },
5275
+ to: { transform: "translateX(0)", opacity: "1" }
5063
5276
  },
5064
5277
  slideOutUp: {
5065
- from: { transform: "translateY(0)", opacity: 1 },
5066
- to: { transform: "translateY(-100%)", opacity: 0 }
5278
+ from: { transform: "translateY(0)", opacity: "1" },
5279
+ to: { transform: "translateY(-100%)", opacity: "0" }
5067
5280
  },
5068
5281
  slideOutDown: {
5069
- from: { transform: "translateY(0)", opacity: 1 },
5070
- to: { transform: "translateY(100%)", opacity: 0 }
5282
+ from: { transform: "translateY(0)", opacity: "1" },
5283
+ to: { transform: "translateY(100%)", opacity: "0" }
5071
5284
  },
5072
5285
  slideOutLeft: {
5073
- from: { transform: "translateX(0)", opacity: 1 },
5074
- to: { transform: "translateX(-100%)", opacity: 0 }
5286
+ from: { transform: "translateX(0)", opacity: "1" },
5287
+ to: { transform: "translateX(-100%)", opacity: "0" }
5075
5288
  },
5076
5289
  slideOutRight: {
5077
- from: { transform: "translateX(0)", opacity: 1 },
5078
- to: { transform: "translateX(100%)", opacity: 0 }
5290
+ from: { transform: "translateX(0)", opacity: "1" },
5291
+ to: { transform: "translateX(100%)", opacity: "0" }
5079
5292
  },
5080
5293
  // Scale animations
5081
5294
  scaleIn: {
5082
- from: { transform: "scale(0.95)", opacity: 0 },
5083
- to: { transform: "scale(1)", opacity: 1 }
5295
+ from: { transform: "scale(0.95)", opacity: "0" },
5296
+ to: { transform: "scale(1)", opacity: "1" }
5084
5297
  },
5085
5298
  scaleOut: {
5086
- from: { transform: "scale(1)", opacity: 1 },
5087
- to: { transform: "scale(0.95)", opacity: 0 }
5299
+ from: { transform: "scale(1)", opacity: "1" },
5300
+ to: { transform: "scale(0.95)", opacity: "0" }
5088
5301
  },
5089
5302
  scaleUp: {
5090
5303
  from: { transform: "scale(1)" },
@@ -5105,8 +5318,8 @@ var keyframes = {
5105
5318
  },
5106
5319
  // Pulse and bounce
5107
5320
  pulse: {
5108
- "0%, 100%": { opacity: 1 },
5109
- "50%": { opacity: 0.5 }
5321
+ "0%, 100%": { opacity: "1" },
5322
+ "50%": { opacity: "0.5" }
5110
5323
  },
5111
5324
  bounce: {
5112
5325
  "0%, 100%": {
@@ -5128,7 +5341,7 @@ var keyframes = {
5128
5341
  ping: {
5129
5342
  "75%, 100%": {
5130
5343
  transform: "scale(2)",
5131
- opacity: 0
5344
+ opacity: "0"
5132
5345
  }
5133
5346
  },
5134
5347
  // Accordion animations (for Radix UI)