@yugnex/nexui 2.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 (138) hide show
  1. package/LICENSE +59 -0
  2. package/css/nexui-base.css +157 -0
  3. package/css/nexui-icons.css +86 -0
  4. package/css/nexui-tokens.css +113 -0
  5. package/css/nexui.css +16 -0
  6. package/dist/assets/geometry.d.ts +98 -0
  7. package/dist/assets/geometry.d.ts.map +1 -0
  8. package/dist/assets/geometry.js +114 -0
  9. package/dist/assets/geometry.js.map +1 -0
  10. package/dist/assets/typography.d.ts +3 -0
  11. package/dist/assets/typography.d.ts.map +1 -0
  12. package/dist/assets/typography.js +178 -0
  13. package/dist/assets/typography.js.map +1 -0
  14. package/dist/core/compiler.d.ts +30 -0
  15. package/dist/core/compiler.d.ts.map +1 -0
  16. package/dist/core/compiler.js +124 -0
  17. package/dist/core/compiler.js.map +1 -0
  18. package/dist/core/cx.d.ts +7 -0
  19. package/dist/core/cx.d.ts.map +1 -0
  20. package/dist/core/cx.js +34 -0
  21. package/dist/core/cx.js.map +1 -0
  22. package/dist/core/matrix.d.ts +118 -0
  23. package/dist/core/matrix.d.ts.map +1 -0
  24. package/dist/core/matrix.js +180 -0
  25. package/dist/core/matrix.js.map +1 -0
  26. package/dist/index.d.ts +27 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +74 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/primitives/avatar.d.ts +8 -0
  31. package/dist/primitives/avatar.d.ts.map +1 -0
  32. package/dist/primitives/avatar.js +146 -0
  33. package/dist/primitives/avatar.js.map +1 -0
  34. package/dist/primitives/badge.d.ts +8 -0
  35. package/dist/primitives/badge.d.ts.map +1 -0
  36. package/dist/primitives/badge.js +88 -0
  37. package/dist/primitives/badge.js.map +1 -0
  38. package/dist/primitives/button.d.ts +10 -0
  39. package/dist/primitives/button.d.ts.map +1 -0
  40. package/dist/primitives/button.js +137 -0
  41. package/dist/primitives/button.js.map +1 -0
  42. package/dist/primitives/checkbox.d.ts +13 -0
  43. package/dist/primitives/checkbox.d.ts.map +1 -0
  44. package/dist/primitives/checkbox.js +107 -0
  45. package/dist/primitives/checkbox.js.map +1 -0
  46. package/dist/primitives/input.d.ts +14 -0
  47. package/dist/primitives/input.d.ts.map +1 -0
  48. package/dist/primitives/input.js +177 -0
  49. package/dist/primitives/input.js.map +1 -0
  50. package/dist/primitives/panel.d.ts +9 -0
  51. package/dist/primitives/panel.d.ts.map +1 -0
  52. package/dist/primitives/panel.js +101 -0
  53. package/dist/primitives/panel.js.map +1 -0
  54. package/dist/primitives/progress.d.ts +8 -0
  55. package/dist/primitives/progress.d.ts.map +1 -0
  56. package/dist/primitives/progress.js +105 -0
  57. package/dist/primitives/progress.js.map +1 -0
  58. package/dist/primitives/separator.d.ts +8 -0
  59. package/dist/primitives/separator.d.ts.map +1 -0
  60. package/dist/primitives/separator.js +69 -0
  61. package/dist/primitives/separator.js.map +1 -0
  62. package/dist/primitives/skeleton.d.ts +8 -0
  63. package/dist/primitives/skeleton.d.ts.map +1 -0
  64. package/dist/primitives/skeleton.js +61 -0
  65. package/dist/primitives/skeleton.js.map +1 -0
  66. package/dist/primitives/spinner.d.ts +8 -0
  67. package/dist/primitives/spinner.d.ts.map +1 -0
  68. package/dist/primitives/spinner.js +64 -0
  69. package/dist/primitives/spinner.js.map +1 -0
  70. package/dist/primitives/status-ring.d.ts +8 -0
  71. package/dist/primitives/status-ring.d.ts.map +1 -0
  72. package/dist/primitives/status-ring.js +101 -0
  73. package/dist/primitives/status-ring.js.map +1 -0
  74. package/dist/primitives/switch.d.ts +12 -0
  75. package/dist/primitives/switch.d.ts.map +1 -0
  76. package/dist/primitives/switch.js +124 -0
  77. package/dist/primitives/switch.js.map +1 -0
  78. package/dist/primitives/text-stream.d.ts +23 -0
  79. package/dist/primitives/text-stream.d.ts.map +1 -0
  80. package/dist/primitives/text-stream.js +167 -0
  81. package/dist/primitives/text-stream.js.map +1 -0
  82. package/dist/tokens/colors.d.ts +127 -0
  83. package/dist/tokens/colors.d.ts.map +1 -0
  84. package/dist/tokens/colors.js +135 -0
  85. package/dist/tokens/colors.js.map +1 -0
  86. package/dist/tokens/motion.d.ts +37 -0
  87. package/dist/tokens/motion.d.ts.map +1 -0
  88. package/dist/tokens/motion.js +93 -0
  89. package/dist/tokens/motion.js.map +1 -0
  90. package/dist/tokens/shadows.d.ts +34 -0
  91. package/dist/tokens/shadows.d.ts.map +1 -0
  92. package/dist/tokens/shadows.js +45 -0
  93. package/dist/tokens/shadows.js.map +1 -0
  94. package/dist/tokens/spacing.d.ts +69 -0
  95. package/dist/tokens/spacing.d.ts.map +1 -0
  96. package/dist/tokens/spacing.js +71 -0
  97. package/dist/tokens/spacing.js.map +1 -0
  98. package/dist/tokens/type.d.ts +166 -0
  99. package/dist/tokens/type.d.ts.map +1 -0
  100. package/dist/tokens/type.js +215 -0
  101. package/dist/tokens/type.js.map +1 -0
  102. package/fonts/NexuiIcons.woff2 +0 -0
  103. package/fonts/NexuiMono-Regular.otf +0 -0
  104. package/fonts/NexuiMono-Regular.woff2 +0 -0
  105. package/fonts/NexuiSans-Bold.otf +0 -0
  106. package/fonts/NexuiSans-Bold.woff2 +0 -0
  107. package/fonts/NexuiSans-Medium.otf +0 -0
  108. package/fonts/NexuiSans-Medium.woff2 +0 -0
  109. package/fonts/NexuiSans-Regular.otf +0 -0
  110. package/fonts/NexuiSans-Regular.woff2 +0 -0
  111. package/native/Cargo.toml +16 -0
  112. package/native/src/lib.rs +127 -0
  113. package/nexui-utils.css +485 -0
  114. package/package.json +58 -0
  115. package/src/assets/geometry.ts +144 -0
  116. package/src/assets/typography.ts +184 -0
  117. package/src/core/compiler.ts +139 -0
  118. package/src/core/cx.ts +50 -0
  119. package/src/core/matrix.ts +195 -0
  120. package/src/index.ts +78 -0
  121. package/src/primitives/avatar.ts +159 -0
  122. package/src/primitives/badge.ts +98 -0
  123. package/src/primitives/button.ts +149 -0
  124. package/src/primitives/checkbox.ts +113 -0
  125. package/src/primitives/input.ts +187 -0
  126. package/src/primitives/panel.ts +111 -0
  127. package/src/primitives/progress.ts +112 -0
  128. package/src/primitives/separator.ts +73 -0
  129. package/src/primitives/skeleton.ts +68 -0
  130. package/src/primitives/spinner.ts +71 -0
  131. package/src/primitives/status-ring.ts +109 -0
  132. package/src/primitives/switch.ts +134 -0
  133. package/src/primitives/text-stream.ts +187 -0
  134. package/src/tokens/colors.ts +149 -0
  135. package/src/tokens/motion.ts +97 -0
  136. package/src/tokens/shadows.ts +58 -0
  137. package/src/tokens/spacing.ts +79 -0
  138. package/src/tokens/type.ts +224 -0
