@thesage/ui 1.1.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/.claude/CLAUDE.md +3 -3
  2. package/LICENSE +21 -0
  3. package/README.md +3 -4
  4. package/dist/dates.js +15 -5
  5. package/dist/dates.js.map +1 -1
  6. package/dist/dates.mjs +15 -5
  7. package/dist/dates.mjs.map +1 -1
  8. package/dist/{fontThemes-Cum0S1DI.d.mts → fontThemes-Dh8mtXES.d.mts} +27 -1
  9. package/dist/{fontThemes-Cum0S1DI.d.ts → fontThemes-Dh8mtXES.d.ts} +27 -1
  10. package/dist/forms.js +1 -1
  11. package/dist/forms.js.map +1 -1
  12. package/dist/forms.mjs +1 -1
  13. package/dist/forms.mjs.map +1 -1
  14. package/dist/{hooks-CobTQpCg.d.mts → hooks-1b8WaQf1.d.mts} +2 -2
  15. package/dist/{hooks-DHPlUx3T.d.ts → hooks-CKW8vE9H.d.ts} +2 -2
  16. package/dist/hooks.d.mts +2 -2
  17. package/dist/hooks.d.ts +2 -2
  18. package/dist/hooks.js +3 -375
  19. package/dist/hooks.js.map +1 -1
  20. package/dist/hooks.mjs +3 -375
  21. package/dist/hooks.mjs.map +1 -1
  22. package/dist/index-DscTIrZ2.d.mts +29 -0
  23. package/dist/index-DscTIrZ2.d.ts +29 -0
  24. package/dist/index.d.mts +62 -36
  25. package/dist/index.d.ts +62 -36
  26. package/dist/index.js +617 -331
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.mjs +634 -348
  29. package/dist/index.mjs.map +1 -1
  30. package/dist/providers-aJW1AKg6.d.mts +30 -0
  31. package/dist/providers-qfyBVcPW.d.ts +30 -0
  32. package/dist/providers.d.mts +2 -1
  33. package/dist/providers.d.ts +2 -1
  34. package/dist/providers.js +226 -375
  35. package/dist/providers.js.map +1 -1
  36. package/dist/providers.mjs +226 -375
  37. package/dist/providers.mjs.map +1 -1
  38. package/dist/tables.js +5 -5
  39. package/dist/tables.js.map +1 -1
  40. package/dist/tables.mjs +5 -5
  41. package/dist/tables.mjs.map +1 -1
  42. package/dist/tokens.d.mts +165 -3
  43. package/dist/tokens.d.ts +165 -3
  44. package/dist/tokens.js +219 -1
  45. package/dist/tokens.js.map +1 -1
  46. package/dist/tokens.mjs +217 -1
  47. package/dist/tokens.mjs.map +1 -1
  48. package/dist/{utils-xrpHqxXR.d.ts → utils-CIIM7dAC.d.ts} +1 -1
  49. package/dist/{utils-DlJKRVzQ.d.mts → utils-Cs04sxth.d.mts} +1 -1
  50. package/dist/utils.d.mts +1 -1
  51. package/dist/utils.d.ts +1 -1
  52. package/package.json +22 -10
  53. package/dist/index-L8R3gyuQ.d.mts +0 -23
  54. package/dist/index-L8R3gyuQ.d.ts +0 -23
  55. package/dist/providers-Dv3LFGtJ.d.mts +0 -17
  56. package/dist/providers-Dv3LFGtJ.d.ts +0 -17
