@mevdragon/vidfarm-devcli 0.5.3 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +3 -3
  2. package/SKILL.director.md +28 -7
  3. package/SKILL.platform.md +9 -5
  4. package/demo/README.md +28 -0
  5. package/demo/dist/app.css +1 -0
  6. package/demo/dist/app.js +1184 -0
  7. package/demo/dist/chunks/chunk-DXB73IDG.js +1 -0
  8. package/demo/dist/chunks/chunk-S7OWAJDS.js +36 -0
  9. package/demo/dist/chunks/chunk-VTIBZ6AN.js +1 -0
  10. package/demo/dist/chunks/dist-ADSJKBVE.js +332 -0
  11. package/demo/dist/chunks/domEditingLayers-VZMLL4AP-SGHWPND4.js +1 -0
  12. package/demo/dist/chunks/hyperframes-player-XB65TCD6.js +425 -0
  13. package/demo/dist/chunks/lib-XAQ37YOE.js +1 -0
  14. package/demo/dist/chunks/src-TJ2QYA4U.js +207 -0
  15. package/demo/dist/favicon.ico +0 -0
  16. package/demo/dist/icons/timeline/audio.svg +7 -0
  17. package/demo/dist/icons/timeline/captions.svg +5 -0
  18. package/demo/dist/icons/timeline/composition.svg +12 -0
  19. package/demo/dist/icons/timeline/image.svg +18 -0
  20. package/demo/dist/icons/timeline/music.svg +10 -0
  21. package/demo/dist/icons/timeline/text.svg +3 -0
  22. package/demo/dist/index.html +15 -0
  23. package/dist/src/account-pages-legacy.js +9396 -0
  24. package/dist/src/account-pages.js +61 -0
  25. package/dist/src/app.js +14663 -0
  26. package/dist/src/cli.js +60 -97
  27. package/dist/src/composition-runtime.js +613 -0
  28. package/dist/src/config.js +173 -0
  29. package/dist/src/context.js +447 -0
  30. package/dist/src/dev-app-legacy.js +739 -0
  31. package/dist/src/dev-app.js +6 -0
  32. package/dist/src/domain.js +2 -0
  33. package/dist/src/editor-chat-history.js +82 -0
  34. package/dist/src/editor-chat.js +449 -0
  35. package/dist/src/editor-dark-theme.js +1128 -0
  36. package/dist/src/frontend/debug.js +71 -0
  37. package/dist/src/frontend/flockposter-cache-store.js +124 -0
  38. package/dist/src/frontend/homepage-client.js +182 -0
  39. package/dist/src/frontend/homepage-shared.js +4 -0
  40. package/dist/src/frontend/homepage-store.js +28 -0
  41. package/dist/src/frontend/homepage-view.js +547 -0
  42. package/dist/src/frontend/page-runtime-client.js +132 -0
  43. package/dist/src/frontend/page-runtime-store.js +9 -0
  44. package/dist/src/frontend/sentry.js +42 -0
  45. package/dist/src/frontend/template-editor-chat.js +3960 -0
  46. package/dist/src/help-page.js +346 -0
  47. package/dist/src/homepage.js +1235 -0
  48. package/dist/src/hyperframes/composition.js +180 -0
  49. package/dist/src/index.js +16 -0
  50. package/dist/src/instrument.js +30 -0
  51. package/dist/src/lib/crypto.js +45 -0
  52. package/dist/src/lib/dev-log.js +54 -0
  53. package/dist/src/lib/display-name.js +11 -0
  54. package/dist/src/lib/ids.js +24 -0
  55. package/dist/src/lib/images.js +19 -0
  56. package/dist/src/lib/json.js +15 -0
  57. package/dist/src/lib/package-root.js +47 -0
  58. package/dist/src/lib/template-paths.js +28 -0
  59. package/dist/src/lib/time.js +7 -0
  60. package/dist/src/lib/url-clean.js +85 -0
  61. package/dist/src/page-runtime.js +2 -0
  62. package/dist/src/page-shell.js +1381 -0
  63. package/dist/src/primitive-context.js +357 -0
  64. package/dist/src/primitive-registry.js +2561 -0
  65. package/dist/src/primitive-sdk.js +4 -0
  66. package/dist/src/primitives/hyperframes-media.js +108 -0
  67. package/dist/src/react-page-shell.js +35 -0
  68. package/dist/src/ready-post-schedule-component.js +1540 -0
  69. package/dist/src/registry.js +296 -0
  70. package/dist/src/runtime.js +35 -0
  71. package/dist/src/services/api-call-history.js +249 -0
  72. package/dist/src/services/auth.js +152 -0
  73. package/dist/src/services/billing-pricing.js +39 -0
  74. package/dist/src/services/billing.js +228 -0
  75. package/dist/src/services/cast.js +127 -0
  76. package/dist/src/services/chat-threads.js +92 -0
  77. package/dist/src/services/composition-sanitize.js +124 -0
  78. package/dist/src/services/composition-watch.js +79 -0
  79. package/dist/src/services/fork-access.js +93 -0
  80. package/dist/src/services/fork-manifest.js +42 -0
  81. package/dist/src/services/ghostcut.js +179 -0
  82. package/dist/src/services/hyperframes.js +2307 -0
  83. package/dist/src/services/job-capacity.js +14 -0
  84. package/dist/src/services/job-logs.js +197 -0
  85. package/dist/src/services/jobs.js +136 -0
  86. package/dist/src/services/local-dynamo.js +0 -0
  87. package/dist/src/services/media-processing.js +766 -0
  88. package/dist/src/services/primitive-media-lambda.js +280 -0
  89. package/dist/src/services/providers.js +2926 -0
  90. package/dist/src/services/rate-limits.js +262 -0
  91. package/dist/src/services/serverless-auth.js +382 -0
  92. package/dist/src/services/serverless-jobs.js +1082 -0
  93. package/dist/src/services/serverless-provider-keys.js +409 -0
  94. package/dist/src/services/serverless-records.js +1385 -0
  95. package/dist/src/services/serverless-template-configs.js +75 -0
  96. package/dist/src/services/storage.js +383 -0
  97. package/dist/src/services/template-certification.js +413 -0
  98. package/dist/src/services/template-loader.js +99 -0
  99. package/dist/src/services/template-runtime-bundles.js +217 -0
  100. package/dist/src/services/template-sources.js +1017 -0
  101. package/dist/src/services/upstream.js +248 -0
  102. package/dist/src/services/video-normalization.js +2 -0
  103. package/dist/src/services/webhooks.js +62 -0
  104. package/dist/src/template-editor-pages.js +2576 -0
  105. package/dist/src/template-editor-shell.js +2840 -0
  106. package/dist/src/template-sdk.js +4 -0
  107. package/dist/src/worker.js +17 -0
  108. package/package.json +6 -4
  109. package/public/assets/homepage-app.js +54 -0
  110. package/public/assets/homepage-client-app.js +80 -0
  111. package/public/assets/page-runtime-client-app.js +94 -0
  112. package/src/assets/SELLING_AWARENESS_STAGES.md +579 -0
  113. package/src/assets/SELLING_WITH_HOOKS.md +377 -0
  114. package/src/assets/SELLING_WITH_VSLS.md +606 -0
  115. package/src/assets/favicon.ico +0 -0
  116. package/src/assets/logo-vidfarm.png +0 -0
