claude-exode-mcp 7.5.7 → 7.5.8

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 (173) hide show
  1. package/MCP_DOCUMENTATION.md +1 -0
  2. package/SKILL.md +10 -0
  3. package/examples/aurum-product-page.exode +3208 -0
  4. package/examples/bell-ring-icon.exode +1 -0
  5. package/examples/drift-kinetic-type.exode +770 -0
  6. package/examples/earbuds-product.exode +214 -0
  7. package/examples/energy-flow.exode +1736 -0
  8. package/examples/flux-hero.exode +223 -0
  9. package/examples/gooey-toggle.exode +214 -0
  10. package/examples/gravity-well.exode +3113 -0
  11. package/examples/heart-icon.exode +1 -0
  12. package/examples/hologram-temple.exode +8100 -0
  13. package/examples/jarful-app.exode +1 -0
  14. package/examples/kip-character-rig.exode +1 -0
  15. package/examples/low-tide-tilt.exode +2216 -0
  16. package/examples/manifest.json +352 -0
  17. package/examples/swipe-stack-carousel.exode +4048 -0
  18. package/examples/tokyo-neon-weather.exode +470 -0
  19. package/examples/typographic-collapse.exode +1578 -0
  20. package/examples/void-product-ad.exode +1269 -0
  21. package/examples/wire-globe-card.exode +580 -0
  22. package/index.d.ts +41 -1
  23. package/index.js +2553 -2407
  24. package/package.json +4 -2
  25. package/render-runtime/exode-runtime.js +20 -20
  26. package/skills/creative-motion/SKILL.md +10 -0
  27. package/skills/creative-motion/recipes/character-rig.js +104 -0
  28. package/skills/creative-motion/recipes/dashboard.js +120 -0
  29. package/skills/creative-motion/recipes/game-arcade.js +203 -0
  30. package/skills/creative-motion/recipes/hero-physics.js +65 -0
  31. package/skills/creative-motion/recipes/pricing.js +88 -0
  32. package/skills/creative-motion/recipes/title-sequence.js +62 -0
  33. package/skills/creative-motion/references/apps.md +37 -0
  34. package/skills/creative-motion/references/gotchas.md +80 -0
  35. package/skills/creative-motion/references/native-layers.md +60 -0
  36. package/skills/creative-motion/references/quality.md +54 -0
  37. package/src/__tests__/buildKit.test.ts +127 -0
  38. package/src/__tests__/effectKnobs.test.ts +162 -0
  39. package/src/__tests__/nativeLayers.test.ts +178 -0
  40. package/src/buildKit.d.ts +301 -0
  41. package/src/buildKit.d.ts.map +1 -0
  42. package/src/buildKit.js +559 -0
  43. package/src/buildKit.js.map +1 -0
  44. package/src/buildKit.ts +520 -0
  45. package/src/compiler.d.ts +4 -0
  46. package/src/compiler.d.ts.map +1 -1
  47. package/src/compiler.js +21 -45
  48. package/src/compiler.js.map +1 -1
  49. package/src/compiler.ts +22 -51
  50. package/src/critique.d.ts +8 -0
  51. package/src/critique.d.ts.map +1 -0
  52. package/src/critique.js +348 -0
  53. package/src/critique.js.map +1 -0
  54. package/src/critique.ts +239 -0
  55. package/src/effectKnobs.d.ts +72 -0
  56. package/src/effectKnobs.d.ts.map +1 -0
  57. package/src/effectKnobs.js +541 -0
  58. package/src/effectKnobs.js.map +1 -0
  59. package/src/effectKnobs.ts +445 -0
  60. package/src/effectOptimizer.d.ts +18 -0
  61. package/src/effectOptimizer.d.ts.map +1 -0
  62. package/src/effectOptimizer.js +125 -0
  63. package/src/effectOptimizer.js.map +1 -0
  64. package/src/effectOptimizer.ts +104 -0
  65. package/src/engine/layout.js +1 -1
  66. package/src/engine/layout.js.map +1 -1
  67. package/src/engine/layout.ts +1 -1
  68. package/src/examples.d.ts +30 -0
  69. package/src/examples.d.ts.map +1 -0
  70. package/src/examples.js +168 -0
  71. package/src/examples.js.map +1 -0
  72. package/src/examples.ts +151 -0
  73. package/src/handlers/artboardHandlers.d.ts.map +1 -1
  74. package/src/handlers/artboardHandlers.js +45 -10
  75. package/src/handlers/artboardHandlers.js.map +1 -1
  76. package/src/handlers/artboardHandlers.ts +43 -12
  77. package/src/handlers/buildHandlers.d.ts +2 -0
  78. package/src/handlers/buildHandlers.d.ts.map +1 -0
  79. package/src/handlers/buildHandlers.js +86 -0
  80. package/src/handlers/buildHandlers.js.map +1 -0
  81. package/src/handlers/buildHandlers.ts +76 -0
  82. package/src/handlers/compilerHandlers.d.ts.map +1 -1
  83. package/src/handlers/compilerHandlers.js +32 -2
  84. package/src/handlers/compilerHandlers.js.map +1 -1
  85. package/src/handlers/compilerHandlers.ts +31 -2
  86. package/src/handlers/exampleHandlers.d.ts +2 -0
  87. package/src/handlers/exampleHandlers.d.ts.map +1 -0
  88. package/src/handlers/exampleHandlers.js +81 -0
  89. package/src/handlers/exampleHandlers.js.map +1 -0
  90. package/src/handlers/exampleHandlers.ts +76 -0
  91. package/src/handlers/renderHandlers.d.ts.map +1 -1
  92. package/src/handlers/renderHandlers.js +100 -2
  93. package/src/handlers/renderHandlers.js.map +1 -1
  94. package/src/handlers/renderHandlers.ts +90 -2
  95. package/src/handlers/scaffoldHandlers.d.ts.map +1 -1
  96. package/src/handlers/scaffoldHandlers.js +3 -0
  97. package/src/handlers/scaffoldHandlers.js.map +1 -1
  98. package/src/handlers/scaffoldHandlers.ts +2 -0
  99. package/src/handlers/widgetHandlers.js +1 -1
  100. package/src/handlers/widgetHandlers.js.map +1 -1
  101. package/src/handlers/widgetHandlers.ts +1 -1
  102. package/src/lottie/convert.d.ts +16 -0
  103. package/src/lottie/convert.d.ts.map +1 -0
  104. package/src/lottie/convert.js +1225 -0
  105. package/src/lottie/convert.js.map +1 -0
  106. package/src/lottie/convert.ts +1134 -0
  107. package/src/lottie/evaluate.d.ts +48 -0
  108. package/src/lottie/evaluate.d.ts.map +1 -0
  109. package/src/lottie/evaluate.js +174 -0
  110. package/src/lottie/evaluate.js.map +1 -0
  111. package/src/lottie/evaluate.ts +184 -0
  112. package/src/nativeLayers.d.ts +76 -0
  113. package/src/nativeLayers.d.ts.map +1 -0
  114. package/src/nativeLayers.js +404 -0
  115. package/src/nativeLayers.js.map +1 -0
  116. package/src/nativeLayers.ts +339 -0
  117. package/src/render/motionBrief.d.ts.map +1 -1
  118. package/src/render/motionBrief.js +4 -0
  119. package/src/render/motionBrief.js.map +1 -1
  120. package/src/render/motionBrief.ts +4 -0
  121. package/src/render/videoRenderer.d.ts.map +1 -1
  122. package/src/render/videoRenderer.js +5 -2
  123. package/src/render/videoRenderer.js.map +1 -1
  124. package/src/render/videoRenderer.ts +5 -2
  125. package/src/rive/convert.d.ts +17 -0
  126. package/src/rive/convert.d.ts.map +1 -0
  127. package/src/rive/convert.js +1779 -0
  128. package/src/rive/convert.js.map +1 -0
  129. package/src/rive/convert.ts +1492 -0
  130. package/src/rive/font.d.ts +13 -0
  131. package/src/rive/font.d.ts.map +1 -0
  132. package/src/rive/font.js +154 -0
  133. package/src/rive/font.js.map +1 -0
  134. package/src/rive/font.ts +132 -0
  135. package/src/rive/layout.d.ts +20 -0
  136. package/src/rive/layout.d.ts.map +1 -0
  137. package/src/rive/layout.js +145 -0
  138. package/src/rive/layout.js.map +1 -0
  139. package/src/rive/layout.ts +140 -0
  140. package/src/rive/reader.d.ts +32 -0
  141. package/src/rive/reader.d.ts.map +1 -0
  142. package/src/rive/reader.js +172 -0
  143. package/src/rive/reader.js.map +1 -0
  144. package/src/rive/reader.ts +160 -0
  145. package/src/rive/schema.generated.d.ts +9 -0
  146. package/src/rive/schema.generated.d.ts.map +1 -0
  147. package/src/rive/schema.generated.js +13 -0
  148. package/src/rive/schema.generated.js.map +1 -0
  149. package/src/rive/schema.generated.ts +13 -0
  150. package/src/schema.d.ts +5 -0
  151. package/src/schema.d.ts.map +1 -1
  152. package/src/schema.js +5 -0
  153. package/src/schema.js.map +1 -1
  154. package/src/schema.ts +6 -0
  155. package/src/serverInstructions.d.ts +2 -0
  156. package/src/serverInstructions.d.ts.map +1 -0
  157. package/src/serverInstructions.js +22 -0
  158. package/src/serverInstructions.js.map +1 -0
  159. package/src/serverInstructions.ts +21 -0
  160. package/src/sseServer.d.ts +2 -0
  161. package/src/sseServer.d.ts.map +1 -0
  162. package/src/sseServer.js +165 -0
  163. package/src/sseServer.js.map +1 -0
  164. package/src/sseServer.ts +189 -0
  165. package/src/utils.d.ts.map +1 -1
  166. package/src/utils.js +23 -1
  167. package/src/utils.js.map +1 -1
  168. package/src/utils.ts +13 -1
  169. package/src/widgets.d.ts +26 -0
  170. package/src/widgets.d.ts.map +1 -1
  171. package/src/widgets.js +89 -45
  172. package/src/widgets.js.map +1 -1
  173. package/src/widgets.ts +88 -45
