Files
school_compare/docs/superpowers/specs/2026-07-02-ux-audit-notes/journey-1-home-find-school.md
T
TudorandClaude Fable 5 f2b71b67d4 docs(audit): correct postcode finding — full postcodes do trigger proximity search
Recheck with 'B91 3DL' via the search box shows the geocoded radius
search works (distances, nearest-first, radius selector, map toggle).
Original P0.3 tested only a partial postcode, which silently falls back
to text search — refiled as P2.0 (silent mode switch on partial input).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 15:01:02 +01:00

109 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Journey 1: Home → find my school — audit notes
**Pages visited:** `/`, `/?search=Welland+Primary` (results), `/?search=B91+3` (postcode results), `/school/146678-welland-primary-school`
**Viewports:** 390×844 (primary), 1440×900 (+720×450 for 200% reflow)
**Site:** live https://schoolcompare.co.uk only. Read-only: searched/filtered, submitted no data-modifying forms.
## Task attempt log
**Mobile (390×844) — Attempt A: find a school by name.**
- Home loads with search input above the fold (input top 176px / bottom 246px of an 844px viewport, 70px tall — comfortable tap target). H1 "Every school in England, *compared.*" at 85px. `Schools near me` button at ~388px. Full page is 3132px tall; content order is search → near-me → admissions-deadline rail → "Start exploring" links → marketing ("What you'll see", "About school data") → footer. **Primary task is first — good.**
- Typed `Welland Primary` (15 keystrokes). **No live autocomplete/typeahead appeared** while typing.
- Tapped `Search`. URL → `/?search=Welland+Primary`. Result was instant (no perceptible wait; no spinner needed). "1 school found", correct school ranked first, rich card: `Good · 2023`, Primary, Academy converter, Ages 411, 74% RWM with down-trend arrow (prev 76%), +12 pts vs national, 131 pupils, Worcestershire.
- Tapped `View``/school/146678-welland-primary-school`, instant.
- **Time-to-school-page: 3 taps (searchbox, Search, View) + typing, effectively instant load. Well under the ~15s target.**
**Mobile — Attempt B: find schools by postcode `B91 3` (Solihull).**
- Same 3-interaction pattern (focus box, type, Enter). URL → `/?search=B91+3`. "8 schools found."
- **Results show NO distance and are NOT sorted by proximity** (sort = "Relevance"). The list mixes phases and the **top result is a Secondary school** (Tudor Grange Academy), followed by an independent all-through, another secondary, then primaries, and a Sixth Form College last. Behaviour is consistent with a postcode-prefix text match against the postcode column, not a geographic radius search.
- Screenshot `j1-postcode-results-mobile.png` confirms cards carry only the LA name ("Solihull"), no "X miles away".
**Desktop (1440×900) — Attempt A repeat + keyboard + zoom.**
- Desktop hero additionally shows a trust badge ("● UPDATED WITH 2026/2027 ADMISSIONS RESULTS") and a value-prop subheading ("24,000+ primary and secondary schools with Key Stage 2 SATs, GCSE results, Ofsted grades, progress scores and admissions data — side by side, in one place"). **Both are absent on the mobile hero** (mobile jumps H1 → search box).
- Name search identical, correct, instant (`j1-search-results-desktop.png`).
- Keyboard: tab order is logical — Skip link → logo → Search/Compare/Rankings/Admissions nav → search input → Search button → Schools near me → content. Skip link, logo, nav links and Search button all get a clear **2px solid orange (#E07256) focus outline**. The search input uses an orange border + very faint ring (`box-shadow rgba(224,114,86,0.12) 0 0 0 3px`, `outline:none`) — visible but weaker than the other controls. Search → results → school link is fully keyboard-operable (standard links/buttons).
- 200% reflow (720×450): **no horizontal scroll** (`scrollWidth == clientWidth == 720`); deadline cards reflow from 1×4 to 2×2, no overlap or clipping. Pass.
## Friction points
- **F1. Search has no autocomplete / typeahead suggestions**
- Evidence: Typing `Welland Primary` (mobile & desktop) produced no suggestion dropdown at any keystroke; snapshots show only the raw input until submit. Screenshot `j1-home-mobile-fold.png`.
- Criterion violated: Nielsen #6 (Recognition rather than recall) + established site-search usability (NN-g "search suggestions"); WCAG-adjacent error-prevention.
- Argument: Parents frequently don't know a school's exact registered name ("Welland" vs "Welland Church of England"). With no suggestions and an exact-ish match required, a misspelling risks a zero-result dead end on the highest-traffic path, and every search costs full typing + a blind submit.
- Severity guess: P1
- **F2. Postcode search shows no distance and isn't sorted by proximity** — **⚠ REVISED after recheck, see addendum at end of file: this holds only for PARTIAL postcodes; a full postcode triggers a working proximity search with distances.**
- Evidence: `/?search=B91+3` → "8 schools found", sort "Relevance", top result a Secondary school, phases mixed (secondary/independent/primary/sixth-form), zero distance shown on any card. Screenshot `j1-postcode-results-mobile.png`.
- Criterion violated: Nielsen #2 (Match between system and the real world) + task-flow obstruction. The placeholder invites a "postcode", which sets an expectation of "nearest schools first"; the delivered value (proximity ordering + distance) is missing.
- Argument: On the core "find my school near me" task, a parent who types their postcode expects the closest schools ranked by distance. Instead they get an unordered, distance-less, mixed-phase list led by a secondary school — it reads as broken and gives no way to judge "which is closest," pushing them to abandon. (Name search works, so the overall journey isn't fully blocked → P1 not P0, but this is the weakest link on the primary task.)
- Severity guess: P1 (candidate P0 for the postcode sub-path)
- **F3. Filter and Sort dropdowns on the results view have no accessible name**
- Evidence: axe `select-name` (impact **critical**, 2 nodes) on `/?search=Welland+Primary`; targets `.FilterBar-module…controlSelect` (phase filter) and `.HomeView-module…sortSelect`.
- Criterion violated: WCAG 2.2 **4.1.2 Name, Role, Value (Level A)**.
- Argument: These are the exact controls a parent uses to narrow a mixed result set to "Primary" or re-sort — and a screen-reader user hears an unlabelled combobox, so cannot tell what either does. This is on the main journey's results view (same `/` route), a clear Level-A failure.
- Severity guess: P1 (candidate P0 — WCAG A failure on the main route)
- **F4. Serious colour-contrast failures on the home page**
- Evidence: axe `color-contrast` (impact serious) — 6 nodes on home (`/`), incl. the active nav tab label, `.btn`, and "how-it-works" step text; 3 nodes on results (incl. `.btn-primary`, Ofsted badge).
- Criterion violated: WCAG 2.2 **1.4.3 Contrast (Minimum) (AA)**.
- Argument: Low-contrast labels and buttons are harder to read for low-vision parents and for everyone on a phone in daylight — the mobile-primary audience. Affects the main CTA styling and the active-tab indicator.
- Severity guess: P1
- **F5. Admissions-deadline rail: keyboard-inaccessible scroll region, defaults to the least-urgent card**
- Evidence: axe `scrollable-region-focusable` (serious, 1 node) on `.countdownRail`; on mobile the rail's default scroll position lands on the 4th card ("Primary Offer Day · 288 days") rather than the nearest deadline ("Secondary · 121 days"), with only a partial card peeking as the scroll cue. Screenshots `j1-home-mobile-fold.png`, `j1-home-mobile-full.png`.
- Criterion violated: WCAG 2.2 **2.1.1 Keyboard (A)** for the scroll region; Nielsen #1 (Visibility of system status) for the ordering.
- Argument: Keyboard/switch users can't reach the later cards, and the odd default scroll buries the single most time-critical deadline (121 days) behind less urgent ones — the opposite of what an anxious parent needs surfaced.
- Severity guess: P2
- **F6. Mobile hero omits the value proposition shown on desktop**
- Evidence: Desktop hero has the "UPDATED WITH 2026/2027…" badge + subheading "24,000+ primary and secondary schools with KS2 SATs, GCSE results, Ofsted grades… side by side, in one place" (`j1-home-desktop-fold.png`). The mobile hero (`j1-home-mobile-fold.png`) drops both — below the poetic-but-vague H1 there is only a search box.
- Criterion violated: Nielsen #1 (Visibility of system status) / recognition-over-recall; mobile content-parity best practice (the primary 63%-of-entries viewport should not lose the core "what is this and why trust it" copy).
- Argument: A first-time parent landing on mobile sees "Every school in England, compared." + a bare box, with no statement of coverage, data sources, or freshness. Weak/absent value proposition above the fold is a classic driver of immediate exits — directly relevant to the 46% home-exit rate.
- Severity guess: P2 (candidate P1 given mobile is the primary, highest-traffic viewport)
## Works well — keep
- **Name search is genuinely excellent.** `Welland Primary` returned the correct school as the sole top result with an information-rich card (Ofsted grade+year, RWM % with year-over-year trend arrow, "+12 pts vs national", pupil count, LA) — 3 taps + typing, instant load, comfortably under the 15s target. This is the journey's strongest asset.
- **Search is the unmistakable primary action.** Prominent, above the fold on both viewports, large (70px) tap target, plain-English placeholder "School name or postcode", single clear "Search" CTA; content order puts the task first.
- **Accessibility fundamentals partly in place:** a working "Skip to main content" link (keyboard-focusable, visible outline), logical tab order, and strong 2px focus outlines on nav/skip/button.
- **Robust responsive reflow:** 200%/720px shows no horizontal scroll and no overlap; deadline cards reflow cleanly.
- **Result cards adapt to phase** (Attainment 8 for secondary, RWM % for primary) — good match to the real-world data a parent expects for each phase.
- **A real proximity path exists** via the "Schools near me" geolocation button (distinct teal styling) — the raw material for good location search is present, just not wired to the postcode text input (see F2).
## Axe results
- `/` (home, initial) @ 390×844: **2 violations**`color-contrast` (serious, 6 nodes), `scrollable-region-focusable` (serious, 1 node).
- `/?search=Welland+Primary` (results) @ 390×844: **2 violations**`color-contrast` (serious, 3 nodes), `select-name` (**critical**, 2 nodes).
- Desktop (1440×900) serves the same DOM/CSS; violations above apply equally (not separately re-scanned).
## Manual WCAG spot checks
- **Touch targets ≥24px:** Pass on the core path — search input 70px tall, Search button large, "Schools near me" 40px, result-card `View`/`+ Compare` full-size. Watch: the small "×" chip on the active-search token is borderline.
- **Keyboard: tab order, focus visibility (desktop):** Pass with a caveat — order is logical and skip/nav/buttons show a clear 2px orange outline; the search **input** relies on an orange border + a very faint 0.12-alpha ring (visible but the weakest indicator on the page — borderline for 2.4.11 Focus Appearance).
- **Zoom 200% text reflow (desktop):** Pass — no horizontal scroll at 720px, no clipping/overlap.
## Why do 46% of visitors exit at home? — observed plausible causes
1. **Postcode expectation mismatch (F2).** Many parents will type their postcode expecting "nearest schools, closest first." They get a distance-less, unsorted, mixed-phase list led by a secondary school — it looks broken, so they leave. This is the biggest task-level leak on the primary journey.
2. **Weak mobile value proposition (F6).** On the 63%-of-entries mobile hero, the vague H1 + bare search box give a first-time visitor no reason to trust or continue; no coverage/freshness/data statement above the fold. Classic bounce driver.
3. **No search assistance (F1).** Typing a school name with zero suggestions and requiring a near-exact match means a spelling slip → likely a zero-result dead end → exit.
4. **Trust/polish erosion (F3, F4).** Critical unlabelled controls and serious contrast failures degrade the "credible data source" impression, especially for the accessibility-dependent and daylight-mobile segments.
5. **Benign exits (nuance for synthesis).** Some "home exits" are successes, not failures: a user who finds their school card and taps an outbound link, or who reads the answer and leaves satisfied. Not the entire 46% is a usability leak — but causes 14 are the addressable share.
## Screenshots
- `j1-home-mobile-fold.png`: mobile home above the fold — H1 + prominent search box + Search CTA, deadline rail beginning.
- `j1-home-mobile-full.png`: full mobile home — content order (search → near-me → deadlines → explore → marketing → footer).
- `j1-search-results-mobile.png`: mobile results for "Welland Primary" — correct single result, rich card.
- `j1-postcode-results-mobile.png`: mobile results for "B91 3" — no distance, relevance sort, secondary school first.
- `j1-home-desktop-fold.png`: desktop home — includes trust badge + value-prop subheading absent on mobile.
- `j1-search-results-desktop.png`: desktop results for "Welland Primary".
- `j1-focus-searchbox-desktop.png`: keyboard focus state on the search input (orange border + faint ring).
- `j1-home-zoom200-desktop.png`: full home at 720px (≈200% reflow) — no horizontal scroll, cards reflow to 2×2.
- `j1-fullpostcode-results-mobile.png` (recheck): mobile results for full postcode "B91 3DL" — "13 schools within 1.0 miles", distance on every card, nearest-first.
## Recheck addendum (2026-07-02) — F2 tested with a FULL postcode
The original Attempt B used the partial postcode `B91 3`. Rechecked with the full postcode **`B91 3DL`** typed into the home search box and submitted:
- The submit handler (`FilterBar.tsx` `isValidPostcode()`, full-postcode regex `/^[A-Z]{1,2}[0-9][A-Z0-9]?\s*[0-9][A-Z]{2}$/i`) recognised it and routed to **`/?postcode=B91+3DL&radius=1`** — the geocoded radius search, not text search.
- Result: heading **"13 schools within 1.0 miles of B91 3DL"**, **every card shows distance** ("0.1 mi", "0.2 mi" … "1.0 mi"), **sorted nearest-first**, plus a "Within: 0.5/1/3/5 miles" radius selector, a List/Map toggle, and a "Nearest first" sort option. Screenshot `j1-fullpostcode-results-mobile.png`. This is exactly the experience F2 asked for — it exists and works well.
- **F2 as originally stated is therefore wrong for full postcodes.** The residual, real finding is narrower: input that *looks like* a location but fails the full-postcode regex — outcodes ("B91"), partials ("B91 3"), postcodes with typos — **silently falls back to name/address text search** (`/?search=…`) with no distances, relevance ordering, and no notice that a full postcode would unlock proximity search. The two result pages look similar enough that a parent won't know which mode they're in. Severity re-guessed at P1→P2 (degraded sub-path with a working primary path and a working "Schools near me" alternative; the failure is silent-mode-switching, not a missing capability).
- Exit-cause list item 1 ("postcode expectation mismatch") should be read with this narrower scope: it applies to partial/malformed postcode input only.