# SchoolCompare UX/UI Audit Execution Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Execute the journey-led UX/UI audit of live schoolcompare.co.uk defined in `docs/superpowers/specs/2026-07-02-ux-audit-design.md`, producing a prioritized (P0–P3) audit report at `docs/superpowers/specs/2026-07-02-ux-audit-report.md`.

**Architecture:** Five journey walk-throughs (traffic-ordered) at two viewports using Playwright browser tools against the live site, each producing a committed notes file with friction points, "works well" observations, and axe-core scan results. A cross-cutting cohesion pass compares components across pages. A final synthesis task converts notes into the prioritized report.

**Tech Stack:** Playwright MCP browser tools (`mcp__plugin_playwright_playwright__*`), axe-core 4.x injected from CDN, markdown notes committed to git.

## Global Constraints

- Audit the **live site** `https://schoolcompare.co.uk` — do not start any local server (CLAUDE.md).
- Viewports: **mobile 390×844 (primary)** and **desktop 1440×900**. Mobile findings weigh more (56% of traffic).
- A finding is valid only if it cites: a Nielsen/NN-g heuristic violation, a WCAG 2.2 AA failure, a mobile-usability standard, or an observed task-flow obstruction. No taste-only findings.
- Every finding: **evidence → argument (why it hurts parents) → recommendation → uplift indication** (which analytics number moves, direction, small/moderate/large band with reasoning — never invented percentages).
- Read-only with respect to the site: browse and inspect only; never submit forms that create/modify data (search and filter interactions are fine).
- Notes live in `docs/superpowers/specs/2026-07-02-ux-audit-notes/`; screenshots go to the session scratchpad (referenced by filename in notes, not committed).
- Analytics baseline for weighting (30 days): entries `/` 63%, `/compare` 20%, `/rankings` 6%; exits `/` 46%, `/compare` 32%, `/rankings` 13%; views `/` 52%, `/compare` 27%, `/rankings` 12%, `/admissions` 5%; school pages ~1% each (SEO long tail); 56% mobile.

**Note on tool schemas:** Playwright tools are deferred. Before first use in any task, load them:
`ToolSearch` with query `select:mcp__plugin_playwright_playwright__browser_navigate,mcp__plugin_playwright_playwright__browser_resize,mcp__plugin_playwright_playwright__browser_snapshot,mcp__plugin_playwright_playwright__browser_take_screenshot,mcp__plugin_playwright_playwright__browser_evaluate,mcp__plugin_playwright_playwright__browser_click,mcp__plugin_playwright_playwright__browser_type,mcp__plugin_playwright_playwright__browser_press_key,mcp__plugin_playwright_playwright__browser_console_messages`

---

### Task 1: Audit scaffolding + axe-core harness verified on the homepage

**Files:**
- Create: `docs/superpowers/specs/2026-07-02-ux-audit-notes/axe-snippet.js`
- Create: `docs/superpowers/specs/2026-07-02-ux-audit-notes/TEMPLATE.md`

**Interfaces:**
- Produces: `axe-snippet.js` — a self-contained async JS function body for `browser_evaluate` that loads axe-core from CDN (idempotent) and returns `{violationCount, violations: [{id, impact, description, nodes: count, sampleTargets}]}` filtered to WCAG 2.2 A/AA rules. All journey tasks run this verbatim on each page state.
- Produces: `TEMPLATE.md` — the notes-file structure every journey task copies.

- [ ] **Step 1: Write the axe harness snippet**

Create `docs/superpowers/specs/2026-07-02-ux-audit-notes/axe-snippet.js`:

```js
// Body for playwright browser_evaluate: () => { ...this content... }
// Loads axe-core 4.x from CDN (skips if already present), runs WCAG A/AA scan.
return (async () => {
  if (!window.axe) {
    await new Promise((resolve, reject) => {
      const s = document.createElement('script');
      s.src = 'https://cdn.jsdelivr.net/npm/axe-core@4.10.2/axe.min.js';
      s.onload = resolve;
      s.onerror = () => reject(new Error('axe failed to load'));
      document.head.appendChild(s);
    });
  }
  const results = await window.axe.run(document, {
    runOnly: { type: 'tag', values: ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22aa'] }
  });
  return {
    url: location.pathname,
    violationCount: results.violations.length,
    violations: results.violations.map(v => ({
      id: v.id,
      impact: v.impact,
      description: v.help,
      nodes: v.nodes.length,
      sampleTargets: v.nodes.slice(0, 3).map(n => n.target.join(' '))
    }))
  };
})();
```

