@mevdragon/vidfarm-devcli 0.16.0 → 0.17.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 (33) hide show
  1. package/.agents/skills/farmville-saas-ux/SKILL.md +156 -0
  2. package/.agents/skills/farmville-saas-ux/assets/starter.html +294 -0
  3. package/.agents/skills/farmville-saas-ux/references/components.md +340 -0
  4. package/.agents/skills/farmville-saas-ux/references/porting-guide.md +121 -0
  5. package/.agents/skills/farmville-saas-ux/references/tokens.md +271 -0
  6. package/.agents/skills/vidfarm-media/SKILL.md +2 -1
  7. package/.agents/skills/vidfarm-media/references/tts.md +20 -1
  8. package/dist/src/account-pages-legacy.js +2 -2
  9. package/dist/src/app.js +441 -77
  10. package/dist/src/editor-chat.js +2 -2
  11. package/dist/src/frontend/homepage-client.js +162 -2
  12. package/dist/src/frontend/homepage-store.js +30 -1
  13. package/dist/src/frontend/homepage-view.js +111 -4
  14. package/dist/src/homepage.js +184 -1
  15. package/dist/src/landing-page.js +367 -0
  16. package/dist/src/primitive-registry.js +278 -2
  17. package/dist/src/reskin/agency-page.js +255 -0
  18. package/dist/src/reskin/calendar-page.js +252 -0
  19. package/dist/src/reskin/chat-page.js +414 -0
  20. package/dist/src/reskin/discover-page.js +380 -0
  21. package/dist/src/reskin/document.js +74 -0
  22. package/dist/src/reskin/help-page.js +318 -0
  23. package/dist/src/reskin/index-page.js +62 -0
  24. package/dist/src/reskin/job-runs-page.js +249 -0
  25. package/dist/src/reskin/library-page.js +515 -0
  26. package/dist/src/reskin/login-page.js +225 -0
  27. package/dist/src/reskin/pricing-page.js +359 -0
  28. package/dist/src/reskin/settings-page.js +353 -0
  29. package/dist/src/reskin/theme.js +265 -0
  30. package/dist/src/services/serverless-records.js +54 -0
  31. package/dist/src/services/swipe-customize.js +434 -0
  32. package/package.json +1 -1
  33. package/public/assets/homepage-client-app.js +22 -22
