conductor-figma 3.0.3 → 3.3.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.
@@ -0,0 +1,638 @@
1
+ // ═══════════════════════════════════════════
2
+ // CONDUCTOR v3.1 — Composition Engine
3
+ // ═══════════════════════════════════════════
4
+ // Generates rich, multi-layered Figma designs.
5
+ // Each section produces 30-60+ elements.
6
+
7
+ import { snap, semanticColors, componentDefaults, typeScale, SPACING, RADIUS, SHADOWS } from './intelligence.js'
8
+
9
+ // ─── Sequence runner ───
10
+ async function runSequence(bridge, commands) {
11
+ var results = []
12
+ for (var i = 0; i < commands.length; i++) {
13
+ var cmd = commands[i]
14
+ var data = {}
15
+ var src = cmd.data
16
+ for (var k in src) {
17
+ if (src.hasOwnProperty(k)) {
18
+ var v = src[k]
19
+ if (typeof v === 'string' && v.charAt(0) === '$') {
20
+ var refIdx = parseInt(v.replace('$','').replace('.id',''))
21
+ if (results[refIdx] && results[refIdx].id) v = results[refIdx].id
22
+ }
23
+ data[k] = v
24
+ }
25
+ }
26
+ try {
27
+ var result = await bridge.send(cmd.type, data)
28
+ results.push(result)
29
+ } catch (e) {
30
+ results.push({ id: null, error: e.message })
31
+ }
32
+ }
33
+ return results
34
+ }
35
+
36
+ // ─── Shorthand builders ───
37
+ function F(name, opts) { opts.name = name; opts.direction = opts.direction || 'VERTICAL'; return { type:'create_frame', data:opts } }
38
+ function H(name, opts) { opts.direction = 'HORIZONTAL'; return F(name, opts) }
39
+ function T(text, opts) { opts.text = text; if (!opts.fontName) opts.fontName = { family:'Inter', style: opts._w || 'Regular' }; delete opts._w; return { type:'create_text', data:opts } }
40
+ function R(name, opts) { opts.name = name; return { type:'create_rectangle', data:opts } }
41
+ function $(idx) { return '$' + idx + '.id' }
42
+
43
+ // ═══════════════════════════════════════════
44
+ // NAVIGATION
45
+ // ═══════════════════════════════════════════
46
+ function composeNav(content, colors, brand, W) {
47
+ var c = [], brandName = (content && content.brand) || 'acme'
48
+ var navItems = (content && content.navItems) || ['Features','Pricing','Docs','Blog']
49
+
50
+ // 0: Nav bar
51
+ c.push(H('Navigation', { width:W, height:64, paddingLeft:40, paddingRight:40, paddingTop:0, paddingBottom:0, gap:0, fill:colors.bg, counterAxisAlignItems:'CENTER' }))
52
+ // 1: Logo mark
53
+ c.push(H('Logo Mark', { parentId:$(0), width:28, height:28, fill:brand, cornerRadius:7, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
54
+ // 2: Logo letter
55
+ c.push(T(brandName.charAt(0).toUpperCase(), { parentId:$(1), fontSize:14, _w:'Bold', color:'#ffffff' }))
56
+ // 3: Brand name
57
+ c.push(T(brandName, { parentId:$(0), fontSize:15, _w:'Semi Bold', color:colors.text1 }))
58
+ // 4: Spacer
59
+ c.push(F('_spacer', { parentId:$(0), width:1, height:1, fill:colors.bg, primaryAxisSizingMode:'FILL' }))
60
+ // 5: Nav links
61
+ c.push(H('Nav Links', { parentId:$(0), gap:28, counterAxisAlignItems:'CENTER' }))
62
+ for (var i = 0; i < navItems.length; i++) {
63
+ c.push(T(navItems[i], { parentId:$(5), fontSize:14, _w:'Medium', color:colors.text3 }))
64
+ }
65
+ // CTA button
66
+ var btnIdx = c.length
67
+ c.push(H('Nav CTA', { parentId:$(0), height:36, paddingLeft:16, paddingRight:16, paddingTop:0, paddingBottom:0, fill:brand, cornerRadius:8, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
68
+ c.push(T('Get started', { parentId:$(btnIdx), fontSize:13, _w:'Semi Bold', color:'#ffffff' }))
69
+ // Divider
70
+ c.push(R('Nav Divider', { parentId:$(0), width:W, height:1, fill:colors.border }))
71
+ return c
72
+ }
73
+
74
+ // ═══════════════════════════════════════════
75
+ // HERO
76
+ // ═══════════════════════════════════════════
77
+ function composeHero(content, colors, brand, W) {
78
+ var c = []
79
+ var title = (content && content.title) || 'Ship faster with\nless overhead'
80
+ var subtitle = (content && content.subtitle) || 'The modern platform for teams that move fast.\nEverything you need to build, deploy, and scale.'
81
+ var ctaText = (content && content.cta) || 'Start for free'
82
+
83
+ // 0: Hero section
84
+ c.push(F('Hero Section', { width:W, paddingTop:112, paddingBottom:96, paddingLeft:48, paddingRight:48, gap:28, fill:colors.bg, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
85
+
86
+ // 1: Overline badge
87
+ c.push(H('Badge', { parentId:$(0), paddingLeft:6, paddingRight:14, paddingTop:5, paddingBottom:5, gap:8, fill:colors.surface2, cornerRadius:20, counterAxisAlignItems:'CENTER' }))
88
+ // 2: Badge dot container
89
+ c.push(H('Badge Dot', { parentId:$(1), width:20, height:20, fill:colors.brand, cornerRadius:10, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
90
+ // 3: Dot inner (sparkle)
91
+ c.push(T('✦', { parentId:$(2), fontSize:9, color:'#ffffff' }))
92
+ // 4: Badge text
93
+ c.push(T('Introducing v3 — now with 201 tools', { parentId:$(1), fontSize:12, _w:'Medium', color:colors.text2 }))
94
+
95
+ // 5: Main heading
96
+ c.push(T(title, { parentId:$(0), fontSize:68, _w:'Bold', color:colors.text1, textAlignHorizontal:'CENTER', lineHeight:1.05 }))
97
+
98
+ // 6: Subtitle
99
+ c.push(T(subtitle, { parentId:$(0), fontSize:19, color:colors.text2, textAlignHorizontal:'CENTER', maxWidth:560 }))
100
+
101
+ // 7: Button row
102
+ c.push(H('Buttons', { parentId:$(0), gap:12, paddingTop:8 }))
103
+ // 8: Primary CTA
104
+ c.push(H('Primary CTA', { parentId:$(7), height:52, paddingLeft:28, paddingRight:28, paddingTop:0, paddingBottom:0, fill:brand, cornerRadius:12, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
105
+ // 9: Primary label
106
+ c.push(T(ctaText, { parentId:$(8), fontSize:16, _w:'Semi Bold', color:'#ffffff' }))
107
+ // 10: Secondary CTA
108
+ c.push(H('Secondary CTA', { parentId:$(7), height:52, paddingLeft:28, paddingRight:28, paddingTop:0, paddingBottom:0, fill:colors.surface, cornerRadius:12, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
109
+ // 11: Secondary label
110
+ c.push(T('See how it works →', { parentId:$(10), fontSize:16, _w:'Medium', color:colors.text2 }))
111
+
112
+ // 12: Social proof row
113
+ c.push(H('Social Proof', { parentId:$(0), gap:12, counterAxisAlignItems:'CENTER', paddingTop:12 }))
114
+ // 13: Avatar stack frame
115
+ c.push(H('Avatars', { parentId:$(12), gap:-8 }))
116
+ // 14-18: Five avatar circles
117
+ var avatarColors = [brand, '#10b981', '#f59e0b', '#ef4444', '#6366f1']
118
+ var avatarLetters = ['A','S','M','J','K']
119
+ for (var ai = 0; ai < 5; ai++) {
120
+ var avIdx = c.length
121
+ c.push(H('Avatar', { parentId:$(13), width:28, height:28, fill:avatarColors[ai], cornerRadius:14, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
122
+ c.push(T(avatarLetters[ai], { parentId:$(avIdx), fontSize:11, _w:'Semi Bold', color:'#ffffff' }))
123
+ }
124
+ // Stars
125
+ c.push(T('★★★★★', { parentId:$(12), fontSize:13, color:'#fbbf24' }))
126
+ // Proof text
127
+ c.push(T('Loved by 10,000+ teams', { parentId:$(12), fontSize:13, _w:'Medium', color:colors.text3 }))
128
+
129
+ return c
130
+ }
131
+
132
+ // ═══════════════════════════════════════════
133
+ // STATS BAR
134
+ // ═══════════════════════════════════════════
135
+ function composeStats(content, colors, brand, W) {
136
+ var c = [], contentW = 1120
137
+ var stats = (content && content.stats) || [
138
+ { value:'10,000+', label:'Teams worldwide' },
139
+ { value:'99.9%', label:'Uptime SLA' },
140
+ { value:'< 50ms', label:'Global latency' },
141
+ { value:'4.9/5', label:'Customer rating' },
142
+ ]
143
+
144
+ // 0: Stats bar
145
+ c.push(H('Stats Bar', { width:W, paddingTop:48, paddingBottom:48, paddingLeft:48, paddingRight:48, fill:colors.bg2, primaryAxisAlignItems:'CENTER' }))
146
+ // 1: Inner container
147
+ c.push(H('Stats Inner', { parentId:$(0), width:contentW }))
148
+
149
+ for (var si = 0; si < stats.length; si++) {
150
+ var sw = Math.floor(contentW / stats.length)
151
+ var sti = c.length
152
+ // Stat frame
153
+ c.push(F('Stat: ' + stats[si].label, { parentId:$(1), width:sw, paddingTop:16, paddingBottom:16, gap:4, counterAxisAlignItems:'CENTER' }))
154
+ // Value
155
+ c.push(T(stats[si].value, { parentId:$(sti), fontSize:36, _w:'Bold', color:colors.text1, textAlignHorizontal:'CENTER' }))
156
+ // Label
157
+ c.push(T(stats[si].label, { parentId:$(sti), fontSize:13, _w:'Medium', color:colors.text3, textAlignHorizontal:'CENTER' }))
158
+ // Vertical divider (except last)
159
+ if (si < stats.length - 1) {
160
+ c.push(R('Divider', { parentId:$(1), width:1, height:48, fill:colors.border }))
161
+ }
162
+ }
163
+ return c
164
+ }
165
+
166
+ // ═══════════════════════════════════════════
167
+ // FEATURES
168
+ // ═══════════════════════════════════════════
169
+ function composeFeatures(content, colors, brand, W) {
170
+ var c = [], contentW = 1120
171
+ var heading = (content && content.title) || 'Everything you need'
172
+ var sub = (content && content.subtitle) || 'Powerful features to help your team ship faster\nand with more confidence.'
173
+ var features = (content && content.features) || [
174
+ { icon:'⚡', title:'Instant Deploy', desc:'Push to deploy in seconds. Zero config.\nAutomatic HTTPS, global CDN, and instant rollbacks.' },
175
+ { icon:'📈', title:'Auto Scale', desc:'Scales to millions of requests automatically.\nPay only for what you use. No capacity planning.' },
176
+ { icon:'🔒', title:'Enterprise Security', desc:'SOC 2 Type II compliant. End-to-end encryption.\nSSO, RBAC, and audit logs built in.' },
177
+ ]
178
+
179
+ // 0: Section
180
+ c.push(F('Features Section', { width:W, paddingTop:96, paddingBottom:96, paddingLeft:48, paddingRight:48, gap:56, fill:colors.bg, counterAxisAlignItems:'CENTER' }))
181
+
182
+ // 1: Header group
183
+ c.push(F('Features Header', { parentId:$(0), gap:12, counterAxisAlignItems:'CENTER' }))
184
+ // 2: Overline
185
+ c.push(T('FEATURES', { parentId:$(1), fontSize:11, _w:'Semi Bold', color:brand, letterSpacing:2.5, textAlignHorizontal:'CENTER' }))
186
+ // 3: Heading
187
+ c.push(T(heading, { parentId:$(1), fontSize:44, _w:'Bold', color:colors.text1, textAlignHorizontal:'CENTER' }))
188
+ // 4: Subtitle
189
+ c.push(T(sub, { parentId:$(1), fontSize:18, color:colors.text2, textAlignHorizontal:'CENTER' }))
190
+
191
+ // 5: Card row
192
+ c.push(H('Feature Cards', { parentId:$(0), width:contentW, gap:20 }))
193
+
194
+ for (var fi = 0; fi < features.length; fi++) {
195
+ var f = features[fi]
196
+ var cw = Math.floor((contentW - (features.length - 1) * 20) / features.length)
197
+ var ci = c.length
198
+
199
+ // Card
200
+ c.push(F(f.title, { parentId:$(5), width:cw, paddingTop:32, paddingBottom:32, paddingLeft:28, paddingRight:28, gap:16, fill:colors.surface, cornerRadius:16 }))
201
+
202
+ // Icon circle
203
+ var iconI = c.length
204
+ c.push(H('Icon BG', { parentId:$(ci), width:48, height:48, fill:colors.surface3, cornerRadius:12, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
205
+ c.push(T(f.icon, { parentId:$(iconI), fontSize:22 }))
206
+
207
+ // Title
208
+ c.push(T(f.title, { parentId:$(ci), fontSize:20, _w:'Semi Bold', color:colors.text1 }))
209
+
210
+ // Description
211
+ c.push(T(f.desc, { parentId:$(ci), fontSize:14, color:colors.text2, lineHeight:1.6 }))
212
+
213
+ // Divider inside card
214
+ c.push(R('Card Divider', { parentId:$(ci), width:cw - 56, height:1, fill:colors.border }))
215
+
216
+ // Learn more link
217
+ c.push(T('Learn more →', { parentId:$(ci), fontSize:13, _w:'Medium', color:brand }))
218
+ }
219
+ return c
220
+ }
221
+
222
+ // ═══════════════════════════════════════════
223
+ // TESTIMONIALS
224
+ // ═══════════════════════════════════════════
225
+ function composeTestimonials(content, colors, brand, W) {
226
+ var c = [], contentW = 1120
227
+ var testimonials = (content && content.testimonials) || [
228
+ { quote:'This product transformed how our team works. The speed and reliability are unmatched.', author:'Sarah Chen', role:'CTO, TechCorp', initial:'S' },
229
+ { quote:'Best tool we adopted this year. Our deployment time dropped by 80%.', author:'Marcus Rivera', role:'VP Engineering, ScaleUp', initial:'M' },
230
+ { quote:'Finally something that actually understands what good design looks like.', author:'Aria Kim', role:'Design Lead, Craft', initial:'A' },
231
+ ]
232
+
233
+ // 0: Section
234
+ c.push(F('Testimonials', { width:W, paddingTop:96, paddingBottom:96, paddingLeft:48, paddingRight:48, gap:56, fill:colors.bg2, counterAxisAlignItems:'CENTER' }))
235
+ // 1: Header
236
+ c.push(F('Testimonials Header', { parentId:$(0), gap:12, counterAxisAlignItems:'CENTER' }))
237
+ c.push(T('TESTIMONIALS', { parentId:$(1), fontSize:11, _w:'Semi Bold', color:brand, letterSpacing:2.5 }))
238
+ c.push(T('Trusted by the best teams', { parentId:$(1), fontSize:44, _w:'Bold', color:colors.text1, textAlignHorizontal:'CENTER' }))
239
+
240
+ // Card row
241
+ var rowIdx = c.length
242
+ c.push(H('Testimonial Cards', { parentId:$(0), width:contentW, gap:16 }))
243
+
244
+ for (var ti = 0; ti < testimonials.length; ti++) {
245
+ var t = testimonials[ti]
246
+ var tw = Math.floor((contentW - (testimonials.length - 1) * 16) / testimonials.length)
247
+ var tidx = c.length
248
+
249
+ // Card
250
+ c.push(F('Testimonial', { parentId:$(rowIdx), width:tw, paddingTop:28, paddingBottom:28, paddingLeft:24, paddingRight:24, gap:16, fill:colors.surface, cornerRadius:16 }))
251
+
252
+ // Stars
253
+ c.push(T('★★★★★', { parentId:$(tidx), fontSize:14, color:'#fbbf24' }))
254
+
255
+ // Quote
256
+ c.push(T('"' + t.quote + '"', { parentId:$(tidx), fontSize:15, color:colors.text1, lineHeight:1.6 }))
257
+
258
+ // Divider
259
+ c.push(R('Divider', { parentId:$(tidx), width:tw - 48, height:1, fill:colors.border }))
260
+
261
+ // Author row
262
+ var authIdx = c.length
263
+ c.push(H('Author', { parentId:$(tidx), gap:10, counterAxisAlignItems:'CENTER' }))
264
+
265
+ // Avatar
266
+ var avIdx = c.length
267
+ c.push(H('Avatar', { parentId:$(authIdx), width:36, height:36, fill:brand, cornerRadius:18, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
268
+ c.push(T(t.initial, { parentId:$(avIdx), fontSize:14, _w:'Semi Bold', color:'#ffffff' }))
269
+
270
+ // Author info
271
+ var infoIdx = c.length
272
+ c.push(F('Author Info', { parentId:$(authIdx), gap:2 }))
273
+ c.push(T(t.author, { parentId:$(infoIdx), fontSize:14, _w:'Semi Bold', color:colors.text1 }))
274
+ c.push(T(t.role, { parentId:$(infoIdx), fontSize:12, color:colors.text3 }))
275
+ }
276
+ return c
277
+ }
278
+
279
+ // ═══════════════════════════════════════════
280
+ // PRICING
281
+ // ═══════════════════════════════════════════
282
+ function composePricing(content, colors, brand, W) {
283
+ var c = [], contentW = 1080
284
+ var tiers = (content && content.tiers) || [
285
+ { 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', hl:false },
286
+ { name:'Pro', price:'$29', period:'/mo', desc:'For growing teams that need more.', features:['Unlimited projects','100,000 API calls/day','Priority support','Advanced analytics','Team collaboration','Custom domains','Webhooks'], cta:'Start free trial', hl:true },
287
+ { 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', hl:false },
288
+ ]
289
+
290
+ // 0: Section
291
+ c.push(F('Pricing Section', { width:W, paddingTop:96, paddingBottom:96, paddingLeft:48, paddingRight:48, gap:56, fill:colors.bg, counterAxisAlignItems:'CENTER' }))
292
+ // Header
293
+ c.push(F('Pricing Header', { parentId:$(0), gap:12, counterAxisAlignItems:'CENTER' }))
294
+ c.push(T('PRICING', { parentId:$(1), fontSize:11, _w:'Semi Bold', color:brand, letterSpacing:2.5 }))
295
+ c.push(T('Simple, transparent pricing', { parentId:$(1), fontSize:44, _w:'Bold', color:colors.text1, textAlignHorizontal:'CENTER' }))
296
+ c.push(T('No hidden fees. Start free, scale as you grow.', { parentId:$(1), fontSize:18, color:colors.text2, textAlignHorizontal:'CENTER' }))
297
+
298
+ // Tier row
299
+ var rowIdx = c.length
300
+ c.push(H('Tiers', { parentId:$(0), width:contentW, gap:16, counterAxisAlignItems:'STRETCH' }))
301
+
302
+ for (var ti = 0; ti < tiers.length; ti++) {
303
+ var t = tiers[ti]
304
+ var tw = Math.floor((contentW - (tiers.length - 1) * 16) / tiers.length)
305
+ var isHl = t.hl
306
+ var tidx = c.length
307
+
308
+ // Card
309
+ c.push(F(t.name, { parentId:$(rowIdx), width:tw, paddingTop:32, paddingBottom:32, paddingLeft:28, paddingRight:28, gap:16, fill:isHl ? colors.surface2 : colors.surface, cornerRadius:16 }))
310
+
311
+ // Popular badge
312
+ if (isHl) {
313
+ var bidx = c.length
314
+ c.push(H('Popular', { parentId:$(tidx), paddingLeft:10, paddingRight:10, paddingTop:4, paddingBottom:4, fill:brand, cornerRadius:6, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
315
+ c.push(T('MOST POPULAR', { parentId:$(bidx), fontSize:9, _w:'Bold', color:'#ffffff' }))
316
+ }
317
+
318
+ // Name
319
+ c.push(T(t.name, { parentId:$(tidx), fontSize:22, _w:'Semi Bold', color:colors.text1 }))
320
+
321
+ // Price row
322
+ var pidx = c.length
323
+ c.push(H('Price', { parentId:$(tidx), gap:4, counterAxisAlignItems:'BASELINE' }))
324
+ c.push(T(t.price, { parentId:$(pidx), fontSize:44, _w:'Bold', color:colors.text1 }))
325
+ if (t.period) {
326
+ c.push(T(t.period, { parentId:$(pidx), fontSize:16, color:colors.text3 }))
327
+ }
328
+
329
+ // Description
330
+ c.push(T(t.desc, { parentId:$(tidx), fontSize:14, color:colors.text2 }))
331
+
332
+ // Divider
333
+ c.push(R('Divider', { parentId:$(tidx), width:tw - 56, height:1, fill:colors.border }))
334
+
335
+ // Features list
336
+ var flidx = c.length
337
+ c.push(F('Features', { parentId:$(tidx), gap:10 }))
338
+ for (var fi = 0; fi < t.features.length; fi++) {
339
+ var flrow = c.length
340
+ c.push(H('Feature', { parentId:$(flidx), gap:8, counterAxisAlignItems:'CENTER' }))
341
+ // Checkmark circle
342
+ var chkIdx = c.length
343
+ c.push(H('Check', { parentId:$(flrow), width:18, height:18, fill:isHl ? brand : colors.surface3, cornerRadius:9, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
344
+ c.push(T('✓', { parentId:$(chkIdx), fontSize:10, _w:'Bold', color:isHl ? '#ffffff' : colors.text2 }))
345
+ c.push(T(t.features[fi], { parentId:$(flrow), fontSize:13, color:colors.text2 }))
346
+ }
347
+
348
+ // Spacer to push button to bottom
349
+ c.push(F('_grow', { parentId:$(tidx), width:1, height:1, primaryAxisSizingMode:'FILL' }))
350
+
351
+ // CTA button
352
+ var btIdx = c.length
353
+ c.push(H(t.cta, { parentId:$(tidx), height:48, paddingLeft:24, paddingRight:24, paddingTop:0, paddingBottom:0, fill:isHl ? brand : 'transparent', cornerRadius:10, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER', primaryAxisSizingMode:'FILL' }))
354
+ c.push(T(t.cta, { parentId:$(btIdx), fontSize:15, _w:'Semi Bold', color:isHl ? '#ffffff' : brand }))
355
+ }
356
+ return c
357
+ }
358
+
359
+ // ═══════════════════════════════════════════
360
+ // CTA SECTION
361
+ // ═══════════════════════════════════════════
362
+ function composeCTA(content, colors, brand, W) {
363
+ var c = [], contentW = 1120
364
+ var title = (content && content.ctaTitle) || 'Ready to get started?'
365
+ var sub = (content && content.ctaSub) || 'Join thousands of teams already shipping faster.\nNo credit card required.'
366
+ var btnText = (content && content.cta) || 'Start for free'
367
+
368
+ // 0: Section bg
369
+ c.push(F('CTA Section', { width:W, paddingTop:96, paddingBottom:96, paddingLeft:48, paddingRight:48, fill:colors.bg2, counterAxisAlignItems:'CENTER' }))
370
+ // 1: CTA Card
371
+ c.push(F('CTA Card', { parentId:$(0), width:contentW, paddingTop:72, paddingBottom:72, paddingLeft:48, paddingRight:48, gap:24, fill:colors.surface, cornerRadius:24, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
372
+ // 2: Heading
373
+ c.push(T(title, { parentId:$(1), fontSize:44, _w:'Bold', color:colors.text1, textAlignHorizontal:'CENTER' }))
374
+ // 3: Subtitle
375
+ c.push(T(sub, { parentId:$(1), fontSize:18, color:colors.text2, textAlignHorizontal:'CENTER' }))
376
+ // 4: Button row
377
+ c.push(H('CTA Buttons', { parentId:$(1), gap:12, paddingTop:8 }))
378
+ // 5: Primary
379
+ c.push(H('CTA Primary', { parentId:$(4), height:56, paddingLeft:32, paddingRight:32, paddingTop:0, paddingBottom:0, fill:brand, cornerRadius:12, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
380
+ c.push(T(btnText, { parentId:$(5), fontSize:17, _w:'Semi Bold', color:'#ffffff' }))
381
+ // 7: Secondary
382
+ c.push(H('CTA Secondary', { parentId:$(4), height:56, paddingLeft:32, paddingRight:32, paddingTop:0, paddingBottom:0, fill:colors.surface2, cornerRadius:12, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
383
+ c.push(T('Talk to sales →', { parentId:$(7), fontSize:17, _w:'Medium', color:colors.text2 }))
384
+
385
+ return c
386
+ }
387
+
388
+ // ═══════════════════════════════════════════
389
+ // FOOTER
390
+ // ═══════════════════════════════════════════
391
+ function composeFooter(content, colors, brand, W) {
392
+ var c = [], brandName = (content && content.brand) || 'acme'
393
+ var cols = [
394
+ { title:'Product', links:['Features','Pricing','Docs','Changelog'] },
395
+ { title:'Company', links:['About','Blog','Careers','Press'] },
396
+ { title:'Legal', links:['Terms','Privacy','License'] },
397
+ ]
398
+
399
+ // 0: Footer top divider
400
+ c.push(R('Footer Divider', { width:W, height:1, fill:colors.border }))
401
+ // 1: Footer frame
402
+ c.push(F('Footer', { width:W, paddingTop:56, paddingBottom:40, paddingLeft:48, paddingRight:48, gap:40, fill:colors.bg }))
403
+
404
+ // 2: Footer columns row
405
+ c.push(H('Footer Columns', { parentId:$(1), gap:0 }))
406
+
407
+ // 3: Brand column (wider)
408
+ c.push(F('Brand Column', { parentId:$(2), width:360, gap:12 }))
409
+ // 4: Brand row
410
+ c.push(H('Brand', { parentId:$(3), gap:8, counterAxisAlignItems:'CENTER' }))
411
+ // Logo mark
412
+ var lmIdx = c.length
413
+ c.push(H('Logo', { parentId:$(4), width:22, height:22, fill:brand, cornerRadius:5, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
414
+ c.push(T(brandName.charAt(0).toUpperCase(), { parentId:$(lmIdx), fontSize:11, _w:'Bold', color:'#ffffff' }))
415
+ c.push(T(brandName, { parentId:$(4), fontSize:14, _w:'Semi Bold', color:colors.text1 }))
416
+ // Description
417
+ c.push(T('Design-intelligent tools for modern teams.\nBuilt with care, shipped with confidence.', { parentId:$(3), fontSize:13, color:colors.text3, lineHeight:1.6 }))
418
+
419
+ // Link columns
420
+ for (var ci2 = 0; ci2 < cols.length; ci2++) {
421
+ var col = cols[ci2]
422
+ var colIdx = c.length
423
+ c.push(F(col.title, { parentId:$(2), width:160, gap:10 }))
424
+ c.push(T(col.title, { parentId:$(colIdx), fontSize:12, _w:'Semi Bold', color:colors.text1 }))
425
+ // Spacer
426
+ c.push(F('_gap', { parentId:$(colIdx), width:1, height:4 }))
427
+ for (var li = 0; li < col.links.length; li++) {
428
+ c.push(T(col.links[li], { parentId:$(colIdx), fontSize:13, color:colors.text3 }))
429
+ }
430
+ }
431
+
432
+ // Bottom bar
433
+ c.push(R('Bottom Divider', { parentId:$(1), width:W - 96, height:1, fill:colors.border }))
434
+ var botIdx = c.length
435
+ c.push(H('Bottom', { parentId:$(1), counterAxisAlignItems:'CENTER' }))
436
+ c.push(T('© 2025 ' + brandName + '. All rights reserved.', { parentId:$(botIdx), fontSize:12, color:colors.text3 }))
437
+
438
+ return c
439
+ }
440
+
441
+ // ═══════════════════════════════════════════
442
+ // DASHBOARD
443
+ // ═══════════════════════════════════════════
444
+ function composeDashboard(content, colors, brand, W) {
445
+ var c = [], sideW = 260
446
+ var metrics = (content && content.metrics) || [
447
+ { label:'Total Revenue', value:'$48,290', change:'+12.5%', up:true },
448
+ { label:'Active Users', value:'2,420', change:'+8.3%', up:true },
449
+ { label:'Conversion', value:'3.24%', change:'-0.8%', up:false },
450
+ { label:'Avg. Session', value:'4m 32s', change:'+15.2%', up:true },
451
+ ]
452
+ var navItems = ['Overview','Analytics','Customers','Products','Settings']
453
+
454
+ // 0: Dashboard root
455
+ c.push(H('Dashboard', { width:W, height:900, fill:colors.bg, gap:0 }))
456
+
457
+ // 1: Sidebar
458
+ c.push(F('Sidebar', { parentId:$(0), width:sideW, height:900, paddingTop:20, paddingBottom:20, paddingLeft:16, paddingRight:16, gap:4, fill:colors.surface }))
459
+
460
+ // 2: Sidebar logo row
461
+ c.push(H('Sidebar Brand', { parentId:$(1), gap:8, counterAxisAlignItems:'CENTER', paddingLeft:8, paddingBottom:16 }))
462
+ var slmIdx = c.length
463
+ c.push(H('Logo', { parentId:$(2), width:24, height:24, fill:brand, cornerRadius:6, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
464
+ c.push(T('C', { parentId:$(slmIdx), fontSize:12, _w:'Bold', color:'#ffffff' }))
465
+ c.push(T('Conductor', { parentId:$(2), fontSize:14, _w:'Semi Bold', color:colors.text1 }))
466
+
467
+ // Nav items
468
+ for (var ni = 0; ni < navItems.length; ni++) {
469
+ var isActive = ni === 0
470
+ var niIdx = c.length
471
+ c.push(H(navItems[ni], { parentId:$(1), height:36, paddingLeft:10, paddingRight:10, paddingTop:0, paddingBottom:0, gap:8, cornerRadius:8, fill:isActive ? colors.surface3 : 'transparent', counterAxisAlignItems:'CENTER', primaryAxisSizingMode:'FILL' }))
472
+ // Dot for active
473
+ if (isActive) {
474
+ c.push(H('Active Dot', { parentId:$(niIdx), width:6, height:6, fill:brand, cornerRadius:3 }))
475
+ }
476
+ c.push(T(navItems[ni], { parentId:$(niIdx), fontSize:13, _w:isActive ? 'Medium' : 'Regular', color:isActive ? colors.text1 : colors.text3 }))
477
+ }
478
+
479
+ // Sidebar divider
480
+ c.push(R('Sidebar Divider', { parentId:$(0), width:1, height:900, fill:colors.border }))
481
+
482
+ // Main area
483
+ var mainIdx = c.length
484
+ c.push(F('Main', { parentId:$(0), height:900, paddingTop:28, paddingBottom:28, paddingLeft:32, paddingRight:32, gap:24, fill:colors.bg, primaryAxisSizingMode:'FILL' }))
485
+
486
+ // Header row
487
+ var hdrIdx = c.length
488
+ c.push(H('Header', { parentId:$(mainIdx), counterAxisAlignItems:'CENTER' }))
489
+ c.push(T('Overview', { parentId:$(hdrIdx), fontSize:24, _w:'Bold', color:colors.text1 }))
490
+ c.push(F('_spacer', { parentId:$(hdrIdx), width:1, height:1, primaryAxisSizingMode:'FILL' }))
491
+ var dlBtnIdx = c.length
492
+ c.push(H('Download', { parentId:$(hdrIdx), height:36, paddingLeft:14, paddingRight:14, paddingTop:0, paddingBottom:0, fill:colors.surface, cornerRadius:8, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
493
+ c.push(T('Export ↓', { parentId:$(dlBtnIdx), fontSize:12, _w:'Medium', color:colors.text2 }))
494
+
495
+ // Metrics row
496
+ var mRowIdx = c.length
497
+ c.push(H('Metrics', { parentId:$(mainIdx), gap:16 }))
498
+
499
+ for (var mi = 0; mi < metrics.length; mi++) {
500
+ var m = metrics[mi]
501
+ var mIdx = c.length
502
+ c.push(F(m.label, { parentId:$(mRowIdx), paddingTop:20, paddingBottom:20, paddingLeft:20, paddingRight:20, gap:8, fill:colors.surface, cornerRadius:12, primaryAxisSizingMode:'FILL' }))
503
+ c.push(T(m.label, { parentId:$(mIdx), fontSize:12, _w:'Medium', color:colors.text3 }))
504
+ c.push(T(m.value, { parentId:$(mIdx), fontSize:28, _w:'Bold', color:colors.text1 }))
505
+ // Change badge
506
+ var chgIdx = c.length
507
+ c.push(H('Change', { parentId:$(mIdx), paddingLeft:6, paddingRight:6, paddingTop:2, paddingBottom:2, fill:m.up ? 'rgba(74,222,128,0.1)' : 'rgba(248,113,113,0.1)', cornerRadius:4 }))
508
+ c.push(T(m.change, { parentId:$(chgIdx), fontSize:11, _w:'Semi Bold', color:m.up ? '#4ade80' : '#f87171' }))
509
+ }
510
+
511
+ // Chart area
512
+ var chartIdx = c.length
513
+ c.push(F('Chart Area', { parentId:$(mainIdx), paddingTop:24, paddingBottom:24, paddingLeft:24, paddingRight:24, gap:16, fill:colors.surface, cornerRadius:12, primaryAxisSizingMode:'FILL' }))
514
+ var chartHdrIdx = c.length
515
+ c.push(H('Chart Header', { parentId:$(chartIdx), counterAxisAlignItems:'CENTER' }))
516
+ c.push(T('Revenue Over Time', { parentId:$(chartHdrIdx), fontSize:16, _w:'Semi Bold', color:colors.text1 }))
517
+ c.push(F('_spacer', { parentId:$(chartHdrIdx), width:1, height:1, primaryAxisSizingMode:'FILL' }))
518
+ // Period pills
519
+ var pillsIdx = c.length
520
+ c.push(H('Period', { parentId:$(chartHdrIdx), gap:4 }))
521
+ var periods = ['7D','30D','90D','1Y']
522
+ for (var pi = 0; pi < periods.length; pi++) {
523
+ var pillIdx = c.length
524
+ c.push(H(periods[pi], { parentId:$(pillsIdx), height:28, paddingLeft:10, paddingRight:10, paddingTop:0, paddingBottom:0, fill:pi === 1 ? colors.surface3 : 'transparent', cornerRadius:6, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
525
+ c.push(T(periods[pi], { parentId:$(pillIdx), fontSize:11, _w:pi === 1 ? 'Medium' : 'Regular', color:pi === 1 ? colors.text1 : colors.text3 }))
526
+ }
527
+ // Chart placeholder
528
+ c.push(R('Chart', { parentId:$(chartIdx), width:800, height:220, fill:colors.surface2, cornerRadius:8 }))
529
+
530
+ return c
531
+ }
532
+
533
+ // ═══════════════════════════════════════════
534
+ // SMART COMPONENTS
535
+ // ═══════════════════════════════════════════
536
+ function composeSmartComponent(type, variant, label, brandColor, mode) {
537
+ var colors = semanticColors(brandColor || '#6366f1', mode || 'dark')
538
+ var brand = brandColor || colors.brand
539
+ var defs = componentDefaults(type, variant)
540
+ if (!defs) return null
541
+ var c = []
542
+
543
+ switch (type) {
544
+ case 'button': {
545
+ c.push(H((label || 'Button') + ' — ' + (variant || 'default'), { height:defs.h, paddingLeft:defs.px, paddingRight:defs.px, paddingTop:0, paddingBottom:0, fill:brand, cornerRadius:defs.radius, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER', gap:8 }))
546
+ c.push(T(label || 'Get started', { parentId:$(0), fontSize:defs.fontSize, _w:defs.fontWeight, color:'#ffffff' }))
547
+ break
548
+ }
549
+ case 'input': {
550
+ c.push(F('Input — ' + (variant || 'default'), { gap:6 }))
551
+ c.push(T(label || 'Email address', { parentId:$(0), fontSize:13, _w:'Medium', color:colors.text2 }))
552
+ c.push(H('Input Field', { parentId:$(0), height:defs.h, paddingLeft:defs.px, paddingRight:defs.px, paddingTop:0, paddingBottom:0, fill:colors.surface, cornerRadius:defs.radius, counterAxisAlignItems:'CENTER' }))
553
+ c.push(T('you@example.com', { parentId:$(2), fontSize:defs.fontSize, color:colors.text3 }))
554
+ break
555
+ }
556
+ case 'card': {
557
+ c.push(F(label || 'Card', { paddingTop:defs.py, paddingBottom:defs.py, paddingLeft:defs.px, paddingRight:defs.px, gap:defs.gap, fill:colors.surface, cornerRadius:defs.radius }))
558
+ var icIdx = c.length
559
+ c.push(H('Icon', { parentId:$(0), width:48, height:48, fill:colors.surface3, cornerRadius:12, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
560
+ c.push(T('⚡', { parentId:$(icIdx), fontSize:22 }))
561
+ c.push(T(label || 'Feature title', { parentId:$(0), fontSize:18, _w:'Semi Bold', color:colors.text1 }))
562
+ c.push(T('A short description of this feature and why it matters to your users.', { parentId:$(0), fontSize:14, color:colors.text2, lineHeight:1.6 }))
563
+ c.push(R('Divider', { parentId:$(0), width:200, height:1, fill:colors.border }))
564
+ c.push(T('Learn more →', { parentId:$(0), fontSize:13, _w:'Medium', color:brand }))
565
+ break
566
+ }
567
+ case 'modal': {
568
+ c.push(F('Modal Overlay', { width:1440, height:900, fill:'#00000080', primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
569
+ c.push(F('Modal', { parentId:$(0), width:defs.maxW, paddingTop:defs.py, paddingBottom:defs.py, paddingLeft:defs.px, paddingRight:defs.px, gap:defs.gap, fill:colors.surface, cornerRadius:defs.radius }))
570
+ c.push(T(label || 'Confirm action', { parentId:$(1), fontSize:18, _w:'Semi Bold', color:colors.text1 }))
571
+ c.push(T('Are you sure you want to proceed? This action cannot be undone.', { parentId:$(1), fontSize:15, color:colors.text2 }))
572
+ c.push(R('Divider', { parentId:$(1), width:defs.maxW - defs.px * 2, height:1, fill:colors.border }))
573
+ c.push(H('Actions', { parentId:$(1), gap:8, primaryAxisAlignItems:'MAX' }))
574
+ c.push(H('Cancel', { parentId:$(5), height:40, paddingLeft:16, paddingRight:16, paddingTop:0, paddingBottom:0, fill:colors.surface2, cornerRadius:8, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
575
+ c.push(T('Cancel', { parentId:$(6), fontSize:14, _w:'Medium', color:colors.text2 }))
576
+ c.push(H('Confirm', { parentId:$(5), height:40, paddingLeft:16, paddingRight:16, paddingTop:0, paddingBottom:0, fill:brand, cornerRadius:8, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
577
+ c.push(T('Confirm', { parentId:$(8), fontSize:14, _w:'Semi Bold', color:'#ffffff' }))
578
+ break
579
+ }
580
+ case 'avatar': {
581
+ c.push(H('Avatar', { width:defs.size, height:defs.size, fill:brand, cornerRadius:defs.radius, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
582
+ c.push(T((label || 'A').charAt(0).toUpperCase(), { parentId:$(0), fontSize:defs.fontSize, _w:defs.fontWeight, color:'#ffffff' }))
583
+ break
584
+ }
585
+ case 'badge': {
586
+ c.push(H('Badge', { height:defs.h, paddingLeft:defs.px, paddingRight:defs.px, paddingTop:0, paddingBottom:0, fill:colors.surface2, cornerRadius:defs.radius, primaryAxisAlignItems:'CENTER', counterAxisAlignItems:'CENTER' }))
587
+ c.push(T(label || 'New', { parentId:$(0), fontSize:defs.fontSize, _w:defs.fontWeight, color:brand }))
588
+ break
589
+ }
590
+ default: {
591
+ c.push(F(type, { paddingTop:16, paddingBottom:16, paddingLeft:16, paddingRight:16, gap:8, fill:colors.surface, cornerRadius:8 }))
592
+ c.push(T(label || type, { parentId:$(0), fontSize:14, color:colors.text1 }))
593
+ }
594
+ }
595
+ return c
596
+ }
597
+
598
+ // ═══════════════════════════════════════════
599
+ // SECTION ROUTER
600
+ // ═══════════════════════════════════════════
601
+ function composeSection(type, content, brandColor, mode, width) {
602
+ var W = width || 1440
603
+ var colors = semanticColors(brandColor || '#6366f1', mode || 'dark')
604
+ var brand = brandColor || '#6366f1'
605
+
606
+ switch (type) {
607
+ case 'nav': return composeNav(content, colors, brand, W)
608
+ case 'hero': return composeHero(content, colors, brand, W)
609
+ case 'stats': return composeStats(content, colors, brand, W)
610
+ case 'features': return composeFeatures(content, colors, brand, W)
611
+ case 'testimonials': return composeTestimonials(content, colors, brand, W)
612
+ case 'pricing': return composePricing(content, colors, brand, W)
613
+ case 'cta': return composeCTA(content, colors, brand, W)
614
+ case 'footer': return composeFooter(content, colors, brand, W)
615
+ case 'dashboard': return composeDashboard(content, colors, brand, W)
616
+ default:
617
+ var c = []
618
+ c.push(F(type + ' Section', { width:W, paddingTop:96, paddingBottom:96, paddingLeft:48, paddingRight:48, gap:32, fill:colors.bg, counterAxisAlignItems:'CENTER' }))
619
+ c.push(T((content && content.title) || type, { parentId:$(0), fontSize:40, _w:'Bold', color:colors.text1, textAlignHorizontal:'CENTER' }))
620
+ return c
621
+ }
622
+ }
623
+
624
+ // ═══════════════════════════════════════════
625
+ // PAGE COMPOSER
626
+ // ═══════════════════════════════════════════
627
+ function composePage(type, content, brandColor, mode, width) {
628
+ var sections = []
629
+ switch (type) {
630
+ case 'landing': sections = ['nav','hero','stats','features','testimonials','cta','footer']; break
631
+ case 'pricing': sections = ['nav','pricing','cta','footer']; break
632
+ case 'dashboard': sections = ['dashboard']; break
633
+ default: sections = ['nav','hero','features','cta','footer']
634
+ }
635
+ return { sections:sections, content:content, brand:brandColor || '#6366f1', mode:mode || 'dark', width:width || 1440 }
636
+ }
637
+
638
+ export { runSequence, composeSmartComponent, composeSection, composePage }