@nebutra/ui 0.2.0 → 0.2.2

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 (55) hide show
  1. package/LICENSE +21 -676
  2. package/README.md +81 -86
  3. package/dist/agent/index.d.ts +119 -0
  4. package/dist/agent/index.js +135 -0
  5. package/dist/agent/index.js.map +1 -0
  6. package/dist/canonical-CrO71UPO.d.ts +4058 -0
  7. package/dist/components/index.d.ts +51 -56
  8. package/dist/components/index.js +1467 -1160
  9. package/dist/components/index.js.map +1 -1
  10. package/dist/hooks/index.d.ts +62 -15
  11. package/dist/hooks/index.js +56 -34
  12. package/dist/hooks/index.js.map +1 -1
  13. package/dist/index-CKLIGfiU.d.ts +19 -0
  14. package/dist/index-Dg4jRJV2.d.ts +57 -0
  15. package/dist/layout/index.d.ts +5 -1
  16. package/dist/layout/index.js +427 -533
  17. package/dist/layout/index.js.map +1 -1
  18. package/dist/layouts/index.js +11 -9
  19. package/dist/layouts/index.js.map +1 -1
  20. package/dist/patterns/index.d.ts +128 -2
  21. package/dist/patterns/index.js +1478 -786
  22. package/dist/patterns/index.js.map +1 -1
  23. package/dist/primitives/canonical.d.ts +25 -0
  24. package/dist/primitives/canonical.js +11903 -0
  25. package/dist/primitives/canonical.js.map +1 -0
  26. package/dist/primitives/index.d.ts +577 -3545
  27. package/dist/primitives/index.js +8002 -6159
  28. package/dist/primitives/index.js.map +1 -1
  29. package/dist/shared/animation/css/index.d.ts +1 -0
  30. package/dist/shared/animation/css/index.js +14 -0
  31. package/dist/shared/animation/css/index.js.map +1 -0
  32. package/dist/shared/animation/index.d.ts +6 -0
  33. package/dist/shared/animation/index.js +272 -0
  34. package/dist/shared/animation/index.js.map +1 -0
  35. package/dist/shared/animation/motion/index.d.ts +4 -0
  36. package/dist/shared/animation/motion/index.js +205 -0
  37. package/dist/shared/animation/motion/index.js.map +1 -0
  38. package/dist/styles/brand-override.css +11 -11
  39. package/dist/tailwind.preset.d.ts +10 -10
  40. package/dist/tailwind.preset.js +7 -4
  41. package/dist/tailwind.preset.js.map +1 -1
  42. package/dist/theme/index.d.ts +2 -2
  43. package/dist/tokens-EAC6uPem.d.ts +302 -0
  44. package/dist/typography/fonts.css +31 -12
  45. package/dist/typography/index.d.ts +27 -27
  46. package/dist/typography/index.js +24 -4
  47. package/dist/typography/index.js.map +1 -1
  48. package/dist/utils/index.d.ts +36 -14
  49. package/dist/utils/index.js +44 -10
  50. package/dist/utils/index.js.map +1 -1
  51. package/package.json +38 -12
  52. package/src/styles/brand-override.css +61 -0
  53. package/src/styles/preset.css +29 -0
  54. package/src/styles/sources.css +27 -0
  55. package/src/typography/fonts.css +129 -0
@@ -71,7 +71,7 @@ declare const fontSmoothing: {
71
71
  readonly textRendering: "optimizeLegibility";
72
72
  };
73
73
  /**
74
- * Font feature settings for Inter
74
+ * Font feature settings for Geist
75
75
  */
