@opencosmos/ui 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 (260) hide show
  1. package/.claude/CLAUDE.md +239 -0
  2. package/README.md +161 -0
  3. package/dist/cli.mjs +151 -0
  4. package/dist/dates.d.mts +20 -0
  5. package/dist/dates.d.ts +20 -0
  6. package/dist/dates.js +240 -0
  7. package/dist/dates.js.map +1 -0
  8. package/dist/dates.mjs +203 -0
  9. package/dist/dates.mjs.map +1 -0
  10. package/dist/dnd.d.mts +126 -0
  11. package/dist/dnd.d.ts +126 -0
  12. package/dist/dnd.js +274 -0
  13. package/dist/dnd.js.map +1 -0
  14. package/dist/dnd.mjs +250 -0
  15. package/dist/dnd.mjs.map +1 -0
  16. package/dist/fontThemes-Dh8mtXES.d.mts +868 -0
  17. package/dist/fontThemes-Dh8mtXES.d.ts +868 -0
  18. package/dist/forms.d.mts +38 -0
  19. package/dist/forms.d.ts +38 -0
  20. package/dist/forms.js +198 -0
  21. package/dist/forms.js.map +1 -0
  22. package/dist/forms.mjs +159 -0
  23. package/dist/forms.mjs.map +1 -0
  24. package/dist/hooks-1b8WaQf1.d.mts +225 -0
  25. package/dist/hooks-CKW8vE9H.d.ts +225 -0
  26. package/dist/hooks.d.mts +3 -0
  27. package/dist/hooks.d.ts +3 -0
  28. package/dist/hooks.js +971 -0
  29. package/dist/hooks.js.map +1 -0
  30. package/dist/hooks.mjs +943 -0
  31. package/dist/hooks.mjs.map +1 -0
  32. package/dist/index-DscTIrZ2.d.mts +29 -0
  33. package/dist/index-DscTIrZ2.d.ts +29 -0
  34. package/dist/index.d.mts +3382 -0
  35. package/dist/index.d.ts +3382 -0
  36. package/dist/index.js +15146 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/index.mjs +14802 -0
  39. package/dist/index.mjs.map +1 -0
  40. package/dist/providers-CXPDMsl7.d.mts +30 -0
  41. package/dist/providers-Dn_Msjvz.d.ts +30 -0
  42. package/dist/providers.d.mts +3 -0
  43. package/dist/providers.d.ts +3 -0
  44. package/dist/providers.js +1885 -0
  45. package/dist/providers.js.map +1 -0
  46. package/dist/providers.mjs +1859 -0
  47. package/dist/providers.mjs.map +1 -0
  48. package/dist/tables.d.mts +10 -0
  49. package/dist/tables.d.ts +10 -0
  50. package/dist/tables.js +248 -0
  51. package/dist/tables.js.map +1 -0
  52. package/dist/tables.mjs +218 -0
  53. package/dist/tables.mjs.map +1 -0
  54. package/dist/tokens.d.mts +1065 -0
  55. package/dist/tokens.d.ts +1065 -0
  56. package/dist/tokens.js +2637 -0
  57. package/dist/tokens.js.map +1 -0
  58. package/dist/tokens.mjs +2555 -0
  59. package/dist/tokens.mjs.map +1 -0
  60. package/dist/utils-CIIM7dAC.d.ts +986 -0
  61. package/dist/utils-Cs04sxth.d.mts +986 -0
  62. package/dist/utils.d.mts +4 -0
  63. package/dist/utils.d.ts +4 -0
  64. package/dist/utils.js +874 -0
  65. package/dist/utils.js.map +1 -0
  66. package/dist/utils.mjs +806 -0
  67. package/dist/utils.mjs.map +1 -0
  68. package/dist/validation-Bj1ye-v_.d.mts +114 -0
  69. package/dist/validation-Bj1ye-v_.d.ts +114 -0
  70. package/dist/webgl.d.mts +104 -0
  71. package/dist/webgl.d.ts +104 -0
  72. package/dist/webgl.js +226 -0
  73. package/dist/webgl.js.map +1 -0
  74. package/dist/webgl.mjs +195 -0
  75. package/dist/webgl.mjs.map +1 -0
  76. package/package.json +267 -0
  77. package/src/cli.ts +206 -0
  78. package/src/component-registry.ts +183 -0
  79. package/src/components/actions/Button.test.tsx +61 -0
  80. package/src/components/actions/Button.tsx +70 -0
  81. package/src/components/actions/Link.tsx +78 -0
  82. package/src/components/actions/Magnetic.tsx +68 -0
  83. package/src/components/actions/Toggle.test.tsx +40 -0
  84. package/src/components/actions/Toggle.tsx +47 -0
  85. package/src/components/actions/ToggleGroup.tsx +70 -0
  86. package/src/components/actions/index.ts +5 -0
  87. package/src/components/backgrounds/FaultyTerminal.tsx +426 -0
  88. package/src/components/backgrounds/OrbBackground.tsx +424 -0
  89. package/src/components/backgrounds/WarpBackground.tsx +358 -0
  90. package/src/components/backgrounds/index.ts +3 -0
  91. package/src/components/blocks/Hero.tsx +142 -0
  92. package/src/components/blocks/social/OpenGraphCard.tsx +243 -0
  93. package/src/components/cursor/SplashCursor.tsx +1315 -0
  94. package/src/components/cursor/TargetCursor.tsx +187 -0
  95. package/src/components/cursor/index.ts +2 -0
  96. package/src/components/data-display/AspectImage.tsx +73 -0
  97. package/src/components/data-display/Avatar.test.tsx +35 -0
  98. package/src/components/data-display/Avatar.tsx +55 -0
  99. package/src/components/data-display/Badge.test.tsx +43 -0
  100. package/src/components/data-display/Badge.tsx +84 -0
  101. package/src/components/data-display/Brand.tsx +123 -0
  102. package/src/components/data-display/Calendar.tsx +70 -0
  103. package/src/components/data-display/Card.test.tsx +92 -0
  104. package/src/components/data-display/Card.tsx +115 -0
  105. package/src/components/data-display/Code.tsx +210 -0
  106. package/src/components/data-display/CollapsibleCodeBlock.tsx +238 -0
  107. package/src/components/data-display/DataTable.tsx +119 -0
  108. package/src/components/data-display/DescriptionList.tsx +41 -0
  109. package/src/components/data-display/GitHubIcon.tsx +44 -0
  110. package/src/components/data-display/Heading.test.tsx +36 -0
  111. package/src/components/data-display/Heading.tsx +83 -0
  112. package/src/components/data-display/StatCard.tsx +195 -0
  113. package/src/components/data-display/Table.tsx +133 -0
  114. package/src/components/data-display/Text.test.tsx +48 -0
  115. package/src/components/data-display/Text.tsx +144 -0
  116. package/src/components/data-display/Timeline.tsx +194 -0
  117. package/src/components/data-display/TreeView.tsx +226 -0
  118. package/src/components/data-display/Typewriter.tsx +119 -0
  119. package/src/components/data-display/VariableWeightText.tsx +130 -0
  120. package/src/components/data-display/index.ts +19 -0
  121. package/src/components/feedback/Alert.test.tsx +44 -0
  122. package/src/components/feedback/Alert.tsx +65 -0
  123. package/src/components/feedback/EmptyState.tsx +113 -0
  124. package/src/components/feedback/Progress.test.tsx +60 -0
  125. package/src/components/feedback/Progress.tsx +30 -0
  126. package/src/components/feedback/ProgressBar.tsx +158 -0
  127. package/src/components/feedback/Skeleton.test.tsx +39 -0
  128. package/src/components/feedback/Skeleton.tsx +45 -0
  129. package/src/components/feedback/Sonner.tsx +28 -0
  130. package/src/components/feedback/Spinner.test.tsx +33 -0
  131. package/src/components/feedback/Spinner.tsx +99 -0
  132. package/src/components/feedback/Stepper.tsx +307 -0
  133. package/src/components/feedback/Toast/Toast.tsx +243 -0
  134. package/src/components/feedback/Toast/index.ts +2 -0
  135. package/src/components/feedback/index.ts +9 -0
  136. package/src/components/forms/Checkbox.test.tsx +40 -0
  137. package/src/components/forms/Checkbox.tsx +31 -0
  138. package/src/components/forms/ColorPicker.tsx +118 -0
  139. package/src/components/forms/Combobox.tsx +96 -0
  140. package/src/components/forms/DragDrop.tsx +440 -0
  141. package/src/components/forms/FileUpload.tsx +252 -0
  142. package/src/components/forms/FilterButton.tsx +65 -0
  143. package/src/components/forms/Form.tsx +197 -0
  144. package/src/components/forms/Input.test.tsx +46 -0
  145. package/src/components/forms/Input.tsx +43 -0
  146. package/src/components/forms/InputOTP.tsx +81 -0
  147. package/src/components/forms/Label.test.tsx +20 -0
  148. package/src/components/forms/Label.tsx +25 -0
  149. package/src/components/forms/RadioGroup.tsx +51 -0
  150. package/src/components/forms/SearchBar.tsx +215 -0
  151. package/src/components/forms/Select.test.tsx +118 -0
  152. package/src/components/forms/Select.tsx +274 -0
  153. package/src/components/forms/Slider.tsx +29 -0
  154. package/src/components/forms/Switch.test.tsx +76 -0
  155. package/src/components/forms/Switch.tsx +30 -0
  156. package/src/components/forms/TextField.tsx +152 -0
  157. package/src/components/forms/Textarea.test.tsx +41 -0
  158. package/src/components/forms/Textarea.tsx +29 -0
  159. package/src/components/forms/ThemeSwitcher.tsx +290 -0
  160. package/src/components/forms/ThemeToggle.tsx +151 -0
  161. package/src/components/forms/index.ts +19 -0
  162. package/src/components/layout/Accordion.test.tsx +66 -0
  163. package/src/components/layout/Accordion.tsx +64 -0
  164. package/src/components/layout/AspectRatio.tsx +7 -0
  165. package/src/components/layout/Carousel.tsx +277 -0
  166. package/src/components/layout/Collapsible.test.tsx +40 -0
  167. package/src/components/layout/Collapsible.tsx +31 -0
  168. package/src/components/layout/Container.test.tsx +45 -0
  169. package/src/components/layout/Container.tsx +99 -0
  170. package/src/components/layout/CustomizerPanel.tsx +400 -0
  171. package/src/components/layout/DatePicker.tsx +57 -0
  172. package/src/components/layout/Footer/Footer.tsx +175 -0
  173. package/src/components/layout/Footer/index.ts +2 -0
  174. package/src/components/layout/GlassSurface.tsx +82 -0
  175. package/src/components/layout/Grid.test.tsx +31 -0
  176. package/src/components/layout/Grid.tsx +130 -0
  177. package/src/components/layout/Header/Header.tsx +450 -0
  178. package/src/components/layout/Header/index.ts +2 -0
  179. package/src/components/layout/PageLayout.tsx +180 -0
  180. package/src/components/layout/PageTemplate.tsx +158 -0
  181. package/src/components/layout/Resizable.tsx +48 -0
  182. package/src/components/layout/ScrollArea.tsx +53 -0
  183. package/src/components/layout/Separator.test.tsx +28 -0
  184. package/src/components/layout/Separator.tsx +29 -0
  185. package/src/components/layout/Sidebar.tsx +171 -0
  186. package/src/components/layout/Stack.test.tsx +41 -0
  187. package/src/components/layout/Stack.tsx +89 -0
  188. package/src/components/layout/glass-surface.css +60 -0
  189. package/src/components/layout/index.ts +18 -0
  190. package/src/components/motion/AnimatedBeam.tsx +159 -0
  191. package/src/components/navigation/Breadcrumb.test.tsx +57 -0
  192. package/src/components/navigation/Breadcrumb.tsx +119 -0
  193. package/src/components/navigation/Breadcrumbs.tsx +221 -0
  194. package/src/components/navigation/Command.tsx +159 -0
  195. package/src/components/navigation/Menubar.tsx +115 -0
  196. package/src/components/navigation/NavLink.tsx +55 -0
  197. package/src/components/navigation/NavigationMenu.tsx +125 -0
  198. package/src/components/navigation/Pagination.tsx +121 -0
  199. package/src/components/navigation/SecondaryNav.tsx +100 -0
  200. package/src/components/navigation/Tabs.test.tsx +47 -0
  201. package/src/components/navigation/Tabs.tsx +60 -0
  202. package/src/components/navigation/TertiaryNav.tsx +90 -0
  203. package/src/components/navigation/index.ts +10 -0
  204. package/src/components/overlays/AlertDialog.test.tsx +69 -0
  205. package/src/components/overlays/AlertDialog.tsx +166 -0
  206. package/src/components/overlays/ContextMenu.tsx +243 -0
  207. package/src/components/overlays/Dialog.test.tsx +79 -0
  208. package/src/components/overlays/Dialog.tsx +158 -0
  209. package/src/components/overlays/Drawer.tsx +128 -0
  210. package/src/components/overlays/Dropdown.tsx +253 -0
  211. package/src/components/overlays/DropdownMenu.tsx +242 -0
  212. package/src/components/overlays/HoverCard.tsx +32 -0
  213. package/src/components/overlays/Modal.tsx +250 -0
  214. package/src/components/overlays/NotificationCenter.tsx +364 -0
  215. package/src/components/overlays/Popover.test.tsx +40 -0
  216. package/src/components/overlays/Popover.tsx +46 -0
  217. package/src/components/overlays/Sheet.tsx +163 -0
  218. package/src/components/overlays/Tooltip.test.tsx +33 -0
  219. package/src/components/overlays/Tooltip.tsx +32 -0
  220. package/src/components/overlays/index.ts +12 -0
  221. package/src/dates.ts +2 -0
  222. package/src/dnd.ts +1 -0
  223. package/src/forms.ts +1 -0
  224. package/src/globals.css +187 -0
  225. package/src/hooks/index.ts +6 -0
  226. package/src/hooks/useForm.ts +247 -0
  227. package/src/hooks/useMotionPreference.test.ts +102 -0
  228. package/src/hooks/useMotionPreference.ts +78 -0
  229. package/src/hooks/useTheme.ts +58 -0
  230. package/src/hooks.ts +9 -0
  231. package/src/index.ts +168 -0
  232. package/src/lib/animations.ts +356 -0
  233. package/src/lib/breadcrumbs.ts +94 -0
  234. package/src/lib/colors.ts +493 -0
  235. package/src/lib/store/customizer.ts +482 -0
  236. package/src/lib/store/index.ts +3 -0
  237. package/src/lib/store/theme.ts +55 -0
  238. package/src/lib/syntax-parser/index.ts +50 -0
  239. package/src/lib/syntax-parser/patterns.ts +64 -0
  240. package/src/lib/syntax-parser/tokenizer.ts +117 -0
  241. package/src/lib/syntax-parser/types.ts +27 -0
  242. package/src/lib/utils.ts +6 -0
  243. package/src/lib/validation.ts +204 -0
  244. package/src/lib/webgl/Color.ts +11 -0
  245. package/src/lib/webgl/Mesh.ts +41 -0
  246. package/src/lib/webgl/Program.ts +118 -0
  247. package/src/lib/webgl/Renderer.ts +51 -0
  248. package/src/lib/webgl/Triangle.ts +27 -0
  249. package/src/lib/webgl/Vec3.ts +18 -0
  250. package/src/lib/webgl/index.ts +13 -0
  251. package/src/nativewind-env.d.ts +1 -0
  252. package/src/providers/ThemeProvider.tsx +461 -0
  253. package/src/providers/index.ts +1 -0
  254. package/src/providers.ts +7 -0
  255. package/src/tables.ts +1 -0
  256. package/src/test/setup.ts +39 -0
  257. package/src/theme.css +158 -0
  258. package/src/tokens.ts +7 -0
  259. package/src/utils.ts +12 -0
  260. package/src/webgl.ts +1 -0