- [ ] **Step 2: Write the notes template**

Create `docs/superpowers/specs/2026-07-02-ux-audit-notes/TEMPLATE.md`:

```markdown
# Journey N: <name> — audit notes

**Pages visited:** <paths>
**Viewports:** 390×844, 1440×900

## Task attempt log
<What was attempted, step by step, and where time/attention went. Note seconds-to-goal where measurable.>

## Friction points
For each:
- **F<N>. <short title>**
  - Evidence: <screenshot filename(s), observed behaviour, axe rule id if applicable>
  - Criterion violated: <heuristic / WCAG SC / mobile standard / task obstruction>
  - Argument: <why this hurts a parent completing the task>
  - Severity guess: <P0/P1/P2/P3 — provisional, finalized in synthesis>

## Works well — keep
- <observation, with why it works>

## Axe results
- <path> @ <viewport>: <violationCount> violations — <ids with impact>

## Manual WCAG spot checks
- Touch targets ≥24px on interactive elements: <pass/fail + examples>
- Keyboard: tab order, focus visibility (desktop only): <pass/fail + examples>
- Zoom 200% text reflow (desktop only): <pass/fail>

## Screenshots
- <filename>: <what it shows>
```

- [ ] **Step 3: Verify the harness against the live homepage**

Load Playwright tool schemas (see Global Constraints note). Then:
1. `browser_resize` to 390×844.
2. `browser_navigate` to `https://schoolcompare.co.uk/`.
3. `browser_evaluate` with the contents of `axe-snippet.js` as the function body.

Expected: a JSON result with `violationCount` (any number ≥ 0) and no thrown error. If the CDN is blocked, switch the `src` to `https://unpkg.com/axe-core@4.10.2/axe.min.js` in the file and re-verify.

- [ ] **Step 4: Take a baseline screenshot to confirm capture works**

`browser_take_screenshot` with filename `home-mobile-baseline.png`. Expected: file saved, path returned.

- [ ] **Step 5: Commit**

```bash
git add docs/superpowers/specs/2026-07-02-ux-audit-notes/
git commit -m "chore(audit): axe harness and notes template for UX audit"
```

---

### Task 2: Journey 1 — Home → find my school (63% of entries, 46% exits)

**Files:**
- Create: `docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-1-home-find-school.md` (copy structure from `TEMPLATE.md`)

**Interfaces:**
- Consumes: `axe-snippet.js` via `browser_evaluate`; `TEMPLATE.md` structure.
- Produces: `journey-1-home-find-school.md` — notes consumed by Task 8 synthesis.

- [ ] **Step 1: Mobile walk-through (390×844)**

1. `browser_resize` 390×844, `browser_navigate` `https://schoolcompare.co.uk/`.
2. `browser_snapshot` — record what is above the fold: is the search input visible without scrolling? What competes for attention? Screenshot `j1-home-mobile-fold.png`.
3. Scroll the full page (`browser_press_key` End or evaluate `window.scrollTo`), screenshot `j1-home-mobile-full.png`. Note content order: does featured/secondary content precede the primary task?
4. **Task attempt A (school by name):** type a real school name into search, e.g. `Welland Primary` (known from analytics). Record: keystrokes-to-results, result quality (is the right school first?), loading feedback, and taps needed to reach `/school/146678-welland-primary-school`. Screenshot the results state `j1-search-results-mobile.png`.
5. **Task attempt B (postcode):** return home, search a plausible postcode (e.g. `B91 3` area for Solihull, or any valid UK postcode like `SW1A 1AA`). Record: is postcode search discoverable/labelled? Distance shown? Sensible ordering? Screenshot `j1-postcode-results-mobile.png`.
6. Record time-to-school-page for both attempts against the spec's ~15s target.
7. Run axe snippet on: home (initial) and home (results visible). Record results.