package/src/widgets.ts CHANGED
@@ -16,6 +16,38 @@ export interface WidgetContent {
16
16
  value?: number | string; // Slider value, InputBox value, RadioGroup selection
17
17
  min?: number; max?: number; step?: number;
18
18
  color?: string; // accent / primary colour
19
+ style?: WidgetStyle; // look preset (default 'auto': derived from the artboard)
20
+ }
21
+
22
+
23
+ export const WIDGET_STYLES = ['auto', 'glass', 'neon', 'editorial', 'brutal', 'minimal'] as const;
24
+ export type WidgetStyle = (typeof WIDGET_STYLES)[number];
25
+
26
+ /** Colours and shape language for widgets, read from the artboard instead of stock blue/grey defaults. */
27
+ export function widgetTheme(artboard: any, style: WidgetStyle = 'auto', accentIn?: string) {
28
+ const bg = String(artboard?.backgroundColor || '#0B0A0F');
29
+ const h = bg.replace('#', '');
30
+ const lum = /^[0-9a-f]{6}$/i.test(h) ? (0.2126 * parseInt(h.slice(0, 2), 16) + 0.7152 * parseInt(h.slice(2, 4), 16) + 0.0722 * parseInt(h.slice(4, 6), 16)) / 255 : 0;
31
+ const dark = lum < 0.5;
32
+ const ink = dark ? '#F2EFEA' : '#141210';
33
+ const accent = accentIn || artboard?.tokens?.colors?.primary || (style === 'neon' ? (dark ? '#5CE1E6' : '#7A3CFF') : style === 'brutal' ? (dark ? '#C6F432' : '#E30613') : ink);
34
+ const onAccent = (() => { const a = accent.replace('#', ''); if (!/^[0-9a-f]{6}$/i.test(a)) return dark ? '#0B0A0F' : '#FFFFFF'; const l = (0.2126 * parseInt(a.slice(0, 2), 16) + 0.7152 * parseInt(a.slice(2, 4), 16) + 0.0722 * parseInt(a.slice(4, 6), 16)) / 255; return l > 0.6 ? '#0B0A0F' : '#FFFFFF'; })();
35
+ const t = {
36
+ dark, ink, accent, onAccent,
37
+ muted: dark ? '#8D8796' : '#6E675C',
38
+ surface: dark ? 'rgba(255, 255, 255, 0.06)' : 'rgba(0, 0, 0, 0.04)',
39
+ surfaceSolid: dark ? '#17151C' : '#FFFFFF',
40
+ line: dark ? 'rgba(255, 255, 255, 0.14)' : 'rgba(0, 0, 0, 0.12)',
41
+ track: dark ? 'rgba(255, 255, 255, 0.12)' : 'rgba(0, 0, 0, 0.10)',
42
+ radius: 12, trackH: 4, thumb: 18, thumbShape: 'Ellipse', thumbRound: 0, thumbStroke: 0, trackStroke: 0, glow: '', font: 'Inter', weight: 600,
43
+ accentFill: accent as any,
44
+ };
45
+ if (style === 'glass') Object.assign(t, { trackH: 6, thumb: 22, radius: 14, glow: dark ? 'rgba(255, 255, 255, 0.35)' : 'rgba(0, 0, 0, 0.18)', surface: dark ? 'rgba(255, 255, 255, 0.08)' : 'rgba(255, 255, 255, 0.55)' });
46
+ if (style === 'neon') Object.assign(t, { trackH: 3, thumb: 16, radius: 10, glow: accent, accentFill: { type: 'LinearGradient', start: [0, 0.5], end: [1, 0.5], stops: [{ offset: 0, color: accent, opacity: 1 }, { offset: 1, color: dark ? '#8B9CFF' : '#FF3D9A', opacity: 1 }] } });
47
+ if (style === 'editorial') Object.assign(t, { trackH: 2, thumb: 0, thumbShape: 'Rectangle', radius: 2, font: 'Georgia', weight: 400 });
48
+ if (style === 'brutal') Object.assign(t, { trackH: 12, thumb: 26, thumbShape: 'Rectangle', thumbRound: 0, thumbStroke: 2, trackStroke: 2, radius: 0, weight: 800, line: ink, track: dark ? '#1A1A1A' : '#FFFFFF' });
49
+ if (style === 'minimal') Object.assign(t, { trackH: 2, thumb: 12, radius: 8, weight: 500 });
50
+ return t;
19
51
  }
