@mevdragon/vidfarm-devcli 0.2.8 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/.env.example +9 -0
  2. package/GETTING_STARTED.developers.md +1 -26
  3. package/README.md +3 -0
  4. package/SKILL.developer.md +327 -4
  5. package/auto-create-templates/AUTO_CREATE_TEMPLATES.md +475 -0
  6. package/auto-create-templates/extractor-system-prompt.md +113 -0
  7. package/auto-create-templates/production-graph.schema.json +276 -0
  8. package/auto-create-templates/runbook.md +140 -0
  9. package/auto-create-templates/template-plan.schema.json +230 -0
  10. package/auto-create-templates/template-planner-prompt.md +75 -0
  11. package/dist/src/account-pages-legacy.js +9064 -0
  12. package/dist/src/account-pages.js +41 -620
  13. package/dist/src/app.js +6627 -244
  14. package/dist/src/cli.js +386 -26
  15. package/dist/src/config.js +12 -2
  16. package/dist/src/context.js +35 -35
  17. package/dist/src/db.js +1016 -53
  18. package/dist/src/dev-app-legacy.js +693 -0
  19. package/dist/src/dev-app.js +4 -904
  20. package/dist/src/domain.js +1 -1
  21. package/dist/src/editor-chat-history.js +72 -0
  22. package/dist/src/editor-chat.js +202 -0
  23. package/dist/src/frontend/flockposter-cache-store.js +116 -0
  24. package/dist/src/frontend/homepage-client.js +114 -0
  25. package/dist/src/frontend/homepage-shared.js +3 -0
  26. package/dist/src/frontend/homepage-store.js +27 -0
  27. package/dist/src/frontend/homepage-view.js +147 -0
  28. package/dist/src/frontend/page-runtime-client.js +100 -0
  29. package/dist/src/frontend/page-runtime-store.js +8 -0
  30. package/dist/src/frontend/template-editor-chat.js +2261 -0
  31. package/dist/src/homepage.js +695 -371
  32. package/dist/src/lib/template-style-options.js +95 -15
  33. package/dist/src/page-runtime.js +1 -0
  34. package/dist/src/page-shell.js +941 -0
  35. package/dist/src/primitive-context.js +163 -0
  36. package/dist/src/primitive-registry.js +340 -0
  37. package/dist/src/primitive-sdk.js +3 -0
  38. package/dist/src/primitives/remotion/html-image.js +28 -0
  39. package/dist/src/react-page-shell.js +34 -0
  40. package/dist/src/ready-post-schedule-component.js +1514 -0
  41. package/dist/src/registry.js +36 -17
  42. package/dist/src/runtime.js +6 -1
  43. package/dist/src/services/api-call-history.js +245 -0
  44. package/dist/src/services/auth.js +25 -3
  45. package/dist/src/services/billing.js +248 -9
  46. package/dist/src/services/chat-threads.js +88 -0
  47. package/dist/src/services/job-logs.js +14 -7
  48. package/dist/src/services/jobs.js +13 -2
  49. package/dist/src/services/providers.js +552 -133
  50. package/dist/src/services/rate-limits.js +236 -0
  51. package/dist/src/services/remotion.js +143 -16
  52. package/dist/src/services/storage.js +10 -8
  53. package/dist/src/services/template-certification.js +11 -2
  54. package/dist/src/services/template-loader.js +3 -1
  55. package/dist/src/services/template-sources.js +68 -3
  56. package/dist/src/template-editor-pages.js +2309 -0
  57. package/dist/src/template-editor-shell.js +1507 -0
  58. package/dist/src/worker.js +120 -22
  59. package/package.json +27 -4
  60. package/public/assets/homepage-app.js +54 -0
  61. package/public/assets/homepage-client-app.js +54 -0
  62. package/public/assets/page-runtime-client-app.js +68 -0
  63. package/dist/templates/vidfarm_template_0000/src/lib/images.js +0 -202
  64. package/dist/templates/vidfarm_template_0000/src/remotion/Root.js +0 -34
  65. package/dist/templates/vidfarm_template_0000/src/remotion/index.js +0 -3
  66. package/dist/templates/vidfarm_template_0000/src/sdk.js +0 -3
  67. package/dist/templates/vidfarm_template_0000/src/style-options.js +0 -51
  68. package/dist/templates/vidfarm_template_0000/src/template-dna.js +0 -9
  69. package/dist/templates/vidfarm_template_0000/src/template.js +0 -1447
  70. package/templates/vidfarm_template_0000/README.md +0 -100
  71. package/templates/vidfarm_template_0000/SKILL.md +0 -225
  72. package/templates/vidfarm_template_0000/assets/Abel-Regular.ttf +0 -0
  73. package/templates/vidfarm_template_0000/assets/DMSerifDisplay-Regular.ttf +0 -0
  74. package/templates/vidfarm_template_0000/assets/Montserrat[wght].ttf +0 -0
  75. package/templates/vidfarm_template_0000/assets/SourceCodePro[wght].ttf +0 -0
  76. package/templates/vidfarm_template_0000/assets/TikTokSans-SemiBold.ttf +0 -0
  77. package/templates/vidfarm_template_0000/assets/Yesteryear-Regular.ttf +0 -0
  78. package/templates/vidfarm_template_0000/composition.json +0 -11
  79. package/templates/vidfarm_template_0000/package.json +0 -27
  80. package/templates/vidfarm_template_0000/research/preview/.gitkeep +0 -1
  81. package/templates/vidfarm_template_0000/research/source_notes.md +0 -7
  82. package/templates/vidfarm_template_0000/src/lib/images.js +0 -202
  83. package/templates/vidfarm_template_0000/src/lib/images.ts +0 -241
  84. package/templates/vidfarm_template_0000/src/remotion/Root.js +0 -33
  85. package/templates/vidfarm_template_0000/src/remotion/Root.tsx +0 -75
  86. package/templates/vidfarm_template_0000/src/remotion/index.js +0 -3
  87. package/templates/vidfarm_template_0000/src/remotion/index.tsx +0 -4
  88. package/templates/vidfarm_template_0000/src/sdk.js +0 -3
  89. package/templates/vidfarm_template_0000/src/sdk.ts +0 -140
  90. package/templates/vidfarm_template_0000/src/style-options.js +0 -51
  91. package/templates/vidfarm_template_0000/src/style-options.ts +0 -60
  92. package/templates/vidfarm_template_0000/src/template-dna.js +0 -9
  93. package/templates/vidfarm_template_0000/src/template-dna.ts +0 -15
  94. package/templates/vidfarm_template_0000/src/template.js +0 -1447
  95. package/templates/vidfarm_template_0000/src/template.ts +0 -2049
  96. package/templates/vidfarm_template_0000/template.config.json +0 -21
  97. package/templates/vidfarm_template_0000/tmp/solobacterium-moorei-slideshow.request.json +0 -31
  98. package/templates/vidfarm_template_0000/tsconfig.json +0 -19