- [ ] **Step 2: Desktop walk-through (1440×900)**

Repeat Step 1's navigation and task attempt A at 1440×900 (screenshots `j1-home-desktop-fold.png`, `j1-search-results-desktop.png`). Additionally: tab through the page with keyboard — record focus visibility and whether search → results → school link is keyboard-operable. Test 200% zoom (`browser_evaluate` `document.body.style.zoom` is NOT valid for this — instead resize to 720×450 which approximates 200% reflow at 1440) and note any loss of content/overlap.

- [ ] **Step 3: Write notes file**

Fill `journey-1-home-find-school.md` per template. Every friction point needs evidence + criterion + argument. Explicitly answer: "why do 46% of visitors exit at home?" — list the plausible causes observed.

- [ ] **Step 4: Commit**

```bash
git add docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-1-home-find-school.md
git commit -m "docs(audit): journey 1 notes — home to school search"
```

---

### Task 3: Journey 2 — Cold landing on a school detail page (SEO long tail)

**Files:**
- Create: `docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-2-school-detail-cold.md`

**Interfaces:**
- Consumes: `axe-snippet.js`, `TEMPLATE.md`.
- Produces: `journey-2-school-detail-cold.md` for Task 8.

- [ ] **Step 1: Mobile cold landing (390×844)**

Navigate **directly** (no prior site context — this simulates a Google arrival) to `https://schoolcompare.co.uk/school/136916-the-castle-school`. Then assess in order:
1. First-screen orientation: within one screen, can a parent tell what site this is, what school this is, and what the site offers? Screenshot `j2-school-mobile-fold.png`.
2. Scroll the entire page. Screenshots at each major section (`j2-school-mobile-<section>.png`). For each data block (results, Ofsted, characteristics, admissions): is it comprehensible to a non-specialist? Is jargon (RWM, expected standard, progress scores) explained in place?
3. Next-step paths: is there an obvious "compare this school" and "schools near this one" action? How many taps to a comparison including this school? Record the exact path or its absence.
4. Repeat the cold landing for a contrasting school `https://schoolcompare.co.uk/school/146678-welland-primary-school` (different data availability) — note any layout breakage or missing-data handling. Screenshot anomalies only.
5. Run axe snippet on both school pages. Record results.

- [ ] **Step 2: Desktop pass (1440×900)**

Reload `.../136916-the-castle-school` at desktop. Screenshot `j2-school-desktop-fold.png`. Check: hero/map rendering, chart legibility, keyboard focus through interactive elements, link affordance (do school-page links look clickable?).

- [ ] **Step 3: Write notes file**

Fill `journey-2-school-detail-cold.md`. Explicitly answer: "a parent lands here from Google — what would make them stay and use the site rather than bounce back to search results?"

- [ ] **Step 4: Commit**

```bash
git add docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-2-school-detail-cold.md
git commit -m "docs(audit): journey 2 notes — cold landing on school detail"
```

---

### Task 4: Journey 3 — Building a comparison (27% of views, 32% exits)

**Files:**
- Create: `docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-3-compare.md`

**Interfaces:**
- Consumes: `axe-snippet.js`, `TEMPLATE.md`.
- Produces: `journey-3-compare.md` for Task 8.

- [ ] **Step 1: Mobile walk-through (390×844)**

1. Navigate to `https://schoolcompare.co.uk/compare` **directly** (20% of sessions enter here). Screenshot empty state `j3-compare-empty-mobile.png`. Is the empty state instructive — does it tell a parent what to do first?
2. Add two schools via whatever mechanism the page offers (search within compare, or navigate to school pages and use their compare action — record which paths exist). Count taps from empty state to a two-school comparison. Screenshot `j3-compare-two-schools-mobile.png`.
3. Assess the comparison output on mobile: are charts/tables legible at 390px? Horizontal scrolling? Can you tell which school is which (colour + label, not colour alone — WCAG 1.4.1)? Are metric names explained?
4. Remove a school; add a third. Any state loss, confusing controls, or dead ends? Does the selection persist if you navigate away and back?
5. Run axe snippet on empty state and populated state. Record results.

