@nebutra/ui 2.0.0 → 3.0.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 (43) hide show
  1. package/dist/{canonical-Bf4czR2u.d.ts → canonical-DEhT4VfS.d.ts} +71 -120
  2. package/dist/card-DunB1gKE.d.ts +105 -0
  3. package/dist/components/index.d.ts +33 -4
  4. package/dist/components/index.js +225 -89
  5. package/dist/components/index.js.map +1 -1
  6. package/dist/editorial/index.d.ts +2 -2
  7. package/dist/editorial/index.js +75 -1
  8. package/dist/editorial/index.js.map +1 -1
  9. package/dist/empty-state-bmfHCOuN.d.ts +86 -0
  10. package/dist/hooks/index.d.ts +18 -1
  11. package/dist/hooks/index.js +120 -5
  12. package/dist/hooks/index.js.map +1 -1
  13. package/dist/index.d.ts +1 -1
  14. package/dist/layout/index.d.ts +17 -58
  15. package/dist/layout/index.js +366 -126
  16. package/dist/layout/index.js.map +1 -1
  17. package/dist/layouts/index.d.ts +1 -1
  18. package/dist/layouts/index.js +89 -15
  19. package/dist/layouts/index.js.map +1 -1
  20. package/dist/patterns/index.d.ts +38 -44
  21. package/dist/patterns/index.js +470 -278
  22. package/dist/patterns/index.js.map +1 -1
  23. package/dist/primitives/canonical.d.ts +3 -1
  24. package/dist/primitives/canonical.js +495 -231
  25. package/dist/primitives/canonical.js.map +1 -1
  26. package/dist/primitives/index.d.ts +90 -62
  27. package/dist/primitives/index.js +1129 -1185
  28. package/dist/primitives/index.js.map +1 -1
  29. package/dist/tailwind.preset.d.ts +32 -32
  30. package/dist/tailwind.preset.js +24 -20
  31. package/dist/tailwind.preset.js.map +1 -1
  32. package/dist/theme/index.d.ts +1 -110
  33. package/dist/typography/fonts.css +8 -16
  34. package/dist/typography/index.d.ts +29 -45
  35. package/dist/typography/index.js +26 -14
  36. package/dist/typography/index.js.map +1 -1
  37. package/dist/utils/index.d.ts +18 -12
  38. package/dist/utils/index.js +94 -18
  39. package/dist/utils/index.js.map +1 -1
  40. package/package.json +6 -10
  41. package/src/typography/fonts.css +8 -16
  42. package/dist/styles/brand-override.css +0 -61
  43. package/src/styles/brand-override.css +0 -61
@@ -104,44 +104,28 @@ declare const fontLicenseNotice: string;
104
104
  * Centralized typography configuration for the entire design system.
105
105
  * All font-related values should come from here.
106
106
  */
107
- /**
108
- * Primary font stack - Used for body text and UI.
109
- *
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
- */
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
- /**
115
- * Heading font stack - Used for titles and emphasis
116
- *
117
- * Geist Sans is the primary display typeface.
118
- */
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
- /**
121
- * Monospace font stack - Used for code and technical content
122
- */
123
- declare const FONT_FAMILY_MONO = "var(--font-mono, var(--font-geist-mono, \"Geist Mono\", ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, monospace))";
124
- /**
125
- * CJK (Chinese/Japanese/Korean) fallback stack
126
- *
127
- * Noto Sans SC is the primary Chinese font.
128
- * Provides consistent rendering for Chinese, Japanese, and Korean text.
129
- */
130
- declare const FONT_FAMILY_CJK = "\"Noto Sans SC\", \"Source Han Sans SC\", \"Source Han Sans\", \"Noto Sans CJK SC\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", sans-serif";
107
+ /** Primary font stack — body text and UI. */
108
+ declare const FONT_FAMILY_PRIMARY: string;
109
+ /** Heading font stack — titles and emphasis (DM Sans, CJK through MiSans). */
110
+ declare const FONT_FAMILY_HEADING: string;
111
+ /** Monospace font stack — code and technical content. */
112
+ declare const FONT_FAMILY_MONO: string;
113
+ /** CJK-locale stack — MiSans behind the Latin face, system CJK faces after it. */
114
+ declare const FONT_FAMILY_CJK: string;
131
115
  /**
132
116
  * Complete font stacks with CJK fallback
133
117
  */
