conductor-figma 0.3.0 → 0.3.1

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/blueprints.js +424 -305
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "conductor-figma",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Design-intelligent MCP server for Figma. 61 tools across 10 categories. 8px grid, type scale ratios, auto-layout, component reuse, accessibility — real design intelligence, not shape proxying.",
5
5
  "author": "0xDragoon",
6
6
  "license": "MIT",
package/src/blueprints.js CHANGED
@@ -1,26 +1,15 @@
1
1
  // ═══════════════════════════════════════════
2
- // CONDUCTOR — Blueprints
2
+ // CONDUCTOR — Blueprints v2
3
3
  // ═══════════════════════════════════════════
4
- // Each blueprint generates a complete command sequence.
5
- // Commands reference previous results via '$N.id' tokens.
6
- // All values are grid-aligned and design-intelligent.
4
+ // Polished, production-grade command sequences.
5
+ // Every value is intentional. Every pixel is grid-aligned.
7
6
 
8
7
  import { snapToGrid, generateTypeScale, generateSemanticColors, generatePalette } from './design/intelligence.js';
9
8
 
10
9
  // ─── Helpers ───
11
10
 
12
11
  function frame(name, opts) {
13
- return {
14
- type: 'create_frame',
15
- data: Object.assign({
16
- name: name,
17
- direction: 'VERTICAL',
18
- padding: 0,
19
- gap: 0,
20
- fill: '#0f0f1a',
21
- cornerRadius: 0,
22
- }, opts),
23
- };
12
+ return { type: 'create_frame', data: Object.assign({ name: name, direction: 'VERTICAL', padding: 0, gap: 0, fill: '#0c0c18', cornerRadius: 0 }, opts) };
24
13
  }
25
14
 