- [ ] **Step 2: Desktop pass (1440×900)**

Repeat comparison-building at desktop. Screenshot `j3-compare-two-schools-desktop.png`. Keyboard-operate the add/remove flow; record focus behaviour. Check chart tooltips/legends for mouse-only interactions.

- [ ] **Step 3: Write notes file**

Fill `journey-3-compare.md`. Explicitly answer: "compare is 32% of exits — is that task-complete satisfaction (fine) or abandonment (problem)? What observed evidence points either way?"

- [ ] **Step 4: Commit**

```bash
git add docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-3-compare.md
git commit -m "docs(audit): journey 3 notes — building a comparison"
```

---

### Task 5: Journey 4 — Rankings → shortlist (12% of views)

**Files:**
- Create: `docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-4-rankings.md`

**Interfaces:**
- Consumes: `axe-snippet.js`, `TEMPLATE.md`.
- Produces: `journey-4-rankings.md` for Task 8.

- [ ] **Step 1: Mobile walk-through (390×844)**

1. Navigate to `https://schoolcompare.co.uk/rankings`. Screenshot default state `j4-rankings-mobile.png`.
2. Is the default ranking explained (which metric, which year, what the numbers mean)? Would a parent understand what "top" means here?
3. Filter to a local authority (e.g. Solihull). Count taps; is the filter discoverable on mobile? Screenshot filtered state `j4-rankings-filtered-mobile.png`.
4. Change the ranking metric. Is the metric picker comprehensible (plain-language labels vs. jargon)?
5. Tap through to a school from the list; navigate back — is filter state preserved? (Back-navigation state loss is a classic mobile task-killer.)
6. Run axe snippet on default and filtered states. Record results.

- [ ] **Step 2: Desktop pass (1440×900)**

Repeat at desktop, screenshot `j4-rankings-desktop.png`. Check table semantics (real `<table>` with headers vs. divs — screen-reader implications), sortability affordances, keyboard operation of filters.

- [ ] **Step 3: Write notes file + commit**

Fill `journey-4-rankings.md`.

```bash
git add docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-4-rankings.md
git commit -m "docs(audit): journey 4 notes — rankings"
```

---

### Task 6: Journey 5 — Admissions content (5% of views, light pass)

**Files:**
- Create: `docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-5-admissions.md`

**Interfaces:**
- Consumes: `axe-snippet.js`, `TEMPLATE.md`.
- Produces: `journey-5-admissions.md` for Task 8.

- [ ] **Step 1: Single mobile pass (390×844)**

1. Navigate to `https://schoolcompare.co.uk/admissions`. Screenshot `j5-admissions-mobile.png`.
2. Light checks only: readability (line length, heading hierarchy), whether the recently added SchoolCompare tool cross-links are present and useful, whether the page's look matches the rest of the site (this feeds the cohesion pass), and one axe scan.
3. Check discoverability in reverse: from the home page, how does a parent find this content at all? (5% views may be a discoverability problem rather than a demand problem — note evidence either way.)

- [ ] **Step 2: Write notes file + commit**

Fill `journey-5-admissions.md` (shorter than the others is expected).

```bash
git add docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-5-admissions.md
git commit -m "docs(audit): journey 5 notes — admissions"
```

---

### Task 7: Cross-cutting cohesion pass

**Files:**
- Create: `docs/superpowers/specs/2026-07-02-ux-audit-notes/cohesion-pass.md`

**Interfaces:**
- Consumes: all journey screenshots (scratchpad) and notes files; live site; optionally `nextjs-app` source for token verification.
- Produces: `cohesion-pass.md` for Task 8.

- [ ] **Step 1: Component comparison across pages**