@@ -0,0 +1,271 @@
1
+ # Farmville SaaS — Design Tokens
2
+
3
+ The complete design system as CSS custom properties. Paste the `:root` block below into your global
4
+ stylesheet and reference the variables everywhere — never hand-pick ad-hoc hex/px values, or the system
5
+ drifts. Values are the real ones distilled from Fillout.com (a Tailwind-v4 default scale + a custom
6
+ honey-gold brand palette + rounded display type).
7
+
8
+ ## Table of contents
9
+ 1. Fonts (loading + stacks)
10
+ 2. The `:root` token block (copy-paste)
11
+ 3. Color rationale
12
+ 4. Typography scale & usage
13
+ 5. Radius, shadow, spacing rationale
14
+ 6. Glass / blur
15
+ 7. Motion
16
+
17
+ ---
18
+
19
+ ## 1. Fonts
20
+
21
+ **Display / headings — `Hanken Grotesk`.** Fillout uses a proprietary rounded grotesque called
22
+ *blMelody*. Hanken Grotesk is the closest free, warm, rounded grotesque with an excellent bold. Good
23
+ alternates, all free on Google Fonts, in order of similarity: **Figtree**, **Gantari**, **Onest**,
24
+ **Plus Jakarta Sans**. If you have a license for blMelody, use it and keep Hanken as the fallback.
25
+
26
+ **Body / UI — `Inter`.** Exact match to Fillout. Free.
27
+
28
+ ```html
29
+ <link rel="preconnect" href="https://fonts.googleapis.com">
30
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
31
+ <link href="https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;600;700;800&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
32
+ ```
33
+
34
+ Rules of thumb:
35
+ - Headlines, section titles, big numbers, the logo → **Hanken Grotesk** (or blMelody).
36
+ - Body copy, labels, buttons, nav items, form fields → **Inter**.
37
+ - Never set body copy in the display font, and never set a huge headline in Inter — the mix is the point.
38
+
39
+ ---
40
+
41
+ ## 2. The `:root` token block
42
+
43
+ ```css
44
+ :root {
45
+ /* ---- Fonts ---- */
46
+ --font-display: "Hanken Grotesk", "blMelody", ui-sans-serif, system-ui, sans-serif;
47
+ --font-body: "Inter", ui-sans-serif, system-ui, -apple-system, sans-serif;
48
+ --font-mono: ui-monospace, "SFMono-Regular", Menlo, Monaco, Consolas, monospace;
49
+
50
+ /* ---- Signature accent: HONEY GOLD (the one "joy" color) ---- */
51
+ --gold-500: #ffc738; /* primary accent */
52
+ --gold-400: #ffd66f; /* lighter */
53
+ --gold-300: #f8d884; /* soft */
54
+ --gold-600: #f6c744; /* focus-ring gold */
55
+ --gold-700: #fcb900; /* deep / hover */
56
+ --gold-tint: #fff5e4; /* pale wash bg */
57
+ --gold-tint2:#ffe9cc; /* warm cream */
58
+
59
+ /* ---- Ink & neutral scale (Tailwind neutral) ---- */
60
+ --ink: #171717; /* primary text, dark buttons, footer */
61
+ --ink-950: #0a0a0a; /* deepest */
62
+ --n-900: #171717;
63
+ --n-800: #262626;
64
+ --n-700: #404040; /* heading text on light */
65
+ --n-600: #525252;
66
+ --n-500: #737373; /* secondary / body text */
67
+ --n-400: #a3a3a3; /* muted, placeholders, disabled */
68
+ --n-300: #d4d4d4; /* strong border */
69
+ --n-200: #ededed; /* hairline border (default) */
70
+ --n-150: #f0f0f0;
71
+ --n-100: #f5f5f5; /* section tint background */
72
+ --n-50: #fbfbfb; /* page background */
73
+ --white: #ffffff; /* card surface */
74
+
75
+ /* ---- Support pastels (icon tiles, nodes, illustration accents) ---- */
76
+ --sky: #3f9fe0; --sky-tint: #e2effd; /* hero sky / info */
77
+ --violet: #9f5bde; --violet-tint: #e4ddfd; /* AI / smart */
78
+ --green: #22c55e; --green-tint: #dcfce7; /* branch / success / nature */
79
+ --coral: #f97316; --coral-tint: #ffe9cc; /* energy / warm */
80
+ --red: #ef4444; --red-tint: #fee2e2; /* destructive */
81
+
82
+ /* ---- Semantic roles ---- */
83
+ --bg: var(--n-50);
84
+ --bg-section: var(--n-100);
85
+ --surface: var(--white);
86
+ --border: var(--n-200);
87
+ --border-strong: var(--n-300);
88
+ --text: var(--n-700);
89
+ --text-muted: var(--n-500);
90
+ --text-faint: var(--n-400);
91
+ --accent: var(--gold-500);
92
+
93
+ /* ---- Radius (curves are signature — nothing sharp) ---- */
94
+ --r-sm: 4px;
95
+ --r-md: 6px; /* inputs, small chips */
96
+ --r-lg: 8px; /* small buttons */
97
+ --r-xl: 12px; /* buttons, icon tiles */
98
+ --r-2xl: 16px; /* cards, nodes */
99
+ --r-3xl: 24px; /* big feature cards, image frames, nav pill */
100
+ --r-full: 9999px; /* nav bar, pill buttons, badges, avatars */
101
+
102
+ /* ---- Shadows (diffuse, low-opacity = soft sunlight, never harsh) ---- */
103
+ --shadow-xs: 0 1px 2px 0 #0000000d;
104
+ --shadow-sm: 0 1px 3px 0 #0000001a, 0 1px 2px -1px #0000001a;
105
+ --shadow-md: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;
106
+ --shadow-lg: 0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;
107
+ --shadow-xl: 0 20px 25px -5px #0000001a, 0 8px 10px -6px #0000001a;
108
+ --shadow-2xl:0 25px 50px -12px #00000040;
109
+ --shadow-card: 0 1px 2px #0000000d, 0 8px 24px -12px #00000014; /* lifted-card ambient */
110
+ --shadow-nav: 0 4px 24px -8px #00000026, 0 1px 2px #0000000d; /* floating glass nav */
111
+ --ring-gold: 0 0 0 3px var(--gold-600), 0 0 14px rgba(246,199,68,.4); /* focus */
112
+
113
+ /* ---- Type scale (rem) ---- */
114
+ --text-xs: 0.75rem; --lh-xs: 1rem;
115
+ --text-sm: 0.875rem; --lh-sm: 1.25rem;
116
+ --text-base:1rem; --lh-base:1.5rem;
117
+ --text-lg: 1.125rem; --lh-lg: 1.75rem;
118
+ --text-xl: 1.25rem; --lh-xl: 1.75rem;
119
+ --text-2xl: 1.5rem; --lh-2xl: 2rem;
120
+ --text-3xl: 1.875rem; --lh-3xl: 2.25rem;
121
+ --text-4xl: 2.25rem; --lh-4xl: 2.5rem;
122
+ --text-5xl: 3rem; --lh-5xl: 1.05;
123
+ --text-6xl: 3.75rem; --lh-6xl: 1.0;
124
+ --text-7xl: 4.5rem; --lh-7xl: 1.0;
125
+ --display: clamp(3rem, 7vw, 6rem); /* hero headline, fluid */
126
+
127
+ /* ---- Font weights ---- */
128
+ --fw-normal: 400; --fw-medium: 500; --fw-semibold: 600;
129
+ --fw-bold: 700; --fw-extrabold: 800;
130
+
131
+ /* ---- Tracking / leading ---- */
132
+ --track-tighter: -0.05em;
133
+ --track-tight: -0.025em; /* headings default */
134
+ --track-normal: 0em;
135
+ --lh-tight: 1.1; --lh-snug: 1.25; --lh-normal: 1.5; --lh-relaxed: 1.6;
136
+
137
+ /* ---- Spacing (4px base) ---- */
138
+ --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px;
139
+ --sp-6: 24px; --sp-8: 32px; --sp-10:40px; --sp-12:48px; --sp-16:64px;
140
+ --sp-20:80px; --sp-24:96px; --sp-32:128px;
141
+ --section-y: clamp(4rem, 9vw, 7rem); /* vertical rhythm between sections */
142
+ --container: 75rem; /* 1200px, max content width */
143
+ --gutter: clamp(1rem, 4vw, 2rem);
144
+
145
+ /* ---- Glass / blur ---- */
146
+ --glass-bg: rgba(251,251,251,0.8);
147
+ --glass-blur: 16px;
148
+
149
+ /* ---- Motion ---- */
150
+ --ease: cubic-bezier(0.22, 1, 0.36, 1); /* gentle ease-out */
151
+ --dur-fast: 150ms; --dur: 220ms; --dur-slow: 320ms;
152
+ }
153
+
154
+ /* Baseline application */
155
+ html { font-size: 16px; }
156
+ body {
157
+ font-family: var(--font-body);
158
+ color: var(--text);
159
+ background: var(--bg);
160
+ -webkit-font-smoothing: antialiased;
161
+ text-rendering: optimizeLegibility;
162
+ }
163
+ h1,h2,h3,h4 {
164
+ font-family: var(--font-display);
165
+ font-weight: var(--fw-extrabold);
166
+ letter-spacing: var(--track-tight);
167
+ line-height: var(--lh-tight);
168
+ color: var(--ink);
169
+ }
170
+ ```
171
+
172
+ ---
173
+
174
+ ## 3. Color rationale
175
+
176
+ - **Honey-gold `#ffc738` is the whole personality.** It is the *only* saturated brand color. Use it
177
+ where you want a smile: the footer's primary CTA, star ratings, a "Publish" chip, the logo, a small
178
+ underline/highlight, a hover glow. If you find yourself using gold on more than ~5–10% of a screen,
179
+ pull back — its power is scarcity. Never pair it with a second competing bright brand color.
180
+ - **Charcoal `#171717` is the workhorse.** Primary buttons on light backgrounds, primary text, the
181
+ footer surface. It reads premium and calm and lets the gold pop.
182
+ - **Everything else is the neutral gray scale.** Backgrounds alternate `#fbfbfb` (page) ↔ `#f5f5f5`
183
+ (tinted section) ↔ `#ffffff` (cards). Borders are the near-invisible `#ededed` hairline. Text steps
184
+ down `#171717` → `#404040` → `#737373` → `#a3a3a3`.
185
+ - **Support pastels are for tiny surfaces only** — icon tiles, workflow nodes, illustration accents,
186
+ chart dots. Each has a saturated glyph color + a pale tint background (violet on `#e4ddfd`, green on
187
+ `#dcfce7`, etc.). They add life without stealing the gold's job.
188
+ - **The illustrated hero introduces sky-blue and green** as *painted* colors, not UI colors. That's
189
+ intentional — the warmth lives in the artwork, the UI stays disciplined.
190
+
191
+ ---
192
+
193
+ ## 4. Typography scale & usage
194
+
195
+ | Element | Font | Size | Weight | Tracking | Line-height |
196
+ |---|---|---|---|---|---|
197
+ | Hero headline | display | `--display` (clamp 3→6rem) | 800 | -0.03em | 1.0 |
198
+ | Section title | display | `--text-5xl`/`4xl` | 800 | -0.025em | 1.05 |
199
+ | Card / feature title | display | `--text-xl`/`2xl` | 700 | -0.02em | 1.2 |
200
+ | Subhead / lede | body | `--text-lg`/`xl` | 400 | 0 | 1.5 |
201
+ | Body copy | body | `--text-base` | 400 | 0 | 1.6 |
202
+ | Small / caption | body | `--text-sm` | 400/500 | 0 | 1.4 |
203
+ | Button label | body | `--text-sm`/`base` | 600 | 0 | 1 |
204
+ | Badge / eyebrow | body | `--text-sm` | 500 | 0 | 1 |
205
+ | Big stat number | display | `--text-5xl`+ | 700 | -0.02em | 1 |
206
+
207
+ **Two-tone hero trick:** split the headline across two lines and set the first line to a translucent
208
+ white and the second to solid white for a soft-to-strong reveal:
209
+
210
+ ```css
211
+ .hero-h1 { font: 800 var(--display)/1.0 var(--font-display); letter-spacing:-0.03em; color:#fff; }
212
+ .hero-h1 .soft { color: rgba(255,255,255,0.55); }
213
+ ```
214
+ ```html
215
+ <h1 class="hero-h1"><span class="soft">Forms that</span><br>do it all</h1>
216
+ ```
217
+
218
+ On light backgrounds, headings are ink `#171717`; subheads are `#737373`.
219
+
220
+ ---
221
+
222
+ ## 5. Radius, shadow, spacing rationale
223
+
224
+ - **Radius is a personality dial and it's turned way up.** Interactive elements are *fully* rounded
225
+ (nav, buttons, badges → `--r-full`). Containers are generously rounded (cards `16px`, big cards &
226
+ image frames `24px`). Only truly small utility elements go as low as `4–6px`. When in doubt, round
227
+ more. A single sharp corner breaks the whole cozy feeling.
228
+ - **Shadows imitate soft ambient sunlight**, not hard drop-shadows. They're always large-radius and
229
+ low-opacity (`#0000001a` ≈ 10% black; the biggest is 25%). Use `--shadow-card` on resting cards and
230
+ `--shadow-nav` on the floating nav. On hover, step a card from `--shadow-card` to `--shadow-lg` and
231
+ nudge it up 2px.
232
+ - **Spacing is generous and rhythmic.** Sections get `--section-y` (≈ 6rem) of vertical padding.
233
+ Content maxes at `--container` (1200px) and stays centered with `--gutter` side padding. Inside
234
+ cards, pad `24–40px`. Whitespace *is* the premium signal — don't crowd.
235
+
236
+ ---
237
+
238
+ ## 6. Glass / blur
239
+
240
+ The floating nav and any sticky "feature tab" bar use frosted glass:
241
+
242
+ ```css
243
+ .glass {
244
+ background: var(--glass-bg); /* rgba(251,251,251,0.8) */
245
+ backdrop-filter: blur(var(--glass-blur)); /* 16px */
246
+ -webkit-backdrop-filter: blur(var(--glass-blur));
247
+ border: 1px solid var(--border);
248
+ box-shadow: var(--shadow-nav);
249
+ }
250
+ ```
251
+ Over the illustrated hero, use a whiter translucent fill (`rgba(255,255,255,0.7)`) so nav text stays legible.
252
+
253
+ ---
254
+
255
+ ## 7. Motion
256
+
257
+ Gentle and springy, never bouncy-cartoonish. One easing curve (`--ease`, a soft ease-out) and short
258
+ durations (150–320ms). The canonical interactions:
259
+
260
+ - **Card hover:** `transform: translateY(-2px)` + shadow `--shadow-card` → `--shadow-lg`.
261
+ - **Button hover:** slight brightness/darken + `--shadow-md`; the trailing `→` arrow nudges right ~3px.
262
+ - **Focus:** `box-shadow: var(--ring-gold)` — the gold glow ring.
263
+ - **Section reveal (optional):** fade-up 12px over 320ms as it enters the viewport.
264
+
265
+ ```css
266
+ .card { transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
267
+ .card:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); }
268
+ .btn .arrow { transition: transform var(--dur) var(--ease); }
269
+ .btn:hover .arrow { transform: translateX(3px); }
270
+ :where(a,button,input,textarea):focus-visible { outline: none; box-shadow: var(--ring-gold); }
271
+ ```
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: vidfarm-media
3
- description: Media resolution for video workflows — narration TTS, word-level timings, BGM, SFX, and image/clip sourcing through vidfarm. Use when a video needs audio (voiceover/narration, music, sound effects), caption word timings, or media assets. Ships the shared audio engine scripts/audio.mjs (audio_request.json → audio_meta.json) used by faceless-explainer, product-launch-video, and general-video; documents vidfarm tts/stt BYOK primitives, the keyless local Kokoro + whisper.cpp engines, and My Files / clip-library / generation sourcing. No third-party media accounts — everything is user-owned or generated on the user's keys.
3
+ description: Media resolution for video workflows — narration TTS, voice-matched speech regeneration ("same speaker, new words"), word-level timings, BGM, SFX, and image/clip sourcing through vidfarm. Use when a video needs audio (voiceover/narration, music, sound effects), rewording of existing narration in the original speaker's voice, caption word timings, or media assets. Ships the shared audio engine scripts/audio.mjs (audio_request.json → audio_meta.json) used by faceless-explainer, product-launch-video, and general-video; documents vidfarm tts/stt BYOK primitives, the keyless local Kokoro + whisper.cpp engines, and My Files / clip-library / generation sourcing. No third-party media accounts — everything is user-owned or generated on the user's keys.
4
4
  ---
