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