Using the screenshots already captured plus targeted re-visits, compare across `/`, `/compare`, `/rankings`, `/admissions`, and a school page:
1. **Typography:** collect computed styles via `browser_evaluate` on each page — e.g. `[...document.querySelectorAll('h1,h2,h3,body p, button, a')].slice(0,40).map(e => ({tag: e.tagName, size: getComputedStyle(e).fontSize, weight: getComputedStyle(e).fontWeight, family: getComputedStyle(e).fontFamily.split(',')[0]}))` — and diff the scales page-to-page. Record any page using off-scale sizes.
2. **Colour:** same technique for `color`, `backgroundColor` on buttons/links/chips; flag near-duplicate colours (e.g. two blues doing the same job) and any accent colour used inconsistently.
3. **Components:** buttons, chips, cards, empty states, loading states — screenshot side-by-side candidates and note variant drift (different radii, padding, casing, icon usage for the same semantic role).
4. **Navigation & page furniture:** header/footer consistency, page-title patterns, back-link behaviour, breadcrumbs presence/absence across page types.
5. **Recent additions check (from spec):** map-blended hero, characteristic chips, admissions cross-links — do they feel native to the rest of the site?

- [ ] **Step 2: Verify against source where ambiguous**

Where a visual inconsistency could be intentional, check `nextjs-app` styles (grep for the relevant component/tokens) to determine whether a design token exists and is being bypassed, or no token exists. Record which — it changes the recommendation (enforce token vs. create token).

- [ ] **Step 3: Write notes file + commit**

Fill `cohesion-pass.md` with the same evidence → criterion → argument structure (criterion here is typically "consistency and standards" heuristic).

```bash
git add docs/superpowers/specs/2026-07-02-ux-audit-notes/cohesion-pass.md
git commit -m "docs(audit): cross-cutting cohesion pass notes"
```

---

### Task 8: Synthesis — prioritized audit report

**Files:**
- Create: `docs/superpowers/specs/2026-07-02-ux-audit-report.md`
- Read: all files in `docs/superpowers/specs/2026-07-02-ux-audit-notes/`, spec `docs/superpowers/specs/2026-07-02-ux-audit-design.md`

**Interfaces:**
- Consumes: journey notes 1–5, cohesion notes.
- Produces: the final deliverable report.

- [ ] **Step 1: Consolidate and deduplicate findings**

Read all six notes files. Merge duplicate findings (same root cause observed in several journeys becomes one finding listing all occurrences). Discard any finding lacking evidence or a cited criterion — the spec forbids taste-only findings.

- [ ] **Step 2: Assign final priorities and uplift indications**

For each finding assign P0–P3 per the spec's definitions (traffic-weighted impact × severity), and an uplift line: **metric** (one of: home 46% exit rate; share of sessions reaching a school page; compare 32% exit rate; rankings→school click-through; school-page bounce-back-to-Google; accessibility compliance), **direction**, **band** (small/moderate/large) **with one-sentence reasoning**. Sanity rules: a P0/P1 must sit on `/`, `/compare`, `/rankings`, or the school-page template; admissions-only findings cap at P2 unless a WCAG failure.

- [ ] **Step 3: Write the report**

Structure (from spec):

```markdown
# SchoolCompare UX/UI Audit — 2026-07-02

## Method summary
<viewports, journeys, tools, analytics baseline — half a page>

## What works today — keep
<explicit list with why; protects against change-for-change's-sake>

## Findings

### P0 — Urgent
<each: title, evidence (screenshots/axe ids), criterion, argument, recommendation, uplift>

### P1 — High
### P2 — Medium
### P3 — Nice-to-have

## Accessibility summary
<axe violation table by page/viewport + manual check results; overall WCAG 2.2 AA posture>

## Suggested implementation sequence
<grouped batches of related fixes, ordered by uplift-per-effort; each batch sized as a plausible follow-up project>
```

- [ ] **Step 4: Self-check the report against the spec**

Verify: every finding has all four elements (evidence/argument/recommendation/uplift); "works well" section is non-empty; uplift bands never state invented percentages; P0/P1 findings all sit on high-traffic paths; report answers the spec's three goals (a) speed-to-information, (b) end-to-end cohesion, (c) standards compliance. Fix inline.

- [ ] **Step 5: Commit**

```bash
git add docs/superpowers/specs/2026-07-02-ux-audit-report.md
git commit -m "docs(audit): prioritized UX/UI audit report"
```