5
5
 
6
6
  # vidfarm-media
@@ -63,6 +63,7 @@ Contract points:
63
63
  | Narration, promptable voice (BYOK) | `vidfarm tts "…" --style "calm, warm narrator"` | Local-first on your env key; `--voice alloy`/`Kore`…; `--cloud` = saved-key platform job → `POST /api/v1/primitives/audio/speech` |
64
64
  | Narration, zero keys | `npx hyperframes tts "…" -v af_heart --json` | Kokoro-82M, local, WAV + duration in JSON |
65
65
  | Transcript + SRT (BYOK) | `vidfarm stt <file\|url>` | Gemini key labels speakers; OpenAI whisper-1 gives real word timestamps |
66
+ | Reword existing narration in the (approximate) original voice | `POST /api/v1/primitives/audio/regenerate-speech` (platform job on saved keys; no devcli command yet) | One job: listens to a video/audio source, profiles the speaker (needs a Gemini key), rewords the transcript per `rewrite_instruction` (or takes exact `text`), regenerates with the closest preset voice + matched style. Always an approximation — OpenAI/Gemini cannot clone voices. Details: `references/tts.md` |
66
67
  | Word timings, zero keys | `npx hyperframes transcribe <audio> --json` | whisper.cpp; writes word-level `transcript.json` |
