@evolve.ui/theme-system 1.0.1 → 1.2.0

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 (119) hide show
  1. package/{allThemes-CFS_9-tk.cjs → allThemes-3d8nhymo.cjs} +12 -2
  2. package/allThemes-3d8nhymo.cjs.map +1 -0
  3. package/{allThemes-OV-ayn4C.mjs → allThemes-Abn6KDm7.mjs} +7 -3
  4. package/allThemes-Abn6KDm7.mjs.map +1 -0
  5. package/allThemes.cjs +1 -1
  6. package/allThemes.d.cts +1 -0
  7. package/allThemes.d.cts.map +1 -1
  8. package/allThemes.d.mts +1 -0
  9. package/allThemes.d.mts.map +1 -1
  10. package/allThemes.mjs +1 -1
  11. package/brands-CE0wIkKX.d.cts +58 -0
  12. package/brands-CE0wIkKX.d.cts.map +1 -0
  13. package/brands-CE0wIkKX.d.mts +58 -0
  14. package/brands-CE0wIkKX.d.mts.map +1 -0
  15. package/brands.cjs +16 -13
  16. package/brands.cjs.map +1 -1
  17. package/brands.d.cts +2 -2
  18. package/brands.d.mts +2 -2
  19. package/brands.mjs +16 -13
  20. package/brands.mjs.map +1 -1
  21. package/css/EverydayHarbor.css +377 -0
  22. package/css/EverydayHarbor.effects.css +650 -0
  23. package/{default-b-tgfyxR.cjs → default-B6VWF0Js.cjs} +237 -36
  24. package/default-B6VWF0Js.cjs.map +1 -0
  25. package/{default-B2n4PnsJ.mjs → default-BogJDhKE.mjs} +238 -37
  26. package/default-BogJDhKE.mjs.map +1 -0
  27. package/effects.cjs +26 -0
  28. package/effects.cjs.map +1 -0
  29. package/effects.d.cts +22 -0
  30. package/effects.d.cts.map +1 -0
  31. package/effects.d.mts +22 -0
  32. package/effects.d.mts.map +1 -0
  33. package/effects.mjs +22 -0
  34. package/effects.mjs.map +1 -0
  35. package/evolve-ui.entries.json +51 -0
  36. package/index.cjs +12 -5
  37. package/index.cjs.map +1 -1
  38. package/index.d.cts +108 -4
  39. package/index.d.cts.map +1 -1
  40. package/index.d.mts +108 -4
  41. package/index.d.mts.map +1 -1
  42. package/index.mjs +9 -6
  43. package/index.mjs.map +1 -1
  44. package/package.json +5 -1
  45. package/{plugin-DPtvp4lp.cjs → plugin-B3PF4RMI.cjs} +299 -110
  46. package/plugin-B3PF4RMI.cjs.map +1 -0
  47. package/{plugin-D4eCyUJe.mjs → plugin-D6aLCeNB.mjs} +258 -111
  48. package/plugin-D6aLCeNB.mjs.map +1 -0
  49. package/src/effects/__fixtures__/fixtureLayer.ts +88 -0
  50. package/src/effects/brands/EverydayHarbor.ts +392 -0
  51. package/src/effects/classes.ts +19 -0
  52. package/src/effects/emit.ts +314 -0
  53. package/src/effects/hooks.ts +493 -0
  54. package/src/effects/index.ts +2 -0
  55. package/src/effects/layers.ts +18 -0
  56. package/src/effects/rules.ts +90 -0
  57. package/src/effects/rules.typecheck.ts +50 -0
  58. package/src/effects/tokens.ts +148 -0
  59. package/src/effects/validate.ts +683 -0
  60. package/src/effects/vocabulary.ts +32 -0
  61. package/src/index.ts +40 -0
  62. package/src/tailwind/animation.ts +30 -0
  63. package/src/tailwind/borderRadius.ts +32 -0
  64. package/src/tailwind/borderWidth.ts +14 -0
  65. package/src/tailwind/boxShadow.ts +19 -0
  66. package/src/tailwind/colors.ts +332 -0
  67. package/src/tailwind/cssVars.ts +301 -0
  68. package/src/tailwind/fontFamily.ts +14 -0
  69. package/src/tailwind/plugin.ts +299 -0
  70. package/src/tailwind/reducedMotion.ts +164 -0
  71. package/src/tailwind/screens.ts +22 -0
  72. package/src/tailwind/spacing.ts +20 -0
  73. package/src/tailwind/text.ts +172 -0
  74. package/src/tailwind/width.ts +14 -0
  75. package/src/themeValues.snapshot.ts +6735 -0
  76. package/src/themes/BasketballTraining.ts +166 -0
  77. package/src/themes/Default.ts +165 -0
  78. package/src/themes/EverydayHarbor.ts +147 -0
  79. package/src/themes/ProfessionalBrand.ts +166 -0
  80. package/src/themes/allThemes.ts +14 -0
  81. package/src/themes/brandSources.ts +37 -0
  82. package/src/themes/brands.ts +63 -0
  83. package/src/themes/common.ts +65 -0
  84. package/src/themes/contrastFloors.ts +26 -0
  85. package/src/themes/generateCSSVars.ts +123 -0
  86. package/src/themes/inkRamps.ts +43 -0
  87. package/src/themes/runtime/basketballTraining.ts +3 -0
  88. package/src/themes/runtime/buildTheme.ts +411 -0
  89. package/src/themes/runtime/default.ts +3 -0
  90. package/src/themes/runtime/everydayHarbor.ts +3 -0
  91. package/src/themes/runtime/professionalBrand.ts +3 -0
  92. package/src/themes/semanticColorTokenSteps.ts +23 -0
  93. package/src/themes/themeType.ts +169 -0
  94. package/src/themes/themeValues.ts +374 -0
  95. package/src/themes/wcag.ts +48 -0
  96. package/src/themes/writeToCSSFile.ts +11 -0
  97. package/src/utils/cn.ts +35 -0
  98. package/src/utils/color.ts +82 -0
  99. package/src/utils/wrapVar.ts +24 -0
  100. package/tailwind/plugin.cjs +5 -1
  101. package/tailwind/plugin.d.cts +458 -1
  102. package/tailwind/plugin.d.cts.map +1 -1
  103. package/tailwind/plugin.d.mts +458 -1
  104. package/tailwind/plugin.d.mts.map +1 -1
  105. package/tailwind/plugin.mjs +2 -2
  106. package/themes/runtime/default.cjs +1 -1
  107. package/themes/runtime/default.mjs +1 -1
  108. package/themes/themeType.d.cts +1 -1
  109. package/themes/themeType.d.mts +1 -1
  110. package/allThemes-CFS_9-tk.cjs.map +0 -1
  111. package/allThemes-OV-ayn4C.mjs.map +0 -1
  112. package/brands-n30rolHQ.d.cts +0 -33
  113. package/brands-n30rolHQ.d.cts.map +0 -1
  114. package/brands-n30rolHQ.d.mts +0 -33
  115. package/brands-n30rolHQ.d.mts.map +0 -1
  116. package/default-B2n4PnsJ.mjs.map +0 -1
  117. package/default-b-tgfyxR.cjs.map +0 -1
  118. package/plugin-D4eCyUJe.mjs.map +0 -1
  119. package/plugin-DPtvp4lp.cjs.map +0 -1
