references/detect.md
---
name: detect
description: "Run the deterministic impeccable detect CLI on code or a URL and present findings clearly."
version: 1.6.0
---
# Anti-Pattern Detector
Run the deterministic `impeccable detect` CLI on code or a URL and present findings clearly.
## Running the Detector
```bash
# Local file or folder
npx impeccable --json path/to/file.html
npx impeccable --json path/to/folder/
# URL
npx impeccable --json https://example.com
```
## Process
1. **Identify the target** from the user's message. If not specified, ask: "What file, folder, or URL should I scan?"
2. **Run** with `--json` flag
3. **Parse** — each finding has: `rule`, `severity` (error|warning|info), `message`, `location`, `suggestion`
4. **Present** grouped by severity, with concrete fix for each
5. **Offer to fix**: "Would you like me to fix any of these?"
## Output Format
```
## Anti-Pattern Report: [target]
Found [N] issues: [E] errors · [W] warnings · [I] informational
### Errors (must fix)
**[rule-name]** — [file]:[line]
[message]
→ Fix: [suggestion]
### Warnings (should fix)
...
### Info (consider fixing)
...
```
If 0 issues: "No anti-patterns detected."
## Common Anti-Patterns
- **missing-focus-ring** — Interactive elements lack visible focus indicators
- **placeholder-as-label** — `placeholder` used without a real `<label>`
- **pure-black** — `#000` or `rgb(0,0,0)` used for large surfaces
- **clipped-dropdown** — `position: absolute` inside `overflow: hidden`
- **missing-reduced-motion** — Animations without `prefers-reduced-motion` fallback
- **tiny-touch-target** — Interactive element smaller than 44×44px
- **arbitrary-z-index** — `z-index` values like 9999
- **outline-none** — `outline: none` without `:focus-visible` replacement
- **hover-only-state** — Hover styles with no equivalent focus style
- **color-only-info** — Information conveyed by color alone
## If Node.js is Not Available
> The detector requires Node.js. Install it from https://nodejs.org, then run `npx impeccable [target]`. In the meantime, I can do a manual review — share your file and I'll run `/siteasy audit` instead.
## Parallax Anti-Patterns
Detect on any page using `.parallax-*` classes, `[data-parallax]`, `animation-timeline`, GSAP `ScrollTrigger`, or Lenis. Cross-reference with `siteasy/references/parallax.md`.
- **parallax-on-text** — Body text or interactive control (CTA, form field, nav) sits inside a moving layer. Anchor controls; only decorative layers move.
- **parallax-bg-attachment-fixed** — `background-attachment: fixed` declared on a parallax layer. Breaks on iOS Safari, jank-prone everywhere. Use `position: sticky` plus `transform` instead.
- **parallax-no-reduced-motion** — Parallax styles or scripts ship without a `@media (prefers-reduced-motion: reduce)` neutralizer.
- **parallax-no-toggle** — No visible manual control to disable motion. WCAG 2.2.2 violation when motion exceeds 5 seconds.
- **parallax-mobile-leak** — Multi-layer parallax remains active below 768px or under `(pointer: coarse)`. Drop to Tier 1 (static or one passive reveal).
- **parallax-layout-animation** — Animates `width`, `height`, `top`, `left`, or margin. Use `transform` and `opacity` only.
- **parallax-non-passive-scroll** — `addEventListener('scroll', ...)` without `{ passive: true }`. INP killer.
- **parallax-lcp-occlusion** — LCP candidate is a parallax layer without `fetchpriority="high"` and explicit `width`/`height`.
- **parallax-heavy-asset** — Layer image above 200 KB or not in AVIF/WebP.
- **parallax-no-static-fallback** — Reduced-motion path leaves an empty or broken section. Must reach content parity.
- **parallax-text-contrast-drift** — Foreground text contrast falls below 4.5:1 at some point along the layer travel. Add an overlay or fix the asset.
- **parallax-stacked-effects** — Two patterns in the same viewport (e.g. horizontal scroll plus zoom plus mouse-follow). Pick one.
- **parallax-will-change-leak** — `will-change: transform` declared permanently. Set when active, remove on idle.
- **parallax-smoothtouch-enabled** — Lenis or equivalent runs with `smoothTouch: true`. Mobile scroll must stay native.
Severity mapping:
- `error`: parallax-on-text, parallax-no-reduced-motion, parallax-layout-animation, parallax-non-passive-scroll, parallax-lcp-occlusion, parallax-smoothtouch-enabled
- `warning`: parallax-bg-attachment-fixed, parallax-no-toggle, parallax-mobile-leak, parallax-heavy-asset, parallax-text-contrast-drift, parallax-stacked-effects, parallax-will-change-leak
- `info`: parallax-no-static-fallback
## WCAG 2.2 Anti-Patterns
Detect against the nine WCAG 2.2 success criteria. Cross-reference with `siteasy/references/wcag-2-2.md`.
- **focus-obscured** — Sticky header, cookie banner, or floating CTA hides the keyboard focus indicator. Violates 2.4.11. Fix with `scroll-padding-top` or `scroll-margin` on focusable elements.
- **target-size-below-24** — Interactive element under 24x24 CSS pixels without 24px clearance. Violates 2.5.8. Exceptions: inline text links, native controls, essential-size targets.
- **drag-without-alternative** — Drag-and-drop interaction with no single-pointer alternative (button, click sequence). Violates 2.5.7.
- **inaccessible-auth** — Login flow requires CAPTCHA, puzzle, or memory test without an alternative (magic link, OAuth, passkey, biometric). Violates 3.3.8. `user-select: none` or pasteblockers on password fields also fail.
- **redundant-entry** — Multi-step form re-asks for information already provided in the same session without justification. Violates 3.3.7.
- **inconsistent-help** — Help mechanisms appear in different relative order across pages. Violates 3.2.6.
- **placeholder-as-label** — Placeholder used as the only label. Fails 2.5.3 (Label in Name) and 3.3.2 (Labels or Instructions). Also fails 1.4.3 (contrast in placeholder color is typically below 4.5:1).
- **paste-disabled-password** — Password input with `onpaste="return false"`, `user-select: none`, or `autocomplete="off"`. Defeats password managers, fails 3.3.8.
- **autocomplete-missing** — Form input matching a standard autocomplete value (email, tel, name, password) without the `autocomplete` attribute. Fails 1.3.5 (Identify Input Purpose).
- **error-not-associated** — Error message not linked to its input via `aria-describedby`. Screen readers announce the input as invalid without the message.
## Image Strategy Anti-Patterns
Detect on any page serving images. Cross-reference with `siteasy/references/image-strategy.md`.
- **img-missing-dimensions** — `<img>` without explicit `width` and `height` attributes. Causes CLS.
- **lcp-image-lazy** — Largest Contentful Paint candidate has `loading="lazy"`. Defers the most important paint.
- **lcp-image-no-priority** — LCP image without `fetchpriority="high"` or `<link rel="preload">`.
- **srcset-without-sizes** — `srcset` with width descriptors but no `sizes` attribute. Browser falls back to 100vw.
- **legacy-format-only** — Hero or content image served only as JPEG or PNG without AVIF/WebP alternatives.
- **gif-animation** — Animated GIF over 200 KB. Convert to MP4 video.
- **alt-attribute-missing** — `<img>` without `alt` attribute (different from empty `alt=""`).
- **alt-not-descriptive** — `alt="image"`, `alt="photo"`, `alt="IMG_xxxx"`, or filename as alt.
- **background-image-content** — Meaningful content (text overlays excepted) served as CSS `background-image` instead of `<img>`. Inaccessible.
## Form Pattern Anti-Patterns
Detect on any `<form>`. Cross-reference with `siteasy/references/form-patterns.md`.
- **form-multi-column** — Independent fields side-by-side beyond the canonical pairs (first/last name, city/state/zip, expiry month/year).
- **submit-permanently-disabled** — Submit button `disabled` until "valid" without surfacing what is missing.
- **validation-on-keystroke** — Inline error fires on every keystroke from the first character.
- **error-summary-only** — Errors listed only at top of form, no inline indication next to the offending field.
- **inputmode-missing** — Numeric input without `inputmode="numeric"`. Mobile keyboard wrong.
- **otp-split-inputs** — One-time-code entered across 6 separate `<input>` elements instead of a single field with `autocomplete="one-time-code"`.
references/preview.md
---
name: preview
description: "Take real browser screenshots using Playwright, read them back visually, and fix what's wrong."
version: 1.6.0
---
# Browser Visual Testing
Take real browser screenshots using Playwright, read them back visually, and fix what's wrong.
## Workflow
### 1. Identify target
- **URL** (`https://...`) → use directly
- **File path** (`index.html`) → start a local server
- **Nothing** → look for `index.html` in workspace root
### 2. Start local server (local files only)
```bash
python3 -m http.server 7331 --directory /absolute/path/to/project &
sleep 1
```
### 3. Install Playwright (first run)
```bash
npx playwright install chromium 2>&1 | tail -5
# On Linux if that fails:
npx playwright install chromium --with-deps 2>&1 | tail -5
```
### 4. Take screenshots
```bash
# Desktop (always)
npx playwright screenshot --browser chromium --full-page \
--viewport-size "1280,800" "http://localhost:7331/index.html" /tmp/pw-desktop.png
# Mobile (always)
npx playwright screenshot --browser chromium --full-page \
--viewport-size "390,844" "http://localhost:7331/index.html" /tmp/pw-mobile.png
# Tablet (--all or --tablet only)
npx playwright screenshot --browser chromium --full-page \
--viewport-size "768,1024" "http://localhost:7331/index.html" /tmp/pw-tablet.png
```
### 5. Read and analyze
```
Read /tmp/pw-desktop.png
Read /tmp/pw-mobile.png
```
Look for: layout breaks, overflow, typography hierarchy, color/contrast failures, spacing issues, component integrity.
### 6. Fix issues
1. Read the relevant file
2. Apply targeted fix with Edit tool
3. Re-screenshot to verify
4. Repeat until output matches intent
### 7. Clean up
```bash
kill $(lsof -ti:7331) 2>/dev/null || true
```
## Common Bug Patterns
| What you see | Likely cause | Fix |
|---|---|---|
| Horizontal scrollbar | `width: 100vw` or negative margins | `overflow-x: hidden` on `body` |
| Text overflows | No `overflow-wrap` | `overflow-wrap: break-word` |
| Image stretched | No `object-fit` | `object-fit: cover; aspect-ratio: 16/9` |
| Sticky nav covers content | No `scroll-padding-top` | `scroll-padding-top: [nav-height]` |
| Mobile text too small | Hard-coded `px` | `clamp(0.875rem, 2.5vw, 1rem)` |
| Dark mode contrast fail | Color not updated | Add `@media (prefers-color-scheme: dark)` override |
references/review.md
---
name: review
description: "You are a senior design engineer reviewing interface quality - not logic or architecture. Your review is direct, specific, and actionable."
version: 1.9.0
---
# Design Engineering Code Review
You are a senior design engineer reviewing interface quality — not logic or architecture. Your review is direct, specific, and actionable.
## Parallel review architecture (multi-agent)
For a full pre-ship review, `/inspect review` dispatches four deterministic defect specialists concurrently, each scoped to one class of front-end defect. Launch them with the Task tool in a single message (one `Task` call per agent, same turn) so they run in parallel. Pass each agent the target file(s) or URL plus any source already in context.
| Sub-agent (`subagent_type`) | Class | Covers |
|---|---|---|
| `inspect-agent-a11y` | Accessibility | contrast, focus indicators, keyboard operability, ARIA, alt text, labels |
| `inspect-agent-interaction` | Interaction | target size and spacing, interactive states, feedback, placeholder-as-label |
| `inspect-agent-layout` | Layout | overflow/clipping, z-index, horizontal scroll, CLS sources, breakpoint breakage |
| `inspect-agent-code` | Code quality | semantic HTML, token discipline, forbidden CSS patterns, motion crimes |
Each agent returns its scored section. Wait for all four, then merge into the tiered checklist below, triaging Tier 1 (must fix) first. If the Task tool or plugin agents are unavailable in the current harness, run the tiered checklist inline instead. Never skip a class silently. For a whole-site pass that also covers search visibility and design quality, use `/audit`.
## What You Check
### Tier 1 — Must fix before shipping
**Motion crimes:**
- `transition: all` → specify exact properties
- `ease-in` on any UI animation → use `ease-out` or custom curve
- Duration > 300ms on interactive UI feedback
- Animating keyboard-initiated actions
- `scale(0)` as animation start → must be `scale(0.95)` minimum
- Missing `@media (prefers-reduced-motion: reduce)` on any animation
- Parallax section without `@media (prefers-reduced-motion: reduce)` neutralizer
- Parallax layer using `background-attachment: fixed` (iOS Safari breakage)
- Parallax scroll handler without `{ passive: true }`
- Body text or interactive control inside a moving parallax layer
- Multi-layer parallax active below 768px viewport
- Animating `width`, `height`, `top`, `left`, or margin on a parallax layer
**Parallax Core Web Vitals violations:**
- LCP candidate occluded by a parallax layer without `fetchpriority="high"`
- Layer image above 200 KB or not in AVIF/WebP
- Layer container without explicit `aspect-ratio` or `width`/`height` (CLS risk)
- `will-change: transform` declared permanently instead of toggled per active state
**Accessibility violations:**
- Interactive element with no accessible name (icon-only button, no `aria-label`)
- `<div>`/`<span>` used as button/link with no `role`, `tabindex`, keyboard handler
- Form input with no `<label>` (placeholder-only is not a label)
- `outline: none` / `outline: 0` with no `:focus-visible` replacement
- `aria-hidden="true"` on an element that receives focus
- Dynamic content inserted without `role="alert"` or `aria-live`
**WCAG 2.2 violations:**
- Focus indicator obscured by sticky header or floating element (2.4.11)
- Interactive target under 24x24 CSS pixels without 24px clearance (2.5.8)
- Drag interaction without a single-pointer alternative (2.5.7)
- Login flow requires cognitive test without alternative (3.3.8)
- Multi-step form re-asks information already provided (3.3.7)
- Paste disabled on password or one-time-code fields
**Image strategy violations:**
- LCP image lazy-loaded or missing `fetchpriority="high"`
- `<img>` missing explicit `width` and `height`
- `srcset` declared without `sizes`
- Hero image served only as JPEG/PNG with no AVIF/WebP alternative
- Meaningful content delivered as `background-image` instead of `<img>`
**Form pattern violations:**
- Placeholder used as sole label
- Submit button permanently disabled without surfacing missing fields
- Validation firing on first keystroke
- Standard input missing `autocomplete` attribute (email, tel, name, password)
- Error message not linked to input via `aria-describedby`
**Forbidden design patterns:**
- `border-left`/`border-right` > 1px as colored accent stripe
- `background-clip: text` gradient on non-hero type
- `#000` or `#ffffff` — use tinted neutrals
- `z-index` above 100 without semantic meaning
- Animating `width`, `height`, `top`, `left`, `margin` — use `transform`
### Tier 2 — Fix if time allows
**Token / CSS architecture:**
- Hardcoded colour values instead of CSS custom properties
- Magic number spacing (e.g., `margin: 13px`) — should be from spacing scale
- Missing dark mode support
- CSS variable used but `color-scheme` not set on `:root`
**Typography:**
- `font-family: Inter` → suggest Geist, Satoshi, or Cabinet Grotesk
- Missing `text-wrap: balance` on headings
- Body text wider than 75ch without `max-width`
- `px` for font sizes — use `rem`
**Layout:**
- `h-screen` on hero → use `min-height: 100dvh`
- `width: 100vw` without overflow protection
- Three-column equal card grid
**Content:**
- Placeholder data ("John Doe", "Acme Corp") in shipped UI
- AI copywriting clichés: "Elevate", "Seamless", "Unleash", "Next-Gen"
**Parallax craft:**
- No manual motion toggle exposed (WCAG 2.2.2 best practice)
- Reduced-motion fallback differs in content from the animated version
- Two competing parallax patterns layered in the same viewport
- Lenis or equivalent running with `smoothTouch: true`
- Mouse-driven parallax with no static fallback on touch
- Adaptive intensity not wired to `navigator.connection`, battery, or hardware tier
- Scroll-driven `animation-timeline` available but unused, falling back to JS handlers unnecessarily
### Tier 3 — Craft improvements
- Missing stagger on list item reveals
- No `@starting-style` for element entry animations
- Opportunity for `clip-path` animation where basic fade is used
- No skeleton loader for async content
## Process
1. **Read** target file(s)
2. **Run** `npx impeccable --json [target]` if applicable
3. **Scan** each tier in the checklist
4. **Output** as Before/After table
5. **If parallax is present** (`.parallax-*`, `animation-timeline`, GSAP `ScrollTrigger`, Lenis), also run `node "${CLAUDE_PLUGIN_ROOT}/skills/siteasy/scripts/parallax-audit.mjs" <target>` and append a "Parallax Vitals" sub-table reporting FPS min/avg, LCP, CLS, INP, and the count of failed parallax anti-patterns. A failing parallax audit caps the overall Score at 5/10 regardless of other strengths.
## Output Format
```markdown
## Design Engineering Review — [filename]
[1-2 sentence summary: overall quality and most critical finding]
### Tier 1 — Must fix
| Before | After | Why |
|--------|-------|-----|
| `transition: all 300ms` | `transition: transform 200ms ease-out` | `all` animates unexpected properties |
### Tier 2 — Should fix
...
### Tier 3 — Worth noting
...
**Score: [X]/10** — [one sentence verdict]
```
Scores: 9-10 ship it · 7-8 minor fixes · 5-6 fix T1 first · 3-4 substantial work needed · 1-2 reconsider approach.
After the review, offer: "Want me to apply the Tier 1 fixes?"
SKILL.md
---
name: inspect
description: "Use when the user wants to scan for design anti-patterns, take a browser screenshot, or do a design engineering code review. Covers: missing focus rings, clipped dropdowns, bad z-index, placeholder-as-label, missing reduced-motion (detect); real Chromium screenshots, mobile/desktop viewports, visual bug fixing (preview); motion crimes, accessibility violations, forbidden CSS patterns, token misuse, Before/After review table (review). Use when the user says: 'screenshot this', 'check for anti-patterns', 'scan my code', 'review before I ship', 'show me what this looks like', 'are there visual bugs', 'critique my code'."
version: 1.14.0
user-invocable: true
argument-hint: "[detect|preview|review] [path/to/file | https://url | paste code]"
allowed-tools:
- Bash(npx impeccable *)
- Bash(npx playwright *)
- Bash(node *)
- Bash(python3 -m http.server *)
- Bash(npx serve *)
- Bash(kill *)
- Bash(lsof *)
- Read
- Write
- Edit
- Task
---
Three quality-check tools in one — run before every ship.
## Commands
| Command | What it does | Reference |
|---------|-------------|-----------|
| `detect [target]` | Deterministic anti-pattern scan — finds focus rings, clipped dropdowns, pure black/white, tiny touch targets, missing reduced-motion, and more | [references/detect.md](references/detect.md) |
| `preview [target]` | Real Chromium screenshot — desktop + mobile viewports, reads back visually, fixes bugs in a loop | [references/preview.md](references/preview.md) |
| `review [file]` | Design engineering code review — motion crimes, a11y violations, forbidden patterns, Before/After table with score | [references/review.md](references/review.md) |
## When to use which
| Situation | Command |
|-----------|---------|
| "Are there any design problems in my code?" | `detect` |
| "What does my site actually look like?" | `preview` |
| "Review my code before I ship" | `review` |
| Just built something with `/siteasy build` | `preview` → `detect` → `review` |
## Severity order
Triage findings highest severity first: fix CRITICAL before HIGH, HIGH before MEDIUM, MEDIUM before LOW. This mirrors the priority order `/siteasy` builds against, so detection and construction never disagree on what to fix first.
| # | Category | Severity |
|---|----------|----------|
| 1 | Accessibility (contrast, focus rings, alt text, keyboard, aria-labels) | CRITICAL |
| 2 | Touch and interaction (target size: 24x24px CSS minimum per WCAG 2.5.8 AA, 44x44px recommended for touch; spacing, feedback) | CRITICAL |
| 3 | Performance and Core Web Vitals (WebP/AVIF, lazy-load, CLS, LCP) | HIGH |
| 4 | Structure and semantics (heading order, landmarks, valid HTML) | HIGH |
| 5 | Layout and responsive (breakpoints, viewport, no horizontal scroll) | HIGH |
| 6 | Typography and color (sizes, line-height, semantic tokens) | MEDIUM |
| 7 | Motion (duration, meaning, prefers-reduced-motion) | MEDIUM |
| 8 | Forms and feedback (labels, inline errors, autocomplete) | MEDIUM |
| 9 | Navigation (back behavior, primary items, active state) | MEDIUM |
| 10 | Data and charts (legends, tooltips, accessible encoding) | LOW |
## Detection rules from data
Beyond the deterministic scan, `detect` can read `tools/data/inspect-rules.csv` for editable Do/Don't rules with good and bad code examples (27 rules) — extend coverage without changing code. To locate a relevant reference fast: `node tools/search-references.mjs "<topic>" --skill inspect`.
## Quick start
If no command is specified:
- With a URL or file path → default to `preview`
- With pasted code → default to `review`
- Otherwise ask: "Do you want a screenshot, an anti-pattern scan, or a code review?"
## Requirements
The `detect` and `review` commands call the `impeccable` CLI through `npx`. It requires Node.js and is fetched on first run. Tested with impeccable 2.3.2. To pin the version and avoid drift from upstream flag changes, run `npx impeccable@2.3.2` instead of `npx impeccable`.
## Recommended pre-ship sequence
```
/inspect detect index.html ← catch obvious anti-patterns first
/inspect preview index.html ← see what it looks like in a real browser
/inspect review index.html ← final engineering quality gate
```