134
118
  declare const fontFamilies: {
135
119
  /** Primary UI and body text */
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))";
120
+ readonly primary: string;
137
121
  /** Headings and titles */
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))";
122
+ readonly heading: string;
139
123
  /** Code and monospace */
140
- readonly mono: "var(--font-mono, var(--font-geist-mono, \"Geist Mono\", ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, monospace))";
124
+ readonly mono: string;
141
125
  /** CJK-specific fallback */
142
- readonly cjk: "\"Noto Sans SC\", \"Source Han Sans SC\", \"Source Han Sans\", \"Noto Sans CJK SC\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", sans-serif";
126
+ readonly cjk: string;
143
127
  /** Primary with CJK fallback for multilingual content */
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)), \"Noto Sans SC\", \"Source Han Sans SC\", \"Source Han Sans\", \"Noto Sans CJK SC\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", sans-serif";
128
+ readonly primaryCJK: `${string}, ${string}`;
145
129
  /** System font stack (fast fallback, no web fonts) */
146
130
  readonly system: "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
147
131
  };
@@ -269,7 +253,7 @@ declare const letterSpacing: {
269
253
  declare const typeStyles: {
270
254
  /** Hero/Display - Large marketing headlines */
271
255
  readonly display: {
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))";
256
+ readonly fontFamily: string;
273
257
  readonly fontSize: "3.75rem";
274
258
  readonly fontWeight: 700;
275
259
  readonly lineHeight: 1.25;
@@ -277,7 +261,7 @@ declare const typeStyles: {
277
261
  };
278
262
  /** H1 - Page titles */
279
263
  readonly h1: {
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))";
264
+ readonly fontFamily: string;
281
265
  readonly fontSize: "3rem";
282
266
  readonly fontWeight: 700;
283
267
  readonly lineHeight: 1.25;
@@ -285,7 +269,7 @@ declare const typeStyles: {
285
269
  };
286
270
  /** H2 - Section titles */
287
271
  readonly h2: {
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))";
272
+ readonly fontFamily: string;
289
273
  readonly fontSize: "2.25rem";
290
274
  readonly fontWeight: 700;
291
275
  readonly lineHeight: 1.25;
@@ -293,7 +277,7 @@ declare const typeStyles: {
293
277
  };
294
278
  /** H3 - Subsection titles */
295
279
  readonly h3: {
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))";
280
+ readonly fontFamily: string;
297
281
  readonly fontSize: "1.875rem";
298
282
  readonly fontWeight: 600;
299
283
  readonly lineHeight: 1.375;
@@ -301,7 +285,7 @@ declare const typeStyles: {
301
285
  };
302
286
  /** H4 - Card titles, small sections */
303
287
  readonly h4: {
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))";
288
+ readonly fontFamily: string;
305
289
  readonly fontSize: "1.5rem";
306
290
  readonly fontWeight: 600;
307
291
  readonly lineHeight: 1.375;
@@ -309,7 +293,7 @@ declare const typeStyles: {
309
293
  };
310
294
  /** H5 - Widget titles */
311
295
  readonly h5: {
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))";
296
+ readonly fontFamily: string;
313
297
  readonly fontSize: "1.25rem";
314
298
  readonly fontWeight: 600;
315
299
  readonly lineHeight: 1.5;
@@ -317,7 +301,7 @@ declare const typeStyles: {
317
301
  };
318
302
  /** H6 - Smallest heading */
319
303
  readonly h6: {
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))";
304
+ readonly fontFamily: string;
321
305
  readonly fontSize: "1.125rem";
322
306
  readonly fontWeight: 600;
323
307
  readonly lineHeight: 1.5;
@@ -325,7 +309,7 @@ declare const typeStyles: {
325
309
  };
326
310
  /** Body - Default paragraph text */
327
311
  readonly body: {
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))";
312
+ readonly fontFamily: string;
329
313
  readonly fontSize: "1rem";
330
314
  readonly fontWeight: 400;
331
315
  readonly lineHeight: 1.5;
@@ -333,7 +317,7 @@ declare const typeStyles: {
333
317
  };
334
318
  /** Body Large - Lead paragraphs */
335
319
  readonly bodyLarge: {
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))";
320
+ readonly fontFamily: string;
337
321
  readonly fontSize: "1.125rem";
338
322
  readonly fontWeight: 400;
339
323
  readonly lineHeight: 1.625;
@@ -341,7 +325,7 @@ declare const typeStyles: {
341
325
  };
342
326
  /** Body Small - Secondary text */
343
327
  readonly bodySmall: {
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))";
328
+ readonly fontFamily: string;
345
329
  readonly fontSize: "0.875rem";