26
15
  function hframe(name, opts) {
@@ -28,246 +17,341 @@ function hframe(name, opts) {
28
17
  }
29
18
 
30
19
  function text(content, opts) {
31
- return {
32
- type: 'create_text',
33
- data: Object.assign({
34
- text: content,
35
- fontSize: 16,
36
- color: '#ffffff',
37
- fontName: { family: 'Inter', style: 'Regular' },
38
- }, opts),
39
- };
20
+ return { type: 'create_text', data: Object.assign({ text: content, fontSize: 16, color: '#ffffff', fontName: { family: 'Inter', style: 'Regular' } }, opts) };
40
21
  }
41
22
 
42
23
  function rect(name, opts) {
43
- return {
44
- type: 'create_rect',
45
- data: Object.assign({ name: name, width: 100, height: 100 }, opts),
46
- };
24
+ return { type: 'create_rect', data: Object.assign({ name: name, width: 100, height: 100 }, opts) };
47
25
  }
48
26
 
49
- function appendTo(parentRef, cmd) {
50
- cmd.data.parentId = parentRef;
51
- return cmd;
52
- }
27
+ function ap(ref, cmd) { cmd.data.parentId = ref; return cmd; }
53
28
 
54
29
  // ═══════════════════════════════════════════
55
- // PAGE BLUEPRINTS
30
+ // LANDING PAGE — Premium quality
56
31
  // ═══════════════════════════════════════════
57
32
 
58
33
  export function buildLandingPage(args) {
59
- var brandColor = args.brandColor || '#6366f1';
60
- var colors = generateSemanticColors(brandColor);
61
- var pageWidth = args.width || 1440;
34
+ var brand = args.brandColor || '#6366f1';
35
+ var W = args.width || 1440;
36
+ var contentW = 1120;
62
37
  var dark = args.darkMode !== false;
63
- var bg = dark ? '#0f0f1a' : '#ffffff';
64
- var textColor = dark ? '#ffffff' : '#111111';
65
- var mutedColor = dark ? '#888899' : '#666677';
66
- var cardBg = dark ? '#16162e' : '#f5f5f7';
67
- var title = args.title || 'Ship faster with less overhead';
68
- var subtitle = args.subtitle || 'The modern platform for teams that move fast. Everything you need to build, deploy, and scale.';
69
- var ctaText = args.ctaText || 'Get started free';
38
+
39
+ // Palette
40
+ var bg = dark ? '#09090f' : '#ffffff';
41
+ var bg2 = dark ? '#0f0f1c' : '#f9f9fb';
42
+ var bg3 = dark ? '#14142a' : '#f3f3f7';
43
+ var cardBg = dark ? '#12122a' : '#ffffff';
44
+ var cardBorder = dark ? '#1e1e3a' : '#e8e8ee';
45
+ var text1 = dark ? '#f0f0f8' : '#111118';
46
+ var text2 = dark ? '#a0a0b8' : '#55556a';
47
+ var text3 = dark ? '#686880' : '#88889a';
48
+ var divider = dark ? '#1a1a32' : '#e4e4ec';
49
+
50
+ var title = args.title || 'Ship faster with\nless overhead';
51
+ var subtitle = args.subtitle || 'The modern platform for teams that move fast.\nEverything you need to build, deploy, and scale.';
52
+ var ctaText = args.ctaText || 'Start for free';
70
53
  var navItems = args.navItems || ['Features', 'Pricing', 'Docs', 'Blog'];
71
54
  var features = args.features || [
72
- { icon: '⚡', title: 'Instant Deploy', desc: 'Push to deploy in seconds. Zero config. Automatic HTTPS and global CDN.' },
73
- { icon: '📈', title: 'Auto Scale', desc: 'Scales to millions automatically. Pay only for what you use.' },
74
- { icon: '🔒', title: 'Enterprise Security', desc: 'SOC 2 compliant. End-to-end encryption. SSO and RBAC built in.' },
55
+ { icon: '⚡', title: 'Instant Deploy', desc: 'Push to deploy in seconds. Zero config. Automatic HTTPS, global CDN, and instant rollbacks.' },
56
+ { icon: '📈', title: 'Auto Scale', desc: 'Scales to millions of requests automatically. Pay only for what you use. No capacity planning.' },
57
+ { icon: '🔒', title: 'Enterprise Security', desc: 'SOC 2 Type II compliant. End-to-end encryption. SSO, RBAC, and audit logs built in.' },
75
58
  ];
76
59
  var stats = args.stats || [
77
60
  { value: '10,000+', label: 'Teams worldwide' },
78
61
  { value: '99.9%', label: 'Uptime SLA' },
79
62
  { value: '< 50ms', label: 'Global latency' },
63
+ { value: '4.9/5', label: 'Customer rating' },
80
64
  ];
81
65
 
82
66
  var cmds = [];
83
67
 
84
- // 0: Page root
85
- cmds.push(frame('Landing Page', { width: pageWidth, height: 2000, fill: bg, gap: 0 }));
68
+ // ── 0: Page Root ──
69
+ cmds.push(frame('Landing Page', { width: W, fill: bg, gap: 0, primaryAxisSizingMode: 'HUG' }));
86
70
 
87
- // 1: Nav
88
- cmds.push(appendTo('$0.id', hframe('Navigation', {
89
- width: pageWidth, height: 64, padding: 24, gap: 16, fill: bg,
71
+ // ── 1: Navigation ──
72
+ var navIdx = cmds.length;
73
+ cmds.push(ap('$0.id', hframe('Navigation', {
74
+ width: W, height: 72, paddingLeft: 48, paddingRight: 48, paddingTop: 0, paddingBottom: 0, gap: 0, fill: bg,
90
75
  counterAxisAlignItems: 'CENTER',
91
76
  })));
92
77
 
93
- // 2: Logo
94
- cmds.push(appendTo('$1.id', text(args.brand || 'acme', {
95
- fontSize: 18, color: textColor, fontName: { family: 'Inter', style: 'Bold' },
78
+ // Nav logo
79
+ cmds.push(ap('$' + navIdx + '.id', text(args.brand || 'acme', {
80
+ fontSize: 20, color: text1, fontName: { family: 'Inter', style: 'Bold' },
96
81
  })));
97
82
 
98
- // 3: Nav spacer
99
- cmds.push(appendTo('$1.id', frame('Spacer', {
100
- width: 1, height: 1, fill: bg,
101
- primaryAxisSizingMode: 'FILL',
83
+ // Nav spacer (pushes links right)
84
+ var spacerIdx = cmds.length;
85
+ cmds.push(ap('$' + navIdx + '.id', frame('_spacer', {
86
+ width: 1, height: 1, fill: bg, primaryAxisSizingMode: 'FILL',
87
+ })));
88
+
89
+ // Nav links container
90
+ var navLinksIdx = cmds.length;
91
+ cmds.push(ap('$' + navIdx + '.id', hframe('Nav Links', {
92
+ gap: 32, fill: bg, counterAxisAlignItems: 'CENTER',
102
93
  })));
103
94
 
104
- // 4-N: Nav links
105
95
  for (var i = 0; i < navItems.length; i++) {
106
- cmds.push(appendTo('$1.id', text(navItems[i], {
107
- fontSize: 14, color: mutedColor, fontName: { family: 'Inter', style: 'Medium' },
96
+ cmds.push(ap('$' + navLinksIdx + '.id', text(navItems[i], {
97
+ fontSize: 14, color: text2, fontName: { family: 'Inter', style: 'Medium' },
108
98
  })));
109
99
  }
110
100
 
111
- // Nav CTA button frame
101
+ // Nav CTA
112
102
  var navBtnIdx = cmds.length;
113
- cmds.push(appendTo('$1.id', hframe('Nav CTA', {
114
- width: 120, height: 36, padding: 12, gap: 0,
115
- fill: brandColor, cornerRadius: 8,
103
+ cmds.push(ap('$' + navIdx + '.id', hframe('Nav CTA', {
104
+ height: 40, paddingLeft: 20, paddingRight: 20, paddingTop: 0, paddingBottom: 0,
105
+ fill: brand, cornerRadius: 8,
116
106
  primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER',
117
107
  })));
118
- cmds.push(appendTo('$' + navBtnIdx + '.id', text('Sign up', {
119
- fontSize: 13, color: '#ffffff', fontName: { family: 'Inter', style: 'Semi Bold' },
108
+ cmds.push(ap('$' + navBtnIdx + '.id', text('Get started', {
109
+ fontSize: 14, color: '#ffffff', fontName: { family: 'Inter', style: 'Semi Bold' },
120
110
  })));
121
111
 
122
- // Hero section
112
+ // ── Divider ──
113
+ cmds.push(ap('$0.id', rect('Nav Divider', { width: W, height: 1, fill: divider })));
114
+
115
+ // ── Hero Section ──
123
116
  var heroIdx = cmds.length;
124
- cmds.push(appendTo('$0.id', frame('Hero Section', {
125
- width: pageWidth, height: 520, padding: 80, gap: 24, fill: bg,
117
+ cmds.push(ap('$0.id', frame('Hero Section', {
118
+ width: W, paddingTop: 96, paddingBottom: 96, paddingLeft: 48, paddingRight: 48,
119
+ gap: 32, fill: bg,
126
120
  primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER',
127
121
  })));
128
122
 
129
- // Hero overline
130
- cmds.push(appendTo('$' + heroIdx + '.id', text('INTRODUCING ' + (args.brand || 'ACME').toUpperCase(), {
131
- fontSize: 12, color: brandColor, fontName: { family: 'Inter', style: 'Semi Bold' },
123
+ // Overline badge
124
+ var badgeIdx = cmds.length;
125
+ cmds.push(ap('$' + heroIdx + '.id', hframe('Badge', {
126
+ paddingLeft: 16, paddingRight: 16, paddingTop: 8, paddingBottom: 8,
127
+ fill: dark ? '#1a1a36' : '#f0f0ff', cornerRadius: 20,
128
+ primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER', gap: 8,
129
+ })));
130
+ cmds.push(ap('$' + badgeIdx + '.id', text('✦', { fontSize: 10, color: brand })));
131
+ cmds.push(ap('$' + badgeIdx + '.id', text('Now available — v2.0 is here', {
132
+ fontSize: 12, color: dark ? '#b0b0d0' : '#5555aa', fontName: { family: 'Inter', style: 'Medium' },
132
133
  })));
133
134
 
134
135
  // Hero heading
135
- cmds.push(appendTo('$' + heroIdx + '.id', text(title, {
136
- fontSize: 56, color: textColor, fontName: { family: 'Inter', style: 'Bold' },
136
+ cmds.push(ap('$' + heroIdx + '.id', text(title, {
137
+ fontSize: 64, color: text1, fontName: { family: 'Inter', style: 'Bold' },
137
138
  textAlignHorizontal: 'CENTER',
138
139
  })));
139
140
 
140
141
  // Hero subtitle
141
- cmds.push(appendTo('$' + heroIdx + '.id', text(subtitle, {
142
- fontSize: 18, color: mutedColor, fontName: { family: 'Inter', style: 'Regular' },
142
+ cmds.push(ap('$' + heroIdx + '.id', text(subtitle, {
143
+ fontSize: 20, color: text2, fontName: { family: 'Inter', style: 'Regular' },
143
144
  textAlignHorizontal: 'CENTER',
144
145
  })));
145
146
 
146
147
  // Hero button row
147
148
  var btnRowIdx = cmds.length;
148
- cmds.push(appendTo('$' + heroIdx + '.id', hframe('Hero Buttons', {
149
- width: 340, height: 48, gap: 12, fill: bg,
149
+ cmds.push(ap('$' + heroIdx + '.id', hframe('Hero Buttons', {
150
+ gap: 12, fill: bg,
150
151
  primaryAxisAlignItems: 'CENTER',
151
152
  })));
152
153
 
153
154
  // Primary CTA
154
- var primaryBtnIdx = cmds.length;
155
- cmds.push(appendTo('$' + btnRowIdx + '.id', hframe('Primary CTA', {
156
- width: 160, height: 48, padding: 16, fill: brandColor, cornerRadius: 10,
155
+ var pBtnIdx = cmds.length;
156
+ cmds.push(ap('$' + btnRowIdx + '.id', hframe('Primary CTA', {
157
+ height: 52, paddingLeft: 28, paddingRight: 28, paddingTop: 0, paddingBottom: 0,
158
+ fill: brand, cornerRadius: 12,
157
159
  primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER',
158
160
  })));
159
- cmds.push(appendTo('$' + primaryBtnIdx + '.id', text(ctaText, {
160
- fontSize: 15, color: '#ffffff', fontName: { family: 'Inter', style: 'Semi Bold' },
161
+ cmds.push(ap('$' + pBtnIdx + '.id', text(ctaText, {
162
+ fontSize: 16, color: '#ffffff', fontName: { family: 'Inter', style: 'Semi Bold' },
161
163
  })));
162
164
 
163
165
  // Secondary CTA
164
- var secBtnIdx = cmds.length;
165
- cmds.push(appendTo('$' + btnRowIdx + '.id', hframe('Secondary CTA', {
166
- width: 160, height: 48, padding: 16, fill: dark ? '#1a1a2e' : '#eeeeee', cornerRadius: 10,
166
+ var sBtnIdx = cmds.length;
167
+ cmds.push(ap('$' + btnRowIdx + '.id', hframe('Secondary CTA', {
168
+ height: 52, paddingLeft: 28, paddingRight: 28, paddingTop: 0, paddingBottom: 0,
169
+ fill: 'transparent', cornerRadius: 12,
167
170
  primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER',
168
171
  })));
169
- cmds.push(appendTo('$' + secBtnIdx + '.id', text('View demo →', {
170
- fontSize: 15, color: dark ? '#ccccdd' : '#333333', fontName: { family: 'Inter', style: 'Medium' },
172
+ cmds.push(ap('$' + sBtnIdx + '.id', text('See how it works →', {
173
+ fontSize: 16, color: text2, fontName: { family: 'Inter', style: 'Medium' },
171
174
  })));
172
175
 
173
- // Stats bar
176
+ // ── Social proof line ──
177
+ var proofIdx = cmds.length;
178
+ cmds.push(ap('$' + heroIdx + '.id', hframe('Social Proof', {
179
+ gap: 8, fill: bg, counterAxisAlignItems: 'CENTER',
180
+ paddingTop: 16,
181
+ })));
182
+ cmds.push(ap('$' + proofIdx + '.id', text('★★★★★', {
183
+ fontSize: 14, color: '#fbbf24',
184
+ })));
185
+ cmds.push(ap('$' + proofIdx + '.id', text('Loved by 10,000+ teams', {
186
+ fontSize: 13, color: text3, fontName: { family: 'Inter', style: 'Medium' },
187
+ })));
188
+
189
+ // ── Stats Section ──
174
190
  var statsIdx = cmds.length;
175
- cmds.push(appendTo('$0.id', hframe('Stats Bar', {
176
- width: pageWidth, height: 120, padding: 48, gap: 80, fill: dark ? '#13132a' : '#f8f8fa',
177
- counterAxisAlignItems: 'CENTER',
191
+ cmds.push(ap('$0.id', hframe('Stats Bar', {
192
+ width: W, paddingTop: 48, paddingBottom: 48, paddingLeft: 48, paddingRight: 48,
193
+ gap: 0, fill: bg2,
194
+ primaryAxisAlignItems: 'CENTER',
195
+ })));
196
+
197
+ // Stats inner container (centered, max-width)
198
+ var statsInnerIdx = cmds.length;
199
+ cmds.push(ap('$' + statsIdx + '.id', hframe('Stats Inner', {
200
+ width: contentW, gap: 0, fill: bg2,
178
201
  })));
179
202
 
180
203
  for (var s = 0; s < stats.length; s++) {
181
204
  var statIdx = cmds.length;
182
- cmds.push(appendTo('$' + statsIdx + '.id', frame('Stat ' + (s + 1), {
183
- width: 200, height: 64, gap: 4, fill: dark ? '#13132a' : '#f8f8fa',
184
- counterAxisAlignItems: 'CENTER',
205
+ var statW = Math.floor(contentW / stats.length);
206
+ cmds.push(ap('$' + statsInnerIdx + '.id', frame('Stat: ' + stats[s].label, {
207
+ width: statW, paddingTop: 24, paddingBottom: 24, gap: 4, fill: bg2,
208
+ primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER',
185
209
  })));
186
- cmds.push(appendTo('$' + statIdx + '.id', text(stats[s].value, {
187
- fontSize: 32, color: textColor, fontName: { family: 'Inter', style: 'Bold' },
210
+ cmds.push(ap('$' + statIdx + '.id', text(stats[s].value, {
211
+ fontSize: 36, color: text1, fontName: { family: 'Inter', style: 'Bold' },
188
212
  })));
189
- cmds.push(appendTo('$' + statIdx + '.id', text(stats[s].label, {
190
- fontSize: 13, color: mutedColor, fontName: { family: 'Inter', style: 'Regular' },
213
+ cmds.push(ap('$' + statIdx + '.id', text(stats[s].label, {
214
+ fontSize: 14, color: text3, fontName: { family: 'Inter', style: 'Medium' },
191
215
  })));
192
216
  }
193
217
 
194
- // Features section
195
- var featSectionIdx = cmds.length;
196
- cmds.push(appendTo('$0.id', frame('Features Section', {
197
- width: pageWidth, padding: 64, gap: 32, fill: bg,
218
+ // ── Features Section ──
219
+ var featIdx = cmds.length;
220
+ cmds.push(ap('$0.id', frame('Features Section', {
221
+ width: W, paddingTop: 96, paddingBottom: 96, paddingLeft: 48, paddingRight: 48,
222
+ gap: 48, fill: bg,
198
223
  counterAxisAlignItems: 'CENTER',
199
224
  })));
200
225
 
201
- cmds.push(appendTo('$' + featSectionIdx + '.id', text('Everything you need', {
202
- fontSize: 36, color: textColor, fontName: { family: 'Inter', style: 'Bold' },
226
+ // Features header
227
+ var featHeaderIdx = cmds.length;
228
+ cmds.push(ap('$' + featIdx + '.id', frame('Features Header', {
229
+ gap: 16, fill: bg, counterAxisAlignItems: 'CENTER',
230
+ })));
231
+ cmds.push(ap('$' + featHeaderIdx + '.id', text('Everything you need', {
232
+ fontSize: 40, color: text1, fontName: { family: 'Inter', style: 'Bold' },
203
233
  textAlignHorizontal: 'CENTER',
204
234
  })));
205
-
206
- cmds.push(appendTo('$' + featSectionIdx + '.id', text('Powerful features to help your team ship faster and with more confidence.', {
207
- fontSize: 16, color: mutedColor, fontName: { family: 'Inter', style: 'Regular' },
235
+ cmds.push(ap('$' + featHeaderIdx + '.id', text('Powerful features to help your team ship faster\nand with more confidence.', {
236
+ fontSize: 18, color: text2, fontName: { family: 'Inter', style: 'Regular' },
208
237
  textAlignHorizontal: 'CENTER',
209
238
  })));
210
239
 
211
240
  // Feature card row
212
241
  var cardRowIdx = cmds.length;
213
- cmds.push(appendTo('$' + featSectionIdx + '.id', hframe('Feature Cards', {
214
- width: pageWidth - 128, gap: 20, fill: bg,
242
+ cmds.push(ap('$' + featIdx + '.id', hframe('Feature Cards', {
243
+ width: contentW, gap: 24, fill: bg,
215
244
  })));
216
245
 
217
246
  for (var f = 0; f < features.length; f++) {
247
+ var cardW = Math.floor((contentW - (features.length - 1) * 24) / features.length);
218
248
  var cardIdx = cmds.length;
219
- var cardWidth = Math.floor((pageWidth - 128 - (features.length - 1) * 20) / features.length);
220
- cmds.push(appendTo('$' + cardRowIdx + '.id', frame(features[f].title, {
221
- width: cardWidth, height: 200, padding: 24, gap: 12, fill: cardBg, cornerRadius: 14,
249
+ cmds.push(ap('$' + cardRowIdx + '.id', frame(features[f].title, {
250
+ width: cardW, paddingTop: 32, paddingBottom: 32, paddingLeft: 28, paddingRight: 28,
251
+ gap: 16, fill: cardBg, cornerRadius: 16,
252
+ })));
253
+
254
+ // Icon circle
255
+ var iconIdx = cmds.length;
256
+ cmds.push(ap('$' + cardIdx + '.id', hframe('Icon', {
257
+ width: 48, height: 48, fill: dark ? '#1c1c3a' : '#f0f0ff', cornerRadius: 12,
258
+ primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER',
222
259
  })));
223
- cmds.push(appendTo('$' + cardIdx + '.id', text(features[f].icon + ' ' + features[f].title, {
224
- fontSize: 18, color: textColor, fontName: { family: 'Inter', style: 'Semi Bold' },
260
+ cmds.push(ap('$' + iconIdx + '.id', text(features[f].icon, { fontSize: 20 })));
261
+
262
+ // Card title
263
+ cmds.push(ap('$' + cardIdx + '.id', text(features[f].title, {
264
+ fontSize: 20, color: text1, fontName: { family: 'Inter', style: 'Semi Bold' },
265
+ })));
266
+
267
+ // Card description
268
+ cmds.push(ap('$' + cardIdx + '.id', text(features[f].desc, {
269
+ fontSize: 15, color: text2, fontName: { family: 'Inter', style: 'Regular' },
225
270
  })));
226
- cmds.push(appendTo('$' + cardIdx + '.id', text(features[f].desc, {
227
- fontSize: 14, color: mutedColor, fontName: { family: 'Inter', style: 'Regular' },
271
+
272
+ // Learn more link
273
+ cmds.push(ap('$' + cardIdx + '.id', text('Learn more →', {
274
+ fontSize: 14, color: brand, fontName: { family: 'Inter', style: 'Medium' },
228
275
  })));
229
276
  }
230
277
 
231
- // CTA section
278
+ // ── CTA Section ──
232
279
  var ctaSectionIdx = cmds.length;
233
- cmds.push(appendTo('$0.id', frame('CTA Section', {
234
- width: pageWidth, padding: 80, gap: 24, fill: dark ? '#0a0a14' : '#f0f0f2',
280
+ cmds.push(ap('$0.id', frame('CTA Section', {
281
+ width: W, paddingTop: 96, paddingBottom: 96, paddingLeft: 48, paddingRight: 48,
282
+ gap: 0, fill: bg2,
283
+ counterAxisAlignItems: 'CENTER',
284
+ })));
285
+
286
+ // CTA card
287
+ var ctaCardIdx = cmds.length;
288
+ cmds.push(ap('$' + ctaSectionIdx + '.id', frame('CTA Card', {
289
+ width: contentW, paddingTop: 64, paddingBottom: 64, paddingLeft: 48, paddingRight: 48,
290
+ gap: 28, fill: dark ? '#14142e' : '#ffffff', cornerRadius: 20,
235
291
  primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER',
236
292
  })));
237
293
 
238
- cmds.push(appendTo('$' + ctaSectionIdx + '.id', text('Ready to get started?', {
239
- fontSize: 40, color: textColor, fontName: { family: 'Inter', style: 'Bold' },
294
+ cmds.push(ap('$' + ctaCardIdx + '.id', text('Ready to get started?', {
295
+ fontSize: 44, color: text1, fontName: { family: 'Inter', style: 'Bold' },
240
296
  textAlignHorizontal: 'CENTER',
241
297
  })));
242
298
 
243
- cmds.push(appendTo('$' + ctaSectionIdx + '.id', text('Join thousands of teams already shipping faster.', {
244
- fontSize: 16, color: mutedColor, fontName: { family: 'Inter', style: 'Regular' },
299
+ cmds.push(ap('$' + ctaCardIdx + '.id', text('Join thousands of teams already shipping faster.\nNo credit card required.', {
300
+ fontSize: 18, color: text2, fontName: { family: 'Inter', style: 'Regular' },
245
301
  textAlignHorizontal: 'CENTER',
246
302
  })));
247
303
 
248
- var ctaBtnIdx = cmds.length;
249
- cmds.push(appendTo('$' + ctaSectionIdx + '.id', hframe('CTA Button', {
250
- width: 200, height: 52, padding: 16, fill: brandColor, cornerRadius: 12,
304
+ var ctaBtnRowIdx = cmds.length;
305
+ cmds.push(ap('$' + ctaCardIdx + '.id', hframe('CTA Buttons', {
306
+ gap: 12, fill: dark ? '#14142e' : '#ffffff',
307
+ })));
308
+
309
+ var ctaPrimaryIdx = cmds.length;
310
+ cmds.push(ap('$' + ctaBtnRowIdx + '.id', hframe('CTA Primary', {
311
+ height: 56, paddingLeft: 32, paddingRight: 32, paddingTop: 0, paddingBottom: 0,
312
+ fill: brand, cornerRadius: 12,
251
313
  primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER',
252
314
  })));
253
- cmds.push(appendTo('$' + ctaBtnIdx + '.id', text(ctaText, {
254
- fontSize: 16, color: '#ffffff', fontName: { family: 'Inter', style: 'Semi Bold' },
315
+ cmds.push(ap('$' + ctaPrimaryIdx + '.id', text(ctaText, {
316
+ fontSize: 17, color: '#ffffff', fontName: { family: 'Inter', style: 'Semi Bold' },
317
+ })));
318
+
319
+ var ctaSecIdx = cmds.length;
320
+ cmds.push(ap('$' + ctaBtnRowIdx + '.id', hframe('CTA Secondary', {
321
+ height: 56, paddingLeft: 32, paddingRight: 32, paddingTop: 0, paddingBottom: 0,
322
+ fill: 'transparent', cornerRadius: 12,
323
+ primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER',
324
+ })));
325
+ cmds.push(ap('$' + ctaSecIdx + '.id', text('Talk to sales →', {
326
+ fontSize: 17, color: text2, fontName: { family: 'Inter', style: 'Medium' },
255
327
  })));
256
328
 
257
- // Footer
329
+ // ── Footer ──
330
+ cmds.push(ap('$0.id', rect('Footer Divider', { width: W, height: 1, fill: divider })));
331
+
258
332
  var footerIdx = cmds.length;
259
- cmds.push(appendTo('$0.id', hframe('Footer', {
260
- width: pageWidth, height: 80, padding: 24, gap: 16, fill: dark ? '#080812' : '#f5f5f7',
333
+ cmds.push(ap('$0.id', hframe('Footer', {
334
+ width: W, paddingTop: 48, paddingBottom: 48, paddingLeft: 48, paddingRight: 48,
335
+ gap: 0, fill: bg,
261
336
  counterAxisAlignItems: 'CENTER',
262
337
  })));
263
338
 
264
- cmds.push(appendTo('$' + footerIdx + '.id', text('© 2025 ' + (args.brand || 'Acme') + '. All rights reserved.', {
265
- fontSize: 13, color: mutedColor, fontName: { family: 'Inter', style: 'Regular' },
339
+ // Footer left
340
+ cmds.push(ap('$' + footerIdx + '.id', text(args.brand || 'acme', {
341
+ fontSize: 16, color: text3, fontName: { family: 'Inter', style: 'Semi Bold' },
342
+ })));
343
+
344
+ // Footer spacer
345
+ cmds.push(ap('$' + footerIdx + '.id', frame('_spacer', { width: 1, height: 1, fill: bg, primaryAxisSizingMode: 'FILL' })));
346
+
347
+ // Footer right
348
+ cmds.push(ap('$' + footerIdx + '.id', text('© 2025 ' + (args.brand || 'Acme') + ' Inc. All rights reserved.', {
349
+ fontSize: 13, color: text3, fontName: { family: 'Inter', style: 'Regular' },
266
350
  })));
267
351
 
268
352
  return {
269
353
  commands: cmds,
270
- description: 'Landing page with nav, hero, stats, features (' + features.length + ' cards), CTA, and footer. ' + cmds.length + ' elements, all auto-layout, ' + (dark ? 'dark' : 'light') + ' theme.',
354
+ description: 'Landing page: nav, hero with badge, ' + stats.length + ' stats, ' + features.length + ' feature cards with icons, CTA card, footer. ' + cmds.length + ' elements.',
271
355
  };
272
356
  }
273
357
 
@@ -276,136 +360,158 @@ export function buildLandingPage(args) {
276
360
  // ═══════════════════════════════════════════
277
361
 
278
362
  export function buildPricingPage(args) {
279
- var brandColor = args.brandColor || '#6366f1';
280
- var pageWidth = args.width || 1440;
281
- var bg = '#0f0f1a';
282
- var textColor = '#ffffff';
283
- var mutedColor = '#888899';
284
- var cardBg = '#16162e';
363
+ var brand = args.brandColor || '#6366f1';
364
+ var W = args.width || 1440;
365
+ var contentW = 1080;
366
+ var bg = '#09090f';
367
+ var bg2 = '#0f0f1c';
368
+ var cardBg = '#12122a';
369
+ var text1 = '#f0f0f8';
370
+ var text2 = '#a0a0b8';
371
+ var text3 = '#686880';
372
+ var divider = '#1a1a32';
373
+
285
374
  var tiers = args.tiers || [
286
- { name: 'Starter', price: '$0', period: '/mo', desc: 'For individuals and small projects', features: ['1 project', '100 API calls/day', 'Community support', 'Basic analytics'], cta: 'Start free', highlighted: false },
287
- { name: 'Pro', price: '$29', period: '/mo', desc: 'For growing teams that need more', features: ['Unlimited projects', '10,000 API calls/day', 'Priority support', 'Advanced analytics', 'Team collaboration', 'Custom domains'], cta: 'Start free trial', highlighted: true },
288
- { name: 'Enterprise', price: 'Custom', period: '', desc: 'For large organizations', features: ['Everything in Pro', 'Unlimited API calls', 'Dedicated support', 'SSO & SAML', 'SLA guarantee', 'Custom integrations', 'On-premise option'], cta: 'Contact sales', highlighted: false },
375
+ { name: 'Starter', price: '$0', period: '/mo', desc: 'For side projects and experiments.', features: ['1 project', '1,000 API calls/day', 'Community support', 'Basic analytics'], cta: 'Start free', highlighted: false },
376
+ { name: 'Pro', price: '$29', period: '/mo', desc: 'For growing teams that need more power.', features: ['Unlimited projects', '100,000 API calls/day', 'Priority support', 'Advanced analytics', 'Team collaboration', 'Custom domains', 'Webhooks'], cta: 'Start free trial', highlighted: true },
377
+ { name: 'Enterprise', price: 'Custom', period: '', desc: 'For organizations with advanced needs.', features: ['Everything in Pro', 'Unlimited API calls', 'Dedicated support', 'SSO & SAML', '99.99% SLA', 'Custom integrations', 'On-premise option', 'Audit logs'], cta: 'Contact sales', highlighted: false },
289
378
  ];
290
379
 
291
380
  var cmds = [];
292
381
 
293
- // 0: Page
294
- cmds.push(frame('Pricing Page', { width: pageWidth, height: 1400, fill: bg, gap: 0 }));
382
+ // 0: Root
383
+ cmds.push(frame('Pricing Page', { width: W, fill: bg, primaryAxisSizingMode: 'HUG' }));
295
384
 
296
- // 1: Header
385
+ // Header
297
386
  var headerIdx = cmds.length;
298
- cmds.push(appendTo('$0.id', frame('Pricing Header', {
299
- width: pageWidth, padding: 80, gap: 16, fill: bg,
387
+ cmds.push(ap('$0.id', frame('Pricing Header', {
388
+ width: W, paddingTop: 96, paddingBottom: 64, paddingLeft: 48, paddingRight: 48,
389
+ gap: 20, fill: bg,
300
390
  primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER',
301
391
  })));
302
392
 
303
- cmds.push(appendTo('$' + headerIdx + '.id', text('Simple, transparent pricing', {
304
- fontSize: 48, color: textColor, fontName: { family: 'Inter', style: 'Bold' },
393
+ cmds.push(ap('$' + headerIdx + '.id', text('Simple, transparent pricing', {
394
+ fontSize: 52, color: text1, fontName: { family: 'Inter', style: 'Bold' },
305
395
  textAlignHorizontal: 'CENTER',
306
396
  })));
307
397
 
308
- cmds.push(appendTo('$' + headerIdx + '.id', text('No hidden fees. No surprises. Cancel anytime.', {
309
- fontSize: 18, color: mutedColor, fontName: { family: 'Inter', style: 'Regular' },
398
+ cmds.push(ap('$' + headerIdx + '.id', text('No hidden fees. No surprises. Cancel anytime.\nStart free and scale as you grow.', {
399
+ fontSize: 18, color: text2, fontName: { family: 'Inter', style: 'Regular' },
310
400
  textAlignHorizontal: 'CENTER',
311
401
  })));
312
402
 
313
- // Tier cards row
403
+ // Tier row
314
404
  var tierRowIdx = cmds.length;
315
- cmds.push(appendTo('$0.id', hframe('Pricing Tiers', {
316
- width: pageWidth, padding: 48, gap: 20, fill: bg,
317
- primaryAxisAlignItems: 'CENTER',
405
+ cmds.push(ap('$0.id', hframe('Pricing Tiers', {
406
+ width: W, paddingLeft: Math.floor((W - contentW) / 2), paddingRight: Math.floor((W - contentW) / 2),
407
+ paddingTop: 0, paddingBottom: 96,
408
+ gap: 20, fill: bg, counterAxisAlignItems: 'STRETCH',
318
409
  })));
319
410
 
320
411
  for (var t = 0; t < tiers.length; t++) {
321
412
  var tier = tiers[t];
322
- var cardW = Math.min(380, Math.floor((pageWidth - 96 - (tiers.length - 1) * 20) / tiers.length));
323
- var isHighlighted = tier.highlighted;
413
+ var isHl = tier.highlighted;
414
+ var cardW = Math.floor((contentW - (tiers.length - 1) * 20) / tiers.length);
324
415
 
325
416
  var tierIdx = cmds.length;
326
- cmds.push(appendTo('$' + tierRowIdx + '.id', frame(tier.name + ' Tier', {
327
- width: cardW, padding: 32, gap: 16, cornerRadius: 16,
328
- fill: isHighlighted ? '#1e1e40' : cardBg,
417
+ cmds.push(ap('$' + tierRowIdx + '.id', frame(tier.name, {
418
+ width: cardW, paddingTop: 36, paddingBottom: 36, paddingLeft: 32, paddingRight: 32,
419
+ gap: 20, cornerRadius: 16,
420
+ fill: isHl ? '#1a1a3e' : cardBg,
329
421
  })));
330
422
 
331
- if (isHighlighted) {
332
- var badgeIdx = cmds.length;
333
- cmds.push(appendTo('$' + tierIdx + '.id', hframe('Popular Badge', {
334
- width: 100, height: 24, padding: 6, fill: brandColor, cornerRadius: 6,
423
+ // Popular badge
424
+ if (isHl) {
425
+ var bIdx = cmds.length;
426
+ cmds.push(ap('$' + tierIdx + '.id', hframe('Popular', {
427
+ paddingLeft: 12, paddingRight: 12, paddingTop: 4, paddingBottom: 4,
428
+ fill: brand, cornerRadius: 6,
335
429
  primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER',
336
430
  })));
337
- cmds.push(appendTo('$' + badgeIdx + '.id', text('POPULAR', {
431
+ cmds.push(ap('$' + bIdx + '.id', text('MOST POPULAR', {
338
432
  fontSize: 10, color: '#ffffff', fontName: { family: 'Inter', style: 'Bold' },
339
433
  })));
340
434
  }
341
435
 
342
- cmds.push(appendTo('$' + tierIdx + '.id', text(tier.name, {
343
- fontSize: 20, color: textColor, fontName: { family: 'Inter', style: 'Semi Bold' },
436
+ // Tier name
437
+ cmds.push(ap('$' + tierIdx + '.id', text(tier.name, {
438
+ fontSize: 22, color: text1, fontName: { family: 'Inter', style: 'Semi Bold' },
344
439
  })));
345
440
 
346
441
  // Price row
347
- var priceRowIdx = cmds.length;
348
- cmds.push(appendTo('$' + tierIdx + '.id', hframe('Price', {
349
- gap: 2, fill: isHighlighted ? '#1e1e40' : cardBg,
442
+ var priceIdx = cmds.length;
443
+ cmds.push(ap('$' + tierIdx + '.id', hframe('Price', {
444
+ gap: 4, fill: isHl ? '#1a1a3e' : cardBg,
350
445
  counterAxisAlignItems: 'BASELINE',
351
446
  })));
352
- cmds.push(appendTo('$' + priceRowIdx + '.id', text(tier.price, {
353
- fontSize: 40, color: textColor, fontName: { family: 'Inter', style: 'Bold' },
447
+ cmds.push(ap('$' + priceIdx + '.id', text(tier.price, {
448
+ fontSize: 48, color: text1, fontName: { family: 'Inter', style: 'Bold' },
354
449
  })));
355
450
  if (tier.period) {
356
- cmds.push(appendTo('$' + priceRowIdx + '.id', text(tier.period, {
357
- fontSize: 16, color: mutedColor, fontName: { family: 'Inter', style: 'Regular' },
451
+ cmds.push(ap('$' + priceIdx + '.id', text(tier.period, {
452
+ fontSize: 16, color: text3, fontName: { family: 'Inter', style: 'Regular' },
358
453
  })));
359
454
  }
360
455
 
361
- cmds.push(appendTo('$' + tierIdx + '.id', text(tier.desc, {
362
- fontSize: 14, color: mutedColor, fontName: { family: 'Inter', style: 'Regular' },
456
+ // Description
457
+ cmds.push(ap('$' + tierIdx + '.id', text(tier.desc, {
458
+ fontSize: 14, color: text2, fontName: { family: 'Inter', style: 'Regular' },
363
459
  })));
364
460
 
365
461
  // Divider
366
- cmds.push(appendTo('$' + tierIdx + '.id', rect('Divider', {
367
- width: cardW - 64, height: 1, fill: '#252540',
462
+ cmds.push(ap('$' + tierIdx + '.id', rect('Divider', {
463
+ width: cardW - 64, height: 1, fill: divider,
464
+ })));
465
+
466
+ // Features list
467
+ var featListIdx = cmds.length;
468
+ cmds.push(ap('$' + tierIdx + '.id', frame('Features', {
469
+ gap: 12, fill: isHl ? '#1a1a3e' : cardBg,
368
470
  })));
369
471
 
370
- // Features
371
472
  for (var fi = 0; fi < tier.features.length; fi++) {
372
- cmds.push(appendTo('$' + tierIdx + '.id', text('✓ ' + tier.features[fi], {
373
- fontSize: 13, color: mutedColor, fontName: { family: 'Inter', style: 'Regular' },
473
+ cmds.push(ap('$' + featListIdx + '.id', text('✓ ' + tier.features[fi], {
474
+ fontSize: 14, color: text2, fontName: { family: 'Inter', style: 'Regular' },
374
475
  })));
375
476
  }
376
477
 
377
478
  // CTA button
378
- var tierBtnIdx = cmds.length;
379
- cmds.push(appendTo('$' + tierIdx + '.id', hframe(tier.cta, {
380
- height: 44, padding: 12,
381
- fill: isHighlighted ? brandColor : 'transparent',
382
- cornerRadius: 8,
479
+ var btnIdx = cmds.length;
480
+ cmds.push(ap('$' + tierIdx + '.id', hframe(tier.cta, {
481
+ height: 48, paddingLeft: 24, paddingRight: 24, paddingTop: 0, paddingBottom: 0,
482
+ fill: isHl ? brand : 'transparent',
483
+ cornerRadius: 10,
383
484
  primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER',
384
485
  primaryAxisSizingMode: 'FILL',
385
486
  })));
386
- cmds.push(appendTo('$' + tierBtnIdx + '.id', text(tier.cta, {
387
- fontSize: 14, color: isHighlighted ? '#ffffff' : brandColor,
487
+ cmds.push(ap('$' + btnIdx + '.id', text(tier.cta, {
488
+ fontSize: 15, color: isHl ? '#ffffff' : brand,
388
489
  fontName: { family: 'Inter', style: 'Semi Bold' },
389
490
  })));
390
491
  }
391
492
 
392
493
  return {
393
494
  commands: cmds,
394
- description: 'Pricing page with ' + tiers.length + ' tiers (' + tiers.map(function(t) { return t.name; }).join(', ') + '). ' + cmds.length + ' elements, all auto-layout.',
495
+ description: 'Pricing page with header and ' + tiers.length + ' tiers (' + tiers.map(function(t) { return t.name; }).join(', ') + '). ' + cmds.length + ' elements.',
395
496
  };
396
497
  }
397
498
 
398
499
  // ═══════════════════════════════════════════
399
- // DASHBOARD PAGE
500
+ // DASHBOARD
400
501
  // ═══════════════════════════════════════════
401
502
 
402
503
  export function buildDashboardPage(args) {
403
- var pageWidth = args.width || 1440;
404
- var bg = '#0f0f1a';
405
- var cardBg = '#16162e';
406
- var textColor = '#ffffff';
407
- var mutedColor = '#888899';
408
- var brandColor = args.brandColor || '#6366f1';
504
+ var W = args.width || 1440;
505
+ var brand = args.brandColor || '#6366f1';
506
+ var bg = '#09090f';
507
+ var sidebarBg = '#0c0c18';
508
+ var cardBg = '#12122a';
509
+ var text1 = '#f0f0f8';
510
+ var text2 = '#a0a0b8';
511
+ var text3 = '#686880';
512
+ var divider = '#1a1a32';
513
+ var sideW = 260;
514
+
409
515
  var metrics = args.metrics || [
410
516
  { label: 'Total Revenue', value: '$48,290', change: '+12.5%', positive: true },
411
517
  { label: 'Active Users', value: '2,420', change: '+8.3%', positive: true },
@@ -415,94 +521,108 @@ export function buildDashboardPage(args) {
415
521
 
416
522
  var cmds = [];
417
523
 
418
- // 0: Page
419
- cmds.push(hframe('Dashboard', { width: pageWidth, height: 900, fill: bg, gap: 0 }));
524
+ cmds.push(hframe('Dashboard', { width: W, height: 900, fill: bg, gap: 0 }));
420
525
 
421
- // 1: Sidebar
422
- var sidebarIdx = cmds.length;
423
- cmds.push(appendTo('$0.id', frame('Sidebar', {
424
- width: 240, height: 900, padding: 16, gap: 8, fill: '#0a0a14',
526
+ // Sidebar
527
+ var sideIdx = cmds.length;
528
+ cmds.push(ap('$0.id', frame('Sidebar', {
529
+ width: sideW, height: 900, paddingTop: 24, paddingBottom: 24, paddingLeft: 20, paddingRight: 20,
530
+ gap: 4, fill: sidebarBg,
425
531
  })));
426
532
 
427
- // Sidebar logo
428
- cmds.push(appendTo('$' + sidebarIdx + '.id', text('◆ Dashboard', {
429
- fontSize: 14, color: textColor, fontName: { family: 'Inter', style: 'Bold' },
533
+ cmds.push(ap('$' + sideIdx + '.id', text('◆ Dashboard', {
534
+ fontSize: 16, color: text1, fontName: { family: 'Inter', style: 'Bold' },
430
535
  })));
431
536
 
432
- // Sidebar spacer
433
- cmds.push(appendTo('$' + sidebarIdx + '.id', frame('Spacer', { width: 1, height: 16, fill: '#0a0a14' })));
537
+ cmds.push(ap('$' + sideIdx + '.id', frame('_gap', { width: 1, height: 20, fill: sidebarBg })));
538
+
539
+ var sideNavItems = [
540
+ { label: 'Overview', active: true },
541
+ { label: 'Analytics', active: false },
542
+ { label: 'Customers', active: false },
543
+ { label: 'Products', active: false },
544
+ { label: 'Settings', active: false },
545
+ ];
434
546
 
435
- // Sidebar nav items
436
- var sideNavItems = ['Overview', 'Analytics', 'Customers', 'Products', 'Settings'];
437
547
  for (var si = 0; si < sideNavItems.length; si++) {
438
- var navItemIdx = cmds.length;
439
- cmds.push(appendTo('$' + sidebarIdx + '.id', hframe(sideNavItems[si], {
440
- height: 36, padding: 12, gap: 8, cornerRadius: 6,
441
- fill: si === 0 ? '#1a1a30' : '#0a0a14',
442
- primaryAxisSizingMode: 'FILL', counterAxisAlignItems: 'CENTER',
548
+ var navItem = sideNavItems[si];
549
+ var niIdx = cmds.length;
550
+ cmds.push(ap('$' + sideIdx + '.id', hframe(navItem.label, {
551
+ height: 40, paddingLeft: 12, paddingRight: 12, paddingTop: 0, paddingBottom: 0,
552
+ gap: 8, cornerRadius: 8,
553
+ fill: navItem.active ? '#1a1a36' : sidebarBg,
554
+ counterAxisAlignItems: 'CENTER', primaryAxisSizingMode: 'FILL',
443
555
  })));
444
- cmds.push(appendTo('$' + navItemIdx + '.id', text(sideNavItems[si], {
445
- fontSize: 13, color: si === 0 ? textColor : mutedColor,
446
- fontName: { family: 'Inter', style: si === 0 ? 'Medium' : 'Regular' },
556
+ cmds.push(ap('$' + niIdx + '.id', text(navItem.label, {
557
+ fontSize: 14, color: navItem.active ? text1 : text3,
558
+ fontName: { family: 'Inter', style: navItem.active ? 'Medium' : 'Regular' },
447
559
  })));
448
560
  }
449
561
 
450
- // Main content area
562
+ // Sidebar divider
563
+ cmds.push(ap('$0.id', rect('Sidebar Divider', { width: 1, height: 900, fill: divider })));
564
+
565
+ // Main
451
566
  var mainIdx = cmds.length;
452
- cmds.push(appendTo('$0.id', frame('Main Content', {
453
- width: pageWidth - 240, height: 900, padding: 32, gap: 24, fill: bg,
567
+ cmds.push(ap('$0.id', frame('Main', {
568
+ width: W - sideW - 1, height: 900,
569
+ paddingTop: 32, paddingBottom: 32, paddingLeft: 40, paddingRight: 40,
570
+ gap: 28, fill: bg,
454
571
  })));
455
572
 
456
- // Header row
457
- var headerIdx = cmds.length;
458
- cmds.push(appendTo('$' + mainIdx + '.id', hframe('Header', {
459
- gap: 16, fill: bg, counterAxisAlignItems: 'CENTER',
460
- primaryAxisSizingMode: 'FILL',
461
- })));
462
- cmds.push(appendTo('$' + headerIdx + '.id', text('Overview', {
463
- fontSize: 24, color: textColor, fontName: { family: 'Inter', style: 'Bold' },
573
+ // Header
574
+ cmds.push(ap('$' + mainIdx + '.id', text('Overview', {
575
+ fontSize: 28, color: text1, fontName: { family: 'Inter', style: 'Bold' },
464
576
  })));
465
577
 
466
- // Metric cards row
578
+ // Metrics row
467
579
  var metricsRowIdx = cmds.length;
468
- cmds.push(appendTo('$' + mainIdx + '.id', hframe('Metrics', {
469
- gap: 16, fill: bg, primaryAxisSizingMode: 'FILL',
580
+ cmds.push(ap('$' + mainIdx + '.id', hframe('Metrics', {
581
+ gap: 20, fill: bg,
470
582
  })));
471
583
 
584
+ var metricW = Math.floor((W - sideW - 1 - 80 - (metrics.length - 1) * 20) / metrics.length);
472
585
  for (var mi = 0; mi < metrics.length; mi++) {
473
- var metricIdx = cmds.length;
474
- var metricW = Math.floor((pageWidth - 240 - 64 - (metrics.length - 1) * 16) / metrics.length);
475
- cmds.push(appendTo('$' + metricsRowIdx + '.id', frame(metrics[mi].label, {
476
- width: metricW, padding: 20, gap: 8, fill: cardBg, cornerRadius: 12,
586
+ var mIdx = cmds.length;
587
+ cmds.push(ap('$' + metricsRowIdx + '.id', frame(metrics[mi].label, {
588
+ width: metricW, paddingTop: 24, paddingBottom: 24, paddingLeft: 24, paddingRight: 24,
589
+ gap: 8, fill: cardBg, cornerRadius: 12,
477
590
  })));
478
- cmds.push(appendTo('$' + metricIdx + '.id', text(metrics[mi].label, {
479
- fontSize: 12, color: mutedColor, fontName: { family: 'Inter', style: 'Medium' },
591
+ cmds.push(ap('$' + mIdx + '.id', text(metrics[mi].label, {
592
+ fontSize: 13, color: text3, fontName: { family: 'Inter', style: 'Medium' },
480
593
  })));
481
- cmds.push(appendTo('$' + metricIdx + '.id', text(metrics[mi].value, {
482
- fontSize: 28, color: textColor, fontName: { family: 'Inter', style: 'Bold' },
594
+ cmds.push(ap('$' + mIdx + '.id', text(metrics[mi].value, {
595
+ fontSize: 32, color: text1, fontName: { family: 'Inter', style: 'Bold' },
483
596
  })));
484
- cmds.push(appendTo('$' + metricIdx + '.id', text(metrics[mi].change, {
485
- fontSize: 12, color: metrics[mi].positive ? '#4ade80' : '#f87171',
486
- fontName: { family: 'Inter', style: 'Medium' },
597
+ cmds.push(ap('$' + mIdx + '.id', text(metrics[mi].change, {
598
+ fontSize: 13, color: metrics[mi].positive ? '#4ade80' : '#f87171',
599
+ fontName: { family: 'Inter', style: 'Semi Bold' },
487
600
  })));
488
601
  }
489
602
 
490
- // Chart placeholder
603
+ // Chart
491
604
  var chartIdx = cmds.length;
492
- cmds.push(appendTo('$' + mainIdx + '.id', frame('Chart Area', {
493
- height: 300, padding: 24, gap: 12, fill: cardBg, cornerRadius: 12,
605
+ cmds.push(ap('$' + mainIdx + '.id', frame('Chart Area', {
606
+ paddingTop: 28, paddingBottom: 28, paddingLeft: 28, paddingRight: 28,
607
+ gap: 16, fill: cardBg, cornerRadius: 12,
494
608
  primaryAxisSizingMode: 'FILL',
495
609
  })));
496
- cmds.push(appendTo('$' + chartIdx + '.id', text('Revenue Over Time', {
497
- fontSize: 16, color: textColor, fontName: { family: 'Inter', style: 'Semi Bold' },
610
+
611
+ var chartHeaderIdx = cmds.length;
612
+ cmds.push(ap('$' + chartIdx + '.id', hframe('Chart Header', {
613
+ gap: 12, fill: cardBg, counterAxisAlignItems: 'CENTER',
614
+ })));
615
+ cmds.push(ap('$' + chartHeaderIdx + '.id', text('Revenue Over Time', {
616
+ fontSize: 18, color: text1, fontName: { family: 'Inter', style: 'Semi Bold' },
498
617
  })));
499
- cmds.push(appendTo('$' + chartIdx + '.id', rect('Chart Placeholder', {
500
- width: 900, height: 200, fill: '#1a1a30', cornerRadius: 8,
618
+
619
+ cmds.push(ap('$' + chartIdx + '.id', rect('Chart Placeholder', {
620
+ width: W - sideW - 1 - 80 - 56, height: 240, fill: '#16163a', cornerRadius: 8,
501
621
  })));
502
622
 
503
623
  return {
504
624
  commands: cmds,
505
- description: 'Dashboard with sidebar nav, header, ' + metrics.length + ' metric cards, and chart area. ' + cmds.length + ' elements, all auto-layout.',
625
+ description: 'Dashboard with sidebar (' + sideNavItems.length + ' nav items), header, ' + metrics.length + ' metric cards, and chart area. ' + cmds.length + ' elements.',
506
626
  };
507
627
  }
508
628
 
@@ -523,120 +643,119 @@ export function buildSection(sectionType, args) {
523
643
  }
524
644
 
525
645
  function buildHeroSection(args) {
526
- var w = args.width || 1440;
527
- var brandColor = args.brandColor || '#6366f1';
646
+ var W = args.width || 1440;
647
+ var brand = args.brandColor || '#6366f1';
648
+ var bg = '#09090f';
528
649
  var cmds = [];
529
650
 
530
- cmds.push(frame('Hero', { width: w, padding: 80, gap: 24, fill: '#0f0f1a', primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER' }));
531
- cmds.push(appendTo('$0.id', text(args.heading || 'Build something great', { fontSize: 56, color: '#ffffff', fontName: { family: 'Inter', style: 'Bold' }, textAlignHorizontal: 'CENTER' })));
532
- cmds.push(appendTo('$0.id', text(args.subheading || 'The platform for modern teams.', { fontSize: 18, color: '#888899', fontName: { family: 'Inter', style: 'Regular' }, textAlignHorizontal: 'CENTER' })));
651
+ cmds.push(frame('Hero', { width: W, paddingTop: 96, paddingBottom: 96, paddingLeft: 48, paddingRight: 48, gap: 32, fill: bg, primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER' }));
652
+ cmds.push(ap('$0.id', text(args.heading || 'Build something great', { fontSize: 64, color: '#f0f0f8', fontName: { family: 'Inter', style: 'Bold' }, textAlignHorizontal: 'CENTER' })));
653
+ cmds.push(ap('$0.id', text(args.subheading || 'The platform for modern teams.', { fontSize: 20, color: '#a0a0b8', textAlignHorizontal: 'CENTER' })));
533
654
 
534
655
  var btnIdx = cmds.length;
535
- cmds.push(appendTo('$0.id', hframe('CTA', { width: 180, height: 48, padding: 16, fill: brandColor, cornerRadius: 10, primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER' })));
536
- cmds.push(appendTo('$' + btnIdx + '.id', text(args.ctaText || 'Get started', { fontSize: 15, color: '#ffffff', fontName: { family: 'Inter', style: 'Semi Bold' } })));
656
+ cmds.push(ap('$0.id', hframe('CTA', { height: 52, paddingLeft: 28, paddingRight: 28, paddingTop: 0, paddingBottom: 0, fill: brand, cornerRadius: 12, primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER' })));
657
+ cmds.push(ap('$' + btnIdx + '.id', text(args.ctaText || 'Get started', { fontSize: 16, color: '#ffffff', fontName: { family: 'Inter', style: 'Semi Bold' } })));
537
658
 
538
659
  return { commands: cmds, description: 'Hero section with heading, subtitle, and CTA.' };
539
660
  }
540
661
 
541
662
  function buildFeaturesSection(args) {
542
- var w = args.width || 1440;
663
+ var W = args.width || 1440;
543
664
  var features = args.features || [
544
- { title: 'Fast', desc: 'Blazing fast performance.' },
545
- { title: 'Secure', desc: 'Enterprise-grade security.' },
546
- { title: 'Scalable', desc: 'Grows with your team.' },
665
+ { title: 'Fast', desc: 'Blazing fast performance out of the box.' },
666
+ { title: 'Secure', desc: 'Enterprise-grade security by default.' },
667
+ { title: 'Scalable', desc: 'Grows seamlessly with your team.' },
547
668
  ];
548
669
  var cmds = [];
549
670
 
550
- cmds.push(frame('Features', { width: w, padding: 64, gap: 32, fill: '#0f0f1a', counterAxisAlignItems: 'CENTER' }));
551
- cmds.push(appendTo('$0.id', text(args.heading || 'Features', { fontSize: 36, color: '#ffffff', fontName: { family: 'Inter', style: 'Bold' }, textAlignHorizontal: 'CENTER' })));
671
+ cmds.push(frame('Features', { width: W, paddingTop: 96, paddingBottom: 96, paddingLeft: 48, paddingRight: 48, gap: 48, fill: '#09090f', counterAxisAlignItems: 'CENTER' }));
672
+ cmds.push(ap('$0.id', text(args.heading || 'Features', { fontSize: 40, color: '#f0f0f8', fontName: { family: 'Inter', style: 'Bold' }, textAlignHorizontal: 'CENTER' })));
552
673
 
553
674
  var rowIdx = cmds.length;
554
- cmds.push(appendTo('$0.id', hframe('Feature Cards', { width: w - 128, gap: 20, fill: '#0f0f1a' })));
675
+ cmds.push(ap('$0.id', hframe('Cards', { width: 1120, gap: 24, fill: '#09090f' })));
555
676
 
556
677
  for (var i = 0; i < features.length; i++) {
557
- var cw = Math.floor((w - 128 - (features.length - 1) * 20) / features.length);
678
+ var cw = Math.floor((1120 - (features.length - 1) * 24) / features.length);
558
679
  var ci = cmds.length;
559
- cmds.push(appendTo('$' + rowIdx + '.id', frame(features[i].title, { width: cw, height: 160, padding: 24, gap: 10, fill: '#16162e', cornerRadius: 12 })));
560
- cmds.push(appendTo('$' + ci + '.id', text(features[i].title, { fontSize: 18, color: '#ffffff', fontName: { family: 'Inter', style: 'Semi Bold' } })));
561
- cmds.push(appendTo('$' + ci + '.id', text(features[i].desc, { fontSize: 14, color: '#888899', fontName: { family: 'Inter', style: 'Regular' } })));
680
+ cmds.push(ap('$' + rowIdx + '.id', frame(features[i].title, { width: cw, paddingTop: 32, paddingBottom: 32, paddingLeft: 28, paddingRight: 28, gap: 16, fill: '#12122a', cornerRadius: 16 })));
681
+ cmds.push(ap('$' + ci + '.id', text(features[i].title, { fontSize: 20, color: '#f0f0f8', fontName: { family: 'Inter', style: 'Semi Bold' } })));
682
+ cmds.push(ap('$' + ci + '.id', text(features[i].desc, { fontSize: 15, color: '#a0a0b8' })));
562
683
  }
563
684
 
564
685
  return { commands: cmds, description: 'Features section with ' + features.length + ' cards.' };
565
686
  }
566
687
 
567
- function buildPricingSection(args) {
568
- return buildPricingPage(args);
569
- }
688
+ function buildPricingSection(args) { return buildPricingPage(args); }
570
689
 
571
690
  function buildCTASection(args) {
572
- var w = args.width || 1440;
573
- var brandColor = args.brandColor || '#6366f1';
691
+ var W = args.width || 1440;
692
+ var brand = args.brandColor || '#6366f1';
574
693
  var cmds = [];
575
694
 
576
- cmds.push(frame('CTA Section', { width: w, padding: 80, gap: 24, fill: '#0a0a14', primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER' }));
577
- cmds.push(appendTo('$0.id', text(args.heading || 'Ready to start?', { fontSize: 40, color: '#ffffff', fontName: { family: 'Inter', style: 'Bold' }, textAlignHorizontal: 'CENTER' })));
578
- cmds.push(appendTo('$0.id', text(args.subheading || 'Join thousands of teams.', { fontSize: 16, color: '#888899', fontName: { family: 'Inter', style: 'Regular' }, textAlignHorizontal: 'CENTER' })));
579
-
695
+ cmds.push(frame('CTA', { width: W, paddingTop: 96, paddingBottom: 96, paddingLeft: 48, paddingRight: 48, gap: 28, fill: '#0f0f1c', primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER' }));
696
+ cmds.push(ap('$0.id', text(args.heading || 'Ready to start?', { fontSize: 44, color: '#f0f0f8', fontName: { family: 'Inter', style: 'Bold' }, textAlignHorizontal: 'CENTER' })));
697
+ cmds.push(ap('$0.id', text(args.subheading || 'Join thousands of teams shipping faster.', { fontSize: 18, color: '#a0a0b8', textAlignHorizontal: 'CENTER' })));
580
698
  var btnIdx = cmds.length;
581
- cmds.push(appendTo('$0.id', hframe('CTA Button', { width: 200, height: 52, padding: 16, fill: brandColor, cornerRadius: 12, primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER' })));
582
- cmds.push(appendTo('$' + btnIdx + '.id', text(args.ctaText || 'Get started free', { fontSize: 16, color: '#ffffff', fontName: { family: 'Inter', style: 'Semi Bold' } })));
699
+ cmds.push(ap('$0.id', hframe('CTA Button', { height: 56, paddingLeft: 32, paddingRight: 32, paddingTop: 0, paddingBottom: 0, fill: brand, cornerRadius: 12, primaryAxisAlignItems: 'CENTER', counterAxisAlignItems: 'CENTER' })));
700
+ cmds.push(ap('$' + btnIdx + '.id', text(args.ctaText || 'Get started free', { fontSize: 17, color: '#ffffff', fontName: { family: 'Inter', style: 'Semi Bold' } })));
583
701
 
584
702
  return { commands: cmds, description: 'CTA section with heading, subtitle, and button.' };
585
703
  }
586
704
 
587
705
  function buildTestimonialsSection(args) {
588
- var w = args.width || 1440;
706
+ var W = args.width || 1440;
589
707
  var testimonials = args.testimonials || [
590
- { quote: 'This product transformed how our team works. Absolutely incredible.', author: 'Sarah Chen', role: 'CTO, TechCorp' },
591
- { quote: 'The best tool we have adopted this year. Our productivity doubled.', author: 'Marcus Rivera', role: 'VP Engineering, ScaleUp' },
708
+ { quote: 'This product transformed how our team works. The speed and reliability are unmatched.', author: 'Sarah Chen', role: 'CTO, TechCorp' },
709
+ { quote: 'Best tool we adopted this year. Our deployment time dropped by 80%.', author: 'Marcus Rivera', role: 'VP Engineering, ScaleUp' },
592
710
  ];
593
711
  var cmds = [];
594
712
 
595
- cmds.push(frame('Testimonials', { width: w, padding: 64, gap: 32, fill: '#0f0f1a', counterAxisAlignItems: 'CENTER' }));
596
- cmds.push(appendTo('$0.id', text('What people say', { fontSize: 36, color: '#ffffff', fontName: { family: 'Inter', style: 'Bold' }, textAlignHorizontal: 'CENTER' })));
713
+ cmds.push(frame('Testimonials', { width: W, paddingTop: 96, paddingBottom: 96, paddingLeft: 48, paddingRight: 48, gap: 48, fill: '#09090f', counterAxisAlignItems: 'CENTER' }));
714
+ cmds.push(ap('$0.id', text('Trusted by the best teams', { fontSize: 40, color: '#f0f0f8', fontName: { family: 'Inter', style: 'Bold' }, textAlignHorizontal: 'CENTER' })));
597
715
 
598
716
  var rowIdx = cmds.length;
599
- cmds.push(appendTo('$0.id', hframe('Testimonial Cards', { width: w - 128, gap: 20, fill: '#0f0f1a' })));
717
+ cmds.push(ap('$0.id', hframe('Cards', { width: 1120, gap: 24, fill: '#09090f' })));
600
718
 
601
719
  for (var i = 0; i < testimonials.length; i++) {
602
- var tw = Math.floor((w - 128 - (testimonials.length - 1) * 20) / testimonials.length);
720
+ var tw = Math.floor((1120 - (testimonials.length - 1) * 24) / testimonials.length);
603
721
  var ti = cmds.length;
604
- cmds.push(appendTo('$' + rowIdx + '.id', frame('Testimonial ' + (i + 1), { width: tw, padding: 24, gap: 16, fill: '#16162e', cornerRadius: 14 })));
605
- cmds.push(appendTo('$' + ti + '.id', text('"' + testimonials[i].quote + '"', { fontSize: 15, color: '#ccccdd', fontName: { family: 'Inter', style: 'Regular' } })));
606
- cmds.push(appendTo('$' + ti + '.id', text(testimonials[i].author, { fontSize: 14, color: '#ffffff', fontName: { family: 'Inter', style: 'Semi Bold' } })));
607
- cmds.push(appendTo('$' + ti + '.id', text(testimonials[i].role, { fontSize: 12, color: '#888899', fontName: { family: 'Inter', style: 'Regular' } })));
722
+ cmds.push(ap('$' + rowIdx + '.id', frame('Testimonial', { width: tw, paddingTop: 32, paddingBottom: 32, paddingLeft: 28, paddingRight: 28, gap: 20, fill: '#12122a', cornerRadius: 16 })));
723
+ cmds.push(ap('$' + ti + '.id', text('★★★★★', { fontSize: 16, color: '#fbbf24' })));
724
+ cmds.push(ap('$' + ti + '.id', text('"' + testimonials[i].quote + '"', { fontSize: 16, color: '#d0d0e0', fontName: { family: 'Inter', style: 'Regular' } })));
725
+ cmds.push(ap('$' + ti + '.id', text(testimonials[i].author, { fontSize: 15, color: '#f0f0f8', fontName: { family: 'Inter', style: 'Semi Bold' } })));
726
+ cmds.push(ap('$' + ti + '.id', text(testimonials[i].role, { fontSize: 13, color: '#686880' })));
608
727
  }
609
728
 
610
729
  return { commands: cmds, description: 'Testimonials with ' + testimonials.length + ' cards.' };
611
730
  }
612
731
 
613
732
  function buildFAQSection(args) {
614
- var w = args.width || 1440;
733
+ var W = args.width || 1440;
615
734
  var faqs = args.faqs || [
616
- { q: 'How do I get started?', a: 'Sign up for free and follow our quick-start guide. Takes less than 5 minutes.' },
617
- { q: 'Can I cancel anytime?', a: 'Yes. No contracts, no cancellation fees. Cancel with one click.' },
618
- { q: 'Do you offer support?', a: 'All plans include email support. Pro and Enterprise get priority support.' },
735
+ { q: 'How do I get started?', a: 'Sign up for a free account and follow our quick-start guide. You will be up and running in less than 5 minutes.' },
736
+ { q: 'Can I cancel anytime?', a: 'Yes. No contracts, no cancellation fees. Cancel with one click from your dashboard.' },
737
+ { q: 'Do you offer support?', a: 'All plans include email support. Pro and Enterprise plans get priority support with guaranteed response times.' },
619
738
  ];
620
739
  var cmds = [];
621
740
 
622
- cmds.push(frame('FAQ', { width: w, padding: 64, gap: 32, fill: '#0f0f1a', counterAxisAlignItems: 'CENTER' }));
623
- cmds.push(appendTo('$0.id', text('Frequently asked questions', { fontSize: 36, color: '#ffffff', fontName: { family: 'Inter', style: 'Bold' }, textAlignHorizontal: 'CENTER' })));
741
+ cmds.push(frame('FAQ', { width: W, paddingTop: 96, paddingBottom: 96, paddingLeft: 48, paddingRight: 48, gap: 48, fill: '#09090f', counterAxisAlignItems: 'CENTER' }));
742
+ cmds.push(ap('$0.id', text('Frequently asked questions', { fontSize: 40, color: '#f0f0f8', fontName: { family: 'Inter', style: 'Bold' }, textAlignHorizontal: 'CENTER' })));
624
743
 
625
744
  var listIdx = cmds.length;
626
- cmds.push(appendTo('$0.id', frame('FAQ List', { width: Math.min(700, w - 128), gap: 12, fill: '#0f0f1a' })));
745
+ cmds.push(ap('$0.id', frame('FAQ List', { width: 720, gap: 12, fill: '#09090f' })));
627
746
 
628
747
  for (var i = 0; i < faqs.length; i++) {
629
- var faqIdx = cmds.length;
630
- cmds.push(appendTo('$' + listIdx + '.id', frame('FAQ ' + (i + 1), { padding: 20, gap: 8, fill: '#16162e', cornerRadius: 10, primaryAxisSizingMode: 'FILL' })));
631
- cmds.push(appendTo('$' + faqIdx + '.id', text(faqs[i].q, { fontSize: 15, color: '#ffffff', fontName: { family: 'Inter', style: 'Semi Bold' } })));
632
- cmds.push(appendTo('$' + faqIdx + '.id', text(faqs[i].a, { fontSize: 13, color: '#888899', fontName: { family: 'Inter', style: 'Regular' } })));
748
+ var fIdx = cmds.length;
749
+ cmds.push(ap('$' + listIdx + '.id', frame('FAQ ' + (i + 1), { paddingTop: 24, paddingBottom: 24, paddingLeft: 24, paddingRight: 24, gap: 8, fill: '#12122a', cornerRadius: 12, primaryAxisSizingMode: 'FILL' })));
750
+ cmds.push(ap('$' + fIdx + '.id', text(faqs[i].q, { fontSize: 16, color: '#f0f0f8', fontName: { family: 'Inter', style: 'Semi Bold' } })));
751
+ cmds.push(ap('$' + fIdx + '.id', text(faqs[i].a, { fontSize: 14, color: '#a0a0b8' })));
633
752
  }
634
753
 
635
754
  return { commands: cmds, description: 'FAQ section with ' + faqs.length + ' items.' };
636
755
  }
637
756
 
638
757
  // ═══════════════════════════════════════════
639
- // BLUEPRINT ROUTER
758
+ // ROUTER
640
759
  // ═══════════════════════════════════════════
641
760
 
642
761
  export function getBlueprint(toolName, args) {