Skill + craft cleanup, detector hardening, native subagent pipeline (#152)

* skill: drop quality tiers, keep the real brand-craft guardrails

Codex's craft/brand pass introduced fast/ship/showpiece "quality bars"
plus brand-specific build gates, asset ledgers, sub-agent review, and
self-graded fallback labels. In practice those tiers became escape
hatches rather than craft pressure: the final output should always be
10/10, and the real decision points are splashiness and maximalism, not
quality.

Removed:
- All quality-bar / showpiece / fast / ship framing in shape.md and craft.md
- Standalone Brand Direction (#4) and Asset Requirements (#10) sections
  in shape's brief; renumbered back to 1-10
- The Brand hard rules section in brand.md (folded its real prohibitions
  into the existing Imagery and Brand bans sections)
- Brand-specific build-gate item, mock-fidelity bullet, production-bar
  bullet, present-step bullet in craft.md
- Asset ledger ceremony in craft Step 4
- Review-only sub-agents and "self-reviewed fallback, not independently
  validated" machinery in craft.md and polish.md
- The For brand surfaces, assess hard failures subsection in polish.md
  and the brand checklist row
- tests/brand-showpiece-reference.test.mjs (and its package.json wiring)

Kept (the real nuggets):
- Asset-substitution prohibition: image-led briefs ship real/generated
  assets or canvas/SVG/WebGL, not generic CSS panels, cards, bullets,
  or copy
- Repeated tiny uppercase tracked kicker labels as a brand ban
- Detector/QA output is defect evidence only, never proof of quality
- "What visual assets are real content here?" discovery question
- Inspect each major section individually for brand and long-form work
- repeated-section-kickers detection rule + fixture
- CLI improvements (JSON to stdout, -json/-fast aliases, severity field)
- critique.md: npx impeccable detect --json fix

Harness output dirs refreshed via bun run build. Full test suite (186)
passes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* skill: strip gate ceremony; require shape pause; allow compact briefs

The setup gate table and IMPECCABLE_PREFLIGHT banner pushed every
craft run through ritual restatement (PRODUCT.md → original prompt
→ round 1 → round 2 → 70-line "confirmed brief" → critique → summary,
all saying the same thing). Replaced with imperative prose that still
demands the same work but skips the user-facing telemetry.

Specifically:

SKILL.md
- Drop the Setup gate table and IMPECCABLE_PREFLIGHT banner.
- Keep the imperative steps explicitly: load context, identify register
  and load brand.md or product.md, AND load the matching command
  reference (craft.md / shape.md / etc.) when a sub-command is invoked.
  The command-reference step is non-negotiable; without craft.md loaded
  the agent skips the shape-and-confirm pause.

craft.md
- Drop the Build Gate / Craft Contract formal sections; replace with
  one paragraph stating prerequisites.
- Step 1 explicitly requires ending the response after presenting the
  shape output; the user must confirm before any code lands. Allows a
  compact 3-5 bullet brief when the prompt + PRODUCT.md already pin
  direction (full 10-section structure reserved for genuinely
  ambiguous tasks).
- Step 3 image gate skips silently when image generation isn't
  natively available; no user-facing announcement.
- Step 6 explicitly legitimizes "first pass clean, shipping" as a
  valid endpoint and bans inventing fake defects to demonstrate
  iteration.

shape.md
- Cap discovery at 1 round by default; second round only when first
  leaves material gaps.
- Adds an "assert-then-confirm, not menu-with-escape" rule: when
  PRODUCT.md and the prompt make one option obvious, name it and ask
  for confirm or override instead of enumerating "Restrained /
  Committed / Or something else?" as a real choice.
- Phase 2 brief has two forms now: compact (default for clear briefs)
  and full structured (genuinely ambiguous). Open Questions can't
  double as leading-with-Recommend; if you'd write "Recommend: X",
  decide X.
- Image gate same as craft.md.

Validated end-to-end with a Haiku skill-on observability run: agent
loads craft.md plus the brief's recommended implementation refs,
pauses for one productive question (accent color, trace fidelity,
CTA), and ships an artifact with zero side-tab violations vs. the
original v1 baseline. Cost trades up modestly for that quality.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* craft.md Step 6: Reading the screenshot is the inspection, not taking it

A v4 eval run took 4 targeted screenshots (hero, mobile, tablet,
query-section) and then never Read any of them back. The agent treated
browser_screenshot itself as "I inspected" and shipped without the
multimodal feedback loop ever closing. Detector caught the resulting
slop (5+ side-tab violations) on adjacent runs that did the same thing.

Step 6 now spells out the pattern explicitly: take the screenshot,
then Read the resulting PNG so its image content enters the
conversation as multimodal input, then critique what you actually see
in the image. With a check: "if your critique could have been written
without looking at the image, you didn't look at the image."

Validated with v5b: agent took 6 screenshots, Read all 6 back, and
shipped with zero detector findings (vs the previous greenfield runs
that hit 1-12 findings each).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* craft + brand: framework foundation, build-pipeline respect, image verification

Three closely-linked additions surfaced by an eval-harness session
investigating why the agent always shipped flat single-file HTML and
zero imagery on greenfield brand briefs.

1. craft.md gains a new Step 0 "Project Foundation" before Shape.
   Detects existing framework / component library / icon set and
   uses what's there. Greenfield: ask the user via AskUserQuestion
   with sensible defaults framed by the brief (Astro for content/
   brand sites, SvelteKit/Next/Nuxt for app surfaces, single
   index.html only for one-shot demos). Skipping the framework
   decision and writing flat HTML "to satisfy the spec" produces
   work that reads as a 2018 prototype regardless of visual
   quality.

2. craft.md Step 5 production bar gains two bullets:
   - Respect the build pipeline. Edit source files and run the
     project's `npm run build`; do not write to build/ / dist/ /
     .next/ directly with cat/heredoc/Bash redirects. Bypassing
     the pipeline skips asset hashing, image optimization, code
     splitting, and CSS extraction.
   - Verify external image URLs before referencing them. Use an
     image-search MCP, web-fetch tool, or browser if available;
     guessed photo IDs ship as broken-image placeholders.

3. brand.md "Imagery" section:
   - Generalizes the Unsplash URL guidance to "verify URLs
     before referencing them" with a hierarchy: image-search MCP
     > web-fetch > confidence-restricted manual selection >
     fewer photos.
   - Tightens the tech/dev-tool exception. Old line "zero imagery
     can be correct" gave models a permission slip. New framing
     keeps the underlying truth (typography + code + diagrams
     primarily carry voice) but raises the floor: imagery still
     earns its place when it serves the brief, and skipping it
     requires naming the typographic/diagrammatic move that's
     carrying the visual weight instead. "Zero imagery is the
     failure mode of laziness, not restraint."

Eval-harness corpus that prompted this: 19/19 brand landing tasks
shipped 0 images each, including ones where Opus had taste enough
to break the dev-tool color default lane. The skill needs to teach
both halves of the decision; the harness shouldn't have to nudge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* detector: body-text-viewport-edge rule + OKLCH/var-resolution + anchor-inherit FP fixes

New rule: body-text-viewport-edge flags body paragraphs that render flush
against the left/right viewport edges (no container padding). Tested via
the new tests/fixtures/antipatterns/body-text-viewport-edge.html fixture
(3 flag cases, 5 pass cases) and the test in detect-antipatterns-browser.

False-positive class fixes — all jsdom-mode only (real browsers resolve
the cascade correctly so these gates stay inert there). Five related
gaps that compounded into ~14× spurious contrast findings on Tailwind v4
pages with OKLCH color tokens:

  • OKLCH parser. jsdom returns the literal "oklch(...)" string from
    getComputedStyle; the detector now converts to sRGB via Björn
    Ottosson's matrices. Handles Tailwind v4's compact minified form
    "oklch(21.5%.02 50)" (no space after %).
  • var() resolution. resolveBackground + checkElementColors now
    accept the existing customPropMap and parse `var(--color-paper)`
    etc. as proper RGB via the new parseColorResolved helper.
  • bg-color before bg-image. The old order bailed on any gradient
    ancestor before checking for a solid background-color underneath,
    causing the body's decorative paper-grain gradient to be measured
    against instead of the page's actual `bg-paper` cream.
  • body/html-level gradient → white fallback. When the only opaque
    ancestor we can read is body/html with a gradient overlay (and
    jsdom can't decompose `background: var(--paper) gradient` to
    extract the solid color), return white instead of falling through
    to resolveGradientStops — which was picking up paper-grain noise
    colors and using them as the bg.
  • Anchor-inherit workaround for jsdom :link UA specificity.
    Tailwind v4's preflight declares `a { color: inherit }` (0,0,1).
    jsdom's UA stylesheet has `:link { color: blue }` at (0,1,1) and
    wins the cascade. Real Chrome wraps :link in :where() (0,0,0) so
    the page rule wins. When the page declares the inherit rule AND
    we see jsdom's default `rgb(0,0,238)` on an anchor, walk to the
    nearest non-anchor ancestor and use its color.
  • Alpha-fallback safety gate. When text has alpha<1 AND we couldn't
    find an opaque ancestor (effectiveBg null), skip the contrast
    finding. Covers any remaining FP class the deeper fixes miss.

Verified end-to-end against an Opus iter-1 artifact on Tailwind v4 with
14 cream/cream FPs + 2 blue-link UA FPs before; 0 findings after, while
the color.html fixture's 12 real low-contrast cases continue to flag
(verified via direct detectHtml calls).

cli/engine/detect-antipatterns-browser.js is the generated browser
distribution — regenerated from .mjs via scripts/build-browser-detector.js
(no manual edits to the generated file).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* craft.md: tighten verbose passages, de-codex Step 6, cut redundancies

Cumulative reduction: 218 → 155 lines (-29%).

Step 0: drop the "Why this matters" paragraph at the end. The body of
Step 0 already makes the framework-pick point; the paragraph just
re-explains it with extra rhetoric.

Step 1: replace the 4-sentence "you must end your response" block with a
single line. The original said the same thing three different ways.

Step 3: trim the conditional / defensive scaffolding (Purpose subsection,
"do not skip because the eventual UI is semantic..." paragraph,
duplicated approval-loop guidance). Mock fidelity inventory preserved.

Step 4: drop the "keep UI text semantic" sentence; it duplicates Step 5's
"Semantic first" rule. The rasterized-vs-semantic decision rule stays.

Step 5: tighten each production-bar bullet to bold-lead + specifics
format. All 15 rules preserved (real content, mock ingredients, semantic
first, spacing/alignment, typography, state coverage, interaction quality,
icon set, build pipeline, image URL verification, optimized imagery,
premium motion, maintainability, technical cleanliness, ask-when-uncertain).

Step 6: rewrite around "look at what you built like a designer would —
your eyes are whatever the harness gives you." Drops Codex-specific
"In Codex, use browser-use" bias. Drops the verbose 3-step Read pattern
(condensed to one sentence). Drops the 1-8 numbered checklist (replaced
by a tight paragraph). Keeps the load-bearing rules: read the PNG,
don't fabricate iteration, mock fidelity reference, exit bar = studio
defensibility.

Step 7: drop the closing "Iterate based on feedback. Good design is
rarely right on the first pass" preachy filler.

All em-dashes converted to semicolons / colons / periods to satisfy
the skill prose validator.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* build: native subagent pipeline + Codex-only asset producer

Adds an agent cross-compile pipeline alongside the existing skill
pipeline. Sources live at skill/agents/*.md; providers that declare
agentFormat (codex-toml, claude-md) emit native subagent files. An
optional providers: <list> field on an agent gates which harnesses
get a copy; default (no field) ships everywhere.

The impeccable-asset-producer agent is opt-in to Codex only. It's
useful for Codex's native image generation path and is untested
elsewhere; Claude has no native image gen anyway.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* brand: inverse-test + cultural-symbol palette guardrail

Two additions to the brand register reference:

- Inverse slop test: describe the page the way a competitor would
  describe theirs. If that sentence fits the modal landing page in
  the category, restart.
- Palette guardrail: when a cultural-symbol palette is the obvious
  pull, reach past it. Let cultural reading come from typography,
  imagery, and copy.

Harness mirrors regenerated; some also catch up to the image-
verification paragraph from e3ad2ef that hadn't been re-synced.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* PRODUCT.md: widen audience beyond developers

Designers, product managers, and engineers all use AI coding tools
and want better design output. Keeping the audience narrow to
"frontend and full-stack developers" understates who the skill is
actually for. Also retitles "developer" to "user/builder" in the
purpose statement.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* site + build: bump rule count to 29, strip changelog from detector check

Two changes:
- site/pages/index.astro: three live mentions of "28 rules / checks"
  bumped to 29 after the body-text-viewport-edge rule landed in
  b9bf496.
- scripts/build.js: the detection-count validator was reading the
  unstripped content, so historical counts inside changelog entries
  (e.g. "28 rules" from an older release note) were flagging against
  the current detector total. The command-count check already strips
  the changelog ul; the detection check now does the same.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test: align hero-eyebrow-chip fixture with relaxed rule gates

b9bf496 intentionally relaxed two gates in checkHeroEyebrow:
- removed the heading-size ≥ 48px anchor (modern hero h1s use
  clamp/vw/var that jsdom can't resolve)
- raised the eyebrow text ceiling from 30 to 60 chars

Two fixture cases that satisfied the negative side of the old gates
now match the rule:

- "Body-Sized Heading Below Eyebrow" — 24px h1 with tracked-caps
  label above. Per the rule's stated intent ("a tiny tan label
  directly above any h1 is the antipattern regardless of how big
  the h1 ends up"), this is a flag.
- "Long Uppercase Sentence Above Hero" — 46-char tracked-caps label
  is under the new 60-char ceiling, so still eyebrow-shaped.

Both cases moved from the should-pass column to should-flag, with
case descriptions rewritten to explain the gate they exercise.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Paul Bakaus <paulbakaus@pauls-mbp-3.lan>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Paul Bakaus
2026-05-12 23:11:18 -07:00
committed by GitHub
co-authored by Paul Bakaus Claude Opus 4.7
parent e587004ee4
commit e7e923c4ef
104 changed files with 3513 additions and 2242 deletions
+6 -19
View File
@@ -5,28 +5,15 @@ description: Use when the user wants to design, redesign, shape, critique, audit
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
## Setup (non-optional)
## Setup
Before any design work or file edits, pass these gates. Skipping them produces generic output that ignores the project.
Before any design work or file edits:
| Gate | Required check | If fail |
|---|---|---|
| Context | The PRODUCT.md / DESIGN.md loader result is known from `node .agents/skills/impeccable/scripts/load-context.mjs`. | Run the loader before continuing. |
| Product | PRODUCT.md exists and is not empty or placeholder (`[TODO]` markers, <200 chars). | Run `$impeccable teach`, refresh context, then resume. Never synthesize PRODUCT.md from the user's original prompt alone. |
| Command | The matching command reference is loaded when a sub-command is used. | Load the reference before continuing. |
| Craft | `$impeccable craft` has a user-confirmed shape brief for this task. `teach` / PRODUCT.md never counts as shape. | Run `$impeccable shape` and wait for explicit brief confirmation. |
| Image | Required visual probes / mocks are generated or skipped with a reason. | Resolve the image-generation gate in `shape.md` or `craft.md` before code. |
| Mutation | All active gates above pass. | Do not edit project files yet. |
1. Load context (PRODUCT.md / DESIGN.md) via the loader script.
2. Identify the register and load the matching register reference (brand.md or product.md).
3. **If the user invoked a sub-command (e.g. `craft`, `shape`, `audit`), load its reference file too.** This is non-negotiable: `craft` without `craft.md` loaded means you'll skip the shape-and-confirm step the user expects.
Codex-style agents must state this before editing files:
```text
IMPECCABLE_PREFLIGHT: context=pass product=pass command_reference=pass shape=pass|not_required image_gate=pass|skipped:<reason> mutation=open
```
For `$impeccable craft`, `shape=pass` is only valid after a separate user response approving the shape design brief, or when the user provided an already-confirmed brief in the request. Do not mark `shape=pass` after writing PRODUCT.md, summarizing assumptions, or drafting an unconfirmed brief yourself.
Other harnesses should follow the same checklist when they can expose this state.
Skipping these produces generic output that ignores the project.
### 1. Context gathering
+7 -3
View File
@@ -12,6 +12,8 @@ Brand isn't a neutral register. AI-generated landing pages have flooded the inte
**The second slop test: aesthetic lane.** Before committing to moves, name the reference. A Klim-style specimen page is one lane; Stripe-minimal is another; Liquid-Death-acid-maximalism is another. Don't drift into editorial-magazine aesthetics on a brief that isn't editorial. A hiking brand with Cormorant italic drop caps has the wrong register within the register.
Then the inverse test: in one sentence, describe what you're about to build the way a competitor would describe theirs. If that sentence fits the modal landing page in the category, restart.
## Typography
### Font selection procedure
@@ -66,6 +68,7 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
- Palette IS voice. A calm brand and a restless brand should not share palette mechanics.
- When the strategy is Committed or Drenched, color carries the brand. Don't hedge with neutrals around the edges. Commit.
- Don't converge across projects. If the last brand surface was restrained-on-cream, this one is not.
- When a cultural-symbol palette is the obvious pull, reach past it. Let the cultural reading come from typography, imagery, and copy, not the palette.
## Layout
@@ -79,14 +82,14 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
Brand surfaces lean on imagery. A restaurant, hotel, magazine, or product landing page without any imagery reads as incomplete, not as restrained. A solid-color rectangle where a hero image should go is worse than a representative stock photo.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse. If the approved comp or brief is image-led, ship real project assets, generated raster assets, or a credible canvas/SVG/WebGL scene. Do not replace photographic, architectural, product, or place imagery with generic CSS panels, decorative diagrams, cards, bullets, or copy.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. Pick real Unsplash photo IDs you're confident exist (`photo-1559339352-11d035aa65de`, `photo-1590490360182-c33d57733427`, etc.); if unsure, pick fewer photos but don't substitute colored `<div>` placeholders.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. **Verify the URLs before referencing them.** If you have an image-search MCP, web-fetch tool, or browser access, use it to find real photo IDs and confirm they resolve. Guessed IDs (even ones that look real) often 404 and ship as broken-image placeholders. Without a verification path, pick fewer photos you're confident exist over more that you guessed; never substitute colored `<div>` placeholders.
- **Search for the brand's physical object**, not the generic category: "handmade pasta on a scratched wooden table" beats "Italian food"; "cypress trees above a limestone hotel facade at dusk" beats "luxury hotel".
- **One decisive photo beats five mediocre ones.** Hero imagery should commit to a mood; padding with more stock doesn't rescue an indecisive one.
- **Alt text is part of the voice.** "Coastal fettuccine, hand-cut, served on the terrace" beats "pasta dish".
Tech / dev-tool brands are the exception where zero imagery can be correct; a developer landing page often carries its voice through typography, code samples, diagrams. Know which kind of brand you're working on.
"Imagery" here is broader than stock photography: product screenshots, custom data visualizations, generated SVG, and canvas/WebGL scenes are all imagery. Text-only pages where typography alone carries the entire visual weight are the failure mode.
## Motion
@@ -102,6 +105,7 @@ Tech / dev-tool brands are the exception where zero imagery can be correct; a de
- Timid palettes and average layouts. Safe = invisible.
- Zero imagery on a brief that implies imagery (restaurant, hotel, food, travel, fashion, photography, hobbyist). Colored blocks where a hero photo belongs.
- Defaulting to editorial-magazine aesthetics (display serif + italic + drop caps + broadsheet grid) on briefs that aren't magazine-shaped. Editorial is ONE aesthetic lane, not the default brand aesthetic.
- Repeated tiny uppercase tracked labels above every section heading. A single strong kicker can be voice; repeating it as section grammar is AI scaffolding unless it's a deliberate, named brand system.
## Brand permissions
+73 -111
View File
@@ -1,43 +1,41 @@
# Craft Flow
Build a feature with impeccable UX and UI quality through a structured process: shape the design, land the visual direction, build real production code, then inspect and improve in-browser until the result meets a high-end studio bar.
Build a feature with impeccable UX and UI quality: shape the design, land the visual direction, build real production code, inspect and improve in-browser until it meets a high-end studio bar.
## Build Gate
Before writing code, you need: PRODUCT.md loaded, register identified and the matching reference loaded, and a confirmed design direction for this task (either from `shape` or supplied by the user). PRODUCT.md is project context, not a task-specific brief.
Craft cannot build until all of these are true:
Treat any approved visual direction (generated mock or stated reference) as a concrete contract for composition, hierarchy, density, atmosphere, signature motifs, and distinctive visual moves. Don't let mocks replace structure, copy, accessibility, or state design. But if the live result lacks the approved direction's major ingredients, the implementation is wrong.
1. PRODUCT context is valid and current.
2. The shape design brief is explicitly confirmed by the user for this task, unless the user already provided a confirmed brief.
3. Implementation references from the brief are loaded.
4. The shape visual probe decision is recorded: generated, skipped with reason, or already resolved.
5. The north-star mock decision is recorded: generated, skipped with reason, or not applicable.
## Step 0: Project Foundation
PRODUCT.md and `teach` answers do **not** satisfy the shape gate. They are project context only. A compact self-authored brief does not satisfy the shape gate either. `shape=pass` requires a separate user response approving the shape brief or an already-confirmed brief supplied by the user.
Before shape, before code: figure out what kind of project you're working in.
Invalid image-skip reasons include: "the final implementation will be semantic HTML/CSS/SVG", "the diagram should stay editable", "a raster mock would not be used directly", or "the product is fictional." Generated probes and mocks are direction artifacts; they are not implementation assets.
Look at the working directory. Run `ls`. Check for:
## Craft Contract
- An existing framework: `astro.config.mjs/ts`, `next.config.js/ts`, `nuxt.config.ts`, `svelte.config.js`, `vite.config.js/ts`, `package.json` with framework deps, `Cargo.toml` + Leptos/Yew, `Gemfile` + Rails. **If found, use it.** Do not start a parallel build, do not introduce a second framework, do not write to `dist/` or `build/` directly. Whatever pipeline the project has, respect it.
- An existing component library or design system: `src/components/`, `app/components/`, a `tokens.css` / `theme.ts`, an `astro.config` `integrations`. Read what's there before adding to it.
- An existing icon set: `lucide-react`, `@phosphor-icons/react`, `@iconify/*`, hand-rolled SVG sprites in `assets/icons/`. **Use what's already in the project**; don't introduce a second set.
Craft is not a first pass. It is a loop with these required artifacts:
If the directory is empty (greenfield), don't pick a framework silently. Ask the user via the AskUserQuestion tool, with sensible defaults framed by the brief:
1. Confirmed design brief from `shape`.
2. Approved visual direction, from generated probes / mocks when image generation is available.
3. Mock fidelity inventory: the visible ingredients from the approved direction that must survive into code.
4. Semantic, functional implementation using the project's real stack and conventions.
5. Browser evidence across relevant viewports.
6. At least one critique-and-fix pass after the first browser inspection, unless the first pass has no material defects.
```text
What should this be built on?
- Astro (default for content-led brand sites, landing pages, marketing surfaces)
- SvelteKit / Next.js / Nuxt (when the brief implies an app surface or significant interactivity)
- Single index.html (one-shot demo, prototype, or a deliberately framework-free experiment)
```
Do not let generated mockups replace interface structure, copy, accessibility, responsive behavior, or state design. But do treat the approved mock as a concrete visual contract for composition, hierarchy, density, atmosphere, signature motifs, image needs, and distinctive visual moves. "North star" means "preserve the important visible ingredients in semantic code," not "use it as loose mood."
Default: Astro for brand briefs, the project's existing framework for product briefs. Ask once; don't re-ask mid-task.
## Step 1: Shape the Design
Run $impeccable shape, passing along whatever feature description the user provided.
Run $impeccable shape, passing along whatever feature description the user provided. Shape is **required** for craft; it is what produces a confirmed direction.
Wait for the design brief to be fully confirmed by the user before proceeding. The brief is your blueprint, and every implementation decision should trace back to it.
Present the shape output and stop. Wait for the user to confirm, override, or course-correct before writing code.
If this craft run resumed after `teach` created PRODUCT.md, run shape now. Do not treat the teach interview, PRODUCT.md, or a summary of project context as a substitute for shape. Shape is task-specific and must cover scope, content/states, visual direction, constraints, anti-goals, probes when applicable, and explicit brief confirmation.
If the user already supplied a confirmed brief or ran shape separately, use it and skip this step.
If the user has already run $impeccable shape and has a confirmed design brief, skip this step and use the existing brief.
When the original prompt + PRODUCT.md already answer scope, content, and visual direction with no real ambiguity, the shape output can be **compact** (3-5 bullets stating what you're building and the visual lane, ending with one or two specific questions or "confirm or override"). The full 10-section structured brief is reserved for genuinely ambiguous, multi-screen, or stakeholder-heavy tasks. Don't pad a clear brief into a long one to look thorough; equally, don't skip the pause to look efficient.
## Step 2: Load References
@@ -55,79 +53,60 @@ Then add references based on the brief's needs:
## Step 3: Land the Visual Direction (Capability-Gated)
Before implementation, generate high-fidelity visual comps when all of these are true:
Generate high-fidelity visual comps before implementation when all three are true:
- The work is **net-new** or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is **mid-fi, high-fi, or production-ready**.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The work is net-new or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is mid-fi, high-fi, or production-ready.
- The harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool). Don't ask the user to set up external APIs.
When those conditions are met, this step is mandatory for **both brand and product work** in Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
Do not skip this step because the eventual UI should be semantic, editable, code-native, responsive, or accessible. Those are implementation requirements, not reasons to avoid visual exploration.
### Purpose
Use the mock step to find a stronger visual lane than code-first generation would reliably discover on its own. The brief remains authoritative on user, purpose, content, constraints, states, and anti-goals. The mock clarifies composition, hierarchy, density, typography, and visual tone.
When met, this step is mandatory for both brand and product work. If image generation isn't available, skip silently. "The eventual UI is semantic/code-native/accessible" is not a reason to skip; those are implementation requirements, not exploration ones.
### What to generate
Generate **1 to 3** high-fidelity north-star comps based on the confirmed brief. If shape already produced direction probes, use those results as input and generate a more resolved mock from the winning lane, not another unrelated exploration.
Generate **1 to 3** high-fidelity north-star comps from the confirmed brief. If shape already produced direction probes, resolve the winning lane further, not an unrelated exploration. Comps must differ in primary visual direction, not just color.
- For brand work, push visual identity, composition, and mood aggressively.
- For product work, still push hierarchy, topology, density, and tone, but keep the comps grounded in realistic product structure and states.
- For landing pages and long-form brand surfaces, show enough of the next section or second fold to establish the system beyond the hero.
The comps must be genuinely different in primary visual direction, not just color variants.
- Brand work: push visual identity, composition, and mood aggressively.
- Product work: push hierarchy, topology, density, tone, grounded in realistic product structure.
- Landing pages and long-form brand surfaces: show enough of the second fold to establish the system beyond the hero.
### Approval loop
Show the comps and ask what should carry forward. If the user asks for changes or the best direction is still weak, generate a focused revision before implementation. Continue until one direction is approved, or until the user explicitly delegates the choice.
Show the comps and ask what carries forward. Iterate until one direction is approved or the user delegates. If the user delegates, pick the strongest direction and explain it from the brief, not personal taste.
If the user delegates, pick the strongest direction and explain the decision using the brief, not personal taste.
Before moving to implementation, summarize:
- What to carry into code
- What **not** to literalize from the mock
This summary is required before Step 4. It is the handoff between visual exploration and semantic implementation.
Before Step 4, summarize what to carry into code and what **not** to literalize from the mock. This is the handoff between visual exploration and semantic implementation.
### Mock fidelity inventory
Before building, inventory the approved mock's major visible ingredients:
Inventory the approved mock's major visible ingredients:
- Hero silhouette and dominant composition.
- Signature motifs: planets, devices, portraits, charts, route lines, insets, badges, or other memorable objects.
- Nav and primary CTA treatment.
- Section sequence visible in the mock, especially the second fold.
- Image-native content the concept depends on.
- Typography, density, color/material treatment, and motion cues.
- Hero silhouette and dominant composition
- Signature motifs (planets, devices, portraits, charts, route lines, insets, badges, etc.)
- Nav and primary CTA treatment
- Section sequence, especially the second fold
- Image-native content the concept depends on
- Typography, density, color/material treatment, motion cues
For each ingredient, decide how it will be implemented: semantic HTML/CSS/SVG, generated asset, sourced project asset, icon library, canvas/WebGL, or an explicitly accepted omission. Do not substitute a different hero composition or new visual driver after approval unless the user approves the change.
For each, decide implementation: semantic HTML/CSS/SVG, generated asset, sourced asset, icon library, canvas/WebGL, or accepted omission. Don't substitute a different hero composition or visual driver post-approval without user sign-off.
Treat the mock as a **north star**, not a screenshot to trace. Do **not** rasterize core UI text or let the mock override the confirmed brief. But if the live result lacks the mock's major visible ingredients, the implementation is wrong.
If a photographic, architectural, product, or place-led mock becomes generic CSS scenery / decorative diagrams / bullets / copy, stop and fix it. That's a broken implementation, not a harmless interpretation.
Treat the mock as a north star, not a screenshot to trace. Don't rasterize core UI text. But if the live result lacks the mock's major ingredients, the implementation is wrong.
## Step 4: Asset Extraction (Need-Gated)
If the chosen direction includes image-native visual ingredients that would materially improve the implementation, generate them as separate assets before building.
If the approved direction needs raster assets, create them before building. Do not replace required imagery with generic cards, bullets, emoji, fake metrics, decorative CSS panels, or filler copy.
Good candidates:
Use the native asset producer (`impeccable_asset_producer` in Codex, `impeccable-asset-producer` in Claude Code) to create clean assets from the hi-fi mock and crops. If you do not have explicit permission to use agents, stop and ask:
- stickers
- badges
- seals
- tickets
- graphic labels
- textures
- abstract objects
- decorative marks
- non-semantic scene elements
```text
Asset production will work better as a scoped subagent job. Should I spawn the Impeccable asset producer subagent for this step?
```
For travel, editorial, portfolio, venue, product showcase, entertainment, education, or any other image-led brand surface, visual assets are usually core content, not decoration. Do not ship abstract CSS panels where the approved mock or subject matter calls for real imagery, generated plates, illustrations, maps, product/object renders, or destination scenes.
Do not skip asset production or silently do it inline. Inline asset production is allowed only if the user declines subagents, the harness cannot spawn the authorized agent, or the user explicitly asks for single-thread mode.
Do **not** export assets for core UI text, navigation, body copy, or any structure that should stay semantic and editable in code.
Pass the approved mock, crop/contact-sheet paths, output directory, dimensions/formats, transparency needs, constraints, and avoid list to the asset producer. Attach image generation capability to the spawned agent when the harness supports it; do not load image-generation reference material into the parent thread first.
Usually **1 to 5** extracted assets is enough. If the design can be built cleanly in HTML/CSS/SVG, prefer that over raster assets. If the mock contains major visual content that cannot be built credibly in code, asset extraction is not optional.
Prefer HTML/CSS/SVG/canvas when they can credibly reproduce an ingredient; use real/generated/stock imagery when the mock or subject matter calls for actual visual content.
## Step 5: Build to Production Quality
@@ -135,50 +114,35 @@ Implement the feature following the design brief. Build in passes so structure,
### Production bar
- Use real or realistic content. Remove placeholder copy, placeholder images, dead links, fake controls, and unused scaffold before presenting.
- Preserve the approved mock's major ingredients. Missing hero objects, missing world/product imagery, different section structure, downgraded CTA/nav treatment, or generic replacements for distinctive motifs are blocking defects unless the user accepted the change.
- Build semantically first: real headings, landmarks, labels, form associations, button/link semantics, accessible names, and state announcements where needed.
- Calibrate spacing, alignment, grid placement, and vertical rhythm deliberately. Do not accept default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- Make typography intentional: chosen font loading strategy, clear hierarchy, readable measure, stable line breaks, tuned wrapping, and no overflow at mobile or large desktop sizes.
- Design realistic state coverage: default, hover where supported, focus-visible, active, disabled, loading, error, success, empty, overflow, long text, short text, and first-run states where relevant.
- Make interaction quality feel finished: keyboard paths, touch targets, feedback timing, scroll behavior, transitions between states, and no hover-only functionality.
- Use icons from the project's established icon set when available. If no set exists, choose a coherent library or use accessible text controls; do not mix unrelated icon styles.
- Optimize imagery and media: correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset` / `picture` for raster assets, and no project-referenced asset left outside the workspace.
- Make motion feel premium: use atmospheric blur, filter, mask, shadow, or reveal effects when they improve the experience; avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- Preserve maintainability: reusable local patterns, clear component boundaries, project conventions, no rasterized UI text, and no hard-coded one-off hacks when a better local pattern exists.
- Fit the technical context: production build passes, no obvious console errors, no avoidable layout shift, no needless dependency, and no broken asset path.
- If you discover a design question that materially changes the brief or approved direction, stop and ask rather than guessing.
- **Real content.** No placeholder copy, placeholder images, dead links, fake controls, or unused scaffold at presentation time.
- **Preserve the approved mock's major ingredients.** Missing hero objects, world/product imagery, section structure, CTA/nav treatment, or distinctive motifs are blocking defects unless the user accepted the change.
- **Semantic first.** Real headings, landmarks, labels, form associations, button/link semantics, accessible names, state announcements where needed.
- **Deliberate spacing and alignment.** No default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- **Intentional typography.** Chosen loading strategy, clear hierarchy, readable measure, stable line breaks, no overflow at any width.
- **Realistic state coverage.** Default, hover, focus-visible, active, disabled, loading, error, success, empty, overflow, long/short text, first-run.
- **Finished interaction quality.** Keyboard paths, touch targets, feedback timing, scroll behavior, state transitions, no hover-only functionality.
- **Coherent icon set.** Use the project's established set; otherwise pick one library or use accessible text. Don't mix.
- **Respect the build pipeline.** Edit source files and run the project's build (`npm run build` or equivalent). Don't write to `build/` / `dist/` / `.next/` with `cat`, heredoc, or Bash redirects; that skips asset hashing, image optimization, code splitting, and CSS extraction, and produces output the dev server won't serve.
- **Verify image URLs before referencing them.** Use image-search MCP or web-fetch when available; guessed photo IDs ship as broken-image placeholders. Without verification, prefer fewer images you're confident about.
- **Optimized imagery and media.** Correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset`/`picture` for raster, no project-referenced asset left outside the workspace.
- **Premium motion.** Use atmospheric blur, filter, mask, shadow, reveal when they improve the experience. Avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- **Maintainable.** Reusable local patterns, clear component boundaries, project conventions. No rasterized UI text or one-off hacks when a local pattern exists.
- **Technically clean.** Production build passes, no console errors, no avoidable layout shift, no needless dependencies, no broken asset paths.
- **Ask when uncertain.** If a discovery materially changes the brief or approved direction, stop and ask. Don't guess.
## Step 6: Browser-Based Iteration
## Step 6: Iterate Visually
**This step is critical.** Do not stop after the first implementation pass.
Look at what you built like a designer would. Your eyes are whatever the harness gives you: a connected browser, a screenshotting tool, Playwright, or asking the user. Use them for responsive testing (mobile, tablet, desktop minimum) and general visual validation.
Open the result in a browser. In Codex, use browser-use or equivalent browser automation when available; otherwise use Playwright or ask the user for screenshots. Inspect screenshots, not just DOM or terminal output.
If your tool returns a file path, read the PNG back into the conversation. A screenshot you didn't read doesn't count.
### Required viewport pass
For long-form brand surfaces, inspect major sections individually. Thumbnails hide spacing, clipping, and cascade defects.
Check the experience at the viewports that matter for the brief. Default minimum:
After the first pass, write an honest critique against the brief, the approved mock's major ingredients (hero silhouette, motifs, imagery, nav/CTA, density), and impeccable's DON'Ts. Patch material defects and re-inspect. **Don't invent defects to demonstrate iteration.** A confident "first pass clean, shipping" beats a fake fix.
- Mobile narrow
- Tablet or small laptop
- Desktop wide
Actively check: responsive behavior (composes, not shrinks), every state (empty / error / loading / edge), craft details (spacing, alignment, hierarchy, contrast, motion timing, focus), performance basics. The exit bar: defensible in a high-end studio review.
For each viewport, capture or inspect the rendered state and look for visual defects: overlap, clipping, weak hierarchy, off-grid alignment, awkward whitespace, cramped controls, unreadable type, broken imagery, hover-only functionality, layout shift, and text overflow.
### Critique and fix loop
After the first browser pass, write a short critique for yourself and patch the implementation. Repeat browser inspection after fixes. Continue until no material issues remain against this checklist:
1. **Does it match the brief?** Compare the live result against every section of the design brief. Fix discrepancies.
2. **Does it match the approved mock?** Compare screenshots against the mock fidelity inventory: hero silhouette, major motifs, imagery, nav/CTA, section sequence, density, color/materials, and second-fold substance. Missing major ingredients are P0 defects.
3. **Does it pass the AI slop test?** If someone saw this and said "AI made this," would they believe it immediately? If yes, it needs more design intention.
4. **Check against impeccable's DON'T guidelines.** Fix any anti-pattern violations.
5. **Check every state.** Navigate through empty, error, loading, and edge case states. Each one should feel intentional, not like an afterthought.
6. **Check responsive behavior.** The design should adapt compositionally, not merely shrink.
7. **Check craft details.** Spacing consistency, optical alignment, type hierarchy, color contrast, image quality, icon coherence, interactive feedback, motion timing, and focus treatment.
8. **Check performance basics.** No obviously oversized images, avoidable layout thrash, blocking animations, or heavy assets without a reason.
The exit bar is not "it works." It is: the rendered result looks intentional at all checked viewports, all expected states are handled, no placeholders remain unless explicitly accepted, and the implementation quality would be defensible in a high-end studio review.
Detector or QA output is defect evidence only; never proof the work is finished.
## Step 7: Present
@@ -189,5 +153,3 @@ Present the result to the user:
- Explain design decisions that connect back to the design brief and, when used, the chosen north-star mock. Include any accepted deviations from the mock; do not hide unimplemented mock ingredients.
- Note any remaining limitations or follow-up risks honestly
- Ask: "What's working? What isn't?"
Iterate based on feedback. Good design is rarely right on the first pass.
@@ -43,7 +43,7 @@ Run the bundled deterministic detector, which flags 27 specific patterns (AI slo
**CLI scan**:
```bash
npx impeccable --json [--fast] [target]
npx impeccable detect --json [--fast] [target]
```
- Pass HTML/JSX/TSX/Vue/Svelte files or directories as `[target]` (anything with markup). Do not pass CSS-only files.
@@ -2,6 +2,8 @@
Perform a meticulous final pass to catch all the small details that separate good work from great work. The difference between shipped and polished.
Detector and automated QA output are defect evidence only. A clean script result is never proof that the design is strong; gather browser evidence and inspect the real interaction path.
## Design System Discovery
Aligning the feature to the design system is **not optional**. Polish without alignment is decoration on top of drift, and it makes the next person's job harder. Discovery comes before any other polish work.
@@ -216,11 +218,12 @@ Sweat the details. Zoom in until the alignment is right and the spacing reads as
Before marking as done:
- **Use it yourself**: Actually interact with the feature
- **Test on real devices**: Not just browser DevTools
- **Ask someone else to review**: Fresh eyes catch things
- **Compare to design**: Match intended design
- **Check all states**: Don't just test happy path
- **Use it yourself**: Actually interact with the feature.
- **Test on real devices**: Not just browser DevTools.
- **Ask someone else to review**: Fresh eyes catch things.
- **Compare to design**: Match intended design.
- **Check all states**: Don't just test happy path.
- **Treat automation carefully**: Run detector or QA commands when they are available and relevant, fix their defects, but never cite a clean result as proof that the work is polished.
## Clean Up
@@ -230,4 +233,3 @@ After polishing, ensure code quality:
- **Remove orphaned code**: Delete unused styles, components, or files made obsolete by polish.
- **Consolidate tokens**: If you introduced new values, check whether they should be tokens.
- **Verify DRYness**: Look for duplication introduced during polishing and consolidate.
+25 -11
View File
@@ -16,14 +16,16 @@ This is a required interaction, not optional guidance. Ask these questions in co
### Interview cadence
Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed design inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
Discovery includes at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
- Use the harness's structured question tool when one exists. Otherwise, ask directly in chat and stop.
- Ask **2-3 questions per round**, then wait for answers.
- Treat PRODUCT.md and DESIGN.md as anchors; they reduce repeated questions but do **not** replace shape for craft. Shape is task-specific.
- Round 1 should clarify purpose, audience/context, and success or emotional outcome.
- Round 2 should clarify content/data/states and scope/fidelity.
- Round 3 should clarify visual direction, constraints, and anti-goals when still unresolved.
- One round is the default. Add a second only if the first answers leave material gaps. Don't run a second round just to feel thorough.
- Round 1 should clarify purpose, audience/context, content/scope, and (for brand) visual direction.
- Round 2, when needed, fills in whatever's still genuinely missing.
**Assert-then-confirm, not menu-with-escape.** When PRODUCT.md and the user's prompt make one option obvious, name it and ask the user to confirm or override. Don't enumerate "Restrained / Committed / Or something else?" as a real choice; "This reads as Restrained, confirm?" beats a four-option menu when the answer is already clear.
### Purpose & Context
- What is this feature for? What problem does it solve?
@@ -36,6 +38,7 @@ Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.
- What are the realistic ranges? (Minimum, typical, maximum, e.g., 0 items, 5 items, 500 items)
- What are the edge cases? (Empty state, error state, first-time use, power user)
- Is any content dynamic? What changes and how often?
- What visual assets are real content here? Note required images, product shots, illustrations, maps, textures, diagrams, generated objects, or existing project assets.
### Design Direction
@@ -72,9 +75,9 @@ After the discovery interview, generate a small set of visual direction probes *
- The work is **net-new** or directionally ambiguous enough that visual exploration will clarify the brief.
- The requested fidelity is **mid-fi, high-fi, or production-ready**. Skip for sketch-only planning.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The current harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool, or similar). Don't ask the user to install APIs or tooling.
When those conditions are met, this step is mandatory for Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
When those conditions are met, this step is mandatory. If image generation isn't natively available, skip silently and proceed; don't announce the skip.
Use probes to explore visual lanes, not to replace the brief.
@@ -104,11 +107,20 @@ The probes should differ in primary visual direction (hierarchy, topology, densi
- Do **not** treat generated imagery as final UX specification, final copy, or final accessibility behavior.
- Do **not** use this step for minor refinements of existing work. It's for shaping a new surface or clarifying a big directional choice.
If image generation is unavailable, or the task doesn't benefit from it, skip this phase only with a one-line reason and proceed directly to the design brief.
If image generation isn't natively available, skip this phase silently and proceed.
## Phase 2: Design Brief
After the interview and any required probes, synthesize everything into a structured design brief. Present it to the user for explicit confirmation before considering this command complete. Stop after asking for confirmation; do not proceed to craft or implementation in the same response unless the user has already approved the brief.
After the interview and any required probes, present a brief and **end your response**. The user must confirm before any implementation runs. Do not present a brief and then continue to code in the same response, even if the brief feels obvious to you. The user's confirmation is the gate.
**Choose the brief shape based on how clear the answers are:**
- **Compact form (3-5 bullets)** when discovery was crisp and the original prompt + PRODUCT.md already pinned scope, content, and direction. State what you're building, the visual lane, and end with one or two specific questions or a clear "confirm or override?" prompt. This is the default for typical craft requests with a clear prompt.
- **Full structured form (sections below)** when the task is genuinely ambiguous, multi-screen, or when the user asked for shape as a standalone step. Use this when the discipline of structure earns its weight.
Don't pad a clear brief into a long one to look thorough. A 70-line brief restating answers the user just gave is noise, not rigor. Equally, don't skip the confirmation pause to look efficient: the pause is the point.
If the user already said "approved" or "go" during discovery for the *exact direction you'd present*, that counts as confirmation; you may proceed without asking again. But if your brief adds anything the user hasn't seen and approved, you must stop and confirm.
### Brief Structure
@@ -136,16 +148,18 @@ List every state the feature needs: default, empty, loading, error, success, edg
How users interact with this feature. What happens on click, hover, scroll? What feedback do they get? What's the flow from entry to completion?
**8. Content Requirements**
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges.
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges. For image-led surfaces, also list the required image/media roles and their likely source (project asset, generated raster, semantic SVG/CSS, canvas/WebGL, icon library, or accepted omission).
**9. Recommended References**
Based on the brief, list which impeccable reference files would be most valuable during implementation (e.g., spatial-design.md for complex layouts, motion-design.md for animated features, interaction-design.md for form-heavy features).
**10. Open Questions**
Anything unresolved that the implementer should resolve during build.
Anything genuinely unresolved. Don't list "open questions" you've already recommended a default for; assert the default and move on. If you'd write `Recommend: X` next to a question, just decide X.
---
STOP and use Codex's structured user-input/question tool when available; if unavailable, ask directly in chat to clarify what you cannot infer. Ask for explicit confirmation of the brief before finishing. If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the brief is confirmed.
STOP and use Codex's structured user-input/question tool when available; if unavailable, ask directly in chat to clarify what you cannot infer.
If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the user confirms direction (or the user already gave a clear go during discovery, which counts).
Once confirmed, the brief is complete. The user can now hand it to $impeccable, or use it to guide any other implementation approach. (If the user wants the full discovery-then-build flow in one step, they should use $impeccable craft instead, which runs this command internally.)
+6 -19
View File
@@ -11,28 +11,15 @@ allowed-tools:
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
## Setup (non-optional)
## Setup
Before any design work or file edits, pass these gates. Skipping them produces generic output that ignores the project.
Before any design work or file edits:
| Gate | Required check | If fail |
|---|---|---|
| Context | The PRODUCT.md / DESIGN.md loader result is known from `node .claude/skills/impeccable/scripts/load-context.mjs`. | Run the loader before continuing. |
| Product | PRODUCT.md exists and is not empty or placeholder (`[TODO]` markers, <200 chars). | Run `/impeccable teach`, refresh context, then resume. Never synthesize PRODUCT.md from the user's original prompt alone. |
| Command | The matching command reference is loaded when a sub-command is used. | Load the reference before continuing. |
| Craft | `/impeccable craft` has a user-confirmed shape brief for this task. `teach` / PRODUCT.md never counts as shape. | Run `/impeccable shape` and wait for explicit brief confirmation. |
| Image | Required visual probes / mocks are generated or skipped with a reason. | Resolve the image-generation gate in `shape.md` or `craft.md` before code. |
| Mutation | All active gates above pass. | Do not edit project files yet. |
1. Load context (PRODUCT.md / DESIGN.md) via the loader script.
2. Identify the register and load the matching register reference (brand.md or product.md).
3. **If the user invoked a sub-command (e.g. `craft`, `shape`, `audit`), load its reference file too.** This is non-negotiable: `craft` without `craft.md` loaded means you'll skip the shape-and-confirm step the user expects.
Codex-style agents must state this before editing files:
```text
IMPECCABLE_PREFLIGHT: context=pass product=pass command_reference=pass shape=pass|not_required image_gate=pass|skipped:<reason> mutation=open
```
For `/impeccable craft`, `shape=pass` is only valid after a separate user response approving the shape design brief, or when the user provided an already-confirmed brief in the request. Do not mark `shape=pass` after writing PRODUCT.md, summarizing assumptions, or drafting an unconfirmed brief yourself.
Other harnesses should follow the same checklist when they can expose this state.
Skipping these produces generic output that ignores the project.
### 1. Context gathering
+7 -3
View File
@@ -12,6 +12,8 @@ Brand isn't a neutral register. AI-generated landing pages have flooded the inte
**The second slop test: aesthetic lane.** Before committing to moves, name the reference. A Klim-style specimen page is one lane; Stripe-minimal is another; Liquid-Death-acid-maximalism is another. Don't drift into editorial-magazine aesthetics on a brief that isn't editorial. A hiking brand with Cormorant italic drop caps has the wrong register within the register.
Then the inverse test: in one sentence, describe what you're about to build the way a competitor would describe theirs. If that sentence fits the modal landing page in the category, restart.
## Typography
### Font selection procedure
@@ -66,6 +68,7 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
- Palette IS voice. A calm brand and a restless brand should not share palette mechanics.
- When the strategy is Committed or Drenched, color carries the brand. Don't hedge with neutrals around the edges. Commit.
- Don't converge across projects. If the last brand surface was restrained-on-cream, this one is not.
- When a cultural-symbol palette is the obvious pull, reach past it. Let the cultural reading come from typography, imagery, and copy, not the palette.
## Layout
@@ -79,14 +82,14 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
Brand surfaces lean on imagery. A restaurant, hotel, magazine, or product landing page without any imagery reads as incomplete, not as restrained. A solid-color rectangle where a hero image should go is worse than a representative stock photo.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse. If the approved comp or brief is image-led, ship real project assets, generated raster assets, or a credible canvas/SVG/WebGL scene. Do not replace photographic, architectural, product, or place imagery with generic CSS panels, decorative diagrams, cards, bullets, or copy.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. Pick real Unsplash photo IDs you're confident exist (`photo-1559339352-11d035aa65de`, `photo-1590490360182-c33d57733427`, etc.); if unsure, pick fewer photos but don't substitute colored `<div>` placeholders.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. **Verify the URLs before referencing them.** If you have an image-search MCP, web-fetch tool, or browser access, use it to find real photo IDs and confirm they resolve. Guessed IDs (even ones that look real) often 404 and ship as broken-image placeholders. Without a verification path, pick fewer photos you're confident exist over more that you guessed; never substitute colored `<div>` placeholders.
- **Search for the brand's physical object**, not the generic category: "handmade pasta on a scratched wooden table" beats "Italian food"; "cypress trees above a limestone hotel facade at dusk" beats "luxury hotel".
- **One decisive photo beats five mediocre ones.** Hero imagery should commit to a mood; padding with more stock doesn't rescue an indecisive one.
- **Alt text is part of the voice.** "Coastal fettuccine, hand-cut, served on the terrace" beats "pasta dish".
Tech / dev-tool brands are the exception where zero imagery can be correct; a developer landing page often carries its voice through typography, code samples, diagrams. Know which kind of brand you're working on.
"Imagery" here is broader than stock photography: product screenshots, custom data visualizations, generated SVG, and canvas/WebGL scenes are all imagery. Text-only pages where typography alone carries the entire visual weight are the failure mode.
## Motion
@@ -102,6 +105,7 @@ Tech / dev-tool brands are the exception where zero imagery can be correct; a de
- Timid palettes and average layouts. Safe = invisible.
- Zero imagery on a brief that implies imagery (restaurant, hotel, food, travel, fashion, photography, hobbyist). Colored blocks where a hero photo belongs.
- Defaulting to editorial-magazine aesthetics (display serif + italic + drop caps + broadsheet grid) on briefs that aren't magazine-shaped. Editorial is ONE aesthetic lane, not the default brand aesthetic.
- Repeated tiny uppercase tracked labels above every section heading. A single strong kicker can be voice; repeating it as section grammar is AI scaffolding unless it's a deliberate, named brand system.
## Brand permissions
+73 -111
View File
@@ -1,43 +1,41 @@
# Craft Flow
Build a feature with impeccable UX and UI quality through a structured process: shape the design, land the visual direction, build real production code, then inspect and improve in-browser until the result meets a high-end studio bar.
Build a feature with impeccable UX and UI quality: shape the design, land the visual direction, build real production code, inspect and improve in-browser until it meets a high-end studio bar.
## Build Gate
Before writing code, you need: PRODUCT.md loaded, register identified and the matching reference loaded, and a confirmed design direction for this task (either from `shape` or supplied by the user). PRODUCT.md is project context, not a task-specific brief.
Craft cannot build until all of these are true:
Treat any approved visual direction (generated mock or stated reference) as a concrete contract for composition, hierarchy, density, atmosphere, signature motifs, and distinctive visual moves. Don't let mocks replace structure, copy, accessibility, or state design. But if the live result lacks the approved direction's major ingredients, the implementation is wrong.
1. PRODUCT context is valid and current.
2. The shape design brief is explicitly confirmed by the user for this task, unless the user already provided a confirmed brief.
3. Implementation references from the brief are loaded.
4. The shape visual probe decision is recorded: generated, skipped with reason, or already resolved.
5. The north-star mock decision is recorded: generated, skipped with reason, or not applicable.
## Step 0: Project Foundation
PRODUCT.md and `teach` answers do **not** satisfy the shape gate. They are project context only. A compact self-authored brief does not satisfy the shape gate either. `shape=pass` requires a separate user response approving the shape brief or an already-confirmed brief supplied by the user.
Before shape, before code: figure out what kind of project you're working in.
Invalid image-skip reasons include: "the final implementation will be semantic HTML/CSS/SVG", "the diagram should stay editable", "a raster mock would not be used directly", or "the product is fictional." Generated probes and mocks are direction artifacts; they are not implementation assets.
Look at the working directory. Run `ls`. Check for:
## Craft Contract
- An existing framework: `astro.config.mjs/ts`, `next.config.js/ts`, `nuxt.config.ts`, `svelte.config.js`, `vite.config.js/ts`, `package.json` with framework deps, `Cargo.toml` + Leptos/Yew, `Gemfile` + Rails. **If found, use it.** Do not start a parallel build, do not introduce a second framework, do not write to `dist/` or `build/` directly. Whatever pipeline the project has, respect it.
- An existing component library or design system: `src/components/`, `app/components/`, a `tokens.css` / `theme.ts`, an `astro.config` `integrations`. Read what's there before adding to it.
- An existing icon set: `lucide-react`, `@phosphor-icons/react`, `@iconify/*`, hand-rolled SVG sprites in `assets/icons/`. **Use what's already in the project**; don't introduce a second set.
Craft is not a first pass. It is a loop with these required artifacts:
If the directory is empty (greenfield), don't pick a framework silently. Ask the user via the AskUserQuestion tool, with sensible defaults framed by the brief:
1. Confirmed design brief from `shape`.
2. Approved visual direction, from generated probes / mocks when image generation is available.
3. Mock fidelity inventory: the visible ingredients from the approved direction that must survive into code.
4. Semantic, functional implementation using the project's real stack and conventions.
5. Browser evidence across relevant viewports.
6. At least one critique-and-fix pass after the first browser inspection, unless the first pass has no material defects.
```text
What should this be built on?
- Astro (default for content-led brand sites, landing pages, marketing surfaces)
- SvelteKit / Next.js / Nuxt (when the brief implies an app surface or significant interactivity)
- Single index.html (one-shot demo, prototype, or a deliberately framework-free experiment)
```
Do not let generated mockups replace interface structure, copy, accessibility, responsive behavior, or state design. But do treat the approved mock as a concrete visual contract for composition, hierarchy, density, atmosphere, signature motifs, image needs, and distinctive visual moves. "North star" means "preserve the important visible ingredients in semantic code," not "use it as loose mood."
Default: Astro for brand briefs, the project's existing framework for product briefs. Ask once; don't re-ask mid-task.
## Step 1: Shape the Design
Run /impeccable shape, passing along whatever feature description the user provided.
Run /impeccable shape, passing along whatever feature description the user provided. Shape is **required** for craft; it is what produces a confirmed direction.
Wait for the design brief to be fully confirmed by the user before proceeding. The brief is your blueprint, and every implementation decision should trace back to it.
Present the shape output and stop. Wait for the user to confirm, override, or course-correct before writing code.
If this craft run resumed after `teach` created PRODUCT.md, run shape now. Do not treat the teach interview, PRODUCT.md, or a summary of project context as a substitute for shape. Shape is task-specific and must cover scope, content/states, visual direction, constraints, anti-goals, probes when applicable, and explicit brief confirmation.
If the user already supplied a confirmed brief or ran shape separately, use it and skip this step.
If the user has already run /impeccable shape and has a confirmed design brief, skip this step and use the existing brief.
When the original prompt + PRODUCT.md already answer scope, content, and visual direction with no real ambiguity, the shape output can be **compact** (3-5 bullets stating what you're building and the visual lane, ending with one or two specific questions or "confirm or override"). The full 10-section structured brief is reserved for genuinely ambiguous, multi-screen, or stakeholder-heavy tasks. Don't pad a clear brief into a long one to look thorough; equally, don't skip the pause to look efficient.
## Step 2: Load References
@@ -55,79 +53,60 @@ Then add references based on the brief's needs:
## Step 3: Land the Visual Direction (Capability-Gated)
Before implementation, generate high-fidelity visual comps when all of these are true:
Generate high-fidelity visual comps before implementation when all three are true:
- The work is **net-new** or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is **mid-fi, high-fi, or production-ready**.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The work is net-new or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is mid-fi, high-fi, or production-ready.
- The harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool). Don't ask the user to set up external APIs.
When those conditions are met, this step is mandatory for **both brand and product work** in Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
Do not skip this step because the eventual UI should be semantic, editable, code-native, responsive, or accessible. Those are implementation requirements, not reasons to avoid visual exploration.
### Purpose
Use the mock step to find a stronger visual lane than code-first generation would reliably discover on its own. The brief remains authoritative on user, purpose, content, constraints, states, and anti-goals. The mock clarifies composition, hierarchy, density, typography, and visual tone.
When met, this step is mandatory for both brand and product work. If image generation isn't available, skip silently. "The eventual UI is semantic/code-native/accessible" is not a reason to skip; those are implementation requirements, not exploration ones.
### What to generate
Generate **1 to 3** high-fidelity north-star comps based on the confirmed brief. If shape already produced direction probes, use those results as input and generate a more resolved mock from the winning lane, not another unrelated exploration.
Generate **1 to 3** high-fidelity north-star comps from the confirmed brief. If shape already produced direction probes, resolve the winning lane further, not an unrelated exploration. Comps must differ in primary visual direction, not just color.
- For brand work, push visual identity, composition, and mood aggressively.
- For product work, still push hierarchy, topology, density, and tone, but keep the comps grounded in realistic product structure and states.
- For landing pages and long-form brand surfaces, show enough of the next section or second fold to establish the system beyond the hero.
The comps must be genuinely different in primary visual direction, not just color variants.
- Brand work: push visual identity, composition, and mood aggressively.
- Product work: push hierarchy, topology, density, tone, grounded in realistic product structure.
- Landing pages and long-form brand surfaces: show enough of the second fold to establish the system beyond the hero.
### Approval loop
Show the comps and ask what should carry forward. If the user asks for changes or the best direction is still weak, generate a focused revision before implementation. Continue until one direction is approved, or until the user explicitly delegates the choice.
Show the comps and ask what carries forward. Iterate until one direction is approved or the user delegates. If the user delegates, pick the strongest direction and explain it from the brief, not personal taste.
If the user delegates, pick the strongest direction and explain the decision using the brief, not personal taste.
Before moving to implementation, summarize:
- What to carry into code
- What **not** to literalize from the mock
This summary is required before Step 4. It is the handoff between visual exploration and semantic implementation.
Before Step 4, summarize what to carry into code and what **not** to literalize from the mock. This is the handoff between visual exploration and semantic implementation.
### Mock fidelity inventory
Before building, inventory the approved mock's major visible ingredients:
Inventory the approved mock's major visible ingredients:
- Hero silhouette and dominant composition.
- Signature motifs: planets, devices, portraits, charts, route lines, insets, badges, or other memorable objects.
- Nav and primary CTA treatment.
- Section sequence visible in the mock, especially the second fold.
- Image-native content the concept depends on.
- Typography, density, color/material treatment, and motion cues.
- Hero silhouette and dominant composition
- Signature motifs (planets, devices, portraits, charts, route lines, insets, badges, etc.)
- Nav and primary CTA treatment
- Section sequence, especially the second fold
- Image-native content the concept depends on
- Typography, density, color/material treatment, motion cues
For each ingredient, decide how it will be implemented: semantic HTML/CSS/SVG, generated asset, sourced project asset, icon library, canvas/WebGL, or an explicitly accepted omission. Do not substitute a different hero composition or new visual driver after approval unless the user approves the change.
For each, decide implementation: semantic HTML/CSS/SVG, generated asset, sourced asset, icon library, canvas/WebGL, or accepted omission. Don't substitute a different hero composition or visual driver post-approval without user sign-off.
Treat the mock as a **north star**, not a screenshot to trace. Do **not** rasterize core UI text or let the mock override the confirmed brief. But if the live result lacks the mock's major visible ingredients, the implementation is wrong.
If a photographic, architectural, product, or place-led mock becomes generic CSS scenery / decorative diagrams / bullets / copy, stop and fix it. That's a broken implementation, not a harmless interpretation.
Treat the mock as a north star, not a screenshot to trace. Don't rasterize core UI text. But if the live result lacks the mock's major ingredients, the implementation is wrong.
## Step 4: Asset Extraction (Need-Gated)
If the chosen direction includes image-native visual ingredients that would materially improve the implementation, generate them as separate assets before building.
If the approved direction needs raster assets, create them before building. Do not replace required imagery with generic cards, bullets, emoji, fake metrics, decorative CSS panels, or filler copy.
Good candidates:
Use the native asset producer (`impeccable_asset_producer` in Codex, `impeccable-asset-producer` in Claude Code) to create clean assets from the hi-fi mock and crops. If you do not have explicit permission to use agents, stop and ask:
- stickers
- badges
- seals
- tickets
- graphic labels
- textures
- abstract objects
- decorative marks
- non-semantic scene elements
```text
Asset production will work better as a scoped subagent job. Should I spawn the Impeccable asset producer subagent for this step?
```
For travel, editorial, portfolio, venue, product showcase, entertainment, education, or any other image-led brand surface, visual assets are usually core content, not decoration. Do not ship abstract CSS panels where the approved mock or subject matter calls for real imagery, generated plates, illustrations, maps, product/object renders, or destination scenes.
Do not skip asset production or silently do it inline. Inline asset production is allowed only if the user declines subagents, the harness cannot spawn the authorized agent, or the user explicitly asks for single-thread mode.
Do **not** export assets for core UI text, navigation, body copy, or any structure that should stay semantic and editable in code.
Pass the approved mock, crop/contact-sheet paths, output directory, dimensions/formats, transparency needs, constraints, and avoid list to the asset producer. Attach image generation capability to the spawned agent when the harness supports it; do not load image-generation reference material into the parent thread first.
Usually **1 to 5** extracted assets is enough. If the design can be built cleanly in HTML/CSS/SVG, prefer that over raster assets. If the mock contains major visual content that cannot be built credibly in code, asset extraction is not optional.
Prefer HTML/CSS/SVG/canvas when they can credibly reproduce an ingredient; use real/generated/stock imagery when the mock or subject matter calls for actual visual content.
## Step 5: Build to Production Quality
@@ -135,50 +114,35 @@ Implement the feature following the design brief. Build in passes so structure,
### Production bar
- Use real or realistic content. Remove placeholder copy, placeholder images, dead links, fake controls, and unused scaffold before presenting.
- Preserve the approved mock's major ingredients. Missing hero objects, missing world/product imagery, different section structure, downgraded CTA/nav treatment, or generic replacements for distinctive motifs are blocking defects unless the user accepted the change.
- Build semantically first: real headings, landmarks, labels, form associations, button/link semantics, accessible names, and state announcements where needed.
- Calibrate spacing, alignment, grid placement, and vertical rhythm deliberately. Do not accept default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- Make typography intentional: chosen font loading strategy, clear hierarchy, readable measure, stable line breaks, tuned wrapping, and no overflow at mobile or large desktop sizes.
- Design realistic state coverage: default, hover where supported, focus-visible, active, disabled, loading, error, success, empty, overflow, long text, short text, and first-run states where relevant.
- Make interaction quality feel finished: keyboard paths, touch targets, feedback timing, scroll behavior, transitions between states, and no hover-only functionality.
- Use icons from the project's established icon set when available. If no set exists, choose a coherent library or use accessible text controls; do not mix unrelated icon styles.
- Optimize imagery and media: correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset` / `picture` for raster assets, and no project-referenced asset left outside the workspace.
- Make motion feel premium: use atmospheric blur, filter, mask, shadow, or reveal effects when they improve the experience; avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- Preserve maintainability: reusable local patterns, clear component boundaries, project conventions, no rasterized UI text, and no hard-coded one-off hacks when a better local pattern exists.
- Fit the technical context: production build passes, no obvious console errors, no avoidable layout shift, no needless dependency, and no broken asset path.
- If you discover a design question that materially changes the brief or approved direction, stop and ask rather than guessing.
- **Real content.** No placeholder copy, placeholder images, dead links, fake controls, or unused scaffold at presentation time.
- **Preserve the approved mock's major ingredients.** Missing hero objects, world/product imagery, section structure, CTA/nav treatment, or distinctive motifs are blocking defects unless the user accepted the change.
- **Semantic first.** Real headings, landmarks, labels, form associations, button/link semantics, accessible names, state announcements where needed.
- **Deliberate spacing and alignment.** No default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- **Intentional typography.** Chosen loading strategy, clear hierarchy, readable measure, stable line breaks, no overflow at any width.
- **Realistic state coverage.** Default, hover, focus-visible, active, disabled, loading, error, success, empty, overflow, long/short text, first-run.
- **Finished interaction quality.** Keyboard paths, touch targets, feedback timing, scroll behavior, state transitions, no hover-only functionality.
- **Coherent icon set.** Use the project's established set; otherwise pick one library or use accessible text. Don't mix.
- **Respect the build pipeline.** Edit source files and run the project's build (`npm run build` or equivalent). Don't write to `build/` / `dist/` / `.next/` with `cat`, heredoc, or Bash redirects; that skips asset hashing, image optimization, code splitting, and CSS extraction, and produces output the dev server won't serve.
- **Verify image URLs before referencing them.** Use image-search MCP or web-fetch when available; guessed photo IDs ship as broken-image placeholders. Without verification, prefer fewer images you're confident about.
- **Optimized imagery and media.** Correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset`/`picture` for raster, no project-referenced asset left outside the workspace.
- **Premium motion.** Use atmospheric blur, filter, mask, shadow, reveal when they improve the experience. Avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- **Maintainable.** Reusable local patterns, clear component boundaries, project conventions. No rasterized UI text or one-off hacks when a local pattern exists.
- **Technically clean.** Production build passes, no console errors, no avoidable layout shift, no needless dependencies, no broken asset paths.
- **Ask when uncertain.** If a discovery materially changes the brief or approved direction, stop and ask. Don't guess.
## Step 6: Browser-Based Iteration
## Step 6: Iterate Visually
**This step is critical.** Do not stop after the first implementation pass.
Look at what you built like a designer would. Your eyes are whatever the harness gives you: a connected browser, a screenshotting tool, Playwright, or asking the user. Use them for responsive testing (mobile, tablet, desktop minimum) and general visual validation.
Open the result in a browser. In Codex, use browser-use or equivalent browser automation when available; otherwise use Playwright or ask the user for screenshots. Inspect screenshots, not just DOM or terminal output.
If your tool returns a file path, read the PNG back into the conversation. A screenshot you didn't read doesn't count.
### Required viewport pass
For long-form brand surfaces, inspect major sections individually. Thumbnails hide spacing, clipping, and cascade defects.
Check the experience at the viewports that matter for the brief. Default minimum:
After the first pass, write an honest critique against the brief, the approved mock's major ingredients (hero silhouette, motifs, imagery, nav/CTA, density), and impeccable's DON'Ts. Patch material defects and re-inspect. **Don't invent defects to demonstrate iteration.** A confident "first pass clean, shipping" beats a fake fix.
- Mobile narrow
- Tablet or small laptop
- Desktop wide
Actively check: responsive behavior (composes, not shrinks), every state (empty / error / loading / edge), craft details (spacing, alignment, hierarchy, contrast, motion timing, focus), performance basics. The exit bar: defensible in a high-end studio review.
For each viewport, capture or inspect the rendered state and look for visual defects: overlap, clipping, weak hierarchy, off-grid alignment, awkward whitespace, cramped controls, unreadable type, broken imagery, hover-only functionality, layout shift, and text overflow.
### Critique and fix loop
After the first browser pass, write a short critique for yourself and patch the implementation. Repeat browser inspection after fixes. Continue until no material issues remain against this checklist:
1. **Does it match the brief?** Compare the live result against every section of the design brief. Fix discrepancies.
2. **Does it match the approved mock?** Compare screenshots against the mock fidelity inventory: hero silhouette, major motifs, imagery, nav/CTA, section sequence, density, color/materials, and second-fold substance. Missing major ingredients are P0 defects.
3. **Does it pass the AI slop test?** If someone saw this and said "AI made this," would they believe it immediately? If yes, it needs more design intention.
4. **Check against impeccable's DON'T guidelines.** Fix any anti-pattern violations.
5. **Check every state.** Navigate through empty, error, loading, and edge case states. Each one should feel intentional, not like an afterthought.
6. **Check responsive behavior.** The design should adapt compositionally, not merely shrink.
7. **Check craft details.** Spacing consistency, optical alignment, type hierarchy, color contrast, image quality, icon coherence, interactive feedback, motion timing, and focus treatment.
8. **Check performance basics.** No obviously oversized images, avoidable layout thrash, blocking animations, or heavy assets without a reason.
The exit bar is not "it works." It is: the rendered result looks intentional at all checked viewports, all expected states are handled, no placeholders remain unless explicitly accepted, and the implementation quality would be defensible in a high-end studio review.
Detector or QA output is defect evidence only; never proof the work is finished.
## Step 7: Present
@@ -189,5 +153,3 @@ Present the result to the user:
- Explain design decisions that connect back to the design brief and, when used, the chosen north-star mock. Include any accepted deviations from the mock; do not hide unimplemented mock ingredients.
- Note any remaining limitations or follow-up risks honestly
- Ask: "What's working? What isn't?"
Iterate based on feedback. Good design is rarely right on the first pass.
@@ -43,7 +43,7 @@ Run the bundled deterministic detector, which flags 27 specific patterns (AI slo
**CLI scan**:
```bash
npx impeccable --json [--fast] [target]
npx impeccable detect --json [--fast] [target]
```
- Pass HTML/JSX/TSX/Vue/Svelte files or directories as `[target]` (anything with markup). Do not pass CSS-only files.
@@ -2,6 +2,8 @@
Perform a meticulous final pass to catch all the small details that separate good work from great work. The difference between shipped and polished.
Detector and automated QA output are defect evidence only. A clean script result is never proof that the design is strong; gather browser evidence and inspect the real interaction path.
## Design System Discovery
Aligning the feature to the design system is **not optional**. Polish without alignment is decoration on top of drift, and it makes the next person's job harder. Discovery comes before any other polish work.
@@ -216,11 +218,12 @@ Sweat the details. Zoom in until the alignment is right and the spacing reads as
Before marking as done:
- **Use it yourself**: Actually interact with the feature
- **Test on real devices**: Not just browser DevTools
- **Ask someone else to review**: Fresh eyes catch things
- **Compare to design**: Match intended design
- **Check all states**: Don't just test happy path
- **Use it yourself**: Actually interact with the feature.
- **Test on real devices**: Not just browser DevTools.
- **Ask someone else to review**: Fresh eyes catch things.
- **Compare to design**: Match intended design.
- **Check all states**: Don't just test happy path.
- **Treat automation carefully**: Run detector or QA commands when they are available and relevant, fix their defects, but never cite a clean result as proof that the work is polished.
## Clean Up
@@ -230,4 +233,3 @@ After polishing, ensure code quality:
- **Remove orphaned code**: Delete unused styles, components, or files made obsolete by polish.
- **Consolidate tokens**: If you introduced new values, check whether they should be tokens.
- **Verify DRYness**: Look for duplication introduced during polishing and consolidate.
+25 -11
View File
@@ -16,14 +16,16 @@ This is a required interaction, not optional guidance. Ask these questions in co
### Interview cadence
Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed design inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
Discovery includes at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
- Use the harness's structured question tool when one exists. Otherwise, ask directly in chat and stop.
- Ask **2-3 questions per round**, then wait for answers.
- Treat PRODUCT.md and DESIGN.md as anchors; they reduce repeated questions but do **not** replace shape for craft. Shape is task-specific.
- Round 1 should clarify purpose, audience/context, and success or emotional outcome.
- Round 2 should clarify content/data/states and scope/fidelity.
- Round 3 should clarify visual direction, constraints, and anti-goals when still unresolved.
- One round is the default. Add a second only if the first answers leave material gaps. Don't run a second round just to feel thorough.
- Round 1 should clarify purpose, audience/context, content/scope, and (for brand) visual direction.
- Round 2, when needed, fills in whatever's still genuinely missing.
**Assert-then-confirm, not menu-with-escape.** When PRODUCT.md and the user's prompt make one option obvious, name it and ask the user to confirm or override. Don't enumerate "Restrained / Committed / Or something else?" as a real choice; "This reads as Restrained, confirm?" beats a four-option menu when the answer is already clear.
### Purpose & Context
- What is this feature for? What problem does it solve?
@@ -36,6 +38,7 @@ Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.
- What are the realistic ranges? (Minimum, typical, maximum, e.g., 0 items, 5 items, 500 items)
- What are the edge cases? (Empty state, error state, first-time use, power user)
- Is any content dynamic? What changes and how often?
- What visual assets are real content here? Note required images, product shots, illustrations, maps, textures, diagrams, generated objects, or existing project assets.
### Design Direction
@@ -72,9 +75,9 @@ After the discovery interview, generate a small set of visual direction probes *
- The work is **net-new** or directionally ambiguous enough that visual exploration will clarify the brief.
- The requested fidelity is **mid-fi, high-fi, or production-ready**. Skip for sketch-only planning.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The current harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool, or similar). Don't ask the user to install APIs or tooling.
When those conditions are met, this step is mandatory for Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
When those conditions are met, this step is mandatory. If image generation isn't natively available, skip silently and proceed; don't announce the skip.
Use probes to explore visual lanes, not to replace the brief.
@@ -104,11 +107,20 @@ The probes should differ in primary visual direction (hierarchy, topology, densi
- Do **not** treat generated imagery as final UX specification, final copy, or final accessibility behavior.
- Do **not** use this step for minor refinements of existing work. It's for shaping a new surface or clarifying a big directional choice.
If image generation is unavailable, or the task doesn't benefit from it, skip this phase only with a one-line reason and proceed directly to the design brief.
If image generation isn't natively available, skip this phase silently and proceed.
## Phase 2: Design Brief
After the interview and any required probes, synthesize everything into a structured design brief. Present it to the user for explicit confirmation before considering this command complete. Stop after asking for confirmation; do not proceed to craft or implementation in the same response unless the user has already approved the brief.
After the interview and any required probes, present a brief and **end your response**. The user must confirm before any implementation runs. Do not present a brief and then continue to code in the same response, even if the brief feels obvious to you. The user's confirmation is the gate.
**Choose the brief shape based on how clear the answers are:**
- **Compact form (3-5 bullets)** when discovery was crisp and the original prompt + PRODUCT.md already pinned scope, content, and direction. State what you're building, the visual lane, and end with one or two specific questions or a clear "confirm or override?" prompt. This is the default for typical craft requests with a clear prompt.
- **Full structured form (sections below)** when the task is genuinely ambiguous, multi-screen, or when the user asked for shape as a standalone step. Use this when the discipline of structure earns its weight.
Don't pad a clear brief into a long one to look thorough. A 70-line brief restating answers the user just gave is noise, not rigor. Equally, don't skip the confirmation pause to look efficient: the pause is the point.
If the user already said "approved" or "go" during discovery for the *exact direction you'd present*, that counts as confirmation; you may proceed without asking again. But if your brief adds anything the user hasn't seen and approved, you must stop and confirm.
### Brief Structure
@@ -136,16 +148,18 @@ List every state the feature needs: default, empty, loading, error, success, edg
How users interact with this feature. What happens on click, hover, scroll? What feedback do they get? What's the flow from entry to completion?
**8. Content Requirements**
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges.
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges. For image-led surfaces, also list the required image/media roles and their likely source (project asset, generated raster, semantic SVG/CSS, canvas/WebGL, icon library, or accepted omission).
**9. Recommended References**
Based on the brief, list which impeccable reference files would be most valuable during implementation (e.g., spatial-design.md for complex layouts, motion-design.md for animated features, interaction-design.md for form-heavy features).
**10. Open Questions**
Anything unresolved that the implementer should resolve during build.
Anything genuinely unresolved. Don't list "open questions" you've already recommended a default for; assert the default and move on. If you'd write `Recommend: X` next to a question, just decide X.
---
STOP and call the AskUserQuestion tool to clarify. Ask for explicit confirmation of the brief before finishing. If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the brief is confirmed.
STOP and call the AskUserQuestion tool to clarify.
If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the user confirms direction (or the user already gave a clear go during discovery, which counts).
Once confirmed, the brief is complete. The user can now hand it to /impeccable, or use it to guide any other implementation approach. (If the user wants the full discovery-then-build flow in one step, they should use /impeccable craft instead, which runs this command internally.)
@@ -0,0 +1,92 @@
name = "impeccable_asset_producer"
description = "Produces clean reusable raster assets from approved Impeccable mock references without redesigning the direction."
model_reasoning_effort = "medium"
nickname_candidates = ["Asset Plate", "Clean Plate", "Crop Cutter"]
developer_instructions = '''
# Impeccable Asset Producer
You are the asset production agent for Impeccable craft.
Your job is production cleanup, not new art direction. Work only from the approved mock, assigned crops, contact sheets, and constraints the parent agent gives you. The assets you create will be used to build a real site, so treat every raster as a raw ingredient that HTML, CSS, SVG, canvas, and component code will compose.
## Core Rule
Do not redesign. Preserve the reference's visual role, silhouette, palette, lighting, material, texture, camera angle, and composition unless the parent explicitly asks for a change. Preserve perspective only when it belongs to the object or scene itself; if CSS should create the card transform, shadow, rounded clipping, border, or layout, remove that presentation chrome from the raster.
## Input Contract
Expect:
- Approved mock path or screenshot reference.
- Crop paths or a contact sheet with crop ids.
- Output directory.
- Required dimensions, format, transparency needs, and avoid list.
- Notes on what should remain semantic HTML/CSS/SVG instead of raster.
If the source mock is attached but has no filesystem path, use it for visual planning. Ask for a path only before cropping or writing assets.
Use defaults unless contradicted:
- `.webp` for opaque photos, backgrounds, and textures.
- `.png` for transparent cutouts, seals, tickets, and illustrations.
- Target production size or at least 2x display size when dimensions are known. Do not use small full-page mock crop size as the default shipping size.
- Remove UI text, navigation, buttons, labels, and body copy by default.
- Keep physical marks only when the parent says they are part of the asset.
- Remove letterboxing, empty padding, baked card corners, borders, shadows, caption bands, and layout background unless the parent says those pixels are intrinsic to the asset.
- Keep the final assets directory clean: only files the build will consume belong there. Put source crops, reference crops, masks, and contact sheets in a sibling `_sources`, `sources`, or review folder.
Ask blockers once, globally. Missing source path/crops or output directory blocks production. Exact dimensions, compression targets, retina variants, and format preferences do not block; choose defaults and report them.
## Workflow
1. Inventory the full approved mock or every assigned crop.
2. Put each visual role in exactly one bucket:
- `produce`: needs generation, image editing, cleanup, cutout work, or a clean plate before it can ship.
- `direct`: can ship as a crop, format conversion, compression pass, or sourced replacement with no generative cleanup.
- `semantic`: build in HTML/CSS/SVG/canvas, no raster output.
3. Treat full-page mock crops as references, not production-resolution source assets. Put a role in `direct` only when the provided source is already a clean, sufficiently large source asset with no semantic text or presentation chrome.
4. Give the parent an execution order for the `produce` bucket.
5. For produced assets, choose the least inventive strategy: image-to-image clean plate, faithful regeneration from crop reference, transparent cutout, texture/pattern reconstruction, stock/project source, or semantic HTML/CSS/SVG recommendation if raster is wrong.
6. Treat every crop as binding reference. In Codex, use the imagegen skill and built-in `image_gen` path by default when generation or editing is needed.
7. Remove baked-in UI text, navigation, buttons, body copy, and mock chrome unless the text is part of the asset.
8. Think through the final DOM/CSS representation before generating. If CSS will own radius, clipping, shadows, borders, perspective, responsive cropping, captions, or card frames, do not bake those into the bitmap.
9. Save outputs non-destructively in the requested project directory.
10. Compare each output against its source crop. If a review/QA tool is available, run it before the final manifest, then retry each major/fatal finding once before finalizing.
Use `direct` only for provided source assets that can already ship after crop tightening, conversion, compression, or naming. Do not ship a small crop from the full-page mock as `direct` just because it looks close.
Use `texture/pattern extraction` only when the source region is already clean enough to sample as texture. If UI, cards, labels, headings, body copy, or footer chrome must be removed to make a reusable texture or background, classify it as crop-derived cleanup or clean-plate work.
Use `semantic` for dashboards, charts, controls, screenshots of whole UI sections, data widgets, card chrome, app frames, icon toolbars, logos, wordmarks, and anything the final implementation can render crisply in HTML/CSS/SVG/canvas. Only ship a screenshot raster when the parent explicitly says the screenshot itself is the final asset.
Semantic does not mean ignored. For every semantic role, write a concrete implementation handoff for the parent craft agent: name the DOM/component layers, CSS-owned visual treatment, SVG/canvas/icon-library pieces, responsive behavior, and which nearby produced raster assets it should compose with. For logos and icons, prefer inline SVG/vector or icon-library implementation unless the parent provides a production logo raster.
For transparency, prefer true alpha output when the tool supports it. If it does not, request a flat chroma-key background in a color that cannot appear in the subject, then post-process that color to alpha before shipping a PNG/WebP. Do not ship the keyed background as the final asset.
## Prompt Pattern
Use this shape for image-to-image work:
```text
Use the provided crop as the approved visual reference.
Recreate the same asset as a clean reusable production image at the target component aspect ratio and at least 2x display resolution.
Preserve silhouette, object/scene perspective, camera angle, palette, lighting, material, texture, and visual role.
Remove baked-in UI copy, navigation, buttons, labels, body text, watermarks, and mock chrome unless explicitly part of the asset.
Remove letterboxing, padding, card borders, rounded clipping, CSS shadows, perspective transforms, caption bands, and layout backgrounds that the implementation should create in code.
Do not add new objects. Do not change the concept. Do not redesign the composition.
```
For transparent cutouts, use the imagegen skill's built-in-first chroma-key workflow unless the parent explicitly authorizes a true native transparency fallback.
## Output Contract
Return a complete manifest, grouped by `produce`, `direct`, and `semantic`. For each asset include: `id`, `source_crop`, `output_path` when applicable, `strategy`, `prompt_used` when applicable, `dimensions`, `format`, `transparency`, `deviations`, and `qa_status`.
For each semantic row include `id`, `implementation`, `notes`, and `qa_status`. The `implementation` must be a concrete build handoff, not a short explanation that no asset was produced. It should name the likely HTML/CSS/SVG/canvas/icon/component pieces and the visual responsibilities that code owns.
`qa_status` must be `accepted`, `needs_parent_review`, or `blocked`. Use `accepted` only after visual comparison passes. Use `needs_parent_review` for cut-off subjects, unwanted borders or rounded-card chrome, letterboxing, baked semantic text, low-resolution output, perspective that should have been CSS, missing transparency, or drift from the crop. Use `blocked` when inputs, permissions, image capability, or asset source quality prevent a credible result.
End with `execution_order`, `blockers`, and `assumptions` sections. Keep blockers global and minimal. Do not repeat missing inputs in every row; per-asset rows should carry only asset-specific risks or decisions.
Do not modify implementation code. Do not edit the approved mock. Do not produce final page copy. The parent craft agent owns implementation and final mock fidelity.
'''
+6 -19
View File
@@ -7,28 +7,15 @@ license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md f
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
## Setup (non-optional)
## Setup
Before any design work or file edits, pass these gates. Skipping them produces generic output that ignores the project.
Before any design work or file edits:
| Gate | Required check | If fail |
|---|---|---|
| Context | The PRODUCT.md / DESIGN.md loader result is known from `node .cursor/skills/impeccable/scripts/load-context.mjs`. | Run the loader before continuing. |
| Product | PRODUCT.md exists and is not empty or placeholder (`[TODO]` markers, <200 chars). | Run `/impeccable teach`, refresh context, then resume. Never synthesize PRODUCT.md from the user's original prompt alone. |
| Command | The matching command reference is loaded when a sub-command is used. | Load the reference before continuing. |
| Craft | `/impeccable craft` has a user-confirmed shape brief for this task. `teach` / PRODUCT.md never counts as shape. | Run `/impeccable shape` and wait for explicit brief confirmation. |
| Image | Required visual probes / mocks are generated or skipped with a reason. | Resolve the image-generation gate in `shape.md` or `craft.md` before code. |
| Mutation | All active gates above pass. | Do not edit project files yet. |
1. Load context (PRODUCT.md / DESIGN.md) via the loader script.
2. Identify the register and load the matching register reference (brand.md or product.md).
3. **If the user invoked a sub-command (e.g. `craft`, `shape`, `audit`), load its reference file too.** This is non-negotiable: `craft` without `craft.md` loaded means you'll skip the shape-and-confirm step the user expects.
Codex-style agents must state this before editing files:
```text
IMPECCABLE_PREFLIGHT: context=pass product=pass command_reference=pass shape=pass|not_required image_gate=pass|skipped:<reason> mutation=open
```
For `/impeccable craft`, `shape=pass` is only valid after a separate user response approving the shape design brief, or when the user provided an already-confirmed brief in the request. Do not mark `shape=pass` after writing PRODUCT.md, summarizing assumptions, or drafting an unconfirmed brief yourself.
Other harnesses should follow the same checklist when they can expose this state.
Skipping these produces generic output that ignores the project.
### 1. Context gathering
+7 -3
View File
@@ -12,6 +12,8 @@ Brand isn't a neutral register. AI-generated landing pages have flooded the inte
**The second slop test: aesthetic lane.** Before committing to moves, name the reference. A Klim-style specimen page is one lane; Stripe-minimal is another; Liquid-Death-acid-maximalism is another. Don't drift into editorial-magazine aesthetics on a brief that isn't editorial. A hiking brand with Cormorant italic drop caps has the wrong register within the register.
Then the inverse test: in one sentence, describe what you're about to build the way a competitor would describe theirs. If that sentence fits the modal landing page in the category, restart.
## Typography
### Font selection procedure
@@ -66,6 +68,7 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
- Palette IS voice. A calm brand and a restless brand should not share palette mechanics.
- When the strategy is Committed or Drenched, color carries the brand. Don't hedge with neutrals around the edges. Commit.
- Don't converge across projects. If the last brand surface was restrained-on-cream, this one is not.
- When a cultural-symbol palette is the obvious pull, reach past it. Let the cultural reading come from typography, imagery, and copy, not the palette.
## Layout
@@ -79,14 +82,14 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
Brand surfaces lean on imagery. A restaurant, hotel, magazine, or product landing page without any imagery reads as incomplete, not as restrained. A solid-color rectangle where a hero image should go is worse than a representative stock photo.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse. If the approved comp or brief is image-led, ship real project assets, generated raster assets, or a credible canvas/SVG/WebGL scene. Do not replace photographic, architectural, product, or place imagery with generic CSS panels, decorative diagrams, cards, bullets, or copy.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. Pick real Unsplash photo IDs you're confident exist (`photo-1559339352-11d035aa65de`, `photo-1590490360182-c33d57733427`, etc.); if unsure, pick fewer photos but don't substitute colored `<div>` placeholders.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. **Verify the URLs before referencing them.** If you have an image-search MCP, web-fetch tool, or browser access, use it to find real photo IDs and confirm they resolve. Guessed IDs (even ones that look real) often 404 and ship as broken-image placeholders. Without a verification path, pick fewer photos you're confident exist over more that you guessed; never substitute colored `<div>` placeholders.
- **Search for the brand's physical object**, not the generic category: "handmade pasta on a scratched wooden table" beats "Italian food"; "cypress trees above a limestone hotel facade at dusk" beats "luxury hotel".
- **One decisive photo beats five mediocre ones.** Hero imagery should commit to a mood; padding with more stock doesn't rescue an indecisive one.
- **Alt text is part of the voice.** "Coastal fettuccine, hand-cut, served on the terrace" beats "pasta dish".
Tech / dev-tool brands are the exception where zero imagery can be correct; a developer landing page often carries its voice through typography, code samples, diagrams. Know which kind of brand you're working on.
"Imagery" here is broader than stock photography: product screenshots, custom data visualizations, generated SVG, and canvas/WebGL scenes are all imagery. Text-only pages where typography alone carries the entire visual weight are the failure mode.
## Motion
@@ -102,6 +105,7 @@ Tech / dev-tool brands are the exception where zero imagery can be correct; a de
- Timid palettes and average layouts. Safe = invisible.
- Zero imagery on a brief that implies imagery (restaurant, hotel, food, travel, fashion, photography, hobbyist). Colored blocks where a hero photo belongs.
- Defaulting to editorial-magazine aesthetics (display serif + italic + drop caps + broadsheet grid) on briefs that aren't magazine-shaped. Editorial is ONE aesthetic lane, not the default brand aesthetic.
- Repeated tiny uppercase tracked labels above every section heading. A single strong kicker can be voice; repeating it as section grammar is AI scaffolding unless it's a deliberate, named brand system.
## Brand permissions
+73 -111
View File
@@ -1,43 +1,41 @@
# Craft Flow
Build a feature with impeccable UX and UI quality through a structured process: shape the design, land the visual direction, build real production code, then inspect and improve in-browser until the result meets a high-end studio bar.
Build a feature with impeccable UX and UI quality: shape the design, land the visual direction, build real production code, inspect and improve in-browser until it meets a high-end studio bar.
## Build Gate
Before writing code, you need: PRODUCT.md loaded, register identified and the matching reference loaded, and a confirmed design direction for this task (either from `shape` or supplied by the user). PRODUCT.md is project context, not a task-specific brief.
Craft cannot build until all of these are true:
Treat any approved visual direction (generated mock or stated reference) as a concrete contract for composition, hierarchy, density, atmosphere, signature motifs, and distinctive visual moves. Don't let mocks replace structure, copy, accessibility, or state design. But if the live result lacks the approved direction's major ingredients, the implementation is wrong.
1. PRODUCT context is valid and current.
2. The shape design brief is explicitly confirmed by the user for this task, unless the user already provided a confirmed brief.
3. Implementation references from the brief are loaded.
4. The shape visual probe decision is recorded: generated, skipped with reason, or already resolved.
5. The north-star mock decision is recorded: generated, skipped with reason, or not applicable.
## Step 0: Project Foundation
PRODUCT.md and `teach` answers do **not** satisfy the shape gate. They are project context only. A compact self-authored brief does not satisfy the shape gate either. `shape=pass` requires a separate user response approving the shape brief or an already-confirmed brief supplied by the user.
Before shape, before code: figure out what kind of project you're working in.
Invalid image-skip reasons include: "the final implementation will be semantic HTML/CSS/SVG", "the diagram should stay editable", "a raster mock would not be used directly", or "the product is fictional." Generated probes and mocks are direction artifacts; they are not implementation assets.
Look at the working directory. Run `ls`. Check for:
## Craft Contract
- An existing framework: `astro.config.mjs/ts`, `next.config.js/ts`, `nuxt.config.ts`, `svelte.config.js`, `vite.config.js/ts`, `package.json` with framework deps, `Cargo.toml` + Leptos/Yew, `Gemfile` + Rails. **If found, use it.** Do not start a parallel build, do not introduce a second framework, do not write to `dist/` or `build/` directly. Whatever pipeline the project has, respect it.
- An existing component library or design system: `src/components/`, `app/components/`, a `tokens.css` / `theme.ts`, an `astro.config` `integrations`. Read what's there before adding to it.
- An existing icon set: `lucide-react`, `@phosphor-icons/react`, `@iconify/*`, hand-rolled SVG sprites in `assets/icons/`. **Use what's already in the project**; don't introduce a second set.
Craft is not a first pass. It is a loop with these required artifacts:
If the directory is empty (greenfield), don't pick a framework silently. Ask the user via the AskUserQuestion tool, with sensible defaults framed by the brief:
1. Confirmed design brief from `shape`.
2. Approved visual direction, from generated probes / mocks when image generation is available.
3. Mock fidelity inventory: the visible ingredients from the approved direction that must survive into code.
4. Semantic, functional implementation using the project's real stack and conventions.
5. Browser evidence across relevant viewports.
6. At least one critique-and-fix pass after the first browser inspection, unless the first pass has no material defects.
```text
What should this be built on?
- Astro (default for content-led brand sites, landing pages, marketing surfaces)
- SvelteKit / Next.js / Nuxt (when the brief implies an app surface or significant interactivity)
- Single index.html (one-shot demo, prototype, or a deliberately framework-free experiment)
```
Do not let generated mockups replace interface structure, copy, accessibility, responsive behavior, or state design. But do treat the approved mock as a concrete visual contract for composition, hierarchy, density, atmosphere, signature motifs, image needs, and distinctive visual moves. "North star" means "preserve the important visible ingredients in semantic code," not "use it as loose mood."
Default: Astro for brand briefs, the project's existing framework for product briefs. Ask once; don't re-ask mid-task.
## Step 1: Shape the Design
Run /impeccable shape, passing along whatever feature description the user provided.
Run /impeccable shape, passing along whatever feature description the user provided. Shape is **required** for craft; it is what produces a confirmed direction.
Wait for the design brief to be fully confirmed by the user before proceeding. The brief is your blueprint, and every implementation decision should trace back to it.
Present the shape output and stop. Wait for the user to confirm, override, or course-correct before writing code.
If this craft run resumed after `teach` created PRODUCT.md, run shape now. Do not treat the teach interview, PRODUCT.md, or a summary of project context as a substitute for shape. Shape is task-specific and must cover scope, content/states, visual direction, constraints, anti-goals, probes when applicable, and explicit brief confirmation.
If the user already supplied a confirmed brief or ran shape separately, use it and skip this step.
If the user has already run /impeccable shape and has a confirmed design brief, skip this step and use the existing brief.
When the original prompt + PRODUCT.md already answer scope, content, and visual direction with no real ambiguity, the shape output can be **compact** (3-5 bullets stating what you're building and the visual lane, ending with one or two specific questions or "confirm or override"). The full 10-section structured brief is reserved for genuinely ambiguous, multi-screen, or stakeholder-heavy tasks. Don't pad a clear brief into a long one to look thorough; equally, don't skip the pause to look efficient.
## Step 2: Load References
@@ -55,79 +53,60 @@ Then add references based on the brief's needs:
## Step 3: Land the Visual Direction (Capability-Gated)
Before implementation, generate high-fidelity visual comps when all of these are true:
Generate high-fidelity visual comps before implementation when all three are true:
- The work is **net-new** or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is **mid-fi, high-fi, or production-ready**.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The work is net-new or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is mid-fi, high-fi, or production-ready.
- The harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool). Don't ask the user to set up external APIs.
When those conditions are met, this step is mandatory for **both brand and product work** in Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
Do not skip this step because the eventual UI should be semantic, editable, code-native, responsive, or accessible. Those are implementation requirements, not reasons to avoid visual exploration.
### Purpose
Use the mock step to find a stronger visual lane than code-first generation would reliably discover on its own. The brief remains authoritative on user, purpose, content, constraints, states, and anti-goals. The mock clarifies composition, hierarchy, density, typography, and visual tone.
When met, this step is mandatory for both brand and product work. If image generation isn't available, skip silently. "The eventual UI is semantic/code-native/accessible" is not a reason to skip; those are implementation requirements, not exploration ones.
### What to generate
Generate **1 to 3** high-fidelity north-star comps based on the confirmed brief. If shape already produced direction probes, use those results as input and generate a more resolved mock from the winning lane, not another unrelated exploration.
Generate **1 to 3** high-fidelity north-star comps from the confirmed brief. If shape already produced direction probes, resolve the winning lane further, not an unrelated exploration. Comps must differ in primary visual direction, not just color.
- For brand work, push visual identity, composition, and mood aggressively.
- For product work, still push hierarchy, topology, density, and tone, but keep the comps grounded in realistic product structure and states.
- For landing pages and long-form brand surfaces, show enough of the next section or second fold to establish the system beyond the hero.
The comps must be genuinely different in primary visual direction, not just color variants.
- Brand work: push visual identity, composition, and mood aggressively.
- Product work: push hierarchy, topology, density, tone, grounded in realistic product structure.
- Landing pages and long-form brand surfaces: show enough of the second fold to establish the system beyond the hero.
### Approval loop
Show the comps and ask what should carry forward. If the user asks for changes or the best direction is still weak, generate a focused revision before implementation. Continue until one direction is approved, or until the user explicitly delegates the choice.
Show the comps and ask what carries forward. Iterate until one direction is approved or the user delegates. If the user delegates, pick the strongest direction and explain it from the brief, not personal taste.
If the user delegates, pick the strongest direction and explain the decision using the brief, not personal taste.
Before moving to implementation, summarize:
- What to carry into code
- What **not** to literalize from the mock
This summary is required before Step 4. It is the handoff between visual exploration and semantic implementation.
Before Step 4, summarize what to carry into code and what **not** to literalize from the mock. This is the handoff between visual exploration and semantic implementation.
### Mock fidelity inventory
Before building, inventory the approved mock's major visible ingredients:
Inventory the approved mock's major visible ingredients:
- Hero silhouette and dominant composition.
- Signature motifs: planets, devices, portraits, charts, route lines, insets, badges, or other memorable objects.
- Nav and primary CTA treatment.
- Section sequence visible in the mock, especially the second fold.
- Image-native content the concept depends on.
- Typography, density, color/material treatment, and motion cues.
- Hero silhouette and dominant composition
- Signature motifs (planets, devices, portraits, charts, route lines, insets, badges, etc.)
- Nav and primary CTA treatment
- Section sequence, especially the second fold
- Image-native content the concept depends on
- Typography, density, color/material treatment, motion cues
For each ingredient, decide how it will be implemented: semantic HTML/CSS/SVG, generated asset, sourced project asset, icon library, canvas/WebGL, or an explicitly accepted omission. Do not substitute a different hero composition or new visual driver after approval unless the user approves the change.
For each, decide implementation: semantic HTML/CSS/SVG, generated asset, sourced asset, icon library, canvas/WebGL, or accepted omission. Don't substitute a different hero composition or visual driver post-approval without user sign-off.
Treat the mock as a **north star**, not a screenshot to trace. Do **not** rasterize core UI text or let the mock override the confirmed brief. But if the live result lacks the mock's major visible ingredients, the implementation is wrong.
If a photographic, architectural, product, or place-led mock becomes generic CSS scenery / decorative diagrams / bullets / copy, stop and fix it. That's a broken implementation, not a harmless interpretation.
Treat the mock as a north star, not a screenshot to trace. Don't rasterize core UI text. But if the live result lacks the mock's major ingredients, the implementation is wrong.
## Step 4: Asset Extraction (Need-Gated)
If the chosen direction includes image-native visual ingredients that would materially improve the implementation, generate them as separate assets before building.
If the approved direction needs raster assets, create them before building. Do not replace required imagery with generic cards, bullets, emoji, fake metrics, decorative CSS panels, or filler copy.
Good candidates:
Use the native asset producer (`impeccable_asset_producer` in Codex, `impeccable-asset-producer` in Claude Code) to create clean assets from the hi-fi mock and crops. If you do not have explicit permission to use agents, stop and ask:
- stickers
- badges
- seals
- tickets
- graphic labels
- textures
- abstract objects
- decorative marks
- non-semantic scene elements
```text
Asset production will work better as a scoped subagent job. Should I spawn the Impeccable asset producer subagent for this step?
```
For travel, editorial, portfolio, venue, product showcase, entertainment, education, or any other image-led brand surface, visual assets are usually core content, not decoration. Do not ship abstract CSS panels where the approved mock or subject matter calls for real imagery, generated plates, illustrations, maps, product/object renders, or destination scenes.
Do not skip asset production or silently do it inline. Inline asset production is allowed only if the user declines subagents, the harness cannot spawn the authorized agent, or the user explicitly asks for single-thread mode.
Do **not** export assets for core UI text, navigation, body copy, or any structure that should stay semantic and editable in code.
Pass the approved mock, crop/contact-sheet paths, output directory, dimensions/formats, transparency needs, constraints, and avoid list to the asset producer. Attach image generation capability to the spawned agent when the harness supports it; do not load image-generation reference material into the parent thread first.
Usually **1 to 5** extracted assets is enough. If the design can be built cleanly in HTML/CSS/SVG, prefer that over raster assets. If the mock contains major visual content that cannot be built credibly in code, asset extraction is not optional.
Prefer HTML/CSS/SVG/canvas when they can credibly reproduce an ingredient; use real/generated/stock imagery when the mock or subject matter calls for actual visual content.
## Step 5: Build to Production Quality
@@ -135,50 +114,35 @@ Implement the feature following the design brief. Build in passes so structure,
### Production bar
- Use real or realistic content. Remove placeholder copy, placeholder images, dead links, fake controls, and unused scaffold before presenting.
- Preserve the approved mock's major ingredients. Missing hero objects, missing world/product imagery, different section structure, downgraded CTA/nav treatment, or generic replacements for distinctive motifs are blocking defects unless the user accepted the change.
- Build semantically first: real headings, landmarks, labels, form associations, button/link semantics, accessible names, and state announcements where needed.
- Calibrate spacing, alignment, grid placement, and vertical rhythm deliberately. Do not accept default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- Make typography intentional: chosen font loading strategy, clear hierarchy, readable measure, stable line breaks, tuned wrapping, and no overflow at mobile or large desktop sizes.
- Design realistic state coverage: default, hover where supported, focus-visible, active, disabled, loading, error, success, empty, overflow, long text, short text, and first-run states where relevant.
- Make interaction quality feel finished: keyboard paths, touch targets, feedback timing, scroll behavior, transitions between states, and no hover-only functionality.
- Use icons from the project's established icon set when available. If no set exists, choose a coherent library or use accessible text controls; do not mix unrelated icon styles.
- Optimize imagery and media: correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset` / `picture` for raster assets, and no project-referenced asset left outside the workspace.
- Make motion feel premium: use atmospheric blur, filter, mask, shadow, or reveal effects when they improve the experience; avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- Preserve maintainability: reusable local patterns, clear component boundaries, project conventions, no rasterized UI text, and no hard-coded one-off hacks when a better local pattern exists.
- Fit the technical context: production build passes, no obvious console errors, no avoidable layout shift, no needless dependency, and no broken asset path.
- If you discover a design question that materially changes the brief or approved direction, stop and ask rather than guessing.
- **Real content.** No placeholder copy, placeholder images, dead links, fake controls, or unused scaffold at presentation time.
- **Preserve the approved mock's major ingredients.** Missing hero objects, world/product imagery, section structure, CTA/nav treatment, or distinctive motifs are blocking defects unless the user accepted the change.
- **Semantic first.** Real headings, landmarks, labels, form associations, button/link semantics, accessible names, state announcements where needed.
- **Deliberate spacing and alignment.** No default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- **Intentional typography.** Chosen loading strategy, clear hierarchy, readable measure, stable line breaks, no overflow at any width.
- **Realistic state coverage.** Default, hover, focus-visible, active, disabled, loading, error, success, empty, overflow, long/short text, first-run.
- **Finished interaction quality.** Keyboard paths, touch targets, feedback timing, scroll behavior, state transitions, no hover-only functionality.
- **Coherent icon set.** Use the project's established set; otherwise pick one library or use accessible text. Don't mix.
- **Respect the build pipeline.** Edit source files and run the project's build (`npm run build` or equivalent). Don't write to `build/` / `dist/` / `.next/` with `cat`, heredoc, or Bash redirects; that skips asset hashing, image optimization, code splitting, and CSS extraction, and produces output the dev server won't serve.
- **Verify image URLs before referencing them.** Use image-search MCP or web-fetch when available; guessed photo IDs ship as broken-image placeholders. Without verification, prefer fewer images you're confident about.
- **Optimized imagery and media.** Correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset`/`picture` for raster, no project-referenced asset left outside the workspace.
- **Premium motion.** Use atmospheric blur, filter, mask, shadow, reveal when they improve the experience. Avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- **Maintainable.** Reusable local patterns, clear component boundaries, project conventions. No rasterized UI text or one-off hacks when a local pattern exists.
- **Technically clean.** Production build passes, no console errors, no avoidable layout shift, no needless dependencies, no broken asset paths.
- **Ask when uncertain.** If a discovery materially changes the brief or approved direction, stop and ask. Don't guess.
## Step 6: Browser-Based Iteration
## Step 6: Iterate Visually
**This step is critical.** Do not stop after the first implementation pass.
Look at what you built like a designer would. Your eyes are whatever the harness gives you: a connected browser, a screenshotting tool, Playwright, or asking the user. Use them for responsive testing (mobile, tablet, desktop minimum) and general visual validation.
Open the result in a browser. In Codex, use browser-use or equivalent browser automation when available; otherwise use Playwright or ask the user for screenshots. Inspect screenshots, not just DOM or terminal output.
If your tool returns a file path, read the PNG back into the conversation. A screenshot you didn't read doesn't count.
### Required viewport pass
For long-form brand surfaces, inspect major sections individually. Thumbnails hide spacing, clipping, and cascade defects.
Check the experience at the viewports that matter for the brief. Default minimum:
After the first pass, write an honest critique against the brief, the approved mock's major ingredients (hero silhouette, motifs, imagery, nav/CTA, density), and impeccable's DON'Ts. Patch material defects and re-inspect. **Don't invent defects to demonstrate iteration.** A confident "first pass clean, shipping" beats a fake fix.
- Mobile narrow
- Tablet or small laptop
- Desktop wide
Actively check: responsive behavior (composes, not shrinks), every state (empty / error / loading / edge), craft details (spacing, alignment, hierarchy, contrast, motion timing, focus), performance basics. The exit bar: defensible in a high-end studio review.
For each viewport, capture or inspect the rendered state and look for visual defects: overlap, clipping, weak hierarchy, off-grid alignment, awkward whitespace, cramped controls, unreadable type, broken imagery, hover-only functionality, layout shift, and text overflow.
### Critique and fix loop
After the first browser pass, write a short critique for yourself and patch the implementation. Repeat browser inspection after fixes. Continue until no material issues remain against this checklist:
1. **Does it match the brief?** Compare the live result against every section of the design brief. Fix discrepancies.
2. **Does it match the approved mock?** Compare screenshots against the mock fidelity inventory: hero silhouette, major motifs, imagery, nav/CTA, section sequence, density, color/materials, and second-fold substance. Missing major ingredients are P0 defects.
3. **Does it pass the AI slop test?** If someone saw this and said "AI made this," would they believe it immediately? If yes, it needs more design intention.
4. **Check against impeccable's DON'T guidelines.** Fix any anti-pattern violations.
5. **Check every state.** Navigate through empty, error, loading, and edge case states. Each one should feel intentional, not like an afterthought.
6. **Check responsive behavior.** The design should adapt compositionally, not merely shrink.
7. **Check craft details.** Spacing consistency, optical alignment, type hierarchy, color contrast, image quality, icon coherence, interactive feedback, motion timing, and focus treatment.
8. **Check performance basics.** No obviously oversized images, avoidable layout thrash, blocking animations, or heavy assets without a reason.
The exit bar is not "it works." It is: the rendered result looks intentional at all checked viewports, all expected states are handled, no placeholders remain unless explicitly accepted, and the implementation quality would be defensible in a high-end studio review.
Detector or QA output is defect evidence only; never proof the work is finished.
## Step 7: Present
@@ -189,5 +153,3 @@ Present the result to the user:
- Explain design decisions that connect back to the design brief and, when used, the chosen north-star mock. Include any accepted deviations from the mock; do not hide unimplemented mock ingredients.
- Note any remaining limitations or follow-up risks honestly
- Ask: "What's working? What isn't?"
Iterate based on feedback. Good design is rarely right on the first pass.
@@ -43,7 +43,7 @@ Run the bundled deterministic detector, which flags 27 specific patterns (AI slo
**CLI scan**:
```bash
npx impeccable --json [--fast] [target]
npx impeccable detect --json [--fast] [target]
```
- Pass HTML/JSX/TSX/Vue/Svelte files or directories as `[target]` (anything with markup). Do not pass CSS-only files.
@@ -2,6 +2,8 @@
Perform a meticulous final pass to catch all the small details that separate good work from great work. The difference between shipped and polished.
Detector and automated QA output are defect evidence only. A clean script result is never proof that the design is strong; gather browser evidence and inspect the real interaction path.
## Design System Discovery
Aligning the feature to the design system is **not optional**. Polish without alignment is decoration on top of drift, and it makes the next person's job harder. Discovery comes before any other polish work.
@@ -216,11 +218,12 @@ Sweat the details. Zoom in until the alignment is right and the spacing reads as
Before marking as done:
- **Use it yourself**: Actually interact with the feature
- **Test on real devices**: Not just browser DevTools
- **Ask someone else to review**: Fresh eyes catch things
- **Compare to design**: Match intended design
- **Check all states**: Don't just test happy path
- **Use it yourself**: Actually interact with the feature.
- **Test on real devices**: Not just browser DevTools.
- **Ask someone else to review**: Fresh eyes catch things.
- **Compare to design**: Match intended design.
- **Check all states**: Don't just test happy path.
- **Treat automation carefully**: Run detector or QA commands when they are available and relevant, fix their defects, but never cite a clean result as proof that the work is polished.
## Clean Up
@@ -230,4 +233,3 @@ After polishing, ensure code quality:
- **Remove orphaned code**: Delete unused styles, components, or files made obsolete by polish.
- **Consolidate tokens**: If you introduced new values, check whether they should be tokens.
- **Verify DRYness**: Look for duplication introduced during polishing and consolidate.
+25 -11
View File
@@ -16,14 +16,16 @@ This is a required interaction, not optional guidance. Ask these questions in co
### Interview cadence
Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed design inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
Discovery includes at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
- Use the harness's structured question tool when one exists. Otherwise, ask directly in chat and stop.
- Ask **2-3 questions per round**, then wait for answers.
- Treat PRODUCT.md and DESIGN.md as anchors; they reduce repeated questions but do **not** replace shape for craft. Shape is task-specific.
- Round 1 should clarify purpose, audience/context, and success or emotional outcome.
- Round 2 should clarify content/data/states and scope/fidelity.
- Round 3 should clarify visual direction, constraints, and anti-goals when still unresolved.
- One round is the default. Add a second only if the first answers leave material gaps. Don't run a second round just to feel thorough.
- Round 1 should clarify purpose, audience/context, content/scope, and (for brand) visual direction.
- Round 2, when needed, fills in whatever's still genuinely missing.
**Assert-then-confirm, not menu-with-escape.** When PRODUCT.md and the user's prompt make one option obvious, name it and ask the user to confirm or override. Don't enumerate "Restrained / Committed / Or something else?" as a real choice; "This reads as Restrained, confirm?" beats a four-option menu when the answer is already clear.
### Purpose & Context
- What is this feature for? What problem does it solve?
@@ -36,6 +38,7 @@ Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.
- What are the realistic ranges? (Minimum, typical, maximum, e.g., 0 items, 5 items, 500 items)
- What are the edge cases? (Empty state, error state, first-time use, power user)
- Is any content dynamic? What changes and how often?
- What visual assets are real content here? Note required images, product shots, illustrations, maps, textures, diagrams, generated objects, or existing project assets.
### Design Direction
@@ -72,9 +75,9 @@ After the discovery interview, generate a small set of visual direction probes *
- The work is **net-new** or directionally ambiguous enough that visual exploration will clarify the brief.
- The requested fidelity is **mid-fi, high-fi, or production-ready**. Skip for sketch-only planning.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The current harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool, or similar). Don't ask the user to install APIs or tooling.
When those conditions are met, this step is mandatory for Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
When those conditions are met, this step is mandatory. If image generation isn't natively available, skip silently and proceed; don't announce the skip.
Use probes to explore visual lanes, not to replace the brief.
@@ -104,11 +107,20 @@ The probes should differ in primary visual direction (hierarchy, topology, densi
- Do **not** treat generated imagery as final UX specification, final copy, or final accessibility behavior.
- Do **not** use this step for minor refinements of existing work. It's for shaping a new surface or clarifying a big directional choice.
If image generation is unavailable, or the task doesn't benefit from it, skip this phase only with a one-line reason and proceed directly to the design brief.
If image generation isn't natively available, skip this phase silently and proceed.
## Phase 2: Design Brief
After the interview and any required probes, synthesize everything into a structured design brief. Present it to the user for explicit confirmation before considering this command complete. Stop after asking for confirmation; do not proceed to craft or implementation in the same response unless the user has already approved the brief.
After the interview and any required probes, present a brief and **end your response**. The user must confirm before any implementation runs. Do not present a brief and then continue to code in the same response, even if the brief feels obvious to you. The user's confirmation is the gate.
**Choose the brief shape based on how clear the answers are:**
- **Compact form (3-5 bullets)** when discovery was crisp and the original prompt + PRODUCT.md already pinned scope, content, and direction. State what you're building, the visual lane, and end with one or two specific questions or a clear "confirm or override?" prompt. This is the default for typical craft requests with a clear prompt.
- **Full structured form (sections below)** when the task is genuinely ambiguous, multi-screen, or when the user asked for shape as a standalone step. Use this when the discipline of structure earns its weight.
Don't pad a clear brief into a long one to look thorough. A 70-line brief restating answers the user just gave is noise, not rigor. Equally, don't skip the confirmation pause to look efficient: the pause is the point.
If the user already said "approved" or "go" during discovery for the *exact direction you'd present*, that counts as confirmation; you may proceed without asking again. But if your brief adds anything the user hasn't seen and approved, you must stop and confirm.
### Brief Structure
@@ -136,16 +148,18 @@ List every state the feature needs: default, empty, loading, error, success, edg
How users interact with this feature. What happens on click, hover, scroll? What feedback do they get? What's the flow from entry to completion?
**8. Content Requirements**
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges.
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges. For image-led surfaces, also list the required image/media roles and their likely source (project asset, generated raster, semantic SVG/CSS, canvas/WebGL, icon library, or accepted omission).
**9. Recommended References**
Based on the brief, list which impeccable reference files would be most valuable during implementation (e.g., spatial-design.md for complex layouts, motion-design.md for animated features, interaction-design.md for form-heavy features).
**10. Open Questions**
Anything unresolved that the implementer should resolve during build.
Anything genuinely unresolved. Don't list "open questions" you've already recommended a default for; assert the default and move on. If you'd write `Recommend: X` next to a question, just decide X.
---
ask the user directly to clarify what you cannot infer. Ask for explicit confirmation of the brief before finishing. If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the brief is confirmed.
ask the user directly to clarify what you cannot infer.
If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the user confirms direction (or the user already gave a clear go during discovery, which counts).
Once confirmed, the brief is complete. The user can now hand it to /impeccable, or use it to guide any other implementation approach. (If the user wants the full discovery-then-build flow in one step, they should use /impeccable craft instead, which runs this command internally.)
+6 -19
View File
@@ -6,28 +6,15 @@ version: 3.0.7
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
## Setup (non-optional)
## Setup
Before any design work or file edits, pass these gates. Skipping them produces generic output that ignores the project.
Before any design work or file edits:
| Gate | Required check | If fail |
|---|---|---|
| Context | The PRODUCT.md / DESIGN.md loader result is known from `node .gemini/skills/impeccable/scripts/load-context.mjs`. | Run the loader before continuing. |
| Product | PRODUCT.md exists and is not empty or placeholder (`[TODO]` markers, <200 chars). | Run `/impeccable teach`, refresh context, then resume. Never synthesize PRODUCT.md from the user's original prompt alone. |
| Command | The matching command reference is loaded when a sub-command is used. | Load the reference before continuing. |
| Craft | `/impeccable craft` has a user-confirmed shape brief for this task. `teach` / PRODUCT.md never counts as shape. | Run `/impeccable shape` and wait for explicit brief confirmation. |
| Image | Required visual probes / mocks are generated or skipped with a reason. | Resolve the image-generation gate in `shape.md` or `craft.md` before code. |
| Mutation | All active gates above pass. | Do not edit project files yet. |
1. Load context (PRODUCT.md / DESIGN.md) via the loader script.
2. Identify the register and load the matching register reference (brand.md or product.md).
3. **If the user invoked a sub-command (e.g. `craft`, `shape`, `audit`), load its reference file too.** This is non-negotiable: `craft` without `craft.md` loaded means you'll skip the shape-and-confirm step the user expects.
Codex-style agents must state this before editing files:
```text
IMPECCABLE_PREFLIGHT: context=pass product=pass command_reference=pass shape=pass|not_required image_gate=pass|skipped:<reason> mutation=open
```
For `/impeccable craft`, `shape=pass` is only valid after a separate user response approving the shape design brief, or when the user provided an already-confirmed brief in the request. Do not mark `shape=pass` after writing PRODUCT.md, summarizing assumptions, or drafting an unconfirmed brief yourself.
Other harnesses should follow the same checklist when they can expose this state.
Skipping these produces generic output that ignores the project.
### 1. Context gathering
+7 -3
View File
@@ -12,6 +12,8 @@ Brand isn't a neutral register. AI-generated landing pages have flooded the inte
**The second slop test: aesthetic lane.** Before committing to moves, name the reference. A Klim-style specimen page is one lane; Stripe-minimal is another; Liquid-Death-acid-maximalism is another. Don't drift into editorial-magazine aesthetics on a brief that isn't editorial. A hiking brand with Cormorant italic drop caps has the wrong register within the register.
Then the inverse test: in one sentence, describe what you're about to build the way a competitor would describe theirs. If that sentence fits the modal landing page in the category, restart.
## Typography
### Font selection procedure
@@ -66,6 +68,7 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
- Palette IS voice. A calm brand and a restless brand should not share palette mechanics.
- When the strategy is Committed or Drenched, color carries the brand. Don't hedge with neutrals around the edges. Commit.
- Don't converge across projects. If the last brand surface was restrained-on-cream, this one is not.
- When a cultural-symbol palette is the obvious pull, reach past it. Let the cultural reading come from typography, imagery, and copy, not the palette.
## Layout
@@ -79,14 +82,14 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
Brand surfaces lean on imagery. A restaurant, hotel, magazine, or product landing page without any imagery reads as incomplete, not as restrained. A solid-color rectangle where a hero image should go is worse than a representative stock photo.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse. If the approved comp or brief is image-led, ship real project assets, generated raster assets, or a credible canvas/SVG/WebGL scene. Do not replace photographic, architectural, product, or place imagery with generic CSS panels, decorative diagrams, cards, bullets, or copy.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. Pick real Unsplash photo IDs you're confident exist (`photo-1559339352-11d035aa65de`, `photo-1590490360182-c33d57733427`, etc.); if unsure, pick fewer photos but don't substitute colored `<div>` placeholders.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. **Verify the URLs before referencing them.** If you have an image-search MCP, web-fetch tool, or browser access, use it to find real photo IDs and confirm they resolve. Guessed IDs (even ones that look real) often 404 and ship as broken-image placeholders. Without a verification path, pick fewer photos you're confident exist over more that you guessed; never substitute colored `<div>` placeholders.
- **Search for the brand's physical object**, not the generic category: "handmade pasta on a scratched wooden table" beats "Italian food"; "cypress trees above a limestone hotel facade at dusk" beats "luxury hotel".
- **One decisive photo beats five mediocre ones.** Hero imagery should commit to a mood; padding with more stock doesn't rescue an indecisive one.
- **Alt text is part of the voice.** "Coastal fettuccine, hand-cut, served on the terrace" beats "pasta dish".
Tech / dev-tool brands are the exception where zero imagery can be correct; a developer landing page often carries its voice through typography, code samples, diagrams. Know which kind of brand you're working on.
"Imagery" here is broader than stock photography: product screenshots, custom data visualizations, generated SVG, and canvas/WebGL scenes are all imagery. Text-only pages where typography alone carries the entire visual weight are the failure mode.
## Motion
@@ -102,6 +105,7 @@ Tech / dev-tool brands are the exception where zero imagery can be correct; a de
- Timid palettes and average layouts. Safe = invisible.
- Zero imagery on a brief that implies imagery (restaurant, hotel, food, travel, fashion, photography, hobbyist). Colored blocks where a hero photo belongs.
- Defaulting to editorial-magazine aesthetics (display serif + italic + drop caps + broadsheet grid) on briefs that aren't magazine-shaped. Editorial is ONE aesthetic lane, not the default brand aesthetic.
- Repeated tiny uppercase tracked labels above every section heading. A single strong kicker can be voice; repeating it as section grammar is AI scaffolding unless it's a deliberate, named brand system.
## Brand permissions
+73 -111
View File
@@ -1,43 +1,41 @@
# Craft Flow
Build a feature with impeccable UX and UI quality through a structured process: shape the design, land the visual direction, build real production code, then inspect and improve in-browser until the result meets a high-end studio bar.
Build a feature with impeccable UX and UI quality: shape the design, land the visual direction, build real production code, inspect and improve in-browser until it meets a high-end studio bar.
## Build Gate
Before writing code, you need: PRODUCT.md loaded, register identified and the matching reference loaded, and a confirmed design direction for this task (either from `shape` or supplied by the user). PRODUCT.md is project context, not a task-specific brief.
Craft cannot build until all of these are true:
Treat any approved visual direction (generated mock or stated reference) as a concrete contract for composition, hierarchy, density, atmosphere, signature motifs, and distinctive visual moves. Don't let mocks replace structure, copy, accessibility, or state design. But if the live result lacks the approved direction's major ingredients, the implementation is wrong.
1. PRODUCT context is valid and current.
2. The shape design brief is explicitly confirmed by the user for this task, unless the user already provided a confirmed brief.
3. Implementation references from the brief are loaded.
4. The shape visual probe decision is recorded: generated, skipped with reason, or already resolved.
5. The north-star mock decision is recorded: generated, skipped with reason, or not applicable.
## Step 0: Project Foundation
PRODUCT.md and `teach` answers do **not** satisfy the shape gate. They are project context only. A compact self-authored brief does not satisfy the shape gate either. `shape=pass` requires a separate user response approving the shape brief or an already-confirmed brief supplied by the user.
Before shape, before code: figure out what kind of project you're working in.
Invalid image-skip reasons include: "the final implementation will be semantic HTML/CSS/SVG", "the diagram should stay editable", "a raster mock would not be used directly", or "the product is fictional." Generated probes and mocks are direction artifacts; they are not implementation assets.
Look at the working directory. Run `ls`. Check for:
## Craft Contract
- An existing framework: `astro.config.mjs/ts`, `next.config.js/ts`, `nuxt.config.ts`, `svelte.config.js`, `vite.config.js/ts`, `package.json` with framework deps, `Cargo.toml` + Leptos/Yew, `Gemfile` + Rails. **If found, use it.** Do not start a parallel build, do not introduce a second framework, do not write to `dist/` or `build/` directly. Whatever pipeline the project has, respect it.
- An existing component library or design system: `src/components/`, `app/components/`, a `tokens.css` / `theme.ts`, an `astro.config` `integrations`. Read what's there before adding to it.
- An existing icon set: `lucide-react`, `@phosphor-icons/react`, `@iconify/*`, hand-rolled SVG sprites in `assets/icons/`. **Use what's already in the project**; don't introduce a second set.
Craft is not a first pass. It is a loop with these required artifacts:
If the directory is empty (greenfield), don't pick a framework silently. Ask the user via the AskUserQuestion tool, with sensible defaults framed by the brief:
1. Confirmed design brief from `shape`.
2. Approved visual direction, from generated probes / mocks when image generation is available.
3. Mock fidelity inventory: the visible ingredients from the approved direction that must survive into code.
4. Semantic, functional implementation using the project's real stack and conventions.
5. Browser evidence across relevant viewports.
6. At least one critique-and-fix pass after the first browser inspection, unless the first pass has no material defects.
```text
What should this be built on?
- Astro (default for content-led brand sites, landing pages, marketing surfaces)
- SvelteKit / Next.js / Nuxt (when the brief implies an app surface or significant interactivity)
- Single index.html (one-shot demo, prototype, or a deliberately framework-free experiment)
```
Do not let generated mockups replace interface structure, copy, accessibility, responsive behavior, or state design. But do treat the approved mock as a concrete visual contract for composition, hierarchy, density, atmosphere, signature motifs, image needs, and distinctive visual moves. "North star" means "preserve the important visible ingredients in semantic code," not "use it as loose mood."
Default: Astro for brand briefs, the project's existing framework for product briefs. Ask once; don't re-ask mid-task.
## Step 1: Shape the Design
Run /impeccable shape, passing along whatever feature description the user provided.
Run /impeccable shape, passing along whatever feature description the user provided. Shape is **required** for craft; it is what produces a confirmed direction.
Wait for the design brief to be fully confirmed by the user before proceeding. The brief is your blueprint, and every implementation decision should trace back to it.
Present the shape output and stop. Wait for the user to confirm, override, or course-correct before writing code.
If this craft run resumed after `teach` created PRODUCT.md, run shape now. Do not treat the teach interview, PRODUCT.md, or a summary of project context as a substitute for shape. Shape is task-specific and must cover scope, content/states, visual direction, constraints, anti-goals, probes when applicable, and explicit brief confirmation.
If the user already supplied a confirmed brief or ran shape separately, use it and skip this step.
If the user has already run /impeccable shape and has a confirmed design brief, skip this step and use the existing brief.
When the original prompt + PRODUCT.md already answer scope, content, and visual direction with no real ambiguity, the shape output can be **compact** (3-5 bullets stating what you're building and the visual lane, ending with one or two specific questions or "confirm or override"). The full 10-section structured brief is reserved for genuinely ambiguous, multi-screen, or stakeholder-heavy tasks. Don't pad a clear brief into a long one to look thorough; equally, don't skip the pause to look efficient.
## Step 2: Load References
@@ -55,79 +53,60 @@ Then add references based on the brief's needs:
## Step 3: Land the Visual Direction (Capability-Gated)
Before implementation, generate high-fidelity visual comps when all of these are true:
Generate high-fidelity visual comps before implementation when all three are true:
- The work is **net-new** or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is **mid-fi, high-fi, or production-ready**.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The work is net-new or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is mid-fi, high-fi, or production-ready.
- The harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool). Don't ask the user to set up external APIs.
When those conditions are met, this step is mandatory for **both brand and product work** in Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
Do not skip this step because the eventual UI should be semantic, editable, code-native, responsive, or accessible. Those are implementation requirements, not reasons to avoid visual exploration.
### Purpose
Use the mock step to find a stronger visual lane than code-first generation would reliably discover on its own. The brief remains authoritative on user, purpose, content, constraints, states, and anti-goals. The mock clarifies composition, hierarchy, density, typography, and visual tone.
When met, this step is mandatory for both brand and product work. If image generation isn't available, skip silently. "The eventual UI is semantic/code-native/accessible" is not a reason to skip; those are implementation requirements, not exploration ones.
### What to generate
Generate **1 to 3** high-fidelity north-star comps based on the confirmed brief. If shape already produced direction probes, use those results as input and generate a more resolved mock from the winning lane, not another unrelated exploration.
Generate **1 to 3** high-fidelity north-star comps from the confirmed brief. If shape already produced direction probes, resolve the winning lane further, not an unrelated exploration. Comps must differ in primary visual direction, not just color.
- For brand work, push visual identity, composition, and mood aggressively.
- For product work, still push hierarchy, topology, density, and tone, but keep the comps grounded in realistic product structure and states.
- For landing pages and long-form brand surfaces, show enough of the next section or second fold to establish the system beyond the hero.
The comps must be genuinely different in primary visual direction, not just color variants.
- Brand work: push visual identity, composition, and mood aggressively.
- Product work: push hierarchy, topology, density, tone, grounded in realistic product structure.
- Landing pages and long-form brand surfaces: show enough of the second fold to establish the system beyond the hero.
### Approval loop
Show the comps and ask what should carry forward. If the user asks for changes or the best direction is still weak, generate a focused revision before implementation. Continue until one direction is approved, or until the user explicitly delegates the choice.
Show the comps and ask what carries forward. Iterate until one direction is approved or the user delegates. If the user delegates, pick the strongest direction and explain it from the brief, not personal taste.
If the user delegates, pick the strongest direction and explain the decision using the brief, not personal taste.
Before moving to implementation, summarize:
- What to carry into code
- What **not** to literalize from the mock
This summary is required before Step 4. It is the handoff between visual exploration and semantic implementation.
Before Step 4, summarize what to carry into code and what **not** to literalize from the mock. This is the handoff between visual exploration and semantic implementation.
### Mock fidelity inventory
Before building, inventory the approved mock's major visible ingredients:
Inventory the approved mock's major visible ingredients:
- Hero silhouette and dominant composition.
- Signature motifs: planets, devices, portraits, charts, route lines, insets, badges, or other memorable objects.
- Nav and primary CTA treatment.
- Section sequence visible in the mock, especially the second fold.
- Image-native content the concept depends on.
- Typography, density, color/material treatment, and motion cues.
- Hero silhouette and dominant composition
- Signature motifs (planets, devices, portraits, charts, route lines, insets, badges, etc.)
- Nav and primary CTA treatment
- Section sequence, especially the second fold
- Image-native content the concept depends on
- Typography, density, color/material treatment, motion cues
For each ingredient, decide how it will be implemented: semantic HTML/CSS/SVG, generated asset, sourced project asset, icon library, canvas/WebGL, or an explicitly accepted omission. Do not substitute a different hero composition or new visual driver after approval unless the user approves the change.
For each, decide implementation: semantic HTML/CSS/SVG, generated asset, sourced asset, icon library, canvas/WebGL, or accepted omission. Don't substitute a different hero composition or visual driver post-approval without user sign-off.
Treat the mock as a **north star**, not a screenshot to trace. Do **not** rasterize core UI text or let the mock override the confirmed brief. But if the live result lacks the mock's major visible ingredients, the implementation is wrong.
If a photographic, architectural, product, or place-led mock becomes generic CSS scenery / decorative diagrams / bullets / copy, stop and fix it. That's a broken implementation, not a harmless interpretation.
Treat the mock as a north star, not a screenshot to trace. Don't rasterize core UI text. But if the live result lacks the mock's major ingredients, the implementation is wrong.
## Step 4: Asset Extraction (Need-Gated)
If the chosen direction includes image-native visual ingredients that would materially improve the implementation, generate them as separate assets before building.
If the approved direction needs raster assets, create them before building. Do not replace required imagery with generic cards, bullets, emoji, fake metrics, decorative CSS panels, or filler copy.
Good candidates:
Use the native asset producer (`impeccable_asset_producer` in Codex, `impeccable-asset-producer` in Claude Code) to create clean assets from the hi-fi mock and crops. If you do not have explicit permission to use agents, stop and ask:
- stickers
- badges
- seals
- tickets
- graphic labels
- textures
- abstract objects
- decorative marks
- non-semantic scene elements
```text
Asset production will work better as a scoped subagent job. Should I spawn the Impeccable asset producer subagent for this step?
```
For travel, editorial, portfolio, venue, product showcase, entertainment, education, or any other image-led brand surface, visual assets are usually core content, not decoration. Do not ship abstract CSS panels where the approved mock or subject matter calls for real imagery, generated plates, illustrations, maps, product/object renders, or destination scenes.
Do not skip asset production or silently do it inline. Inline asset production is allowed only if the user declines subagents, the harness cannot spawn the authorized agent, or the user explicitly asks for single-thread mode.
Do **not** export assets for core UI text, navigation, body copy, or any structure that should stay semantic and editable in code.
Pass the approved mock, crop/contact-sheet paths, output directory, dimensions/formats, transparency needs, constraints, and avoid list to the asset producer. Attach image generation capability to the spawned agent when the harness supports it; do not load image-generation reference material into the parent thread first.
Usually **1 to 5** extracted assets is enough. If the design can be built cleanly in HTML/CSS/SVG, prefer that over raster assets. If the mock contains major visual content that cannot be built credibly in code, asset extraction is not optional.
Prefer HTML/CSS/SVG/canvas when they can credibly reproduce an ingredient; use real/generated/stock imagery when the mock or subject matter calls for actual visual content.
## Step 5: Build to Production Quality
@@ -135,50 +114,35 @@ Implement the feature following the design brief. Build in passes so structure,
### Production bar
- Use real or realistic content. Remove placeholder copy, placeholder images, dead links, fake controls, and unused scaffold before presenting.
- Preserve the approved mock's major ingredients. Missing hero objects, missing world/product imagery, different section structure, downgraded CTA/nav treatment, or generic replacements for distinctive motifs are blocking defects unless the user accepted the change.
- Build semantically first: real headings, landmarks, labels, form associations, button/link semantics, accessible names, and state announcements where needed.
- Calibrate spacing, alignment, grid placement, and vertical rhythm deliberately. Do not accept default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- Make typography intentional: chosen font loading strategy, clear hierarchy, readable measure, stable line breaks, tuned wrapping, and no overflow at mobile or large desktop sizes.
- Design realistic state coverage: default, hover where supported, focus-visible, active, disabled, loading, error, success, empty, overflow, long text, short text, and first-run states where relevant.
- Make interaction quality feel finished: keyboard paths, touch targets, feedback timing, scroll behavior, transitions between states, and no hover-only functionality.
- Use icons from the project's established icon set when available. If no set exists, choose a coherent library or use accessible text controls; do not mix unrelated icon styles.
- Optimize imagery and media: correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset` / `picture` for raster assets, and no project-referenced asset left outside the workspace.
- Make motion feel premium: use atmospheric blur, filter, mask, shadow, or reveal effects when they improve the experience; avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- Preserve maintainability: reusable local patterns, clear component boundaries, project conventions, no rasterized UI text, and no hard-coded one-off hacks when a better local pattern exists.
- Fit the technical context: production build passes, no obvious console errors, no avoidable layout shift, no needless dependency, and no broken asset path.
- If you discover a design question that materially changes the brief or approved direction, stop and ask rather than guessing.
- **Real content.** No placeholder copy, placeholder images, dead links, fake controls, or unused scaffold at presentation time.
- **Preserve the approved mock's major ingredients.** Missing hero objects, world/product imagery, section structure, CTA/nav treatment, or distinctive motifs are blocking defects unless the user accepted the change.
- **Semantic first.** Real headings, landmarks, labels, form associations, button/link semantics, accessible names, state announcements where needed.
- **Deliberate spacing and alignment.** No default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- **Intentional typography.** Chosen loading strategy, clear hierarchy, readable measure, stable line breaks, no overflow at any width.
- **Realistic state coverage.** Default, hover, focus-visible, active, disabled, loading, error, success, empty, overflow, long/short text, first-run.
- **Finished interaction quality.** Keyboard paths, touch targets, feedback timing, scroll behavior, state transitions, no hover-only functionality.
- **Coherent icon set.** Use the project's established set; otherwise pick one library or use accessible text. Don't mix.
- **Respect the build pipeline.** Edit source files and run the project's build (`npm run build` or equivalent). Don't write to `build/` / `dist/` / `.next/` with `cat`, heredoc, or Bash redirects; that skips asset hashing, image optimization, code splitting, and CSS extraction, and produces output the dev server won't serve.
- **Verify image URLs before referencing them.** Use image-search MCP or web-fetch when available; guessed photo IDs ship as broken-image placeholders. Without verification, prefer fewer images you're confident about.
- **Optimized imagery and media.** Correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset`/`picture` for raster, no project-referenced asset left outside the workspace.
- **Premium motion.** Use atmospheric blur, filter, mask, shadow, reveal when they improve the experience. Avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- **Maintainable.** Reusable local patterns, clear component boundaries, project conventions. No rasterized UI text or one-off hacks when a local pattern exists.
- **Technically clean.** Production build passes, no console errors, no avoidable layout shift, no needless dependencies, no broken asset paths.
- **Ask when uncertain.** If a discovery materially changes the brief or approved direction, stop and ask. Don't guess.
## Step 6: Browser-Based Iteration
## Step 6: Iterate Visually
**This step is critical.** Do not stop after the first implementation pass.
Look at what you built like a designer would. Your eyes are whatever the harness gives you: a connected browser, a screenshotting tool, Playwright, or asking the user. Use them for responsive testing (mobile, tablet, desktop minimum) and general visual validation.
Open the result in a browser. In Codex, use browser-use or equivalent browser automation when available; otherwise use Playwright or ask the user for screenshots. Inspect screenshots, not just DOM or terminal output.
If your tool returns a file path, read the PNG back into the conversation. A screenshot you didn't read doesn't count.
### Required viewport pass
For long-form brand surfaces, inspect major sections individually. Thumbnails hide spacing, clipping, and cascade defects.
Check the experience at the viewports that matter for the brief. Default minimum:
After the first pass, write an honest critique against the brief, the approved mock's major ingredients (hero silhouette, motifs, imagery, nav/CTA, density), and impeccable's DON'Ts. Patch material defects and re-inspect. **Don't invent defects to demonstrate iteration.** A confident "first pass clean, shipping" beats a fake fix.
- Mobile narrow
- Tablet or small laptop
- Desktop wide
Actively check: responsive behavior (composes, not shrinks), every state (empty / error / loading / edge), craft details (spacing, alignment, hierarchy, contrast, motion timing, focus), performance basics. The exit bar: defensible in a high-end studio review.
For each viewport, capture or inspect the rendered state and look for visual defects: overlap, clipping, weak hierarchy, off-grid alignment, awkward whitespace, cramped controls, unreadable type, broken imagery, hover-only functionality, layout shift, and text overflow.
### Critique and fix loop
After the first browser pass, write a short critique for yourself and patch the implementation. Repeat browser inspection after fixes. Continue until no material issues remain against this checklist:
1. **Does it match the brief?** Compare the live result against every section of the design brief. Fix discrepancies.
2. **Does it match the approved mock?** Compare screenshots against the mock fidelity inventory: hero silhouette, major motifs, imagery, nav/CTA, section sequence, density, color/materials, and second-fold substance. Missing major ingredients are P0 defects.
3. **Does it pass the AI slop test?** If someone saw this and said "AI made this," would they believe it immediately? If yes, it needs more design intention.
4. **Check against impeccable's DON'T guidelines.** Fix any anti-pattern violations.
5. **Check every state.** Navigate through empty, error, loading, and edge case states. Each one should feel intentional, not like an afterthought.
6. **Check responsive behavior.** The design should adapt compositionally, not merely shrink.
7. **Check craft details.** Spacing consistency, optical alignment, type hierarchy, color contrast, image quality, icon coherence, interactive feedback, motion timing, and focus treatment.
8. **Check performance basics.** No obviously oversized images, avoidable layout thrash, blocking animations, or heavy assets without a reason.
The exit bar is not "it works." It is: the rendered result looks intentional at all checked viewports, all expected states are handled, no placeholders remain unless explicitly accepted, and the implementation quality would be defensible in a high-end studio review.
Detector or QA output is defect evidence only; never proof the work is finished.
## Step 7: Present
@@ -189,5 +153,3 @@ Present the result to the user:
- Explain design decisions that connect back to the design brief and, when used, the chosen north-star mock. Include any accepted deviations from the mock; do not hide unimplemented mock ingredients.
- Note any remaining limitations or follow-up risks honestly
- Ask: "What's working? What isn't?"
Iterate based on feedback. Good design is rarely right on the first pass.
@@ -43,7 +43,7 @@ Run the bundled deterministic detector, which flags 27 specific patterns (AI slo
**CLI scan**:
```bash
npx impeccable --json [--fast] [target]
npx impeccable detect --json [--fast] [target]
```
- Pass HTML/JSX/TSX/Vue/Svelte files or directories as `[target]` (anything with markup). Do not pass CSS-only files.
@@ -2,6 +2,8 @@
Perform a meticulous final pass to catch all the small details that separate good work from great work. The difference between shipped and polished.
Detector and automated QA output are defect evidence only. A clean script result is never proof that the design is strong; gather browser evidence and inspect the real interaction path.
## Design System Discovery
Aligning the feature to the design system is **not optional**. Polish without alignment is decoration on top of drift, and it makes the next person's job harder. Discovery comes before any other polish work.
@@ -216,11 +218,12 @@ Sweat the details. Zoom in until the alignment is right and the spacing reads as
Before marking as done:
- **Use it yourself**: Actually interact with the feature
- **Test on real devices**: Not just browser DevTools
- **Ask someone else to review**: Fresh eyes catch things
- **Compare to design**: Match intended design
- **Check all states**: Don't just test happy path
- **Use it yourself**: Actually interact with the feature.
- **Test on real devices**: Not just browser DevTools.
- **Ask someone else to review**: Fresh eyes catch things.
- **Compare to design**: Match intended design.
- **Check all states**: Don't just test happy path.
- **Treat automation carefully**: Run detector or QA commands when they are available and relevant, fix their defects, but never cite a clean result as proof that the work is polished.
## Clean Up
@@ -230,4 +233,3 @@ After polishing, ensure code quality:
- **Remove orphaned code**: Delete unused styles, components, or files made obsolete by polish.
- **Consolidate tokens**: If you introduced new values, check whether they should be tokens.
- **Verify DRYness**: Look for duplication introduced during polishing and consolidate.
+25 -11
View File
@@ -16,14 +16,16 @@ This is a required interaction, not optional guidance. Ask these questions in co
### Interview cadence
Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed design inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
Discovery includes at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
- Use the harness's structured question tool when one exists. Otherwise, ask directly in chat and stop.
- Ask **2-3 questions per round**, then wait for answers.
- Treat PRODUCT.md and DESIGN.md as anchors; they reduce repeated questions but do **not** replace shape for craft. Shape is task-specific.
- Round 1 should clarify purpose, audience/context, and success or emotional outcome.
- Round 2 should clarify content/data/states and scope/fidelity.
- Round 3 should clarify visual direction, constraints, and anti-goals when still unresolved.
- One round is the default. Add a second only if the first answers leave material gaps. Don't run a second round just to feel thorough.
- Round 1 should clarify purpose, audience/context, content/scope, and (for brand) visual direction.
- Round 2, when needed, fills in whatever's still genuinely missing.
**Assert-then-confirm, not menu-with-escape.** When PRODUCT.md and the user's prompt make one option obvious, name it and ask the user to confirm or override. Don't enumerate "Restrained / Committed / Or something else?" as a real choice; "This reads as Restrained, confirm?" beats a four-option menu when the answer is already clear.
### Purpose & Context
- What is this feature for? What problem does it solve?
@@ -36,6 +38,7 @@ Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.
- What are the realistic ranges? (Minimum, typical, maximum, e.g., 0 items, 5 items, 500 items)
- What are the edge cases? (Empty state, error state, first-time use, power user)
- Is any content dynamic? What changes and how often?
- What visual assets are real content here? Note required images, product shots, illustrations, maps, textures, diagrams, generated objects, or existing project assets.
### Design Direction
@@ -72,9 +75,9 @@ After the discovery interview, generate a small set of visual direction probes *
- The work is **net-new** or directionally ambiguous enough that visual exploration will clarify the brief.
- The requested fidelity is **mid-fi, high-fi, or production-ready**. Skip for sketch-only planning.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The current harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool, or similar). Don't ask the user to install APIs or tooling.
When those conditions are met, this step is mandatory for Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
When those conditions are met, this step is mandatory. If image generation isn't natively available, skip silently and proceed; don't announce the skip.
Use probes to explore visual lanes, not to replace the brief.
@@ -104,11 +107,20 @@ The probes should differ in primary visual direction (hierarchy, topology, densi
- Do **not** treat generated imagery as final UX specification, final copy, or final accessibility behavior.
- Do **not** use this step for minor refinements of existing work. It's for shaping a new surface or clarifying a big directional choice.
If image generation is unavailable, or the task doesn't benefit from it, skip this phase only with a one-line reason and proceed directly to the design brief.
If image generation isn't natively available, skip this phase silently and proceed.
## Phase 2: Design Brief
After the interview and any required probes, synthesize everything into a structured design brief. Present it to the user for explicit confirmation before considering this command complete. Stop after asking for confirmation; do not proceed to craft or implementation in the same response unless the user has already approved the brief.
After the interview and any required probes, present a brief and **end your response**. The user must confirm before any implementation runs. Do not present a brief and then continue to code in the same response, even if the brief feels obvious to you. The user's confirmation is the gate.
**Choose the brief shape based on how clear the answers are:**
- **Compact form (3-5 bullets)** when discovery was crisp and the original prompt + PRODUCT.md already pinned scope, content, and direction. State what you're building, the visual lane, and end with one or two specific questions or a clear "confirm or override?" prompt. This is the default for typical craft requests with a clear prompt.
- **Full structured form (sections below)** when the task is genuinely ambiguous, multi-screen, or when the user asked for shape as a standalone step. Use this when the discipline of structure earns its weight.
Don't pad a clear brief into a long one to look thorough. A 70-line brief restating answers the user just gave is noise, not rigor. Equally, don't skip the confirmation pause to look efficient: the pause is the point.
If the user already said "approved" or "go" during discovery for the *exact direction you'd present*, that counts as confirmation; you may proceed without asking again. But if your brief adds anything the user hasn't seen and approved, you must stop and confirm.
### Brief Structure
@@ -136,16 +148,18 @@ List every state the feature needs: default, empty, loading, error, success, edg
How users interact with this feature. What happens on click, hover, scroll? What feedback do they get? What's the flow from entry to completion?
**8. Content Requirements**
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges.
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges. For image-led surfaces, also list the required image/media roles and their likely source (project asset, generated raster, semantic SVG/CSS, canvas/WebGL, icon library, or accepted omission).
**9. Recommended References**
Based on the brief, list which impeccable reference files would be most valuable during implementation (e.g., spatial-design.md for complex layouts, motion-design.md for animated features, interaction-design.md for form-heavy features).
**10. Open Questions**
Anything unresolved that the implementer should resolve during build.
Anything genuinely unresolved. Don't list "open questions" you've already recommended a default for; assert the default and move on. If you'd write `Recommend: X` next to a question, just decide X.
---
ask the user directly to clarify what you cannot infer. Ask for explicit confirmation of the brief before finishing. If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the brief is confirmed.
ask the user directly to clarify what you cannot infer.
If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the user confirms direction (or the user already gave a clear go during discovery, which counts).
Once confirmed, the brief is complete. The user can now hand it to /impeccable, or use it to guide any other implementation approach. (If the user wants the full discovery-then-build flow in one step, they should use /impeccable craft instead, which runs this command internally.)
+6 -19
View File
@@ -9,28 +9,15 @@ license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md f
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
## Setup (non-optional)
## Setup
Before any design work or file edits, pass these gates. Skipping them produces generic output that ignores the project.
Before any design work or file edits:
| Gate | Required check | If fail |
|---|---|---|
| Context | The PRODUCT.md / DESIGN.md loader result is known from `node .github/skills/impeccable/scripts/load-context.mjs`. | Run the loader before continuing. |
| Product | PRODUCT.md exists and is not empty or placeholder (`[TODO]` markers, <200 chars). | Run `/impeccable teach`, refresh context, then resume. Never synthesize PRODUCT.md from the user's original prompt alone. |
| Command | The matching command reference is loaded when a sub-command is used. | Load the reference before continuing. |
| Craft | `/impeccable craft` has a user-confirmed shape brief for this task. `teach` / PRODUCT.md never counts as shape. | Run `/impeccable shape` and wait for explicit brief confirmation. |
| Image | Required visual probes / mocks are generated or skipped with a reason. | Resolve the image-generation gate in `shape.md` or `craft.md` before code. |
| Mutation | All active gates above pass. | Do not edit project files yet. |
1. Load context (PRODUCT.md / DESIGN.md) via the loader script.
2. Identify the register and load the matching register reference (brand.md or product.md).
3. **If the user invoked a sub-command (e.g. `craft`, `shape`, `audit`), load its reference file too.** This is non-negotiable: `craft` without `craft.md` loaded means you'll skip the shape-and-confirm step the user expects.
Codex-style agents must state this before editing files:
```text
IMPECCABLE_PREFLIGHT: context=pass product=pass command_reference=pass shape=pass|not_required image_gate=pass|skipped:<reason> mutation=open
```
For `/impeccable craft`, `shape=pass` is only valid after a separate user response approving the shape design brief, or when the user provided an already-confirmed brief in the request. Do not mark `shape=pass` after writing PRODUCT.md, summarizing assumptions, or drafting an unconfirmed brief yourself.
Other harnesses should follow the same checklist when they can expose this state.
Skipping these produces generic output that ignores the project.
### 1. Context gathering
+7 -3
View File
@@ -12,6 +12,8 @@ Brand isn't a neutral register. AI-generated landing pages have flooded the inte
**The second slop test: aesthetic lane.** Before committing to moves, name the reference. A Klim-style specimen page is one lane; Stripe-minimal is another; Liquid-Death-acid-maximalism is another. Don't drift into editorial-magazine aesthetics on a brief that isn't editorial. A hiking brand with Cormorant italic drop caps has the wrong register within the register.
Then the inverse test: in one sentence, describe what you're about to build the way a competitor would describe theirs. If that sentence fits the modal landing page in the category, restart.
## Typography
### Font selection procedure
@@ -66,6 +68,7 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
- Palette IS voice. A calm brand and a restless brand should not share palette mechanics.
- When the strategy is Committed or Drenched, color carries the brand. Don't hedge with neutrals around the edges. Commit.
- Don't converge across projects. If the last brand surface was restrained-on-cream, this one is not.
- When a cultural-symbol palette is the obvious pull, reach past it. Let the cultural reading come from typography, imagery, and copy, not the palette.
## Layout
@@ -79,14 +82,14 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
Brand surfaces lean on imagery. A restaurant, hotel, magazine, or product landing page without any imagery reads as incomplete, not as restrained. A solid-color rectangle where a hero image should go is worse than a representative stock photo.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse. If the approved comp or brief is image-led, ship real project assets, generated raster assets, or a credible canvas/SVG/WebGL scene. Do not replace photographic, architectural, product, or place imagery with generic CSS panels, decorative diagrams, cards, bullets, or copy.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. Pick real Unsplash photo IDs you're confident exist (`photo-1559339352-11d035aa65de`, `photo-1590490360182-c33d57733427`, etc.); if unsure, pick fewer photos but don't substitute colored `<div>` placeholders.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. **Verify the URLs before referencing them.** If you have an image-search MCP, web-fetch tool, or browser access, use it to find real photo IDs and confirm they resolve. Guessed IDs (even ones that look real) often 404 and ship as broken-image placeholders. Without a verification path, pick fewer photos you're confident exist over more that you guessed; never substitute colored `<div>` placeholders.
- **Search for the brand's physical object**, not the generic category: "handmade pasta on a scratched wooden table" beats "Italian food"; "cypress trees above a limestone hotel facade at dusk" beats "luxury hotel".
- **One decisive photo beats five mediocre ones.** Hero imagery should commit to a mood; padding with more stock doesn't rescue an indecisive one.
- **Alt text is part of the voice.** "Coastal fettuccine, hand-cut, served on the terrace" beats "pasta dish".
Tech / dev-tool brands are the exception where zero imagery can be correct; a developer landing page often carries its voice through typography, code samples, diagrams. Know which kind of brand you're working on.
"Imagery" here is broader than stock photography: product screenshots, custom data visualizations, generated SVG, and canvas/WebGL scenes are all imagery. Text-only pages where typography alone carries the entire visual weight are the failure mode.
## Motion
@@ -102,6 +105,7 @@ Tech / dev-tool brands are the exception where zero imagery can be correct; a de
- Timid palettes and average layouts. Safe = invisible.
- Zero imagery on a brief that implies imagery (restaurant, hotel, food, travel, fashion, photography, hobbyist). Colored blocks where a hero photo belongs.
- Defaulting to editorial-magazine aesthetics (display serif + italic + drop caps + broadsheet grid) on briefs that aren't magazine-shaped. Editorial is ONE aesthetic lane, not the default brand aesthetic.
- Repeated tiny uppercase tracked labels above every section heading. A single strong kicker can be voice; repeating it as section grammar is AI scaffolding unless it's a deliberate, named brand system.
## Brand permissions
+73 -111
View File
@@ -1,43 +1,41 @@
# Craft Flow
Build a feature with impeccable UX and UI quality through a structured process: shape the design, land the visual direction, build real production code, then inspect and improve in-browser until the result meets a high-end studio bar.
Build a feature with impeccable UX and UI quality: shape the design, land the visual direction, build real production code, inspect and improve in-browser until it meets a high-end studio bar.
## Build Gate
Before writing code, you need: PRODUCT.md loaded, register identified and the matching reference loaded, and a confirmed design direction for this task (either from `shape` or supplied by the user). PRODUCT.md is project context, not a task-specific brief.
Craft cannot build until all of these are true:
Treat any approved visual direction (generated mock or stated reference) as a concrete contract for composition, hierarchy, density, atmosphere, signature motifs, and distinctive visual moves. Don't let mocks replace structure, copy, accessibility, or state design. But if the live result lacks the approved direction's major ingredients, the implementation is wrong.
1. PRODUCT context is valid and current.
2. The shape design brief is explicitly confirmed by the user for this task, unless the user already provided a confirmed brief.
3. Implementation references from the brief are loaded.
4. The shape visual probe decision is recorded: generated, skipped with reason, or already resolved.
5. The north-star mock decision is recorded: generated, skipped with reason, or not applicable.
## Step 0: Project Foundation
PRODUCT.md and `teach` answers do **not** satisfy the shape gate. They are project context only. A compact self-authored brief does not satisfy the shape gate either. `shape=pass` requires a separate user response approving the shape brief or an already-confirmed brief supplied by the user.
Before shape, before code: figure out what kind of project you're working in.
Invalid image-skip reasons include: "the final implementation will be semantic HTML/CSS/SVG", "the diagram should stay editable", "a raster mock would not be used directly", or "the product is fictional." Generated probes and mocks are direction artifacts; they are not implementation assets.
Look at the working directory. Run `ls`. Check for:
## Craft Contract
- An existing framework: `astro.config.mjs/ts`, `next.config.js/ts`, `nuxt.config.ts`, `svelte.config.js`, `vite.config.js/ts`, `package.json` with framework deps, `Cargo.toml` + Leptos/Yew, `Gemfile` + Rails. **If found, use it.** Do not start a parallel build, do not introduce a second framework, do not write to `dist/` or `build/` directly. Whatever pipeline the project has, respect it.
- An existing component library or design system: `src/components/`, `app/components/`, a `tokens.css` / `theme.ts`, an `astro.config` `integrations`. Read what's there before adding to it.
- An existing icon set: `lucide-react`, `@phosphor-icons/react`, `@iconify/*`, hand-rolled SVG sprites in `assets/icons/`. **Use what's already in the project**; don't introduce a second set.
Craft is not a first pass. It is a loop with these required artifacts:
If the directory is empty (greenfield), don't pick a framework silently. Ask the user via the AskUserQuestion tool, with sensible defaults framed by the brief:
1. Confirmed design brief from `shape`.
2. Approved visual direction, from generated probes / mocks when image generation is available.
3. Mock fidelity inventory: the visible ingredients from the approved direction that must survive into code.
4. Semantic, functional implementation using the project's real stack and conventions.
5. Browser evidence across relevant viewports.
6. At least one critique-and-fix pass after the first browser inspection, unless the first pass has no material defects.
```text
What should this be built on?
- Astro (default for content-led brand sites, landing pages, marketing surfaces)
- SvelteKit / Next.js / Nuxt (when the brief implies an app surface or significant interactivity)
- Single index.html (one-shot demo, prototype, or a deliberately framework-free experiment)
```
Do not let generated mockups replace interface structure, copy, accessibility, responsive behavior, or state design. But do treat the approved mock as a concrete visual contract for composition, hierarchy, density, atmosphere, signature motifs, image needs, and distinctive visual moves. "North star" means "preserve the important visible ingredients in semantic code," not "use it as loose mood."
Default: Astro for brand briefs, the project's existing framework for product briefs. Ask once; don't re-ask mid-task.
## Step 1: Shape the Design
Run /impeccable shape, passing along whatever feature description the user provided.
Run /impeccable shape, passing along whatever feature description the user provided. Shape is **required** for craft; it is what produces a confirmed direction.
Wait for the design brief to be fully confirmed by the user before proceeding. The brief is your blueprint, and every implementation decision should trace back to it.
Present the shape output and stop. Wait for the user to confirm, override, or course-correct before writing code.
If this craft run resumed after `teach` created PRODUCT.md, run shape now. Do not treat the teach interview, PRODUCT.md, or a summary of project context as a substitute for shape. Shape is task-specific and must cover scope, content/states, visual direction, constraints, anti-goals, probes when applicable, and explicit brief confirmation.
If the user already supplied a confirmed brief or ran shape separately, use it and skip this step.
If the user has already run /impeccable shape and has a confirmed design brief, skip this step and use the existing brief.
When the original prompt + PRODUCT.md already answer scope, content, and visual direction with no real ambiguity, the shape output can be **compact** (3-5 bullets stating what you're building and the visual lane, ending with one or two specific questions or "confirm or override"). The full 10-section structured brief is reserved for genuinely ambiguous, multi-screen, or stakeholder-heavy tasks. Don't pad a clear brief into a long one to look thorough; equally, don't skip the pause to look efficient.
## Step 2: Load References
@@ -55,79 +53,60 @@ Then add references based on the brief's needs:
## Step 3: Land the Visual Direction (Capability-Gated)
Before implementation, generate high-fidelity visual comps when all of these are true:
Generate high-fidelity visual comps before implementation when all three are true:
- The work is **net-new** or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is **mid-fi, high-fi, or production-ready**.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The work is net-new or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is mid-fi, high-fi, or production-ready.
- The harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool). Don't ask the user to set up external APIs.
When those conditions are met, this step is mandatory for **both brand and product work** in Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
Do not skip this step because the eventual UI should be semantic, editable, code-native, responsive, or accessible. Those are implementation requirements, not reasons to avoid visual exploration.
### Purpose
Use the mock step to find a stronger visual lane than code-first generation would reliably discover on its own. The brief remains authoritative on user, purpose, content, constraints, states, and anti-goals. The mock clarifies composition, hierarchy, density, typography, and visual tone.
When met, this step is mandatory for both brand and product work. If image generation isn't available, skip silently. "The eventual UI is semantic/code-native/accessible" is not a reason to skip; those are implementation requirements, not exploration ones.
### What to generate
Generate **1 to 3** high-fidelity north-star comps based on the confirmed brief. If shape already produced direction probes, use those results as input and generate a more resolved mock from the winning lane, not another unrelated exploration.
Generate **1 to 3** high-fidelity north-star comps from the confirmed brief. If shape already produced direction probes, resolve the winning lane further, not an unrelated exploration. Comps must differ in primary visual direction, not just color.
- For brand work, push visual identity, composition, and mood aggressively.
- For product work, still push hierarchy, topology, density, and tone, but keep the comps grounded in realistic product structure and states.
- For landing pages and long-form brand surfaces, show enough of the next section or second fold to establish the system beyond the hero.
The comps must be genuinely different in primary visual direction, not just color variants.
- Brand work: push visual identity, composition, and mood aggressively.
- Product work: push hierarchy, topology, density, tone, grounded in realistic product structure.
- Landing pages and long-form brand surfaces: show enough of the second fold to establish the system beyond the hero.
### Approval loop
Show the comps and ask what should carry forward. If the user asks for changes or the best direction is still weak, generate a focused revision before implementation. Continue until one direction is approved, or until the user explicitly delegates the choice.
Show the comps and ask what carries forward. Iterate until one direction is approved or the user delegates. If the user delegates, pick the strongest direction and explain it from the brief, not personal taste.
If the user delegates, pick the strongest direction and explain the decision using the brief, not personal taste.
Before moving to implementation, summarize:
- What to carry into code
- What **not** to literalize from the mock
This summary is required before Step 4. It is the handoff between visual exploration and semantic implementation.
Before Step 4, summarize what to carry into code and what **not** to literalize from the mock. This is the handoff between visual exploration and semantic implementation.
### Mock fidelity inventory
Before building, inventory the approved mock's major visible ingredients:
Inventory the approved mock's major visible ingredients:
- Hero silhouette and dominant composition.
- Signature motifs: planets, devices, portraits, charts, route lines, insets, badges, or other memorable objects.
- Nav and primary CTA treatment.
- Section sequence visible in the mock, especially the second fold.
- Image-native content the concept depends on.
- Typography, density, color/material treatment, and motion cues.
- Hero silhouette and dominant composition
- Signature motifs (planets, devices, portraits, charts, route lines, insets, badges, etc.)
- Nav and primary CTA treatment
- Section sequence, especially the second fold
- Image-native content the concept depends on
- Typography, density, color/material treatment, motion cues
For each ingredient, decide how it will be implemented: semantic HTML/CSS/SVG, generated asset, sourced project asset, icon library, canvas/WebGL, or an explicitly accepted omission. Do not substitute a different hero composition or new visual driver after approval unless the user approves the change.
For each, decide implementation: semantic HTML/CSS/SVG, generated asset, sourced asset, icon library, canvas/WebGL, or accepted omission. Don't substitute a different hero composition or visual driver post-approval without user sign-off.
Treat the mock as a **north star**, not a screenshot to trace. Do **not** rasterize core UI text or let the mock override the confirmed brief. But if the live result lacks the mock's major visible ingredients, the implementation is wrong.
If a photographic, architectural, product, or place-led mock becomes generic CSS scenery / decorative diagrams / bullets / copy, stop and fix it. That's a broken implementation, not a harmless interpretation.
Treat the mock as a north star, not a screenshot to trace. Don't rasterize core UI text. But if the live result lacks the mock's major ingredients, the implementation is wrong.
## Step 4: Asset Extraction (Need-Gated)
If the chosen direction includes image-native visual ingredients that would materially improve the implementation, generate them as separate assets before building.
If the approved direction needs raster assets, create them before building. Do not replace required imagery with generic cards, bullets, emoji, fake metrics, decorative CSS panels, or filler copy.
Good candidates:
Use the native asset producer (`impeccable_asset_producer` in Codex, `impeccable-asset-producer` in Claude Code) to create clean assets from the hi-fi mock and crops. If you do not have explicit permission to use agents, stop and ask:
- stickers
- badges
- seals
- tickets
- graphic labels
- textures
- abstract objects
- decorative marks
- non-semantic scene elements
```text
Asset production will work better as a scoped subagent job. Should I spawn the Impeccable asset producer subagent for this step?
```
For travel, editorial, portfolio, venue, product showcase, entertainment, education, or any other image-led brand surface, visual assets are usually core content, not decoration. Do not ship abstract CSS panels where the approved mock or subject matter calls for real imagery, generated plates, illustrations, maps, product/object renders, or destination scenes.
Do not skip asset production or silently do it inline. Inline asset production is allowed only if the user declines subagents, the harness cannot spawn the authorized agent, or the user explicitly asks for single-thread mode.
Do **not** export assets for core UI text, navigation, body copy, or any structure that should stay semantic and editable in code.
Pass the approved mock, crop/contact-sheet paths, output directory, dimensions/formats, transparency needs, constraints, and avoid list to the asset producer. Attach image generation capability to the spawned agent when the harness supports it; do not load image-generation reference material into the parent thread first.
Usually **1 to 5** extracted assets is enough. If the design can be built cleanly in HTML/CSS/SVG, prefer that over raster assets. If the mock contains major visual content that cannot be built credibly in code, asset extraction is not optional.
Prefer HTML/CSS/SVG/canvas when they can credibly reproduce an ingredient; use real/generated/stock imagery when the mock or subject matter calls for actual visual content.
## Step 5: Build to Production Quality
@@ -135,50 +114,35 @@ Implement the feature following the design brief. Build in passes so structure,
### Production bar
- Use real or realistic content. Remove placeholder copy, placeholder images, dead links, fake controls, and unused scaffold before presenting.
- Preserve the approved mock's major ingredients. Missing hero objects, missing world/product imagery, different section structure, downgraded CTA/nav treatment, or generic replacements for distinctive motifs are blocking defects unless the user accepted the change.
- Build semantically first: real headings, landmarks, labels, form associations, button/link semantics, accessible names, and state announcements where needed.
- Calibrate spacing, alignment, grid placement, and vertical rhythm deliberately. Do not accept default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- Make typography intentional: chosen font loading strategy, clear hierarchy, readable measure, stable line breaks, tuned wrapping, and no overflow at mobile or large desktop sizes.
- Design realistic state coverage: default, hover where supported, focus-visible, active, disabled, loading, error, success, empty, overflow, long text, short text, and first-run states where relevant.
- Make interaction quality feel finished: keyboard paths, touch targets, feedback timing, scroll behavior, transitions between states, and no hover-only functionality.
- Use icons from the project's established icon set when available. If no set exists, choose a coherent library or use accessible text controls; do not mix unrelated icon styles.
- Optimize imagery and media: correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset` / `picture` for raster assets, and no project-referenced asset left outside the workspace.
- Make motion feel premium: use atmospheric blur, filter, mask, shadow, or reveal effects when they improve the experience; avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- Preserve maintainability: reusable local patterns, clear component boundaries, project conventions, no rasterized UI text, and no hard-coded one-off hacks when a better local pattern exists.
- Fit the technical context: production build passes, no obvious console errors, no avoidable layout shift, no needless dependency, and no broken asset path.
- If you discover a design question that materially changes the brief or approved direction, stop and ask rather than guessing.
- **Real content.** No placeholder copy, placeholder images, dead links, fake controls, or unused scaffold at presentation time.
- **Preserve the approved mock's major ingredients.** Missing hero objects, world/product imagery, section structure, CTA/nav treatment, or distinctive motifs are blocking defects unless the user accepted the change.
- **Semantic first.** Real headings, landmarks, labels, form associations, button/link semantics, accessible names, state announcements where needed.
- **Deliberate spacing and alignment.** No default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- **Intentional typography.** Chosen loading strategy, clear hierarchy, readable measure, stable line breaks, no overflow at any width.
- **Realistic state coverage.** Default, hover, focus-visible, active, disabled, loading, error, success, empty, overflow, long/short text, first-run.
- **Finished interaction quality.** Keyboard paths, touch targets, feedback timing, scroll behavior, state transitions, no hover-only functionality.
- **Coherent icon set.** Use the project's established set; otherwise pick one library or use accessible text. Don't mix.
- **Respect the build pipeline.** Edit source files and run the project's build (`npm run build` or equivalent). Don't write to `build/` / `dist/` / `.next/` with `cat`, heredoc, or Bash redirects; that skips asset hashing, image optimization, code splitting, and CSS extraction, and produces output the dev server won't serve.
- **Verify image URLs before referencing them.** Use image-search MCP or web-fetch when available; guessed photo IDs ship as broken-image placeholders. Without verification, prefer fewer images you're confident about.
- **Optimized imagery and media.** Correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset`/`picture` for raster, no project-referenced asset left outside the workspace.
- **Premium motion.** Use atmospheric blur, filter, mask, shadow, reveal when they improve the experience. Avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- **Maintainable.** Reusable local patterns, clear component boundaries, project conventions. No rasterized UI text or one-off hacks when a local pattern exists.
- **Technically clean.** Production build passes, no console errors, no avoidable layout shift, no needless dependencies, no broken asset paths.
- **Ask when uncertain.** If a discovery materially changes the brief or approved direction, stop and ask. Don't guess.
## Step 6: Browser-Based Iteration
## Step 6: Iterate Visually
**This step is critical.** Do not stop after the first implementation pass.
Look at what you built like a designer would. Your eyes are whatever the harness gives you: a connected browser, a screenshotting tool, Playwright, or asking the user. Use them for responsive testing (mobile, tablet, desktop minimum) and general visual validation.
Open the result in a browser. In Codex, use browser-use or equivalent browser automation when available; otherwise use Playwright or ask the user for screenshots. Inspect screenshots, not just DOM or terminal output.
If your tool returns a file path, read the PNG back into the conversation. A screenshot you didn't read doesn't count.
### Required viewport pass
For long-form brand surfaces, inspect major sections individually. Thumbnails hide spacing, clipping, and cascade defects.
Check the experience at the viewports that matter for the brief. Default minimum:
After the first pass, write an honest critique against the brief, the approved mock's major ingredients (hero silhouette, motifs, imagery, nav/CTA, density), and impeccable's DON'Ts. Patch material defects and re-inspect. **Don't invent defects to demonstrate iteration.** A confident "first pass clean, shipping" beats a fake fix.
- Mobile narrow
- Tablet or small laptop
- Desktop wide
Actively check: responsive behavior (composes, not shrinks), every state (empty / error / loading / edge), craft details (spacing, alignment, hierarchy, contrast, motion timing, focus), performance basics. The exit bar: defensible in a high-end studio review.
For each viewport, capture or inspect the rendered state and look for visual defects: overlap, clipping, weak hierarchy, off-grid alignment, awkward whitespace, cramped controls, unreadable type, broken imagery, hover-only functionality, layout shift, and text overflow.
### Critique and fix loop
After the first browser pass, write a short critique for yourself and patch the implementation. Repeat browser inspection after fixes. Continue until no material issues remain against this checklist:
1. **Does it match the brief?** Compare the live result against every section of the design brief. Fix discrepancies.
2. **Does it match the approved mock?** Compare screenshots against the mock fidelity inventory: hero silhouette, major motifs, imagery, nav/CTA, section sequence, density, color/materials, and second-fold substance. Missing major ingredients are P0 defects.
3. **Does it pass the AI slop test?** If someone saw this and said "AI made this," would they believe it immediately? If yes, it needs more design intention.
4. **Check against impeccable's DON'T guidelines.** Fix any anti-pattern violations.
5. **Check every state.** Navigate through empty, error, loading, and edge case states. Each one should feel intentional, not like an afterthought.
6. **Check responsive behavior.** The design should adapt compositionally, not merely shrink.
7. **Check craft details.** Spacing consistency, optical alignment, type hierarchy, color contrast, image quality, icon coherence, interactive feedback, motion timing, and focus treatment.
8. **Check performance basics.** No obviously oversized images, avoidable layout thrash, blocking animations, or heavy assets without a reason.
The exit bar is not "it works." It is: the rendered result looks intentional at all checked viewports, all expected states are handled, no placeholders remain unless explicitly accepted, and the implementation quality would be defensible in a high-end studio review.
Detector or QA output is defect evidence only; never proof the work is finished.
## Step 7: Present
@@ -189,5 +153,3 @@ Present the result to the user:
- Explain design decisions that connect back to the design brief and, when used, the chosen north-star mock. Include any accepted deviations from the mock; do not hide unimplemented mock ingredients.
- Note any remaining limitations or follow-up risks honestly
- Ask: "What's working? What isn't?"
Iterate based on feedback. Good design is rarely right on the first pass.
@@ -43,7 +43,7 @@ Run the bundled deterministic detector, which flags 27 specific patterns (AI slo
**CLI scan**:
```bash
npx impeccable --json [--fast] [target]
npx impeccable detect --json [--fast] [target]
```
- Pass HTML/JSX/TSX/Vue/Svelte files or directories as `[target]` (anything with markup). Do not pass CSS-only files.
@@ -2,6 +2,8 @@
Perform a meticulous final pass to catch all the small details that separate good work from great work. The difference between shipped and polished.
Detector and automated QA output are defect evidence only. A clean script result is never proof that the design is strong; gather browser evidence and inspect the real interaction path.
## Design System Discovery
Aligning the feature to the design system is **not optional**. Polish without alignment is decoration on top of drift, and it makes the next person's job harder. Discovery comes before any other polish work.
@@ -216,11 +218,12 @@ Sweat the details. Zoom in until the alignment is right and the spacing reads as
Before marking as done:
- **Use it yourself**: Actually interact with the feature
- **Test on real devices**: Not just browser DevTools
- **Ask someone else to review**: Fresh eyes catch things
- **Compare to design**: Match intended design
- **Check all states**: Don't just test happy path
- **Use it yourself**: Actually interact with the feature.
- **Test on real devices**: Not just browser DevTools.
- **Ask someone else to review**: Fresh eyes catch things.
- **Compare to design**: Match intended design.
- **Check all states**: Don't just test happy path.
- **Treat automation carefully**: Run detector or QA commands when they are available and relevant, fix their defects, but never cite a clean result as proof that the work is polished.
## Clean Up
@@ -230,4 +233,3 @@ After polishing, ensure code quality:
- **Remove orphaned code**: Delete unused styles, components, or files made obsolete by polish.
- **Consolidate tokens**: If you introduced new values, check whether they should be tokens.
- **Verify DRYness**: Look for duplication introduced during polishing and consolidate.
+25 -11
View File
@@ -16,14 +16,16 @@ This is a required interaction, not optional guidance. Ask these questions in co
### Interview cadence
Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed design inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
Discovery includes at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
- Use the harness's structured question tool when one exists. Otherwise, ask directly in chat and stop.
- Ask **2-3 questions per round**, then wait for answers.
- Treat PRODUCT.md and DESIGN.md as anchors; they reduce repeated questions but do **not** replace shape for craft. Shape is task-specific.
- Round 1 should clarify purpose, audience/context, and success or emotional outcome.
- Round 2 should clarify content/data/states and scope/fidelity.
- Round 3 should clarify visual direction, constraints, and anti-goals when still unresolved.
- One round is the default. Add a second only if the first answers leave material gaps. Don't run a second round just to feel thorough.
- Round 1 should clarify purpose, audience/context, content/scope, and (for brand) visual direction.
- Round 2, when needed, fills in whatever's still genuinely missing.
**Assert-then-confirm, not menu-with-escape.** When PRODUCT.md and the user's prompt make one option obvious, name it and ask the user to confirm or override. Don't enumerate "Restrained / Committed / Or something else?" as a real choice; "This reads as Restrained, confirm?" beats a four-option menu when the answer is already clear.
### Purpose & Context
- What is this feature for? What problem does it solve?
@@ -36,6 +38,7 @@ Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.
- What are the realistic ranges? (Minimum, typical, maximum, e.g., 0 items, 5 items, 500 items)
- What are the edge cases? (Empty state, error state, first-time use, power user)
- Is any content dynamic? What changes and how often?
- What visual assets are real content here? Note required images, product shots, illustrations, maps, textures, diagrams, generated objects, or existing project assets.
### Design Direction
@@ -72,9 +75,9 @@ After the discovery interview, generate a small set of visual direction probes *
- The work is **net-new** or directionally ambiguous enough that visual exploration will clarify the brief.
- The requested fidelity is **mid-fi, high-fi, or production-ready**. Skip for sketch-only planning.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The current harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool, or similar). Don't ask the user to install APIs or tooling.
When those conditions are met, this step is mandatory for Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
When those conditions are met, this step is mandatory. If image generation isn't natively available, skip silently and proceed; don't announce the skip.
Use probes to explore visual lanes, not to replace the brief.
@@ -104,11 +107,20 @@ The probes should differ in primary visual direction (hierarchy, topology, densi
- Do **not** treat generated imagery as final UX specification, final copy, or final accessibility behavior.
- Do **not** use this step for minor refinements of existing work. It's for shaping a new surface or clarifying a big directional choice.
If image generation is unavailable, or the task doesn't benefit from it, skip this phase only with a one-line reason and proceed directly to the design brief.
If image generation isn't natively available, skip this phase silently and proceed.
## Phase 2: Design Brief
After the interview and any required probes, synthesize everything into a structured design brief. Present it to the user for explicit confirmation before considering this command complete. Stop after asking for confirmation; do not proceed to craft or implementation in the same response unless the user has already approved the brief.
After the interview and any required probes, present a brief and **end your response**. The user must confirm before any implementation runs. Do not present a brief and then continue to code in the same response, even if the brief feels obvious to you. The user's confirmation is the gate.
**Choose the brief shape based on how clear the answers are:**
- **Compact form (3-5 bullets)** when discovery was crisp and the original prompt + PRODUCT.md already pinned scope, content, and direction. State what you're building, the visual lane, and end with one or two specific questions or a clear "confirm or override?" prompt. This is the default for typical craft requests with a clear prompt.
- **Full structured form (sections below)** when the task is genuinely ambiguous, multi-screen, or when the user asked for shape as a standalone step. Use this when the discipline of structure earns its weight.
Don't pad a clear brief into a long one to look thorough. A 70-line brief restating answers the user just gave is noise, not rigor. Equally, don't skip the confirmation pause to look efficient: the pause is the point.
If the user already said "approved" or "go" during discovery for the *exact direction you'd present*, that counts as confirmation; you may proceed without asking again. But if your brief adds anything the user hasn't seen and approved, you must stop and confirm.
### Brief Structure
@@ -136,16 +148,18 @@ List every state the feature needs: default, empty, loading, error, success, edg
How users interact with this feature. What happens on click, hover, scroll? What feedback do they get? What's the flow from entry to completion?
**8. Content Requirements**
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges.
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges. For image-led surfaces, also list the required image/media roles and their likely source (project asset, generated raster, semantic SVG/CSS, canvas/WebGL, icon library, or accepted omission).
**9. Recommended References**
Based on the brief, list which impeccable reference files would be most valuable during implementation (e.g., spatial-design.md for complex layouts, motion-design.md for animated features, interaction-design.md for form-heavy features).
**10. Open Questions**
Anything unresolved that the implementer should resolve during build.
Anything genuinely unresolved. Don't list "open questions" you've already recommended a default for; assert the default and move on. If you'd write `Recommend: X` next to a question, just decide X.
---
ask the user directly to clarify what you cannot infer. Ask for explicit confirmation of the brief before finishing. If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the brief is confirmed.
ask the user directly to clarify what you cannot infer.
If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the user confirms direction (or the user already gave a clear go during discovery, which counts).
Once confirmed, the brief is complete. The user can now hand it to /impeccable, or use it to guide any other implementation approach. (If the user wants the full discovery-then-build flow in one step, they should use /impeccable craft instead, which runs this command internally.)
+8 -3
View File
@@ -66,6 +66,9 @@ extension/detector/
evals/
tests/evals-v2/
# Video backlog & scripts (local working files, not for distribution)
videos/
# Generated sub-pages (legacy, now replaced by Astro content collections)
site/public/docs/
site/public/anti-patterns/
@@ -86,7 +89,9 @@ site/public/js/generated/
# time, and they enable clean submodule use. Run `bun run build` to refresh
# them after editing skill/.
#
# Codex CLI consumes `.agents/skills/`; `.codex/` is not used. Ignore it so
# local artifacts or old trees are never committed.
.codex/
# Codex CLI consumes `.agents/skills/`; native custom agents live under
# `.codex/agents/`. Keep only those agent definitions tracked.
.codex/*
!.codex/agents/
!.codex/agents/**
.astro/
+6 -19
View File
@@ -7,28 +7,15 @@ license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md f
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
## Setup (non-optional)
## Setup
Before any design work or file edits, pass these gates. Skipping them produces generic output that ignores the project.
Before any design work or file edits:
| Gate | Required check | If fail |
|---|---|---|
| Context | The PRODUCT.md / DESIGN.md loader result is known from `node .kiro/skills/impeccable/scripts/load-context.mjs`. | Run the loader before continuing. |
| Product | PRODUCT.md exists and is not empty or placeholder (`[TODO]` markers, <200 chars). | Run `/impeccable teach`, refresh context, then resume. Never synthesize PRODUCT.md from the user's original prompt alone. |
| Command | The matching command reference is loaded when a sub-command is used. | Load the reference before continuing. |
| Craft | `/impeccable craft` has a user-confirmed shape brief for this task. `teach` / PRODUCT.md never counts as shape. | Run `/impeccable shape` and wait for explicit brief confirmation. |
| Image | Required visual probes / mocks are generated or skipped with a reason. | Resolve the image-generation gate in `shape.md` or `craft.md` before code. |
| Mutation | All active gates above pass. | Do not edit project files yet. |
1. Load context (PRODUCT.md / DESIGN.md) via the loader script.
2. Identify the register and load the matching register reference (brand.md or product.md).
3. **If the user invoked a sub-command (e.g. `craft`, `shape`, `audit`), load its reference file too.** This is non-negotiable: `craft` without `craft.md` loaded means you'll skip the shape-and-confirm step the user expects.
Codex-style agents must state this before editing files:
```text
IMPECCABLE_PREFLIGHT: context=pass product=pass command_reference=pass shape=pass|not_required image_gate=pass|skipped:<reason> mutation=open
```
For `/impeccable craft`, `shape=pass` is only valid after a separate user response approving the shape design brief, or when the user provided an already-confirmed brief in the request. Do not mark `shape=pass` after writing PRODUCT.md, summarizing assumptions, or drafting an unconfirmed brief yourself.
Other harnesses should follow the same checklist when they can expose this state.
Skipping these produces generic output that ignores the project.
### 1. Context gathering
+7 -3
View File
@@ -12,6 +12,8 @@ Brand isn't a neutral register. AI-generated landing pages have flooded the inte
**The second slop test: aesthetic lane.** Before committing to moves, name the reference. A Klim-style specimen page is one lane; Stripe-minimal is another; Liquid-Death-acid-maximalism is another. Don't drift into editorial-magazine aesthetics on a brief that isn't editorial. A hiking brand with Cormorant italic drop caps has the wrong register within the register.
Then the inverse test: in one sentence, describe what you're about to build the way a competitor would describe theirs. If that sentence fits the modal landing page in the category, restart.
## Typography
### Font selection procedure
@@ -66,6 +68,7 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
- Palette IS voice. A calm brand and a restless brand should not share palette mechanics.
- When the strategy is Committed or Drenched, color carries the brand. Don't hedge with neutrals around the edges. Commit.
- Don't converge across projects. If the last brand surface was restrained-on-cream, this one is not.
- When a cultural-symbol palette is the obvious pull, reach past it. Let the cultural reading come from typography, imagery, and copy, not the palette.
## Layout
@@ -79,14 +82,14 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
Brand surfaces lean on imagery. A restaurant, hotel, magazine, or product landing page without any imagery reads as incomplete, not as restrained. A solid-color rectangle where a hero image should go is worse than a representative stock photo.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse. If the approved comp or brief is image-led, ship real project assets, generated raster assets, or a credible canvas/SVG/WebGL scene. Do not replace photographic, architectural, product, or place imagery with generic CSS panels, decorative diagrams, cards, bullets, or copy.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. Pick real Unsplash photo IDs you're confident exist (`photo-1559339352-11d035aa65de`, `photo-1590490360182-c33d57733427`, etc.); if unsure, pick fewer photos but don't substitute colored `<div>` placeholders.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. **Verify the URLs before referencing them.** If you have an image-search MCP, web-fetch tool, or browser access, use it to find real photo IDs and confirm they resolve. Guessed IDs (even ones that look real) often 404 and ship as broken-image placeholders. Without a verification path, pick fewer photos you're confident exist over more that you guessed; never substitute colored `<div>` placeholders.
- **Search for the brand's physical object**, not the generic category: "handmade pasta on a scratched wooden table" beats "Italian food"; "cypress trees above a limestone hotel facade at dusk" beats "luxury hotel".
- **One decisive photo beats five mediocre ones.** Hero imagery should commit to a mood; padding with more stock doesn't rescue an indecisive one.
- **Alt text is part of the voice.** "Coastal fettuccine, hand-cut, served on the terrace" beats "pasta dish".
Tech / dev-tool brands are the exception where zero imagery can be correct; a developer landing page often carries its voice through typography, code samples, diagrams. Know which kind of brand you're working on.
"Imagery" here is broader than stock photography: product screenshots, custom data visualizations, generated SVG, and canvas/WebGL scenes are all imagery. Text-only pages where typography alone carries the entire visual weight are the failure mode.
## Motion
@@ -102,6 +105,7 @@ Tech / dev-tool brands are the exception where zero imagery can be correct; a de
- Timid palettes and average layouts. Safe = invisible.
- Zero imagery on a brief that implies imagery (restaurant, hotel, food, travel, fashion, photography, hobbyist). Colored blocks where a hero photo belongs.
- Defaulting to editorial-magazine aesthetics (display serif + italic + drop caps + broadsheet grid) on briefs that aren't magazine-shaped. Editorial is ONE aesthetic lane, not the default brand aesthetic.
- Repeated tiny uppercase tracked labels above every section heading. A single strong kicker can be voice; repeating it as section grammar is AI scaffolding unless it's a deliberate, named brand system.
## Brand permissions
+73 -111
View File
@@ -1,43 +1,41 @@
# Craft Flow
Build a feature with impeccable UX and UI quality through a structured process: shape the design, land the visual direction, build real production code, then inspect and improve in-browser until the result meets a high-end studio bar.
Build a feature with impeccable UX and UI quality: shape the design, land the visual direction, build real production code, inspect and improve in-browser until it meets a high-end studio bar.
## Build Gate
Before writing code, you need: PRODUCT.md loaded, register identified and the matching reference loaded, and a confirmed design direction for this task (either from `shape` or supplied by the user). PRODUCT.md is project context, not a task-specific brief.
Craft cannot build until all of these are true:
Treat any approved visual direction (generated mock or stated reference) as a concrete contract for composition, hierarchy, density, atmosphere, signature motifs, and distinctive visual moves. Don't let mocks replace structure, copy, accessibility, or state design. But if the live result lacks the approved direction's major ingredients, the implementation is wrong.
1. PRODUCT context is valid and current.
2. The shape design brief is explicitly confirmed by the user for this task, unless the user already provided a confirmed brief.
3. Implementation references from the brief are loaded.
4. The shape visual probe decision is recorded: generated, skipped with reason, or already resolved.
5. The north-star mock decision is recorded: generated, skipped with reason, or not applicable.
## Step 0: Project Foundation
PRODUCT.md and `teach` answers do **not** satisfy the shape gate. They are project context only. A compact self-authored brief does not satisfy the shape gate either. `shape=pass` requires a separate user response approving the shape brief or an already-confirmed brief supplied by the user.
Before shape, before code: figure out what kind of project you're working in.
Invalid image-skip reasons include: "the final implementation will be semantic HTML/CSS/SVG", "the diagram should stay editable", "a raster mock would not be used directly", or "the product is fictional." Generated probes and mocks are direction artifacts; they are not implementation assets.
Look at the working directory. Run `ls`. Check for:
## Craft Contract
- An existing framework: `astro.config.mjs/ts`, `next.config.js/ts`, `nuxt.config.ts`, `svelte.config.js`, `vite.config.js/ts`, `package.json` with framework deps, `Cargo.toml` + Leptos/Yew, `Gemfile` + Rails. **If found, use it.** Do not start a parallel build, do not introduce a second framework, do not write to `dist/` or `build/` directly. Whatever pipeline the project has, respect it.
- An existing component library or design system: `src/components/`, `app/components/`, a `tokens.css` / `theme.ts`, an `astro.config` `integrations`. Read what's there before adding to it.
- An existing icon set: `lucide-react`, `@phosphor-icons/react`, `@iconify/*`, hand-rolled SVG sprites in `assets/icons/`. **Use what's already in the project**; don't introduce a second set.
Craft is not a first pass. It is a loop with these required artifacts:
If the directory is empty (greenfield), don't pick a framework silently. Ask the user via the AskUserQuestion tool, with sensible defaults framed by the brief:
1. Confirmed design brief from `shape`.
2. Approved visual direction, from generated probes / mocks when image generation is available.
3. Mock fidelity inventory: the visible ingredients from the approved direction that must survive into code.
4. Semantic, functional implementation using the project's real stack and conventions.
5. Browser evidence across relevant viewports.
6. At least one critique-and-fix pass after the first browser inspection, unless the first pass has no material defects.
```text
What should this be built on?
- Astro (default for content-led brand sites, landing pages, marketing surfaces)
- SvelteKit / Next.js / Nuxt (when the brief implies an app surface or significant interactivity)
- Single index.html (one-shot demo, prototype, or a deliberately framework-free experiment)
```
Do not let generated mockups replace interface structure, copy, accessibility, responsive behavior, or state design. But do treat the approved mock as a concrete visual contract for composition, hierarchy, density, atmosphere, signature motifs, image needs, and distinctive visual moves. "North star" means "preserve the important visible ingredients in semantic code," not "use it as loose mood."
Default: Astro for brand briefs, the project's existing framework for product briefs. Ask once; don't re-ask mid-task.
## Step 1: Shape the Design
Run /impeccable shape, passing along whatever feature description the user provided.
Run /impeccable shape, passing along whatever feature description the user provided. Shape is **required** for craft; it is what produces a confirmed direction.
Wait for the design brief to be fully confirmed by the user before proceeding. The brief is your blueprint, and every implementation decision should trace back to it.
Present the shape output and stop. Wait for the user to confirm, override, or course-correct before writing code.
If this craft run resumed after `teach` created PRODUCT.md, run shape now. Do not treat the teach interview, PRODUCT.md, or a summary of project context as a substitute for shape. Shape is task-specific and must cover scope, content/states, visual direction, constraints, anti-goals, probes when applicable, and explicit brief confirmation.
If the user already supplied a confirmed brief or ran shape separately, use it and skip this step.
If the user has already run /impeccable shape and has a confirmed design brief, skip this step and use the existing brief.
When the original prompt + PRODUCT.md already answer scope, content, and visual direction with no real ambiguity, the shape output can be **compact** (3-5 bullets stating what you're building and the visual lane, ending with one or two specific questions or "confirm or override"). The full 10-section structured brief is reserved for genuinely ambiguous, multi-screen, or stakeholder-heavy tasks. Don't pad a clear brief into a long one to look thorough; equally, don't skip the pause to look efficient.
## Step 2: Load References
@@ -55,79 +53,60 @@ Then add references based on the brief's needs:
## Step 3: Land the Visual Direction (Capability-Gated)
Before implementation, generate high-fidelity visual comps when all of these are true:
Generate high-fidelity visual comps before implementation when all three are true:
- The work is **net-new** or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is **mid-fi, high-fi, or production-ready**.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The work is net-new or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is mid-fi, high-fi, or production-ready.
- The harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool). Don't ask the user to set up external APIs.
When those conditions are met, this step is mandatory for **both brand and product work** in Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
Do not skip this step because the eventual UI should be semantic, editable, code-native, responsive, or accessible. Those are implementation requirements, not reasons to avoid visual exploration.
### Purpose
Use the mock step to find a stronger visual lane than code-first generation would reliably discover on its own. The brief remains authoritative on user, purpose, content, constraints, states, and anti-goals. The mock clarifies composition, hierarchy, density, typography, and visual tone.
When met, this step is mandatory for both brand and product work. If image generation isn't available, skip silently. "The eventual UI is semantic/code-native/accessible" is not a reason to skip; those are implementation requirements, not exploration ones.
### What to generate
Generate **1 to 3** high-fidelity north-star comps based on the confirmed brief. If shape already produced direction probes, use those results as input and generate a more resolved mock from the winning lane, not another unrelated exploration.
Generate **1 to 3** high-fidelity north-star comps from the confirmed brief. If shape already produced direction probes, resolve the winning lane further, not an unrelated exploration. Comps must differ in primary visual direction, not just color.
- For brand work, push visual identity, composition, and mood aggressively.
- For product work, still push hierarchy, topology, density, and tone, but keep the comps grounded in realistic product structure and states.
- For landing pages and long-form brand surfaces, show enough of the next section or second fold to establish the system beyond the hero.
The comps must be genuinely different in primary visual direction, not just color variants.
- Brand work: push visual identity, composition, and mood aggressively.
- Product work: push hierarchy, topology, density, tone, grounded in realistic product structure.
- Landing pages and long-form brand surfaces: show enough of the second fold to establish the system beyond the hero.
### Approval loop
Show the comps and ask what should carry forward. If the user asks for changes or the best direction is still weak, generate a focused revision before implementation. Continue until one direction is approved, or until the user explicitly delegates the choice.
Show the comps and ask what carries forward. Iterate until one direction is approved or the user delegates. If the user delegates, pick the strongest direction and explain it from the brief, not personal taste.
If the user delegates, pick the strongest direction and explain the decision using the brief, not personal taste.
Before moving to implementation, summarize:
- What to carry into code
- What **not** to literalize from the mock
This summary is required before Step 4. It is the handoff between visual exploration and semantic implementation.
Before Step 4, summarize what to carry into code and what **not** to literalize from the mock. This is the handoff between visual exploration and semantic implementation.
### Mock fidelity inventory
Before building, inventory the approved mock's major visible ingredients:
Inventory the approved mock's major visible ingredients:
- Hero silhouette and dominant composition.
- Signature motifs: planets, devices, portraits, charts, route lines, insets, badges, or other memorable objects.
- Nav and primary CTA treatment.
- Section sequence visible in the mock, especially the second fold.
- Image-native content the concept depends on.
- Typography, density, color/material treatment, and motion cues.
- Hero silhouette and dominant composition
- Signature motifs (planets, devices, portraits, charts, route lines, insets, badges, etc.)
- Nav and primary CTA treatment
- Section sequence, especially the second fold
- Image-native content the concept depends on
- Typography, density, color/material treatment, motion cues
For each ingredient, decide how it will be implemented: semantic HTML/CSS/SVG, generated asset, sourced project asset, icon library, canvas/WebGL, or an explicitly accepted omission. Do not substitute a different hero composition or new visual driver after approval unless the user approves the change.
For each, decide implementation: semantic HTML/CSS/SVG, generated asset, sourced asset, icon library, canvas/WebGL, or accepted omission. Don't substitute a different hero composition or visual driver post-approval without user sign-off.
Treat the mock as a **north star**, not a screenshot to trace. Do **not** rasterize core UI text or let the mock override the confirmed brief. But if the live result lacks the mock's major visible ingredients, the implementation is wrong.
If a photographic, architectural, product, or place-led mock becomes generic CSS scenery / decorative diagrams / bullets / copy, stop and fix it. That's a broken implementation, not a harmless interpretation.
Treat the mock as a north star, not a screenshot to trace. Don't rasterize core UI text. But if the live result lacks the mock's major ingredients, the implementation is wrong.
## Step 4: Asset Extraction (Need-Gated)
If the chosen direction includes image-native visual ingredients that would materially improve the implementation, generate them as separate assets before building.
If the approved direction needs raster assets, create them before building. Do not replace required imagery with generic cards, bullets, emoji, fake metrics, decorative CSS panels, or filler copy.
Good candidates:
Use the native asset producer (`impeccable_asset_producer` in Codex, `impeccable-asset-producer` in Claude Code) to create clean assets from the hi-fi mock and crops. If you do not have explicit permission to use agents, stop and ask:
- stickers
- badges
- seals
- tickets
- graphic labels
- textures
- abstract objects
- decorative marks
- non-semantic scene elements
```text
Asset production will work better as a scoped subagent job. Should I spawn the Impeccable asset producer subagent for this step?
```
For travel, editorial, portfolio, venue, product showcase, entertainment, education, or any other image-led brand surface, visual assets are usually core content, not decoration. Do not ship abstract CSS panels where the approved mock or subject matter calls for real imagery, generated plates, illustrations, maps, product/object renders, or destination scenes.
Do not skip asset production or silently do it inline. Inline asset production is allowed only if the user declines subagents, the harness cannot spawn the authorized agent, or the user explicitly asks for single-thread mode.
Do **not** export assets for core UI text, navigation, body copy, or any structure that should stay semantic and editable in code.
Pass the approved mock, crop/contact-sheet paths, output directory, dimensions/formats, transparency needs, constraints, and avoid list to the asset producer. Attach image generation capability to the spawned agent when the harness supports it; do not load image-generation reference material into the parent thread first.
Usually **1 to 5** extracted assets is enough. If the design can be built cleanly in HTML/CSS/SVG, prefer that over raster assets. If the mock contains major visual content that cannot be built credibly in code, asset extraction is not optional.
Prefer HTML/CSS/SVG/canvas when they can credibly reproduce an ingredient; use real/generated/stock imagery when the mock or subject matter calls for actual visual content.
## Step 5: Build to Production Quality
@@ -135,50 +114,35 @@ Implement the feature following the design brief. Build in passes so structure,
### Production bar
- Use real or realistic content. Remove placeholder copy, placeholder images, dead links, fake controls, and unused scaffold before presenting.
- Preserve the approved mock's major ingredients. Missing hero objects, missing world/product imagery, different section structure, downgraded CTA/nav treatment, or generic replacements for distinctive motifs are blocking defects unless the user accepted the change.
- Build semantically first: real headings, landmarks, labels, form associations, button/link semantics, accessible names, and state announcements where needed.
- Calibrate spacing, alignment, grid placement, and vertical rhythm deliberately. Do not accept default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- Make typography intentional: chosen font loading strategy, clear hierarchy, readable measure, stable line breaks, tuned wrapping, and no overflow at mobile or large desktop sizes.
- Design realistic state coverage: default, hover where supported, focus-visible, active, disabled, loading, error, success, empty, overflow, long text, short text, and first-run states where relevant.
- Make interaction quality feel finished: keyboard paths, touch targets, feedback timing, scroll behavior, transitions between states, and no hover-only functionality.
- Use icons from the project's established icon set when available. If no set exists, choose a coherent library or use accessible text controls; do not mix unrelated icon styles.
- Optimize imagery and media: correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset` / `picture` for raster assets, and no project-referenced asset left outside the workspace.
- Make motion feel premium: use atmospheric blur, filter, mask, shadow, or reveal effects when they improve the experience; avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- Preserve maintainability: reusable local patterns, clear component boundaries, project conventions, no rasterized UI text, and no hard-coded one-off hacks when a better local pattern exists.
- Fit the technical context: production build passes, no obvious console errors, no avoidable layout shift, no needless dependency, and no broken asset path.
- If you discover a design question that materially changes the brief or approved direction, stop and ask rather than guessing.
- **Real content.** No placeholder copy, placeholder images, dead links, fake controls, or unused scaffold at presentation time.
- **Preserve the approved mock's major ingredients.** Missing hero objects, world/product imagery, section structure, CTA/nav treatment, or distinctive motifs are blocking defects unless the user accepted the change.
- **Semantic first.** Real headings, landmarks, labels, form associations, button/link semantics, accessible names, state announcements where needed.
- **Deliberate spacing and alignment.** No default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- **Intentional typography.** Chosen loading strategy, clear hierarchy, readable measure, stable line breaks, no overflow at any width.
- **Realistic state coverage.** Default, hover, focus-visible, active, disabled, loading, error, success, empty, overflow, long/short text, first-run.
- **Finished interaction quality.** Keyboard paths, touch targets, feedback timing, scroll behavior, state transitions, no hover-only functionality.
- **Coherent icon set.** Use the project's established set; otherwise pick one library or use accessible text. Don't mix.
- **Respect the build pipeline.** Edit source files and run the project's build (`npm run build` or equivalent). Don't write to `build/` / `dist/` / `.next/` with `cat`, heredoc, or Bash redirects; that skips asset hashing, image optimization, code splitting, and CSS extraction, and produces output the dev server won't serve.
- **Verify image URLs before referencing them.** Use image-search MCP or web-fetch when available; guessed photo IDs ship as broken-image placeholders. Without verification, prefer fewer images you're confident about.
- **Optimized imagery and media.** Correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset`/`picture` for raster, no project-referenced asset left outside the workspace.
- **Premium motion.** Use atmospheric blur, filter, mask, shadow, reveal when they improve the experience. Avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- **Maintainable.** Reusable local patterns, clear component boundaries, project conventions. No rasterized UI text or one-off hacks when a local pattern exists.
- **Technically clean.** Production build passes, no console errors, no avoidable layout shift, no needless dependencies, no broken asset paths.
- **Ask when uncertain.** If a discovery materially changes the brief or approved direction, stop and ask. Don't guess.
## Step 6: Browser-Based Iteration
## Step 6: Iterate Visually
**This step is critical.** Do not stop after the first implementation pass.
Look at what you built like a designer would. Your eyes are whatever the harness gives you: a connected browser, a screenshotting tool, Playwright, or asking the user. Use them for responsive testing (mobile, tablet, desktop minimum) and general visual validation.
Open the result in a browser. In Codex, use browser-use or equivalent browser automation when available; otherwise use Playwright or ask the user for screenshots. Inspect screenshots, not just DOM or terminal output.
If your tool returns a file path, read the PNG back into the conversation. A screenshot you didn't read doesn't count.
### Required viewport pass
For long-form brand surfaces, inspect major sections individually. Thumbnails hide spacing, clipping, and cascade defects.
Check the experience at the viewports that matter for the brief. Default minimum:
After the first pass, write an honest critique against the brief, the approved mock's major ingredients (hero silhouette, motifs, imagery, nav/CTA, density), and impeccable's DON'Ts. Patch material defects and re-inspect. **Don't invent defects to demonstrate iteration.** A confident "first pass clean, shipping" beats a fake fix.
- Mobile narrow
- Tablet or small laptop
- Desktop wide
Actively check: responsive behavior (composes, not shrinks), every state (empty / error / loading / edge), craft details (spacing, alignment, hierarchy, contrast, motion timing, focus), performance basics. The exit bar: defensible in a high-end studio review.
For each viewport, capture or inspect the rendered state and look for visual defects: overlap, clipping, weak hierarchy, off-grid alignment, awkward whitespace, cramped controls, unreadable type, broken imagery, hover-only functionality, layout shift, and text overflow.
### Critique and fix loop
After the first browser pass, write a short critique for yourself and patch the implementation. Repeat browser inspection after fixes. Continue until no material issues remain against this checklist:
1. **Does it match the brief?** Compare the live result against every section of the design brief. Fix discrepancies.
2. **Does it match the approved mock?** Compare screenshots against the mock fidelity inventory: hero silhouette, major motifs, imagery, nav/CTA, section sequence, density, color/materials, and second-fold substance. Missing major ingredients are P0 defects.
3. **Does it pass the AI slop test?** If someone saw this and said "AI made this," would they believe it immediately? If yes, it needs more design intention.
4. **Check against impeccable's DON'T guidelines.** Fix any anti-pattern violations.
5. **Check every state.** Navigate through empty, error, loading, and edge case states. Each one should feel intentional, not like an afterthought.
6. **Check responsive behavior.** The design should adapt compositionally, not merely shrink.
7. **Check craft details.** Spacing consistency, optical alignment, type hierarchy, color contrast, image quality, icon coherence, interactive feedback, motion timing, and focus treatment.
8. **Check performance basics.** No obviously oversized images, avoidable layout thrash, blocking animations, or heavy assets without a reason.
The exit bar is not "it works." It is: the rendered result looks intentional at all checked viewports, all expected states are handled, no placeholders remain unless explicitly accepted, and the implementation quality would be defensible in a high-end studio review.
Detector or QA output is defect evidence only; never proof the work is finished.
## Step 7: Present
@@ -189,5 +153,3 @@ Present the result to the user:
- Explain design decisions that connect back to the design brief and, when used, the chosen north-star mock. Include any accepted deviations from the mock; do not hide unimplemented mock ingredients.
- Note any remaining limitations or follow-up risks honestly
- Ask: "What's working? What isn't?"
Iterate based on feedback. Good design is rarely right on the first pass.
@@ -43,7 +43,7 @@ Run the bundled deterministic detector, which flags 27 specific patterns (AI slo
**CLI scan**:
```bash
npx impeccable --json [--fast] [target]
npx impeccable detect --json [--fast] [target]
```
- Pass HTML/JSX/TSX/Vue/Svelte files or directories as `[target]` (anything with markup). Do not pass CSS-only files.
+8 -6
View File
@@ -2,6 +2,8 @@
Perform a meticulous final pass to catch all the small details that separate good work from great work. The difference between shipped and polished.
Detector and automated QA output are defect evidence only. A clean script result is never proof that the design is strong; gather browser evidence and inspect the real interaction path.
## Design System Discovery
Aligning the feature to the design system is **not optional**. Polish without alignment is decoration on top of drift, and it makes the next person's job harder. Discovery comes before any other polish work.
@@ -216,11 +218,12 @@ Sweat the details. Zoom in until the alignment is right and the spacing reads as
Before marking as done:
- **Use it yourself**: Actually interact with the feature
- **Test on real devices**: Not just browser DevTools
- **Ask someone else to review**: Fresh eyes catch things
- **Compare to design**: Match intended design
- **Check all states**: Don't just test happy path
- **Use it yourself**: Actually interact with the feature.
- **Test on real devices**: Not just browser DevTools.
- **Ask someone else to review**: Fresh eyes catch things.
- **Compare to design**: Match intended design.
- **Check all states**: Don't just test happy path.
- **Treat automation carefully**: Run detector or QA commands when they are available and relevant, fix their defects, but never cite a clean result as proof that the work is polished.
## Clean Up
@@ -230,4 +233,3 @@ After polishing, ensure code quality:
- **Remove orphaned code**: Delete unused styles, components, or files made obsolete by polish.
- **Consolidate tokens**: If you introduced new values, check whether they should be tokens.
- **Verify DRYness**: Look for duplication introduced during polishing and consolidate.
+25 -11
View File
@@ -16,14 +16,16 @@ This is a required interaction, not optional guidance. Ask these questions in co
### Interview cadence
Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed design inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
Discovery includes at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
- Use the harness's structured question tool when one exists. Otherwise, ask directly in chat and stop.
- Ask **2-3 questions per round**, then wait for answers.
- Treat PRODUCT.md and DESIGN.md as anchors; they reduce repeated questions but do **not** replace shape for craft. Shape is task-specific.
- Round 1 should clarify purpose, audience/context, and success or emotional outcome.
- Round 2 should clarify content/data/states and scope/fidelity.
- Round 3 should clarify visual direction, constraints, and anti-goals when still unresolved.
- One round is the default. Add a second only if the first answers leave material gaps. Don't run a second round just to feel thorough.
- Round 1 should clarify purpose, audience/context, content/scope, and (for brand) visual direction.
- Round 2, when needed, fills in whatever's still genuinely missing.
**Assert-then-confirm, not menu-with-escape.** When PRODUCT.md and the user's prompt make one option obvious, name it and ask the user to confirm or override. Don't enumerate "Restrained / Committed / Or something else?" as a real choice; "This reads as Restrained, confirm?" beats a four-option menu when the answer is already clear.
### Purpose & Context
- What is this feature for? What problem does it solve?
@@ -36,6 +38,7 @@ Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.
- What are the realistic ranges? (Minimum, typical, maximum, e.g., 0 items, 5 items, 500 items)
- What are the edge cases? (Empty state, error state, first-time use, power user)
- Is any content dynamic? What changes and how often?
- What visual assets are real content here? Note required images, product shots, illustrations, maps, textures, diagrams, generated objects, or existing project assets.
### Design Direction
@@ -72,9 +75,9 @@ After the discovery interview, generate a small set of visual direction probes *
- The work is **net-new** or directionally ambiguous enough that visual exploration will clarify the brief.
- The requested fidelity is **mid-fi, high-fi, or production-ready**. Skip for sketch-only planning.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The current harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool, or similar). Don't ask the user to install APIs or tooling.
When those conditions are met, this step is mandatory for Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
When those conditions are met, this step is mandatory. If image generation isn't natively available, skip silently and proceed; don't announce the skip.
Use probes to explore visual lanes, not to replace the brief.
@@ -104,11 +107,20 @@ The probes should differ in primary visual direction (hierarchy, topology, densi
- Do **not** treat generated imagery as final UX specification, final copy, or final accessibility behavior.
- Do **not** use this step for minor refinements of existing work. It's for shaping a new surface or clarifying a big directional choice.
If image generation is unavailable, or the task doesn't benefit from it, skip this phase only with a one-line reason and proceed directly to the design brief.
If image generation isn't natively available, skip this phase silently and proceed.
## Phase 2: Design Brief
After the interview and any required probes, synthesize everything into a structured design brief. Present it to the user for explicit confirmation before considering this command complete. Stop after asking for confirmation; do not proceed to craft or implementation in the same response unless the user has already approved the brief.
After the interview and any required probes, present a brief and **end your response**. The user must confirm before any implementation runs. Do not present a brief and then continue to code in the same response, even if the brief feels obvious to you. The user's confirmation is the gate.
**Choose the brief shape based on how clear the answers are:**
- **Compact form (3-5 bullets)** when discovery was crisp and the original prompt + PRODUCT.md already pinned scope, content, and direction. State what you're building, the visual lane, and end with one or two specific questions or a clear "confirm or override?" prompt. This is the default for typical craft requests with a clear prompt.
- **Full structured form (sections below)** when the task is genuinely ambiguous, multi-screen, or when the user asked for shape as a standalone step. Use this when the discipline of structure earns its weight.
Don't pad a clear brief into a long one to look thorough. A 70-line brief restating answers the user just gave is noise, not rigor. Equally, don't skip the confirmation pause to look efficient: the pause is the point.
If the user already said "approved" or "go" during discovery for the *exact direction you'd present*, that counts as confirmation; you may proceed without asking again. But if your brief adds anything the user hasn't seen and approved, you must stop and confirm.
### Brief Structure
@@ -136,16 +148,18 @@ List every state the feature needs: default, empty, loading, error, success, edg
How users interact with this feature. What happens on click, hover, scroll? What feedback do they get? What's the flow from entry to completion?
**8. Content Requirements**
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges.
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges. For image-led surfaces, also list the required image/media roles and their likely source (project asset, generated raster, semantic SVG/CSS, canvas/WebGL, icon library, or accepted omission).
**9. Recommended References**
Based on the brief, list which impeccable reference files would be most valuable during implementation (e.g., spatial-design.md for complex layouts, motion-design.md for animated features, interaction-design.md for form-heavy features).
**10. Open Questions**
Anything unresolved that the implementer should resolve during build.
Anything genuinely unresolved. Don't list "open questions" you've already recommended a default for; assert the default and move on. If you'd write `Recommend: X` next to a question, just decide X.
---
ask the user directly to clarify what you cannot infer. Ask for explicit confirmation of the brief before finishing. If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the brief is confirmed.
ask the user directly to clarify what you cannot infer.
If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the user confirms direction (or the user already gave a clear go during discovery, which counts).
Once confirmed, the brief is complete. The user can now hand it to /impeccable, or use it to guide any other implementation approach. (If the user wants the full discovery-then-build flow in one step, they should use /impeccable craft instead, which runs this command internally.)
+6 -19
View File
@@ -11,28 +11,15 @@ allowed-tools:
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
## Setup (non-optional)
## Setup
Before any design work or file edits, pass these gates. Skipping them produces generic output that ignores the project.
Before any design work or file edits:
| Gate | Required check | If fail |
|---|---|---|
| Context | The PRODUCT.md / DESIGN.md loader result is known from `node .opencode/skills/impeccable/scripts/load-context.mjs`. | Run the loader before continuing. |
| Product | PRODUCT.md exists and is not empty or placeholder (`[TODO]` markers, <200 chars). | Run `/impeccable teach`, refresh context, then resume. Never synthesize PRODUCT.md from the user's original prompt alone. |
| Command | The matching command reference is loaded when a sub-command is used. | Load the reference before continuing. |
| Craft | `/impeccable craft` has a user-confirmed shape brief for this task. `teach` / PRODUCT.md never counts as shape. | Run `/impeccable shape` and wait for explicit brief confirmation. |
| Image | Required visual probes / mocks are generated or skipped with a reason. | Resolve the image-generation gate in `shape.md` or `craft.md` before code. |
| Mutation | All active gates above pass. | Do not edit project files yet. |
1. Load context (PRODUCT.md / DESIGN.md) via the loader script.
2. Identify the register and load the matching register reference (brand.md or product.md).
3. **If the user invoked a sub-command (e.g. `craft`, `shape`, `audit`), load its reference file too.** This is non-negotiable: `craft` without `craft.md` loaded means you'll skip the shape-and-confirm step the user expects.
Codex-style agents must state this before editing files:
```text
IMPECCABLE_PREFLIGHT: context=pass product=pass command_reference=pass shape=pass|not_required image_gate=pass|skipped:<reason> mutation=open
```
For `/impeccable craft`, `shape=pass` is only valid after a separate user response approving the shape design brief, or when the user provided an already-confirmed brief in the request. Do not mark `shape=pass` after writing PRODUCT.md, summarizing assumptions, or drafting an unconfirmed brief yourself.
Other harnesses should follow the same checklist when they can expose this state.
Skipping these produces generic output that ignores the project.
### 1. Context gathering
@@ -12,6 +12,8 @@ Brand isn't a neutral register. AI-generated landing pages have flooded the inte
**The second slop test: aesthetic lane.** Before committing to moves, name the reference. A Klim-style specimen page is one lane; Stripe-minimal is another; Liquid-Death-acid-maximalism is another. Don't drift into editorial-magazine aesthetics on a brief that isn't editorial. A hiking brand with Cormorant italic drop caps has the wrong register within the register.
Then the inverse test: in one sentence, describe what you're about to build the way a competitor would describe theirs. If that sentence fits the modal landing page in the category, restart.
## Typography
### Font selection procedure
@@ -66,6 +68,7 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
- Palette IS voice. A calm brand and a restless brand should not share palette mechanics.
- When the strategy is Committed or Drenched, color carries the brand. Don't hedge with neutrals around the edges. Commit.
- Don't converge across projects. If the last brand surface was restrained-on-cream, this one is not.
- When a cultural-symbol palette is the obvious pull, reach past it. Let the cultural reading come from typography, imagery, and copy, not the palette.
## Layout
@@ -79,14 +82,14 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
Brand surfaces lean on imagery. A restaurant, hotel, magazine, or product landing page without any imagery reads as incomplete, not as restrained. A solid-color rectangle where a hero image should go is worse than a representative stock photo.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse. If the approved comp or brief is image-led, ship real project assets, generated raster assets, or a credible canvas/SVG/WebGL scene. Do not replace photographic, architectural, product, or place imagery with generic CSS panels, decorative diagrams, cards, bullets, or copy.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. Pick real Unsplash photo IDs you're confident exist (`photo-1559339352-11d035aa65de`, `photo-1590490360182-c33d57733427`, etc.); if unsure, pick fewer photos but don't substitute colored `<div>` placeholders.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. **Verify the URLs before referencing them.** If you have an image-search MCP, web-fetch tool, or browser access, use it to find real photo IDs and confirm they resolve. Guessed IDs (even ones that look real) often 404 and ship as broken-image placeholders. Without a verification path, pick fewer photos you're confident exist over more that you guessed; never substitute colored `<div>` placeholders.
- **Search for the brand's physical object**, not the generic category: "handmade pasta on a scratched wooden table" beats "Italian food"; "cypress trees above a limestone hotel facade at dusk" beats "luxury hotel".
- **One decisive photo beats five mediocre ones.** Hero imagery should commit to a mood; padding with more stock doesn't rescue an indecisive one.
- **Alt text is part of the voice.** "Coastal fettuccine, hand-cut, served on the terrace" beats "pasta dish".
Tech / dev-tool brands are the exception where zero imagery can be correct; a developer landing page often carries its voice through typography, code samples, diagrams. Know which kind of brand you're working on.
"Imagery" here is broader than stock photography: product screenshots, custom data visualizations, generated SVG, and canvas/WebGL scenes are all imagery. Text-only pages where typography alone carries the entire visual weight are the failure mode.
## Motion
@@ -102,6 +105,7 @@ Tech / dev-tool brands are the exception where zero imagery can be correct; a de
- Timid palettes and average layouts. Safe = invisible.
- Zero imagery on a brief that implies imagery (restaurant, hotel, food, travel, fashion, photography, hobbyist). Colored blocks where a hero photo belongs.
- Defaulting to editorial-magazine aesthetics (display serif + italic + drop caps + broadsheet grid) on briefs that aren't magazine-shaped. Editorial is ONE aesthetic lane, not the default brand aesthetic.
- Repeated tiny uppercase tracked labels above every section heading. A single strong kicker can be voice; repeating it as section grammar is AI scaffolding unless it's a deliberate, named brand system.
## Brand permissions
+73 -111
View File
@@ -1,43 +1,41 @@
# Craft Flow
Build a feature with impeccable UX and UI quality through a structured process: shape the design, land the visual direction, build real production code, then inspect and improve in-browser until the result meets a high-end studio bar.
Build a feature with impeccable UX and UI quality: shape the design, land the visual direction, build real production code, inspect and improve in-browser until it meets a high-end studio bar.
## Build Gate
Before writing code, you need: PRODUCT.md loaded, register identified and the matching reference loaded, and a confirmed design direction for this task (either from `shape` or supplied by the user). PRODUCT.md is project context, not a task-specific brief.
Craft cannot build until all of these are true:
Treat any approved visual direction (generated mock or stated reference) as a concrete contract for composition, hierarchy, density, atmosphere, signature motifs, and distinctive visual moves. Don't let mocks replace structure, copy, accessibility, or state design. But if the live result lacks the approved direction's major ingredients, the implementation is wrong.
1. PRODUCT context is valid and current.
2. The shape design brief is explicitly confirmed by the user for this task, unless the user already provided a confirmed brief.
3. Implementation references from the brief are loaded.
4. The shape visual probe decision is recorded: generated, skipped with reason, or already resolved.
5. The north-star mock decision is recorded: generated, skipped with reason, or not applicable.
## Step 0: Project Foundation
PRODUCT.md and `teach` answers do **not** satisfy the shape gate. They are project context only. A compact self-authored brief does not satisfy the shape gate either. `shape=pass` requires a separate user response approving the shape brief or an already-confirmed brief supplied by the user.
Before shape, before code: figure out what kind of project you're working in.
Invalid image-skip reasons include: "the final implementation will be semantic HTML/CSS/SVG", "the diagram should stay editable", "a raster mock would not be used directly", or "the product is fictional." Generated probes and mocks are direction artifacts; they are not implementation assets.
Look at the working directory. Run `ls`. Check for:
## Craft Contract
- An existing framework: `astro.config.mjs/ts`, `next.config.js/ts`, `nuxt.config.ts`, `svelte.config.js`, `vite.config.js/ts`, `package.json` with framework deps, `Cargo.toml` + Leptos/Yew, `Gemfile` + Rails. **If found, use it.** Do not start a parallel build, do not introduce a second framework, do not write to `dist/` or `build/` directly. Whatever pipeline the project has, respect it.
- An existing component library or design system: `src/components/`, `app/components/`, a `tokens.css` / `theme.ts`, an `astro.config` `integrations`. Read what's there before adding to it.
- An existing icon set: `lucide-react`, `@phosphor-icons/react`, `@iconify/*`, hand-rolled SVG sprites in `assets/icons/`. **Use what's already in the project**; don't introduce a second set.
Craft is not a first pass. It is a loop with these required artifacts:
If the directory is empty (greenfield), don't pick a framework silently. Ask the user via the AskUserQuestion tool, with sensible defaults framed by the brief:
1. Confirmed design brief from `shape`.
2. Approved visual direction, from generated probes / mocks when image generation is available.
3. Mock fidelity inventory: the visible ingredients from the approved direction that must survive into code.
4. Semantic, functional implementation using the project's real stack and conventions.
5. Browser evidence across relevant viewports.
6. At least one critique-and-fix pass after the first browser inspection, unless the first pass has no material defects.
```text
What should this be built on?
- Astro (default for content-led brand sites, landing pages, marketing surfaces)
- SvelteKit / Next.js / Nuxt (when the brief implies an app surface or significant interactivity)
- Single index.html (one-shot demo, prototype, or a deliberately framework-free experiment)
```
Do not let generated mockups replace interface structure, copy, accessibility, responsive behavior, or state design. But do treat the approved mock as a concrete visual contract for composition, hierarchy, density, atmosphere, signature motifs, image needs, and distinctive visual moves. "North star" means "preserve the important visible ingredients in semantic code," not "use it as loose mood."
Default: Astro for brand briefs, the project's existing framework for product briefs. Ask once; don't re-ask mid-task.
## Step 1: Shape the Design
Run /impeccable shape, passing along whatever feature description the user provided.
Run /impeccable shape, passing along whatever feature description the user provided. Shape is **required** for craft; it is what produces a confirmed direction.
Wait for the design brief to be fully confirmed by the user before proceeding. The brief is your blueprint, and every implementation decision should trace back to it.
Present the shape output and stop. Wait for the user to confirm, override, or course-correct before writing code.
If this craft run resumed after `teach` created PRODUCT.md, run shape now. Do not treat the teach interview, PRODUCT.md, or a summary of project context as a substitute for shape. Shape is task-specific and must cover scope, content/states, visual direction, constraints, anti-goals, probes when applicable, and explicit brief confirmation.
If the user already supplied a confirmed brief or ran shape separately, use it and skip this step.
If the user has already run /impeccable shape and has a confirmed design brief, skip this step and use the existing brief.
When the original prompt + PRODUCT.md already answer scope, content, and visual direction with no real ambiguity, the shape output can be **compact** (3-5 bullets stating what you're building and the visual lane, ending with one or two specific questions or "confirm or override"). The full 10-section structured brief is reserved for genuinely ambiguous, multi-screen, or stakeholder-heavy tasks. Don't pad a clear brief into a long one to look thorough; equally, don't skip the pause to look efficient.
## Step 2: Load References
@@ -55,79 +53,60 @@ Then add references based on the brief's needs:
## Step 3: Land the Visual Direction (Capability-Gated)
Before implementation, generate high-fidelity visual comps when all of these are true:
Generate high-fidelity visual comps before implementation when all three are true:
- The work is **net-new** or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is **mid-fi, high-fi, or production-ready**.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The work is net-new or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is mid-fi, high-fi, or production-ready.
- The harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool). Don't ask the user to set up external APIs.
When those conditions are met, this step is mandatory for **both brand and product work** in Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
Do not skip this step because the eventual UI should be semantic, editable, code-native, responsive, or accessible. Those are implementation requirements, not reasons to avoid visual exploration.
### Purpose
Use the mock step to find a stronger visual lane than code-first generation would reliably discover on its own. The brief remains authoritative on user, purpose, content, constraints, states, and anti-goals. The mock clarifies composition, hierarchy, density, typography, and visual tone.
When met, this step is mandatory for both brand and product work. If image generation isn't available, skip silently. "The eventual UI is semantic/code-native/accessible" is not a reason to skip; those are implementation requirements, not exploration ones.
### What to generate
Generate **1 to 3** high-fidelity north-star comps based on the confirmed brief. If shape already produced direction probes, use those results as input and generate a more resolved mock from the winning lane, not another unrelated exploration.
Generate **1 to 3** high-fidelity north-star comps from the confirmed brief. If shape already produced direction probes, resolve the winning lane further, not an unrelated exploration. Comps must differ in primary visual direction, not just color.
- For brand work, push visual identity, composition, and mood aggressively.
- For product work, still push hierarchy, topology, density, and tone, but keep the comps grounded in realistic product structure and states.
- For landing pages and long-form brand surfaces, show enough of the next section or second fold to establish the system beyond the hero.
The comps must be genuinely different in primary visual direction, not just color variants.
- Brand work: push visual identity, composition, and mood aggressively.
- Product work: push hierarchy, topology, density, tone, grounded in realistic product structure.
- Landing pages and long-form brand surfaces: show enough of the second fold to establish the system beyond the hero.
### Approval loop
Show the comps and ask what should carry forward. If the user asks for changes or the best direction is still weak, generate a focused revision before implementation. Continue until one direction is approved, or until the user explicitly delegates the choice.
Show the comps and ask what carries forward. Iterate until one direction is approved or the user delegates. If the user delegates, pick the strongest direction and explain it from the brief, not personal taste.
If the user delegates, pick the strongest direction and explain the decision using the brief, not personal taste.
Before moving to implementation, summarize:
- What to carry into code
- What **not** to literalize from the mock
This summary is required before Step 4. It is the handoff between visual exploration and semantic implementation.
Before Step 4, summarize what to carry into code and what **not** to literalize from the mock. This is the handoff between visual exploration and semantic implementation.
### Mock fidelity inventory
Before building, inventory the approved mock's major visible ingredients:
Inventory the approved mock's major visible ingredients:
- Hero silhouette and dominant composition.
- Signature motifs: planets, devices, portraits, charts, route lines, insets, badges, or other memorable objects.
- Nav and primary CTA treatment.
- Section sequence visible in the mock, especially the second fold.
- Image-native content the concept depends on.
- Typography, density, color/material treatment, and motion cues.
- Hero silhouette and dominant composition
- Signature motifs (planets, devices, portraits, charts, route lines, insets, badges, etc.)
- Nav and primary CTA treatment
- Section sequence, especially the second fold
- Image-native content the concept depends on
- Typography, density, color/material treatment, motion cues
For each ingredient, decide how it will be implemented: semantic HTML/CSS/SVG, generated asset, sourced project asset, icon library, canvas/WebGL, or an explicitly accepted omission. Do not substitute a different hero composition or new visual driver after approval unless the user approves the change.
For each, decide implementation: semantic HTML/CSS/SVG, generated asset, sourced asset, icon library, canvas/WebGL, or accepted omission. Don't substitute a different hero composition or visual driver post-approval without user sign-off.
Treat the mock as a **north star**, not a screenshot to trace. Do **not** rasterize core UI text or let the mock override the confirmed brief. But if the live result lacks the mock's major visible ingredients, the implementation is wrong.
If a photographic, architectural, product, or place-led mock becomes generic CSS scenery / decorative diagrams / bullets / copy, stop and fix it. That's a broken implementation, not a harmless interpretation.
Treat the mock as a north star, not a screenshot to trace. Don't rasterize core UI text. But if the live result lacks the mock's major ingredients, the implementation is wrong.
## Step 4: Asset Extraction (Need-Gated)
If the chosen direction includes image-native visual ingredients that would materially improve the implementation, generate them as separate assets before building.
If the approved direction needs raster assets, create them before building. Do not replace required imagery with generic cards, bullets, emoji, fake metrics, decorative CSS panels, or filler copy.
Good candidates:
Use the native asset producer (`impeccable_asset_producer` in Codex, `impeccable-asset-producer` in Claude Code) to create clean assets from the hi-fi mock and crops. If you do not have explicit permission to use agents, stop and ask:
- stickers
- badges
- seals
- tickets
- graphic labels
- textures
- abstract objects
- decorative marks
- non-semantic scene elements
```text
Asset production will work better as a scoped subagent job. Should I spawn the Impeccable asset producer subagent for this step?
```
For travel, editorial, portfolio, venue, product showcase, entertainment, education, or any other image-led brand surface, visual assets are usually core content, not decoration. Do not ship abstract CSS panels where the approved mock or subject matter calls for real imagery, generated plates, illustrations, maps, product/object renders, or destination scenes.
Do not skip asset production or silently do it inline. Inline asset production is allowed only if the user declines subagents, the harness cannot spawn the authorized agent, or the user explicitly asks for single-thread mode.
Do **not** export assets for core UI text, navigation, body copy, or any structure that should stay semantic and editable in code.
Pass the approved mock, crop/contact-sheet paths, output directory, dimensions/formats, transparency needs, constraints, and avoid list to the asset producer. Attach image generation capability to the spawned agent when the harness supports it; do not load image-generation reference material into the parent thread first.
Usually **1 to 5** extracted assets is enough. If the design can be built cleanly in HTML/CSS/SVG, prefer that over raster assets. If the mock contains major visual content that cannot be built credibly in code, asset extraction is not optional.
Prefer HTML/CSS/SVG/canvas when they can credibly reproduce an ingredient; use real/generated/stock imagery when the mock or subject matter calls for actual visual content.
## Step 5: Build to Production Quality
@@ -135,50 +114,35 @@ Implement the feature following the design brief. Build in passes so structure,
### Production bar
- Use real or realistic content. Remove placeholder copy, placeholder images, dead links, fake controls, and unused scaffold before presenting.
- Preserve the approved mock's major ingredients. Missing hero objects, missing world/product imagery, different section structure, downgraded CTA/nav treatment, or generic replacements for distinctive motifs are blocking defects unless the user accepted the change.
- Build semantically first: real headings, landmarks, labels, form associations, button/link semantics, accessible names, and state announcements where needed.
- Calibrate spacing, alignment, grid placement, and vertical rhythm deliberately. Do not accept default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- Make typography intentional: chosen font loading strategy, clear hierarchy, readable measure, stable line breaks, tuned wrapping, and no overflow at mobile or large desktop sizes.
- Design realistic state coverage: default, hover where supported, focus-visible, active, disabled, loading, error, success, empty, overflow, long text, short text, and first-run states where relevant.
- Make interaction quality feel finished: keyboard paths, touch targets, feedback timing, scroll behavior, transitions between states, and no hover-only functionality.
- Use icons from the project's established icon set when available. If no set exists, choose a coherent library or use accessible text controls; do not mix unrelated icon styles.
- Optimize imagery and media: correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset` / `picture` for raster assets, and no project-referenced asset left outside the workspace.
- Make motion feel premium: use atmospheric blur, filter, mask, shadow, or reveal effects when they improve the experience; avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- Preserve maintainability: reusable local patterns, clear component boundaries, project conventions, no rasterized UI text, and no hard-coded one-off hacks when a better local pattern exists.
- Fit the technical context: production build passes, no obvious console errors, no avoidable layout shift, no needless dependency, and no broken asset path.
- If you discover a design question that materially changes the brief or approved direction, stop and ask rather than guessing.
- **Real content.** No placeholder copy, placeholder images, dead links, fake controls, or unused scaffold at presentation time.
- **Preserve the approved mock's major ingredients.** Missing hero objects, world/product imagery, section structure, CTA/nav treatment, or distinctive motifs are blocking defects unless the user accepted the change.
- **Semantic first.** Real headings, landmarks, labels, form associations, button/link semantics, accessible names, state announcements where needed.
- **Deliberate spacing and alignment.** No default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- **Intentional typography.** Chosen loading strategy, clear hierarchy, readable measure, stable line breaks, no overflow at any width.
- **Realistic state coverage.** Default, hover, focus-visible, active, disabled, loading, error, success, empty, overflow, long/short text, first-run.
- **Finished interaction quality.** Keyboard paths, touch targets, feedback timing, scroll behavior, state transitions, no hover-only functionality.
- **Coherent icon set.** Use the project's established set; otherwise pick one library or use accessible text. Don't mix.
- **Respect the build pipeline.** Edit source files and run the project's build (`npm run build` or equivalent). Don't write to `build/` / `dist/` / `.next/` with `cat`, heredoc, or Bash redirects; that skips asset hashing, image optimization, code splitting, and CSS extraction, and produces output the dev server won't serve.
- **Verify image URLs before referencing them.** Use image-search MCP or web-fetch when available; guessed photo IDs ship as broken-image placeholders. Without verification, prefer fewer images you're confident about.
- **Optimized imagery and media.** Correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset`/`picture` for raster, no project-referenced asset left outside the workspace.
- **Premium motion.** Use atmospheric blur, filter, mask, shadow, reveal when they improve the experience. Avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- **Maintainable.** Reusable local patterns, clear component boundaries, project conventions. No rasterized UI text or one-off hacks when a local pattern exists.
- **Technically clean.** Production build passes, no console errors, no avoidable layout shift, no needless dependencies, no broken asset paths.
- **Ask when uncertain.** If a discovery materially changes the brief or approved direction, stop and ask. Don't guess.
## Step 6: Browser-Based Iteration
## Step 6: Iterate Visually
**This step is critical.** Do not stop after the first implementation pass.
Look at what you built like a designer would. Your eyes are whatever the harness gives you: a connected browser, a screenshotting tool, Playwright, or asking the user. Use them for responsive testing (mobile, tablet, desktop minimum) and general visual validation.
Open the result in a browser. In Codex, use browser-use or equivalent browser automation when available; otherwise use Playwright or ask the user for screenshots. Inspect screenshots, not just DOM or terminal output.
If your tool returns a file path, read the PNG back into the conversation. A screenshot you didn't read doesn't count.
### Required viewport pass
For long-form brand surfaces, inspect major sections individually. Thumbnails hide spacing, clipping, and cascade defects.
Check the experience at the viewports that matter for the brief. Default minimum:
After the first pass, write an honest critique against the brief, the approved mock's major ingredients (hero silhouette, motifs, imagery, nav/CTA, density), and impeccable's DON'Ts. Patch material defects and re-inspect. **Don't invent defects to demonstrate iteration.** A confident "first pass clean, shipping" beats a fake fix.
- Mobile narrow
- Tablet or small laptop
- Desktop wide
Actively check: responsive behavior (composes, not shrinks), every state (empty / error / loading / edge), craft details (spacing, alignment, hierarchy, contrast, motion timing, focus), performance basics. The exit bar: defensible in a high-end studio review.
For each viewport, capture or inspect the rendered state and look for visual defects: overlap, clipping, weak hierarchy, off-grid alignment, awkward whitespace, cramped controls, unreadable type, broken imagery, hover-only functionality, layout shift, and text overflow.
### Critique and fix loop
After the first browser pass, write a short critique for yourself and patch the implementation. Repeat browser inspection after fixes. Continue until no material issues remain against this checklist:
1. **Does it match the brief?** Compare the live result against every section of the design brief. Fix discrepancies.
2. **Does it match the approved mock?** Compare screenshots against the mock fidelity inventory: hero silhouette, major motifs, imagery, nav/CTA, section sequence, density, color/materials, and second-fold substance. Missing major ingredients are P0 defects.
3. **Does it pass the AI slop test?** If someone saw this and said "AI made this," would they believe it immediately? If yes, it needs more design intention.
4. **Check against impeccable's DON'T guidelines.** Fix any anti-pattern violations.
5. **Check every state.** Navigate through empty, error, loading, and edge case states. Each one should feel intentional, not like an afterthought.
6. **Check responsive behavior.** The design should adapt compositionally, not merely shrink.
7. **Check craft details.** Spacing consistency, optical alignment, type hierarchy, color contrast, image quality, icon coherence, interactive feedback, motion timing, and focus treatment.
8. **Check performance basics.** No obviously oversized images, avoidable layout thrash, blocking animations, or heavy assets without a reason.
The exit bar is not "it works." It is: the rendered result looks intentional at all checked viewports, all expected states are handled, no placeholders remain unless explicitly accepted, and the implementation quality would be defensible in a high-end studio review.
Detector or QA output is defect evidence only; never proof the work is finished.
## Step 7: Present
@@ -189,5 +153,3 @@ Present the result to the user:
- Explain design decisions that connect back to the design brief and, when used, the chosen north-star mock. Include any accepted deviations from the mock; do not hide unimplemented mock ingredients.
- Note any remaining limitations or follow-up risks honestly
- Ask: "What's working? What isn't?"
Iterate based on feedback. Good design is rarely right on the first pass.
@@ -43,7 +43,7 @@ Run the bundled deterministic detector, which flags 27 specific patterns (AI slo
**CLI scan**:
```bash
npx impeccable --json [--fast] [target]
npx impeccable detect --json [--fast] [target]
```
- Pass HTML/JSX/TSX/Vue/Svelte files or directories as `[target]` (anything with markup). Do not pass CSS-only files.
@@ -2,6 +2,8 @@
Perform a meticulous final pass to catch all the small details that separate good work from great work. The difference between shipped and polished.
Detector and automated QA output are defect evidence only. A clean script result is never proof that the design is strong; gather browser evidence and inspect the real interaction path.
## Design System Discovery
Aligning the feature to the design system is **not optional**. Polish without alignment is decoration on top of drift, and it makes the next person's job harder. Discovery comes before any other polish work.
@@ -216,11 +218,12 @@ Sweat the details. Zoom in until the alignment is right and the spacing reads as
Before marking as done:
- **Use it yourself**: Actually interact with the feature
- **Test on real devices**: Not just browser DevTools
- **Ask someone else to review**: Fresh eyes catch things
- **Compare to design**: Match intended design
- **Check all states**: Don't just test happy path
- **Use it yourself**: Actually interact with the feature.
- **Test on real devices**: Not just browser DevTools.
- **Ask someone else to review**: Fresh eyes catch things.
- **Compare to design**: Match intended design.
- **Check all states**: Don't just test happy path.
- **Treat automation carefully**: Run detector or QA commands when they are available and relevant, fix their defects, but never cite a clean result as proof that the work is polished.
## Clean Up
@@ -230,4 +233,3 @@ After polishing, ensure code quality:
- **Remove orphaned code**: Delete unused styles, components, or files made obsolete by polish.
- **Consolidate tokens**: If you introduced new values, check whether they should be tokens.
- **Verify DRYness**: Look for duplication introduced during polishing and consolidate.
+25 -11
View File
@@ -16,14 +16,16 @@ This is a required interaction, not optional guidance. Ask these questions in co
### Interview cadence
Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed design inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
Discovery includes at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
- Use the harness's structured question tool when one exists. Otherwise, ask directly in chat and stop.
- Ask **2-3 questions per round**, then wait for answers.
- Treat PRODUCT.md and DESIGN.md as anchors; they reduce repeated questions but do **not** replace shape for craft. Shape is task-specific.
- Round 1 should clarify purpose, audience/context, and success or emotional outcome.
- Round 2 should clarify content/data/states and scope/fidelity.
- Round 3 should clarify visual direction, constraints, and anti-goals when still unresolved.
- One round is the default. Add a second only if the first answers leave material gaps. Don't run a second round just to feel thorough.
- Round 1 should clarify purpose, audience/context, content/scope, and (for brand) visual direction.
- Round 2, when needed, fills in whatever's still genuinely missing.
**Assert-then-confirm, not menu-with-escape.** When PRODUCT.md and the user's prompt make one option obvious, name it and ask the user to confirm or override. Don't enumerate "Restrained / Committed / Or something else?" as a real choice; "This reads as Restrained, confirm?" beats a four-option menu when the answer is already clear.
### Purpose & Context
- What is this feature for? What problem does it solve?
@@ -36,6 +38,7 @@ Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.
- What are the realistic ranges? (Minimum, typical, maximum, e.g., 0 items, 5 items, 500 items)
- What are the edge cases? (Empty state, error state, first-time use, power user)
- Is any content dynamic? What changes and how often?
- What visual assets are real content here? Note required images, product shots, illustrations, maps, textures, diagrams, generated objects, or existing project assets.
### Design Direction
@@ -72,9 +75,9 @@ After the discovery interview, generate a small set of visual direction probes *
- The work is **net-new** or directionally ambiguous enough that visual exploration will clarify the brief.
- The requested fidelity is **mid-fi, high-fi, or production-ready**. Skip for sketch-only planning.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The current harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool, or similar). Don't ask the user to install APIs or tooling.
When those conditions are met, this step is mandatory for Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
When those conditions are met, this step is mandatory. If image generation isn't natively available, skip silently and proceed; don't announce the skip.
Use probes to explore visual lanes, not to replace the brief.
@@ -104,11 +107,20 @@ The probes should differ in primary visual direction (hierarchy, topology, densi
- Do **not** treat generated imagery as final UX specification, final copy, or final accessibility behavior.
- Do **not** use this step for minor refinements of existing work. It's for shaping a new surface or clarifying a big directional choice.
If image generation is unavailable, or the task doesn't benefit from it, skip this phase only with a one-line reason and proceed directly to the design brief.
If image generation isn't natively available, skip this phase silently and proceed.
## Phase 2: Design Brief
After the interview and any required probes, synthesize everything into a structured design brief. Present it to the user for explicit confirmation before considering this command complete. Stop after asking for confirmation; do not proceed to craft or implementation in the same response unless the user has already approved the brief.
After the interview and any required probes, present a brief and **end your response**. The user must confirm before any implementation runs. Do not present a brief and then continue to code in the same response, even if the brief feels obvious to you. The user's confirmation is the gate.
**Choose the brief shape based on how clear the answers are:**
- **Compact form (3-5 bullets)** when discovery was crisp and the original prompt + PRODUCT.md already pinned scope, content, and direction. State what you're building, the visual lane, and end with one or two specific questions or a clear "confirm or override?" prompt. This is the default for typical craft requests with a clear prompt.
- **Full structured form (sections below)** when the task is genuinely ambiguous, multi-screen, or when the user asked for shape as a standalone step. Use this when the discipline of structure earns its weight.
Don't pad a clear brief into a long one to look thorough. A 70-line brief restating answers the user just gave is noise, not rigor. Equally, don't skip the confirmation pause to look efficient: the pause is the point.
If the user already said "approved" or "go" during discovery for the *exact direction you'd present*, that counts as confirmation; you may proceed without asking again. But if your brief adds anything the user hasn't seen and approved, you must stop and confirm.
### Brief Structure
@@ -136,16 +148,18 @@ List every state the feature needs: default, empty, loading, error, success, edg
How users interact with this feature. What happens on click, hover, scroll? What feedback do they get? What's the flow from entry to completion?
**8. Content Requirements**
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges.
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges. For image-led surfaces, also list the required image/media roles and their likely source (project asset, generated raster, semantic SVG/CSS, canvas/WebGL, icon library, or accepted omission).
**9. Recommended References**
Based on the brief, list which impeccable reference files would be most valuable during implementation (e.g., spatial-design.md for complex layouts, motion-design.md for animated features, interaction-design.md for form-heavy features).
**10. Open Questions**
Anything unresolved that the implementer should resolve during build.
Anything genuinely unresolved. Don't list "open questions" you've already recommended a default for; assert the default and move on. If you'd write `Recommend: X` next to a question, just decide X.
---
STOP and call the `question` tool to clarify. Ask for explicit confirmation of the brief before finishing. If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the brief is confirmed.
STOP and call the `question` tool to clarify.
If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the user confirms direction (or the user already gave a clear go during discovery, which counts).
Once confirmed, the brief is complete. The user can now hand it to /impeccable, or use it to guide any other implementation approach. (If the user wants the full discovery-then-build flow in one step, they should use /impeccable craft instead, which runs this command internally.)
+6 -19
View File
@@ -9,28 +9,15 @@ allowed-tools:
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
## Setup (non-optional)
## Setup
Before any design work or file edits, pass these gates. Skipping them produces generic output that ignores the project.
Before any design work or file edits:
| Gate | Required check | If fail |
|---|---|---|
| Context | The PRODUCT.md / DESIGN.md loader result is known from `node .pi/skills/impeccable/scripts/load-context.mjs`. | Run the loader before continuing. |
| Product | PRODUCT.md exists and is not empty or placeholder (`[TODO]` markers, <200 chars). | Run `/impeccable teach`, refresh context, then resume. Never synthesize PRODUCT.md from the user's original prompt alone. |
| Command | The matching command reference is loaded when a sub-command is used. | Load the reference before continuing. |
| Craft | `/impeccable craft` has a user-confirmed shape brief for this task. `teach` / PRODUCT.md never counts as shape. | Run `/impeccable shape` and wait for explicit brief confirmation. |
| Image | Required visual probes / mocks are generated or skipped with a reason. | Resolve the image-generation gate in `shape.md` or `craft.md` before code. |
| Mutation | All active gates above pass. | Do not edit project files yet. |
1. Load context (PRODUCT.md / DESIGN.md) via the loader script.
2. Identify the register and load the matching register reference (brand.md or product.md).
3. **If the user invoked a sub-command (e.g. `craft`, `shape`, `audit`), load its reference file too.** This is non-negotiable: `craft` without `craft.md` loaded means you'll skip the shape-and-confirm step the user expects.
Codex-style agents must state this before editing files:
```text
IMPECCABLE_PREFLIGHT: context=pass product=pass command_reference=pass shape=pass|not_required image_gate=pass|skipped:<reason> mutation=open
```
For `/impeccable craft`, `shape=pass` is only valid after a separate user response approving the shape design brief, or when the user provided an already-confirmed brief in the request. Do not mark `shape=pass` after writing PRODUCT.md, summarizing assumptions, or drafting an unconfirmed brief yourself.
Other harnesses should follow the same checklist when they can expose this state.
Skipping these produces generic output that ignores the project.
### 1. Context gathering
+7 -3
View File
@@ -12,6 +12,8 @@ Brand isn't a neutral register. AI-generated landing pages have flooded the inte
**The second slop test: aesthetic lane.** Before committing to moves, name the reference. A Klim-style specimen page is one lane; Stripe-minimal is another; Liquid-Death-acid-maximalism is another. Don't drift into editorial-magazine aesthetics on a brief that isn't editorial. A hiking brand with Cormorant italic drop caps has the wrong register within the register.
Then the inverse test: in one sentence, describe what you're about to build the way a competitor would describe theirs. If that sentence fits the modal landing page in the category, restart.
## Typography
### Font selection procedure
@@ -66,6 +68,7 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
- Palette IS voice. A calm brand and a restless brand should not share palette mechanics.
- When the strategy is Committed or Drenched, color carries the brand. Don't hedge with neutrals around the edges. Commit.
- Don't converge across projects. If the last brand surface was restrained-on-cream, this one is not.
- When a cultural-symbol palette is the obvious pull, reach past it. Let the cultural reading come from typography, imagery, and copy, not the palette.
## Layout
@@ -79,14 +82,14 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
Brand surfaces lean on imagery. A restaurant, hotel, magazine, or product landing page without any imagery reads as incomplete, not as restrained. A solid-color rectangle where a hero image should go is worse than a representative stock photo.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse. If the approved comp or brief is image-led, ship real project assets, generated raster assets, or a credible canvas/SVG/WebGL scene. Do not replace photographic, architectural, product, or place imagery with generic CSS panels, decorative diagrams, cards, bullets, or copy.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. Pick real Unsplash photo IDs you're confident exist (`photo-1559339352-11d035aa65de`, `photo-1590490360182-c33d57733427`, etc.); if unsure, pick fewer photos but don't substitute colored `<div>` placeholders.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. **Verify the URLs before referencing them.** If you have an image-search MCP, web-fetch tool, or browser access, use it to find real photo IDs and confirm they resolve. Guessed IDs (even ones that look real) often 404 and ship as broken-image placeholders. Without a verification path, pick fewer photos you're confident exist over more that you guessed; never substitute colored `<div>` placeholders.
- **Search for the brand's physical object**, not the generic category: "handmade pasta on a scratched wooden table" beats "Italian food"; "cypress trees above a limestone hotel facade at dusk" beats "luxury hotel".
- **One decisive photo beats five mediocre ones.** Hero imagery should commit to a mood; padding with more stock doesn't rescue an indecisive one.
- **Alt text is part of the voice.** "Coastal fettuccine, hand-cut, served on the terrace" beats "pasta dish".
Tech / dev-tool brands are the exception where zero imagery can be correct; a developer landing page often carries its voice through typography, code samples, diagrams. Know which kind of brand you're working on.
"Imagery" here is broader than stock photography: product screenshots, custom data visualizations, generated SVG, and canvas/WebGL scenes are all imagery. Text-only pages where typography alone carries the entire visual weight are the failure mode.
## Motion
@@ -102,6 +105,7 @@ Tech / dev-tool brands are the exception where zero imagery can be correct; a de
- Timid palettes and average layouts. Safe = invisible.
- Zero imagery on a brief that implies imagery (restaurant, hotel, food, travel, fashion, photography, hobbyist). Colored blocks where a hero photo belongs.
- Defaulting to editorial-magazine aesthetics (display serif + italic + drop caps + broadsheet grid) on briefs that aren't magazine-shaped. Editorial is ONE aesthetic lane, not the default brand aesthetic.
- Repeated tiny uppercase tracked labels above every section heading. A single strong kicker can be voice; repeating it as section grammar is AI scaffolding unless it's a deliberate, named brand system.
## Brand permissions
+73 -111
View File
@@ -1,43 +1,41 @@
# Craft Flow
Build a feature with impeccable UX and UI quality through a structured process: shape the design, land the visual direction, build real production code, then inspect and improve in-browser until the result meets a high-end studio bar.
Build a feature with impeccable UX and UI quality: shape the design, land the visual direction, build real production code, inspect and improve in-browser until it meets a high-end studio bar.
## Build Gate
Before writing code, you need: PRODUCT.md loaded, register identified and the matching reference loaded, and a confirmed design direction for this task (either from `shape` or supplied by the user). PRODUCT.md is project context, not a task-specific brief.
Craft cannot build until all of these are true:
Treat any approved visual direction (generated mock or stated reference) as a concrete contract for composition, hierarchy, density, atmosphere, signature motifs, and distinctive visual moves. Don't let mocks replace structure, copy, accessibility, or state design. But if the live result lacks the approved direction's major ingredients, the implementation is wrong.
1. PRODUCT context is valid and current.
2. The shape design brief is explicitly confirmed by the user for this task, unless the user already provided a confirmed brief.
3. Implementation references from the brief are loaded.
4. The shape visual probe decision is recorded: generated, skipped with reason, or already resolved.
5. The north-star mock decision is recorded: generated, skipped with reason, or not applicable.
## Step 0: Project Foundation
PRODUCT.md and `teach` answers do **not** satisfy the shape gate. They are project context only. A compact self-authored brief does not satisfy the shape gate either. `shape=pass` requires a separate user response approving the shape brief or an already-confirmed brief supplied by the user.
Before shape, before code: figure out what kind of project you're working in.
Invalid image-skip reasons include: "the final implementation will be semantic HTML/CSS/SVG", "the diagram should stay editable", "a raster mock would not be used directly", or "the product is fictional." Generated probes and mocks are direction artifacts; they are not implementation assets.
Look at the working directory. Run `ls`. Check for:
## Craft Contract
- An existing framework: `astro.config.mjs/ts`, `next.config.js/ts`, `nuxt.config.ts`, `svelte.config.js`, `vite.config.js/ts`, `package.json` with framework deps, `Cargo.toml` + Leptos/Yew, `Gemfile` + Rails. **If found, use it.** Do not start a parallel build, do not introduce a second framework, do not write to `dist/` or `build/` directly. Whatever pipeline the project has, respect it.
- An existing component library or design system: `src/components/`, `app/components/`, a `tokens.css` / `theme.ts`, an `astro.config` `integrations`. Read what's there before adding to it.
- An existing icon set: `lucide-react`, `@phosphor-icons/react`, `@iconify/*`, hand-rolled SVG sprites in `assets/icons/`. **Use what's already in the project**; don't introduce a second set.
Craft is not a first pass. It is a loop with these required artifacts:
If the directory is empty (greenfield), don't pick a framework silently. Ask the user via the AskUserQuestion tool, with sensible defaults framed by the brief:
1. Confirmed design brief from `shape`.
2. Approved visual direction, from generated probes / mocks when image generation is available.
3. Mock fidelity inventory: the visible ingredients from the approved direction that must survive into code.
4. Semantic, functional implementation using the project's real stack and conventions.
5. Browser evidence across relevant viewports.
6. At least one critique-and-fix pass after the first browser inspection, unless the first pass has no material defects.
```text
What should this be built on?
- Astro (default for content-led brand sites, landing pages, marketing surfaces)
- SvelteKit / Next.js / Nuxt (when the brief implies an app surface or significant interactivity)
- Single index.html (one-shot demo, prototype, or a deliberately framework-free experiment)
```
Do not let generated mockups replace interface structure, copy, accessibility, responsive behavior, or state design. But do treat the approved mock as a concrete visual contract for composition, hierarchy, density, atmosphere, signature motifs, image needs, and distinctive visual moves. "North star" means "preserve the important visible ingredients in semantic code," not "use it as loose mood."
Default: Astro for brand briefs, the project's existing framework for product briefs. Ask once; don't re-ask mid-task.
## Step 1: Shape the Design
Run /impeccable shape, passing along whatever feature description the user provided.
Run /impeccable shape, passing along whatever feature description the user provided. Shape is **required** for craft; it is what produces a confirmed direction.
Wait for the design brief to be fully confirmed by the user before proceeding. The brief is your blueprint, and every implementation decision should trace back to it.
Present the shape output and stop. Wait for the user to confirm, override, or course-correct before writing code.
If this craft run resumed after `teach` created PRODUCT.md, run shape now. Do not treat the teach interview, PRODUCT.md, or a summary of project context as a substitute for shape. Shape is task-specific and must cover scope, content/states, visual direction, constraints, anti-goals, probes when applicable, and explicit brief confirmation.
If the user already supplied a confirmed brief or ran shape separately, use it and skip this step.
If the user has already run /impeccable shape and has a confirmed design brief, skip this step and use the existing brief.
When the original prompt + PRODUCT.md already answer scope, content, and visual direction with no real ambiguity, the shape output can be **compact** (3-5 bullets stating what you're building and the visual lane, ending with one or two specific questions or "confirm or override"). The full 10-section structured brief is reserved for genuinely ambiguous, multi-screen, or stakeholder-heavy tasks. Don't pad a clear brief into a long one to look thorough; equally, don't skip the pause to look efficient.
## Step 2: Load References
@@ -55,79 +53,60 @@ Then add references based on the brief's needs:
## Step 3: Land the Visual Direction (Capability-Gated)
Before implementation, generate high-fidelity visual comps when all of these are true:
Generate high-fidelity visual comps before implementation when all three are true:
- The work is **net-new** or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is **mid-fi, high-fi, or production-ready**.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The work is net-new or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is mid-fi, high-fi, or production-ready.
- The harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool). Don't ask the user to set up external APIs.
When those conditions are met, this step is mandatory for **both brand and product work** in Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
Do not skip this step because the eventual UI should be semantic, editable, code-native, responsive, or accessible. Those are implementation requirements, not reasons to avoid visual exploration.
### Purpose
Use the mock step to find a stronger visual lane than code-first generation would reliably discover on its own. The brief remains authoritative on user, purpose, content, constraints, states, and anti-goals. The mock clarifies composition, hierarchy, density, typography, and visual tone.
When met, this step is mandatory for both brand and product work. If image generation isn't available, skip silently. "The eventual UI is semantic/code-native/accessible" is not a reason to skip; those are implementation requirements, not exploration ones.
### What to generate
Generate **1 to 3** high-fidelity north-star comps based on the confirmed brief. If shape already produced direction probes, use those results as input and generate a more resolved mock from the winning lane, not another unrelated exploration.
Generate **1 to 3** high-fidelity north-star comps from the confirmed brief. If shape already produced direction probes, resolve the winning lane further, not an unrelated exploration. Comps must differ in primary visual direction, not just color.
- For brand work, push visual identity, composition, and mood aggressively.
- For product work, still push hierarchy, topology, density, and tone, but keep the comps grounded in realistic product structure and states.
- For landing pages and long-form brand surfaces, show enough of the next section or second fold to establish the system beyond the hero.
The comps must be genuinely different in primary visual direction, not just color variants.
- Brand work: push visual identity, composition, and mood aggressively.
- Product work: push hierarchy, topology, density, tone, grounded in realistic product structure.
- Landing pages and long-form brand surfaces: show enough of the second fold to establish the system beyond the hero.
### Approval loop
Show the comps and ask what should carry forward. If the user asks for changes or the best direction is still weak, generate a focused revision before implementation. Continue until one direction is approved, or until the user explicitly delegates the choice.
Show the comps and ask what carries forward. Iterate until one direction is approved or the user delegates. If the user delegates, pick the strongest direction and explain it from the brief, not personal taste.
If the user delegates, pick the strongest direction and explain the decision using the brief, not personal taste.
Before moving to implementation, summarize:
- What to carry into code
- What **not** to literalize from the mock
This summary is required before Step 4. It is the handoff between visual exploration and semantic implementation.
Before Step 4, summarize what to carry into code and what **not** to literalize from the mock. This is the handoff between visual exploration and semantic implementation.
### Mock fidelity inventory
Before building, inventory the approved mock's major visible ingredients:
Inventory the approved mock's major visible ingredients:
- Hero silhouette and dominant composition.
- Signature motifs: planets, devices, portraits, charts, route lines, insets, badges, or other memorable objects.
- Nav and primary CTA treatment.
- Section sequence visible in the mock, especially the second fold.
- Image-native content the concept depends on.
- Typography, density, color/material treatment, and motion cues.
- Hero silhouette and dominant composition
- Signature motifs (planets, devices, portraits, charts, route lines, insets, badges, etc.)
- Nav and primary CTA treatment
- Section sequence, especially the second fold
- Image-native content the concept depends on
- Typography, density, color/material treatment, motion cues
For each ingredient, decide how it will be implemented: semantic HTML/CSS/SVG, generated asset, sourced project asset, icon library, canvas/WebGL, or an explicitly accepted omission. Do not substitute a different hero composition or new visual driver after approval unless the user approves the change.
For each, decide implementation: semantic HTML/CSS/SVG, generated asset, sourced asset, icon library, canvas/WebGL, or accepted omission. Don't substitute a different hero composition or visual driver post-approval without user sign-off.
Treat the mock as a **north star**, not a screenshot to trace. Do **not** rasterize core UI text or let the mock override the confirmed brief. But if the live result lacks the mock's major visible ingredients, the implementation is wrong.
If a photographic, architectural, product, or place-led mock becomes generic CSS scenery / decorative diagrams / bullets / copy, stop and fix it. That's a broken implementation, not a harmless interpretation.
Treat the mock as a north star, not a screenshot to trace. Don't rasterize core UI text. But if the live result lacks the mock's major ingredients, the implementation is wrong.
## Step 4: Asset Extraction (Need-Gated)
If the chosen direction includes image-native visual ingredients that would materially improve the implementation, generate them as separate assets before building.
If the approved direction needs raster assets, create them before building. Do not replace required imagery with generic cards, bullets, emoji, fake metrics, decorative CSS panels, or filler copy.
Good candidates:
Use the native asset producer (`impeccable_asset_producer` in Codex, `impeccable-asset-producer` in Claude Code) to create clean assets from the hi-fi mock and crops. If you do not have explicit permission to use agents, stop and ask:
- stickers
- badges
- seals
- tickets
- graphic labels
- textures
- abstract objects
- decorative marks
- non-semantic scene elements
```text
Asset production will work better as a scoped subagent job. Should I spawn the Impeccable asset producer subagent for this step?
```
For travel, editorial, portfolio, venue, product showcase, entertainment, education, or any other image-led brand surface, visual assets are usually core content, not decoration. Do not ship abstract CSS panels where the approved mock or subject matter calls for real imagery, generated plates, illustrations, maps, product/object renders, or destination scenes.
Do not skip asset production or silently do it inline. Inline asset production is allowed only if the user declines subagents, the harness cannot spawn the authorized agent, or the user explicitly asks for single-thread mode.
Do **not** export assets for core UI text, navigation, body copy, or any structure that should stay semantic and editable in code.
Pass the approved mock, crop/contact-sheet paths, output directory, dimensions/formats, transparency needs, constraints, and avoid list to the asset producer. Attach image generation capability to the spawned agent when the harness supports it; do not load image-generation reference material into the parent thread first.
Usually **1 to 5** extracted assets is enough. If the design can be built cleanly in HTML/CSS/SVG, prefer that over raster assets. If the mock contains major visual content that cannot be built credibly in code, asset extraction is not optional.
Prefer HTML/CSS/SVG/canvas when they can credibly reproduce an ingredient; use real/generated/stock imagery when the mock or subject matter calls for actual visual content.
## Step 5: Build to Production Quality
@@ -135,50 +114,35 @@ Implement the feature following the design brief. Build in passes so structure,
### Production bar
- Use real or realistic content. Remove placeholder copy, placeholder images, dead links, fake controls, and unused scaffold before presenting.
- Preserve the approved mock's major ingredients. Missing hero objects, missing world/product imagery, different section structure, downgraded CTA/nav treatment, or generic replacements for distinctive motifs are blocking defects unless the user accepted the change.
- Build semantically first: real headings, landmarks, labels, form associations, button/link semantics, accessible names, and state announcements where needed.
- Calibrate spacing, alignment, grid placement, and vertical rhythm deliberately. Do not accept default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- Make typography intentional: chosen font loading strategy, clear hierarchy, readable measure, stable line breaks, tuned wrapping, and no overflow at mobile or large desktop sizes.
- Design realistic state coverage: default, hover where supported, focus-visible, active, disabled, loading, error, success, empty, overflow, long text, short text, and first-run states where relevant.
- Make interaction quality feel finished: keyboard paths, touch targets, feedback timing, scroll behavior, transitions between states, and no hover-only functionality.
- Use icons from the project's established icon set when available. If no set exists, choose a coherent library or use accessible text controls; do not mix unrelated icon styles.
- Optimize imagery and media: correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset` / `picture` for raster assets, and no project-referenced asset left outside the workspace.
- Make motion feel premium: use atmospheric blur, filter, mask, shadow, or reveal effects when they improve the experience; avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- Preserve maintainability: reusable local patterns, clear component boundaries, project conventions, no rasterized UI text, and no hard-coded one-off hacks when a better local pattern exists.
- Fit the technical context: production build passes, no obvious console errors, no avoidable layout shift, no needless dependency, and no broken asset path.
- If you discover a design question that materially changes the brief or approved direction, stop and ask rather than guessing.
- **Real content.** No placeholder copy, placeholder images, dead links, fake controls, or unused scaffold at presentation time.
- **Preserve the approved mock's major ingredients.** Missing hero objects, world/product imagery, section structure, CTA/nav treatment, or distinctive motifs are blocking defects unless the user accepted the change.
- **Semantic first.** Real headings, landmarks, labels, form associations, button/link semantics, accessible names, state announcements where needed.
- **Deliberate spacing and alignment.** No default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- **Intentional typography.** Chosen loading strategy, clear hierarchy, readable measure, stable line breaks, no overflow at any width.
- **Realistic state coverage.** Default, hover, focus-visible, active, disabled, loading, error, success, empty, overflow, long/short text, first-run.
- **Finished interaction quality.** Keyboard paths, touch targets, feedback timing, scroll behavior, state transitions, no hover-only functionality.
- **Coherent icon set.** Use the project's established set; otherwise pick one library or use accessible text. Don't mix.
- **Respect the build pipeline.** Edit source files and run the project's build (`npm run build` or equivalent). Don't write to `build/` / `dist/` / `.next/` with `cat`, heredoc, or Bash redirects; that skips asset hashing, image optimization, code splitting, and CSS extraction, and produces output the dev server won't serve.
- **Verify image URLs before referencing them.** Use image-search MCP or web-fetch when available; guessed photo IDs ship as broken-image placeholders. Without verification, prefer fewer images you're confident about.
- **Optimized imagery and media.** Correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset`/`picture` for raster, no project-referenced asset left outside the workspace.
- **Premium motion.** Use atmospheric blur, filter, mask, shadow, reveal when they improve the experience. Avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- **Maintainable.** Reusable local patterns, clear component boundaries, project conventions. No rasterized UI text or one-off hacks when a local pattern exists.
- **Technically clean.** Production build passes, no console errors, no avoidable layout shift, no needless dependencies, no broken asset paths.
- **Ask when uncertain.** If a discovery materially changes the brief or approved direction, stop and ask. Don't guess.
## Step 6: Browser-Based Iteration
## Step 6: Iterate Visually
**This step is critical.** Do not stop after the first implementation pass.
Look at what you built like a designer would. Your eyes are whatever the harness gives you: a connected browser, a screenshotting tool, Playwright, or asking the user. Use them for responsive testing (mobile, tablet, desktop minimum) and general visual validation.
Open the result in a browser. In Codex, use browser-use or equivalent browser automation when available; otherwise use Playwright or ask the user for screenshots. Inspect screenshots, not just DOM or terminal output.
If your tool returns a file path, read the PNG back into the conversation. A screenshot you didn't read doesn't count.
### Required viewport pass
For long-form brand surfaces, inspect major sections individually. Thumbnails hide spacing, clipping, and cascade defects.
Check the experience at the viewports that matter for the brief. Default minimum:
After the first pass, write an honest critique against the brief, the approved mock's major ingredients (hero silhouette, motifs, imagery, nav/CTA, density), and impeccable's DON'Ts. Patch material defects and re-inspect. **Don't invent defects to demonstrate iteration.** A confident "first pass clean, shipping" beats a fake fix.
- Mobile narrow
- Tablet or small laptop
- Desktop wide
Actively check: responsive behavior (composes, not shrinks), every state (empty / error / loading / edge), craft details (spacing, alignment, hierarchy, contrast, motion timing, focus), performance basics. The exit bar: defensible in a high-end studio review.
For each viewport, capture or inspect the rendered state and look for visual defects: overlap, clipping, weak hierarchy, off-grid alignment, awkward whitespace, cramped controls, unreadable type, broken imagery, hover-only functionality, layout shift, and text overflow.
### Critique and fix loop
After the first browser pass, write a short critique for yourself and patch the implementation. Repeat browser inspection after fixes. Continue until no material issues remain against this checklist:
1. **Does it match the brief?** Compare the live result against every section of the design brief. Fix discrepancies.
2. **Does it match the approved mock?** Compare screenshots against the mock fidelity inventory: hero silhouette, major motifs, imagery, nav/CTA, section sequence, density, color/materials, and second-fold substance. Missing major ingredients are P0 defects.
3. **Does it pass the AI slop test?** If someone saw this and said "AI made this," would they believe it immediately? If yes, it needs more design intention.
4. **Check against impeccable's DON'T guidelines.** Fix any anti-pattern violations.
5. **Check every state.** Navigate through empty, error, loading, and edge case states. Each one should feel intentional, not like an afterthought.
6. **Check responsive behavior.** The design should adapt compositionally, not merely shrink.
7. **Check craft details.** Spacing consistency, optical alignment, type hierarchy, color contrast, image quality, icon coherence, interactive feedback, motion timing, and focus treatment.
8. **Check performance basics.** No obviously oversized images, avoidable layout thrash, blocking animations, or heavy assets without a reason.
The exit bar is not "it works." It is: the rendered result looks intentional at all checked viewports, all expected states are handled, no placeholders remain unless explicitly accepted, and the implementation quality would be defensible in a high-end studio review.
Detector or QA output is defect evidence only; never proof the work is finished.
## Step 7: Present
@@ -189,5 +153,3 @@ Present the result to the user:
- Explain design decisions that connect back to the design brief and, when used, the chosen north-star mock. Include any accepted deviations from the mock; do not hide unimplemented mock ingredients.
- Note any remaining limitations or follow-up risks honestly
- Ask: "What's working? What isn't?"
Iterate based on feedback. Good design is rarely right on the first pass.
+1 -1
View File
@@ -43,7 +43,7 @@ Run the bundled deterministic detector, which flags 27 specific patterns (AI slo
**CLI scan**:
```bash
npx impeccable --json [--fast] [target]
npx impeccable detect --json [--fast] [target]
```
- Pass HTML/JSX/TSX/Vue/Svelte files or directories as `[target]` (anything with markup). Do not pass CSS-only files.
+8 -6
View File
@@ -2,6 +2,8 @@
Perform a meticulous final pass to catch all the small details that separate good work from great work. The difference between shipped and polished.
Detector and automated QA output are defect evidence only. A clean script result is never proof that the design is strong; gather browser evidence and inspect the real interaction path.
## Design System Discovery
Aligning the feature to the design system is **not optional**. Polish without alignment is decoration on top of drift, and it makes the next person's job harder. Discovery comes before any other polish work.
@@ -216,11 +218,12 @@ Sweat the details. Zoom in until the alignment is right and the spacing reads as
Before marking as done:
- **Use it yourself**: Actually interact with the feature
- **Test on real devices**: Not just browser DevTools
- **Ask someone else to review**: Fresh eyes catch things
- **Compare to design**: Match intended design
- **Check all states**: Don't just test happy path
- **Use it yourself**: Actually interact with the feature.
- **Test on real devices**: Not just browser DevTools.
- **Ask someone else to review**: Fresh eyes catch things.
- **Compare to design**: Match intended design.
- **Check all states**: Don't just test happy path.
- **Treat automation carefully**: Run detector or QA commands when they are available and relevant, fix their defects, but never cite a clean result as proof that the work is polished.
## Clean Up
@@ -230,4 +233,3 @@ After polishing, ensure code quality:
- **Remove orphaned code**: Delete unused styles, components, or files made obsolete by polish.
- **Consolidate tokens**: If you introduced new values, check whether they should be tokens.
- **Verify DRYness**: Look for duplication introduced during polishing and consolidate.
+25 -11
View File
@@ -16,14 +16,16 @@ This is a required interaction, not optional guidance. Ask these questions in co
### Interview cadence
Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed design inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
Discovery includes at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
- Use the harness's structured question tool when one exists. Otherwise, ask directly in chat and stop.
- Ask **2-3 questions per round**, then wait for answers.
- Treat PRODUCT.md and DESIGN.md as anchors; they reduce repeated questions but do **not** replace shape for craft. Shape is task-specific.
- Round 1 should clarify purpose, audience/context, and success or emotional outcome.
- Round 2 should clarify content/data/states and scope/fidelity.
- Round 3 should clarify visual direction, constraints, and anti-goals when still unresolved.
- One round is the default. Add a second only if the first answers leave material gaps. Don't run a second round just to feel thorough.
- Round 1 should clarify purpose, audience/context, content/scope, and (for brand) visual direction.
- Round 2, when needed, fills in whatever's still genuinely missing.
**Assert-then-confirm, not menu-with-escape.** When PRODUCT.md and the user's prompt make one option obvious, name it and ask the user to confirm or override. Don't enumerate "Restrained / Committed / Or something else?" as a real choice; "This reads as Restrained, confirm?" beats a four-option menu when the answer is already clear.
### Purpose & Context
- What is this feature for? What problem does it solve?
@@ -36,6 +38,7 @@ Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.
- What are the realistic ranges? (Minimum, typical, maximum, e.g., 0 items, 5 items, 500 items)
- What are the edge cases? (Empty state, error state, first-time use, power user)
- Is any content dynamic? What changes and how often?
- What visual assets are real content here? Note required images, product shots, illustrations, maps, textures, diagrams, generated objects, or existing project assets.
### Design Direction
@@ -72,9 +75,9 @@ After the discovery interview, generate a small set of visual direction probes *
- The work is **net-new** or directionally ambiguous enough that visual exploration will clarify the brief.
- The requested fidelity is **mid-fi, high-fi, or production-ready**. Skip for sketch-only planning.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The current harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool, or similar). Don't ask the user to install APIs or tooling.
When those conditions are met, this step is mandatory for Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
When those conditions are met, this step is mandatory. If image generation isn't natively available, skip silently and proceed; don't announce the skip.
Use probes to explore visual lanes, not to replace the brief.
@@ -104,11 +107,20 @@ The probes should differ in primary visual direction (hierarchy, topology, densi
- Do **not** treat generated imagery as final UX specification, final copy, or final accessibility behavior.
- Do **not** use this step for minor refinements of existing work. It's for shaping a new surface or clarifying a big directional choice.
If image generation is unavailable, or the task doesn't benefit from it, skip this phase only with a one-line reason and proceed directly to the design brief.
If image generation isn't natively available, skip this phase silently and proceed.
## Phase 2: Design Brief
After the interview and any required probes, synthesize everything into a structured design brief. Present it to the user for explicit confirmation before considering this command complete. Stop after asking for confirmation; do not proceed to craft or implementation in the same response unless the user has already approved the brief.
After the interview and any required probes, present a brief and **end your response**. The user must confirm before any implementation runs. Do not present a brief and then continue to code in the same response, even if the brief feels obvious to you. The user's confirmation is the gate.
**Choose the brief shape based on how clear the answers are:**
- **Compact form (3-5 bullets)** when discovery was crisp and the original prompt + PRODUCT.md already pinned scope, content, and direction. State what you're building, the visual lane, and end with one or two specific questions or a clear "confirm or override?" prompt. This is the default for typical craft requests with a clear prompt.
- **Full structured form (sections below)** when the task is genuinely ambiguous, multi-screen, or when the user asked for shape as a standalone step. Use this when the discipline of structure earns its weight.
Don't pad a clear brief into a long one to look thorough. A 70-line brief restating answers the user just gave is noise, not rigor. Equally, don't skip the confirmation pause to look efficient: the pause is the point.
If the user already said "approved" or "go" during discovery for the *exact direction you'd present*, that counts as confirmation; you may proceed without asking again. But if your brief adds anything the user hasn't seen and approved, you must stop and confirm.
### Brief Structure
@@ -136,16 +148,18 @@ List every state the feature needs: default, empty, loading, error, success, edg
How users interact with this feature. What happens on click, hover, scroll? What feedback do they get? What's the flow from entry to completion?
**8. Content Requirements**
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges.
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges. For image-led surfaces, also list the required image/media roles and their likely source (project asset, generated raster, semantic SVG/CSS, canvas/WebGL, icon library, or accepted omission).
**9. Recommended References**
Based on the brief, list which impeccable reference files would be most valuable during implementation (e.g., spatial-design.md for complex layouts, motion-design.md for animated features, interaction-design.md for form-heavy features).
**10. Open Questions**
Anything unresolved that the implementer should resolve during build.
Anything genuinely unresolved. Don't list "open questions" you've already recommended a default for; assert the default and move on. If you'd write `Recommend: X` next to a question, just decide X.
---
ask the user directly to clarify what you cannot infer. Ask for explicit confirmation of the brief before finishing. If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the brief is confirmed.
ask the user directly to clarify what you cannot infer.
If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the user confirms direction (or the user already gave a clear go during discovery, which counts).
Once confirmed, the brief is complete. The user can now hand it to /impeccable, or use it to guide any other implementation approach. (If the user wants the full discovery-then-build flow in one step, they should use /impeccable craft instead, which runs this command internally.)
+6 -19
View File
@@ -11,28 +11,15 @@ allowed-tools:
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
## Setup (non-optional)
## Setup
Before any design work or file edits, pass these gates. Skipping them produces generic output that ignores the project.
Before any design work or file edits:
| Gate | Required check | If fail |
|---|---|---|
| Context | The PRODUCT.md / DESIGN.md loader result is known from `node .qoder/skills/impeccable/scripts/load-context.mjs`. | Run the loader before continuing. |
| Product | PRODUCT.md exists and is not empty or placeholder (`[TODO]` markers, <200 chars). | Run `/impeccable teach`, refresh context, then resume. Never synthesize PRODUCT.md from the user's original prompt alone. |
| Command | The matching command reference is loaded when a sub-command is used. | Load the reference before continuing. |
| Craft | `/impeccable craft` has a user-confirmed shape brief for this task. `teach` / PRODUCT.md never counts as shape. | Run `/impeccable shape` and wait for explicit brief confirmation. |
| Image | Required visual probes / mocks are generated or skipped with a reason. | Resolve the image-generation gate in `shape.md` or `craft.md` before code. |
| Mutation | All active gates above pass. | Do not edit project files yet. |
1. Load context (PRODUCT.md / DESIGN.md) via the loader script.
2. Identify the register and load the matching register reference (brand.md or product.md).
3. **If the user invoked a sub-command (e.g. `craft`, `shape`, `audit`), load its reference file too.** This is non-negotiable: `craft` without `craft.md` loaded means you'll skip the shape-and-confirm step the user expects.
Codex-style agents must state this before editing files:
```text
IMPECCABLE_PREFLIGHT: context=pass product=pass command_reference=pass shape=pass|not_required image_gate=pass|skipped:<reason> mutation=open
```
For `/impeccable craft`, `shape=pass` is only valid after a separate user response approving the shape design brief, or when the user provided an already-confirmed brief in the request. Do not mark `shape=pass` after writing PRODUCT.md, summarizing assumptions, or drafting an unconfirmed brief yourself.
Other harnesses should follow the same checklist when they can expose this state.
Skipping these produces generic output that ignores the project.
### 1. Context gathering
+7 -3
View File
@@ -12,6 +12,8 @@ Brand isn't a neutral register. AI-generated landing pages have flooded the inte
**The second slop test: aesthetic lane.** Before committing to moves, name the reference. A Klim-style specimen page is one lane; Stripe-minimal is another; Liquid-Death-acid-maximalism is another. Don't drift into editorial-magazine aesthetics on a brief that isn't editorial. A hiking brand with Cormorant italic drop caps has the wrong register within the register.
Then the inverse test: in one sentence, describe what you're about to build the way a competitor would describe theirs. If that sentence fits the modal landing page in the category, restart.
## Typography
### Font selection procedure
@@ -66,6 +68,7 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
- Palette IS voice. A calm brand and a restless brand should not share palette mechanics.
- When the strategy is Committed or Drenched, color carries the brand. Don't hedge with neutrals around the edges. Commit.
- Don't converge across projects. If the last brand surface was restrained-on-cream, this one is not.
- When a cultural-symbol palette is the obvious pull, reach past it. Let the cultural reading come from typography, imagery, and copy, not the palette.
## Layout
@@ -79,14 +82,14 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
Brand surfaces lean on imagery. A restaurant, hotel, magazine, or product landing page without any imagery reads as incomplete, not as restrained. A solid-color rectangle where a hero image should go is worse than a representative stock photo.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse. If the approved comp or brief is image-led, ship real project assets, generated raster assets, or a credible canvas/SVG/WebGL scene. Do not replace photographic, architectural, product, or place imagery with generic CSS panels, decorative diagrams, cards, bullets, or copy.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. Pick real Unsplash photo IDs you're confident exist (`photo-1559339352-11d035aa65de`, `photo-1590490360182-c33d57733427`, etc.); if unsure, pick fewer photos but don't substitute colored `<div>` placeholders.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. **Verify the URLs before referencing them.** If you have an image-search MCP, web-fetch tool, or browser access, use it to find real photo IDs and confirm they resolve. Guessed IDs (even ones that look real) often 404 and ship as broken-image placeholders. Without a verification path, pick fewer photos you're confident exist over more that you guessed; never substitute colored `<div>` placeholders.
- **Search for the brand's physical object**, not the generic category: "handmade pasta on a scratched wooden table" beats "Italian food"; "cypress trees above a limestone hotel facade at dusk" beats "luxury hotel".
- **One decisive photo beats five mediocre ones.** Hero imagery should commit to a mood; padding with more stock doesn't rescue an indecisive one.
- **Alt text is part of the voice.** "Coastal fettuccine, hand-cut, served on the terrace" beats "pasta dish".
Tech / dev-tool brands are the exception where zero imagery can be correct; a developer landing page often carries its voice through typography, code samples, diagrams. Know which kind of brand you're working on.
"Imagery" here is broader than stock photography: product screenshots, custom data visualizations, generated SVG, and canvas/WebGL scenes are all imagery. Text-only pages where typography alone carries the entire visual weight are the failure mode.
## Motion
@@ -102,6 +105,7 @@ Tech / dev-tool brands are the exception where zero imagery can be correct; a de
- Timid palettes and average layouts. Safe = invisible.
- Zero imagery on a brief that implies imagery (restaurant, hotel, food, travel, fashion, photography, hobbyist). Colored blocks where a hero photo belongs.
- Defaulting to editorial-magazine aesthetics (display serif + italic + drop caps + broadsheet grid) on briefs that aren't magazine-shaped. Editorial is ONE aesthetic lane, not the default brand aesthetic.
- Repeated tiny uppercase tracked labels above every section heading. A single strong kicker can be voice; repeating it as section grammar is AI scaffolding unless it's a deliberate, named brand system.
## Brand permissions
+73 -111
View File
@@ -1,43 +1,41 @@
# Craft Flow
Build a feature with impeccable UX and UI quality through a structured process: shape the design, land the visual direction, build real production code, then inspect and improve in-browser until the result meets a high-end studio bar.
Build a feature with impeccable UX and UI quality: shape the design, land the visual direction, build real production code, inspect and improve in-browser until it meets a high-end studio bar.
## Build Gate
Before writing code, you need: PRODUCT.md loaded, register identified and the matching reference loaded, and a confirmed design direction for this task (either from `shape` or supplied by the user). PRODUCT.md is project context, not a task-specific brief.
Craft cannot build until all of these are true:
Treat any approved visual direction (generated mock or stated reference) as a concrete contract for composition, hierarchy, density, atmosphere, signature motifs, and distinctive visual moves. Don't let mocks replace structure, copy, accessibility, or state design. But if the live result lacks the approved direction's major ingredients, the implementation is wrong.
1. PRODUCT context is valid and current.
2. The shape design brief is explicitly confirmed by the user for this task, unless the user already provided a confirmed brief.
3. Implementation references from the brief are loaded.
4. The shape visual probe decision is recorded: generated, skipped with reason, or already resolved.
5. The north-star mock decision is recorded: generated, skipped with reason, or not applicable.
## Step 0: Project Foundation
PRODUCT.md and `teach` answers do **not** satisfy the shape gate. They are project context only. A compact self-authored brief does not satisfy the shape gate either. `shape=pass` requires a separate user response approving the shape brief or an already-confirmed brief supplied by the user.
Before shape, before code: figure out what kind of project you're working in.
Invalid image-skip reasons include: "the final implementation will be semantic HTML/CSS/SVG", "the diagram should stay editable", "a raster mock would not be used directly", or "the product is fictional." Generated probes and mocks are direction artifacts; they are not implementation assets.
Look at the working directory. Run `ls`. Check for:
## Craft Contract
- An existing framework: `astro.config.mjs/ts`, `next.config.js/ts`, `nuxt.config.ts`, `svelte.config.js`, `vite.config.js/ts`, `package.json` with framework deps, `Cargo.toml` + Leptos/Yew, `Gemfile` + Rails. **If found, use it.** Do not start a parallel build, do not introduce a second framework, do not write to `dist/` or `build/` directly. Whatever pipeline the project has, respect it.
- An existing component library or design system: `src/components/`, `app/components/`, a `tokens.css` / `theme.ts`, an `astro.config` `integrations`. Read what's there before adding to it.
- An existing icon set: `lucide-react`, `@phosphor-icons/react`, `@iconify/*`, hand-rolled SVG sprites in `assets/icons/`. **Use what's already in the project**; don't introduce a second set.
Craft is not a first pass. It is a loop with these required artifacts:
If the directory is empty (greenfield), don't pick a framework silently. Ask the user via the AskUserQuestion tool, with sensible defaults framed by the brief:
1. Confirmed design brief from `shape`.
2. Approved visual direction, from generated probes / mocks when image generation is available.
3. Mock fidelity inventory: the visible ingredients from the approved direction that must survive into code.
4. Semantic, functional implementation using the project's real stack and conventions.
5. Browser evidence across relevant viewports.
6. At least one critique-and-fix pass after the first browser inspection, unless the first pass has no material defects.
```text
What should this be built on?
- Astro (default for content-led brand sites, landing pages, marketing surfaces)
- SvelteKit / Next.js / Nuxt (when the brief implies an app surface or significant interactivity)
- Single index.html (one-shot demo, prototype, or a deliberately framework-free experiment)
```
Do not let generated mockups replace interface structure, copy, accessibility, responsive behavior, or state design. But do treat the approved mock as a concrete visual contract for composition, hierarchy, density, atmosphere, signature motifs, image needs, and distinctive visual moves. "North star" means "preserve the important visible ingredients in semantic code," not "use it as loose mood."
Default: Astro for brand briefs, the project's existing framework for product briefs. Ask once; don't re-ask mid-task.
## Step 1: Shape the Design
Run /impeccable shape, passing along whatever feature description the user provided.
Run /impeccable shape, passing along whatever feature description the user provided. Shape is **required** for craft; it is what produces a confirmed direction.
Wait for the design brief to be fully confirmed by the user before proceeding. The brief is your blueprint, and every implementation decision should trace back to it.
Present the shape output and stop. Wait for the user to confirm, override, or course-correct before writing code.
If this craft run resumed after `teach` created PRODUCT.md, run shape now. Do not treat the teach interview, PRODUCT.md, or a summary of project context as a substitute for shape. Shape is task-specific and must cover scope, content/states, visual direction, constraints, anti-goals, probes when applicable, and explicit brief confirmation.
If the user already supplied a confirmed brief or ran shape separately, use it and skip this step.
If the user has already run /impeccable shape and has a confirmed design brief, skip this step and use the existing brief.
When the original prompt + PRODUCT.md already answer scope, content, and visual direction with no real ambiguity, the shape output can be **compact** (3-5 bullets stating what you're building and the visual lane, ending with one or two specific questions or "confirm or override"). The full 10-section structured brief is reserved for genuinely ambiguous, multi-screen, or stakeholder-heavy tasks. Don't pad a clear brief into a long one to look thorough; equally, don't skip the pause to look efficient.
## Step 2: Load References
@@ -55,79 +53,60 @@ Then add references based on the brief's needs:
## Step 3: Land the Visual Direction (Capability-Gated)
Before implementation, generate high-fidelity visual comps when all of these are true:
Generate high-fidelity visual comps before implementation when all three are true:
- The work is **net-new** or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is **mid-fi, high-fi, or production-ready**.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The work is net-new or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is mid-fi, high-fi, or production-ready.
- The harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool). Don't ask the user to set up external APIs.
When those conditions are met, this step is mandatory for **both brand and product work** in Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
Do not skip this step because the eventual UI should be semantic, editable, code-native, responsive, or accessible. Those are implementation requirements, not reasons to avoid visual exploration.
### Purpose
Use the mock step to find a stronger visual lane than code-first generation would reliably discover on its own. The brief remains authoritative on user, purpose, content, constraints, states, and anti-goals. The mock clarifies composition, hierarchy, density, typography, and visual tone.
When met, this step is mandatory for both brand and product work. If image generation isn't available, skip silently. "The eventual UI is semantic/code-native/accessible" is not a reason to skip; those are implementation requirements, not exploration ones.
### What to generate
Generate **1 to 3** high-fidelity north-star comps based on the confirmed brief. If shape already produced direction probes, use those results as input and generate a more resolved mock from the winning lane, not another unrelated exploration.
Generate **1 to 3** high-fidelity north-star comps from the confirmed brief. If shape already produced direction probes, resolve the winning lane further, not an unrelated exploration. Comps must differ in primary visual direction, not just color.
- For brand work, push visual identity, composition, and mood aggressively.
- For product work, still push hierarchy, topology, density, and tone, but keep the comps grounded in realistic product structure and states.
- For landing pages and long-form brand surfaces, show enough of the next section or second fold to establish the system beyond the hero.
The comps must be genuinely different in primary visual direction, not just color variants.
- Brand work: push visual identity, composition, and mood aggressively.
- Product work: push hierarchy, topology, density, tone, grounded in realistic product structure.
- Landing pages and long-form brand surfaces: show enough of the second fold to establish the system beyond the hero.
### Approval loop
Show the comps and ask what should carry forward. If the user asks for changes or the best direction is still weak, generate a focused revision before implementation. Continue until one direction is approved, or until the user explicitly delegates the choice.
Show the comps and ask what carries forward. Iterate until one direction is approved or the user delegates. If the user delegates, pick the strongest direction and explain it from the brief, not personal taste.
If the user delegates, pick the strongest direction and explain the decision using the brief, not personal taste.
Before moving to implementation, summarize:
- What to carry into code
- What **not** to literalize from the mock
This summary is required before Step 4. It is the handoff between visual exploration and semantic implementation.
Before Step 4, summarize what to carry into code and what **not** to literalize from the mock. This is the handoff between visual exploration and semantic implementation.
### Mock fidelity inventory
Before building, inventory the approved mock's major visible ingredients:
Inventory the approved mock's major visible ingredients:
- Hero silhouette and dominant composition.
- Signature motifs: planets, devices, portraits, charts, route lines, insets, badges, or other memorable objects.
- Nav and primary CTA treatment.
- Section sequence visible in the mock, especially the second fold.
- Image-native content the concept depends on.
- Typography, density, color/material treatment, and motion cues.
- Hero silhouette and dominant composition
- Signature motifs (planets, devices, portraits, charts, route lines, insets, badges, etc.)
- Nav and primary CTA treatment
- Section sequence, especially the second fold
- Image-native content the concept depends on
- Typography, density, color/material treatment, motion cues
For each ingredient, decide how it will be implemented: semantic HTML/CSS/SVG, generated asset, sourced project asset, icon library, canvas/WebGL, or an explicitly accepted omission. Do not substitute a different hero composition or new visual driver after approval unless the user approves the change.
For each, decide implementation: semantic HTML/CSS/SVG, generated asset, sourced asset, icon library, canvas/WebGL, or accepted omission. Don't substitute a different hero composition or visual driver post-approval without user sign-off.
Treat the mock as a **north star**, not a screenshot to trace. Do **not** rasterize core UI text or let the mock override the confirmed brief. But if the live result lacks the mock's major visible ingredients, the implementation is wrong.
If a photographic, architectural, product, or place-led mock becomes generic CSS scenery / decorative diagrams / bullets / copy, stop and fix it. That's a broken implementation, not a harmless interpretation.
Treat the mock as a north star, not a screenshot to trace. Don't rasterize core UI text. But if the live result lacks the mock's major ingredients, the implementation is wrong.
## Step 4: Asset Extraction (Need-Gated)
If the chosen direction includes image-native visual ingredients that would materially improve the implementation, generate them as separate assets before building.
If the approved direction needs raster assets, create them before building. Do not replace required imagery with generic cards, bullets, emoji, fake metrics, decorative CSS panels, or filler copy.
Good candidates:
Use the native asset producer (`impeccable_asset_producer` in Codex, `impeccable-asset-producer` in Claude Code) to create clean assets from the hi-fi mock and crops. If you do not have explicit permission to use agents, stop and ask:
- stickers
- badges
- seals
- tickets
- graphic labels
- textures
- abstract objects
- decorative marks
- non-semantic scene elements
```text
Asset production will work better as a scoped subagent job. Should I spawn the Impeccable asset producer subagent for this step?
```
For travel, editorial, portfolio, venue, product showcase, entertainment, education, or any other image-led brand surface, visual assets are usually core content, not decoration. Do not ship abstract CSS panels where the approved mock or subject matter calls for real imagery, generated plates, illustrations, maps, product/object renders, or destination scenes.
Do not skip asset production or silently do it inline. Inline asset production is allowed only if the user declines subagents, the harness cannot spawn the authorized agent, or the user explicitly asks for single-thread mode.
Do **not** export assets for core UI text, navigation, body copy, or any structure that should stay semantic and editable in code.
Pass the approved mock, crop/contact-sheet paths, output directory, dimensions/formats, transparency needs, constraints, and avoid list to the asset producer. Attach image generation capability to the spawned agent when the harness supports it; do not load image-generation reference material into the parent thread first.
Usually **1 to 5** extracted assets is enough. If the design can be built cleanly in HTML/CSS/SVG, prefer that over raster assets. If the mock contains major visual content that cannot be built credibly in code, asset extraction is not optional.
Prefer HTML/CSS/SVG/canvas when they can credibly reproduce an ingredient; use real/generated/stock imagery when the mock or subject matter calls for actual visual content.
## Step 5: Build to Production Quality
@@ -135,50 +114,35 @@ Implement the feature following the design brief. Build in passes so structure,
### Production bar
- Use real or realistic content. Remove placeholder copy, placeholder images, dead links, fake controls, and unused scaffold before presenting.
- Preserve the approved mock's major ingredients. Missing hero objects, missing world/product imagery, different section structure, downgraded CTA/nav treatment, or generic replacements for distinctive motifs are blocking defects unless the user accepted the change.
- Build semantically first: real headings, landmarks, labels, form associations, button/link semantics, accessible names, and state announcements where needed.
- Calibrate spacing, alignment, grid placement, and vertical rhythm deliberately. Do not accept default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- Make typography intentional: chosen font loading strategy, clear hierarchy, readable measure, stable line breaks, tuned wrapping, and no overflow at mobile or large desktop sizes.
- Design realistic state coverage: default, hover where supported, focus-visible, active, disabled, loading, error, success, empty, overflow, long text, short text, and first-run states where relevant.
- Make interaction quality feel finished: keyboard paths, touch targets, feedback timing, scroll behavior, transitions between states, and no hover-only functionality.
- Use icons from the project's established icon set when available. If no set exists, choose a coherent library or use accessible text controls; do not mix unrelated icon styles.
- Optimize imagery and media: correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset` / `picture` for raster assets, and no project-referenced asset left outside the workspace.
- Make motion feel premium: use atmospheric blur, filter, mask, shadow, or reveal effects when they improve the experience; avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- Preserve maintainability: reusable local patterns, clear component boundaries, project conventions, no rasterized UI text, and no hard-coded one-off hacks when a better local pattern exists.
- Fit the technical context: production build passes, no obvious console errors, no avoidable layout shift, no needless dependency, and no broken asset path.
- If you discover a design question that materially changes the brief or approved direction, stop and ask rather than guessing.
- **Real content.** No placeholder copy, placeholder images, dead links, fake controls, or unused scaffold at presentation time.
- **Preserve the approved mock's major ingredients.** Missing hero objects, world/product imagery, section structure, CTA/nav treatment, or distinctive motifs are blocking defects unless the user accepted the change.
- **Semantic first.** Real headings, landmarks, labels, form associations, button/link semantics, accessible names, state announcements where needed.
- **Deliberate spacing and alignment.** No default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- **Intentional typography.** Chosen loading strategy, clear hierarchy, readable measure, stable line breaks, no overflow at any width.
- **Realistic state coverage.** Default, hover, focus-visible, active, disabled, loading, error, success, empty, overflow, long/short text, first-run.
- **Finished interaction quality.** Keyboard paths, touch targets, feedback timing, scroll behavior, state transitions, no hover-only functionality.
- **Coherent icon set.** Use the project's established set; otherwise pick one library or use accessible text. Don't mix.
- **Respect the build pipeline.** Edit source files and run the project's build (`npm run build` or equivalent). Don't write to `build/` / `dist/` / `.next/` with `cat`, heredoc, or Bash redirects; that skips asset hashing, image optimization, code splitting, and CSS extraction, and produces output the dev server won't serve.
- **Verify image URLs before referencing them.** Use image-search MCP or web-fetch when available; guessed photo IDs ship as broken-image placeholders. Without verification, prefer fewer images you're confident about.
- **Optimized imagery and media.** Correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset`/`picture` for raster, no project-referenced asset left outside the workspace.
- **Premium motion.** Use atmospheric blur, filter, mask, shadow, reveal when they improve the experience. Avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- **Maintainable.** Reusable local patterns, clear component boundaries, project conventions. No rasterized UI text or one-off hacks when a local pattern exists.
- **Technically clean.** Production build passes, no console errors, no avoidable layout shift, no needless dependencies, no broken asset paths.
- **Ask when uncertain.** If a discovery materially changes the brief or approved direction, stop and ask. Don't guess.
## Step 6: Browser-Based Iteration
## Step 6: Iterate Visually
**This step is critical.** Do not stop after the first implementation pass.
Look at what you built like a designer would. Your eyes are whatever the harness gives you: a connected browser, a screenshotting tool, Playwright, or asking the user. Use them for responsive testing (mobile, tablet, desktop minimum) and general visual validation.
Open the result in a browser. In Codex, use browser-use or equivalent browser automation when available; otherwise use Playwright or ask the user for screenshots. Inspect screenshots, not just DOM or terminal output.
If your tool returns a file path, read the PNG back into the conversation. A screenshot you didn't read doesn't count.
### Required viewport pass
For long-form brand surfaces, inspect major sections individually. Thumbnails hide spacing, clipping, and cascade defects.
Check the experience at the viewports that matter for the brief. Default minimum:
After the first pass, write an honest critique against the brief, the approved mock's major ingredients (hero silhouette, motifs, imagery, nav/CTA, density), and impeccable's DON'Ts. Patch material defects and re-inspect. **Don't invent defects to demonstrate iteration.** A confident "first pass clean, shipping" beats a fake fix.
- Mobile narrow
- Tablet or small laptop
- Desktop wide
Actively check: responsive behavior (composes, not shrinks), every state (empty / error / loading / edge), craft details (spacing, alignment, hierarchy, contrast, motion timing, focus), performance basics. The exit bar: defensible in a high-end studio review.
For each viewport, capture or inspect the rendered state and look for visual defects: overlap, clipping, weak hierarchy, off-grid alignment, awkward whitespace, cramped controls, unreadable type, broken imagery, hover-only functionality, layout shift, and text overflow.
### Critique and fix loop
After the first browser pass, write a short critique for yourself and patch the implementation. Repeat browser inspection after fixes. Continue until no material issues remain against this checklist:
1. **Does it match the brief?** Compare the live result against every section of the design brief. Fix discrepancies.
2. **Does it match the approved mock?** Compare screenshots against the mock fidelity inventory: hero silhouette, major motifs, imagery, nav/CTA, section sequence, density, color/materials, and second-fold substance. Missing major ingredients are P0 defects.
3. **Does it pass the AI slop test?** If someone saw this and said "AI made this," would they believe it immediately? If yes, it needs more design intention.
4. **Check against impeccable's DON'T guidelines.** Fix any anti-pattern violations.
5. **Check every state.** Navigate through empty, error, loading, and edge case states. Each one should feel intentional, not like an afterthought.
6. **Check responsive behavior.** The design should adapt compositionally, not merely shrink.
7. **Check craft details.** Spacing consistency, optical alignment, type hierarchy, color contrast, image quality, icon coherence, interactive feedback, motion timing, and focus treatment.
8. **Check performance basics.** No obviously oversized images, avoidable layout thrash, blocking animations, or heavy assets without a reason.
The exit bar is not "it works." It is: the rendered result looks intentional at all checked viewports, all expected states are handled, no placeholders remain unless explicitly accepted, and the implementation quality would be defensible in a high-end studio review.
Detector or QA output is defect evidence only; never proof the work is finished.
## Step 7: Present
@@ -189,5 +153,3 @@ Present the result to the user:
- Explain design decisions that connect back to the design brief and, when used, the chosen north-star mock. Include any accepted deviations from the mock; do not hide unimplemented mock ingredients.
- Note any remaining limitations or follow-up risks honestly
- Ask: "What's working? What isn't?"
Iterate based on feedback. Good design is rarely right on the first pass.
@@ -43,7 +43,7 @@ Run the bundled deterministic detector, which flags 27 specific patterns (AI slo
**CLI scan**:
```bash
npx impeccable --json [--fast] [target]
npx impeccable detect --json [--fast] [target]
```
- Pass HTML/JSX/TSX/Vue/Svelte files or directories as `[target]` (anything with markup). Do not pass CSS-only files.
+8 -6
View File
@@ -2,6 +2,8 @@
Perform a meticulous final pass to catch all the small details that separate good work from great work. The difference between shipped and polished.
Detector and automated QA output are defect evidence only. A clean script result is never proof that the design is strong; gather browser evidence and inspect the real interaction path.
## Design System Discovery
Aligning the feature to the design system is **not optional**. Polish without alignment is decoration on top of drift, and it makes the next person's job harder. Discovery comes before any other polish work.
@@ -216,11 +218,12 @@ Sweat the details. Zoom in until the alignment is right and the spacing reads as
Before marking as done:
- **Use it yourself**: Actually interact with the feature
- **Test on real devices**: Not just browser DevTools
- **Ask someone else to review**: Fresh eyes catch things
- **Compare to design**: Match intended design
- **Check all states**: Don't just test happy path
- **Use it yourself**: Actually interact with the feature.
- **Test on real devices**: Not just browser DevTools.
- **Ask someone else to review**: Fresh eyes catch things.
- **Compare to design**: Match intended design.
- **Check all states**: Don't just test happy path.
- **Treat automation carefully**: Run detector or QA commands when they are available and relevant, fix their defects, but never cite a clean result as proof that the work is polished.
## Clean Up
@@ -230,4 +233,3 @@ After polishing, ensure code quality:
- **Remove orphaned code**: Delete unused styles, components, or files made obsolete by polish.
- **Consolidate tokens**: If you introduced new values, check whether they should be tokens.
- **Verify DRYness**: Look for duplication introduced during polishing and consolidate.
+25 -11
View File
@@ -16,14 +16,16 @@ This is a required interaction, not optional guidance. Ask these questions in co
### Interview cadence
Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed design inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
Discovery includes at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
- Use the harness's structured question tool when one exists. Otherwise, ask directly in chat and stop.
- Ask **2-3 questions per round**, then wait for answers.
- Treat PRODUCT.md and DESIGN.md as anchors; they reduce repeated questions but do **not** replace shape for craft. Shape is task-specific.
- Round 1 should clarify purpose, audience/context, and success or emotional outcome.
- Round 2 should clarify content/data/states and scope/fidelity.
- Round 3 should clarify visual direction, constraints, and anti-goals when still unresolved.
- One round is the default. Add a second only if the first answers leave material gaps. Don't run a second round just to feel thorough.
- Round 1 should clarify purpose, audience/context, content/scope, and (for brand) visual direction.
- Round 2, when needed, fills in whatever's still genuinely missing.
**Assert-then-confirm, not menu-with-escape.** When PRODUCT.md and the user's prompt make one option obvious, name it and ask the user to confirm or override. Don't enumerate "Restrained / Committed / Or something else?" as a real choice; "This reads as Restrained, confirm?" beats a four-option menu when the answer is already clear.
### Purpose & Context
- What is this feature for? What problem does it solve?
@@ -36,6 +38,7 @@ Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.
- What are the realistic ranges? (Minimum, typical, maximum, e.g., 0 items, 5 items, 500 items)
- What are the edge cases? (Empty state, error state, first-time use, power user)
- Is any content dynamic? What changes and how often?
- What visual assets are real content here? Note required images, product shots, illustrations, maps, textures, diagrams, generated objects, or existing project assets.
### Design Direction
@@ -72,9 +75,9 @@ After the discovery interview, generate a small set of visual direction probes *
- The work is **net-new** or directionally ambiguous enough that visual exploration will clarify the brief.
- The requested fidelity is **mid-fi, high-fi, or production-ready**. Skip for sketch-only planning.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The current harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool, or similar). Don't ask the user to install APIs or tooling.
When those conditions are met, this step is mandatory for Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
When those conditions are met, this step is mandatory. If image generation isn't natively available, skip silently and proceed; don't announce the skip.
Use probes to explore visual lanes, not to replace the brief.
@@ -104,11 +107,20 @@ The probes should differ in primary visual direction (hierarchy, topology, densi
- Do **not** treat generated imagery as final UX specification, final copy, or final accessibility behavior.
- Do **not** use this step for minor refinements of existing work. It's for shaping a new surface or clarifying a big directional choice.
If image generation is unavailable, or the task doesn't benefit from it, skip this phase only with a one-line reason and proceed directly to the design brief.
If image generation isn't natively available, skip this phase silently and proceed.
## Phase 2: Design Brief
After the interview and any required probes, synthesize everything into a structured design brief. Present it to the user for explicit confirmation before considering this command complete. Stop after asking for confirmation; do not proceed to craft or implementation in the same response unless the user has already approved the brief.
After the interview and any required probes, present a brief and **end your response**. The user must confirm before any implementation runs. Do not present a brief and then continue to code in the same response, even if the brief feels obvious to you. The user's confirmation is the gate.
**Choose the brief shape based on how clear the answers are:**
- **Compact form (3-5 bullets)** when discovery was crisp and the original prompt + PRODUCT.md already pinned scope, content, and direction. State what you're building, the visual lane, and end with one or two specific questions or a clear "confirm or override?" prompt. This is the default for typical craft requests with a clear prompt.
- **Full structured form (sections below)** when the task is genuinely ambiguous, multi-screen, or when the user asked for shape as a standalone step. Use this when the discipline of structure earns its weight.
Don't pad a clear brief into a long one to look thorough. A 70-line brief restating answers the user just gave is noise, not rigor. Equally, don't skip the confirmation pause to look efficient: the pause is the point.
If the user already said "approved" or "go" during discovery for the *exact direction you'd present*, that counts as confirmation; you may proceed without asking again. But if your brief adds anything the user hasn't seen and approved, you must stop and confirm.
### Brief Structure
@@ -136,16 +148,18 @@ List every state the feature needs: default, empty, loading, error, success, edg
How users interact with this feature. What happens on click, hover, scroll? What feedback do they get? What's the flow from entry to completion?
**8. Content Requirements**
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges.
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges. For image-led surfaces, also list the required image/media roles and their likely source (project asset, generated raster, semantic SVG/CSS, canvas/WebGL, icon library, or accepted omission).
**9. Recommended References**
Based on the brief, list which impeccable reference files would be most valuable during implementation (e.g., spatial-design.md for complex layouts, motion-design.md for animated features, interaction-design.md for form-heavy features).
**10. Open Questions**
Anything unresolved that the implementer should resolve during build.
Anything genuinely unresolved. Don't list "open questions" you've already recommended a default for; assert the default and move on. If you'd write `Recommend: X` next to a question, just decide X.
---
ask the user directly to clarify what you cannot infer. Ask for explicit confirmation of the brief before finishing. If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the brief is confirmed.
ask the user directly to clarify what you cannot infer.
If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the user confirms direction (or the user already gave a clear go during discovery, which counts).
Once confirmed, the brief is complete. The user can now hand it to /impeccable, or use it to guide any other implementation approach. (If the user wants the full discovery-then-build flow in one step, they should use /impeccable craft instead, which runs this command internally.)
+6 -19
View File
@@ -11,28 +11,15 @@ allowed-tools:
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
## Setup (non-optional)
## Setup
Before any design work or file edits, pass these gates. Skipping them produces generic output that ignores the project.
Before any design work or file edits:
| Gate | Required check | If fail |
|---|---|---|
| Context | The PRODUCT.md / DESIGN.md loader result is known from `node .rovodev/skills/impeccable/scripts/load-context.mjs`. | Run the loader before continuing. |
| Product | PRODUCT.md exists and is not empty or placeholder (`[TODO]` markers, <200 chars). | Run `/impeccable teach`, refresh context, then resume. Never synthesize PRODUCT.md from the user's original prompt alone. |
| Command | The matching command reference is loaded when a sub-command is used. | Load the reference before continuing. |
| Craft | `/impeccable craft` has a user-confirmed shape brief for this task. `teach` / PRODUCT.md never counts as shape. | Run `/impeccable shape` and wait for explicit brief confirmation. |
| Image | Required visual probes / mocks are generated or skipped with a reason. | Resolve the image-generation gate in `shape.md` or `craft.md` before code. |
| Mutation | All active gates above pass. | Do not edit project files yet. |
1. Load context (PRODUCT.md / DESIGN.md) via the loader script.
2. Identify the register and load the matching register reference (brand.md or product.md).
3. **If the user invoked a sub-command (e.g. `craft`, `shape`, `audit`), load its reference file too.** This is non-negotiable: `craft` without `craft.md` loaded means you'll skip the shape-and-confirm step the user expects.
Codex-style agents must state this before editing files:
```text
IMPECCABLE_PREFLIGHT: context=pass product=pass command_reference=pass shape=pass|not_required image_gate=pass|skipped:<reason> mutation=open
```
For `/impeccable craft`, `shape=pass` is only valid after a separate user response approving the shape design brief, or when the user provided an already-confirmed brief in the request. Do not mark `shape=pass` after writing PRODUCT.md, summarizing assumptions, or drafting an unconfirmed brief yourself.
Other harnesses should follow the same checklist when they can expose this state.
Skipping these produces generic output that ignores the project.
### 1. Context gathering
@@ -12,6 +12,8 @@ Brand isn't a neutral register. AI-generated landing pages have flooded the inte
**The second slop test: aesthetic lane.** Before committing to moves, name the reference. A Klim-style specimen page is one lane; Stripe-minimal is another; Liquid-Death-acid-maximalism is another. Don't drift into editorial-magazine aesthetics on a brief that isn't editorial. A hiking brand with Cormorant italic drop caps has the wrong register within the register.
Then the inverse test: in one sentence, describe what you're about to build the way a competitor would describe theirs. If that sentence fits the modal landing page in the category, restart.
## Typography
### Font selection procedure
@@ -66,6 +68,7 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
- Palette IS voice. A calm brand and a restless brand should not share palette mechanics.
- When the strategy is Committed or Drenched, color carries the brand. Don't hedge with neutrals around the edges. Commit.
- Don't converge across projects. If the last brand surface was restrained-on-cream, this one is not.
- When a cultural-symbol palette is the obvious pull, reach past it. Let the cultural reading come from typography, imagery, and copy, not the palette.
## Layout
@@ -79,14 +82,14 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
Brand surfaces lean on imagery. A restaurant, hotel, magazine, or product landing page without any imagery reads as incomplete, not as restrained. A solid-color rectangle where a hero image should go is worse than a representative stock photo.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse. If the approved comp or brief is image-led, ship real project assets, generated raster assets, or a credible canvas/SVG/WebGL scene. Do not replace photographic, architectural, product, or place imagery with generic CSS panels, decorative diagrams, cards, bullets, or copy.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. Pick real Unsplash photo IDs you're confident exist (`photo-1559339352-11d035aa65de`, `photo-1590490360182-c33d57733427`, etc.); if unsure, pick fewer photos but don't substitute colored `<div>` placeholders.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. **Verify the URLs before referencing them.** If you have an image-search MCP, web-fetch tool, or browser access, use it to find real photo IDs and confirm they resolve. Guessed IDs (even ones that look real) often 404 and ship as broken-image placeholders. Without a verification path, pick fewer photos you're confident exist over more that you guessed; never substitute colored `<div>` placeholders.
- **Search for the brand's physical object**, not the generic category: "handmade pasta on a scratched wooden table" beats "Italian food"; "cypress trees above a limestone hotel facade at dusk" beats "luxury hotel".
- **One decisive photo beats five mediocre ones.** Hero imagery should commit to a mood; padding with more stock doesn't rescue an indecisive one.
- **Alt text is part of the voice.** "Coastal fettuccine, hand-cut, served on the terrace" beats "pasta dish".
Tech / dev-tool brands are the exception where zero imagery can be correct; a developer landing page often carries its voice through typography, code samples, diagrams. Know which kind of brand you're working on.
"Imagery" here is broader than stock photography: product screenshots, custom data visualizations, generated SVG, and canvas/WebGL scenes are all imagery. Text-only pages where typography alone carries the entire visual weight are the failure mode.
## Motion
@@ -102,6 +105,7 @@ Tech / dev-tool brands are the exception where zero imagery can be correct; a de
- Timid palettes and average layouts. Safe = invisible.
- Zero imagery on a brief that implies imagery (restaurant, hotel, food, travel, fashion, photography, hobbyist). Colored blocks where a hero photo belongs.
- Defaulting to editorial-magazine aesthetics (display serif + italic + drop caps + broadsheet grid) on briefs that aren't magazine-shaped. Editorial is ONE aesthetic lane, not the default brand aesthetic.
- Repeated tiny uppercase tracked labels above every section heading. A single strong kicker can be voice; repeating it as section grammar is AI scaffolding unless it's a deliberate, named brand system.
## Brand permissions
+73 -111
View File
@@ -1,43 +1,41 @@
# Craft Flow
Build a feature with impeccable UX and UI quality through a structured process: shape the design, land the visual direction, build real production code, then inspect and improve in-browser until the result meets a high-end studio bar.
Build a feature with impeccable UX and UI quality: shape the design, land the visual direction, build real production code, inspect and improve in-browser until it meets a high-end studio bar.
## Build Gate
Before writing code, you need: PRODUCT.md loaded, register identified and the matching reference loaded, and a confirmed design direction for this task (either from `shape` or supplied by the user). PRODUCT.md is project context, not a task-specific brief.
Craft cannot build until all of these are true:
Treat any approved visual direction (generated mock or stated reference) as a concrete contract for composition, hierarchy, density, atmosphere, signature motifs, and distinctive visual moves. Don't let mocks replace structure, copy, accessibility, or state design. But if the live result lacks the approved direction's major ingredients, the implementation is wrong.
1. PRODUCT context is valid and current.
2. The shape design brief is explicitly confirmed by the user for this task, unless the user already provided a confirmed brief.
3. Implementation references from the brief are loaded.
4. The shape visual probe decision is recorded: generated, skipped with reason, or already resolved.
5. The north-star mock decision is recorded: generated, skipped with reason, or not applicable.
## Step 0: Project Foundation
PRODUCT.md and `teach` answers do **not** satisfy the shape gate. They are project context only. A compact self-authored brief does not satisfy the shape gate either. `shape=pass` requires a separate user response approving the shape brief or an already-confirmed brief supplied by the user.
Before shape, before code: figure out what kind of project you're working in.
Invalid image-skip reasons include: "the final implementation will be semantic HTML/CSS/SVG", "the diagram should stay editable", "a raster mock would not be used directly", or "the product is fictional." Generated probes and mocks are direction artifacts; they are not implementation assets.
Look at the working directory. Run `ls`. Check for:
## Craft Contract
- An existing framework: `astro.config.mjs/ts`, `next.config.js/ts`, `nuxt.config.ts`, `svelte.config.js`, `vite.config.js/ts`, `package.json` with framework deps, `Cargo.toml` + Leptos/Yew, `Gemfile` + Rails. **If found, use it.** Do not start a parallel build, do not introduce a second framework, do not write to `dist/` or `build/` directly. Whatever pipeline the project has, respect it.
- An existing component library or design system: `src/components/`, `app/components/`, a `tokens.css` / `theme.ts`, an `astro.config` `integrations`. Read what's there before adding to it.
- An existing icon set: `lucide-react`, `@phosphor-icons/react`, `@iconify/*`, hand-rolled SVG sprites in `assets/icons/`. **Use what's already in the project**; don't introduce a second set.
Craft is not a first pass. It is a loop with these required artifacts:
If the directory is empty (greenfield), don't pick a framework silently. Ask the user via the AskUserQuestion tool, with sensible defaults framed by the brief:
1. Confirmed design brief from `shape`.
2. Approved visual direction, from generated probes / mocks when image generation is available.
3. Mock fidelity inventory: the visible ingredients from the approved direction that must survive into code.
4. Semantic, functional implementation using the project's real stack and conventions.
5. Browser evidence across relevant viewports.
6. At least one critique-and-fix pass after the first browser inspection, unless the first pass has no material defects.
```text
What should this be built on?
- Astro (default for content-led brand sites, landing pages, marketing surfaces)
- SvelteKit / Next.js / Nuxt (when the brief implies an app surface or significant interactivity)
- Single index.html (one-shot demo, prototype, or a deliberately framework-free experiment)
```
Do not let generated mockups replace interface structure, copy, accessibility, responsive behavior, or state design. But do treat the approved mock as a concrete visual contract for composition, hierarchy, density, atmosphere, signature motifs, image needs, and distinctive visual moves. "North star" means "preserve the important visible ingredients in semantic code," not "use it as loose mood."
Default: Astro for brand briefs, the project's existing framework for product briefs. Ask once; don't re-ask mid-task.
## Step 1: Shape the Design
Run /impeccable shape, passing along whatever feature description the user provided.
Run /impeccable shape, passing along whatever feature description the user provided. Shape is **required** for craft; it is what produces a confirmed direction.
Wait for the design brief to be fully confirmed by the user before proceeding. The brief is your blueprint, and every implementation decision should trace back to it.
Present the shape output and stop. Wait for the user to confirm, override, or course-correct before writing code.
If this craft run resumed after `teach` created PRODUCT.md, run shape now. Do not treat the teach interview, PRODUCT.md, or a summary of project context as a substitute for shape. Shape is task-specific and must cover scope, content/states, visual direction, constraints, anti-goals, probes when applicable, and explicit brief confirmation.
If the user already supplied a confirmed brief or ran shape separately, use it and skip this step.
If the user has already run /impeccable shape and has a confirmed design brief, skip this step and use the existing brief.
When the original prompt + PRODUCT.md already answer scope, content, and visual direction with no real ambiguity, the shape output can be **compact** (3-5 bullets stating what you're building and the visual lane, ending with one or two specific questions or "confirm or override"). The full 10-section structured brief is reserved for genuinely ambiguous, multi-screen, or stakeholder-heavy tasks. Don't pad a clear brief into a long one to look thorough; equally, don't skip the pause to look efficient.
## Step 2: Load References
@@ -55,79 +53,60 @@ Then add references based on the brief's needs:
## Step 3: Land the Visual Direction (Capability-Gated)
Before implementation, generate high-fidelity visual comps when all of these are true:
Generate high-fidelity visual comps before implementation when all three are true:
- The work is **net-new** or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is **mid-fi, high-fi, or production-ready**.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The work is net-new or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is mid-fi, high-fi, or production-ready.
- The harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool). Don't ask the user to set up external APIs.
When those conditions are met, this step is mandatory for **both brand and product work** in Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
Do not skip this step because the eventual UI should be semantic, editable, code-native, responsive, or accessible. Those are implementation requirements, not reasons to avoid visual exploration.
### Purpose
Use the mock step to find a stronger visual lane than code-first generation would reliably discover on its own. The brief remains authoritative on user, purpose, content, constraints, states, and anti-goals. The mock clarifies composition, hierarchy, density, typography, and visual tone.
When met, this step is mandatory for both brand and product work. If image generation isn't available, skip silently. "The eventual UI is semantic/code-native/accessible" is not a reason to skip; those are implementation requirements, not exploration ones.
### What to generate
Generate **1 to 3** high-fidelity north-star comps based on the confirmed brief. If shape already produced direction probes, use those results as input and generate a more resolved mock from the winning lane, not another unrelated exploration.
Generate **1 to 3** high-fidelity north-star comps from the confirmed brief. If shape already produced direction probes, resolve the winning lane further, not an unrelated exploration. Comps must differ in primary visual direction, not just color.
- For brand work, push visual identity, composition, and mood aggressively.
- For product work, still push hierarchy, topology, density, and tone, but keep the comps grounded in realistic product structure and states.
- For landing pages and long-form brand surfaces, show enough of the next section or second fold to establish the system beyond the hero.
The comps must be genuinely different in primary visual direction, not just color variants.
- Brand work: push visual identity, composition, and mood aggressively.
- Product work: push hierarchy, topology, density, tone, grounded in realistic product structure.
- Landing pages and long-form brand surfaces: show enough of the second fold to establish the system beyond the hero.
### Approval loop
Show the comps and ask what should carry forward. If the user asks for changes or the best direction is still weak, generate a focused revision before implementation. Continue until one direction is approved, or until the user explicitly delegates the choice.
Show the comps and ask what carries forward. Iterate until one direction is approved or the user delegates. If the user delegates, pick the strongest direction and explain it from the brief, not personal taste.
If the user delegates, pick the strongest direction and explain the decision using the brief, not personal taste.
Before moving to implementation, summarize:
- What to carry into code
- What **not** to literalize from the mock
This summary is required before Step 4. It is the handoff between visual exploration and semantic implementation.
Before Step 4, summarize what to carry into code and what **not** to literalize from the mock. This is the handoff between visual exploration and semantic implementation.
### Mock fidelity inventory
Before building, inventory the approved mock's major visible ingredients:
Inventory the approved mock's major visible ingredients:
- Hero silhouette and dominant composition.
- Signature motifs: planets, devices, portraits, charts, route lines, insets, badges, or other memorable objects.
- Nav and primary CTA treatment.
- Section sequence visible in the mock, especially the second fold.
- Image-native content the concept depends on.
- Typography, density, color/material treatment, and motion cues.
- Hero silhouette and dominant composition
- Signature motifs (planets, devices, portraits, charts, route lines, insets, badges, etc.)
- Nav and primary CTA treatment
- Section sequence, especially the second fold
- Image-native content the concept depends on
- Typography, density, color/material treatment, motion cues
For each ingredient, decide how it will be implemented: semantic HTML/CSS/SVG, generated asset, sourced project asset, icon library, canvas/WebGL, or an explicitly accepted omission. Do not substitute a different hero composition or new visual driver after approval unless the user approves the change.
For each, decide implementation: semantic HTML/CSS/SVG, generated asset, sourced asset, icon library, canvas/WebGL, or accepted omission. Don't substitute a different hero composition or visual driver post-approval without user sign-off.
Treat the mock as a **north star**, not a screenshot to trace. Do **not** rasterize core UI text or let the mock override the confirmed brief. But if the live result lacks the mock's major visible ingredients, the implementation is wrong.
If a photographic, architectural, product, or place-led mock becomes generic CSS scenery / decorative diagrams / bullets / copy, stop and fix it. That's a broken implementation, not a harmless interpretation.
Treat the mock as a north star, not a screenshot to trace. Don't rasterize core UI text. But if the live result lacks the mock's major ingredients, the implementation is wrong.
## Step 4: Asset Extraction (Need-Gated)
If the chosen direction includes image-native visual ingredients that would materially improve the implementation, generate them as separate assets before building.
If the approved direction needs raster assets, create them before building. Do not replace required imagery with generic cards, bullets, emoji, fake metrics, decorative CSS panels, or filler copy.
Good candidates:
Use the native asset producer (`impeccable_asset_producer` in Codex, `impeccable-asset-producer` in Claude Code) to create clean assets from the hi-fi mock and crops. If you do not have explicit permission to use agents, stop and ask:
- stickers
- badges
- seals
- tickets
- graphic labels
- textures
- abstract objects
- decorative marks
- non-semantic scene elements
```text
Asset production will work better as a scoped subagent job. Should I spawn the Impeccable asset producer subagent for this step?
```
For travel, editorial, portfolio, venue, product showcase, entertainment, education, or any other image-led brand surface, visual assets are usually core content, not decoration. Do not ship abstract CSS panels where the approved mock or subject matter calls for real imagery, generated plates, illustrations, maps, product/object renders, or destination scenes.
Do not skip asset production or silently do it inline. Inline asset production is allowed only if the user declines subagents, the harness cannot spawn the authorized agent, or the user explicitly asks for single-thread mode.
Do **not** export assets for core UI text, navigation, body copy, or any structure that should stay semantic and editable in code.
Pass the approved mock, crop/contact-sheet paths, output directory, dimensions/formats, transparency needs, constraints, and avoid list to the asset producer. Attach image generation capability to the spawned agent when the harness supports it; do not load image-generation reference material into the parent thread first.
Usually **1 to 5** extracted assets is enough. If the design can be built cleanly in HTML/CSS/SVG, prefer that over raster assets. If the mock contains major visual content that cannot be built credibly in code, asset extraction is not optional.
Prefer HTML/CSS/SVG/canvas when they can credibly reproduce an ingredient; use real/generated/stock imagery when the mock or subject matter calls for actual visual content.
## Step 5: Build to Production Quality
@@ -135,50 +114,35 @@ Implement the feature following the design brief. Build in passes so structure,
### Production bar
- Use real or realistic content. Remove placeholder copy, placeholder images, dead links, fake controls, and unused scaffold before presenting.
- Preserve the approved mock's major ingredients. Missing hero objects, missing world/product imagery, different section structure, downgraded CTA/nav treatment, or generic replacements for distinctive motifs are blocking defects unless the user accepted the change.
- Build semantically first: real headings, landmarks, labels, form associations, button/link semantics, accessible names, and state announcements where needed.
- Calibrate spacing, alignment, grid placement, and vertical rhythm deliberately. Do not accept default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- Make typography intentional: chosen font loading strategy, clear hierarchy, readable measure, stable line breaks, tuned wrapping, and no overflow at mobile or large desktop sizes.
- Design realistic state coverage: default, hover where supported, focus-visible, active, disabled, loading, error, success, empty, overflow, long text, short text, and first-run states where relevant.
- Make interaction quality feel finished: keyboard paths, touch targets, feedback timing, scroll behavior, transitions between states, and no hover-only functionality.
- Use icons from the project's established icon set when available. If no set exists, choose a coherent library or use accessible text controls; do not mix unrelated icon styles.
- Optimize imagery and media: correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset` / `picture` for raster assets, and no project-referenced asset left outside the workspace.
- Make motion feel premium: use atmospheric blur, filter, mask, shadow, or reveal effects when they improve the experience; avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- Preserve maintainability: reusable local patterns, clear component boundaries, project conventions, no rasterized UI text, and no hard-coded one-off hacks when a better local pattern exists.
- Fit the technical context: production build passes, no obvious console errors, no avoidable layout shift, no needless dependency, and no broken asset path.
- If you discover a design question that materially changes the brief or approved direction, stop and ask rather than guessing.
- **Real content.** No placeholder copy, placeholder images, dead links, fake controls, or unused scaffold at presentation time.
- **Preserve the approved mock's major ingredients.** Missing hero objects, world/product imagery, section structure, CTA/nav treatment, or distinctive motifs are blocking defects unless the user accepted the change.
- **Semantic first.** Real headings, landmarks, labels, form associations, button/link semantics, accessible names, state announcements where needed.
- **Deliberate spacing and alignment.** No default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- **Intentional typography.** Chosen loading strategy, clear hierarchy, readable measure, stable line breaks, no overflow at any width.
- **Realistic state coverage.** Default, hover, focus-visible, active, disabled, loading, error, success, empty, overflow, long/short text, first-run.
- **Finished interaction quality.** Keyboard paths, touch targets, feedback timing, scroll behavior, state transitions, no hover-only functionality.
- **Coherent icon set.** Use the project's established set; otherwise pick one library or use accessible text. Don't mix.
- **Respect the build pipeline.** Edit source files and run the project's build (`npm run build` or equivalent). Don't write to `build/` / `dist/` / `.next/` with `cat`, heredoc, or Bash redirects; that skips asset hashing, image optimization, code splitting, and CSS extraction, and produces output the dev server won't serve.
- **Verify image URLs before referencing them.** Use image-search MCP or web-fetch when available; guessed photo IDs ship as broken-image placeholders. Without verification, prefer fewer images you're confident about.
- **Optimized imagery and media.** Correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset`/`picture` for raster, no project-referenced asset left outside the workspace.
- **Premium motion.** Use atmospheric blur, filter, mask, shadow, reveal when they improve the experience. Avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- **Maintainable.** Reusable local patterns, clear component boundaries, project conventions. No rasterized UI text or one-off hacks when a local pattern exists.
- **Technically clean.** Production build passes, no console errors, no avoidable layout shift, no needless dependencies, no broken asset paths.
- **Ask when uncertain.** If a discovery materially changes the brief or approved direction, stop and ask. Don't guess.
## Step 6: Browser-Based Iteration
## Step 6: Iterate Visually
**This step is critical.** Do not stop after the first implementation pass.
Look at what you built like a designer would. Your eyes are whatever the harness gives you: a connected browser, a screenshotting tool, Playwright, or asking the user. Use them for responsive testing (mobile, tablet, desktop minimum) and general visual validation.
Open the result in a browser. In Codex, use browser-use or equivalent browser automation when available; otherwise use Playwright or ask the user for screenshots. Inspect screenshots, not just DOM or terminal output.
If your tool returns a file path, read the PNG back into the conversation. A screenshot you didn't read doesn't count.
### Required viewport pass
For long-form brand surfaces, inspect major sections individually. Thumbnails hide spacing, clipping, and cascade defects.
Check the experience at the viewports that matter for the brief. Default minimum:
After the first pass, write an honest critique against the brief, the approved mock's major ingredients (hero silhouette, motifs, imagery, nav/CTA, density), and impeccable's DON'Ts. Patch material defects and re-inspect. **Don't invent defects to demonstrate iteration.** A confident "first pass clean, shipping" beats a fake fix.
- Mobile narrow
- Tablet or small laptop
- Desktop wide
Actively check: responsive behavior (composes, not shrinks), every state (empty / error / loading / edge), craft details (spacing, alignment, hierarchy, contrast, motion timing, focus), performance basics. The exit bar: defensible in a high-end studio review.
For each viewport, capture or inspect the rendered state and look for visual defects: overlap, clipping, weak hierarchy, off-grid alignment, awkward whitespace, cramped controls, unreadable type, broken imagery, hover-only functionality, layout shift, and text overflow.
### Critique and fix loop
After the first browser pass, write a short critique for yourself and patch the implementation. Repeat browser inspection after fixes. Continue until no material issues remain against this checklist:
1. **Does it match the brief?** Compare the live result against every section of the design brief. Fix discrepancies.
2. **Does it match the approved mock?** Compare screenshots against the mock fidelity inventory: hero silhouette, major motifs, imagery, nav/CTA, section sequence, density, color/materials, and second-fold substance. Missing major ingredients are P0 defects.
3. **Does it pass the AI slop test?** If someone saw this and said "AI made this," would they believe it immediately? If yes, it needs more design intention.
4. **Check against impeccable's DON'T guidelines.** Fix any anti-pattern violations.
5. **Check every state.** Navigate through empty, error, loading, and edge case states. Each one should feel intentional, not like an afterthought.
6. **Check responsive behavior.** The design should adapt compositionally, not merely shrink.
7. **Check craft details.** Spacing consistency, optical alignment, type hierarchy, color contrast, image quality, icon coherence, interactive feedback, motion timing, and focus treatment.
8. **Check performance basics.** No obviously oversized images, avoidable layout thrash, blocking animations, or heavy assets without a reason.
The exit bar is not "it works." It is: the rendered result looks intentional at all checked viewports, all expected states are handled, no placeholders remain unless explicitly accepted, and the implementation quality would be defensible in a high-end studio review.
Detector or QA output is defect evidence only; never proof the work is finished.
## Step 7: Present
@@ -189,5 +153,3 @@ Present the result to the user:
- Explain design decisions that connect back to the design brief and, when used, the chosen north-star mock. Include any accepted deviations from the mock; do not hide unimplemented mock ingredients.
- Note any remaining limitations or follow-up risks honestly
- Ask: "What's working? What isn't?"
Iterate based on feedback. Good design is rarely right on the first pass.
@@ -43,7 +43,7 @@ Run the bundled deterministic detector, which flags 27 specific patterns (AI slo
**CLI scan**:
```bash
npx impeccable --json [--fast] [target]
npx impeccable detect --json [--fast] [target]
```
- Pass HTML/JSX/TSX/Vue/Svelte files or directories as `[target]` (anything with markup). Do not pass CSS-only files.
@@ -2,6 +2,8 @@
Perform a meticulous final pass to catch all the small details that separate good work from great work. The difference between shipped and polished.
Detector and automated QA output are defect evidence only. A clean script result is never proof that the design is strong; gather browser evidence and inspect the real interaction path.
## Design System Discovery
Aligning the feature to the design system is **not optional**. Polish without alignment is decoration on top of drift, and it makes the next person's job harder. Discovery comes before any other polish work.
@@ -216,11 +218,12 @@ Sweat the details. Zoom in until the alignment is right and the spacing reads as
Before marking as done:
- **Use it yourself**: Actually interact with the feature
- **Test on real devices**: Not just browser DevTools
- **Ask someone else to review**: Fresh eyes catch things
- **Compare to design**: Match intended design
- **Check all states**: Don't just test happy path
- **Use it yourself**: Actually interact with the feature.
- **Test on real devices**: Not just browser DevTools.
- **Ask someone else to review**: Fresh eyes catch things.
- **Compare to design**: Match intended design.
- **Check all states**: Don't just test happy path.
- **Treat automation carefully**: Run detector or QA commands when they are available and relevant, fix their defects, but never cite a clean result as proof that the work is polished.
## Clean Up
@@ -230,4 +233,3 @@ After polishing, ensure code quality:
- **Remove orphaned code**: Delete unused styles, components, or files made obsolete by polish.
- **Consolidate tokens**: If you introduced new values, check whether they should be tokens.
- **Verify DRYness**: Look for duplication introduced during polishing and consolidate.
+25 -11
View File
@@ -16,14 +16,16 @@ This is a required interaction, not optional guidance. Ask these questions in co
### Interview cadence
Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed design inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
Discovery includes at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
- Use the harness's structured question tool when one exists. Otherwise, ask directly in chat and stop.
- Ask **2-3 questions per round**, then wait for answers.
- Treat PRODUCT.md and DESIGN.md as anchors; they reduce repeated questions but do **not** replace shape for craft. Shape is task-specific.
- Round 1 should clarify purpose, audience/context, and success or emotional outcome.
- Round 2 should clarify content/data/states and scope/fidelity.
- Round 3 should clarify visual direction, constraints, and anti-goals when still unresolved.
- One round is the default. Add a second only if the first answers leave material gaps. Don't run a second round just to feel thorough.
- Round 1 should clarify purpose, audience/context, content/scope, and (for brand) visual direction.
- Round 2, when needed, fills in whatever's still genuinely missing.
**Assert-then-confirm, not menu-with-escape.** When PRODUCT.md and the user's prompt make one option obvious, name it and ask the user to confirm or override. Don't enumerate "Restrained / Committed / Or something else?" as a real choice; "This reads as Restrained, confirm?" beats a four-option menu when the answer is already clear.
### Purpose & Context
- What is this feature for? What problem does it solve?
@@ -36,6 +38,7 @@ Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.
- What are the realistic ranges? (Minimum, typical, maximum, e.g., 0 items, 5 items, 500 items)
- What are the edge cases? (Empty state, error state, first-time use, power user)
- Is any content dynamic? What changes and how often?
- What visual assets are real content here? Note required images, product shots, illustrations, maps, textures, diagrams, generated objects, or existing project assets.
### Design Direction
@@ -72,9 +75,9 @@ After the discovery interview, generate a small set of visual direction probes *
- The work is **net-new** or directionally ambiguous enough that visual exploration will clarify the brief.
- The requested fidelity is **mid-fi, high-fi, or production-ready**. Skip for sketch-only planning.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The current harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool, or similar). Don't ask the user to install APIs or tooling.
When those conditions are met, this step is mandatory for Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
When those conditions are met, this step is mandatory. If image generation isn't natively available, skip silently and proceed; don't announce the skip.
Use probes to explore visual lanes, not to replace the brief.
@@ -104,11 +107,20 @@ The probes should differ in primary visual direction (hierarchy, topology, densi
- Do **not** treat generated imagery as final UX specification, final copy, or final accessibility behavior.
- Do **not** use this step for minor refinements of existing work. It's for shaping a new surface or clarifying a big directional choice.
If image generation is unavailable, or the task doesn't benefit from it, skip this phase only with a one-line reason and proceed directly to the design brief.
If image generation isn't natively available, skip this phase silently and proceed.
## Phase 2: Design Brief
After the interview and any required probes, synthesize everything into a structured design brief. Present it to the user for explicit confirmation before considering this command complete. Stop after asking for confirmation; do not proceed to craft or implementation in the same response unless the user has already approved the brief.
After the interview and any required probes, present a brief and **end your response**. The user must confirm before any implementation runs. Do not present a brief and then continue to code in the same response, even if the brief feels obvious to you. The user's confirmation is the gate.
**Choose the brief shape based on how clear the answers are:**
- **Compact form (3-5 bullets)** when discovery was crisp and the original prompt + PRODUCT.md already pinned scope, content, and direction. State what you're building, the visual lane, and end with one or two specific questions or a clear "confirm or override?" prompt. This is the default for typical craft requests with a clear prompt.
- **Full structured form (sections below)** when the task is genuinely ambiguous, multi-screen, or when the user asked for shape as a standalone step. Use this when the discipline of structure earns its weight.
Don't pad a clear brief into a long one to look thorough. A 70-line brief restating answers the user just gave is noise, not rigor. Equally, don't skip the confirmation pause to look efficient: the pause is the point.
If the user already said "approved" or "go" during discovery for the *exact direction you'd present*, that counts as confirmation; you may proceed without asking again. But if your brief adds anything the user hasn't seen and approved, you must stop and confirm.
### Brief Structure
@@ -136,16 +148,18 @@ List every state the feature needs: default, empty, loading, error, success, edg
How users interact with this feature. What happens on click, hover, scroll? What feedback do they get? What's the flow from entry to completion?
**8. Content Requirements**
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges.
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges. For image-led surfaces, also list the required image/media roles and their likely source (project asset, generated raster, semantic SVG/CSS, canvas/WebGL, icon library, or accepted omission).
**9. Recommended References**
Based on the brief, list which impeccable reference files would be most valuable during implementation (e.g., spatial-design.md for complex layouts, motion-design.md for animated features, interaction-design.md for form-heavy features).
**10. Open Questions**
Anything unresolved that the implementer should resolve during build.
Anything genuinely unresolved. Don't list "open questions" you've already recommended a default for; assert the default and move on. If you'd write `Recommend: X` next to a question, just decide X.
---
ask the user directly to clarify what you cannot infer. Ask for explicit confirmation of the brief before finishing. If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the brief is confirmed.
ask the user directly to clarify what you cannot infer.
If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the user confirms direction (or the user already gave a clear go during discovery, which counts).
Once confirmed, the brief is complete. The user can now hand it to /impeccable, or use it to guide any other implementation approach. (If the user wants the full discovery-then-build flow in one step, they should use /impeccable craft instead, which runs this command internally.)
+6 -19
View File
@@ -9,28 +9,15 @@ license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md f
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
## Setup (non-optional)
## Setup
Before any design work or file edits, pass these gates. Skipping them produces generic output that ignores the project.
Before any design work or file edits:
| Gate | Required check | If fail |
|---|---|---|
| Context | The PRODUCT.md / DESIGN.md loader result is known from `node .trae-cn/skills/impeccable/scripts/load-context.mjs`. | Run the loader before continuing. |
| Product | PRODUCT.md exists and is not empty or placeholder (`[TODO]` markers, <200 chars). | Run `/impeccable teach`, refresh context, then resume. Never synthesize PRODUCT.md from the user's original prompt alone. |
| Command | The matching command reference is loaded when a sub-command is used. | Load the reference before continuing. |
| Craft | `/impeccable craft` has a user-confirmed shape brief for this task. `teach` / PRODUCT.md never counts as shape. | Run `/impeccable shape` and wait for explicit brief confirmation. |
| Image | Required visual probes / mocks are generated or skipped with a reason. | Resolve the image-generation gate in `shape.md` or `craft.md` before code. |
| Mutation | All active gates above pass. | Do not edit project files yet. |
1. Load context (PRODUCT.md / DESIGN.md) via the loader script.
2. Identify the register and load the matching register reference (brand.md or product.md).
3. **If the user invoked a sub-command (e.g. `craft`, `shape`, `audit`), load its reference file too.** This is non-negotiable: `craft` without `craft.md` loaded means you'll skip the shape-and-confirm step the user expects.
Codex-style agents must state this before editing files:
```text
IMPECCABLE_PREFLIGHT: context=pass product=pass command_reference=pass shape=pass|not_required image_gate=pass|skipped:<reason> mutation=open
```
For `/impeccable craft`, `shape=pass` is only valid after a separate user response approving the shape design brief, or when the user provided an already-confirmed brief in the request. Do not mark `shape=pass` after writing PRODUCT.md, summarizing assumptions, or drafting an unconfirmed brief yourself.
Other harnesses should follow the same checklist when they can expose this state.
Skipping these produces generic output that ignores the project.
### 1. Context gathering
@@ -12,6 +12,8 @@ Brand isn't a neutral register. AI-generated landing pages have flooded the inte
**The second slop test: aesthetic lane.** Before committing to moves, name the reference. A Klim-style specimen page is one lane; Stripe-minimal is another; Liquid-Death-acid-maximalism is another. Don't drift into editorial-magazine aesthetics on a brief that isn't editorial. A hiking brand with Cormorant italic drop caps has the wrong register within the register.
Then the inverse test: in one sentence, describe what you're about to build the way a competitor would describe theirs. If that sentence fits the modal landing page in the category, restart.
## Typography
### Font selection procedure
@@ -66,6 +68,7 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
- Palette IS voice. A calm brand and a restless brand should not share palette mechanics.
- When the strategy is Committed or Drenched, color carries the brand. Don't hedge with neutrals around the edges. Commit.
- Don't converge across projects. If the last brand surface was restrained-on-cream, this one is not.
- When a cultural-symbol palette is the obvious pull, reach past it. Let the cultural reading come from typography, imagery, and copy, not the palette.
## Layout
@@ -79,14 +82,14 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
Brand surfaces lean on imagery. A restaurant, hotel, magazine, or product landing page without any imagery reads as incomplete, not as restrained. A solid-color rectangle where a hero image should go is worse than a representative stock photo.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse. If the approved comp or brief is image-led, ship real project assets, generated raster assets, or a credible canvas/SVG/WebGL scene. Do not replace photographic, architectural, product, or place imagery with generic CSS panels, decorative diagrams, cards, bullets, or copy.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. Pick real Unsplash photo IDs you're confident exist (`photo-1559339352-11d035aa65de`, `photo-1590490360182-c33d57733427`, etc.); if unsure, pick fewer photos but don't substitute colored `<div>` placeholders.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. **Verify the URLs before referencing them.** If you have an image-search MCP, web-fetch tool, or browser access, use it to find real photo IDs and confirm they resolve. Guessed IDs (even ones that look real) often 404 and ship as broken-image placeholders. Without a verification path, pick fewer photos you're confident exist over more that you guessed; never substitute colored `<div>` placeholders.
- **Search for the brand's physical object**, not the generic category: "handmade pasta on a scratched wooden table" beats "Italian food"; "cypress trees above a limestone hotel facade at dusk" beats "luxury hotel".
- **One decisive photo beats five mediocre ones.** Hero imagery should commit to a mood; padding with more stock doesn't rescue an indecisive one.
- **Alt text is part of the voice.** "Coastal fettuccine, hand-cut, served on the terrace" beats "pasta dish".
Tech / dev-tool brands are the exception where zero imagery can be correct; a developer landing page often carries its voice through typography, code samples, diagrams. Know which kind of brand you're working on.
"Imagery" here is broader than stock photography: product screenshots, custom data visualizations, generated SVG, and canvas/WebGL scenes are all imagery. Text-only pages where typography alone carries the entire visual weight are the failure mode.
## Motion
@@ -102,6 +105,7 @@ Tech / dev-tool brands are the exception where zero imagery can be correct; a de
- Timid palettes and average layouts. Safe = invisible.
- Zero imagery on a brief that implies imagery (restaurant, hotel, food, travel, fashion, photography, hobbyist). Colored blocks where a hero photo belongs.
- Defaulting to editorial-magazine aesthetics (display serif + italic + drop caps + broadsheet grid) on briefs that aren't magazine-shaped. Editorial is ONE aesthetic lane, not the default brand aesthetic.
- Repeated tiny uppercase tracked labels above every section heading. A single strong kicker can be voice; repeating it as section grammar is AI scaffolding unless it's a deliberate, named brand system.
## Brand permissions
+73 -111
View File
@@ -1,43 +1,41 @@
# Craft Flow
Build a feature with impeccable UX and UI quality through a structured process: shape the design, land the visual direction, build real production code, then inspect and improve in-browser until the result meets a high-end studio bar.
Build a feature with impeccable UX and UI quality: shape the design, land the visual direction, build real production code, inspect and improve in-browser until it meets a high-end studio bar.
## Build Gate
Before writing code, you need: PRODUCT.md loaded, register identified and the matching reference loaded, and a confirmed design direction for this task (either from `shape` or supplied by the user). PRODUCT.md is project context, not a task-specific brief.
Craft cannot build until all of these are true:
Treat any approved visual direction (generated mock or stated reference) as a concrete contract for composition, hierarchy, density, atmosphere, signature motifs, and distinctive visual moves. Don't let mocks replace structure, copy, accessibility, or state design. But if the live result lacks the approved direction's major ingredients, the implementation is wrong.
1. PRODUCT context is valid and current.
2. The shape design brief is explicitly confirmed by the user for this task, unless the user already provided a confirmed brief.
3. Implementation references from the brief are loaded.
4. The shape visual probe decision is recorded: generated, skipped with reason, or already resolved.
5. The north-star mock decision is recorded: generated, skipped with reason, or not applicable.
## Step 0: Project Foundation
PRODUCT.md and `teach` answers do **not** satisfy the shape gate. They are project context only. A compact self-authored brief does not satisfy the shape gate either. `shape=pass` requires a separate user response approving the shape brief or an already-confirmed brief supplied by the user.
Before shape, before code: figure out what kind of project you're working in.
Invalid image-skip reasons include: "the final implementation will be semantic HTML/CSS/SVG", "the diagram should stay editable", "a raster mock would not be used directly", or "the product is fictional." Generated probes and mocks are direction artifacts; they are not implementation assets.
Look at the working directory. Run `ls`. Check for:
## Craft Contract
- An existing framework: `astro.config.mjs/ts`, `next.config.js/ts`, `nuxt.config.ts`, `svelte.config.js`, `vite.config.js/ts`, `package.json` with framework deps, `Cargo.toml` + Leptos/Yew, `Gemfile` + Rails. **If found, use it.** Do not start a parallel build, do not introduce a second framework, do not write to `dist/` or `build/` directly. Whatever pipeline the project has, respect it.
- An existing component library or design system: `src/components/`, `app/components/`, a `tokens.css` / `theme.ts`, an `astro.config` `integrations`. Read what's there before adding to it.
- An existing icon set: `lucide-react`, `@phosphor-icons/react`, `@iconify/*`, hand-rolled SVG sprites in `assets/icons/`. **Use what's already in the project**; don't introduce a second set.
Craft is not a first pass. It is a loop with these required artifacts:
If the directory is empty (greenfield), don't pick a framework silently. Ask the user via the AskUserQuestion tool, with sensible defaults framed by the brief:
1. Confirmed design brief from `shape`.
2. Approved visual direction, from generated probes / mocks when image generation is available.
3. Mock fidelity inventory: the visible ingredients from the approved direction that must survive into code.
4. Semantic, functional implementation using the project's real stack and conventions.
5. Browser evidence across relevant viewports.
6. At least one critique-and-fix pass after the first browser inspection, unless the first pass has no material defects.
```text
What should this be built on?
- Astro (default for content-led brand sites, landing pages, marketing surfaces)
- SvelteKit / Next.js / Nuxt (when the brief implies an app surface or significant interactivity)
- Single index.html (one-shot demo, prototype, or a deliberately framework-free experiment)
```
Do not let generated mockups replace interface structure, copy, accessibility, responsive behavior, or state design. But do treat the approved mock as a concrete visual contract for composition, hierarchy, density, atmosphere, signature motifs, image needs, and distinctive visual moves. "North star" means "preserve the important visible ingredients in semantic code," not "use it as loose mood."
Default: Astro for brand briefs, the project's existing framework for product briefs. Ask once; don't re-ask mid-task.
## Step 1: Shape the Design
Run /impeccable shape, passing along whatever feature description the user provided.
Run /impeccable shape, passing along whatever feature description the user provided. Shape is **required** for craft; it is what produces a confirmed direction.
Wait for the design brief to be fully confirmed by the user before proceeding. The brief is your blueprint, and every implementation decision should trace back to it.
Present the shape output and stop. Wait for the user to confirm, override, or course-correct before writing code.
If this craft run resumed after `teach` created PRODUCT.md, run shape now. Do not treat the teach interview, PRODUCT.md, or a summary of project context as a substitute for shape. Shape is task-specific and must cover scope, content/states, visual direction, constraints, anti-goals, probes when applicable, and explicit brief confirmation.
If the user already supplied a confirmed brief or ran shape separately, use it and skip this step.
If the user has already run /impeccable shape and has a confirmed design brief, skip this step and use the existing brief.
When the original prompt + PRODUCT.md already answer scope, content, and visual direction with no real ambiguity, the shape output can be **compact** (3-5 bullets stating what you're building and the visual lane, ending with one or two specific questions or "confirm or override"). The full 10-section structured brief is reserved for genuinely ambiguous, multi-screen, or stakeholder-heavy tasks. Don't pad a clear brief into a long one to look thorough; equally, don't skip the pause to look efficient.
## Step 2: Load References
@@ -55,79 +53,60 @@ Then add references based on the brief's needs:
## Step 3: Land the Visual Direction (Capability-Gated)
Before implementation, generate high-fidelity visual comps when all of these are true:
Generate high-fidelity visual comps before implementation when all three are true:
- The work is **net-new** or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is **mid-fi, high-fi, or production-ready**.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The work is net-new or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is mid-fi, high-fi, or production-ready.
- The harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool). Don't ask the user to set up external APIs.
When those conditions are met, this step is mandatory for **both brand and product work** in Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
Do not skip this step because the eventual UI should be semantic, editable, code-native, responsive, or accessible. Those are implementation requirements, not reasons to avoid visual exploration.
### Purpose
Use the mock step to find a stronger visual lane than code-first generation would reliably discover on its own. The brief remains authoritative on user, purpose, content, constraints, states, and anti-goals. The mock clarifies composition, hierarchy, density, typography, and visual tone.
When met, this step is mandatory for both brand and product work. If image generation isn't available, skip silently. "The eventual UI is semantic/code-native/accessible" is not a reason to skip; those are implementation requirements, not exploration ones.
### What to generate
Generate **1 to 3** high-fidelity north-star comps based on the confirmed brief. If shape already produced direction probes, use those results as input and generate a more resolved mock from the winning lane, not another unrelated exploration.
Generate **1 to 3** high-fidelity north-star comps from the confirmed brief. If shape already produced direction probes, resolve the winning lane further, not an unrelated exploration. Comps must differ in primary visual direction, not just color.
- For brand work, push visual identity, composition, and mood aggressively.
- For product work, still push hierarchy, topology, density, and tone, but keep the comps grounded in realistic product structure and states.
- For landing pages and long-form brand surfaces, show enough of the next section or second fold to establish the system beyond the hero.
The comps must be genuinely different in primary visual direction, not just color variants.
- Brand work: push visual identity, composition, and mood aggressively.
- Product work: push hierarchy, topology, density, tone, grounded in realistic product structure.
- Landing pages and long-form brand surfaces: show enough of the second fold to establish the system beyond the hero.
### Approval loop
Show the comps and ask what should carry forward. If the user asks for changes or the best direction is still weak, generate a focused revision before implementation. Continue until one direction is approved, or until the user explicitly delegates the choice.
Show the comps and ask what carries forward. Iterate until one direction is approved or the user delegates. If the user delegates, pick the strongest direction and explain it from the brief, not personal taste.
If the user delegates, pick the strongest direction and explain the decision using the brief, not personal taste.
Before moving to implementation, summarize:
- What to carry into code
- What **not** to literalize from the mock
This summary is required before Step 4. It is the handoff between visual exploration and semantic implementation.
Before Step 4, summarize what to carry into code and what **not** to literalize from the mock. This is the handoff between visual exploration and semantic implementation.
### Mock fidelity inventory
Before building, inventory the approved mock's major visible ingredients:
Inventory the approved mock's major visible ingredients:
- Hero silhouette and dominant composition.
- Signature motifs: planets, devices, portraits, charts, route lines, insets, badges, or other memorable objects.
- Nav and primary CTA treatment.
- Section sequence visible in the mock, especially the second fold.
- Image-native content the concept depends on.
- Typography, density, color/material treatment, and motion cues.
- Hero silhouette and dominant composition
- Signature motifs (planets, devices, portraits, charts, route lines, insets, badges, etc.)
- Nav and primary CTA treatment
- Section sequence, especially the second fold
- Image-native content the concept depends on
- Typography, density, color/material treatment, motion cues
For each ingredient, decide how it will be implemented: semantic HTML/CSS/SVG, generated asset, sourced project asset, icon library, canvas/WebGL, or an explicitly accepted omission. Do not substitute a different hero composition or new visual driver after approval unless the user approves the change.
For each, decide implementation: semantic HTML/CSS/SVG, generated asset, sourced asset, icon library, canvas/WebGL, or accepted omission. Don't substitute a different hero composition or visual driver post-approval without user sign-off.
Treat the mock as a **north star**, not a screenshot to trace. Do **not** rasterize core UI text or let the mock override the confirmed brief. But if the live result lacks the mock's major visible ingredients, the implementation is wrong.
If a photographic, architectural, product, or place-led mock becomes generic CSS scenery / decorative diagrams / bullets / copy, stop and fix it. That's a broken implementation, not a harmless interpretation.
Treat the mock as a north star, not a screenshot to trace. Don't rasterize core UI text. But if the live result lacks the mock's major ingredients, the implementation is wrong.
## Step 4: Asset Extraction (Need-Gated)
If the chosen direction includes image-native visual ingredients that would materially improve the implementation, generate them as separate assets before building.
If the approved direction needs raster assets, create them before building. Do not replace required imagery with generic cards, bullets, emoji, fake metrics, decorative CSS panels, or filler copy.
Good candidates:
Use the native asset producer (`impeccable_asset_producer` in Codex, `impeccable-asset-producer` in Claude Code) to create clean assets from the hi-fi mock and crops. If you do not have explicit permission to use agents, stop and ask:
- stickers
- badges
- seals
- tickets
- graphic labels
- textures
- abstract objects
- decorative marks
- non-semantic scene elements
```text
Asset production will work better as a scoped subagent job. Should I spawn the Impeccable asset producer subagent for this step?
```
For travel, editorial, portfolio, venue, product showcase, entertainment, education, or any other image-led brand surface, visual assets are usually core content, not decoration. Do not ship abstract CSS panels where the approved mock or subject matter calls for real imagery, generated plates, illustrations, maps, product/object renders, or destination scenes.
Do not skip asset production or silently do it inline. Inline asset production is allowed only if the user declines subagents, the harness cannot spawn the authorized agent, or the user explicitly asks for single-thread mode.
Do **not** export assets for core UI text, navigation, body copy, or any structure that should stay semantic and editable in code.
Pass the approved mock, crop/contact-sheet paths, output directory, dimensions/formats, transparency needs, constraints, and avoid list to the asset producer. Attach image generation capability to the spawned agent when the harness supports it; do not load image-generation reference material into the parent thread first.
Usually **1 to 5** extracted assets is enough. If the design can be built cleanly in HTML/CSS/SVG, prefer that over raster assets. If the mock contains major visual content that cannot be built credibly in code, asset extraction is not optional.
Prefer HTML/CSS/SVG/canvas when they can credibly reproduce an ingredient; use real/generated/stock imagery when the mock or subject matter calls for actual visual content.
## Step 5: Build to Production Quality
@@ -135,50 +114,35 @@ Implement the feature following the design brief. Build in passes so structure,
### Production bar
- Use real or realistic content. Remove placeholder copy, placeholder images, dead links, fake controls, and unused scaffold before presenting.
- Preserve the approved mock's major ingredients. Missing hero objects, missing world/product imagery, different section structure, downgraded CTA/nav treatment, or generic replacements for distinctive motifs are blocking defects unless the user accepted the change.
- Build semantically first: real headings, landmarks, labels, form associations, button/link semantics, accessible names, and state announcements where needed.
- Calibrate spacing, alignment, grid placement, and vertical rhythm deliberately. Do not accept default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- Make typography intentional: chosen font loading strategy, clear hierarchy, readable measure, stable line breaks, tuned wrapping, and no overflow at mobile or large desktop sizes.
- Design realistic state coverage: default, hover where supported, focus-visible, active, disabled, loading, error, success, empty, overflow, long text, short text, and first-run states where relevant.
- Make interaction quality feel finished: keyboard paths, touch targets, feedback timing, scroll behavior, transitions between states, and no hover-only functionality.
- Use icons from the project's established icon set when available. If no set exists, choose a coherent library or use accessible text controls; do not mix unrelated icon styles.
- Optimize imagery and media: correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset` / `picture` for raster assets, and no project-referenced asset left outside the workspace.
- Make motion feel premium: use atmospheric blur, filter, mask, shadow, or reveal effects when they improve the experience; avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- Preserve maintainability: reusable local patterns, clear component boundaries, project conventions, no rasterized UI text, and no hard-coded one-off hacks when a better local pattern exists.
- Fit the technical context: production build passes, no obvious console errors, no avoidable layout shift, no needless dependency, and no broken asset path.
- If you discover a design question that materially changes the brief or approved direction, stop and ask rather than guessing.
- **Real content.** No placeholder copy, placeholder images, dead links, fake controls, or unused scaffold at presentation time.
- **Preserve the approved mock's major ingredients.** Missing hero objects, world/product imagery, section structure, CTA/nav treatment, or distinctive motifs are blocking defects unless the user accepted the change.
- **Semantic first.** Real headings, landmarks, labels, form associations, button/link semantics, accessible names, state announcements where needed.
- **Deliberate spacing and alignment.** No default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- **Intentional typography.** Chosen loading strategy, clear hierarchy, readable measure, stable line breaks, no overflow at any width.
- **Realistic state coverage.** Default, hover, focus-visible, active, disabled, loading, error, success, empty, overflow, long/short text, first-run.
- **Finished interaction quality.** Keyboard paths, touch targets, feedback timing, scroll behavior, state transitions, no hover-only functionality.
- **Coherent icon set.** Use the project's established set; otherwise pick one library or use accessible text. Don't mix.
- **Respect the build pipeline.** Edit source files and run the project's build (`npm run build` or equivalent). Don't write to `build/` / `dist/` / `.next/` with `cat`, heredoc, or Bash redirects; that skips asset hashing, image optimization, code splitting, and CSS extraction, and produces output the dev server won't serve.
- **Verify image URLs before referencing them.** Use image-search MCP or web-fetch when available; guessed photo IDs ship as broken-image placeholders. Without verification, prefer fewer images you're confident about.
- **Optimized imagery and media.** Correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset`/`picture` for raster, no project-referenced asset left outside the workspace.
- **Premium motion.** Use atmospheric blur, filter, mask, shadow, reveal when they improve the experience. Avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- **Maintainable.** Reusable local patterns, clear component boundaries, project conventions. No rasterized UI text or one-off hacks when a local pattern exists.
- **Technically clean.** Production build passes, no console errors, no avoidable layout shift, no needless dependencies, no broken asset paths.
- **Ask when uncertain.** If a discovery materially changes the brief or approved direction, stop and ask. Don't guess.
## Step 6: Browser-Based Iteration
## Step 6: Iterate Visually
**This step is critical.** Do not stop after the first implementation pass.
Look at what you built like a designer would. Your eyes are whatever the harness gives you: a connected browser, a screenshotting tool, Playwright, or asking the user. Use them for responsive testing (mobile, tablet, desktop minimum) and general visual validation.
Open the result in a browser. In Codex, use browser-use or equivalent browser automation when available; otherwise use Playwright or ask the user for screenshots. Inspect screenshots, not just DOM or terminal output.
If your tool returns a file path, read the PNG back into the conversation. A screenshot you didn't read doesn't count.
### Required viewport pass
For long-form brand surfaces, inspect major sections individually. Thumbnails hide spacing, clipping, and cascade defects.
Check the experience at the viewports that matter for the brief. Default minimum:
After the first pass, write an honest critique against the brief, the approved mock's major ingredients (hero silhouette, motifs, imagery, nav/CTA, density), and impeccable's DON'Ts. Patch material defects and re-inspect. **Don't invent defects to demonstrate iteration.** A confident "first pass clean, shipping" beats a fake fix.
- Mobile narrow
- Tablet or small laptop
- Desktop wide
Actively check: responsive behavior (composes, not shrinks), every state (empty / error / loading / edge), craft details (spacing, alignment, hierarchy, contrast, motion timing, focus), performance basics. The exit bar: defensible in a high-end studio review.
For each viewport, capture or inspect the rendered state and look for visual defects: overlap, clipping, weak hierarchy, off-grid alignment, awkward whitespace, cramped controls, unreadable type, broken imagery, hover-only functionality, layout shift, and text overflow.
### Critique and fix loop
After the first browser pass, write a short critique for yourself and patch the implementation. Repeat browser inspection after fixes. Continue until no material issues remain against this checklist:
1. **Does it match the brief?** Compare the live result against every section of the design brief. Fix discrepancies.
2. **Does it match the approved mock?** Compare screenshots against the mock fidelity inventory: hero silhouette, major motifs, imagery, nav/CTA, section sequence, density, color/materials, and second-fold substance. Missing major ingredients are P0 defects.
3. **Does it pass the AI slop test?** If someone saw this and said "AI made this," would they believe it immediately? If yes, it needs more design intention.
4. **Check against impeccable's DON'T guidelines.** Fix any anti-pattern violations.
5. **Check every state.** Navigate through empty, error, loading, and edge case states. Each one should feel intentional, not like an afterthought.
6. **Check responsive behavior.** The design should adapt compositionally, not merely shrink.
7. **Check craft details.** Spacing consistency, optical alignment, type hierarchy, color contrast, image quality, icon coherence, interactive feedback, motion timing, and focus treatment.
8. **Check performance basics.** No obviously oversized images, avoidable layout thrash, blocking animations, or heavy assets without a reason.
The exit bar is not "it works." It is: the rendered result looks intentional at all checked viewports, all expected states are handled, no placeholders remain unless explicitly accepted, and the implementation quality would be defensible in a high-end studio review.
Detector or QA output is defect evidence only; never proof the work is finished.
## Step 7: Present
@@ -189,5 +153,3 @@ Present the result to the user:
- Explain design decisions that connect back to the design brief and, when used, the chosen north-star mock. Include any accepted deviations from the mock; do not hide unimplemented mock ingredients.
- Note any remaining limitations or follow-up risks honestly
- Ask: "What's working? What isn't?"
Iterate based on feedback. Good design is rarely right on the first pass.
@@ -43,7 +43,7 @@ Run the bundled deterministic detector, which flags 27 specific patterns (AI slo
**CLI scan**:
```bash
npx impeccable --json [--fast] [target]
npx impeccable detect --json [--fast] [target]
```
- Pass HTML/JSX/TSX/Vue/Svelte files or directories as `[target]` (anything with markup). Do not pass CSS-only files.
@@ -2,6 +2,8 @@
Perform a meticulous final pass to catch all the small details that separate good work from great work. The difference between shipped and polished.
Detector and automated QA output are defect evidence only. A clean script result is never proof that the design is strong; gather browser evidence and inspect the real interaction path.
## Design System Discovery
Aligning the feature to the design system is **not optional**. Polish without alignment is decoration on top of drift, and it makes the next person's job harder. Discovery comes before any other polish work.
@@ -216,11 +218,12 @@ Sweat the details. Zoom in until the alignment is right and the spacing reads as
Before marking as done:
- **Use it yourself**: Actually interact with the feature
- **Test on real devices**: Not just browser DevTools
- **Ask someone else to review**: Fresh eyes catch things
- **Compare to design**: Match intended design
- **Check all states**: Don't just test happy path
- **Use it yourself**: Actually interact with the feature.
- **Test on real devices**: Not just browser DevTools.
- **Ask someone else to review**: Fresh eyes catch things.
- **Compare to design**: Match intended design.
- **Check all states**: Don't just test happy path.
- **Treat automation carefully**: Run detector or QA commands when they are available and relevant, fix their defects, but never cite a clean result as proof that the work is polished.
## Clean Up
@@ -230,4 +233,3 @@ After polishing, ensure code quality:
- **Remove orphaned code**: Delete unused styles, components, or files made obsolete by polish.
- **Consolidate tokens**: If you introduced new values, check whether they should be tokens.
- **Verify DRYness**: Look for duplication introduced during polishing and consolidate.
+25 -11
View File
@@ -16,14 +16,16 @@ This is a required interaction, not optional guidance. Ask these questions in co
### Interview cadence
Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed design inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
Discovery includes at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
- Use the harness's structured question tool when one exists. Otherwise, ask directly in chat and stop.
- Ask **2-3 questions per round**, then wait for answers.
- Treat PRODUCT.md and DESIGN.md as anchors; they reduce repeated questions but do **not** replace shape for craft. Shape is task-specific.
- Round 1 should clarify purpose, audience/context, and success or emotional outcome.
- Round 2 should clarify content/data/states and scope/fidelity.
- Round 3 should clarify visual direction, constraints, and anti-goals when still unresolved.
- One round is the default. Add a second only if the first answers leave material gaps. Don't run a second round just to feel thorough.
- Round 1 should clarify purpose, audience/context, content/scope, and (for brand) visual direction.
- Round 2, when needed, fills in whatever's still genuinely missing.
**Assert-then-confirm, not menu-with-escape.** When PRODUCT.md and the user's prompt make one option obvious, name it and ask the user to confirm or override. Don't enumerate "Restrained / Committed / Or something else?" as a real choice; "This reads as Restrained, confirm?" beats a four-option menu when the answer is already clear.
### Purpose & Context
- What is this feature for? What problem does it solve?
@@ -36,6 +38,7 @@ Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.
- What are the realistic ranges? (Minimum, typical, maximum, e.g., 0 items, 5 items, 500 items)
- What are the edge cases? (Empty state, error state, first-time use, power user)
- Is any content dynamic? What changes and how often?
- What visual assets are real content here? Note required images, product shots, illustrations, maps, textures, diagrams, generated objects, or existing project assets.
### Design Direction
@@ -72,9 +75,9 @@ After the discovery interview, generate a small set of visual direction probes *
- The work is **net-new** or directionally ambiguous enough that visual exploration will clarify the brief.
- The requested fidelity is **mid-fi, high-fi, or production-ready**. Skip for sketch-only planning.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The current harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool, or similar). Don't ask the user to install APIs or tooling.
When those conditions are met, this step is mandatory for Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
When those conditions are met, this step is mandatory. If image generation isn't natively available, skip silently and proceed; don't announce the skip.
Use probes to explore visual lanes, not to replace the brief.
@@ -104,11 +107,20 @@ The probes should differ in primary visual direction (hierarchy, topology, densi
- Do **not** treat generated imagery as final UX specification, final copy, or final accessibility behavior.
- Do **not** use this step for minor refinements of existing work. It's for shaping a new surface or clarifying a big directional choice.
If image generation is unavailable, or the task doesn't benefit from it, skip this phase only with a one-line reason and proceed directly to the design brief.
If image generation isn't natively available, skip this phase silently and proceed.
## Phase 2: Design Brief
After the interview and any required probes, synthesize everything into a structured design brief. Present it to the user for explicit confirmation before considering this command complete. Stop after asking for confirmation; do not proceed to craft or implementation in the same response unless the user has already approved the brief.
After the interview and any required probes, present a brief and **end your response**. The user must confirm before any implementation runs. Do not present a brief and then continue to code in the same response, even if the brief feels obvious to you. The user's confirmation is the gate.
**Choose the brief shape based on how clear the answers are:**
- **Compact form (3-5 bullets)** when discovery was crisp and the original prompt + PRODUCT.md already pinned scope, content, and direction. State what you're building, the visual lane, and end with one or two specific questions or a clear "confirm or override?" prompt. This is the default for typical craft requests with a clear prompt.
- **Full structured form (sections below)** when the task is genuinely ambiguous, multi-screen, or when the user asked for shape as a standalone step. Use this when the discipline of structure earns its weight.
Don't pad a clear brief into a long one to look thorough. A 70-line brief restating answers the user just gave is noise, not rigor. Equally, don't skip the confirmation pause to look efficient: the pause is the point.
If the user already said "approved" or "go" during discovery for the *exact direction you'd present*, that counts as confirmation; you may proceed without asking again. But if your brief adds anything the user hasn't seen and approved, you must stop and confirm.
### Brief Structure
@@ -136,16 +148,18 @@ List every state the feature needs: default, empty, loading, error, success, edg
How users interact with this feature. What happens on click, hover, scroll? What feedback do they get? What's the flow from entry to completion?
**8. Content Requirements**
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges.
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges. For image-led surfaces, also list the required image/media roles and their likely source (project asset, generated raster, semantic SVG/CSS, canvas/WebGL, icon library, or accepted omission).
**9. Recommended References**
Based on the brief, list which impeccable reference files would be most valuable during implementation (e.g., spatial-design.md for complex layouts, motion-design.md for animated features, interaction-design.md for form-heavy features).
**10. Open Questions**
Anything unresolved that the implementer should resolve during build.
Anything genuinely unresolved. Don't list "open questions" you've already recommended a default for; assert the default and move on. If you'd write `Recommend: X` next to a question, just decide X.
---
ask the user directly to clarify what you cannot infer. Ask for explicit confirmation of the brief before finishing. If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the brief is confirmed.
ask the user directly to clarify what you cannot infer.
If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the user confirms direction (or the user already gave a clear go during discovery, which counts).
Once confirmed, the brief is complete. The user can now hand it to /impeccable, or use it to guide any other implementation approach. (If the user wants the full discovery-then-build flow in one step, they should use /impeccable craft instead, which runs this command internally.)
+6 -19
View File
@@ -9,28 +9,15 @@ license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md f
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
## Setup (non-optional)
## Setup
Before any design work or file edits, pass these gates. Skipping them produces generic output that ignores the project.
Before any design work or file edits:
| Gate | Required check | If fail |
|---|---|---|
| Context | The PRODUCT.md / DESIGN.md loader result is known from `node .trae/skills/impeccable/scripts/load-context.mjs`. | Run the loader before continuing. |
| Product | PRODUCT.md exists and is not empty or placeholder (`[TODO]` markers, <200 chars). | Run `/impeccable teach`, refresh context, then resume. Never synthesize PRODUCT.md from the user's original prompt alone. |
| Command | The matching command reference is loaded when a sub-command is used. | Load the reference before continuing. |
| Craft | `/impeccable craft` has a user-confirmed shape brief for this task. `teach` / PRODUCT.md never counts as shape. | Run `/impeccable shape` and wait for explicit brief confirmation. |
| Image | Required visual probes / mocks are generated or skipped with a reason. | Resolve the image-generation gate in `shape.md` or `craft.md` before code. |
| Mutation | All active gates above pass. | Do not edit project files yet. |
1. Load context (PRODUCT.md / DESIGN.md) via the loader script.
2. Identify the register and load the matching register reference (brand.md or product.md).
3. **If the user invoked a sub-command (e.g. `craft`, `shape`, `audit`), load its reference file too.** This is non-negotiable: `craft` without `craft.md` loaded means you'll skip the shape-and-confirm step the user expects.
Codex-style agents must state this before editing files:
```text
IMPECCABLE_PREFLIGHT: context=pass product=pass command_reference=pass shape=pass|not_required image_gate=pass|skipped:<reason> mutation=open
```
For `/impeccable craft`, `shape=pass` is only valid after a separate user response approving the shape design brief, or when the user provided an already-confirmed brief in the request. Do not mark `shape=pass` after writing PRODUCT.md, summarizing assumptions, or drafting an unconfirmed brief yourself.
Other harnesses should follow the same checklist when they can expose this state.
Skipping these produces generic output that ignores the project.
### 1. Context gathering
+7 -3
View File
@@ -12,6 +12,8 @@ Brand isn't a neutral register. AI-generated landing pages have flooded the inte
**The second slop test: aesthetic lane.** Before committing to moves, name the reference. A Klim-style specimen page is one lane; Stripe-minimal is another; Liquid-Death-acid-maximalism is another. Don't drift into editorial-magazine aesthetics on a brief that isn't editorial. A hiking brand with Cormorant italic drop caps has the wrong register within the register.
Then the inverse test: in one sentence, describe what you're about to build the way a competitor would describe theirs. If that sentence fits the modal landing page in the category, restart.
## Typography
### Font selection procedure
@@ -66,6 +68,7 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
- Palette IS voice. A calm brand and a restless brand should not share palette mechanics.
- When the strategy is Committed or Drenched, color carries the brand. Don't hedge with neutrals around the edges. Commit.
- Don't converge across projects. If the last brand surface was restrained-on-cream, this one is not.
- When a cultural-symbol palette is the obvious pull, reach past it. Let the cultural reading come from typography, imagery, and copy, not the palette.
## Layout
@@ -79,14 +82,14 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
Brand surfaces lean on imagery. A restaurant, hotel, magazine, or product landing page without any imagery reads as incomplete, not as restrained. A solid-color rectangle where a hero image should go is worse than a representative stock photo.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse. If the approved comp or brief is image-led, ship real project assets, generated raster assets, or a credible canvas/SVG/WebGL scene. Do not replace photographic, architectural, product, or place imagery with generic CSS panels, decorative diagrams, cards, bullets, or copy.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. Pick real Unsplash photo IDs you're confident exist (`photo-1559339352-11d035aa65de`, `photo-1590490360182-c33d57733427`, etc.); if unsure, pick fewer photos but don't substitute colored `<div>` placeholders.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. **Verify the URLs before referencing them.** If you have an image-search MCP, web-fetch tool, or browser access, use it to find real photo IDs and confirm they resolve. Guessed IDs (even ones that look real) often 404 and ship as broken-image placeholders. Without a verification path, pick fewer photos you're confident exist over more that you guessed; never substitute colored `<div>` placeholders.
- **Search for the brand's physical object**, not the generic category: "handmade pasta on a scratched wooden table" beats "Italian food"; "cypress trees above a limestone hotel facade at dusk" beats "luxury hotel".
- **One decisive photo beats five mediocre ones.** Hero imagery should commit to a mood; padding with more stock doesn't rescue an indecisive one.
- **Alt text is part of the voice.** "Coastal fettuccine, hand-cut, served on the terrace" beats "pasta dish".
Tech / dev-tool brands are the exception where zero imagery can be correct; a developer landing page often carries its voice through typography, code samples, diagrams. Know which kind of brand you're working on.
"Imagery" here is broader than stock photography: product screenshots, custom data visualizations, generated SVG, and canvas/WebGL scenes are all imagery. Text-only pages where typography alone carries the entire visual weight are the failure mode.
## Motion
@@ -102,6 +105,7 @@ Tech / dev-tool brands are the exception where zero imagery can be correct; a de
- Timid palettes and average layouts. Safe = invisible.
- Zero imagery on a brief that implies imagery (restaurant, hotel, food, travel, fashion, photography, hobbyist). Colored blocks where a hero photo belongs.
- Defaulting to editorial-magazine aesthetics (display serif + italic + drop caps + broadsheet grid) on briefs that aren't magazine-shaped. Editorial is ONE aesthetic lane, not the default brand aesthetic.
- Repeated tiny uppercase tracked labels above every section heading. A single strong kicker can be voice; repeating it as section grammar is AI scaffolding unless it's a deliberate, named brand system.
## Brand permissions
+73 -111
View File
@@ -1,43 +1,41 @@
# Craft Flow
Build a feature with impeccable UX and UI quality through a structured process: shape the design, land the visual direction, build real production code, then inspect and improve in-browser until the result meets a high-end studio bar.
Build a feature with impeccable UX and UI quality: shape the design, land the visual direction, build real production code, inspect and improve in-browser until it meets a high-end studio bar.
## Build Gate
Before writing code, you need: PRODUCT.md loaded, register identified and the matching reference loaded, and a confirmed design direction for this task (either from `shape` or supplied by the user). PRODUCT.md is project context, not a task-specific brief.
Craft cannot build until all of these are true:
Treat any approved visual direction (generated mock or stated reference) as a concrete contract for composition, hierarchy, density, atmosphere, signature motifs, and distinctive visual moves. Don't let mocks replace structure, copy, accessibility, or state design. But if the live result lacks the approved direction's major ingredients, the implementation is wrong.
1. PRODUCT context is valid and current.
2. The shape design brief is explicitly confirmed by the user for this task, unless the user already provided a confirmed brief.
3. Implementation references from the brief are loaded.
4. The shape visual probe decision is recorded: generated, skipped with reason, or already resolved.
5. The north-star mock decision is recorded: generated, skipped with reason, or not applicable.
## Step 0: Project Foundation
PRODUCT.md and `teach` answers do **not** satisfy the shape gate. They are project context only. A compact self-authored brief does not satisfy the shape gate either. `shape=pass` requires a separate user response approving the shape brief or an already-confirmed brief supplied by the user.
Before shape, before code: figure out what kind of project you're working in.
Invalid image-skip reasons include: "the final implementation will be semantic HTML/CSS/SVG", "the diagram should stay editable", "a raster mock would not be used directly", or "the product is fictional." Generated probes and mocks are direction artifacts; they are not implementation assets.
Look at the working directory. Run `ls`. Check for:
## Craft Contract
- An existing framework: `astro.config.mjs/ts`, `next.config.js/ts`, `nuxt.config.ts`, `svelte.config.js`, `vite.config.js/ts`, `package.json` with framework deps, `Cargo.toml` + Leptos/Yew, `Gemfile` + Rails. **If found, use it.** Do not start a parallel build, do not introduce a second framework, do not write to `dist/` or `build/` directly. Whatever pipeline the project has, respect it.
- An existing component library or design system: `src/components/`, `app/components/`, a `tokens.css` / `theme.ts`, an `astro.config` `integrations`. Read what's there before adding to it.
- An existing icon set: `lucide-react`, `@phosphor-icons/react`, `@iconify/*`, hand-rolled SVG sprites in `assets/icons/`. **Use what's already in the project**; don't introduce a second set.
Craft is not a first pass. It is a loop with these required artifacts:
If the directory is empty (greenfield), don't pick a framework silently. Ask the user via the AskUserQuestion tool, with sensible defaults framed by the brief:
1. Confirmed design brief from `shape`.
2. Approved visual direction, from generated probes / mocks when image generation is available.
3. Mock fidelity inventory: the visible ingredients from the approved direction that must survive into code.
4. Semantic, functional implementation using the project's real stack and conventions.
5. Browser evidence across relevant viewports.
6. At least one critique-and-fix pass after the first browser inspection, unless the first pass has no material defects.
```text
What should this be built on?
- Astro (default for content-led brand sites, landing pages, marketing surfaces)
- SvelteKit / Next.js / Nuxt (when the brief implies an app surface or significant interactivity)
- Single index.html (one-shot demo, prototype, or a deliberately framework-free experiment)
```
Do not let generated mockups replace interface structure, copy, accessibility, responsive behavior, or state design. But do treat the approved mock as a concrete visual contract for composition, hierarchy, density, atmosphere, signature motifs, image needs, and distinctive visual moves. "North star" means "preserve the important visible ingredients in semantic code," not "use it as loose mood."
Default: Astro for brand briefs, the project's existing framework for product briefs. Ask once; don't re-ask mid-task.
## Step 1: Shape the Design
Run /impeccable shape, passing along whatever feature description the user provided.
Run /impeccable shape, passing along whatever feature description the user provided. Shape is **required** for craft; it is what produces a confirmed direction.
Wait for the design brief to be fully confirmed by the user before proceeding. The brief is your blueprint, and every implementation decision should trace back to it.
Present the shape output and stop. Wait for the user to confirm, override, or course-correct before writing code.
If this craft run resumed after `teach` created PRODUCT.md, run shape now. Do not treat the teach interview, PRODUCT.md, or a summary of project context as a substitute for shape. Shape is task-specific and must cover scope, content/states, visual direction, constraints, anti-goals, probes when applicable, and explicit brief confirmation.
If the user already supplied a confirmed brief or ran shape separately, use it and skip this step.
If the user has already run /impeccable shape and has a confirmed design brief, skip this step and use the existing brief.
When the original prompt + PRODUCT.md already answer scope, content, and visual direction with no real ambiguity, the shape output can be **compact** (3-5 bullets stating what you're building and the visual lane, ending with one or two specific questions or "confirm or override"). The full 10-section structured brief is reserved for genuinely ambiguous, multi-screen, or stakeholder-heavy tasks. Don't pad a clear brief into a long one to look thorough; equally, don't skip the pause to look efficient.
## Step 2: Load References
@@ -55,79 +53,60 @@ Then add references based on the brief's needs:
## Step 3: Land the Visual Direction (Capability-Gated)
Before implementation, generate high-fidelity visual comps when all of these are true:
Generate high-fidelity visual comps before implementation when all three are true:
- The work is **net-new** or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is **mid-fi, high-fi, or production-ready**.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The work is net-new or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is mid-fi, high-fi, or production-ready.
- The harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool). Don't ask the user to set up external APIs.
When those conditions are met, this step is mandatory for **both brand and product work** in Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
Do not skip this step because the eventual UI should be semantic, editable, code-native, responsive, or accessible. Those are implementation requirements, not reasons to avoid visual exploration.
### Purpose
Use the mock step to find a stronger visual lane than code-first generation would reliably discover on its own. The brief remains authoritative on user, purpose, content, constraints, states, and anti-goals. The mock clarifies composition, hierarchy, density, typography, and visual tone.
When met, this step is mandatory for both brand and product work. If image generation isn't available, skip silently. "The eventual UI is semantic/code-native/accessible" is not a reason to skip; those are implementation requirements, not exploration ones.
### What to generate
Generate **1 to 3** high-fidelity north-star comps based on the confirmed brief. If shape already produced direction probes, use those results as input and generate a more resolved mock from the winning lane, not another unrelated exploration.
Generate **1 to 3** high-fidelity north-star comps from the confirmed brief. If shape already produced direction probes, resolve the winning lane further, not an unrelated exploration. Comps must differ in primary visual direction, not just color.
- For brand work, push visual identity, composition, and mood aggressively.
- For product work, still push hierarchy, topology, density, and tone, but keep the comps grounded in realistic product structure and states.
- For landing pages and long-form brand surfaces, show enough of the next section or second fold to establish the system beyond the hero.
The comps must be genuinely different in primary visual direction, not just color variants.
- Brand work: push visual identity, composition, and mood aggressively.
- Product work: push hierarchy, topology, density, tone, grounded in realistic product structure.
- Landing pages and long-form brand surfaces: show enough of the second fold to establish the system beyond the hero.
### Approval loop
Show the comps and ask what should carry forward. If the user asks for changes or the best direction is still weak, generate a focused revision before implementation. Continue until one direction is approved, or until the user explicitly delegates the choice.
Show the comps and ask what carries forward. Iterate until one direction is approved or the user delegates. If the user delegates, pick the strongest direction and explain it from the brief, not personal taste.
If the user delegates, pick the strongest direction and explain the decision using the brief, not personal taste.
Before moving to implementation, summarize:
- What to carry into code
- What **not** to literalize from the mock
This summary is required before Step 4. It is the handoff between visual exploration and semantic implementation.
Before Step 4, summarize what to carry into code and what **not** to literalize from the mock. This is the handoff between visual exploration and semantic implementation.
### Mock fidelity inventory
Before building, inventory the approved mock's major visible ingredients:
Inventory the approved mock's major visible ingredients:
- Hero silhouette and dominant composition.
- Signature motifs: planets, devices, portraits, charts, route lines, insets, badges, or other memorable objects.
- Nav and primary CTA treatment.
- Section sequence visible in the mock, especially the second fold.
- Image-native content the concept depends on.
- Typography, density, color/material treatment, and motion cues.
- Hero silhouette and dominant composition
- Signature motifs (planets, devices, portraits, charts, route lines, insets, badges, etc.)
- Nav and primary CTA treatment
- Section sequence, especially the second fold
- Image-native content the concept depends on
- Typography, density, color/material treatment, motion cues
For each ingredient, decide how it will be implemented: semantic HTML/CSS/SVG, generated asset, sourced project asset, icon library, canvas/WebGL, or an explicitly accepted omission. Do not substitute a different hero composition or new visual driver after approval unless the user approves the change.
For each, decide implementation: semantic HTML/CSS/SVG, generated asset, sourced asset, icon library, canvas/WebGL, or accepted omission. Don't substitute a different hero composition or visual driver post-approval without user sign-off.
Treat the mock as a **north star**, not a screenshot to trace. Do **not** rasterize core UI text or let the mock override the confirmed brief. But if the live result lacks the mock's major visible ingredients, the implementation is wrong.
If a photographic, architectural, product, or place-led mock becomes generic CSS scenery / decorative diagrams / bullets / copy, stop and fix it. That's a broken implementation, not a harmless interpretation.
Treat the mock as a north star, not a screenshot to trace. Don't rasterize core UI text. But if the live result lacks the mock's major ingredients, the implementation is wrong.
## Step 4: Asset Extraction (Need-Gated)
If the chosen direction includes image-native visual ingredients that would materially improve the implementation, generate them as separate assets before building.
If the approved direction needs raster assets, create them before building. Do not replace required imagery with generic cards, bullets, emoji, fake metrics, decorative CSS panels, or filler copy.
Good candidates:
Use the native asset producer (`impeccable_asset_producer` in Codex, `impeccable-asset-producer` in Claude Code) to create clean assets from the hi-fi mock and crops. If you do not have explicit permission to use agents, stop and ask:
- stickers
- badges
- seals
- tickets
- graphic labels
- textures
- abstract objects
- decorative marks
- non-semantic scene elements
```text
Asset production will work better as a scoped subagent job. Should I spawn the Impeccable asset producer subagent for this step?
```
For travel, editorial, portfolio, venue, product showcase, entertainment, education, or any other image-led brand surface, visual assets are usually core content, not decoration. Do not ship abstract CSS panels where the approved mock or subject matter calls for real imagery, generated plates, illustrations, maps, product/object renders, or destination scenes.
Do not skip asset production or silently do it inline. Inline asset production is allowed only if the user declines subagents, the harness cannot spawn the authorized agent, or the user explicitly asks for single-thread mode.
Do **not** export assets for core UI text, navigation, body copy, or any structure that should stay semantic and editable in code.
Pass the approved mock, crop/contact-sheet paths, output directory, dimensions/formats, transparency needs, constraints, and avoid list to the asset producer. Attach image generation capability to the spawned agent when the harness supports it; do not load image-generation reference material into the parent thread first.
Usually **1 to 5** extracted assets is enough. If the design can be built cleanly in HTML/CSS/SVG, prefer that over raster assets. If the mock contains major visual content that cannot be built credibly in code, asset extraction is not optional.
Prefer HTML/CSS/SVG/canvas when they can credibly reproduce an ingredient; use real/generated/stock imagery when the mock or subject matter calls for actual visual content.
## Step 5: Build to Production Quality
@@ -135,50 +114,35 @@ Implement the feature following the design brief. Build in passes so structure,
### Production bar
- Use real or realistic content. Remove placeholder copy, placeholder images, dead links, fake controls, and unused scaffold before presenting.
- Preserve the approved mock's major ingredients. Missing hero objects, missing world/product imagery, different section structure, downgraded CTA/nav treatment, or generic replacements for distinctive motifs are blocking defects unless the user accepted the change.
- Build semantically first: real headings, landmarks, labels, form associations, button/link semantics, accessible names, and state announcements where needed.
- Calibrate spacing, alignment, grid placement, and vertical rhythm deliberately. Do not accept default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- Make typography intentional: chosen font loading strategy, clear hierarchy, readable measure, stable line breaks, tuned wrapping, and no overflow at mobile or large desktop sizes.
- Design realistic state coverage: default, hover where supported, focus-visible, active, disabled, loading, error, success, empty, overflow, long text, short text, and first-run states where relevant.
- Make interaction quality feel finished: keyboard paths, touch targets, feedback timing, scroll behavior, transitions between states, and no hover-only functionality.
- Use icons from the project's established icon set when available. If no set exists, choose a coherent library or use accessible text controls; do not mix unrelated icon styles.
- Optimize imagery and media: correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset` / `picture` for raster assets, and no project-referenced asset left outside the workspace.
- Make motion feel premium: use atmospheric blur, filter, mask, shadow, or reveal effects when they improve the experience; avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- Preserve maintainability: reusable local patterns, clear component boundaries, project conventions, no rasterized UI text, and no hard-coded one-off hacks when a better local pattern exists.
- Fit the technical context: production build passes, no obvious console errors, no avoidable layout shift, no needless dependency, and no broken asset path.
- If you discover a design question that materially changes the brief or approved direction, stop and ask rather than guessing.
- **Real content.** No placeholder copy, placeholder images, dead links, fake controls, or unused scaffold at presentation time.
- **Preserve the approved mock's major ingredients.** Missing hero objects, world/product imagery, section structure, CTA/nav treatment, or distinctive motifs are blocking defects unless the user accepted the change.
- **Semantic first.** Real headings, landmarks, labels, form associations, button/link semantics, accessible names, state announcements where needed.
- **Deliberate spacing and alignment.** No default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- **Intentional typography.** Chosen loading strategy, clear hierarchy, readable measure, stable line breaks, no overflow at any width.
- **Realistic state coverage.** Default, hover, focus-visible, active, disabled, loading, error, success, empty, overflow, long/short text, first-run.
- **Finished interaction quality.** Keyboard paths, touch targets, feedback timing, scroll behavior, state transitions, no hover-only functionality.
- **Coherent icon set.** Use the project's established set; otherwise pick one library or use accessible text. Don't mix.
- **Respect the build pipeline.** Edit source files and run the project's build (`npm run build` or equivalent). Don't write to `build/` / `dist/` / `.next/` with `cat`, heredoc, or Bash redirects; that skips asset hashing, image optimization, code splitting, and CSS extraction, and produces output the dev server won't serve.
- **Verify image URLs before referencing them.** Use image-search MCP or web-fetch when available; guessed photo IDs ship as broken-image placeholders. Without verification, prefer fewer images you're confident about.
- **Optimized imagery and media.** Correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset`/`picture` for raster, no project-referenced asset left outside the workspace.
- **Premium motion.** Use atmospheric blur, filter, mask, shadow, reveal when they improve the experience. Avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- **Maintainable.** Reusable local patterns, clear component boundaries, project conventions. No rasterized UI text or one-off hacks when a local pattern exists.
- **Technically clean.** Production build passes, no console errors, no avoidable layout shift, no needless dependencies, no broken asset paths.
- **Ask when uncertain.** If a discovery materially changes the brief or approved direction, stop and ask. Don't guess.
## Step 6: Browser-Based Iteration
## Step 6: Iterate Visually
**This step is critical.** Do not stop after the first implementation pass.
Look at what you built like a designer would. Your eyes are whatever the harness gives you: a connected browser, a screenshotting tool, Playwright, or asking the user. Use them for responsive testing (mobile, tablet, desktop minimum) and general visual validation.
Open the result in a browser. In Codex, use browser-use or equivalent browser automation when available; otherwise use Playwright or ask the user for screenshots. Inspect screenshots, not just DOM or terminal output.
If your tool returns a file path, read the PNG back into the conversation. A screenshot you didn't read doesn't count.
### Required viewport pass
For long-form brand surfaces, inspect major sections individually. Thumbnails hide spacing, clipping, and cascade defects.
Check the experience at the viewports that matter for the brief. Default minimum:
After the first pass, write an honest critique against the brief, the approved mock's major ingredients (hero silhouette, motifs, imagery, nav/CTA, density), and impeccable's DON'Ts. Patch material defects and re-inspect. **Don't invent defects to demonstrate iteration.** A confident "first pass clean, shipping" beats a fake fix.
- Mobile narrow
- Tablet or small laptop
- Desktop wide
Actively check: responsive behavior (composes, not shrinks), every state (empty / error / loading / edge), craft details (spacing, alignment, hierarchy, contrast, motion timing, focus), performance basics. The exit bar: defensible in a high-end studio review.
For each viewport, capture or inspect the rendered state and look for visual defects: overlap, clipping, weak hierarchy, off-grid alignment, awkward whitespace, cramped controls, unreadable type, broken imagery, hover-only functionality, layout shift, and text overflow.
### Critique and fix loop
After the first browser pass, write a short critique for yourself and patch the implementation. Repeat browser inspection after fixes. Continue until no material issues remain against this checklist:
1. **Does it match the brief?** Compare the live result against every section of the design brief. Fix discrepancies.
2. **Does it match the approved mock?** Compare screenshots against the mock fidelity inventory: hero silhouette, major motifs, imagery, nav/CTA, section sequence, density, color/materials, and second-fold substance. Missing major ingredients are P0 defects.
3. **Does it pass the AI slop test?** If someone saw this and said "AI made this," would they believe it immediately? If yes, it needs more design intention.
4. **Check against impeccable's DON'T guidelines.** Fix any anti-pattern violations.
5. **Check every state.** Navigate through empty, error, loading, and edge case states. Each one should feel intentional, not like an afterthought.
6. **Check responsive behavior.** The design should adapt compositionally, not merely shrink.
7. **Check craft details.** Spacing consistency, optical alignment, type hierarchy, color contrast, image quality, icon coherence, interactive feedback, motion timing, and focus treatment.
8. **Check performance basics.** No obviously oversized images, avoidable layout thrash, blocking animations, or heavy assets without a reason.
The exit bar is not "it works." It is: the rendered result looks intentional at all checked viewports, all expected states are handled, no placeholders remain unless explicitly accepted, and the implementation quality would be defensible in a high-end studio review.
Detector or QA output is defect evidence only; never proof the work is finished.
## Step 7: Present
@@ -189,5 +153,3 @@ Present the result to the user:
- Explain design decisions that connect back to the design brief and, when used, the chosen north-star mock. Include any accepted deviations from the mock; do not hide unimplemented mock ingredients.
- Note any remaining limitations or follow-up risks honestly
- Ask: "What's working? What isn't?"
Iterate based on feedback. Good design is rarely right on the first pass.
@@ -43,7 +43,7 @@ Run the bundled deterministic detector, which flags 27 specific patterns (AI slo
**CLI scan**:
```bash
npx impeccable --json [--fast] [target]
npx impeccable detect --json [--fast] [target]
```
- Pass HTML/JSX/TSX/Vue/Svelte files or directories as `[target]` (anything with markup). Do not pass CSS-only files.
+8 -6
View File
@@ -2,6 +2,8 @@
Perform a meticulous final pass to catch all the small details that separate good work from great work. The difference between shipped and polished.
Detector and automated QA output are defect evidence only. A clean script result is never proof that the design is strong; gather browser evidence and inspect the real interaction path.
## Design System Discovery
Aligning the feature to the design system is **not optional**. Polish without alignment is decoration on top of drift, and it makes the next person's job harder. Discovery comes before any other polish work.
@@ -216,11 +218,12 @@ Sweat the details. Zoom in until the alignment is right and the spacing reads as
Before marking as done:
- **Use it yourself**: Actually interact with the feature
- **Test on real devices**: Not just browser DevTools
- **Ask someone else to review**: Fresh eyes catch things
- **Compare to design**: Match intended design
- **Check all states**: Don't just test happy path
- **Use it yourself**: Actually interact with the feature.
- **Test on real devices**: Not just browser DevTools.
- **Ask someone else to review**: Fresh eyes catch things.
- **Compare to design**: Match intended design.
- **Check all states**: Don't just test happy path.
- **Treat automation carefully**: Run detector or QA commands when they are available and relevant, fix their defects, but never cite a clean result as proof that the work is polished.
## Clean Up
@@ -230,4 +233,3 @@ After polishing, ensure code quality:
- **Remove orphaned code**: Delete unused styles, components, or files made obsolete by polish.
- **Consolidate tokens**: If you introduced new values, check whether they should be tokens.
- **Verify DRYness**: Look for duplication introduced during polishing and consolidate.
+25 -11
View File
@@ -16,14 +16,16 @@ This is a required interaction, not optional guidance. Ask these questions in co
### Interview cadence
Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed design inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
Discovery includes at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
- Use the harness's structured question tool when one exists. Otherwise, ask directly in chat and stop.
- Ask **2-3 questions per round**, then wait for answers.
- Treat PRODUCT.md and DESIGN.md as anchors; they reduce repeated questions but do **not** replace shape for craft. Shape is task-specific.
- Round 1 should clarify purpose, audience/context, and success or emotional outcome.
- Round 2 should clarify content/data/states and scope/fidelity.
- Round 3 should clarify visual direction, constraints, and anti-goals when still unresolved.
- One round is the default. Add a second only if the first answers leave material gaps. Don't run a second round just to feel thorough.
- Round 1 should clarify purpose, audience/context, content/scope, and (for brand) visual direction.
- Round 2, when needed, fills in whatever's still genuinely missing.
**Assert-then-confirm, not menu-with-escape.** When PRODUCT.md and the user's prompt make one option obvious, name it and ask the user to confirm or override. Don't enumerate "Restrained / Committed / Or something else?" as a real choice; "This reads as Restrained, confirm?" beats a four-option menu when the answer is already clear.
### Purpose & Context
- What is this feature for? What problem does it solve?
@@ -36,6 +38,7 @@ Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.
- What are the realistic ranges? (Minimum, typical, maximum, e.g., 0 items, 5 items, 500 items)
- What are the edge cases? (Empty state, error state, first-time use, power user)
- Is any content dynamic? What changes and how often?
- What visual assets are real content here? Note required images, product shots, illustrations, maps, textures, diagrams, generated objects, or existing project assets.
### Design Direction
@@ -72,9 +75,9 @@ After the discovery interview, generate a small set of visual direction probes *
- The work is **net-new** or directionally ambiguous enough that visual exploration will clarify the brief.
- The requested fidelity is **mid-fi, high-fi, or production-ready**. Skip for sketch-only planning.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The current harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool, or similar). Don't ask the user to install APIs or tooling.
When those conditions are met, this step is mandatory for Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
When those conditions are met, this step is mandatory. If image generation isn't natively available, skip silently and proceed; don't announce the skip.
Use probes to explore visual lanes, not to replace the brief.
@@ -104,11 +107,20 @@ The probes should differ in primary visual direction (hierarchy, topology, densi
- Do **not** treat generated imagery as final UX specification, final copy, or final accessibility behavior.
- Do **not** use this step for minor refinements of existing work. It's for shaping a new surface or clarifying a big directional choice.
If image generation is unavailable, or the task doesn't benefit from it, skip this phase only with a one-line reason and proceed directly to the design brief.
If image generation isn't natively available, skip this phase silently and proceed.
## Phase 2: Design Brief
After the interview and any required probes, synthesize everything into a structured design brief. Present it to the user for explicit confirmation before considering this command complete. Stop after asking for confirmation; do not proceed to craft or implementation in the same response unless the user has already approved the brief.
After the interview and any required probes, present a brief and **end your response**. The user must confirm before any implementation runs. Do not present a brief and then continue to code in the same response, even if the brief feels obvious to you. The user's confirmation is the gate.
**Choose the brief shape based on how clear the answers are:**
- **Compact form (3-5 bullets)** when discovery was crisp and the original prompt + PRODUCT.md already pinned scope, content, and direction. State what you're building, the visual lane, and end with one or two specific questions or a clear "confirm or override?" prompt. This is the default for typical craft requests with a clear prompt.
- **Full structured form (sections below)** when the task is genuinely ambiguous, multi-screen, or when the user asked for shape as a standalone step. Use this when the discipline of structure earns its weight.
Don't pad a clear brief into a long one to look thorough. A 70-line brief restating answers the user just gave is noise, not rigor. Equally, don't skip the confirmation pause to look efficient: the pause is the point.
If the user already said "approved" or "go" during discovery for the *exact direction you'd present*, that counts as confirmation; you may proceed without asking again. But if your brief adds anything the user hasn't seen and approved, you must stop and confirm.
### Brief Structure
@@ -136,16 +148,18 @@ List every state the feature needs: default, empty, loading, error, success, edg
How users interact with this feature. What happens on click, hover, scroll? What feedback do they get? What's the flow from entry to completion?
**8. Content Requirements**
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges.
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges. For image-led surfaces, also list the required image/media roles and their likely source (project asset, generated raster, semantic SVG/CSS, canvas/WebGL, icon library, or accepted omission).
**9. Recommended References**
Based on the brief, list which impeccable reference files would be most valuable during implementation (e.g., spatial-design.md for complex layouts, motion-design.md for animated features, interaction-design.md for form-heavy features).
**10. Open Questions**
Anything unresolved that the implementer should resolve during build.
Anything genuinely unresolved. Don't list "open questions" you've already recommended a default for; assert the default and move on. If you'd write `Recommend: X` next to a question, just decide X.
---
ask the user directly to clarify what you cannot infer. Ask for explicit confirmation of the brief before finishing. If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the brief is confirmed.
ask the user directly to clarify what you cannot infer.
If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the user confirms direction (or the user already gave a clear go during discovery, which counts).
Once confirmed, the brief is complete. The user can now hand it to /impeccable, or use it to guide any other implementation approach. (If the user wants the full discovery-then-build flow in one step, they should use /impeccable craft instead, which runs this command internally.)
+10 -1
View File
@@ -50,7 +50,7 @@ Fields marked with * are spec-standard. Others are provider extensions.
Notes:
- Gemini CLI validates only `name` and `description`; other spec fields are parsed but ignored.
- Codex CLI uses a separate `agents/openai.yaml` sidecar for extended metadata (icons, branding, MCP tools, invocation control).
- Codex CLI uses a separate `agents/openai.yaml` sidecar for skill metadata (icons, branding, MCP tools, invocation control). Native Codex custom agents are separate TOML files under `.codex/agents/` or `~/.codex/agents/`.
- Kiro recognizes `user-invocable` and `disable-model-invocation` per community reports but does not formally document them.
- Unknown fields are silently ignored by all harnesses.
@@ -73,6 +73,15 @@ Notes:
All harnesses support the `{skill-name}/SKILL.md` directory structure with optional `reference/`, `scripts/`, and `assets/` subdirectories.
## Native Subagent Directory Structure
| Harness | Native directory | File format |
|---------|------------------|-------------|
| Claude Code | `.claude/agents/` | Markdown with YAML frontmatter |
| Codex CLI | `.codex/agents/` | TOML |
Impeccable keeps canonical agent prompts under `skill/agents/` and emits provider-native files only for harnesses with documented subagent formats.
## Placeholder / Variable Substitution
Claude Code supports runtime variable substitution directly in SKILL.md bodies: `$ARGUMENTS`, `$0`-`$N`, `${CLAUDE_SKILL_DIR}`, `${CLAUDE_SESSION_ID}`. No other harness supports substitution in skills.
+2 -2
View File
@@ -6,11 +6,11 @@ brand
## Users
Frontend and full-stack developers who use AI coding tools (Cursor, Claude Code, Gemini CLI, Codex CLI, and others) and want better design output from their AI. They land on the site from GitHub, social media, or word of mouth, already aware that AI-generated UIs have quality problems. They're looking for a practical solution, not education about the problem.
Designers, product managers, and engineers who use AI coding tools (Cursor, Claude Code, Gemini CLI, Codex CLI, and others) and want better design output from their AI. They land on the site from GitHub, social media, or word of mouth, already aware that AI-generated UIs have quality problems. They're looking for a practical solution, not education about the problem.
## Product Purpose
Impeccable gives developers a shared design vocabulary with their AI, delivered as a plug-and-play skill that works in every major AI coding harness. Success is measured in two ways: (1) the developer can steer AI output with design precision instead of vague prose, and (2) the AI produces interfaces that pass professional design review, not "looks like an AI made it" output.
Impeccable gives builders a shared design vocabulary with their AI, delivered as a plug-and-play skill that works in every major AI coding harness. Success is measured in two ways: (1) the user can steer AI output with design precision instead of vague prose, and (2) the AI produces interfaces that pass professional design review, not "looks like an AI made it" output.
## Brand Personality
+4
View File
@@ -145,10 +145,14 @@ cp -r dist/gemini/.gemini your-project/
```bash
# Project-local
cp -r dist/agents/.agents your-project/
mkdir -p your-project/.codex
cp -r dist/codex/.codex/agents your-project/.codex/
# Or user-wide
mkdir -p ~/.agents/skills
cp -r dist/agents/.agents/skills/* ~/.agents/skills/
mkdir -p ~/.codex
cp -r dist/codex/.codex/agents ~/.codex/
```
**GitHub Copilot:**
+495 -43
View File
@@ -257,6 +257,16 @@ const ANTIPATTERNS = [
skillSection: 'Typography',
skillGuideline: 'tiny uppercase tracked label above the hero headline',
},
{
id: 'repeated-section-kickers',
category: 'slop',
severity: 'advisory',
name: 'Repeated section kicker labels',
description:
'Repeating tiny uppercase tracked labels above section headings turns a brand page into AI editorial scaffolding. Replace them with stronger structure, artifacts, imagery, or a deliberate brand system.',
skillSection: 'Typography',
skillGuideline: 'repeated eyebrow or kicker labels as section scaffolding',
},
// ── Quality: general design and accessibility issues ──
{
@@ -309,6 +319,13 @@ const ANTIPATTERNS = [
description:
'Text is too close to the edge of its container. Add at least 8px (ideally 12-16px) of padding inside bordered or colored containers.',
},
{
id: 'body-text-viewport-edge',
category: 'quality',
name: 'Body text touching viewport edge',
description:
'Body paragraphs render flush against the left or right viewport edge with no container providing horizontal padding. Wrap content in a container with at least 16px (ideally 24-32px) of horizontal padding, or apply max-width with mx-auto.',
},
{
id: 'tight-leading',
category: 'quality',
@@ -553,7 +570,20 @@ function checkColors(opts) {
const isLargeText = fontSize >= 18 || (fontSize >= 14 && fontWeight >= 700) || isHeading;
const threshold = isLargeText ? 3.0 : 4.5;
if (ratio < threshold) {
findings.push({ id: 'low-contrast', snippet: `${ratio.toFixed(1)}:1 (need ${threshold}:1) — text ${colorToHex(textColor)} on ${colorToHex(bgs[worstIdx])}` });
// Skip the false-positive class where text has alpha < 1 AND we
// couldn't find an opaque ancestor (effectiveBg is null, we're
// comparing against gradient-stop fallback). In jsdom mode the
// detector can't resolve `var(--X)` color tokens, so a dark
// section sitting between the text and the body's decorative
// gradient is invisible to us — we end up measuring contrast
// against the body's paper-grain noise instead of the real
// local bg. Real low-contrast bugs use alpha=1 and have a
// resolvable opaque ancestor; semi-transparent Tailwind tokens
// like `text-paper/60` on `bg-ink` sections are the FP pattern.
const isAlphaFallbackFP = !IS_BROWSER && !effectiveBg && (textColor.a != null && textColor.a < 1);
if (!isAlphaFallbackFP) {
findings.push({ id: 'low-contrast', snippet: `${ratio.toFixed(1)}:1 (need ${threshold}:1) — text ${colorToHex(textColor)} on ${colorToHex(bgs[worstIdx])}` });
}
}
}
@@ -698,41 +728,114 @@ function checkItalicSerif(opts) {
}];
}
// Color saturation check. Returns true when the color has visible
// chroma — i.e., it's an "accent color" rather than near-neutral.
// Handles rgb()/rgba(), #hex, oklch(), and hsl(). var() refs are
// expected to be pre-resolved by the caller.
function isAccentColor(cssColor) {
if (!cssColor) return false;
const s = String(cssColor).trim();
// rgb / rgba — direct channel-distance check.
const rgbM = /rgba?\(\s*(\d+)\s*,?\s+|\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/.exec(s.replace(/rgba?\(\s*/, 'rgb(').replace(/,/g, ', '));
const rgbStrict = /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/.exec(s);
if (rgbStrict) {
const r = +rgbStrict[1], g = +rgbStrict[2], b = +rgbStrict[3];
return (Math.max(r, g, b) - Math.min(r, g, b)) >= 40;
}
// #hex — 3, 4, 6, or 8 digit.
const hexM = /^#([0-9a-f]{3,8})\b/i.exec(s);
if (hexM) {
let h = hexM[1];
if (h.length === 3 || h.length === 4) h = h.split('').map((c) => c + c).join('').slice(0, 6);
else h = h.slice(0, 6);
if (h.length === 6) {
const r = parseInt(h.slice(0, 2), 16);
const g = parseInt(h.slice(2, 4), 16);
const b = parseInt(h.slice(4, 6), 16);
return (Math.max(r, g, b) - Math.min(r, g, b)) >= 40;
}
}
// oklch(L C H) — chroma C is what matters. Typical neutral grays
// have C < 0.02; visible accents are 0.05+. CSS minification can
// collapse spaces between L% and C ("oklch(43%.15 34)"), so we
// extract all numbers and take the second rather than matching a
// strict L-then-whitespace-then-C pattern.
if (/^oklch\(/i.test(s)) {
const nums = s.match(/\d*\.\d+|\d+/g);
if (nums && nums.length >= 2) {
const c = parseFloat(nums[1]);
return !Number.isNaN(c) && c >= 0.05;
}
}
// hsl(H, S%, L%) — saturation > 20% reads as accent.
const hslM = /hsla?\(\s*[\d.]+\s*,\s*([\d.]+)%/i.exec(s);
if (hslM) {
const sat = parseFloat(hslM[1]);
return !Number.isNaN(sat) && sat >= 20;
}
return false;
}
// Sibling-relationship rule. Anchor on a hero-scale h1, look at the
// previousElementSibling, and gate on uppercase + tracked + small.
// previousElementSibling, and gate on EITHER the classic tracked-
// uppercase eyebrow OR the modern accent-colored bold eyebrow.
function checkHeroEyebrow(opts) {
const {
headingTag, headingText, headingFontSize,
siblingTag, siblingText, siblingTextTransform,
siblingFontSize, siblingLetterSpacing,
siblingFontWeight, siblingColor,
} = opts;
if (headingTag !== 'h1') return [];
if (!headingFontSize || headingFontSize < 48) return [];
// We previously gated on headingFontSize >= 48 to anchor "hero scale".
// But modern hero h1s use clamp() / vw / var(--text-*), none of which
// jsdom can resolve — the computed value comes back as "2em" or
// "var(--text-9xl)" and parseFloat returns 2 or NaN. The gate fails
// on virtually every Tailwind v4 / framework build. The other gates
// (sibling text 2-60 chars, font-size ≤ 14px, accent-bold OR
// tracked-caps) are tight enough to avoid false positives on non-
// hero h1s — a tiny tan label directly above any h1 is the
// antipattern regardless of how big the h1 ends up.
if (!siblingTag) return [];
// An h2 above an h1 is a different anti-pattern (heading hierarchy / dual
// headings) — never an eyebrow.
if (HEADING_TAGS.has(siblingTag)) return [];
const text = (siblingText || '').trim();
if (text.length < 2 || text.length > 30) return [];
if (text.length < 2 || text.length > 60) return [];
if (!(siblingFontSize > 0 && siblingFontSize <= 14)) return [];
// Uppercase: either via text-transform, or the content is already typed
// uppercase (no lowercase letters, at least one uppercase letter).
// Branch A: classic tracked-uppercase eyebrow.
const isUppercased = siblingTextTransform === 'uppercase'
|| (/[A-Z]/.test(text) && !/[a-z]/.test(text));
if (!isUppercased) return [];
const isClassicTracked = isUppercased && siblingLetterSpacing >= 1.6;
if (!(siblingLetterSpacing >= 1.6)) return [];
if (!(siblingFontSize > 0 && siblingFontSize <= 14)) return [];
// Branch B: modern accent-bold eyebrow — sentence case, low
// tracking, but bold + accent-colored. The style choices changed;
// the pattern is the same kicker-above-headline anti-pattern.
const weight = Number(siblingFontWeight) || 400;
const isAccentBold = weight >= 700 && isAccentColor(siblingColor || '');
if (!isClassicTracked && !isAccentBold) return [];
const headingTextSnippet = (headingText || '').trim().slice(0, 60);
const eyebrowSnippet = text.slice(0, 40);
const style = isClassicTracked ? 'tracked-caps' : 'accent-bold';
return [{
id: 'hero-eyebrow-chip',
snippet: `eyebrow chip "${eyebrowSnippet}" above ${headingTag} "${headingTextSnippet}"`,
snippet: `eyebrow chip (${style}) "${eyebrowSnippet}" above ${headingTag} "${headingTextSnippet}"`,
}];
}
function checkRepeatedSectionKickers(opts) {
const { candidates, minCount = 3 } = opts;
if (!Array.isArray(candidates) || candidates.length < minCount) return [];
return candidates.map(candidate => ({
id: 'repeated-section-kickers',
snippet: `repeated section kicker "${candidate.kickerText}" before ${candidate.headingTag} "${candidate.headingText}" (${candidates.length} on page)`,
}));
}
const LAYOUT_TRANSITION_PROPS = new Set([
'width', 'height', 'padding', 'margin',
'max-height', 'max-width', 'min-height', 'min-width',
@@ -974,43 +1077,60 @@ function readOwnBackgroundColor(el, computedStyle) {
return bg;
}
function resolveBackground(el, win) {
function resolveBackground(el, win, customPropMap) {
let current = el;
while (current && current.nodeType === 1) {
const style = IS_BROWSER ? getComputedStyle(current) : win.getComputedStyle(current);
// If this element has a background-image (gradient or url), it's visually
// opaque but we can't determine the effective color — bail out so callers
// don't get a false solid-color answer.
const bgImage = style.backgroundImage || '';
if (bgImage && bgImage !== 'none' && (/gradient/i.test(bgImage) || /url\s*\(/i.test(bgImage))) {
return null;
}
const hasGradientOrUrl = bgImage && bgImage !== 'none' && (/gradient/i.test(bgImage) || /url\s*\(/i.test(bgImage));
// Try the solid bg-color FIRST. If the element has both a solid color
// and a gradient/url overlay (a common pattern: `background: var(--paper)
// radial-gradient(...)` for paper-grain texture), the solid color is the
// dominant visible surface for contrast purposes; the overlay is
// decorative. The old behavior bailed on any gradient ancestor, which
// caused massive false-positive contrast findings on grain-textured
// body backgrounds.
let bg = parseRgb(style.backgroundColor);
if (!IS_BROWSER && (!bg || bg.a < 0.1)) {
// jsdom doesn't decompose background shorthand — parse raw style attr
const rawStyle = current.getAttribute?.('style') || '';
const bgMatch = rawStyle.match(/background(?:-color)?\s*:\s*([^;]+)/i);
const inlineBg = bgMatch ? bgMatch[1].trim() : '';
// Check for gradient or url() image in inline style too
if (/gradient/i.test(inlineBg) || /url\s*\(/i.test(inlineBg)) return null;
bg = parseRgb(inlineBg);
if (!bg && inlineBg) {
const hexMatch = inlineBg.match(/#([0-9a-f]{6}|[0-9a-f]{3})\b/i);
if (hexMatch) {
const h = hexMatch[1];
if (h.length === 6) {
bg = { r: parseInt(h.slice(0,2), 16), g: parseInt(h.slice(2,4), 16), b: parseInt(h.slice(4,6), 16), a: 1 };
} else {
bg = { r: parseInt(h[0]+h[0], 16), g: parseInt(h[1]+h[1], 16), b: parseInt(h[2]+h[2], 16), a: 1 };
}
// jsdom returns literal "var(--X)" / "oklch(...)" strings. Resolve
// through customPropMap so Tailwind v4 color tokens become RGB.
if (customPropMap) {
bg = parseColorResolved(style.backgroundColor, customPropMap);
}
if (!bg || bg.a < 0.1) {
// Inline-style fallback. jsdom doesn't decompose background
// shorthand, so colors set via inline style are otherwise invisible.
const rawStyle = current.getAttribute?.('style') || '';
const bgMatch = rawStyle.match(/background(?:-color)?\s*:\s*([^;]+)/i);
const inlineBg = bgMatch ? bgMatch[1].trim() : '';
if (inlineBg && !/gradient/i.test(inlineBg) && !/url\s*\(/i.test(inlineBg)) {
bg = parseColorResolved(inlineBg, customPropMap) || parseAnyColor(inlineBg);
}
}
}
if (bg && bg.a > 0.1) {
if (IS_BROWSER || bg.a >= 0.5) return bg;
}
// No solid bg-color at this level. If THIS level has a gradient/url
// with no underlying solid color we can read:
// • on body/html: assume white. Body-level gradients are almost
// always decorative texture (paper grain, noise) on top of a
// solid bg-color the page set via `background: var(--paper)`
// shorthand — which jsdom can't decompose into bg-color. The
// downstream gradient-stops fallback path produces catastrophic
// false positives in this case (gradient noise stops have
// accidental browns/blacks that look like card backgrounds).
// • on other elements: bail to null and let the caller fall back
// to gradient stops (gradient buttons / hero sections are real
// bgs worth checking against).
if (hasGradientOrUrl) {
if (current.tagName === 'BODY' || current.tagName === 'HTML') {
return { r: 255, g: 255, b: 255, a: 1 };
}
return null;
}
current = current.parentElement;
}
return { r: 255, g: 255, b: 255 };
@@ -1228,9 +1348,245 @@ function checkElementHeroEyebrowDOM(el) {
siblingTextTransform: sibStyle.textTransform || '',
siblingFontSize: parseFloat(sibStyle.fontSize) || 0,
siblingLetterSpacing: parseFloat(sibStyle.letterSpacing) || 0,
siblingFontWeight: sibStyle.fontWeight || '',
siblingColor: sibStyle.color || '',
});
}
// Build a map of CSS custom properties declared on :root / :host / html.
// Used to resolve var(--X) refs that jsdom returns verbatim in
// getComputedStyle. Tailwind v4 routes every utility class through
// CSS vars (font-weight: var(--font-weight-bold), font-size:
// var(--text-xs), letter-spacing: var(--tracking-widest)), so without
// resolution every style-based check silently fails on Tailwind v4
// builds — the values come back as literal "var(--font-weight-bold)"
// strings and parseFloat returns NaN.
function buildCustomPropMap(document) {
const map = new Map();
let sheets;
try { sheets = Array.from(document.styleSheets || []); }
catch { return map; }
for (const sheet of sheets) {
let rules;
try { rules = Array.from(sheet.cssRules || []); }
catch { continue; }
for (const rule of rules) {
// Style rules only (type 1). Walk @media / @supports if present.
if (rule.type === 4 /* MEDIA_RULE */ || rule.type === 12 /* SUPPORTS_RULE */) {
try { rules.push(...Array.from(rule.cssRules || [])); } catch { /* ignore */ }
continue;
}
if (rule.type !== 1 /* STYLE_RULE */) continue;
const sel = rule.selectorText || '';
if (!/(^|,\s*)(:root|html|:host)\b/i.test(sel)) continue;
const style = rule.style;
if (!style) continue;
for (let i = 0; i < style.length; i++) {
const prop = style[i];
if (!prop || !prop.startsWith('--')) continue;
const val = style.getPropertyValue(prop).trim();
if (val) map.set(prop, val);
}
}
}
return map;
}
// Resolve var(--X[, fallback]) refs in a computed-style value string.
// Recurses up to 8 levels for chained refs (--a: var(--b)). Returns
// the original string when no refs are present or the chain doesn't
// resolve. Safe to call on already-resolved values.
function resolveVarRefs(raw, customPropMap, depth = 0) {
if (typeof raw !== 'string' || !raw.includes('var(')) return raw;
if (depth > 8) return raw;
return raw.replace(/var\(\s*(--[a-zA-Z0-9_-]+)\s*(?:,\s*([^)]+))?\)/g, (_m, name, fallback) => {
const v = customPropMap.get(name);
if (v != null) return resolveVarRefs(v, customPropMap, depth + 1);
return fallback ? resolveVarRefs(fallback.trim(), customPropMap, depth + 1) : _m;
});
}
// OKLCH → sRGB conversion (Björn Ottosson's matrices). L in 0..1 (or %),
// C in 0..~0.4 typical, H in degrees. Returns clamped {r,g,b,a:1} in 0..255.
// Needed because jsdom doesn't compute oklch() values — getComputedStyle
// returns the literal "oklch(...)" string. Without this, the entire
// Tailwind v4 color palette (which is OKLCH-based) is invisible to the
// detector's contrast / color checks.
function oklchToRgb(L, C, H) {
const hRad = (H * Math.PI) / 180;
const a = C * Math.cos(hRad);
const b = C * Math.sin(hRad);
const l_ = L + 0.3963377774 * a + 0.2158037573 * b;
const m_ = L - 0.1055613458 * a - 0.0638541728 * b;
const s_ = L - 0.0894841775 * a - 1.2914855480 * b;
const lc = l_ * l_ * l_, mc = m_ * m_ * m_, sc = s_ * s_ * s_;
const rLin = 4.0767416621 * lc - 3.3077115913 * mc + 0.2309699292 * sc;
const gLin = -1.2684380046 * lc + 2.6097574011 * mc - 0.3413193965 * sc;
const bLin = -0.0041960863 * lc - 0.7034186147 * mc + 1.7076147010 * sc;
const enc = (x) => {
const c = Math.max(0, Math.min(1, x));
return c <= 0.0031308 ? 12.92 * c : 1.055 * Math.pow(c, 1 / 2.4) - 0.055;
};
return {
r: Math.round(enc(rLin) * 255),
g: Math.round(enc(gLin) * 255),
b: Math.round(enc(bLin) * 255),
a: 1,
};
}
// Extended color parser: rgb/rgba/hex/oklch. Returns null on no match.
// Use this when the input might be any CSS color form; use plain parseRgb
// when you only expect computed rgb() values from real browsers.
function parseAnyColor(s) {
if (!s || typeof s !== 'string') return null;
const str = s.trim();
if (str === 'transparent' || str === 'currentcolor' || str === 'inherit') return null;
let m;
m = str.match(/rgba?\(\s*(\d+(?:\.\d+)?)\s*,?\s*(\d+(?:\.\d+)?)\s*,?\s*(\d+(?:\.\d+)?)(?:\s*[,/]\s*([\d.]+))?\s*\)/);
if (m) return { r: Math.round(+m[1]), g: Math.round(+m[2]), b: Math.round(+m[3]), a: m[4] !== undefined ? +m[4] : 1 };
m = str.match(/^#([0-9a-f]{3,8})$/i);
if (m) {
const h = m[1];
if (h.length === 3 || h.length === 4) {
return {
r: parseInt(h[0] + h[0], 16),
g: parseInt(h[1] + h[1], 16),
b: parseInt(h[2] + h[2], 16),
a: h.length === 4 ? parseInt(h[3] + h[3], 16) / 255 : 1,
};
}
if (h.length === 6 || h.length === 8) {
return {
r: parseInt(h.slice(0, 2), 16),
g: parseInt(h.slice(2, 4), 16),
b: parseInt(h.slice(4, 6), 16),
a: h.length === 8 ? parseInt(h.slice(6, 8), 16) / 255 : 1,
};
}
}
// OKLCH parser. Tailwind v4's CSS minifier squishes the space after
// `%` ("21.5%.02 50"), so the separator between L and C may be absent.
// Match L (with optional %), then C and H separated permissively.
m = str.match(/oklch\(\s*([\d.]+)(%?)\s*[\s,]*\s*([\d.]+)\s*[\s,]+\s*([-\d.]+)(?:deg)?\s*\)/i);
if (m) {
const Lnum = parseFloat(m[1]);
const L = m[2] === '%' ? Lnum / 100 : Lnum;
return oklchToRgb(L, parseFloat(m[3]), parseFloat(m[4]));
}
return null;
}
// Resolve var() refs in a color string (via customPropMap), then parse.
// Returns null on any failure. Used in jsdom-mode paths where
// getComputedStyle returns literal "var(--X)" or "oklch(...)" strings.
function parseColorResolved(str, customPropMap) {
if (!str) return null;
const resolved = customPropMap ? resolveVarRefs(str, customPropMap) : str;
return parseAnyColor(resolved);
}
const REPEATED_KICKER_SKIP_SELECTOR = [
'nav',
'form',
'table',
'thead',
'tbody',
'tfoot',
'figure',
'figcaption',
'ol',
'ul',
'li',
'[role="navigation"]',
'[aria-label*="breadcrumb" i]',
'[class*="breadcrumb" i]',
'[data-impeccable-allow-kickers]',
].join(',');
function cleanInlineText(el) {
return [...el.childNodes]
.filter(n => n.nodeType === 3)
.map(n => n.textContent)
.join(' ')
.replace(/\s+/g, ' ')
.trim();
}
function isRepeatedKickerCandidate(opts) {
const {
headingTag,
headingText,
headingFontSize,
kickerTag,
kickerText,
kickerTextTransform,
kickerFontSize,
kickerLetterSpacing,
} = opts;
if (!['h2', 'h3', 'h4'].includes(headingTag)) return false;
if (!headingText || headingText.length < 3) return false;
if (!(headingFontSize >= 20)) return false;
if (!kickerTag || HEADING_TAGS.has(kickerTag)) return false;
if (!['p', 'span', 'div', 'small'].includes(kickerTag)) return false;
if (!kickerText || kickerText.length < 2 || kickerText.length > 34) return false;
if (/^step\s*\d+/i.test(kickerText) || /^\d{1,2}$/.test(kickerText)) return false;
const isUppercased = kickerTextTransform === 'uppercase'
|| (/[A-Z]/.test(kickerText) && !/[a-z]/.test(kickerText));
if (!isUppercased) return false;
if (!(kickerFontSize > 0 && kickerFontSize <= 14)) return false;
const minTrackedSpacing = Math.max(1, kickerFontSize * 0.08);
if (!(kickerLetterSpacing >= minTrackedSpacing)) return false;
return true;
}
function collectRepeatedSectionKickerCandidates(doc, getStyle, resolveLetterSpacing) {
const candidates = [];
for (const heading of doc.querySelectorAll('h2, h3, h4')) {
if (heading.closest?.(REPEATED_KICKER_SKIP_SELECTOR)) continue;
const kicker = heading.previousElementSibling;
if (!kicker || kicker.closest?.(REPEATED_KICKER_SKIP_SELECTOR)) continue;
const headingStyle = getStyle(heading);
const kickerStyle = getStyle(kicker);
const headingText = (heading.textContent || '').replace(/\s+/g, ' ').trim();
const kickerText = cleanInlineText(kicker) || (kicker.textContent || '').replace(/\s+/g, ' ').trim();
const headingFontSize = resolveLetterSpacing(headingStyle.fontSize || '', 16) || parseFloat(headingStyle.fontSize) || 0;
const kickerFontSize = resolveLetterSpacing(kickerStyle.fontSize || '', 16) || parseFloat(kickerStyle.fontSize) || 0;
const kickerLetterSpacing = resolveLetterSpacing(kickerStyle.letterSpacing || '', kickerFontSize);
if (!isRepeatedKickerCandidate({
headingTag: heading.tagName.toLowerCase(),
headingText,
headingFontSize,
kickerTag: kicker.tagName.toLowerCase(),
kickerText,
kickerTextTransform: kickerStyle.textTransform || '',
kickerFontSize,
kickerLetterSpacing,
})) {
continue;
}
candidates.push({
headingTag: heading.tagName.toLowerCase(),
headingText: headingText.replace(/^"|"$/g, '').slice(0, 60),
kickerText: kickerText.slice(0, 40),
});
}
return candidates;
}
function checkRepeatedSectionKickersDOM() {
const candidates = collectRepeatedSectionKickerCandidates(
document,
(el) => getComputedStyle(el),
(value, fontSize) => resolveLengthPx(value, fontSize) || 0,
);
return checkRepeatedSectionKickers({ candidates });
}
function checkElementMotionDOM(el) {
const tag = el.tagName.toLowerCase();
if (SAFE_TAGS.has(tag)) return [];
@@ -1381,7 +1737,7 @@ function resolveLengthPx(value, fontSizePx) {
// Both adapters resolve font-size, line-height and letter-spacing to pixels
// before calling this so the pure function only deals with numbers.
function checkQuality(opts) {
const { el, tag, style, hasDirectText, textLen, fontSize, lineHeightPx, letterSpacingPx, rect, lineMax = 80 } = opts;
const { el, tag, style, hasDirectText, textLen, fontSize, lineHeightPx, letterSpacingPx, rect, lineMax = 80, viewportWidth = 0 } = opts;
const findings = [];
// Skip browser extension injected elements
const elId = el.id || '';
@@ -1432,6 +1788,40 @@ function checkQuality(opts) {
}
}
// --- Body text touching viewport edge --- (browser-only: needs rect)
// Catches the failure mode where the agent ships body paragraphs
// with NO container providing horizontal padding — text bleeds
// directly to the viewport edge. Different from cramped-padding,
// which requires a colored/bordered container. Here the failure
// is the absence of the container entirely.
//
// Gate aggressively to avoid false positives:
// - <p> or <li> only (body content; not headings, not nav, not
// wrappers)
// - text > 40 chars (paragraph-like, not a label)
// - rect.width > 50% of viewport (real body, not a pull-quote)
// - rect.left < 16 OR rect.right > viewport - 16 (actually
// touching the edge)
// - not inside <nav> or <header> (those legitimately bleed)
// - element itself has no background-color (intentional full-bleed
// sections set a bg-color and provide their own internal padding)
if (rect && hasDirectText && textLen > 40 && ['P', 'LI'].includes(tag.toUpperCase()) && viewportWidth > 0) {
const inNavHeader = el.closest && (el.closest('nav') || el.closest('header'));
const hasOwnBg = style.backgroundColor && style.backgroundColor !== 'rgba(0, 0, 0, 0)' && style.backgroundColor !== 'transparent';
const isPositioned = ['fixed', 'absolute'].includes(style.position || '');
const widthRatio = rect.width / viewportWidth;
const leftClose = rect.left < 16;
const rightClose = rect.right > viewportWidth - 16;
if (!inNavHeader && !hasOwnBg && !isPositioned && widthRatio > 0.5 && (leftClose || rightClose)) {
const which = leftClose && rightClose
? `left ${Math.round(rect.left)}px / right ${Math.round(viewportWidth - rect.right)}px`
: leftClose
? `left ${Math.round(rect.left)}px`
: `right ${Math.round(viewportWidth - rect.right)}px`;
findings.push({ id: 'body-text-viewport-edge', snippet: `<${tag.toLowerCase()}> with ${textLen}-char body bleeds to viewport edge (${which})` });
}
}
// --- Tight line height ---
if (hasDirectText && textLen > 50 && !['h1','h2','h3','h4','h5','h6'].includes(tag)) {
if (lineHeightPx != null && fontSize > 0) {
@@ -1493,7 +1883,8 @@ function checkElementQualityDOM(el) {
const letterSpacingPx = resolveLengthPx(style.letterSpacing, fontSize);
const rect = el.getBoundingClientRect();
const lineMax = (typeof window !== 'undefined' && window.__IMPECCABLE_CONFIG__?.lineLengthMax) || 80;
return checkQuality({ el, tag, style, hasDirectText, textLen, fontSize, lineHeightPx, letterSpacingPx, rect, lineMax });
const viewportWidth = (typeof window !== 'undefined' ? window.innerWidth : 0) || 0;
return checkQuality({ el, tag, style, hasDirectText, textLen, fontSize, lineHeightPx, letterSpacingPx, rect, lineMax, viewportWidth });
}
// Pure page-level skipped-heading walk. Takes a Document so it works in both
@@ -1568,14 +1959,47 @@ function checkElementBorders(tag, style, overrides, resolvedRadius) {
return checkBorders(tag, widths, colors, radius);
}
function checkElementColors(el, style, tag, window) {
function checkElementColors(el, style, tag, window, customPropMap, hasAnchorInheritRule) {
const directText = [...el.childNodes].filter(n => n.nodeType === 3).map(n => n.textContent).join('');
const hasDirectText = directText.trim().length > 0;
const effectiveBg = resolveBackground(el, window);
const effectiveBg = resolveBackground(el, window, customPropMap);
// jsdom returns literal "var(--X)" / "oklch(...)" for color, so plain
// parseRgb misses Tailwind-tokenized text colors. Resolve through the
// customPropMap first; fall back to parseRgb for vanilla rgb() pages.
let textColor = customPropMap ? parseColorResolved(style.color, customPropMap) : null;
if (!textColor) textColor = parseRgb(style.color);
// Anchor-inherit FP workaround: jsdom's UA stylesheet has `:link { color:
// blue }` at high specificity. The page's `a { color: inherit }` rule
// (Tailwind v4 preflight) loses to jsdom even though it WINS in real
// browsers (Chrome's UA wraps :link in :where() — zero specificity).
// When the page declares the inherit rule AND we see jsdom's default
// link blue on an anchor, walk to the nearest non-anchor ancestor and
// use its color instead.
if (
hasAnchorInheritRule &&
textColor &&
textColor.r === 0 && textColor.g === 0 && textColor.b === 238 &&
(tag === 'a' || el.closest?.('a'))
) {
let cur = el.parentElement;
while (cur && cur.tagName !== 'HTML') {
if (cur.tagName !== 'A') {
const ps = window.getComputedStyle(cur);
const inh = (customPropMap ? parseColorResolved(ps.color, customPropMap) : null) || parseRgb(ps.color);
if (inh && !(inh.r === 0 && inh.g === 0 && inh.b === 238)) {
textColor = inh;
break;
}
}
cur = cur.parentElement;
}
}
return checkColors({
tag,
textColor: parseRgb(style.color),
textColor,
bgColor: readOwnBackgroundColor(el, style),
effectiveBg,
effectiveBgStops: effectiveBg ? null : resolveGradientStops(el, window),
@@ -1637,27 +2061,46 @@ function checkElementItalicSerif(el, style, tag) {
});
}
function checkElementHeroEyebrow(el, style, tag, window) {
function checkElementHeroEyebrow(el, style, tag, window, customPropMap) {
if (tag !== 'h1') return [];
const sibling = el.previousElementSibling;
if (!sibling) return [];
const sibStyle = window.getComputedStyle(sibling);
const siblingFontSize = parseFloat(sibStyle.fontSize) || 0;
// Resolve Tailwind v4 CSS-variable wrappers (font-weight:var(--font-weight-bold)
// etc.) before parsing. jsdom returns these verbatim from getComputedStyle;
// without resolution every style-based gate fails silently on Tailwind v4 builds.
const fontSizeRaw = customPropMap ? resolveVarRefs(sibStyle.fontSize, customPropMap) : sibStyle.fontSize;
const fontWeightRaw = customPropMap ? resolveVarRefs(sibStyle.fontWeight, customPropMap) : sibStyle.fontWeight;
const letterSpacingRaw = customPropMap ? resolveVarRefs(sibStyle.letterSpacing, customPropMap) : sibStyle.letterSpacing;
const colorRaw = customPropMap ? resolveVarRefs(sibStyle.color, customPropMap) : sibStyle.color;
const headingFontSizeRaw = customPropMap ? resolveVarRefs(style.fontSize, customPropMap) : style.fontSize;
const siblingFontSize = parseFloat(fontSizeRaw) || 0;
// resolveLengthPx returns null for 'normal' / 'auto'; coerce to 0 so the
// gate falls through cleanly. jsdom returns letter-spacing verbatim
// (e.g. '0.15em'), unlike real browsers, so this conversion is required.
return checkHeroEyebrow({
headingTag: tag,
headingText: el.textContent || '',
headingFontSize: parseFloat(style.fontSize) || 0,
headingFontSize: parseFloat(headingFontSizeRaw) || 0,
siblingTag: sibling.tagName.toLowerCase(),
siblingText: sibling.textContent || '',
siblingTextTransform: sibStyle.textTransform || '',
siblingFontSize,
siblingLetterSpacing: resolveLengthPx(sibStyle.letterSpacing, siblingFontSize) || 0,
siblingLetterSpacing: resolveLengthPx(letterSpacingRaw, siblingFontSize) || 0,
siblingFontWeight: fontWeightRaw || '',
siblingColor: colorRaw || '',
});
}
function checkRepeatedSectionKickersFromDoc(doc, win) {
const candidates = collectRepeatedSectionKickerCandidates(
doc,
(el) => win.getComputedStyle(el),
(value, fontSize) => resolveLengthPx(value, fontSize) || 0,
);
return checkRepeatedSectionKickers({ candidates });
}
function checkElementMotion(tag, style) {
return checkMotion({
tag,
@@ -2511,6 +2954,7 @@ if (IS_BROWSER) {
return {
type: f.type || f.id,
category: ap ? ap.category : 'quality',
severity: ap?.severity || 'warning',
detail: f.detail || f.snippet,
name: ap ? ap.name : (f.type || f.id),
description: ap ? ap.description : '',
@@ -2585,6 +3029,14 @@ if (IS_BROWSER) {
allFindings.push({ el: document.body, findings: typoFindings });
}
const sectionKickerFindings = checkRepeatedSectionKickersDOM()
.map(f => ({ type: f.id, detail: f.snippet }))
.filter(f => _ruleOk(f.type));
if (sectionKickerFindings.length > 0) {
pageLevelFindings.push(...sectionKickerFindings);
allFindings.push({ el: document.body, findings: sectionKickerFindings });
}
const layoutFindings = checkLayout().filter(f => _ruleOk(f.type));
for (const f of layoutFindings) {
const el = f.el || document.body;
+594 -49
View File
@@ -253,6 +253,16 @@ const ANTIPATTERNS = [
skillSection: 'Typography',
skillGuideline: 'tiny uppercase tracked label above the hero headline',
},
{
id: 'repeated-section-kickers',
category: 'slop',
severity: 'advisory',
name: 'Repeated section kicker labels',
description:
'Repeating tiny uppercase tracked labels above section headings turns a brand page into AI editorial scaffolding. Replace them with stronger structure, artifacts, imagery, or a deliberate brand system.',
skillSection: 'Typography',
skillGuideline: 'repeated eyebrow or kicker labels as section scaffolding',
},
// ── Quality: general design and accessibility issues ──
{
@@ -305,6 +315,13 @@ const ANTIPATTERNS = [
description:
'Text is too close to the edge of its container. Add at least 8px (ideally 12-16px) of padding inside bordered or colored containers.',
},
{
id: 'body-text-viewport-edge',
category: 'quality',
name: 'Body text touching viewport edge',
description:
'Body paragraphs render flush against the left or right viewport edge with no container providing horizontal padding. Wrap content in a container with at least 16px (ideally 24-32px) of horizontal padding, or apply max-width with mx-auto.',
},
{
id: 'tight-leading',
category: 'quality',
@@ -549,7 +566,20 @@ function checkColors(opts) {
const isLargeText = fontSize >= 18 || (fontSize >= 14 && fontWeight >= 700) || isHeading;
const threshold = isLargeText ? 3.0 : 4.5;
if (ratio < threshold) {
findings.push({ id: 'low-contrast', snippet: `${ratio.toFixed(1)}:1 (need ${threshold}:1) — text ${colorToHex(textColor)} on ${colorToHex(bgs[worstIdx])}` });
// Skip the false-positive class where text has alpha < 1 AND we
// couldn't find an opaque ancestor (effectiveBg is null, we're
// comparing against gradient-stop fallback). In jsdom mode the
// detector can't resolve `var(--X)` color tokens, so a dark
// section sitting between the text and the body's decorative
// gradient is invisible to us — we end up measuring contrast
// against the body's paper-grain noise instead of the real
// local bg. Real low-contrast bugs use alpha=1 and have a
// resolvable opaque ancestor; semi-transparent Tailwind tokens
// like `text-paper/60` on `bg-ink` sections are the FP pattern.
const isAlphaFallbackFP = !IS_BROWSER && !effectiveBg && (textColor.a != null && textColor.a < 1);
if (!isAlphaFallbackFP) {
findings.push({ id: 'low-contrast', snippet: `${ratio.toFixed(1)}:1 (need ${threshold}:1) — text ${colorToHex(textColor)} on ${colorToHex(bgs[worstIdx])}` });
}
}
}
@@ -694,41 +724,114 @@ function checkItalicSerif(opts) {
}];
}
// Color saturation check. Returns true when the color has visible
// chroma — i.e., it's an "accent color" rather than near-neutral.
// Handles rgb()/rgba(), #hex, oklch(), and hsl(). var() refs are
// expected to be pre-resolved by the caller.
function isAccentColor(cssColor) {
if (!cssColor) return false;
const s = String(cssColor).trim();
// rgb / rgba — direct channel-distance check.
const rgbM = /rgba?\(\s*(\d+)\s*,?\s+|\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/.exec(s.replace(/rgba?\(\s*/, 'rgb(').replace(/,/g, ', '));
const rgbStrict = /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/.exec(s);
if (rgbStrict) {
const r = +rgbStrict[1], g = +rgbStrict[2], b = +rgbStrict[3];
return (Math.max(r, g, b) - Math.min(r, g, b)) >= 40;
}
// #hex — 3, 4, 6, or 8 digit.
const hexM = /^#([0-9a-f]{3,8})\b/i.exec(s);
if (hexM) {
let h = hexM[1];
if (h.length === 3 || h.length === 4) h = h.split('').map((c) => c + c).join('').slice(0, 6);
else h = h.slice(0, 6);
if (h.length === 6) {
const r = parseInt(h.slice(0, 2), 16);
const g = parseInt(h.slice(2, 4), 16);
const b = parseInt(h.slice(4, 6), 16);
return (Math.max(r, g, b) - Math.min(r, g, b)) >= 40;
}
}
// oklch(L C H) — chroma C is what matters. Typical neutral grays
// have C < 0.02; visible accents are 0.05+. CSS minification can
// collapse spaces between L% and C ("oklch(43%.15 34)"), so we
// extract all numbers and take the second rather than matching a
// strict L-then-whitespace-then-C pattern.
if (/^oklch\(/i.test(s)) {
const nums = s.match(/\d*\.\d+|\d+/g);
if (nums && nums.length >= 2) {
const c = parseFloat(nums[1]);
return !Number.isNaN(c) && c >= 0.05;
}
}
// hsl(H, S%, L%) — saturation > 20% reads as accent.
const hslM = /hsla?\(\s*[\d.]+\s*,\s*([\d.]+)%/i.exec(s);
if (hslM) {
const sat = parseFloat(hslM[1]);
return !Number.isNaN(sat) && sat >= 20;
}
return false;
}
// Sibling-relationship rule. Anchor on a hero-scale h1, look at the
// previousElementSibling, and gate on uppercase + tracked + small.
// previousElementSibling, and gate on EITHER the classic tracked-
// uppercase eyebrow OR the modern accent-colored bold eyebrow.
function checkHeroEyebrow(opts) {
const {
headingTag, headingText, headingFontSize,
siblingTag, siblingText, siblingTextTransform,
siblingFontSize, siblingLetterSpacing,
siblingFontWeight, siblingColor,
} = opts;
if (headingTag !== 'h1') return [];
if (!headingFontSize || headingFontSize < 48) return [];
// We previously gated on headingFontSize >= 48 to anchor "hero scale".
// But modern hero h1s use clamp() / vw / var(--text-*), none of which
// jsdom can resolve — the computed value comes back as "2em" or
// "var(--text-9xl)" and parseFloat returns 2 or NaN. The gate fails
// on virtually every Tailwind v4 / framework build. The other gates
// (sibling text 2-60 chars, font-size ≤ 14px, accent-bold OR
// tracked-caps) are tight enough to avoid false positives on non-
// hero h1s — a tiny tan label directly above any h1 is the
// antipattern regardless of how big the h1 ends up.
if (!siblingTag) return [];
// An h2 above an h1 is a different anti-pattern (heading hierarchy / dual
// headings) — never an eyebrow.
if (HEADING_TAGS.has(siblingTag)) return [];
const text = (siblingText || '').trim();
if (text.length < 2 || text.length > 30) return [];
if (text.length < 2 || text.length > 60) return [];
if (!(siblingFontSize > 0 && siblingFontSize <= 14)) return [];
// Uppercase: either via text-transform, or the content is already typed
// uppercase (no lowercase letters, at least one uppercase letter).
// Branch A: classic tracked-uppercase eyebrow.
const isUppercased = siblingTextTransform === 'uppercase'
|| (/[A-Z]/.test(text) && !/[a-z]/.test(text));
if (!isUppercased) return [];
const isClassicTracked = isUppercased && siblingLetterSpacing >= 1.6;
if (!(siblingLetterSpacing >= 1.6)) return [];
if (!(siblingFontSize > 0 && siblingFontSize <= 14)) return [];
// Branch B: modern accent-bold eyebrow — sentence case, low
// tracking, but bold + accent-colored. The style choices changed;
// the pattern is the same kicker-above-headline anti-pattern.
const weight = Number(siblingFontWeight) || 400;
const isAccentBold = weight >= 700 && isAccentColor(siblingColor || '');
if (!isClassicTracked && !isAccentBold) return [];
const headingTextSnippet = (headingText || '').trim().slice(0, 60);
const eyebrowSnippet = text.slice(0, 40);
const style = isClassicTracked ? 'tracked-caps' : 'accent-bold';
return [{
id: 'hero-eyebrow-chip',
snippet: `eyebrow chip "${eyebrowSnippet}" above ${headingTag} "${headingTextSnippet}"`,
snippet: `eyebrow chip (${style}) "${eyebrowSnippet}" above ${headingTag} "${headingTextSnippet}"`,
}];
}
function checkRepeatedSectionKickers(opts) {
const { candidates, minCount = 3 } = opts;
if (!Array.isArray(candidates) || candidates.length < minCount) return [];
return candidates.map(candidate => ({
id: 'repeated-section-kickers',
snippet: `repeated section kicker "${candidate.kickerText}" before ${candidate.headingTag} "${candidate.headingText}" (${candidates.length} on page)`,
}));
}
const LAYOUT_TRANSITION_PROPS = new Set([
'width', 'height', 'padding', 'margin',
'max-height', 'max-width', 'min-height', 'min-width',
@@ -970,43 +1073,60 @@ function readOwnBackgroundColor(el, computedStyle) {
return bg;
}
function resolveBackground(el, win) {
function resolveBackground(el, win, customPropMap) {
let current = el;
while (current && current.nodeType === 1) {
const style = IS_BROWSER ? getComputedStyle(current) : win.getComputedStyle(current);
// If this element has a background-image (gradient or url), it's visually
// opaque but we can't determine the effective color — bail out so callers
// don't get a false solid-color answer.
const bgImage = style.backgroundImage || '';
if (bgImage && bgImage !== 'none' && (/gradient/i.test(bgImage) || /url\s*\(/i.test(bgImage))) {
return null;
}
const hasGradientOrUrl = bgImage && bgImage !== 'none' && (/gradient/i.test(bgImage) || /url\s*\(/i.test(bgImage));
// Try the solid bg-color FIRST. If the element has both a solid color
// and a gradient/url overlay (a common pattern: `background: var(--paper)
// radial-gradient(...)` for paper-grain texture), the solid color is the
// dominant visible surface for contrast purposes; the overlay is
// decorative. The old behavior bailed on any gradient ancestor, which
// caused massive false-positive contrast findings on grain-textured
// body backgrounds.
let bg = parseRgb(style.backgroundColor);
if (!IS_BROWSER && (!bg || bg.a < 0.1)) {
// jsdom doesn't decompose background shorthand — parse raw style attr
const rawStyle = current.getAttribute?.('style') || '';
const bgMatch = rawStyle.match(/background(?:-color)?\s*:\s*([^;]+)/i);
const inlineBg = bgMatch ? bgMatch[1].trim() : '';
// Check for gradient or url() image in inline style too
if (/gradient/i.test(inlineBg) || /url\s*\(/i.test(inlineBg)) return null;
bg = parseRgb(inlineBg);
if (!bg && inlineBg) {
const hexMatch = inlineBg.match(/#([0-9a-f]{6}|[0-9a-f]{3})\b/i);
if (hexMatch) {
const h = hexMatch[1];
if (h.length === 6) {
bg = { r: parseInt(h.slice(0,2), 16), g: parseInt(h.slice(2,4), 16), b: parseInt(h.slice(4,6), 16), a: 1 };
} else {
bg = { r: parseInt(h[0]+h[0], 16), g: parseInt(h[1]+h[1], 16), b: parseInt(h[2]+h[2], 16), a: 1 };
}
// jsdom returns literal "var(--X)" / "oklch(...)" strings. Resolve
// through customPropMap so Tailwind v4 color tokens become RGB.
if (customPropMap) {
bg = parseColorResolved(style.backgroundColor, customPropMap);
}
if (!bg || bg.a < 0.1) {
// Inline-style fallback. jsdom doesn't decompose background
// shorthand, so colors set via inline style are otherwise invisible.
const rawStyle = current.getAttribute?.('style') || '';
const bgMatch = rawStyle.match(/background(?:-color)?\s*:\s*([^;]+)/i);
const inlineBg = bgMatch ? bgMatch[1].trim() : '';
if (inlineBg && !/gradient/i.test(inlineBg) && !/url\s*\(/i.test(inlineBg)) {
bg = parseColorResolved(inlineBg, customPropMap) || parseAnyColor(inlineBg);
}
}
}
if (bg && bg.a > 0.1) {
if (IS_BROWSER || bg.a >= 0.5) return bg;
}
// No solid bg-color at this level. If THIS level has a gradient/url
// with no underlying solid color we can read:
// • on body/html: assume white. Body-level gradients are almost
// always decorative texture (paper grain, noise) on top of a
// solid bg-color the page set via `background: var(--paper)`
// shorthand — which jsdom can't decompose into bg-color. The
// downstream gradient-stops fallback path produces catastrophic
// false positives in this case (gradient noise stops have
// accidental browns/blacks that look like card backgrounds).
// • on other elements: bail to null and let the caller fall back
// to gradient stops (gradient buttons / hero sections are real
// bgs worth checking against).
if (hasGradientOrUrl) {
if (current.tagName === 'BODY' || current.tagName === 'HTML') {
return { r: 255, g: 255, b: 255, a: 1 };
}
return null;
}
current = current.parentElement;
}
return { r: 255, g: 255, b: 255 };
@@ -1224,9 +1344,245 @@ function checkElementHeroEyebrowDOM(el) {
siblingTextTransform: sibStyle.textTransform || '',
siblingFontSize: parseFloat(sibStyle.fontSize) || 0,
siblingLetterSpacing: parseFloat(sibStyle.letterSpacing) || 0,
siblingFontWeight: sibStyle.fontWeight || '',
siblingColor: sibStyle.color || '',
});
}
// Build a map of CSS custom properties declared on :root / :host / html.
// Used to resolve var(--X) refs that jsdom returns verbatim in
// getComputedStyle. Tailwind v4 routes every utility class through
// CSS vars (font-weight: var(--font-weight-bold), font-size:
// var(--text-xs), letter-spacing: var(--tracking-widest)), so without
// resolution every style-based check silently fails on Tailwind v4
// builds — the values come back as literal "var(--font-weight-bold)"
// strings and parseFloat returns NaN.
function buildCustomPropMap(document) {
const map = new Map();
let sheets;
try { sheets = Array.from(document.styleSheets || []); }
catch { return map; }
for (const sheet of sheets) {
let rules;
try { rules = Array.from(sheet.cssRules || []); }
catch { continue; }
for (const rule of rules) {
// Style rules only (type 1). Walk @media / @supports if present.
if (rule.type === 4 /* MEDIA_RULE */ || rule.type === 12 /* SUPPORTS_RULE */) {
try { rules.push(...Array.from(rule.cssRules || [])); } catch { /* ignore */ }
continue;
}
if (rule.type !== 1 /* STYLE_RULE */) continue;
const sel = rule.selectorText || '';
if (!/(^|,\s*)(:root|html|:host)\b/i.test(sel)) continue;
const style = rule.style;
if (!style) continue;
for (let i = 0; i < style.length; i++) {
const prop = style[i];
if (!prop || !prop.startsWith('--')) continue;
const val = style.getPropertyValue(prop).trim();
if (val) map.set(prop, val);
}
}
}
return map;
}
// Resolve var(--X[, fallback]) refs in a computed-style value string.
// Recurses up to 8 levels for chained refs (--a: var(--b)). Returns
// the original string when no refs are present or the chain doesn't
// resolve. Safe to call on already-resolved values.
function resolveVarRefs(raw, customPropMap, depth = 0) {
if (typeof raw !== 'string' || !raw.includes('var(')) return raw;
if (depth > 8) return raw;
return raw.replace(/var\(\s*(--[a-zA-Z0-9_-]+)\s*(?:,\s*([^)]+))?\)/g, (_m, name, fallback) => {
const v = customPropMap.get(name);
if (v != null) return resolveVarRefs(v, customPropMap, depth + 1);
return fallback ? resolveVarRefs(fallback.trim(), customPropMap, depth + 1) : _m;
});
}
// OKLCH → sRGB conversion (Björn Ottosson's matrices). L in 0..1 (or %),
// C in 0..~0.4 typical, H in degrees. Returns clamped {r,g,b,a:1} in 0..255.
// Needed because jsdom doesn't compute oklch() values — getComputedStyle
// returns the literal "oklch(...)" string. Without this, the entire
// Tailwind v4 color palette (which is OKLCH-based) is invisible to the
// detector's contrast / color checks.
function oklchToRgb(L, C, H) {
const hRad = (H * Math.PI) / 180;
const a = C * Math.cos(hRad);
const b = C * Math.sin(hRad);
const l_ = L + 0.3963377774 * a + 0.2158037573 * b;
const m_ = L - 0.1055613458 * a - 0.0638541728 * b;
const s_ = L - 0.0894841775 * a - 1.2914855480 * b;
const lc = l_ * l_ * l_, mc = m_ * m_ * m_, sc = s_ * s_ * s_;
const rLin = 4.0767416621 * lc - 3.3077115913 * mc + 0.2309699292 * sc;
const gLin = -1.2684380046 * lc + 2.6097574011 * mc - 0.3413193965 * sc;
const bLin = -0.0041960863 * lc - 0.7034186147 * mc + 1.7076147010 * sc;
const enc = (x) => {
const c = Math.max(0, Math.min(1, x));
return c <= 0.0031308 ? 12.92 * c : 1.055 * Math.pow(c, 1 / 2.4) - 0.055;
};
return {
r: Math.round(enc(rLin) * 255),
g: Math.round(enc(gLin) * 255),
b: Math.round(enc(bLin) * 255),
a: 1,
};
}
// Extended color parser: rgb/rgba/hex/oklch. Returns null on no match.
// Use this when the input might be any CSS color form; use plain parseRgb
// when you only expect computed rgb() values from real browsers.
function parseAnyColor(s) {
if (!s || typeof s !== 'string') return null;
const str = s.trim();
if (str === 'transparent' || str === 'currentcolor' || str === 'inherit') return null;
let m;
m = str.match(/rgba?\(\s*(\d+(?:\.\d+)?)\s*,?\s*(\d+(?:\.\d+)?)\s*,?\s*(\d+(?:\.\d+)?)(?:\s*[,/]\s*([\d.]+))?\s*\)/);
if (m) return { r: Math.round(+m[1]), g: Math.round(+m[2]), b: Math.round(+m[3]), a: m[4] !== undefined ? +m[4] : 1 };
m = str.match(/^#([0-9a-f]{3,8})$/i);
if (m) {
const h = m[1];
if (h.length === 3 || h.length === 4) {
return {
r: parseInt(h[0] + h[0], 16),
g: parseInt(h[1] + h[1], 16),
b: parseInt(h[2] + h[2], 16),
a: h.length === 4 ? parseInt(h[3] + h[3], 16) / 255 : 1,
};
}
if (h.length === 6 || h.length === 8) {
return {
r: parseInt(h.slice(0, 2), 16),
g: parseInt(h.slice(2, 4), 16),
b: parseInt(h.slice(4, 6), 16),
a: h.length === 8 ? parseInt(h.slice(6, 8), 16) / 255 : 1,
};
}
}
// OKLCH parser. Tailwind v4's CSS minifier squishes the space after
// `%` ("21.5%.02 50"), so the separator between L and C may be absent.
// Match L (with optional %), then C and H separated permissively.
m = str.match(/oklch\(\s*([\d.]+)(%?)\s*[\s,]*\s*([\d.]+)\s*[\s,]+\s*([-\d.]+)(?:deg)?\s*\)/i);
if (m) {
const Lnum = parseFloat(m[1]);
const L = m[2] === '%' ? Lnum / 100 : Lnum;
return oklchToRgb(L, parseFloat(m[3]), parseFloat(m[4]));
}
return null;
}
// Resolve var() refs in a color string (via customPropMap), then parse.
// Returns null on any failure. Used in jsdom-mode paths where
// getComputedStyle returns literal "var(--X)" or "oklch(...)" strings.
function parseColorResolved(str, customPropMap) {
if (!str) return null;
const resolved = customPropMap ? resolveVarRefs(str, customPropMap) : str;
return parseAnyColor(resolved);
}
const REPEATED_KICKER_SKIP_SELECTOR = [
'nav',
'form',
'table',
'thead',
'tbody',
'tfoot',
'figure',
'figcaption',
'ol',
'ul',
'li',
'[role="navigation"]',
'[aria-label*="breadcrumb" i]',
'[class*="breadcrumb" i]',
'[data-impeccable-allow-kickers]',
].join(',');
function cleanInlineText(el) {
return [...el.childNodes]
.filter(n => n.nodeType === 3)
.map(n => n.textContent)
.join(' ')
.replace(/\s+/g, ' ')
.trim();
}
function isRepeatedKickerCandidate(opts) {
const {
headingTag,
headingText,
headingFontSize,
kickerTag,
kickerText,
kickerTextTransform,
kickerFontSize,
kickerLetterSpacing,
} = opts;
if (!['h2', 'h3', 'h4'].includes(headingTag)) return false;
if (!headingText || headingText.length < 3) return false;
if (!(headingFontSize >= 20)) return false;
if (!kickerTag || HEADING_TAGS.has(kickerTag)) return false;
if (!['p', 'span', 'div', 'small'].includes(kickerTag)) return false;
if (!kickerText || kickerText.length < 2 || kickerText.length > 34) return false;
if (/^step\s*\d+/i.test(kickerText) || /^\d{1,2}$/.test(kickerText)) return false;
const isUppercased = kickerTextTransform === 'uppercase'
|| (/[A-Z]/.test(kickerText) && !/[a-z]/.test(kickerText));
if (!isUppercased) return false;
if (!(kickerFontSize > 0 && kickerFontSize <= 14)) return false;
const minTrackedSpacing = Math.max(1, kickerFontSize * 0.08);
if (!(kickerLetterSpacing >= minTrackedSpacing)) return false;
return true;
}
function collectRepeatedSectionKickerCandidates(doc, getStyle, resolveLetterSpacing) {
const candidates = [];
for (const heading of doc.querySelectorAll('h2, h3, h4')) {
if (heading.closest?.(REPEATED_KICKER_SKIP_SELECTOR)) continue;
const kicker = heading.previousElementSibling;
if (!kicker || kicker.closest?.(REPEATED_KICKER_SKIP_SELECTOR)) continue;
const headingStyle = getStyle(heading);
const kickerStyle = getStyle(kicker);
const headingText = (heading.textContent || '').replace(/\s+/g, ' ').trim();
const kickerText = cleanInlineText(kicker) || (kicker.textContent || '').replace(/\s+/g, ' ').trim();
const headingFontSize = resolveLetterSpacing(headingStyle.fontSize || '', 16) || parseFloat(headingStyle.fontSize) || 0;
const kickerFontSize = resolveLetterSpacing(kickerStyle.fontSize || '', 16) || parseFloat(kickerStyle.fontSize) || 0;
const kickerLetterSpacing = resolveLetterSpacing(kickerStyle.letterSpacing || '', kickerFontSize);
if (!isRepeatedKickerCandidate({
headingTag: heading.tagName.toLowerCase(),
headingText,
headingFontSize,
kickerTag: kicker.tagName.toLowerCase(),
kickerText,
kickerTextTransform: kickerStyle.textTransform || '',
kickerFontSize,
kickerLetterSpacing,
})) {
continue;
}
candidates.push({
headingTag: heading.tagName.toLowerCase(),
headingText: headingText.replace(/^"|"$/g, '').slice(0, 60),
kickerText: kickerText.slice(0, 40),
});
}
return candidates;
}
function checkRepeatedSectionKickersDOM() {
const candidates = collectRepeatedSectionKickerCandidates(
document,
(el) => getComputedStyle(el),
(value, fontSize) => resolveLengthPx(value, fontSize) || 0,
);
return checkRepeatedSectionKickers({ candidates });
}
function checkElementMotionDOM(el) {
const tag = el.tagName.toLowerCase();
if (SAFE_TAGS.has(tag)) return [];
@@ -1377,7 +1733,7 @@ function resolveLengthPx(value, fontSizePx) {
// Both adapters resolve font-size, line-height and letter-spacing to pixels
// before calling this so the pure function only deals with numbers.
function checkQuality(opts) {
const { el, tag, style, hasDirectText, textLen, fontSize, lineHeightPx, letterSpacingPx, rect, lineMax = 80 } = opts;
const { el, tag, style, hasDirectText, textLen, fontSize, lineHeightPx, letterSpacingPx, rect, lineMax = 80, viewportWidth = 0 } = opts;
const findings = [];
// Skip browser extension injected elements
const elId = el.id || '';
@@ -1428,6 +1784,40 @@ function checkQuality(opts) {
}
}
// --- Body text touching viewport edge --- (browser-only: needs rect)
// Catches the failure mode where the agent ships body paragraphs
// with NO container providing horizontal padding — text bleeds
// directly to the viewport edge. Different from cramped-padding,
// which requires a colored/bordered container. Here the failure
// is the absence of the container entirely.
//
// Gate aggressively to avoid false positives:
// - <p> or <li> only (body content; not headings, not nav, not
// wrappers)
// - text > 40 chars (paragraph-like, not a label)
// - rect.width > 50% of viewport (real body, not a pull-quote)
// - rect.left < 16 OR rect.right > viewport - 16 (actually
// touching the edge)
// - not inside <nav> or <header> (those legitimately bleed)
// - element itself has no background-color (intentional full-bleed
// sections set a bg-color and provide their own internal padding)
if (rect && hasDirectText && textLen > 40 && ['P', 'LI'].includes(tag.toUpperCase()) && viewportWidth > 0) {
const inNavHeader = el.closest && (el.closest('nav') || el.closest('header'));
const hasOwnBg = style.backgroundColor && style.backgroundColor !== 'rgba(0, 0, 0, 0)' && style.backgroundColor !== 'transparent';
const isPositioned = ['fixed', 'absolute'].includes(style.position || '');
const widthRatio = rect.width / viewportWidth;
const leftClose = rect.left < 16;
const rightClose = rect.right > viewportWidth - 16;
if (!inNavHeader && !hasOwnBg && !isPositioned && widthRatio > 0.5 && (leftClose || rightClose)) {
const which = leftClose && rightClose
? `left ${Math.round(rect.left)}px / right ${Math.round(viewportWidth - rect.right)}px`
: leftClose
? `left ${Math.round(rect.left)}px`
: `right ${Math.round(viewportWidth - rect.right)}px`;
findings.push({ id: 'body-text-viewport-edge', snippet: `<${tag.toLowerCase()}> with ${textLen}-char body bleeds to viewport edge (${which})` });
}
}
// --- Tight line height ---
if (hasDirectText && textLen > 50 && !['h1','h2','h3','h4','h5','h6'].includes(tag)) {
if (lineHeightPx != null && fontSize > 0) {
@@ -1489,7 +1879,8 @@ function checkElementQualityDOM(el) {
const letterSpacingPx = resolveLengthPx(style.letterSpacing, fontSize);
const rect = el.getBoundingClientRect();
const lineMax = (typeof window !== 'undefined' && window.__IMPECCABLE_CONFIG__?.lineLengthMax) || 80;
return checkQuality({ el, tag, style, hasDirectText, textLen, fontSize, lineHeightPx, letterSpacingPx, rect, lineMax });
const viewportWidth = (typeof window !== 'undefined' ? window.innerWidth : 0) || 0;
return checkQuality({ el, tag, style, hasDirectText, textLen, fontSize, lineHeightPx, letterSpacingPx, rect, lineMax, viewportWidth });
}
// Pure page-level skipped-heading walk. Takes a Document so it works in both
@@ -1564,14 +1955,47 @@ function checkElementBorders(tag, style, overrides, resolvedRadius) {
return checkBorders(tag, widths, colors, radius);
}
function checkElementColors(el, style, tag, window) {
function checkElementColors(el, style, tag, window, customPropMap, hasAnchorInheritRule) {
const directText = [...el.childNodes].filter(n => n.nodeType === 3).map(n => n.textContent).join('');
const hasDirectText = directText.trim().length > 0;
const effectiveBg = resolveBackground(el, window);
const effectiveBg = resolveBackground(el, window, customPropMap);
// jsdom returns literal "var(--X)" / "oklch(...)" for color, so plain
// parseRgb misses Tailwind-tokenized text colors. Resolve through the
// customPropMap first; fall back to parseRgb for vanilla rgb() pages.
let textColor = customPropMap ? parseColorResolved(style.color, customPropMap) : null;
if (!textColor) textColor = parseRgb(style.color);
// Anchor-inherit FP workaround: jsdom's UA stylesheet has `:link { color:
// blue }` at high specificity. The page's `a { color: inherit }` rule
// (Tailwind v4 preflight) loses to jsdom even though it WINS in real
// browsers (Chrome's UA wraps :link in :where() — zero specificity).
// When the page declares the inherit rule AND we see jsdom's default
// link blue on an anchor, walk to the nearest non-anchor ancestor and
// use its color instead.
if (
hasAnchorInheritRule &&
textColor &&
textColor.r === 0 && textColor.g === 0 && textColor.b === 238 &&
(tag === 'a' || el.closest?.('a'))
) {
let cur = el.parentElement;
while (cur && cur.tagName !== 'HTML') {
if (cur.tagName !== 'A') {
const ps = window.getComputedStyle(cur);
const inh = (customPropMap ? parseColorResolved(ps.color, customPropMap) : null) || parseRgb(ps.color);
if (inh && !(inh.r === 0 && inh.g === 0 && inh.b === 238)) {
textColor = inh;
break;
}
}
cur = cur.parentElement;
}
}
return checkColors({
tag,
textColor: parseRgb(style.color),
textColor,
bgColor: readOwnBackgroundColor(el, style),
effectiveBg,
effectiveBgStops: effectiveBg ? null : resolveGradientStops(el, window),
@@ -1633,27 +2057,46 @@ function checkElementItalicSerif(el, style, tag) {
});
}
function checkElementHeroEyebrow(el, style, tag, window) {
function checkElementHeroEyebrow(el, style, tag, window, customPropMap) {
if (tag !== 'h1') return [];
const sibling = el.previousElementSibling;
if (!sibling) return [];
const sibStyle = window.getComputedStyle(sibling);
const siblingFontSize = parseFloat(sibStyle.fontSize) || 0;
// Resolve Tailwind v4 CSS-variable wrappers (font-weight:var(--font-weight-bold)
// etc.) before parsing. jsdom returns these verbatim from getComputedStyle;
// without resolution every style-based gate fails silently on Tailwind v4 builds.
const fontSizeRaw = customPropMap ? resolveVarRefs(sibStyle.fontSize, customPropMap) : sibStyle.fontSize;
const fontWeightRaw = customPropMap ? resolveVarRefs(sibStyle.fontWeight, customPropMap) : sibStyle.fontWeight;
const letterSpacingRaw = customPropMap ? resolveVarRefs(sibStyle.letterSpacing, customPropMap) : sibStyle.letterSpacing;
const colorRaw = customPropMap ? resolveVarRefs(sibStyle.color, customPropMap) : sibStyle.color;
const headingFontSizeRaw = customPropMap ? resolveVarRefs(style.fontSize, customPropMap) : style.fontSize;
const siblingFontSize = parseFloat(fontSizeRaw) || 0;
// resolveLengthPx returns null for 'normal' / 'auto'; coerce to 0 so the
// gate falls through cleanly. jsdom returns letter-spacing verbatim
// (e.g. '0.15em'), unlike real browsers, so this conversion is required.
return checkHeroEyebrow({
headingTag: tag,
headingText: el.textContent || '',
headingFontSize: parseFloat(style.fontSize) || 0,
headingFontSize: parseFloat(headingFontSizeRaw) || 0,
siblingTag: sibling.tagName.toLowerCase(),
siblingText: sibling.textContent || '',
siblingTextTransform: sibStyle.textTransform || '',
siblingFontSize,
siblingLetterSpacing: resolveLengthPx(sibStyle.letterSpacing, siblingFontSize) || 0,
siblingLetterSpacing: resolveLengthPx(letterSpacingRaw, siblingFontSize) || 0,
siblingFontWeight: fontWeightRaw || '',
siblingColor: colorRaw || '',
});
}
function checkRepeatedSectionKickersFromDoc(doc, win) {
const candidates = collectRepeatedSectionKickerCandidates(
doc,
(el) => win.getComputedStyle(el),
(value, fontSize) => resolveLengthPx(value, fontSize) || 0,
);
return checkRepeatedSectionKickers({ candidates });
}
function checkElementMotion(tag, style) {
return checkMotion({
tag,
@@ -2507,6 +2950,7 @@ if (IS_BROWSER) {
return {
type: f.type || f.id,
category: ap ? ap.category : 'quality',
severity: ap?.severity || 'warning',
detail: f.detail || f.snippet,
name: ap ? ap.name : (f.type || f.id),
description: ap ? ap.description : '',
@@ -2581,6 +3025,14 @@ if (IS_BROWSER) {
allFindings.push({ el: document.body, findings: typoFindings });
}
const sectionKickerFindings = checkRepeatedSectionKickersDOM()
.map(f => ({ type: f.id, detail: f.snippet }))
.filter(f => _ruleOk(f.type));
if (sectionKickerFindings.length > 0) {
pageLevelFindings.push(...sectionKickerFindings);
allFindings.push({ el: document.body, findings: sectionKickerFindings });
}
const layoutFindings = checkLayout().filter(f => _ruleOk(f.type));
for (const f of layoutFindings) {
const el = f.el || document.body;
@@ -2719,7 +3171,7 @@ function getAP(id) {
function finding(id, filePath, snippet, line = 0) {
const ap = getAP(id);
return { antipattern: id, name: ap.name, description: ap.description, file: filePath, line, snippet };
return { antipattern: id, name: ap.name, description: ap.description, severity: ap.severity || 'warning', file: filePath, line, snippet };
}
/** Check if content looks like a full page (not a component/partial) */
@@ -2900,6 +3352,48 @@ function buildBorderOverrideMap(document, window) {
return map;
}
// Strip `@layer NAME { … }` wrappers from a CSS / HTML source, leaving
// the inner rules as flat CSS. jsdom doesn't implement CSS @layer, so
// any rule inside a layer block becomes invisible to getComputedStyle.
// Tailwind v4 makes this ubiquitous: every utility class lives in
// `@layer utilities`, and Preflight lives in `@layer base`. Without
// unwrapping, every Tailwind-styled element returns empty computed
// styles. We walk the source character-by-character, balancing braces
// so we correctly handle nested style rules inside the layer block.
function unwrapCssAtLayer(source) {
if (!source || !source.includes('@layer')) return source;
// Find `@layer <name>? {` openers. The match starts at the @, and
// we then balance braces from the opening { onward.
const re = /@layer\b[^{;]*\{/g;
let out = '';
let lastIdx = 0;
let m;
while ((m = re.exec(source)) !== null) {
const openStart = m.index;
const openEnd = m.index + m[0].length; // position right after `{`
let depth = 1;
let i = openEnd;
while (i < source.length && depth > 0) {
const c = source.charCodeAt(i);
if (c === 0x7b /* { */) depth++;
else if (c === 0x7d /* } */) depth--;
i++;
}
if (depth !== 0) {
// Unbalanced — bail and return source unchanged.
return source;
}
// Emit everything before the @layer, then the inner contents
// (between the opening { and the matched closing }), then advance.
out += source.slice(lastIdx, openStart);
out += source.slice(openEnd, i - 1); // i-1 = position of the closing }
lastIdx = i;
re.lastIndex = i;
}
out += source.slice(lastIdx);
return out;
}
// ---------------------------------------------------------------------------
// jsdom detection (default for HTML files)
// ---------------------------------------------------------------------------
@@ -2936,6 +3430,16 @@ async function detectHtml(filePath) {
}
}
// jsdom does not implement CSS `@layer` rules — every utility class
// inside `@layer utilities { ... }` is silently ignored, so computed
// styles come back empty. Tailwind v4 wraps every utility class in
// an @layer, which means jsdom returns empty strings for fontSize /
// fontWeight / textTransform / letterSpacing on every Tailwind-styled
// element. Strip the @layer wrapper, keep the inner rules as flat
// CSS that jsdom can process. The cascade ordering @layer provides
// doesn't matter for our checks — we only read computed values.
processedHtml = unwrapCssAtLayer(processedHtml);
const dom = new JSDOM(processedHtml, {
url: `file://${resolvedPath}`,
});
@@ -2949,6 +3453,39 @@ async function detectHtml(filePath) {
// by the border check adapter as a fallback.
const borderOverrides = buildBorderOverrideMap(document, window);
// Pre-pass: collect :root / :host / html CSS custom properties so the
// checks can resolve var(--X) refs that jsdom returns verbatim from
// getComputedStyle. Tailwind v4 wraps every utility-class value in a
// CSS var; without this, font-weight / font-size / letter-spacing /
// color all come back as literal "var(--X)" strings.
const customPropMap = buildCustomPropMap(document);
// Pre-pass: detect whether the page's CSS declares `a { color: inherit }`
// (Tailwind v4 preflight signature). When present, real browsers render
// anchors using the cascaded ancestor color, but jsdom's UA stylesheet
// applies `:link { color: blue }` at higher specificity, so anchors come
// back as `rgb(0, 0, 238)` regardless. checkElementColors uses this
// flag to walk for the cascaded color when it sees jsdom's blue default
// on an anchor — preventing a whole class of contrast false positives
// on Tailwind v4 pages.
let hasAnchorInheritRule = false;
const scanForAnchorInherit = (rules) => {
for (const rule of rules) {
if (rule.selectorText === 'a' && rule.style && rule.style.color === 'inherit') return true;
// Recurse into @layer / @media / @supports / etc.
if (rule.cssRules && scanForAnchorInherit(rule.cssRules)) return true;
}
return false;
};
for (const sheet of document.styleSheets) {
try {
if (scanForAnchorInherit(sheet.cssRules || [])) {
hasAnchorInheritRule = true;
break;
}
} catch (e) { /* cross-origin sheet, skip */ }
}
// Element-level checks (borders + colors + motion)
for (const el of document.querySelectorAll('*')) {
const tag = el.tagName.toLowerCase();
@@ -2957,10 +3494,10 @@ async function detectHtml(filePath) {
for (const f of checkElementBorders(tag, style, borderOverrides.get(el), resolvedRadius)) {
findings.push(finding(f.id, filePath, f.snippet));
}
for (const f of checkElementColors(el, style, tag, window)) {
for (const f of checkElementColors(el, style, tag, window, customPropMap, hasAnchorInheritRule)) {
findings.push(finding(f.id, filePath, f.snippet));
}
for (const f of checkElementGlow(tag, style, resolveBackground(el.parentElement || el, window))) {
for (const f of checkElementGlow(tag, style, resolveBackground(el.parentElement || el, window, customPropMap))) {
findings.push(finding(f.id, filePath, f.snippet));
}
for (const f of checkElementMotion(tag, style)) {
@@ -2972,7 +3509,7 @@ async function detectHtml(filePath) {
for (const f of checkElementItalicSerif(el, style, tag)) {
findings.push(finding(f.id, filePath, f.snippet));
}
for (const f of checkElementHeroEyebrow(el, style, tag, window)) {
for (const f of checkElementHeroEyebrow(el, style, tag, window, customPropMap)) {
findings.push(finding(f.id, filePath, f.snippet));
}
for (const f of checkElementQuality(el, style, tag, window)) {
@@ -2985,6 +3522,9 @@ async function detectHtml(filePath) {
for (const f of checkPageTypography(document, window)) {
findings.push(finding(f.id, filePath, f.snippet));
}
for (const f of checkRepeatedSectionKickersFromDoc(document, window)) {
findings.push(finding(f.id, filePath, f.snippet));
}
for (const f of checkPageLayout(document, window)) {
findings.push(finding(f.id, filePath, f.snippet));
}
@@ -3653,7 +4193,11 @@ Examples:
}
async function main() {
const args = process.argv.slice(2);
const args = process.argv.slice(2).map(arg => {
if (arg === '-json') return '--json';
if (arg === '-fast') return '--fast';
return arg;
});
const jsonMode = args.includes('--json');
const helpMode = args.includes('--help');
const fastMode = args.includes('--fast');
@@ -3762,7 +4306,8 @@ async function main() {
}
if (allFindings.length > 0) {
process.stderr.write(formatFindings(allFindings, jsonMode) + '\n');
if (jsonMode) process.stdout.write(formatFindings(allFindings, true) + '\n');
else process.stderr.write(formatFindings(allFindings, false) + '\n');
process.exit(2);
}
if (jsonMode) process.stdout.write('[]\n');
+6 -19
View File
@@ -11,28 +11,15 @@ allowed-tools:
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
## Setup (non-optional)
## Setup
Before any design work or file edits, pass these gates. Skipping them produces generic output that ignores the project.
Before any design work or file edits:
| Gate | Required check | If fail |
|---|---|---|
| Context | The PRODUCT.md / DESIGN.md loader result is known from `node .claude/skills/impeccable/scripts/load-context.mjs`. | Run the loader before continuing. |
| Product | PRODUCT.md exists and is not empty or placeholder (`[TODO]` markers, <200 chars). | Run `/impeccable teach`, refresh context, then resume. Never synthesize PRODUCT.md from the user's original prompt alone. |
| Command | The matching command reference is loaded when a sub-command is used. | Load the reference before continuing. |
| Craft | `/impeccable craft` has a user-confirmed shape brief for this task. `teach` / PRODUCT.md never counts as shape. | Run `/impeccable shape` and wait for explicit brief confirmation. |
| Image | Required visual probes / mocks are generated or skipped with a reason. | Resolve the image-generation gate in `shape.md` or `craft.md` before code. |
| Mutation | All active gates above pass. | Do not edit project files yet. |
1. Load context (PRODUCT.md / DESIGN.md) via the loader script.
2. Identify the register and load the matching register reference (brand.md or product.md).
3. **If the user invoked a sub-command (e.g. `craft`, `shape`, `audit`), load its reference file too.** This is non-negotiable: `craft` without `craft.md` loaded means you'll skip the shape-and-confirm step the user expects.
Codex-style agents must state this before editing files:
```text
IMPECCABLE_PREFLIGHT: context=pass product=pass command_reference=pass shape=pass|not_required image_gate=pass|skipped:<reason> mutation=open
```
For `/impeccable craft`, `shape=pass` is only valid after a separate user response approving the shape design brief, or when the user provided an already-confirmed brief in the request. Do not mark `shape=pass` after writing PRODUCT.md, summarizing assumptions, or drafting an unconfirmed brief yourself.
Other harnesses should follow the same checklist when they can expose this state.
Skipping these produces generic output that ignores the project.
### 1. Context gathering
+7 -3
View File
@@ -12,6 +12,8 @@ Brand isn't a neutral register. AI-generated landing pages have flooded the inte
**The second slop test: aesthetic lane.** Before committing to moves, name the reference. A Klim-style specimen page is one lane; Stripe-minimal is another; Liquid-Death-acid-maximalism is another. Don't drift into editorial-magazine aesthetics on a brief that isn't editorial. A hiking brand with Cormorant italic drop caps has the wrong register within the register.
Then the inverse test: in one sentence, describe what you're about to build the way a competitor would describe theirs. If that sentence fits the modal landing page in the category, restart.
## Typography
### Font selection procedure
@@ -66,6 +68,7 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
- Palette IS voice. A calm brand and a restless brand should not share palette mechanics.
- When the strategy is Committed or Drenched, color carries the brand. Don't hedge with neutrals around the edges. Commit.
- Don't converge across projects. If the last brand surface was restrained-on-cream, this one is not.
- When a cultural-symbol palette is the obvious pull, reach past it. Let the cultural reading come from typography, imagery, and copy, not the palette.
## Layout
@@ -79,14 +82,14 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
Brand surfaces lean on imagery. A restaurant, hotel, magazine, or product landing page without any imagery reads as incomplete, not as restrained. A solid-color rectangle where a hero image should go is worse than a representative stock photo.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse. If the approved comp or brief is image-led, ship real project assets, generated raster assets, or a credible canvas/SVG/WebGL scene. Do not replace photographic, architectural, product, or place imagery with generic CSS panels, decorative diagrams, cards, bullets, or copy.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. Pick real Unsplash photo IDs you're confident exist (`photo-1559339352-11d035aa65de`, `photo-1590490360182-c33d57733427`, etc.); if unsure, pick fewer photos but don't substitute colored `<div>` placeholders.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. **Verify the URLs before referencing them.** If you have an image-search MCP, web-fetch tool, or browser access, use it to find real photo IDs and confirm they resolve. Guessed IDs (even ones that look real) often 404 and ship as broken-image placeholders. Without a verification path, pick fewer photos you're confident exist over more that you guessed; never substitute colored `<div>` placeholders.
- **Search for the brand's physical object**, not the generic category: "handmade pasta on a scratched wooden table" beats "Italian food"; "cypress trees above a limestone hotel facade at dusk" beats "luxury hotel".
- **One decisive photo beats five mediocre ones.** Hero imagery should commit to a mood; padding with more stock doesn't rescue an indecisive one.
- **Alt text is part of the voice.** "Coastal fettuccine, hand-cut, served on the terrace" beats "pasta dish".
Tech / dev-tool brands are the exception where zero imagery can be correct; a developer landing page often carries its voice through typography, code samples, diagrams. Know which kind of brand you're working on.
"Imagery" here is broader than stock photography: product screenshots, custom data visualizations, generated SVG, and canvas/WebGL scenes are all imagery. Text-only pages where typography alone carries the entire visual weight are the failure mode.
## Motion
@@ -102,6 +105,7 @@ Tech / dev-tool brands are the exception where zero imagery can be correct; a de
- Timid palettes and average layouts. Safe = invisible.
- Zero imagery on a brief that implies imagery (restaurant, hotel, food, travel, fashion, photography, hobbyist). Colored blocks where a hero photo belongs.
- Defaulting to editorial-magazine aesthetics (display serif + italic + drop caps + broadsheet grid) on briefs that aren't magazine-shaped. Editorial is ONE aesthetic lane, not the default brand aesthetic.
- Repeated tiny uppercase tracked labels above every section heading. A single strong kicker can be voice; repeating it as section grammar is AI scaffolding unless it's a deliberate, named brand system.
## Brand permissions
+73 -111
View File
@@ -1,43 +1,41 @@
# Craft Flow
Build a feature with impeccable UX and UI quality through a structured process: shape the design, land the visual direction, build real production code, then inspect and improve in-browser until the result meets a high-end studio bar.
Build a feature with impeccable UX and UI quality: shape the design, land the visual direction, build real production code, inspect and improve in-browser until it meets a high-end studio bar.
## Build Gate
Before writing code, you need: PRODUCT.md loaded, register identified and the matching reference loaded, and a confirmed design direction for this task (either from `shape` or supplied by the user). PRODUCT.md is project context, not a task-specific brief.
Craft cannot build until all of these are true:
Treat any approved visual direction (generated mock or stated reference) as a concrete contract for composition, hierarchy, density, atmosphere, signature motifs, and distinctive visual moves. Don't let mocks replace structure, copy, accessibility, or state design. But if the live result lacks the approved direction's major ingredients, the implementation is wrong.
1. PRODUCT context is valid and current.
2. The shape design brief is explicitly confirmed by the user for this task, unless the user already provided a confirmed brief.
3. Implementation references from the brief are loaded.
4. The shape visual probe decision is recorded: generated, skipped with reason, or already resolved.
5. The north-star mock decision is recorded: generated, skipped with reason, or not applicable.
## Step 0: Project Foundation
PRODUCT.md and `teach` answers do **not** satisfy the shape gate. They are project context only. A compact self-authored brief does not satisfy the shape gate either. `shape=pass` requires a separate user response approving the shape brief or an already-confirmed brief supplied by the user.
Before shape, before code: figure out what kind of project you're working in.
Invalid image-skip reasons include: "the final implementation will be semantic HTML/CSS/SVG", "the diagram should stay editable", "a raster mock would not be used directly", or "the product is fictional." Generated probes and mocks are direction artifacts; they are not implementation assets.
Look at the working directory. Run `ls`. Check for:
## Craft Contract
- An existing framework: `astro.config.mjs/ts`, `next.config.js/ts`, `nuxt.config.ts`, `svelte.config.js`, `vite.config.js/ts`, `package.json` with framework deps, `Cargo.toml` + Leptos/Yew, `Gemfile` + Rails. **If found, use it.** Do not start a parallel build, do not introduce a second framework, do not write to `dist/` or `build/` directly. Whatever pipeline the project has, respect it.
- An existing component library or design system: `src/components/`, `app/components/`, a `tokens.css` / `theme.ts`, an `astro.config` `integrations`. Read what's there before adding to it.
- An existing icon set: `lucide-react`, `@phosphor-icons/react`, `@iconify/*`, hand-rolled SVG sprites in `assets/icons/`. **Use what's already in the project**; don't introduce a second set.
Craft is not a first pass. It is a loop with these required artifacts:
If the directory is empty (greenfield), don't pick a framework silently. Ask the user via the AskUserQuestion tool, with sensible defaults framed by the brief:
1. Confirmed design brief from `shape`.
2. Approved visual direction, from generated probes / mocks when image generation is available.
3. Mock fidelity inventory: the visible ingredients from the approved direction that must survive into code.
4. Semantic, functional implementation using the project's real stack and conventions.
5. Browser evidence across relevant viewports.
6. At least one critique-and-fix pass after the first browser inspection, unless the first pass has no material defects.
```text
What should this be built on?
- Astro (default for content-led brand sites, landing pages, marketing surfaces)
- SvelteKit / Next.js / Nuxt (when the brief implies an app surface or significant interactivity)
- Single index.html (one-shot demo, prototype, or a deliberately framework-free experiment)
```
Do not let generated mockups replace interface structure, copy, accessibility, responsive behavior, or state design. But do treat the approved mock as a concrete visual contract for composition, hierarchy, density, atmosphere, signature motifs, image needs, and distinctive visual moves. "North star" means "preserve the important visible ingredients in semantic code," not "use it as loose mood."
Default: Astro for brand briefs, the project's existing framework for product briefs. Ask once; don't re-ask mid-task.
## Step 1: Shape the Design
Run /impeccable shape, passing along whatever feature description the user provided.
Run /impeccable shape, passing along whatever feature description the user provided. Shape is **required** for craft; it is what produces a confirmed direction.
Wait for the design brief to be fully confirmed by the user before proceeding. The brief is your blueprint, and every implementation decision should trace back to it.
Present the shape output and stop. Wait for the user to confirm, override, or course-correct before writing code.
If this craft run resumed after `teach` created PRODUCT.md, run shape now. Do not treat the teach interview, PRODUCT.md, or a summary of project context as a substitute for shape. Shape is task-specific and must cover scope, content/states, visual direction, constraints, anti-goals, probes when applicable, and explicit brief confirmation.
If the user already supplied a confirmed brief or ran shape separately, use it and skip this step.
If the user has already run /impeccable shape and has a confirmed design brief, skip this step and use the existing brief.
When the original prompt + PRODUCT.md already answer scope, content, and visual direction with no real ambiguity, the shape output can be **compact** (3-5 bullets stating what you're building and the visual lane, ending with one or two specific questions or "confirm or override"). The full 10-section structured brief is reserved for genuinely ambiguous, multi-screen, or stakeholder-heavy tasks. Don't pad a clear brief into a long one to look thorough; equally, don't skip the pause to look efficient.
## Step 2: Load References
@@ -55,79 +53,60 @@ Then add references based on the brief's needs:
## Step 3: Land the Visual Direction (Capability-Gated)
Before implementation, generate high-fidelity visual comps when all of these are true:
Generate high-fidelity visual comps before implementation when all three are true:
- The work is **net-new** or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is **mid-fi, high-fi, or production-ready**.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The work is net-new or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is mid-fi, high-fi, or production-ready.
- The harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool). Don't ask the user to set up external APIs.
When those conditions are met, this step is mandatory for **both brand and product work** in Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
Do not skip this step because the eventual UI should be semantic, editable, code-native, responsive, or accessible. Those are implementation requirements, not reasons to avoid visual exploration.
### Purpose
Use the mock step to find a stronger visual lane than code-first generation would reliably discover on its own. The brief remains authoritative on user, purpose, content, constraints, states, and anti-goals. The mock clarifies composition, hierarchy, density, typography, and visual tone.
When met, this step is mandatory for both brand and product work. If image generation isn't available, skip silently. "The eventual UI is semantic/code-native/accessible" is not a reason to skip; those are implementation requirements, not exploration ones.
### What to generate
Generate **1 to 3** high-fidelity north-star comps based on the confirmed brief. If shape already produced direction probes, use those results as input and generate a more resolved mock from the winning lane, not another unrelated exploration.
Generate **1 to 3** high-fidelity north-star comps from the confirmed brief. If shape already produced direction probes, resolve the winning lane further, not an unrelated exploration. Comps must differ in primary visual direction, not just color.
- For brand work, push visual identity, composition, and mood aggressively.
- For product work, still push hierarchy, topology, density, and tone, but keep the comps grounded in realistic product structure and states.
- For landing pages and long-form brand surfaces, show enough of the next section or second fold to establish the system beyond the hero.
The comps must be genuinely different in primary visual direction, not just color variants.
- Brand work: push visual identity, composition, and mood aggressively.
- Product work: push hierarchy, topology, density, tone, grounded in realistic product structure.
- Landing pages and long-form brand surfaces: show enough of the second fold to establish the system beyond the hero.
### Approval loop
Show the comps and ask what should carry forward. If the user asks for changes or the best direction is still weak, generate a focused revision before implementation. Continue until one direction is approved, or until the user explicitly delegates the choice.
Show the comps and ask what carries forward. Iterate until one direction is approved or the user delegates. If the user delegates, pick the strongest direction and explain it from the brief, not personal taste.
If the user delegates, pick the strongest direction and explain the decision using the brief, not personal taste.
Before moving to implementation, summarize:
- What to carry into code
- What **not** to literalize from the mock
This summary is required before Step 4. It is the handoff between visual exploration and semantic implementation.
Before Step 4, summarize what to carry into code and what **not** to literalize from the mock. This is the handoff between visual exploration and semantic implementation.
### Mock fidelity inventory
Before building, inventory the approved mock's major visible ingredients:
Inventory the approved mock's major visible ingredients:
- Hero silhouette and dominant composition.
- Signature motifs: planets, devices, portraits, charts, route lines, insets, badges, or other memorable objects.
- Nav and primary CTA treatment.
- Section sequence visible in the mock, especially the second fold.
- Image-native content the concept depends on.
- Typography, density, color/material treatment, and motion cues.
- Hero silhouette and dominant composition
- Signature motifs (planets, devices, portraits, charts, route lines, insets, badges, etc.)
- Nav and primary CTA treatment
- Section sequence, especially the second fold
- Image-native content the concept depends on
- Typography, density, color/material treatment, motion cues
For each ingredient, decide how it will be implemented: semantic HTML/CSS/SVG, generated asset, sourced project asset, icon library, canvas/WebGL, or an explicitly accepted omission. Do not substitute a different hero composition or new visual driver after approval unless the user approves the change.
For each, decide implementation: semantic HTML/CSS/SVG, generated asset, sourced asset, icon library, canvas/WebGL, or accepted omission. Don't substitute a different hero composition or visual driver post-approval without user sign-off.
Treat the mock as a **north star**, not a screenshot to trace. Do **not** rasterize core UI text or let the mock override the confirmed brief. But if the live result lacks the mock's major visible ingredients, the implementation is wrong.
If a photographic, architectural, product, or place-led mock becomes generic CSS scenery / decorative diagrams / bullets / copy, stop and fix it. That's a broken implementation, not a harmless interpretation.
Treat the mock as a north star, not a screenshot to trace. Don't rasterize core UI text. But if the live result lacks the mock's major ingredients, the implementation is wrong.
## Step 4: Asset Extraction (Need-Gated)
If the chosen direction includes image-native visual ingredients that would materially improve the implementation, generate them as separate assets before building.
If the approved direction needs raster assets, create them before building. Do not replace required imagery with generic cards, bullets, emoji, fake metrics, decorative CSS panels, or filler copy.
Good candidates:
Use the native asset producer (`impeccable_asset_producer` in Codex, `impeccable-asset-producer` in Claude Code) to create clean assets from the hi-fi mock and crops. If you do not have explicit permission to use agents, stop and ask:
- stickers
- badges
- seals
- tickets
- graphic labels
- textures
- abstract objects
- decorative marks
- non-semantic scene elements
```text
Asset production will work better as a scoped subagent job. Should I spawn the Impeccable asset producer subagent for this step?
```
For travel, editorial, portfolio, venue, product showcase, entertainment, education, or any other image-led brand surface, visual assets are usually core content, not decoration. Do not ship abstract CSS panels where the approved mock or subject matter calls for real imagery, generated plates, illustrations, maps, product/object renders, or destination scenes.
Do not skip asset production or silently do it inline. Inline asset production is allowed only if the user declines subagents, the harness cannot spawn the authorized agent, or the user explicitly asks for single-thread mode.
Do **not** export assets for core UI text, navigation, body copy, or any structure that should stay semantic and editable in code.
Pass the approved mock, crop/contact-sheet paths, output directory, dimensions/formats, transparency needs, constraints, and avoid list to the asset producer. Attach image generation capability to the spawned agent when the harness supports it; do not load image-generation reference material into the parent thread first.
Usually **1 to 5** extracted assets is enough. If the design can be built cleanly in HTML/CSS/SVG, prefer that over raster assets. If the mock contains major visual content that cannot be built credibly in code, asset extraction is not optional.
Prefer HTML/CSS/SVG/canvas when they can credibly reproduce an ingredient; use real/generated/stock imagery when the mock or subject matter calls for actual visual content.
## Step 5: Build to Production Quality
@@ -135,50 +114,35 @@ Implement the feature following the design brief. Build in passes so structure,
### Production bar
- Use real or realistic content. Remove placeholder copy, placeholder images, dead links, fake controls, and unused scaffold before presenting.
- Preserve the approved mock's major ingredients. Missing hero objects, missing world/product imagery, different section structure, downgraded CTA/nav treatment, or generic replacements for distinctive motifs are blocking defects unless the user accepted the change.
- Build semantically first: real headings, landmarks, labels, form associations, button/link semantics, accessible names, and state announcements where needed.
- Calibrate spacing, alignment, grid placement, and vertical rhythm deliberately. Do not accept default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- Make typography intentional: chosen font loading strategy, clear hierarchy, readable measure, stable line breaks, tuned wrapping, and no overflow at mobile or large desktop sizes.
- Design realistic state coverage: default, hover where supported, focus-visible, active, disabled, loading, error, success, empty, overflow, long text, short text, and first-run states where relevant.
- Make interaction quality feel finished: keyboard paths, touch targets, feedback timing, scroll behavior, transitions between states, and no hover-only functionality.
- Use icons from the project's established icon set when available. If no set exists, choose a coherent library or use accessible text controls; do not mix unrelated icon styles.
- Optimize imagery and media: correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset` / `picture` for raster assets, and no project-referenced asset left outside the workspace.
- Make motion feel premium: use atmospheric blur, filter, mask, shadow, or reveal effects when they improve the experience; avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- Preserve maintainability: reusable local patterns, clear component boundaries, project conventions, no rasterized UI text, and no hard-coded one-off hacks when a better local pattern exists.
- Fit the technical context: production build passes, no obvious console errors, no avoidable layout shift, no needless dependency, and no broken asset path.
- If you discover a design question that materially changes the brief or approved direction, stop and ask rather than guessing.
- **Real content.** No placeholder copy, placeholder images, dead links, fake controls, or unused scaffold at presentation time.
- **Preserve the approved mock's major ingredients.** Missing hero objects, world/product imagery, section structure, CTA/nav treatment, or distinctive motifs are blocking defects unless the user accepted the change.
- **Semantic first.** Real headings, landmarks, labels, form associations, button/link semantics, accessible names, state announcements where needed.
- **Deliberate spacing and alignment.** No default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- **Intentional typography.** Chosen loading strategy, clear hierarchy, readable measure, stable line breaks, no overflow at any width.
- **Realistic state coverage.** Default, hover, focus-visible, active, disabled, loading, error, success, empty, overflow, long/short text, first-run.
- **Finished interaction quality.** Keyboard paths, touch targets, feedback timing, scroll behavior, state transitions, no hover-only functionality.
- **Coherent icon set.** Use the project's established set; otherwise pick one library or use accessible text. Don't mix.
- **Respect the build pipeline.** Edit source files and run the project's build (`npm run build` or equivalent). Don't write to `build/` / `dist/` / `.next/` with `cat`, heredoc, or Bash redirects; that skips asset hashing, image optimization, code splitting, and CSS extraction, and produces output the dev server won't serve.
- **Verify image URLs before referencing them.** Use image-search MCP or web-fetch when available; guessed photo IDs ship as broken-image placeholders. Without verification, prefer fewer images you're confident about.
- **Optimized imagery and media.** Correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset`/`picture` for raster, no project-referenced asset left outside the workspace.
- **Premium motion.** Use atmospheric blur, filter, mask, shadow, reveal when they improve the experience. Avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- **Maintainable.** Reusable local patterns, clear component boundaries, project conventions. No rasterized UI text or one-off hacks when a local pattern exists.
- **Technically clean.** Production build passes, no console errors, no avoidable layout shift, no needless dependencies, no broken asset paths.
- **Ask when uncertain.** If a discovery materially changes the brief or approved direction, stop and ask. Don't guess.
## Step 6: Browser-Based Iteration
## Step 6: Iterate Visually
**This step is critical.** Do not stop after the first implementation pass.
Look at what you built like a designer would. Your eyes are whatever the harness gives you: a connected browser, a screenshotting tool, Playwright, or asking the user. Use them for responsive testing (mobile, tablet, desktop minimum) and general visual validation.
Open the result in a browser. In Codex, use browser-use or equivalent browser automation when available; otherwise use Playwright or ask the user for screenshots. Inspect screenshots, not just DOM or terminal output.
If your tool returns a file path, read the PNG back into the conversation. A screenshot you didn't read doesn't count.
### Required viewport pass
For long-form brand surfaces, inspect major sections individually. Thumbnails hide spacing, clipping, and cascade defects.
Check the experience at the viewports that matter for the brief. Default minimum:
After the first pass, write an honest critique against the brief, the approved mock's major ingredients (hero silhouette, motifs, imagery, nav/CTA, density), and impeccable's DON'Ts. Patch material defects and re-inspect. **Don't invent defects to demonstrate iteration.** A confident "first pass clean, shipping" beats a fake fix.
- Mobile narrow
- Tablet or small laptop
- Desktop wide
Actively check: responsive behavior (composes, not shrinks), every state (empty / error / loading / edge), craft details (spacing, alignment, hierarchy, contrast, motion timing, focus), performance basics. The exit bar: defensible in a high-end studio review.
For each viewport, capture or inspect the rendered state and look for visual defects: overlap, clipping, weak hierarchy, off-grid alignment, awkward whitespace, cramped controls, unreadable type, broken imagery, hover-only functionality, layout shift, and text overflow.
### Critique and fix loop
After the first browser pass, write a short critique for yourself and patch the implementation. Repeat browser inspection after fixes. Continue until no material issues remain against this checklist:
1. **Does it match the brief?** Compare the live result against every section of the design brief. Fix discrepancies.
2. **Does it match the approved mock?** Compare screenshots against the mock fidelity inventory: hero silhouette, major motifs, imagery, nav/CTA, section sequence, density, color/materials, and second-fold substance. Missing major ingredients are P0 defects.
3. **Does it pass the AI slop test?** If someone saw this and said "AI made this," would they believe it immediately? If yes, it needs more design intention.
4. **Check against impeccable's DON'T guidelines.** Fix any anti-pattern violations.
5. **Check every state.** Navigate through empty, error, loading, and edge case states. Each one should feel intentional, not like an afterthought.
6. **Check responsive behavior.** The design should adapt compositionally, not merely shrink.
7. **Check craft details.** Spacing consistency, optical alignment, type hierarchy, color contrast, image quality, icon coherence, interactive feedback, motion timing, and focus treatment.
8. **Check performance basics.** No obviously oversized images, avoidable layout thrash, blocking animations, or heavy assets without a reason.
The exit bar is not "it works." It is: the rendered result looks intentional at all checked viewports, all expected states are handled, no placeholders remain unless explicitly accepted, and the implementation quality would be defensible in a high-end studio review.
Detector or QA output is defect evidence only; never proof the work is finished.
## Step 7: Present
@@ -189,5 +153,3 @@ Present the result to the user:
- Explain design decisions that connect back to the design brief and, when used, the chosen north-star mock. Include any accepted deviations from the mock; do not hide unimplemented mock ingredients.
- Note any remaining limitations or follow-up risks honestly
- Ask: "What's working? What isn't?"
Iterate based on feedback. Good design is rarely right on the first pass.
@@ -43,7 +43,7 @@ Run the bundled deterministic detector, which flags 27 specific patterns (AI slo
**CLI scan**:
```bash
npx impeccable --json [--fast] [target]
npx impeccable detect --json [--fast] [target]
```
- Pass HTML/JSX/TSX/Vue/Svelte files or directories as `[target]` (anything with markup). Do not pass CSS-only files.
+8 -6
View File
@@ -2,6 +2,8 @@
Perform a meticulous final pass to catch all the small details that separate good work from great work. The difference between shipped and polished.
Detector and automated QA output are defect evidence only. A clean script result is never proof that the design is strong; gather browser evidence and inspect the real interaction path.
## Design System Discovery
Aligning the feature to the design system is **not optional**. Polish without alignment is decoration on top of drift, and it makes the next person's job harder. Discovery comes before any other polish work.
@@ -216,11 +218,12 @@ Sweat the details. Zoom in until the alignment is right and the spacing reads as
Before marking as done:
- **Use it yourself**: Actually interact with the feature
- **Test on real devices**: Not just browser DevTools
- **Ask someone else to review**: Fresh eyes catch things
- **Compare to design**: Match intended design
- **Check all states**: Don't just test happy path
- **Use it yourself**: Actually interact with the feature.
- **Test on real devices**: Not just browser DevTools.
- **Ask someone else to review**: Fresh eyes catch things.
- **Compare to design**: Match intended design.
- **Check all states**: Don't just test happy path.
- **Treat automation carefully**: Run detector or QA commands when they are available and relevant, fix their defects, but never cite a clean result as proof that the work is polished.
## Clean Up
@@ -230,4 +233,3 @@ After polishing, ensure code quality:
- **Remove orphaned code**: Delete unused styles, components, or files made obsolete by polish.
- **Consolidate tokens**: If you introduced new values, check whether they should be tokens.
- **Verify DRYness**: Look for duplication introduced during polishing and consolidate.
+25 -11
View File
@@ -16,14 +16,16 @@ This is a required interaction, not optional guidance. Ask these questions in co
### Interview cadence
Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed design inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
Discovery includes at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
- Use the harness's structured question tool when one exists. Otherwise, ask directly in chat and stop.
- Ask **2-3 questions per round**, then wait for answers.
- Treat PRODUCT.md and DESIGN.md as anchors; they reduce repeated questions but do **not** replace shape for craft. Shape is task-specific.
- Round 1 should clarify purpose, audience/context, and success or emotional outcome.
- Round 2 should clarify content/data/states and scope/fidelity.
- Round 3 should clarify visual direction, constraints, and anti-goals when still unresolved.
- One round is the default. Add a second only if the first answers leave material gaps. Don't run a second round just to feel thorough.
- Round 1 should clarify purpose, audience/context, content/scope, and (for brand) visual direction.
- Round 2, when needed, fills in whatever's still genuinely missing.
**Assert-then-confirm, not menu-with-escape.** When PRODUCT.md and the user's prompt make one option obvious, name it and ask the user to confirm or override. Don't enumerate "Restrained / Committed / Or something else?" as a real choice; "This reads as Restrained, confirm?" beats a four-option menu when the answer is already clear.
### Purpose & Context
- What is this feature for? What problem does it solve?
@@ -36,6 +38,7 @@ Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.
- What are the realistic ranges? (Minimum, typical, maximum, e.g., 0 items, 5 items, 500 items)
- What are the edge cases? (Empty state, error state, first-time use, power user)
- Is any content dynamic? What changes and how often?
- What visual assets are real content here? Note required images, product shots, illustrations, maps, textures, diagrams, generated objects, or existing project assets.
### Design Direction
@@ -72,9 +75,9 @@ After the discovery interview, generate a small set of visual direction probes *
- The work is **net-new** or directionally ambiguous enough that visual exploration will clarify the brief.
- The requested fidelity is **mid-fi, high-fi, or production-ready**. Skip for sketch-only planning.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The current harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool, or similar). Don't ask the user to install APIs or tooling.
When those conditions are met, this step is mandatory for Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
When those conditions are met, this step is mandatory. If image generation isn't natively available, skip silently and proceed; don't announce the skip.
Use probes to explore visual lanes, not to replace the brief.
@@ -104,11 +107,20 @@ The probes should differ in primary visual direction (hierarchy, topology, densi
- Do **not** treat generated imagery as final UX specification, final copy, or final accessibility behavior.
- Do **not** use this step for minor refinements of existing work. It's for shaping a new surface or clarifying a big directional choice.
If image generation is unavailable, or the task doesn't benefit from it, skip this phase only with a one-line reason and proceed directly to the design brief.
If image generation isn't natively available, skip this phase silently and proceed.
## Phase 2: Design Brief
After the interview and any required probes, synthesize everything into a structured design brief. Present it to the user for explicit confirmation before considering this command complete. Stop after asking for confirmation; do not proceed to craft or implementation in the same response unless the user has already approved the brief.
After the interview and any required probes, present a brief and **end your response**. The user must confirm before any implementation runs. Do not present a brief and then continue to code in the same response, even if the brief feels obvious to you. The user's confirmation is the gate.
**Choose the brief shape based on how clear the answers are:**
- **Compact form (3-5 bullets)** when discovery was crisp and the original prompt + PRODUCT.md already pinned scope, content, and direction. State what you're building, the visual lane, and end with one or two specific questions or a clear "confirm or override?" prompt. This is the default for typical craft requests with a clear prompt.
- **Full structured form (sections below)** when the task is genuinely ambiguous, multi-screen, or when the user asked for shape as a standalone step. Use this when the discipline of structure earns its weight.
Don't pad a clear brief into a long one to look thorough. A 70-line brief restating answers the user just gave is noise, not rigor. Equally, don't skip the confirmation pause to look efficient: the pause is the point.
If the user already said "approved" or "go" during discovery for the *exact direction you'd present*, that counts as confirmation; you may proceed without asking again. But if your brief adds anything the user hasn't seen and approved, you must stop and confirm.
### Brief Structure
@@ -136,16 +148,18 @@ List every state the feature needs: default, empty, loading, error, success, edg
How users interact with this feature. What happens on click, hover, scroll? What feedback do they get? What's the flow from entry to completion?
**8. Content Requirements**
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges.
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges. For image-led surfaces, also list the required image/media roles and their likely source (project asset, generated raster, semantic SVG/CSS, canvas/WebGL, icon library, or accepted omission).
**9. Recommended References**
Based on the brief, list which impeccable reference files would be most valuable during implementation (e.g., spatial-design.md for complex layouts, motion-design.md for animated features, interaction-design.md for form-heavy features).
**10. Open Questions**
Anything unresolved that the implementer should resolve during build.
Anything genuinely unresolved. Don't list "open questions" you've already recommended a default for; assert the default and move on. If you'd write `Recommend: X` next to a question, just decide X.
---
STOP and call the AskUserQuestion tool to clarify. Ask for explicit confirmation of the brief before finishing. If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the brief is confirmed.
STOP and call the AskUserQuestion tool to clarify.
If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the user confirms direction (or the user already gave a clear go during discovery, which counts).
Once confirmed, the brief is complete. The user can now hand it to /impeccable, or use it to guide any other implementation approach. (If the user wants the full discovery-then-build flow in one step, they should use /impeccable craft instead, which runs this command internally.)
+35 -3
View File
@@ -95,9 +95,11 @@ function generateCounts(rootDir, skills, buildDir) {
}
}
// Check for stale detection counts
// Check for stale detection counts. Use the changelog-stripped content
// so historical counts in changelog entries (e.g. "28 rules" from an
// older release) don't flag against the current detector total.
const detectPattern = /\b(\d+)\s+(deterministic\s+)?(checks|patterns|rules|detections)/gi;
for (const match of content.matchAll(detectPattern)) {
for (const match of strippedContent.matchAll(detectPattern)) {
const num = parseInt(match[1]);
if (num !== detectionCount && num > 10) { // ignore small numbers like "3 patterns"
console.error(`${relPath}: found "${match[0]}" but detection count is ${detectionCount}`);
@@ -390,7 +392,7 @@ This folder contains skills for all supported tools:
.cursor/ -> Cursor
.claude/ -> Claude Code
.gemini/ -> Gemini CLI
.codex/ -> Legacy bundle folder in this ZIP (Codex CLI uses .agents/)
.codex/ -> Codex custom agents (Codex skills use .agents/)
.agents/ -> Codex CLI
.github/ -> GitHub Copilot
.kiro/ -> Kiro
@@ -662,6 +664,18 @@ async function build() {
}
}
for (const { provider, configDir, agentFormat } of Object.values(PROVIDERS)) {
if (!agentFormat) continue;
const agentsSrc = path.join(DIST_DIR, provider, configDir, 'agents');
const agentsDest = path.join(ROOT_DIR, configDir, 'agents');
if (fs.existsSync(agentsDest)) fs.rmSync(agentsDest, { recursive: true, force: true });
if (fs.existsSync(agentsSrc)) {
copyDirSync(agentsSrc, agentsDest);
}
}
// Remove deprecated skill stubs from local harness dirs. They exist
// in dist/ so the cleanup script can redirect users, but they should
// not clutter the repo's own skill directories.
@@ -691,15 +705,29 @@ async function build() {
const pluginRoot = path.join(ROOT_DIR, 'plugin');
const pluginManifestDir = path.join(pluginRoot, '.claude-plugin');
const pluginSkillsDir = path.join(pluginRoot, 'skills');
const pluginAgentsDir = path.join(pluginRoot, 'agents');
if (fs.existsSync(pluginManifestDir)) fs.rmSync(pluginManifestDir, { recursive: true });
if (fs.existsSync(pluginSkillsDir)) fs.rmSync(pluginSkillsDir, { recursive: true });
if (fs.existsSync(pluginAgentsDir)) fs.rmSync(pluginAgentsDir, { recursive: true });
const rootManifest = JSON.parse(fs.readFileSync(path.join(ROOT_DIR, '.claude-plugin/plugin.json'), 'utf-8'));
const claudeAgentsSrc = path.join(DIST_DIR, 'claude-code', '.claude', 'agents');
const pluginAgentEntries = fs.existsSync(claudeAgentsSrc)
? fs.readdirSync(claudeAgentsSrc)
.filter(file => file.endsWith('.md'))
.sort()
.map(file => `./agents/${file}`)
: [];
// Trailing slash on the skills path matches the documented schema in
// code.claude.com/docs/en/plugins-reference. Issue #86 has 3 reporters
// converging on "add trailing slash to fix slash commands not registering";
// the docs schema example consistently uses `"./custom/skills/"` form.
const pluginManifest = { ...rootManifest, skills: './skills/' };
if (pluginAgentEntries.length) {
pluginManifest.agents = pluginAgentEntries;
} else {
delete pluginManifest.agents;
}
fs.mkdirSync(pluginManifestDir, { recursive: true });
fs.writeFileSync(
path.join(pluginManifestDir, 'plugin.json'),
@@ -712,6 +740,10 @@ async function build() {
copyDirSync(claudeSkillsSrc, path.join(pluginSkillsDir, 'impeccable'));
}
if (fs.existsSync(claudeAgentsSrc)) {
copyDirSync(claudeAgentsSrc, pluginAgentsDir);
}
console.log('📦 Built Claude Code plugin subtree at ./plugin/');
// Generate authoritative counts and validate references
+86 -1
View File
@@ -65,6 +65,72 @@ function buildOpenAIMetadata(skill) {
};
}
function formatTomlString(value) {
return JSON.stringify(String(value));
}
function formatTomlMultiline(value) {
const normalized = String(value).trim().replace(/\r\n/g, '\n');
if (!normalized.includes("'''")) {
return `'''\n${normalized}\n'''`;
}
return `"""\n${normalized.replace(/\\/g, '\\\\').replace(/"""/g, '\\"""')}\n"""`;
}
function formatTomlArray(values) {
return `[${values.map(formatTomlString).join(', ')}]`;
}
function buildCodexAgent(agent, body) {
const lines = [
`name = ${formatTomlString(agent.codexName || agent.name.replace(/-/g, '_'))}`,
`description = ${formatTomlString(agent.description)}`,
];
if (agent.effort) {
lines.push(`model_reasoning_effort = ${formatTomlString(agent.effort)}`);
}
if (agent.nicknameCandidates?.length) {
lines.push(`nickname_candidates = ${formatTomlArray(agent.nicknameCandidates)}`);
}
lines.push(`developer_instructions = ${formatTomlMultiline(body)}`);
return `${lines.join('\n')}\n`;
}
function buildClaudeAgent(agent, body) {
const frontmatter = {
name: agent.claudeName || agent.name,
description: agent.description,
};
if (agent.tools) frontmatter.tools = agent.tools;
if (agent.model) frontmatter.model = agent.model;
if (agent.effort) frontmatter.effort = agent.effort;
if (agent.maxTurns) frontmatter.maxTurns = agent.maxTurns;
return `${generateYamlFrontmatter(frontmatter)}\n${body.trim()}\n`;
}
function buildAgentFile(config, agent, body) {
if (config.agentFormat === 'codex-toml') {
return {
filename: `${agent.codexName || agent.name.replace(/-/g, '_')}.toml`,
content: buildCodexAgent(agent, body),
};
}
if (config.agentFormat === 'claude-md') {
return {
filename: `${agent.claudeName || agent.name}.md`,
content: buildClaudeAgent(agent, body),
};
}
return null;
}
/**
* Create a transformer function for a given provider config.
*
@@ -94,6 +160,7 @@ export function createTransformer(config) {
let refCount = 0;
let scriptCount = 0;
let agentCount = 0;
for (const skill of skills) {
const skillName = skill.name;
@@ -171,9 +238,27 @@ export function createTransformer(config) {
}
}
if (config.agentFormat) {
const agentsDir = path.join(providerDir, `${configDir}/agents`);
for (const skill of skills) {
for (const agent of skill.agents || []) {
// Agents can declare `providers: <list>` to limit which harnesses
// they emit to. Default (no field) ships everywhere with agentFormat.
if (agent.providers && !agent.providers.includes(provider)) continue;
const body = replacePlaceholders(agent.body, placeholderKey, [], allSkillNames);
const agentFile = buildAgentFile(config, agent, body);
if (!agentFile) continue;
ensureDir(agentsDir);
writeFile(path.join(agentsDir, agentFile.filename), agentFile.content);
agentCount++;
}
}
}
const skillWord = skills.length === 1 ? 'skill' : 'skills';
const refInfo = refCount > 0 ? ` (${refCount} reference files)` : '';
const scriptInfo = scriptCount > 0 ? ` (${scriptCount} script files)` : '';
console.log(` ${displayName}: ${skills.length} ${skillWord}${refInfo}${scriptInfo}`);
const agentInfo = agentCount > 0 ? ` (${agentCount} agent files)` : '';
console.log(`${displayName}: ${skills.length} ${skillWord}${refInfo}${scriptInfo}${agentInfo}`);
};
}
+2
View File
@@ -20,6 +20,7 @@ export const PROVIDERS = {
configDir: '.claude',
displayName: 'Claude Code',
frontmatterFields: ['user-invocable', 'argument-hint', 'license', 'compatibility', 'metadata', 'allowed-tools'],
agentFormat: 'claude-md',
},
gemini: {
provider: 'gemini',
@@ -34,6 +35,7 @@ export const PROVIDERS = {
frontmatterFields: [],
includeVersion: false,
writeOpenAIMetadata: true,
agentFormat: 'codex-toml',
},
agents: {
provider: 'agents',
+35 -1
View File
@@ -203,6 +203,39 @@ export function readSourceFiles(rootDir) {
}
}
const agents = [];
const agentsDir = path.join(skillDir, 'agents');
if (fs.existsSync(agentsDir)) {
const agentFiles = fs.readdirSync(agentsDir).filter(f => f.endsWith('.md'));
for (const agentFile of agentFiles) {
const agentPath = path.join(agentsDir, agentFile);
const agentContent = fs.readFileSync(agentPath, 'utf-8');
const { frontmatter: agentFrontmatter, body: agentBody } = parseFrontmatter(agentContent);
const name = agentFrontmatter.name || path.basename(agentFile, '.md');
const providersRaw = agentFrontmatter.providers;
let providers = null;
if (Array.isArray(providersRaw)) {
providers = providersRaw.map(p => String(p).trim()).filter(Boolean);
} else if (typeof providersRaw === 'string' && providersRaw.trim()) {
providers = providersRaw.split(',').map(p => p.trim()).filter(Boolean);
}
agents.push({
name,
codexName: agentFrontmatter['codex-name'] || name.replace(/-/g, '_'),
claudeName: agentFrontmatter['claude-name'] || name,
description: agentFrontmatter.description || '',
tools: agentFrontmatter.tools || '',
model: agentFrontmatter.model || '',
effort: agentFrontmatter.effort || '',
maxTurns: agentFrontmatter['max-turns'] ? Number(agentFrontmatter['max-turns']) : '',
nicknameCandidates: agentFrontmatter['nickname-candidates'] || [],
providers,
body: agentBody,
filePath: agentPath,
});
}
}
skills.push({
name: frontmatter.name || 'impeccable',
description: frontmatter.description || '',
@@ -216,7 +249,8 @@ export function readSourceFiles(rootDir) {
body,
filePath: skillMdPath,
references,
scripts
scripts,
agents
});
return { skills };
+4 -4
View File
@@ -491,7 +491,7 @@ import '../styles/sub-pages.css';
<article class="why-panel" id="why-panel-6" role="tabpanel" data-index="6" hidden>
<h3 class="why-panel-title">Block AI slop before it ships.</h3>
<p class="why-panel-body">Run <code>npx impeccable detect src/</code> on a PR branch and get JSON output with every purple gradient, nested card, low-contrast label, and gradient-text heading caught. Fail the build on severity. 27 deterministic checks, no LLM required, no API key, no flaky scoring. Gate your PRs the same way you gate lint and types.</p>
<p class="why-panel-body">Run <code>npx impeccable detect src/</code> on a PR branch and get JSON output with every purple gradient, nested card, low-contrast label, and gradient-text heading caught. Fail the build on severity. 29 deterministic checks, no LLM required, no API key, no flaky scoring. Gate your PRs the same way you gate lint and types.</p>
<div class="why-visual why-visual--ci">
<div class="why-ci-window">
<div class="why-ci-header">
@@ -507,7 +507,7 @@ import '../styles/sub-pages.css';
</div>
</div>
</div>
<p class="why-panel-meta">27 rules &middot; <code>--json</code> &middot; <code>--fast</code> &middot; exit codes for CI.</p>
<p class="why-panel-meta">29 rules &middot; <code>--json</code> &middot; <code>--fast</code> &middot; exit codes for CI.</p>
</article>
<article class="why-panel" id="why-panel-7" role="tabpanel" data-index="7" hidden>
@@ -834,7 +834,7 @@ import '../styles/sub-pages.css';
<svg class="install-step-arrow" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M9 6l6 6-6 6"/></svg>
</summary>
<div class="install-step-body">
<p class="install-path-desc">Run anti-pattern scans outside the skill: in CI, in a PR check, or against a whole directory. 27 deterministic rules, no LLM required, JSON output ready for build gates.</p>
<p class="install-path-desc">Run anti-pattern scans outside the skill: in CI, in a PR check, or against a whole directory. 29 deterministic rules, no LLM required, JSON output ready for build gates.</p>
<div class="install-cmd-block">
<div class="install-cmd-line">
@@ -1062,7 +1062,7 @@ import '../styles/sub-pages.css';
<ul class="changelog-items">
<li><strong>Renamed <code>frontend-design</code> to <code>impeccable</code>.</strong> The core skill now shares its name with the project, and the teach subcommand moved from <code>/teach-impeccable</code> to <code>/impeccable teach</code>. One skill, one namespace.</li>
<li><strong>Skill rewritten against evals.</strong> Fifteen briefs ran through gpt-5.4 and Qwen 3.6 Plus, with and without the skill loaded, then graded side by side. More font and color variety, fewer purple gradients, much better Codex output. The single change that moved the numbers most: before the model commits to a font or palette, it has to name its first three instincts and reject them.</li>
<li><strong>Anti-pattern detection engine.</strong> 27 deterministic rules across typography, color, layout, motion, and quality. Handles oklch, oklab, lch, and lab color formats, CSS variables inside border shorthands, gradient-backed text, and emoji-only nodes.</li>
<li><strong>Anti-pattern detection engine.</strong> 28 deterministic rules across typography, color, layout, motion, and quality. Handles oklch, oklab, lch, and lab color formats, CSS variables inside border shorthands, gradient-backed text, and emoji-only nodes.</li>
<li><strong>CLI: <code>npx impeccable detect</code>.</strong> Scans HTML, CSS, JSX/TSX, Vue, Svelte, and CSS-in-JS. Framework detection, multi-file import tracking, Puppeteer-backed live URL scanning, CI-ready JSON output, and a <code>--fast</code> regex mode for huge codebases.</li>
<li><strong>Chrome DevTools extension.</strong> One-click detection on any page: yours, staging, production, or someone else's. Reads live computed styles, surfaces findings in an interactive panel, and highlights elements on the page. In Chrome Web Store review.</li>
<li><strong><code>/critique</code> got teeth.</strong> Persona sub-agents review in parallel, score against Nielsen's heuristics, run the detector automatically, and open a live browser overlay so you can walk each finding in place.</li>
+6 -19
View File
@@ -10,28 +10,15 @@ license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md f
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
## Setup (non-optional)
## Setup
Before any design work or file edits, pass these gates. Skipping them produces generic output that ignores the project.
Before any design work or file edits:
| Gate | Required check | If fail |
|---|---|---|
| Context | The PRODUCT.md / DESIGN.md loader result is known from `node {{scripts_path}}/load-context.mjs`. | Run the loader before continuing. |
| Product | PRODUCT.md exists and is not empty or placeholder (`[TODO]` markers, <200 chars). | Run `{{command_prefix}}impeccable teach`, refresh context, then resume. Never synthesize PRODUCT.md from the user's original prompt alone. |
| Command | The matching command reference is loaded when a sub-command is used. | Load the reference before continuing. |
| Craft | `{{command_prefix}}impeccable craft` has a user-confirmed shape brief for this task. `teach` / PRODUCT.md never counts as shape. | Run `{{command_prefix}}impeccable shape` and wait for explicit brief confirmation. |
| Image | Required visual probes / mocks are generated or skipped with a reason. | Resolve the image-generation gate in `shape.md` or `craft.md` before code. |
| Mutation | All active gates above pass. | Do not edit project files yet. |
1. Load context (PRODUCT.md / DESIGN.md) via the loader script.
2. Identify the register and load the matching register reference (brand.md or product.md).
3. **If the user invoked a sub-command (e.g. `craft`, `shape`, `audit`), load its reference file too.** This is non-negotiable: `craft` without `craft.md` loaded means you'll skip the shape-and-confirm step the user expects.
Codex-style agents must state this before editing files:
```text
IMPECCABLE_PREFLIGHT: context=pass product=pass command_reference=pass shape=pass|not_required image_gate=pass|skipped:<reason> mutation=open
```
For `{{command_prefix}}impeccable craft`, `shape=pass` is only valid after a separate user response approving the shape design brief, or when the user provided an already-confirmed brief in the request. Do not mark `shape=pass` after writing PRODUCT.md, summarizing assumptions, or drafting an unconfirmed brief yourself.
Other harnesses should follow the same checklist when they can expose this state.
Skipping these produces generic output that ignores the project.
### 1. Context gathering
+101
View File
@@ -0,0 +1,101 @@
---
name: impeccable-asset-producer
codex-name: impeccable_asset_producer
description: Produces clean reusable raster assets from approved Impeccable mock references without redesigning the direction.
tools: Read, Write, Edit, Bash, Glob, Grep
model: inherit
effort: medium
max-turns: 12
providers: codex
nickname-candidates:
- Asset Plate
- Clean Plate
- Crop Cutter
---
# Impeccable Asset Producer
You are the asset production agent for Impeccable craft.
Your job is production cleanup, not new art direction. Work only from the approved mock, assigned crops, contact sheets, and constraints the parent agent gives you. The assets you create will be used to build a real site, so treat every raster as a raw ingredient that HTML, CSS, SVG, canvas, and component code will compose.
## Core Rule
Do not redesign. Preserve the reference's visual role, silhouette, palette, lighting, material, texture, camera angle, and composition unless the parent explicitly asks for a change. Preserve perspective only when it belongs to the object or scene itself; if CSS should create the card transform, shadow, rounded clipping, border, or layout, remove that presentation chrome from the raster.
## Input Contract
Expect:
- Approved mock path or screenshot reference.
- Crop paths or a contact sheet with crop ids.
- Output directory.
- Required dimensions, format, transparency needs, and avoid list.
- Notes on what should remain semantic HTML/CSS/SVG instead of raster.
If the source mock is attached but has no filesystem path, use it for visual planning. Ask for a path only before cropping or writing assets.
Use defaults unless contradicted:
- `.webp` for opaque photos, backgrounds, and textures.
- `.png` for transparent cutouts, seals, tickets, and illustrations.
- Target production size or at least 2x display size when dimensions are known. Do not use small full-page mock crop size as the default shipping size.
- Remove UI text, navigation, buttons, labels, and body copy by default.
- Keep physical marks only when the parent says they are part of the asset.
- Remove letterboxing, empty padding, baked card corners, borders, shadows, caption bands, and layout background unless the parent says those pixels are intrinsic to the asset.
- Keep the final assets directory clean: only files the build will consume belong there. Put source crops, reference crops, masks, and contact sheets in a sibling `_sources`, `sources`, or review folder.
Ask blockers once, globally. Missing source path/crops or output directory blocks production. Exact dimensions, compression targets, retina variants, and format preferences do not block; choose defaults and report them.
## Workflow
1. Inventory the full approved mock or every assigned crop.
2. Put each visual role in exactly one bucket:
- `produce`: needs generation, image editing, cleanup, cutout work, or a clean plate before it can ship.
- `direct`: can ship as a crop, format conversion, compression pass, or sourced replacement with no generative cleanup.
- `semantic`: build in HTML/CSS/SVG/canvas, no raster output.
3. Treat full-page mock crops as references, not production-resolution source assets. Put a role in `direct` only when the provided source is already a clean, sufficiently large source asset with no semantic text or presentation chrome.
4. Give the parent an execution order for the `produce` bucket.
5. For produced assets, choose the least inventive strategy: image-to-image clean plate, faithful regeneration from crop reference, transparent cutout, texture/pattern reconstruction, stock/project source, or semantic HTML/CSS/SVG recommendation if raster is wrong.
6. Treat every crop as binding reference. In Codex, use the imagegen skill and built-in `image_gen` path by default when generation or editing is needed.
7. Remove baked-in UI text, navigation, buttons, body copy, and mock chrome unless the text is part of the asset.
8. Think through the final DOM/CSS representation before generating. If CSS will own radius, clipping, shadows, borders, perspective, responsive cropping, captions, or card frames, do not bake those into the bitmap.
9. Save outputs non-destructively in the requested project directory.
10. Compare each output against its source crop. If a review/QA tool is available, run it before the final manifest, then retry each major/fatal finding once before finalizing.
Use `direct` only for provided source assets that can already ship after crop tightening, conversion, compression, or naming. Do not ship a small crop from the full-page mock as `direct` just because it looks close.
Use `texture/pattern extraction` only when the source region is already clean enough to sample as texture. If UI, cards, labels, headings, body copy, or footer chrome must be removed to make a reusable texture or background, classify it as crop-derived cleanup or clean-plate work.
Use `semantic` for dashboards, charts, controls, screenshots of whole UI sections, data widgets, card chrome, app frames, icon toolbars, logos, wordmarks, and anything the final implementation can render crisply in HTML/CSS/SVG/canvas. Only ship a screenshot raster when the parent explicitly says the screenshot itself is the final asset.
Semantic does not mean ignored. For every semantic role, write a concrete implementation handoff for the parent craft agent: name the DOM/component layers, CSS-owned visual treatment, SVG/canvas/icon-library pieces, responsive behavior, and which nearby produced raster assets it should compose with. For logos and icons, prefer inline SVG/vector or icon-library implementation unless the parent provides a production logo raster.
For transparency, prefer true alpha output when the tool supports it. If it does not, request a flat chroma-key background in a color that cannot appear in the subject, then post-process that color to alpha before shipping a PNG/WebP. Do not ship the keyed background as the final asset.
## Prompt Pattern
Use this shape for image-to-image work:
```text
Use the provided crop as the approved visual reference.
Recreate the same asset as a clean reusable production image at the target component aspect ratio and at least 2x display resolution.
Preserve silhouette, object/scene perspective, camera angle, palette, lighting, material, texture, and visual role.
Remove baked-in UI copy, navigation, buttons, labels, body text, watermarks, and mock chrome unless explicitly part of the asset.
Remove letterboxing, padding, card borders, rounded clipping, CSS shadows, perspective transforms, caption bands, and layout backgrounds that the implementation should create in code.
Do not add new objects. Do not change the concept. Do not redesign the composition.
```
For transparent cutouts, use the imagegen skill's built-in-first chroma-key workflow unless the parent explicitly authorizes a true native transparency fallback.
## Output Contract
Return a complete manifest, grouped by `produce`, `direct`, and `semantic`. For each asset include: `id`, `source_crop`, `output_path` when applicable, `strategy`, `prompt_used` when applicable, `dimensions`, `format`, `transparency`, `deviations`, and `qa_status`.
For each semantic row include `id`, `implementation`, `notes`, and `qa_status`. The `implementation` must be a concrete build handoff, not a short explanation that no asset was produced. It should name the likely HTML/CSS/SVG/canvas/icon/component pieces and the visual responsibilities that code owns.
`qa_status` must be `accepted`, `needs_parent_review`, or `blocked`. Use `accepted` only after visual comparison passes. Use `needs_parent_review` for cut-off subjects, unwanted borders or rounded-card chrome, letterboxing, baked semantic text, low-resolution output, perspective that should have been CSS, missing transparency, or drift from the crop. Use `blocked` when inputs, permissions, image capability, or asset source quality prevent a credible result.
End with `execution_order`, `blockers`, and `assumptions` sections. Keep blockers global and minimal. Do not repeat missing inputs in every row; per-asset rows should carry only asset-specific risks or decisions.
Do not modify implementation code. Do not edit the approved mock. Do not produce final page copy. The parent craft agent owns implementation and final mock fidelity.
+7 -3
View File
@@ -12,6 +12,8 @@ Brand isn't a neutral register. AI-generated landing pages have flooded the inte
**The second slop test: aesthetic lane.** Before committing to moves, name the reference. A Klim-style specimen page is one lane; Stripe-minimal is another; Liquid-Death-acid-maximalism is another. Don't drift into editorial-magazine aesthetics on a brief that isn't editorial. A hiking brand with Cormorant italic drop caps has the wrong register within the register.
Then the inverse test: in one sentence, describe what you're about to build the way a competitor would describe theirs. If that sentence fits the modal landing page in the category, restart.
## Typography
### Font selection procedure
@@ -66,6 +68,7 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
- Palette IS voice. A calm brand and a restless brand should not share palette mechanics.
- When the strategy is Committed or Drenched, color carries the brand. Don't hedge with neutrals around the edges. Commit.
- Don't converge across projects. If the last brand surface was restrained-on-cream, this one is not.
- When a cultural-symbol palette is the obvious pull, reach past it. Let the cultural reading come from typography, imagery, and copy, not the palette.
## Layout
@@ -79,14 +82,14 @@ Brand surfaces have permission for Committed, Full palette, and Drenched strateg
Brand surfaces lean on imagery. A restaurant, hotel, magazine, or product landing page without any imagery reads as incomplete, not as restrained. A solid-color rectangle where a hero image should go is worse than a representative stock photo.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse.
**When the brief implies imagery (restaurants, hotels, magazines, photography, hobbyist communities, food, travel, fashion, product), you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse. If the approved comp or brief is image-led, ship real project assets, generated raster assets, or a credible canvas/SVG/WebGL scene. Do not replace photographic, architectural, product, or place imagery with generic CSS panels, decorative diagrams, cards, bullets, or copy.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. Pick real Unsplash photo IDs you're confident exist (`photo-1559339352-11d035aa65de`, `photo-1590490360182-c33d57733427`, etc.); if unsure, pick fewer photos but don't substitute colored `<div>` placeholders.
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. **Verify the URLs before referencing them.** If you have an image-search MCP, web-fetch tool, or browser access, use it to find real photo IDs and confirm they resolve. Guessed IDs (even ones that look real) often 404 and ship as broken-image placeholders. Without a verification path, pick fewer photos you're confident exist over more that you guessed; never substitute colored `<div>` placeholders.
- **Search for the brand's physical object**, not the generic category: "handmade pasta on a scratched wooden table" beats "Italian food"; "cypress trees above a limestone hotel facade at dusk" beats "luxury hotel".
- **One decisive photo beats five mediocre ones.** Hero imagery should commit to a mood; padding with more stock doesn't rescue an indecisive one.
- **Alt text is part of the voice.** "Coastal fettuccine, hand-cut, served on the terrace" beats "pasta dish".
Tech / dev-tool brands are the exception where zero imagery can be correct; a developer landing page often carries its voice through typography, code samples, diagrams. Know which kind of brand you're working on.
"Imagery" here is broader than stock photography: product screenshots, custom data visualizations, generated SVG, and canvas/WebGL scenes are all imagery. Text-only pages where typography alone carries the entire visual weight are the failure mode.
## Motion
@@ -102,6 +105,7 @@ Tech / dev-tool brands are the exception where zero imagery can be correct; a de
- Timid palettes and average layouts. Safe = invisible.
- Zero imagery on a brief that implies imagery (restaurant, hotel, food, travel, fashion, photography, hobbyist). Colored blocks where a hero photo belongs.
- Defaulting to editorial-magazine aesthetics (display serif + italic + drop caps + broadsheet grid) on briefs that aren't magazine-shaped. Editorial is ONE aesthetic lane, not the default brand aesthetic.
- Repeated tiny uppercase tracked labels above every section heading. A single strong kicker can be voice; repeating it as section grammar is AI scaffolding unless it's a deliberate, named brand system.
## Brand permissions
+73 -111
View File
@@ -1,43 +1,41 @@
# Craft Flow
Build a feature with impeccable UX and UI quality through a structured process: shape the design, land the visual direction, build real production code, then inspect and improve in-browser until the result meets a high-end studio bar.
Build a feature with impeccable UX and UI quality: shape the design, land the visual direction, build real production code, inspect and improve in-browser until it meets a high-end studio bar.
## Build Gate
Before writing code, you need: PRODUCT.md loaded, register identified and the matching reference loaded, and a confirmed design direction for this task (either from `shape` or supplied by the user). PRODUCT.md is project context, not a task-specific brief.
Craft cannot build until all of these are true:
Treat any approved visual direction (generated mock or stated reference) as a concrete contract for composition, hierarchy, density, atmosphere, signature motifs, and distinctive visual moves. Don't let mocks replace structure, copy, accessibility, or state design. But if the live result lacks the approved direction's major ingredients, the implementation is wrong.
1. PRODUCT context is valid and current.
2. The shape design brief is explicitly confirmed by the user for this task, unless the user already provided a confirmed brief.
3. Implementation references from the brief are loaded.
4. The shape visual probe decision is recorded: generated, skipped with reason, or already resolved.
5. The north-star mock decision is recorded: generated, skipped with reason, or not applicable.
## Step 0: Project Foundation
PRODUCT.md and `teach` answers do **not** satisfy the shape gate. They are project context only. A compact self-authored brief does not satisfy the shape gate either. `shape=pass` requires a separate user response approving the shape brief or an already-confirmed brief supplied by the user.
Before shape, before code: figure out what kind of project you're working in.
Invalid image-skip reasons include: "the final implementation will be semantic HTML/CSS/SVG", "the diagram should stay editable", "a raster mock would not be used directly", or "the product is fictional." Generated probes and mocks are direction artifacts; they are not implementation assets.
Look at the working directory. Run `ls`. Check for:
## Craft Contract
- An existing framework: `astro.config.mjs/ts`, `next.config.js/ts`, `nuxt.config.ts`, `svelte.config.js`, `vite.config.js/ts`, `package.json` with framework deps, `Cargo.toml` + Leptos/Yew, `Gemfile` + Rails. **If found, use it.** Do not start a parallel build, do not introduce a second framework, do not write to `dist/` or `build/` directly. Whatever pipeline the project has, respect it.
- An existing component library or design system: `src/components/`, `app/components/`, a `tokens.css` / `theme.ts`, an `astro.config` `integrations`. Read what's there before adding to it.
- An existing icon set: `lucide-react`, `@phosphor-icons/react`, `@iconify/*`, hand-rolled SVG sprites in `assets/icons/`. **Use what's already in the project**; don't introduce a second set.
Craft is not a first pass. It is a loop with these required artifacts:
If the directory is empty (greenfield), don't pick a framework silently. Ask the user via the AskUserQuestion tool, with sensible defaults framed by the brief:
1. Confirmed design brief from `shape`.
2. Approved visual direction, from generated probes / mocks when image generation is available.
3. Mock fidelity inventory: the visible ingredients from the approved direction that must survive into code.
4. Semantic, functional implementation using the project's real stack and conventions.
5. Browser evidence across relevant viewports.
6. At least one critique-and-fix pass after the first browser inspection, unless the first pass has no material defects.
```text
What should this be built on?
- Astro (default for content-led brand sites, landing pages, marketing surfaces)
- SvelteKit / Next.js / Nuxt (when the brief implies an app surface or significant interactivity)
- Single index.html (one-shot demo, prototype, or a deliberately framework-free experiment)
```
Do not let generated mockups replace interface structure, copy, accessibility, responsive behavior, or state design. But do treat the approved mock as a concrete visual contract for composition, hierarchy, density, atmosphere, signature motifs, image needs, and distinctive visual moves. "North star" means "preserve the important visible ingredients in semantic code," not "use it as loose mood."
Default: Astro for brand briefs, the project's existing framework for product briefs. Ask once; don't re-ask mid-task.
## Step 1: Shape the Design
Run {{command_prefix}}impeccable shape, passing along whatever feature description the user provided.
Run {{command_prefix}}impeccable shape, passing along whatever feature description the user provided. Shape is **required** for craft; it is what produces a confirmed direction.
Wait for the design brief to be fully confirmed by the user before proceeding. The brief is your blueprint, and every implementation decision should trace back to it.
Present the shape output and stop. Wait for the user to confirm, override, or course-correct before writing code.
If this craft run resumed after `teach` created PRODUCT.md, run shape now. Do not treat the teach interview, PRODUCT.md, or a summary of project context as a substitute for shape. Shape is task-specific and must cover scope, content/states, visual direction, constraints, anti-goals, probes when applicable, and explicit brief confirmation.
If the user already supplied a confirmed brief or ran shape separately, use it and skip this step.
If the user has already run {{command_prefix}}impeccable shape and has a confirmed design brief, skip this step and use the existing brief.
When the original prompt + PRODUCT.md already answer scope, content, and visual direction with no real ambiguity, the shape output can be **compact** (3-5 bullets stating what you're building and the visual lane, ending with one or two specific questions or "confirm or override"). The full 10-section structured brief is reserved for genuinely ambiguous, multi-screen, or stakeholder-heavy tasks. Don't pad a clear brief into a long one to look thorough; equally, don't skip the pause to look efficient.
## Step 2: Load References
@@ -55,79 +53,60 @@ Then add references based on the brief's needs:
## Step 3: Land the Visual Direction (Capability-Gated)
Before implementation, generate high-fidelity visual comps when all of these are true:
Generate high-fidelity visual comps before implementation when all three are true:
- The work is **net-new** or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is **mid-fi, high-fi, or production-ready**.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The work is net-new or visually open-ended enough that composition exploration will improve the build.
- The brief's scope is mid-fi, high-fi, or production-ready.
- The harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool). Don't ask the user to set up external APIs.
When those conditions are met, this step is mandatory for **both brand and product work** in Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
Do not skip this step because the eventual UI should be semantic, editable, code-native, responsive, or accessible. Those are implementation requirements, not reasons to avoid visual exploration.
### Purpose
Use the mock step to find a stronger visual lane than code-first generation would reliably discover on its own. The brief remains authoritative on user, purpose, content, constraints, states, and anti-goals. The mock clarifies composition, hierarchy, density, typography, and visual tone.
When met, this step is mandatory for both brand and product work. If image generation isn't available, skip silently. "The eventual UI is semantic/code-native/accessible" is not a reason to skip; those are implementation requirements, not exploration ones.
### What to generate
Generate **1 to 3** high-fidelity north-star comps based on the confirmed brief. If shape already produced direction probes, use those results as input and generate a more resolved mock from the winning lane, not another unrelated exploration.
Generate **1 to 3** high-fidelity north-star comps from the confirmed brief. If shape already produced direction probes, resolve the winning lane further, not an unrelated exploration. Comps must differ in primary visual direction, not just color.
- For brand work, push visual identity, composition, and mood aggressively.
- For product work, still push hierarchy, topology, density, and tone, but keep the comps grounded in realistic product structure and states.
- For landing pages and long-form brand surfaces, show enough of the next section or second fold to establish the system beyond the hero.
The comps must be genuinely different in primary visual direction, not just color variants.
- Brand work: push visual identity, composition, and mood aggressively.
- Product work: push hierarchy, topology, density, tone, grounded in realistic product structure.
- Landing pages and long-form brand surfaces: show enough of the second fold to establish the system beyond the hero.
### Approval loop
Show the comps and ask what should carry forward. If the user asks for changes or the best direction is still weak, generate a focused revision before implementation. Continue until one direction is approved, or until the user explicitly delegates the choice.
Show the comps and ask what carries forward. Iterate until one direction is approved or the user delegates. If the user delegates, pick the strongest direction and explain it from the brief, not personal taste.
If the user delegates, pick the strongest direction and explain the decision using the brief, not personal taste.
Before moving to implementation, summarize:
- What to carry into code
- What **not** to literalize from the mock
This summary is required before Step 4. It is the handoff between visual exploration and semantic implementation.
Before Step 4, summarize what to carry into code and what **not** to literalize from the mock. This is the handoff between visual exploration and semantic implementation.
### Mock fidelity inventory
Before building, inventory the approved mock's major visible ingredients:
Inventory the approved mock's major visible ingredients:
- Hero silhouette and dominant composition.
- Signature motifs: planets, devices, portraits, charts, route lines, insets, badges, or other memorable objects.
- Nav and primary CTA treatment.
- Section sequence visible in the mock, especially the second fold.
- Image-native content the concept depends on.
- Typography, density, color/material treatment, and motion cues.
- Hero silhouette and dominant composition
- Signature motifs (planets, devices, portraits, charts, route lines, insets, badges, etc.)
- Nav and primary CTA treatment
- Section sequence, especially the second fold
- Image-native content the concept depends on
- Typography, density, color/material treatment, motion cues
For each ingredient, decide how it will be implemented: semantic HTML/CSS/SVG, generated asset, sourced project asset, icon library, canvas/WebGL, or an explicitly accepted omission. Do not substitute a different hero composition or new visual driver after approval unless the user approves the change.
For each, decide implementation: semantic HTML/CSS/SVG, generated asset, sourced asset, icon library, canvas/WebGL, or accepted omission. Don't substitute a different hero composition or visual driver post-approval without user sign-off.
Treat the mock as a **north star**, not a screenshot to trace. Do **not** rasterize core UI text or let the mock override the confirmed brief. But if the live result lacks the mock's major visible ingredients, the implementation is wrong.
If a photographic, architectural, product, or place-led mock becomes generic CSS scenery / decorative diagrams / bullets / copy, stop and fix it. That's a broken implementation, not a harmless interpretation.
Treat the mock as a north star, not a screenshot to trace. Don't rasterize core UI text. But if the live result lacks the mock's major ingredients, the implementation is wrong.
## Step 4: Asset Extraction (Need-Gated)
If the chosen direction includes image-native visual ingredients that would materially improve the implementation, generate them as separate assets before building.
If the approved direction needs raster assets, create them before building. Do not replace required imagery with generic cards, bullets, emoji, fake metrics, decorative CSS panels, or filler copy.
Good candidates:
Use the native asset producer (`impeccable_asset_producer` in Codex, `impeccable-asset-producer` in Claude Code) to create clean assets from the hi-fi mock and crops. If you do not have explicit permission to use agents, stop and ask:
- stickers
- badges
- seals
- tickets
- graphic labels
- textures
- abstract objects
- decorative marks
- non-semantic scene elements
```text
Asset production will work better as a scoped subagent job. Should I spawn the Impeccable asset producer subagent for this step?
```
For travel, editorial, portfolio, venue, product showcase, entertainment, education, or any other image-led brand surface, visual assets are usually core content, not decoration. Do not ship abstract CSS panels where the approved mock or subject matter calls for real imagery, generated plates, illustrations, maps, product/object renders, or destination scenes.
Do not skip asset production or silently do it inline. Inline asset production is allowed only if the user declines subagents, the harness cannot spawn the authorized agent, or the user explicitly asks for single-thread mode.
Do **not** export assets for core UI text, navigation, body copy, or any structure that should stay semantic and editable in code.
Pass the approved mock, crop/contact-sheet paths, output directory, dimensions/formats, transparency needs, constraints, and avoid list to the asset producer. Attach image generation capability to the spawned agent when the harness supports it; do not load image-generation reference material into the parent thread first.
Usually **1 to 5** extracted assets is enough. If the design can be built cleanly in HTML/CSS/SVG, prefer that over raster assets. If the mock contains major visual content that cannot be built credibly in code, asset extraction is not optional.
Prefer HTML/CSS/SVG/canvas when they can credibly reproduce an ingredient; use real/generated/stock imagery when the mock or subject matter calls for actual visual content.
## Step 5: Build to Production Quality
@@ -135,50 +114,35 @@ Implement the feature following the design brief. Build in passes so structure,
### Production bar
- Use real or realistic content. Remove placeholder copy, placeholder images, dead links, fake controls, and unused scaffold before presenting.
- Preserve the approved mock's major ingredients. Missing hero objects, missing world/product imagery, different section structure, downgraded CTA/nav treatment, or generic replacements for distinctive motifs are blocking defects unless the user accepted the change.
- Build semantically first: real headings, landmarks, labels, form associations, button/link semantics, accessible names, and state announcements where needed.
- Calibrate spacing, alignment, grid placement, and vertical rhythm deliberately. Do not accept default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- Make typography intentional: chosen font loading strategy, clear hierarchy, readable measure, stable line breaks, tuned wrapping, and no overflow at mobile or large desktop sizes.
- Design realistic state coverage: default, hover where supported, focus-visible, active, disabled, loading, error, success, empty, overflow, long text, short text, and first-run states where relevant.
- Make interaction quality feel finished: keyboard paths, touch targets, feedback timing, scroll behavior, transitions between states, and no hover-only functionality.
- Use icons from the project's established icon set when available. If no set exists, choose a coherent library or use accessible text controls; do not mix unrelated icon styles.
- Optimize imagery and media: correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset` / `picture` for raster assets, and no project-referenced asset left outside the workspace.
- Make motion feel premium: use atmospheric blur, filter, mask, shadow, or reveal effects when they improve the experience; avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- Preserve maintainability: reusable local patterns, clear component boundaries, project conventions, no rasterized UI text, and no hard-coded one-off hacks when a better local pattern exists.
- Fit the technical context: production build passes, no obvious console errors, no avoidable layout shift, no needless dependency, and no broken asset path.
- If you discover a design question that materially changes the brief or approved direction, stop and ask rather than guessing.
- **Real content.** No placeholder copy, placeholder images, dead links, fake controls, or unused scaffold at presentation time.
- **Preserve the approved mock's major ingredients.** Missing hero objects, world/product imagery, section structure, CTA/nav treatment, or distinctive motifs are blocking defects unless the user accepted the change.
- **Semantic first.** Real headings, landmarks, labels, form associations, button/link semantics, accessible names, state announcements where needed.
- **Deliberate spacing and alignment.** No default gaps, arbitrary margins, unbalanced whitespace, or accidental optical misalignment.
- **Intentional typography.** Chosen loading strategy, clear hierarchy, readable measure, stable line breaks, no overflow at any width.
- **Realistic state coverage.** Default, hover, focus-visible, active, disabled, loading, error, success, empty, overflow, long/short text, first-run.
- **Finished interaction quality.** Keyboard paths, touch targets, feedback timing, scroll behavior, state transitions, no hover-only functionality.
- **Coherent icon set.** Use the project's established set; otherwise pick one library or use accessible text. Don't mix.
- **Respect the build pipeline.** Edit source files and run the project's build (`npm run build` or equivalent). Don't write to `build/` / `dist/` / `.next/` with `cat`, heredoc, or Bash redirects; that skips asset hashing, image optimization, code splitting, and CSS extraction, and produces output the dev server won't serve.
- **Verify image URLs before referencing them.** Use image-search MCP or web-fetch when available; guessed photo IDs ship as broken-image placeholders. Without verification, prefer fewer images you're confident about.
- **Optimized imagery and media.** Correct dimensions, useful alt text, lazy loading below the fold, modern formats when practical, responsive `srcset`/`picture` for raster, no project-referenced asset left outside the workspace.
- **Premium motion.** Use atmospheric blur, filter, mask, shadow, reveal when they improve the experience. Avoid casual layout-property animation, bound expensive effects, verify smoothness in-browser, respect reduced motion, and avoid choreography that blocks task completion.
- **Maintainable.** Reusable local patterns, clear component boundaries, project conventions. No rasterized UI text or one-off hacks when a local pattern exists.
- **Technically clean.** Production build passes, no console errors, no avoidable layout shift, no needless dependencies, no broken asset paths.
- **Ask when uncertain.** If a discovery materially changes the brief or approved direction, stop and ask. Don't guess.
## Step 6: Browser-Based Iteration
## Step 6: Iterate Visually
**This step is critical.** Do not stop after the first implementation pass.
Look at what you built like a designer would. Your eyes are whatever the harness gives you: a connected browser, a screenshotting tool, Playwright, or asking the user. Use them for responsive testing (mobile, tablet, desktop minimum) and general visual validation.
Open the result in a browser. In Codex, use browser-use or equivalent browser automation when available; otherwise use Playwright or ask the user for screenshots. Inspect screenshots, not just DOM or terminal output.
If your tool returns a file path, read the PNG back into the conversation. A screenshot you didn't read doesn't count.
### Required viewport pass
For long-form brand surfaces, inspect major sections individually. Thumbnails hide spacing, clipping, and cascade defects.
Check the experience at the viewports that matter for the brief. Default minimum:
After the first pass, write an honest critique against the brief, the approved mock's major ingredients (hero silhouette, motifs, imagery, nav/CTA, density), and impeccable's DON'Ts. Patch material defects and re-inspect. **Don't invent defects to demonstrate iteration.** A confident "first pass clean, shipping" beats a fake fix.
- Mobile narrow
- Tablet or small laptop
- Desktop wide
Actively check: responsive behavior (composes, not shrinks), every state (empty / error / loading / edge), craft details (spacing, alignment, hierarchy, contrast, motion timing, focus), performance basics. The exit bar: defensible in a high-end studio review.
For each viewport, capture or inspect the rendered state and look for visual defects: overlap, clipping, weak hierarchy, off-grid alignment, awkward whitespace, cramped controls, unreadable type, broken imagery, hover-only functionality, layout shift, and text overflow.
### Critique and fix loop
After the first browser pass, write a short critique for yourself and patch the implementation. Repeat browser inspection after fixes. Continue until no material issues remain against this checklist:
1. **Does it match the brief?** Compare the live result against every section of the design brief. Fix discrepancies.
2. **Does it match the approved mock?** Compare screenshots against the mock fidelity inventory: hero silhouette, major motifs, imagery, nav/CTA, section sequence, density, color/materials, and second-fold substance. Missing major ingredients are P0 defects.
3. **Does it pass the AI slop test?** If someone saw this and said "AI made this," would they believe it immediately? If yes, it needs more design intention.
4. **Check against impeccable's DON'T guidelines.** Fix any anti-pattern violations.
5. **Check every state.** Navigate through empty, error, loading, and edge case states. Each one should feel intentional, not like an afterthought.
6. **Check responsive behavior.** The design should adapt compositionally, not merely shrink.
7. **Check craft details.** Spacing consistency, optical alignment, type hierarchy, color contrast, image quality, icon coherence, interactive feedback, motion timing, and focus treatment.
8. **Check performance basics.** No obviously oversized images, avoidable layout thrash, blocking animations, or heavy assets without a reason.
The exit bar is not "it works." It is: the rendered result looks intentional at all checked viewports, all expected states are handled, no placeholders remain unless explicitly accepted, and the implementation quality would be defensible in a high-end studio review.
Detector or QA output is defect evidence only; never proof the work is finished.
## Step 7: Present
@@ -189,5 +153,3 @@ Present the result to the user:
- Explain design decisions that connect back to the design brief and, when used, the chosen north-star mock. Include any accepted deviations from the mock; do not hide unimplemented mock ingredients.
- Note any remaining limitations or follow-up risks honestly
- Ask: "What's working? What isn't?"
Iterate based on feedback. Good design is rarely right on the first pass.
+1 -1
View File
@@ -43,7 +43,7 @@ Run the bundled deterministic detector, which flags 27 specific patterns (AI slo
**CLI scan**:
```bash
npx impeccable --json [--fast] [target]
npx impeccable detect --json [--fast] [target]
```
- Pass HTML/JSX/TSX/Vue/Svelte files or directories as `[target]` (anything with markup). Do not pass CSS-only files.
+8 -6
View File
@@ -2,6 +2,8 @@
Perform a meticulous final pass to catch all the small details that separate good work from great work. The difference between shipped and polished.
Detector and automated QA output are defect evidence only. A clean script result is never proof that the design is strong; gather browser evidence and inspect the real interaction path.
## Design System Discovery
Aligning the feature to the design system is **not optional**. Polish without alignment is decoration on top of drift, and it makes the next person's job harder. Discovery comes before any other polish work.
@@ -216,11 +218,12 @@ Sweat the details. Zoom in until the alignment is right and the spacing reads as
Before marking as done:
- **Use it yourself**: Actually interact with the feature
- **Test on real devices**: Not just browser DevTools
- **Ask someone else to review**: Fresh eyes catch things
- **Compare to design**: Match intended design
- **Check all states**: Don't just test happy path
- **Use it yourself**: Actually interact with the feature.
- **Test on real devices**: Not just browser DevTools.
- **Ask someone else to review**: Fresh eyes catch things.
- **Compare to design**: Match intended design.
- **Check all states**: Don't just test happy path.
- **Treat automation carefully**: Run detector or QA commands when they are available and relevant, fix their defects, but never cite a clean result as proof that the work is polished.
## Clean Up
@@ -230,4 +233,3 @@ After polishing, ensure code quality:
- **Remove orphaned code**: Delete unused styles, components, or files made obsolete by polish.
- **Consolidate tokens**: If you introduced new values, check whether they should be tokens.
- **Verify DRYness**: Look for duplication introduced during polishing and consolidate.
+25 -11
View File
@@ -16,14 +16,16 @@ This is a required interaction, not optional guidance. Ask these questions in co
### Interview cadence
Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed design inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
Discovery includes at least one user-answer round unless PRODUCT.md, DESIGN.md, or an already-confirmed brief directly answers the needed inputs. With a sparse prompt, do **not** synthesize a complete brief for confirmation on the first response.
- Use the harness's structured question tool when one exists. Otherwise, ask directly in chat and stop.
- Ask **2-3 questions per round**, then wait for answers.
- Treat PRODUCT.md and DESIGN.md as anchors; they reduce repeated questions but do **not** replace shape for craft. Shape is task-specific.
- Round 1 should clarify purpose, audience/context, and success or emotional outcome.
- Round 2 should clarify content/data/states and scope/fidelity.
- Round 3 should clarify visual direction, constraints, and anti-goals when still unresolved.
- One round is the default. Add a second only if the first answers leave material gaps. Don't run a second round just to feel thorough.
- Round 1 should clarify purpose, audience/context, content/scope, and (for brand) visual direction.
- Round 2, when needed, fills in whatever's still genuinely missing.
**Assert-then-confirm, not menu-with-escape.** When PRODUCT.md and the user's prompt make one option obvious, name it and ask the user to confirm or override. Don't enumerate "Restrained / Committed / Or something else?" as a real choice; "This reads as Restrained, confirm?" beats a four-option menu when the answer is already clear.
### Purpose & Context
- What is this feature for? What problem does it solve?
@@ -36,6 +38,7 @@ Discovery must include at least one user-answer round unless PRODUCT.md, DESIGN.
- What are the realistic ranges? (Minimum, typical, maximum, e.g., 0 items, 5 items, 500 items)
- What are the edge cases? (Empty state, error state, first-time use, power user)
- Is any content dynamic? What changes and how often?
- What visual assets are real content here? Note required images, product shots, illustrations, maps, textures, diagrams, generated objects, or existing project assets.
### Design Direction
@@ -72,9 +75,9 @@ After the discovery interview, generate a small set of visual direction probes *
- The work is **net-new** or directionally ambiguous enough that visual exploration will clarify the brief.
- The requested fidelity is **mid-fi, high-fi, or production-ready**. Skip for sketch-only planning.
- The current harness has **built-in image generation capability** (for example, Codex with a native image tool). Do **not** ask the user to set up external APIs, shell scripts, or one-off tooling just to do this.
- The current harness gives you native image generation (Codex's `image_gen`, an equivalent MCP tool, or similar). Don't ask the user to install APIs or tooling.
When those conditions are met, this step is mandatory for Codex and any harness with built-in image generation. Use native image generation; in Codex, use the built-in `image_gen` tool via the imagegen skill. If image generation is unavailable, do not ask the user to install APIs or tooling. State in one line that the image step is skipped because the harness lacks native image generation, then proceed.
When those conditions are met, this step is mandatory. If image generation isn't natively available, skip silently and proceed; don't announce the skip.
Use probes to explore visual lanes, not to replace the brief.
@@ -104,11 +107,20 @@ The probes should differ in primary visual direction (hierarchy, topology, densi
- Do **not** treat generated imagery as final UX specification, final copy, or final accessibility behavior.
- Do **not** use this step for minor refinements of existing work. It's for shaping a new surface or clarifying a big directional choice.
If image generation is unavailable, or the task doesn't benefit from it, skip this phase only with a one-line reason and proceed directly to the design brief.
If image generation isn't natively available, skip this phase silently and proceed.
## Phase 2: Design Brief
After the interview and any required probes, synthesize everything into a structured design brief. Present it to the user for explicit confirmation before considering this command complete. Stop after asking for confirmation; do not proceed to craft or implementation in the same response unless the user has already approved the brief.
After the interview and any required probes, present a brief and **end your response**. The user must confirm before any implementation runs. Do not present a brief and then continue to code in the same response, even if the brief feels obvious to you. The user's confirmation is the gate.
**Choose the brief shape based on how clear the answers are:**
- **Compact form (3-5 bullets)** when discovery was crisp and the original prompt + PRODUCT.md already pinned scope, content, and direction. State what you're building, the visual lane, and end with one or two specific questions or a clear "confirm or override?" prompt. This is the default for typical craft requests with a clear prompt.
- **Full structured form (sections below)** when the task is genuinely ambiguous, multi-screen, or when the user asked for shape as a standalone step. Use this when the discipline of structure earns its weight.
Don't pad a clear brief into a long one to look thorough. A 70-line brief restating answers the user just gave is noise, not rigor. Equally, don't skip the confirmation pause to look efficient: the pause is the point.
If the user already said "approved" or "go" during discovery for the *exact direction you'd present*, that counts as confirmation; you may proceed without asking again. But if your brief adds anything the user hasn't seen and approved, you must stop and confirm.
### Brief Structure
@@ -136,16 +148,18 @@ List every state the feature needs: default, empty, loading, error, success, edg
How users interact with this feature. What happens on click, hover, scroll? What feedback do they get? What's the flow from entry to completion?
**8. Content Requirements**
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges.
What copy, labels, empty state messages, error messages, and microcopy are needed. Note any dynamic content and its realistic ranges. For image-led surfaces, also list the required image/media roles and their likely source (project asset, generated raster, semantic SVG/CSS, canvas/WebGL, icon library, or accepted omission).
**9. Recommended References**
Based on the brief, list which impeccable reference files would be most valuable during implementation (e.g., spatial-design.md for complex layouts, motion-design.md for animated features, interaction-design.md for form-heavy features).
**10. Open Questions**
Anything unresolved that the implementer should resolve during build.
Anything genuinely unresolved. Don't list "open questions" you've already recommended a default for; assert the default and move on. If you'd write `Recommend: X` next to a question, just decide X.
---
{{ask_instruction}} Ask for explicit confirmation of the brief before finishing. If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the brief is confirmed.
{{ask_instruction}}
If the user disagrees with any part, revisit the relevant discovery questions. A shape run is incomplete until the user confirms direction (or the user already gave a clear go during discovery, which counts).
Once confirmed, the brief is complete. The user can now hand it to {{command_prefix}}impeccable, or use it to guide any other implementation approach. (If the user wants the full discovery-then-build flow in one step, they should use {{command_prefix}}impeccable craft instead, which runs this command internally.)
+52
View File
@@ -162,6 +162,58 @@ This is a test skill body.`;
expect(fs.existsSync(path.join(DIST_DIR, 'codex/.codex/skills/test-skill/SKILL.md'))).toBe(true);
});
test('integration: emits native subagent files for Codex and Claude Code', () => {
const skillContent = `---
name: test-skill
description: A test skill
---
This is a test skill body.`;
const agentContent = `---
name: asset-producer
codex-name: asset_producer
description: Produces assets from approved crops
tools: Read, Write
model: inherit
effort: medium
max-turns: 8
nickname-candidates:
- Asset Plate
---
Do not redesign the approved crop.`;
const skillDir = path.join(TEST_DIR, 'skill');
fs.mkdirSync(path.join(skillDir, 'agents'), { recursive: true });
fs.writeFileSync(path.join(skillDir, 'SKILL.md'), skillContent);
fs.writeFileSync(path.join(skillDir, 'agents/asset-producer.md'), agentContent);
const DIST_DIR = path.join(TEST_DIR, 'dist');
const { skills } = utils.readSourceFiles(TEST_DIR);
const patterns = utils.readPatterns(TEST_DIR);
transformers.transformClaudeCode(skills, DIST_DIR, patterns);
transformers.transformCodex(skills, DIST_DIR, patterns);
const claudeAgentPath = path.join(DIST_DIR, 'claude-code/.claude/agents/asset-producer.md');
const codexAgentPath = path.join(DIST_DIR, 'codex/.codex/agents/asset_producer.toml');
expect(fs.existsSync(claudeAgentPath)).toBe(true);
expect(fs.existsSync(codexAgentPath)).toBe(true);
const claudeAgent = fs.readFileSync(claudeAgentPath, 'utf-8');
expect(claudeAgent).toContain('name: asset-producer');
expect(claudeAgent).toContain('tools: Read, Write');
expect(claudeAgent).toContain('maxTurns: 8');
const codexAgent = fs.readFileSync(codexAgentPath, 'utf-8');
expect(codexAgent).toContain('name = "asset_producer"');
expect(codexAgent).toContain('model_reasoning_effort = "medium"');
expect(codexAgent).toContain('nickname_candidates = ["Asset Plate"]');
expect(codexAgent).toContain('developer_instructions =');
});
test('integration: verify transformations are correct', () => {
const skillContent = `---
name: audit
@@ -97,4 +97,14 @@ describe('detectUrl — browser-only fixtures', () => {
const f = await detectUrl(`${BASE}/fixtures/antipatterns/quality.html`);
assert.equal(f.filter(r => r.antipattern === 'line-length').length, 1);
});
it('body-text-viewport-edge: 3 flag paragraphs/list-items, 0 pass cases', async () => {
const f = await detectUrl(`${BASE}/fixtures/antipatterns/body-text-viewport-edge.html`);
const edges = f.filter(r => r.antipattern === 'body-text-viewport-edge');
// Fixture has 3 escape-styled <p>/<li> paragraphs that bleed to
// the viewport edges. The pass column has 5 paragraphs that
// should not fire (centered container, inside nav, inside header,
// inside section with own background, short label < 40 chars).
assert.equal(edges.length, 3, `expected 3 body-text-viewport-edge findings, got ${edges.length}: ${JSON.stringify(edges.map(e => e.snippet))}`);
});
});
+40 -2
View File
@@ -341,14 +341,17 @@ describe('detectHtml — hero-eyebrow-chip', () => {
'Span Eyebrow Above Hero',
'Pill Chip Above Hero',
'Already Uppercase Text',
// The rule no longer gates on heading font size (modern hero h1s
// use clamp() / vw / var() that jsdom can't resolve), and the
// eyebrow text ceiling moved 30 → 60 chars. Both shapes now flag.
'Body-Sized Heading Below Eyebrow',
'Long Uppercase Sentence Above Hero',
];
const SHOULD_PASS = [
'Eyebrow With Normal Tracking',
'Body-Sized Heading Below Eyebrow',
'Uppercase Caption Far From Hero',
'Hero With No Eyebrow',
'Heading Above Heading',
'Long Uppercase Sentence Above Hero',
];
it('hero-eyebrow-chip: flags only the should-flag column', async () => {
@@ -371,6 +374,41 @@ describe('detectHtml — hero-eyebrow-chip', () => {
});
});
describe('detectHtml — repeated-section-kickers', () => {
const SHOULD_FLAG = [
'The Future Is Admitted',
'A Private Rehearsal',
'Reviewed, Not Sold',
'Touch the Future',
];
const SHOULD_PASS = [
'Breadcrumb Before Heading',
'Form Heading Is Separate',
'Step Indicator',
'Figure Caption Label',
'Normal Case Kicker',
'Intentional Brand Label',
];
it('repeated-section-kickers: flags only repeated section scaffolding', async () => {
const f = await detectHtml(path.join(FIXTURES, 'repeated-section-kickers.html'));
const flagged = new Set();
for (const r of f) {
if (r.antipattern !== 'repeated-section-kickers') continue;
assert.equal(r.severity, 'advisory');
const matches = [...(r.snippet || '').matchAll(/"([^"]+)"/g)];
if (matches.length) flagged.add(matches[matches.length - 1][1]);
}
for (const text of SHOULD_FLAG) {
assert.ok(flagged.has(text), `expected "${text}" to be flagged as repeated-section-kickers`);
}
for (const text of SHOULD_PASS) {
assert.ok(!flagged.has(text), `"${text}" should NOT be flagged as repeated-section-kickers`);
}
});
});
describe('detectHtml — motion', () => {
// jsdom doesn't fully apply class-based styles, so the absolute finding counts
// are lower than what a real browser would see. The hardcoded counts below are

Some files were not shown because too many files have changed in this diff Show More