sketchmark 2.1.0 → 2.1.2
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 -7
- package/ANIMATABLE_MATRIX.md +0 -177
- package/KERNEL_SPEC.md +0 -412
- package/PACKS.md +0 -81
- package/PRESETS.md +0 -182
- package/dist/src/builders/index.d.ts +0 -64
- package/dist/src/builders/index.js +0 -212
- package/dist/src/compounds.d.ts +0 -13
- package/dist/src/compounds.js +0 -118
- package/dist/src/deck.d.ts +0 -4
- package/dist/src/deck.js +0 -91
- package/dist/src/export/index.d.ts +0 -8
- package/dist/src/export/index.js +0 -15
- package/dist/src/kernel.d.ts +0 -8
- package/dist/src/kernel.js +0 -68
- package/dist/src/motion.d.ts +0 -4
- package/dist/src/motion.js +0 -262
- package/dist/src/patch.d.ts +0 -5
- package/dist/src/patch.js +0 -72
- package/dist/src/player/index.d.ts +0 -68
- package/dist/src/player/index.js +0 -600
- package/dist/src/project.d.ts +0 -11
- package/dist/src/project.js +0 -107
- package/dist/src/render/raw-three.d.ts +0 -7
- package/dist/src/render/raw-three.js +0 -17
- package/dist/src/render/three-html.d.ts +0 -2
- package/dist/src/render/three-html.js +0 -257
- package/dist/src/render/three-preview-svg.d.ts +0 -3
- package/dist/src/render/three-preview-svg.js +0 -102
- package/dist/src/scenes.d.ts +0 -4
- package/dist/src/scenes.js +0 -26
- package/dist/src/sequences.d.ts +0 -43
- package/dist/src/sequences.js +0 -109
- package/dist/src/shapes/builtins.d.ts +0 -2
- package/dist/src/shapes/builtins.js +0 -393
- package/dist/src/shapes/common.d.ts +0 -9
- package/dist/src/shapes/common.js +0 -76
- package/dist/src/shapes/geometry.d.ts +0 -22
- package/dist/src/shapes/geometry.js +0 -166
- package/dist/src/shapes/index.d.ts +0 -2
- package/dist/src/shapes/index.js +0 -18
- package/dist/src/shapes/registry.d.ts +0 -8
- package/dist/src/shapes/registry.js +0 -31
- package/dist/src/shapes/types.d.ts +0 -32
- package/dist/src/shapes/types.js +0 -2
- package/examples/1730642890464.jpg +0 -0
- package/examples/app-screen.svg +0 -1
- package/examples/app-screen.visual.json +0 -503
- package/examples/dashboard-table.svg +0 -1
- package/examples/dashboard-table.visual.json +0 -708
- package/examples/dev-docs.svg +0 -1
- package/examples/dev-docs.visual.json +0 -248
- package/examples/explainer.mp4 +0 -0
- package/examples/explainer.visual.json +0 -1713
- package/examples/group-origin-effects-lab-check.svg +0 -1
- package/examples/group-origin-effects-lab.visual.json +0 -1880
- package/examples/image-clip-radius.visual.json +0 -271
- package/examples/make-app-screen.cjs +0 -368
- package/examples/make-dashboard-table.cjs +0 -277
- package/examples/make-dev-docs.cjs +0 -233
- package/examples/make-explainer.cjs +0 -438
- package/examples/make-group-origin-effects-lab.cjs +0 -370
- package/examples/make-image-clip-radius.cjs +0 -169
- package/examples/make-modal-dialog.cjs +0 -355
- package/examples/make-origin-effects-lab.cjs +0 -311
- package/examples/make-preset-character-motion.cjs +0 -32
- package/examples/make-presets-demo.cjs +0 -30
- package/examples/make-pricing.cjs +0 -286
- package/examples/make-product-demo.cjs +0 -468
- package/examples/make-product-hero.cjs +0 -223
- package/examples/make-release-notes.cjs +0 -333
- package/examples/make-settings-panel.cjs +0 -435
- package/examples/make-split-preview.cjs +0 -248
- package/examples/make-storyboard.cjs +0 -215
- package/examples/make-transcript.cjs +0 -234
- package/examples/make-typography-test.cjs +0 -397
- package/examples/make-ui-demo-explainer.cjs +0 -1094
- package/examples/make-ui-flow.cjs +0 -762
- package/examples/make-walkthrough.cjs +0 -815
- package/examples/modal-dialog.svg +0 -1
- package/examples/modal-dialog.visual.json +0 -239
- package/examples/origin-effects-lab-check.svg +0 -1
- package/examples/origin-effects-lab.visual.json +0 -1412
- package/examples/preset-character-motion.visual.json +0 -949
- package/examples/presets-demo.visual.json +0 -787
- package/examples/pricing.svg +0 -1
- package/examples/pricing.visual.json +0 -652
- package/examples/product-demo.mp4 +0 -0
- package/examples/product-demo.visual.json +0 -866
- package/examples/product-hero.svg +0 -1
- package/examples/product-hero.visual.json +0 -242
- package/examples/release-notes.svg +0 -1
- package/examples/release-notes.visual.json +0 -467
- package/examples/settings-panel.svg +0 -1
- package/examples/settings-panel.visual.json +0 -501
- package/examples/split-preview.svg +0 -1
- package/examples/split-preview.visual.json +0 -124
- package/examples/storyboard.svg +0 -1
- package/examples/storyboard.visual.json +0 -312
- package/examples/transcript.svg +0 -1
- package/examples/transcript.visual.json +0 -407
- package/examples/typography-indent-check.svg +0 -1
- package/examples/typography-lineheight-0.svg +0 -1
- package/examples/typography-lineheight-2.svg +0 -1
- package/examples/typography-test-check.svg +0 -1
- package/examples/typography-test.svg +0 -1
- package/examples/typography-test.visual.json +0 -757
- package/examples/ui-demo-explainer-billing.svg +0 -1
- package/examples/ui-demo-explainer-check.svg +0 -1
- package/examples/ui-demo-explainer-save.svg +0 -1
- package/examples/ui-demo-explainer-toggle.svg +0 -1
- package/examples/ui-demo-explainer.mp4 +0 -0
- package/examples/ui-demo-explainer.visual.json +0 -2597
- package/examples/ui-flow.mp4 +0 -0
- package/examples/ui-flow.visual.json +0 -1211
- package/examples/walkthrough.mp4 +0 -0
- package/examples/walkthrough.visual.json +0 -1372
|
@@ -1,435 +0,0 @@
|
|
|
1
|
-
const fs = require("fs");
|
|
2
|
-
const path = require("path");
|
|
3
|
-
|
|
4
|
-
const width = 960;
|
|
5
|
-
const height = 1200;
|
|
6
|
-
const bg = "#f8fafc";
|
|
7
|
-
const font = "Inter, system-ui, sans-serif";
|
|
8
|
-
|
|
9
|
-
const colors = {
|
|
10
|
-
title: "#0f172a",
|
|
11
|
-
section: "#1e293b",
|
|
12
|
-
label: "#334155",
|
|
13
|
-
helper: "#64748b",
|
|
14
|
-
placeholder: "#94a3b8",
|
|
15
|
-
inputBg: "#ffffff",
|
|
16
|
-
inputBorder: "#cbd5e1",
|
|
17
|
-
toggleOn: "#2563eb",
|
|
18
|
-
toggleOff: "#d1d5db",
|
|
19
|
-
toggleKnob: "#ffffff",
|
|
20
|
-
warningBg: "#fef3c7",
|
|
21
|
-
warningBorder: "#f59e0b",
|
|
22
|
-
warningText: "#92400e",
|
|
23
|
-
btnPrimaryBg: "#2563eb",
|
|
24
|
-
btnPrimaryText: "#ffffff",
|
|
25
|
-
btnSecondaryBg: "#ffffff",
|
|
26
|
-
btnSecondaryText: "#475569",
|
|
27
|
-
btnSecondaryBorder: "#cbd5e1",
|
|
28
|
-
divider: "#e2e8f0",
|
|
29
|
-
cardBg: "#ffffff",
|
|
30
|
-
cardBorder: "#e2e8f0"
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const padX = 64;
|
|
34
|
-
const contentW = width - padX * 2;
|
|
35
|
-
let y = 48;
|
|
36
|
-
|
|
37
|
-
const elements = [];
|
|
38
|
-
|
|
39
|
-
// Panel title
|
|
40
|
-
elements.push({
|
|
41
|
-
id: "panel-title",
|
|
42
|
-
type: "text",
|
|
43
|
-
x: padX,
|
|
44
|
-
y: y,
|
|
45
|
-
text: "Settings",
|
|
46
|
-
align: "left",
|
|
47
|
-
valign: "top",
|
|
48
|
-
fontSize: 32,
|
|
49
|
-
fontFamily: font,
|
|
50
|
-
weight: 700,
|
|
51
|
-
fill: colors.title
|
|
52
|
-
});
|
|
53
|
-
y += 48;
|
|
54
|
-
|
|
55
|
-
elements.push({
|
|
56
|
-
id: "panel-desc",
|
|
57
|
-
type: "text",
|
|
58
|
-
x: padX,
|
|
59
|
-
y: y,
|
|
60
|
-
text: "Manage your account preferences and application configuration.",
|
|
61
|
-
align: "left",
|
|
62
|
-
valign: "top",
|
|
63
|
-
fontSize: 14,
|
|
64
|
-
fontFamily: font,
|
|
65
|
-
weight: 400,
|
|
66
|
-
fill: colors.helper
|
|
67
|
-
});
|
|
68
|
-
y += 40;
|
|
69
|
-
|
|
70
|
-
// === Section 1: Profile ===
|
|
71
|
-
y = renderSectionCard("profile", "Profile", y, function(startY) {
|
|
72
|
-
let cy = startY;
|
|
73
|
-
|
|
74
|
-
// Display Name field
|
|
75
|
-
cy = renderTextField("display-name", "Display Name", "Your public-facing name shown across the application.", "Jane Doe", cy);
|
|
76
|
-
cy += 24;
|
|
77
|
-
|
|
78
|
-
// Email field
|
|
79
|
-
cy = renderTextField("email", "Email Address", "Used for notifications and account recovery.", "jane@example.com", cy);
|
|
80
|
-
|
|
81
|
-
return cy;
|
|
82
|
-
});
|
|
83
|
-
y += 32;
|
|
84
|
-
|
|
85
|
-
// === Section 2: Notifications ===
|
|
86
|
-
y = renderSectionCard("notif", "Notifications", y, function(startY) {
|
|
87
|
-
let cy = startY;
|
|
88
|
-
|
|
89
|
-
// Toggle: Email notifications
|
|
90
|
-
cy = renderToggle("email-notif", "Email Notifications", "Receive updates about activity in your projects.", true, cy);
|
|
91
|
-
cy += 24;
|
|
92
|
-
|
|
93
|
-
// Toggle: Marketing
|
|
94
|
-
cy = renderToggle("marketing", "Marketing Emails", "Occasional product announcements and feature previews.", false, cy);
|
|
95
|
-
cy += 24;
|
|
96
|
-
|
|
97
|
-
// Toggle: Slack integration
|
|
98
|
-
cy = renderToggle("slack", "Slack Integration", "Push real-time alerts to your connected Slack workspace.", true, cy);
|
|
99
|
-
|
|
100
|
-
return cy;
|
|
101
|
-
});
|
|
102
|
-
y += 32;
|
|
103
|
-
|
|
104
|
-
// === Section 3: Security ===
|
|
105
|
-
y = renderSectionCard("security", "Security", y, function(startY) {
|
|
106
|
-
let cy = startY;
|
|
107
|
-
|
|
108
|
-
// Toggle: 2FA
|
|
109
|
-
cy = renderToggle("twofa", "Two-Factor Authentication", "Adds an extra layer of protection to your account.", true, cy);
|
|
110
|
-
cy += 24;
|
|
111
|
-
|
|
112
|
-
// Session timeout field
|
|
113
|
-
cy = renderTextField("session", "Session Timeout", "Automatically log out after this period of inactivity.", "30 minutes", cy);
|
|
114
|
-
cy += 24;
|
|
115
|
-
|
|
116
|
-
// Warning note
|
|
117
|
-
cy = renderWarning("security-warn", "Disabling 2FA will immediately remove the second factor from\nyour account. You will not be prompted again until re-enabled.", cy);
|
|
118
|
-
|
|
119
|
-
return cy;
|
|
120
|
-
});
|
|
121
|
-
y += 40;
|
|
122
|
-
|
|
123
|
-
// === Buttons row ===
|
|
124
|
-
const btnH = 42;
|
|
125
|
-
const btnR = 8;
|
|
126
|
-
const saveBtnW = 120;
|
|
127
|
-
const resetBtnW = 100;
|
|
128
|
-
const btnGap = 16;
|
|
129
|
-
const btnRowX = padX;
|
|
130
|
-
|
|
131
|
-
// Reset button (secondary, left)
|
|
132
|
-
elements.push({
|
|
133
|
-
id: "btn-reset-bg",
|
|
134
|
-
type: "path",
|
|
135
|
-
d: roundedRect(btnRowX, y, resetBtnW, btnH, btnR),
|
|
136
|
-
fill: colors.btnSecondaryBg,
|
|
137
|
-
stroke: colors.btnSecondaryBorder,
|
|
138
|
-
strokeWidth: 1
|
|
139
|
-
});
|
|
140
|
-
elements.push({
|
|
141
|
-
id: "btn-reset-label",
|
|
142
|
-
type: "text",
|
|
143
|
-
x: btnRowX + resetBtnW / 2,
|
|
144
|
-
y: y + btnH / 2,
|
|
145
|
-
text: "Reset",
|
|
146
|
-
align: "center",
|
|
147
|
-
valign: "middle",
|
|
148
|
-
fontSize: 14,
|
|
149
|
-
fontFamily: font,
|
|
150
|
-
weight: 500,
|
|
151
|
-
fill: colors.btnSecondaryText
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
// Save button (primary, next to reset)
|
|
155
|
-
const saveBtnX = btnRowX + resetBtnW + btnGap;
|
|
156
|
-
elements.push({
|
|
157
|
-
id: "btn-save-bg",
|
|
158
|
-
type: "path",
|
|
159
|
-
d: roundedRect(saveBtnX, y, saveBtnW, btnH, btnR),
|
|
160
|
-
fill: colors.btnPrimaryBg,
|
|
161
|
-
stroke: "none"
|
|
162
|
-
});
|
|
163
|
-
elements.push({
|
|
164
|
-
id: "btn-save-label",
|
|
165
|
-
type: "text",
|
|
166
|
-
x: saveBtnX + saveBtnW / 2,
|
|
167
|
-
y: y + btnH / 2,
|
|
168
|
-
text: "Save Changes",
|
|
169
|
-
align: "center",
|
|
170
|
-
valign: "middle",
|
|
171
|
-
fontSize: 14,
|
|
172
|
-
fontFamily: font,
|
|
173
|
-
weight: 600,
|
|
174
|
-
fill: colors.btnPrimaryText
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
// --- Helpers ---
|
|
178
|
-
|
|
179
|
-
function renderSectionCard(prefix, title, startY, contentFn) {
|
|
180
|
-
const headerH = 44;
|
|
181
|
-
const innerPad = 24;
|
|
182
|
-
|
|
183
|
-
// We render content first to measure, then wrap in card
|
|
184
|
-
const tempY = startY + headerH + innerPad;
|
|
185
|
-
const endY = contentFn(tempY);
|
|
186
|
-
const cardH = (endY - startY) + innerPad;
|
|
187
|
-
|
|
188
|
-
// Card bg
|
|
189
|
-
elements.push({
|
|
190
|
-
id: `${prefix}-card`,
|
|
191
|
-
type: "path",
|
|
192
|
-
d: roundedRect(padX, startY, contentW, cardH, 10),
|
|
193
|
-
fill: colors.cardBg,
|
|
194
|
-
stroke: colors.cardBorder,
|
|
195
|
-
strokeWidth: 1
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
// Section title
|
|
199
|
-
elements.push({
|
|
200
|
-
id: `${prefix}-title`,
|
|
201
|
-
type: "text",
|
|
202
|
-
x: padX + innerPad,
|
|
203
|
-
y: startY + 18,
|
|
204
|
-
text: title,
|
|
205
|
-
align: "left",
|
|
206
|
-
valign: "top",
|
|
207
|
-
fontSize: 18,
|
|
208
|
-
fontFamily: font,
|
|
209
|
-
weight: 600,
|
|
210
|
-
fill: colors.section
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
// Divider under title
|
|
214
|
-
elements.push({
|
|
215
|
-
id: `${prefix}-div`,
|
|
216
|
-
type: "path",
|
|
217
|
-
d: `M ${padX} ${startY + headerH} L ${padX + contentW} ${startY + headerH}`,
|
|
218
|
-
stroke: colors.divider,
|
|
219
|
-
strokeWidth: 1,
|
|
220
|
-
fill: "none"
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
return startY + cardH;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
function renderTextField(id, label, helper, placeholder, cy) {
|
|
227
|
-
const innerPad = 24;
|
|
228
|
-
const fieldX = padX + innerPad;
|
|
229
|
-
const fieldW = contentW - innerPad * 2;
|
|
230
|
-
|
|
231
|
-
// Label
|
|
232
|
-
elements.push({
|
|
233
|
-
id: `${id}-label`,
|
|
234
|
-
type: "text",
|
|
235
|
-
x: fieldX,
|
|
236
|
-
y: cy,
|
|
237
|
-
text: label,
|
|
238
|
-
align: "left",
|
|
239
|
-
valign: "top",
|
|
240
|
-
fontSize: 14,
|
|
241
|
-
fontFamily: font,
|
|
242
|
-
weight: 500,
|
|
243
|
-
fill: colors.label
|
|
244
|
-
});
|
|
245
|
-
cy += 22;
|
|
246
|
-
|
|
247
|
-
// Helper text
|
|
248
|
-
elements.push({
|
|
249
|
-
id: `${id}-helper`,
|
|
250
|
-
type: "text",
|
|
251
|
-
x: fieldX,
|
|
252
|
-
y: cy,
|
|
253
|
-
text: helper,
|
|
254
|
-
align: "left",
|
|
255
|
-
valign: "top",
|
|
256
|
-
fontSize: 12,
|
|
257
|
-
fontFamily: font,
|
|
258
|
-
weight: 400,
|
|
259
|
-
fill: colors.helper
|
|
260
|
-
});
|
|
261
|
-
cy += 24;
|
|
262
|
-
|
|
263
|
-
// Input field background
|
|
264
|
-
const inputH = 38;
|
|
265
|
-
elements.push({
|
|
266
|
-
id: `${id}-input-bg`,
|
|
267
|
-
type: "path",
|
|
268
|
-
d: roundedRect(fieldX, cy, fieldW, inputH, 6),
|
|
269
|
-
fill: colors.inputBg,
|
|
270
|
-
stroke: colors.inputBorder,
|
|
271
|
-
strokeWidth: 1
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
// Placeholder text
|
|
275
|
-
elements.push({
|
|
276
|
-
id: `${id}-placeholder`,
|
|
277
|
-
type: "text",
|
|
278
|
-
x: fieldX + 12,
|
|
279
|
-
y: cy + inputH / 2,
|
|
280
|
-
text: placeholder,
|
|
281
|
-
align: "left",
|
|
282
|
-
valign: "middle",
|
|
283
|
-
fontSize: 13,
|
|
284
|
-
fontFamily: font,
|
|
285
|
-
weight: 400,
|
|
286
|
-
fill: colors.placeholder
|
|
287
|
-
});
|
|
288
|
-
cy += inputH;
|
|
289
|
-
|
|
290
|
-
return cy;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
function renderToggle(id, label, helper, isOn, cy) {
|
|
294
|
-
const innerPad = 24;
|
|
295
|
-
const fieldX = padX + innerPad;
|
|
296
|
-
|
|
297
|
-
// Label
|
|
298
|
-
elements.push({
|
|
299
|
-
id: `${id}-label`,
|
|
300
|
-
type: "text",
|
|
301
|
-
x: fieldX,
|
|
302
|
-
y: cy,
|
|
303
|
-
text: label,
|
|
304
|
-
align: "left",
|
|
305
|
-
valign: "top",
|
|
306
|
-
fontSize: 14,
|
|
307
|
-
fontFamily: font,
|
|
308
|
-
weight: 500,
|
|
309
|
-
fill: colors.label
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
// Toggle track (right-aligned)
|
|
313
|
-
const toggleW = 40;
|
|
314
|
-
const toggleH = 22;
|
|
315
|
-
const toggleX = padX + contentW - innerPad - toggleW;
|
|
316
|
-
const toggleY = cy - 2;
|
|
317
|
-
const trackR = toggleH / 2;
|
|
318
|
-
|
|
319
|
-
elements.push({
|
|
320
|
-
id: `${id}-track`,
|
|
321
|
-
type: "path",
|
|
322
|
-
d: roundedRect(toggleX, toggleY, toggleW, toggleH, trackR),
|
|
323
|
-
fill: isOn ? colors.toggleOn : colors.toggleOff,
|
|
324
|
-
stroke: "none"
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
// Toggle knob
|
|
328
|
-
const knobR = 8;
|
|
329
|
-
const knobCx = isOn ? toggleX + toggleW - trackR : toggleX + trackR;
|
|
330
|
-
const knobCy = toggleY + toggleH / 2;
|
|
331
|
-
elements.push({
|
|
332
|
-
id: `${id}-knob`,
|
|
333
|
-
type: "path",
|
|
334
|
-
d: `M ${knobCx} ${knobCy - knobR} A ${knobR} ${knobR} 0 1 1 ${knobCx} ${knobCy + knobR} A ${knobR} ${knobR} 0 1 1 ${knobCx} ${knobCy - knobR} Z`,
|
|
335
|
-
fill: colors.toggleKnob,
|
|
336
|
-
stroke: "none"
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
cy += 22;
|
|
340
|
-
|
|
341
|
-
// Helper text
|
|
342
|
-
elements.push({
|
|
343
|
-
id: `${id}-helper`,
|
|
344
|
-
type: "text",
|
|
345
|
-
x: fieldX,
|
|
346
|
-
y: cy,
|
|
347
|
-
text: helper,
|
|
348
|
-
align: "left",
|
|
349
|
-
valign: "top",
|
|
350
|
-
fontSize: 12,
|
|
351
|
-
fontFamily: font,
|
|
352
|
-
weight: 400,
|
|
353
|
-
fill: colors.helper
|
|
354
|
-
});
|
|
355
|
-
cy += 20;
|
|
356
|
-
|
|
357
|
-
return cy;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
function renderWarning(id, text, cy) {
|
|
361
|
-
const innerPad = 24;
|
|
362
|
-
const fieldX = padX + innerPad;
|
|
363
|
-
const fieldW = contentW - innerPad * 2;
|
|
364
|
-
const warnPadX = 14;
|
|
365
|
-
const warnPadY = 12;
|
|
366
|
-
const lineCount = text.split("\n").length;
|
|
367
|
-
const warnH = lineCount * 20 + warnPadY * 2;
|
|
368
|
-
|
|
369
|
-
elements.push({
|
|
370
|
-
id: `${id}-bg`,
|
|
371
|
-
type: "path",
|
|
372
|
-
d: roundedRect(fieldX, cy, fieldW, warnH, 6),
|
|
373
|
-
fill: colors.warningBg,
|
|
374
|
-
stroke: colors.warningBorder,
|
|
375
|
-
strokeWidth: 1
|
|
376
|
-
});
|
|
377
|
-
|
|
378
|
-
elements.push({
|
|
379
|
-
id: `${id}-icon`,
|
|
380
|
-
type: "text",
|
|
381
|
-
x: fieldX + warnPadX,
|
|
382
|
-
y: cy + warnPadY,
|
|
383
|
-
text: "⚠",
|
|
384
|
-
align: "left",
|
|
385
|
-
valign: "top",
|
|
386
|
-
fontSize: 14,
|
|
387
|
-
fontFamily: font,
|
|
388
|
-
weight: 400,
|
|
389
|
-
fill: colors.warningText
|
|
390
|
-
});
|
|
391
|
-
|
|
392
|
-
elements.push({
|
|
393
|
-
id: `${id}-text`,
|
|
394
|
-
type: "text",
|
|
395
|
-
x: fieldX + warnPadX + 22,
|
|
396
|
-
y: cy + warnPadY + 1,
|
|
397
|
-
text: text,
|
|
398
|
-
align: "left",
|
|
399
|
-
valign: "top",
|
|
400
|
-
fontSize: 12,
|
|
401
|
-
fontFamily: font,
|
|
402
|
-
weight: 400,
|
|
403
|
-
lineHeight: 1.65,
|
|
404
|
-
fill: colors.warningText,
|
|
405
|
-
maxWidth: fieldW - warnPadX * 2 - 22
|
|
406
|
-
});
|
|
407
|
-
|
|
408
|
-
cy += warnH;
|
|
409
|
-
return cy;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
function roundedRect(x, y, w, h, r) {
|
|
413
|
-
return [
|
|
414
|
-
`M ${x + r} ${y}`,
|
|
415
|
-
`L ${x + w - r} ${y}`,
|
|
416
|
-
`Q ${x + w} ${y} ${x + w} ${y + r}`,
|
|
417
|
-
`L ${x + w} ${y + h - r}`,
|
|
418
|
-
`Q ${x + w} ${y + h} ${x + w - r} ${y + h}`,
|
|
419
|
-
`L ${x + r} ${y + h}`,
|
|
420
|
-
`Q ${x} ${y + h} ${x} ${y + h - r}`,
|
|
421
|
-
`L ${x} ${y + r}`,
|
|
422
|
-
`Q ${x} ${y} ${x + r} ${y}`,
|
|
423
|
-
"Z"
|
|
424
|
-
].join(" ");
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
const doc = {
|
|
428
|
-
version: 1,
|
|
429
|
-
canvas: { width, height, background: bg },
|
|
430
|
-
elements
|
|
431
|
-
};
|
|
432
|
-
|
|
433
|
-
const outPath = path.join(__dirname, "settings-panel.visual.json");
|
|
434
|
-
fs.writeFileSync(outPath, JSON.stringify(doc, null, 2));
|
|
435
|
-
console.log("Written:", outPath);
|
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
const fs = require("fs");
|
|
2
|
-
const path = require("path");
|
|
3
|
-
|
|
4
|
-
const width = 1200;
|
|
5
|
-
const height = 600;
|
|
6
|
-
const bg = "#f8fafc";
|
|
7
|
-
const font = "Inter, system-ui, sans-serif";
|
|
8
|
-
const monoFont = "JetBrains Mono, Fira Code, monospace";
|
|
9
|
-
|
|
10
|
-
const colors = {
|
|
11
|
-
codeBg: "#1e293b",
|
|
12
|
-
codeText: "#e2e8f0",
|
|
13
|
-
codeKeyword: "#7dd3fc",
|
|
14
|
-
codeString: "#86efac",
|
|
15
|
-
codeNumber: "#fcd34d",
|
|
16
|
-
previewBg: "#ffffff",
|
|
17
|
-
previewBorder: "#e2e8f0",
|
|
18
|
-
previewTitle: "#0f172a",
|
|
19
|
-
previewCaption: "#64748b",
|
|
20
|
-
badgeBg: "#8b5cf6",
|
|
21
|
-
badgeText: "#ffffff",
|
|
22
|
-
sectionLabel: "#64748b"
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const padX = 48;
|
|
26
|
-
const padY = 48;
|
|
27
|
-
const gapX = 40;
|
|
28
|
-
const colW = (width - padX * 2 - gapX) / 2;
|
|
29
|
-
|
|
30
|
-
const elements = [];
|
|
31
|
-
|
|
32
|
-
// === LEFT SIDE: Code block ===
|
|
33
|
-
|
|
34
|
-
const codeX = padX;
|
|
35
|
-
const codeY = padY;
|
|
36
|
-
const codeW = colW;
|
|
37
|
-
const codeH = height - padY * 2;
|
|
38
|
-
const codeR = 12;
|
|
39
|
-
const codePad = 24;
|
|
40
|
-
|
|
41
|
-
// Code block background
|
|
42
|
-
elements.push({
|
|
43
|
-
id: "code-bg",
|
|
44
|
-
type: "path",
|
|
45
|
-
d: roundedRect(codeX, codeY, codeW, codeH, codeR),
|
|
46
|
-
fill: colors.codeBg,
|
|
47
|
-
stroke: "none"
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
// Section label above code
|
|
51
|
-
elements.push({
|
|
52
|
-
id: "code-label",
|
|
53
|
-
type: "text",
|
|
54
|
-
x: codeX + codePad,
|
|
55
|
-
y: codeY + 20,
|
|
56
|
-
text: "document.visual.json",
|
|
57
|
-
align: "left",
|
|
58
|
-
valign: "top",
|
|
59
|
-
fontSize: 11,
|
|
60
|
-
fontFamily: monoFont,
|
|
61
|
-
weight: 500,
|
|
62
|
-
fill: colors.sectionLabel
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
// JSON code content
|
|
66
|
-
const jsonCode = `{
|
|
67
|
-
"version": 1,
|
|
68
|
-
"canvas": {
|
|
69
|
-
"width": 400,
|
|
70
|
-
"height": 300,
|
|
71
|
-
"background": "#ffffff"
|
|
72
|
-
},
|
|
73
|
-
"elements": [
|
|
74
|
-
{
|
|
75
|
-
"id": "card",
|
|
76
|
-
"type": "path",
|
|
77
|
-
"d": "M 20 20 L 380 20 ...",
|
|
78
|
-
"fill": "#f1f5f9",
|
|
79
|
-
"stroke": "#e2e8f0"
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
"id": "title",
|
|
83
|
-
"type": "text",
|
|
84
|
-
"x": 40,
|
|
85
|
-
"y": 60,
|
|
86
|
-
"text": "Welcome",
|
|
87
|
-
"fontSize": 24,
|
|
88
|
-
"weight": 700
|
|
89
|
-
}
|
|
90
|
-
]
|
|
91
|
-
}`;
|
|
92
|
-
|
|
93
|
-
elements.push({
|
|
94
|
-
id: "code-text",
|
|
95
|
-
type: "text",
|
|
96
|
-
x: codeX + codePad,
|
|
97
|
-
y: codeY + 48,
|
|
98
|
-
text: jsonCode,
|
|
99
|
-
align: "left",
|
|
100
|
-
valign: "top",
|
|
101
|
-
fontSize: 12,
|
|
102
|
-
fontFamily: monoFont,
|
|
103
|
-
weight: 400,
|
|
104
|
-
lineHeight: 1.5,
|
|
105
|
-
fill: colors.codeText,
|
|
106
|
-
maxWidth: codeW - codePad * 2
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
// === RIGHT SIDE: Preview ===
|
|
110
|
-
|
|
111
|
-
const previewX = padX + colW + gapX;
|
|
112
|
-
const previewY = padY;
|
|
113
|
-
const previewW = colW;
|
|
114
|
-
const previewH = height - padY * 2;
|
|
115
|
-
|
|
116
|
-
// Centered "Rendered output" badge above preview card
|
|
117
|
-
const badgeW = 130;
|
|
118
|
-
const badgeH = 26;
|
|
119
|
-
const badgeX = previewX + (previewW - badgeW) / 2;
|
|
120
|
-
const badgeY = previewY;
|
|
121
|
-
const badgeR = 13;
|
|
122
|
-
|
|
123
|
-
elements.push({
|
|
124
|
-
id: "badge-bg",
|
|
125
|
-
type: "path",
|
|
126
|
-
d: roundedRect(badgeX, badgeY, badgeW, badgeH, badgeR),
|
|
127
|
-
fill: colors.badgeBg,
|
|
128
|
-
stroke: "none"
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
elements.push({
|
|
132
|
-
id: "badge-text",
|
|
133
|
-
type: "text",
|
|
134
|
-
x: badgeX + badgeW / 2,
|
|
135
|
-
y: badgeY + badgeH / 2,
|
|
136
|
-
text: "Rendered output",
|
|
137
|
-
align: "center",
|
|
138
|
-
valign: "middle",
|
|
139
|
-
fontSize: 11,
|
|
140
|
-
fontFamily: font,
|
|
141
|
-
weight: 600,
|
|
142
|
-
fill: colors.badgeText
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
// Preview container
|
|
146
|
-
const cardY = badgeY + badgeH + 20;
|
|
147
|
-
const cardH = previewH - badgeH - 20;
|
|
148
|
-
const cardR = 12;
|
|
149
|
-
const cardPad = 32;
|
|
150
|
-
|
|
151
|
-
elements.push({
|
|
152
|
-
id: "preview-bg",
|
|
153
|
-
type: "path",
|
|
154
|
-
d: roundedRect(previewX, cardY, previewW, cardH, cardR),
|
|
155
|
-
fill: colors.previewBg,
|
|
156
|
-
stroke: colors.previewBorder,
|
|
157
|
-
strokeWidth: 1
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
// Inner rendered card (the visual output)
|
|
161
|
-
const innerCardX = previewX + cardPad;
|
|
162
|
-
const innerCardY = cardY + cardPad;
|
|
163
|
-
const innerCardW = previewW - cardPad * 2;
|
|
164
|
-
const innerCardH = 200;
|
|
165
|
-
const innerCardR = 8;
|
|
166
|
-
|
|
167
|
-
elements.push({
|
|
168
|
-
id: "inner-card-bg",
|
|
169
|
-
type: "path",
|
|
170
|
-
d: roundedRect(innerCardX, innerCardY, innerCardW, innerCardH, innerCardR),
|
|
171
|
-
fill: "#f1f5f9",
|
|
172
|
-
stroke: "#e2e8f0",
|
|
173
|
-
strokeWidth: 1
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
// Inner card title (the "Welcome" from the JSON)
|
|
177
|
-
elements.push({
|
|
178
|
-
id: "inner-card-title",
|
|
179
|
-
type: "text",
|
|
180
|
-
x: innerCardX + 24,
|
|
181
|
-
y: innerCardY + 32,
|
|
182
|
-
text: "Welcome",
|
|
183
|
-
align: "left",
|
|
184
|
-
valign: "top",
|
|
185
|
-
fontSize: 24,
|
|
186
|
-
fontFamily: font,
|
|
187
|
-
weight: 700,
|
|
188
|
-
fill: colors.previewTitle
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
// Inner card body text
|
|
192
|
-
elements.push({
|
|
193
|
-
id: "inner-card-body",
|
|
194
|
-
type: "text",
|
|
195
|
-
x: innerCardX + 24,
|
|
196
|
-
y: innerCardY + 72,
|
|
197
|
-
text: "This card was rendered from the JSON\ndefinition on the left. The kernel resolves\nall elements into positioned primitives.",
|
|
198
|
-
align: "left",
|
|
199
|
-
valign: "top",
|
|
200
|
-
fontSize: 13,
|
|
201
|
-
fontFamily: font,
|
|
202
|
-
weight: 400,
|
|
203
|
-
lineHeight: 1.55,
|
|
204
|
-
fill: colors.previewCaption,
|
|
205
|
-
maxWidth: innerCardW - 48
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
// Preview caption below the inner card
|
|
209
|
-
elements.push({
|
|
210
|
-
id: "preview-caption",
|
|
211
|
-
type: "text",
|
|
212
|
-
x: previewX + cardPad,
|
|
213
|
-
y: innerCardY + innerCardH + 28,
|
|
214
|
-
text: "Live preview updates as the document changes.\nNo build step required — just edit and see.",
|
|
215
|
-
align: "left",
|
|
216
|
-
valign: "top",
|
|
217
|
-
fontSize: 13,
|
|
218
|
-
fontFamily: font,
|
|
219
|
-
weight: 400,
|
|
220
|
-
lineHeight: 1.55,
|
|
221
|
-
fill: colors.previewCaption,
|
|
222
|
-
maxWidth: previewW - cardPad * 2
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
function roundedRect(x, y, w, h, r) {
|
|
226
|
-
return [
|
|
227
|
-
`M ${x + r} ${y}`,
|
|
228
|
-
`L ${x + w - r} ${y}`,
|
|
229
|
-
`Q ${x + w} ${y} ${x + w} ${y + r}`,
|
|
230
|
-
`L ${x + w} ${y + h - r}`,
|
|
231
|
-
`Q ${x + w} ${y + h} ${x + w - r} ${y + h}`,
|
|
232
|
-
`L ${x + r} ${y + h}`,
|
|
233
|
-
`Q ${x} ${y + h} ${x} ${y + h - r}`,
|
|
234
|
-
`L ${x} ${y + r}`,
|
|
235
|
-
`Q ${x} ${y} ${x + r} ${y}`,
|
|
236
|
-
"Z"
|
|
237
|
-
].join(" ");
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
const doc = {
|
|
241
|
-
version: 1,
|
|
242
|
-
canvas: { width, height, background: bg },
|
|
243
|
-
elements
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
const outPath = path.join(__dirname, "split-preview.visual.json");
|
|
247
|
-
fs.writeFileSync(outPath, JSON.stringify(doc, null, 2));
|
|
248
|
-
console.log("Written:", outPath);
|