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.
- package/package.json +1 -1
- 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.
|
|
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
|
-
//
|
|
5
|
-
//
|
|
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
|
|
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
|
|
30
|
+
// LANDING PAGE — Premium quality
|
|
56
31
|
// ═══════════════════════════════════════════
|
|
57
32
|
|
|
58
33
|
export function buildLandingPage(args) {
|
|
59
|
-
var
|
|
60
|
-
var
|
|
61
|
-
var
|
|
34
|
+
var brand = args.brandColor || '#6366f1';
|
|
35
|
+
var W = args.width || 1440;
|
|
36
|
+
var contentW = 1120;
|
|
62
37
|
var dark = args.darkMode !== false;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
var
|
|
66
|
-
var
|
|
67
|
-
var
|
|
68
|
-
var
|
|
69
|
-
var
|
|
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
|
|
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
|
|
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
|
|
85
|
-
cmds.push(frame('Landing Page', { width:
|
|
68
|
+
// ── 0: Page Root ──
|
|
69
|
+
cmds.push(frame('Landing Page', { width: W, fill: bg, gap: 0, primaryAxisSizingMode: 'HUG' }));
|
|
86
70
|
|
|
87
|
-
// 1:
|
|
88
|
-
cmds.
|
|
89
|
-
|
|
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
|
-
//
|
|
94
|
-
cmds.push(
|
|
95
|
-
fontSize:
|
|
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
|
-
//
|
|
99
|
-
cmds.
|
|
100
|
-
|
|
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(
|
|
107
|
-
fontSize: 14, color:
|
|
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
|
|
101
|
+
// Nav CTA
|
|
112
102
|
var navBtnIdx = cmds.length;
|
|
113
|
-
cmds.push(
|
|
114
|
-
|
|
115
|
-
fill:
|
|
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(
|
|
119
|
-
fontSize:
|
|
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
|
-
//
|
|
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(
|
|
125
|
-
width:
|
|
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
|
-
//
|
|
130
|
-
|
|
131
|
-
|
|
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(
|
|
136
|
-
fontSize:
|
|
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(
|
|
142
|
-
fontSize:
|
|
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(
|
|
149
|
-
|
|
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
|
|
155
|
-
cmds.push(
|
|
156
|
-
|
|
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(
|
|
160
|
-
fontSize:
|
|
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
|
|
165
|
-
cmds.push(
|
|
166
|
-
|
|
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(
|
|
170
|
-
fontSize:
|
|
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
|
-
//
|
|
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(
|
|
176
|
-
width:
|
|
177
|
-
|
|
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
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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(
|
|
187
|
-
fontSize:
|
|
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(
|
|
190
|
-
fontSize:
|
|
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
|
|
195
|
-
var
|
|
196
|
-
cmds.push(
|
|
197
|
-
width:
|
|
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
|
-
|
|
202
|
-
|
|
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
|
-
|
|
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(
|
|
214
|
-
width:
|
|
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
|
-
|
|
220
|
-
|
|
221
|
-
|
|
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(
|
|
224
|
-
|
|
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
|
-
|
|
227
|
-
|
|
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
|
|
278
|
+
// ── CTA Section ──
|
|
232
279
|
var ctaSectionIdx = cmds.length;
|
|
233
|
-
cmds.push(
|
|
234
|
-
width:
|
|
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(
|
|
239
|
-
fontSize:
|
|
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(
|
|
244
|
-
fontSize:
|
|
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
|
|
249
|
-
cmds.push(
|
|
250
|
-
|
|
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(
|
|
254
|
-
fontSize:
|
|
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(
|
|
260
|
-
width:
|
|
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
|
-
|
|
265
|
-
|
|
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
|
|
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
|
|
280
|
-
var
|
|
281
|
-
var
|
|
282
|
-
var
|
|
283
|
-
var
|
|
284
|
-
var cardBg = '#
|
|
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
|
|
287
|
-
{ name: 'Pro', price: '$29', period: '/mo', desc: 'For growing teams that need more', features: ['Unlimited projects', '
|
|
288
|
-
{ name: 'Enterprise', price: 'Custom', period: '', desc: 'For
|
|
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:
|
|
294
|
-
cmds.push(frame('Pricing Page', { width:
|
|
382
|
+
// 0: Root
|
|
383
|
+
cmds.push(frame('Pricing Page', { width: W, fill: bg, primaryAxisSizingMode: 'HUG' }));
|
|
295
384
|
|
|
296
|
-
//
|
|
385
|
+
// Header
|
|
297
386
|
var headerIdx = cmds.length;
|
|
298
|
-
cmds.push(
|
|
299
|
-
width:
|
|
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(
|
|
304
|
-
fontSize:
|
|
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(
|
|
309
|
-
fontSize: 18, color:
|
|
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
|
|
403
|
+
// Tier row
|
|
314
404
|
var tierRowIdx = cmds.length;
|
|
315
|
-
cmds.push(
|
|
316
|
-
width:
|
|
317
|
-
|
|
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
|
|
323
|
-
var
|
|
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(
|
|
327
|
-
width: cardW,
|
|
328
|
-
|
|
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
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
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(
|
|
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
|
-
|
|
343
|
-
|
|
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
|
|
348
|
-
cmds.push(
|
|
349
|
-
gap:
|
|
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(
|
|
353
|
-
fontSize:
|
|
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(
|
|
357
|
-
fontSize: 16, color:
|
|
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
|
-
|
|
362
|
-
|
|
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(
|
|
367
|
-
width: cardW - 64, height: 1, fill:
|
|
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(
|
|
373
|
-
fontSize:
|
|
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
|
|
379
|
-
cmds.push(
|
|
380
|
-
height:
|
|
381
|
-
fill:
|
|
382
|
-
cornerRadius:
|
|
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(
|
|
387
|
-
fontSize:
|
|
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
|
|
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
|
|
500
|
+
// DASHBOARD
|
|
400
501
|
// ═══════════════════════════════════════════
|
|
401
502
|
|
|
402
503
|
export function buildDashboardPage(args) {
|
|
403
|
-
var
|
|
404
|
-
var
|
|
405
|
-
var
|
|
406
|
-
var
|
|
407
|
-
var
|
|
408
|
-
var
|
|
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
|
-
|
|
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
|
-
//
|
|
422
|
-
var
|
|
423
|
-
cmds.push(
|
|
424
|
-
width:
|
|
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
|
-
|
|
428
|
-
|
|
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
|
-
|
|
433
|
-
|
|
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
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
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(
|
|
445
|
-
fontSize:
|
|
446
|
-
fontName: { family: 'Inter', style:
|
|
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
|
-
//
|
|
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(
|
|
453
|
-
width:
|
|
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
|
|
457
|
-
|
|
458
|
-
|
|
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
|
-
//
|
|
578
|
+
// Metrics row
|
|
467
579
|
var metricsRowIdx = cmds.length;
|
|
468
|
-
cmds.push(
|
|
469
|
-
gap:
|
|
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
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
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(
|
|
479
|
-
fontSize:
|
|
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(
|
|
482
|
-
fontSize:
|
|
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(
|
|
485
|
-
fontSize:
|
|
486
|
-
fontName: { family: 'Inter', style: '
|
|
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
|
|
603
|
+
// Chart
|
|
491
604
|
var chartIdx = cmds.length;
|
|
492
|
-
cmds.push(
|
|
493
|
-
|
|
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
|
-
|
|
497
|
-
|
|
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
|
-
|
|
500
|
-
|
|
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
|
|
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
|
|
527
|
-
var
|
|
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:
|
|
531
|
-
cmds.push(
|
|
532
|
-
cmds.push(
|
|
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(
|
|
536
|
-
cmds.push(
|
|
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
|
|
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:
|
|
551
|
-
cmds.push(
|
|
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(
|
|
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((
|
|
678
|
+
var cw = Math.floor((1120 - (features.length - 1) * 24) / features.length);
|
|
558
679
|
var ci = cmds.length;
|
|
559
|
-
cmds.push(
|
|
560
|
-
cmds.push(
|
|
561
|
-
cmds.push(
|
|
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
|
|
573
|
-
var
|
|
691
|
+
var W = args.width || 1440;
|
|
692
|
+
var brand = args.brandColor || '#6366f1';
|
|
574
693
|
var cmds = [];
|
|
575
694
|
|
|
576
|
-
cmds.push(frame('CTA
|
|
577
|
-
cmds.push(
|
|
578
|
-
cmds.push(
|
|
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(
|
|
582
|
-
cmds.push(
|
|
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
|
|
706
|
+
var W = args.width || 1440;
|
|
589
707
|
var testimonials = args.testimonials || [
|
|
590
|
-
{ quote: 'This product transformed how our team works.
|
|
591
|
-
{ quote: '
|
|
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:
|
|
596
|
-
cmds.push(
|
|
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(
|
|
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((
|
|
720
|
+
var tw = Math.floor((1120 - (testimonials.length - 1) * 24) / testimonials.length);
|
|
603
721
|
var ti = cmds.length;
|
|
604
|
-
cmds.push(
|
|
605
|
-
cmds.push(
|
|
606
|
-
cmds.push(
|
|
607
|
-
cmds.push(
|
|
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
|
|
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.
|
|
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:
|
|
623
|
-
cmds.push(
|
|
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(
|
|
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
|
|
630
|
-
cmds.push(
|
|
631
|
-
cmds.push(
|
|
632
|
-
cmds.push(
|
|
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
|
-
//
|
|
758
|
+
// ROUTER
|
|
640
759
|
// ═══════════════════════════════════════════
|
|
641
760
|
|
|
642
761
|
export function getBlueprint(toolName, args) {
|