# 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: — audit notes **Pages visited:** **Viewports:** 390×844, 1440×900 ## Task attempt log ## Friction points For each: - **F. ** - Evidence: - Criterion violated: - Argument: - Severity guess: ## Works well — keep - ## Axe results - @ : violations — ## Manual WCAG spot checks - Touch targets ≥24px on interactive elements: - Keyboard: tab order, focus visibility (desktop only): - Zoom 200% text reflow (desktop only): ## Screenshots - : ``` - [ ] **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-
.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 `` 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 ## What works today — keep ## Findings ### P0 — Urgent ### P1 — High ### P2 — Medium ### P3 — Nice-to-have ## Accessibility summary ## Suggested implementation sequence ``` - [ ] **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" ```