76
76
  declare const fontFeatureSettings: {
77
77
  /** Enable common ligatures and contextual alternates */
@@ -105,22 +105,22 @@ declare const fontLicenseNotice: string;
105
105
  * All font-related values should come from here.
106
106
  */
107
107
  /**
108
- * Primary font stack - Used for body text and UI
108
+ * Primary font stack - Used for body text and UI.
109
109
  *
110
- * Poppins is the primary font for English text. vivo Sans is for Chinese.
111
- * Falls back through system fonts for maximum compatibility.
110
+ * Token-first so next/font's generated face wins when available; the literal
111
+ * family stack remains as a standalone fallback for docs/tests.
112
112
  */
113
- declare const FONT_FAMILY_PRIMARY = "\"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
113
+ declare const FONT_FAMILY_PRIMARY = "var(--font-sans, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))";
114
114
  /**
115
115
  * Heading font stack - Used for titles and emphasis
116
116
  *
117
117
  * Geist Sans is the primary display typeface.
118
118
  */
119
- declare const FONT_FAMILY_HEADING = "\"Geist\", \"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
119
+ declare const FONT_FAMILY_HEADING = "var(--font-heading, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))";
120
120
  /**
121
121
  * Monospace font stack - Used for code and technical content
122
122
  */
123
- declare const FONT_FAMILY_MONO = "\"JetBrains Mono\", \"Fira Code\", ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace";
123
+ declare const FONT_FAMILY_MONO = "var(--font-mono, var(--font-geist-mono, \"Geist Mono\", ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, monospace))";
124
124
  /**
125
125
  * CJK (Chinese/Japanese/Korean) fallback stack
126
126
  *
@@ -133,15 +133,15 @@ declare const FONT_FAMILY_CJK = "\"vivo Sans\", \"Source Han Sans SC\", \"Source
133
133
  */
134
134
  declare const fontFamilies: {
135
135
  /** Primary UI and body text */
136
- readonly primary: "\"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
136
+ readonly primary: "var(--font-sans, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))";
137
137
  /** Headings and titles */
138
- readonly heading: "\"Geist\", \"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
138
+ readonly heading: "var(--font-heading, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))";
139
139
  /** Code and monospace */
140
- readonly mono: "\"JetBrains Mono\", \"Fira Code\", ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace";
140
+ readonly mono: "var(--font-mono, var(--font-geist-mono, \"Geist Mono\", ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, monospace))";
141
141
  /** CJK-specific fallback */
142
142
  readonly cjk: "\"vivo Sans\", \"Source Han Sans SC\", \"Source Han Sans\", \"Noto Sans CJK SC\", \"Noto Sans SC\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", sans-serif";
143
143
  /** Primary with CJK fallback for multilingual content */
144
- readonly primaryCJK: "\"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"vivo Sans\", \"Source Han Sans SC\", \"Source Han Sans\", \"Noto Sans CJK SC\", \"Noto Sans SC\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", sans-serif";
144
+ readonly primaryCJK: "var(--font-sans, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif)), \"vivo Sans\", \"Source Han Sans SC\", \"Source Han Sans\", \"Noto Sans CJK SC\", \"Noto Sans SC\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", sans-serif";
145
145
  /** System font stack (fast fallback, no web fonts) */
146
146
  readonly system: "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
147
147
  };
@@ -269,7 +269,7 @@ declare const letterSpacing: {
269
269
  declare const typeStyles: {
270
270
  /** Hero/Display - Large marketing headlines */
271
271
  readonly display: {
272
- readonly fontFamily: "\"Geist\", \"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
272
+ readonly fontFamily: "var(--font-heading, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))";
273
273
  readonly fontSize: "3.75rem";
274
274
  readonly fontWeight: 700;
275
275
  readonly lineHeight: 1.25;
@@ -277,7 +277,7 @@ declare const typeStyles: {
277
277
  };
278
278
  /** H1 - Page titles */
279
279
  readonly h1: {
280
- readonly fontFamily: "\"Geist\", \"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
280
+ readonly fontFamily: "var(--font-heading, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))";
281
281
  readonly fontSize: "3rem";
282
282
  readonly fontWeight: 700;
283
283
  readonly lineHeight: 1.25;
@@ -285,7 +285,7 @@ declare const typeStyles: {
285
285
  };
286
286
  /** H2 - Section titles */
287
287
  readonly h2: {
288
- readonly fontFamily: "\"Geist\", \"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
288
+ readonly fontFamily: "var(--font-heading, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))";
289
289
  readonly fontSize: "2.25rem";
290
290
  readonly fontWeight: 700;
291
291
  readonly lineHeight: 1.25;
@@ -293,7 +293,7 @@ declare const typeStyles: {
293
293
  };
294
294
  /** H3 - Subsection titles */
295
295
  readonly h3: {
296
- readonly fontFamily: "\"Geist\", \"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
296
+ readonly fontFamily: "var(--font-heading, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))";
297
297
  readonly fontSize: "1.875rem";
298
298
  readonly fontWeight: 600;
299
299
  readonly lineHeight: 1.375;
@@ -301,7 +301,7 @@ declare const typeStyles: {
301
301
  };
302
302
  /** H4 - Card titles, small sections */
303
303
  readonly h4: {
304
- readonly fontFamily: "\"Geist\", \"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
304
+ readonly fontFamily: "var(--font-heading, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))";
305
305
  readonly fontSize: "1.5rem";
306
306
  readonly fontWeight: 600;
307
307
  readonly lineHeight: 1.375;
@@ -309,7 +309,7 @@ declare const typeStyles: {
309
309
  };
310
310
  /** H5 - Widget titles */
311
311
  readonly h5: {
312
- readonly fontFamily: "\"Geist\", \"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
312
+ readonly fontFamily: "var(--font-heading, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))";
313
313
  readonly fontSize: "1.25rem";
314
314
  readonly fontWeight: 600;
315
315
  readonly lineHeight: 1.5;
@@ -317,7 +317,7 @@ declare const typeStyles: {
317
317
  };
318
318
  /** H6 - Smallest heading */
319
319
  readonly h6: {
320
- readonly fontFamily: "\"Geist\", \"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
320
+ readonly fontFamily: "var(--font-heading, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))";
321
321
  readonly fontSize: "1.125rem";
322
322
  readonly fontWeight: 600;
323
323
  readonly lineHeight: 1.5;
@@ -325,7 +325,7 @@ declare const typeStyles: {
325
325
  };
326
326
  /** Body - Default paragraph text */
327
327
  readonly body: {
328
- readonly fontFamily: "\"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
328
+ readonly fontFamily: "var(--font-sans, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))";
329
329
  readonly fontSize: "1rem";
330
330
  readonly fontWeight: 400;
331
331
  readonly lineHeight: 1.5;
@@ -333,7 +333,7 @@ declare const typeStyles: {
333
333
  };
334
334
  /** Body Large - Lead paragraphs */
335
335
  readonly bodyLarge: {
336
- readonly fontFamily: "\"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
336
+ readonly fontFamily: "var(--font-sans, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))";
337
337
  readonly fontSize: "1.125rem";
338
338
  readonly fontWeight: 400;
339
339
  readonly lineHeight: 1.625;
@@ -341,7 +341,7 @@ declare const typeStyles: {
341
341
  };
342
342
  /** Body Small - Secondary text */
343
343
  readonly bodySmall: {
344
- readonly fontFamily: "\"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
344
+ readonly fontFamily: "var(--font-sans, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))";
345
345
  readonly fontSize: "0.875rem";
346
346
  readonly fontWeight: 400;
347
347
  readonly lineHeight: 1.5;
@@ -349,7 +349,7 @@ declare const typeStyles: {
349
349
  };
350
350
  /** Caption - Image captions, timestamps */
351
351
  readonly caption: {
352
- readonly fontFamily: "\"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
352
+ readonly fontFamily: "var(--font-sans, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))";
353
353
  readonly fontSize: "0.75rem";
354
354
  readonly fontWeight: 400;
355
355
  readonly lineHeight: 1.5;
@@ -357,7 +357,7 @@ declare const typeStyles: {
357
357
  };
358
358
  /** Label - Form labels, UI labels */
359
359
  readonly label: {
360
- readonly fontFamily: "\"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
360
+ readonly fontFamily: "var(--font-sans, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))";
361
361
  readonly fontSize: "0.875rem";
362
362
  readonly fontWeight: 500;
363
363
  readonly lineHeight: 1.25;
@@ -365,7 +365,7 @@ declare const typeStyles: {
365
365
  };
366
366
  /** Button - Button text */
367
367
  readonly button: {
368
- readonly fontFamily: "\"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
368
+ readonly fontFamily: "var(--font-sans, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))";
369
369
  readonly fontSize: "0.875rem";
370
370
  readonly fontWeight: 500;
371
371
  readonly lineHeight: 1.25;
@@ -373,7 +373,7 @@ declare const typeStyles: {
373
373
  };
374
374
  /** Code - Inline code */
375
375
  readonly code: {
376
- readonly fontFamily: "\"JetBrains Mono\", \"Fira Code\", ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace";
376
+ readonly fontFamily: "var(--font-mono, var(--font-geist-mono, \"Geist Mono\", ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, monospace))";
377
377
  readonly fontSize: "0.875rem";
378
378
  readonly fontWeight: 400;
379
379
  readonly lineHeight: 1.5;
@@ -381,7 +381,7 @@ declare const typeStyles: {
381
381
  };
382
382
  /** Code Block - Code blocks */
383
383
  readonly codeBlock: {
384
- readonly fontFamily: "\"JetBrains Mono\", \"Fira Code\", ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace";
384
+ readonly fontFamily: "var(--font-mono, var(--font-geist-mono, \"Geist Mono\", ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, monospace))";
385
385
  readonly fontSize: "0.875rem";
386
386
  readonly fontWeight: 400;
387
387
  readonly lineHeight: 1.625;
@@ -389,7 +389,7 @@ declare const typeStyles: {
389
389
  };
390
390
  /** Overline - Small caps labels */
391
391
  readonly overline: {
392
- readonly fontFamily: "\"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
392
+ readonly fontFamily: "var(--font-sans, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))";
393
393
  readonly fontSize: "0.75rem";
394
394
  readonly fontWeight: 600;
395
395
  readonly lineHeight: 1.5;
@@ -1,5 +1,23 @@
1
1
  // src/typography/fonts.ts
2
2
  var fonts = {
3
+ geistSans: {
4
+ family: "Geist",
5
+ weights: [300, 400, 500, 600, 700],
6
+ italic: false,
7
+ display: "swap",
8
+ variable: true,
9
+ license: "OFL",
10
+ licenseUrl: "https://github.com/vercel/geist-font/blob/main/LICENSE.txt"
11
+ },
12
+ geistMono: {
13
+ family: "Geist Mono",
14
+ weights: [400, 500, 600, 700],
15
+ italic: false,
16
+ display: "swap",
17
+ variable: true,
18
+ license: "OFL",
19
+ licenseUrl: "https://github.com/vercel/geist-font/blob/main/LICENSE.txt"
20
+ },
3
21
  inter: {
4
22
  family: "Inter",
5
23
  weights: [300, 400, 500, 600, 700],
@@ -46,7 +64,7 @@ function getGoogleFontsUrl(fontKeys) {
46
64
  if (!families) return "";
47
65
  return `https://fonts.googleapis.com/css2?family=${families}&display=swap`;
48
66
  }
49
- var defaultFonts = ["inter", "jetbrainsMono"];
67
+ var defaultFonts = ["geistSans", "geistMono"];
50
68
  var cjkFonts = ["sourceHanSans"];
51
69
  var allFonts = [...defaultFonts, ...cjkFonts];
52
70
  function getFontPreloadLinks(fontKeys) {
@@ -110,6 +128,8 @@ Fonts used in this project are licensed under open-source licenses:
110
128
 
111
129
  - Inter: SIL Open Font License 1.1
112
130
  - Public Sans: SIL Open Font License 1.1
131
+ - Geist: SIL Open Font License 1.1
132
+ - Geist Mono: SIL Open Font License 1.1
113
133
  - JetBrains Mono: SIL Open Font License 1.1
114
134
  - Noto Sans SC (Source Han Sans): SIL Open Font License 1.1
115
135
 
@@ -117,9 +137,9 @@ All fonts are free for commercial use. See individual license files for details.
117
137
  `.trim();
118
138
 
119
139
  // src/typography/tokens.ts
120
- var FONT_FAMILY_PRIMARY = '"Poppins", "vivo Sans", "PingFang SC", "Microsoft YaHei", "Noto Sans SC", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif';
121
- var FONT_FAMILY_HEADING = '"Geist", "Poppins", "vivo Sans", "PingFang SC", "Microsoft YaHei", "Noto Sans SC", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif';
122
- var FONT_FAMILY_MONO = '"JetBrains Mono", "Fira Code", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace';
140
+ var FONT_FAMILY_PRIMARY = 'var(--font-sans, var(--font-geist-sans, "Geist", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif))';
141
+ var FONT_FAMILY_HEADING = 'var(--font-heading, var(--font-geist-sans, "Geist", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif))';
142
+ var FONT_FAMILY_MONO = 'var(--font-mono, var(--font-geist-mono, "Geist Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace))';
123
143
  var FONT_FAMILY_CJK = '"vivo Sans", "Source Han Sans SC", "Source Han Sans", "Noto Sans CJK SC", "Noto Sans SC", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif';
124
144
  var fontFamilies = {
125
145
  /** Primary UI and body text */
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/typography/fonts.ts","../../src/typography/tokens.ts"],"names":["fontFamilies"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Font Configuration and Loading Utilities\n *\n * Handles web font loading, preloading, and performance optimization.\n */\n\n// ============================================\n// Font Definitions\n// ============================================\n\n/**\n * Font configuration object\n */\nexport interface FontConfig {\n /** Font family name */\n family: string;\n /** Font weights to load */\n weights: number[];\n /** Include italic variants */\n italic?: boolean;\n /** Font display strategy */\n display?: \"auto\" | \"block\" | \"swap\" | \"fallback\" | \"optional\";\n /** Is this a variable font */\n variable?: boolean;\n /** Google Fonts URL parameter name */\n googleFontsParam?: string;\n /** Self-hosted font URL */\n selfHostUrl?: string;\n /** Font license */\n license: \"OFL\" | \"Apache-2.0\" | \"Ubuntu\" | \"MIT\" | \"Other\";\n /** Source URL for license */\n licenseUrl?: string;\n}\n\n/**\n * Registered fonts for the design system\n */\nexport const fonts: Record<string, FontConfig> = {\n inter: {\n family: \"Inter\",\n weights: [300, 400, 500, 600, 700],\n italic: false,\n display: \"swap\",\n variable: true,\n googleFontsParam: \"Inter:wght@300;400;500;600;700\",\n license: \"OFL\",\n licenseUrl: \"https://github.com/rsms/inter/blob/master/LICENSE.txt\",\n },\n\n publicSans: {\n family: \"Public Sans\",\n weights: [300, 400, 500, 600, 700],\n italic: true,\n display: \"swap\",\n variable: true,\n googleFontsParam: \"Public+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,400;1,500\",\n license: \"OFL\",\n licenseUrl: \"https://github.com/uswds/public-sans/blob/develop/LICENSE.md\",\n },\n\n jetbrainsMono: {\n family: \"JetBrains Mono\",\n weights: [400, 500, 700],\n italic: false,\n display: \"swap\",\n variable: true,\n googleFontsParam: \"JetBrains+Mono:wght@400;500;700\",\n license: \"OFL\",\n licenseUrl: \"https://github.com/JetBrains/JetBrainsMono/blob/master/OFL.txt\",\n },\n\n sourceHanSans: {\n family: \"Noto Sans SC\",\n weights: [400, 500, 700],\n italic: false,\n display: \"swap\",\n variable: false,\n googleFontsParam: \"Noto+Sans+SC:wght@400;500;700\",\n license: \"OFL\",\n licenseUrl: \"https://github.com/adobe-fonts/source-han-sans/blob/master/LICENSE.txt\",\n },\n};\n\n// ============================================\n// Google Fonts URL Builder\n// ============================================\n\n/**\n * Generate Google Fonts URL for specified fonts\n */\nexport function getGoogleFontsUrl(fontKeys: (keyof typeof fonts)[]): string {\n const families = fontKeys\n .map((key) => fonts[key]?.googleFontsParam)\n .filter(Boolean)\n .join(\"&family=\");\n\n if (!families) return \"\";\n\n return `https://fonts.googleapis.com/css2?family=${families}&display=swap`;\n}\n\n/**\n * Default fonts to load\n */\nexport const defaultFonts: (keyof typeof fonts)[] = [\"inter\", \"jetbrainsMono\"];\n\n/**\n * Fonts for CJK (Chinese) support\n */\nexport const cjkFonts: (keyof typeof fonts)[] = [\"sourceHanSans\"];\n\n/**\n * All fonts including CJK\n */\nexport const allFonts: (keyof typeof fonts)[] = [...defaultFonts, ...cjkFonts];\n\n// ============================================\n// Font Loading Utilities\n// ============================================\n\n/**\n * Generate preload link elements for critical fonts\n */\nexport function getFontPreloadLinks(fontKeys: (keyof typeof fonts)[]): string[] {\n return fontKeys\n .map((key) => {\n const font = fonts[key];\n if (!font) return \"\";\n\n const url = getGoogleFontsUrl([key]);\n return `<link rel=\"preload\" href=\"${url}\" as=\"style\" crossorigin>`;\n })\n .filter(Boolean);\n}\n\n/**\n * Generate link element for Google Fonts\n */\nexport function getGoogleFontsLink(fontKeys: (keyof typeof fonts)[]): string {\n const url = getGoogleFontsUrl(fontKeys);\n if (!url) return \"\";\n\n return `<link rel=\"stylesheet\" href=\"${url}\">`;\n}\n\n/**\n * Check if fonts are loaded\n */\nexport async function areFontsLoaded(fontFamilies: string[]): Promise<boolean> {\n if (typeof document === \"undefined\") return false;\n\n try {\n await Promise.all(fontFamilies.map((family) => document.fonts.load(`16px \"${family}\"`)));\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Wait for fonts to load with timeout\n */\nexport async function waitForFonts(fontFamilies: string[], timeout = 3000): Promise<boolean> {\n if (typeof document === \"undefined\") return false;\n\n return new Promise((resolve) => {\n const timer = setTimeout(() => resolve(false), timeout);\n\n areFontsLoaded(fontFamilies).then((loaded) => {\n clearTimeout(timer);\n resolve(loaded);\n });\n });\n}\n\n// ============================================\n// CSS-in-JS Helpers\n// ============================================\n\n/**\n * Font smoothing CSS for crisp text rendering\n */\nexport const fontSmoothing = {\n WebkitFontSmoothing: \"antialiased\",\n MozOsxFontSmoothing: \"grayscale\",\n textRendering: \"optimizeLegibility\",\n} as const;\n\n/**\n * Font feature settings for Inter\n */\nexport const fontFeatureSettings = {\n /** Enable common ligatures and contextual alternates */\n normal: '\"calt\" 1, \"liga\" 1',\n /** Enable tabular figures for aligned numbers */\n tabular: '\"tnum\" 1, \"calt\" 1',\n /** Enable case-sensitive forms */\n case: '\"case\" 1',\n /** Enable stylistic set 01 (alternate digits) */\n ss01: '\"ss01\" 1',\n /** Enable stylistic set 02 (alternate a) */\n ss02: '\"ss02\" 1',\n} as const;\n\n// ============================================\n// License Information\n// ============================================\n\n/**\n * Get license information for all used fonts\n */\nexport function getFontLicenses(): Array<{\n family: string;\n license: string;\n url?: string | undefined;\n}> {\n return Object.values(fonts).map((font) => ({\n family: font.family,\n license: font.license,\n url: font.licenseUrl,\n }));\n}\n\n/**\n * Font license compliance notice\n */\nexport const fontLicenseNotice = `\nFonts used in this project are licensed under open-source licenses:\n\n- Inter: SIL Open Font License 1.1\n- Public Sans: SIL Open Font License 1.1\n- JetBrains Mono: SIL Open Font License 1.1\n- Noto Sans SC (Source Han Sans): SIL Open Font License 1.1\n\nAll fonts are free for commercial use. See individual license files for details.\n`.trim();\n","/**\n * Typography Tokens\n *\n * Centralized typography configuration for the entire design system.\n * All font-related values should come from here.\n */\n\n// ============================================\n// Font Families\n// ============================================\n\n/**\n * Primary font stack - Used for body text and UI\n *\n * Poppins is the primary font for English text. vivo Sans is for Chinese.\n * Falls back through system fonts for maximum compatibility.\n */\nexport const FONT_FAMILY_PRIMARY =\n '\"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif';\n\n/**\n * Heading font stack - Used for titles and emphasis\n *\n * Geist Sans is the primary display typeface.\n */\nexport const FONT_FAMILY_HEADING =\n '\"Geist\", \"Poppins\", \"vivo Sans\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans SC\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif';\n\n/**\n * Monospace font stack - Used for code and technical content\n */\nexport const FONT_FAMILY_MONO =\n '\"JetBrains Mono\", \"Fira Code\", ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace';\n\n/**\n * CJK (Chinese/Japanese/Korean) fallback stack\n *\n * vivo Sans is the primary Chinese font.\n * Provides consistent rendering for Chinese, Japanese, and Korean text.\n */\nexport const FONT_FAMILY_CJK =\n '\"vivo Sans\", \"Source Han Sans SC\", \"Source Han Sans\", \"Noto Sans CJK SC\", \"Noto Sans SC\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", sans-serif';\n\n/**\n * Complete font stacks with CJK fallback\n */\nexport const fontFamilies = {\n /** Primary UI and body text */\n primary: FONT_FAMILY_PRIMARY,\n\n /** Headings and titles */\n heading: FONT_FAMILY_HEADING,\n\n /** Code and monospace */\n mono: FONT_FAMILY_MONO,\n\n /** CJK-specific fallback */\n cjk: FONT_FAMILY_CJK,\n\n /** Primary with CJK fallback for multilingual content */\n primaryCJK: `${FONT_FAMILY_PRIMARY}, ${FONT_FAMILY_CJK}`,\n\n /** System font stack (fast fallback, no web fonts) */\n system: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif',\n} as const;\n\n// ============================================\n// Type Scale\n// ============================================\n\n/**\n * Font size scale using rem units for accessibility\n *\n * Base: 16px = 1rem\n * Each step follows a modular scale (~1.25 ratio)\n */\nexport const fontSizes = {\n /** 12px - Micro text, badges */\n xs: \"0.75rem\",\n\n /** 14px - Small text, captions, labels */\n sm: \"0.875rem\",\n\n /** 16px - Base body text */\n base: \"1rem\",\n\n /** 18px - Lead text, larger body */\n lg: \"1.125rem\",\n\n /** 20px - Small headings, subtitles */\n xl: \"1.25rem\",\n\n /** 24px - H4 equivalent */\n \"2xl\": \"1.5rem\",\n\n /** 30px - H3 equivalent */\n \"3xl\": \"1.875rem\",\n\n /** 36px - H2 equivalent */\n \"4xl\": \"2.25rem\",\n\n /** 48px - H1 equivalent */\n \"5xl\": \"3rem\",\n\n /** 60px - Display/Hero text */\n \"6xl\": \"3.75rem\",\n\n /** 72px - Large display */\n \"7xl\": \"4.5rem\",\n\n /** 96px - Extra large display */\n \"8xl\": \"6rem\",\n} as const;\n\n/**\n * Font size in pixels (for cases where rem isn't suitable)\n */\nexport const fontSizesPx = {\n xs: 12,\n sm: 14,\n base: 16,\n lg: 18,\n xl: 20,\n \"2xl\": 24,\n \"3xl\": 30,\n \"4xl\": 36,\n \"5xl\": 48,\n \"6xl\": 60,\n \"7xl\": 72,\n \"8xl\": 96,\n} as const;\n\n// ============================================\n// Line Heights\n// ============================================\n\n/**\n * Line height scale\n *\n * Using unitless values for better inheritance.\n */\nexport const lineHeights = {\n /** 1 - Single line, icons */\n none: 1,\n\n /** 1.25 - Tight, for large headings */\n tight: 1.25,\n\n /** 1.375 - Slightly snug */\n snug: 1.375,\n\n /** 1.5 - Normal body text */\n normal: 1.5,\n\n /** 1.625 - Relaxed reading */\n relaxed: 1.625,\n\n /** 1.75 - Loose, for small text */\n loose: 1.75,\n\n /** 2 - Double spaced */\n double: 2,\n} as const;\n\n// ============================================\n// Font Weights\n// ============================================\n\n/**\n * Font weight scale\n *\n * Inter and Public Sans support all these weights.\n * Variable fonts can use any value 100-900.\n */\nexport const fontWeights = {\n /** 100 - Thin (if available) */\n thin: 100,\n\n /** 200 - Extra light */\n extralight: 200,\n\n /** 300 - Light */\n light: 300,\n\n /** 400 - Regular/Normal */\n normal: 400,\n\n /** 500 - Medium */\n medium: 500,\n\n /** 600 - Semibold */\n semibold: 600,\n\n /** 700 - Bold */\n bold: 700,\n\n /** 800 - Extra bold */\n extrabold: 800,\n\n /** 900 - Black */\n black: 900,\n} as const;\n\n// ============================================\n// Letter Spacing (Tracking)\n// ============================================\n\n/**\n * Letter spacing scale\n *\n * Negative values for tight headlines, positive for small caps.\n */\nexport const letterSpacing = {\n /** -0.05em - Very tight, large display only */\n tighter: \"-0.05em\",\n\n /** -0.025em - Slightly tight, headings */\n tight: \"-0.025em\",\n\n /** 0 - Normal */\n normal: \"0\",\n\n /** 0.025em - Slightly wide */\n wide: \"0.025em\",\n\n /** 0.05em - Wide, for small caps */\n wider: \"0.05em\",\n\n /** 0.1em - Very wide, all caps */\n widest: \"0.1em\",\n} as const;\n\n// ============================================\n// Combined Type Styles\n// ============================================\n\n/**\n * Pre-defined typography presets\n *\n * These combine font-family, size, weight, and line-height\n * for common use cases.\n */\nexport const typeStyles = {\n /** Hero/Display - Large marketing headlines */\n display: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes[\"6xl\"],\n fontWeight: fontWeights.bold,\n lineHeight: lineHeights.tight,\n letterSpacing: letterSpacing.tight,\n },\n\n /** H1 - Page titles */\n h1: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes[\"5xl\"],\n fontWeight: fontWeights.bold,\n lineHeight: lineHeights.tight,\n letterSpacing: letterSpacing.tight,\n },\n\n /** H2 - Section titles */\n h2: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes[\"4xl\"],\n fontWeight: fontWeights.bold,\n lineHeight: lineHeights.tight,\n letterSpacing: letterSpacing.tight,\n },\n\n /** H3 - Subsection titles */\n h3: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes[\"3xl\"],\n fontWeight: fontWeights.semibold,\n lineHeight: lineHeights.snug,\n letterSpacing: letterSpacing.normal,\n },\n\n /** H4 - Card titles, small sections */\n h4: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes[\"2xl\"],\n fontWeight: fontWeights.semibold,\n lineHeight: lineHeights.snug,\n letterSpacing: letterSpacing.normal,\n },\n\n /** H5 - Widget titles */\n h5: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes.xl,\n fontWeight: fontWeights.semibold,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.normal,\n },\n\n /** H6 - Smallest heading */\n h6: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes.lg,\n fontWeight: fontWeights.semibold,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Body - Default paragraph text */\n body: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.base,\n fontWeight: fontWeights.normal,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Body Large - Lead paragraphs */\n bodyLarge: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.lg,\n fontWeight: fontWeights.normal,\n lineHeight: lineHeights.relaxed,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Body Small - Secondary text */\n bodySmall: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.sm,\n fontWeight: fontWeights.normal,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Caption - Image captions, timestamps */\n caption: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.xs,\n fontWeight: fontWeights.normal,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.wide,\n },\n\n /** Label - Form labels, UI labels */\n label: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.sm,\n fontWeight: fontWeights.medium,\n lineHeight: lineHeights.tight,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Button - Button text */\n button: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.sm,\n fontWeight: fontWeights.medium,\n lineHeight: lineHeights.tight,\n letterSpacing: letterSpacing.wide,\n },\n\n /** Code - Inline code */\n code: {\n fontFamily: fontFamilies.mono,\n fontSize: fontSizes.sm,\n fontWeight: fontWeights.normal,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Code Block - Code blocks */\n codeBlock: {\n fontFamily: fontFamilies.mono,\n fontSize: fontSizes.sm,\n fontWeight: fontWeights.normal,\n lineHeight: lineHeights.relaxed,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Overline - Small caps labels */\n overline: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.xs,\n fontWeight: fontWeights.semibold,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.widest,\n textTransform: \"uppercase\" as const,\n },\n} as const;\n\nexport type TypeStyle = keyof typeof typeStyles;\n\n// ============================================\n// Responsive Typography\n// ============================================\n\n/**\n * Fluid typography clamp values\n *\n * Format: clamp(min, preferred, max)\n * Uses viewport width for smooth scaling.\n */\nexport const fluidFontSizes = {\n /** Display: 36px to 72px */\n display: \"clamp(2.25rem, 5vw + 1rem, 4.5rem)\",\n\n /** H1: 30px to 48px */\n h1: \"clamp(1.875rem, 4vw + 0.5rem, 3rem)\",\n\n /** H2: 24px to 36px */\n h2: \"clamp(1.5rem, 3vw + 0.5rem, 2.25rem)\",\n\n /** H3: 20px to 30px */\n h3: \"clamp(1.25rem, 2vw + 0.5rem, 1.875rem)\",\n\n /** Body: 14px to 18px */\n body: \"clamp(0.875rem, 1vw + 0.5rem, 1.125rem)\",\n} as const;\n\n// ============================================\n// Type Exports\n// ============================================\n\nexport type FontFamily = keyof typeof fontFamilies;\nexport type FontSize = keyof typeof fontSizes;\nexport type LineHeight = keyof typeof lineHeights;\nexport type FontWeight = keyof typeof fontWeights;\nexport type LetterSpacing = keyof typeof letterSpacing;\n"]}
1
+ {"version":3,"sources":["../../src/typography/fonts.ts","../../src/typography/tokens.ts"],"names":["fontFamilies"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Font Configuration and Loading Utilities\n *\n * Handles web font loading, preloading, and performance optimization.\n */\n\n// ============================================\n// Font Definitions\n// ============================================\n\n/**\n * Font configuration object\n */\nexport interface FontConfig {\n /** Font family name */\n family: string;\n /** Font weights to load */\n weights: number[];\n /** Include italic variants */\n italic?: boolean;\n /** Font display strategy */\n display?: \"auto\" | \"block\" | \"swap\" | \"fallback\" | \"optional\";\n /** Is this a variable font */\n variable?: boolean;\n /** Google Fonts URL parameter name */\n googleFontsParam?: string;\n /** Self-hosted font URL */\n selfHostUrl?: string;\n /** Font license */\n license: \"OFL\" | \"Apache-2.0\" | \"Ubuntu\" | \"MIT\" | \"Other\";\n /** Source URL for license */\n licenseUrl?: string;\n}\n\n/**\n * Registered fonts for the design system\n */\nexport const fonts: Record<string, FontConfig> = {\n geistSans: {\n family: \"Geist\",\n weights: [300, 400, 500, 600, 700],\n italic: false,\n display: \"swap\",\n variable: true,\n license: \"OFL\",\n licenseUrl: \"https://github.com/vercel/geist-font/blob/main/LICENSE.txt\",\n },\n\n geistMono: {\n family: \"Geist Mono\",\n weights: [400, 500, 600, 700],\n italic: false,\n display: \"swap\",\n variable: true,\n license: \"OFL\",\n licenseUrl: \"https://github.com/vercel/geist-font/blob/main/LICENSE.txt\",\n },\n\n inter: {\n family: \"Inter\",\n weights: [300, 400, 500, 600, 700],\n italic: false,\n display: \"swap\",\n variable: true,\n googleFontsParam: \"Inter:wght@300;400;500;600;700\",\n license: \"OFL\",\n licenseUrl: \"https://github.com/rsms/inter/blob/master/LICENSE.txt\",\n },\n\n publicSans: {\n family: \"Public Sans\",\n weights: [300, 400, 500, 600, 700],\n italic: true,\n display: \"swap\",\n variable: true,\n googleFontsParam: \"Public+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,400;1,500\",\n license: \"OFL\",\n licenseUrl: \"https://github.com/uswds/public-sans/blob/develop/LICENSE.md\",\n },\n\n jetbrainsMono: {\n family: \"JetBrains Mono\",\n weights: [400, 500, 700],\n italic: false,\n display: \"swap\",\n variable: true,\n googleFontsParam: \"JetBrains+Mono:wght@400;500;700\",\n license: \"OFL\",\n licenseUrl: \"https://github.com/JetBrains/JetBrainsMono/blob/master/OFL.txt\",\n },\n\n sourceHanSans: {\n family: \"Noto Sans SC\",\n weights: [400, 500, 700],\n italic: false,\n display: \"swap\",\n variable: false,\n googleFontsParam: \"Noto+Sans+SC:wght@400;500;700\",\n license: \"OFL\",\n licenseUrl: \"https://github.com/adobe-fonts/source-han-sans/blob/master/LICENSE.txt\",\n },\n};\n\n// ============================================\n// Google Fonts URL Builder\n// ============================================\n\n/**\n * Generate Google Fonts URL for specified fonts\n */\nexport function getGoogleFontsUrl(fontKeys: (keyof typeof fonts)[]): string {\n const families = fontKeys\n .map((key) => fonts[key]?.googleFontsParam)\n .filter(Boolean)\n .join(\"&family=\");\n\n if (!families) return \"\";\n\n return `https://fonts.googleapis.com/css2?family=${families}&display=swap`;\n}\n\n/**\n * Default fonts to load\n */\nexport const defaultFonts: (keyof typeof fonts)[] = [\"geistSans\", \"geistMono\"];\n\n/**\n * Fonts for CJK (Chinese) support\n */\nexport const cjkFonts: (keyof typeof fonts)[] = [\"sourceHanSans\"];\n\n/**\n * All fonts including CJK\n */\nexport const allFonts: (keyof typeof fonts)[] = [...defaultFonts, ...cjkFonts];\n\n// ============================================\n// Font Loading Utilities\n// ============================================\n\n/**\n * Generate preload link elements for critical fonts\n */\nexport function getFontPreloadLinks(fontKeys: (keyof typeof fonts)[]): string[] {\n return fontKeys\n .map((key) => {\n const font = fonts[key];\n if (!font) return \"\";\n\n const url = getGoogleFontsUrl([key]);\n return `<link rel=\"preload\" href=\"${url}\" as=\"style\" crossorigin>`;\n })\n .filter(Boolean);\n}\n\n/**\n * Generate link element for Google Fonts\n */\nexport function getGoogleFontsLink(fontKeys: (keyof typeof fonts)[]): string {\n const url = getGoogleFontsUrl(fontKeys);\n if (!url) return \"\";\n\n return `<link rel=\"stylesheet\" href=\"${url}\">`;\n}\n\n/**\n * Check if fonts are loaded\n */\nexport async function areFontsLoaded(fontFamilies: string[]): Promise<boolean> {\n if (typeof document === \"undefined\") return false;\n\n try {\n await Promise.all(fontFamilies.map((family) => document.fonts.load(`16px \"${family}\"`)));\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Wait for fonts to load with timeout\n */\nexport async function waitForFonts(fontFamilies: string[], timeout = 3000): Promise<boolean> {\n if (typeof document === \"undefined\") return false;\n\n return new Promise((resolve) => {\n const timer = setTimeout(() => resolve(false), timeout);\n\n areFontsLoaded(fontFamilies).then((loaded) => {\n clearTimeout(timer);\n resolve(loaded);\n });\n });\n}\n\n// ============================================\n// CSS-in-JS Helpers\n// ============================================\n\n/**\n * Font smoothing CSS for crisp text rendering\n */\nexport const fontSmoothing = {\n WebkitFontSmoothing: \"antialiased\",\n MozOsxFontSmoothing: \"grayscale\",\n textRendering: \"optimizeLegibility\",\n} as const;\n\n/**\n * Font feature settings for Geist\n */\nexport const fontFeatureSettings = {\n /** Enable common ligatures and contextual alternates */\n normal: '\"calt\" 1, \"liga\" 1',\n /** Enable tabular figures for aligned numbers */\n tabular: '\"tnum\" 1, \"calt\" 1',\n /** Enable case-sensitive forms */\n case: '\"case\" 1',\n /** Enable stylistic set 01 (alternate digits) */\n ss01: '\"ss01\" 1',\n /** Enable stylistic set 02 (alternate a) */\n ss02: '\"ss02\" 1',\n} as const;\n\n// ============================================\n// License Information\n// ============================================\n\n/**\n * Get license information for all used fonts\n */\nexport function getFontLicenses(): Array<{\n family: string;\n license: string;\n url?: string | undefined;\n}> {\n return Object.values(fonts).map((font) => ({\n family: font.family,\n license: font.license,\n url: font.licenseUrl,\n }));\n}\n\n/**\n * Font license compliance notice\n */\nexport const fontLicenseNotice = `\nFonts used in this project are licensed under open-source licenses:\n\n- Inter: SIL Open Font License 1.1\n- Public Sans: SIL Open Font License 1.1\n- Geist: SIL Open Font License 1.1\n- Geist Mono: SIL Open Font License 1.1\n- JetBrains Mono: SIL Open Font License 1.1\n- Noto Sans SC (Source Han Sans): SIL Open Font License 1.1\n\nAll fonts are free for commercial use. See individual license files for details.\n`.trim();\n","/**\n * Typography Tokens\n *\n * Centralized typography configuration for the entire design system.\n * All font-related values should come from here.\n */\n\n// ============================================\n// Font Families\n// ============================================\n\n/**\n * Primary font stack - Used for body text and UI.\n *\n * Token-first so next/font's generated face wins when available; the literal\n * family stack remains as a standalone fallback for docs/tests.\n */\nexport const FONT_FAMILY_PRIMARY =\n 'var(--font-sans, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))';\n\n/**\n * Heading font stack - Used for titles and emphasis\n *\n * Geist Sans is the primary display typeface.\n */\nexport const FONT_FAMILY_HEADING =\n 'var(--font-heading, var(--font-geist-sans, \"Geist\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif))';\n\n/**\n * Monospace font stack - Used for code and technical content\n */\nexport const FONT_FAMILY_MONO =\n 'var(--font-mono, var(--font-geist-mono, \"Geist Mono\", ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, monospace))';\n\n/**\n * CJK (Chinese/Japanese/Korean) fallback stack\n *\n * vivo Sans is the primary Chinese font.\n * Provides consistent rendering for Chinese, Japanese, and Korean text.\n */\nexport const FONT_FAMILY_CJK =\n '\"vivo Sans\", \"Source Han Sans SC\", \"Source Han Sans\", \"Noto Sans CJK SC\", \"Noto Sans SC\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", sans-serif';\n\n/**\n * Complete font stacks with CJK fallback\n */\nexport const fontFamilies = {\n /** Primary UI and body text */\n primary: FONT_FAMILY_PRIMARY,\n\n /** Headings and titles */\n heading: FONT_FAMILY_HEADING,\n\n /** Code and monospace */\n mono: FONT_FAMILY_MONO,\n\n /** CJK-specific fallback */\n cjk: FONT_FAMILY_CJK,\n\n /** Primary with CJK fallback for multilingual content */\n primaryCJK: `${FONT_FAMILY_PRIMARY}, ${FONT_FAMILY_CJK}`,\n\n /** System font stack (fast fallback, no web fonts) */\n system: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif',\n} as const;\n\n// ============================================\n// Type Scale\n// ============================================\n\n/**\n * Font size scale using rem units for accessibility\n *\n * Base: 16px = 1rem\n * Each step follows a modular scale (~1.25 ratio)\n */\nexport const fontSizes = {\n /** 12px - Micro text, badges */\n xs: \"0.75rem\",\n\n /** 14px - Small text, captions, labels */\n sm: \"0.875rem\",\n\n /** 16px - Base body text */\n base: \"1rem\",\n\n /** 18px - Lead text, larger body */\n lg: \"1.125rem\",\n\n /** 20px - Small headings, subtitles */\n xl: \"1.25rem\",\n\n /** 24px - H4 equivalent */\n \"2xl\": \"1.5rem\",\n\n /** 30px - H3 equivalent */\n \"3xl\": \"1.875rem\",\n\n /** 36px - H2 equivalent */\n \"4xl\": \"2.25rem\",\n\n /** 48px - H1 equivalent */\n \"5xl\": \"3rem\",\n\n /** 60px - Display/Hero text */\n \"6xl\": \"3.75rem\",\n\n /** 72px - Large display */\n \"7xl\": \"4.5rem\",\n\n /** 96px - Extra large display */\n \"8xl\": \"6rem\",\n} as const;\n\n/**\n * Font size in pixels (for cases where rem isn't suitable)\n */\nexport const fontSizesPx = {\n xs: 12,\n sm: 14,\n base: 16,\n lg: 18,\n xl: 20,\n \"2xl\": 24,\n \"3xl\": 30,\n \"4xl\": 36,\n \"5xl\": 48,\n \"6xl\": 60,\n \"7xl\": 72,\n \"8xl\": 96,\n} as const;\n\n// ============================================\n// Line Heights\n// ============================================\n\n/**\n * Line height scale\n *\n * Using unitless values for better inheritance.\n */\nexport const lineHeights = {\n /** 1 - Single line, icons */\n none: 1,\n\n /** 1.25 - Tight, for large headings */\n tight: 1.25,\n\n /** 1.375 - Slightly snug */\n snug: 1.375,\n\n /** 1.5 - Normal body text */\n normal: 1.5,\n\n /** 1.625 - Relaxed reading */\n relaxed: 1.625,\n\n /** 1.75 - Loose, for small text */\n loose: 1.75,\n\n /** 2 - Double spaced */\n double: 2,\n} as const;\n\n// ============================================\n// Font Weights\n// ============================================\n\n/**\n * Font weight scale\n *\n * Inter and Public Sans support all these weights.\n * Variable fonts can use any value 100-900.\n */\nexport const fontWeights = {\n /** 100 - Thin (if available) */\n thin: 100,\n\n /** 200 - Extra light */\n extralight: 200,\n\n /** 300 - Light */\n light: 300,\n\n /** 400 - Regular/Normal */\n normal: 400,\n\n /** 500 - Medium */\n medium: 500,\n\n /** 600 - Semibold */\n semibold: 600,\n\n /** 700 - Bold */\n bold: 700,\n\n /** 800 - Extra bold */\n extrabold: 800,\n\n /** 900 - Black */\n black: 900,\n} as const;\n\n// ============================================\n// Letter Spacing (Tracking)\n// ============================================\n\n/**\n * Letter spacing scale\n *\n * Negative values for tight headlines, positive for small caps.\n */\nexport const letterSpacing = {\n /** -0.05em - Very tight, large display only */\n tighter: \"-0.05em\",\n\n /** -0.025em - Slightly tight, headings */\n tight: \"-0.025em\",\n\n /** 0 - Normal */\n normal: \"0\",\n\n /** 0.025em - Slightly wide */\n wide: \"0.025em\",\n\n /** 0.05em - Wide, for small caps */\n wider: \"0.05em\",\n\n /** 0.1em - Very wide, all caps */\n widest: \"0.1em\",\n} as const;\n\n// ============================================\n// Combined Type Styles\n// ============================================\n\n/**\n * Pre-defined typography presets\n *\n * These combine font-family, size, weight, and line-height\n * for common use cases.\n */\nexport const typeStyles = {\n /** Hero/Display - Large marketing headlines */\n display: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes[\"6xl\"],\n fontWeight: fontWeights.bold,\n lineHeight: lineHeights.tight,\n letterSpacing: letterSpacing.tight,\n },\n\n /** H1 - Page titles */\n h1: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes[\"5xl\"],\n fontWeight: fontWeights.bold,\n lineHeight: lineHeights.tight,\n letterSpacing: letterSpacing.tight,\n },\n\n /** H2 - Section titles */\n h2: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes[\"4xl\"],\n fontWeight: fontWeights.bold,\n lineHeight: lineHeights.tight,\n letterSpacing: letterSpacing.tight,\n },\n\n /** H3 - Subsection titles */\n h3: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes[\"3xl\"],\n fontWeight: fontWeights.semibold,\n lineHeight: lineHeights.snug,\n letterSpacing: letterSpacing.normal,\n },\n\n /** H4 - Card titles, small sections */\n h4: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes[\"2xl\"],\n fontWeight: fontWeights.semibold,\n lineHeight: lineHeights.snug,\n letterSpacing: letterSpacing.normal,\n },\n\n /** H5 - Widget titles */\n h5: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes.xl,\n fontWeight: fontWeights.semibold,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.normal,\n },\n\n /** H6 - Smallest heading */\n h6: {\n fontFamily: fontFamilies.heading,\n fontSize: fontSizes.lg,\n fontWeight: fontWeights.semibold,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Body - Default paragraph text */\n body: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.base,\n fontWeight: fontWeights.normal,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Body Large - Lead paragraphs */\n bodyLarge: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.lg,\n fontWeight: fontWeights.normal,\n lineHeight: lineHeights.relaxed,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Body Small - Secondary text */\n bodySmall: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.sm,\n fontWeight: fontWeights.normal,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Caption - Image captions, timestamps */\n caption: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.xs,\n fontWeight: fontWeights.normal,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.wide,\n },\n\n /** Label - Form labels, UI labels */\n label: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.sm,\n fontWeight: fontWeights.medium,\n lineHeight: lineHeights.tight,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Button - Button text */\n button: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.sm,\n fontWeight: fontWeights.medium,\n lineHeight: lineHeights.tight,\n letterSpacing: letterSpacing.wide,\n },\n\n /** Code - Inline code */\n code: {\n fontFamily: fontFamilies.mono,\n fontSize: fontSizes.sm,\n fontWeight: fontWeights.normal,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Code Block - Code blocks */\n codeBlock: {\n fontFamily: fontFamilies.mono,\n fontSize: fontSizes.sm,\n fontWeight: fontWeights.normal,\n lineHeight: lineHeights.relaxed,\n letterSpacing: letterSpacing.normal,\n },\n\n /** Overline - Small caps labels */\n overline: {\n fontFamily: fontFamilies.primary,\n fontSize: fontSizes.xs,\n fontWeight: fontWeights.semibold,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.widest,\n textTransform: \"uppercase\" as const,\n },\n} as const;\n\nexport type TypeStyle = keyof typeof typeStyles;\n\n// ============================================\n// Responsive Typography\n// ============================================\n\n/**\n * Fluid typography clamp values\n *\n * Format: clamp(min, preferred, max)\n * Uses viewport width for smooth scaling.\n */\nexport const fluidFontSizes = {\n /** Display: 36px to 72px */\n display: \"clamp(2.25rem, 5vw + 1rem, 4.5rem)\",\n\n /** H1: 30px to 48px */\n h1: \"clamp(1.875rem, 4vw + 0.5rem, 3rem)\",\n\n /** H2: 24px to 36px */\n h2: \"clamp(1.5rem, 3vw + 0.5rem, 2.25rem)\",\n\n /** H3: 20px to 30px */\n h3: \"clamp(1.25rem, 2vw + 0.5rem, 1.875rem)\",\n\n /** Body: 14px to 18px */\n body: \"clamp(0.875rem, 1vw + 0.5rem, 1.125rem)\",\n} as const;\n\n// ============================================\n// Type Exports\n// ============================================\n\nexport type FontFamily = keyof typeof fontFamilies;\nexport type FontSize = keyof typeof fontSizes;\nexport type LineHeight = keyof typeof lineHeights;\nexport type FontWeight = keyof typeof fontWeights;\nexport type LetterSpacing = keyof typeof letterSpacing;\n"]}
@@ -3,35 +3,57 @@ import { ClassValue } from 'clsx';
3
3
  declare function cn(...inputs: ClassValue[]): string;
4
4
 
5
5
  /**
6
- * Brand Color Utilities
6
+ * Runtime color resolution for APIs that cannot consume CSS variables
7
+ * (Canvas, WebGL, some animation libs).
7
8
  *
8
- * Resolves Nebutra brand CSS variables at runtime for components that
9
- * require raw hex values (e.g. WebGL shaders, Canvas APIs, animation libraries
10
- * that can't consume `var(--token)` strings directly).
9
+ * Layers (do not mix):
10
+ * - Product action / CTA: getProductPrimary() → semantic `--primary` (roles.action)
11
+ * - Brand mark / AI badge / logo tint: getBrandMark() → `--brand-mark` (roles.brand)
12
+ * - VI lock (print / legal assets): getBrandPrimary() → `--brand-primary` hex
11
13
  *
12
- * Components that accept CSS color strings (inline styles, gradients, SVG)
13
- * should prefer `var(--brand-primary)` / `var(--brand-accent)` directly
14
- * instead of calling these helpers.
14
+ * Prefer CSS / Tailwind in components:
15
+ * - `bg-primary` for CTAs
16
+ * - `bg-brand-mark` / `text-brand-mark` for Logo/AI badge (see recipe.css)
17
+ *
18
+ * @see packages/design/ARCHITECTURE.md
19
+ * @see packages/design/tokens/recipe.css
15
20
  */
16
- /** SSR / no-DOM fallbacks — only used when `window` is unavailable. */
21
+ /** SSR fallbacks when document is unavailable */
17
22
  declare const BRAND_FALLBACK: {
23
+ /** VI 云毓蓝 — identity only */
18
24
  readonly primary: "#0033FE";
19
25
  readonly accent: "#0BF1C3";
20
26
  readonly tertiary: "#5c7cfa";
21
27
  readonly primaryDark: "#002ad4";
22
28
  readonly backDark: "#000830";
29
+ /** Soft product action (matches themes/light --primary ≈ #254bfa) */
30
+ readonly productPrimary: "#254bfa";
31
+ /**
32
+ * Brand mark fallback (= product action when factory brand has action≡brand).
33
+ * Skins may diverge (e.g. Linear purple action + indigo mark).
34
+ */
35
+ readonly brandMark: "#254bfa";
36
+ readonly brandMarkForeground: "#ffffff";
23
37
  };
24
38
  /**
25
39
  * Read a CSS variable from :root and return its trimmed value.
26
- * Falls back to `fallback` in SSR/no-DOM environments or when the var
27
- * is unresolved (empty string).
28
40
  */
29
41
  declare function readCssVar(name: string, fallback: string): string;
30
- /** Resolve `--brand-primary` to a hex/color string (with SSR fallback). */
42
+ /**
43
+ * Product action color — follows the active skin (`--primary`).
44
+ * Use for shaders/canvas that must match buttons/CTAs.
45
+ */
46
+ declare function getProductPrimary(): string;
47
+ /** VI lock color — legal / print lockups only (not product chrome). */
31
48
  declare function getBrandPrimary(): string;
32
- /** Resolve `--brand-accent` to a hex/color string (with SSR fallback). */
49
+ /**
50
+ * Product brand-mark (roles.brand) — Logo tile, AI badge, identity chips.
51
+ * Never use for default CTA (that is getProductPrimary / --primary).
52
+ */
53
+ declare function getBrandMark(): string;
54
+ /** Foreground on brand-mark surfaces. */
55
+ declare function getBrandMarkForeground(): string;
33
56
  declare function getBrandAccent(): string;
34
- /** Resolve `--brand-tertiary` to a hex/color string (with SSR fallback). */
35
57
  declare function getBrandTertiary(): string;
36
58
 
37
59
  /**
@@ -58,4 +80,4 @@ type Breakpoint = keyof typeof BREAKPOINTS;
58
80
  */
59
81
  declare function isBreakpointUp(breakpoint: Breakpoint): boolean;
60
82
 
61
- export { BRAND_FALLBACK, BREAKPOINTS, type Breakpoint, cn, getBrandAccent, getBrandPrimary, getBrandTertiary, isBreakpointUp, readCssVar };
83
+ export { BRAND_FALLBACK, BREAKPOINTS, type Breakpoint, cn, getBrandAccent, getBrandMark, getBrandMarkForeground, getBrandPrimary, getBrandTertiary, getProductPrimary, isBreakpointUp, readCssVar };
@@ -9,16 +9,20 @@ function cn(...inputs) {
9
9
 
10
10
  // src/utils/brand-colors.ts
11
11
  var BRAND_FALLBACK = {
12
+ /** VI 云毓蓝 — identity only */
12
13
  primary: "#0033FE",
13
- // nebutra-blue-500
14
14
  accent: "#0BF1C3",
15
- // nebutra-cyan-500
16
15
  tertiary: "#5c7cfa",
17
- // nebutra-blue-400
18
16
  primaryDark: "#002ad4",
19
- // nebutra-blue-600
20
- backDark: "#000830"
21
- // nebutra-blue-950
17
+ backDark: "#000830",
18
+ /** Soft product action (matches themes/light --primary ≈ #254bfa) */
19
+ productPrimary: "#254bfa",
20
+ /**
21
+ * Brand mark fallback (= product action when factory brand has action≡brand).
22
+ * Skins may diverge (e.g. Linear purple action + indigo mark).
23
+ */
24
+ brandMark: "#254bfa",
25
+ brandMarkForeground: "#ffffff"
22
26
  };
23
27
  function readCssVar(name, fallback) {
24
28
  if (typeof window === "undefined" || typeof document === "undefined") {
@@ -27,14 +31,44 @@ function readCssVar(name, fallback) {
27
31
  const value = getComputedStyle(document.documentElement).getPropertyValue(name).trim();
28
32
  return value || fallback;
29
33
  }
34
+ function asCssColor(value, fallback) {
35
+ const v = value.trim() || fallback;
36
+ if (v.startsWith("#") || v.startsWith("rgb") || v.startsWith("hsl") || v.startsWith("oklch") || v.startsWith("color(")) {
37
+ return v;
38
+ }
39
+ return `hsl(${v})`;
40
+ }
41
+ function getProductPrimary() {
42
+ return asCssColor(readCssVar("--primary", "228 85% 56%"), BRAND_FALLBACK.productPrimary);
43
+ }
30
44
  function getBrandPrimary() {
31
- return readCssVar("--brand-primary", BRAND_FALLBACK.primary);
45
+ return asCssVarColor("--brand-primary", BRAND_FALLBACK.primary);
46
+ }
47
+ function getBrandMark() {
48
+ const raw = readCssVar("--brand-mark", "228 85% 56%");
49
+ if (/var\(\s*--primary\s*\)/u.test(raw)) {
50
+ return getProductPrimary();
51
+ }
52
+ return asCssColor(raw, BRAND_FALLBACK.brandMark);
53
+ }
54
+ function getBrandMarkForeground() {
55
+ const raw = readCssVar("--brand-mark-foreground", "0 0% 100%");
56
+ if (/var\(\s*--primary-foreground\s*\)/u.test(raw)) {
57
+ return asCssColor(
58
+ readCssVar("--primary-foreground", "0 0% 100%"),
59
+ BRAND_FALLBACK.brandMarkForeground
60
+ );
61
+ }
62
+ return asCssColor(raw, BRAND_FALLBACK.brandMarkForeground);
63
+ }
64
+ function asCssVarColor(name, fallback) {
65
+ return asCssColor(readCssVar(name, fallback), fallback);
32
66
  }
33
67
  function getBrandAccent() {
34
- return readCssVar("--brand-accent", BRAND_FALLBACK.accent);
68
+ return asCssVarColor("--brand-accent", BRAND_FALLBACK.accent);
35
69
  }
36
70
  function getBrandTertiary() {
37
- return readCssVar("--brand-tertiary", BRAND_FALLBACK.tertiary);
71
+ return asCssVarColor("--brand-tertiary", BRAND_FALLBACK.tertiary);
38
72
  }
39
73
 
40
74
  // src/utils/index.ts
@@ -50,6 +84,6 @@ function isBreakpointUp(breakpoint) {
50
84
  return window.innerWidth >= BREAKPOINTS[breakpoint];
51
85
  }
52
86
 
53
- export { BRAND_FALLBACK, BREAKPOINTS, cn, getBrandAccent, getBrandPrimary, getBrandTertiary, isBreakpointUp, readCssVar };
87
+ export { BRAND_FALLBACK, BREAKPOINTS, cn, getBrandAccent, getBrandMark, getBrandMarkForeground, getBrandPrimary, getBrandTertiary, getProductPrimary, isBreakpointUp, readCssVar };
54
88
  //# sourceMappingURL=index.js.map
55
89
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/cn.ts","../../src/utils/brand-colors.ts","../../src/utils/index.ts"],"names":[],"mappings":";;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;;;ACQO,IAAM,cAAA,GAAiB;AAAA,EAC5B,OAAA,EAAS,SAAA;AAAA;AAAA,EACT,MAAA,EAAQ,SAAA;AAAA;AAAA,EACR,QAAA,EAAU,SAAA;AAAA;AAAA,EACV,WAAA,EAAa,SAAA;AAAA;AAAA,EACb,QAAA,EAAU;AAAA;AACZ;AAOO,SAAS,UAAA,CAAW,MAAc,QAAA,EAA0B;AACjE,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,aAAa,WAAA,EAAa;AACpE,IAAA,OAAO,QAAA;AAAA,EACT;AACA,EAAA,MAAM,KAAA,GAAQ,iBAAiB,QAAA,CAAS,eAAe,EAAE,gBAAA,CAAiB,IAAI,EAAE,IAAA,EAAK;AACrF,EAAA,OAAO,KAAA,IAAS,QAAA;AAClB;AAGO,SAAS,eAAA,GAA0B;AACxC,EAAA,OAAO,UAAA,CAAW,iBAAA,EAAmB,cAAA,CAAe,OAAO,CAAA;AAC7D;AAGO,SAAS,cAAA,GAAyB;AACvC,EAAA,OAAO,UAAA,CAAW,gBAAA,EAAkB,cAAA,CAAe,MAAM,CAAA;AAC3D;AAGO,SAAS,gBAAA,GAA2B;AACzC,EAAA,OAAO,UAAA,CAAW,kBAAA,EAAoB,cAAA,CAAe,QAAQ,CAAA;AAC/D;;;AClCO,IAAM,WAAA,GAAc;AAAA,EACzB,EAAA,EAAI,CAAA;AAAA,EACJ,EAAA,EAAI,GAAA;AAAA,EACJ,EAAA,EAAI,GAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI;AACN;AAOO,SAAS,eAAe,UAAA,EAAiC;AAC9D,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,IAAA;AAC1C,EAAA,OAAO,MAAA,CAAO,UAAA,IAAc,WAAA,CAAY,UAAU,CAAA;AACpD","file":"index.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","/**\n * Brand Color Utilities\n *\n * Resolves Nebutra brand CSS variables at runtime for components that\n * require raw hex values (e.g. WebGL shaders, Canvas APIs, animation libraries\n * that can't consume `var(--token)` strings directly).\n *\n * Components that accept CSS color strings (inline styles, gradients, SVG)\n * should prefer `var(--brand-primary)` / `var(--brand-accent)` directly\n * instead of calling these helpers.\n */\n\n/** SSR / no-DOM fallbacks — only used when `window` is unavailable. */\nexport const BRAND_FALLBACK = {\n primary: \"#0033FE\", // nebutra-blue-500\n accent: \"#0BF1C3\", // nebutra-cyan-500\n tertiary: \"#5c7cfa\", // nebutra-blue-400\n primaryDark: \"#002ad4\", // nebutra-blue-600\n backDark: \"#000830\", // nebutra-blue-950\n} as const;\n\n/**\n * Read a CSS variable from :root and return its trimmed value.\n * Falls back to `fallback` in SSR/no-DOM environments or when the var\n * is unresolved (empty string).\n */\nexport function readCssVar(name: string, fallback: string): string {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n return fallback;\n }\n const value = getComputedStyle(document.documentElement).getPropertyValue(name).trim();\n return value || fallback;\n}\n\n/** Resolve `--brand-primary` to a hex/color string (with SSR fallback). */\nexport function getBrandPrimary(): string {\n return readCssVar(\"--brand-primary\", BRAND_FALLBACK.primary);\n}\n\n/** Resolve `--brand-accent` to a hex/color string (with SSR fallback). */\nexport function getBrandAccent(): string {\n return readCssVar(\"--brand-accent\", BRAND_FALLBACK.accent);\n}\n\n/** Resolve `--brand-tertiary` to a hex/color string (with SSR fallback). */\nexport function getBrandTertiary(): string {\n return readCssVar(\"--brand-tertiary\", BRAND_FALLBACK.tertiary);\n}\n","/**\n * Utility Functions\n */\n\n/**\n * Merge class names — canonical implementation from ./cn.ts\n * Uses twMerge(clsx(...)) to correctly resolve Tailwind class conflicts.\n */\nexport { cn } from \"./cn\";\n\n/**\n * Breakpoint values (matches Primer)\n */\nexport const BREAKPOINTS = {\n xs: 0,\n sm: 544,\n md: 768,\n lg: 1012,\n xl: 1280,\n} as const;\n\nexport type Breakpoint = keyof typeof BREAKPOINTS;\n\n/**\n * Check if viewport is at or above breakpoint\n */\nexport function isBreakpointUp(breakpoint: Breakpoint): boolean {\n if (typeof window === \"undefined\") return true;\n return window.innerWidth >= BREAKPOINTS[breakpoint];\n}\n\nexport {\n BRAND_FALLBACK,\n getBrandAccent,\n getBrandPrimary,\n getBrandTertiary,\n readCssVar,\n} from \"./brand-colors\";\n"]}
1
+ {"version":3,"sources":["../../src/utils/cn.ts","../../src/utils/brand-colors.ts","../../src/utils/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","/**\n * Runtime color resolution for APIs that cannot consume CSS variables\n * (Canvas, WebGL, some animation libs).\n *\n * Layers (do not mix):\n * - Product action / CTA: getProductPrimary() → semantic `--primary` (roles.action)\n * - Brand mark / AI badge / logo tint: getBrandMark() → `--brand-mark` (roles.brand)\n * - VI lock (print / legal assets): getBrandPrimary() → `--brand-primary` hex\n *\n * Prefer CSS / Tailwind in components:\n * - `bg-primary` for CTAs\n * - `bg-brand-mark` / `text-brand-mark` for Logo/AI badge (see recipe.css)\n *\n * @see packages/design/ARCHITECTURE.md\n * @see packages/design/tokens/recipe.css\n */\n\n/** SSR fallbacks when document is unavailable */\nexport const BRAND_FALLBACK = {\n /** VI 云毓蓝 — identity only */\n primary: \"#0033FE\",\n accent: \"#0BF1C3\",\n tertiary: \"#5c7cfa\",\n primaryDark: \"#002ad4\",\n backDark: \"#000830\",\n /** Soft product action (matches themes/light --primary ≈ #254bfa) */\n productPrimary: \"#254bfa\",\n /**\n * Brand mark fallback (= product action when factory brand has action≡brand).\n * Skins may diverge (e.g. Linear purple action + indigo mark).\n */\n brandMark: \"#254bfa\",\n brandMarkForeground: \"#ffffff\",\n} as const;\n\n/**\n * Read a CSS variable from :root and return its trimmed value.\n */\nexport function readCssVar(name: string, fallback: string): string {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n return fallback;\n }\n const value = getComputedStyle(document.documentElement).getPropertyValue(name).trim();\n return value || fallback;\n}\n\n/** Turn HSL channel triple or full color into a CSS color string. */\nfunction asCssColor(value: string, fallback: string): string {\n const v = value.trim() || fallback;\n if (\n v.startsWith(\"#\") ||\n v.startsWith(\"rgb\") ||\n v.startsWith(\"hsl\") ||\n v.startsWith(\"oklch\") ||\n v.startsWith(\"color(\")\n ) {\n return v;\n }\n // shadcn-style \"228 85% 56%\"\n return `hsl(${v})`;\n}\n\n/**\n * Product action color — follows the active skin (`--primary`).\n * Use for shaders/canvas that must match buttons/CTAs.\n */\nexport function getProductPrimary(): string {\n return asCssColor(readCssVar(\"--primary\", \"228 85% 56%\"), BRAND_FALLBACK.productPrimary);\n}\n\n/** VI lock color — legal / print lockups only (not product chrome). */\nexport function getBrandPrimary(): string {\n return asCssVarColor(\"--brand-primary\", BRAND_FALLBACK.primary);\n}\n\n/**\n * Product brand-mark (roles.brand) — Logo tile, AI badge, identity chips.\n * Never use for default CTA (that is getProductPrimary / --primary).\n */\nexport function getBrandMark(): string {\n const raw = readCssVar(\"--brand-mark\", \"228 85% 56%\");\n // Factory recipe defaults `--brand-mark: var(--primary)` — resolve to action color.\n if (/var\\(\\s*--primary\\s*\\)/u.test(raw)) {\n return getProductPrimary();\n }\n return asCssColor(raw, BRAND_FALLBACK.brandMark);\n}\n\n/** Foreground on brand-mark surfaces. */\nexport function getBrandMarkForeground(): string {\n const raw = readCssVar(\"--brand-mark-foreground\", \"0 0% 100%\");\n if (/var\\(\\s*--primary-foreground\\s*\\)/u.test(raw)) {\n return asCssColor(\n readCssVar(\"--primary-foreground\", \"0 0% 100%\"),\n BRAND_FALLBACK.brandMarkForeground,\n );\n }\n return asCssColor(raw, BRAND_FALLBACK.brandMarkForeground);\n}\n\nfunction asCssVarColor(name: string, fallback: string): string {\n return asCssColor(readCssVar(name, fallback), fallback);\n}\n\nexport function getBrandAccent(): string {\n return asCssVarColor(\"--brand-accent\", BRAND_FALLBACK.accent);\n}\n\nexport function getBrandTertiary(): string {\n return asCssVarColor(\"--brand-tertiary\", BRAND_FALLBACK.tertiary);\n}\n","/**\n * Utility Functions\n */\n\n/**\n * Merge class names — canonical implementation from ./cn.ts\n * Uses twMerge(clsx(...)) to correctly resolve Tailwind class conflicts.\n */\nexport { cn } from \"./cn\";\n\n/**\n * Breakpoint values (matches Primer)\n */\nexport const BREAKPOINTS = {\n xs: 0,\n sm: 544,\n md: 768,\n lg: 1012,\n xl: 1280,\n} as const;\n\nexport type Breakpoint = keyof typeof BREAKPOINTS;\n\n/**\n * Check if viewport is at or above breakpoint\n */\nexport function isBreakpointUp(breakpoint: Breakpoint): boolean {\n if (typeof window === \"undefined\") return true;\n return window.innerWidth >= BREAKPOINTS[breakpoint];\n}\n\nexport {\n BRAND_FALLBACK,\n getBrandAccent,\n getBrandMark,\n getBrandMarkForeground,\n getBrandPrimary,\n getBrandTertiary,\n getProductPrimary,\n readCssVar,\n} from \"./brand-colors\";\n"]}