20
52
 
21
53
  type Input = { id: string; name: string; value: any; nodes: { id: string; x: number; y: number }[] };
@@ -49,7 +81,8 @@ export function createWidget(artboard: any, type: WidgetType, opts: {
49
81
  return id;
50
82
  };
51
83
  const tokens = artboard.tokens || {};
52
- const primary = c.color || tokens.colors?.primary || '#3b82f6';
84
+ const T = widgetTheme(artboard, (c.style as WidgetStyle) || 'auto', c.color);
85
+ const primary = T.accent;
53
86
  const controlRadius = tokens.radii?.control ?? tokens.radii?.md ?? 8;
54
87
  const transform = { x: opts.x ?? Math.round((artboard.width || 800) / 2), y: opts.y ?? Math.round((artboard.height || 600) / 2), rotation: 0, scale_x: 1, scale_y: 1, opacity: 1, skew_x: 0, skew_y: 0 };
55
88
  const base = (variant: string, geometry: any, extra: any = {}) => ({
@@ -67,17 +100,18 @@ export function createWidget(artboard: any, type: WidgetType, opts: {
67
100
 
68
101
  switch (type) {
69
102
  case 'Button': {
70
- obj = base('button', { type: 'Widget', width: 150, height: 44, cornerRadius: controlRadius }, {
103
+ const r = T.radius >= 12 ? 22 : T.radius;
104
+ obj = base('button', { type: 'Widget', width: 160, height: 46, cornerRadius: r }, {
71
105
  semanticTag: 'control',
72
- style: { stroke: { color: 'rgba(255, 255, 255, 0.18)', width: 1, opacity: 1 } },
106
+ style: { stroke: { color: T.line, width: T.trackStroke || 1, opacity: 1 } },
73
107
  options: {
74
- backgroundColor: { type: 'LinearGradient', stops: [{ offset: 0, color: primary }, { offset: 1, color: primary }] },
75
- borderColor: 'rgba(255, 255, 255, 0.18)', borderWidth: 1, accentColor: '#60a5fa', cornerRadius: controlRadius,
76
- shadow: { isEnabled: false, blur: 16, offsetY: 6, offsetX: 0, color: 'rgba(37, 99, 235, 0.35)' },
77
- label: { text: c.label ?? 'Button', color: '#ffffff', fontSize: 14, fontFamily: 'Inter', fontWeight: 600 },
108
+ backgroundColor: typeof T.accentFill === 'string' ? { type: 'LinearGradient', stops: [{ offset: 0, color: primary }, { offset: 1, color: primary }] } : T.accentFill,
109
+ borderColor: T.trackStroke ? T.ink : 'transparent', borderWidth: T.trackStroke, accentColor: primary, cornerRadius: r,
110
+ shadow: { isEnabled: !!T.glow, blur: 18, offsetY: 6, offsetX: 0, color: T.glow || 'rgba(0, 0, 0, 0.3)' },
111
+ label: { text: c.label ?? 'Button', color: T.onAccent, fontSize: 14, fontFamily: T.font, fontWeight: T.weight },
78
112
  icon: { enabled: false, svgPath: '', position: 'left', gap: 8 },
79
- hoverStyle: { backgroundColor: { type: 'LinearGradient', stops: [{ offset: 0, color: primary }, { offset: 1, color: primary }] }, borderColor: 'rgba(255, 255, 255, 0.35)', color: '#ffffff', scale: 1.02, cornerRadius: controlRadius, shadow: { isEnabled: true, blur: 20, offsetY: 8, offsetX: 0, color: 'rgba(37, 99, 235, 0.5)' } },
80
- activeStyle: { scale: 0.98, cornerRadius: controlRadius, shadow: { isEnabled: false, blur: 8, offsetY: 2, offsetX: 0, color: 'rgba(37, 99, 235, 0.2)' } },
113
+ hoverStyle: { scale: 1.03, cornerRadius: r, shadow: { isEnabled: true, blur: 26, offsetY: 10, offsetX: 0, color: T.glow || (T.dark ? 'rgba(0, 0, 0, 0.5)' : 'rgba(0, 0, 0, 0.18)') } },
114
+ activeStyle: { scale: 0.97, cornerRadius: r, shadow: { isEnabled: false, blur: 6, offsetY: 2, offsetX: 0, color: 'rgba(0, 0, 0, 0.2)' } },
81
115
  },
82
116
  });
83
117
  obj.interactions = [...hoverPair(obj.id),
@@ -89,11 +123,11 @@ export function createWidget(artboard: any, type: WidgetType, opts: {
89
123
  obj = base('inputbox', { type: 'Widget', width: 240, height: 42, cornerRadius: controlRadius }, {
90
124
  semanticTag: 'control', style: { stroke: { color: 'transparent', width: 0, opacity: 0 } },
91
125
  options: {
92
- value: c.value !== undefined ? String(c.value) : '', placeholder: c.label ?? 'Type something...', fontSize: 14, fontFamily: 'Inter', fontWeight: 400, color: '#f8fafc',
93
- backgroundColor: '#18181b', borderColor: '#334155', borderWidth: 1, cornerRadius: controlRadius, padding: { left: 14, right: 14, top: 0, bottom: 0 },
126
+ value: c.value !== undefined ? String(c.value) : '', placeholder: c.label ?? 'Type something...', fontSize: 14, fontFamily: T.font, fontWeight: 400, color: T.ink,
127
+ backgroundColor: T.surfaceSolid, borderColor: T.trackStroke ? T.ink : T.line, borderWidth: 1, cornerRadius: controlRadius, padding: { left: 14, right: 14, top: 0, bottom: 0 },
94
128
  accentColor: primary, leftIcon: { visible: false, char: '', svgPath: '' }, rightIcon: { visible: false, char: '', svgPath: '' }, disabled: false,
95
- hoverStyle: { backgroundColor: '#27272a', borderColor: '#475569', color: '#ffffff', cornerRadius: controlRadius, scale: 1.01 },
96
- activeStyle: { backgroundColor: '#18181b', borderColor: primary, color: '#ffffff', borderWidth: 1.5, cornerRadius: controlRadius, scale: 1.0 },
129
+ hoverStyle: { backgroundColor: T.surfaceSolid, borderColor: T.muted, color: T.ink, cornerRadius: controlRadius, scale: 1.0 },
130
+ activeStyle: { backgroundColor: T.surfaceSolid, borderColor: primary, color: T.ink, borderWidth: 1.5, cornerRadius: controlRadius, scale: 1.0 },
97
131
  },
98
132
  });
99
133
  obj.interactions = [...hoverPair(obj.id),
@@ -102,29 +136,38 @@ export function createWidget(artboard: any, type: WidgetType, opts: {
102
136
  break;
103
137
  }
104
138
  case 'Toggle': {
105
- obj = base('toggle', { type: 'Widget', width: 52, height: 30 }, {
139
+ const brutal = T.thumbShape === 'Rectangle' && T.trackStroke > 0;
140
+ obj = base('toggle', { type: 'Widget', width: brutal ? 60 : 52, height: brutal ? 32 : 30 }, {
106
141
  style: { stroke: { color: 'transparent', width: 0, opacity: 0 } },
107
142
  options: {
108
- checked: !!c.checked, activeColor: primary, accentColor: primary, inactiveColor: '#cbd5e1', knobColor: '#ffffff', cornerRadius: 15,
109
- knobShape: 'Circle', knobSize: 0, knobPadding: 2, trackShape: 'Pill',
110
- leftLabel: { enabled: true, text: 'Off', fontSize: 12, fontFamily: 'Inter', color: '#6b7280', gap: 8 },
111
- rightLabel: { enabled: true, text: 'On', fontSize: 12, fontFamily: 'Inter', color: '#6b7280', gap: 8 }, disabled: false,
143
+ checked: !!c.checked, activeColor: primary, accentColor: primary, inactiveColor: T.track, knobColor: T.dark ? '#FFFFFF' : (brutal ? T.ink : '#FFFFFF'), cornerRadius: brutal ? 0 : 15,
144
+ borderColor: brutal ? T.ink : T.line, borderWidth: brutal ? 2 : 1,
145
+ /* 'Rectangle' as a toggle shape is a 24×24 icon path that squashes; a Pill with radius 0 is a true rectangle */
146
+ knobShape: brutal ? 'Square' : 'Circle', knobSize: 0, knobPadding: brutal ? 4 : 3, trackShape: 'Pill',
147
+ toggleStyle: { knobColor: T.onAccent, borderColor: primary },
148
+ leftLabel: { enabled: c.label !== undefined, text: c.label ?? '', fontSize: 13, fontFamily: T.font, color: T.muted, gap: 10 },
149
+ rightLabel: { enabled: false, text: '', fontSize: 13, fontFamily: T.font, color: T.muted, gap: 10 }, disabled: false,
112
150
  },
113
151
  });
114
152
  obj.interactions = hoverPair(obj.id);
115
153
  break;
116
154
  }
117
155
  case 'Slider': {
118
- obj = base('slider', { type: 'Widget', width: 200, height: 24 }, {
156
+ const editorial = T.thumb === 0;
157
+ obj = base('slider', { type: 'Widget', width: 260, height: 28 }, {
119
158
  style: { fill: { type: 'Solid', color: 'transparent', opacity: 0 }, stroke: { color: 'transparent', width: 0, opacity: 0 } },
120
159
  options: {
121
- value: typeof c.value === 'number' ? c.value : 50, min: c.min ?? 0, max: c.max ?? 100, step: c.step ?? 1, trackHeight: 6, trackRoundedness: 3, trackShape: 'Rectangle', trackPath: '',
122
- trackStrokeWidth: 0, trackStrokeColor: '', accentColor: primary, inactiveColor: '#cbd5e1', thumbShape: 'Ellipse', thumbPath: '', thumbIcon: '',
123
- thumbWidth: 18, thumbHeight: 18, thumbRoundedness: 0, thumbColor: '#ffffff', thumbStrokeWidth: 0, thumbStrokeColor: '',
124
- tooltipColor: '#ffffff', tooltipBgColor: '#1e293b', tooltipOffsetX: 0, tooltipOffsetY: -25, disabled: false, showValueTooltip: false,
125
- hoverStyle: { scale: 1.04 }, activeStyle: { scale: 0.96 },
126
- label: { text: c.label ?? 'Label', visible: c.label !== undefined, fontSize: 12, color: '#374151' },
127
- helperText: { text: 'Helper text', visible: false, fontSize: 11, color: '#6b7280' },
160
+ value: typeof c.value === 'number' ? c.value : 50, min: c.min ?? 0, max: c.max ?? 100, step: c.step ?? 1,
161
+ trackHeight: T.trackH, trackRoundedness: T.trackStroke ? 0 : T.trackH / 2, trackShape: 'Rectangle', trackPath: '',
162
+ trackStrokeWidth: T.trackStroke, trackStrokeColor: T.trackStroke ? T.ink : '', accentColor: T.accentFill, activeColor: T.accentFill, inactiveColor: T.track,
163
+ thumbShape: T.thumbShape, thumbPath: '', thumbIcon: '',
164
+ thumbWidth: editorial ? 3 : T.thumb, thumbHeight: editorial ? 18 : T.thumb, thumbRoundedness: T.thumbRound,
165
+ thumbColor: T.thumbStroke ? (T.dark ? T.accent : '#FFFFFF') : (T.dark ? '#FFFFFF' : (editorial ? T.ink : '#FFFFFF')),
166
+ thumbStrokeWidth: T.thumbStroke || (T.dark || editorial ? 0 : 1), thumbStrokeColor: T.thumbStroke ? T.ink : T.line,
167
+ tooltipColor: T.onAccent, tooltipBgColor: primary, tooltipOffsetX: 0, tooltipOffsetY: -28, disabled: false, showValueTooltip: !!c.label || T.glow !== '',
168
+ hoverStyle: { thumbWidth: editorial ? 3 : T.thumb + 4, thumbHeight: editorial ? 24 : T.thumb + 4 }, activeStyle: { thumbWidth: editorial ? 4 : T.thumb + 6, thumbHeight: editorial ? 26 : T.thumb + 6, trackHeight: T.trackH + 1 },
169
+ label: { text: c.label ?? 'Label', visible: c.label !== undefined, fontSize: 13, color: T.muted },
170
+ helperText: { text: 'Helper text', visible: false, fontSize: 11, color: T.muted },
128
171
  },
129
172
  });
130
173
  obj.interactions = hoverPair(obj.id);
@@ -138,12 +181,12 @@ export function createWidget(artboard: any, type: WidgetType, opts: {
138
181
  style: { fill: { type: 'Solid', color: 'transparent', opacity: 0 }, stroke: { color: 'transparent', width: 0, opacity: 0 } },
139
182
  options: {
140
183
  placeholder: c.label ?? 'Select...', selectedOption: null, optionsList: items, isOpen: false, previewState: 'default',
141
- fontSize: 14, fontFamily: 'Inter', fontWeight: 400, color: '#f8fafc', backgroundColor: '#1e293b', borderColor: '#334155',
142
- borderWidth: 1, cornerRadius: 8, chevronSize: 16, chevronColor: '#94a3b8', chevronType: 'chevron', closedIconPath: 'M 0 0 L 4 4 L 8 0',
143
- openIconPath: 'M 0 0 L 4 4 L 8 0', closedIconAngle: 0, openIconAngle: 180, listBackgroundColor: '#0f172a', listTextColor: '#e2e8f0',
144
- listHoverColor: '#1e293b', listBorderColor: '#334155', listBorderWidth: 1, listCornerRadius: 8, listPadding: 4,
145
- itemHeight: 32, disabled: false, accentColor: primary, hoverBackgroundColor: '#334155', activeBackgroundColor: '#0f172a',
146
- itemHoverBackgroundColor: '#1e293b', itemSelectedBackgroundColor: primary, itemSelectedColor: '#ffffff',
184
+ fontSize: 14, fontFamily: T.font, fontWeight: 400, color: T.ink, backgroundColor: T.surfaceSolid, borderColor: T.trackStroke ? T.ink : T.line,
185
+ borderWidth: 1, cornerRadius: 8, chevronSize: 16, chevronColor: T.muted, chevronType: 'chevron', closedIconPath: 'M 0 0 L 4 4 L 8 0',
186
+ openIconPath: 'M 0 0 L 4 4 L 8 0', closedIconAngle: 0, openIconAngle: 180, listBackgroundColor: T.surfaceSolid, listTextColor: T.ink,
187
+ listHoverColor: T.surface, listBorderColor: T.line, listBorderWidth: 1, listCornerRadius: 8, listPadding: 4,
188
+ itemHeight: 34, disabled: false, accentColor: primary, hoverBackgroundColor: T.surface, activeBackgroundColor: T.surfaceSolid,
189
+ itemHoverBackgroundColor: T.surface, itemSelectedBackgroundColor: primary, itemSelectedColor: T.onAccent,
147
190
  dataInputId: optionsVar, isDataVarEnabled: true, selectedOutputId: selectedVar,
148
191
  },
149
192
  });
@@ -154,11 +197,11 @@ export function createWidget(artboard: any, type: WidgetType, opts: {
154
197
  obj = base('checkbox', { type: 'Checkbox', width: 140, height: 24 }, {
155
198
  style: { stroke: { color: 'transparent', width: 0, opacity: 0 } },
156
199
  options: {
157
- checked: !!c.checked, activeColor: primary, inactiveColor: 'transparent', checkColor: '#ffffff', boxSize: 18, cornerRadius: 4, borderWidth: 1.5, borderColor: '#9ca3af',
158
- label: { text: c.label ?? 'Checkbox', position: 'right', fontSize: 14, fontFamily: 'Inter', color: '#111827', gap: 8 },
200
+ checked: !!c.checked, activeColor: primary, inactiveColor: 'transparent', checkColor: T.onAccent, boxSize: 18, cornerRadius: T.trackStroke ? 0 : 5, borderWidth: T.trackStroke || 1.5, borderColor: T.trackStroke ? T.ink : T.line,
201
+ label: { text: c.label ?? 'Checkbox', position: 'right', fontSize: 14, fontFamily: T.font, color: T.ink, gap: 10 },
159
202
  disabled: false, previewState: 'default',
160
- hoverStyle: { backgroundColor: '#2563eb', borderColor: '#2563eb', checkColor: '#ffffff', scale: 1.05 },
161
- activeStyle: { backgroundColor: '#1d4ed8', borderColor: '#1d4ed8', checkColor: '#ffffff', scale: 0.95 },
203
+ hoverStyle: { borderColor: primary, checkColor: T.onAccent, scale: 1.05 },
204
+ activeStyle: { backgroundColor: primary, borderColor: primary, checkColor: T.onAccent, scale: 0.95 },
162
205
  },
163
206
  interactions: [{ trigger: 'onClick', action: 'Toggle Boolean', targetInputId: 'checked' }],
164
207
  });
@@ -172,12 +215,12 @@ export function createWidget(artboard: any, type: WidgetType, opts: {
172
215
  options: {
173
216
  selectedValue: c.value !== undefined ? String(c.value) : items[0], optionsList: items, orientation: 'vertical', itemGap: 10,
174
217
  radioShape: 'circle', radioSize: 9, borderWidth: 2, borderRadius: 0, fillEmpty: 'transparent', customShapePath: '',
175
- activeColor: primary, inactiveColor: '#94a3b8', textColor: '#111827', fontSize: 14, fontFamily: 'Inter', fontWeight: 400, disabled: false,
218
+ activeColor: primary, inactiveColor: T.muted, textColor: T.ink, fontSize: 14, fontFamily: T.font, fontWeight: 400, disabled: false,
176
219
  isDataVarEnabled: true, dataInputId: varId,
177
- label: { text: c.label ?? 'Radio Group', position: 'top', fontSize: 12, fontFamily: 'Inter', color: '#374151', gap: 6 },
220
+ label: { text: c.label ?? 'Radio Group', position: 'top', fontSize: 12, fontFamily: T.font, color: T.muted, gap: 6 },
178
221
  previewState: 'default',
179
- hoverStyle: { activeColor: '#2563eb', inactiveColor: '#64748b', textColor: '#111827', scale: 1.02 },
180
- activeStyle: { activeColor: '#1d4ed8', inactiveColor: '#475569', textColor: '#111827', scale: 0.98 },
222
+ hoverStyle: { activeColor: primary, inactiveColor: T.ink, textColor: T.ink, scale: 1.02 },
223
+ activeStyle: { activeColor: primary, inactiveColor: T.ink, textColor: T.ink, scale: 0.98 },
181
224
  },
182
225
  });
183
226
  break;
@@ -191,7 +234,7 @@ export function createWidget(artboard: any, type: WidgetType, opts: {
191
234
  type: 'Widget', style: none, constraints: [], isVisible: true, isLocked: false,
192
235
  options: {
193
236
  items, orientation: 'vertical', itemGap: 12, itemHeight: 50, itemWidth: 200, padding: 10, scrollOffset: 0, glassEffect: true, glowIntensity: 2,
194
- glowColor: 'rgba(59, 130, 246, 0.3)', accentColor: primary, itemBackgroundColor: 'rgba(0, 0, 0, 0.04)', itemTextColor: '#111827',
237
+ glowColor: T.glow || T.line, accentColor: primary, itemBackgroundColor: T.surface, itemTextColor: T.ink,
195
238
  backgroundColor: 'transparent', borderColor: 'rgba(0, 0, 0, 0.12)', borderWidth: 0, cornerRadius: 12, showScrollbar: true,
196
239
  scrollbarColor: 'rgba(0, 0, 0, 0.2)', scrollbarWidth: 2, isDataVarEnabled: true, dataInputId: varId,
197
240
  },
@@ -207,7 +250,7 @@ export function createWidget(artboard: any, type: WidgetType, opts: {
207
250
  geometry: {
208
251
  type: 'LineGraph', width: opts.width ?? 300, height: opts.height ?? 150,
209
252
  datasets: [{ id: 'dataset_1', label: c.seriesLabel ?? 'Revenue', data, lineColor: primary, lineWidth: 3, showArea: true, areaColor: 'rgba(59, 130, 246, 0.15)', smoothing: true, showPoints: true, pointSize: 6, pointFill: primary, pointStrokeColor: '#ffffff', pointStrokeWidth: 2, isVarEnabled: true, inputId: varId }],
210
- showXAxis: true, showYAxis: true, xAxisColor: 'rgba(0, 0, 0, 0.15)', yAxisColor: 'rgba(0, 0, 0, 0.15)', showLegend: true, legendColor: '#374151',
253
+ showXAxis: true, showYAxis: true, xAxisColor: T.line, yAxisColor: T.line, showLegend: true, legendColor: T.muted,
211
254
  showXLabels: true, showYLabels: true, axisLabelColor: '#4b5563', backgroundColor: 'transparent', cornerRadius: 0,
212
255
  },
213
256
  };
@@ -225,7 +268,7 @@ export function createWidget(artboard: any, type: WidgetType, opts: {
225
268
  orientation: 'vertical', barWidth: 18, barGap: 4, barCornerRadius: 4,
226
269
  showXAxis: true, showYAxis: true, xAxisColor: 'rgba(0, 0, 0, 0.15)', yAxisColor: 'rgba(0, 0, 0, 0.15)',
227
270
  showXLabels: true, showYLabels: true, axisLabelColor: '#4b5563', axisLabelFontSize: 10,
228
- showLegend: true, legendColor: '#111827', legendFontSize: 10, showGridLines: true, gridColor: 'rgba(0, 0, 0, 0.06)',
271
+ showLegend: true, legendColor: T.muted, legendFontSize: 10, showGridLines: true, gridColor: T.track,
229
272
  cardBackground: '#ffffff', cardBackgroundOpacity: 0.04, cardBorderColor: 'rgba(0, 0, 0, 0.08)', barGradient: true, showValueOnTop: false,
230
273
  isDataVarEnabled: true, dataInputId: catVar, isDatasetsVarEnabled: true, datasetInputIds: [dsVar],
231
274
  },
@@ -239,8 +282,8 @@ export function createWidget(artboard: any, type: WidgetType, opts: {
239
282
  obj = base('piechart', { type: 'PieChart', width: 180, height: 180 }, { style: none });
240
283
  obj.options = {
241
284
  slices: data.map((v, i) => ({ id: `slice-${i}-${obj.id}`, label: labels[i] || `Item ${i + 1}`, value: v, color: '' })),
242
- innerRadius: 0.5, showLabels: true, labelColor: '#111827', labelFontSize: 10, showLegend: true, legendColor: '#374151', legendFontSize: 10,
243
- colorPalette: 'vibrant', chartType: 'donut', showCenterText: true, centerTextColor: '#111827', centerLabelColor: '#6b7280',
285
+ innerRadius: 0.5, showLabels: true, labelColor: T.ink, labelFontSize: 10, showLegend: true, legendColor: T.muted, legendFontSize: 10,
286
+ colorPalette: 'vibrant', chartType: 'donut', showCenterText: true, centerTextColor: T.ink, centerLabelColor: T.muted,
244
287
  centerLabel: c.label ?? 'Total', sliceGap: 3, cardBackground: '#ffffff', cardBackgroundOpacity: 0.04, cardBorderColor: 'rgba(0, 0, 0, 0.08)',
245
288
  isDataVarEnabled: true, dataInputId: varId,
246
289
  };