@@ -37,225 +37,6 @@ var useThemeStore = create()(
37
37
  import { create as create2 } from "zustand";
38
38
  import { persist as persist2 } from "zustand/middleware";
39
39
 
40
- // ../tokens/src/base.ts
41
- var baseTokens = {
42
- /**
43
- * Spacing scale (based on 4px grid)
44
- */
45
- spacing: {
46
- "0": "0",
47
- "0.5": "0.125rem",
48
- // 2px
49
- "1": "0.25rem",
50
- // 4px
51
- "2": "0.5rem",
52
- // 8px
53
- "3": "0.75rem",
54
- // 12px
55
- "4": "1rem",
56
- // 16px
57
- "5": "1.25rem",
58
- // 20px
59
- "6": "1.5rem",
60
- // 24px
61
- "8": "2rem",
62
- // 32px
63
- "10": "2.5rem",
64
- // 40px
65
- "12": "3rem",
66
- // 48px
67
- "16": "4rem",
68
- // 64px
69
- "20": "5rem",
70
- // 80px
71
- "24": "6rem",
72
- // 96px
73
- "32": "8rem"
74
- // 128px
75
- },
76
- /**
77
- * Typography scales
78
- */
79
- fontSize: {
80
- "xs": "0.75rem",
81
- // 12px
82
- "sm": "0.875rem",
83
- // 14px
84
- "base": "1rem",
85
- // 16px
86
- "lg": "1.125rem",
87
- // 18px
88
- "xl": "1.25rem",
89
- // 20px
90
- "2xl": "1.5rem",
91
- // 24px
92
- "3xl": "1.875rem",
93
- // 30px
94
- "4xl": "2.25rem",
95
- // 36px
96
- "5xl": "3rem",
97
- // 48px
98
- "6xl": "3.75rem",
99
- // 60px
100
- "7xl": "4.5rem",
101
- // 72px
102
- "8xl": "6rem"
103
- // 96px
104
- },
105
- fontWeight: {
106
- light: "300",
107
- normal: "400",
108
- medium: "500",
109
- semibold: "600",
110
- bold: "700",
111
- extrabold: "800",
112
- black: "900"
113
- },
114
- lineHeight: {
115
- none: "1",
116
- tight: "1.25",
117
- snug: "1.375",
118
- normal: "1.5",
119
- relaxed: "1.625",
120
- loose: "2"
121
- },
122
- /**
123
- * Border radius
124
- */
125
- borderRadius: {
126
- none: "0",
127
- sm: "0.125rem",
128
- // 2px
129
- DEFAULT: "0.25rem",
130
- // 4px
131
- md: "0.375rem",
132
- // 6px
133
- lg: "0.5rem",
134
- // 8px
135
- xl: "0.75rem",
136
- // 12px
137
- "2xl": "1rem",
138
- // 16px
139
- "3xl": "1.5rem",
140
- // 24px
141
- full: "9999px"
142
- },
143
- /**
144
- * Motion durations (base values - themes can override)
145
- */
146
- duration: {
147
- instant: "0ms",
148
- fast: "150ms",
149
- normal: "300ms",
150
- slow: "500ms",
151
- slower: "800ms"
152
- },
153
- /**
154
- * Easing curves (base values - themes can override)
155
- */
156
- ease: {
157
- linear: "linear",
158
- in: "cubic-bezier(0.4, 0, 1, 1)",
159
- out: "cubic-bezier(0, 0, 0.2, 1)",
160
- inOut: "cubic-bezier(0.4, 0, 0.2, 1)"
161
- },
162
- /**
163
- * Z-index scale
164
- */
165
- zIndex: {
166
- "auto": "auto",
167
- "0": "0",
168
- "10": "10",
169
- "20": "20",
170
- "30": "30",
171
- "40": "40",
172
- "50": "50",
173
- dropdown: "1000",
174
- sticky: "1020",
175
- fixed: "1030",
176
- modalBackdrop: "1040",
177
- modal: "1050",
178
- popover: "1060",
179
- tooltip: "1070"
180
- },
181
- /**
182
- * Focus ring configuration
183
- */
184
- focus: {
185
- width: "2px",
186
- offset: "2px",
187
- style: "solid"
188
- }
189
- };
190
- var spacing = {
191
- xs: baseTokens.spacing["1"],
192
- // 4px — Tight internal padding
193
- sm: baseTokens.spacing["2"],
194
- // 8px — Default gap
195
- md: baseTokens.spacing["4"],
196
- // 16px — Section padding
197
- lg: baseTokens.spacing["6"],
198
- // 24px — Card padding
199
- xl: baseTokens.spacing["8"],
200
- // 32px — Section margins
201
- "2xl": baseTokens.spacing["12"],
202
- // 48px — Page sections
203
- "3xl": baseTokens.spacing["16"]
204
- // 64px — Major divisions
205
- };
206
- var typography = {
207
- fonts: {
208
- sans: "var(--font-body)",
209
- serif: "var(--font-heading)",
210
- mono: "var(--font-mono)"
211
- },
212
- sizes: {
213
- xs: baseTokens.fontSize.xs,
214
- // 12px — Fine print
215
- sm: baseTokens.fontSize.sm,
216
- // 14px — Secondary text
217
- base: baseTokens.fontSize.base,
218
- // 16px — Body text
219
- lg: baseTokens.fontSize.lg,
220
- // 18px — Lead paragraphs
221
- xl: baseTokens.fontSize.xl,
222
- // 20px — Section headers
223
- "2xl": baseTokens.fontSize["2xl"],
224
- // 24px — Page headers
225
- "3xl": baseTokens.fontSize["3xl"]
226
- // 30px — Hero text
227
- },
228
- weights: {
229
- normal: baseTokens.fontWeight.normal,
230
- // 400
231
- medium: baseTokens.fontWeight.medium,
232
- // 500
233
- semibold: baseTokens.fontWeight.semibold,
234
- // 600
235
- bold: baseTokens.fontWeight.bold
236
- // 700
237
- },
238
- leading: {
239
- tight: baseTokens.lineHeight.tight,
240
- // 1.25 — Headings
241
- normal: baseTokens.lineHeight.normal,
242
- // 1.5 — Body
243
- relaxed: baseTokens.lineHeight.relaxed
244
- // 1.625 — Spacious reading
245
- }
246
- };
247
- var motion = {
248
- duration: baseTokens.duration,
249
- easing: {
250
- default: baseTokens.ease.out,
251
- // Most transitions
252
- spring: "cubic-bezier(0.16, 1, 0.3, 1)",
253
- // Playful interactions
254
- linear: baseTokens.ease.linear
255
- // Progress indicators
256
- }
257
- };
258
-
259
40
  // ../tokens/src/studio.ts
260
41
  var studioTokens = {
261
42
  light: {
@@ -765,156 +546,203 @@ var voltTokens = {
765
546
  }
766
547
  };
767
548
 
768
- // ../tokens/src/typography.ts
769
- var fontSizes = {
770
- // Body text scale
771
- xs: { base: "0.75rem", mobile: "0.75rem" },
772
- // 12px
773
- sm: { base: "0.875rem", mobile: "0.875rem" },
774
- // 14px
775
- base: { base: "1rem", mobile: "1rem" },
776
- // 16px
777
- lg: { base: "1.125rem", mobile: "1rem" },
778
- // 18px / 16px mobile
779
- xl: { base: "1.25rem", mobile: "1.125rem" },
780
- // 20px / 18px mobile
781
- "2xl": { base: "1.5rem", mobile: "1.25rem" },
782
- // 24px / 20px mobile
783
- "3xl": { base: "1.875rem", mobile: "1.5rem" },
784
- // 30px / 24px mobile
785
- // Heading scale (h6 → h1)
786
- "4xl": { base: "2.25rem", mobile: "1.875rem" },
787
- // 36px / 30px - h3
788
- "5xl": { base: "3rem", mobile: "2.25rem" },
789
- // 48px / 36px - h2
790
- "6xl": { base: "3.75rem", mobile: "2.5rem" },
791
- // 60px / 40px - h1
792
- "7xl": { base: "4.5rem", mobile: "3rem" },
793
- // 72px / 48px - Display
794
- "8xl": { base: "6rem", mobile: "3.75rem" },
795
- // 96px / 60px - Hero
796
- "9xl": { base: "8rem", mobile: "4.5rem" }
797
- // 128px / 72px - Ultra
798
- };
799
- var fontWeights = {
800
- thin: "100",
801
- extralight: "200",
802
- light: "300",
803
- normal: "400",
804
- medium: "500",
805
- semibold: "600",
806
- bold: "700",
807
- extrabold: "800",
808
- black: "900"
809
- };
810
- var lineHeights = {
811
- none: "1",
812
- tight: "1.25",
813
- snug: "1.375",
814
- normal: "1.5",
815
- relaxed: "1.625",
816
- loose: "1.75",
817
- extraloose: "2"
818
- };
819
- var letterSpacing = {
820
- tighter: "-0.05em",
821
- tight: "-0.025em",
822
- normal: "0",
823
- wide: "0.025em",
824
- wider: "0.05em",
825
- widest: "0.1em"
826
- };
827
- var typePresets = {
828
- "display-large": {
829
- size: fontSizes["8xl"],
830
- weight: fontWeights.bold,
831
- lineHeight: lineHeights.none,
832
- letterSpacing: letterSpacing.tighter,
833
- description: "Large hero text, landing pages"
834
- },
835
- "display": {
836
- size: fontSizes["7xl"],
837
- weight: fontWeights.bold,
838
- lineHeight: lineHeights.tight,
839
- letterSpacing: letterSpacing.tight,
840
- description: "Hero sections, major headings"
841
- },
842
- "heading-1": {
843
- size: fontSizes["6xl"],
844
- weight: fontWeights.bold,
845
- lineHeight: lineHeights.tight,
846
- letterSpacing: letterSpacing.tight,
847
- description: "Page titles, h1"
848
- },
849
- "heading-2": {
850
- size: fontSizes["5xl"],
851
- weight: fontWeights.bold,
852
- lineHeight: lineHeights.tight,
853
- letterSpacing: letterSpacing.normal,
854
- description: "Section titles, h2"
855
- },
856
- "heading-3": {
857
- size: fontSizes["4xl"],
858
- weight: fontWeights.semibold,
859
- lineHeight: lineHeights.snug,
860
- letterSpacing: letterSpacing.normal,
861
- description: "Subsection titles, h3"
862
- },
863
- "heading-4": {
864
- size: fontSizes["2xl"],
865
- weight: fontWeights.semibold,
866
- lineHeight: lineHeights.snug,
867
- letterSpacing: letterSpacing.normal,
868
- description: "Component titles, h4"
869
- },
870
- "heading-5": {
871
- size: fontSizes.xl,
872
- weight: fontWeights.medium,
873
- lineHeight: lineHeights.normal,
874
- letterSpacing: letterSpacing.normal,
875
- description: "Small headings, h5"
876
- },
877
- "heading-6": {
878
- size: fontSizes.lg,
879
- weight: fontWeights.medium,
880
- lineHeight: lineHeights.normal,
881
- letterSpacing: letterSpacing.normal,
882
- description: "Tiny headings, h6"
883
- },
884
- "body-large": {
885
- size: fontSizes.lg,
886
- weight: fontWeights.normal,
887
- lineHeight: lineHeights.relaxed,
888
- letterSpacing: letterSpacing.normal,
889
- description: "Lead paragraphs, intro text"
890
- },
891
- "body": {
892
- size: fontSizes.base,
893
- weight: fontWeights.normal,
894
- lineHeight: lineHeights.normal,
895
- letterSpacing: letterSpacing.normal,
896
- description: "Default body text"
549
+ // ../tokens/src/speedboat.ts
550
+ var speedboatTokens = {
551
+ light: {
552
+ colors: {
553
+ // Backgrounds
554
+ background: "#FFFFFF",
555
+ backgroundSecondary: "#F8F8F8",
556
+ // grey50
557
+ backgroundTertiary: "#ECECEC",
558
+ // grey100
559
+ // Foregrounds
560
+ foreground: "#212121",
561
+ // grey900 ContentPrimary
562
+ foregroundSecondary: "#5D5D5D",
563
+ // grey700 ContentSecondary
564
+ foregroundTertiary: "#8891A7",
565
+ // grey500 muted icons
566
+ // Brand
567
+ primary: "#346BEA",
568
+ // accent blue
569
+ primaryForeground: "#FFFFFF",
570
+ secondary: "#EBF0FD",
571
+ // blue100 chip bg
572
+ secondaryForeground: "#1E49AA",
573
+ // blue600 chip text
574
+ accent: "#346BEA",
575
+ // same as primary for Speedboat
576
+ accentForeground: "#FFFFFF",
577
+ // Borders
578
+ border: "#ECECEC",
579
+ // grey100 — BorderPrimary
580
+ borderSubtle: "#F8F8F8",
581
+ // grey50
582
+ // States
583
+ hover: "#F8F8F8",
584
+ // grey50
585
+ active: "#ECECEC",
586
+ // grey100
587
+ // Link hover states
588
+ linkHover: "#1E49AA",
589
+ // blue600
590
+ linkHoverForeground: "#FFFFFF",
591
+ // Semantic
592
+ success: "#2E7D32",
593
+ successForeground: "#FFFFFF",
594
+ warning: "#E65100",
595
+ warningForeground: "#FFFFFF",
596
+ error: "#C62828",
597
+ errorForeground: "#FFFFFF",
598
+ info: "#346BEA",
599
+ infoForeground: "#FFFFFF",
600
+ // Component-specific colors
601
+ card: "#FFFFFF",
602
+ cardForeground: "#212121",
603
+ popover: "#FFFFFF",
604
+ popoverForeground: "#212121",
605
+ muted: "#F8F8F8",
606
+ // grey50
607
+ mutedForeground: "#8891A7",
608
+ // grey500
609
+ destructive: "#C62828",
610
+ // error red
611
+ destructiveForeground: "#FFFFFF",
612
+ input: "#DFDFDF",
613
+ // grey200 — input borders
614
+ ring: "#346BEA",
615
+ // accent blue for focus rings
616
+ // Surface
617
+ surface: "#F8F8F8",
618
+ // grey50
619
+ // Glass effects
620
+ glass: "rgba(255, 255, 255, 0.85)",
621
+ glassBorder: "rgba(0, 0, 0, 0.08)"
622
+ },
623
+ effects: {
624
+ blur: {
625
+ sm: "blur(4px)",
626
+ md: "blur(8px)",
627
+ lg: "blur(16px)",
628
+ xl: "blur(24px)"
629
+ },
630
+ shadow: {
631
+ sm: "0 1px 2px rgba(0, 0, 0, 0.05)",
632
+ md: "0 2px 8px rgba(0, 0, 0, 0.08)",
633
+ lg: "0 4px 16px rgba(0, 0, 0, 0.10)",
634
+ xl: "0 8px 24px rgba(0, 0, 0, 0.12)",
635
+ "2xl": "0 16px 48px rgba(0, 0, 0, 0.16)"
636
+ }
637
+ }
897
638
  },
898
- "body-small": {
899
- size: fontSizes.sm,
900
- weight: fontWeights.normal,
901
- lineHeight: lineHeights.normal,
902
- letterSpacing: letterSpacing.normal,
903
- description: "Small body text, fine print"
639
+ dark: {
640
+ colors: {
641
+ // Backgrounds — derived dark palette
642
+ background: "#0F1117",
643
+ backgroundSecondary: "#1A1C25",
644
+ backgroundTertiary: "#252833",
645
+ // Foregrounds
646
+ foreground: "#F0F0F2",
647
+ foregroundSecondary: "#A0A3B1",
648
+ foregroundTertiary: "#6B6F80",
649
+ // Brand — keep the accent blue, slightly brighten for dark bg
650
+ primary: "#4A7FF7",
651
+ primaryForeground: "#FFFFFF",
652
+ secondary: "#1E2540",
653
+ secondaryForeground: "#A6C1FF",
654
+ // blue300
655
+ accent: "#4A7FF7",
656
+ accentForeground: "#FFFFFF",
657
+ // Borders
658
+ border: "#2E3140",
659
+ borderSubtle: "#1A1C25",
660
+ // States
661
+ hover: "#1A1C25",
662
+ active: "#252833",
663
+ // Link hover states
664
+ linkHover: "#A6C1FF",
665
+ // blue300 — lighter for dark mode
666
+ linkHoverForeground: "#0F1117",
667
+ // Semantic — slightly brighter versions for dark bg
668
+ success: "#4CAF50",
669
+ successForeground: "#FFFFFF",
670
+ warning: "#FF8A50",
671
+ warningForeground: "#FFFFFF",
672
+ error: "#EF5350",
673
+ errorForeground: "#FFFFFF",
674
+ info: "#4A7FF7",
675
+ infoForeground: "#FFFFFF",
676
+ // Component-specific colors
677
+ card: "#1A1C25",
678
+ cardForeground: "#F0F0F2",
679
+ popover: "#1A1C25",
680
+ popoverForeground: "#F0F0F2",
681
+ muted: "#252833",
682
+ mutedForeground: "#6B6F80",
683
+ destructive: "#EF5350",
684
+ destructiveForeground: "#FFFFFF",
685
+ input: "#2E3140",
686
+ ring: "#4A7FF7",
687
+ // Surface
688
+ surface: "#1A1C25",
689
+ // Glass effects
690
+ glass: "rgba(15, 17, 23, 0.85)",
691
+ glassBorder: "rgba(255, 255, 255, 0.08)"
692
+ },
693
+ effects: {
694
+ blur: {
695
+ sm: "blur(4px)",
696
+ md: "blur(8px)",
697
+ lg: "blur(16px)",
698
+ xl: "blur(24px)"
699
+ },
700
+ shadow: {
701
+ sm: "0 1px 2px rgba(0, 0, 0, 0.20)",
702
+ md: "0 2px 8px rgba(0, 0, 0, 0.30)",
703
+ lg: "0 4px 16px rgba(0, 0, 0, 0.35)",
704
+ xl: "0 8px 24px rgba(0, 0, 0, 0.40)",
705
+ "2xl": "0 16px 48px rgba(0, 0, 0, 0.50)"
706
+ }
707
+ }
904
708
  },
905
- "caption": {
906
- size: fontSizes.xs,
907
- weight: fontWeights.normal,
908
- lineHeight: lineHeights.snug,
909
- letterSpacing: letterSpacing.wide,
910
- description: "Captions, labels, metadata"
709
+ /**
710
+ * Motion personality for Speedboat theme
711
+ * Professional and snappy — slightly faster than Studio
712
+ */
713
+ motion: {
714
+ getDuration: (intensity) => {
715
+ if (intensity === 0) return "0ms";
716
+ const ms = 120 + (intensity - 1) * 35;
717
+ return `${ms}ms`;
718
+ },
719
+ ease: {
720
+ default: "cubic-bezier(0.4, 0, 0.2, 1)",
721
+ in: "cubic-bezier(0.4, 0, 1, 1)",
722
+ out: "cubic-bezier(0, 0, 0.2, 1)",
723
+ spring: "cubic-bezier(0.16, 1, 0.3, 1)"
724
+ }
911
725
  },
912
- "overline": {
913
- size: fontSizes.xs,
914
- weight: fontWeights.semibold,
915
- lineHeight: lineHeights.normal,
916
- letterSpacing: letterSpacing.widest,
917
- description: "Eyebrows, categories, all-caps labels"
726
+ /**
727
+ * Typography for Speedboat theme
728
+ * Montserrat headings + Roboto body — Moloco brand fonts
729
+ */
730
+ typography: {
731
+ heading: {
732
+ fontFamily: "var(--font-montserrat)",
733
+ fontWeight: "700",
734
+ letterSpacing: "-0.01em"
735
+ },
736
+ body: {
737
+ fontFamily: "var(--font-roboto)",
738
+ fontWeight: "400",
739
+ letterSpacing: "0"
740
+ },
741
+ mono: {
742
+ fontFamily: "var(--font-geist-mono)",
743
+ fontWeight: "400",
744
+ letterSpacing: "0"
745
+ }
918
746
  }
919
747
  };
920
748
 
@@ -1735,7 +1563,8 @@ import { Fragment, jsx } from "react/jsx-runtime";
1735
1563
  var themeTokens = {
1736
1564
  studio: studioTokens,
1737
1565
  terra: terraTokens,
1738
- volt: voltTokens
1566
+ volt: voltTokens,
1567
+ speedboat: speedboatTokens
1739
1568
  };
1740
1569
  var fontFamilies = {
1741
1570
  studio: {
@@ -1751,6 +1580,11 @@ var fontFamilies = {
1751
1580
  volt: {
1752
1581
  sans: "var(--font-volt-heading)",
1753
1582
  mono: "var(--font-mono)"
1583
+ },
1584
+ speedboat: {
1585
+ heading: "var(--font-montserrat)",
1586
+ body: "var(--font-roboto)",
1587
+ mono: "var(--font-mono)"
1754
1588
  }
1755
1589
  };
1756
1590
  function getThemeVars(theme, mode) {
@@ -1795,6 +1629,16 @@ function getThemeVars(theme, mode) {
1795
1629
  "--color-active": colors?.active || colors?.backgroundTertiary || "#f0f0f0",
1796
1630
  "--color-link-hover": colors?.linkHover || colors?.primary || "#0a0a0a",
1797
1631
  "--color-link-hover-foreground": colors?.linkHoverForeground || colors?.background || "#ffffff",
1632
+ // Component-specific (previously only set in globals.css defaults)
1633
+ "--color-card": colors?.card || colors?.background || "#ffffff",
1634
+ "--color-card-foreground": colors?.cardForeground || colors?.foreground || "#0a0a0a",
1635
+ "--color-popover": colors?.popover || colors?.background || "#ffffff",
1636
+ "--color-popover-foreground": colors?.popoverForeground || colors?.foreground || "#0a0a0a",
1637
+ "--color-muted": colors?.muted || colors?.backgroundSecondary || "#f5f5f5",
1638
+ "--color-muted-foreground": colors?.mutedForeground || colors?.foregroundTertiary || "#737373",
1639
+ "--color-destructive": colors?.destructive || colors?.error || "#ef4444",
1640
+ "--color-destructive-foreground": colors?.destructiveForeground || "#ffffff",
1641
+ "--color-input": colors?.input || colors?.border || "#d4d4d4",
1798
1642
  // Effects - Blur
1799
1643
  "--effect-blur-sm": effects?.blur?.sm || "blur(4px)",
1800
1644
  "--effect-blur-md": effects?.blur?.md || "blur(8px)",
@@ -1833,9 +1677,9 @@ function getThemeVars(theme, mode) {
1833
1677
  "--code-border": mode === "light" ? codeColors.light.border : codeColors.dark.border
1834
1678
  };
1835
1679
  }
1836
- function mergeCustomColorTokens(baseTokens2, customPalette) {
1680
+ function mergeCustomColorTokens(baseTokens, customPalette) {
1837
1681
  return {
1838
- ...baseTokens2,
1682
+ ...baseTokens,
1839
1683
  // Override primary color
1840
1684
  "--color-primary": customPalette.primary,
1841
1685
  "--color-primary-foreground": customPalette.primaryForeground,
@@ -1853,12 +1697,12 @@ function mergeCustomColorTokens(baseTokens2, customPalette) {
1853
1697
  // Override secondary color if provided (advanced mode)
1854
1698
  ...customPalette.secondary && {
1855
1699
  "--color-secondary": customPalette.secondary,
1856
- "--color-secondary-foreground": customPalette.secondaryForeground || baseTokens2["--color-secondary-foreground"]
1700
+ "--color-secondary-foreground": customPalette.secondaryForeground || baseTokens["--color-secondary-foreground"]
1857
1701
  },
1858
1702
  // Override accent color if provided (advanced mode)
1859
1703
  ...customPalette.accent && {
1860
1704
  "--color-accent": customPalette.accent,
1861
- "--color-accent-foreground": customPalette.accentForeground || baseTokens2["--color-accent-foreground"]
1705
+ "--color-accent-foreground": customPalette.accentForeground || baseTokens["--color-accent-foreground"]
1862
1706
  },
1863
1707
  // Apply ALL derived tokens from dependency graph
1864
1708
  // This automatically updates:
@@ -1912,11 +1756,18 @@ function validateThemeTokens(theme, mode) {
1912
1756
  console.log(`[ThemeProvider] \u2713 Theme validation passed for "${theme}" (${mode} mode)`);
1913
1757
  }
1914
1758
  }
1915
- function ThemeProvider({ children }) {
1916
- const { theme, mode } = useThemeStore();
1759
+ function ThemeProvider({ children, defaultTheme, defaultMode }) {
1760
+ const { theme, mode, setTheme, setMode } = useThemeStore();
1917
1761
  const customPalette = useCustomizer((state) => state.customColors?.[theme]?.[mode]);
1918
1762
  const [isTransitioning, setIsTransitioning] = useState(false);
1919
1763
  const [mounted, setMounted] = useState(false);
1764
+ useEffect(() => {
1765
+ if (!defaultTheme && !defaultMode) return;
1766
+ const persisted = typeof window !== "undefined" && localStorage.getItem("ecosystem-theme");
1767
+ if (persisted) return;
1768
+ if (defaultTheme) setTheme(defaultTheme);
1769
+ if (defaultMode) setMode(defaultMode);
1770
+ }, []);
1920
1771
  useEffect(() => {
1921
1772
  setMounted(true);
1922
1773
  }, []);
@@ -1924,7 +1775,7 @@ function ThemeProvider({ children }) {
1924
1775
  if (!mounted) return;
1925
1776
  setIsTransitioning(true);
1926
1777
  const root = document.documentElement;
1927
- const baseTokens2 = getThemeVars(theme, mode);
1778
+ const baseTokens = getThemeVars(theme, mode);
1928
1779
  console.log("[ThemeProvider] Update:", {
1929
1780
  theme,
1930
1781
  mode,
@@ -1932,7 +1783,7 @@ function ThemeProvider({ children }) {
1932
1783
  customPrimary: customPalette?.primary,
1933
1784
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
1934
1785
  });
1935
- const finalTokens = customPalette ? mergeCustomColorTokens(baseTokens2, customPalette) : baseTokens2;
1786
+ const finalTokens = customPalette ? mergeCustomColorTokens(baseTokens, customPalette) : baseTokens;
1936
1787
  root.classList.add("theme-transitioning");
1937
1788
  Object.entries(finalTokens).forEach(([key, value]) => {
1938
1789
  root.style.setProperty(key, value);