A Claude Code / Cursor / Windsurf skill for building UI that doesn't look AI-generated.
▶ See the live site & demo · ⭐ Star this repo if it saves you from one more indigo gradient — that star is the whole thanks the project asks for, and it helps other builders find it.
git clone https://github.com/codeswithroh/tastemaker ~/.claude/skills/tastemakerRestart Claude Code, then just ask it to build any UI — "build a landing page for a coffee subscription" — and tastemaker triggers automatically. No config, no API keys, nothing to invoke. (Using Cursor or Windsurf? Drop the folder in their skills directory instead.)
Ask an LLM to build a UI and you get the same handful of defaults every time: indigo-to-purple gradients, the same soft-shadow rounded card, a generic hero. That's not a prompting problem — it's what happens when a model has to invent visual taste from scratch, with no grounding and no memory of what you actually like.
Tastemaker fixes this with three ideas instead of a bigger catalog of presets:
- Ground in real pixels, not descriptions. Give it reference images and it extracts real color/contrast tokens deterministically from the actual pixels (
scripts/extract_palette.py) — not a text summary of the vibe, regenerated from that summary. Text-mediated style transfer is lossy; that's most of why AI UI looks generic even from a detailed prompt. - Remember, don't re-derive. Once a project's style is locked (
.tastemaker/style-lock.md), every later screen/component reuses it instead of drifting. Across projects, a lightweight personal profile (~/.tastemaker/profile.md) carries forward what you keep vs. reject, so your second project starts warm instead of cold. - Scope to what's actually being built. Reads your PRD/spec first to figure out which screens/components need design work, instead of dumping a generic design system disconnected from the real product.
Drop the tastemaker/ folder into your project's skills directory (or wherever your agent loads skills from — Claude Code, Cursor, and Windsurf all support this). Everything here runs locally; no hosted backend.
Requires Python 3 + Pillow for the deterministic color extraction script (pip install Pillow). Falls back gracefully to a vision-based read if Pillow isn't installed.
The design goal: a single prompt produces a complete site — real photos, illustrations, icons, and scroll animation all present the first time — with nothing the end user ever has to see as a credit line, and no accounts to set up. Every default source is keyless, API-first, and attribution-free by license:
- Photos → Openverse (
scripts/fetch_photos.py, no API key). Searches 800M+ openly-licensed images, filtered to CC0 / public-domain, which require zero attribution. Unsplash was dropped because its API forces visible on-site attribution; Pixabay remains an optional--source pixabayupgrade (needs a key) for higher-curation imagery. - Illustrations → built in — each concept is matched to real illustrator-grade art and recolored to the project's accent, zero attribution.
- Icons → Iconify (
scripts/fetch_icons.py, no API key) — permissively-licensed open sets (Lucide, Tabler, Phosphor…), pre-tinted to the accent, no attribution. - Credit in the code, never on the page.
fetch_photos.pywrites aCREDITScomment block (creator + source + license per photo) to drop into your HTML/CSS source as a voluntary thank-you — visible to developers reading the code, invisible to end users. Generous credit, zero visual hindrance. - Manual exceptions (unDraw, Streamline) are in
references/illustration-sources.mdfor when a section needs something the defaults don't fit — the exception, not the norm.
The upshot: photos, icons, and illustrations all fetch with no keys and no signups, so the single-prompt, complete-site promise holds out of the box.
Motion → GSAP + ScrollTrigger, loaded via CDN (plain HTML/CSS) or npm install gsap (React/Vue/etc.) — see references/tech-stack-guides.md. Free for commercial use, including ScrollTrigger and every previously-paid plugin, since Webflow's 2024 acquisition of GreenSock. Includes scroll-storytelling patterns (pinned sections, scrubbed reveals, sequenced hero timelines) so a landing page unfolds as you scroll rather than sitting static.
Most existing design skills for coding agents (e.g. curated style/palette libraries with search) give the model a bigger menu of canned presets to pick from. That's still generic — a library of options, not your taste, and it forgets everything once the session ends.
Tastemaker's actual differentiators:
- Reference images are the primary input, extracted deterministically, not just described in a prompt.
- Style, once established for a project, is locked and reused — no drift between screens generated in separate sessions.
- Personal taste persists and compounds across projects via a local profile file — the tool gets more accurate for a given developer the more they use it.
- Includes an asset-consistency step (one anchor asset, everything else conditioned on it) and an SVG validator (
scripts/validate_assets.py) that catches malformed generated assets before they ship — a real bug class (illegal--inside SVG<!-- -->comments silently breaking rendering) this project found during its own testing. - A curated style/pattern library (
references/) exists as a fallback for cold starts with no references — but it's explicitly scaffolding to adapt, not a catalog to apply unchanged.
tastemaker/
├── SKILL.md — the workflow, read this first
├── references/
│ ├── style-lock-format.md — schema for .tastemaker/style-lock.md
│ ├── style-tokens.md — starter palettes/type/shape by mood (cold-start fallback)
│ ├── component-patterns.md — layout patterns by screen type
│ ├── anti-slop-checklist.md — pre-delivery checks
│ ├── tech-stack-guides.md — wiring tokens (and GSAP) into React/Vue/SwiftUI/Flutter/plain CSS
│ ├── animation-guidelines.md — GSAP as default motion engine + scroll-storytelling patterns
│ └── illustration-sources.md — the attribution-free asset map (Openverse photos / built-in illustrations / Iconify icons), manual exceptions
├── scripts/
│ ├── extract_palette.py — deterministic color/contrast extraction from images
│ ├── validate_assets.py — SVG well-formedness validation
│ ├── fetch_photos.py — real photography via Openverse (keyless, CC0) + code-comment credits; optional Pixabay upgrade
│ ├── fetch_icons.py — icons via Iconify (no key, attribution-free, pre-tinted)
│ └── recolor_svg.py — recolor local SVGs (already on disk) to the locked accent
└── assets/
├── gsap-starter.js — default motion: wires data-reveal/data-reveal-group to GSAP + ScrollTrigger
├── reveal.css — dependency-free scroll-reveal fallback (same markup convention)
└── reveal.js — pairs with reveal.css
MIT.