Skip to content
Atelier

Atelier

On site A|B testing for unsure frontend designs

Created on 24th April 2026

Atelier

Atelier

On site A|B testing for unsure frontend designs

The problem your project solves

The broken internal loop

Every design team has the same workflow problem: feedback on landing pages is lost between a screenshot, a paragraph, and a guess.

  • A PM scribbles "make it more premium" on a Figma comment.
  • A designer tries three things in parallel, loses two of them.
  • A dev implements one, and the stakeholder says "no, more like Aesop."

The iteration loop is serial, lossy, and opinion-driven. Current AI tools make it worse — one-shot regeneration means every variant overwrites the last, and the "more premium palette" suggestion comes back as generic AI slop: "use a modern color scheme", "refine the typography". Specifically what? Nobody knows.

Atelier fixes the loop. Every critique becomes a branch on an infinite canvas you can see, compare, and keep. Every suggestion is grounded in real landing pages crawled from the open web — so "make it premium" lands as "swap Inter for Cormorant Garamond 700 italic, use Aesop's #EDE5D8 parchment, ghost outlined CTA."

How you are solving it

Every round of feedback is a branch, not an overwrite

Atelier is an infinite canvas (React Flow) where every variant is a live node with an iframe thumbnail. Seed from a URL, paste HTML, or pick one of 6 curated aesthetic templates.

From there, three AI primitives:

  1. Fork with Claude — prompt ("make the hero warmer"), choose Haiku/Sonnet/Opus, get a new child node with full HTML rewritten. Streams in via SSE so users see progress, not a 30s spinner.
  2. Grounded Critics — name a target vibe ("premium luxury"). Genspark pulls 3 real landing pages matching that vibe, Claude reads them, and returns 4–8 concrete, severity-tagged suggestions that cite the real pages. Users approve which to apply; one rewrite ships them all.
  3. Drag-to-combine (Opus) — drag one variant onto another and Opus synthesizes them into a new branch with dashed edges showing which parent donated what.

And a zero-loss viewer: click Compare on any two nodes, both full pages render side-by-side with desktop/tablet/mobile viewports. Nothing is lost between branches.

Stack: FastAPI + SQLAlchemy backend, Vite + React + Tailwind + React Flow frontend, Supabase (Postgres + object storage), Render for deploy. All source at github.com/bchuazw/atelier.

Use of Genspark

Genspark turns Claude's critics from "AI slop" into "cite-your-sources"

The problem with AI critiques: ask an LLM "make this more premium" and it responds with "use a more refined palette, modernize the typography." Useless.

Our solution uses the Genspark CLI (@genspark/cli) as a grounded research layer for the Critics feature:

  1. User enables "Ground with Genspark research" in the Critics dialog and specifies a target theme ("premium luxury").
  2. Backend (apps/api/atelier_api/providers/genspark.py) shells out to gsk web_search → pulls 3 real landing pages matching the theme (Aesop, Awwwards luxury category winners, Dribbble e-commerce).
  3. Parallel gsk crawler calls on each URL → returns full page markdown.
  4. That markdown is injected into Claude's critique prompt as "REAL-WORLD REFERENCES" context.
  5. Claude now returns suggestions like "Swap Inter for Cormorant Garamond 700 italic — every Awwwards luxury winner uses editorial serifs" and "Replace terracotta #c87050 with burnished gold #B89A5A, matching Dribbble's luxury category consensus."
  6. The UI renders the reference URLs as clickable chips so judges / users can verify the citations.

Architecture note: we initially tried batch_crawl_url_and_answer (one call, per-URL Q&A) but it returned "No content found" on the free plan for every URL we tested (including aesop.com and stripe.com). Fanning out N parallel crawler calls worked reliably and is still fast — ~10s for 3 sites on top of Claude's ~25s.

Windows subprocess fix: asyncio.create_subprocess_exec can't execute gsk.CMD (WinError 193). Switched to asyncio.to_thread(subprocess.run) which handles .CMD wrappers transparently.

Feature-flagged gracefully: if GENSPARK_API_KEY is missing or the gsk binary isn't on PATH, grounded critics silently degrades to Claude-only. Users see a "Genspark returned no references" notice; nothing breaks. On Render's Python runtime (no Node) this fallback kicks in, so the deployed demo runs Claude-only while the 2-minute video showcases the full Genspark pipeline.

Provider module: apps/api/atelier_api/providers/genspark.py
Wired into: apps/api/atelier_api/routes/critics.py

Use of Claude

Claude is the brain of every generative moment in Atelier

Four distinct Claude integrations, each picking the right model for the job:

  1. Fork rewrites (Haiku 4.5 / Sonnet 4.6 / Opus 4.7). Every "make the hero warmer" prompt calls Claude with the full current HTML + the user's instruction + project context. Streams back via SSE. Users pick the model from a compact picker — Haiku for 6-second drafts, Sonnet for production rewrites, Opus when they want the highest fidelity.
  2. Design Critics (Sonnet, default). Given target theme + optional Genspark grounding + current HTML, returns strict-JSON suggestions with category / severity / rationale tags. Users approve a subset; one composed prompt re-enters Claude to apply them all coherently.
  3. Drag-to-combine (Opus). Merging two sibling variants needs high fidelity reasoning about which stylistic choices to donate vs keep. Opus reads both HTMLs + the chosen aspects (typography / palette / layout / copy) and synthesizes a new variant that preserves the target's structure while importing only the listed aspects from the source.
  4. Feedback decomposition (AutoReason-style, Sonnet). Paste a stakeholder's multi-point paragraph; Claude extracts atomic change items with individual rationales. Users approve the checklist; one fork applies them all.

Prompt caching on the long system prompts (critic rubric, merge rubric) via cache_control: ephemeral — costs drop ~90% on follow-up calls within the same 5-minute window.

BYOK + fallback: users can POST their own key to /settings/api-key at runtime, or rely on the server-side ANTHROPIC_API_KEY. The /settings/status endpoint reports source-of-truth so the UI can warn "no key set."

Core call site: apps/api/atelier_api/providers/claude.py
System prompts: in apps/api/atelier_api/routes/ (fork, critics, merge, feedback — each has a cached system prompt).

What is the deployed URL for this project?

https://atelier-web.onrender.com

Tracks Applied (1)

Hackathon Prizes

Technologies used

Discussion

Builders also viewed

See more projects on Devfolio