67
68
  | Captions straight into a composition | `vidfarm captions generate <dir>` | whisper-1 real timings when an OpenAI key exists; estimates otherwise |
68
69
 
@@ -21,7 +21,26 @@ vidfarm tts "Welcome back to the channel" --style "calm, warm bedtime narrator"
21
21
  - Gemini (`gemini-*-tts`, TitleCase, also the default family for OpenRouter TTS): `Kore, Puck, Charon, Aoede, Fenrir, Leda, Orus, Zephyr, Achernar, Achird, Algenib, Algieba, Alnilam, Autonoe, Callirrhoe, Despina, Enceladus, Erinome, Gacrux, Iapetus, Laomedeia, Pulcherrima, Rasalgethi, Sadachbia, Sadaltager, Schedar, Sulafat, Umbriel, Vindemiatrix, Zubenelgenubi`
22
22
  - **Formats**: `--format mp3|wav` (default mp3). `--json` prints `{ ok, provider, model, out, … }`.
23
23
 
24
- ## Keyless local TTS Kokoro-82M
24
+ ## Voice-matched regeneration"same speaker, new words"
25
+
26
+ ```bash
27
+ # Platform job on saved keys (no devcli command yet); poll the returned job_id.
28
+ POST /api/v1/primitives/audio/regenerate-speech # alias: /api/v1/primitives/regenerate-speech
29
+ { "tracer": "…", "payload": {
30
+ "source_url": "…", # video or audio; video audio is demuxed automatically
31
+ "rewrite_instruction": "mention the summer sale instead of the discount code",
32
+ "text": "…", # OR: the exact new script (one of the two is required)
33
+ "voice": "…", "instructions": "…", # optional preset override / extra style guidance
34
+ "provider": "…", "model": "…", "language": "…", "output_format": "mp3|wav"
35
+ } }
36
+ ```
37
+
38
+ One job: listens to the source, profiles the dominant speaker with an audio-native Gemini call (verbatim transcript + gender/age/accent/pace/pitch/energy profile + a dense style direction + the closest preset in both voice families), rewords the transcript per `rewrite_instruction` (keeping length and rhythm) or takes the exact `text`, then regenerates via TTS with the matched preset + profiled style instructions. Result: durable `audioUrl`, `script`, `original_transcript`, `voice_profile`, `voice_match`, plus a `regenerate-speech.json` artifact.
39
+
40
+ - **Honesty rule (non-negotiable): this is an approximation, never a clone.** Neither OpenAI nor Gemini exposes voice cloning through their public APIs — both offer preset voices with style steering only (actual cloning is sales-allowlisted at both, e.g. OpenAI "Custom Voices", Google Chirp 3 Instant Custom Voice). `voice_match` says `"approximate"` or `"none"`; always present it that way to the user. True self-serve cloning would need an ElevenLabs/Cartesia-class provider or a local OSS model (F5-TTS, CosyVoice, XTTS-v2, Chatterbox) — none are wired into vidfarm today.
41
+ - **Voice profiling needs a saved Gemini key** (it is the audio-native LLM). With only openai/openrouter keys the job degrades gracefully: STT transcript + reword still work, but the voice is a default or explicitly passed preset and `voice_match` is `"none"`.
42
+ - Sources over ~40 minutes of speech must be trimmed first (same cap as `/audio/transcribe`).
43
+ - To swap the result into a composition: mute the original span (`/videos/mute` or the layer's volume), then place `audioUrl` as a new audio layer.
25
44
 
26
45
  ```bash
27
46
  npx hyperframes tts "Welcome back" -v af_heart -o line.wav --json # {"ok":true,"durationSeconds":…,"outputPath":…}
@@ -880,10 +880,10 @@ export function renderSettingsPage(input) {
880
880
  </div>
881
881
  <div class="profile-field">
882
882
  <div class="profile-field-head">
883
- <label for="about">Profile notes</label>
883
+ <label for="about">Product / offer description</label>
884
884
  <button type="submit" data-profile-about-save disabled>Save</button>
885
885
  </div>
886
- <textarea id="about" name="about" placeholder="What should your operators or collaborators know about this account?" data-profile-about data-initial-value="${escapeAttribute(input.about ?? "")}">${escapeHtml(input.about ?? "")}</textarea>
886
+ <textarea id="about" name="about" placeholder="Describe your product or offer what it is, who it's for, and the promise. Swipe mode uses this to auto-recut templates into ads for you." data-profile-about data-initial-value="${escapeAttribute(input.about ?? "")}">${escapeHtml(input.about ?? "")}</textarea>
887
887
  </div>
888
888
  </form>
889
889
  <section class="files-card" data-files-card>