@@ -0,0 +1,97 @@
1
+ // @yugnex/nexui — Motion Tokens
2
+ // Easing curves + durations. Matches native platform conventions.
3
+
4
+ export const NEXUI_EASING = {
5
+ // Standard — element moves between two screen states
6
+ standard: "cubic-bezier(0.2, 0, 0, 1)",
7
+ // Decelerate — element enters the screen (decelerates to rest)
8
+ decelerate: "cubic-bezier(0, 0, 0.2, 1)",
9
+ // Accelerate — element leaves the screen (accelerates to exit)
10
+ accelerate: "cubic-bezier(0.3, 0, 1, 1)",
11
+ // Linear — progress bars, loaders
12
+ linear: "linear",
13
+ // Spring — interactive, snap, bouncy (for emphasis)
14
+ spring: "cubic-bezier(0.34, 1.56, 0.64, 1)",
15
+ // Sharp — micro-interactions (toggles, chips)
16
+ sharp: "cubic-bezier(0.4, 0, 0.6, 1)",
17
+ } as const;
18
+
19
+ export const NEXUI_DURATION = {
20
+ // Micro — icon state change, badge pulse
21
+ 50: "50ms",
22
+ // Fast — tooltip show/hide, focus ring
23
+ 100: "100ms",
24
+ // Quick — button feedback, checkbox
25
+ 150: "150ms",
26
+ // Standard — panel collapse, menu open
27
+ 200: "200ms",
28
+ // Smooth — drawer, modal, tab transitions
29
+ 300: "300ms",
30
+ // Deliberate — page-level transitions
31
+ 400: "400ms",
32
+ // Slow — complex choreography
33
+ 500: "500ms",
34
+ // Elaborate — data visualization entry
35
+ 700: "700ms",
36
+ // Cinematic — splash, hero
37
+ 1000: "1000ms",
38
+ } as const;
39
+
40
+ // Semantic transition presets — use these in components
41
+ export const NEXUI_TRANSITION = {
42
+ "instant": `all ${NEXUI_DURATION[50]} ${NEXUI_EASING.sharp}`,
43
+ "fast": `all ${NEXUI_DURATION[100]} ${NEXUI_EASING.standard}`,
44
+ "base": `all ${NEXUI_DURATION[200]} ${NEXUI_EASING.standard}`,
45
+ "smooth": `all ${NEXUI_DURATION[300]} ${NEXUI_EASING.decelerate}`,
46
+ "slow": `all ${NEXUI_DURATION[500]} ${NEXUI_EASING.decelerate}`,
47
+ "none": "none",
48
+
49
+ // Specific property transitions (better performance than `all`)
50
+ "colors": `color ${NEXUI_DURATION[150]} ${NEXUI_EASING.standard}, background-color ${NEXUI_DURATION[150]} ${NEXUI_EASING.standard}, border-color ${NEXUI_DURATION[150]} ${NEXUI_EASING.standard}, fill ${NEXUI_DURATION[150]} ${NEXUI_EASING.standard}, stroke ${NEXUI_DURATION[150]} ${NEXUI_EASING.standard}`,
51
+ "opacity": `opacity ${NEXUI_DURATION[200]} ${NEXUI_EASING.standard}`,
52
+ "transform": `transform ${NEXUI_DURATION[200]} ${NEXUI_EASING.standard}`,
53
+ "ring": `box-shadow ${NEXUI_DURATION[150]} ${NEXUI_EASING.standard}`,
54
+ "slide-in": `transform ${NEXUI_DURATION[300]} ${NEXUI_EASING.decelerate}, opacity ${NEXUI_DURATION[300]} ${NEXUI_EASING.decelerate}`,
55
+ "slide-out": `transform ${NEXUI_DURATION[200]} ${NEXUI_EASING.accelerate}, opacity ${NEXUI_DURATION[200]} ${NEXUI_EASING.accelerate}`,
56
+ "scale": `transform ${NEXUI_DURATION[200]} ${NEXUI_EASING.spring}`,
57
+ "ring-score": `stroke-dashoffset ${NEXUI_DURATION[700]} ${NEXUI_EASING.decelerate}`,
58
+ } as const;
59
+
60
+ // Keyframe definitions — inject once per page via NexuiTypographySheet or initializeNexuiEngine
61
+ export const NEXUI_KEYFRAMES = `
62
+ @keyframes nx-fade-in {
63
+ from { opacity: 0; }
64
+ to { opacity: 1; }
65
+ }
66
+ @keyframes nx-fade-out {
67
+ from { opacity: 1; }
68
+ to { opacity: 0; }
69
+ }
70
+ @keyframes nx-slide-up {
71
+ from { opacity: 0; transform: translateY(8px); }
72
+ to { opacity: 1; transform: translateY(0); }
73
+ }
74
+ @keyframes nx-slide-down {
75
+ from { opacity: 0; transform: translateY(-8px); }
76
+ to { opacity: 1; transform: translateY(0); }
77
+ }
78
+ @keyframes nx-scale-in {
79
+ from { opacity: 0; transform: scale(0.95); }
80
+ to { opacity: 1; transform: scale(1); }
81
+ }
82
+ @keyframes nx-spin {
83
+ to { transform: rotate(360deg); }
84
+ }
85
+ @keyframes nx-pulse-ring {
86
+ 0%, 100% { opacity: 1; }
87
+ 50% { opacity: 0.4; }
88
+ }
89
+ @keyframes nx-shimmer {
90
+ 0% { background-position: -200% 0; }
91
+ 100% { background-position: 200% 0; }
92
+ }
93
+ @keyframes nx-blink {
94
+ 0%, 100% { opacity: 1; }
95
+ 50% { opacity: 0; }
96
+ }
97
+ `;
@@ -0,0 +1,58 @@
1
+ // @yugnex/nexui — Shadow / Elevation System
2
+ // Two rulesets: void (dark UI shadows use color + opacity) and terminal.
3
+
4
+ export const NEXUI_SHADOWS_VOID = {
5
+ // Flat — no elevation
6
+ "none": "none",
7
+
8
+ // Subtle — cards, inline elements on same surface
9
+ "xs": "0 1px 2px rgba(0,0,0,0.40)",
10
+
11
+ // Low — floating buttons, popover triggers
12
+ "sm": "0 1px 3px rgba(0,0,0,0.50), 0 1px 2px rgba(0,0,0,0.30)",
13
+
14
+ // Standard — cards, panels
15
+ "md": "0 4px 6px rgba(0,0,0,0.40), 0 2px 4px rgba(0,0,0,0.30)",
16
+
17
+ // Elevated — dropdowns, date pickers
18
+ "lg": "0 10px 15px rgba(0,0,0,0.50), 0 4px 6px rgba(0,0,0,0.30)",
19
+
20
+ // High — modals, dialogs
21
+ "xl": "0 20px 25px rgba(0,0,0,0.55), 0 8px 10px rgba(0,0,0,0.30)",
22
+
23
+ // Overlay — full-screen drawers, command palette
24
+ "2xl": "0 25px 50px rgba(0,0,0,0.65)",
25
+
26
+ // Accent glow — focused inputs, highlighted cards
27
+ "glow-accent": "0 0 0 3px rgba(232,144,16,0.30), 0 0 16px rgba(232,144,16,0.12)",
28
+ "glow-live": "0 0 0 3px rgba(15,212,198,0.25), 0 0 16px rgba(15,212,198,0.10)",
29
+ "glow-success": "0 0 0 3px rgba(34,197,94,0.25), 0 0 12px rgba(34,197,94,0.08)",
30
+ "glow-error": "0 0 0 3px rgba(239,68,68,0.30), 0 0 12px rgba(239,68,68,0.10)",
31
+
32
+ // Focus ring — keyboard nav, ARIA
33
+ "focus": "0 0 0 2px #0D1117, 0 0 0 4px rgba(232,144,16,0.60)",
34
+
35
+ // Inset — pressed states, sunken containers
36
+ "inner": "inset 0 2px 4px rgba(0,0,0,0.40)",
37
+ "inner-strong": "inset 0 2px 8px rgba(0,0,0,0.60)",
38
+ } as const;
39
+
40
+ export const NEXUI_SHADOWS_TERMINAL = {
41
+ "none": "none",
42
+ "xs": "0 1px 2px rgba(0,0,0,0.70)",
43
+ "sm": "0 1px 3px rgba(0,0,0,0.80), 0 1px 2px rgba(0,0,0,0.50)",
44
+ "md": "0 4px 6px rgba(0,0,0,0.70), 0 2px 4px rgba(0,0,0,0.50)",
45
+ "lg": "0 10px 15px rgba(0,0,0,0.80), 0 4px 6px rgba(0,0,0,0.50)",
46
+ "xl": "0 20px 25px rgba(0,0,0,0.85), 0 8px 10px rgba(0,0,0,0.50)",
47
+ "2xl": "0 25px 50px rgba(0,0,0,0.90)",
48
+
49
+ "glow-accent": "0 0 0 3px rgba(232,144,16,0.30), 0 0 16px rgba(232,144,16,0.12)",
50
+ "glow-live": "0 0 0 3px rgba(16,185,129,0.30), 0 0 16px rgba(16,185,129,0.12)",
51
+ "glow-success": "0 0 0 3px rgba(16,185,129,0.30), 0 0 12px rgba(16,185,129,0.10)",
52
+ "glow-error": "0 0 0 3px rgba(239,68,68,0.35), 0 0 12px rgba(239,68,68,0.12)",
53
+ "focus": "0 0 0 2px #000000, 0 0 0 4px rgba(16,185,129,0.60)",
54
+ "inner": "inset 0 2px 4px rgba(0,0,0,0.70)",
55
+ "inner-strong": "inset 0 2px 8px rgba(0,0,0,0.90)",
56
+ } as const;
57
+
58
+ export type ShadowKey = keyof typeof NEXUI_SHADOWS_VOID;
@@ -0,0 +1,79 @@
1
+ // @yugnex/nexui — Spacing Scale
2
+ // 4px base unit. All values are multiples of 4px.
3
+
4
+ export const NEXUI_SPACE = {
5
+ 0: "0px",
6
+ px: "1px",
7
+ 0.5: "2px",
8
+ 1: "4px",
9
+ 1.5: "6px",
10
+ 2: "8px",
11
+ 2.5: "10px",
12
+ 3: "12px",
13
+ 3.5: "14px",
14
+ 4: "16px",
15
+ 5: "20px",
16
+ 6: "24px",
17
+ 7: "28px",
18
+ 8: "32px",
19
+ 9: "36px",
20
+ 10: "40px",
21
+ 11: "44px",
22
+ 12: "48px",
23
+ 14: "56px",
24
+ 16: "64px",
25
+ 20: "80px",
26
+ 24: "96px",
27
+ 28: "112px",
28
+ 32: "128px",
29
+ 36: "144px",
30
+ 40: "160px",
31
+ 44: "176px",
32
+ 48: "192px",
33
+ 52: "208px",
34
+ 56: "224px",
35
+ 60: "240px",
36
+ 64: "256px",
37
+ 72: "288px",
38
+ 80: "320px",
39
+ 96: "384px",
40
+ } as const;
41
+
42
+ export type SpaceKey = keyof typeof NEXUI_SPACE;
43
+
44
+ // Semantic spacing aliases — what components reference
45
+ export const NEXUI_SPACE_SEMANTIC = {
46
+ "component-xs": NEXUI_SPACE[1], // 4px — tight internal padding
47
+ "component-sm": NEXUI_SPACE[2], // 8px — small component padding
48
+ "component-md": NEXUI_SPACE[3], // 12px — standard component padding
49
+ "component-lg": NEXUI_SPACE[4], // 16px — large component padding
50
+ "component-xl": NEXUI_SPACE[6], // 24px — extra-large component padding
51
+
52
+ "layout-xs": NEXUI_SPACE[4], // 16px — tight section gap
53
+ "layout-sm": NEXUI_SPACE[6], // 24px — small section gap
54
+ "layout-md": NEXUI_SPACE[8], // 32px — standard section gap
55
+ "layout-lg": NEXUI_SPACE[12], // 48px — large section gap
56
+ "layout-xl": NEXUI_SPACE[16], // 64px — page-level gap
57
+
58
+ "inline-xs": NEXUI_SPACE[1], // 4px — inline element gap
59
+ "inline-sm": NEXUI_SPACE[2], // 8px — small inline gap
60
+ "inline-md": NEXUI_SPACE[3], // 12px — standard inline gap
61
+ "inline-lg": NEXUI_SPACE[4], // 16px — large inline gap
62
+
63
+ "icon-sm": NEXUI_SPACE[4], // 16px — small icon size
64
+ "icon-md": NEXUI_SPACE[5], // 20px — standard icon size
65
+ "icon-lg": NEXUI_SPACE[6], // 24px — large icon size
66
+
67
+ "radius-none": "0px",
68
+ "radius-xs": "2px",
69
+ "radius-sm": "4px",
70
+ "radius-md": "6px",
71
+ "radius-lg": "8px",
72
+ "radius-xl": "12px",
73
+ "radius-2xl": "16px",
74
+ "radius-full": "9999px",
75
+
76
+ "border-thin": "1px",
77
+ "border-medium": "1.5px",
78
+ "border-thick": "2px",
79
+ } as const;
@@ -0,0 +1,224 @@
1
+ // @yugnex/nexui — Typography Tokens
2
+ // Fluid type scale: clamp(minPx, yIntersect + slope*100vw, maxPx)
3
+ // Min viewport: 320px. Max viewport: 1440px.
4
+
5
+ const MIN_VP = 320;
6
+ const MAX_VP = 1440;
7
+
8
+ function fluid(minPx: number, maxPx: number): string {
9
+ const slope = (maxPx - minPx) / (MAX_VP - MIN_VP);
10
+ const y = minPx - slope * MIN_VP;
11
+ const yFixed = parseFloat(y.toFixed(4));
12
+ const slopeFixed = parseFloat((slope * 100).toFixed(4));
13
+ const sign = yFixed >= 0 ? "+" : "-";
14
+ return `clamp(${minPx}px, ${Math.abs(yFixed)}px ${sign} ${slopeFixed}vw, ${maxPx}px)`;
15
+ }
16
+
17
+ // Type scale — based on a modular scale of 1.25 (Major Third)
18
+ export const NEXUI_FONT_SIZE = {
19
+ "2xs": fluid(10, 11), // micro labels, timestamps
20
+ "xs": fluid(11, 12), // captions, helper text
21
+ "sm": fluid(12, 13), // secondary body, badge text
22
+ "base": fluid(13, 14), // primary body
23
+ "md": fluid(14, 15), // large body, button labels
24
+ "lg": fluid(16, 18), // subheading
25
+ "xl": fluid(18, 20), // section heading
26
+ "2xl": fluid(20, 24), // page heading
27
+ "3xl": fluid(24, 30), // display sm
28
+ "4xl": fluid(30, 36), // display md
29
+ "5xl": fluid(36, 48), // display lg
30
+ "6xl": fluid(48, 60), // hero
31
+ "7xl": fluid(60, 72), // mega hero
32
+ } as const;
33
+
34
+ export const NEXUI_LINE_HEIGHT = {
35
+ "none": "1",
36
+ "tight": "1.15",
37
+ "snug": "1.3",
38
+ "normal": "1.5",
39
+ "relaxed": "1.65",
40
+ "loose": "1.8",
41
+ "code": "1.7",
42
+ } as const;
43
+
44
+ export const NEXUI_LETTER_SPACING = {
45
+ "tighter": "-0.04em",
46
+ "tight": "-0.02em",
47
+ "normal": "0em",
48
+ "wide": "0.04em",
49
+ "wider": "0.08em",
50
+ "widest": "0.16em",
51
+ "mono": "0.02em",
52
+ "caps": "0.06em",
53
+ } as const;
54
+
55
+ export const NEXUI_FONT_WEIGHT = {
56
+ "thin": "100",
57
+ "extralight": "200",
58
+ "light": "300",
59
+ "regular": "400",
60
+ "medium": "500",
61
+ "semibold": "600",
62
+ "bold": "700",
63
+ "extrabold": "800",
64
+ "black": "900",
65
+ } as const;
66
+
67
+ // Font family stacks — zero font file dependency (web-safe system stack)
68
+ // When NexuiSans/NexuiMono WOFF2 files are available, prepend them first.
69
+ export const NEXUI_FONT_FAMILY = {
70
+ "sans": [
71
+ "NexuiSans", // reserved — provide via @font-face
72
+ "Inter", // common on modern systems
73
+ "system-ui",
74
+ "-apple-system",
75
+ "BlinkMacSystemFont",
76
+ "Segoe UI",
77
+ "Roboto",
78
+ "Helvetica Neue",
79
+ "Arial",
80
+ "sans-serif",
81
+ ].join(", "),
82
+
83
+ "mono": [
84
+ "NexuiMono", // reserved — provide via @font-face
85
+ "JetBrains Mono",
86
+ "Fira Code",
87
+ "Cascadia Code",
88
+ "SF Mono",
89
+ "ui-monospace",
90
+ "SFMono-Regular",
91
+ "Menlo",
92
+ "Monaco",
93
+ "Consolas",
94
+ "Liberation Mono",
95
+ "Courier New",
96
+ "monospace",
97
+ ].join(", "),
98
+
99
+ "display": [
100
+ "NexuiDisplay", // reserved — provide via @font-face
101
+ "Cal Sans",
102
+ "DM Sans",
103
+ "Inter",
104
+ "system-ui",
105
+ "sans-serif",
106
+ ].join(", "),
107
+ } as const;
108
+
109
+ // Semantic text role presets — map directly to component style objects
110
+ export const NEXUI_TEXT_ROLES = {
111
+ "display-lg": {
112
+ fontSize: NEXUI_FONT_SIZE["5xl"],
113
+ fontWeight: NEXUI_FONT_WEIGHT["bold"],
114
+ lineHeight: NEXUI_LINE_HEIGHT["tight"],
115
+ letterSpacing: NEXUI_LETTER_SPACING["tight"],
116
+ fontFamily: NEXUI_FONT_FAMILY["display"],
117
+ },
118
+ "display-md": {
119
+ fontSize: NEXUI_FONT_SIZE["4xl"],
120
+ fontWeight: NEXUI_FONT_WEIGHT["bold"],
121
+ lineHeight: NEXUI_LINE_HEIGHT["tight"],
122
+ letterSpacing: NEXUI_LETTER_SPACING["tight"],
123
+ fontFamily: NEXUI_FONT_FAMILY["display"],
124
+ },
125
+ "heading-xl": {
126
+ fontSize: NEXUI_FONT_SIZE["3xl"],
127
+ fontWeight: NEXUI_FONT_WEIGHT["semibold"],
128
+ lineHeight: NEXUI_LINE_HEIGHT["snug"],
129
+ letterSpacing: NEXUI_LETTER_SPACING["tight"],
130
+ fontFamily: NEXUI_FONT_FAMILY["sans"],
131
+ },
132
+ "heading-lg": {
133
+ fontSize: NEXUI_FONT_SIZE["2xl"],
134
+ fontWeight: NEXUI_FONT_WEIGHT["semibold"],
135
+ lineHeight: NEXUI_LINE_HEIGHT["snug"],
136
+ letterSpacing: NEXUI_LETTER_SPACING["normal"],
137
+ fontFamily: NEXUI_FONT_FAMILY["sans"],
138
+ },
139
+ "heading-md": {
140
+ fontSize: NEXUI_FONT_SIZE["xl"],
141
+ fontWeight: NEXUI_FONT_WEIGHT["semibold"],
142
+ lineHeight: NEXUI_LINE_HEIGHT["snug"],
143
+ letterSpacing: NEXUI_LETTER_SPACING["normal"],
144
+ fontFamily: NEXUI_FONT_FAMILY["sans"],
145
+ },
146
+ "heading-sm": {
147
+ fontSize: NEXUI_FONT_SIZE["lg"],
148
+ fontWeight: NEXUI_FONT_WEIGHT["medium"],
149
+ lineHeight: NEXUI_LINE_HEIGHT["normal"],
150
+ letterSpacing: NEXUI_LETTER_SPACING["normal"],
151
+ fontFamily: NEXUI_FONT_FAMILY["sans"],
152
+ },
153
+ "label-lg": {
154
+ fontSize: NEXUI_FONT_SIZE["md"],
155
+ fontWeight: NEXUI_FONT_WEIGHT["medium"],
156
+ lineHeight: NEXUI_LINE_HEIGHT["normal"],
157
+ letterSpacing: NEXUI_LETTER_SPACING["normal"],
158
+ fontFamily: NEXUI_FONT_FAMILY["sans"],
159
+ },
160
+ "label-md": {
161
+ fontSize: NEXUI_FONT_SIZE["base"],
162
+ fontWeight: NEXUI_FONT_WEIGHT["medium"],
163
+ lineHeight: NEXUI_LINE_HEIGHT["normal"],
164
+ letterSpacing: NEXUI_LETTER_SPACING["normal"],
165
+ fontFamily: NEXUI_FONT_FAMILY["sans"],
166
+ },
167
+ "label-sm": {
168
+ fontSize: NEXUI_FONT_SIZE["sm"],
169
+ fontWeight: NEXUI_FONT_WEIGHT["medium"],
170
+ lineHeight: NEXUI_LINE_HEIGHT["normal"],
171
+ letterSpacing: NEXUI_LETTER_SPACING["wide"],
172
+ fontFamily: NEXUI_FONT_FAMILY["sans"],
173
+ },
174
+ "label-caps": {
175
+ fontSize: NEXUI_FONT_SIZE["xs"],
176
+ fontWeight: NEXUI_FONT_WEIGHT["semibold"],
177
+ lineHeight: NEXUI_LINE_HEIGHT["normal"],
178
+ letterSpacing: NEXUI_LETTER_SPACING["caps"],
179
+ fontFamily: NEXUI_FONT_FAMILY["sans"],
180
+ textTransform: "uppercase" as const,
181
+ },
182
+ "body-lg": {
183
+ fontSize: NEXUI_FONT_SIZE["md"],
184
+ fontWeight: NEXUI_FONT_WEIGHT["regular"],
185
+ lineHeight: NEXUI_LINE_HEIGHT["relaxed"],
186
+ letterSpacing: NEXUI_LETTER_SPACING["normal"],
187
+ fontFamily: NEXUI_FONT_FAMILY["sans"],
188
+ },
189
+ "body-md": {
190
+ fontSize: NEXUI_FONT_SIZE["base"],
191
+ fontWeight: NEXUI_FONT_WEIGHT["regular"],
192
+ lineHeight: NEXUI_LINE_HEIGHT["relaxed"],
193
+ letterSpacing: NEXUI_LETTER_SPACING["normal"],
194
+ fontFamily: NEXUI_FONT_FAMILY["sans"],
195
+ },
196
+ "body-sm": {
197
+ fontSize: NEXUI_FONT_SIZE["sm"],
198
+ fontWeight: NEXUI_FONT_WEIGHT["regular"],
199
+ lineHeight: NEXUI_LINE_HEIGHT["normal"],
200
+ letterSpacing: NEXUI_LETTER_SPACING["normal"],
201
+ fontFamily: NEXUI_FONT_FAMILY["sans"],
202
+ },
203
+ "caption": {
204
+ fontSize: NEXUI_FONT_SIZE["xs"],
205
+ fontWeight: NEXUI_FONT_WEIGHT["regular"],
206
+ lineHeight: NEXUI_LINE_HEIGHT["normal"],
207
+ letterSpacing: NEXUI_LETTER_SPACING["normal"],
208
+ fontFamily: NEXUI_FONT_FAMILY["sans"],
209
+ },
210
+ "code-base": {
211
+ fontSize: NEXUI_FONT_SIZE["sm"],
212
+ fontWeight: NEXUI_FONT_WEIGHT["regular"],
213
+ lineHeight: NEXUI_LINE_HEIGHT["code"],
214
+ letterSpacing: NEXUI_LETTER_SPACING["mono"],
215
+ fontFamily: NEXUI_FONT_FAMILY["mono"],
216
+ },
217
+ "code-sm": {
218
+ fontSize: NEXUI_FONT_SIZE["xs"],
219
+ fontWeight: NEXUI_FONT_WEIGHT["regular"],
220
+ lineHeight: NEXUI_LINE_HEIGHT["code"],
221
+ letterSpacing: NEXUI_LETTER_SPACING["mono"],
222
+ fontFamily: NEXUI_FONT_FAMILY["mono"],
223
+ },
224
+ } as const;