# UX Audit

> Run a UX/UI audit on a web project. Scans for hardcoded CSS values, accessibility violations, design token inconsistencies, and component patterns. Outputs to Figma (canvas API), reveal.js slide deck, or scrollable HTML. Publish to Vercel/Netlify/Surge. Defaults to @rolemodel/optics but configurable for any design system.

- Skill: `rolemodel/ux-audit` (Agent Skill, multi-file: 44 files)
- Install (CLI): `npx skillmds@latest add rolemodel/ux-audit`
- Raw SKILL.md: https://api.skillmd.com/api/skills/rolemodel/ux-audit/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Design & Media
- Author: rolemodel (https://skillmd.com/u/rolemodel)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/rolemodel/ux-audit

---


# UX/UI Audit Skill

Run structured UX/UI audits on web projects in **two sessions**:

1. **Discovery & Review** — Scan the codebase, identify findings, and walk through them interactively with the team. This is an internal conversation — collaborative, iterative, and thorough.
2. **Client Report** — After design work is complete (Figma mockups, prototypes), come back to generate the polished client-facing deliverable with real screenshots, video walkthroughs, and interactive embeds.

Output to **reveal.js** (component-based slide deck), **Figma** (direct canvas write), or **scrollable HTML**. Publish to Vercel, Netlify, or Surge. Generate DTCG token JSON only when the audit explicitly needs importable token artifacts.

## Workflow Overview

```
┌─────────────────────────────────────────────────┐
│  SESSION 1: Discovery & Review                  │
│                                                 │
│  Phase 1: Codebase scan + tech stack detection  │
│  Phase 2: Design token mapping                  │
│  Phase 3: Heuristic audit (10 sections)         │
│  Phase 4: Interactive review ← YOU ARE HERE     │
│           Walk each finding with the team.       │
│           Confirm, reject, reprioritize.         │
│           Output: reviewed-findings.json         │
│                                                 │
│  ⏸  PAUSE — Design work happens here            │
│     Figma mockups, prototypes, redesigns         │
│                                                 │
│  SESSION 2: Client Report                       │
│                                                 │
│  Phase 5: Report generation (reveal/figma/html) │
│           Pull screenshots from Figma designs    │
│           Add video walkthrough + interactive    │
│           embed if available                     │
│  Phase 6: Figma deliverables + optional tokens  │
│  Phase 7: Publish to web                        │
└─────────────────────────────────────────────────┘
```

## Prerequisites

Run the setup script from the repo root — it checks everything and tells you what's missing:

```bash
./scripts/setup.sh
```

**What's needed:**

| Dependency | Required? | Purpose |
|-----------|-----------|---------|
| Claude Code CLI | Yes | Runtime for the skill |
| Node.js 18+ | Yes | Token generation scripts (.mjs) |
| Figma plugin | Recommended | Screenshots, canvas writes, design inspection |
| ripgrep (`rg`) | Optional | Powers `scan-hardcoded-values.sh` |
| GitHub CLI (`gh`) | Optional | Project search from GitHub in `run-audit-agent.sh` |

**Figma skills used by this audit:**

| Skill | When used | Purpose |
|-------|-----------|---------|
| `figma-use` | **Every** `use_figma` call (mandatory) | Loads Plugin API context; skipping it causes hard-to-debug failures |
| `figma-generate-design` | Phase 5–6 (Figma format) | Section-by-section canvas assembly using design system tokens |
| `figma-create-new-file` | Phase 6 (template duplication) | Creates the project-specific audit file from the template |

Without the Figma plugin, the skill still works — it skips Figma-dependent features and uses reveal.js or HTML output instead.

## Invocation

Most users only need two commands — one for each session:

| Command | What it does |
|---------|-------------|
| `/ux-audit` | **Session 1**: Scans the codebase, maps tokens, runs the heuristic audit, then walks you through each finding interactively. Ends with a reviewed findings file and instructions for the design phase. |
| `/ux-audit report` | **Session 2**: After design work is done, generates the client-facing report with screenshots, video, and embeds. Offers to publish when complete. |

That's it. Phases run automatically within each session — the user never needs to think about phase numbers.

### Advanced: Individual Phase Commands

For power users, CI, or re-running a specific step:

```bash
/ux-audit scan          # Phase 1 only: tech stack + codebase scan
/ux-audit tokens        # Phase 2 only: design token mapping
/ux-audit audit         # Phase 3 only: heuristic audit (10 sections)
/ux-audit review        # Phase 4 only: interactive finding review
/ux-audit report        # Phase 5 only: generate the client report
/ux-audit figma         # Phase 6 only: Figma deliverables + optional token JSON
/ux-audit publish       # Phase 7 only: deploy to Vercel/Netlify/Surge
```

### Shell Scripts

```bash
# Interactive — prompts for everything
./scripts/run-audit-agent.sh

# Non-interactive (CI/automation)
./scripts/run-audit-agent.sh ~/Development/my-app --client --reveal

# Publish with guided setup (checks auth, installs CLI if needed)
./scripts/publish-report.sh
```

### Audience Mode

Every audit runs in one of two modes. If not specified, ask the user.

- `/ux-audit --internal` — **Internal/Technical mode**: direct language, developer-focused, names specific code issues, uses severity labels (Critical/High/Medium/Pattern)
- `/ux-audit --client` — **Client-facing mode**: Uses the **"Then / Now / Next"** narrative arc from [references/team-guide.md](references/team-guide.md). Diplomatic language, frames findings as improvement opportunities, acknowledges existing quality, never paints the project as "bad" or "poorly built." Findings are organized by **4 thematic lenses** (Experience Gaps, Visual & Brand Coherence, Modernization Moments, Strategic Opportunities) — NOT by severity. The report should feel like "a magazine, not a bug report."

The mode can also be set in `.ux-audit.json` via `"audience": "internal"` or `"audience": "client"`.

### Output Format

Three output formats are available. Set via CLI flag or `"format"` in `.ux-audit.json`:

| Format | Flag | Description | Best For |
|--------|------|-------------|----------|
| **reveal** | `--reveal` | Self-contained reveal.js slide deck (HTML + inlined CSS + CDN JS). Arrow keys, swipe, or click to navigate. | Web sharing, presentations, PDF export |
| **figma** | `--figma` | Direct write to Figma canvas via Plugin API. Uses the [Figma template](references/figma-workflow.md) as the visual structure. | Editable design deliverables, client collaboration |
| **html** | `--html` | Scrollable single-page HTML with companion CSS. | Internal reviews, print |

- `reveal` and `figma` are only valid with `--client` mode
- Default format is `"reveal"` for client mode, `"html"` for internal mode
- `reveal` format supports PDF export via `?print-pdf` query parameter (see [reveal.js PDF docs](https://revealjs.com/pdf-export/))
- `figma` format requires the Figma Desktop MCP server (`b20fbcc1`) connected
- All formats support web publishing via `./scripts/publish-report.sh` (Vercel, Netlify, or Surge)

See [references/tone-guide.md](references/tone-guide.md) for detailed language rules for each mode.
See [references/team-guide.md](references/team-guide.md) for the complete client audit philosophy and deliverable structure.
See [references/paged-document-handoff.md](references/paged-document-handoff.md) for the handoff from reviewed findings into a branded paged-document artifact.
See [references/figma-workflow.md](references/figma-workflow.md) for the Figma canvas workflow.

### Required References

Read these files before beginning any audit phase:

- **[references/laws-of-ux.md](references/laws-of-ux.md)** — The 21 Laws of UX with review checklists, code examples, and review flags. Use as the authoritative source for all UX principle evaluations in Phase 3 and the UX Principles Assessment in Phase 4.
- [references/tone-guide.md](references/tone-guide.md) — Language rules for internal vs client mode
- [references/team-guide.md](references/team-guide.md) — Client audit philosophy and deliverable structure
- [references/severity-model.md](references/severity-model.md) — Finding classification (Critical/High/Medium/Pattern)
- [references/audit-checklist.md](references/audit-checklist.md) — Scan patterns for hardcoded values

### Additional Arguments

Arguments after the phase name are passed as context. For example:
- `/ux-audit scan app/javascript/stylesheets` — scan only that directory
- `/ux-audit figma gnJ9S1Bf1o8cWIxKpCy1Ec` — push to a specific Figma file

## Configuration

Look for `.ux-audit.json` in the project root. If it does not exist, ask the user these questions and create it:

1. **Audience** — `"internal"` (developer team) or `"client"` (external stakeholder). Default: `"client"`.
2. **Output format** — `"reveal"` (slide deck), `"figma"` (canvas write), or `"html"` (scrollable). Default: `"reveal"` for client, `"html"` for internal.
3. **Target design system** — default: `@rolemodel/optics`. Accept any CSS framework name.
4. **Brand primary color** — accept hex (#F7BD04), HSL (hsl(46, 97%, 49%)), or "use default"
5. **Brand font family** — default from project's existing CSS
6. **Portfolio URL** — URL to the company portfolio page (for cover image + client logo scraping). Example: `https://rolemodelsoftware.com/portfolio`
7. **Case study URL** — URL to the project's case study page (for narrative context). Optional.
8. **Figma file key** — target file, or "create new", or "skip"
9. **Publish provider** — `"vercel"` (default), `"netlify"`, or `"surge"`
10. **Output directory** — default: `dev-tools/ux-audit-output`

Config schema:

```json
{
  "audience": "client",
  "format": "reveal",
  "designSystem": {
    "name": "optics",
    "package": "@rolemodel/optics",
    "version": "2.3.0",
    "tokenPrefix": "--op-"
  },
  "brand": {
    "name": "ProjectName",
    "primaryHue": 46,
    "primarySaturation": 97,
    "primaryLightness": 49,
    "neutralHue": 226,
    "neutralSaturation": 5,
    "fontFamily": "DM Sans",
    "caseStudyUrl": null,
    "portfolioUrl": null
  },
  "figma": {
    "fileKey": null,
    "templateKey": "iyfRvWyTHSbNYtpBcjuvGg",
    "outputMode": "newFile"
  },
  "publish": {
    "provider": "vercel",
    "projectName": null
  },
  "outputDir": "dev-tools/ux-audit-output",
  "appUrl": "http://localhost:3000"
}
```

The `audience` field accepts `"internal"` or `"client"`. This controls:
- Report template selection (technical vs client-facing)
- Report structure (severity-based vs Then/Now/Next with 4 thematic lenses)
- Finding language and tone (direct vs diplomatic, "what we observed" + "what this means for users")
- Executive summary framing (stats-driven vs narrative paragraph + callout)

The `format` field accepts `"reveal"` (default for client), `"figma"`, or `"html"`:
- **`"reveal"`** — Component-based HTML slide deck built from the bundled `revealjs-template/` assets. Shareable via URL, PDF-exportable via `?print-pdf`. Only valid with `audience: "client"`.
- **`"figma"`** — Direct write to Figma canvas via the Plugin API. Uses the template at `figma.templateKey` as the visual structure. The agent duplicates the template, then populates it section-by-section. Only valid with `audience: "client"`. Requires Figma Desktop MCP.
- **`"html"`** — Scrollable single-page HTML with companion CSS file. Works for both audience modes.

The `brand.portfolioUrl` field (e.g., `"https://rolemodelsoftware.com/portfolio"`) is used to **web-scrape the cover image and client logo**. The scraper looks for `data-framer-background-image-wrapper` elements on Framer-built portfolio pages to find the project card with the hero background and logo overlay.

The `figma` section controls Figma output:
- `fileKey` — Target Figma file for output (or `null` for new file)
- `templateKey` — Figma template file key (default: `"iyfRvWyTHSbNYtpBcjuvGg"`)
- `outputMode` — `"newFile"` (duplicate template) or `"existingFile"` (write to fileKey)

The `publish` section controls static deployment:
- `provider` — `"vercel"` (default), `"netlify"`, or `"surge"`
- `projectName` — override the deployed project name (default: `{brand.name}-assessment` slugified). This becomes the Vercel subdomain, e.g. `rapidair-assessment.vercel.app` — keep it clean and client-facing, no internal tool names.

When `designSystem.name` is `"optics"`, use the Optics MCP tools (`mcp__optics__*`) for token lookups, component mapping, and contrast checking. For any other design system, fall back to Grep/Read-based analysis.

### Token artifact rule

Phase 2 always maps observed values to the target design system because that helps the audit explain drift, contrast risk, and remediation effort. **Do not assume new token files are needed.** DTCG token JSON generation is conditional and should only run when at least one of these is true:

- the user explicitly asks for Figma Variables import files;
- `.ux-audit.json` has `"tokens": { "generate": true }`;
- the target design system does not already exist in the destination Figma file and the team needs a portable token artifact;
- the audit deliverable includes a formal token migration package, not just a report.

Skip token JSON generation when the product already has an adequate design system and the audit only needs mapping tables, remediation notes, screenshots, or a client report. When skipping, say: `Token JSON skipped — mapping documented in report; no importable token artifact requested.`

### Figma MCP Usage Limits

Figma MCP tool calls are **rate-limited by plan** — not billed per request, but hard-capped daily. Exceeding the limit locks you out for the rest of the day. Plan accordingly.

| Plan + Seat Type | Daily Limit | Per-Minute |
|-----------------|-------------|------------|
| Enterprise (Full/Dev) | 600 calls/day | unlimited |
| Pro/Organization (Full/Dev) | 200 calls/day | 15–20/min |
| Starter or View/Collab | **6 calls/month** | — |

**Estimated usage per audit phase:**

| Operation | Estimated Calls | Notes |
|-----------|----------------|-------|
| Read design context (`get_design_context`) | 3–8 | Depends on number of screens inspected |
| Get screenshots (`get_screenshot`) | 3–10 | One per finding with a mockup |
| Get metadata (`get_metadata`) | 1–3 | Structure overview |
| Search design system (`search_design_system`) | 2–5 | Component/variable discovery |
| Write to canvas (`use_figma`) | 10–30 | Section-by-section population |
| **Full audit (read + write)** | **~20–55 calls** | ~25% of Pro daily limit |
| **Read-only audit (no Figma output)** | **~8–15 calls** | Screenshots + context only |

**Exempt from rate limits:** `generate_figma_design` (HTML capture), `add_code_connect_map`, `whoami`.

**Before running Figma phases**, the agent should:
1. Estimate the number of calls needed based on finding count
2. Warn the user: *"This audit will use approximately N of your 200 daily Figma MCP calls. Proceed?"*
3. If the user is on a Starter/View plan (6/month), warn strongly and suggest using the reveal.js HTML format instead

**To minimize usage:**
- Use `format: "reveal"` (HTML) for the report — zero Figma write calls
- Pull screenshots in batch (`get_screenshot` for multiple nodes in sequence)
- Only use `format: "figma"` when the client specifically needs an editable Figma deliverable

## Phase 1: Tech Stack Detection + Codebase Scan

**Goal**: Identify the project's tech stack and scan for all hardcoded values.

### Pre-flight: Locate the Project

If the current working directory doesn't look like a project (no `Gemfile`, `package.json`, or source files), ask the user:

*"I don't see a project here. What's the project name?"*

Then attempt to find it:

1. **Search locally** — check common paths:
   ```bash
   ls -d ~/Development/{name} ~/projects/{name} ~/code/{name} 2>/dev/null
   ```

2. **Search GitHub** — if not found locally, search the org:
   ```bash
   gh repo list RoleModel --limit 100 --json name,url | jq '.[] | select(.name | test("name"; "i"))'
   ```
   If found, offer to clone it:
   ```
   Found "RoleModel/{name}" on GitHub. Clone it to ~/Development/{name}? (yes/no)
   ```
   Clone with:
   ```bash
   gh repo clone RoleModel/{name} ~/Development/{name}
   ```

3. **If nothing found** — ask the user for the full path or repo URL.

Once the project directory is confirmed, `cd` into it and proceed.

### Steps

1. **Detect tech stack** by checking for:
   - `Gemfile` → Rails (check version in Gemfile.lock)
   - `package.json` → check for react, vue, svelte, next, nuxt, angular
   - `.scss` files → SCSS preprocessor
   - `tailwind.config.*` → Tailwind CSS
   - `@rolemodel/optics` in package.json → Optics already present
   - Determine templating: `.slim`, `.erb`, `.haml`, `.tsx`, `.jsx`, `.vue`

2. **Find all stylesheet files** using Glob:
   - `**/*.scss`, `**/*.css`, `**/*.less` (excluding node_modules, vendor)
   - Also check JSX/TSX for inline styles: `**/*.jsx`, `**/*.tsx`

3. **Scan for hardcoded values** using Grep on each stylesheet file. Reference [references/audit-checklist.md](references/audit-checklist.md) for the complete list of patterns. Key patterns:
   - Hex colors: `#[0-9a-fA-F]{3,8}`
   - Pixel values in spacing properties: `(padding|margin|gap|top|right|bottom|left).*\d+px`
   - Hardcoded font-size: `font-size:\s*\d`
   - Literal box-shadow: `box-shadow:` not followed by `var(`
   - Literal border-radius: `border-radius:` not followed by `var(`
   - Exclude values in comments (`//` and `/* */` lines)

4. **Detect existing token systems**:
   - CSS custom properties: `--[a-z]` declarations in `:root` or `html`
   - SCSS variables: `\$[a-z]` declarations
   - Count which files USE tokens vs hardcode values

5. **Fetch cover image, client logo, and case study context**:

   Image sourcing uses **two URLs** from config — `brand.portfolioUrl` for the card images and `brand.caseStudyUrl` for narrative context.

   **Cover image + client logo** (from `brand.portfolioUrl`):

   The portfolio page (e.g., `https://rolemodelsoftware.com/portfolio`) contains project cards — each with a background image and overlaid client logo. These are inside `data-framer-background-image-wrapper` elements on Framer-built sites.

   ```bash
   # Scrape portfolio page for project card images
   # The page may lazy-load cards — use "Load More" button or fetch the full DOM
   curl -sL "{portfolioUrl}" | grep -oP 'data-framer-background-image-wrapper[^<]*<img[^>]+src="[^"]+"' | grep -oP 'src="\K[^"]+'
   ```

   To find the **correct project card**:
   1. Search the page for the project name (case-insensitive) — it may be in an `alt` attribute, nearby text, or link href
   2. The card's `data-framer-background-image-wrapper` `<img>` gives you the **hero background image**
   3. Look for a second image inside the same card container — this is typically the **client logo** (often an SVG or white-on-dark logo)
   4. If the portfolio uses pagination ("Load More"), the project may not be in the initial HTML — note this for the user

   Store as:
   - `HERO_IMAGE_URL` → `{{HERO_IMAGE_URL}}` template placeholder (cover slide background)
   - `CLIENT_LOGO_URL` → `{{CLIENT_LOGO_URL}}` template placeholder (cover slide logo)

   If nothing found or fetch fails, keep the cover on the dark token fallback (`--dark`).

   **Hero image from case study page** (fallback if portfolio scrape fails):
   ```bash
   curl -sL "{caseStudyUrl}" | grep -oP 'data-framer-background-image-wrapper[^<]*<img[^>]+src="\K[^"]+'  | head -5
   ```
   Pick the image that visually represents the project (product photography or hero scene, not the company logo or abstract blur).

   **Case study narrative context** — used to write the report:
   Use `WebFetch` on the `caseStudyUrl` with this prompt: *"Extract: (1) the problem or business need the software solved, (2) key features or capabilities built, (3) any outcomes, metrics, or impact statements, (4) quotes or notable language used to describe the product. Return as structured bullet points."*

   Store this as `CASE_STUDY_CONTEXT`. Use it in Phase 4 to:
   - **"Then" section**: ground the strengths in the original business purpose. Instead of "the app has autosave", write "autosave was built to support long design sessions in the field — and it works." Use the case study's language about what was accomplished and why.
   - **Executive Summary narrative**: reference real outcomes or impact language from the case study rather than generic framing.
   - **"Now" framing**: frame current gaps as *evolved expectations*, not failures. "When this was built, X — today users expect Y."
   - Never fabricate outcomes — only use what the case study explicitly states. If the case study is vague, use it for tone and domain context only.

6. **Report summary** to user:
   ```
   Phase 1 Complete: Codebase Scan
   Tech stack: [framework] + [frontend lib], [preprocessor]
   Files scanned: N stylesheet files
   Hardcoded hex colors: N across M files
   Hardcoded pixel values: N across M files
   Hardcoded font sizes: N
   Existing CSS vars: N
   Existing SCSS vars: N
   Design system in use: [name or "none"]
   ```

Store all findings in memory for subsequent phases.

## Phase 2: Design Token Mapping

**Goal**: Map every existing token and hardcoded value to the target design system.

### Steps

1. **Collect unique values** from Phase 1 scan:
   - Deduplicate hex colors
   - Deduplicate spacing/size values
   - Deduplicate font-size values
   - Deduplicate shadow definitions
   - Deduplicate border-radius values

2. **Map to target design system**:

   **If Optics** (use MCP tools):
   - For each unique color: call `mcp__optics__suggest_token_migration` with the hex value
   - For foreground/background pairs in CSS: call `mcp__optics__check_contrast`
   - For spacing: compare against `mcp__optics__search_tokens` category "spacing"
   - For border-radius: compare against `mcp__optics__search_tokens` category "border"
   - For shadows: compare against `mcp__optics__search_tokens` category "shadow"
   - For typography: compare against `mcp__optics__search_tokens` category "typography"
   - Use `mcp__optics__list_components` to identify mappable components

   **If NOT Optics** (grep-based):
   - Read the target system's CSS/token files from node_modules or docs
   - Build mapping table manually by comparing values
   - Use WebSearch if needed to find documentation

3. **Classify each mapping**:
   - **Exact**: Values match exactly
   - **Close**: Values within reasonable tolerance (e.g., 2px spacing, 5% color)
   - **Miss**: No good equivalent in target system
   - **WCAG Fail**: Current value has a contrast issue

4. **Report summary**:
   ```
   Phase 2 Complete: Token Mapping
   Colors mapped: N/M (X exact, Y close, Z miss)
   Spacing mapped: N/M
   Border radius: N/M
   Typography: N/M
   Shadows: N/M
   Components mappable: N of M
   WCAG contrast failures: N
   ```

## Phase 3: Heuristic Audit

**Goal**: Walk the product through the 10 UX sections from [references/day-1-audit-checklist.html](references/day-1-audit-checklist.html) and produce classified findings for each. Combine observable heuristic evaluation (via `appUrl` or provided screenshots) with static code analysis patterns.

Apply the 21 Laws of UX from [references/laws-of-ux.md](references/laws-of-ux.md) throughout this phase. Use the Review Checklist to identify which laws are relevant to each section, and cite specific laws when documenting findings.

Run all 10 sections. For each section, produce a list of findings classified by severity using [references/severity-model.md](references/severity-model.md).

### Section 1: First Impressions & Visual Coherence

Walk the app at `appUrl` (or use screenshots if provided). Check:

- Does the product make a strong first impression? Is the purpose clear in the first 30 seconds?
- Is the visual language consistent? Check button styles, typography, color usage, spacing, and iconography across multiple screens.
- Does the brand come through clearly?
- Is there visual hierarchy on key screens — can you tell what's most important at a glance?
- Is the color system doing meaningful work (semantic usage) or are colors arbitrary?
- Does the typography scale feel intentional? Are heading levels distinct?

Code scan support: count unique hex colors and font-size values from Phase 1 to quantify inconsistency.

### Section 2: Navigation & Wayfinding

- Is the navigation structure predictable (follows conventions users know)?
- Do users always know where they are? Active states, breadcrumbs, page titles?
- Are navigation labels clear, plain-language, jargon-free?
- Is navigation depth appropriate (≤3 clicks to most things)?
- Does navigation work on mobile?
- Are there dead ends — screens with no clear path forward or back?

Code scan support: grep for `display: none` inside media queries (content being hidden vs adapting).

### Section 3: Cognitive Load & Complexity

- Are screens trying to do too much? Flag pages with overwhelming options or decisions.
- Is information chunked effectively — related items grouped, easy to scan?
- Are forms as simple as possible? Extra fields, illogical order?
- Does the UI use meaningful defaults to reduce decisions?
- Is the language plain and direct, or does it require interpretation?
- Are there progress indicators for multi-step processes?

### Section 4: Key Flows & Task Completion

Identify the top 2–3 core user tasks before evaluating this section. Walk each flow end to end.

- Is the entry point obvious?
- Are calls to action clear and appropriately sized?
- Does the flow match the user's mental model of the task?
- Are there unnecessary interruptions or confirmation steps?
- Are error states handled gracefully — clear, human, actionable?
- Does the product handle edge cases (empty states, long content, slow connections)?
- What is the peak moment and ending of each flow — are they positive?

### Section 5: Feedback & System Communication

- Does the product acknowledge user actions (buttons, form submissions)?
- Are loading states handled with visual feedback?
- Are success and error states distinct and immediately clear?
- Is undo/back behavior predictable?
- Are notifications and alerts used appropriately (not over-interrupting)?

Code scan support: grep for loading spinner patterns; grep for success/error toast/flash component usage.

### Section 6: Consistency & Standards

- Do similar elements behave the same way throughout?
- Does the product follow platform conventions (web, iOS, Android)?
- Is the component set stable, or are there one-off UI elements?
- Are interactive elements visually distinguishable from static ones?

Code scan support: Phase 1 hardcoded value counts per file indicate where visual drift is concentrated.

### Section 7: Accessibility

Static code analysis — grep the codebase for each of the following:

**Focus management**:
- `outline:\s*(none|0)` without corresponding `:focus-visible` replacement
- Missing skip-nav link (`[href="#main"]` or similar)
- Missing `<main>` landmark

**ARIA issues**:
- `role="menu"` on `<nav>` elements (incorrect — should be `navigation`)
- Buttons/toggles missing `aria-expanded`
- Icon-only buttons missing `aria-label`
- `<img` without `alt` attribute
- `<iframe` without `title` attribute
- Modals without `role="dialog"` and `aria-modal="true"`

**Semantic HTML**:
- `<a>` wrapping `<button>` (or vice versa)
- `<div>` with click handlers but no `role="button"` or `tabindex`
- `user-scalable=no` or `maximum-scale=1` in viewport meta

**Color contrast**:
- For each foreground/background pair identified in Phase 1, check WCAG AA ratio
- If Optics: use `mcp__optics__check_contrast`
- Flag anything below 4.5:1 (normal text) or 3:1 (large text)

**Form accessibility**:
- `<input>` without associated `<label>` or `aria-label`
- `<select>` placeholder options not `disabled`
- Missing `aria-required` on required fields
- No inline validation (submit-only)

Also note observable accessibility gaps from the product walkthrough: tap target sizes, motion, color-only status indicators.

### Section 8: Mobile & Responsive Behavior

- Does the layout adapt gracefully across breakpoints (mobile, tablet, desktop)?
- Are touch targets appropriately sized (minimum 44×44px)?
- Is any content hidden on mobile that's visible on desktop?
- Does the navigation pattern work on mobile? Is it thumb-friendly?
- Do forms work on mobile keyboards (correct input types, numeric for phone)?

Code scan support: grep for `@media` queries and `display: none` patterns within them.

### Section 9: Performance Perception

Observable only — not a technical perf audit:

- Does the product feel fast? Note any perceived slowness during loading, transitions, interactions.
- Are images and media obviously oversized?
- Are transitions and animations additive or distracting?

### Section 10: Strategic & Forward-Looking Notes

Step back from individual findings:

- What is the product's single strongest moment? What should be protected and built on?
- Where is the product most constrained by past decisions?
- What 1–2 changes would have the highest user impact with moderate effort?
- Is there a meaningful modernization opportunity (design system, accessibility overhaul, mobile-first)?
- What does "next" look like for this product?

### Phase 3 Output

Report summary to user:

```
Phase 3 Complete: Heuristic Audit
Section 1 – First Impressions:    N findings
Section 2 – Navigation:           N findings
Section 3 – Cognitive Load:       N findings
Section 4 – Key Flows:            N findings
Section 5 – Feedback:             N findings
Section 6 – Consistency:          N findings
Section 7 – Accessibility:        N findings (M WCAG violations)
Section 8 – Mobile:               N findings
Section 9 – Performance:          N findings
Section 10 – Strategic:           N findings
Total: N findings (C critical, H high, M medium, P patterns)
```

Classify each finding using [references/severity-model.md](references/severity-model.md).

## Phase 4: Interactive Review

**Goal**: Walk through every finding with the team member running the audit. Confirm, reject, refine, and prioritize before any design work begins. This is the most important phase — it ensures the report is grounded in shared understanding, not just automated analysis.

**This phase is interactive.** Do not skip it. Do not batch-approve findings. Present each one and wait for input.

### How It Works

For each finding from Phase 3, present it to the user and ask:

1. **Present the finding** clearly:
   ```
   ── Finding 3 of 17 ─────────────────────────────
   Section: Navigation & Wayfinding
   Severity: High

   "Active nav state is missing — users can't tell where they are."

   Evidence: No .active or aria-current class on nav links.
   Files: app/views/layouts/_nav.html.slim:12-28
   ─────────────────────────────────────────────────
   ```

2. **Ask for confirmation**:
   - "Do you agree with this finding? (yes / no / modify)"
   - If **no** → mark as rejected, ask why (store the reason), move on
   - If **modify** → ask what should change (wording, severity, scope), update the finding
   - If **yes** → proceed to prioritization

3. **Ask for prioritization** (for confirmed findings):
   - "Should this be in the client report? (yes / maybe / internal-only)"
   - `yes` → included in the client deliverable
   - `maybe` → flagged for discussion, not in v1 of the report
   - `internal-only` → stays in internal notes, not shown to client

4. **Ask for design direction** (for client-facing findings):
   - "Any thoughts on the redesign direction? Or should we propose something?"
   - Capture notes like "use a floating panel instead" or "they've mentioned wanting tabs"
   - These notes inform the design work that happens between sessions

5. **Ask for grouping preference**:
   - "Which lens does this fit? (experience / visual / modernization / strategic)"
   - Default to the auto-classified lens, but let the reviewer override

### Review Output

After all findings are reviewed, write `{outputDir}/reviewed-findings.json`:

```json
{
  "reviewedAt": "2026-03-25T10:00:00Z",
  "reviewer": "Dallas",
  "totalFindings": 17,
  "confirmed": 12,
  "rejected": 3,
  "modified": 2,
  "findings": [
    {
      "id": "nav-active-state",
      "section": "Navigation & Wayfinding",
      "severity": "high",
      "title": "Active nav state is missing",
      "description": "...",
      "status": "confirmed",
      "includeInReport": true,
      "lens": "experience",
      "designNotes": "Use aria-current with visible indicator",
      "files": ["app/views/layouts/_nav.html.slim:12-28"]
    }
  ]
}
```

Also print a summary:

```
Phase 4 Complete: Interactive Review
Reviewed by: Dallas
Confirmed: 12 findings (10 for client report, 2 internal-only)
Rejected: 3 findings
Modified: 2 findings
Maybe/discuss: 2 findings

Findings saved to: {outputDir}/reviewed-findings.json

Next steps:
  1. Design work — create Figma mockups for the confirmed findings
  2. When designs are ready, run: /ux-audit report
```

### Session Break

**This is where Session 1 ends.** The team now does the design work:
- Create Figma mockups for confirmed findings
- Build prototypes if needed
- Record a video walkthrough of the redesigns
- Set up an interactive demo deploy (optional)

When designs are complete, start Session 2 with `/ux-audit report`.

---

## Phase 5: Report Generation

**Goal**: Generate the comprehensive client-facing report using confirmed findings from Phase 4 and completed design work.

### Pre-flight: Gather Design Assets

Before generating the report, ask the user about available design assets:

1. **"Where are the Figma mockups?"** — Get the Figma file key and node IDs for redesign screens. Use `mcp__figma__get_screenshot(nodeId, fileKey)` to pull them.

2. **"Is there a video walkthrough?"** — If yes, get the file path (e.g., `rapidair-demo.mp4`). This becomes a dedicated slide in the reveal deck.

3. **"Is there a live demo URL?"** — If yes (e.g., `https://rapidair.vercel.app`), this becomes an interactive embed slide using `data-background-iframe`.

4. **"Any screenshots to include?"** — Get paths to app screenshots (current state or redesigned). These go inline with each finding slide.

5. **Read `{outputDir}/reviewed-findings.json`** — This is the source of truth for which findings to include. Only findings with `"includeInReport": true` go in the client report. Use each finding's `lens`, `designNotes`, and `severity` to inform the narrative.

If `reviewed-findings.json` doesn't exist, warn the user: *"No reviewed findings found. Run `/ux-audit review` first to walk through findings with the team."* Offer to proceed with all Phase 3 findings as a fallback.

### Steps

1. **Select output path** based on audience mode and format:

   | Audience | Format | Template | Notes |
    |----------|--------|----------|-------|
    | Internal | html | [report-template.html](references/html-template/report-template.html) + [.css](references/html-template/report-template.css) | Scrollable, file paths + line numbers |
    | Client | html | [report-template-client.html](references/html-template/report-template-client.html) + [.css](references/html-template/report-template-client.css) | Scrollable, Then/Now/Next |
    | Client | html (magazine) | [report-template-magazine.html](references/html-template/report-template-magazine.html) + [.css](references/html-template/report-template-magazine.css) | 8.5×11 aspect-ratio slides, Figma-copyable |
    | Client | reveal | [revealjs-template/index.html](references/revealjs-template/index.html) + bundled assets | Reusable component-based slide deck |
    | Client | figma | [Figma template](references/figma-workflow.md) (`iyfRvWyTHSbNYtpBcjuvGg`) | Direct canvas write via Plugin API |

   **CRITICAL — Do not write any CSS.** For HTML formats, the CSS files are complete and final. Copy the template HTML and its companion CSS file verbatim into the output directory. The only style override allowed is:
   ```html
   <style>:root { --accent: #F5A623; }</style>
   ```

   **Reveal format**: Start from [references/revealjs-template/index.html](references/revealjs-template/index.html). Copy the full `revealjs-template/` bundle into the output directory, then populate the deck by composing its audit-kit web components inside `<section>` slides. Keep `audit-kit.js`, `reveal-audit-theme.css`, `local-fonts.css`, `RMS-lcon.svg`, and `fonts/` alongside `index.html`. Supports PDF export via `?print-pdf` query parameter.

   **Figma format**: Load the `figma-use` skill, then use `use_figma` to write content section-by-section to a duplicate of the Figma template. See [references/figma-workflow.md](references/figma-workflow.md) for the complete workflow. The `figma-generate-design` skill handles discovering components and assembling screens.

   **Image sourcing** (all formats):
   - **Cover image + client logo**: Web scraped from `brand.portfolioUrl` (Phase 1 step 5)
   - **Current state screenshots**: Capture from `appUrl` via Playwright or browser automation
   - **Redesign mockups from Figma**: Use `mcp__figma__get_screenshot(nodeId, fileKey)` to pull from the project's Figma design file
   - **Embedding**: For reveal/HTML, use base64 data URIs for self-contained deployment, or external URLs for lighter files. For Figma format, images are inserted via the Plugin API

2. **Apply tone rules** from [references/tone-guide.md](references/tone-guide.md):
   - All finding titles, descriptions, and executive summary language must follow the active tone guide
   - Client mode: every finding must be rewritten before inclusion (see tone guide for transformation rules)

3. Replace template placeholders:
   - `{{PROJECT_NAME}}` — from .ux-audit.json brand.name
   - `{{DESIGN_SYSTEM}}` — from .ux-audit.json designSystem.name
   - `{{ACCENT_COLOR}}` — computed from brand primary HSL
   - `{{FONT_FAMILY}}` — from .ux-audit.json brand.fontFamily
   - `{{DATE}}` — current date
   - `{{FINDING_COUNT}}` — total findings from Phase 1-3
   - `{{TECH_STACK}}` — from Phase 1 detection

4. **Populate data sections** (differs by audience):

   **Client mode** — uses **Then / Now / Next** narrative arc from team guide:

   **Executive Summary** (one page, shareable upward):
   - 3 high-level stats meaningful to non-technical readers (e.g. "7/12 UX Principles Met", "5 Accessibility Improvements", "3 Strategic Opportunities")
   - One narrative paragraph: plain language, no jargon, core opportunity + 2-3 recommended actions + shape of impact
   - One callout with the single most important takeaway

   **Then** — Honor the original work (green section):
   - 4-6 genuine strengths of the existing product
   - What were the constraints? What did it accomplish?
   - This is NOT faint praise — it's real recognition of what was built well
   - Frame: "this was well-executed for the context it was built in"

   **Now** — What's changed, organized by 4 thematic lenses:

   Each finding pairs **"what we observed"** with **"what this means for users."** Every observation must come from actually reading the application code. Never fabricate.

   - **Lens 1: Experience Gaps** — Where users have to work harder than they should. Confusing navigation, flows that don't match mental models, missing confirmations, empty states, etc.
   - **Lens 2: Visual & Brand Coherence** — Design inconsistencies that accumulate over time. Includes a **type scale visual** and **color palette visual** showing current state vs what's available in the target design system. Frame as: "there's an opportunity to make this feel like one cohesive, modern product again."
   - **Lens 3: Modernization Moments** — Table-stakes improvements since the original design: accessibility (WCAG), mobile responsiveness, component systems, focus management, keyboard navigation.
   - **Lens 4: Strategic Opportunities** — Where the product is constrained by old design decisions. What could it do that it doesn't today? This section should feel generative — a glimpse of v-next, not a punch list.

   Also include:
   - **UX Principles Assessment** — 8-12 principles from [references/laws-of-ux.md](references/laws-of-ux.md) evaluated against 

…(truncated)