346
330
  readonly fontWeight: 400;
347
331
  readonly lineHeight: 1.5;
@@ -349,7 +333,7 @@ declare const typeStyles: {
349
333
  };
350
334
  /** Caption - Image captions, timestamps */
351
335
  readonly caption: {
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))";
336
+ readonly fontFamily: string;
353
337
  readonly fontSize: "0.75rem";
354
338
  readonly fontWeight: 400;
355
339
  readonly lineHeight: 1.5;
@@ -357,7 +341,7 @@ declare const typeStyles: {
357
341
  };
358
342
  /** Label - Form labels, UI labels */
359
343
  readonly label: {
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))";
344
+ readonly fontFamily: string;
361
345
  readonly fontSize: "0.875rem";
362
346
  readonly fontWeight: 500;
363
347
  readonly lineHeight: 1.25;
@@ -365,7 +349,7 @@ declare const typeStyles: {
365
349
  };
366
350
  /** Button - Button text */
367
351
  readonly button: {
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))";
352
+ readonly fontFamily: string;
369
353
  readonly fontSize: "0.875rem";
370
354
  readonly fontWeight: 500;
371
355
  readonly lineHeight: 1.25;
@@ -373,7 +357,7 @@ declare const typeStyles: {
373
357
  };
374
358
  /** Code - Inline code */