package/dist/tokens.js ADDED
@@ -0,0 +1,2637 @@
1
+ "use client";
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/tokens.ts
22
+ var tokens_exports = {};
23
+ __export(tokens_exports, {
24
+ COLOR_MODES: () => COLOR_MODES,
25
+ PUBLIC_THEME_NAMES: () => PUBLIC_THEME_NAMES,
26
+ THEME_NAMES: () => THEME_NAMES,
27
+ accentColorDerivations: () => accentColorDerivations,
28
+ adjustLightness: () => adjustLightness,
29
+ adjustOpacity: () => adjustOpacity,
30
+ adjustSaturation: () => adjustSaturation,
31
+ baseTokens: () => baseTokens,
32
+ codeColors: () => codeColors,
33
+ colorPalettes: () => colorPalettes,
34
+ computeDerivedTokens: () => computeDerivedTokens,
35
+ fontFamilies: () => fontFamilies,
36
+ fontLoadingConfig: () => fontLoadingConfig,
37
+ fontSizes: () => fontSizes,
38
+ fontThemes: () => fontThemes,
39
+ fontWeights: () => fontWeights,
40
+ generateScale: () => generateScale,
41
+ getAccessibleFontThemes: () => getAccessibleFontThemes,
42
+ getAccessiblePalettes: () => getAccessiblePalettes,
43
+ getContrastRatio: () => getContrastRatio,
44
+ getDependentTokens: () => getDependentTokens,
45
+ getFontThemeById: () => getFontThemeById,
46
+ getFontThemesByCategory: () => getFontThemesByCategory,
47
+ getFontThemesByMood: () => getFontThemesByMood,
48
+ getFontThemesForUseCase: () => getFontThemesForUseCase,
49
+ getFontVariable: () => getFontVariable,
50
+ getLuminance: () => getLuminance,
51
+ getOptimalForeground: () => getOptimalForeground,
52
+ getPalettesByCategory: () => getPalettesByCategory,
53
+ getPalettesByMood: () => getPalettesByMood,
54
+ getPalettesForUseCase: () => getPalettesForUseCase,
55
+ getResponsiveFontSize: () => getResponsiveFontSize,
56
+ getThemeFontVariables: () => getThemeFontVariables,
57
+ hexToHSL: () => hexToHSL,
58
+ hexToRgb: () => hexToRgb,
59
+ hslToHex: () => hslToHex,
60
+ letterSpacing: () => letterSpacing,
61
+ lineHeights: () => lineHeights,
62
+ modeSpecificDerivations: () => modeSpecificDerivations,
63
+ motion: () => motion,
64
+ primaryColorDerivations: () => primaryColorDerivations,
65
+ rotateHue: () => rotateHue,
66
+ secondaryColorDerivations: () => secondaryColorDerivations,
67
+ semanticLetterSpacing: () => semanticLetterSpacing,
68
+ semanticLineHeights: () => semanticLineHeights,
69
+ semanticSizes: () => semanticSizes,
70
+ semanticWeights: () => semanticWeights,
71
+ spacing: () => spacing,
72
+ speedboatTokens: () => speedboatTokens,
73
+ studioTokens: () => studioTokens,
74
+ syntaxColors: () => syntaxColors,
75
+ terraTokens: () => terraTokens,
76
+ tokenDependencyGraph: () => tokenDependencyGraph,
77
+ typePresets: () => typePresets,
78
+ typography: () => typography,
79
+ typographySystem: () => typographySystem,
80
+ voltTokens: () => voltTokens
81
+ });
82
+ module.exports = __toCommonJS(tokens_exports);
83
+
84
+ // ../tokens/src/base.ts
85
+ var baseTokens = {
86
+ /**
87
+ * Spacing scale (based on 4px grid)
88
+ */
89
+ spacing: {
90
+ "0": "0",
91
+ "0.5": "0.125rem",
92
+ // 2px
93
+ "1": "0.25rem",
94
+ // 4px
95
+ "2": "0.5rem",
96
+ // 8px
97
+ "3": "0.75rem",
98
+ // 12px
99
+ "4": "1rem",
100
+ // 16px
101
+ "5": "1.25rem",
102
+ // 20px
103
+ "6": "1.5rem",
104
+ // 24px
105
+ "8": "2rem",
106
+ // 32px
107
+ "10": "2.5rem",
108
+ // 40px
109
+ "12": "3rem",
110
+ // 48px
111
+ "16": "4rem",
112
+ // 64px
113
+ "20": "5rem",
114
+ // 80px
115
+ "24": "6rem",
116
+ // 96px
117
+ "32": "8rem"
118
+ // 128px
119
+ },
120
+ /**
121
+ * Typography scales
122
+ */
123
+ fontSize: {
124
+ "xs": "0.75rem",
125
+ // 12px
126
+ "sm": "0.875rem",
127
+ // 14px
128
+ "base": "1rem",
129
+ // 16px
130
+ "lg": "1.125rem",
131
+ // 18px
132
+ "xl": "1.25rem",
133
+ // 20px
134
+ "2xl": "1.5rem",
135
+ // 24px
136
+ "3xl": "1.875rem",
137
+ // 30px
138
+ "4xl": "2.25rem",
139
+ // 36px
140
+ "5xl": "3rem",
141
+ // 48px
142
+ "6xl": "3.75rem",
143
+ // 60px
144
+ "7xl": "4.5rem",
145
+ // 72px
146
+ "8xl": "6rem"
147
+ // 96px
148
+ },
149
+ fontWeight: {
150
+ light: "300",
151
+ normal: "400",
152
+ medium: "500",
153
+ semibold: "600",
154
+ bold: "700",
155
+ extrabold: "800",
156
+ black: "900"
157
+ },
158
+ lineHeight: {
159
+ none: "1",
160
+ tight: "1.25",
161
+ snug: "1.375",
162
+ normal: "1.5",
163
+ relaxed: "1.625",
164
+ loose: "2"
165
+ },
166
+ /**
167
+ * Border radius
168
+ */
169
+ borderRadius: {
170
+ none: "0",
171
+ sm: "0.125rem",
172
+ // 2px
173
+ DEFAULT: "0.25rem",
174
+ // 4px
175
+ md: "0.375rem",
176
+ // 6px
177
+ lg: "0.5rem",
178
+ // 8px
179
+ xl: "0.75rem",
180
+ // 12px
181
+ "2xl": "1rem",
182
+ // 16px
183
+ "3xl": "1.5rem",
184
+ // 24px
185
+ full: "9999px"
186
+ },
187
+ /**
188
+ * Motion durations (base values - themes can override)
189
+ */
190
+ duration: {
191
+ instant: "0ms",
192
+ fast: "150ms",
193
+ normal: "300ms",
194
+ slow: "500ms",
195
+ slower: "800ms"
196
+ },
197
+ /**
198
+ * Easing curves (base values - themes can override)
199
+ */
200
+ ease: {
201
+ linear: "linear",
202
+ in: "cubic-bezier(0.4, 0, 1, 1)",
203
+ out: "cubic-bezier(0, 0, 0.2, 1)",
204
+ inOut: "cubic-bezier(0.4, 0, 0.2, 1)"
205
+ },
206
+ /**
207
+ * Z-index scale
208
+ */
209
+ zIndex: {
210
+ "auto": "auto",
211
+ "0": "0",
212
+ "10": "10",
213
+ "20": "20",
214
+ "30": "30",
215
+ "40": "40",
216
+ "50": "50",
217
+ dropdown: "1000",
218
+ sticky: "1020",
219
+ fixed: "1030",
220
+ modalBackdrop: "1040",
221
+ modal: "1050",
222
+ popover: "1060",
223
+ tooltip: "1070"
224
+ },
225
+ /**
226
+ * Focus ring configuration
227
+ */
228
+ focus: {
229
+ width: "2px",
230
+ offset: "2px",
231
+ style: "solid"
232
+ }
233
+ };
234
+ var spacing = {
235
+ xs: baseTokens.spacing["1"],
236
+ // 4px — Tight internal padding
237
+ sm: baseTokens.spacing["2"],
238
+ // 8px — Default gap
239
+ md: baseTokens.spacing["4"],
240
+ // 16px — Section padding
241
+ lg: baseTokens.spacing["6"],
242
+ // 24px — Card padding
243
+ xl: baseTokens.spacing["8"],
244
+ // 32px — Section margins
245
+ "2xl": baseTokens.spacing["12"],
246
+ // 48px — Page sections
247
+ "3xl": baseTokens.spacing["16"]
248
+ // 64px — Major divisions
249
+ };
250
+ var typography = {
251
+ fonts: {
252
+ sans: "var(--font-body)",
253
+ serif: "var(--font-heading)",
254
+ mono: "var(--font-mono)"
255
+ },
256
+ sizes: {
257
+ xs: baseTokens.fontSize.xs,
258
+ // 12px — Fine print
259
+ sm: baseTokens.fontSize.sm,
260
+ // 14px — Secondary text
261
+ base: baseTokens.fontSize.base,
262
+ // 16px — Body text
263
+ lg: baseTokens.fontSize.lg,
264
+ // 18px — Lead paragraphs
265
+ xl: baseTokens.fontSize.xl,
266
+ // 20px — Section headers
267
+ "2xl": baseTokens.fontSize["2xl"],
268
+ // 24px — Page headers
269
+ "3xl": baseTokens.fontSize["3xl"]
270
+ // 30px — Hero text
271
+ },
272
+ weights: {
273
+ normal: baseTokens.fontWeight.normal,
274
+ // 400
275
+ medium: baseTokens.fontWeight.medium,
276
+ // 500
277
+ semibold: baseTokens.fontWeight.semibold,
278
+ // 600
279
+ bold: baseTokens.fontWeight.bold
280
+ // 700
281
+ },
282
+ leading: {
283
+ tight: baseTokens.lineHeight.tight,
284
+ // 1.25 — Headings
285
+ normal: baseTokens.lineHeight.normal,
286
+ // 1.5 — Body
287
+ relaxed: baseTokens.lineHeight.relaxed
288
+ // 1.625 — Spacious reading
289
+ }
290
+ };
291
+ var motion = {
292
+ duration: baseTokens.duration,
293
+ easing: {
294
+ default: baseTokens.ease.out,
295
+ // Most transitions
296
+ spring: "cubic-bezier(0.16, 1, 0.3, 1)",
297
+ // Playful interactions
298
+ linear: baseTokens.ease.linear
299
+ // Progress indicators
300
+ }
301
+ };
302
+
303
+ // ../tokens/src/studio.ts
304
+ var studioTokens = {
305
+ light: {
306
+ colors: {
307
+ // Backgrounds
308
+ background: "#ffffff",
309
+ backgroundSecondary: "#fafafa",
310
+ backgroundTertiary: "#f5f5f5",
311
+ // Foregrounds
312
+ foreground: "#0a0a0a",
313
+ foregroundSecondary: "#525252",
314
+ foregroundTertiary: "#a3a3a3",
315
+ // Brand
316
+ primary: "#0a0a0a",
317
+ primaryForeground: "#ffffff",
318
+ secondary: "#f5f5f5",
319
+ secondaryForeground: "#0a0a0a",
320
+ accent: "#0070f3",
321
+ accentForeground: "#ffffff",
322
+ // Borders
323
+ border: "#d4d4d4",
324
+ borderSubtle: "#f5f5f5",
325
+ // States
326
+ hover: "#fafafa",
327
+ active: "#f0f0f0",
328
+ // Link hover states
329
+ linkHover: "#0a0a0a",
330
+ linkHoverForeground: "#ffffff",
331
+ // Semantic
332
+ success: "#00a86b",
333
+ successForeground: "#ffffff",
334
+ warning: "#f59e0b",
335
+ warningForeground: "#ffffff",
336
+ error: "#ef4444",
337
+ errorForeground: "#ffffff",
338
+ info: "#0070f3",
339
+ infoForeground: "#ffffff",
340
+ // Component-specific colors
341
+ card: "#ffffff",
342
+ cardForeground: "#0a0a0a",
343
+ popover: "#ffffff",
344
+ popoverForeground: "#0a0a0a",
345
+ muted: "#f5f5f5",
346
+ mutedForeground: "#737373",
347
+ destructive: "#ef4444",
348
+ destructiveForeground: "#ffffff",
349
+ input: "#d4d4d4",
350
+ ring: "#0a0a0a",
351
+ // Surface is used by various components
352
+ surface: "#fafafa",
353
+ // Glass effects
354
+ glass: "rgba(255, 255, 255, 0.7)",
355
+ glassBorder: "rgba(0, 0, 0, 0.1)"
356
+ },
357
+ effects: {
358
+ blur: {
359
+ sm: "blur(4px)",
360
+ md: "blur(8px)",
361
+ lg: "blur(16px)",
362
+ xl: "blur(24px)"
363
+ },
364
+ shadow: {
365
+ sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
366
+ md: "0 4px 6px -1px rgba(0, 0, 0, 0.1)",
367
+ lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1)",
368
+ xl: "0 20px 25px -5px rgba(0, 0, 0, 0.1)",
369
+ "2xl": "0 25px 50px -12px rgba(0, 0, 0, 0.25)"
370
+ }
371
+ }
372
+ },
373
+ dark: {
374
+ colors: {
375
+ // Backgrounds
376
+ background: "#000000",
377
+ backgroundSecondary: "#171717",
378
+ backgroundTertiary: "#262626",
379
+ // Foregrounds
380
+ foreground: "#fafafa",
381
+ foregroundSecondary: "#a3a3a3",
382
+ foregroundTertiary: "#858585",
383
+ // Brand
384
+ primary: "#ffffff",
385
+ primaryForeground: "#0a0a0a",
386
+ secondary: "#262626",
387
+ secondaryForeground: "#fafafa",
388
+ accent: "#0090ff",
389
+ accentForeground: "#ffffff",
390
+ // Borders
391
+ border: "#404040",
392
+ borderSubtle: "#1a1a1a",
393
+ // States
394
+ hover: "#1a1a1a",
395
+ active: "#262626",
396
+ // Link hover states
397
+ linkHover: "#ffffff",
398
+ linkHoverForeground: "#0a0a0a",
399
+ // Semantic
400
+ success: "#10b981",
401
+ successForeground: "#ffffff",
402
+ warning: "#f59e0b",
403
+ warningForeground: "#ffffff",
404
+ error: "#ef4444",
405
+ errorForeground: "#ffffff",
406
+ info: "#0090ff",
407
+ infoForeground: "#ffffff",
408
+ // Component-specific colors
409
+ card: "#0a0a0a",
410
+ cardForeground: "#fafafa",
411
+ popover: "#0a0a0a",
412
+ popoverForeground: "#fafafa",
413
+ muted: "#262626",
414
+ mutedForeground: "#a3a3a3",
415
+ destructive: "#ef4444",
416
+ destructiveForeground: "#ffffff",
417
+ input: "#404040",
418
+ ring: "#d4d4d4",
419
+ // Surface is used by various components
420
+ surface: "#171717",
421
+ // Glass effects
422
+ glass: "rgba(0, 0, 0, 0.7)",
423
+ glassBorder: "rgba(255, 255, 255, 0.1)"
424
+ },
425
+ effects: {
426
+ blur: {
427
+ sm: "blur(4px)",
428
+ md: "blur(8px)",
429
+ lg: "blur(16px)",
430
+ xl: "blur(24px)"
431
+ },
432
+ shadow: {
433
+ sm: "0 1px 2px 0 rgba(0, 0, 0, 0.3)",
434
+ md: "0 4px 6px -1px rgba(0, 0, 0, 0.5)",
435
+ lg: "0 10px 15px -3px rgba(0, 0, 0, 0.6)",
436
+ xl: "0 20px 25px -5px rgba(0, 0, 0, 0.7)",
437
+ "2xl": "0 25px 50px -12px rgba(0, 0, 0, 0.8)"
438
+ }
439
+ }
440
+ },
441
+ /**
442
+ * Motion personality for Studio theme
443
+ */
444
+ motion: {
445
+ // Duration scales based on motion slider (0-10)
446
+ getDuration: (intensity) => {
447
+ if (intensity === 0) return "0ms";
448
+ const ms = 150 + (intensity - 1) * 40;
449
+ return `${ms}ms`;
450
+ },
451
+ // Easing curves - smooth and professional
452
+ ease: {
453
+ default: "cubic-bezier(0.4, 0, 0.2, 1)",
454
+ // ease-in-out
455
+ in: "cubic-bezier(0.4, 0, 1, 1)",
456
+ out: "cubic-bezier(0, 0, 0.2, 1)",
457
+ spring: "cubic-bezier(0.16, 1, 0.3, 1)"
458
+ // Smooth spring
459
+ }
460
+ },
461
+ /**
462
+ * Interaction tokens for Studio theme
463
+ * Subtle, professional — minimal overlay, gentle scale
464
+ */
465
+ interactions: {
466
+ hover: { overlayColor: { light: "#000000", dark: "#ffffff" }, opacity: 0.06 },
467
+ active: { scale: 0.98 },
468
+ focus: { ringWidth: "2px", ringOffset: "2px" },
469
+ disabled: { opacity: 0.5 }
470
+ },
471
+ typography: {
472
+ heading: {
473
+ fontFamily: "var(--font-geist-sans)",
474
+ fontWeight: "600",
475
+ letterSpacing: "-0.02em"
476
+ },
477
+ body: {
478
+ fontFamily: "var(--font-geist-sans)",
479
+ fontWeight: "400",
480
+ letterSpacing: "0"
481
+ },
482
+ mono: {
483
+ fontFamily: "var(--font-geist-mono)",
484
+ fontWeight: "400",
485
+ letterSpacing: "0"
486
+ }
487
+ }
488
+ };
489
+
490
+ // ../tokens/src/terra.ts
491
+ var terraTokens = {
492
+ light: {
493
+ colors: {
494
+ // Warm, earthy backgrounds
495
+ background: "#faf8f5",
496
+ backgroundSecondary: "#f5f1eb",
497
+ backgroundTertiary: "#ede8e0",
498
+ // Warm neutrals for text
499
+ foreground: "#2d2823",
500
+ foregroundSecondary: "#5a524a",
501
+ foregroundTertiary: "#8a7f72",
502
+ // Muted sage green as primary
503
+ primary: "#7a9b7f",
504
+ primaryForeground: "#faf8f5",
505
+ primaryHover: "#6a8b6f",
506
+ // Secondary - warm stone
507
+ secondary: "#ede8e0",
508
+ secondaryForeground: "#2d2823",
509
+ // Warm terracotta accent
510
+ accent: "#c17a5f",
511
+ accentForeground: "#faf8f5",
512
+ accentHover: "#b16a4f",
513
+ // Semantic colors with muted, organic tones
514
+ success: "#6b8e6f",
515
+ successForeground: "#faf8f5",
516
+ warning: "#d4a574",
517
+ warningForeground: "#2d2823",
518
+ error: "#c17a5f",
519
+ errorForeground: "#faf8f5",
520
+ info: "#8b9dc3",
521
+ infoForeground: "#faf8f5",
522
+ // Borders - warm subtle
523
+ border: "#e0d8cf",
524
+ borderSubtle: "#ede8e0",
525
+ // States
526
+ hover: "#f5f1eb",
527
+ active: "#ede8e0",
528
+ // Link hover states - Muted sage green
529
+ linkHover: "#7a9b7f",
530
+ linkHoverForeground: "#faf8f5",
531
+ // Soft glass effects
532
+ glass: "rgba(250, 248, 245, 0.85)",
533
+ glassBorder: "rgba(122, 155, 127, 0.15)"
534
+ },
535
+ effects: {
536
+ blur: {
537
+ sm: "blur(6px)",
538
+ md: "blur(12px)",
539
+ lg: "blur(20px)",
540
+ xl: "blur(32px)"
541
+ },
542
+ shadow: {
543
+ sm: "0 2px 4px 0 rgba(45, 40, 35, 0.06)",
544
+ md: "0 4px 8px -2px rgba(45, 40, 35, 0.08)",
545
+ lg: "0 8px 16px -4px rgba(45, 40, 35, 0.12)",
546
+ xl: "0 16px 32px -8px rgba(45, 40, 35, 0.16)",
547
+ "2xl": "0 24px 48px -12px rgba(45, 40, 35, 0.20)"
548
+ }
549
+ }
550
+ },
551
+ dark: {
552
+ colors: {
553
+ // Deep forest backgrounds
554
+ background: "#1a1614",
555
+ backgroundSecondary: "#252220",
556
+ backgroundTertiary: "#2f2b28",
557
+ // Warm light text
558
+ foreground: "#f5f1eb",
559
+ foregroundSecondary: "#c7bfb5",
560
+ foregroundTertiary: "#8a7f72",
561
+ // Brighter sage for dark mode
562
+ primary: "#a8c5ad",
563
+ primaryForeground: "#1a1614",
564
+ primaryHover: "#b8d5bd",
565
+ // Secondary - lighter warm stone
566
+ secondary: "#2f2b28",
567
+ secondaryForeground: "#f5f1eb",
568
+ // Warm peachy accent for dark
569
+ accent: "#e5a78a",
570
+ accentForeground: "#1a1614",
571
+ accentHover: "#f5b79a",
572
+ // Semantic colors adjusted for dark
573
+ success: "#95b89a",
574
+ successForeground: "#1a1614",
575
+ warning: "#e5c59a",
576
+ warningForeground: "#1a1614",
577
+ error: "#e5a78a",
578
+ errorForeground: "#1a1614",
579
+ info: "#a8b5d5",
580
+ infoForeground: "#1a1614",
581
+ // Borders
582
+ border: "#3a3530",
583
+ borderSubtle: "#2f2b28",
584
+ // States
585
+ hover: "#252220",
586
+ active: "#2f2b28",
587
+ // Link hover states - Brighter sage for dark mode
588
+ linkHover: "#a8c5ad",
589
+ linkHoverForeground: "#1a1614",
590
+ // Dark glass effects
591
+ glass: "rgba(26, 22, 20, 0.85)",
592
+ glassBorder: "rgba(168, 197, 173, 0.2)"
593
+ },
594
+ effects: {
595
+ blur: {
596
+ sm: "blur(6px)",
597
+ md: "blur(12px)",
598
+ lg: "blur(20px)",
599
+ xl: "blur(32px)"
600
+ },
601
+ shadow: {
602
+ sm: "0 2px 4px 0 rgba(0, 0, 0, 0.3)",
603
+ md: "0 4px 8px -2px rgba(0, 0, 0, 0.4)",
604
+ lg: "0 8px 16px -4px rgba(0, 0, 0, 0.5)",
605
+ xl: "0 16px 32px -8px rgba(0, 0, 0, 0.6)",
606
+ "2xl": "0 24px 48px -12px rgba(0, 0, 0, 0.7)"
607
+ }
608
+ }
609
+ },
610
+ motion: {
611
+ getDuration: (intensity) => {
612
+ if (intensity === 0) return "0ms";
613
+ const ms = 300 + (intensity - 1) * 60;
614
+ return `${ms}ms`;
615
+ },
616
+ ease: {
617
+ default: "cubic-bezier(0.33, 1, 0.68, 1)",
618
+ // Organic, flowing
619
+ in: "cubic-bezier(0.4, 0, 1, 1)",
620
+ out: "cubic-bezier(0, 0, 0.2, 1)",
621
+ spring: "cubic-bezier(0.16, 1, 0.3, 1)"
622
+ }
623
+ },
624
+ /**
625
+ * Interaction tokens for Terra theme
626
+ * Warm, organic — earthy overlay tones, softer scale
627
+ */
628
+ interactions: {
629
+ hover: { overlayColor: { light: "#2d2823", dark: "#f5f1eb" }, opacity: 0.07 },
630
+ active: { scale: 0.97 },
631
+ focus: { ringWidth: "2px", ringOffset: "2px" },
632
+ disabled: { opacity: 0.5 }
633
+ },
634
+ typography: {
635
+ heading: {
636
+ fontFamily: "var(--font-terra-serif)",
637
+ // Lora serif
638
+ fontWeight: "600",
639
+ letterSpacing: "-0.01em"
640
+ },
641
+ body: {
642
+ fontFamily: "var(--font-terra-sans)",
643
+ // Instrument Sans
644
+ fontWeight: "400",
645
+ letterSpacing: "0"
646
+ },
647
+ mono: {
648
+ fontFamily: "var(--font-terra-mono)",
649
+ fontWeight: "400",
650
+ letterSpacing: "0"
651
+ }
652
+ }
653
+ };
654
+
655
+ // ../tokens/src/volt.ts
656
+ var voltTokens = {
657
+ light: {
658
+ colors: {
659
+ // Bright, punchy backgrounds
660
+ background: "#ffffff",
661
+ backgroundSecondary: "#f8f9fb",
662
+ backgroundTertiary: "#f0f2f5",
663
+ // Sharp contrast text
664
+ foreground: "#0a0a0a",
665
+ foregroundSecondary: "#4a4a4a",
666
+ foregroundTertiary: "#8a8a8a",
667
+ // Electric blue primary (WCAG AA compliant)
668
+ primary: "#0066ff",
669
+ primaryForeground: "#ffffff",
670
+ primaryHover: "#0052cc",
671
+ // Secondary - cool gray
672
+ secondary: "#f0f2f5",
673
+ secondaryForeground: "#0a0a0a",
674
+ // Vibrant cyan accent
675
+ accent: "#00d9ff",
676
+ accentForeground: "#0a0a0a",
677
+ accentHover: "#00c3e6",
678
+ // Bold semantic colors
679
+ success: "#00cc66",
680
+ successForeground: "#ffffff",
681
+ warning: "#ffaa00",
682
+ warningForeground: "#0a0a0a",
683
+ error: "#ff3366",
684
+ errorForeground: "#ffffff",
685
+ info: "#3399ff",
686
+ infoForeground: "#ffffff",
687
+ // Borders
688
+ border: "#e0e4ea",
689
+ borderSubtle: "#f0f2f5",
690
+ // States
691
+ hover: "#f8f9fb",
692
+ active: "#f0f2f5",
693
+ // Link hover states - Electric blue with high contrast
694
+ linkHover: "#0066ff",
695
+ linkHoverForeground: "#ffffff",
696
+ // Crisp glass effects
697
+ glass: "rgba(255, 255, 255, 0.8)",
698
+ glassBorder: "rgba(0, 102, 255, 0.2)"
699
+ },
700
+ effects: {
701
+ blur: {
702
+ sm: "blur(8px)",
703
+ md: "blur(16px)",
704
+ lg: "blur(32px)",
705
+ xl: "blur(48px)"
706
+ },
707
+ shadow: {
708
+ sm: "0 0 8px rgba(0, 102, 255, 0.15)",
709
+ md: "0 0 16px rgba(0, 102, 255, 0.2)",
710
+ lg: "0 0 24px rgba(0, 102, 255, 0.25)",
711
+ xl: "0 0 32px rgba(0, 102, 255, 0.3)",
712
+ "2xl": "0 0 48px rgba(0, 102, 255, 0.4)"
713
+ }
714
+ }
715
+ },
716
+ dark: {
717
+ colors: {
718
+ // Pure black cyberpunk background
719
+ background: "#000000",
720
+ backgroundSecondary: "#0a0a0a",
721
+ backgroundTertiary: "#141414",
722
+ // Bright white text
723
+ foreground: "#ffffff",
724
+ foregroundSecondary: "#b3b3b3",
725
+ foregroundTertiary: "#666666",
726
+ // Neon blue primary
727
+ primary: "#0099ff",
728
+ primaryForeground: "#000000",
729
+ primaryHover: "#00aaff",
730
+ // Secondary - dark gray
731
+ secondary: "#141414",
732
+ secondaryForeground: "#ffffff",
733
+ // Neon cyan accent
734
+ accent: "#00ffff",
735
+ accentForeground: "#000000",
736
+ accentHover: "#33ffff",
737
+ // Neon semantic colors
738
+ success: "#00ff99",
739
+ successForeground: "#000000",
740
+ warning: "#ffcc00",
741
+ warningForeground: "#000000",
742
+ error: "#ff0066",
743
+ errorForeground: "#ffffff",
744
+ info: "#66ccff",
745
+ infoForeground: "#000000",
746
+ // Borders
747
+ border: "#1a1a1a",
748
+ borderSubtle: "#141414",
749
+ // States
750
+ hover: "#0a0a0a",
751
+ active: "#141414",
752
+ // Link hover states - Neon cyan (high luma)
753
+ linkHover: "#00ffff",
754
+ linkHoverForeground: "#000000",
755
+ // Dark glass with glow
756
+ glass: "rgba(0, 0, 0, 0.8)",
757
+ glassBorder: "rgba(0, 153, 255, 0.3)"
758
+ },
759
+ effects: {
760
+ blur: {
761
+ sm: "blur(8px)",
762
+ md: "blur(16px)",
763
+ lg: "blur(32px)",
764
+ xl: "blur(48px)"
765
+ },
766
+ shadow: {
767
+ sm: "0 0 12px rgba(0, 153, 255, 0.4)",
768
+ md: "0 0 20px rgba(0, 153, 255, 0.5)",
769
+ lg: "0 0 32px rgba(0, 153, 255, 0.6)",
770
+ xl: "0 0 48px rgba(0, 153, 255, 0.7)",
771
+ "2xl": "0 0 64px rgba(0, 153, 255, 0.8)"
772
+ }
773
+ }
774
+ },
775
+ motion: {
776
+ getDuration: (intensity) => {
777
+ if (intensity === 0) return "0ms";
778
+ const ms = 100 + (intensity - 1) * 25;
779
+ return `${ms}ms`;
780
+ },
781
+ ease: {
782
+ default: "cubic-bezier(0.16, 1, 0.3, 1)",
783
+ // Snappy spring
784
+ in: "cubic-bezier(0.4, 0, 1, 1)",
785
+ out: "cubic-bezier(0, 0, 0.2, 1)",
786
+ spring: "cubic-bezier(0.68, -0.55, 0.27, 1.55)"
787
+ // Bouncy
788
+ }
789
+ },
790
+ /**
791
+ * Interaction tokens for Volt theme
792
+ * Electric, brand-tinted — blue overlay, punchy scale
793
+ */
794
+ interactions: {
795
+ hover: { overlayColor: { light: "#0066ff", dark: "#0099ff" }, opacity: 0.1 },
796
+ active: { scale: 0.96 },
797
+ focus: { ringWidth: "2px", ringOffset: "2px" },
798
+ disabled: { opacity: 0.5 }
799
+ },
800
+ typography: {
801
+ heading: {
802
+ fontFamily: "var(--font-volt-sans)",
803
+ // Space Grotesk
804
+ fontWeight: "700",
805
+ // Bold
806
+ letterSpacing: "-0.03em"
807
+ },
808
+ body: {
809
+ fontFamily: "var(--font-volt-sans)",
810
+ fontWeight: "400",
811
+ letterSpacing: "0"
812
+ },
813
+ mono: {
814
+ fontFamily: "var(--font-volt-mono)",
815
+ // Fira Code
816
+ fontWeight: "400",
817
+ letterSpacing: "0"
818
+ }
819
+ }
820
+ };
821
+
822
+ // ../tokens/src/speedboat.ts
823
+ var speedboatTokens = {
824
+ light: {
825
+ colors: {
826
+ // Backgrounds
827
+ background: "#FFFFFF",
828
+ backgroundSecondary: "#F8F8F8",
829
+ // grey50
830
+ backgroundTertiary: "#ECECEC",
831
+ // grey100
832
+ // Foregrounds
833
+ foreground: "#212121",
834
+ // grey900 — ContentPrimary
835
+ foregroundSecondary: "#5D5D5D",
836
+ // grey700 — ContentSecondary
837
+ foregroundTertiary: "#8891A7",
838
+ // grey500 — muted icons
839
+ // Brand
840
+ primary: "#346BEA",
841
+ // accent blue
842
+ primaryForeground: "#FFFFFF",
843
+ secondary: "#EBF0FD",
844
+ // blue100 — chip bg
845
+ secondaryForeground: "#1E49AA",
846
+ // blue600 — chip text
847
+ accent: "#346BEA",
848
+ // same as primary for Speedboat
849
+ accentForeground: "#FFFFFF",
850
+ // Borders
851
+ border: "#ECECEC",
852
+ // grey100 — BorderPrimary
853
+ borderSubtle: "#F8F8F8",
854
+ // grey50
855
+ // States
856
+ hover: "#F8F8F8",
857
+ // grey50
858
+ active: "#ECECEC",
859
+ // grey100
860
+ // Link hover states
861
+ linkHover: "#1E49AA",
862
+ // blue600
863
+ linkHoverForeground: "#FFFFFF",
864
+ // Semantic
865
+ success: "#2E7D32",
866
+ successForeground: "#FFFFFF",
867
+ warning: "#E65100",
868
+ warningForeground: "#FFFFFF",
869
+ error: "#C62828",
870
+ errorForeground: "#FFFFFF",
871
+ info: "#346BEA",
872
+ infoForeground: "#FFFFFF",
873
+ // Component-specific colors
874
+ card: "#FFFFFF",
875
+ cardForeground: "#212121",
876
+ popover: "#FFFFFF",
877
+ popoverForeground: "#212121",
878
+ muted: "#F8F8F8",
879
+ // grey50
880
+ mutedForeground: "#8891A7",
881
+ // grey500
882
+ destructive: "#C62828",
883
+ // error red
884
+ destructiveForeground: "#FFFFFF",
885
+ input: "#DFDFDF",
886
+ // grey200 — input borders
887
+ ring: "#346BEA",
888
+ // accent blue for focus rings
889
+ // Surface
890
+ surface: "#F8F8F8",
891
+ // grey50
892
+ // Glass effects
893
+ glass: "rgba(255, 255, 255, 0.85)",
894
+ glassBorder: "rgba(0, 0, 0, 0.08)"
895
+ },
896
+ effects: {
897
+ blur: {
898
+ sm: "blur(4px)",
899
+ md: "blur(8px)",
900
+ lg: "blur(16px)",
901
+ xl: "blur(24px)"
902
+ },
903
+ shadow: {
904
+ sm: "0 1px 2px rgba(0, 0, 0, 0.05)",
905
+ md: "0 2px 8px rgba(0, 0, 0, 0.08)",
906
+ lg: "0 4px 16px rgba(0, 0, 0, 0.10)",
907
+ xl: "0 8px 24px rgba(0, 0, 0, 0.12)",
908
+ "2xl": "0 16px 48px rgba(0, 0, 0, 0.16)"
909
+ }
910
+ }
911
+ },
912
+ dark: {
913
+ colors: {
914
+ // Backgrounds — derived dark palette
915
+ background: "#0F1117",
916
+ backgroundSecondary: "#1A1C25",
917
+ backgroundTertiary: "#252833",
918
+ // Foregrounds
919
+ foreground: "#F0F0F2",
920
+ foregroundSecondary: "#A0A3B1",
921
+ foregroundTertiary: "#6B6F80",
922
+ // Brand — keep the accent blue, slightly brighten for dark bg
923
+ primary: "#4A7FF7",
924
+ primaryForeground: "#FFFFFF",
925
+ secondary: "#1E2540",
926
+ secondaryForeground: "#A6C1FF",
927
+ // blue300
928
+ accent: "#4A7FF7",
929
+ accentForeground: "#FFFFFF",
930
+ // Borders
931
+ border: "#2E3140",
932
+ borderSubtle: "#1A1C25",
933
+ // States
934
+ hover: "#1A1C25",
935
+ active: "#252833",
936
+ // Link hover states
937
+ linkHover: "#A6C1FF",
938
+ // blue300 — lighter for dark mode
939
+ linkHoverForeground: "#0F1117",
940
+ // Semantic — slightly brighter versions for dark bg
941
+ success: "#4CAF50",
942
+ successForeground: "#FFFFFF",
943
+ warning: "#FF8A50",
944
+ warningForeground: "#FFFFFF",
945
+ error: "#EF5350",
946
+ errorForeground: "#FFFFFF",
947
+ info: "#4A7FF7",
948
+ infoForeground: "#FFFFFF",
949
+ // Component-specific colors
950
+ card: "#1A1C25",
951
+ cardForeground: "#F0F0F2",
952
+ popover: "#1A1C25",
953
+ popoverForeground: "#F0F0F2",
954
+ muted: "#252833",
955
+ mutedForeground: "#6B6F80",
956
+ destructive: "#EF5350",
957
+ destructiveForeground: "#FFFFFF",
958
+ input: "#2E3140",
959
+ ring: "#4A7FF7",
960
+ // Surface
961
+ surface: "#1A1C25",
962
+ // Glass effects
963
+ glass: "rgba(15, 17, 23, 0.85)",
964
+ glassBorder: "rgba(255, 255, 255, 0.08)"
965
+ },
966
+ effects: {
967
+ blur: {
968
+ sm: "blur(4px)",
969
+ md: "blur(8px)",
970
+ lg: "blur(16px)",
971
+ xl: "blur(24px)"
972
+ },
973
+ shadow: {
974
+ sm: "0 1px 2px rgba(0, 0, 0, 0.20)",
975
+ md: "0 2px 8px rgba(0, 0, 0, 0.30)",
976
+ lg: "0 4px 16px rgba(0, 0, 0, 0.35)",
977
+ xl: "0 8px 24px rgba(0, 0, 0, 0.40)",
978
+ "2xl": "0 16px 48px rgba(0, 0, 0, 0.50)"
979
+ }
980
+ }
981
+ },
982
+ /**
983
+ * Motion personality for Speedboat theme
984
+ * Professional and snappy — slightly faster than Studio
985
+ */
986
+ motion: {
987
+ getDuration: (intensity) => {
988
+ if (intensity === 0) return "0ms";
989
+ const ms = 120 + (intensity - 1) * 35;
990
+ return `${ms}ms`;
991
+ },
992
+ ease: {
993
+ default: "cubic-bezier(0.4, 0, 0.2, 1)",
994
+ in: "cubic-bezier(0.4, 0, 1, 1)",
995
+ out: "cubic-bezier(0, 0, 0.2, 1)",
996
+ spring: "cubic-bezier(0.16, 1, 0.3, 1)"
997
+ }
998
+ },
999
+ /**
1000
+ * Interaction tokens for Speedboat theme
1001
+ * Professional, clean — matches Studio's subtle feel
1002
+ */
1003
+ interactions: {
1004
+ hover: { overlayColor: { light: "#000000", dark: "#ffffff" }, opacity: 0.06 },
1005
+ active: { scale: 0.98 },
1006
+ focus: { ringWidth: "2px", ringOffset: "2px" },
1007
+ disabled: { opacity: 0.5 }
1008
+ },
1009
+ /**
1010
+ * Typography for Speedboat theme
1011
+ * Montserrat headings + Roboto body — Moloco brand fonts
1012
+ */
1013
+ typography: {
1014
+ heading: {
1015
+ fontFamily: "var(--font-montserrat)",
1016
+ fontWeight: "700",
1017
+ letterSpacing: "-0.01em"
1018
+ },
1019
+ body: {
1020
+ fontFamily: "var(--font-roboto)",
1021
+ fontWeight: "400",
1022
+ letterSpacing: "0"
1023
+ },
1024
+ mono: {
1025
+ fontFamily: "var(--font-geist-mono)",
1026
+ fontWeight: "400",
1027
+ letterSpacing: "0"
1028
+ }
1029
+ }
1030
+ };
1031
+
1032
+ // ../tokens/src/typography.ts
1033
+ var fontFamilies = {
1034
+ studio: {
1035
+ heading: "Outfit",
1036
+ body: "Manrope",
1037
+ mono: "Fira Code",
1038
+ description: "Modern geometric sans-serif with clean readability",
1039
+ usage: {
1040
+ heading: "Headlines, titles, emphasis",
1041
+ body: "Paragraphs, UI text, readable content",
1042
+ mono: "Code blocks, technical content"
1043
+ }
1044
+ },
1045
+ terra: {
1046
+ heading: "Lora",
1047
+ // Serif for elegance
1048
+ body: "Instrument Sans",
1049
+ serif: "Lora",
1050
+ // Explicit serif reference
1051
+ sans: "Instrument Sans",
1052
+ // Explicit sans reference
1053
+ mono: "Fira Code",
1054
+ description: "Elegant serif headings with modern sans body",
1055
+ usage: {
1056
+ heading: "Elegant headings, article titles",
1057
+ body: "Long-form content, UI text",
1058
+ serif: "Pull quotes, emphasis",
1059
+ sans: "UI elements, captions",
1060
+ mono: "Code blocks, technical content"
1061
+ }
1062
+ },
1063
+ volt: {
1064
+ heading: "Space Grotesk",
1065
+ body: "Space Grotesk",
1066
+ sans: "Space Grotesk",
1067
+ mono: "Fira Code",
1068
+ description: "Tech-forward, consistent geometric throughout",
1069
+ usage: {
1070
+ heading: "All headlines",
1071
+ body: "All body text (unified typography)",
1072
+ sans: "All sans-serif needs",
1073
+ mono: "Code blocks, technical content"
1074
+ }
1075
+ },
1076
+ speedboat: {
1077
+ heading: "Montserrat",
1078
+ body: "Roboto",
1079
+ sans: "Roboto",
1080
+ mono: "Fira Code",
1081
+ description: "Moloco brand typography \u2014 Montserrat headings with Roboto body",
1082
+ usage: {
1083
+ heading: "Brand headings, section titles",
1084
+ body: "UI text, data labels, form content",
1085
+ sans: "All sans-serif needs",
1086
+ mono: "Code blocks, technical content"
1087
+ }
1088
+ }
1089
+ };
1090
+ var fontLoadingConfig = {
1091
+ studio: {
1092
+ heading: { family: "Outfit", weights: ["300", "400", "500", "600", "700", "800"] },
1093
+ body: { family: "Manrope", weights: ["300", "400", "500", "600", "700", "800"] },
1094
+ mono: { family: "Fira Code", weights: ["400", "500", "600", "700"] }
1095
+ },
1096
+ terra: {
1097
+ heading: { family: "Lora", weights: ["400", "500", "600", "700"] },
1098
+ body: { family: "Instrument Sans", weights: ["400", "500", "600", "700"] },
1099
+ mono: { family: "Fira Code", weights: ["400", "500", "600", "700"] }
1100
+ },
1101
+ volt: {
1102
+ heading: { family: "Space Grotesk", weights: ["300", "400", "500", "600", "700"] },
1103
+ body: { family: "Space Grotesk", weights: ["300", "400", "500", "600", "700"] },
1104
+ mono: { family: "Fira Code", weights: ["400", "500", "600", "700"] }
1105
+ }
1106
+ };
1107
+ var fontSizes = {
1108
+ // Body text scale
1109
+ xs: { base: "0.75rem", mobile: "0.75rem" },
1110
+ // 12px
1111
+ sm: { base: "0.875rem", mobile: "0.875rem" },
1112
+ // 14px
1113
+ base: { base: "1rem", mobile: "1rem" },
1114
+ // 16px
1115
+ lg: { base: "1.125rem", mobile: "1rem" },
1116
+ // 18px / 16px mobile
1117
+ xl: { base: "1.25rem", mobile: "1.125rem" },
1118
+ // 20px / 18px mobile
1119
+ "2xl": { base: "1.5rem", mobile: "1.25rem" },
1120
+ // 24px / 20px mobile
1121
+ "3xl": { base: "1.875rem", mobile: "1.5rem" },
1122
+ // 30px / 24px mobile
1123
+ // Heading scale (h6 → h1)
1124
+ "4xl": { base: "2.25rem", mobile: "1.875rem" },
1125
+ // 36px / 30px - h3
1126
+ "5xl": { base: "3rem", mobile: "2.25rem" },
1127
+ // 48px / 36px - h2
1128
+ "6xl": { base: "3.75rem", mobile: "2.5rem" },
1129
+ // 60px / 40px - h1
1130
+ "7xl": { base: "4.5rem", mobile: "3rem" },
1131
+ // 72px / 48px - Display
1132
+ "8xl": { base: "6rem", mobile: "3.75rem" },
1133
+ // 96px / 60px - Hero
1134
+ "9xl": { base: "8rem", mobile: "4.5rem" }
1135
+ // 128px / 72px - Ultra
1136
+ };
1137
+ var semanticSizes = {
1138
+ "heading-1": "hero",
1139
+ "heading-2": "5xl",
1140
+ "heading-3": "4xl",
1141
+ "heading-4": "2xl",
1142
+ "heading-5": "xl",
1143
+ "heading-6": "lg",
1144
+ "body-large": "lg",
1145
+ "body": "base",
1146
+ "body-small": "sm",
1147
+ "caption": "xs"
1148
+ };
1149
+ var fontWeights = {
1150
+ thin: "100",
1151
+ extralight: "200",
1152
+ light: "300",
1153
+ normal: "400",
1154
+ medium: "500",
1155
+ semibold: "600",
1156
+ bold: "700",
1157
+ extrabold: "800",
1158
+ black: "900"
1159
+ };
1160
+ var semanticWeights = {
1161
+ heading: "bold",
1162
+ // Default heading weight
1163
+ "heading-light": "semibold",
1164
+ "heading-heavy": "extrabold",
1165
+ body: "normal",
1166
+ // Default body weight
1167
+ "body-emphasis": "medium",
1168
+ "body-strong": "semibold",
1169
+ caption: "normal"
1170
+ };
1171
+ var lineHeights = {
1172
+ none: "1",
1173
+ tight: "1.25",
1174
+ snug: "1.375",
1175
+ normal: "1.5",
1176
+ relaxed: "1.625",
1177
+ loose: "1.75",
1178
+ extraloose: "2"
1179
+ };
1180
+ var semanticLineHeights = {
1181
+ heading: "tight",
1182
+ "heading-display": "none",
1183
+ // Very tight for large display text
1184
+ body: "normal",
1185
+ "body-relaxed": "relaxed",
1186
+ caption: "snug"
1187
+ };
1188
+ var letterSpacing = {
1189
+ tighter: "-0.05em",
1190
+ tight: "-0.025em",
1191
+ normal: "0",
1192
+ wide: "0.025em",
1193
+ wider: "0.05em",
1194
+ widest: "0.1em"
1195
+ };
1196
+ var semanticLetterSpacing = {
1197
+ heading: "tight",
1198
+ "heading-display": "tighter",
1199
+ body: "normal",
1200
+ "small-caps": "wider",
1201
+ "all-caps": "widest"
1202
+ };
1203
+ var typePresets = {
1204
+ "display-large": {
1205
+ size: fontSizes["8xl"],
1206
+ weight: fontWeights.bold,
1207
+ lineHeight: lineHeights.none,
1208
+ letterSpacing: letterSpacing.tighter,
1209
+ description: "Large hero text, landing pages"
1210
+ },
1211
+ "display": {
1212
+ size: fontSizes["7xl"],
1213
+ weight: fontWeights.bold,
1214
+ lineHeight: lineHeights.tight,
1215
+ letterSpacing: letterSpacing.tight,
1216
+ description: "Hero sections, major headings"
1217
+ },
1218
+ "heading-1": {
1219
+ size: fontSizes["6xl"],
1220
+ weight: fontWeights.bold,
1221
+ lineHeight: lineHeights.tight,
1222
+ letterSpacing: letterSpacing.tight,
1223
+ description: "Page titles, h1"
1224
+ },
1225
+ "heading-2": {
1226
+ size: fontSizes["5xl"],
1227
+ weight: fontWeights.bold,
1228
+ lineHeight: lineHeights.tight,
1229
+ letterSpacing: letterSpacing.normal,
1230
+ description: "Section titles, h2"
1231
+ },
1232
+ "heading-3": {
1233
+ size: fontSizes["4xl"],
1234
+ weight: fontWeights.semibold,
1235
+ lineHeight: lineHeights.snug,
1236
+ letterSpacing: letterSpacing.normal,
1237
+ description: "Subsection titles, h3"
1238
+ },
1239
+ "heading-4": {
1240
+ size: fontSizes["2xl"],
1241
+ weight: fontWeights.semibold,
1242
+ lineHeight: lineHeights.snug,
1243
+ letterSpacing: letterSpacing.normal,
1244
+ description: "Component titles, h4"
1245
+ },
1246
+ "heading-5": {
1247
+ size: fontSizes.xl,
1248
+ weight: fontWeights.medium,
1249
+ lineHeight: lineHeights.normal,
1250
+ letterSpacing: letterSpacing.normal,
1251
+ description: "Small headings, h5"
1252
+ },
1253
+ "heading-6": {
1254
+ size: fontSizes.lg,
1255
+ weight: fontWeights.medium,
1256
+ lineHeight: lineHeights.normal,
1257
+ letterSpacing: letterSpacing.normal,
1258
+ description: "Tiny headings, h6"
1259
+ },
1260
+ "body-large": {
1261
+ size: fontSizes.lg,
1262
+ weight: fontWeights.normal,
1263
+ lineHeight: lineHeights.relaxed,
1264
+ letterSpacing: letterSpacing.normal,
1265
+ description: "Lead paragraphs, intro text"
1266
+ },
1267
+ "body": {
1268
+ size: fontSizes.base,
1269
+ weight: fontWeights.normal,
1270
+ lineHeight: lineHeights.normal,
1271
+ letterSpacing: letterSpacing.normal,
1272
+ description: "Default body text"
1273
+ },
1274
+ "body-small": {
1275
+ size: fontSizes.sm,
1276
+ weight: fontWeights.normal,
1277
+ lineHeight: lineHeights.normal,
1278
+ letterSpacing: letterSpacing.normal,
1279
+ description: "Small body text, fine print"
1280
+ },
1281
+ "caption": {
1282
+ size: fontSizes.xs,
1283
+ weight: fontWeights.normal,
1284
+ lineHeight: lineHeights.snug,
1285
+ letterSpacing: letterSpacing.wide,
1286
+ description: "Captions, labels, metadata"
1287
+ },
1288
+ "overline": {
1289
+ size: fontSizes.xs,
1290
+ weight: fontWeights.semibold,
1291
+ lineHeight: lineHeights.normal,
1292
+ letterSpacing: letterSpacing.widest,
1293
+ description: "Eyebrows, categories, all-caps labels"
1294
+ }
1295
+ };
1296
+ function getFontVariable(theme, type) {
1297
+ return `--font-${theme}-${type}`;
1298
+ }
1299
+ function getThemeFontVariables(theme) {
1300
+ const fonts = fontFamilies[theme];
1301
+ const vars = {};
1302
+ Object.entries(fonts).forEach(([key, value]) => {
1303
+ if (typeof value === "string") {
1304
+ vars[`--font-${theme}-${key}`] = value;
1305
+ }
1306
+ });
1307
+ return vars;
1308
+ }
1309
+ function getResponsiveFontSize(sizeKey) {
1310
+ const size = fontSizes[sizeKey];
1311
+ return `font-size: ${size.mobile}; @media (min-width: 768px) { font-size: ${size.base}; }`;
1312
+ }
1313
+ var typographySystem = {
1314
+ families: fontFamilies,
1315
+ sizes: fontSizes,
1316
+ weights: fontWeights,
1317
+ lineHeights,
1318
+ letterSpacing,
1319
+ presets: typePresets,
1320
+ semantic: {
1321
+ sizes: semanticSizes,
1322
+ weights: semanticWeights,
1323
+ lineHeights: semanticLineHeights,
1324
+ letterSpacing: semanticLetterSpacing
1325
+ },
1326
+ utils: {
1327
+ getFontVariable,
1328
+ getThemeFontVariables,
1329
+ getResponsiveFontSize
1330
+ }
1331
+ };
1332
+
1333
+ // ../tokens/src/syntax.ts
1334
+ var syntaxColors = {
1335
+ light: {
1336
+ comment: "#22863a",
1337
+ // Green for comments
1338
+ keyword: "#8250df",
1339
+ // Purple for keywords (import, export, const, etc.)
1340
+ function: "#6639ba",
1341
+ // Purple for function names
1342
+ string: "#c1592a",
1343
+ // Orange for strings
1344
+ number: "#0a3069",
1345
+ // Blue for numbers
1346
+ boolean: "#0550ae",
1347
+ // Blue for booleans
1348
+ operator: "#1a1a1a",
1349
+ // Almost black for operators
1350
+ property: "#0550ae",
1351
+ // Blue for properties
1352
+ className: "#005cc5",
1353
+ // Blue for class names
1354
+ tag: "#005cc5",
1355
+ // Blue for HTML/JSX tags
1356
+ attribute: "#0550ae",
1357
+ // Blue for attributes
1358
+ variable: "#0550ae",
1359
+ // Blue for variables
1360
+ punctuation: "#57606a",
1361
+ // Gray for punctuation
1362
+ plain: "#1a1a1a"
1363
+ // Default text color
1364
+ },
1365
+ dark: {
1366
+ comment: "#6A9955",
1367
+ // Green for comments
1368
+ keyword: "#C586C0",
1369
+ // Purple for keywords (import, export, const, etc.)
1370
+ function: "#DCDCAA",
1371
+ // Yellow for function names
1372
+ string: "#CE9178",
1373
+ // Orange for strings
1374
+ number: "#B5CEA8",
1375
+ // Light green for numbers
1376
+ boolean: "#569CD6",
1377
+ // Blue for booleans
1378
+ operator: "#D4D4D4",
1379
+ // Light gray for operators
1380
+ property: "#9CDCFE",
1381
+ // Light blue for properties
1382
+ className: "#4EC9B0",
1383
+ // Cyan for class names
1384
+ tag: "#4EC9B0",
1385
+ // Cyan for HTML/JSX tags
1386
+ attribute: "#9CDCFE",
1387
+ // Light blue for attributes
1388
+ variable: "#9CDCFE",
1389
+ // Light blue for variables
1390
+ punctuation: "#808080",
1391
+ // Gray for punctuation
1392
+ plain: "#D4D4D4"
1393
+ // Default text color
1394
+ }
1395
+ };
1396
+ var codeColors = {
1397
+ light: {
1398
+ // Block code background - cool gray for subtle distinction
1399
+ blockBackground: "#F8F9FA",
1400
+ // Inline code background - pale amber for warmth and visibility
1401
+ inlineBackground: "#FEF3E7",
1402
+ // Border color for definition and separation
1403
+ border: "#E1E4E8"
1404
+ },
1405
+ dark: {
1406
+ // Block code background - VS Code-inspired dark background
1407
+ blockBackground: "#1E1E1E",
1408
+ // Inline code background - slightly lighter for contrast
1409
+ inlineBackground: "#252525",
1410
+ // Border color for definition
1411
+ border: "#3D3D3D"
1412
+ }
1413
+ };
1414
+
1415
+ // ../tokens/src/color-palettes.ts
1416
+ var colorPalettes = [
1417
+ // === PROFESSIONAL ===
1418
+ {
1419
+ id: "deep-trust",
1420
+ name: "Deep Trust",
1421
+ description: "Confident navy with subtle warmth",
1422
+ category: "professional",
1423
+ primary: "#1e3a5f",
1424
+ secondary: "#64748b",
1425
+ accent: "#f59e0b",
1426
+ harmony: "Split-Complementary",
1427
+ bestFor: ["Finance", "Legal", "Enterprise SaaS"],
1428
+ rationale: "Navy (trust, authority) paired with Slate (neutral utility) and Amber (approachable warmth). The amber accent draws attention to CTAs without disrupting professional gravitas. High contrast ratios ensure accessibility.",
1429
+ wcagAA: true,
1430
+ wcagAAA: true
1431
+ },
1432
+ {
1433
+ id: "graphite-precision",
1434
+ name: "Graphite Precision",
1435
+ description: "Modern technical authority",
1436
+ category: "professional",
1437
+ primary: "#0f172a",
1438
+ secondary: "#475569",
1439
+ accent: "#0ea5e9",
1440
+ harmony: "Analogous + Accent",
1441
+ bestFor: ["Dev Tools", "Analytics", "SaaS Dashboards"],
1442
+ rationale: "Near-black primary (Slate 900) conveys technical sophistication. Steel secondary provides UI structure. Sky blue accent pops for interactive elements. Inspired by developer tools like VS Code and GitHub.",
1443
+ wcagAA: true,
1444
+ wcagAAA: false
1445
+ },
1446
+ {
1447
+ id: "obsidian-gold",
1448
+ name: "Obsidian Gold",
1449
+ description: "Premium high-end authority",
1450
+ category: "professional",
1451
+ primary: "#09090b",
1452
+ secondary: "#3f3f46",
1453
+ accent: "#ca8a04",
1454
+ harmony: "Complementary",
1455
+ bestFor: ["Luxury Tech", "Premium Services", "High-End Products"],
1456
+ rationale: "Zinc 950 primary delivers true premium feel without harsh black. Zinc 700 secondary creates layered depth for cards and containers. Yellow-700 gold accent signals exclusivity and value.",
1457
+ wcagAA: true,
1458
+ wcagAAA: true
1459
+ },
1460
+ {
1461
+ id: "slate-ember",
1462
+ name: "Slate Ember",
1463
+ description: "Warm corporate modernism",
1464
+ category: "professional",
1465
+ primary: "#334155",
1466
+ secondary: "#94a3b8",
1467
+ accent: "#ea580c",
1468
+ harmony: "Complementary",
1469
+ bestFor: ["Consulting", "B2B Services", "Corporate Sites"],
1470
+ rationale: "Slate 700 primary feels mature yet approachable. Slate 400 secondary lightens UI without losing professionalism. Orange 600 accent energizes without overwhelming\u2014perfect for subtle call-to-action emphasis.",
1471
+ wcagAA: true,
1472
+ wcagAAA: true
1473
+ },
1474
+ // === CREATIVE ===
1475
+ {
1476
+ id: "sunset-gradient",
1477
+ name: "Sunset Gradient",
1478
+ description: "Warm analogous energy flow",
1479
+ category: "creative",
1480
+ primary: "#db2777",
1481
+ secondary: "#f97316",
1482
+ accent: "#fbbf24",
1483
+ harmony: "Analogous",
1484
+ bestFor: ["Design Agencies", "Portfolios", "Creative Studios"],
1485
+ rationale: "Pink 600 \u2192 Orange 500 \u2192 Amber 400 creates natural warmth progression mimicking golden hour. This analogous flow feels cohesive yet dynamic. Works beautifully with white backgrounds and dark text.",
1486
+ wcagAA: true,
1487
+ wcagAAA: false
1488
+ },
1489
+ {
1490
+ id: "electric-violet",
1491
+ name: "Electric Violet",
1492
+ description: "Bold complementary punch",
1493
+ category: "creative",
1494
+ primary: "#7c3aed",
1495
+ secondary: "#be185d",
1496
+ accent: "#fb923c",
1497
+ harmony: "Triadic",
1498
+ bestFor: ["Entertainment", "Events", "Music", "Gaming"],
1499
+ rationale: "Violet 600, Rose 700, and Orange 400 form a dynamic triadic harmony. Each color is equidistant on the wheel, creating maximum visual interest while maintaining balance. Use violet as dominant, rose for sections, orange for CTAs.",
1500
+ wcagAA: true,
1501
+ wcagAAA: false
1502
+ },
1503
+ {
1504
+ id: "indigo-bloom",
1505
+ name: "Indigo Bloom",
1506
+ description: "Sophisticated feminine power",
1507
+ category: "creative",
1508
+ primary: "#4338ca",
1509
+ secondary: "#be123c",
1510
+ accent: "#d946ef",
1511
+ harmony: "Split-Complementary",
1512
+ bestFor: ["Beauty", "Fashion Tech", "Lifestyle Apps"],
1513
+ rationale: "Indigo 700 anchors with depth and sophistication. Rose 700 provides rich contrast. Fuchsia 500 accent sparkles for highlights and interactions. The palette balances strength with approachability.",
1514
+ wcagAA: true,
1515
+ wcagAAA: true
1516
+ },
1517
+ {
1518
+ id: "coral-reef",
1519
+ name: "Coral Reef",
1520
+ description: "Playful warmth with depth",
1521
+ category: "creative",
1522
+ primary: "#f43f5e",
1523
+ secondary: "#06b6d4",
1524
+ accent: "#fcd34d",
1525
+ harmony: "Triadic",
1526
+ bestFor: ["Social Apps", "Community Platforms", "Lifestyle"],
1527
+ rationale: "Rose 500 (coral), Cyan 500 (ocean), and Amber 300 (sand) evoke tropical vibrancy. This triadic scheme feels energetic yet grounded. Great for apps targeting younger, socially-engaged audiences.",
1528
+ wcagAA: true,
1529
+ wcagAAA: false
1530
+ },
1531
+ // === NATURE ===
1532
+ {
1533
+ id: "forest-floor",
1534
+ name: "Forest Floor",
1535
+ description: "Deep organic earthiness",
1536
+ category: "nature",
1537
+ primary: "#14532d",
1538
+ secondary: "#78350f",
1539
+ accent: "#84cc16",
1540
+ harmony: "Analogous + Accent",
1541
+ bestFor: ["Sustainability", "Wellness", "Organic Products"],
1542
+ rationale: "Green 900 (deep forest) and Amber 900 (rich earth/bark) create grounded warmth. Lime 500 accent represents new growth and vitality. This palette speaks to environmental consciousness and natural authenticity.",
1543
+ wcagAA: true,
1544
+ wcagAAA: true
1545
+ },
1546
+ {
1547
+ id: "ocean-calm",
1548
+ name: "Ocean Calm",
1549
+ description: "Tranquil aquatic serenity",
1550
+ category: "nature",
1551
+ primary: "#0f766e",
1552
+ secondary: "#0284c7",
1553
+ accent: "#22d3ee",
1554
+ harmony: "Analogous",
1555
+ bestFor: ["Healthcare", "Meditation", "Clean Tech"],
1556
+ rationale: "Teal 700, Sky 600, and Cyan 400 form a calming blue-green progression. Mimics depth variations in water. Low emotional intensity promotes trust and calm\u2014ideal for wellness and health applications.",
1557
+ wcagAA: true,
1558
+ wcagAAA: false
1559
+ },
1560
+ {
1561
+ id: "sage-garden",
1562
+ name: "Sage Garden",
1563
+ description: "Botanical mindfulness",
1564
+ category: "nature",
1565
+ primary: "#6366f1",
1566
+ secondary: "#059669",
1567
+ accent: "#fef08a",
1568
+ harmony: "Triadic",
1569
+ bestFor: ["Meditation Apps", "Spa", "Personal Growth"],
1570
+ rationale: "Indigo 500 (lavender energy), Emerald 600 (sage calm), Yellow 200 (morning light). Named colors match actual botanicals. Soft yellow accent provides gentle illumination for key interactions.",
1571
+ wcagAA: true,
1572
+ wcagAAA: false
1573
+ },
1574
+ {
1575
+ id: "desert-dawn",
1576
+ name: "Desert Dawn",
1577
+ description: "Warm arid minimalism",
1578
+ category: "nature",
1579
+ primary: "#d6d3d1",
1580
+ secondary: "#a8a29e",
1581
+ accent: "#c2410c",
1582
+ harmony: "Monochromatic + Accent",
1583
+ bestFor: ["Architecture", "Interior Design", "Artisan Goods"],
1584
+ rationale: "Stone 300 and Stone 400 create subtle warmth typical of desert sands. Orange 700 accent recalls desert flora and sunset. Minimalist yet rich\u2014perfect for showcasing products and photography.",
1585
+ wcagAA: false,
1586
+ wcagAAA: false
1587
+ },
1588
+ // === VIBRANT ===
1589
+ {
1590
+ id: "neon-signal",
1591
+ name: "Neon Signal",
1592
+ description: "High-energy cyberpunk electric",
1593
+ category: "vibrant",
1594
+ primary: "#06b6d4",
1595
+ secondary: "#d946ef",
1596
+ accent: "#fde047",
1597
+ harmony: "Triadic (CMY-based)",
1598
+ bestFor: ["Gaming", "Web3", "Music Streaming", "Youth Apps"],
1599
+ rationale: "Cyan 500, Fuchsia 500, Yellow 300 approximate CMY primaries\u2014the digital/print color model. Creates electric, almost glitch-aesthetic energy. Use sparingly on dark backgrounds for maximum impact.",
1600
+ wcagAA: false,
1601
+ wcagAAA: false
1602
+ },
1603
+ {
1604
+ id: "citrus-burst",
1605
+ name: "Citrus Burst",
1606
+ description: "Maximum fresh impact",
1607
+ category: "vibrant",
1608
+ primary: "#65a30d",
1609
+ secondary: "#7c3aed",
1610
+ accent: "#14b8a6",
1611
+ harmony: "Split-Complementary",
1612
+ bestFor: ["Sports", "Energy Drinks", "Youth Brands"],
1613
+ rationale: "Lime 600, Violet 600, and Teal 500 create intentional visual tension. The near-complementary lime/violet pairing vibrates with energy, while teal accent provides unexpected freshness. Bold and unapologetic.",
1614
+ wcagAA: false,
1615
+ wcagAAA: false
1616
+ },
1617
+ {
1618
+ id: "fire-intensity",
1619
+ name: "Fire Intensity",
1620
+ description: "Passionate warmth progression",
1621
+ category: "vibrant",
1622
+ primary: "#b91c1c",
1623
+ secondary: "#ea580c",
1624
+ accent: "#fbbf24",
1625
+ harmony: "Analogous (Warm)",
1626
+ bestFor: ["Food Delivery", "Fitness", "Action Sports"],
1627
+ rationale: "Red 700 \u2192 Orange 600 \u2192 Amber 400 represents heat intensity from coals to flame to spark. This warm analogous progression demands attention and creates urgency. Best balanced with plenty of whitespace.",
1628
+ wcagAA: true,
1629
+ wcagAAA: false
1630
+ },
1631
+ {
1632
+ id: "aurora-borealis",
1633
+ name: "Aurora Borealis",
1634
+ description: "Ethereal northern lights",
1635
+ category: "vibrant",
1636
+ primary: "#0891b2",
1637
+ secondary: "#7c3aed",
1638
+ accent: "#22c55e",
1639
+ harmony: "Triadic",
1640
+ bestFor: ["Astronomy Apps", "Science", "Innovation"],
1641
+ rationale: "Cyan 600, Violet 600, and Green 500 capture the magical shifting hues of aurora displays. Equally spaced on the wheel, they create visual wonder without chaos. Perfect for science and exploration themes.",
1642
+ wcagAA: true,
1643
+ wcagAAA: false
1644
+ },
1645
+ // === MINIMAL ===
1646
+ {
1647
+ id: "swiss-mono",
1648
+ name: "Swiss Mono",
1649
+ description: "International style precision",
1650
+ category: "minimal",
1651
+ primary: "#000000",
1652
+ secondary: "#52525b",
1653
+ accent: "#2563eb",
1654
+ harmony: "Achromatic + Accent",
1655
+ bestFor: ["Typography", "Photography", "Editorial"],
1656
+ rationale: "Pure black and Zinc 600 honor Swiss International Style. Blue 600 accent (classic 'international blue') provides subtle direction without disrupting minimalist purity. Maximum contrast, zero distraction.",
1657
+ wcagAA: true,
1658
+ wcagAAA: true
1659
+ },
1660
+ {
1661
+ id: "paper-whisper",
1662
+ name: "Paper Whisper",
1663
+ description: "Soft reading comfort",
1664
+ category: "minimal",
1665
+ primary: "#27272a",
1666
+ secondary: "#71717a",
1667
+ accent: "#a1a1aa",
1668
+ harmony: "Monochromatic",
1669
+ bestFor: ["Reading Apps", "Journaling", "Documentation"],
1670
+ rationale: "Zinc 800, 500, and 400 create subtle hierarchy without color distraction. True monochrome reduces cognitive load for reading-heavy interfaces. Accent provides gentle distinction for interactive elements.",
1671
+ wcagAA: true,
1672
+ wcagAAA: true
1673
+ },
1674
+ {
1675
+ id: "cool-slate",
1676
+ name: "Cool Slate",
1677
+ description: "Technical quiet confidence",
1678
+ category: "minimal",
1679
+ primary: "#334155",
1680
+ secondary: "#64748b",
1681
+ accent: "#38bdf8",
1682
+ harmony: "Analogous + Accent",
1683
+ bestFor: ["Architecture Portfolios", "Consulting", "Legal Tech"],
1684
+ rationale: "Slate 700 and 500 create cool, professional atmosphere. Sky 400 accent whispers rather than shouts\u2014perfect for subtle navigation cues and sparse interactive highlights.",
1685
+ wcagAA: true,
1686
+ wcagAAA: true
1687
+ },
1688
+ {
1689
+ id: "warm-neutral",
1690
+ name: "Warm Neutral",
1691
+ description: "Organic minimalism",
1692
+ category: "minimal",
1693
+ primary: "#292524",
1694
+ secondary: "#78716c",
1695
+ accent: "#92400e",
1696
+ harmony: "Monochromatic + Accent",
1697
+ bestFor: ["Artisan E-commerce", "Coffee Brands", "Craft"],
1698
+ rationale: "Stone 800 and 500 provide warmth missing from pure grays. Amber 800 accent recalls coffee, leather, wood\u2014materials with character. Minimal but not cold, modern but not sterile.",
1699
+ wcagAA: true,
1700
+ wcagAAA: true
1701
+ },
1702
+ // === LUXURY ===
1703
+ {
1704
+ id: "royal-velvet",
1705
+ name: "Royal Velvet",
1706
+ description: "Regal opulent depth",
1707
+ category: "luxury",
1708
+ primary: "#4c1d95",
1709
+ secondary: "#1e1b4b",
1710
+ accent: "#d97706",
1711
+ harmony: "Complementary",
1712
+ bestFor: ["VIP Services", "Luxury Hotels", "Private Banking"],
1713
+ rationale: "Violet 900 (deep purple) and Indigo 950 (near-black midnight) create layered richness. Amber 600 gold accent adds warmth and signals value. Historically associated with royalty and exclusivity.",
1714
+ wcagAA: true,
1715
+ wcagAAA: true
1716
+ },
1717
+ {
1718
+ id: "champagne-noir",
1719
+ name: "Champagne Noir",
1720
+ description: "High-fashion sophistication",
1721
+ category: "luxury",
1722
+ primary: "#0c0a09",
1723
+ secondary: "#1c1917",
1724
+ accent: "#d4af37",
1725
+ harmony: "Monochromatic + Metallic",
1726
+ bestFor: ["Fashion", "Jewelry", "Luxury Retail"],
1727
+ rationale: "Stone 950 (warm black) and Stone 900 create subtle depth. True metallic gold (#D4AF37) elevates beyond standard amber. The warmth in blacks prevents coldness while maintaining elegance.",
1728
+ wcagAA: true,
1729
+ wcagAAA: true
1730
+ },
1731
+ {
1732
+ id: "emerald-club",
1733
+ name: "Emerald Club",
1734
+ description: "Old money establishment",
1735
+ category: "luxury",
1736
+ primary: "#064e3b",
1737
+ secondary: "#166534",
1738
+ accent: "#b45309",
1739
+ harmony: "Analogous + Accent",
1740
+ bestFor: ["Private Clubs", "Wealth Management", "Heritage Brands"],
1741
+ rationale: "Emerald 900 and Green 800 create tone-on-tone richness associated with stability and tradition. Bronze/Amber 700 accent recalls old brass and mahogany. Communicates established trustworthiness.",
1742
+ wcagAA: true,
1743
+ wcagAAA: true
1744
+ },
1745
+ {
1746
+ id: "midnight-sapphire",
1747
+ name: "Midnight Sapphire",
1748
+ description: "Contemporary luxury tech",
1749
+ category: "luxury",
1750
+ primary: "#172554",
1751
+ secondary: "#1e3a8a",
1752
+ accent: "#fafafa",
1753
+ harmony: "Monochromatic + Contrast",
1754
+ bestFor: ["Luxury Auto", "Premium Electronics", "Elite Services"],
1755
+ rationale: "Blue 950 and Blue 800 create depth like sapphire gemstone. Pure white (Zinc 50) accent cuts through dramatically. Modern luxury aesthetic\u2014think high-end automotive interfaces.",
1756
+ wcagAA: true,
1757
+ wcagAAA: true
1758
+ },
1759
+ // === PLAYFUL ===
1760
+ {
1761
+ id: "candy-shop",
1762
+ name: "Candy Shop",
1763
+ description: "Joyful youthful sweetness",
1764
+ category: "playful",
1765
+ primary: "#ec4899",
1766
+ secondary: "#8b5cf6",
1767
+ accent: "#facc15",
1768
+ harmony: "Triadic",
1769
+ bestFor: ["Kids Apps", "Toys", "Gaming", "Entertainment"],
1770
+ rationale: "Pink 500 (bubble gum), Violet 500 (grape), Yellow 400 (lemon drop) evoke candy store joy. Classic gender-neutral playful combination. High saturation communicates energy and fun.",
1771
+ wcagAA: false,
1772
+ wcagAAA: false
1773
+ },
1774
+ {
1775
+ id: "sunny-day",
1776
+ name: "Sunny Day",
1777
+ description: "Optimistic primary colors",
1778
+ category: "playful",
1779
+ primary: "#2563eb",
1780
+ secondary: "#16a34a",
1781
+ accent: "#fbbf24",
1782
+ harmony: "Triadic (Primary-based)",
1783
+ bestFor: ["Education", "Children's Apps", "Learning Platforms"],
1784
+ rationale: "Blue 600 (sky), Green 600 (grass), Amber 400 (sun) are universally recognized and accessible. This primary-adjacent scheme feels familiar and approachable to all ages and cultures.",
1785
+ wcagAA: true,
1786
+ wcagAAA: false
1787
+ },
1788
+ {
1789
+ id: "mint-berry",
1790
+ name: "Mint Berry",
1791
+ description: "Fresh dessert sweetness",
1792
+ category: "playful",
1793
+ primary: "#10b981",
1794
+ secondary: "#ec4899",
1795
+ accent: "#06b6d4",
1796
+ harmony: "Split-Complementary",
1797
+ bestFor: ["Food Apps", "Lifestyle", "Wellness for Youth"],
1798
+ rationale: "Emerald 500 (mint), Pink 500 (berry), Cyan 500 (ice) create dessert-inspired freshness. High contrast between green and pink creates visual interest while cyan cools the palette.",
1799
+ wcagAA: false,
1800
+ wcagAAA: false
1801
+ },
1802
+ {
1803
+ id: "rainbow-pop",
1804
+ name: "Rainbow Pop",
1805
+ description: "Maximalist celebration",
1806
+ category: "playful",
1807
+ primary: "#f43f5e",
1808
+ secondary: "#8b5cf6",
1809
+ accent: "#06b6d4",
1810
+ harmony: "Triadic",
1811
+ bestFor: ["Pride Events", "Festivals", "Inclusive Communities"],
1812
+ rationale: "Rose 500, Violet 500, Cyan 500 span the visible spectrum. Celebrates diversity and inclusion through color. Each hue can represent different aspects while maintaining visual harmony.",
1813
+ wcagAA: false,
1814
+ wcagAAA: false
1815
+ },
1816
+ // === ACCESSIBLE ===
1817
+ {
1818
+ id: "high-clarity",
1819
+ name: "High Clarity",
1820
+ description: "Maximum readability",
1821
+ category: "accessible",
1822
+ primary: "#1f2937",
1823
+ secondary: "#4b5563",
1824
+ accent: "#0284c7",
1825
+ harmony: "Monochromatic + Accent",
1826
+ bestFor: ["Government", "Healthcare", "Education"],
1827
+ rationale: "Gray 800 and 600 on white exceed WCAG AAA contrast requirements (7:1+). Sky 600 accent passes AA for large text. Designed for universal accessibility including visual impairments.",
1828
+ wcagAA: true,
1829
+ wcagAAA: true
1830
+ },
1831
+ {
1832
+ id: "safe-contrast",
1833
+ name: "Safe Contrast",
1834
+ description: "Color-blind friendly",
1835
+ category: "accessible",
1836
+ primary: "#0369a1",
1837
+ secondary: "#374151",
1838
+ accent: "#ea580c",
1839
+ harmony: "Complementary",
1840
+ bestFor: ["Data Visualization", "Forms", "Critical Interfaces"],
1841
+ rationale: "Sky 700 and Gray 700 are distinguishable across common color blindness types. Orange 600 accent avoids red-green confusion. Tested with deuteranopia, protanopia, and tritanopia simulations.",
1842
+ wcagAA: true,
1843
+ wcagAAA: false
1844
+ },
1845
+ {
1846
+ id: "gentle-reader",
1847
+ name: "Gentle Reader",
1848
+ description: "Low eye strain",
1849
+ category: "accessible",
1850
+ primary: "#44403c",
1851
+ secondary: "#78716c",
1852
+ accent: "#2563eb",
1853
+ harmony: "Monochromatic + Accent",
1854
+ bestFor: ["Long-Form Reading", "Elderly Users", "Medical"],
1855
+ rationale: "Stone 700 and 500 avoid harsh black while maintaining readability. Reduced contrast prevents eye fatigue for extended reading. Blue 600 accent is universally distinguishable.",
1856
+ wcagAA: true,
1857
+ wcagAAA: true
1858
+ },
1859
+ {
1860
+ id: "clear-signal",
1861
+ name: "Clear Signal",
1862
+ description: "Semantic color safe",
1863
+ category: "accessible",
1864
+ primary: "#1e293b",
1865
+ secondary: "#64748b",
1866
+ accent: "#7c3aed",
1867
+ harmony: "Analogous + Accent",
1868
+ bestFor: ["Medical Interfaces", "Critical Systems", "Accessibility-First"],
1869
+ rationale: "Slate 800 and 500 provide clear hierarchy. Violet 600 accent is visible to most color vision types and doesn't conflict with semantic red/green/yellow states. Reserves those colors for their intended meanings.",
1870
+ wcagAA: true,
1871
+ wcagAAA: true
1872
+ }
1873
+ ];
1874
+ function getPalettesByCategory(category) {
1875
+ return colorPalettes.filter((p) => p.category === category);
1876
+ }
1877
+ function getPalettesByMood(mood) {
1878
+ return colorPalettes.filter(
1879
+ (p) => p.description.toLowerCase().includes(mood.toLowerCase()) || p.rationale?.toLowerCase().includes(mood.toLowerCase()) || p.mood?.some((m) => m.toLowerCase().includes(mood.toLowerCase()))
1880
+ );
1881
+ }
1882
+ function getPalettesForUseCase(useCase) {
1883
+ return colorPalettes.filter(
1884
+ (p) => p.bestFor?.some((uc) => uc.toLowerCase().includes(useCase.toLowerCase()))
1885
+ );
1886
+ }
1887
+ function getAccessiblePalettes(level = "AA") {
1888
+ return colorPalettes.filter(
1889
+ (p) => level === "AAA" ? p.wcagAAA : p.wcagAA
1890
+ );
1891
+ }
1892
+
1893
+ // ../tokens/src/color-utils.ts
1894
+ function hexToRgb(hex) {
1895
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
1896
+ return result ? {
1897
+ r: parseInt(result[1], 16),
1898
+ g: parseInt(result[2], 16),
1899
+ b: parseInt(result[3], 16)
1900
+ } : null;
1901
+ }
1902
+ function hexToHSL(hex) {
1903
+ const rgb = hexToRgb(hex);
1904
+ if (!rgb) return { h: 0, s: 0, l: 0 };
1905
+ const r = rgb.r / 255;
1906
+ const g = rgb.g / 255;
1907
+ const b = rgb.b / 255;
1908
+ const max = Math.max(r, g, b);
1909
+ const min = Math.min(r, g, b);
1910
+ let h = 0, s = 0, l = (max + min) / 2;
1911
+ if (max !== min) {
1912
+ const d = max - min;
1913
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
1914
+ switch (max) {
1915
+ case r:
1916
+ h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
1917
+ break;
1918
+ case g:
1919
+ h = ((b - r) / d + 2) / 6;
1920
+ break;
1921
+ case b:
1922
+ h = ((r - g) / d + 4) / 6;
1923
+ break;
1924
+ }
1925
+ }
1926
+ return {
1927
+ h: Math.round(h * 360),
1928
+ s: Math.round(s * 100),
1929
+ l: Math.round(l * 100)
1930
+ };
1931
+ }
1932
+ function hslToHex(h, s, l) {
1933
+ h = h / 360;
1934
+ s = s / 100;
1935
+ l = l / 100;
1936
+ let r, g, b;
1937
+ if (s === 0) {
1938
+ r = g = b = l;
1939
+ } else {
1940
+ const hue2rgb = (p2, q2, t) => {
1941
+ if (t < 0) t += 1;
1942
+ if (t > 1) t -= 1;
1943
+ if (t < 1 / 6) return p2 + (q2 - p2) * 6 * t;
1944
+ if (t < 1 / 2) return q2;
1945
+ if (t < 2 / 3) return p2 + (q2 - p2) * (2 / 3 - t) * 6;
1946
+ return p2;
1947
+ };
1948
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
1949
+ const p = 2 * l - q;
1950
+ r = hue2rgb(p, q, h + 1 / 3);
1951
+ g = hue2rgb(p, q, h);
1952
+ b = hue2rgb(p, q, h - 1 / 3);
1953
+ }
1954
+ const toHex = (x) => {
1955
+ const hex = Math.round(x * 255).toString(16);
1956
+ return hex.length === 1 ? "0" + hex : hex;
1957
+ };
1958
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
1959
+ }
1960
+ function adjustLightness(hex, percent) {
1961
+ const hsl = hexToHSL(hex);
1962
+ const newL = Math.max(0, Math.min(100, hsl.l + percent));
1963
+ return hslToHex(hsl.h, hsl.s, newL);
1964
+ }
1965
+ function adjustSaturation(hex, percent) {
1966
+ const hsl = hexToHSL(hex);
1967
+ const newS = Math.max(0, Math.min(100, hsl.s + percent));
1968
+ return hslToHex(hsl.h, newS, hsl.l);
1969
+ }
1970
+ function rotateHue(hex, degrees) {
1971
+ const hsl = hexToHSL(hex);
1972
+ const newH = (hsl.h + degrees) % 360;
1973
+ return hslToHex(newH, hsl.s, hsl.l);
1974
+ }
1975
+ function adjustOpacity(hex, opacity) {
1976
+ const rgb = hexToRgb(hex);
1977
+ if (!rgb) return hex;
1978
+ return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${opacity})`;
1979
+ }
1980
+ function getLuminance(r, g, b) {
1981
+ const [rs, gs, bs] = [r, g, b].map((c) => {
1982
+ const srgb = c / 255;
1983
+ return srgb <= 0.03928 ? srgb / 12.92 : Math.pow((srgb + 0.055) / 1.055, 2.4);
1984
+ });
1985
+ return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;
1986
+ }
1987
+ function getContrastRatio(hex1, hex2) {
1988
+ const rgb1 = hexToRgb(hex1);
1989
+ const rgb2 = hexToRgb(hex2);
1990
+ if (!rgb1 || !rgb2) return 0;
1991
+ const lum1 = getLuminance(rgb1.r, rgb1.g, rgb1.b);
1992
+ const lum2 = getLuminance(rgb2.r, rgb2.g, rgb2.b);
1993
+ const lighter = Math.max(lum1, lum2);
1994
+ const darker = Math.min(lum1, lum2);
1995
+ return (lighter + 0.05) / (darker + 0.05);
1996
+ }
1997
+ function getOptimalForeground(bgHex, whiteHex = "#ffffff", blackHex = "#000000") {
1998
+ const whiteRatio = getContrastRatio(bgHex, whiteHex);
1999
+ const blackRatio = getContrastRatio(bgHex, blackHex);
2000
+ return whiteRatio > blackRatio ? whiteHex : blackHex;
2001
+ }
2002
+
2003
+ // ../tokens/src/token-graph.ts
2004
+ var primaryColorDerivations = {
2005
+ // Links use primary color
2006
+ "--color-link": {
2007
+ source: "--color-primary",
2008
+ transform: (primary) => primary,
2009
+ description: "Links inherit primary brand color"
2010
+ },
2011
+ // Focus ring uses primary color
2012
+ "--color-ring": {
2013
+ source: "--color-primary",
2014
+ transform: (primary) => primary,
2015
+ description: "Focus rings use primary for brand consistency"
2016
+ },
2017
+ // Link hover is slightly darker primary
2018
+ "--color-link-hover": {
2019
+ source: "--color-primary",
2020
+ transform: (primary) => adjustLightness(primary, -10),
2021
+ description: "Link hover is 10% darker for visual feedback"
2022
+ },
2023
+ // Chart primary series
2024
+ "--chart-1": {
2025
+ source: "--color-primary",
2026
+ transform: (primary) => primary,
2027
+ description: "First chart series uses primary"
2028
+ },
2029
+ // Chart secondary series (lighter tint)
2030
+ "--chart-2": {
2031
+ source: "--color-primary",
2032
+ transform: (primary) => adjustLightness(primary, 20),
2033
+ description: "Second chart series is lighter tint of primary"
2034
+ },
2035
+ // Chart tertiary series (darker shade)
2036
+ "--chart-3": {
2037
+ source: "--color-primary",
2038
+ transform: (primary) => adjustLightness(primary, -15),
2039
+ description: "Third chart series is darker shade of primary"
2040
+ },
2041
+ // Chart quaternary (desaturated primary)
2042
+ "--chart-4": {
2043
+ source: "--color-primary",
2044
+ transform: (primary) => adjustSaturation(primary, -30),
2045
+ description: "Fourth chart series is muted primary"
2046
+ },
2047
+ // Chart quinary (complementary color)
2048
+ "--chart-5": {
2049
+ source: "--color-primary",
2050
+ transform: (primary) => rotateHue(primary, 180),
2051
+ description: "Fifth chart series is complementary to primary"
2052
+ }
2053
+ };
2054
+ var secondaryColorDerivations = {
2055
+ // Hover states
2056
+ "--color-hover": {
2057
+ source: "--color-secondary",
2058
+ transform: (secondary) => secondary,
2059
+ description: "Hover backgrounds use secondary"
2060
+ },
2061
+ // Active states
2062
+ "--color-active": {
2063
+ source: "--color-secondary",
2064
+ transform: (secondary) => adjustLightness(secondary, -5),
2065
+ description: "Active state is slightly darker secondary"
2066
+ },
2067
+ // Muted backgrounds
2068
+ "--color-muted": {
2069
+ source: "--color-secondary",
2070
+ transform: (secondary) => secondary,
2071
+ description: "Muted sections use secondary color"
2072
+ }
2073
+ };
2074
+ var accentColorDerivations = {
2075
+ // Info semantic color uses accent
2076
+ "--color-info": {
2077
+ source: "--color-accent",
2078
+ transform: (accent) => accent,
2079
+ description: "Info semantic color uses accent"
2080
+ },
2081
+ // Info foreground calculated for contrast
2082
+ "--color-info-foreground": {
2083
+ source: "--color-accent",
2084
+ transform: (accent) => getOptimalForeground(accent),
2085
+ description: "Info foreground calculated for contrast"
2086
+ }
2087
+ };
2088
+ var modeSpecificDerivations = {
2089
+ "--color-primary-muted": {
2090
+ light: {
2091
+ source: "--color-primary",
2092
+ transform: (primary) => adjustLightness(primary, 40),
2093
+ description: "Muted primary for light backgrounds"
2094
+ },
2095
+ dark: {
2096
+ source: "--color-primary",
2097
+ transform: (primary) => adjustLightness(primary, -20),
2098
+ description: "Muted primary for dark backgrounds"
2099
+ }
2100
+ },
2101
+ "--color-primary-subtle": {
2102
+ light: {
2103
+ source: "--color-primary",
2104
+ transform: (primary) => adjustOpacity(primary, 0.1),
2105
+ description: "Subtle primary background for light mode"
2106
+ },
2107
+ dark: {
2108
+ source: "--color-primary",
2109
+ transform: (primary) => adjustOpacity(primary, 0.2),
2110
+ description: "Subtle primary background for dark mode"
2111
+ }
2112
+ }
2113
+ };
2114
+ var tokenDependencyGraph = {
2115
+ primary: primaryColorDerivations,
2116
+ secondary: secondaryColorDerivations,
2117
+ accent: accentColorDerivations,
2118
+ modeSpecific: modeSpecificDerivations
2119
+ };
2120
+ function getDependentTokens(sourceToken) {
2121
+ const dependents = [];
2122
+ Object.entries(primaryColorDerivations).forEach(([token, config]) => {
2123
+ if (config.source === sourceToken) {
2124
+ dependents.push(token);
2125
+ }
2126
+ });
2127
+ Object.entries(secondaryColorDerivations).forEach(([token, config]) => {
2128
+ if (config.source === sourceToken) {
2129
+ dependents.push(token);
2130
+ }
2131
+ });
2132
+ Object.entries(accentColorDerivations).forEach(([token, config]) => {
2133
+ if (config.source === sourceToken) {
2134
+ dependents.push(token);
2135
+ }
2136
+ });
2137
+ return dependents;
2138
+ }
2139
+ function computeDerivedTokens(sourceToken, sourceValue, mode) {
2140
+ const derived = {};
2141
+ Object.entries(primaryColorDerivations).forEach(([token, config]) => {
2142
+ if (config.source === sourceToken) {
2143
+ derived[token] = config.transform(sourceValue);
2144
+ }
2145
+ });
2146
+ Object.entries(secondaryColorDerivations).forEach(([token, config]) => {
2147
+ if (config.source === sourceToken) {
2148
+ derived[token] = config.transform(sourceValue);
2149
+ }
2150
+ });
2151
+ Object.entries(accentColorDerivations).forEach(([token, config]) => {
2152
+ if (config.source === sourceToken) {
2153
+ derived[token] = config.transform(sourceValue);
2154
+ }
2155
+ });
2156
+ Object.entries(modeSpecificDerivations).forEach(([token, configs]) => {
2157
+ const config = configs[mode];
2158
+ if (config.source === sourceToken) {
2159
+ derived[token] = config.transform(sourceValue);
2160
+ }
2161
+ });
2162
+ return derived;
2163
+ }
2164
+
2165
+ // ../tokens/src/fontThemes.ts
2166
+ var fontThemes = [
2167
+ // === PROFESSIONAL ===
2168
+ {
2169
+ id: "studio",
2170
+ name: "Studio",
2171
+ description: "Professional and balanced, perfect for modern SaaS products",
2172
+ category: "professional",
2173
+ heading: "Outfit",
2174
+ body: "Manrope",
2175
+ mono: "Fira Code",
2176
+ headingWeight: "700",
2177
+ bodyWeight: "400",
2178
+ letterSpacing: { heading: "-0.02em", body: "0" },
2179
+ lineHeight: { heading: "1.2", body: "1.6" },
2180
+ wcagReadable: true,
2181
+ mood: ["professional", "modern", "clean"],
2182
+ bestFor: "SaaS products, business sites, dashboards",
2183
+ pairing: "Sans + Sans (Geometric + Humanist)"
2184
+ },
2185
+ {
2186
+ id: "modern-swiss",
2187
+ name: "Modern Swiss",
2188
+ description: "Clean and neutral, maximum readability",
2189
+ category: "professional",
2190
+ heading: "Inter",
2191
+ body: "Inter",
2192
+ mono: "JetBrains Mono",
2193
+ headingWeight: "700",
2194
+ bodyWeight: "400",
2195
+ letterSpacing: { heading: "-0.02em", body: "0" },
2196
+ lineHeight: { heading: "1.2", body: "1.7" },
2197
+ wcagReadable: true,
2198
+ mood: ["minimal", "clean", "modern"],
2199
+ bestFor: "Documentation, dashboards, data-heavy UIs",
2200
+ pairing: "Sans (Single Font)"
2201
+ },
2202
+ {
2203
+ id: "corporate-authority",
2204
+ name: "Corporate Authority",
2205
+ description: "Classic sans-serif with technical precision",
2206
+ category: "professional",
2207
+ heading: "Roboto",
2208
+ body: "Roboto",
2209
+ mono: "Roboto Mono",
2210
+ headingWeight: "700",
2211
+ bodyWeight: "400",
2212
+ letterSpacing: { heading: "-0.01em", body: "0" },
2213
+ lineHeight: { heading: "1.2", body: "1.6" },
2214
+ wcagReadable: true,
2215
+ mood: ["corporate", "reliable", "neutral"],
2216
+ bestFor: "Enterprise software, Google-style products, admin panels",
2217
+ pairing: "Sans (Roboto Family)"
2218
+ },
2219
+ // === EDITORIAL ===
2220
+ {
2221
+ id: "sage",
2222
+ name: "Sage",
2223
+ description: "Elegant serif heading with clean sans body",
2224
+ category: "editorial",
2225
+ heading: "Lora",
2226
+ body: "Instrument Sans",
2227
+ mono: "Fira Code",
2228
+ headingWeight: "600",
2229
+ bodyWeight: "400",
2230
+ letterSpacing: { heading: "-0.01em", body: "0" },
2231
+ lineHeight: { heading: "1.3", body: "1.7" },
2232
+ wcagReadable: true,
2233
+ mood: ["elegant", "warm", "organic"],
2234
+ bestFor: "Editorial sites, blogs, portfolios",
2235
+ pairing: "Serif + Sans (Classic Editorial)"
2236
+ },
2237
+ {
2238
+ id: "editorial-classic",
2239
+ name: "Editorial Classic",
2240
+ description: "Timeless serif pairing for long-form content",
2241
+ category: "editorial",
2242
+ heading: "Playfair Display",
2243
+ body: "Source Sans Pro",
2244
+ mono: "Fira Code",
2245
+ headingWeight: "700",
2246
+ bodyWeight: "400",
2247
+ letterSpacing: { heading: "0", body: "0" },
2248
+ lineHeight: { heading: "1.2", body: "1.7" },
2249
+ wcagReadable: true,
2250
+ mood: ["classic", "elegant", "readable"],
2251
+ bestFor: "Magazines, blogs, long-form articles",
2252
+ pairing: "Serif + Sans (High Contrast)"
2253
+ },
2254
+ {
2255
+ id: "literary",
2256
+ name: "Literary",
2257
+ description: "Sophisticated serif pairing for premium content",
2258
+ category: "editorial",
2259
+ heading: "Merriweather",
2260
+ body: "Lato",
2261
+ mono: "Fira Code",
2262
+ headingWeight: "700",
2263
+ bodyWeight: "400",
2264
+ letterSpacing: { heading: "0", body: "0" },
2265
+ lineHeight: { heading: "1.3", body: "1.7" },
2266
+ wcagReadable: true,
2267
+ mood: ["sophisticated", "literary", "warm"],
2268
+ bestFor: "Publishing, literary journals, premium blogs",
2269
+ pairing: "Serif + Sans (Warm & Readable)"
2270
+ },
2271
+ // === TECH ===
2272
+ {
2273
+ id: "volt",
2274
+ name: "Volt",
2275
+ description: "Bold and electric, one font for everything",
2276
+ category: "tech",
2277
+ heading: "Space Grotesk",
2278
+ body: "Space Grotesk",
2279
+ mono: "Fira Code",
2280
+ headingWeight: "700",
2281
+ bodyWeight: "400",
2282
+ letterSpacing: { heading: "-0.03em", body: "0" },
2283
+ lineHeight: { heading: "1.2", body: "1.6" },
2284
+ wcagReadable: true,
2285
+ mood: ["bold", "modern", "tech"],
2286
+ bestFor: "Tech startups, developer tools, portfolios",
2287
+ pairing: "Sans (Single Font)"
2288
+ },
2289
+ {
2290
+ id: "tech-mono",
2291
+ name: "Tech Monospace",
2292
+ description: "Monospace everything, for the hackers",
2293
+ category: "tech",
2294
+ heading: "JetBrains Mono",
2295
+ body: "JetBrains Mono",
2296
+ mono: "JetBrains Mono",
2297
+ headingWeight: "700",
2298
+ bodyWeight: "400",
2299
+ letterSpacing: { heading: "0", body: "0" },
2300
+ lineHeight: { heading: "1.2", body: "1.6" },
2301
+ wcagReadable: true,
2302
+ mood: ["tech", "hacker", "minimal"],
2303
+ bestFor: "Developer tools, coding tutorials, terminal UIs",
2304
+ pairing: "Mono (Single Font)"
2305
+ },
2306
+ {
2307
+ id: "dev-tools",
2308
+ name: "Dev Tools",
2309
+ description: "GitHub-inspired clean technical aesthetic",
2310
+ category: "tech",
2311
+ heading: "IBM Plex Sans",
2312
+ body: "IBM Plex Sans",
2313
+ mono: "IBM Plex Mono",
2314
+ headingWeight: "600",
2315
+ bodyWeight: "400",
2316
+ letterSpacing: { heading: "-0.01em", body: "0" },
2317
+ lineHeight: { heading: "1.2", body: "1.6" },
2318
+ wcagReadable: true,
2319
+ mood: ["technical", "precise", "modern"],
2320
+ bestFor: "Developer platforms, code editors, documentation",
2321
+ pairing: "Sans (IBM Plex Family)"
2322
+ },
2323
+ // === FRIENDLY ===
2324
+ {
2325
+ id: "friendly-rounded",
2326
+ name: "Friendly & Rounded",
2327
+ description: "Approachable and warm, great for consumer apps",
2328
+ category: "friendly",
2329
+ heading: "Quicksand",
2330
+ body: "Open Sans",
2331
+ mono: "Fira Code",
2332
+ headingWeight: "600",
2333
+ bodyWeight: "400",
2334
+ letterSpacing: { heading: "0", body: "0" },
2335
+ lineHeight: { heading: "1.3", body: "1.7" },
2336
+ wcagReadable: true,
2337
+ mood: ["friendly", "approachable", "warm"],
2338
+ bestFor: "Consumer apps, education, healthcare",
2339
+ pairing: "Rounded Sans + Humanist Sans"
2340
+ },
2341
+ {
2342
+ id: "warm-welcome",
2343
+ name: "Warm Welcome",
2344
+ description: "Inviting and accessible for all audiences",
2345
+ category: "friendly",
2346
+ heading: "Nunito",
2347
+ body: "Nunito Sans",
2348
+ mono: "Fira Code",
2349
+ headingWeight: "700",
2350
+ bodyWeight: "400",
2351
+ letterSpacing: { heading: "-0.01em", body: "0" },
2352
+ lineHeight: { heading: "1.3", body: "1.7" },
2353
+ wcagReadable: true,
2354
+ mood: ["welcoming", "friendly", "accessible"],
2355
+ bestFor: "Community platforms, education, non-profits",
2356
+ pairing: "Rounded Sans (Nunito Family)"
2357
+ },
2358
+ // === MINIMAL ===
2359
+ {
2360
+ id: "minimal-sans",
2361
+ name: "Minimal Sans",
2362
+ description: "Pure simplicity with Work Sans",
2363
+ category: "minimal",
2364
+ heading: "Work Sans",
2365
+ body: "Work Sans",
2366
+ mono: "Fira Code",
2367
+ headingWeight: "600",
2368
+ bodyWeight: "400",
2369
+ letterSpacing: { heading: "-0.02em", body: "0" },
2370
+ lineHeight: { heading: "1.2", body: "1.6" },
2371
+ wcagReadable: true,
2372
+ mood: ["minimal", "clean", "efficient"],
2373
+ bestFor: "Minimalist sites, portfolios, agencies",
2374
+ pairing: "Sans (Single Font)"
2375
+ },
2376
+ {
2377
+ id: "system-ui",
2378
+ name: "System UI",
2379
+ description: "Native system fonts for instant familiarity",
2380
+ category: "minimal",
2381
+ heading: "System UI",
2382
+ body: "System UI",
2383
+ mono: "SF Mono",
2384
+ headingWeight: "700",
2385
+ bodyWeight: "400",
2386
+ letterSpacing: { heading: "-0.01em", body: "0" },
2387
+ lineHeight: { heading: "1.2", body: "1.6" },
2388
+ wcagReadable: true,
2389
+ mood: ["native", "fast", "familiar"],
2390
+ bestFor: "Performance-critical apps, utilities, system tools",
2391
+ pairing: "System Fonts (Zero Load Time)"
2392
+ },
2393
+ // === LUXURY ===
2394
+ {
2395
+ id: "luxury-serif",
2396
+ name: "Luxury Serif",
2397
+ description: "Sophisticated and high-end",
2398
+ category: "luxury",
2399
+ heading: "Cormorant Garamond",
2400
+ body: "Raleway",
2401
+ mono: "Fira Code",
2402
+ headingWeight: "600",
2403
+ bodyWeight: "300",
2404
+ letterSpacing: { heading: "0.02em", body: "0.01em" },
2405
+ lineHeight: { heading: "1.3", body: "1.7" },
2406
+ wcagReadable: false,
2407
+ // Thinner weights
2408
+ mood: ["luxury", "elegant", "sophisticated"],
2409
+ bestFor: "Fashion, luxury brands, high-end services",
2410
+ pairing: "Serif + Thin Sans"
2411
+ },
2412
+ {
2413
+ id: "prestige",
2414
+ name: "Prestige",
2415
+ description: "Refined elegance with Bodoni-inspired display",
2416
+ category: "luxury",
2417
+ heading: "Libre Bodoni",
2418
+ body: "Montserrat",
2419
+ mono: "Fira Code",
2420
+ headingWeight: "700",
2421
+ bodyWeight: "300",
2422
+ letterSpacing: { heading: "0.03em", body: "0.02em" },
2423
+ lineHeight: { heading: "1.2", body: "1.7" },
2424
+ wcagReadable: false,
2425
+ // Display font + thin weight
2426
+ mood: ["prestige", "refined", "luxurious"],
2427
+ bestFor: "Luxury fashion, jewelry, premium services",
2428
+ pairing: "Serif Display + Geometric Sans"
2429
+ },
2430
+ // === CREATIVE ===
2431
+ {
2432
+ id: "creative-bold",
2433
+ name: "Creative Bold",
2434
+ description: "Strong personality with Poppins",
2435
+ category: "creative",
2436
+ heading: "Poppins",
2437
+ body: "Poppins",
2438
+ mono: "Fira Code",
2439
+ headingWeight: "700",
2440
+ bodyWeight: "400",
2441
+ letterSpacing: { heading: "-0.01em", body: "0" },
2442
+ lineHeight: { heading: "1.2", body: "1.6" },
2443
+ wcagReadable: true,
2444
+ mood: ["bold", "creative", "energetic"],
2445
+ bestFor: "Creative agencies, portfolios, marketing sites",
2446
+ pairing: "Geometric Sans (Single Font)"
2447
+ },
2448
+ {
2449
+ id: "artistic-flair",
2450
+ name: "Artistic Flair",
2451
+ description: "Expressive serif with modern sans",
2452
+ category: "creative",
2453
+ heading: "Abril Fatface",
2454
+ body: "Work Sans",
2455
+ mono: "Fira Code",
2456
+ headingWeight: "400",
2457
+ bodyWeight: "400",
2458
+ letterSpacing: { heading: "0", body: "0" },
2459
+ lineHeight: { heading: "1.1", body: "1.6" },
2460
+ wcagReadable: true,
2461
+ mood: ["artistic", "expressive", "bold"],
2462
+ bestFor: "Art galleries, creative studios, designer portfolios",
2463
+ pairing: "Display Serif + Neutral Sans"
2464
+ },
2465
+ // === PLAYFUL ===
2466
+ {
2467
+ id: "playful-rounded",
2468
+ name: "Playful Rounded",
2469
+ description: "Fun and energetic for youth audiences",
2470
+ category: "playful",
2471
+ heading: "Fredoka",
2472
+ body: "Karla",
2473
+ mono: "Fira Code",
2474
+ headingWeight: "700",
2475
+ bodyWeight: "400",
2476
+ letterSpacing: { heading: "0", body: "0" },
2477
+ lineHeight: { heading: "1.3", body: "1.6" },
2478
+ wcagReadable: true,
2479
+ mood: ["playful", "fun", "youthful"],
2480
+ bestFor: "Kids apps, games, entertainment",
2481
+ pairing: "Rounded Display + Grotesque Sans"
2482
+ }
2483
+ ];
2484
+ function getFontThemesByCategory(category) {
2485
+ return fontThemes.filter((ft) => ft.category === category);
2486
+ }
2487
+ function getFontThemesByMood(mood) {
2488
+ return fontThemes.filter(
2489
+ (ft) => ft.description.toLowerCase().includes(mood.toLowerCase()) || ft.bestFor?.toLowerCase().includes(mood.toLowerCase()) || ft.mood?.some((m) => m.toLowerCase().includes(mood.toLowerCase()))
2490
+ );
2491
+ }
2492
+ function getFontThemesForUseCase(useCase) {
2493
+ return fontThemes.filter(
2494
+ (ft) => ft.bestFor?.toLowerCase().includes(useCase.toLowerCase())
2495
+ );
2496
+ }
2497
+ function getAccessibleFontThemes() {
2498
+ return fontThemes.filter((ft) => ft.wcagReadable === true);
2499
+ }
2500
+ function getFontThemeById(id) {
2501
+ return fontThemes.find((ft) => ft.id === id);
2502
+ }
2503
+ function generateScale(fontTheme) {
2504
+ const headingWeight = parseInt(fontTheme.headingWeight || "700", 10);
2505
+ const bodyWeight = parseInt(fontTheme.bodyWeight || "400", 10);
2506
+ const headingLetterSpacing = fontTheme.letterSpacing?.heading || "-0.02em";
2507
+ const bodyLetterSpacing = fontTheme.letterSpacing?.body || "0";
2508
+ const headingLineHeight = parseFloat(fontTheme.lineHeight?.heading || "1.2");
2509
+ const bodyLineHeight = parseFloat(fontTheme.lineHeight?.body || "1.6");
2510
+ return {
2511
+ display: {
2512
+ fontFamily: fontTheme.heading,
2513
+ weight: Math.min(headingWeight + 100, 800),
2514
+ // Slightly bolder for display
2515
+ size: 96,
2516
+ lineHeight: 1.1,
2517
+ letterSpacing: "-0.03em"
2518
+ },
2519
+ h1: {
2520
+ fontFamily: fontTheme.heading,
2521
+ weight: headingWeight,
2522
+ size: 64,
2523
+ lineHeight: headingLineHeight,
2524
+ letterSpacing: headingLetterSpacing
2525
+ },
2526
+ h2: {
2527
+ fontFamily: fontTheme.heading,
2528
+ weight: Math.max(headingWeight - 100, 600),
2529
+ // Slightly lighter than H1
2530
+ size: 48,
2531
+ lineHeight: 1.3,
2532
+ letterSpacing: headingLetterSpacing === "-0.02em" ? "-0.01em" : headingLetterSpacing
2533
+ },
2534
+ h3: {
2535
+ fontFamily: fontTheme.heading,
2536
+ weight: Math.max(headingWeight - 100, 600),
2537
+ size: 36,
2538
+ lineHeight: 1.3,
2539
+ letterSpacing: "0"
2540
+ },
2541
+ h4: {
2542
+ fontFamily: fontTheme.heading,
2543
+ weight: Math.max(headingWeight - 100, 600),
2544
+ size: 24,
2545
+ lineHeight: 1.4,
2546
+ letterSpacing: "0"
2547
+ },
2548
+ body: {
2549
+ fontFamily: fontTheme.body,
2550
+ weight: bodyWeight,
2551
+ size: 16,
2552
+ lineHeight: bodyLineHeight,
2553
+ letterSpacing: bodyLetterSpacing
2554
+ },
2555
+ small: {
2556
+ fontFamily: fontTheme.body,
2557
+ weight: bodyWeight,
2558
+ size: 14,
2559
+ lineHeight: 1.5,
2560
+ letterSpacing: "0.01em"
2561
+ },
2562
+ code: {
2563
+ fontFamily: fontTheme.mono,
2564
+ weight: 400,
2565
+ // Code is typically regular weight
2566
+ size: 14,
2567
+ lineHeight: 1.4,
2568
+ letterSpacing: "0"
2569
+ }
2570
+ };
2571
+ }
2572
+
2573
+ // ../tokens/src/index.ts
2574
+ var THEME_NAMES = ["studio", "terra", "volt", "speedboat"];
2575
+ var PUBLIC_THEME_NAMES = ["studio", "terra", "volt"];
2576
+ var COLOR_MODES = ["light", "dark"];
2577
+ // Annotate the CommonJS export names for ESM import in node:
2578
+ 0 && (module.exports = {
2579
+ COLOR_MODES,
2580
+ PUBLIC_THEME_NAMES,
2581
+ THEME_NAMES,
2582
+ accentColorDerivations,
2583
+ adjustLightness,
2584
+ adjustOpacity,
2585
+ adjustSaturation,
2586
+ baseTokens,
2587
+ codeColors,
2588
+ colorPalettes,
2589
+ computeDerivedTokens,
2590
+ fontFamilies,
2591
+ fontLoadingConfig,
2592
+ fontSizes,
2593
+ fontThemes,
2594
+ fontWeights,
2595
+ generateScale,
2596
+ getAccessibleFontThemes,
2597
+ getAccessiblePalettes,
2598
+ getContrastRatio,
2599
+ getDependentTokens,
2600
+ getFontThemeById,
2601
+ getFontThemesByCategory,
2602
+ getFontThemesByMood,
2603
+ getFontThemesForUseCase,
2604
+ getFontVariable,
2605
+ getLuminance,
2606
+ getOptimalForeground,
2607
+ getPalettesByCategory,
2608
+ getPalettesByMood,
2609
+ getPalettesForUseCase,
2610
+ getResponsiveFontSize,
2611
+ getThemeFontVariables,
2612
+ hexToHSL,
2613
+ hexToRgb,
2614
+ hslToHex,
2615
+ letterSpacing,
2616
+ lineHeights,
2617
+ modeSpecificDerivations,
2618
+ motion,
2619
+ primaryColorDerivations,
2620
+ rotateHue,
2621
+ secondaryColorDerivations,
2622
+ semanticLetterSpacing,
2623
+ semanticLineHeights,
2624
+ semanticSizes,
2625
+ semanticWeights,
2626
+ spacing,
2627
+ speedboatTokens,
2628
+ studioTokens,
2629
+ syntaxColors,
2630
+ terraTokens,
2631
+ tokenDependencyGraph,
2632
+ typePresets,
2633
+ typography,
2634
+ typographySystem,
2635
+ voltTokens
2636
+ });
2637
+ //# sourceMappingURL=tokens.js.map