Impeccable: A Design Vocabulary for Your AI Harness
Impeccable is a free Agent Skill pack, by Paul Bakaus, that gives an AI coding agent and its user a shared vocabulary — 23 invocable commands such as typeset, quieter, and colorize — for describing hierarchy, contrast, and restraint in generated interfaces. It runs inside a project’s own repository, inheriting existing tokens and components, and since v4 can also direct entirely new page builds and redesigns.
Generate a UI with any AI tool and you can spot it instantly: the purple-to-blue gradient, the cramped padding, the bouncy easing, the dark glow on a card. AI frontends all share one look — not because the models have bad taste, but because they have no words for hierarchy, contrast, and restraint. Ask for “better spacing” and you get a guess.
Impeccable, by Paul Bakaus, is a design language that fixes the vocabulary problem on both sides. It gives your agent 23 invocable commands and gives you the same terms, so you can ask for the exact thing — typeset the headings, quieter on this section, colorize strategically — instead of describing it and hoping. It runs inside your repo and inherits your existing tokens, components, and conventions. And since the v4 release (July 2026) it no longer only refines what you have: it can build new pages and redesigns too, through a visual direction you approve before any code is written.
What you’ll walk away with from Impeccable
Section titled “What you’ll walk away with from Impeccable”- Why AI-generated UIs converge on the same look, and what a shared vocabulary fixes
- How to install Impeccable and set up the context files every command reads
- Every one of the 23 commands — what it does, how it works, when to reach for it, and the detail worth knowing
- How v4’s “direction by dice” makes new builds land somewhere the model wouldn’t have gone alone
- Live Mode for in-browser iteration and the critique overlay for visual reviews
- The
detectCLI, design hooks, anddoctor— the automation layer for CI and long-lived projects - When to reach for Impeccable versus the broader design pipeline
Install
Section titled “Install”From your project root:
npx impeccable installThe installer detects which AI tools you use, writes the skill files into the right folders (.claude/skills/, .cursor/skills/, …), and asks whether to install project-locally or globally. Check and update later with:
npx impeccable check # is my install current?npx impeccable update # pull the latest buildThen run the one-time setup inside your AI tool:
/impeccable initThe context files everything reads
Section titled “The context files everything reads”Impeccable’s answer to “how does the AI know what our product should look like” is a small set of files in your repo. init interviews you about the product — who it’s for, how it’s positioned, what evidence you have, which brand commitments are non-negotiable — and writes the first one. The rest accumulate as you work:
| File | Holds | Written by |
|---|---|---|
PRODUCT.md | Platform, users, positioning, evidence, brand commitments | init (edit it — it’s yours) |
DESIGN.md | Colors, typography, components, radii, design rules | document (generated from your code) |
.impeccable/design.json | Structured token sidecar for automation | document — regenerate, never hand-edit |
.impeccable/surfaces/*.md | Per-page strategy: audience, proof sequence, chosen direction | Auto-written during work |
.impeccable/config.json | Detector ignores, hook settings, monorepo roots | You (config.local.json for git-ignored personal overrides) |
Two consequences are worth spelling out. First, surfaces remember their strategy: a later session continues a page’s argument instead of inventing a new one. Second, monorepos resolve context per workspace — each app uses its own PRODUCT.md/DESIGN.md and falls back to the repo root for anything it doesn’t define, with projectRoots globs in config when your workspace layout doesn’t match your design boundaries.
Four modes, chosen per surface
Section titled “Four modes, chosen per surface”v4 classifies every surface by what the visitor came to do, not by what the company sells — and adjusts its vocabulary and priorities accordingly:
| Mode | Surfaces | What wins |
|---|---|---|
| Persuade | Landing pages, campaigns, pricing | Distinctive type, committed palettes — design has to earn attention |
| Operate | Apps, dashboards, admin tools | Scanability and native expectations; brand lives in precise details |
| Read | Docs, guides, changelogs | Measure, rhythm, quiet hierarchy — comprehension first |
| Experience | Portfolios, galleries, showcases | The artifact leads; the interface recedes |
The mode is decided per surface, so one project can hold all four: a tool’s landing page is Persuade even if the product is Operate; a fashion house’s documentation is still Read.
The 23 commands
Section titled “The 23 commands”Every command is invoked as /impeccable <command> <target>. v4 regrouped them by intent — you name the discipline instead of describing the symptom:
| Group | Commands |
|---|---|
| Create | impeccable, shape |
| Evaluate | audit, critique |
| Refine | animate, bolder, colorize, delight, layout, overdrive, quieter, typeset |
| Simplify | adapt, clarify, distill |
| Harden | harden, onboard, optimize, polish |
| System | init, document, extract, live |
The commands are designed as pairs: bolder ↔ quieter are two halves of voice; audit finds technical issues and harden fixes them; critique reviews and polish refines; init captures the product and shape plans the surface. Before shipping, the docs recommend a “pre-ship gauntlet” of audit, clarify, and harden.
What follows is the full catalog, command by command — what each one does, how it works, and the detail worth knowing before you run it.
Create
Section titled “Create”impeccable — the router and the freeform request
Section titled “impeccable — the router and the freeform request”The main command, used two ways. Bare /impeccable inspects the project — do the context files exist, what state is the code in — and recommends two or three next moves, waiting for you to choose. With a plain-English request (/impeccable redo this hero section) it picks the right specialist command or does the work directly, reading PRODUCT.md, DESIGN.md, and the surface’s mode before writing a line.
Reach for it when you don’t know where to start, when no specialist command maps cleanly, or when the work spans several disciplines at once (“redo this hero” touches layout, type, color, and motion — no single command owns that). The docs are explicit about the right attitude: it’s an opinionated design partner, not a linter. If you have a real reason to push back — brand guideline, accessibility constraint, user research — push back with the reason and it works with you; silently ignoring the opinion is what produces worse output.
shape — discovery before code
Section titled “shape — discovery before code”Where a feature starts. shape runs a structured discovery interview — 5 to 10 conversational questions about purpose and context, content and realistic data ranges, design goals, and constraints — and refuses to write code during the phase. The output is a design brief: purpose, user and their state of mind, content, intended feeling, constraints. “A compass, not a spec” — it captures intent, not UI.
Use it whenever a ticket is vague or you catch yourself writing JSX to figure out what the product should be. The interview costs maybe five minutes; the rewrites it avoids are measured in hours. The trap is answering with “standard” or “normal” — specificity is the whole point, and “rushed, on mobile, mid-meeting” changes everything downstream. If you want discovery and the build in one go, skip shape and just describe the surface — the new-work flow runs the same interview and reuses shape’s answers if it already ran.
Evaluate
Section titled “Evaluate”audit — does this hold up
Section titled “audit — does this hold up”The technical counterpart to critique: where critique asks “does this feel right”, audit asks “does this hold up”. It scans five dimensions — accessibility (WCAG contrast, ARIA, keyboard nav, form labels), performance, theming (hard-coded colors, dark-mode coverage), responsive behavior, and anti-patterns (the same deterministic checks the detector runs) — scores each 0–4, and tags every finding P0 (blocks release) through P3 (polish). What comes back is a single document you can paste into a ticket tracker.
The design decision worth knowing: audit documents, it doesn’t fix. You route the P0s to harden, the perf findings to optimize, the rest to polish. On a native project the five web dimensions swap out for VoiceOver/TalkBack behavior, Dynamic Type, platform touch-target minimums, and HIG/Material 3 conformance. The classic mistake is skipping the dimensions you assume are fine — theming and responsive are the ones that usually aren’t.
critique — an honest second opinion
Section titled “critique — an honest second opinion”For work that’s functionally done, when the question is “is it any good”. Critique runs two independent assessments in parallel so they can’t bias each other: an LLM design review (Nielsen’s ten heuristics scored 0–4, a cognitive-load count out of eight, the emotional journey through the flow, brand fit against PRODUCT.md) and the deterministic detector. It also tests through persona lenses — “the evaluator, comparing us to two alternatives on a Tuesday evening”, “the skeptic, who has seen every SaaS landing and is bored” — each scoring the page separately.
The merged report gives an AI-slop verdict (pass/fail with the specific tells), the heuristic scores, three to five priority issues with what/why/fix, and — the part the docs say people wrongly skip — provocative questions the interface can’t decide for itself, which are usually the fixes that change the design most. Don’t run it on half-finished work (it scores incompleteness, not badness), and treat scores as diagnostic, not a grade.
Refine
Section titled “Refine”animate — motion that communicates
Section titled “animate — motion that communicates”For interfaces where state changes are instant and jarring and the user never quite trusts that their click registered. It finds the static moments that need motion — entrances and exits (200–300ms fades with subtle Y or scale), state feedback (hover, focus, loading, success), view transitions, progress — and applies them with strict discipline: easing is always exponential ease-out (“real objects decelerate smoothly”), and it animates transform and opacity only, using grid-template-rows for height transitions.
The interesting part is what it refuses: ask for bounces or elastic springs “for energy” and it won’t give them to you — that’s decoration, and bounce easing is literally a detector rule. Every animation ships with a prefers-reduced-motion fallback, non-negotiable. It’s not a dial: “more animation” is not a request it honors.
bolder — from safe to committed
Section titled “bolder — from safe to committed”For interfaces that look like every other interface: generic sans, medium weights, soft shadows, modest accent, forgettable. Bolder amplifies four axes — scale (display type pushed to clamp(3rem, 6vw, 6rem) and beyond), weight contrast (300 against 800 instead of medium against regular), color commitment (the accent at full strength, backgrounds that take a stance), and compositional confidence (asymmetry, off-grid, scale jumps).
Its core rule: it does not add, it amplifies what’s already there — a three-color design doesn’t get a fourth color, it gets harder commitment to the three. And since v3.9, with a DESIGN.md present it stays inside your design system, asking before it expands it. Don’t run it on dashboards or operator tools (“boldness earns its place on marketing pages, hero moments, and content features”), and if the result shouts, quieter is the designed follow-up.
colorize — strategic color, not a rainbow
Section titled “colorize — strategic color, not a rainbow”The counterweight to “everything is gray”. It reads your brand color, gives the primary action the strongest expression of it, derives muted variants for secondary accents, and — the cleverest move — tints your neutrals toward the brand hue at 0.005–0.01 chroma: invisible per pixel, but it makes the whole page cohere subconsciously.
It works in OKLCH rather than HSL, so equal lightness steps look equal and chroma drops automatically toward the extremes — “color that feels considered instead of computed”. Typical diff: brand hex becomes --color-accent: oklch(62% 0.18 240), chart series get three distinct hues at matched lightness so no series visually dominates. It needs a starting hue (it asks if PRODUCT.md doesn’t have one), and it only adds — an already-garish interface needs quieter first.
delight — personality that survives deletion
Section titled “delight — personality that survives deletion”A finishing skill, never the first thing you run. It hunts the places designers skip: empty states (“Your dashboard is quiet. Let’s fix that.”), loading moments (a three-stage message that advances as sync progresses), success feedback (a one-time celebratory toast — after that, a quiet checkmark), microcopy, and easter eggs that reward attention.
Two rules make it work. It reads brand tone from PRODUCT.md and matches it — a clinical analytics tool gets dry, precise cleverness, not jokes. And every delight moment must still work perfectly if you delete the delight: nothing functional depends on the smile. It’s deliberately conservative — one moment of delight is memorable, twenty become noise.
layout — spacing, rhythm, hierarchy
Section titled “layout — spacing, rhythm, hierarchy”For pages where nothing is technically wrong but nothing is breathing: equal padding everywhere, monotonous grids, hierarchy that relies on size alone. It assesses five dimensions — spacing consistency (are there random 13px gaps), visual hierarchy (does the eye land on the primary action within two seconds), grid and alignment, rhythm (does the page alternate tight and generous, or is everything uniform), and density.
Typical fixes: the spacing scale unified to 8/16/24/48/96, decorative borders replaced by spacing-driven grouping, primary actions pulled out of the flow with real buffer. The most useful thing it can tell you is also the hardest to hear: if the verdict is “nothing is primary”, no spacing tweak fixes that — you need a content decision.
overdrive — one extraordinary moment
Section titled “overdrive — one extraordinary moment”The permission slip for technical ambition: WebGL shader heroes, tables that handle a million rows, dialogs that morph out of their trigger, cinematic View Transitions. The discipline is that it picks one moment and commits, rather than spreading effect across the interface — and everything is budgeted, profiled at 60fps, and shipped with reduced-motion fallbacks.
Its output is announced with a ──── ⚡ OVERDRIVE ──── banner so you know you’re entering a more ambitious mode: expect larger diffs, new dependencies, and implementation depth beyond the other commands. It works because it’s rare — “if every page has cinematic moments, none of them are cinematic” — and it’s explicitly wrong for operator tools, where reliability beats spectacle.
quieter — turn it down without losing the point
Section titled “quieter — turn it down without losing the point”The counterweight to bolder, for interfaces shouting at full volume: neon on dark, gradient text, six accent colors, everything animated. It reduces along four axes — color (down to one primary plus muted support, desaturated in OKLCH), contrast (pure white and black pulled back to paper and ink), decoration (shadows and borders that do no work removed), and motion (slowed, auto-play removed).
The promise that distinguishes it from a blanket “make it minimal”: it preserves intent. “If the original had a point of view, the quieter version has the same point of view with more confidence — refinement, not neutralization.” Diagnostic tip from the docs: “too busy” usually means too many things, which is a distill job; quieter fixes too loud.
typeset — typography that looks designed
Section titled “typeset — typography that looks designed”For text that looks like default typography: muddy hierarchy, three sizes that read the same, body copy at 14px, a “display font” that is actually just Inter bold. It assesses font choices (are you on the invisible defaults — Inter, Roboto, Arial), hierarchy (at least a 1.25× ratio between steps), scale coherence, readability (45–75 characters per line, 16px minimum body), and consistency (no one-off font-size overrides).
A distinction worth stealing even if you never run the command: it builds fixed rem scales for app UIs and fluid clamp scales for marketing pages — fluid typography belongs where line length varies dramatically, not in a settings screen. Font suggestions come from the brand voice in PRODUCT.md; without init, they’ll be generic.
Simplify
Section titled “Simplify”adapt — another context, same features
Section titled “adapt — another context, same features”For taking a design that’s solid in one context and making it work in another: mobile from desktop, tablet from mobile, print from web, email from dashboard. It works through breakpoints and fluid layout, touch targets (44px minimums, tap zones larger than visual bounds), navigation patterns (sidebars become bottom nav, hover states get touch equivalents), and content priority (what stays visible, what collapses, what goes).
The non-negotiable rule is in the name of the section: adapt, don’t amputate — if mobile hides things desktop can do, that’s a regression, not an adaptation. And mobile isn’t a smaller desktop; it’s a different context (“thumbs, interruption, short sessions”). On native projects it swaps vocabularies entirely: phone-to-tablet, one platform’s conventions to the other’s. The docs recommend running harden afterward — responsive layouts reveal the edge cases that only show up at 320px.
clarify — words that explain themselves
Section titled “clarify — words that explain themselves”For interface text that makes people stop and think. It rewrites across the surfaces where UX copy actually fails: labels and hints (direct, specific), button copy (verb-first, describes the outcome), error messages (what went wrong, whose fault, what to do next — never blaming the user), empty states (orient, explain, offer a next step), tooltips (add what the label can’t carry, never restate it), and confirmation dialogs (name the consequences).
The before/after examples tell the story: “Invalid input” becomes “This card number is 15 digits. You entered 14.” and “Submit” becomes “Charge $29 and subscribe”. Voice is tuned to the audience in PRODUCT.md — technical readers get precision, anxious moments (payment, delete) get reassurance. Two boundaries: it’s for functional UX text, not marketing copy; and if the copy is already clear, you want delight, not a clever rewrite.
distill — ruthless subtraction
Section titled “distill — ruthless subtraction”Starts from one question: what is the single job this interface is trying to do? Everything that doesn’t serve that job is on the chopping block. It works in two passes — name the complexity sources (too many elements, excessive variation, visual noise, feature creep), then edit ruthlessly: remove, combine, hide behind disclosures, consolidate variation into a single treatment.
A typical pass collapses four card styles into one, demotes two of three button variants to text links, and regroups a 14-item sidebar from five sections into three. The principle is “fewer obstacles, not fewer features” — distill removes what’s in the way, never what users rely on daily. Timing matters: run it after critique flags cognitive load, but not while the feature is still growing, or you’ll distill the same thing again next week.
Harden
Section titled “Harden”harden — the day the interface meets reality
Section titled “harden — the day the interface meets reality”Real user data is messy: 60-character names, German product titles, prices in the billions, 500 errors, offline modes, right-to-left text. Harden works through four dimensions — text and data extremes, error scenarios (network failures, 4xx/5xx, rate limits, concurrent operations), internationalization (German runs ~30% longer than English; dates, currencies, RTL), and device context (touch, slow connections, low-power mode) — and applies the concrete fix for each failure mode it finds.
A typical run on a profile page: ellipsis with a tooltip on .user-name, the bio switched to max-height with a “show more” disclosure, an empty state added, a skeleton loader for the async avatar, tested at name lengths 1/20/60/200. Run it per page, not all at once — and don’t skip i18n because “we’re English-only for now”: i18n-safe layouts are simply better layouts.
onboard — the path to the aha moment
Section titled “onboard — the path to the aha moment”Everything starts from one question: what is the aha moment, and how fast can a new user get there? It designs the surfaces that decide retention — the first-run experience (tour, blank canvas, or filled example the user can modify), empty states (where am I, why is this empty, what do I do next), setup (minimized fields, smart defaults, each step explaining why), progressive disclosure, and activation events, instrumented and celebrated quietly.
It explicitly resists the two default failure modes: the over-tutorialized carousel users click through before touching anything (“most products don’t need a tour, they need a better first screen — tours are a crutch”) and zero-onboarding that drops users into an empty app. If you can’t say in one sentence what the user should feel in the first 60 seconds, the docs send you back to shape first.
optimize — performance with receipts
Section titled “optimize — performance with receipts”For interfaces that feel slow: late first paint, janky scroll, an 800KB bundle. It works five dimensions — Web Vitals (LCP, INP, CLS), rendering (unnecessary re-renders, layout thrash), animation properties, images (lazy loading, srcset, AVIF, dimensions set against CLS), and bundle size (dead code, missing code-splitting).
What makes it trustworthy is its accounting: it measures before and after, quantifies every fix, and rolls back changes that don’t move a metric. The output reads like a ledger — “LCP: 3.2s → 1.4s: hero image preloaded (−800ms), render-blocking font stylesheet removed (−240ms)”. It also knows when to stop: if LCP is 1.1s and INP is 80ms, it tells you the design work matters more.
polish — the last pass before shipping
Section titled “polish — the last pass before shipping”Hunts the small details that separate shipped from polished: half-pixel misalignments, forgotten focus states, loading transitions that flash, copy that drifts in tone. It discovers your design system first, then works six dimensions — alignment and spacing, typography (widows, kerning), color and contrast, interaction states (hover, focus, active, disabled, loading, error, success — every state accounted for), motion, and copy — and also pulls drifted features back in line, replacing hard-coded values with tokens and custom one-offs with shared components.
The docs define what a healthy run looks like, and it’s telling: “five small fixes, no rewrites”. If polish turns into rearchitecting a layout, you needed critique or layout instead — and polish catches feel-based issues while audit catches measurable ones, so the pre-ship pair is both.
System
Section titled “System”init — the interview everything else reads
Section titled “init — the interview everything else reads”Run once at the start (and again when positioning shifts). It scans the codebase first — README, package.json, components, tokens, brand assets — and turns that into a hypothesis rather than a questionnaire, quoting back what it inferred (“from the routes and the Swift package, this reads as an iOS app — match?”) and asking at most three questions per round: who the primary user is and in what situation, what the product makes possible that a neighbor couldn’t truthfully copy, and what durable constraints or evidence future work must preserve.
Two deliberate refusals shape it. It won’t ask about aesthetics — no colors, no fonts, no references; those belong to the design work, where the surface and its direction get decided together. And its “Evidence on hand” section records what’s real (including absences: “no customer logos yet, do not invent any”), so nothing downstream fabricates a logo wall or a fake metric. PRODUCT.md stays strategy-only; the visual system lives in DESIGN.md, which init offers to generate at the end.
document — your design system, in a format tools can parse
Section titled “document — your design system, in a format tools can parse”Scans your code in priority order — CSS custom properties, Tailwind config, CSS-in-JS themes, token files, component source, computed styles from the rendered page — and asks exactly one grouped question about what a scan can’t infer: what the system is for, including a named metaphor for the whole thing (“The Editorial Sanctuary”) and descriptive color names (“Deep Muted Teal-Navy”, not “blue-800”).
The output follows the Google Stitch DESIGN.md format: exactly six sections (Overview, Colors, Typography, Elevation, Components, Do’s and Don’ts) with headers fixed character-for-character so other DESIGN.md-aware tools can parse the file, plus the .impeccable/design.json sidecar that powers Live Mode and the design-aware detector rules. The file is primarily for the AI — its forceful “never/always” register is intentional. On a fresh project with no code to scan, document --seed asks five strategic questions and writes an honest scaffold marked <!-- SEED -->; a fake full spec is worse than no spec.
extract — when your codebase became a design system by accident
Section titled “extract — when your codebase became a design system by accident”For the moment you notice the same button style in twelve places and hex colors scattered everywhere. It runs three steps: discover the drift (repeated values, button variants, spacing that accidentally matches a scale), propose primitives (token names, component APIs with variant and size), and migrate the call sites in the same pass — extraction without migration just creates a third way of doing the same thing.
Its restraint is the feature: it only extracts what’s used three or more times with the same intent — “two usages are not a pattern”, and it never extracts because something might be reused later, because premature abstraction is worse than duplication. A typical run: 14 button instances across 8 files become one Button component with four variants, ~180 lines of duplicated CSS deleted, three missing tokens added.
live — the browser as the canvas
Section titled “live — the browser as the canvas”Covered in depth below — the short version: pick an element on your running dev server, annotate with chips, freeform text, comment pins, or strokes, and get three production-quality variants hot-swapped in via HMR, each anchored to a genuinely different archetype. Accept one and it writes back to true source.
Scope is the thing to understand: Live Mode iterates on a single picked element. For “redo the entire pricing page”, talk to /impeccable directly. And if brand fit matters, have PRODUCT.md and DESIGN.md in place first — DESIGN.md wins on visual decisions, PRODUCT.md wins on voice, and without them variants drift toward generic defaults.
New builds in v4: direction by dice
Section titled “New builds in v4: direction by dice”The headline change in v4 is how Impeccable handles new work — a greenfield build, a new page, a redesign. It starts from a measurement: ask a coding model for something creative and it builds its favorite idea, every run. In the v4 research campaign (~200 sampled concepts, $2,600 of evals), 30 of 35 answers came back as the identical concept even when the request was framed sixteen different ways. The models don’t lack creativity, the authors conclude — they lack variance.
The fix is to take the choice of direction away from the model’s own ranking:
-
Classification. You describe the work conversationally (
/impeccable redesign the marketing site). Impeccable works out the job type — blank slate, new page in an existing product, section added to a working page, redesign, or scoped refinement — and each gets a different amount of freedom. An addition inherits the surrounding page’s look and decides only what it introduces; a redesign treats the old look as evidence to replace, not something to polish. -
The roll. The model derives grounded directions from your product, and an outside seed deals six challenger “worlds” beside them from a deck of 188 hand-approved graphic systems (out of 360 reviewed) — Dubois data portraits, split-flap boards, Saul Bass titles. Worlds are challengers, not templates: they only take the build if they beat the product-derived directions on merit. Every roll prints a key that reproduces it.
-
You decide. In an attended session Impeccable opens a decision page: one committed direction leading, the challengers as alternates. You can accept, re-roll (“deal again” — no duplicates), or steer with one line (“too corporate”). A direction you pinned always wins, your explicit choices (“1970s hi-fi catalog look, Futura”) lock in and override everything, and rejecting all of it is a valid answer — nothing gets built until you pick.
-
Rendered before built. The chosen direction is drawn as a design-system board (palette, type, component character) and a first-surface mock at a real viewport, and the build is then corrected against those images. No native image tool in your harness? Set
OPENAI_API_KEYand it renders through gpt-image-2, telling you it bills your key first. -
A contract, then a check. Before code, the agent writes a five-block contract (thesis, own world, story, first viewport, form — 150 words max) into the artifact’s opening comment. A finishing review then audits the result against it, promise by promise, in its own subagent where the harness allows.
Candidate directions also have to pass five tests before they’re dealt: Truth (the relationships exist in the actual product), Translation (works independent of its source styling), Consequence (removing its best element weakens the page), Survival (works across devices and budgets), and Fit (honest tradeoffs for the brief). The full methodology — including why “generate ideas, pick the best one” collapses at the selection step, not the ideation step — is written up at impeccable.style/research.
Live Mode
Section titled “Live Mode”/impeccable live turns iteration into a browser session against your running dev server. A helper starts on port 8400, injects a picker into your dev entry, and a small pill appears at the bottom of the page:
- Pick an element. A context bar appears: choose a command chip (
bolder,typeset,layout, …), type a freeform instruction (“more playful”, “less SaaS”), drop comment pins on specific parts (a pin near the title is about the title, not the whole element), or draw strokes — a closed loop marks importance, an arrow shows direction, a cross marks deletion. - Generate. Three genuinely different variants render in place, each anchored to a distinct archetype —
colorizegives three hue families,animatethree motion vocabularies,layoutthree structural arrangements. Cycle them with arrow keys. - Accept (Enter) and the variant writes back to your true source file, with CSS consolidated into your project’s real stylesheet rather than left inline. Escape discards all three.
It works against any dev server with hot-module reload — Vite, Next.js, SvelteKit, Astro, Nuxt, Bun, TanStack (Router and Start since v4.0.2) — or a plain HTML file. It’s labeled beta: solid on the common paths, with edge cases on unusual setups. On strict-CSP apps it detects the block and offers a one-time, development-only patch guarded by NODE_ENV === "development". If the port sticks around, /impeccable live stop releases it.
Critique with the visual overlay
Section titled “Critique with the visual overlay”/impeccable critique the pricing page at localhost:3000/pricing runs two independent assessments in parallel: an LLM review (Nielsen’s ten heuristics, a cognitive-load checklist, brand fit read from PRODUCT.md) and the deterministic detector. On harnesses with browser automation it opens the page with an overlay that outlines every finding in place, with a floating label naming the rule — no screenshot-to-paragraph mapping, and after a fix you reload and watch the outline disappear, so you never ship a fix that didn’t actually satisfy the rule.
The report scores three layers: heuristics (target: 3.5+/4 average), cognitive load (target: fewer than 2 checklist failures), and a binary AI-slop verdict. The same overlay ships as a Chrome extension — one click on any page, no harness involved.
The detect CLI: an anti-slop gate for CI
Section titled “The detect CLI: an anti-slop gate for CI”Separate from the harness commands, Impeccable ships a deterministic detector — no LLM, no API key — that you can run anywhere:
npx impeccable detect src/ # a source foldernpx impeccable detect index.html # a single filenpx impeccable detect https://example.com # a rendered pagecat component.css | npx impeccable detect # stdinnpx impeccable detect --json . # machine-readableThe pattern catalog has grown fast: 44 rules when we first covered it, 64 patterns today, of which 59 are enforced deterministically (the other five are judgment calls that stay in critique’s LLM review). Each rule is tagged by how it runs: CLI (static, no browser), Browser (deterministic but needs real layout — runs via the extension or Puppeteer), or LLM-only. The catalog, browsable at impeccable.style/slop with eleven synthetic slop pages to try the overlay on, spans nine categories:
| Category | Rules | Flavor |
|---|---|---|
| Your design system | 4 | Font, color, radius, or type size that drifts from DESIGN.md |
| Visual details | 8 | Side-tab accent borders, decorative grids, glassmorphism, hairline-border-plus-glow |
| Typography | 10 | Flat hierarchy, icon tiles above headings, italic-serif heroes, overused fonts (Inter, Geist, Instrument Serif) |
| Color & contrast | 6 | Purple/cyan palettes, radial glow halos, gradient text, the reflexive cream/beige background |
| Layout & space | 13 | Nested cards, monotonous spacing, over-long lines, overflow, clipped popovers |
| Motion | 6 | Pulsing status dots, blinking fake cursors, marquees, bounce easing, layout-property animation |
| Copy | 5 | Em-dash overuse, marketing buzzwords, aphoristic cadence, “theater” framing |
| Imagery | 2 | Shape-assembled hero art, broken or placeholder images |
| General quality | 10 | Contrast failures, cramped padding, uncaught script errors, content stuck at opacity: 0 |
The first category is the interesting one: with a DESIGN.md in the project, the detector stops being generic and starts flagging drift from your own system — a font outside your documented stack, a literal color outside your palette, a radius off your shape scale.
It exits 0 on clean, 2 on findings, 1 on failure, which drops straight into a PR check. Intentional exceptions don’t have to fight the gate: manage them with npx impeccable ignores list|add-value|add-file (stored in .impeccable/config.json, with reasons), or inline:
/* impeccable-disable-next-line bounce-easing */It reads JSX, TSX, Vue, Svelte, Astro, CSS, and HTML out of the box, and server-side templates (Blade, ERB, Twig, Handlebars) if you name their extensions in config. Useful flags: --scope type narrows to one domain, --no-design-system skips the personalized rules, --no-config runs raw. One honest limit: the engine reads HTML and CSS, so it has nothing to say about native iOS or Android code.
Design hooks: the detector on autopilot
Section titled “Design hooks: the detector on autopilot”Instead of remembering to run detect, you can have it run automatically every time your agent edits a UI file. /impeccable hooks on installs a provider-native hook manifest — .claude/settings.local.json for Claude Code, .github/hooks/impeccable.json for Copilot (CLI and cloud agent), .codex/hooks.json for Codex, .cursor/hooks.json for Cursor. Claude Code, Copilot, and Codex check after each edit; Cursor reviews proposed writes before they land and can block them.
The clever part is two-speed reporting. Nagging the model with every rule on every edit measurably made it play safe, so per-edit checks now surface only what is objectively broken — contrast failures, overflowing text, broken images, glow, drift from your own design system — and everything else waits for one full pass across every UI file touched, at the end of the session. (Set hook: { "perEditRules": "all" } if you want the firehose back.)
Control it with /impeccable hooks status|on|off, save confirmed exceptions with /impeccable hooks ignore-value overused-font Inter --shared --reason "Brand font", and configure it under the hook key in .impeccable/config.json (enabled, quiet, auditLog for an NDJSON debug log). IMPECCABLE_HOOK_DISABLED=1 kills it for one shell session.
Doctor: keeping an older project current
Section titled “Doctor: keeping an older project current”v4 changed what PRODUCT.md holds, so projects set up under v3 carry answers the current version no longer reads. Impeccable now runs a cheap staleness check at session start (each finding raised at most once a week; "stalenessCheck": false disables it) and offers /impeccable doctor for the deep pass: how much UI work shipped since DESIGN.md was last touched, ignored detector rules that no longer exist, a hook whose script path stopped resolving and has been scanning nothing while looking installed. Mechanical drift it repairs itself; judgment calls it routes to init or document with the specific gap named. In monorepos it prints a table of which apps carry their own context and which silently inherit the root’s — including the expensive-to-miss case of an iOS app inheriting web-only guidance.
Native iOS and Android (alpha)
Section titled “Native iOS and Android (alpha)”One of the most-requested features landed in v4 as an alpha: init works out the platform from the project, and on an iOS, Android, or cross-platform codebase it loads the Apple HIG or Material 3 rulebook on top of the design guidance — audit and adapt become native passes covering VoiceOver, TalkBack, touch targets, and platform conformance instead of CSS. Live Mode, the detector, and the design hook all read a browser or parse HTML, so they sit out on native projects.
When to reach for it
Section titled “When to reach for it”- Your AI-built UI is functional but generic and you want to direct specific improvements without learning to art-direct in prose.
- You’re starting a new page or a redesign and want it to land somewhere other than the model’s favorite idea — with a direction you approve before code.
- You want a deterministic design-quality gate in CI (
detect), or the same check running automatically on every agent edit (hooks). - You’re polishing an existing codebase and need changes to inherit your tokens and components, not fight them.
For a full design-to-code methodology — mockup, prototype, design system, implementation — Impeccable slots into the build and polish stages of the four-stage design pipeline rather than replacing it. And where Impeccable audits design, shadcn/improve audits architecture — they’re complementary skills.
Taste Skill overlaps more since v4: both now constrain generation up front. The difference is mechanism — Taste Skill imposes one curated direction with hard rules; Impeccable derives directions from your product, deals challengers beside them, and makes you pick. Reach for Taste Skill when you want an opinionated house style on the first pass; reach for Impeccable when you want variance grounded in your own brand, plus the audit/refine vocabulary for everything after.