Chat wizard + visual swatches. Here's the system design:
Where it fits in the current flow:
HomePage → pick template → EditorPage (variations + filmstrip)
↓
"Personalize" button (NEW)
↓
Chat Wizard (NEW)
↓
Personalized image generated
The wizard opens as a side panel or overlay on EditorPage, after the user has picked a template + variation they like.
Chat Wizard — 5-step conversational flow:
Each step is one AI message + user response. The AI adapts its language based on the template type (quote vs promo vs product).
Step 1: Headline
AI: "What's your headline? The current text says 'LESS IS MORE'
— what should it say for you?"
User types: "TRAIN HARDER"
→ Stores: { headline: "TRAIN HARDER" }
Step 2: Brand Context
AI: "Nice! Who's this for — describe your brand or business
in a few words"
User types: "Crossfit gym in Austin"
→ Stores: { brand: "Crossfit gym in Austin" }
Step 3: Colors (VISUAL SWATCHES)
AI: "Pick a color vibe that matches your brand:"
[Shows 12 swatch circles from STYLE_MODIFIERS — Neon Dark,
Pastel Soft, Bold Primary, Earth Organic, etc.]
[Also has "Custom" option to type hex codes]
User clicks: Earth & Organic
→ Stores: { style_id: "earth_organic", colors: "terracotta, sage..." }
Step 4: Mood/Energy
AI: "What feeling should people get from this post?"
[Shows 5 clickable chips:]
🔥 Urgent/FOMO | 🧘 Calm/Trust | ⚡ Energy/Hype
💎 Premium/Luxury | 🎉 Fun/Playful
User clicks: ⚡ Energy/Hype
→ Stores: { mood: "energy" }
Step 5: Call to Action
AI: "Last one — what should people do after seeing this?"
[Shows clickable options:]
"Shop Now" | "Book Now" | "Link in Bio" | "DM Us"
"Save This" | "No CTA"
User clicks: "Book Now"
→ Stores: { cta: "Book Now" }
After step 5, the wizard compiles everything into a personalized prompt and generates the final image.
Backend: New /api/personalize endpoint
POST /api/personalize
{
"template_id": "ig_post_minimalist",
"variation_prompt": "...", # from selected variation
"personalization": {
"headline": "TRAIN HARDER",
"brand": "Crossfit gym in Austin",
"style_id": "earth_organic",
"mood": "energy",
"cta": "Book Now"
}
}The backend builds a merged prompt:
- Takes the variation's prompt (or base template prompt)
- Swaps placeholder text with user's headline
- Appends style modifier from selected swatch
- Adds mood/energy direction
- Adds CTA text + positioning
- Sends to Gemini Pro for final generation
Returns the personalized image URL.
Frontend: ChatWizard component
New component ChatWizard.jsx that renders inside EditorPage:
- Slides in from the right as a panel (desktop) or bottom sheet (mobile)
- Each step is a chat bubble from "AI" + user input area
- Steps 3/4/5 use clickable chips/swatches instead of text input
- Shows a progress indicator (step 1/5, 2/5, etc.)
- After step 5: "Generating your design..." spinner, then result
- User can go back to any step and change their answer
- "Start over" button clears all answers
Data flow:
ChatWizard state:
{
step: 3,
answers: {
headline: "TRAIN HARDER",
brand: "Crossfit gym in Austin",
style_id: null, // not answered yet
mood: null,
cta: null
},
generating: false,
result: null
}
Key design decisions to confirm:
-
Panel placement — Right side panel (like Figma's properties panel) or modal overlay? I'd lean panel so the user can still see the current template while answering.
-
Should the AI messages be dynamic? — e.g., after user says "Crossfit gym in Austin", the AI could respond "Cool, a CrossFit gym! Let's pick colors that match that energy" before showing swatches. This makes it feel more conversational but costs an LLM call per step. Alternative: pre-written messages that reference the template type only (no LLM call, faster).
-
Re-generation — After seeing the personalized result, should the user be able to say "make it bolder" or "change background to darker" in free-text? That's a v2 feature but worth knowing if you want to architect for it now.