@@ -0,0 +1,941 @@
1
+ export function escapeHtml(value) {
2
+ return value
3
+ .replace(/&/g, "&")
4
+ .replace(/</g, "&lt;")
5
+ .replace(/>/g, "&gt;")
6
+ .replace(/"/g, "&quot;");
7
+ }
8
+ export function escapeAttribute(value) {
9
+ return escapeHtml(value).replace(/'/g, "&#39;");
10
+ }
11
+ export function escapeJsonForHtml(value) {
12
+ return JSON.stringify(value)
13
+ .replace(/</g, "\\u003c")
14
+ .replace(/>/g, "\\u003e")
15
+ .replace(/&/g, "\\u0026");
16
+ }
17
+ export function withAccountQuery(href, accountId) {
18
+ if (!accountId || !href.startsWith("/")) {
19
+ return href;
20
+ }
21
+ const url = new URL(href, "https://vidfarm.local");
22
+ if (url.pathname.startsWith("/u/")) {
23
+ return `${url.pathname}${url.search}${url.hash}`;
24
+ }
25
+ return `/u/${encodeURIComponent(accountId)}${url.pathname}${url.search}${url.hash}`;
26
+ }
27
+ export function resolveAccountDisplayName(input) {
28
+ const email = input?.email?.trim() || "";
29
+ const displayName = input?.displayName?.trim() || "";
30
+ if (displayName) {
31
+ return displayName;
32
+ }
33
+ if (!email) {
34
+ return "";
35
+ }
36
+ return email
37
+ .split("@")[0]
38
+ .replace(/[._-]+/g, " ")
39
+ .replace(/\b\w/g, (match) => match.toUpperCase());
40
+ }
41
+ function renderNavIcon(kind) {
42
+ if (kind === "discover") {
43
+ return `<svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M10 3v4"/><path d="M10 13v4"/><path d="M3 10h4"/><path d="M13 10h4"/><path d="m5.8 5.8 2.3 2.3"/><path d="m11.9 11.9 2.3 2.3"/><path d="m14.2 5.8-2.3 2.3"/><path d="m8.1 11.9-2.3 2.3"/></svg>`;
44
+ }
45
+ if (kind === "library") {
46
+ return `<svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 4.5h3v11h-3z"/><path d="M8.7 4.5h3v11h-3z"/><path d="m13.4 5.1 2.3-.6 2.2 10.7-2.3.6z"/></svg>`;
47
+ }
48
+ if (kind === "calendar") {
49
+ return `<svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><circle cx="10" cy="10" r="7.2"/><path d="M10 6.3v4.1l2.8 1.7"/></svg>`;
50
+ }
51
+ return `<svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M14.8 15.2a5.4 5.4 0 1 0-9.6 0"/><circle cx="10" cy="6.8" r="3.1"/></svg>`;
52
+ }
53
+ export function renderPrimaryNav(input) {
54
+ const items = input.loggedIn
55
+ ? [
56
+ { id: "discover", href: withAccountQuery("/discover", input.accountId), label: "Discover", icon: renderNavIcon("discover") },
57
+ { id: "library", href: withAccountQuery("/library", input.accountId), label: "Library", icon: renderNavIcon("library") },
58
+ { id: "calendar", href: withAccountQuery("/calendar", input.accountId), label: "Calendar", icon: renderNavIcon("calendar") },
59
+ { id: "settings", href: withAccountQuery("/settings", input.accountId), label: "Settings", icon: renderNavIcon("settings") }
60
+ ]
61
+ : [
62
+ { id: "discover", href: "/discover", label: "Discover", icon: renderNavIcon("discover") },
63
+ { id: "login", href: "/login", label: "Login", icon: renderNavIcon("settings") }
64
+ ];
65
+ return `
66
+ <nav class="primary-nav" aria-label="Primary">
67
+ ${items.map((item) => `
68
+ <a class="nav-link${item.id === input.current ? " is-active" : ""}" href="${item.href}">
69
+ <span class="nav-icon" aria-hidden="true">${item.icon}</span>
70
+ <span>${item.label}</span>
71
+ </a>
72
+ `).join("")}
73
+ </nav>
74
+ `;
75
+ }
76
+ export function renderBrandLockup(input) {
77
+ const email = input?.email?.trim() || "";
78
+ const derivedName = resolveAccountDisplayName(input);
79
+ const href = withAccountQuery("/discover", input?.accountId);
80
+ const accountMeta = email
81
+ ? `<div class="brand-account-meta">${escapeHtml(derivedName)} <span>(${escapeHtml(email)})</span></div>`
82
+ : "";
83
+ return `
84
+ <a class="brand-lockup" href="${escapeAttribute(href)}">
85
+ <img class="brand-logo-image" src="/assets/logo-vidfarm.png" alt="VidFarm AI" />
86
+ <div class="brand-copy">
87
+ <div class="brand-title brand-title-static">VidFarm<span class="brand-title-mobile-hidden"> AI</span></div>
88
+ ${accountMeta}
89
+ </div>
90
+ </a>
91
+ `;
92
+ }
93
+ export function renderPageShell(input) {
94
+ return `<!doctype html>
95
+ <html lang="en">
96
+ <head>
97
+ <meta charset="utf-8" />
98
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
99
+ <title>${escapeHtml(input.title)}</title>
100
+ <link rel="icon" href="/assets/favicon.ico" sizes="any" />
101
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
102
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
103
+ <link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet" />
104
+ <style>
105
+ :root {
106
+ color-scheme: light;
107
+ --bg: #f8f4eb;
108
+ --paper: rgba(255, 252, 247, 0.88);
109
+ --paper-strong: rgba(255, 252, 247, 0.96);
110
+ --panel: transparent;
111
+ --panel-muted: rgba(250, 245, 234, 0.9);
112
+ --ink: #2f3748;
113
+ --muted: #74829c;
114
+ --line: rgba(209, 219, 233, 0.9);
115
+ --line-strong: rgba(191, 164, 109, 0.42);
116
+ --accent: #dec081;
117
+ --accent-deep: #243041;
118
+ --accent-soft: rgba(222, 192, 129, 0.18);
119
+ --shadow: 0 24px 80px rgba(15, 23, 42, 0.08);
120
+ --shadow-soft: 0 16px 36px rgba(148, 109, 42, 0.08);
121
+ --radius-lg: 32px;
122
+ --radius-md: 26px;
123
+ --radius-sm: 18px;
124
+ }
125
+
126
+ * {
127
+ box-sizing: border-box;
128
+ }
129
+
130
+ html {
131
+ height: 100%;
132
+ min-height: 100%;
133
+ overflow: hidden;
134
+ }
135
+
136
+ body {
137
+ margin: 0;
138
+ height: 100%;
139
+ min-height: 100%;
140
+ overflow: hidden;
141
+ color: var(--ink);
142
+ font-family: "Manrope", sans-serif;
143
+ background:
144
+ radial-gradient(circle at 12% 18%, rgba(222, 192, 129, 0.28), transparent 24%),
145
+ radial-gradient(circle at 84% 12%, rgba(123, 92, 29, 0.12), transparent 22%),
146
+ linear-gradient(180deg, rgba(255, 255, 255, 0.65), rgba(255, 255, 255, 0)),
147
+ linear-gradient(145deg, #f8f4eb 0%, #f1e7d3 52%, #e9dbba 100%);
148
+ background-attachment: fixed;
149
+ }
150
+
151
+ body::before {
152
+ content: "";
153
+ position: fixed;
154
+ inset: 0;
155
+ pointer-events: none;
156
+ background-image:
157
+ linear-gradient(rgba(96, 74, 36, 0.035) 1px, transparent 1px),
158
+ linear-gradient(90deg, rgba(96, 74, 36, 0.035) 1px, transparent 1px);
159
+ background-size: 30px 30px;
160
+ mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0.38), transparent 86%);
161
+ }
162
+
163
+ a {
164
+ color: inherit;
165
+ }
166
+
167
+ button,
168
+ input,
169
+ select,
170
+ textarea {
171
+ font: inherit;
172
+ }
173
+
174
+ .app-shell {
175
+ width: min(1980px, calc(100vw - 40px));
176
+ margin: 0 auto;
177
+ height: 100dvh;
178
+ min-height: 0;
179
+ padding: 20px 0 28px;
180
+ }
181
+
182
+ .app-shell.is-wide {
183
+ width: min(1980px, calc(100vw - 40px));
184
+ }
185
+
186
+ .app-shell.is-narrow {
187
+ width: min(1980px, calc(100vw - 40px));
188
+ }
189
+
190
+ .page-stack {
191
+ display: grid;
192
+ height: 100%;
193
+ min-height: 0;
194
+ gap: 18px;
195
+ }
196
+
197
+ .frame {
198
+ position: relative;
199
+ display: grid;
200
+ grid-template-rows: auto minmax(0, 1fr);
201
+ min-height: 0;
202
+ overflow: hidden;
203
+ border-radius: var(--radius-lg);
204
+ background: var(--panel);
205
+ }
206
+
207
+ .frame-body {
208
+ display: grid;
209
+ min-height: 0;
210
+ gap: 20px;
211
+ padding: 14px 0 0;
212
+ }
213
+
214
+ .topbar {
215
+ display: flex;
216
+ align-items: center;
217
+ justify-content: space-between;
218
+ gap: 12px;
219
+ min-height: 76px;
220
+ padding: 10px 16px 10px 20px;
221
+ border: 1px solid rgba(255, 255, 255, 0.82);
222
+ border-radius: var(--radius-lg);
223
+ background: var(--paper);
224
+ box-shadow: var(--shadow);
225
+ }
226
+
227
+ .brand-lockup {
228
+ display: flex;
229
+ flex: 1 1 min(0, 58%);
230
+ align-items: center;
231
+ gap: 14px;
232
+ min-width: 0;
233
+ color: inherit;
234
+ text-decoration: none;
235
+ }
236
+
237
+ .brand-lockup:hover,
238
+ .brand-lockup:focus {
239
+ text-decoration: none;
240
+ }
241
+
242
+ .brand-logo-image {
243
+ display: block;
244
+ width: auto;
245
+ height: 44px;
246
+ max-width: min(220px, 38vw);
247
+ object-fit: contain;
248
+ object-position: left center;
249
+ flex: 0 0 auto;
250
+ border-radius: 12px;
251
+ }
252
+
253
+ .brand-mark {
254
+ display: inline-flex;
255
+ align-items: center;
256
+ justify-content: center;
257
+ width: 38px;
258
+ height: 38px;
259
+ border-radius: 999px;
260
+ background: #111934;
261
+ color: #f3e8cd;
262
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
263
+ }
264
+
265
+ .brand-mark svg {
266
+ width: 20px;
267
+ height: 20px;
268
+ }
269
+
270
+ .brand-copy {
271
+ display: flex;
272
+ align-items: center;
273
+ gap: 10px;
274
+ min-width: 0;
275
+ flex-wrap: wrap;
276
+ }
277
+
278
+ .brand-account-meta {
279
+ min-width: 0;
280
+ color: rgba(116, 130, 156, 0.78);
281
+ font-size: 0.94rem;
282
+ line-height: 1.2;
283
+ font-weight: 500;
284
+ letter-spacing: -0.01em;
285
+ white-space: nowrap;
286
+ overflow: hidden;
287
+ text-overflow: ellipsis;
288
+ }
289
+
290
+ .brand-account-meta span {
291
+ color: rgba(116, 130, 156, 0.62);
292
+ }
293
+
294
+ .eyebrow {
295
+ font-size: 10px;
296
+ font-weight: 700;
297
+ letter-spacing: 0.28em;
298
+ text-transform: uppercase;
299
+ color: var(--muted);
300
+ }
301
+
302
+ .brand-title {
303
+ font-family: "Instrument Serif", serif;
304
+ font-size: clamp(1.65rem, 1.85vw, 2rem);
305
+ line-height: 0.92;
306
+ font-weight: 400;
307
+ letter-spacing: -0.05em;
308
+ color: #1f2635;
309
+ }
310
+
311
+ .brand-title-static {
312
+ font-family: "Instrument Serif", serif;
313
+ font-size: clamp(1.5rem, 1.7vw, 1.85rem);
314
+ line-height: 0.92;
315
+ font-weight: 400;
316
+ letter-spacing: -0.05em;
317
+ text-transform: none;
318
+ color: #1f2635;
319
+ }
320
+
321
+ .brand-description {
322
+ min-width: 0;
323
+ color: #66758d;
324
+ font-size: 0.94rem;
325
+ }
326
+
327
+ .topbar-actions {
328
+ display: flex;
329
+ flex-wrap: wrap;
330
+ flex: 1 1 auto;
331
+ gap: 6px;
332
+ justify-content: flex-end;
333
+ min-width: 0;
334
+ }
335
+
336
+ .primary-nav {
337
+ display: flex;
338
+ flex-wrap: nowrap;
339
+ gap: 4px;
340
+ align-items: center;
341
+ justify-content: flex-end;
342
+ width: auto;
343
+ min-width: 0;
344
+ max-width: 100%;
345
+ padding: 3px;
346
+ border: 1px solid rgba(191, 164, 109, 0.28);
347
+ border-radius: 22px;
348
+ background: linear-gradient(180deg, rgba(247, 241, 230, 0.94), rgba(244, 236, 223, 0.96));
349
+ box-shadow:
350
+ inset 0 1px 0 rgba(255, 255, 255, 0.88),
351
+ 0 8px 18px rgba(138, 102, 32, 0.08);
352
+ }
353
+
354
+ .nav-link {
355
+ display: inline-flex;
356
+ flex: 0 0 auto;
357
+ align-items: center;
358
+ justify-content: center;
359
+ gap: 8px;
360
+ min-height: 38px;
361
+ padding: 0 14px;
362
+ white-space: nowrap;
363
+ border: 1px solid transparent;
364
+ border-radius: 16px;
365
+ color: #6f6451;
366
+ text-decoration: none;
367
+ font-size: 0.9rem;
368
+ font-weight: 600;
369
+ transition: background 160ms ease, color 160ms ease, border-color 160ms ease, box-shadow 160ms ease;
370
+ }
371
+
372
+ .nav-link:hover {
373
+ color: var(--ink);
374
+ }
375
+
376
+ .nav-link.is-active {
377
+ border-color: rgba(232, 223, 204, 0.9);
378
+ background: rgba(255, 252, 247, 0.96);
379
+ color: var(--ink);
380
+ box-shadow: 0 8px 20px rgba(101, 73, 18, 0.08);
381
+ }
382
+
383
+ .nav-icon,
384
+ .nav-icon svg {
385
+ width: 16px;
386
+ height: 16px;
387
+ }
388
+
389
+ .surface,
390
+ .surface-hero,
391
+ .surface-muted {
392
+ position: relative;
393
+ border-radius: var(--radius-md);
394
+ background: transparent;
395
+ }
396
+
397
+ .surface-hero {
398
+ background:
399
+ radial-gradient(circle at top right, rgba(195, 159, 86, 0.14), transparent 26%),
400
+ transparent;
401
+ }
402
+
403
+ h1,
404
+ h2,
405
+ h3 {
406
+ margin: 0;
407
+ color: #1f2635;
408
+ }
409
+
410
+ h1 {
411
+ font-family: "Instrument Serif", serif;
412
+ font-size: clamp(3rem, 5vw, 4.6rem);
413
+ line-height: 0.88;
414
+ font-weight: 400;
415
+ letter-spacing: -0.07em;
416
+ text-wrap: balance;
417
+ }
418
+
419
+ h2 {
420
+ font-family: "Instrument Serif", serif;
421
+ font-size: clamp(1.8rem, 2.8vw, 2.7rem);
422
+ line-height: 0.92;
423
+ font-weight: 400;
424
+ letter-spacing: -0.06em;
425
+ }
426
+
427
+ h3 {
428
+ font-size: 1.12rem;
429
+ line-height: 1.2;
430
+ font-weight: 600;
431
+ letter-spacing: -0.03em;
432
+ }
433
+
434
+ p {
435
+ margin: 0;
436
+ color: var(--muted);
437
+ line-height: 1.65;
438
+ }
439
+
440
+ .lede {
441
+ max-width: 56ch;
442
+ font-size: 0.98rem;
443
+ }
444
+
445
+ .hero-grid,
446
+ .split-grid,
447
+ .card-grid,
448
+ .stats-grid,
449
+ .field-grid,
450
+ .toolbar {
451
+ display: grid;
452
+ gap: 16px;
453
+ }
454
+
455
+ .hero-grid {
456
+ grid-template-columns: minmax(0, 1.55fr) minmax(280px, 0.85fr);
457
+ align-items: stretch;
458
+ }
459
+
460
+ .split-grid {
461
+ grid-template-columns: minmax(300px, 340px) minmax(0, 1fr);
462
+ }
463
+
464
+ .page-hero {
465
+ display: grid;
466
+ grid-template-columns: minmax(0, 1.55fr) minmax(260px, 0.85fr);
467
+ gap: 18px;
468
+ align-items: start;
469
+ }
470
+
471
+ .page-section {
472
+ display: grid;
473
+ gap: 14px;
474
+ }
475
+
476
+ .page-section-head {
477
+ display: flex;
478
+ align-items: end;
479
+ justify-content: space-between;
480
+ gap: 16px;
481
+ }
482
+
483
+ .metric-grid {
484
+ display: grid;
485
+ gap: 14px;
486
+ }
487
+
488
+ .metric {
489
+ display: grid;
490
+ gap: 8px;
491
+ }
492
+
493
+ .card-grid {
494
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
495
+ }
496
+
497
+ .stats-grid {
498
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
499
+ }
500
+
501
+ .field-grid.cols-2 {
502
+ grid-template-columns: repeat(2, minmax(0, 1fr));
503
+ }
504
+
505
+ .field-grid.cols-3 {
506
+ grid-template-columns: repeat(3, minmax(0, 1fr));
507
+ }
508
+
509
+ .stack {
510
+ display: grid;
511
+ gap: 16px;
512
+ }
513
+
514
+ .stack-lg {
515
+ display: grid;
516
+ gap: 22px;
517
+ }
518
+
519
+ .kicker {
520
+ display: inline-flex;
521
+ align-items: center;
522
+ gap: 10px;
523
+ min-height: 34px;
524
+ width: max-content;
525
+ max-width: 100%;
526
+ align-self: start;
527
+ padding: 0 14px;
528
+ border: 1px solid rgba(209, 219, 233, 0.96);
529
+ border-radius: 999px;
530
+ background: rgba(255, 255, 255, 0.9);
531
+ color: #6f7d95;
532
+ font-size: 11px;
533
+ font-weight: 700;
534
+ letter-spacing: 0.24em;
535
+ text-transform: uppercase;
536
+ }
537
+
538
+ .kicker.is-muted {
539
+ color: var(--muted);
540
+ }
541
+
542
+ .button,
543
+ button,
544
+ .link-button,
545
+ .cta-button {
546
+ display: inline-flex;
547
+ align-items: center;
548
+ justify-content: center;
549
+ gap: 10px;
550
+ min-height: 46px;
551
+ padding: 0 18px;
552
+ border: 1px solid rgba(219, 196, 146, 0.8);
553
+ border-radius: 999px;
554
+ background: #dec081;
555
+ color: #243041;
556
+ text-decoration: none;
557
+ font-size: 0.95rem;
558
+ font-weight: 600;
559
+ cursor: pointer;
560
+ transition:
561
+ transform 160ms ease,
562
+ border-color 160ms ease,
563
+ background 160ms ease,
564
+ box-shadow 160ms ease;
565
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
566
+ }
567
+
568
+ .button:hover,
569
+ button:hover,
570
+ .link-button:hover {
571
+ transform: translateY(-1px);
572
+ border-color: rgba(191, 164, 109, 0.9);
573
+ box-shadow:
574
+ inset 0 1px 0 rgba(255, 255, 255, 0.84),
575
+ 0 12px 28px rgba(118, 89, 38, 0.15);
576
+ }
577
+
578
+ .button.secondary,
579
+ button.secondary,
580
+ .link-button.secondary {
581
+ background: rgba(255, 255, 255, 0.88);
582
+ color: var(--ink);
583
+ }
584
+
585
+ .button.ghost,
586
+ button.ghost,
587
+ .link-button.ghost {
588
+ background: rgba(255, 255, 255, 0.34);
589
+ }
590
+
591
+ button[disabled] {
592
+ cursor: not-allowed;
593
+ opacity: 0.5;
594
+ transform: none;
595
+ box-shadow: none;
596
+ }
597
+
598
+ .input,
599
+ input,
600
+ select,
601
+ textarea {
602
+ width: 100%;
603
+ border: 1px solid var(--line);
604
+ border-radius: 999px;
605
+ background: rgba(255, 255, 255, 0.92);
606
+ color: var(--ink);
607
+ padding: 14px 16px;
608
+ outline: none;
609
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8);
610
+ }
611
+
612
+ textarea {
613
+ min-height: 140px;
614
+ border-radius: 24px;
615
+ resize: vertical;
616
+ }
617
+
618
+ input:focus,
619
+ select:focus,
620
+ textarea:focus {
621
+ border-color: rgba(191, 164, 109, 0.9);
622
+ box-shadow:
623
+ inset 0 1px 0 rgba(255, 255, 255, 0.9),
624
+ 0 0 0 4px var(--accent-soft);
625
+ }
626
+
627
+ label,
628
+ .label {
629
+ display: block;
630
+ margin-bottom: 8px;
631
+ color: var(--muted);
632
+ font-size: 11px;
633
+ font-weight: 700;
634
+ letter-spacing: 0.3em;
635
+ text-transform: uppercase;
636
+ }
637
+
638
+ .label-group {
639
+ display: grid;
640
+ gap: 8px;
641
+ }
642
+
643
+ .notice {
644
+ padding: 14px 16px;
645
+ border: 1px solid rgba(209, 219, 233, 0.96);
646
+ border-radius: 18px;
647
+ background: rgba(255, 255, 255, 0.82);
648
+ color: var(--ink);
649
+ }
650
+
651
+ .notice-success {
652
+ border-color: rgba(209, 219, 233, 0.96);
653
+ background: rgba(255, 255, 255, 0.82);
654
+ color: var(--ink);
655
+ }
656
+
657
+ .notice-error {
658
+ border-color: rgba(214, 107, 107, 0.35);
659
+ background: rgba(191, 38, 38, 0.1);
660
+ color: #7f1d1d;
661
+ }
662
+
663
+ .helper,
664
+ .tiny,
665
+ .meta-copy {
666
+ color: #7a879e;
667
+ font-size: 0.94rem;
668
+ }
669
+
670
+ .tiny {
671
+ font-size: 0.86rem;
672
+ }
673
+
674
+ .pill {
675
+ display: inline-flex;
676
+ align-items: center;
677
+ gap: 8px;
678
+ min-height: 34px;
679
+ padding: 0 12px;
680
+ border: 1px solid rgba(209, 219, 233, 0.96);
681
+ border-radius: 999px;
682
+ background: rgba(255, 255, 255, 0.9);
683
+ color: #6f7d95;
684
+ font-size: 11px;
685
+ font-weight: 700;
686
+ letter-spacing: 0.24em;
687
+ text-transform: uppercase;
688
+ }
689
+
690
+ .status-pill.is-active::before,
691
+ .pill.is-active::before {
692
+ content: "";
693
+ width: 8px;
694
+ height: 8px;
695
+ border-radius: 999px;
696
+ background: var(--accent);
697
+ box-shadow: 0 0 0 4px rgba(222, 192, 129, 0.22);
698
+ }
699
+
700
+ .status-row,
701
+ .toolbar {
702
+ display: flex;
703
+ flex-wrap: wrap;
704
+ align-items: center;
705
+ }
706
+
707
+ .toolbar,
708
+ .status-row {
709
+ gap: 10px;
710
+ }
711
+
712
+ .keyline {
713
+ height: 1px;
714
+ background: linear-gradient(90deg, rgba(112, 86, 34, 0), rgba(209, 219, 233, 0.96), rgba(112, 86, 34, 0));
715
+ }
716
+
717
+ .empty-state {
718
+ padding: 18px;
719
+ border: 1px dashed rgba(209, 219, 233, 0.96);
720
+ border-radius: 18px;
721
+ background: rgba(255, 255, 255, 0.5);
722
+ color: var(--muted);
723
+ }
724
+
725
+ .loading-inline {
726
+ display: inline-flex;
727
+ align-items: center;
728
+ gap: 10px;
729
+ }
730
+
731
+ .loading-spinner {
732
+ display: inline-block;
733
+ width: 16px;
734
+ height: 16px;
735
+ border: 2px solid rgba(36, 48, 65, 0.18);
736
+ border-top-color: rgba(36, 48, 65, 0.78);
737
+ border-radius: 999px;
738
+ animation: vidfarm-spin 0.8s linear infinite;
739
+ flex: 0 0 auto;
740
+ }
741
+
742
+ @keyframes vidfarm-spin {
743
+ to {
744
+ transform: rotate(360deg);
745
+ }
746
+ }
747
+
748
+ code,
749
+ pre {
750
+ font-family: "SFMono-Regular", Menlo, Consolas, monospace;
751
+ }
752
+
753
+ pre {
754
+ margin: 0;
755
+ border: 1px solid rgba(73, 57, 26, 0.18);
756
+ border-radius: 18px;
757
+ background: #211a12;
758
+ color: #f8eed6;
759
+ padding: 16px;
760
+ overflow: auto;
761
+ white-space: pre-wrap;
762
+ word-break: break-word;
763
+ }
764
+
765
+ ${input.style ?? ""}
766
+
767
+ @media (max-width: 767px) {
768
+ .hero-grid,
769
+ .split-grid,
770
+ .page-hero {
771
+ grid-template-columns: 1fr;
772
+ }
773
+ }
774
+
775
+ @media (max-width: 767px) {
776
+ html,
777
+ body {
778
+ height: auto;
779
+ min-height: 100%;
780
+ overflow: auto;
781
+ overflow-x: hidden;
782
+ }
783
+
784
+ .app-shell,
785
+ .app-shell.is-wide,
786
+ .app-shell.is-narrow {
787
+ width: min(100vw - 14px, 1980px);
788
+ height: auto;
789
+ min-height: 100svh;
790
+ padding-top: 8px;
791
+ padding-bottom: 18px;
792
+ }
793
+
794
+ .page-stack,
795
+ .frame {
796
+ height: auto;
797
+ min-height: 0;
798
+ overflow: visible;
799
+ }
800
+
801
+ .topbar {
802
+ min-height: auto;
803
+ padding: 8px;
804
+ border-radius: 24px;
805
+ align-items: center;
806
+ flex-wrap: nowrap;
807
+ gap: 8px;
808
+ }
809
+
810
+ .brand-lockup {
811
+ flex: 0 0 auto;
812
+ width: auto;
813
+ gap: 7px;
814
+ }
815
+
816
+ .brand-copy {
817
+ display: flex;
818
+ flex: 0 0 auto;
819
+ min-width: 0;
820
+ gap: 0;
821
+ flex-wrap: nowrap;
822
+ }
823
+
824
+ .brand-title-static {
825
+ font-size: 1.24rem;
826
+ line-height: 1;
827
+ }
828
+
829
+ .brand-account-meta {
830
+ display: none;
831
+ }
832
+
833
+ .brand-title-mobile-hidden {
834
+ display: none;
835
+ }
836
+
837
+ .topbar-actions {
838
+ flex: 1 1 auto;
839
+ width: auto;
840
+ justify-content: flex-end;
841
+ overflow: visible;
842
+ padding-bottom: 0;
843
+ scrollbar-width: none;
844
+ }
845
+
846
+ .topbar-actions::-webkit-scrollbar {
847
+ display: none;
848
+ }
849
+
850
+ .brand-logo-image {
851
+ height: 32px;
852
+ max-width: 38px;
853
+ }
854
+
855
+ .primary-nav {
856
+ min-width: 0;
857
+ width: auto;
858
+ max-width: 100%;
859
+ flex-wrap: nowrap;
860
+ justify-content: flex-end;
861
+ gap: 2px;
862
+ padding: 2px;
863
+ border-radius: 18px;
864
+ overflow: hidden;
865
+ }
866
+
867
+ .nav-link {
868
+ flex: 0 1 auto;
869
+ min-height: 34px;
870
+ gap: 4px;
871
+ padding: 0 6px;
872
+ border-radius: 14px;
873
+ font-size: 0.68rem;
874
+ }
875
+
876
+ .nav-link > span:not(.nav-icon) {
877
+ display: inline;
878
+ min-width: 0;
879
+ overflow: visible;
880
+ text-overflow: clip;
881
+ white-space: nowrap;
882
+ }
883
+
884
+ .nav-icon,
885
+ .nav-icon svg {
886
+ width: 12px;
887
+ height: 12px;
888
+ }
889
+
890
+ @media (max-width: 374px) {
891
+ .topbar {
892
+ gap: 6px;
893
+ }
894
+
895
+ .brand-logo-image {
896
+ height: 30px;
897
+ max-width: 34px;
898
+ }
899
+
900
+ .brand-lockup {
901
+ gap: 5px;
902
+ }
903
+
904
+ .brand-title-static {
905
+ font-size: 1.08rem;
906
+ }
907
+
908
+ .primary-nav {
909
+ gap: 1px;
910
+ }
911
+
912
+ .nav-link {
913
+ gap: 3px;
914
+ padding: 0 4px;
915
+ font-size: 0.62rem;
916
+ }
917
+ }
918
+
919
+ .field-grid.cols-2,
920
+ .field-grid.cols-3 {
921
+ grid-template-columns: 1fr;
922
+ }
923
+
924
+ h1 {
925
+ font-size: clamp(2.2rem, 14vw, 3.2rem);
926
+ }
927
+ }
928
+ </style>
929
+ </head>
930
+ <body>
931
+ <main class="app-shell${input.mainClass ? ` ${escapeHtml(input.mainClass)}` : ""}">
932
+ <div class="page-stack${input.shellClass ? ` ${escapeHtml(input.shellClass)}` : ""}">
933
+ ${input.body}
934
+ </div>
935
+ </main>
936
+ ${input.runtimeBoot ? `<div id="page-runtime-root" hidden></div>
937
+ <script id="page-runtime-boot" type="application/json">${escapeJsonForHtml(input.runtimeBoot)}</script>
938
+ <script type="module" src="/assets/page-runtime-client-app.js"></script>` : ""}
939
+ </body>
940
+ </html>`;
941
+ }