@@ -0,0 +1,1381 @@
1
+ import { EDITOR_DARK_THEME_CSS } from "./editor-dark-theme.js";
2
+ export function escapeHtml(value) {
3
+ return value
4
+ .replace(/&/g, "&")
5
+ .replace(/</g, "&lt;")
6
+ .replace(/>/g, "&gt;")
7
+ .replace(/"/g, "&quot;");
8
+ }
9
+ export function escapeAttribute(value) {
10
+ return escapeHtml(value).replace(/'/g, "&#39;");
11
+ }
12
+ export function escapeJsonForHtml(value) {
13
+ return JSON.stringify(value)
14
+ .replace(/</g, "\\u003c")
15
+ .replace(/>/g, "\\u003e")
16
+ .replace(/&/g, "\\u0026");
17
+ }
18
+ export function withAccountQuery(href, accountId) {
19
+ if (!accountId || !href.startsWith("/")) {
20
+ return href;
21
+ }
22
+ const url = new URL(href, "https://vidfarm.local");
23
+ if (url.pathname.startsWith("/u/")) {
24
+ return `${url.pathname}${url.search}${url.hash}`;
25
+ }
26
+ if (url.pathname === "/discover" || url.pathname.startsWith("/discover/") || url.pathname === "/help") {
27
+ return `${url.pathname}${url.search}${url.hash}`;
28
+ }
29
+ return `/u/${encodeURIComponent(accountId)}${url.pathname}${url.search}${url.hash}`;
30
+ }
31
+ export function resolveAccountDisplayName(input) {
32
+ const email = input?.email?.trim() || "";
33
+ const displayName = input?.displayName?.trim() || "";
34
+ if (displayName) {
35
+ return displayName;
36
+ }
37
+ if (!email) {
38
+ return "";
39
+ }
40
+ return email
41
+ .split("@")[0]
42
+ .replace(/[._-]+/g, " ")
43
+ .replace(/\b\w/g, (match) => match.toUpperCase());
44
+ }
45
+ function renderNavIcon(kind) {
46
+ if (kind === "discover") {
47
+ 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>`;
48
+ }
49
+ if (kind === "library") {
50
+ 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>`;
51
+ }
52
+ if (kind === "calendar") {
53
+ 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>`;
54
+ }
55
+ if (kind === "chat") {
56
+ return `<svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M4.2 5.2a2 2 0 0 1 2-2h7.6a2 2 0 0 1 2 2v5.6a2 2 0 0 1-2 2H9.2l-4.1 3.1v-3.1a2 2 0 0 1-.9-1.7Z"/><path d="M7.3 7.1h5.4"/><path d="M7.3 9.6h3.7"/></svg>`;
57
+ }
58
+ if (kind === "settings") {
59
+ 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>`;
60
+ }
61
+ if (kind === "help") {
62
+ 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="M8.1 8a2.2 2.2 0 1 1 3.7 1.6c-.8.7-1.4 1.1-1.4 2.2"/><path d="M10 14.8h.01"/></svg>`;
63
+ }
64
+ return `<svg viewBox="0 0 20 20" fill="currentColor"><circle cx="4.2" cy="10" r="1.45"/><circle cx="10" cy="10" r="1.45"/><circle cx="15.8" cy="10" r="1.45"/></svg>`;
65
+ }
66
+ function renderMenuIcon() {
67
+ return `<svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"><path d="M3.5 5.5h13"/><path d="M3.5 10h13"/><path d="M3.5 14.5h13"/></svg>`;
68
+ }
69
+ export function renderPrimaryNav(input) {
70
+ const items = input.loggedIn
71
+ ? [
72
+ { id: "discover", href: withAccountQuery("/discover", input.accountId), label: "Discover", icon: renderNavIcon("discover") },
73
+ { id: "library", href: withAccountQuery("/library", input.accountId), label: "Library", icon: renderNavIcon("library") },
74
+ { id: "calendar", href: withAccountQuery("/calendar", input.accountId), label: "Calendar", icon: renderNavIcon("calendar") },
75
+ { id: "settings", href: withAccountQuery("/settings", input.accountId), label: "Settings", icon: renderNavIcon("settings") }
76
+ ]
77
+ : [
78
+ { id: "discover", href: "/discover", label: "Discover", icon: renderNavIcon("discover") },
79
+ { id: "login", href: "/login", label: "Login", icon: renderNavIcon("settings") }
80
+ ];
81
+ const menuItems = input.loggedIn
82
+ ? [
83
+ { id: "chat", href: withAccountQuery("/chat", input.accountId), label: "Chat" },
84
+ { id: "job-runs", href: withAccountQuery("/job-runs", input.accountId), label: "Run History" },
85
+ { id: "inpaint", href: withAccountQuery("/inpaint", input.accountId), label: "Inpaint" },
86
+ { id: "help", href: "/help", label: "Help" },
87
+ { id: "logout", action: "logout", label: "Log Out" }
88
+ ]
89
+ : [
90
+ { id: "help", href: "/help", label: "Help" },
91
+ { id: "login", href: "/login", label: "Login" }
92
+ ];
93
+ const mobileMenuPrimaryItems = items.filter((item) => !menuItems.some((menuItem) => menuItem.id === item.id));
94
+ const logoutDialog = input.loggedIn ? `
95
+ <dialog class="logout-dialog" data-logout-dialog>
96
+ <div class="logout-dialog-head">
97
+ <div class="label logout-dialog-kicker">Log out</div>
98
+ <h3>Log out of this browser?</h3>
99
+ <p>This clears the stored developer key, workspace access, and local session state for the current browser.</p>
100
+ </div>
101
+ <div class="toolbar logout-dialog-actions">
102
+ <button type="button" class="secondary" data-close-logout-dialog>Cancel</button>
103
+ <form method="post" action="/logout" data-logout-form>
104
+ <input type="hidden" name="account" value="${escapeAttribute(input.accountId ?? "")}" />
105
+ <button type="submit" class="danger">Yes, log out</button>
106
+ </form>
107
+ </div>
108
+ </dialog>
109
+ ` : "";
110
+ return `
111
+ <nav class="primary-nav" aria-label="Primary">
112
+ ${items.map((item) => `
113
+ <a class="nav-link${item.id === input.current ? " is-active" : ""}" href="${item.href}">
114
+ <span class="nav-icon" aria-hidden="true">${item.icon}</span>
115
+ <span>${item.label}</span>
116
+ </a>
117
+ `).join("")}
118
+ ${menuItems.map((item) => `
119
+ ${"href" in item ? `
120
+ <a class="nav-link nav-mobile-extra${item.id === input.current ? " is-active" : ""}" href="${escapeAttribute(item.href ?? "#")}">
121
+ <span>${escapeHtml(item.label)}</span>
122
+ </a>
123
+ ` : `
124
+ <button type="button" class="nav-link nav-mobile-extra nav-action-link" data-open-logout-dialog>
125
+ <span>${escapeHtml(item.label)}</span>
126
+ </button>
127
+ `}
128
+ `).join("")}
129
+ ${menuItems.length ? `
130
+ <details class="nav-menu">
131
+ <summary class="nav-link nav-menu-trigger" aria-label="Open navigation menu">
132
+ <span class="nav-icon nav-menu-desktop-icon" aria-hidden="true">${renderNavIcon("more")}</span>
133
+ <span class="nav-icon nav-menu-mobile-icon" aria-hidden="true">${renderMenuIcon()}</span>
134
+ <span class="nav-menu-label">Menu</span>
135
+ </summary>
136
+ <div class="nav-menu-panel" role="menu">
137
+ ${mobileMenuPrimaryItems.map((item) => `
138
+ <a class="nav-menu-item nav-menu-mobile-only${item.id === input.current ? " is-active" : ""}" role="menuitem" href="${escapeAttribute(item.href ?? "#")}">${escapeHtml(item.label)}</a>
139
+ `).join("")}
140
+ ${menuItems.map((item) => `
141
+ ${"href" in item ? `
142
+ <a class="nav-menu-item${item.id === input.current ? " is-active" : ""}" role="menuitem" href="${escapeAttribute(item.href ?? "#")}">${escapeHtml(item.label)}</a>
143
+ ` : `
144
+ <button type="button" class="nav-menu-item nav-menu-button" role="menuitem" data-open-logout-dialog>${escapeHtml(item.label)}</button>
145
+ `}
146
+ `).join("")}
147
+ </div>
148
+ </details>
149
+ ` : ""}
150
+ </nav>
151
+ ${logoutDialog}
152
+ `;
153
+ }
154
+ export function renderBrandLockup(input) {
155
+ const email = input?.email?.trim() || "";
156
+ const derivedName = resolveAccountDisplayName(input);
157
+ const href = withAccountQuery("/discover", input?.accountId);
158
+ const accountMeta = email
159
+ ? `<div class="brand-account-meta">${escapeHtml(derivedName)} <span>(${escapeHtml(email)})</span></div>`
160
+ : "";
161
+ return `
162
+ <a class="brand-lockup" href="${escapeAttribute(href)}">
163
+ <img class="brand-logo-image" src="/assets/logo-vidfarm.png" alt="VidFarm AI" />
164
+ <div class="brand-copy">
165
+ <div class="brand-title brand-title-static">VidFarm<span class="brand-title-mobile-hidden"> AI</span></div>
166
+ ${accountMeta}
167
+ </div>
168
+ </a>
169
+ `;
170
+ }
171
+ export function renderPageShell(input) {
172
+ const isEditorTheme = input.bodyClass?.split(/\s+/).includes("is-editor-theme") ?? false;
173
+ return `<!doctype html>
174
+ <html lang="en">
175
+ <head>
176
+ <meta charset="utf-8" />
177
+ <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
178
+ <title>${escapeHtml(input.title)}</title>
179
+ <link rel="icon" href="/assets/favicon.ico" sizes="any" />
180
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
181
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
182
+ <link href="https://fonts.googleapis.com/css2?family=Bebas+Neue&family=Instrument+Serif:ital@0;1&family=JetBrains+Mono:wght@500;600;700;800&family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet" />
183
+ <style>
184
+ :root {
185
+ color-scheme: light;
186
+ --bg: #f8f4eb;
187
+ --paper: rgba(255, 252, 247, 0.88);
188
+ --paper-strong: rgba(255, 252, 247, 0.96);
189
+ --panel: transparent;
190
+ --panel-muted: rgba(250, 245, 234, 0.9);
191
+ --ink: #2f3748;
192
+ --muted: #74829c;
193
+ --line: rgba(209, 219, 233, 0.9);
194
+ --line-strong: rgba(191, 164, 109, 0.42);
195
+ --accent: #dec081;
196
+ --accent-deep: #243041;
197
+ --accent-soft: rgba(222, 192, 129, 0.18);
198
+ --shadow: 0 24px 80px rgba(15, 23, 42, 0.08);
199
+ --shadow-soft: 0 16px 36px rgba(148, 109, 42, 0.08);
200
+ --radius-lg: 32px;
201
+ --radius-md: 26px;
202
+ --radius-sm: 18px;
203
+ }
204
+
205
+ * {
206
+ box-sizing: border-box;
207
+ }
208
+
209
+ html {
210
+ height: 100%;
211
+ min-height: 100%;
212
+ overflow: hidden;
213
+ }
214
+
215
+ body {
216
+ margin: 0;
217
+ height: 100%;
218
+ min-height: 100%;
219
+ overflow: hidden;
220
+ color: var(--ink);
221
+ font-family: "Manrope", sans-serif;
222
+ background:
223
+ radial-gradient(circle at 12% 18%, rgba(222, 192, 129, 0.28), transparent 24%),
224
+ radial-gradient(circle at 84% 12%, rgba(123, 92, 29, 0.12), transparent 22%),
225
+ linear-gradient(180deg, rgba(255, 255, 255, 0.65), rgba(255, 255, 255, 0)),
226
+ linear-gradient(145deg, #f8f4eb 0%, #f1e7d3 52%, #e9dbba 100%);
227
+ background-attachment: fixed;
228
+ }
229
+
230
+ body::before {
231
+ content: "";
232
+ position: fixed;
233
+ inset: 0;
234
+ pointer-events: none;
235
+ background-image:
236
+ linear-gradient(rgba(96, 74, 36, 0.035) 1px, transparent 1px),
237
+ linear-gradient(90deg, rgba(96, 74, 36, 0.035) 1px, transparent 1px);
238
+ background-size: 30px 30px;
239
+ mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0.38), transparent 86%);
240
+ }
241
+
242
+ a {
243
+ color: inherit;
244
+ }
245
+
246
+ button,
247
+ input,
248
+ select,
249
+ textarea {
250
+ font: inherit;
251
+ }
252
+
253
+ .app-shell {
254
+ width: min(1980px, calc(100vw - 40px));
255
+ margin: 0 auto;
256
+ height: 100dvh;
257
+ min-height: 0;
258
+ padding: 20px 0 28px;
259
+ }
260
+
261
+ .app-shell.is-wide {
262
+ width: min(1980px, calc(100vw - 40px));
263
+ }
264
+
265
+ .app-shell.is-narrow {
266
+ width: min(1980px, calc(100vw - 40px));
267
+ }
268
+
269
+ .page-stack {
270
+ display: grid;
271
+ height: 100%;
272
+ min-height: 0;
273
+ gap: 18px;
274
+ }
275
+
276
+ .frame {
277
+ position: relative;
278
+ display: grid;
279
+ grid-template-rows: auto minmax(0, 1fr);
280
+ min-height: 0;
281
+ overflow: hidden;
282
+ border-radius: var(--radius-lg);
283
+ background: var(--panel);
284
+ }
285
+
286
+ .frame-body {
287
+ display: grid;
288
+ min-height: 0;
289
+ gap: 20px;
290
+ padding: 14px 0 0;
291
+ }
292
+
293
+ .topbar {
294
+ display: flex;
295
+ align-items: center;
296
+ justify-content: space-between;
297
+ gap: 12px;
298
+ min-height: 76px;
299
+ padding: 10px 16px 10px 20px;
300
+ border: 1px solid rgba(255, 255, 255, 0.82);
301
+ border-radius: var(--radius-lg);
302
+ background: var(--paper);
303
+ box-shadow: var(--shadow);
304
+ }
305
+
306
+ .brand-lockup {
307
+ display: flex;
308
+ flex: 1 1 min(0, 58%);
309
+ align-items: center;
310
+ gap: 14px;
311
+ min-width: 0;
312
+ color: inherit;
313
+ text-decoration: none;
314
+ }
315
+
316
+ .brand-lockup:hover,
317
+ .brand-lockup:focus {
318
+ text-decoration: none;
319
+ }
320
+
321
+ .brand-logo-image {
322
+ display: block;
323
+ width: auto;
324
+ height: 44px;
325
+ max-width: min(220px, 38vw);
326
+ object-fit: contain;
327
+ object-position: left center;
328
+ flex: 0 0 auto;
329
+ border-radius: 12px;
330
+ }
331
+
332
+ .brand-mark {
333
+ display: inline-flex;
334
+ align-items: center;
335
+ justify-content: center;
336
+ width: 38px;
337
+ height: 38px;
338
+ border-radius: 999px;
339
+ background: #111934;
340
+ color: #f3e8cd;
341
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
342
+ }
343
+
344
+ .brand-mark svg {
345
+ width: 20px;
346
+ height: 20px;
347
+ }
348
+
349
+ .brand-copy {
350
+ display: flex;
351
+ align-items: center;
352
+ gap: 10px;
353
+ min-width: 0;
354
+ flex-wrap: wrap;
355
+ }
356
+
357
+ .brand-account-meta {
358
+ min-width: 0;
359
+ color: rgba(116, 130, 156, 0.78);
360
+ font-size: 0.94rem;
361
+ line-height: 1.2;
362
+ font-weight: 500;
363
+ letter-spacing: -0.01em;
364
+ white-space: nowrap;
365
+ overflow: hidden;
366
+ text-overflow: ellipsis;
367
+ }
368
+
369
+ .brand-account-meta span {
370
+ color: rgba(116, 130, 156, 0.62);
371
+ }
372
+
373
+ .eyebrow {
374
+ font-size: 10px;
375
+ font-weight: 700;
376
+ letter-spacing: 0.28em;
377
+ text-transform: uppercase;
378
+ color: var(--muted);
379
+ }
380
+
381
+ .brand-title {
382
+ font-family: "Instrument Serif", serif;
383
+ font-size: clamp(1.65rem, 1.85vw, 2rem);
384
+ line-height: 0.92;
385
+ font-weight: 400;
386
+ letter-spacing: -0.05em;
387
+ color: #1f2635;
388
+ }
389
+
390
+ .brand-title-static {
391
+ font-family: "Instrument Serif", serif;
392
+ font-size: clamp(1.5rem, 1.7vw, 1.85rem);
393
+ line-height: 0.92;
394
+ font-weight: 400;
395
+ letter-spacing: -0.05em;
396
+ text-transform: none;
397
+ color: #1f2635;
398
+ }
399
+
400
+ .brand-description {
401
+ min-width: 0;
402
+ color: #66758d;
403
+ font-size: 0.94rem;
404
+ }
405
+
406
+ .topbar-actions {
407
+ display: flex;
408
+ flex-wrap: wrap;
409
+ flex: 1 1 auto;
410
+ gap: 6px;
411
+ justify-content: flex-end;
412
+ min-width: 0;
413
+ }
414
+
415
+ .primary-nav {
416
+ display: flex;
417
+ flex-wrap: nowrap;
418
+ gap: 4px;
419
+ align-items: center;
420
+ justify-content: flex-end;
421
+ width: auto;
422
+ min-width: 0;
423
+ max-width: 100%;
424
+ padding: 3px;
425
+ border: 1px solid rgba(191, 164, 109, 0.28);
426
+ border-radius: 22px;
427
+ background: linear-gradient(180deg, rgba(247, 241, 230, 0.94), rgba(244, 236, 223, 0.96));
428
+ box-shadow:
429
+ inset 0 1px 0 rgba(255, 255, 255, 0.88),
430
+ 0 8px 18px rgba(138, 102, 32, 0.08);
431
+ }
432
+
433
+ .nav-link {
434
+ display: inline-flex;
435
+ flex: 0 0 auto;
436
+ align-items: center;
437
+ justify-content: center;
438
+ gap: 8px;
439
+ min-height: 38px;
440
+ padding: 0 14px;
441
+ white-space: nowrap;
442
+ border: 1px solid transparent;
443
+ border-radius: 16px;
444
+ color: #6f6451;
445
+ text-decoration: none;
446
+ font-size: 0.9rem;
447
+ font-weight: 600;
448
+ transition: background 160ms ease, color 160ms ease, border-color 160ms ease, box-shadow 160ms ease;
449
+ }
450
+
451
+ .nav-link:hover {
452
+ color: var(--ink);
453
+ }
454
+
455
+ .nav-link.is-active {
456
+ border-color: rgba(232, 223, 204, 0.9);
457
+ background: rgba(255, 252, 247, 0.96);
458
+ color: var(--ink);
459
+ box-shadow: 0 8px 20px rgba(101, 73, 18, 0.08);
460
+ }
461
+
462
+ .nav-menu {
463
+ position: relative;
464
+ flex: 0 0 auto;
465
+ }
466
+
467
+ .nav-menu > summary {
468
+ list-style: none;
469
+ cursor: pointer;
470
+ }
471
+
472
+ .nav-menu > summary::-webkit-details-marker {
473
+ display: none;
474
+ }
475
+
476
+ .nav-menu-trigger {
477
+ min-width: 34px;
478
+ padding: 0 8px;
479
+ color: rgba(111, 100, 81, 0.68);
480
+ }
481
+
482
+ .nav-menu-trigger:hover,
483
+ .nav-menu[open] > .nav-menu-trigger {
484
+ color: rgba(47, 55, 72, 0.82);
485
+ }
486
+
487
+ .nav-menu-label {
488
+ display: none;
489
+ }
490
+
491
+ .nav-menu-mobile-icon,
492
+ .nav-menu-mobile-only {
493
+ display: none;
494
+ }
495
+
496
+ .nav-menu-panel {
497
+ position: absolute;
498
+ z-index: 40;
499
+ top: calc(100% + 8px);
500
+ right: 0;
501
+ display: grid;
502
+ width: max-content;
503
+ min-width: 142px;
504
+ padding: 6px;
505
+ border: 1px solid rgba(191, 164, 109, 0.3);
506
+ border-radius: 14px;
507
+ background: rgba(255, 252, 247, 0.98);
508
+ box-shadow: 0 18px 38px rgba(81, 58, 20, 0.15);
509
+ }
510
+
511
+ .nav-menu-item {
512
+ display: flex;
513
+ align-items: center;
514
+ justify-content: flex-start;
515
+ width: 100%;
516
+ min-height: 34px;
517
+ padding: 0 10px;
518
+ border: 0;
519
+ border-radius: 10px;
520
+ background: transparent;
521
+ color: #5d6a80;
522
+ font-size: 0.88rem;
523
+ font-weight: 700;
524
+ font-family: inherit;
525
+ text-align: left;
526
+ text-decoration: none;
527
+ white-space: nowrap;
528
+ cursor: pointer;
529
+ }
530
+
531
+ .nav-menu-item:hover,
532
+ .nav-menu-item.is-active {
533
+ background: rgba(244, 236, 223, 0.86);
534
+ color: var(--ink);
535
+ }
536
+
537
+ .nav-menu-item.nav-menu-mobile-only {
538
+ display: none;
539
+ }
540
+
541
+ .nav-action-link {
542
+ border: 1px solid transparent;
543
+ background: transparent;
544
+ font-family: inherit;
545
+ }
546
+
547
+ .nav-mobile-extra {
548
+ display: none;
549
+ }
550
+
551
+ .nav-icon,
552
+ .nav-icon svg {
553
+ width: 16px;
554
+ height: 16px;
555
+ }
556
+
557
+ .surface,
558
+ .surface-hero,
559
+ .surface-muted {
560
+ position: relative;
561
+ border-radius: var(--radius-md);
562
+ background: transparent;
563
+ }
564
+
565
+ .surface-hero {
566
+ background:
567
+ radial-gradient(circle at top right, rgba(195, 159, 86, 0.14), transparent 26%),
568
+ transparent;
569
+ }
570
+
571
+ h1,
572
+ h2,
573
+ h3 {
574
+ margin: 0;
575
+ color: #1f2635;
576
+ }
577
+
578
+ h1 {
579
+ font-family: "Instrument Serif", serif;
580
+ font-size: clamp(3rem, 5vw, 4.6rem);
581
+ line-height: 0.88;
582
+ font-weight: 400;
583
+ letter-spacing: -0.07em;
584
+ text-wrap: balance;
585
+ }
586
+
587
+ h2 {
588
+ font-family: "Instrument Serif", serif;
589
+ font-size: clamp(1.8rem, 2.8vw, 2.7rem);
590
+ line-height: 0.92;
591
+ font-weight: 400;
592
+ letter-spacing: -0.06em;
593
+ }
594
+
595
+ h3 {
596
+ font-size: 1.12rem;
597
+ line-height: 1.2;
598
+ font-weight: 600;
599
+ letter-spacing: -0.03em;
600
+ }
601
+
602
+ p {
603
+ margin: 0;
604
+ color: var(--muted);
605
+ line-height: 1.65;
606
+ }
607
+
608
+ .lede {
609
+ max-width: 56ch;
610
+ font-size: 0.98rem;
611
+ }
612
+
613
+ .hero-grid,
614
+ .split-grid,
615
+ .card-grid,
616
+ .stats-grid,
617
+ .field-grid,
618
+ .toolbar {
619
+ display: grid;
620
+ gap: 16px;
621
+ }
622
+
623
+ .hero-grid {
624
+ grid-template-columns: minmax(0, 1.55fr) minmax(280px, 0.85fr);
625
+ align-items: stretch;
626
+ }
627
+
628
+ .split-grid {
629
+ grid-template-columns: minmax(300px, 340px) minmax(0, 1fr);
630
+ }
631
+
632
+ .page-hero {
633
+ display: grid;
634
+ grid-template-columns: minmax(0, 1.55fr) minmax(260px, 0.85fr);
635
+ gap: 18px;
636
+ align-items: start;
637
+ }
638
+
639
+ .page-section {
640
+ display: grid;
641
+ gap: 14px;
642
+ }
643
+
644
+ .page-section-head {
645
+ display: flex;
646
+ align-items: end;
647
+ justify-content: space-between;
648
+ gap: 16px;
649
+ }
650
+
651
+ .metric-grid {
652
+ display: grid;
653
+ gap: 14px;
654
+ }
655
+
656
+ .metric {
657
+ display: grid;
658
+ gap: 8px;
659
+ }
660
+
661
+ .card-grid {
662
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
663
+ }
664
+
665
+ .stats-grid {
666
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
667
+ }
668
+
669
+ .field-grid.cols-2 {
670
+ grid-template-columns: repeat(2, minmax(0, 1fr));
671
+ }
672
+
673
+ .field-grid.cols-3 {
674
+ grid-template-columns: repeat(3, minmax(0, 1fr));
675
+ }
676
+
677
+ .logout-dialog {
678
+ width: min(28rem, calc(100vw - 1.5rem));
679
+ padding: 0;
680
+ border: 1px solid rgba(235, 195, 195, 0.96);
681
+ border-radius: 30px;
682
+ background: rgba(255, 250, 250, 0.98);
683
+ box-shadow: 0 28px 72px rgba(113, 30, 30, 0.16);
684
+ }
685
+
686
+ .logout-dialog::backdrop {
687
+ background: rgba(36, 24, 24, 0.24);
688
+ backdrop-filter: blur(8px);
689
+ }
690
+
691
+ .logout-dialog-head {
692
+ display: grid;
693
+ gap: 12px;
694
+ padding: 24px 24px 20px;
695
+ border-bottom: 1px solid rgba(235, 195, 195, 0.96);
696
+ background: rgba(148, 47, 47, 0.05);
697
+ }
698
+
699
+ .logout-dialog-kicker {
700
+ margin-bottom: 0;
701
+ color: #a33f3f;
702
+ }
703
+
704
+ .logout-dialog-head h3 {
705
+ margin: 0;
706
+ font-size: 2rem;
707
+ line-height: 0.95;
708
+ letter-spacing: -0.05em;
709
+ color: #571d1d;
710
+ }
711
+
712
+ .logout-dialog-head p {
713
+ margin: 0;
714
+ color: rgba(109, 36, 36, 0.8);
715
+ }
716
+
717
+ .logout-dialog-actions {
718
+ justify-content: flex-end;
719
+ padding: 20px 24px 24px;
720
+ }
721
+
722
+ .logout-dialog-actions form {
723
+ margin: 0;
724
+ }
725
+
726
+ .stack {
727
+ display: grid;
728
+ gap: 16px;
729
+ }
730
+
731
+ .stack-lg {
732
+ display: grid;
733
+ gap: 22px;
734
+ }
735
+
736
+ .kicker {
737
+ display: inline-flex;
738
+ align-items: center;
739
+ gap: 10px;
740
+ min-height: 34px;
741
+ width: max-content;
742
+ max-width: 100%;
743
+ align-self: start;
744
+ padding: 0 14px;
745
+ border: 1px solid rgba(209, 219, 233, 0.96);
746
+ border-radius: 999px;
747
+ background: rgba(255, 255, 255, 0.9);
748
+ color: #6f7d95;
749
+ font-size: 11px;
750
+ font-weight: 700;
751
+ letter-spacing: 0.24em;
752
+ text-transform: uppercase;
753
+ }
754
+
755
+ .kicker.is-muted {
756
+ color: var(--muted);
757
+ }
758
+
759
+ .button,
760
+ button,
761
+ .link-button,
762
+ .cta-button {
763
+ display: inline-flex;
764
+ align-items: center;
765
+ justify-content: center;
766
+ gap: 10px;
767
+ min-height: 46px;
768
+ padding: 0 18px;
769
+ border: 1px solid rgba(219, 196, 146, 0.8);
770
+ border-radius: 999px;
771
+ background: #dec081;
772
+ color: #243041;
773
+ text-decoration: none;
774
+ font-size: 0.95rem;
775
+ font-weight: 600;
776
+ cursor: pointer;
777
+ transition:
778
+ transform 160ms ease,
779
+ border-color 160ms ease,
780
+ background 160ms ease,
781
+ box-shadow 160ms ease;
782
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
783
+ }
784
+
785
+ @media (hover: hover) {
786
+ .button:hover,
787
+ button:hover,
788
+ .link-button:hover {
789
+ transform: translateY(-1px);
790
+ border-color: rgba(191, 164, 109, 0.9);
791
+ box-shadow:
792
+ inset 0 1px 0 rgba(255, 255, 255, 0.84),
793
+ 0 12px 28px rgba(118, 89, 38, 0.15);
794
+ }
795
+ }
796
+
797
+ .button.secondary,
798
+ button.secondary,
799
+ .link-button.secondary {
800
+ background: rgba(255, 255, 255, 0.88);
801
+ color: var(--ink);
802
+ }
803
+
804
+ .button.danger,
805
+ button.danger {
806
+ border-color: rgba(192, 90, 90, 0.42);
807
+ background: #9f3d3d;
808
+ color: #fff8f8;
809
+ }
810
+
811
+ @media (hover: hover) {
812
+ .button.danger:hover,
813
+ button.danger:hover {
814
+ border-color: rgba(160, 58, 58, 0.62);
815
+ box-shadow: 0 12px 28px rgba(128, 38, 38, 0.18);
816
+ }
817
+ }
818
+
819
+ .nav-menu-button:hover,
820
+ .nav-action-link:hover {
821
+ transform: none;
822
+ box-shadow: none;
823
+ }
824
+
825
+ .button.ghost,
826
+ button.ghost,
827
+ .link-button.ghost {
828
+ background: rgba(255, 255, 255, 0.34);
829
+ }
830
+
831
+ button[disabled] {
832
+ cursor: not-allowed;
833
+ opacity: 0.5;
834
+ transform: none;
835
+ box-shadow: none;
836
+ }
837
+
838
+ .input,
839
+ input,
840
+ select,
841
+ textarea {
842
+ width: 100%;
843
+ border: 1px solid var(--line);
844
+ border-radius: 999px;
845
+ background: rgba(255, 255, 255, 0.92);
846
+ color: var(--ink);
847
+ padding: 14px 16px;
848
+ outline: none;
849
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8);
850
+ }
851
+
852
+ textarea {
853
+ min-height: 140px;
854
+ border-radius: 24px;
855
+ resize: vertical;
856
+ }
857
+
858
+ input:focus,
859
+ select:focus,
860
+ textarea:focus {
861
+ border-color: rgba(191, 164, 109, 0.9);
862
+ box-shadow:
863
+ inset 0 1px 0 rgba(255, 255, 255, 0.9),
864
+ 0 0 0 4px var(--accent-soft);
865
+ }
866
+
867
+ label,
868
+ .label {
869
+ display: block;
870
+ margin-bottom: 8px;
871
+ color: var(--muted);
872
+ font-size: 11px;
873
+ font-weight: 700;
874
+ letter-spacing: 0.3em;
875
+ text-transform: uppercase;
876
+ }
877
+
878
+ .label-group {
879
+ display: grid;
880
+ gap: 8px;
881
+ }
882
+
883
+ .notice {
884
+ padding: 14px 16px;
885
+ border: 1px solid rgba(209, 219, 233, 0.96);
886
+ border-radius: 18px;
887
+ background: rgba(255, 255, 255, 0.82);
888
+ color: var(--ink);
889
+ }
890
+
891
+ .notice-success {
892
+ border-color: rgba(209, 219, 233, 0.96);
893
+ background: rgba(255, 255, 255, 0.82);
894
+ color: var(--ink);
895
+ }
896
+
897
+ .notice-error {
898
+ border-color: rgba(214, 107, 107, 0.35);
899
+ background: rgba(191, 38, 38, 0.1);
900
+ color: #7f1d1d;
901
+ }
902
+
903
+ .helper,
904
+ .tiny,
905
+ .meta-copy {
906
+ color: #7a879e;
907
+ font-size: 0.94rem;
908
+ }
909
+
910
+ .tiny {
911
+ font-size: 0.86rem;
912
+ }
913
+
914
+ .pill {
915
+ display: inline-flex;
916
+ align-items: center;
917
+ gap: 8px;
918
+ min-height: 34px;
919
+ padding: 0 12px;
920
+ border: 1px solid rgba(209, 219, 233, 0.96);
921
+ border-radius: 999px;
922
+ background: rgba(255, 255, 255, 0.9);
923
+ color: #6f7d95;
924
+ font-size: 11px;
925
+ font-weight: 700;
926
+ letter-spacing: 0.24em;
927
+ text-transform: uppercase;
928
+ }
929
+
930
+ .status-pill.is-active::before,
931
+ .pill.is-active::before {
932
+ content: "";
933
+ width: 8px;
934
+ height: 8px;
935
+ border-radius: 999px;
936
+ background: var(--accent);
937
+ box-shadow: 0 0 0 4px rgba(222, 192, 129, 0.22);
938
+ }
939
+
940
+ .status-row,
941
+ .toolbar {
942
+ display: flex;
943
+ flex-wrap: wrap;
944
+ align-items: center;
945
+ }
946
+
947
+ .toolbar,
948
+ .status-row {
949
+ gap: 10px;
950
+ }
951
+
952
+ .keyline {
953
+ height: 1px;
954
+ background: linear-gradient(90deg, rgba(112, 86, 34, 0), rgba(209, 219, 233, 0.96), rgba(112, 86, 34, 0));
955
+ }
956
+
957
+ .empty-state {
958
+ padding: 18px;
959
+ border: 1px dashed rgba(209, 219, 233, 0.96);
960
+ border-radius: 18px;
961
+ background: rgba(255, 255, 255, 0.5);
962
+ color: var(--muted);
963
+ }
964
+
965
+ .auth-main .page-stack {
966
+ align-content: center;
967
+ justify-items: center;
968
+ padding: 24px 12px;
969
+ }
970
+
971
+ .auth-card {
972
+ display: grid;
973
+ gap: 14px;
974
+ width: 100%;
975
+ max-width: 560px;
976
+ margin: 0 auto;
977
+ padding: 28px;
978
+ border: 1px solid var(--line);
979
+ border-radius: var(--radius-md);
980
+ background: var(--paper-strong);
981
+ box-shadow: var(--shadow-soft);
982
+ }
983
+
984
+ .auth-card h1,
985
+ .auth-card h2,
986
+ .auth-card h3,
987
+ .auth-card p {
988
+ overflow-wrap: anywhere;
989
+ }
990
+
991
+ .loading-inline {
992
+ display: inline-flex;
993
+ align-items: center;
994
+ gap: 10px;
995
+ }
996
+
997
+ .loading-spinner {
998
+ display: inline-block;
999
+ width: 16px;
1000
+ height: 16px;
1001
+ border: 2px solid rgba(36, 48, 65, 0.18);
1002
+ border-top-color: rgba(36, 48, 65, 0.78);
1003
+ border-radius: 999px;
1004
+ animation: vidfarm-spin 0.8s linear infinite;
1005
+ flex: 0 0 auto;
1006
+ }
1007
+
1008
+ @keyframes vidfarm-spin {
1009
+ to {
1010
+ transform: rotate(360deg);
1011
+ }
1012
+ }
1013
+
1014
+ code,
1015
+ pre {
1016
+ font-family: "SFMono-Regular", Menlo, Consolas, monospace;
1017
+ }
1018
+
1019
+ pre {
1020
+ margin: 0;
1021
+ border: 1px solid rgba(73, 57, 26, 0.18);
1022
+ border-radius: 18px;
1023
+ background: #211a12;
1024
+ color: #f8eed6;
1025
+ padding: 16px;
1026
+ overflow: auto;
1027
+ white-space: pre-wrap;
1028
+ word-break: break-word;
1029
+ }
1030
+
1031
+ ${input.style ?? ""}
1032
+
1033
+ ${isEditorTheme ? EDITOR_DARK_THEME_CSS : ""}
1034
+
1035
+ @media (max-width: 1024px) {
1036
+ .hero-grid,
1037
+ .split-grid,
1038
+ .page-hero {
1039
+ grid-template-columns: 1fr;
1040
+ }
1041
+ }
1042
+
1043
+ @media (max-width: 1024px) {
1044
+ html,
1045
+ body {
1046
+ height: auto;
1047
+ min-height: 100%;
1048
+ overflow: auto;
1049
+ overflow-x: hidden;
1050
+ }
1051
+
1052
+ body {
1053
+ background-attachment: scroll;
1054
+ }
1055
+
1056
+ .app-shell,
1057
+ .app-shell.is-wide,
1058
+ .app-shell.is-narrow {
1059
+ width: min(100vw - 14px, 1980px);
1060
+ height: auto;
1061
+ min-height: 100svh;
1062
+ padding-top: 8px;
1063
+ padding-bottom: calc(18px + env(safe-area-inset-bottom));
1064
+ }
1065
+
1066
+ .page-stack,
1067
+ .frame {
1068
+ height: auto;
1069
+ min-height: 0;
1070
+ overflow: visible;
1071
+ }
1072
+
1073
+ .topbar {
1074
+ min-height: auto;
1075
+ padding: 8px;
1076
+ border-radius: 24px;
1077
+ align-items: center;
1078
+ flex-wrap: nowrap;
1079
+ gap: 8px;
1080
+ }
1081
+
1082
+ .brand-lockup {
1083
+ flex: 1 1 auto;
1084
+ width: auto;
1085
+ gap: 7px;
1086
+ }
1087
+
1088
+ .brand-copy {
1089
+ display: flex;
1090
+ flex: 0 0 auto;
1091
+ min-width: 0;
1092
+ gap: 0;
1093
+ flex-wrap: nowrap;
1094
+ }
1095
+
1096
+ .brand-title-static {
1097
+ font-size: 1.24rem;
1098
+ line-height: 1;
1099
+ }
1100
+
1101
+ .brand-account-meta {
1102
+ display: none;
1103
+ }
1104
+
1105
+ .brand-title-mobile-hidden {
1106
+ display: none;
1107
+ }
1108
+
1109
+ .topbar-actions {
1110
+ flex: 0 0 auto;
1111
+ width: auto;
1112
+ justify-content: flex-end;
1113
+ overflow: visible;
1114
+ padding-bottom: 0;
1115
+ scrollbar-width: none;
1116
+ }
1117
+
1118
+ .topbar-actions::-webkit-scrollbar {
1119
+ display: none;
1120
+ }
1121
+
1122
+ .brand-logo-image {
1123
+ height: 32px;
1124
+ max-width: 38px;
1125
+ }
1126
+
1127
+ .primary-nav {
1128
+ min-width: 0;
1129
+ width: auto;
1130
+ max-width: none;
1131
+ flex-wrap: nowrap;
1132
+ justify-content: flex-end;
1133
+ gap: 0;
1134
+ padding: 0;
1135
+ border: 0;
1136
+ border-radius: 0;
1137
+ background: transparent;
1138
+ box-shadow: none;
1139
+ overflow: visible;
1140
+ }
1141
+
1142
+ .primary-nav > .nav-link {
1143
+ display: none;
1144
+ }
1145
+
1146
+ .nav-link {
1147
+ flex: 0 0 auto;
1148
+ min-height: 44px;
1149
+ gap: 6px;
1150
+ padding: 0 12px;
1151
+ border-radius: 14px;
1152
+ font-size: 0.86rem;
1153
+ }
1154
+
1155
+ .nav-mobile-extra {
1156
+ display: none;
1157
+ }
1158
+
1159
+ .nav-menu {
1160
+ display: block;
1161
+ }
1162
+
1163
+ .nav-menu-trigger {
1164
+ min-width: 44px;
1165
+ width: 44px;
1166
+ height: 44px;
1167
+ padding: 0;
1168
+ border: 1px solid rgba(191, 164, 109, 0.32);
1169
+ border-radius: 15px;
1170
+ background: rgba(255, 252, 247, 0.96);
1171
+ color: var(--ink);
1172
+ box-shadow: 0 8px 18px rgba(138, 102, 32, 0.1);
1173
+ }
1174
+
1175
+ .nav-menu-desktop-icon {
1176
+ display: none;
1177
+ }
1178
+
1179
+ .nav-menu-mobile-icon {
1180
+ display: inline-flex;
1181
+ }
1182
+
1183
+ .nav-menu-panel {
1184
+ top: calc(100% + 10px);
1185
+ right: 0;
1186
+ width: min(82vw, 260px);
1187
+ min-width: 190px;
1188
+ max-height: calc(100svh - 92px);
1189
+ overflow: auto;
1190
+ padding: 8px;
1191
+ border-radius: 16px;
1192
+ box-shadow: 0 20px 46px rgba(81, 58, 20, 0.18);
1193
+ }
1194
+
1195
+ .nav-menu-item {
1196
+ min-height: 42px;
1197
+ padding: 0 12px;
1198
+ border-radius: 12px;
1199
+ font-size: 0.88rem;
1200
+ }
1201
+
1202
+ .nav-menu-item.nav-menu-mobile-only {
1203
+ display: flex;
1204
+ }
1205
+
1206
+ .nav-link > span:not(.nav-icon) {
1207
+ display: none;
1208
+ }
1209
+
1210
+ .nav-link > .nav-menu-label {
1211
+ display: none;
1212
+ }
1213
+
1214
+ .nav-icon,
1215
+ .nav-icon svg {
1216
+ width: 18px;
1217
+ height: 18px;
1218
+ }
1219
+
1220
+ @media (max-width: 560px) {
1221
+ .primary-nav > .nav-link {
1222
+ display: none;
1223
+ }
1224
+
1225
+ .primary-nav > .nav-link > span:not(.nav-icon) {
1226
+ display: none;
1227
+ }
1228
+ }
1229
+
1230
+ @media (max-width: 374px) {
1231
+ .topbar {
1232
+ gap: 6px;
1233
+ }
1234
+
1235
+ .brand-logo-image {
1236
+ height: 30px;
1237
+ max-width: 34px;
1238
+ }
1239
+
1240
+ .brand-lockup {
1241
+ gap: 5px;
1242
+ }
1243
+
1244
+ .brand-title-static {
1245
+ font-size: 1.08rem;
1246
+ }
1247
+
1248
+ .primary-nav {
1249
+ gap: 3px;
1250
+ }
1251
+
1252
+ .nav-link {
1253
+ gap: 3px;
1254
+ padding: 0 6px;
1255
+ font-size: 0.72rem;
1256
+ }
1257
+ }
1258
+
1259
+ .field-grid.cols-2,
1260
+ .field-grid.cols-3 {
1261
+ grid-template-columns: 1fr;
1262
+ }
1263
+
1264
+ h1 {
1265
+ font-size: clamp(1.9rem, 8vw, 2.6rem);
1266
+ }
1267
+ }
1268
+ </style>
1269
+ <script src="/assets/sentry-config.js"></script>
1270
+ </head>
1271
+ <body${input.bodyClass ? ` class="${escapeAttribute(input.bodyClass)}"` : ""}>
1272
+ <main class="app-shell${input.mainClass ? ` ${escapeHtml(input.mainClass)}` : ""}">
1273
+ <div class="page-stack${input.shellClass ? ` ${escapeHtml(input.shellClass)}` : ""}">
1274
+ ${input.body}
1275
+ </div>
1276
+ </main>
1277
+ <script>
1278
+ (() => {
1279
+ const logoutDialog = document.querySelector("[data-logout-dialog]");
1280
+ const logoutForm = document.querySelector("[data-logout-form]");
1281
+ const openLogoutButtons = document.querySelectorAll("[data-open-logout-dialog]");
1282
+ const closeLogoutButtons = document.querySelectorAll("[data-close-logout-dialog]");
1283
+
1284
+ function clearLogoutAccountCache() {
1285
+ if (!(logoutForm instanceof HTMLFormElement)) {
1286
+ return;
1287
+ }
1288
+ const account = String(new FormData(logoutForm).get("account") || "").trim();
1289
+ if (!account) {
1290
+ return;
1291
+ }
1292
+ try {
1293
+ const registryIndexKey = "vidfarm:agency:accounts:index";
1294
+ const rawIds = window.localStorage.getItem(registryIndexKey);
1295
+ const ids = rawIds ? JSON.parse(rawIds) : [];
1296
+ if (Array.isArray(ids)) {
1297
+ window.localStorage.setItem(registryIndexKey, JSON.stringify(ids.filter((value) => value !== account)));
1298
+ }
1299
+ window.localStorage.removeItem("vidfarm:agency:account_" + account);
1300
+ window.localStorage.removeItem("vidfarm:flockposter-cache:v1_" + account);
1301
+ window.localStorage.removeItem("vidfarm:discover-bookmarks:v1_" + account);
1302
+ } catch {
1303
+ // Ignore storage failures.
1304
+ }
1305
+ }
1306
+
1307
+ if (logoutDialog instanceof HTMLDialogElement && openLogoutButtons.length) {
1308
+ openLogoutButtons.forEach((button) => {
1309
+ button.addEventListener("click", () => {
1310
+ if (!logoutDialog.open) {
1311
+ logoutDialog.showModal();
1312
+ }
1313
+ });
1314
+ });
1315
+ closeLogoutButtons.forEach((button) => {
1316
+ button.addEventListener("click", () => logoutDialog.close());
1317
+ });
1318
+ logoutDialog.addEventListener("click", (event) => {
1319
+ const rect = logoutDialog.getBoundingClientRect();
1320
+ const isBackdropClick =
1321
+ event.clientX < rect.left ||
1322
+ event.clientX > rect.right ||
1323
+ event.clientY < rect.top ||
1324
+ event.clientY > rect.bottom;
1325
+ if (isBackdropClick) {
1326
+ logoutDialog.close();
1327
+ }
1328
+ });
1329
+ } else if (openLogoutButtons.length && logoutForm instanceof HTMLFormElement) {
1330
+ openLogoutButtons.forEach((button) => {
1331
+ button.addEventListener("click", () => {
1332
+ if (window.confirm("Log out of this browser and clear local workspace access?")) {
1333
+ logoutForm.requestSubmit();
1334
+ }
1335
+ });
1336
+ });
1337
+ }
1338
+
1339
+ if (logoutForm instanceof HTMLFormElement) {
1340
+ logoutForm.addEventListener("submit", clearLogoutAccountCache);
1341
+ }
1342
+
1343
+ const navMenus = document.querySelectorAll("details.nav-menu");
1344
+ if (navMenus.length) {
1345
+ const closeNavMenus = () => {
1346
+ navMenus.forEach((menu) => {
1347
+ if (menu instanceof HTMLDetailsElement && menu.open) {
1348
+ menu.open = false;
1349
+ }
1350
+ });
1351
+ };
1352
+ document.addEventListener("click", (event) => {
1353
+ if (!(event.target instanceof Node)) {
1354
+ return;
1355
+ }
1356
+ navMenus.forEach((menu) => {
1357
+ if (menu instanceof HTMLDetailsElement && menu.open && !menu.contains(event.target)) {
1358
+ menu.open = false;
1359
+ }
1360
+ });
1361
+ });
1362
+ document.addEventListener("keydown", (event) => {
1363
+ if (event.key === "Escape") {
1364
+ closeNavMenus();
1365
+ }
1366
+ });
1367
+ navMenus.forEach((menu) => {
1368
+ menu.querySelectorAll(".nav-menu-item").forEach((item) => {
1369
+ item.addEventListener("click", () => closeNavMenus());
1370
+ });
1371
+ });
1372
+ }
1373
+ })();
1374
+ </script>
1375
+ ${input.runtimeBoot ? `<div id="page-runtime-root" hidden></div>
1376
+ <script id="page-runtime-boot" type="application/json">${escapeJsonForHtml(input.runtimeBoot)}</script>
1377
+ <script type="module" src="/assets/page-runtime-client-app.js"></script>` : ""}
1378
+ </body>
1379
+ </html>`;
1380
+ }
1381
+ //# sourceMappingURL=page-shell.js.map