375
359
  readonly code: {
376
- readonly fontFamily: "var(--font-mono, var(--font-geist-mono, \"Geist Mono\", ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, monospace))";
360
+ readonly fontFamily: string;
377
361
  readonly fontSize: "0.875rem";
378
362
  readonly fontWeight: 400;
379
363
  readonly lineHeight: 1.5;
@@ -381,7 +365,7 @@ declare const typeStyles: {
381
365
  };
382
366
  /** Code Block - Code blocks */
383
367
  readonly codeBlock: {
384
- readonly fontFamily: "var(--font-mono, var(--font-geist-mono, \"Geist Mono\", ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, monospace))";
368
+ readonly fontFamily: string;
385
369
  readonly fontSize: "0.875rem";
386
370
  readonly fontWeight: 400;
387
371
  readonly lineHeight: 1.625;
@@ -389,7 +373,7 @@ declare const typeStyles: {
389
373
  };
390
374
  /** Overline - Small caps labels */
391
375
  readonly overline: {
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))";
376
+ readonly fontFamily: string;
393
377
  readonly fontSize: "0.75rem";
394
378
  readonly fontWeight: 600;
395
379
  readonly lineHeight: 1.5;
@@ -1,3 +1,5 @@
1
+ import { tokenValue } from '@nebutra/tokens/values';
2
+
1
3
  // src/typography/fonts.ts
2
4
  var fonts = {
3
5
  geistSans: {
@@ -48,15 +50,25 @@ var fonts = {
48
50
  license: "OFL",
49
51
  licenseUrl: "https://github.com/JetBrains/JetBrainsMono/blob/master/OFL.txt"
50
52
  },
51
- sourceHanSans: {
52
- family: "Noto Sans SC",
53
- weights: [400, 500, 700],
53
+ dmSans: {
54
+ family: "DM Sans",
55
+ weights: [400, 500, 600],
54
56
  italic: false,
55
57
  display: "swap",
56
- variable: false,
57
- googleFontsParam: "Noto+Sans+SC:wght@400;500;700",
58
+ variable: true,
59
+ selfHostUrl: "@nebutra/fonts/next/cjk (dmSans)",
58
60
  license: "OFL",
59
- licenseUrl: "https://github.com/adobe-fonts/source-han-sans/blob/master/LICENSE.txt"
61
+ licenseUrl: "https://github.com/googlefonts/dm-fonts/blob/main/OFL.txt"
62
+ },
63
+ misans: {
64
+ family: "MiSans",
65
+ weights: [400, 500, 600, 700],
66
+ italic: false,
67
+ display: "swap",
68
+ variable: false,
69
+ selfHostUrl: "@nebutra/fonts/next/cjk (misans)",
70
+ license: "Other",
71
+ licenseUrl: "https://hyperos.mi.com/font/zh/download/"
60
72
  }
61
73
  };
62
74
  function getGoogleFontsUrl(fontKeys) {
@@ -65,7 +77,7 @@ function getGoogleFontsUrl(fontKeys) {
65
77
  return `https://fonts.googleapis.com/css2?family=${families}&display=swap`;
66
78
  }
67
79
  var defaultFonts = ["geistSans", "geistMono"];
68
- var cjkFonts = ["sourceHanSans"];
80
+ var cjkFonts = ["misans"];
69
81
  var allFonts = [...defaultFonts, ...cjkFonts];
70
82
  function getFontPreloadLinks(fontKeys) {
71
83
  return fontKeys.map((key) => {
@@ -131,16 +143,16 @@ Fonts used in this project are licensed under open-source licenses:
131
143
  - Geist: SIL Open Font License 1.1
132
144
  - Geist Mono: SIL Open Font License 1.1
133
145
  - JetBrains Mono: SIL Open Font License 1.1
134
- - Noto Sans SC (Source Han Sans): SIL Open Font License 1.1
146
+ - DM Sans: SIL Open Font License 1.1
147
+ - MiSans (Xiaomi): free for commercial use; embedding requires stating that MiSans is used
135
148
 
136
149
  All fonts are free for commercial use. See individual license files for details.
137
150
  `.trim();
138
-
139
- // src/typography/tokens.ts
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))';
143
- var FONT_FAMILY_CJK = '"Noto Sans SC", "Source Han Sans SC", "Source Han Sans", "Noto Sans CJK SC", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif';
151
+ var tokenFirst = (name) => `var(${name}, ${tokenValue(name)})`;
152
+ var FONT_FAMILY_PRIMARY = tokenFirst("--font-sans");
153
+ var FONT_FAMILY_HEADING = tokenFirst("--font-heading");
154
+ var FONT_FAMILY_MONO = tokenFirst("--font-mono");
155
+ var FONT_FAMILY_CJK = tokenFirst("--font-cn");
144
156
  var fontFamilies = {
145
157
  /** Primary UI and body text */
146
158
  primary: FONT_FAMILY_PRIMARY,
@@ -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 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 * Noto Sans SC is the primary Chinese font.\n * Provides consistent rendering for Chinese, Japanese, and Korean text.\n */\nexport const FONT_FAMILY_CJK =\n '\"Noto Sans SC\", \"Source Han Sans SC\", \"Source Han Sans\", \"Noto Sans CJK 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 dmSans: {\n family: \"DM Sans\",\n weights: [400, 500, 600],\n italic: false,\n display: \"swap\",\n variable: true,\n selfHostUrl: \"@nebutra/fonts/next/cjk (dmSans)\",\n license: \"OFL\",\n licenseUrl: \"https://github.com/googlefonts/dm-fonts/blob/main/OFL.txt\",\n },\n\n misans: {\n family: \"MiSans\",\n weights: [400, 500, 600, 700],\n italic: false,\n display: \"swap\",\n variable: false,\n selfHostUrl: \"@nebutra/fonts/next/cjk (misans)\",\n license: \"Other\",\n licenseUrl: \"https://hyperos.mi.com/font/zh/download/\",\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)[] = [\"misans\"];\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- DM Sans: SIL Open Font License 1.1\n- MiSans (Xiaomi): free for commercial use; embedding requires stating that MiSans is used\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\nimport { tokenValue } from \"@nebutra/tokens/values\";\n\n// ============================================\n// Font Families\n// ============================================\n\n/**\n * Font stacks as CSS values: the token first, then — for a surface that never\n * loaded the token stylesheet — the token's own declared value, read from\n * @nebutra/tokens/values. The fallback is the stylesheet, not a copy of it.\n */\nconst tokenFirst = (name: \"--font-sans\" | \"--font-heading\" | \"--font-mono\" | \"--font-cn\") =>\n `var(${name}, ${tokenValue(name)})`;\n\n/** Primary font stack — body text and UI. */\nexport const FONT_FAMILY_PRIMARY = tokenFirst(\"--font-sans\");\n\n/** Heading font stack — titles and emphasis (DM Sans, CJK through MiSans). */\nexport const FONT_FAMILY_HEADING = tokenFirst(\"--font-heading\");\n\n/** Monospace font stack — code and technical content. */\nexport const FONT_FAMILY_MONO = tokenFirst(\"--font-mono\");\n\n/** CJK-locale stack — MiSans behind the Latin face, system CJK faces after it. */\nexport const FONT_FAMILY_CJK = tokenFirst(\"--font-cn\");\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"]}
@@ -49,22 +49,28 @@ declare function withHtmlProps<E extends keyof React.JSX.IntrinsicElements, Extr
49
49
  * @see packages/design/ARCHITECTURE.md
50
50
  * @see packages/design/tokens/recipe.css
51
51
  */
52
- /** SSR fallbacks when document is unavailable */
52
+ /**
53
+ * SSR fallbacks when document is unavailable — the light-mode token values,
54
+ * read from @nebutra/tokens/values rather than restated. Hand-copied, these
55
+ * had drifted: the product action was still the old blue after --primary
56
+ * became ink (a shader painted blue on the server and flipped to ink on
57
+ * hydration) and tertiary named a colour --brand-tertiary does not hold.
58
+ */
53
59
  declare const BRAND_FALLBACK: {
54
60
  /** VI 云毓蓝 — identity only */
55
- readonly primary: "#0033FE";
56
- readonly accent: "#0BF1C3";
57
- readonly tertiary: "#5c7cfa";
58
- readonly primaryDark: "#002ad4";
59
- readonly backDark: "#000830";
60
- /** Soft product action (matches themes/light --primary ≈ #254bfa) */
61
- readonly productPrimary: "#254bfa";
61
+ readonly primary: string;
62
+ readonly accent: string;
63
+ readonly tertiary: string;
64
+ readonly primaryDark: string;
65
+ readonly backDark: string;
66
+ /** Product action — semantic --primary */
67
+ readonly productPrimary: string;
62
68
  /**
63
- * Brand mark fallback (= product action when factory brand has action≡brand).
64
- * Skins may diverge (e.g. Linear purple action + indigo mark).
69
+ * Brand mark fallback (= product action: the factory recipe sets
70
+ * --brand-mark: var(--primary)). Skins may diverge.
65
71
  */
66
- readonly brandMark: "#254bfa";
67
- readonly brandMarkForeground: "#ffffff";
72
+ readonly brandMark: string;
73
+ readonly brandMarkForeground: string;
68
74
  };
69
75
  /**
70
76
  * Read a CSS variable from :root and return its trimmed value.
@@ -1,11 +1,86 @@
1
1
  import { clsx } from 'clsx';
2
- import { twMerge } from 'tailwind-merge';
2
+ import { extendTailwindMerge } from 'tailwind-merge';
3
+ import { tokenColor, tokenValue } from '@nebutra/tokens/values';
3
4
 
4
5
  // src/utils/auth-surfaces.ts
5
6
  var AUTH_FORM_COLUMN_CLASS = "relative mx-auto min-w-0 w-[min(100%,360px)] shrink-0";
6
7
  var AUTH_PRIMARY_CTA_CLASS = "h-11 w-full";
7
8
  var AUTH_OAUTH_GRID_CLASS = "grid grid-cols-2 gap-2";
8
9
  var AUTH_OAUTH_BUTTON_CLASS = "h-9 w-full justify-center gap-2 border-border bg-background px-2.5 text-sm font-medium text-foreground shadow-none hover:bg-muted";
10
+
11
+ // src/utils/tw-merge-theme.generated.ts
12
+ var TW_MERGE_THEME = {
13
+ breakpoint: ["3xl", "shell", "tight", "xs"],
14
+ container: ["content", "text", "wide"],
15
+ ease: ["brand", "in", "in-out", "out", "spring"],
16
+ font: ["cn", "display", "heading", "mono", "sans"],
17
+ leading: ["display", "heading"],
18
+ radius: ["2xl", "3xl", "button", "card", "full", "lg", "md", "none", "panel", "sm", "xl", "xs"],
19
+ shadow: [
20
+ "2xl",
21
+ "ambient-glow",
22
+ "ambient-lg",
23
+ "ambient-md",
24
+ "ambient-sm",
25
+ "brand",
26
+ "brand-lg",
27
+ "glass-lg",
28
+ "glass-md",
29
+ "glass-sm",
30
+ "glow-accent",
31
+ "glow-accent-lg",
32
+ "glow-accent-sm",
33
+ "glow-primary",
34
+ "lg",
35
+ "md",
36
+ "sheen",
37
+ "sm",
38
+ "xl",
39
+ "xs"
40
+ ],
41
+ text: [
42
+ "2xl",
43
+ "2xs",
44
+ "3xl",
45
+ "4xl",
46
+ "5xl",
47
+ "6xl",
48
+ "7xl",
49
+ "8xl",
50
+ "9xl",
51
+ "base",
52
+ "body",
53
+ "display",
54
+ "label",
55
+ "lg",
56
+ "meta",
57
+ "sm",
58
+ "ui",
59
+ "xl",
60
+ "xs"
61
+ ],
62
+ tracking: ["display", "heading", "label", "tight"]
63
+ };
64
+ var TW_MERGE_CLASS_GROUPS = {
65
+ duration: [{ duration: ["cinematic", "flow", "micro", "reveal"] }]
66
+ };
67
+
68
+ // src/utils/cn.ts
69
+ var twMerge = extendTailwindMerge({
70
+ extend: {
71
+ theme: Object.fromEntries(
72
+ Object.entries(TW_MERGE_THEME).map(([key, values]) => [key, [...values]])
73
+ ),
74
+ classGroups: Object.fromEntries(
75
+ Object.entries(TW_MERGE_CLASS_GROUPS).map(([key, groups]) => [
76
+ key,
77
+ groups.map(
78
+ (group) => Object.fromEntries(Object.entries(group).map(([k, v]) => [k, [...v]]))
79
+ )
80
+ ])
81
+ )
82
+ }
83
+ });
9
84
  function cn(...inputs) {
10
85
  return twMerge(clsx(inputs));
11
86
  }
@@ -18,23 +93,21 @@ function asPlainStyle(style) {
18
93
  function withHtmlProps(Component) {
19
94
  return Component;
20
95
  }
21
-
22
- // src/utils/brand-colors.ts
23
96
  var BRAND_FALLBACK = {
24
97
  /** VI 云毓蓝 — identity only */
25
- primary: "#0033FE",
26
- accent: "#0BF1C3",
27
- tertiary: "#5c7cfa",
28
- primaryDark: "#002ad4",
29
- backDark: "#000830",
30
- /** Soft product action (matches themes/light --primary ≈ #254bfa) */
31
- productPrimary: "#254bfa",
98
+ primary: tokenColor("--brand-primary"),
99
+ accent: tokenColor("--brand-accent"),
100
+ tertiary: tokenColor("--brand-tertiary"),
101
+ primaryDark: tokenColor("--nebutra-blue-600"),
102
+ backDark: tokenColor("--nebutra-blue-950"),
103
+ /** Product action — semantic --primary */
104
+ productPrimary: tokenColor("--primary"),
32
105
  /**
33
- * Brand mark fallback (= product action when factory brand has action≡brand).
34
- * Skins may diverge (e.g. Linear purple action + indigo mark).
106
+ * Brand mark fallback (= product action: the factory recipe sets
107
+ * --brand-mark: var(--primary)). Skins may diverge.
35
108
  */
36
- brandMark: "#254bfa",
37
- brandMarkForeground: "#ffffff"
109
+ brandMark: tokenColor("--primary"),
110
+ brandMarkForeground: tokenColor("--primary-foreground")
38
111
  };
39
112
  function readCssVar(name, fallback) {
40
113
  if (typeof window === "undefined" || typeof document === "undefined") {
@@ -51,23 +124,26 @@ function asCssColor(value, fallback) {
51
124
  return `hsl(${v})`;
52
125
  }
53
126
  function getProductPrimary() {
54
- return asCssColor(readCssVar("--primary", "228 85% 56%"), BRAND_FALLBACK.productPrimary);
127
+ return asCssColor(
128
+ readCssVar("--primary", tokenValue("--primary")),
129
+ BRAND_FALLBACK.productPrimary
130
+ );
55
131
  }
56
132
  function getBrandPrimary() {
57
133
  return asCssVarColor("--brand-primary", BRAND_FALLBACK.primary);
58
134
  }
59
135
  function getBrandMark() {
60
- const raw = readCssVar("--brand-mark", "228 85% 56%");
136
+ const raw = readCssVar("--brand-mark", tokenValue("--primary"));
61
137
  if (/var\(\s*--primary\s*\)/u.test(raw)) {
62
138
  return getProductPrimary();
63
139
  }
64
140
  return asCssColor(raw, BRAND_FALLBACK.brandMark);
65
141
  }
66
142
  function getBrandMarkForeground() {
67
- const raw = readCssVar("--brand-mark-foreground", "0 0% 100%");
143
+ const raw = readCssVar("--brand-mark-foreground", tokenValue("--primary-foreground"));
68
144
  if (/var\(\s*--primary-foreground\s*\)/u.test(raw)) {
69
145
  return asCssColor(
70
- readCssVar("--primary-foreground", "0 0% 100%"),
146
+ readCssVar("--primary-foreground", tokenValue("--primary-foreground")),
71
147
  BRAND_FALLBACK.brandMarkForeground
72
148
  );
73
149
  }