@@ -0,0 +1,411 @@
1
+ import type { Brands } from '../brands';
2
+ import type { CleanTheme, Theme, TypographySpec } from '../themeType';
3
+
4
+ import { boxShadow } from '../../tailwind/boxShadow';
5
+ import * as cssVars from '../../tailwind/cssVars';
6
+ import { fontFamily } from '../../tailwind/fontFamily';
7
+ import { brandSources } from '../brandSources';
8
+ import { breakpoints, radius, spacing, width } from '../common';
9
+
10
+ const variable = (name: string): string => `var(${name})`;
11
+
12
+ type TextSpecInput = Omit<TypographySpec, 'family' | 'style'> & {
13
+ family?: TypographySpec['family'];
14
+ };
15
+
16
+ const textSpec = ({
17
+ family = fontFamily.primary,
18
+ height,
19
+ size,
20
+ spacing: letterSpacing,
21
+ transform,
22
+ weight,
23
+ }: TextSpecInput): TypographySpec => ({
24
+ family,
25
+ height,
26
+ size,
27
+ spacing: letterSpacing,
28
+ style: 'normal',
29
+ transform,
30
+ weight,
31
+ });
32
+
33
+ const buildTypography = (): Theme['typography'] => {
34
+ const bodyPrimary = textSpec({
35
+ height: '24px',
36
+ size: '16px',
37
+ spacing: variable(cssVars.letterSpacingBodyPrimary),
38
+ weight: variable(cssVars.fontWeightBodyPrimary),
39
+ });
40
+ const bodySecondary = textSpec({
41
+ height: '22px',
42
+ size: '14px',
43
+ spacing: variable(cssVars.letterSpacingBodySecondary),
44
+ weight: variable(cssVars.fontWeightBodySecondary),
45
+ });
46
+
47
+ return {
48
+ body: {
49
+ primary: bodyPrimary,
50
+ secondary: bodySecondary,
51
+ },
52
+ button: {
53
+ '100': textSpec({
54
+ height: '20px',
55
+ size: variable(cssVars.fontSizeButton100),
56
+ spacing: variable(cssVars.letterSpacingButton),
57
+ transform: variable(cssVars.textTransformButton),
58
+ weight: variable(cssVars.fontWeightButton),
59
+ }),
60
+ '200': textSpec({
61
+ height: '18px',
62
+ size: variable(cssVars.fontSizeButton200),
63
+ spacing: variable(cssVars.letterSpacingButton),
64
+ transform: variable(cssVars.textTransformButton),
65
+ weight: variable(cssVars.fontWeightButton),
66
+ }),
67
+ },
68
+ caption: {
69
+ '100': textSpec({
70
+ height: '18px',
71
+ size: '12px',
72
+ spacing: variable(cssVars.letterSpacingCaption),
73
+ weight: variable(cssVars.fontWeightCaption),
74
+ }),
75
+ },
76
+ heading: {
77
+ '000': textSpec({
78
+ family: fontFamily.secondary,
79
+ height: '56px',
80
+ size: '40px',
81
+ spacing: variable(cssVars.letterSpacingH1),
82
+ weight: variable(cssVars.fontWeightH1),
83
+ }),
84
+ '100': {
85
+ ...textSpec({
86
+ family: fontFamily.secondary,
87
+ height: '48px',
88
+ size: '32px',
89
+ spacing: variable(cssVars.letterSpacingH1),
90
+ weight: variable(cssVars.fontWeightH1),
91
+ }),
92
+ mobile: textSpec({
93
+ family: fontFamily.secondary,
94
+ height: '36px',
95
+ size: '24px',
96
+ spacing: variable(cssVars.letterSpacingH1Mobile),
97
+ weight: variable(cssVars.fontWeightH1),
98
+ }),
99
+ },
100
+ '200': {
101
+ ...textSpec({
102
+ family: fontFamily.secondary,
103
+ height: '36px',
104
+ size: '24px',
105
+ spacing: variable(cssVars.letterSpacingH2),
106
+ weight: variable(cssVars.fontWeightH2),
107
+ }),
108
+ mobile: textSpec({
109
+ family: fontFamily.secondary,
110
+ height: '30px',
111
+ size: '20px',
112
+ spacing: variable(cssVars.letterSpacingH2Mobile),
113
+ weight: variable(cssVars.fontWeightH2),
114
+ }),
115
+ },
116
+ '300': {
117
+ ...textSpec({
118
+ family: fontFamily.secondary,
119
+ height: '30px',
120
+ size: '20px',
121
+ spacing: variable(cssVars.letterSpacingH3),
122
+ weight: variable(cssVars.fontWeightH3),
123
+ }),
124
+ // Mirrors `.hui-text-h3`'s mobile block in `tailwind/text.ts` — keep in lockstep
125
+ // (DS-97 / SA-04; `tailwind/text.spec.ts` binds the two).
126
+ mobile: textSpec({
127
+ family: fontFamily.secondary,
128
+ height: '27px',
129
+ size: '18px',
130
+ spacing: variable(cssVars.letterSpacingH3Mobile),
131
+ weight: variable(cssVars.fontWeightH3),
132
+ }),
133
+ },
134
+ '400': textSpec({
135
+ family: fontFamily.secondary,
136
+ height: '24px',
137
+ size: '16px',
138
+ spacing: variable(cssVars.letterSpacingH4),
139
+ weight: variable(cssVars.fontWeightH4),
140
+ }),
141
+ '500': textSpec({
142
+ height: '24px',
143
+ size: '16px',
144
+ spacing: variable(cssVars.letterSpacingH5),
145
+ weight: variable(cssVars.fontWeightH5),
146
+ }),
147
+ '600': textSpec({
148
+ height: '22px',
149
+ size: '14px',
150
+ spacing: variable(cssVars.letterSpacingH6),
151
+ transform: variable(cssVars.textTransformH6),
152
+ weight: variable(cssVars.fontWeightH6),
153
+ }),
154
+ },
155
+ label: {
156
+ mini: textSpec({
157
+ height: '14px',
158
+ size: '12px',
159
+ spacing: variable(cssVars.letterSpacingLabelMini),
160
+ transform: variable(cssVars.textTransformLabelMini),
161
+ weight: variable(cssVars.fontWeightLabelMini),
162
+ }),
163
+ strong: textSpec({
164
+ height: '22px',
165
+ size: '14px',
166
+ spacing: variable(cssVars.letterSpacingLabelStrong),
167
+ weight: variable(cssVars.fontWeightLabelStrong),
168
+ }),
169
+ },
170
+ };
171
+ };
172
+
173
+ export const buildRuntimeTheme = (brand: Brands): CleanTheme => {
174
+ const source = brandSources[brand];
175
+ const v = variable;
176
+
177
+ return {
178
+ border: {
179
+ radius,
180
+ width,
181
+ },
182
+ brand,
183
+ breakpoints,
184
+ button: {
185
+ border: { radius: v(cssVars.buttonBorderRadius) },
186
+ favorite: {
187
+ default: {
188
+ color: { background: v(cssVars.colorBackgroundPrimary), border: v(cssVars.colorBorderPrimary) },
189
+ },
190
+ disabled: {
191
+ color: { background: v(cssVars.colorBackgroundDisabled), border: v(cssVars.colorBorderDisabled) },
192
+ },
193
+ hover: { color: { background: v(cssVars.colorBackgroundHover), border: v(cssVars.colorBorderHover) } },
194
+ pressed: {
195
+ color: { background: v(cssVars.colorBackgroundPressed), border: v(cssVars.colorBorderSelected) },
196
+ },
197
+ selected: {
198
+ color: { background: v(cssVars.colorBackgroundPrimary), border: v(cssVars.colorBorderSelected) },
199
+ },
200
+ },
201
+ inline: {
202
+ alt: {
203
+ default: { color: { text: v(cssVars.colorLinkInverse) } },
204
+ hover: { color: { text: v(cssVars.colorLinkInverseHover) } },
205
+ pressed: { color: { text: v(cssVars.colorLinkInversePressed) } },
206
+ },
207
+ default: { color: { text: v(cssVars.colorLinkPrimary) } },
208
+ hover: { color: { text: v(cssVars.colorLinkHover) } },
209
+ inverse: { color: { text: v(cssVars.colorLinkInverse) } },
210
+ pressed: { color: { text: v(cssVars.colorLinkPressed) } },
211
+ weak: { color: { text: v(cssVars.colorLinkSecondary) } },
212
+ },
213
+ primary: {
214
+ alt: {
215
+ color: {
216
+ background: v(cssVars.colorBackgroundInverse),
217
+ border: v(cssVars.colorBorderInverse),
218
+ text: v(cssVars.colorTextInverse),
219
+ },
220
+ focused: { color: { background: v(cssVars.colorBackgroundHoverInverse) } },
221
+ hover: {
222
+ color: {
223
+ background: v(cssVars.colorBackgroundHoverInverse),
224
+ border: v(cssVars.colorBorderInverse),
225
+ },
226
+ },
227
+ pressed: {
228
+ color: {
229
+ background: v(cssVars.colorBackgroundPressedInverse),
230
+ border: v(cssVars.colorBorderInverse),
231
+ },
232
+ },
233
+ },
234
+ color: { background: v(cssVars.colorLinkPrimary), text: v(cssVars.colorTextInverse) },
235
+ focused: { color: { background: v(cssVars.colorLinkHover) } },
236
+ hover: { color: { background: v(cssVars.colorLinkHover) } },
237
+ pressed: { color: { background: v(cssVars.colorLinkPressed) } },
238
+ },
239
+ secondary: {
240
+ alt: {
241
+ color: {
242
+ background: v(cssVars.colorBackgroundPrimary),
243
+ border: v(cssVars.colorBorderInverse),
244
+ text: v(cssVars.colorTextInverse),
245
+ },
246
+ focused: {
247
+ color: {
248
+ background: v(cssVars.colorBackgroundHoverInverse),
249
+ text: v(cssVars.colorTextPrimary),
250
+ },
251
+ },
252
+ hover: {
253
+ color: {
254
+ background: v(cssVars.colorBackgroundHoverInverse),
255
+ border: v(cssVars.colorBorderInverse),
256
+ text: v(cssVars.colorTextPrimary),
257
+ },
258
+ },
259
+ pressed: {
260
+ color: {
261
+ background: v(cssVars.colorBackgroundPressedInverse),
262
+ border: v(cssVars.colorBorderInverse),
263
+ },
264
+ },
265
+ },
266
+ color: {
267
+ background: v(cssVars.colorBackgroundPrimary),
268
+ border: v(cssVars.colorBorderPrimary),
269
+ text: v(cssVars.colorTextPrimary),
270
+ },
271
+ focused: { color: { background: v(cssVars.colorBackgroundHover) } },
272
+ hover: {
273
+ color: {
274
+ background: v(cssVars.colorBackgroundHover),
275
+ border: v(cssVars.colorBorderHover),
276
+ text: v(cssVars.colorTextInverse),
277
+ },
278
+ },
279
+ pressed: {
280
+ color: { background: v(cssVars.colorBackgroundPressed), border: v(cssVars.colorBorderSelected) },
281
+ },
282
+ },
283
+ tertiary: {
284
+ color: { text: v(cssVars.colorLinkPrimary) },
285
+ hover: { color: { background: v(cssVars.colorBackgroundHover) } },
286
+ pressed: { color: { background: v(cssVars.colorBackgroundPressed) } },
287
+ },
288
+ },
289
+ checkbox: { border: { radius: v(cssVars.checkboxBorderRadius) } },
290
+ color: {
291
+ background: {
292
+ critical: {
293
+ dark: v(cssVars.colorBackgroundCriticalDark),
294
+ light: v(cssVars.colorBackgroundCriticalLight),
295
+ },
296
+ decorative: v(cssVars.colorBackgroundTertiary),
297
+ disabled: v(cssVars.colorBackgroundDisabled),
298
+ field: { default: v(cssVars.colorBackgroundPrimary) },
299
+ hover: v(cssVars.colorBackgroundHover),
300
+ info: { dark: v(cssVars.colorBackgroundInfoDark), light: v(cssVars.colorBackgroundInfoLight) },
301
+ inverse: v(cssVars.colorBackgroundInverse),
302
+ neutral: { dark: v(cssVars.colorBackgroundInverse), light: v(cssVars.colorBackgroundSubdued) },
303
+ pressed: v(cssVars.colorBackgroundPressed),
304
+ primary: v(cssVars.colorBackgroundPrimary),
305
+ secondary: v(cssVars.colorBackgroundSecondary),
306
+ subdued: v(cssVars.colorBackgroundSubdued),
307
+ success: { dark: v(cssVars.colorBackgroundSuccessDark), light: v(cssVars.colorBackgroundSuccessLight) },
308
+ tertiary: v(cssVars.colorBackgroundTertiary),
309
+ warning: { dark: v(cssVars.colorBackgroundWarningDark), light: v(cssVars.colorBackgroundWarningLight) },
310
+ },
311
+ border: {
312
+ critical: v(cssVars.colorBorderCritical),
313
+ disabled: v(cssVars.colorBorderDisabled),
314
+ divider: {
315
+ black: v(cssVars.colorBorderBlack),
316
+ dark: v(cssVars.colorBorderPrimary),
317
+ default: v(cssVars.colorBorderSecondary),
318
+ inverse: v(cssVars.colorBorderInverse),
319
+ light: v(cssVars.colorBorderTertiary),
320
+ },
321
+ focused: { default: v(cssVars.colorFocusPrimary), inverse: v(cssVars.colorFocusInverse) },
322
+ hover: v(cssVars.colorBorderHover),
323
+ info: v(cssVars.colorBorderInfo),
324
+ inverse: v(cssVars.colorBorderInverse),
325
+ primary: v(cssVars.colorBorderPrimary),
326
+ secondary: v(cssVars.colorBorderSecondary),
327
+ selected: v(cssVars.colorBorderSelected),
328
+ success: v(cssVars.colorBorderSuccess),
329
+ warning: v(cssVars.colorBorderWarning),
330
+ },
331
+ icon: {
332
+ active: v(cssVars.colorIconPrimary),
333
+ alt: {
334
+ active: v(cssVars.colorIconInverse),
335
+ default: v(cssVars.colorIconInverse),
336
+ hover: v(cssVars.colorIconSecondary),
337
+ },
338
+ critical: v(cssVars.colorIconCritical),
339
+ decorative: {
340
+ alt: v(cssVars.colorIconSecondary),
341
+ default: v(cssVars.colorIconPrimary),
342
+ light: v(cssVars.colorIconDisabled),
343
+ },
344
+ default: v(cssVars.colorIconPrimary),
345
+ disabled: v(cssVars.colorIconDisabled),
346
+ hover: v(cssVars.colorIconSecondary),
347
+ info: v(cssVars.colorIconInfo),
348
+ inverse: v(cssVars.colorIconInverse),
349
+ primary: {
350
+ alt: {
351
+ active: v(cssVars.colorIconInverse),
352
+ default: v(cssVars.colorIconSecondary),
353
+ hover: v(cssVars.colorIconPrimary),
354
+ },
355
+ default: v(cssVars.colorIconPrimary),
356
+ },
357
+ success: v(cssVars.colorIconSuccess),
358
+ warning: { default: v(cssVars.colorIconWarning), light: v(cssVars.colorBackgroundWarningLight) },
359
+ },
360
+ keyboardFocus: v(cssVars.colorFocusPrimary),
361
+ keyboardFocusInverse: v(cssVars.colorFocusInverse),
362
+ shadow: {
363
+ '01': boxShadow['01'],
364
+ '02': boxShadow['02'],
365
+ '03': boxShadow['03'],
366
+ },
367
+ skeleton: { default: v(cssVars.colorBackgroundSubdued) },
368
+ text: {
369
+ alt: v(cssVars.colorTextInverse),
370
+ critical: v(cssVars.colorTextCritical),
371
+ disabled: v(cssVars.colorTextDisabled),
372
+ error: v(cssVars.colorTextCritical),
373
+ inactive: v(cssVars.colorTextInactive),
374
+ info: v(cssVars.colorTextInfo),
375
+ inverse: v(cssVars.colorTextInverse),
376
+ link: {
377
+ active: v(cssVars.colorLinkPressed),
378
+ default: v(cssVars.colorLinkPrimary),
379
+ disabled: v(cssVars.colorLinkDisabled),
380
+ focused: v(cssVars.colorLinkHover),
381
+ hover: v(cssVars.colorLinkHover),
382
+ inverse: v(cssVars.colorLinkInverse),
383
+ monochrome: v(cssVars.colorLinkMonochrome),
384
+ weak: v(cssVars.colorLinkSecondary),
385
+ },
386
+ primary: v(cssVars.colorTextPrimary),
387
+ secondary: v(cssVars.colorTextSecondary),
388
+ standard: v(cssVars.colorTextPrimary),
389
+ success: v(cssVars.colorTextSuccess),
390
+ warning: { default: v(cssVars.colorTextWarning), light: v(cssVars.colorBackgroundWarningLight) },
391
+ weak: v(cssVars.colorTextSecondary),
392
+ },
393
+ transparent00: 'rgb(0 0 0 / 0%)',
394
+ transparent05: 'rgb(0 0 0 / 5%)',
395
+ transparent20: 'rgb(0 0 0 / 20%)',
396
+ transparent40: 'rgb(0 0 0 / 40%)',
397
+ },
398
+ core: Object.fromEntries(Object.entries(source.coreColors).map(([key]) => [key, key])),
399
+ elevation: {
400
+ '01': v(cssVars.shadow01),
401
+ '02': v(cssVars.shadow02),
402
+ '03': v(cssVars.shadow03),
403
+ '04': v(cssVars.shadow04),
404
+ '05': v(cssVars.shadow05),
405
+ },
406
+ input: { border: { radius: v(cssVars.inputBorderRadius) } },
407
+ spacing,
408
+ toggle: { border: { radius: v(cssVars.buttonBorderRadius) } },
409
+ typography: buildTypography(),
410
+ };
411
+ };
@@ -0,0 +1,3 @@
1
+ import { buildRuntimeTheme } from './buildTheme';
2
+
3
+ export const defaultTheme = buildRuntimeTheme('Default');
@@ -0,0 +1,3 @@
1
+ import { buildRuntimeTheme } from './buildTheme';
2
+
3
+ export const everydayHarborTheme = buildRuntimeTheme('EverydayHarbor');
@@ -0,0 +1,3 @@
1
+ import { buildRuntimeTheme } from './buildTheme';
2
+
3
+ export const professionalBrandTheme = buildRuntimeTheme('ProfessionalBrand');
@@ -0,0 +1,23 @@
1
+ import { nonColorVariables } from './Default';
2
+
3
+ /**
4
+ * Maps each semantic color token (e.g. `text-critical`) to the core palette step
5
+ * it resolves to (e.g. `critical-500`), parsed from the Default brand's
6
+ * `nonColorVariables`. The semantic → step mapping is identical across the paper
7
+ * brands (only the core hex values differ per brand), so Default is canonical.
8
+ * Ink brands reuse this map on reversed ramps and rebind a handful of tokens
9
+ * (EverydayHarbor: `everydayHarborOverrides`), so this table describes Default and
10
+ * is not valid for them.
11
+ *
12
+ * Single source of truth for docs/tooling that need to show which step a semantic
13
+ * token points at — derive from this rather than hand-maintaining a duplicate table.
14
+ */
15
+ export const semanticColorTokenSteps: Record<string, string> = Object.fromEntries(
16
+ Object.entries(nonColorVariables).flatMap(([key, value]) => {
17
+ if (!key.startsWith('--color-')) {
18
+ return [];
19
+ }
20
+ const match = /^var\(--color-(.+)\)$/.exec(value);
21
+ return match ? [[key.slice('--color-'.length), match[1]]] : [];
22
+ })
23
+ );
@@ -0,0 +1,169 @@
1
+ import type { Brands } from './brands';
2
+
3
+ type TokenValue = string;
4
+ type Px = string;
5
+
6
+ export type TypographySpec = {
7
+ family: TokenValue;
8
+ height: Px;
9
+ size: Px;
10
+ spacing: Px;
11
+ style: string;
12
+ transform?: string;
13
+ weight: number | TokenValue;
14
+ };
15
+
16
+ type Typography = {
17
+ body: Record<'primary' | 'secondary', TypographySpec>;
18
+ button: Record<'100' | '200', TypographySpec>;
19
+ caption: Record<'100', TypographySpec>;
20
+ heading: Record<'000' | '400' | '500' | '600', TypographySpec> &
21
+ Record<'100' | '200' | '300', TypographySpec & { mobile: TypographySpec }>;
22
+ label: Record<'mini' | 'strong', TypographySpec>;
23
+ };
24
+
25
+ type Color = {
26
+ background: {
27
+ critical: Record<'dark' | 'light', TokenValue>;
28
+ decorative: TokenValue;
29
+ disabled: TokenValue;
30
+ field: { default: TokenValue };
31
+ hover: TokenValue;
32
+ info: Record<'dark' | 'light', TokenValue>;
33
+ inverse: TokenValue;
34
+ neutral: Record<'dark' | 'light', TokenValue>;
35
+ pressed: TokenValue;
36
+ primary: TokenValue;
37
+ secondary: TokenValue;
38
+ subdued: TokenValue;
39
+ success: Record<'dark' | 'light', TokenValue>;
40
+ tertiary: TokenValue;
41
+ warning: Record<'dark' | 'light', TokenValue>;
42
+ };
43
+ border: {
44
+ critical: TokenValue;
45
+ disabled: TokenValue;
46
+ divider: Record<'black' | 'dark' | 'default' | 'inverse' | 'light', TokenValue>;
47
+ focused: Record<'default' | 'inverse', TokenValue>;
48
+ hover: TokenValue;
49
+ info: TokenValue;
50
+ inverse: TokenValue;
51
+ primary: TokenValue;
52
+ secondary: TokenValue;
53
+ selected: TokenValue;
54
+ success: TokenValue;
55
+ warning: TokenValue;
56
+ };
57
+ icon: {
58
+ active: TokenValue;
59
+ alt: Record<'active' | 'default' | 'hover', TokenValue>;
60
+ critical: TokenValue;
61
+ decorative: Record<'alt' | 'default' | 'light', TokenValue>;
62
+ default: TokenValue;
63
+ disabled: TokenValue;
64
+ hover: TokenValue;
65
+ info: TokenValue;
66
+ inverse: TokenValue;
67
+ primary: { alt: { active: TokenValue; default: TokenValue; hover: TokenValue }; default: TokenValue };
68
+ success: TokenValue;
69
+ warning: { default: TokenValue; light: TokenValue };
70
+ };
71
+ keyboardFocus: TokenValue;
72
+ keyboardFocusInverse: TokenValue;
73
+ shadow: Record<'01' | '02' | '03', TokenValue>;
74
+ skeleton: Record<'default', TokenValue>;
75
+ text: {
76
+ alt: TokenValue;
77
+ critical: TokenValue;
78
+ disabled: TokenValue;
79
+ error: TokenValue;
80
+ inactive: TokenValue;
81
+ info: TokenValue;
82
+ inverse: TokenValue;
83
+ link: {
84
+ active: TokenValue;
85
+ default: TokenValue;
86
+ disabled: TokenValue;
87
+ focused: TokenValue;
88
+ hover: TokenValue;
89
+ inverse: TokenValue;
90
+ monochrome: TokenValue;
91
+ weak: TokenValue;
92
+ };
93
+ primary: TokenValue;
94
+ secondary: TokenValue;
95
+ standard: TokenValue;
96
+ success: TokenValue;
97
+ warning: Record<'default' | 'light', TokenValue>;
98
+ weak: TokenValue;
99
+ };
100
+ transparent00: TokenValue;
101
+ transparent05: TokenValue;
102
+ transparent20: TokenValue;
103
+ transparent40: TokenValue;
104
+ };
105
+
106
+ type StrAndValue<Keys extends string> = Record<Keys, Px> & Record<`${Keys}Value`, number>;
107
+
108
+ type Spacing = StrAndValue<'lg' | 'md' | 'sm' | 'xl' | 'xs' | 'xxl' | 'xxs' | 'xxxl' | 'xxxs'>;
109
+ type Breakpoints = StrAndValue<'lgMax' | 'lgMin' | 'mdMax' | 'mdMin' | 'smMax' | 'smMin' | 'xlMin' | 'xsMax'>;
110
+
111
+ type ButtonTheme = {
112
+ border: { radius: Px };
113
+ favorite: Record<
114
+ 'default' | 'disabled' | 'hover' | 'pressed' | 'selected',
115
+ { color: { background: TokenValue; border: TokenValue } }
116
+ >;
117
+ inline: Record<'default' | 'hover' | 'inverse' | 'pressed' | 'weak', { color: { text: TokenValue } }> & {
118
+ alt: Record<'default' | 'hover' | 'pressed', { color: { text: TokenValue } }>;
119
+ };
120
+ primary: {
121
+ alt: {
122
+ color: { background: TokenValue; border: TokenValue; text: TokenValue };
123
+ focused: { color: { background: TokenValue } };
124
+ hover: { color: { background: TokenValue; border: TokenValue } };
125
+ pressed: { color: { background: TokenValue; border: TokenValue } };
126
+ };
127
+ color: { background: TokenValue; text: TokenValue };
128
+ focused: { color: { background: TokenValue } };
129
+ hover: { color: { background: TokenValue } };
130
+ pressed: { color: { background: TokenValue } };
131
+ };
132
+ secondary: {
133
+ alt: {
134
+ color: { background: TokenValue; border: TokenValue; text: TokenValue };
135
+ focused: { color: { background: TokenValue; text: TokenValue } };
136
+ hover: { color: { background: TokenValue; border: TokenValue; text: TokenValue } };
137
+ pressed: { color: { background: TokenValue; border: TokenValue } };
138
+ };
139
+ color: { background: TokenValue; border: TokenValue; text: TokenValue };
140
+ focused: { color: { background: TokenValue } };
141
+ hover: { color: { background: TokenValue; border: TokenValue; text: TokenValue } };
142
+ pressed: { color: { background: TokenValue; border: TokenValue } };
143
+ };
144
+ tertiary: {
145
+ color: { text: TokenValue };
146
+ hover: { color: { background: TokenValue } };
147
+ pressed: { color: { background: TokenValue } };
148
+ };
149
+ };
150
+
151
+ export type Theme = {
152
+ border: {
153
+ radius: Record<'circle' | 'lg' | 'md' | 'sm' | 'xl' | 'xs' | 'zero', string>;
154
+ width: Record<'lg' | 'md' | 'sm' | 'xs' | 'xxs', string>;
155
+ };
156
+ brand: Brands;
157
+ breakpoints: Breakpoints;
158
+ button: ButtonTheme;
159
+ checkbox: { border: { radius: Px } };
160
+ color: Color;
161
+ core: Record<string, TokenValue>;
162
+ elevation: Record<'01' | '02' | '03' | '04' | '05', string>;
163
+ input: { border: { radius: string } };
164
+ spacing: Spacing;
165
+ toggle: { border: { radius: string } };
166
+ typography: Typography;
167
+ };
168
+
169
+ export type CleanTheme = Theme;