Compare commits

...
Author SHA1 Message Date
tudor 0f1ca660cb Merge pull request 'fix(places): phase-grouped tables, plain-English measures, styled links' (#118) from fix/place-page-presentation into fix/place-title-brand-doubling
Reviewed-on: #118
2026-08-21 20:53:20 +00:00
Tudor 3c69b65ff0 fix(places): phase-grouped tables, plain-English measures, styled links
Three presentation faults on the place pages, all found by looking at a
rendered page rather than at a test.

An unphased place page showed one primary-only measure for a list holding both
phases: 8 of 27 rows on /schools/brentwood were blank, because secondaries
have no reading-writing-maths score. Picking the other measure would only have
inverted which rows were empty, and putting both in one column would have
mixed a percentage with a 0-90 score. Each phase now gets its own table, so a
blank cell means the school genuinely has no published result — which is worth
saying, and now says "Not published" rather than a bare dash.

"RWM expected" was invented here. The site already names the measure in
METRIC_DEFINITIONS, surfaced at /api/metrics: "Reading, Writing & Maths
Combined %". The heading now reads "Reading, writing & maths" with the full
definition in the tooltip.

Links carried no class at all, so they rendered as default blue underlined
browser links beside a site that styles table links as body colour with a
brand hover. They now follow RankingsView's convention, and running-copy links
take the brand colour.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-21 21:49:39 +01:00
TudorandClaude Opus 5 24e114dee7 fix(places): stop the place titles doubling the brand
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 27s
Every place page shipped as 'Schools in Brentwood - Compare 27 Schools |
schoolcompare | schoolcompare'. The root layout's title template appends
'| schoolcompare' to any plain-string title, and all four place routes already
carried the brand. W8 opted the other routes out with an absolute title; the
place routes were written afterwards and did not inherit the lesson.

~2,600 titles affected, and the repetition pushed them past Google's
truncation point, so the doubled brand displaced real words in the result.

An e2e journey now asserts no title repeats the brand, across the static
routes and a place page, so this cannot come back on a route added later.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-21 21:43:32 +01:00
tudor 6c5db0c266 Merge pull request 'fix(places): submit and link the phase variants' (#116) from fix/place-phase-variants into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 19s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 51s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 0s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m29s
Reviewed-on: #116
2026-08-21 19:46:55 +00:00
TudorandClaude Opus 5 6f749ed21f fix(places): submit and link the phase variants
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 17s
PR Checks / Build Frontend (no push) (pull_request) Successful in 45s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 2m39s
/schools/[place]/[phase] shipped as routes but reached nothing. The sitemap
emitted one URL per registry entry and the registry had no phase dimension, so
~950 pages were absent from every sitemap — and PlaceView did not link them
either, leaving them reachable by nothing at all.

That is the query shape the baseline actually showed: 'primary schools in
beccles', 'secondary schools in brentwood'. Publishing the routes without a
path in meant building for the demand and then hiding from it.

Place now carries phase_urns so the per-phase threshold can be applied without
re-querying, the sitemap emits a variant wherever a phase clears the threshold
on its own, and the API exposes the qualifying phases so the place page links
only variants that exist. Outcodes are excluded: nobody searches 'primary
schools in SW11' and those routes do not exist.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-21 20:43:07 +01:00
tudor d423826840 Merge pull request 'fix(places): a locality collision must not break the sitemap' (#115) from fix/locality-collision-skip into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 19s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 51s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 1m13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m38s
Reviewed-on: #115
2026-08-21 19:26:02 +00:00
TudorandClaude Opus 5 d3c63ccc6d fix(places): a locality collision must not break the sitemap
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m4s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 18s
PR Checks / Build Frontend (no push) (pull_request) Successful in 45s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 34s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 34s
Sitemap regeneration failed on staging. 'richmond' in the curated locality
list collides with the GIAS town Richmond in North Yorkshire (37 schools), the
registry raised, and the admin endpoint 500d — taking down sitemap generation
for all 25,000 school pages over one bad row of curated data.

The guard now skips the colliding locality and logs an error. Skipping still
achieves what the guard was for — a locality never silently shadows a town —
without letting curated data break the site. That matters beyond this bug:
GIAS town names change with no code change here, so a raise could fire
spontaneously in production later.

Also removes four localities that were London boroughs rather than districts.
Hackney, Islington, Greenwich and Ealing are local authorities with 104, 72,
108 and 115 schools and already have authority pages; a locality defined by
two or three outcodes would have been a partial near-duplicate of one — the
thin-content failure the two-namespace design exists to avoid. A test now
guards the whole borough list.

Validated against the live corpus: 15 localities, no town collisions, no
authority duplicates, all 15 clear the threshold.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-21 20:20:52 +01:00
tudor b93eb3a691 Merge pull request 'feat(seo): the location layer — town, locality, authority and outcode pages (W2)' (#114) from feat/w2-location-layer into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 19s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 51s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 1m18s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 4s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 11m8s
Reviewed-on: #114
2026-08-21 17:56:05 +00:00
TudorandClaude Opus 5 6b871ce1e9 feat(places): ItemList and BreadcrumbList, and the e2e gate
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 18s
PR Checks / Build Frontend (no push) (pull_request) Successful in 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 36s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 4m33s
ItemList tells Google the page is a ranked set rather than prose;
BreadcrumbList puts the place in a hierarchy. School URLs in the markup are
absolute on the canonical host, since a relative URL in JSON-LD is ambiguous.

Eight journeys covering all four families, the two-namespace guarantee, the
threshold, the canonical, the sitemap and the local-versus-England line — the
last because that comparison is the reason these pages are not a name dropped
into a template.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-21 18:19:08 +01:00
TudorandClaude Opus 5 c981d89137 feat(places): town, locality, authority and outcode routes
Every generateStaticParams is gated behind PRERENDER_PLACES and wrapped in the
same try/catch the school route uses. The plan claimed authority pages were
'few enough to always prebuild' — but few enough still means the API must be
reachable at build time, and in CI it is not: the build failed with
ECONNREFUSED rather than degrading to ISR.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-21 18:17:57 +01:00
TudorandClaude Opus 5 de5e790112 feat(places): place page client and view component
One component for all four families: they differ in what fills the registry,
not in what the page shows, so a second would be a second place to forget the
same change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-21 18:15:10 +01:00
TudorandClaude Opus 5 42138fc402 feat(places): submit place and outcode sitemaps
Separate children per family so Search Console reports the location layer's
indexation apart from the school pages' — which is the point of the index
built in W1, and the number the stop condition watches.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-21 18:13:55 +01:00
TudorandClaude Opus 5 c5af476213 feat(places): /api/places registry and place detail endpoints
The registry is cached for the process and reset by the same admin endpoint
that rebuilds the sitemaps, so places and sitemap always describe the same
corpus rather than drifting apart.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-21 18:13:05 +01:00
TudorandClaude Opus 5 de853b90b3 feat(places): London localities and postcode districts
The GIAS town field puts 1,819 London schools under the single value
'London', so it cannot answer 'schools in Battersea' — a query that appears in
the baseline. No single field can: parliamentary constituency gives Battersea
but not Canary Wharf, admin_ward gives Canary Wharf but not Battersea, and
neither gives Clapham or Shoreditch. So a locality is curated, defined by the
postcode districts it covers, which needs no new ingestion.

A locality may not shadow a published town: the registry raises rather than
silently costing a page that carries real demand. One below the threshold is
logged rather than raising, because a locality can legitimately be too small.

The pipeline seed mirrors the module, with a test guarding the drift — the
same arrangement gias_codes has, and for the same reason: the backend image
does not contain pipeline/.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-21 18:11:56 +01:00
TudorandClaude Opus 5 759d9f5cea feat(places): registry of towns and authorities
Two namespaces because 67 town names collide with an authority name and
neither set contains the other — postal towns cross authority boundaries, so
Bedford the town holds 104 schools against the authority's 86.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-21 18:10:37 +01:00
TudorandClaude Opus 5 555d3f0a7d docs(seo): implementation plan for the W2 location layer
Seven tasks: the place registry, London localities and outcodes, the places
API, per-family sitemaps, the shared place view, the four route families, and
structured data plus the e2e gate.

Two things the plan corrects against the spec. The backend image does not
contain pipeline/, so the curated locality list cannot live only in a dbt
seed — it follows the gias_codes.py precedent instead, canonical in backend
with the seed as a mirror. And NationalAverages is nested by phase rather than
flat, which the first draft read wrongly and would have rendered every page
without its England comparison.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-21 18:09:35 +01:00
TudorandClaude Opus 5 ecc847091c docs(seo): design for the W2 location layer
Supersedes the original spec's W2. The Search Console baseline inverted its
ordering: every measured location query is town or district level, none is an
administrative area, and phase is part of the query rather than a filter.

Two problems the original design did not anticipate. 67 viable towns share a
name with a local authority, and the authority is the larger set in only 43 of
them — postal towns cross authority boundaries, so neither can absorb the
other. Two namespaces resolve it by construction. And the GIAS town field
collapses 1,819 London schools into one value, which a curated
locality-to-outcode seed solves without new ingestion.

Sizing is measured against the live 25,185-school corpus rather than
estimated: 783 viable towns, 1,760 outcodes, 154 authorities.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-21 18:09:35 +01:00
tudor b187a478c9 Merge pull request 'feat(seo): rewrite the C1 snippets to earn the click (W8)' (#113) from feat/seo-metadata-c1 into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 49s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m24s
Reviewed-on: #113
2026-08-20 23:26:12 +00:00
TudorandClaude Opus 5 c0547c45e5 feat(seo): rewrite the C1 snippets to earn the click (W8)
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 11s
The baseline says these pages already rank and are not clicked. 'compare
school performance' sits at position 6.1 with 0.43% CTR; 'compare schools' at
7.2 with 0.87%. The brand query 'school compare' draws 9.16% from the same
neighbourhood of the same results page, which rules out a ranking explanation
— when the snippet gives a reason to click, it gets clicked.

These SERPs are owned by the DfE's own 'Compare school performance' service.
The old title put a lowercase brand nobody searches for in the most valuable
pixels, then a near-paraphrase of that service's name. Beside the government's
own result it read as a lookalike.

Intent in the title, differentiator in the description. Titles now match what
people type, and the descriptions carry the one fact gov.uk does not publish:
how close you had to live to get a place.

/compare deliberately takes the tool phrasing rather than the homepage's, so
the two pages stop competing for one phrase. The root layout's default and
Open Graph copy were saying something different again; they now agree.

No hard school counts in any of it. The corpus moves with every data refresh
and this repo has already shipped one copy bug of that kind.

Tests guard the mechanics — SERP length, intent keyword, the differentiator,
no brand-first title — and leave the wording free to iterate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-21 00:21:08 +01:00
tudor 4a3928df9f Merge pull request 'fix(seo): a school is publishable on any year's results, not the latest' (#112) from fix/sitemap-any-year-data into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 18s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 49s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 0s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m24s
Reviewed-on: #112
2026-08-20 23:15:19 +00:00
TudorandClaude Opus 5 07c97a46c5 fix(seo): a school is publishable on any year's results, not the latest
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 16s
PR Checks / Build Frontend (no push) (pull_request) Successful in 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 53s
_school_sitemap_rows tested only the latest year's row, which quietly dropped
every school with results in its history but a null row for the most recent
year — a school that stopped reporting, or whose figures were suppressed for
small-cohort disclosure.

The Mallard Academy (150367) is the case that caught it: real KS2 results for
2015-16 through 2018-19, then null rows from 2022-23 on. Its detail page shows
all four years; the sitemap omitted it. Sampling 40 of the 2,206 excluded
schools found 4 like this, so roughly 220 real pages were being withheld.

Publishable is now a property of the school, computed across every row, while
lastmod still comes from the latest row so the most recent Ofsted date wins.
The field list is a module constant shared with _has_publishable_data so the
two checks cannot drift.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-21 00:04:32 +01:00
tudor bb81337aba Merge pull request 'fix(seo): keep staging out of the search index' (#111) from fix/staging-noindex into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 51s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 2m1s
Reviewed-on: #111
2026-08-20 22:39:38 +00:00
TudorandClaude Opus 5 b34511e459 chore: record the branch cleanup manifest
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 16s
PR Checks / Build Frontend (no push) (pull_request) Successful in 45s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m30s
79 remote branches deleted: 77 fully merged into main, plus
feat/seo-crawl-hygiene and feat/england-only-corpus, whose content is
preserved on feat/seo-crawl-hygiene-main (PR #110).

Each line carries the SHA, so any branch can be restored with
  git push origin <sha>:refs/heads/<name>

The 14 branches left standing all carry content that differs from main and
none of them is mine to judge abandoned.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-20 23:23:30 +01:00
tudor f928a15c1e Merge pull request 'fix(seo): crawl hygiene and a per-family sitemap index (W1)' (#110) from feat/seo-crawl-hygiene-main into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 18s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 50s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m21s
Reviewed-on: #110
2026-08-20 22:23:10 +00:00
TudorandClaude Opus 5 1fc1e07d21 fix(seo): keep staging out of the search index
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Canceled after 13s
PR Checks / Build Pipeline (no push) (pull_request) Canceled after 0s
PR Checks / AI Code Review (Claude) (pull_request) Canceled after 0s
Staging serves the same image as production off stx., with robots.txt saying
Allow: / and no noindex — a fully crawlable duplicate of the site. Nothing
appears indexed today, most likely because the pages canonicalise across to
production, but that is a side effect rather than a control.

X-Robots-Tag, not a robots.txt Disallow. Disallow blocks crawling, which is
not the same as blocking indexing: a disallowed URL can still be indexed from
external links, and blocking the crawl means Google never fetches the page and
so never sees a noindex at all. Staging stays crawlable and answers noindex.

Matched on the staging host explicitly rather than 'any host that is not
production'. The inverted form would cover future environments automatically,
but its failure mode is deindexing production if the Host header ever arrives
rewritten by a proxy — which cannot be verified from here. This form's failure
mode is a new environment being indexable until someone adds it, which is
recoverable. Any new non-production hostname must be added.

The journeys only ever run against staging (deploy.yml passes
STAGING_BASE_URL; promote.yml smoke-polls production without Playwright), so
asserting the header there is safe. The two assertions live in one test
because the halves only work together.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-20 23:21:58 +01:00
TudorandClaude Opus 5 2208ad93c1 feat(seo): split the sitemap into a per-family index
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m4s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 17s
PR Checks / Build Frontend (no push) (pull_request) Successful in 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m2s
Search Console reports coverage per submitted sitemap, so one file per page
family is what will make W2's location pages measurable when they land. The
index's lastmod is generation time, which is the correct semantic there —
unlike on a <url>, where it would be a claim we cannot support.

Children sit under /sitemaps/ because Next only treats a whole bracketed path
segment as dynamic; a route folder named sitemap-[...parts] would be read as a
literal static segment and never match. Confirmed by the build output, which
lists /sitemaps/[...parts] as a dynamic route.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-20 23:15:00 +01:00
TudorandClaude Opus 5 24f3cb4c65 fix(seo): submit only school pages that have something to show
Drops the schools with neither results nor an Ofsted grade, adds /admissions
which was never listed, replaces the invented priority and changefreq with a
lastmod taken from each school's Ofsted date.

lastmod is omitted where no date is known rather than defaulted to now. An
always-now lastmod is a claim Google learns to distrust; absent honestly
means unknown.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-20 23:15:00 +01:00
TudorandClaude Opus 5 3816b92d06 fix(seo): noindex parameterised comparisons, keep bare /compare
25,193 schools make ~317 million pairs. The bare page stays indexable as the
landing page for the head term; the parameter space goes noindex, follow so
its outbound links still count.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-20 23:15:00 +01:00
TudorandClaude Opus 5 51ce2d6373 fix(seo): declare a canonical on every route
The homepage read eleven search params and declared no canonical, so every
filter combination was a crawlable near-duplicate of the page we most want to
rank. Rankings and admissions declared none either.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-20 23:15:00 +01:00
TudorandClaude Opus 5 5ddc7314fd fix(seo): canonicalise on the www host, which is the one that serves 200
The apex 301s to www at Cloudflare, but metadataBase, the school-page
canonical, robots.txt's Sitemap: line and the sitemap's own <loc> entries all
named the apex. Every one of those pointed Google at a redirect.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-20 23:15:00 +01:00
tudor 8ad2070e76 Merge pull request 'fix(data): drop the Welsh school GIAS does not type as Welsh' (#109) from fix/welsh-establishment-leak into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 49s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 1m18s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m25s
Reviewed-on: #109
2026-08-20 21:59:38 +00:00
TudorandClaude Opus 5 3aad5101a8 fix(data): drop the Welsh school GIAS does not type as Welsh
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 45s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 38s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 54s
Beechwood College (URN 142458, Sully, CF64 5SE) survived the England-only
filter. GIAS types it a Special post 16 institution (32), not a Welsh
establishment (30), so filtering on establishment type alone left it behind —
the last Welsh school on the site, and the reason Vale of Glamorgan was still
in the authority list.

The earlier verification claimed the type codes mapped onto the Welsh
authorities in both directions. That was checked exhaustively for Cardiff and
by count for three others; Vale of Glamorgan was never checked, and it was the
one that did not hold.

LA code is the reliable discriminator: GIAS gives the 22 Welsh unitary
authorities the contiguous block 660-681, which English authorities never use.
Filtering on postcode would have been wrong — Redbrook, Tutshill, Wyedean and
two other Gloucestershire schools carry NP16/NP25 postcodes because Royal Mail
areas straddle the border, and they are English schools with English data. An
e2e test now pins those five so the fix cannot be simplified into a postcode
filter later.

The 660-681 range is documented GIAS structure this project cannot verify from
its own data, so the range filters and the authority NAME checks: if the range
is ever wrong, a Welsh authority reappears in assert_england_only_schools and
the pipeline fails loudly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-20 22:54:24 +01:00
tudor c47fe38971 Merge pull request 'feat(data): publish England only, dropping Welsh and overseas establishments' (#107) from feat/england-only-corpus into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 51s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 1m15s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m27s
Reviewed-on: #107
2026-08-20 21:20:13 +00:00
tudor 8f211577c8 Merge pull request 'fix(e2e): scope the Distance-tab assertion, and separate the tile figures' (#106) from fix/e2e-distance-locator into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 50s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 1m26s
Reviewed-on: #106
2026-08-20 21:18:28 +00:00
TudorandClaude Opus 5 69f2201244 docs(seo): correct W1 plan's sitemap child routes
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 35s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 9s
Next only treats a whole bracketed path segment as dynamic, so the planned
app/sitemap-[...parts]/route.ts would have been read as a literal static
folder and never matched. Children move under /sitemaps/.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-20 22:09:00 +01:00
TudorandClaude Opus 5 e6048c9ca6 docs(seo): implementation plan for W1, crawl hygiene and sitemap
Five tasks: one canonical host, canonicals on every route, noindex on
parameterised comparisons, a sitemap that drops dataless schools and invented
priorities, and a per-family sitemap index.

Planning turned up a fault the spec had missed: the apex 301s to www, but
metadataBase, the school-page canonical, robots.txt's Sitemap: line and every
sitemap <loc> named the apex. Task 1 fixes it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-20 22:05:00 +01:00
TudorandClaude Opus 5 7650b16f62 feat(data): publish England only, dropping Welsh and overseas establishments
GIAS ships the whole UK plus overseas and offshore establishments. None of
them carry comparable DfE performance data — Wales does not publish on the
English measures at all — so every one of these pages rendered with null
results, null Ofsted and null phase. There were 2,036 of them: 1,569 Welsh,
123 offshore (Jersey, Guernsey, Isle of Man, Gibraltar), 316 British schools
overseas and 28 service children's schools. All 2,036 were being submitted to
search engines, alongside 29 local authorities that existed in the filters
purely to list them.

Filter at the mart boundary rather than the view layer. dim_school and
dim_location both exclude TypeOfEstablishment in {25, 26, 30, 37}, listed once
as vars.non_england_school_type_codes. Everything downstream reads those two
marts — search, the school page, /api/filters, rankings, Typesense and
build_sitemap() — so one filter removes them from the site and the sitemap
together, and Typesense drops them on its next rebuild since it recreates the
collection and swaps the alias rather than upserting in place.

coalesce rather than a bare NOT IN: a null type code would make the predicate
null and drop the row silently, and an unknown type is not grounds for
exclusion. No establishment has a null type today, but a future GIAS refresh
could ship one and the loss would be invisible.

assert_england_only_schools guards both directions: no excluded type survives
in dim_school, and dim_location holds no URN dim_school lacks — the API
inner-joins them, so the two filters drifting apart would silently shrink the
corpus.

Corpus goes from 27,229 schools to 25,193, and the authority list from 182 to
153. The 1,569 Welsh URLs now 404.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
2026-08-20 21:46:28 +01:00
TudorandClaude Opus 5 9abd020967 fix(e2e): scope the Distance-tab assertion, and separate the tile figures
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m4s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 59s
The failing journey was wrong; the page was correct.

  Locator: getByRole('button', { name: 'Distance' })
  Expected: 0   Received: 1

getByRole matches accessible names by case-insensitive SUBSTRING, so
{ name: 'Distance' } matched <button>Show this distance on a map</button> —
the map toggle added by the same feature. The assertion was meant to say "no
Distance tab in the admissions segmented control" and instead said "no button
anywhere whose label contains the word distance".

Now scoped to the control it is about, via its own aria-label, and read
positively: the tab list must contain "This year" and must not contain
"Distance". An absence check against an unscoped locator passes for the wrong
reason the moment the selector stops matching, which is exactly how the
regression this test guards would return unnoticed.

Two sibling locators had the same weakness and are tightened: 'Check' is a
prefix of the button's own busy label "Checking…", and the figure matcher
accepted `(miles|m)` — a leftover from the mixed-unit era that would have kept
passing if the headline regressed to metres, which is the thing #105 just
fixed.

Tightening that matcher surfaced a real defect behind it. The cut-off figure
and its metric support are flex children with the gap drawn by CSS and nothing
between them in the text layer, so the element read "0.88 miles1.4 km" —
what a screen reader announces, and why a `miles\b` boundary could never
match. Both templates now carry an explicit space. Whitespace text nodes are
not rendered as flex items, so the reading changes and the layout does not.

Verified against staging: 54/54.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WDvkyqqHABm4bmth2kjAxE
2026-08-20 21:01:28 +01:00
tudor 228eb214f5 Merge pull request 'fix(admissions): state distance in miles throughout, never mixed' (#105) from fix/standardise-distance-units into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 51s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m28s
Reviewed-on: #105
2026-08-20 19:39:18 +00:00
TudorandClaude Opus 5 ea5249a2ea fix(admissions): state distance in miles throughout, never mixed
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 45s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 11s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 58s
The postcode check read "69 m away — inside the September 2026 cut-off of
0.17 miles". Both numbers are right and the sentence is still useless: the
reader has to convert one of them to check a comparison we had already made
for them.

The cause was a readability rule of mine in formatCutoffDistance, which swapped
to metres below 100m on the grounds that "0.04 miles" carries less than "69 m".
Taken one figure at a time that holds. Taken in a sentence containing two
figures it guarantees a mismatch whenever they fall either side of the
threshold — and a 270m cut-off with a nearby home does exactly that.

Miles now lead everywhere. It is the unit UK school admissions runs on:
councils publish cut-offs in miles (90% of the collected source rows), and it
is what a parent has already been quoted in their booklet and offer letter.
The metric figure survives only as support beside the miles figure on the
Admissions tile, where it converts the same value rather than presenting a
second one to compare.

Below 0.01 miles the decimal places run out rather than the unit being wrong,
so a very short distance is described — "under 0.01 miles" — instead of
rounding to a flat "0.00 miles", which would read as no distance at all.

Both figures in the verdict now go through one formatter with no fallback that
could reach for another unit. The old `?? "N m"` fallbacks on that line were a
second route to the same defect and are gone.

Covered by a sweep over sixty home/cut-off combinations spanning the old
switch point, asserting no verdict contains a metric reading and that exactly
two miles figures appear; plus the reported case pinned verbatim, and an e2e
guard on the rendered verdict.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WDvkyqqHABm4bmth2kjAxE
2026-08-20 20:35:05 +01:00
tudor ffe7e04951 Merge pull request 'feat(admissions): publish the latest cut-off only, holding history back' (#104) from feat/latest-cutoff-only into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 19s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 50s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m29s
Reviewed-on: #104
2026-08-20 17:51:18 +00:00
TudorandClaude Opus 5 c9a1892bfb feat(admissions): publish the latest cut-off only, holding history back
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m4s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 16s
PR Checks / Build Frontend (no push) (pull_request) Successful in 45s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 11s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 3m17s
Earlier years are to become a paid feature, so they stop being published.

The load-bearing part is that this is a change to the API, not only to the
page. /api/schools/{urn} is public and unauthenticated: leaving
admission_distance_history in the payload while declining to render it would
have handed the whole record to anyone who opened the network tab. It is
withheld at the source, and the page follows.

Nothing changes upstream. The tap, the plausibility band and
fact_admission_distance are untouched and still load every published year, so
restoring history for entitled callers is a change to one function in
data_loader rather than a re-collection.

What the reader now gets is the latest figure on the Admissions tile, and a
Distance section that answers the question the number alone cannot: whether
their own address falls inside it. Retitled to "How far away are you?", which
is what it now does — the previous title described a record that is no longer
there.

Removed with the history: the trend chart, the year-by-year table, the
per-year verdict strip, the trend summary and the coverage note, along with
their CSS. The section goes from 743px to 417px.

One consequence worth naming. A run of years used to soften a single close
call — a home just outside one year's cut-off was usually inside another. With
one year published, the "too close to call" band is the entire safety margin
between a parent and a place they do not have, so the verdict now names its
year, and the three outcomes are tinted apart rather than distinguished by
wording alone.

The existing stylesheet test earned its keep here: the three verdict classes
were referenced before they were written, and it caught them. Unstyled, a
"beyond the cut-off" result would have been indistinguishable from an "inside"
one — the exact failure the longhand class map was written to prevent.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WDvkyqqHABm4bmth2kjAxE
2026-08-20 18:44:57 +01:00
tudor 50b599a09b Merge pull request 'fix(admissions): move the cut-off detail into its own section' (#103) from fix/admissions-section-height into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 52s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m29s
Reviewed-on: #103
2026-08-20 14:03:01 +00:00
TudorandClaude Opus 5 94151c58ea fix(admissions): move the cut-off detail into its own section
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m5s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 13s
PR Checks / Build Frontend (no push) (pull_request) Successful in 45s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 11s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m59s
The admissions card measured 1503px on a live school page — half the height
of every section put together, and nearly three times the next largest — with
its default view rendering as four tiles adrift in about 1080px of blank card.

The cause was a layout trick meeting content it was never sized for. The
admissions views are stacked in one grid cell so switching them never shifts
layout, and the hidden ones keep their box: only visibility is dropped. That
works while the views are comparable. The distance view added in #102 carries
a chart, a table and a map, came to 1402px against the tile grid's 316px, and
pinned every other view to its height — including the one that renders by
default, which nobody had clicked.

Rather than only unpinning it, the detail moves out. Every other topic on the
page is a section with a nav entry, and "how close did we need to live, and
would we have got in?" is a topic, not a variant reading of the intake
figures. The headline number stays on the Admissions tile where the intake
story is; the record behind it now lives in a Distance section directly below.

  admissions   1503px -> 554px
  distance        new -> 743px   (median section on the page is ~528px)

Three further changes, each of which also makes the content better rather
than only shorter:

  * The map renders on request. Before a postcode is entered it is a circle
    drawn round a school, and it costs a Leaflet bundle and 240px to say so;
    a successful check opens it automatically, which is the point at which it
    starts answering something. Map height 320px -> 240px.
  * The chart appears only at the four published years that let the summary
    state a direction. Below that we already refuse to call the series a
    trend, and a line through three points asserts one regardless of what the
    sentence beneath it admits. The table carries those years anyway, with
    the reasons a line cannot show.
  * Three caveat paragraphs become one. They said walking-route twice and
    made the same point about priorities in two voices. It now sits in
    CutoffDistanceDetail rather than inside the check, so it still renders
    for a school with coordinates missing, where there is a table but no map
    and no check.

The new e2e guard asserts no section exceeds 2.5x the median section height.
Measuring the card's internals cannot catch this: the tile grid is flex: 1,
so it absorbs the stretch and every box still looks full. The first version
of this test targeted an arbitrary primary, passed against the live bug, and
proved nothing; pointed at a school that actually holds cut-off history it
fails on staging with "#admissions is 1459px against a 526px median".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WDvkyqqHABm4bmth2kjAxE
2026-08-20 14:54:02 +01:00
tudor 8bf6145a73 Merge pull request 'feat(admissions): add the cut-off history, map and postcode check' (#102) from feat/last-distance-offered-full into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 20s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 51s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 1m14s
Reviewed-on: #102
2026-08-17 07:51:14 +00:00
TudorandClaude Opus 5 a72323874f feat(admissions): add the cut-off history, map and postcode check
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 17s
PR Checks / Build Frontend (no push) (pull_request) Successful in 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m39s
Completes the last-distance-offered feature against the mockup: the
year-by-year record, the same numbers drawn over real streets, and the
reader's own address measured against them.

Serving the history
  The first cut deliberately served only the latest year, because a plain
  series would draw a trend line straight through gaps that are absences of
  publication, not of a cut-off. That reasoning is answered rather than
  abandoned: cutoffYearRows classifies every year in the span, and the chart
  breaks the line rather than interpolating across it.

  A missing year is not one fact but three. It may be unpublished; it may be
  a year the school was not oversubscribed; or there may be no record at all.
  Collapsing them into "no data" throws away the reassuring case and hides
  the important caveat, so each is stated in words in the table.

  The claim is held to what the data supports. fact_admissions.oversubscribed
  compares FIRST PREFERENCES against places, which does not establish that
  every applicant was offered one — so the copy says "places available on
  first preferences" and a test asserts the stronger claim never appears.

The trend summary is not a verdict
  It names both endpoints and their years and lets the reader conclude. It is
  withheld below four published points, and a swing under a tenth of the
  earlier figure is reported as "broadly the same" rather than dressed up as
  a direction.

The postcode check
  This is the only place on the site that answers a question about a family
  rather than a school, so most of the care went into what it refuses to say.
  postcodes.io returns a centroid covering roughly fifteen addresses, which
  against a 500 m cut-off is a fifth of the whole distance — so a margin
  inside 100 m returns "too close to call" rather than a place a family does
  not have. Unpublished years count as unknown, never as a pass. The limits
  are stated before the check is used, not revealed with the answer.

  The postcode is geocoded in the browser and never stored.

Both templates
  Banded and selective secondaries are exactly where this matters most, so
  the detail is shared. The primary page gives it a third tab; the secondary
  page is one flat panel by design and renders it inline.

Absence is explained rather than reported. A selective school's missing
figure is explained by how it admits; a consistently undersubscribed school
reads as good news.

Also makes the batch loader's test double honour ORDER BY. It was a no-op,
so "latest row per URN" was really "first row in the fixture" and the test
would have passed with the sort reversed or removed.

Verified: 214 frontend tests, 54 backend, 45/53 e2e green against staging
(the 8 cut-off journeys skip until the DAG runs). Rendered offline against
the real compiled CSS in both themes and at 390px; every new surface clears
WCAG AA, measured on composited pixels.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WDvkyqqHABm4bmth2kjAxE
2026-08-16 13:42:06 +01:00
tudor 5a71f54d94 Merge pull request 'feat(admissions): show the last distance offered where councils publish it' (#101) from feat/last-distance-offered into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 43s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 51s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 3m15s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 2m53s
Reviewed-on: #101
2026-08-16 12:21:24 +00:00
TudorandClaude Opus 5 88c653215d feat(admissions): show the last distance offered where councils publish it
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 31s
PR Checks / Build Frontend (no push) (pull_request) Successful in 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 1m12s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 2m7s
Adds the cut-off distance a parent actually asks about — "how close do we
need to live?" — end to end: a Singer tap, dbt staging and mart models, an
Airflow DAG, and a tile on both detail templates. 3,597 schools across 57
local authorities carry a figure; the rest are unchanged.

There is no national source for this. Each LA publishes its own cut-offs in
its own format, and the collected CSV is transcribed from PDFs, spreadsheets
and web pages — so most of the work here is deciding what is safe to show.

Data
  * tap-uk-school-distance loads the CSV verbatim into raw. Keyed on
    (urn, year, school_name), because school_name carries the admission
    route: (urn, year) alone collides on 118 keys and a reload would have
    silently dropped every band but one.
  * stg_school_distance applies a 25 m – 25 km plausibility band. The source
    contains 0.0-mile rows (published where a school filled on a higher
    criterion), 1-metre cut-offs, and one reading 533 miles — ~4% of rows,
    all of which would put a visibly wrong number on a live page.
  * fact_admission_distance collapses routes to one row per school per year
    using the furthest, and keeps route_count so the page can say the figure
    is the widest of several bands rather than the one for a given child.

Serving
  * Kept out of fact_admissions: that mart is EES-derived and near-complete
    for England, this one covers 57 LAs, and the two refresh independently.
  * Latest year only. Coverage is ragged — a school may have 2021 and 2026
    and nothing between — so a history array would invite a trend line drawn
    through gaps that are absences of publication, not of a cut-off.
  * The Admissions section now renders on either source. 3% of the schools
    that render have a cut-off and no EES admissions row, and gating on
    admissions alone would have hidden the figure on those pages.

Interface
  * The year travels with the figure everywhere it appears; a cut-off
    detached from its admissions round is not a fact about anything.
  * "Not a fixed catchment — it moves every year" sits under every instance,
    because that is the inference a parent will otherwise draw.
  * Replaces a hardcoded "Historical distance cut-off data is not available
    for this school" that appeared on every secondary page, including the
    ones whose council does publish it. The absence is now stated only when
    it is real, and names the authority that would hold it.

The tint costs the muted tokens their AA margin: measured on the composited
backdrop (not the computed one, which reports the untinted card), --text-muted
falls to 4.09:1 in dark theme. The tile uses --text-secondary instead — 6.50:1
dark, 6.60:1 light.

The DAG is manual, like the other annual ones: councils publish on allocation
day, each on its own timetable, so there is no date worth scheduling against.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WDvkyqqHABm4bmth2kjAxE
2026-08-15 22:48:30 +01:00
tudor 5156a85bd1 Merge pull request 'chore: drop the hero byline, and refresh a figure in the UX audit notes' (#100) from chore/byline-removal-and-audit-figure into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 50s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 1m5s
Reviewed-on: #100
2026-08-15 09:25:59 +00:00
TudorandClaude Opus 5 fa1abff642 chore: drop the hero byline, and refresh a figure in the UX audit notes
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 6s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 47s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 14s
Two unrelated working-tree changes, committed as one at the owner's request.

Removes "Built for parents, by a parent." and its comment from the hero. It
was added two commits ago; taking it out is the owner's call, and the reasons
it was placed under the search rather than in the footer no longer apply.

The .heroByline rules in HomeView.module.css are deliberately left in place.
They are now unreferenced, but the class was purpose-built for this one line
and keeping it makes restoring the byline a one-line change. If the removal is
permanent, that block (and its 640px media query) should go with it.

Also updates two quoted figures in the 2026-07-02 UX audit notes from
"24,000+" to "27,000+".

Worth noting for the record: that file documents what the page said when it was
audited, and at that time it genuinely did say "24,000+" — which was itself the
bug later fixed by reading unique_schools instead of a field the API never
sent. Editing the quoted evidence makes the note read consistently with the
current site, at the cost of no longer being a verbatim record of what was
observed. Left as the owner edited it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 10:21:29 +01:00
tudor 38acc76555 Merge pull request 'fix(charts): make the national-average marker visible on both templates' (#99) from fix/chart-marker-contrast into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 49s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 16s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 1m3s
Reviewed-on: #99
2026-08-15 08:56:40 +00:00
tudor c7e0c2eac7 Merge pull request 'feat(home): swap in the higher-fidelity hero artwork' (#98) from feat/hero-artwork-v2 into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 51s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 59s
Reviewed-on: #98
2026-08-15 08:56:33 +00:00
TudorandClaude Opus 5 59ac9c10b9 fix(charts): make the national-average marker visible on both templates
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m1s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 46s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m5s
The marker was var(--brand) — the identical value to the bar fill it sits on.
Measured by pixel-sampling every bar on both templates, in both themes:

  primary   SatsChart .natTick        1.00:1  (6 bars)
  secondary .att8VizNatLine           1.00:1

Not low contrast. The same colour. It scored 5.47:1 only against the empty
track, which means it was visible precisely when a school was BELOW the
national average and vanished for every school at or above it — failing for
exactly the schools people are looking for.

No single colour fixes this, because the marker's position is data-driven: it
can land on the bar, on the empty track, or across the boundary. It is now a
knockout — a light core carrying a dark edge, both from tokens that flip with
the theme, so one part or the other always separates:

              on the bar        on the track
  light       5.47 / 9.70:1     15.17:1
  dark        7.81 / 10.85:1    13.52:1

THE LEGEND DESCRIBED A CHART THAT DID NOT EXIST

Both data swatches were var(--status-above) green while their bars were
var(--brand) teal, and the two were identical to each other — one swatch for
two series. Worse, the only swatch matching the bar colour was the one
labelled "National average", so reading the chart by matching colours told you
the teal bars were the benchmark. Each swatch now carries its bar's exact
value, and the marker swatch mirrors the knockout.

TWO SERIES, ONE COLOUR

Expected and Exceeding were both var(--brand), distinguished only by row.
They are a sequential pair — exceeding is the same cohort at a harder bar — so
they take two steps of one hue, the harder measure being the step further from
the ground in each theme.

They measure 1.77:1 (light) and 1.39:1 (dark) against each other, and that is
accepted rather than overlooked: two fills that must EACH clear 3:1 against
the same white track are geometrically forced close together. The distinction
is carried by the row labels and printed values; colour is redundant here, not
load-bearing.

THE TEST THAT SHOULD HAVE CAUGHT THIS

The WCAG journey composites backgrounds by walking the ancestor chain, but
these markers are absolutely positioned over a sibling — ancestor-walking is
structurally blind to overlap, which is why this shipped in two templates and
passed every gate. The new journey asks the stacking order instead, via
document.elementsFromPoint.

Writing it surfaced a second trap worth recording: elementsFromPoint takes
viewport coordinates and returns an empty stack off-screen, and these markers
sit ~1200px down. The first version defaulted an empty stack to white, which
made teal-on-teal look like teal-on-white and PASS in the light theme. It now
scrolls each marker into view and counts any marker it cannot resolve a
backdrop for as a failure rather than a pass.

Verified both directions: the new journey fails against current staging with
"1.00:1 over rgb(15,118,110)" in both themes, and passes against this build
with 6/6 markers measured at 5.47–15.17:1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 09:48:41 +01:00
TudorandClaude Opus 5 eddf74745f feat(home): swap in the higher-fidelity hero artwork
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 43s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 11s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 13s
Same 16:9 frame, but not a drop-in replacement — the composition, palette and
copy area all moved, and each one drives a change here.

COPY AREA

The old artwork was a flat #FDF9F3 down its whole left side. This one runs
peach #FEE8D2 at the top to cream #FDF3E7 around 43% height, and below ~48%
the left edge is foliage rather than cream at all. --hero-ground is resampled
to #FEF2E1, the middle of the pale run where the headline and search actually
sit; the scrim covers the foliage further down.

Measured on rendered pixels with the text hidden, sampling the real glyph runs
(via Range, not the element boxes) plus a 120px growth margin:

           title      body      byline
  light    13.61:1    5.74:1    6.66:1
  dark      9.49:1    5.45:1    8.35:1

Body drops from 6.52:1 to 5.74:1 as the foliage comes closer, still clear.

BAND CROP

The schoolhouse moved to ~82% across the frame, leaving only ~140px of artwork
to its right, so the band crop is anchored to the right edge and takes 1344px
back — putting the school at 73%, which the build script now derives and
prints rather than leaving it to drift from the CSS.

The crop is also 3.2:1 rather than matching the phone. The band is not one
ratio: it runs 2.4:1 on a phone to about 3.8:1 under the one-column
breakpoint. Cropping at the narrow end means the wide end throws away height,
which cut the flag off the roof and the base off the building. Sitting above
the middle costs a little width on phones — where the crop's left is hillside —
and keeps the building whole where it matters.

BAND HEIGHTS

Raised to 13rem (861–860px) and 10rem (≤640px). The band was widest-per-height
at exactly 640px, where an 8.5rem band measured 4.2:1 — worse than any wider
viewport, because the height steps down at that breakpoint while the width does
not. Ratios across the range are now 2.0 / 2.6 / 3.6 / 3.1 / 3.8 rather than
spiking. The search still lands at 442px on a 667px viewport.

WEIGHT

Source is 3.1MB; a browser fetches one file — 29–59kB on desktop, 10–14kB on a
phone. Widths re-cut for the larger master: 2000/1400/1000 wide, 1344/900/600
band.

Verified: 0 AA failures across both themes at 1440 / 860 / 390, every srcset
entry present on disk with no orphans, tsc clean, 159/159, build green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 09:22:37 +01:00
tudor d5f3fdf0f9 Merge pull request 'feat(home): add a first-person byline under the hero search' (#97) from feat/hero-byline into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 51s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 1m1s
Reviewed-on: #97
2026-08-15 08:00:47 +00:00
TudorandClaude Opus 5 3015c37bac feat(home): add a first-person byline under the hero search
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 12s
PR Checks / Build Frontend (no push) (pull_request) Successful in 43s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 11s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 9s
"Built for parents, by a parent." — the one line on the page written by a
person rather than by a product.

Placed under the search rather than in the footer, which is where it would
have been true and unread. It does its work at the moment someone is deciding
whether to trust a page full of government statistics, which is the moment
they are looking at the search box.

Set apart without shouting: display face, a step down in size, and a short
brand rule in place of a bullet. No italic — Manrope ships none in the loaded
weights, so font-style would be synthesised into a slant, the same reason
.heroEmph resets it.

Deliberately the only claim of its kind on the page. Every other trust signal
here is about the data's provenance and is checkable against the DfE and
Ofsted; this one is about who built it, and is not. So it is stated once,
plainly, and never repeated — the opposite of the "Official & trusted" line it
now sits near, which claimed something about the site that was not true.

Measured 7.26:1 in the light theme and 8.86:1 in dark.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 08:59:43 +01:00
tudor 153b26a32f Merge pull request 'fix(home): stop implying we are official, and fix the mobile hero and search' (#96) from fix/hero-mobile-and-wording into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 50s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 56s
Reviewed-on: #96
2026-08-14 22:28:33 +00:00
tudor e373241d51 Merge pull request 'fix(e2e): assert the brand lockup and touch icon as they are actually built' (#95) from fix/e2e-brand-assertions into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 51s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 11s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 1m2s
Reviewed-on: #95
2026-08-14 22:28:10 +00:00
TudorandClaude Opus 5 4043270a77 fix(home): stop implying we are official, and fix the mobile hero and search
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 48s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 11s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m6s
Three things, all reported from the live mobile view.

WE ARE NOT AN OFFICIAL SERVICE

The value prop read "Official & trusted", whose grammatical subject is this
site — it reads as a claim that schoolcompare is an official service. It is
not; it is an independent site that republishes official figures. Now "Built
on official data", which describes the data instead.

Checked every other use of the word: all nine describe the data ("official DfE
figures", "the official figure isn't in") and are correct as they stand. That
one title was the only place the site described itself.

The footer now says it outright — "An independent site. Not affiliated with
the Department for Education or Ofsted." — so it appears on every page rather
than being left to inference. An e2e test asserts both halves: that the
statement is present, and that no text presents the site itself as official.

The disclaimer first measured 4.71:1 against a 4.5 floor. That is a fine
margin for decoration and the wrong one for a line whose job is to be legible
to someone checking whether this is a government site; it is now 5.59:1,
quieter than the copy around it by size rather than by contrast.

THE ARTWORK SAT UNDER THE SEARCH ON PHONES

The DOM keeps .heroContent first so the desktop overlay does not depend on
source order, which left the band stranded at the bottom of the panel, reading
as a strip stuck on the end rather than a hero image. `order` moves it above
the copy on phones; it is decorative and aria-hidden, so no reading order
changes. Measured on a 667px viewport — the shortest phone still in use — the
search button lands at 418px, comfortably inside the fold.

THE SEARCH INPUT WAS UNUSABLE ON PHONES

"Search schools" is a fixed 134px with white-space: nowrap, so it took 48% of
the row. Measured on staging:

  390px   input text space 102px   placeholder needs 194px
  360px                     72px
  320px                     32px

At 320px you could not see what you were typing. The button now wraps to its
own full-width row below 480px, which fixes 360px and up — 390px goes from
102px to 226px of text space. The pill stays a single element, so it keeps its
border, shadow and :focus-within ring, and the button gains a full-width tap
target.

320px is still ~30px short. Closing it needs a shorter placeholder, which three
other tests match on by exact string; left alone deliberately rather than
churn them for a width that is effectively gone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 22:59:12 +01:00
TudorandClaude Opus 5 e65688d600 fix(e2e): assert the brand lockup and touch icon as they are actually built
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 48s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 11s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 21s
The staging gate has been failing these two since the supplied logo artwork
replaced the reconstruction. Both tests were still asserting the previous
implementation, and both were right to fail — they were just describing
something the site no longer does.

  the header carries the schoolcompare lockup
    Looked for an <svg> inside the header link. The mark is raster now:
    <picture><source><img src="/brand/mark.png">. Nothing matched, so the
    locator timed out.

  the brand asset set is complete and served
    Requested /apple-icon, which 404s. The route moved when the generated
    app/apple-icon.tsx became a static app/apple-icon.png — generated icons
    serve at /apple-icon, static ones at /apple-icon.png with a content hash.
    The icon was present and correctly linked the whole time.

Both now read from the page instead of hardcoding the shape of the answer: the
touch icon is fetched from its own <link rel="apple-touch-icon"> href, the way
this test already handles og:image, so it follows whatever Next emits.

The lockup assertion also got stronger rather than merely corrected. A
<picture> whose sources all 404 still lays out and still satisfies
toBeVisible(), so that alone would go green on a broken lockup; it now asserts
naturalWidth, which only a decoded image can satisfy.

Verified against staging directly: 41/41 pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 22:34:22 +01:00
tudor 7f4dfa2748 Merge pull request 'fix(home): art-direct the hero's fallback path, and declare sharp' (#94) from fix/hero-fallback-and-sharp into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 50s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m12s
Reviewed-on: #94
2026-08-14 21:28:13 +00:00
TudorandClaude Opus 5 bdaa05cd54 style(home): lift the hero artwork's dark-theme brightness to 0.75
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 48s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 9s
At 0.52 the scene was legible but heavily suppressed; 0.75 lets the hills,
path and schoolhouse read while the white H1 stays comfortably the brightest
thing on the panel.

Re-measured rather than assumed, because in the dark theme the text is light
and the artwork is behind it — brightening the image lowers text contrast
rather than raising it. Off rendered pixels, sampling background up to 120px
past each line's right edge:

  brightness   title      body
  0.52         11.01:1    6.44:1
  0.75          9.48:1    5.21:1

Both still clear the 4.5:1 floor, body being the binding one. The trade is
recorded next to the value so the next person to reach for it knows it has a
floor and not just a taste range.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 22:26:23 +01:00
TudorandClaude Opus 5 043506cb6b fix(home): art-direct the hero's fallback path, and declare sharp
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m4s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 45s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m32s
Two findings from review on #93, both verified before fixing.

<img src> cannot vary by viewport, so it was always the wide desktop crop. A
browser taking neither AVIF nor WebP therefore fell through to the desktop
frame on a phone and lost the schoolhouse — the exact failure the two-crop
<picture> exists to prevent, surviving in the one path nobody looks at. The
band JPEG the build script already emitted was never referenced, which was the
tell. It now backs a <source media> placed after the modern formats, so they
still win wherever they are supported.

Verified by stripping the AVIF and WebP <source>s at runtime and letting
<picture> re-resolve, which is what an old browser actually sees:

  phone    hero-band-500.avif  →  hero-band-700.jpg   (band crop, school kept)
  desktop  hero-wide-1672.avif →  hero-wide-1200.jpg

sharp was not declared: it arrives transitively from next@16.1.6, so the
documented regeneration command works today and breaks on a Next upgrade or a
clean install that resolves differently. Declared in devDependencies for the
same reason next.config.js already declares its traced font files rather than
trusting the tracer to keep finding them.

The third finding — that the hero's licence is marked unconfirmed in
CREDITS.md while the artwork ships — is accurate and deliberate. It is the
owner's to answer; recording it as unknown is the point of the file.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 22:07:01 +01:00
tudor 0466986195 Merge pull request 'feat(home): use the supplied hero artwork instead of a drawn one' (#93) from feat/hero-artwork into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 53s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m14s
Reviewed-on: #93
2026-08-14 20:41:46 +00:00
TudorandClaude Opus 5 3f0e05cc99 feat(home): use the supplied hero artwork instead of a drawn one
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 46s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m29s
Replaces the hand-drawn SVG landscape with the illustration supplied by the
project owner. Master is assets/hero-source.png; everything under
public/brand/hero-* comes from scripts/build-hero-images.js and should never be
hand-edited.

LAYOUT

The artwork is composed as a full-bleed hero: it reserves an empty cream area
down its left side for the headline. The old hero was a two-column grid with
art in the right 0.88fr, which would have cropped that reserved area off and
shrunk the scene into a thumbnail — the one thing the picture is built not to
be. So the panel is now a single layered block: artwork behind, copy on top,
and below the one-column breakpoint the artwork leaves the background and
becomes a band under the search.

Overlaying does not survive down to phone widths — the panel gets too narrow
for the copy to stay inside the cream, so the scrim would have to cover nearly
the whole image and you would be left with a tinted rectangle. Hence the
switch at 860px rather than a single treatment stretched across every width.

CONTRAST

The copy sits on a gradient of --hero-ground, a new token sampled from the
artwork's own cream (#FDF9F3) rather than from Sand. Sand is eight to thirteen
points darker per channel, which leaves a visible seam straight down the hero.
The scrim exists because the artwork is a fixed image on a fluid panel: past
some width the headline would otherwise land on hillside green.

Measured on rendered pixels, sampling background up to 120px beyond the right
edge of each line, so a longer line still has margin:

  light  title 14.36:1   body 6.52:1
  dark   title 11.01:1   body 6.44:1

The worst light case is hillside green showing through the scrim at 6.52:1.

TWO CROPS

The slot is two shapes: roughly 2.1:1–2.7:1 behind the desktop panel, and
2.6:1–4.9:1 as the band. A single file under object-fit: cover centre-crops,
and at the band's extreme that slices a strip through the scene and loses the
schoolhouse — exactly how the drawn hero failed on phones. <picture> switches
crop, not just resolution: the band file is pre-cropped around the school and
is already near 2.6:1, with the subject at ~65% across so squeezing toward
4.9:1 crops the empty sides instead.

WEIGHT

1.6 MB PNG in, AVIF and WebP out; a browser fetches exactly one file — about
23–33 kB on desktop, 9–18 kB on a phone. The JPEG is only the <img> fallback.
`sizes` describes the real panel box (max-width 1400 minus padding) rather than
100vw, which over-requested a candidate at every width on the LCP element.

DARK THEME

A raster cannot be re-graded token by token the way the drawing was, but it
would reproduce the same failure — a bright illustration is the brightest
object on a near-black page. It is dimmed in CSS to read as dusk, and the
scrim fades it into the dark panel rather than into cream.

TESTS

The two illustration journeys are replaced by three, each covering a failure
that still renders a valid-looking page: the artwork actually loading
(naturalWidth, not src), the crop switching at the breakpoint, a modern format
winning negotiation, and the dark theme dimming it.

public/brand/CREDITS.md records provenance for every asset in that folder. The
hero's licence line is marked unconfirmed — that one needs the owner.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 21:36:40 +01:00
tudor f1819e9c4d Merge pull request 'fix(home): correct what the landing page claims, and give it one rhythm' (#92) from fix/homepage-truth-and-rhythm-main into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 51s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 0s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m13s
Reviewed-on: #92
2026-08-14 18:18:53 +00:00
TudorandClaude Opus 5 97ac5c9cef fix(a11y): clear the four AA failures blocking the staging E2E gate
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 49s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 5m29s
Main's staging E2E has been red since #90. Two of the four failures were the
staging container serving a stale image at the moment the gate ran — apple-icon
and the header lockup both check out against staging now. The other two were
real, and both are the same mistake: a colour pairing verified against one
ground while the element sits on another.

  * .heroEyebrow  --brand on its own 10% tint over Sand is 4.19:1. The token
    clears AA on Sand, but the tint darkens the ground under the label, and
    that composite was never the thing measured. --brand-strong is 5.85:1.

  * .hiwVisual    The preview panel was grounded in Sand while everything
    inside it is a translucent status tint — and those tints are specced to
    clear AA over --bg-card. Over Sand the report-card chips landed at 4.22:1
    and 4.29:1. The ratio depended on a background two levels up. Moving the
    panel to the card surface puts them at 5.69:1 and 5.81:1; a border keeps
    it reading as an inset frame now that panel and card share a colour.

  * Footer .sectionTitle  --sage flips with the theme; the footer band does
    not (it is teal in both). So the pairing only held in one of them — the
    dark sage measured 4.08:1, on every page. Now --on-sunken-muted, which is
    what the --on-sunken-* family exists for, as Footer.tsx's own header
    comment already says.

  * .compareHeadLabel  --text-muted on the header row's tint is 4.45:1 in the
    dark theme. Under by a hair, same cause. Now --text-secondary.

The harness gained the footer, because it had no footer and so could not have
caught the one failure that appeared on all three pages. Rewriting fragments
now uses each CSS module's own hash — the footer rewritten with HomeView's
prefix renders unstyled, which would have made any contrast measured on it
meaningless while still reporting a number.

Verified: 0 AA failures in both themes across the assembled page, measured with
the same probe the e2e test uses, against the real compiled CSS.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 18:08:38 +01:00
TudorandClaude Opus 5 dc22fd2853 fix(home): correct what the landing page claims, and give it one rhythm
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m5s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 46s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m25s
The homepage made four statements that were not true, carried elements that
asked nothing of anyone, and had a hero illustration that broke in both the
places it had to work.

Claims, all verified against the code or the API:

  * "24,000+ schools" (three places) against a real 27,230. The fact box meant
    to show the live figure rendered its own fallback on every request, because
    DataInfoResponse declared a `total_schools` field the API has never sent —
    it sends `unique_schools`. The fetch succeeded; only that field was
    undefined, so nothing threw and nothing failed. The interface, not the
    code, was the thing that was wrong.
  * "Up to three schools side by side" against MAX_SCHOOLS = 5, contradicting a
    card 400px below it that correctly said five.
  * "Class sizes" — data the codebase has never held. That copy line was the
    only hit in a full-repo grep.
  * Invented results and Ofsted grades attributed to two real, named schools
    in the compare preview.

Also one feature, three words: Compare (nav), shortlist (footer), pin (cards).
Settled on Compare everywhere. And <title> was the bare string "Home".

Cut: the trust line (repeated the coverage figure one paragraph after the hero
gave it, behind three decorative dots), the "Start exploring" row (three links
to two destinations already in the nav), the six-row coverage table, and three
of the four countdown cards — which gave the page's largest numeral to dates up
to 245 days away, two of them offer days, which cannot be missed. All four
dates remain, at proportionate weight. Value-prop titles drop from <h2> to <p>;
they were outranking the page's real headings in the document outline.

Rhythm: the gaps between the seven landing bands were 24/32/24/16/48/32/16px,
each band setting its own margin, with four different section-header
treatments between them. The page container now owns one gap, and there is one
header pattern. An e2e test asserts the gaps are identical.

Illustration: it kept a fixed light palette in both themes, which left a pale
sky slab as the brightest object on a near-black page, out-shouting the H1 and
the search box. It now reads from --ill-* tokens with a dark re-grade. And the
hero slot ranges from 1.34:1 to 4.9:1 across breakpoints, which no single
composition survives under `slice` — at 860x176 a 540x520 scene shows only its
bottom 110 units, so the schoolhouse was cropped away entirely on phones,
leaving hills and a pin pointing at nothing. There are now two compositions,
each drawn against the crop window its own breakpoint produces, with CSS
showing one. Both are static server-rendered SVG.

The deadline bar renders on the server rather than on hydrate. The effect-based
version needed a reserved height, and one guessed number cannot cover a block
whose supporting line wraps differently at every width — measured, it was short
at all four, shifting the page up to 108px on a phone.

Verified on the built output through an offline render harness (no local
server): real compiled CSS, real rendered markup, four widths, both themes.
tsc clean, 159/159 unit tests, build green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 17:29:47 +01:00
tudor 6b117dd26c Merge pull request 'feat(brand): use the supplied logo artwork instead of a reconstruction' (#90) from feat/brand-logo-artwork into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 42s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 53s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 2m0s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m42s
Reviewed-on: #90
2026-08-08 21:41:47 +00:00
Tudor 9ee4d45a94 fix(brand): give both logo colourways one canvas so the aspect hint is right
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m1s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 35s
PR Checks / Build Frontend (no push) (pull_request) Successful in 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 1m11s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 10s
LogoMark derived width from a single hardcoded 153/189, taken from mark.png,
while mark-on-dark.png was 98×112. Both call sites size the mark with
height:100%/width:auto, so the rendered size came out right in the end — but
the width/height attributes are the pre-load aspect hint, so the on-dark
artwork reserved the wrong box and reflowed on load. Any future call site
without that CSS would have rendered it stretched outright.

Per-variant attributes would not have fixed it. variant="auto" is a single
<img> whose srcset swaps the file underneath it, so one set of attributes has
to serve both colourways; the only correct fix is for the two files to share
a ratio.

They also had different artwork ratios (0.810 against 0.833) and different
padding, which the review did not reach: the logo changed size slightly
whenever the OS theme flipped. Both are now written onto one 176×208 canvas
with the artwork at the same height, centred, so they are drop-in swappable.

Measured on the built output, header mark, before → after:
  light   attr 31×38, rendered 30.75×38   →   attr 32×38, rendered 32.15×38
  dark    attr 31×38, rendered 33.25×38   →   attr 32×38, rendered 32.15×38
A 2.25px reflow and a cross-theme size jump both become 0.15px of rounding.

The share card reads the same file and had its own hardcoded 45×56, which the
re-crop would have stretched; it is now 47×56, with a comment tying it to the
canvas. The comment on ASPECT records that re-cropping either file means
re-normalising both.

Verified: tsc clean, 159/159 tests, build green, and both files report
naturalWidth 176 × naturalHeight 208 in the browser.
2026-08-08 22:39:28 +01:00
Tudor b11ee3c8de feat(brand): use the supplied logo artwork instead of a reconstruction
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m6s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 12s
PR Checks / Build Frontend (no push) (pull_request) Successful in 49s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m7s
The mark shipped so far was my SVG approximation, and it was wrong: the real
mark is a teardrop pin with a white window and a path flowing out of its base,
carrying three leaves — not a circle with a separate tail.

Both colourways are extracted from the supplied sheet, which has a genuinely
transparent background, so these are the artwork rather than a trace:

  public/brand/mark.png          teal pin, white window and path, green leaves
  public/brand/mark-on-dark.png  white pin with the counter knocked through

Two colourways are needed, not one. Rendered against every real ground, the
teal pin holds up on Warm White, white cards, Sand and both dark-theme grounds
— but it vanishes on the teal footer band, where only the white window
survives. The header therefore serves the teal artwork and swaps to the
on-dark artwork for dark-theme viewers through a <picture> source, needing no
JavaScript; the footer forces on-dark, because its band is teal in both
themes.

Everything downstream now derives from those two files: the favicon
(app/icon.png, replacing icon.svg), the touch icon (app/apple-icon.png,
replacing the generated apple-icon.tsx), the three PWA rasters, and the share
card, which reads public/brand/mark.png off disk so it can never drift from
the header. The logo sizing CSS keyed off a square box, which would have
squashed a 153:189 artwork — height now drives and width follows.

The wordmark stays live text in Manrope. The sheet's wordmark is a raster with
visible edge fringing, and the written style guide specifies Manrope; live
text also stays selectable, scales cleanly and recolours with the theme.

KNOWN LIMITATION: the largest instance on the sheet is 153×189. That is ample
for the header at 38px, the favicon and the share card, but short of the 512px
PWA icon, which is upscaled and slightly soft. A vector would fix it and is a
single swap — every consumer goes through components/Logo.tsx or public/brand.

Verified: tsc clean, 159/159 tests, build green, /icon.png and /apple-icon.png
emit as static routes, and the header, footer, share card and all five icons
were rendered and inspected in both themes.
2026-08-08 22:22:58 +01:00
tudor eecb84fb35 Merge pull request 'feat(brand): adopt the schoolcompare identity across the site' (#89) from feat/schoolcompare-brand into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 49s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m6s
Reviewed-on: #89
2026-08-07 17:58:55 +00:00
Tudor 39e5c11274 fix(brand): match the below-average tint to its own hue, and finish the casing
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 6s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 43s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 3m19s
Three review findings.

--status-below-bg carried the raw --coral tuple (249,115,96) instead of the
hue it belongs to (#A9481F → 169,72,31), so "below average" chips rendered a
coral-pink wash behind terracotta text — the one solid/tint pair in the file
whose hues disagreed. Alpha drops 0.15 → 0.12 to match --status-above-bg, so
the two chips read as equal weight; left at 0.15 the darker terracotta tint
takes the label to 4.45:1 on Warm White, under the 4.5 floor. At 0.12 it is
4.86:1 on cards and 4.67:1 on Warm White.

Auditing the whole file for the same class of error turned up one more:
--action-bg was also a --coral tint while --action is the darkened #BE3C27.
It is unused today and the dark-theme value was already correct, but it is
aligned so a future coral ghost button gets a matching label and ground. The
five phase pairs also "mismatch" by the same test and are deliberately left
alone: those pair a pastel ground (sage, sky, mustard, lavender) with a deeper
text hue, which is exactly what the guideline's Chips/Tags show.

The lowercase wordmark had only reached the visual chrome. Every user-visible
occurrence now matches: page title and template, appleWebApp title, authors,
OpenGraph and Twitter titles and siteName, the school page's siteName, the PWA
manifest name and short_name, the footer copyright line, the nav's aria-label,
the Web Share API strings, and the editorial paragraph. Comments in lib/*.ts
and AdmissionsView still say "SchoolCompare"; they describe the codebase rather
than the mark, so they are left to keep this diff to the reported problem.

The comment explaining why the font classes belong on <html> still described
--font-schibsted, which no longer exists. It now names --font-manrope and
--font-inter, and records that the e2e typeface assertion is the only guard —
this failure mode throws nothing and fails no unit test.

Verified: tsc clean, 159/159 tests, build green, and the rendered title is now
"School Admissions Guide | schoolcompare". Status and phase labels re-checked
on their own composited tints over both light grounds — all clear AA.
2026-08-07 18:33:30 +01:00
Tudor accc562b90 feat(brand): adopt the schoolcompare identity across the site
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 13s
PR Checks / Build Frontend (no push) (pull_request) Successful in 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 4m29s
Implements the supplied brand guideline: the pin-and-leaf mark, the lowercase
schoolcompare wordmark, Manrope for headings and Inter for everything a person
reads a number from, the deep-teal/coral/mustard/sage palette, and the rounder
geometry the guideline asks for.

The landing hero is rebuilt to the concept: a Sand panel carrying the
proposition, the search and a trust line, with the brand landscape bleeding to
the panel's right edge, followed by the four value props.

Concept vs reality — where the guideline describes something this product does
not have, the real feature takes its place and the decision is recorded in a
code comment next to it:

- The Thriving Score is not implemented. Four of its five sub-scores (pastoral,
  enrichment, community, facilities) have no source in DfE or Ofsted data, and
  its band names are Ofsted's own, which would sit beside the real Ofsted grade
  and be indistinguishable from it.
- Guides, About, Favourites and Sign in are not added to the nav — there are no
  such pages and no accounts system. Rankings and Admissions, which the
  guideline omits, keep their places because they exist.
- The fourth value prop is "Never miss a deadline" rather than "Save & revisit",
  which would need shortlisting.

Two deviations from the supplied swatches, both forced by contrast and both
confined to text and fills. Coral #F97360 under a white label measures 2.75:1
against a 4.5 floor, so --action is a darkened #BE3C27 and the original coral
survives as --coral for tints, borders and illustration. Mustard #F2C94C is
1.5:1 as text, so --mustard-ink carries labels while --mustard stays exact for
fills and rings. Every token clears AA on all three light grounds; Sand is the
binding one, so several values sit a step darker than white alone would need.

The guideline is light-only, but the site already ships a dark theme, so it is
rebuilt from the same tokens rather than dropped.

Verified: tsc clean, 159/159 unit tests, production build green, and the
generated share card and app icon render from the new mark. The hero and the
site chrome were rendered from the compiled CSS and the prerendered markup to
confirm Manrope and Inter actually resolve — a font token that silently falls
back has shipped here before.
2026-08-07 18:05:49 +01:00
tudor f31f6f8404 Merge pull request 'fix(design): correct the font assertion (serif$ matched sans-serif) and make the Leaflet overrides win' (#88) from fix/leaflet-specificity-and-font-assertion into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 15s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 57s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 1m8s
Reviewed-on: #88
2026-08-06 14:47:05 +00:00
TudorandClaude Opus 5 8d50afef1e fix(design): meet AA on tinted surfaces, and stop the footer inverting in dark
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m11s
PR Checks / Backend Smoke (pull_request) Successful in 9s
PR Checks / Build Backend (no push) (pull_request) Successful in 12s
PR Checks / Build Frontend (no push) (pull_request) Successful in 52s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 11s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 3m6s
Full audit across home, search, rankings, admissions, compare, and primary /
secondary / special / no-data school pages, in both themes, measuring computed
styles rather than reading CSS.

Contrast: the status hues were specced against --bg-primary, but they are used
as chip text on their own tint, which sits on cards and secondary surfaces
rather than the page ground. Measured in the wild they were 3.85–4.44:1 —
under AA — on Ofsted badges, delta chips, report-card chips and metric values,
i.e. most of the product's actual signal. Darkened the light hues
(#0e6e66 → #0b625a, #9a5b00 → #7f4a00) and lifted the dark teal
(#3fb3a4 → #4fc0b0) so each clears AA on its own tint, which is the worst case
rather than the easy one. Chart and series ramps follow.

The footer was painting itself with a text token and lettering itself with a
background token: `background: var(--text-primary); color: var(--bg-secondary)`.
That reads correctly in one theme and inverts in the other — in dark mode it
became a light slab at the bottom of a dark page, with amber section headings
at 1.98:1. Added --surface-sunken and its on-* companions, which stay dark in
BOTH themes (deliberately not --surface-inverse, whose whole job is to flip),
and moved the footer onto them. Section headings were also using a status hue
purely as decoration; they are now a muted on-surface token.

The "Open full map" pill was a fixed white background with a themed text
colour, so in dark mode it rendered light violet on white at 1.84:1. Both
sides are token-driven now.

Tabular numerals are now the default for .main rather than per-component
opt-in, with prose opting back out — a handful of figures (miniNatPill,
compareRowVal, factVal) had been missed by the class-name-based pass.

Added a two-theme AA gate over home, rankings and admissions. It waits for
`transition: color` to settle first: an earlier measurement pass read
mid-transition values and reported seven failures that did not exist at rest.
Worth stating plainly — most of what a naive audit flags here is its own
artifact, and the check has to account for that to be worth having.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 15:38:31 +01:00
TudorandClaude Opus 5 45a3e7fb8f fix(design): correct the font assertion and make the Leaflet overrides win
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 49s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m10s
Two follow-ups from watching the staging E2E run and re-auditing the live site.

The typeface gate failed, but the site was right. Staging now serves
"Schibsted Grotesk", "Schibsted Grotesk Fallback", …, -apple-system, sans-serif
— exactly what it should. My assertion was /Times|serif$/, and `serif$` matches
the tail of `sans-serif`, so a healthy stack could never pass. It now checks
the FIRST family in the stack (the only one actually requested) and matches
Times as a whole word. Also asserts running prose resolves to Literata, which
the earlier version never covered.

The Leaflet overrides from the previous fix never took effect. leaflet.css is
imported from a client component, so its chunk loads after globals.css; at
equal specificity (both bare `.leaflet-container`) the later sheet wins.
Verified on the live page: my rule sat at stylesheet index 0, Leaflet's at
index 3, and the attribution link was still #0078A8. Prefixing the overrides
with `html` takes them to 0,1,1, which beats a bare class regardless of load
order — injecting that on the live page turned the background to
rgb(233,232,226) and the link to rgb(88,74,155).

The palette gate would have caught this, except it skipped everything inside
.leaflet-container to avoid flagging OSM tile imagery — which also skipped
Leaflet's own chrome. Narrowed the exemption to .leaflet-tile-pane so the map
controls are now covered.

Also dropped the duplicated family name from the font tokens: next/font
already expands the variable to the family plus its metric-matched fallback,
so the stack was naming Schibsted Grotesk twice. It looked like a safety net
but wasn't — an unresolvable var() with no fallback invalidates the whole
declaration, so the literal after it never gets a turn.

Verified against live staging: body and headings resolve to Schibsted Grotesk,
prose to Literata, the search input is --text-primary rather than pure black,
and the higher-specificity Leaflet rules win when injected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 14:04:36 +01:00
tudor 91b49f1a59 Merge pull request 'fix(design): resolve the font tokens — staging was rendering entirely in Times' (#87) from fix/font-cascade-and-map-palette into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 53s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 58s
Reviewed-on: #87
2026-08-06 12:52:34 +00:00
TudorandClaude Opus 5 2433101fa0 fix(design): resolve the font tokens, and pull form controls and map chrome onto the palette
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 50s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m22s
Staging audit of the Cohort identity found the whole site rendering in Times.

Root cause: next/font's variable classes were on <body>, while globals.css
declares --font-display/--font-ui/--font-prose on :root as
`var(--font-schibsted), ...`. A custom property's var() references resolve on
the element that declares it, so at :root --font-schibsted was undefined,
--font-display computed to the guaranteed-invalid value, and every
font-family referencing it fell back. Nothing threw and the build was green —
the only symptom was visual.

Verified the mechanism in a browser both ways round: class on <body> gives an
empty token and a Times body font; class on <html> resolves to Schibsted
Grotesk. The classes now sit on <html>.

Two colour escapes from the same audit:

* Form controls don't inherit font or colour from their parent, so the omni
  search input and the map's "Open full map" button rendered in the system
  font at pure black. Nearly invisible against --text-primary in light mode
  and completely invisible on the dark ground. Added a base inherit rule.
* Leaflet ships its own palette — a #ddd tile backdrop, #333 attribution text
  and a #0078A8 link blue that was the most saturated colour anywhere on the
  site. The map chrome now uses tokens; the tiles stay as OSM renders them.

Three e2e gates added, because the existing suite passed while the site was
entirely in Times:

* the font tokens resolve to a non-empty value and the applied family is
  Schibsted, not a serif fallback
* no visible element renders in the browser's default black
* every rendered colour comes from the token palette — the manual audit,
  turned into a gate

Also made the og:image check environment-relative: metadataBase pins canonical
URLs to the production host, so the absolute URL pointed off-environment when
the suite ran against staging.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 13:38:17 +01:00
tudor f43a8ecb69 Merge pull request 'feat(design): adopt the Cohort identity — palette, type, mark and dark theme' (#86) from design/cohort-identity into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 54s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m1s
Reviewed-on: #86
2026-08-06 11:36:02 +00:00
TudorandClaude Opus 5 8c3a5cc4e9 fix(design): keep below/attention off the brand hue, harden the share-card fonts
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 49s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 1m8s
Review follow-up on #86.

The blind coral -> brand rename recreated the exact collision this PR set out
to remove: coral had been both the primary CTA and the "below average" signal,
so every negative indicator followed --primary onto iris. Sixteen rules moved
back onto the status ramp — delta chips, trend-down arrows, progress-negative
values, statusBad, chipBad/badgeBad, and the urgent deadline chips.

The Ofsted scale had also lost its worst step, with grade 4 landing on brand
while 1-2 were teal and 3 was amber. It now escalates by weight rather than by
reaching for another hue: a tinted amber chip for "requires improvement", a
solid amber one for "inadequate" (5.1:1 light, 7.7:1 dark). Report-card grade 5
follows the same rule.

globals.css now describes status as valence — teal above/good, amber
below/needs-attention — which is what it has to mean for an urgent deadline,
rather than the narrower "comparison point only" the first draft claimed.

On the share-card fonts: /opengraph-image is prerendered, so the font read
happens in the builder stage where assets/ exists, and the baked PNG ships
inside .next/standalone/.next/server/app/. File tracing independently places
the fonts at .next/standalone/assets, which the existing standalone COPY
carries to /app/assets. So the reported ENOENT doesn't occur — but it depends
on the tracer resolving a runtime join(), and a miss would be a silent 500
rather than a build failure. Declared outputFileTracingIncludes for the route
and made the Dockerfile COPY explicit so neither is left to inference.

Also repointed the immutable Cache-Control rule from the deleted favicon.svg
to app/icon.svg, where it was caching a 404.

Verified: tsc clean, 159/159 tests, clean rebuild prerenders all three image
routes with the fonts present in standalone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 12:29:53 +01:00
TudorandClaude Opus 5 8ab0ac0a04 feat(design): adopt the Cohort identity — new palette, type, mark and dark theme
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m6s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 12s
PR Checks / Build Frontend (no push) (pull_request) Successful in 49s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 3m13s
Implements the direction agreed from the identity board: Route C ("Cohort")
with the paper ground from C1, the Schibsted Grotesk / Literata pairing from
C2, and the iris accent from C3. Dark theme is in scope from the start rather
than retrofitted.

The audit found three things wrong beyond taste:

* No brand asset set. og:image was absent entirely, so every link shared into
  a class WhatsApp group rendered as a bare grey card. apple-touch-icon pointed
  at an SVG, which iOS ignores, and the manifest shipped no PNGs, so Android
  installs had no icon. The header mark and the favicon had also drifted into
  two different logos.
* No colour discipline. --primary and --trend-down were the same coral, so the
  main CTA and "below average" shared a hue. 58 distinct hex values were spread
  across component CSS, and the chart palette was still Chart.js's stock demo
  colours.
* A dark theme that was declared but never built — themeColor announced a dark
  variant with no dark styling behind it.

What changed:

Colour now has exactly three jobs that never borrow each other's hues: brand
(iris) for interactive and identity, status (teal/amber) for above/below a
comparison point, and phase for categories. Teal/amber rather than green/red
keeps the above/below signal readable for every form of colour blindness.
Every chromatic literal in component CSS is now a token, and the JS-painted
surfaces (Chart.js, Leaflet) read the tokens through lib/theme so they follow
the theme instead of ignoring it.

The mark is the five-bar cohort spread — the same object as the distribution
strip inside a school row, built from opacity steps so it inverts cleanly.
components/Logo.tsx is the single source; the favicon, apple-icon and share
card all derive from its geometry.

globals.css drops 123 dead global classes left over from the vanilla-JS app
(only the btn family, .skip-link and .main were still referenced), along with
the noise overlay. It also gains prefers-reduced-motion support, which was
missing entirely, and a type scale so the 54 ad-hoc font sizes have somewhere
to converge.

Verified: tsc clean, 159 unit tests pass, production build succeeds and
prerenders /icon.svg, /apple-icon and /opengraph-image. Three e2e journeys
added for the asset set, the themeColor/background match, and the dark theme
actually repainting — all silent failures that nothing on the page reveals.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 12:13:04 +01:00
tudor c298a29b61 Merge pull request 'fix(detail): restore the shell's mobile header/nav CSS' (#85) from perf/server-client-split into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 46s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 55s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 2m13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 2s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 1m12s
Reviewed-on: #85
2026-08-06 09:33:34 +00:00
TudorandClaude Opus 5 e098ad4bd1 fix(detail): restore the shell's mobile header/nav CSS
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m6s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 36s
PR Checks / Build Frontend (no push) (pull_request) Successful in 46s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 1m19s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 9s
The server/client split moved the header and sticky nav markup into
SchoolDetailShell, but their responsive rules stayed behind in
schoolSections.module.css. CSS Modules hash class names per file, so those
rules stopped matching entirely: on mobile the header details block never
collapsed ("Show all details" e2e journey failed), the toggle itself never
appeared, and the section-nav mobile swap (menu button in, link row out)
never applied.

Ports the stranded blocks into SchoolDetailShell.module.css verbatim: the
768px header block (stacked header, wrapped meta pills, details toggle +
collapse) and the 640px section-nav blocks (scroll-fade mask, bottom-sheet
panel, control swap). Adds a jest guard that every class a components/school
component references is defined in the stylesheet that component imports —
it fails on the three classes that had no rule at all here
(headerDetailsOpen, atEnd, sectionNavBackLabel).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 10:31:12 +01:00
tudor 5f961bf7f4 Merge pull request 'perf(detail): render school detail sections on the server' (#84) from perf/server-client-split into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 57s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 2m6s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m23s
Reviewed-on: #84
2026-08-02 21:03:32 +00:00
TudorandClaude Opus 5 803e68970c refactor(detail): drop dead derived state from the shell
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m4s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 47s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 1m12s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 9m28s
Leftover from the mechanical extraction: the shell still called
computeSchoolFlags() and derived isReportCard / ofstedInspectedDate /
oeifAreas / oeifAllSameGrade / deprivationDesc / primaryAvg / secondaryAvg on
every render, duplicating work page.tsx already does. None of those values
were referenced in its JSX anymore -- that logic moved to the section
composers.

The chrome needs only four locally-derived values (latestResults, phase,
isAllThrough, hasLocation), all one-liners over props it already owns.

Removing them made seven props dead, which TypeScript caught at both call
sites: absenceData, ofsted, admissions, admissionsHistory, deprivation,
finance and nationalAvg now go straight to the section composers and never
reach the client component. The shell's surface is down to schoolInfo,
yearlyData, census, navItems and children.

No behaviour change: 155 tests pass and the characterization tests remain
byte-identical to the commit that introduced them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 21:54:59 +01:00
TudorandClaude Opus 5 ec2d12478e test(e2e): cover the detail page server/client boundary
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m7s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 14s
PR Checks / Build Frontend (no push) (pull_request) Successful in 53s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 1m14s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 3m23s
Two journeys for what the split actually changed: the admissions toggle (the
one client island inside an otherwise server-rendered section) and the sticky
nav resolving to server-rendered sections. The nav is client-rendered from a
server-computed list while the sections render on the server, so a mismatch
between the two halves would only show up in a real browser.

Existing journeys already cover all-through and special-school pages.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 21:41:18 +01:00
TudorandClaude Opus 5 4c229aec6e chore: drop unused SWR hooks and dependency
useSchools, useFilters, useMetrics and useSchoolDetails were imported by
nothing and were the only consumers of swr. All data fetching goes through
lib/api.ts on the server.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 21:39:59 +01:00
TudorandClaude Opus 5 752eb07310 refactor(detail): render sections on the server behind a client shell
page.tsx now composes the sections and passes them through SchoolDetailShell
as children, so ~1,300 lines of static markup stop shipping as client
JavaScript. The shell keeps what is genuinely interactive: back link, header
reveal, hero map, compare CTA, sticky nav and scroll-spy.

The scroll-spy already located sections via document.getElementById, so it
works unchanged against server-rendered children.

Charts needed a client wrapper: next/dynamic with ssr:false is illegal in a
Server Component, so components/school/charts.tsx is the boundary that keeps
Chart.js (64 KB gz) lazy and browser-only.

Measured on this build:
- school route client chunk: 8 KB gz (33 KB raw)
- total static JS across all chunks: 380.6 -> 350.7 KB gz
- section markup is absent from every client chunk ("Got their first choice",
  "Ofsted reports", "Most deprived" etc. all return 0 hits); shell strings
  still present, as expected
- shared baseline unchanged at 172 KB gz -- out of scope, as designed

The 14 characterization tests pass byte-identical to the commit that
introduced them. Only the render helper changed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 21:39:21 +01:00
TudorandClaude Opus 5 a7f6ff4035 refactor(detail): extract sections as server components
Moves ~1,300 lines of section markup out of the two client views into
components/school/, mirroring the components/compare/ layout. Twelve section
components plus shared primitives, all server components. The only client
file is AdmissionsViewToggle, which owns the hidden/aria-pressed state and
receives both views as server-rendered children.

JSX was extracted mechanically rather than retyped, so the markup the CSS
modules depend on is verbatim.

Sharing follows measured similarity, not assumption:
- Finances (91%) shared. The secondary premises-cost card is gated behind a
  prop so primary pages are unchanged; enabling it is a one-line follow-up.
- Ofsted (80%) shared, but behind a variant prop. The headline similarity hid
  a real fork: on a school with no overall grade the primary page shows a
  "Not rated" badge while the secondary shows a four-area OEIF panel, and the
  disclaimer copy differs. Both preserved exactly; reconciling them is a
  human decision, not a side effect of a move.
- Admissions (14%) and History (40%) kept separate.

Not yet wired up -- the old views still render.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 21:33:28 +01:00
TudorandClaude Opus 5 2f786787b9 style(detail): merge the two detail stylesheets
Builds components/school/schoolSections.module.css from the primary module,
plus 35 secondary-only rules, so shared section components have one stylesheet.

Three categories of difference, handled separately so nothing changes visually:

- 7 incidental-drift properties unioned in (overflow-wrap, word-break,
  min-width, user-select) -- fixes that landed on one page and were never
  back-ported. Also fixes latent long-school-name overflow on the page that
  lacked them.
- 4 genuinely visual class differences kept as explicit variants:
  genderBar, heroStatValue, genderSplitBoys, genderSplitGirls. font-weight on
  the genderSplit pair was reclassified from drift to visual -- unioning it
  would have bolded the primary page.
- 17 rules that exist only in the secondary stylesheet but target shared class
  names (.card, .sectionTitle, .metricCard). Applied flat these would restyle
  the primary page, so they are scoped under .secondaryScope, which only
  SecondarySchoolSections will carry.

Audited: every rule in both original stylesheets is a subset of the merged one
(0 MISSING, 0 LOST), excluding the documented variants.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 21:18:15 +01:00
TudorandClaude Opus 5 5044c24895 refactor(detail): extract derived flags and nav items to lib
Pure data-shape logic moves out of the client components so page.tsx can
compute the section list on the server without importing them.

The secondary page is not a variant of the primary one -- different section
ids (gcse, wellbeing), different flags, and History gated on more than one
year rather than at least one -- so it gets its own computeSecondaryFlags and
buildSecondaryNavItems rather than bending a shared function.

Adds 16 unit tests covering the all-through and special-school branches,
previously reachable only through a full component render.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 21:14:35 +01:00
TudorandClaude Opus 5 d74cc95034 refactor(detail): fetch national averages on the server
Both detail views fetched /api/national-averages in a useEffect, so the
England-comparison deltas popped in after hydration and every section that
uses them was pinned to the client. The page now fetches it in parallel with
the school details (backend-cached 1h, degrades to null) and passes it down.

Removes one client round-trip per detail page and unblocks the section
extraction.

Characterization tests pass unmodified; only the render helper changed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 21:11:08 +01:00
TudorandClaude Opus 5 7c43a1baaf test: pin school detail behaviour before refactor
14 characterization tests covering Ofsted (both OEIF and Report Card layouts),
KS2 results with the England delta, KS4 Attainment 8 / Progress 8 / EBacc,
all-through dual rendering, special-school comparison suppression (PR #70),
the admissions year/trend toggle, and conditional section rendering.

All rendering goes through renderSchoolDetail(), the single seam the
server/client split is allowed to change. The assertions must survive the
refactor unmodified.

Excludes __tests__/support from testMatch: it holds fixtures and helpers, not
suites, and the glob was failing them as empty test files.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 21:09:18 +01:00
TudorandClaude Opus 5 bcf3498086 test: add jsdom globals and school detail fixtures
jsdom provides neither IntersectionObserver nor scrollTo; both detail views
use them. Adds four fixtures (primary, secondary, all-through, special)
covering the branches the characterization tests will pin.

SchoolResult carries 57 required nullable fields, so fixtures are built from
an all-null base row and override only what they exercise.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 21:06:14 +01:00
TudorandClaude Opus 5 7199c3a90b docs(perf): implementation plan for detail-page server/client split
Nine tasks mapping to the spec's commit sequence, each ending in an
independently testable deliverable.

Also corrects the spec's section-sharing table: measured similarity shows
Admissions (14%) and History (40%) are not shareable between the two views,
only Ofsted (80%) and Finances (91%). This costs no bytes -- the win comes
from sections being server components, not from sharing them -- and cuts the
diff and regression risk.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 20:52:56 +01:00
TudorandClaude Opus 5 97dd69a512 docs(perf): resolve CSS strategy for shared section components
Planning surfaced a gap: the two detail views' CSS modules share 79 class
names, 22 with differing rules, 16 of those used in section markup by both
views. Shared sections cannot use one stylesheet without visual change.

Resolution: union the 14 incidental-drift differences (defensive overflow
properties never back-ported between the views), and keep the 2 genuine
visual differences (.genderBar, .heroStatValue) as distinct classes behind a
variant prop. Adds an isolated CSS-merge commit so a visual regression
bisects to the merge rather than a JSX move.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 20:47:21 +01:00
TudorandClaude Opus 5 d1c92ea7d5 docs(perf): spec for detail-page server/client split
Design for splitting SchoolDetailView (65KB) and SecondarySchoolDetailView
(46KB) into server section components behind a small client shell, following
the existing components/compare/ decomposition pattern.

Key constraint: a server component imported by a client component becomes
client, so sections are composed in page.tsx and passed through the shell as
children. Moving /api/national-averages server-side is a prerequisite, since
the England-comparison deltas feed most sections.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 15:35:54 +01:00
tudor cab7b4fe91 Merge pull request 'feat(detail): move religious character into header details + mobile reveal' (#83) from feat/detail-header-details-reveal into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 52s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 47s
Reviewed-on: #83
2026-07-24 12:15:14 +00:00
TudorandClaude Opus 4.8 96d5fcf5b0 feat(detail): move religious character into header details + mobile reveal
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m1s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 47s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 52s
Religious character now sits with the other labelled header details (near
County / Constituency) as "Religious character: <denomination>" ("None" for
Does not apply / None), instead of as an identity chip.

On mobile/tablet (≤768px) the header details block was hidden outright; it's
now collapsed behind a "Show all details" toggle that reveals the full block
(headteacher, website, pupils, trust, phone, religious character, county,
constituency). Applied to both the primary and secondary detail views for
parity. Extends the e2e journey with the mobile toggle behaviour.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 12:24:16 +01:00
tudor 8cf2ac47c1 Merge pull request 'feat(detail): surface GIAS identity/contact details, drop unwired sections' (#82) from feat/detail-gias-fields-remove-unwired into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 23s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 1m37s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 2m33s
Reviewed-on: #82
2026-07-24 10:56:34 +00:00
TudorandClaude Opus 4.8 a102508ef1 fix(data): strip any table alias in missing-column matcher, not just s.
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m1s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 17s
PR Checks / Build Frontend (no push) (pull_request) Successful in 42s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 9s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m49s
The graceful-degradation fallback keys off the column named in a Postgres
UndefinedColumn error, but the matcher only stripped an `s.` alias. The two
new dim_location columns (county, parliamentary_constituency) are selected
via the `l.` alias and Postgres reports them unquoted as
"column l.county does not exist" — which the old regex failed to match at
all, returning None.

If dim_school is rebuilt (telephone/nursery present) but dim_location is not
yet (county/parliamentary_constituency missing) — plausible since they are
independently-rebuilt dbt models — the fallback branch never matched and
load_school_data_as_dataframe() returned an empty DataFrame, showing zero
schools sitewide instead of degrading those columns to NULL.

Generalise the alias prefix to `\w+\.` and cover the l.-qualified case in
tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 09:58:27 +01:00
TudorandClaude Opus 4.8 684da611ff feat(detail): always show religious character, "None" for no religious character
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m1s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 22s
PR Checks / Build Frontend (no push) (pull_request) Successful in 43s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 2m56s
Previously the chip was hidden for "Does not apply"/"None". Show it in all
cases, rendering "None" for those two sentinel values.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 09:24:27 +01:00
TudorandClaude Opus 4.8 0186227ced feat(detail): surface GIAS identity/contact details, drop unwired sections
PR Checks / Frontend Typecheck + Tests (pull_request) Canceled after 58s
PR Checks / Backend Smoke (pull_request) Canceled after 0s
PR Checks / Build Backend (no push) (pull_request) Canceled after 0s
PR Checks / Build Frontend (no push) (pull_request) Canceled after 0s
PR Checks / Build Pipeline (no push) (pull_request) Canceled after 0s
PR Checks / AI Code Review (Claude) (pull_request) Canceled after 0s
Add seven school-identity fields to the detail header (both primary and
secondary views): age range, religious character, nursery and sixth-form
indicators as chips; telephone (tel: link), county and parliamentary
constituency as header details. religious_denomination, age_range and
has_sixth_form were already served; telephone, nursery_provision, county
and parliamentary_constituency are newly wired through the marts query
(with a NULL fallback for un-rebuilt marts, mirroring has_sixth_form) and
the school_info API response.

Remove three UI sections the backend never populated (always null): Year 1
Phonics, the SEN "types of additional needs" breakdown, and the average
class-size card — along with their now-dead props, route plumbing, and the
SenDetail/Phonics types + class_size_avg field.

Extend the e2e detail journey to assert the Phonics section is gone and the
new header fields render when the record carries them.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 09:23:08 +01:00
tudor 59b5f3f163 Merge pull request 'feat(ui): viewport-aware InfoPopover replaces broken metric tooltips' (#81) from feat/info-popover-tooltip into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 53s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 5m2s
Reviewed-on: #81
2026-07-22 14:48:13 +00:00
TudorandClaude Opus 4.8 8e763e39d1 test(e2e): compare help popover stays within the mobile viewport
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m5s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 47s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m33s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 15:38:56 +01:00
TudorandClaude Opus 4.8 84bca53c7e refactor(compare): row-label help uses InfoPopover, not native title
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 15:38:25 +01:00
TudorandClaude Opus 4.8 15b7493b85 refactor(ui): MetricTooltip delegates to InfoPopover (circled ? glyph)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 15:37:33 +01:00
TudorandClaude Opus 4.8 1d9d2eb5ae feat(ui): add InfoPopover — viewport-aware metric help via Floating UI
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 15:36:23 +01:00
TudorandClaude Opus 4.8 ddb42badb6 build(deps): add @floating-ui/react for the info popover
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 15:35:21 +01:00
TudorandClaude Opus 4.8 702408d6a4 docs(compare): implementation plan for InfoPopover metric help
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 15:34:38 +01:00
TudorandClaude Opus 4.8 09d94e513e docs(compare): design for unified InfoPopover metric-help affordance
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 15:30:40 +01:00
tudor 598ba9af4e Merge pull request 'fix(compare): a no-results school no longer blanks the trend chart' (#80) from fix/compare-null-year-blanks-chart into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 58s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 2m49s
Reviewed-on: #80
2026-07-22 14:23:25 +00:00
TudorandClaude Opus 4.8 dc85254ad2 fix(compare): a no-results school no longer blanks the trend chart
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m8s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 13s
PR Checks / Build Frontend (no push) (pull_request) Successful in 49s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 54s
Adding a school with no performance data to a comparison made every
school's trend line disappear until that school was removed.

Root cause: /api/compare returns such a school with a single phantom
yearly_data row (the dim_school LEFT JOIN) whose year is null. In
buildCompareChart, Math.trunc(null) is 0, so the axis was seeded at
year 0; fillAcademicYears then walked 0, 101, 202, … and hit its
50-step cap long before reaching the real years, leaving every
school's series mapped entirely to null.

Fix: ignore yearly rows without a real numeric year when building the
axis and the per-school year map. Regression test added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 15:17:43 +01:00
tudor 2f038285f6 Merge pull request 'feat(security): allow analytics subdomain to iframe the site' (#79) from feat/allow-analytics-iframe-embed into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 15s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 53s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 1m15s
Reviewed-on: #79
2026-07-21 21:52:34 +00:00
TudorandClaude Opus 4.8 9556595800 feat(security): allow analytics subdomain to iframe the site
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 48s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 8s
Replace X-Frame-Options: SAMEORIGIN with a CSP frame-ancestors directive
so analytics.schoolcompare.co.uk (Umami heatmap/recorder) can embed the
site while all other origins stay blocked. X-Frame-Options cannot allow a
specific sibling subdomain (ALLOW-FROM is deprecated/ignored by modern
browsers), so frame-ancestors is the correct replacement.

Also update the nginx snippet in DEPLOYMENT.md to match, so the reverse
proxy doesn't re-inject a conflicting X-Frame-Options header.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 22:50:44 +01:00
tudor d02a323cdc Merge pull request 'fix(detail): give Results Over Time chart more height on desktop' (#78) from fix/detail-trend-chart-taller into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 58s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 1m13s
Reviewed-on: #78
2026-07-21 21:08:34 +00:00
TudorandClaude Opus 4.8 32f8a02862 fix(detail): give Results Over Time chart more height on desktop
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m6s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 47s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 11s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 13s
The trend chart was capped at 280px tall on desktop, squishing the
lines together and making them hard to read. Raise the base
.chartContainer height to 380px in both the primary and secondary
detail views.

Mobile is unaffected: the base value is already overridden to
height:auto by the existing max-width:768px query, where
PerformanceChart's own .chartWrapper carries the canvas height.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-21 22:05:10 +01:00
tudor 7e3096c881 Merge pull request 'feat(analytics): load Umami heatmap recorder' (#77) from feat/umami-heatmap-recorder into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 15s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 54s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 47s
Reviewed-on: #77
2026-07-21 15:06:04 +00:00
TudorandClaude Opus 4.8 1f80571b1f feat(analytics): load Umami heatmap recorder
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m4s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 47s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 42s
Adds the Umami session recorder (recorder.js) that powers heatmaps,
alongside the existing analytics tracker. Loaded via next/script with
the same data-domains guard as the main tracker so it only fires on the
production hostnames — staging runs the same image under a different
host and must not feed the heatmap.

Cookieless: recorder.js uses Umami's server-side session model (no
cookie or local storage on the device), so it adds no new PECR
consent trigger.

Verified with tsc --noEmit and next build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-21 16:03:18 +01:00
tudor 3132f07af2 Merge pull request 'fix(detail): compare each SATs bar to its own national benchmark' (#76) from fix/sats-per-level-national into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 20s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 51s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 44s
Reviewed-on: #76
2026-07-21 13:56:55 +00:00
TudorandClaude Opus 4.8 8a9ba30cc2 fix(detail): compare each SATs bar to its own national benchmark
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 18s
PR Checks / Build Frontend (no push) (pull_request) Successful in 45s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 9s
The KS2 SATs chart drew a single national-average line spanning the
full height of each subject's chart area, positioned at the national
*expected* value. But the area stacks two bars — Expected and Exceeding
— and the higher-standard/greater-depth national is a very different,
much lower figure (e.g. reading higher standard ~29% vs expected ~75%).
So the line crossed the Exceeding bar at the wrong place, making every
school's exceeding result look far below national when it wasn't.

The per-subject higher-standard nationals were already computed in the
fact_ks2_national_averages mart; they just weren't serialized. Fix:

- backend: add reading_high_pct, writing_gd_pct (writing = greater
  depth) and maths_high_pct to the national-averages payload.
- SchoolDetailView: pass a nationalExceedingPct per subject, mapping
  writing to the greater-depth figure.
- SatsChart: replace the single full-height line with a national marker
  on each bar's own track (coral tick + "nat X%" in the bar header), so
  Expected and Exceeding each sit against the correct benchmark.

KS2 only; the secondary Attainment 8 chart already uses one line for
one measure and is untouched.

Verified: tsc --noEmit, next build, and backend pytest (national
averages marts, incl. a new test guarding the per-subject nationals).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-21 14:55:43 +01:00
tudor 388b496cc5 Merge pull request 'feat(admissions): surface easy-to-miss deadlines as callout boxes' (#75) from fix/rankings-admissions-accuracy into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 51s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 44s
Reviewed-on: #75
2026-07-21 11:27:20 +00:00
TudorandClaude Opus 4.8 15da060e4a feat(admissions): surface easy-to-miss deadlines as callout boxes
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m1s
PR Checks / Backend Smoke (pull_request) Successful in 6s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 42s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 9s
The selective-school registration and faith-school SIF warnings were
added as prose in the criteria steps, where they read as ordinary
sentences and were easy to skim past. Pulled them into structured
callout boxes with an amber "note" treatment (using the page's own
gold accent tokens), a warning glyph, and a bold lead-in — so the two
deadlines parents most often miss actually stand out.

- Added a `callouts` field to Step; render as a callout group between
  the body and the tool link (both primary and secondary timelines).
- Reverted the warning text back out of the step bodies so it isn't
  duplicated.

Verified with tsc --noEmit and next build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-21 12:22:49 +01:00
tudor 5981916b82 Merge pull request 'fix(rankings,admissions): correct education-accuracy audit findings' (#74) from fix/rankings-admissions-accuracy into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 50s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 44s
Reviewed-on: #74
2026-07-21 11:16:14 +00:00
TudorandClaude Opus 4.8 a5b2296240 fix(rankings,admissions): correct accuracy issues from education audit
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 42s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m11s
Follow-up audit of the rankings and admissions pages.

Admissions (AdmissionsView.tsx):
- National Offer Day no longer claims offers publish "from 12:01 am";
  release times are set per-council (often late afternoon, some
  overnight), so it now tells parents to check their council's page.
- Secondary preference count no longer states a flat "up to six"
  (that's London/Pan-London); most LAs allow three to six. Mirrors the
  hedge the primary step already used.
- Added the two deadlines that most often catch parents out: selective
  schools' separate entrance-test registration (months earlier), and
  faith schools' supplementary information form sent direct to the
  school. Covered in both the primary and secondary criteria steps.
- Reworded the equal-preference tip so it's precise: order is the
  tie-break among schools you qualify for (you get the highest-ranked
  one), not irrelevant.

Rankings (RankingsView.tsx):
- Subtitle "Top-performing schools by X" -> "Schools ranked by X", so
  it isn't nonsensical for context/equity/absence metrics.
- KS2 progress isn't published for 2023/24 or 2024/25 (no KS1
  baseline). Selecting a primary progress metric on a recent year used
  to dead-end on a generic "No rankings found". Added a scoped caveat
  to the progress hint and an explanatory empty-state (primary only —
  secondary Progress 8 is published).

Added an admissions smoke journey (static content, stable milestones).
Verified with tsc --noEmit and next build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-21 12:08:50 +01:00
tudor af23fbf27e Merge pull request 'fix(home): correct education/Ofsted claims on the landing page' (#73) from fix/homepage-education-accuracy into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 51s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 43s
Reviewed-on: #73
2026-07-21 09:04:57 +00:00
TudorandClaude Opus 4.8 22e9eb2d48 fix(home): make Att8 bar match its numbers and separate safeguarding
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 6s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 42s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m6s
Two internal-consistency fixes on the "What you'll see" mock:

- The Attainment 8 bar had drifted from the numbers beside it (fill 68%
  / line 57% vs a 54.8 score and 45.9 national avg). Restored the mock's
  original 1:1 value-to-percent mapping: fill 54.8%, national line 45.9%.
- The report card grouped "Safeguarding: Met" in the same five-point
  list as the graded areas, but safeguarding is a separate binary
  met/not-met judgement under the real framework. Moved it below the
  list behind a divider, with an outlined chip and a "separate check"
  label so it no longer reads as a graded area.

Verified with tsc --noEmit and next build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-21 10:01:10 +01:00
TudorandClaude Opus 4.8 13253116c2 fix(home): correct remaining KS2/Ofsted terminology on the landing page
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m1s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 41s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 9s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m35s
Follow-up to the accuracy pass — the medium-severity wording issues
from the same expert review:

- KS2 "Exceeding" isn't a DfE term. The above-expected level is the
  "higher standard" for the reading and maths tests and "greater depth"
  for teacher-assessed writing. Labelled per subject, and brought the
  illustrative reading value down from an implausible 73% (national
  higher standard is ~29%) to a realistic strong-school figure.
- Attributed inspection outcomes to Ofsted, not only the DfE (Ofsted is
  a separate non-ministerial department).
- Hero: "2026/2027 admissions results" -> "the 2026/27 admissions
  round" (admissions produce offers, not results, and we don't hold
  per-school offer outcomes).

Tightened .miniRowHead so the longer "Greater depth" label stays on one
line and the three subject columns keep their bars aligned (the visual
is desktop-only; hidden on mobile).

Verified with tsc --noEmit and next build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-21 09:07:23 +01:00
TudorandClaude Opus 4.8 1b8adb91ee fix(home): correct education/Ofsted claims on the landing page
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 12s
PR Checks / Build Frontend (no push) (pull_request) Successful in 42s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 37s
Homepage marketing content had drifted from both the current
education regime and the app's own school pages. An expert accuracy
review surfaced five issues (3 critical, 2 high):

- Ofsted card showed a single "OUTSTANDING" word-grade. Overall grades
  were abolished (Sept 2024) and inspections now produce a report card
  on a five-point scale (from Nov 2025). Rebuilt the card as a report
  card with per-area ratings + stand-alone safeguarding, matching what
  CompareOfsted actually renders on a school page.
- Attainment 8 "National avg 50.2" was wrong; the real 2024/25 figure
  is 45.9. Corrected the benchmark and the illustrative school value.
- Compare mock featured a KS2 "Reading progress" score, but KS2
  progress isn't published for 2023/24 or 2024/25 (no post-COVID KS1
  baseline). Swapped for Higher standard (RWM), which is published.
- Editorial called it "UK school performance data"; the data is
  England-only. Now matches the hero and page metadata.
- Softened the "40-page inspection report" exaggeration.

Landing-page copy isn't covered by e2e journeys, so no test changes.
Verified with tsc --noEmit and next build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-21 09:00:02 +01:00
tudor ca4fc647a5 Merge pull request 'fix(detail): let the special-school note span the full container width' (#72) from fix/special-note-full-width into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 55s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 43s
Reviewed-on: #72
2026-07-20 21:53:27 +00:00
TudorandClaude Opus 4.8 261403bcd2 fix(detail): let the special-school note span the full container width
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m1s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 45s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 13s
Drop the note's `max-width: 72ch`, which left it stopping well short of the
section's right edge. It now fills the results-section container like the
subtitle paragraph above it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-20 22:49:11 +01:00
tudor e4c8b86fe7 Merge pull request 'fix(detail): align Ofsted Report Card grade chips' (#71) from fix/report-card-chip-alignment into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 52s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 0s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 44s
Reviewed-on: #71
2026-07-20 21:32:45 +00:00
TudorandClaude Opus 4.8 1c1df77961 fix(detail): align Ofsted Report Card grade chips
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m4s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 9s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 8s
The grade boxes rendered inconsistently: Safeguarding "Met" was a small
0.8125rem inline pill while grade values ("Strong") were 1.25rem full-width
chips, and because category labels wrap to one or two lines each value sat at
a different vertical position. Two-line values like "Expected standard" also
produced a taller box.

Add a scoped `.gradeGrid` modifier (Report Card + OEIF grids in both the
primary and secondary detail views) that reserves two label lines so every
chip shares a baseline, and gives all value chips one font size, padding and
min-height — long text wraps inside an equal-height chip via max-width:100%.
Scoped rather than touching the shared `.metricCard`/`.metricValue` used by
the finance, phonics and admissions sections.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-20 22:31:58 +01:00
tudor 993822d769 Merge pull request 'fix: don’t portray special schools as failing the mainstream benchmark' (#70) from fix/special-schools-not-failing into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 53s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 7s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 3m40s
Reviewed-on: #70
2026-07-20 21:14:57 +00:00
TudorandClaude Opus 4.8 0b36eace9d fix(review): accurate PRU/AP copy, unbundle same-school trend, de-dupe note CSS
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 46s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 12s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m38s
Three review points on the special-schools change:

1. Copy accuracy — the context note said "Its pupils have special educational
   needs" for every isSpecialSchool() match, but the helper also matches pupil
   referral units and alternative provision, whose pupils are educated outside
   a mainstream setting (e.g. after exclusion) and are not necessarily SEND.
   Extracted a shared <SpecialSchoolNote> with type-aware copy: SEND wording
   only for genuine special schools; PRUs/AP get their own accurate wording.

2. Same-school trend was conflated with the England comparison — SchoolRow's
   year-over-year trend arrow (and the school's own figure) were gated on the
   same flag that drops the vs-England delta, hiding a still-meaningful trend
   for special schools with real data. Split the two: the school's OWN RWM
   figure + trend show whenever there's a real value (special schools
   included; only a placeholder all-zero row is hidden); only the vs-England
   delta is additionally dropped for special/PRU/AP. Mirrored in
   SecondarySchoolRow (own Attainment 8 shown; only the vs-LA delta dropped).

3. De-duplicated the .specialNote CSS (was copy-pasted between the two detail
   view module files) into SpecialSchoolNote.module.css, owned by the shared
   component so it can't drift.

New SpecialSchoolNote unit tests assert SEND wording for special schools and
NOT for PRUs/AP. tsc clean; 112/112 unit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-20 22:09:32 +01:00
TudorandClaude Opus 4.8 de943ded19 fix(review): don't suppress a genuine mainstream 0 in the rows
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 6s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 49s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m48s
Review feedback: the rankings/search rows treated any exactly-0 attainment as
not comparable regardless of school type, so a genuine 0 at a mainstream
school rendered as "—" (looks like missing data) and dropped its delta —
stricter and inconsistent with SchoolDetailView's placeholder check.

- SchoolRow: match SchoolDetailView's ks2Placeholder signature — suppress only
  when ALL of RWM + reading + writing + maths are 0 (special/suppressed
  signature), not on a bare rwm === 0. A genuine 0% combined (some pupils met
  individual subjects but not all three) is not all-zero, so it stays
  comparable and shows its real figure + trend.
- SecondarySchoolRow: Attainment 8 is a single 0–80 score with no subject
  breakdown to form an all-zero signature, so key off establishment type only
  (drop the bare att8 === 0 guard). A genuine (if extreme) 0.0 shows its value
  + LA delta.
- For consistency, apply the same to the detail views: drop the bare
  attainment_8_score === 0 guard (KS4 keys off isSpecial only); KS2 keeps the
  all-four-subjects-zero placeholder signature.

Special schools / PRUs / AP are still handled via isSpecialSchool everywhere.
tsc clean; 108/108 unit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-20 21:58:13 +01:00
TudorandClaude Opus 4.8 ae6ef6860b fix: don't portray special schools as failing the mainstream benchmark
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m8s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 46s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m1s
Special schools, PRUs and alternative provision teach pupils with SEND who
sit the same KS2/KS4 assessments but very few reach the mainstream "expected
standard". Their headline attainment is therefore ~0% (or a very low
Attainment 8), and the site was comparing that to the England average and
painting it red — e.g. Greenmead School (a community special school) rendered
as "0.0% — −62 pts below England average" with three 0% red SATs bars. That
portrays a special school as catastrophically failing against a benchmark
that doesn't fit it.

Add a shared `isSpecialSchool()` helper (detects every DfE special-school
establishment type — all contain "special" — plus PRUs / alternative
provision) and drop the mainstream England comparison + "below" framing for
these schools across every surface:

- Detail (primary + secondary): a plain-English context note explaining the
  school is special and why the comparison isn't shown; England-average delta
  chips, "England avg" hints, the SATs national markers, the Attainment-8
  "vs national" bar and the trend chart's England overlay are all suppressed.
  An all-zero placeholder SATs row hides the (empty) subject bar chart and the
  "why is combined lower" bridge.
- Rankings / search rows (primary + secondary): the mainstream RWM / Attainment
  8 stat shows "—" with no "vs national" delta, instead of "0% · −62 vs
  national".
- Compare: special schools' attainment values are dropped (no misleading dot
  at 0% / no "Below England average" chip); progress banding, which IS a fair
  measure for special schools, is kept.

Belt-and-braces zero-guard: a whole-row zero attainment (special or a
suppressed cohort) is also treated as not-comparable, while a legitimate
single 0 (e.g. 0% exceeding at a mainstream school) stays comparable.

Tests: new isSpecialSchool unit tests (every DfE special type matched, no
mainstream false positives); an e2e journey asserts Greenmead shows the
special-school note and no England-average comparison. tsc clean; 108/108 unit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-20 20:39:16 +01:00
tudor 4e316b4e38 Merge pull request 'fix(detail): label the phase of all-through admissions figures (Batch F review fix)' (#69) from fix/detail-allthrough-admissions-phase into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 52s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 0s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 56s
Reviewed-on: #69
2026-07-20 16:18:44 +00:00
415 changed files with 75741 additions and 9046 deletions

No files matched your search

+6
View File
@@ -5,3 +5,9 @@ __pycache__/
pipeline/transform/target/
pipeline/transform/logs/
pipeline/transform/.user.yml
# Playwright MCP scratch output (screenshots, console logs, page snapshots)
.playwright-mcp/
# Playwright run artefacts written when the suite is run from the repo root
test-results/
@@ -0,0 +1,7 @@
[ 3229ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 13147ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 29488ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 183884ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=Welland+Primary:0
[ 193559ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=Welland+Primary:0
[ 213136ms] [WARNING] Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options @ https://schoolcompare.co.uk/_next/static/chunks/b6104424f97d1001.js:0
[ 216340ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/146678-welland-primary-school:0
@@ -0,0 +1,4 @@
[ 3260ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 13186ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 155792ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=B91+3:0
[ 165424ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=B91+3:0
@@ -0,0 +1,4 @@
[ 3144ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 13088ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 23226ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=Welland+Primary:0
[ 33141ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=Welland+Primary:0
@@ -0,0 +1,2 @@
[ 3090ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 13086ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
@@ -0,0 +1,4 @@
[ 3320ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[ 13262ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[ 31275ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[ 167053ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
@@ -0,0 +1,2 @@
[ 3489ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=136916&metric=attainment_8_score:0
[ 13346ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=136916&metric=attainment_8_score:0
@@ -0,0 +1,4 @@
[ 67ms] [WARNING] Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options @ https://schoolcompare.co.uk/_next/static/chunks/b6104424f97d1001.js:0
[ 3111ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/146678-welland-primary-school:0
[ 13084ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/146678-welland-primary-school:0
[ 70899ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/146678-welland-primary-school:0
@@ -0,0 +1,2 @@
[ 3297ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[ 13095ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
@@ -0,0 +1,3 @@
[ 3677ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[ 13096ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[ 480177ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
@@ -0,0 +1,2 @@
[ 4073ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=136916&metric=attainment_8_score:0
[ 13162ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=136916&metric=attainment_8_score:0
@@ -0,0 +1,14 @@
[ 3410ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct:0
[ 13266ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct:0
[ 41131ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct:0
[ 49979ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161:0
[ 59609ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161:0
[ 66865ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161:0
[ 77770ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161%2C113105:0
[ 87487ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161%2C113105:0
[ 213040ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161:0
[ 222647ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161:0
[ 240300ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161:0
[ 248166ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161%2C136916:0
[ 257801ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161%2C136916:0
[ 270504ms] [WARNING] Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options @ https://schoolcompare.co.uk/_next/static/chunks/b6104424f97d1001.js:0
@@ -0,0 +1,2 @@
[ 3428ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=142161%2C136916&metric=rwm_expected_pct:0
[ 13145ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=142161%2C136916&metric=rwm_expected_pct:0
@@ -0,0 +1,3 @@
[ 61ms] [WARNING] Deprecated API for given entry type. @ https://analytics.schoolcompare.co.uk/script.js:0
[ 3522ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=142161%2C136916&metric=rwm_expected_pct:0
[ 13114ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=142161%2C136916&metric=rwm_expected_pct:0
@@ -0,0 +1,5 @@
[ 3857ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=142161%2C113105&metric=rwm_expected_pct:0
[ 13294ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=142161%2C113105&metric=rwm_expected_pct:0
[ 73049ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=142161%2C113105&metric=rwm_expected_pct:0
[ 95050ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=142161%2C113105%2C124613&metric=rwm_expected_pct:0
[ 104770ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=142161%2C113105%2C124613&metric=rwm_expected_pct:0
@@ -0,0 +1,18 @@
[ 3222ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings:0
[ 13105ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings:0
[ 47024ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings:0
[ 129393ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?local_authority=Solihull:0
[ 138906ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?local_authority=Solihull:0
[ 173757ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?local_authority=Solihull&metric=rwm_expected_pct:0
[ 183459ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?local_authority=Solihull&metric=rwm_expected_pct:0
[ 196217ms] [WARNING] Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options @ https://schoolcompare.co.uk/_next/static/chunks/b6104424f97d1001.js:0
[ 200016ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/148084-lady-katherine-leveson-church-of-england-primary-school:0
[ 209230ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/148084-lady-katherine-leveson-church-of-england-primary-school:0
[ 215436ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?local_authority=Solihull&metric=rwm_expected_pct:0
[ 225403ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?local_authority=Solihull&metric=rwm_expected_pct:0
[ 260204ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/104049-sharmans-cross-junior-school:0
[ 270092ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/104049-sharmans-cross-junior-school:0
[ 290140ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/104049-sharmans-cross-junior-school:0
[ 1476417ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?local_authority=Solihull&metric=rwm_expected_pct:0
[ 1486368ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?local_authority=Solihull&metric=rwm_expected_pct:0
[ 1506402ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?local_authority=Solihull&metric=rwm_expected_pct:0
@@ -0,0 +1,4 @@
[ 3180ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings:0
[ 7050ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings:0
[ 13109ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings:0
[ 23380ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings:0
@@ -0,0 +1,2 @@
[ 3354ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 13301ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
@@ -0,0 +1 @@
[ 68ms] [WARNING] Deprecated API for given entry type. @ https://analytics.schoolcompare.co.uk/script.js:0
@@ -0,0 +1 @@
[ 71ms] [WARNING] Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options @ https://schoolcompare.co.uk/_next/static/chunks/b6104424f97d1001.js:0
@@ -0,0 +1 @@
[ 68ms] [WARNING] Deprecated API for given entry type. @ https://analytics.schoolcompare.co.uk/script.js:0
@@ -0,0 +1,3 @@
[ 3407ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=B91%203DL:0
[ 13281ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=B91%203DL:0
[ 33311ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=B91%203DL:0
@@ -0,0 +1,3 @@
[ 3178ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 9456ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?postcode=B91+3DL&radius=1:0
[ 19269ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?postcode=B91+3DL&radius=1:0
@@ -0,0 +1,4 @@
[ 3422ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[ 13307ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[ 33265ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[15619214ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
@@ -0,0 +1,2 @@
[ 3300ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 13157ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
@@ -0,0 +1,2 @@
[ 3263ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=Welland+Primary:0
[ 13184ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=Welland+Primary:0
@@ -0,0 +1,2 @@
[ 3142ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings:0
[ 13108ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings:0
@@ -0,0 +1,2 @@
[ 5101581ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/8903db4d490d6a65.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 5101581ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
@@ -0,0 +1,4 @@
[ 3285ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 13107ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 33154ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 37100ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
@@ -0,0 +1,2 @@
[ 3253ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=Welland+Primary:0
[ 9999ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=Welland+Primary:0
@@ -0,0 +1,2 @@
[ 3316ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[ 13172ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
@@ -0,0 +1,2 @@
[ 3218ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?metric=rwm_high_pct:0
[ 13206ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?metric=rwm_high_pct:0
@@ -0,0 +1 @@
[ 77ms] [WARNING] Deprecated API for given entry type. @ https://analytics.schoolcompare.co.uk/script.js:0
@@ -0,0 +1 @@
[ 72ms] [WARNING] Deprecated API for given entry type. @ https://analytics.schoolcompare.co.uk/script.js:0
@@ -0,0 +1,2 @@
[ 3633ms] [WARNING] The resource https://www.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://www.schoolcompare.co.uk/compare?urns=101038%2C101022%2C101036&metric=rwm_expected_pct:0
[ 13405ms] [WARNING] The resource https://www.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://www.schoolcompare.co.uk/compare?urns=101038%2C101022%2C101036&metric=rwm_expected_pct:0
@@ -0,0 +1,10 @@
[ 336ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 338ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 351ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 3412ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=101038%2C101022&metric=rwm_expected_pct:0
[ 10491ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 13493ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=101038%2C101022&metric=rwm_expected_pct:0
[ 25526ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 28528ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=101038%2C101022&metric=rwm_expected_pct:0
[ 55600ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 58602ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=101038%2C101022&metric=rwm_expected_pct:0
@@ -0,0 +1,12 @@
[ 185ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/la-averages:0
[ 204ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 231ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/national-averages:0
[ 3299ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
[ 10242ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 13245ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
[ 25282ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 28285ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
[ 215055ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 218057ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
[ 260123ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 263125ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
@@ -0,0 +1,2 @@
[ 3573ms] [WARNING] The resource https://www.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://www.schoolcompare.co.uk/compare?urns=101038%2C101022&metric=rwm_expected_pct:0
[ 13319ms] [WARNING] The resource https://www.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://www.schoolcompare.co.uk/compare?urns=101038%2C101022&metric=rwm_expected_pct:0
@@ -0,0 +1,2 @@
[ 166ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/la-averages:0
[ 3388ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
@@ -0,0 +1 @@
[ 3248ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=101038%2C101022&metric=rwm_expected_pct:0
@@ -0,0 +1,2 @@
[ 95ms] [ERROR] Failed to load resource: the server responded with a status of 404 () @ https://stx.schoolcompare.co.uk/search?search=primary:0
[ 3287ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/search?search=primary:0
@@ -0,0 +1,3 @@
[ 3271ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/:0
[ 8281ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/la-averages:0
[ 11313ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
@@ -0,0 +1,2 @@
[ 3730ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=137306%2C138690&metric=rwm_expected_pct:0
[ 33217ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=137306%2C138690&metric=rwm_expected_pct:0
@@ -0,0 +1,3 @@
[ 137ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/la-averages:0
[ 3227ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
[ 7230ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
@@ -0,0 +1,2 @@
[ 3272ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=137306%2C138690%2C139016&metric=rwm_expected_pct:0
[ 9317ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=137306%2C138690%2C139016&metric=rwm_expected_pct:0
@@ -0,0 +1,2 @@
[ 3495ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=101037%2C101026%2C101014%2C101038%2C101022&metric=rwm_expected_pct:0
[ 33343ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=101037%2C101026%2C101014%2C101038%2C101022&metric=rwm_expected_pct:0
@@ -0,0 +1,3 @@
[ 166ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/la-averages:0
[ 3265ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
[ 33242ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
@@ -0,0 +1,3 @@
[ 210ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/la-averages:0
[ 3561ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?postcode=B1%201BB:0
[ 33283ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?postcode=B1%201BB:0
@@ -0,0 +1,14 @@
[ 320ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/la-averages:0
[ 3662ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?postcode=B1%201BB:0
[ 10839ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?postcode=B1%201BB:0
[ 16913ms] TypeError: r.current?.requestFullscreen is not a function
at https://stx.schoolcompare.co.uk/_next/static/chunks/a94dcea45b9ebb2c.js:1:25166
at sY (https://stx.schoolcompare.co.uk/_next/static/chunks/69be39811437728d.js:1:160839)
at https://stx.schoolcompare.co.uk/_next/static/chunks/69be39811437728d.js:1:166727
at tD (https://stx.schoolcompare.co.uk/_next/static/chunks/69be39811437728d.js:1:29334)
at s3 (https://stx.schoolcompare.co.uk/_next/static/chunks/69be39811437728d.js:1:162072)
at fC (https://stx.schoolcompare.co.uk/_next/static/chunks/69be39811437728d.js:1:198038)
at fN (https://stx.schoolcompare.co.uk/_next/static/chunks/69be39811437728d.js:1:197860)
at eval (eval at <anonymous> (eval at evaluate (:303:30)), <anonymous>:4:16)
at eval (eval at evaluate (:303:30), <anonymous>:4:50)
at UtilityScript.evaluate (<anonymous>:305:16)
@@ -0,0 +1,5 @@
[ 213ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/la-averages:0
[ 3418ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
[ 33266ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
[242896019ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
[257299531ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
@@ -0,0 +1,2 @@
[ 3717ms] [WARNING] The resource https://www.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://www.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
[ 13359ms] [WARNING] The resource https://www.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://www.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
@@ -0,0 +1 @@
[ 70ms] [ERROR] Failed to load resource: the server responded with a status of 404 (File not found) @ http://localhost:8471/favicon.ico:0
@@ -0,0 +1 @@
[ 73ms] [ERROR] Failed to load resource: the server responded with a status of 404 (File not found) @ http://localhost:8471/favicon.ico:0
@@ -0,0 +1,3 @@
[ 3942ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
[ 131774ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362&metric=rwm_expected_pct:0
[ 419746ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362&metric=rwm_expected_pct:0
@@ -0,0 +1 @@
[ 50ms] [ERROR] Failed to load resource: the server responded with a status of 404 (File not found) @ http://localhost:8492/favicon.ico:0
@@ -0,0 +1 @@
[ 3664ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
@@ -0,0 +1 @@
[ 3236ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
@@ -0,0 +1 @@
[ 37ms] [ERROR] Failed to load resource: the server responded with a status of 404 (File not found) @ http://localhost:8493/favicon.ico:0
@@ -0,0 +1 @@
[ 42ms] [ERROR] Failed to load resource: the server responded with a status of 404 (File not found) @ http://localhost:8494/favicon.ico:0
@@ -0,0 +1 @@
[ 40ms] [ERROR] Failed to load resource: the server responded with a status of 404 (File not found) @ http://localhost:8495/favicon.ico:0
@@ -0,0 +1 @@
[ 3479ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
@@ -0,0 +1 @@
[ 3334ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
@@ -0,0 +1 @@
[ 3462ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
@@ -0,0 +1,2 @@
[ 3520ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=136276%2C137086%2C102052&metric=attainment_8_score:0
[26254907ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=136276%2C137086%2C102052&metric=attainment_8_score:0
@@ -0,0 +1 @@
[ 3498ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
@@ -0,0 +1 @@
[ 3382ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
@@ -0,0 +1,3 @@
[ 3562ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
[ 84848ms] [WARNING] Canvas2D: Multiple readback operations using getImageData are faster with the willReadFrequently attribute set to true. See: https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-will-read-frequently @ :5
[ 122267ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=reading_expected_pct:0
@@ -0,0 +1 @@
[ 3424ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=136276%2C137086%2C102052&metric=attainment_8_score:0
@@ -0,0 +1 @@
[ 3313ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=136276%2C137086%2C102052&metric=attainment_8_score:0
@@ -0,0 +1 @@
[ 3511ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C136276&metric=rwm_expected_pct:0
@@ -0,0 +1 @@
[ 3364ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C136276&metric=rwm_expected_pct:0
@@ -0,0 +1,2 @@
[ 3588ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
[ 49500ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
@@ -0,0 +1 @@
[ 44ms] [ERROR] Failed to load resource: the server responded with a status of 404 (File not found) @ http://localhost:8791/favicon.ico:0
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 946 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 KiB

@@ -0,0 +1,151 @@
- generic [active] [ref=f1e1]:
- link "Skip to main content" [ref=f1e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f1e3]:
- link "SchoolCompare home" [ref=f1e5] [cursor=pointer]:
- /url: /
- img [ref=f1e7]
- generic [ref=f1e11]: SchoolCompare
- navigation "Main navigation" [ref=f1e12]:
- link "Search" [ref=f1e13] [cursor=pointer]:
- /url: /
- img [ref=f1e15]
- generic [ref=f1e18]: Search
- link "Compare" [ref=f1e19] [cursor=pointer]:
- /url: /compare
- img [ref=f1e21]
- generic [ref=f1e24]: Compare
- link "Rankings" [ref=f1e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f1e27]
- generic [ref=f1e28]: Rankings
- link "Admissions" [ref=f1e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f1e31]
- generic [ref=f1e34]: Admissions
- main [ref=f1e35]:
- generic [ref=f1e36]:
- heading "Every school in England, compared." [level=1] [ref=f1e38]:
- text: Every school in England,
- emphasis [ref=f1e39]: compared.
- generic [ref=f1e42]:
- searchbox "School name or postcode" [ref=f1e43]
- button "Search" [ref=f1e44] [cursor=pointer]
- button "Schools near me" [ref=f1e47] [cursor=pointer]:
- img [ref=f1e48]
- text: Schools near me
- generic [ref=f1e51]:
- generic [ref=f1e52]:
- generic [ref=f1e53]: Key admissions deadlines
- link "Full admissions guide →" [ref=f1e54] [cursor=pointer]:
- /url: /admissions
- generic [ref=f1e55]:
- generic [ref=f1e56]:
- generic [ref=f1e57]: Secondary · Deadline
- generic [ref=f1e59]: 121days
- generic [ref=f1e60]: Secondary applications close
- generic [ref=f1e61]: Sat, 31 October 2026
- generic [ref=f1e62]:
- generic [ref=f1e63]: Primary · Deadline
- generic [ref=f1e65]: 197days
- generic [ref=f1e66]: Primary applications close
- generic [ref=f1e67]: Fri, 15 January 2027
- generic [ref=f1e68]:
- generic [ref=f1e69]: Secondary · Offer Day
- generic [ref=f1e71]: 242days
- generic [ref=f1e72]: Secondary National Offer Day
- generic [ref=f1e73]: Mon, 1 March 2027
- generic [ref=f1e74]:
- generic [ref=f1e75]: Primary · Offer Day
- generic [ref=f1e77]: 288days
- generic [ref=f1e78]: Primary National Offer Day
- generic [ref=f1e79]: Fri, 16 April 2027
- generic [ref=f1e80]:
- generic [ref=f1e81]: Start exploring
- generic [ref=f1e82]:
- link "Top-rated primary schools" [ref=f1e83] [cursor=pointer]:
- /url: /rankings
- text: Top-rated primary schools
- link "Top-rated secondary schools" [ref=f1e85] [cursor=pointer]:
- /url: /rankings
- text: Top-rated secondary schools
- link "Start a comparison" [ref=f1e87] [cursor=pointer]:
- /url: /compare
- text: Start a comparison
- generic [ref=f1e89]:
- generic [ref=f1e90]:
- heading "What you'll see on every school" [level=2] [ref=f1e91]
- generic [ref=f1e92]: Primary or secondary — the page adapts to the phase
- generic [ref=f1e93]:
- generic [ref=f1e95]:
- generic [ref=f1e96]: Performance
- generic [ref=f1e97]: Results against the national average
- paragraph [ref=f1e98]: For primary schools, each subject's Expected and Exceeding percentages side by side. For secondary schools, GCSE Attainment 8 with the national benchmark overlaid.
- generic [ref=f1e100]:
- generic [ref=f1e101]: Judgement
- generic [ref=f1e102]: Ofsted at a glance
- paragraph [ref=f1e103]: Current grade, inspection date, and a plain-English headline — without opening a 40-page report.
- generic [ref=f1e105]:
- generic [ref=f1e106]: Compare
- generic [ref=f1e107]: Side-by-side shortlists
- paragraph [ref=f1e108]: Pin up to five schools and every metric aligns in the same columns — works for primary and secondary alike.
- generic [ref=f1e110]:
- generic [ref=f1e111]:
- generic [ref=f1e112]: About school data
- heading "Making UK school performance data actually readable" [level=2] [ref=f1e113]
- paragraph [ref=f1e114]: School performance data in England is rich but fragmented. The Department for Education publishes Key Stage 2 SATs, GCSE attainment, Ofsted outcomes, progress scores, admissions figures and demographics — each in its own table, each with its own jargon.
- paragraph [ref=f1e115]: SchoolCompare brings it all into one place. Every school page shows performance against the national average, explains what the numbers mean, and lets you shortlist schools side by side. Built for parents, governors, journalists, and anyone who wants to understand a school without reading a 40-page inspection report.
- generic [ref=f1e116]:
- heading "Coverage at a glance" [level=3] [ref=f1e117]
- generic [ref=f1e118]:
- generic [ref=f1e119]: Schools covered
- generic [ref=f1e120]: 24,000+
- generic [ref=f1e121]:
- generic [ref=f1e122]: Local authorities
- generic [ref=f1e123]: "182"
- generic [ref=f1e124]:
- generic [ref=f1e125]: Phases
- generic [ref=f1e126]: Primary & Secondary
- generic [ref=f1e127]:
- generic [ref=f1e128]: Latest results year
- generic [ref=f1e129]: 2024/25
- generic [ref=f1e130]:
- generic [ref=f1e131]: Historical data
- generic [ref=f1e132]: 2016–2025
- generic [ref=f1e133]:
- generic [ref=f1e134]: Metrics per school
- generic [ref=f1e135]: 40+
- contentinfo [ref=f1e136]:
- generic [ref=f1e137]:
- generic [ref=f1e138]:
- generic [ref=f1e139]:
- heading "SchoolCompare" [level=3] [ref=f1e140]
- paragraph [ref=f1e141]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f1e142] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f1e143]:
- heading "Product" [level=4] [ref=f1e144]
- list [ref=f1e145]:
- listitem [ref=f1e146]:
- link "Search schools" [ref=f1e147] [cursor=pointer]:
- /url: /
- listitem [ref=f1e148]:
- link "Rankings" [ref=f1e149] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f1e150]:
- link "Compare shortlist" [ref=f1e151] [cursor=pointer]:
- /url: /compare
- listitem [ref=f1e152]:
- link "Admissions guide" [ref=f1e153] [cursor=pointer]:
- /url: /admissions
- generic [ref=f1e154]:
- heading "Resources" [level=4] [ref=f1e155]
- list [ref=f1e156]:
- listitem [ref=f1e157]:
- link "School Performance Tables" [ref=f1e158] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f1e159]:
- link "Ofsted reports" [ref=f1e160] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f1e162]: © 2026 SchoolCompare.co.uk
- alert [ref=f1e163]
@@ -0,0 +1,151 @@
- generic [ref=f1e1]:
- link "Skip to main content" [ref=f1e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f1e3]:
- link "SchoolCompare home" [ref=f1e5] [cursor=pointer]:
- /url: /
- img [ref=f1e7]
- generic [ref=f1e11]: SchoolCompare
- navigation "Main navigation" [ref=f1e12]:
- link "Search" [ref=f1e13] [cursor=pointer]:
- /url: /
- img [ref=f1e15]
- generic [ref=f1e18]: Search
- link "Compare" [ref=f1e19] [cursor=pointer]:
- /url: /compare
- img [ref=f1e21]
- generic [ref=f1e24]: Compare
- link "Rankings" [ref=f1e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f1e27]
- generic [ref=f1e28]: Rankings
- link "Admissions" [ref=f1e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f1e31]
- generic [ref=f1e34]: Admissions
- main [ref=f1e35]:
- generic [ref=f1e36]:
- heading "Every school in England, compared." [level=1] [ref=f1e38]:
- text: Every school in England,
- emphasis [ref=f1e39]: compared.
- generic [ref=f1e42]:
- searchbox "School name or postcode" [active] [ref=f1e43]
- button "Search" [ref=f1e44] [cursor=pointer]
- button "Schools near me" [ref=f1e47] [cursor=pointer]:
- img [ref=f1e48]
- text: Schools near me
- generic [ref=f1e51]:
- generic [ref=f1e52]:
- generic [ref=f1e53]: Key admissions deadlines
- link "Full admissions guide →" [ref=f1e54] [cursor=pointer]:
- /url: /admissions
- generic [ref=f1e55]:
- generic [ref=f1e56]:
- generic [ref=f1e57]: Secondary · Deadline
- generic [ref=f1e59]: 121days
- generic [ref=f1e60]: Secondary applications close
- generic [ref=f1e61]: Sat, 31 October 2026
- generic [ref=f1e62]:
- generic [ref=f1e63]: Primary · Deadline
- generic [ref=f1e65]: 197days
- generic [ref=f1e66]: Primary applications close
- generic [ref=f1e67]: Fri, 15 January 2027
- generic [ref=f1e68]:
- generic [ref=f1e69]: Secondary · Offer Day
- generic [ref=f1e71]: 242days
- generic [ref=f1e72]: Secondary National Offer Day
- generic [ref=f1e73]: Mon, 1 March 2027
- generic [ref=f1e74]:
- generic [ref=f1e75]: Primary · Offer Day
- generic [ref=f1e77]: 288days
- generic [ref=f1e78]: Primary National Offer Day
- generic [ref=f1e79]: Fri, 16 April 2027
- generic [ref=f1e80]:
- generic [ref=f1e81]: Start exploring
- generic [ref=f1e82]:
- link "Top-rated primary schools" [ref=f1e83] [cursor=pointer]:
- /url: /rankings
- text: Top-rated primary schools
- link "Top-rated secondary schools" [ref=f1e85] [cursor=pointer]:
- /url: /rankings
- text: Top-rated secondary schools
- link "Start a comparison" [ref=f1e87] [cursor=pointer]:
- /url: /compare
- text: Start a comparison
- generic [ref=f1e89]:
- generic [ref=f1e90]:
- heading "What you'll see on every school" [level=2] [ref=f1e91]
- generic [ref=f1e92]: Primary or secondary — the page adapts to the phase
- generic [ref=f1e93]:
- generic [ref=f1e95]:
- generic [ref=f1e96]: Performance
- generic [ref=f1e97]: Results against the national average
- paragraph [ref=f1e98]: For primary schools, each subject's Expected and Exceeding percentages side by side. For secondary schools, GCSE Attainment 8 with the national benchmark overlaid.
- generic [ref=f1e100]:
- generic [ref=f1e101]: Judgement
- generic [ref=f1e102]: Ofsted at a glance
- paragraph [ref=f1e103]: Current grade, inspection date, and a plain-English headline — without opening a 40-page report.
- generic [ref=f1e105]:
- generic [ref=f1e106]: Compare
- generic [ref=f1e107]: Side-by-side shortlists
- paragraph [ref=f1e108]: Pin up to five schools and every metric aligns in the same columns — works for primary and secondary alike.
- generic [ref=f1e110]:
- generic [ref=f1e111]:
- generic [ref=f1e112]: About school data
- heading "Making UK school performance data actually readable" [level=2] [ref=f1e113]
- paragraph [ref=f1e114]: School performance data in England is rich but fragmented. The Department for Education publishes Key Stage 2 SATs, GCSE attainment, Ofsted outcomes, progress scores, admissions figures and demographics — each in its own table, each with its own jargon.
- paragraph [ref=f1e115]: SchoolCompare brings it all into one place. Every school page shows performance against the national average, explains what the numbers mean, and lets you shortlist schools side by side. Built for parents, governors, journalists, and anyone who wants to understand a school without reading a 40-page inspection report.
- generic [ref=f1e116]:
- heading "Coverage at a glance" [level=3] [ref=f1e117]
- generic [ref=f1e118]:
- generic [ref=f1e119]: Schools covered
- generic [ref=f1e120]: 24,000+
- generic [ref=f1e121]:
- generic [ref=f1e122]: Local authorities
- generic [ref=f1e123]: "182"
- generic [ref=f1e124]:
- generic [ref=f1e125]: Phases
- generic [ref=f1e126]: Primary & Secondary
- generic [ref=f1e127]:
- generic [ref=f1e128]: Latest results year
- generic [ref=f1e129]: 2024/25
- generic [ref=f1e130]:
- generic [ref=f1e131]: Historical data
- generic [ref=f1e132]: 2016–2025
- generic [ref=f1e133]:
- generic [ref=f1e134]: Metrics per school
- generic [ref=f1e135]: 40+
- contentinfo [ref=f1e136]:
- generic [ref=f1e137]:
- generic [ref=f1e138]:
- generic [ref=f1e139]:
- heading "SchoolCompare" [level=3] [ref=f1e140]
- paragraph [ref=f1e141]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f1e142] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f1e143]:
- heading "Product" [level=4] [ref=f1e144]
- list [ref=f1e145]:
- listitem [ref=f1e146]:
- link "Search schools" [ref=f1e147] [cursor=pointer]:
- /url: /
- listitem [ref=f1e148]:
- link "Rankings" [ref=f1e149] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f1e150]:
- link "Compare shortlist" [ref=f1e151] [cursor=pointer]:
- /url: /compare
- listitem [ref=f1e152]:
- link "Admissions guide" [ref=f1e153] [cursor=pointer]:
- /url: /admissions
- generic [ref=f1e154]:
- heading "Resources" [level=4] [ref=f1e155]
- list [ref=f1e156]:
- listitem [ref=f1e157]:
- link "School Performance Tables" [ref=f1e158] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f1e159]:
- link "Ofsted reports" [ref=f1e160] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f1e162]: © 2026 SchoolCompare.co.uk
- alert [ref=f1e163]
@@ -0,0 +1,151 @@
- generic [ref=f1e1]:
- link "Skip to main content" [ref=f1e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f1e3]:
- link "SchoolCompare home" [ref=f1e5] [cursor=pointer]:
- /url: /
- img [ref=f1e7]
- generic [ref=f1e11]: SchoolCompare
- navigation "Main navigation" [ref=f1e12]:
- link "Search" [ref=f1e13] [cursor=pointer]:
- /url: /
- img [ref=f1e15]
- generic [ref=f1e18]: Search
- link "Compare" [ref=f1e19] [cursor=pointer]:
- /url: /compare
- img [ref=f1e21]
- generic [ref=f1e24]: Compare
- link "Rankings" [ref=f1e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f1e27]
- generic [ref=f1e28]: Rankings
- link "Admissions" [ref=f1e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f1e31]
- generic [ref=f1e34]: Admissions
- main [ref=f1e35]:
- generic [ref=f1e36]:
- heading "Every school in England, compared." [level=1] [ref=f1e38]:
- text: Every school in England,
- emphasis [ref=f1e39]: compared.
- generic [ref=f1e42]:
- searchbox "School name or postcode" [active] [ref=f1e43]: Welland Primary
- button "Search" [ref=f1e44] [cursor=pointer]
- button "Schools near me" [ref=f1e47] [cursor=pointer]:
- img [ref=f1e48]
- text: Schools near me
- generic [ref=f1e51]:
- generic [ref=f1e52]:
- generic [ref=f1e53]: Key admissions deadlines
- link "Full admissions guide →" [ref=f1e54] [cursor=pointer]:
- /url: /admissions
- generic [ref=f1e55]:
- generic [ref=f1e56]:
- generic [ref=f1e57]: Secondary · Deadline
- generic [ref=f1e59]: 121days
- generic [ref=f1e60]: Secondary applications close
- generic [ref=f1e61]: Sat, 31 October 2026
- generic [ref=f1e62]:
- generic [ref=f1e63]: Primary · Deadline
- generic [ref=f1e65]: 197days
- generic [ref=f1e66]: Primary applications close
- generic [ref=f1e67]: Fri, 15 January 2027
- generic [ref=f1e68]:
- generic [ref=f1e69]: Secondary · Offer Day
- generic [ref=f1e71]: 242days
- generic [ref=f1e72]: Secondary National Offer Day
- generic [ref=f1e73]: Mon, 1 March 2027
- generic [ref=f1e74]:
- generic [ref=f1e75]: Primary · Offer Day
- generic [ref=f1e77]: 288days
- generic [ref=f1e78]: Primary National Offer Day
- generic [ref=f1e79]: Fri, 16 April 2027
- generic [ref=f1e80]:
- generic [ref=f1e81]: Start exploring
- generic [ref=f1e82]:
- link "Top-rated primary schools" [ref=f1e83] [cursor=pointer]:
- /url: /rankings
- text: Top-rated primary schools
- link "Top-rated secondary schools" [ref=f1e85] [cursor=pointer]:
- /url: /rankings
- text: Top-rated secondary schools
- link "Start a comparison" [ref=f1e87] [cursor=pointer]:
- /url: /compare
- text: Start a comparison
- generic [ref=f1e89]:
- generic [ref=f1e90]:
- heading "What you'll see on every school" [level=2] [ref=f1e91]
- generic [ref=f1e92]: Primary or secondary — the page adapts to the phase
- generic [ref=f1e93]:
- generic [ref=f1e95]:
- generic [ref=f1e96]: Performance
- generic [ref=f1e97]: Results against the national average
- paragraph [ref=f1e98]: For primary schools, each subject's Expected and Exceeding percentages side by side. For secondary schools, GCSE Attainment 8 with the national benchmark overlaid.
- generic [ref=f1e100]:
- generic [ref=f1e101]: Judgement
- generic [ref=f1e102]: Ofsted at a glance
- paragraph [ref=f1e103]: Current grade, inspection date, and a plain-English headline — without opening a 40-page report.
- generic [ref=f1e105]:
- generic [ref=f1e106]: Compare
- generic [ref=f1e107]: Side-by-side shortlists
- paragraph [ref=f1e108]: Pin up to five schools and every metric aligns in the same columns — works for primary and secondary alike.
- generic [ref=f1e110]:
- generic [ref=f1e111]:
- generic [ref=f1e112]: About school data
- heading "Making UK school performance data actually readable" [level=2] [ref=f1e113]
- paragraph [ref=f1e114]: School performance data in England is rich but fragmented. The Department for Education publishes Key Stage 2 SATs, GCSE attainment, Ofsted outcomes, progress scores, admissions figures and demographics — each in its own table, each with its own jargon.
- paragraph [ref=f1e115]: SchoolCompare brings it all into one place. Every school page shows performance against the national average, explains what the numbers mean, and lets you shortlist schools side by side. Built for parents, governors, journalists, and anyone who wants to understand a school without reading a 40-page inspection report.
- generic [ref=f1e116]:
- heading "Coverage at a glance" [level=3] [ref=f1e117]
- generic [ref=f1e118]:
- generic [ref=f1e119]: Schools covered
- generic [ref=f1e120]: 24,000+
- generic [ref=f1e121]:
- generic [ref=f1e122]: Local authorities
- generic [ref=f1e123]: "182"
- generic [ref=f1e124]:
- generic [ref=f1e125]: Phases
- generic [ref=f1e126]: Primary & Secondary
- generic [ref=f1e127]:
- generic [ref=f1e128]: Latest results year
- generic [ref=f1e129]: 2024/25
- generic [ref=f1e130]:
- generic [ref=f1e131]: Historical data
- generic [ref=f1e132]: 2016–2025
- generic [ref=f1e133]:
- generic [ref=f1e134]: Metrics per school
- generic [ref=f1e135]: 40+
- contentinfo [ref=f1e136]:
- generic [ref=f1e137]:
- generic [ref=f1e138]:
- generic [ref=f1e139]:
- heading "SchoolCompare" [level=3] [ref=f1e140]
- paragraph [ref=f1e141]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f1e142] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f1e143]:
- heading "Product" [level=4] [ref=f1e144]
- list [ref=f1e145]:
- listitem [ref=f1e146]:
- link "Search schools" [ref=f1e147] [cursor=pointer]:
- /url: /
- listitem [ref=f1e148]:
- link "Rankings" [ref=f1e149] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f1e150]:
- link "Compare shortlist" [ref=f1e151] [cursor=pointer]:
- /url: /compare
- listitem [ref=f1e152]:
- link "Admissions guide" [ref=f1e153] [cursor=pointer]:
- /url: /admissions
- generic [ref=f1e154]:
- heading "Resources" [level=4] [ref=f1e155]
- list [ref=f1e156]:
- listitem [ref=f1e157]:
- link "School Performance Tables" [ref=f1e158] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f1e159]:
- link "Ofsted reports" [ref=f1e160] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f1e162]: © 2026 SchoolCompare.co.uk
- alert [ref=f1e163]
@@ -0,0 +1,108 @@
- generic [active] [ref=f1e1]:
- link "Skip to main content" [ref=f1e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f1e3]:
- link "SchoolCompare home" [ref=f1e5] [cursor=pointer]:
- /url: /
- img [ref=f1e7]
- generic [ref=f1e11]: SchoolCompare
- navigation "Main navigation" [ref=f1e12]:
- link "Search" [ref=f1e13] [cursor=pointer]:
- /url: /
- img [ref=f1e15]
- generic [ref=f1e18]: Search
- link "Compare" [ref=f1e19] [cursor=pointer]:
- /url: /compare
- img [ref=f1e21]
- generic [ref=f1e24]: Compare
- link "Rankings" [ref=f1e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f1e27]
- generic [ref=f1e28]: Rankings
- link "Admissions" [ref=f1e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f1e31]
- generic [ref=f1e34]: Admissions
- main [ref=f1e35]:
- generic [ref=f1e36]:
- generic [ref=f1e40]:
- generic [ref=f1e42]:
- searchbox "School name or postcode" [ref=f1e43]: Welland Primary
- button "Search" [ref=f1e44] [cursor=pointer]
- generic [ref=f1e164]:
- combobox [ref=f1e165] [cursor=pointer]:
- option "All Phases" [selected]
- option "Primary"
- button "Advanced" [ref=f1e166] [cursor=pointer]: Advanced
- button "Clear" [ref=f1e168] [cursor=pointer]
- generic [ref=f1e169]:
- generic [ref=f1e170]:
- heading "1 school found" [level=2] [ref=f1e171]
- combobox [ref=f1e173] [cursor=pointer]:
- 'option "Sort: Relevance" [selected]'
- option "Highest Reading, Writing & Maths %"
- option "Lowest Reading, Writing & Maths %"
- option "Name A–Z"
- generic [ref=f1e175]:
- text: "Search: Welland Primary"
- link "×" [ref=f1e176] [cursor=pointer]:
- /url: /
- generic [ref=f1e178]:
- generic [ref=f1e179]:
- generic [ref=f1e180]:
- link "Welland Primary School" [ref=f1e181] [cursor=pointer]:
- /url: /school/146678-welland-primary-school
- generic [ref=f1e182]: Good · 2023
- generic [ref=f1e183]:
- generic [ref=f1e184]: Primary
- generic [ref=f1e185]: Academy converter
- generic [ref=f1e186]: Ages 4–11
- generic [ref=f1e187]:
- generic [ref=f1e188]:
- strong [ref=f1e189]: 74%
- 'generic "Previous year: 76.0%" [ref=f1e190]':
- img "Trend down" [ref=f1e191]
- generic [ref=f1e193]: Reading, Writing & Maths
- generic [ref=f1e194]: +12 pts vs national
- generic [ref=f1e195]:
- strong [ref=f1e196]: "131"
- generic [ref=f1e197]: pupils
- generic [ref=f1e199]: Worcestershire
- generic [ref=f1e200]:
- link "View" [ref=f1e201] [cursor=pointer]:
- /url: /school/146678-welland-primary-school
- button "+ Compare" [ref=f1e202] [cursor=pointer]
- contentinfo [ref=f1e136]:
- generic [ref=f1e137]:
- generic [ref=f1e138]:
- generic [ref=f1e139]:
- heading "SchoolCompare" [level=3] [ref=f1e140]
- paragraph [ref=f1e141]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f1e142] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f1e143]:
- heading "Product" [level=4] [ref=f1e144]
- list [ref=f1e145]:
- listitem [ref=f1e146]:
- link "Search schools" [ref=f1e147] [cursor=pointer]:
- /url: /
- listitem [ref=f1e148]:
- link "Rankings" [ref=f1e149] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f1e150]:
- link "Compare shortlist" [ref=f1e151] [cursor=pointer]:
- /url: /compare
- listitem [ref=f1e152]:
- link "Admissions guide" [ref=f1e153] [cursor=pointer]:
- /url: /admissions
- generic [ref=f1e154]:
- heading "Resources" [level=4] [ref=f1e155]
- list [ref=f1e156]:
- listitem [ref=f1e157]:
- link "School Performance Tables" [ref=f1e158] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f1e159]:
- link "Ofsted reports" [ref=f1e160] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f1e162]: © 2026 SchoolCompare.co.uk
- alert [ref=f1e163]
@@ -0,0 +1,268 @@
- generic [active] [ref=f2e1]:
- link "Skip to main content" [ref=f2e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f2e3]:
- link "SchoolCompare home" [ref=f2e5] [cursor=pointer]:
- /url: /
- img [ref=f2e7]
- generic [ref=f2e11]: SchoolCompare
- navigation "Main navigation" [ref=f2e12]:
- link "Search" [ref=f2e13] [cursor=pointer]:
- /url: /
- img [ref=f2e15]
- generic [ref=f2e18]: Search
- link "Compare" [ref=f2e19] [cursor=pointer]:
- /url: /compare
- img [ref=f2e21]
- generic [ref=f2e24]: Compare
- link "Rankings" [ref=f2e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f2e27]
- generic [ref=f2e28]: Rankings
- link "Admissions" [ref=f2e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f2e31]
- generic [ref=f2e34]: Admissions
- main [ref=f2e35]:
- generic [ref=f2e36]:
- button "Back" [ref=f2e37] [cursor=pointer]:
- generic [ref=f2e38]: ←
- text: Back
- generic [ref=f2e39]:
- generic [ref=f2e40]:
- generic [ref=f2e41]:
- img [ref=f2e45] [cursor=pointer]
- generic [ref=f2e48]:
- link "Leaflet" [ref=f2e49] [cursor=pointer]:
- /url: https://leafletjs.com
- img [ref=f2e50]
- text: Leaflet
- text: "| ©"
- link "OpenStreetMap" [ref=f2e54] [cursor=pointer]:
- /url: https://www.openstreetmap.org/copyright
- text: contributors
- button "Open full map" [ref=f2e55] [cursor=pointer]:
- generic [ref=f2e56]:
- img [ref=f2e57]
- text: Open full map
- generic [ref=f2e59]:
- generic [ref=f2e60]:
- heading "Welland Primary School" [level=1] [ref=f2e61]
- generic [ref=f2e62]:
- generic [ref=f2e63]: Worcestershire
- generic [ref=f2e64]: Academy converter
- paragraph [ref=f2e65]:
- text: Marlbank Road, Welland, Malvern, WR13 6NE ·
- button "View on map ↗" [ref=f2e66] [cursor=pointer]
- button "+ Add to Compare" [ref=f2e68] [cursor=pointer]
- navigation "Page sections" [ref=f2e69]:
- button "Back to top" [ref=f2e70] [cursor=pointer]:
- generic [ref=f2e71]: ↑
- button "Section Ofsted" [ref=f2e72] [cursor=pointer]:
- generic [ref=f2e73]:
- generic [ref=f2e74]: Section
- generic [ref=f2e75]: Ofsted
- generic [ref=f2e76]: ▾
- generic [ref=f2e77]:
- heading "Ofsted Rating Inspected 6 June 2023 Ofsted reports ↗" [level=2] [ref=f2e78]:
- text: Ofsted Rating
- generic [ref=f2e79]: Inspected 6 June 2023
- link "Ofsted reports ↗" [ref=f2e80] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/inspection-reports/find-inspection-report/provider/ELS/146678
- generic [ref=f2e82]: Good
- paragraph [ref=f2e83]: From September 2024, Ofsted no longer makes an overall effectiveness judgement in inspections of state-funded schools.
- paragraph [ref=f2e84]:
- text: Rated
- strong [ref=f2e85]: Good
- text: across all inspected areas — Quality of Teaching, Behaviour, Pupils' Development and Leadership.
- generic [ref=f2e86]:
- heading "SATs Results (2024/25)" [level=2] [ref=f2e87]
- paragraph [ref=f2e88]: End-of-primary-school tests taken by Year 6 pupils. National averages shown for comparison.
- generic [ref=f2e89]:
- generic [ref=f2e90]:
- generic [ref=f2e91]: Reading, Writing & Maths combined
- generic [ref=f2e92]:
- text: 74.0%
- generic [ref=f2e93]: +12 pts
- generic [ref=f2e94]: "National avg: 62%"
- generic [ref=f2e95]:
- generic [ref=f2e96]: Exceeding expected level (Reading, Writing & Maths)
- generic [ref=f2e97]:
- text: 11.0%
- generic [ref=f2e98]: +3 pts
- generic [ref=f2e99]: "National avg: 8%"
- generic [ref=f2e100]:
- generic [ref=f2e101]: "?"
- generic [ref=f2e102]:
- generic [ref=f2e103]:
- text: Why is combined lower? A pupil is only counted if they met the bar in
- strong [ref=f2e104]: all three
- text: subjects. Some passed reading but not writing; some passed writing but not maths.
- generic [ref=f2e105]:
- generic [ref=f2e106]:
- text: Reading
- strong [ref=f2e107]: 74%
- generic [ref=f2e108]: ·
- generic [ref=f2e109]:
- text: Writing
- strong [ref=f2e110]: 74%
- generic [ref=f2e111]: ·
- generic [ref=f2e112]:
- text: Maths
- strong [ref=f2e113]: 81%
- generic [ref=f2e114]: →
- generic [ref=f2e115]:
- text: All three
- strong [ref=f2e116]: 74%
- generic [ref=f2e117]:
- generic [ref=f2e118]:
- generic [ref=f2e119]:
- generic [ref=f2e120]: Reading
- generic [ref=f2e121]:
- generic:
- generic: 75%
- generic [ref=f2e122]:
- generic [ref=f2e124]:
- generic [ref=f2e125]: Expected
- generic [ref=f2e126]: 74%
- generic [ref=f2e130]:
- generic [ref=f2e131]: Exceeding
- generic [ref=f2e132]: 48%
- generic [ref=f2e135]:
- generic [ref=f2e137]: 0%
- generic [ref=f2e139]: 25%
- generic [ref=f2e141]: 50%
- generic [ref=f2e143]: 75%
- generic [ref=f2e145]: 100%
- generic [ref=f2e146]:
- generic [ref=f2e147]: Writing
- generic [ref=f2e148]:
- generic:
- generic: 72%
- generic [ref=f2e149]:
- generic [ref=f2e151]:
- generic [ref=f2e152]: Expected
- generic [ref=f2e153]: 74%
- generic [ref=f2e157]:
- generic [ref=f2e158]: Exceeding
- generic [ref=f2e159]: 11%
- generic [ref=f2e162]:
- generic [ref=f2e164]: 0%
- generic [ref=f2e166]: 25%
- generic [ref=f2e168]: 50%
- generic [ref=f2e170]: 75%
- generic [ref=f2e172]: 100%
- generic [ref=f2e173]:
- generic [ref=f2e174]: Maths
- generic [ref=f2e175]:
- generic:
- generic: 74%
- generic [ref=f2e176]:
- generic [ref=f2e178]:
- generic [ref=f2e179]: Expected
- generic [ref=f2e180]: 81%
- generic [ref=f2e184]:
- generic [ref=f2e185]: Exceeding
- generic [ref=f2e186]: 33%
- generic [ref=f2e189]:
- generic [ref=f2e191]: 0%
- generic [ref=f2e193]: 25%
- generic [ref=f2e195]: 50%
- generic [ref=f2e197]: 75%
- generic [ref=f2e199]: 100%
- generic [ref=f2e200]:
- generic [ref=f2e201]: Expected standard
- generic [ref=f2e203]: Exceeding / high score
- generic [ref=f2e205]: National average
- generic [ref=f2e207]:
- generic [ref=f2e208]:
- heading "Admissions" [level=2] [ref=f2e209]
- group "Admissions view" [ref=f2e210]:
- button "This year" [pressed] [ref=f2e211] [cursor=pointer]
- button "8-year trend" [ref=f2e212] [cursor=pointer]
- generic [ref=f2e215]:
- generic [ref=f2e216]:
- definition [ref=f2e217]: "21"
- term [ref=f2e218]: Places offered
- generic [ref=f2e219]:
- definition [ref=f2e220]: "19"
- term [ref=f2e221]: Wanted it first
- generic [ref=f2e222]:
- definition [ref=f2e223]:
- text: "19"
- generic [ref=f2e224]: of 19 · 100.0%
- term [ref=f2e225]: Got their first choice
- generic [ref=f2e226]:
- definition [ref=f2e227]: "45"
- term [ref=f2e228]: Applied in total
- generic [ref=f2e229]:
- heading "Pupils & Inclusion" [level=2] [ref=f2e230]
- generic [ref=f2e231]:
- generic [ref=f2e232]:
- generic [ref=f2e233]: Eligible for pupil premium
- generic [ref=f2e234]: 26.0%
- generic [ref=f2e235]: Pupils from disadvantaged backgrounds
- generic [ref=f2e236]:
- generic [ref=f2e237]: English as an additional language
- generic [ref=f2e238]: 0.0%
- generic [ref=f2e239]:
- generic [ref=f2e240]: Pupils receiving SEN support
- generic [ref=f2e241]: 4.0%
- generic [ref=f2e242]:
- generic [ref=f2e243]: Boys and girls
- generic [ref=f2e244]:
- generic [ref=f2e245]: 48%
- generic [ref=f2e246]: girls
- generic [ref=f2e247]: ·
- generic [ref=f2e248]: 52%
- generic [ref=f2e249]: boys
- 'img "Gender split: 48% girls, 52% boys" [ref=f2e250]'
- generic [ref=f2e253]: 64 girls, 70 boys
- generic [ref=f2e254]:
- heading "Results Over Time" [level=2] [ref=f2e255]
- generic [ref=f2e257]:
- generic [ref=f2e258]: ↓ Reading, Writing & Maths peaked at 81% (2022/23), currently 74%
- generic [ref=f2e259]:
- generic [ref=f2e260]: KS2 SATs · Reading, Writing & Maths
- tablist "Select metric" [ref=f2e261]:
- tab "At expected level" [selected] [ref=f2e262] [cursor=pointer]
- tab "Above expected level" [ref=f2e263] [cursor=pointer]
- tab "Pupil progress" [ref=f2e264] [cursor=pointer]
- img [ref=f2e266]
- paragraph [ref=f2e267]: "* No data for 2019/20 or 2020/21 — national assessments were cancelled due to COVID-19."
- group [ref=f2e268]:
- generic "▸ View raw year-by-year data" [ref=f2e269] [cursor=pointer]
- contentinfo [ref=f2e270]:
- generic [ref=f2e271]:
- generic [ref=f2e272]:
- generic [ref=f2e273]:
- heading "SchoolCompare" [level=3] [ref=f2e274]
- paragraph [ref=f2e275]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f2e276] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f2e277]:
- heading "Product" [level=4] [ref=f2e278]
- list [ref=f2e279]:
- listitem [ref=f2e280]:
- link "Search schools" [ref=f2e281] [cursor=pointer]:
- /url: /
- listitem [ref=f2e282]:
- link "Rankings" [ref=f2e283] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f2e284]:
- link "Compare shortlist" [ref=f2e285] [cursor=pointer]:
- /url: /compare
- listitem [ref=f2e286]:
- link "Admissions guide" [ref=f2e287] [cursor=pointer]:
- /url: /admissions
- generic [ref=f2e288]:
- heading "Resources" [level=4] [ref=f2e289]
- list [ref=f2e290]:
- listitem [ref=f2e291]:
- link "School Performance Tables" [ref=f2e292] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f2e293]:
- link "Ofsted reports" [ref=f2e294] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f2e296]: © 2026 SchoolCompare.co.uk
- alert [ref=f2e297]
@@ -0,0 +1,151 @@
- generic [active] [ref=f3e1]:
- link "Skip to main content" [ref=f3e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f3e3]:
- link "SchoolCompare home" [ref=f3e5] [cursor=pointer]:
- /url: /
- img [ref=f3e7]
- generic [ref=f3e11]: SchoolCompare
- navigation "Main navigation" [ref=f3e12]:
- link "Search" [ref=f3e13] [cursor=pointer]:
- /url: /
- img [ref=f3e15]
- generic [ref=f3e18]: Search
- link "Compare" [ref=f3e19] [cursor=pointer]:
- /url: /compare
- img [ref=f3e21]
- generic [ref=f3e24]: Compare
- link "Rankings" [ref=f3e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f3e27]
- generic [ref=f3e28]: Rankings
- link "Admissions" [ref=f3e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f3e31]
- generic [ref=f3e34]: Admissions
- main [ref=f3e35]:
- generic [ref=f3e36]:
- heading "Every school in England, compared." [level=1] [ref=f3e38]:
- text: Every school in England,
- emphasis [ref=f3e39]: compared.
- generic [ref=f3e42]:
- searchbox "School name or postcode" [ref=f3e43]
- button "Search" [ref=f3e44] [cursor=pointer]
- button "Schools near me" [ref=f3e47] [cursor=pointer]:
- img [ref=f3e48]
- text: Schools near me
- generic [ref=f3e51]:
- generic [ref=f3e52]:
- generic [ref=f3e53]: Key admissions deadlines
- link "Full admissions guide →" [ref=f3e54] [cursor=pointer]:
- /url: /admissions
- generic [ref=f3e55]:
- generic [ref=f3e56]:
- generic [ref=f3e57]: Secondary · Deadline
- generic [ref=f3e59]: 121days
- generic [ref=f3e60]: Secondary applications close
- generic [ref=f3e61]: Sat, 31 October 2026
- generic [ref=f3e62]:
- generic [ref=f3e63]: Primary · Deadline
- generic [ref=f3e65]: 197days
- generic [ref=f3e66]: Primary applications close
- generic [ref=f3e67]: Fri, 15 January 2027
- generic [ref=f3e68]:
- generic [ref=f3e69]: Secondary · Offer Day
- generic [ref=f3e71]: 242days
- generic [ref=f3e72]: Secondary National Offer Day
- generic [ref=f3e73]: Mon, 1 March 2027
- generic [ref=f3e74]:
- generic [ref=f3e75]: Primary · Offer Day
- generic [ref=f3e77]: 288days
- generic [ref=f3e78]: Primary National Offer Day
- generic [ref=f3e79]: Fri, 16 April 2027
- generic [ref=f3e80]:
- generic [ref=f3e81]: Start exploring
- generic [ref=f3e82]:
- link "Top-rated primary schools" [ref=f3e83] [cursor=pointer]:
- /url: /rankings
- text: Top-rated primary schools
- link "Top-rated secondary schools" [ref=f3e85] [cursor=pointer]:
- /url: /rankings
- text: Top-rated secondary schools
- link "Start a comparison" [ref=f3e87] [cursor=pointer]:
- /url: /compare
- text: Start a comparison
- generic [ref=f3e89]:
- generic [ref=f3e90]:
- heading "What you'll see on every school" [level=2] [ref=f3e91]
- generic [ref=f3e92]: Primary or secondary — the page adapts to the phase
- generic [ref=f3e93]:
- generic [ref=f3e95]:
- generic [ref=f3e96]: Performance
- generic [ref=f3e97]: Results against the national average
- paragraph [ref=f3e98]: For primary schools, each subject's Expected and Exceeding percentages side by side. For secondary schools, GCSE Attainment 8 with the national benchmark overlaid.
- generic [ref=f3e100]:
- generic [ref=f3e101]: Judgement
- generic [ref=f3e102]: Ofsted at a glance
- paragraph [ref=f3e103]: Current grade, inspection date, and a plain-English headline — without opening a 40-page report.
- generic [ref=f3e105]:
- generic [ref=f3e106]: Compare
- generic [ref=f3e107]: Side-by-side shortlists
- paragraph [ref=f3e108]: Pin up to five schools and every metric aligns in the same columns — works for primary and secondary alike.
- generic [ref=f3e110]:
- generic [ref=f3e111]:
- generic [ref=f3e112]: About school data
- heading "Making UK school performance data actually readable" [level=2] [ref=f3e113]
- paragraph [ref=f3e114]: School performance data in England is rich but fragmented. The Department for Education publishes Key Stage 2 SATs, GCSE attainment, Ofsted outcomes, progress scores, admissions figures and demographics — each in its own table, each with its own jargon.
- paragraph [ref=f3e115]: SchoolCompare brings it all into one place. Every school page shows performance against the national average, explains what the numbers mean, and lets you shortlist schools side by side. Built for parents, governors, journalists, and anyone who wants to understand a school without reading a 40-page inspection report.
- generic [ref=f3e116]:
- heading "Coverage at a glance" [level=3] [ref=f3e117]
- generic [ref=f3e118]:
- generic [ref=f3e119]: Schools covered
- generic [ref=f3e120]: 24,000+
- generic [ref=f3e121]:
- generic [ref=f3e122]: Local authorities
- generic [ref=f3e123]: "182"
- generic [ref=f3e124]:
- generic [ref=f3e125]: Phases
- generic [ref=f3e126]: Primary & Secondary
- generic [ref=f3e127]:
- generic [ref=f3e128]: Latest results year
- generic [ref=f3e129]: 2024/25
- generic [ref=f3e130]:
- generic [ref=f3e131]: Historical data
- generic [ref=f3e132]: 2016–2025
- generic [ref=f3e133]:
- generic [ref=f3e134]: Metrics per school
- generic [ref=f3e135]: 40+
- contentinfo [ref=f3e136]:
- generic [ref=f3e137]:
- generic [ref=f3e138]:
- generic [ref=f3e139]:
- heading "SchoolCompare" [level=3] [ref=f3e140]
- paragraph [ref=f3e141]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f3e142] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f3e143]:
- heading "Product" [level=4] [ref=f3e144]
- list [ref=f3e145]:
- listitem [ref=f3e146]:
- link "Search schools" [ref=f3e147] [cursor=pointer]:
- /url: /
- listitem [ref=f3e148]:
- link "Rankings" [ref=f3e149] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f3e150]:
- link "Compare shortlist" [ref=f3e151] [cursor=pointer]:
- /url: /compare
- listitem [ref=f3e152]:
- link "Admissions guide" [ref=f3e153] [cursor=pointer]:
- /url: /admissions
- generic [ref=f3e154]:
- heading "Resources" [level=4] [ref=f3e155]
- list [ref=f3e156]:
- listitem [ref=f3e157]:
- link "School Performance Tables" [ref=f3e158] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f3e159]:
- link "Ofsted reports" [ref=f3e160] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f3e162]: © 2026 SchoolCompare.co.uk
- alert [ref=f3e163]
@@ -0,0 +1,151 @@
- generic [ref=f3e1]:
- link "Skip to main content" [ref=f3e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f3e3]:
- link "SchoolCompare home" [ref=f3e5] [cursor=pointer]:
- /url: /
- img [ref=f3e7]
- generic [ref=f3e11]: SchoolCompare
- navigation "Main navigation" [ref=f3e12]:
- link "Search" [ref=f3e13] [cursor=pointer]:
- /url: /
- img [ref=f3e15]
- generic [ref=f3e18]: Search
- link "Compare" [ref=f3e19] [cursor=pointer]:
- /url: /compare
- img [ref=f3e21]
- generic [ref=f3e24]: Compare
- link "Rankings" [ref=f3e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f3e27]
- generic [ref=f3e28]: Rankings
- link "Admissions" [ref=f3e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f3e31]
- generic [ref=f3e34]: Admissions
- main [ref=f3e35]:
- generic [ref=f3e36]:
- heading "Every school in England, compared." [level=1] [ref=f3e38]:
- text: Every school in England,
- emphasis [ref=f3e39]: compared.
- generic [ref=f3e42]:
- searchbox "School name or postcode" [active] [ref=f3e43]: B91 3
- button "Search" [ref=f3e44] [cursor=pointer]
- button "Schools near me" [ref=f3e47] [cursor=pointer]:
- img [ref=f3e48]
- text: Schools near me
- generic [ref=f3e51]:
- generic [ref=f3e52]:
- generic [ref=f3e53]: Key admissions deadlines
- link "Full admissions guide →" [ref=f3e54] [cursor=pointer]:
- /url: /admissions
- generic [ref=f3e55]:
- generic [ref=f3e56]:
- generic [ref=f3e57]: Secondary · Deadline
- generic [ref=f3e59]: 121days
- generic [ref=f3e60]: Secondary applications close
- generic [ref=f3e61]: Sat, 31 October 2026
- generic [ref=f3e62]:
- generic [ref=f3e63]: Primary · Deadline
- generic [ref=f3e65]: 197days
- generic [ref=f3e66]: Primary applications close
- generic [ref=f3e67]: Fri, 15 January 2027
- generic [ref=f3e68]:
- generic [ref=f3e69]: Secondary · Offer Day
- generic [ref=f3e71]: 242days
- generic [ref=f3e72]: Secondary National Offer Day
- generic [ref=f3e73]: Mon, 1 March 2027
- generic [ref=f3e74]:
- generic [ref=f3e75]: Primary · Offer Day
- generic [ref=f3e77]: 288days
- generic [ref=f3e78]: Primary National Offer Day
- generic [ref=f3e79]: Fri, 16 April 2027
- generic [ref=f3e80]:
- generic [ref=f3e81]: Start exploring
- generic [ref=f3e82]:
- link "Top-rated primary schools" [ref=f3e83] [cursor=pointer]:
- /url: /rankings
- text: Top-rated primary schools
- link "Top-rated secondary schools" [ref=f3e85] [cursor=pointer]:
- /url: /rankings
- text: Top-rated secondary schools
- link "Start a comparison" [ref=f3e87] [cursor=pointer]:
- /url: /compare
- text: Start a comparison
- generic [ref=f3e89]:
- generic [ref=f3e90]:
- heading "What you'll see on every school" [level=2] [ref=f3e91]
- generic [ref=f3e92]: Primary or secondary — the page adapts to the phase
- generic [ref=f3e93]:
- generic [ref=f3e95]:
- generic [ref=f3e96]: Performance
- generic [ref=f3e97]: Results against the national average
- paragraph [ref=f3e98]: For primary schools, each subject's Expected and Exceeding percentages side by side. For secondary schools, GCSE Attainment 8 with the national benchmark overlaid.
- generic [ref=f3e100]:
- generic [ref=f3e101]: Judgement
- generic [ref=f3e102]: Ofsted at a glance
- paragraph [ref=f3e103]: Current grade, inspection date, and a plain-English headline — without opening a 40-page report.
- generic [ref=f3e105]:
- generic [ref=f3e106]: Compare
- generic [ref=f3e107]: Side-by-side shortlists
- paragraph [ref=f3e108]: Pin up to five schools and every metric aligns in the same columns — works for primary and secondary alike.
- generic [ref=f3e110]:
- generic [ref=f3e111]:
- generic [ref=f3e112]: About school data
- heading "Making UK school performance data actually readable" [level=2] [ref=f3e113]
- paragraph [ref=f3e114]: School performance data in England is rich but fragmented. The Department for Education publishes Key Stage 2 SATs, GCSE attainment, Ofsted outcomes, progress scores, admissions figures and demographics — each in its own table, each with its own jargon.
- paragraph [ref=f3e115]: SchoolCompare brings it all into one place. Every school page shows performance against the national average, explains what the numbers mean, and lets you shortlist schools side by side. Built for parents, governors, journalists, and anyone who wants to understand a school without reading a 40-page inspection report.
- generic [ref=f3e116]:
- heading "Coverage at a glance" [level=3] [ref=f3e117]
- generic [ref=f3e118]:
- generic [ref=f3e119]: Schools covered
- generic [ref=f3e120]: 24,000+
- generic [ref=f3e121]:
- generic [ref=f3e122]: Local authorities
- generic [ref=f3e123]: "182"
- generic [ref=f3e124]:
- generic [ref=f3e125]: Phases
- generic [ref=f3e126]: Primary & Secondary
- generic [ref=f3e127]:
- generic [ref=f3e128]: Latest results year
- generic [ref=f3e129]: 2024/25
- generic [ref=f3e130]:
- generic [ref=f3e131]: Historical data
- generic [ref=f3e132]: 2016–2025
- generic [ref=f3e133]:
- generic [ref=f3e134]: Metrics per school
- generic [ref=f3e135]: 40+
- contentinfo [ref=f3e136]:
- generic [ref=f3e137]:
- generic [ref=f3e138]:
- generic [ref=f3e139]:
- heading "SchoolCompare" [level=3] [ref=f3e140]
- paragraph [ref=f3e141]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f3e142] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f3e143]:
- heading "Product" [level=4] [ref=f3e144]
- list [ref=f3e145]:
- listitem [ref=f3e146]:
- link "Search schools" [ref=f3e147] [cursor=pointer]:
- /url: /
- listitem [ref=f3e148]:
- link "Rankings" [ref=f3e149] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f3e150]:
- link "Compare shortlist" [ref=f3e151] [cursor=pointer]:
- /url: /compare
- listitem [ref=f3e152]:
- link "Admissions guide" [ref=f3e153] [cursor=pointer]:
- /url: /admissions
- generic [ref=f3e154]:
- heading "Resources" [level=4] [ref=f3e155]
- list [ref=f3e156]:
- listitem [ref=f3e157]:
- link "School Performance Tables" [ref=f3e158] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f3e159]:
- link "Ofsted reports" [ref=f3e160] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f3e162]: © 2026 SchoolCompare.co.uk
- alert [ref=f3e163]
@@ -0,0 +1,277 @@
- generic [ref=f3e1]:
- link "Skip to main content" [ref=f3e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f3e3]:
- link "SchoolCompare home" [ref=f3e5] [cursor=pointer]:
- /url: /
- img [ref=f3e7]
- generic [ref=f3e11]: SchoolCompare
- navigation "Main navigation" [ref=f3e12]:
- link "Search" [ref=f3e13] [cursor=pointer]:
- /url: /
- img [ref=f3e15]
- generic [ref=f3e18]: Search
- link "Compare" [ref=f3e19] [cursor=pointer]:
- /url: /compare
- img [ref=f3e21]
- generic [ref=f3e24]: Compare
- link "Rankings" [ref=f3e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f3e27]
- generic [ref=f3e28]: Rankings
- link "Admissions" [ref=f3e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f3e31]
- generic [ref=f3e34]: Admissions
- main [ref=f3e35]:
- generic [ref=f3e36]:
- generic [ref=f3e40]:
- generic [ref=f3e42]:
- searchbox "School name or postcode" [active] [ref=f3e43]: B91 3
- button "Search" [ref=f3e44] [cursor=pointer]
- generic [ref=f3e164]:
- combobox [ref=f3e165] [cursor=pointer]:
- option "All Phases" [selected]
- option "16 plus"
- option "All-through"
- option "Primary"
- option "Secondary"
- button "Advanced" [ref=f3e166] [cursor=pointer]: Advanced
- button "Clear" [ref=f3e168] [cursor=pointer]
- generic [ref=f3e169]:
- generic [ref=f3e170]:
- heading "8 schools found" [level=2] [ref=f3e171]
- combobox [ref=f3e173] [cursor=pointer]:
- 'option "Sort: Relevance" [selected]'
- option "Highest Reading, Writing & Maths %"
- option "Lowest Reading, Writing & Maths %"
- option "Highest Attainment 8"
- option "Lowest Attainment 8"
- option "Name A–Z"
- generic [ref=f3e175]:
- text: "Search: B91 3"
- link "×" [ref=f3e176] [cursor=pointer]:
- /url: /
- generic [ref=f3e177]:
- generic [ref=f3e178]:
- generic [ref=f3e179]:
- generic [ref=f3e180]:
- link "Tudor Grange Academy, Solihull" [ref=f3e181] [cursor=pointer]:
- /url: /school/136310-tudor-grange-academy-solihull
- generic [ref=f3e182]: Inspected · 2025
- generic [ref=f3e183]:
- generic [ref=f3e184]: Secondary
- generic [ref=f3e185]: Academy converter
- generic [ref=f3e186]: Ages 11–18
- generic [ref=f3e187]: Sixth form
- generic [ref=f3e188]: Selective
- generic [ref=f3e189]:
- generic [ref=f3e190]:
- strong [ref=f3e191]: "58.7"
- generic [ref=f3e192]: Attainment 8
- generic [ref=f3e193]: +14.4 vs LA avg
- generic [ref=f3e194]:
- strong [ref=f3e195]: "278"
- generic [ref=f3e196]: pupils
- generic [ref=f3e198]: Solihull
- generic [ref=f3e199]:
- link "View" [ref=f3e200] [cursor=pointer]:
- /url: /school/136310-tudor-grange-academy-solihull
- button "+ Compare" [ref=f3e201] [cursor=pointer]
- generic [ref=f3e202]:
- generic [ref=f3e203]:
- generic [ref=f3e204]:
- link "Solihull School" [ref=f3e205] [cursor=pointer]:
- /url: /school/104124-solihull-school
- generic [ref=f3e206]: Not yet inspected
- generic [ref=f3e207]:
- generic [ref=f3e208]: All-through
- generic [ref=f3e209]: Other independent school
- generic [ref=f3e210]: Ages 3–19
- generic [ref=f3e211]: Selective
- generic [ref=f3e212]:
- generic [ref=f3e213]:
- strong [ref=f3e214]: "41.4"
- generic [ref=f3e215]: Attainment 8
- generic [ref=f3e216]: "-2.9 vs LA avg"
- generic [ref=f3e217]:
- strong [ref=f3e218]: "148"
- generic [ref=f3e219]: pupils
- generic [ref=f3e221]: Solihull
- generic [ref=f3e222]:
- link "View" [ref=f3e223] [cursor=pointer]:
- /url: /school/104124-solihull-school
- button "+ Compare" [ref=f3e224] [cursor=pointer]
- generic [ref=f3e225]:
- generic [ref=f3e226]:
- generic [ref=f3e227]:
- link "St Peter's Catholic School" [ref=f3e228] [cursor=pointer]:
- /url: /school/148094-st-peters-catholic-school
- generic [ref=f3e229]: Inspected · 2025
- generic [ref=f3e230]:
- generic [ref=f3e231]: Secondary
- generic [ref=f3e232]: Academy converter
- generic [ref=f3e233]: Ages 11–18
- generic [ref=f3e234]: Sixth form
- generic [ref=f3e235]: Selective
- generic [ref=f3e236]:
- generic [ref=f3e237]:
- strong [ref=f3e238]: "53.4"
- generic [ref=f3e239]: Attainment 8
- generic [ref=f3e240]: +9.1 vs LA avg
- generic [ref=f3e241]:
- strong [ref=f3e242]: "204"
- generic [ref=f3e243]: pupils
- generic [ref=f3e245]: Solihull
- generic [ref=f3e246]:
- link "View" [ref=f3e247] [cursor=pointer]:
- /url: /school/148094-st-peters-catholic-school
- button "+ Compare" [ref=f3e248] [cursor=pointer]
- generic [ref=f3e249]:
- generic [ref=f3e250]:
- generic [ref=f3e251]:
- link "Widney Junior School" [ref=f3e252] [cursor=pointer]:
- /url: /school/104054-widney-junior-school
- generic [ref=f3e253]: Good · 2024
- generic [ref=f3e254]:
- generic [ref=f3e255]: Primary
- generic [ref=f3e256]: Community school
- generic [ref=f3e257]: Ages 7–11
- generic [ref=f3e258]:
- generic [ref=f3e259]:
- strong [ref=f3e260]: 80%
- 'generic "Previous year: 78.0%" [ref=f3e261]':
- img "Trend up" [ref=f3e262]
- generic [ref=f3e264]: Reading, Writing & Maths
- generic [ref=f3e265]: +18 pts vs national
- generic [ref=f3e266]:
- strong [ref=f3e267]: "327"
- generic [ref=f3e268]: pupils
- generic [ref=f3e270]: Solihull
- generic [ref=f3e271]:
- link "View" [ref=f3e272] [cursor=pointer]:
- /url: /school/104054-widney-junior-school
- button "+ Compare" [ref=f3e273] [cursor=pointer]
- generic [ref=f3e274]:
- generic [ref=f3e275]:
- generic [ref=f3e276]:
- link "St Alphege Church of England Junior School" [ref=f3e277] [cursor=pointer]:
- /url: /school/104092-st-alphege-church-of-england-junior-school
- generic [ref=f3e278]: Inspected · 2025
- generic [ref=f3e279]:
- generic [ref=f3e280]: Primary
- generic [ref=f3e281]: Voluntary aided school
- generic [ref=f3e282]: Ages 7–11
- generic [ref=f3e283]: Church of England
- generic [ref=f3e284]:
- generic [ref=f3e285]:
- strong [ref=f3e286]: 86%
- 'generic "Previous year: 84.0%" [ref=f3e287]':
- img "Trend up" [ref=f3e288]
- generic [ref=f3e290]: Reading, Writing & Maths
- generic [ref=f3e291]: +24 pts vs national
- generic [ref=f3e292]:
- strong [ref=f3e293]: "257"
- generic [ref=f3e294]: pupils
- generic [ref=f3e296]: Solihull
- generic [ref=f3e297]:
- link "View" [ref=f3e298] [cursor=pointer]:
- /url: /school/104092-st-alphege-church-of-england-junior-school
- button "+ Compare" [ref=f3e299] [cursor=pointer]
- generic [ref=f3e300]:
- generic [ref=f3e301]:
- generic [ref=f3e302]:
- link "St Augustine's Catholic Primary School" [ref=f3e303] [cursor=pointer]:
- /url: /school/148087-st-augustines-catholic-primary-school
- generic [ref=f3e304]: Good · 2023
- generic [ref=f3e305]:
- generic [ref=f3e306]: Primary
- generic [ref=f3e307]: Academy converter
- generic [ref=f3e308]: Ages 3–11
- generic [ref=f3e309]: Roman Catholic
- generic [ref=f3e310]:
- generic [ref=f3e311]:
- strong [ref=f3e312]: 84%
- 'generic "Previous year: 79.0%" [ref=f3e313]':
- img "Trend up" [ref=f3e314]
- generic [ref=f3e316]: Reading, Writing & Maths
- generic [ref=f3e317]: +22 pts vs national
- generic [ref=f3e318]:
- strong [ref=f3e319]: "231"
- generic [ref=f3e320]: pupils
- generic [ref=f3e322]: Solihull
- generic [ref=f3e323]:
- link "View" [ref=f3e324] [cursor=pointer]:
- /url: /school/148087-st-augustines-catholic-primary-school
- button "+ Compare" [ref=f3e325] [cursor=pointer]
- generic [ref=f3e326]:
- generic [ref=f3e327]:
- generic [ref=f3e328]:
- link "St Alphege Church of England Infant and Nursery School" [ref=f3e329] [cursor=pointer]:
- /url: /school/104090-st-alphege-church-of-england-infant-and-nursery-school
- generic [ref=f3e330]: Inspected · 2025
- generic [ref=f3e331]:
- generic [ref=f3e332]: Primary
- generic [ref=f3e333]: Voluntary aided school
- generic [ref=f3e334]: Ages 3–7
- generic [ref=f3e335]: Church of England
- generic [ref=f3e337]:
- strong [ref=f3e338]: —
- generic [ref=f3e339]: Reading, Writing & Maths
- generic [ref=f3e341]: Solihull
- generic [ref=f3e342]:
- link "View" [ref=f3e343] [cursor=pointer]:
- /url: /school/104090-st-alphege-church-of-england-infant-and-nursery-school
- button "+ Compare" [ref=f3e344] [cursor=pointer]
- generic [ref=f3e345]:
- generic [ref=f3e346]:
- generic [ref=f3e347]:
- link "Solihull Sixth Form College" [ref=f3e348] [cursor=pointer]:
- /url: /school/144887-solihull-sixth-form-college
- generic [ref=f3e349]: Not yet inspected
- generic [ref=f3e350]:
- generic [ref=f3e351]: Post-16
- generic [ref=f3e352]: Academy 16-19 converter
- generic [ref=f3e353]: Ages 16–19
- generic [ref=f3e355]:
- strong [ref=f3e356]: —
- generic [ref=f3e357]: Reading, Writing & Maths
- generic [ref=f3e359]: Solihull
- generic [ref=f3e360]:
- link "View" [ref=f3e361] [cursor=pointer]:
- /url: /school/144887-solihull-sixth-form-college
- button "+ Compare" [ref=f3e362] [cursor=pointer]
- contentinfo [ref=f3e136]:
- generic [ref=f3e137]:
- generic [ref=f3e138]:
- generic [ref=f3e139]:
- heading "SchoolCompare" [level=3] [ref=f3e140]
- paragraph [ref=f3e141]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f3e142] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f3e143]:
- heading "Product" [level=4] [ref=f3e144]
- list [ref=f3e145]:
- listitem [ref=f3e146]:
- link "Search schools" [ref=f3e147] [cursor=pointer]:
- /url: /
- listitem [ref=f3e148]:
- link "Rankings" [ref=f3e149] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f3e150]:
- link "Compare shortlist" [ref=f3e151] [cursor=pointer]:
- /url: /compare
- listitem [ref=f3e152]:
- link "Admissions guide" [ref=f3e153] [cursor=pointer]:
- /url: /admissions
- generic [ref=f3e154]:
- heading "Resources" [level=4] [ref=f3e155]
- list [ref=f3e156]:
- listitem [ref=f3e157]:
- link "School Performance Tables" [ref=f3e158] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f3e159]:
- link "Ofsted reports" [ref=f3e160] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f3e162]: © 2026 SchoolCompare.co.uk
- alert [ref=f3e163]
@@ -0,0 +1,229 @@
- generic [active] [ref=f4e1]:
- link "Skip to main content" [ref=f4e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f4e3]:
- generic [ref=f4e4]:
- link "SchoolCompare home" [ref=f4e5] [cursor=pointer]:
- /url: /
- img [ref=f4e7]
- generic [ref=f4e11]: SchoolCompare
- navigation "Main navigation" [ref=f4e12]:
- link "Search" [ref=f4e13] [cursor=pointer]:
- /url: /
- link "Compare" [ref=f4e14] [cursor=pointer]:
- /url: /compare
- link "Rankings" [ref=f4e15] [cursor=pointer]:
- /url: /rankings
- link "Admissions" [ref=f4e16] [cursor=pointer]:
- /url: /admissions
- main [ref=f4e17]:
- generic [ref=f4e18]:
- generic [ref=f4e19]:
- generic [ref=f4e20]: Updated with 2026/2027 admissions results
- heading "Every school in England, compared." [level=1] [ref=f4e22]:
- text: Every school in England,
- emphasis [ref=f4e23]: compared.
- paragraph [ref=f4e24]:
- strong [ref=f4e25]: 24,000+ primary and secondary schools
- text: with Key Stage 2 SATs, GCSE results, Ofsted grades, progress scores and admissions data — side by side, in one place.
- generic [ref=f4e28]:
- searchbox "School name or postcode" [ref=f4e29]
- button "Search" [ref=f4e30] [cursor=pointer]
- button "Schools near me" [ref=f4e33] [cursor=pointer]:
- img [ref=f4e34]
- text: Schools near me
- generic [ref=f4e37]:
- generic [ref=f4e38]:
- generic [ref=f4e39]: Key admissions deadlines
- link "Full admissions guide →" [ref=f4e40] [cursor=pointer]:
- /url: /admissions
- generic [ref=f4e41]:
- generic [ref=f4e42]:
- generic [ref=f4e43]: Secondary · Deadline
- generic [ref=f4e45]: 121days
- generic [ref=f4e46]: Secondary applications close
- generic [ref=f4e47]: Sat, 31 October 2026
- generic [ref=f4e48]:
- generic [ref=f4e49]: Primary · Deadline
- generic [ref=f4e51]: 197days
- generic [ref=f4e52]: Primary applications close
- generic [ref=f4e53]: Fri, 15 January 2027
- generic [ref=f4e54]:
- generic [ref=f4e55]: Secondary · Offer Day
- generic [ref=f4e57]: 242days
- generic [ref=f4e58]: Secondary National Offer Day
- generic [ref=f4e59]: Mon, 1 March 2027
- generic [ref=f4e60]:
- generic [ref=f4e61]: Primary · Offer Day
- generic [ref=f4e63]: 288days
- generic [ref=f4e64]: Primary National Offer Day
- generic [ref=f4e65]: Fri, 16 April 2027
- generic [ref=f4e66]:
- generic [ref=f4e67]: Start exploring
- generic [ref=f4e68]:
- link "Top-rated primary schools" [ref=f4e69] [cursor=pointer]:
- /url: /rankings
- text: Top-rated primary schools
- link "Top-rated secondary schools" [ref=f4e71] [cursor=pointer]:
- /url: /rankings
- text: Top-rated secondary schools
- link "Start a comparison" [ref=f4e73] [cursor=pointer]:
- /url: /compare
- text: Start a comparison
- generic [ref=f4e75]:
- generic [ref=f4e76]:
- heading "What you'll see on every school" [level=2] [ref=f4e77]
- generic [ref=f4e78]: Primary or secondary — the page adapts to the phase
- generic [ref=f4e79]:
- generic [ref=f4e80]:
- generic [ref=f4e81]:
- generic [ref=f4e82]:
- generic [ref=f4e83]:
- text: Primary · Year 6 ·
- strong [ref=f4e84]: Key Stage 2 SATs
- generic [ref=f4e85]:
- generic [ref=f4e86]:
- generic [ref=f4e87]: Reading
- generic [ref=f4e88]:
- generic [ref=f4e89]: Expected
- strong [ref=f4e90]: 96%
- generic [ref=f4e91]:
- generic: 75%
- generic [ref=f4e93]:
- generic [ref=f4e94]: Exceeding
- strong [ref=f4e95]: 73%
- generic [ref=f4e98]:
- generic [ref=f4e99]: Writing
- generic [ref=f4e100]:
- generic [ref=f4e101]: Expected
- strong [ref=f4e102]: 81%
- generic [ref=f4e103]:
- generic: 72%
- generic [ref=f4e105]:
- generic [ref=f4e106]: Exceeding
- strong [ref=f4e107]: 15%
- generic [ref=f4e110]:
- generic [ref=f4e111]: Maths
- generic [ref=f4e112]:
- generic [ref=f4e113]: Expected
- strong [ref=f4e114]: 85%
- generic [ref=f4e115]:
- generic: 74%
- generic [ref=f4e117]:
- generic [ref=f4e118]: Exceeding
- strong [ref=f4e119]: 47%
- generic [ref=f4e122]:
- generic [ref=f4e123]:
- text: Secondary · Year 11 ·
- strong [ref=f4e124]: GCSE Attainment 8
- generic [ref=f4e125]:
- generic [ref=f4e127]:
- generic [ref=f4e128]: This school
- generic [ref=f4e129]: National avg 50.2
- generic [ref=f4e133]:
- generic [ref=f4e134]: "62.4"
- generic [ref=f4e135]: +12.2 vs national
- generic [ref=f4e136]:
- generic [ref=f4e137]: Performance
- generic [ref=f4e138]: Results against the national average
- paragraph [ref=f4e139]: For primary schools, each subject's Expected and Exceeding percentages side by side. For secondary schools, GCSE Attainment 8 with the national benchmark overlaid.
- generic [ref=f4e140]:
- generic [ref=f4e142]:
- generic [ref=f4e145]: Latest Ofsted inspection
- generic [ref=f4e146]: OUTSTANDING
- generic [ref=f4e147]:
- text: Rated
- emphasis [ref=f4e148]: Outstanding
- text: at last inspection.
- generic [ref=f4e149]: Full inspection · March 2024
- generic [ref=f4e150]:
- generic [ref=f4e151]: Judgement
- generic [ref=f4e152]: Ofsted at a glance
- paragraph [ref=f4e153]: Current grade, inspection date, and a plain-English headline — without opening a 40-page report.
- generic [ref=f4e154]:
- generic [ref=f4e156]:
- generic [ref=f4e157]:
- generic [ref=f4e158]: Metric
- generic [ref=f4e159]:
- text: Our Lady
- text: Queen of Heaven
- generic [ref=f4e160]:
- text: St Mary's
- text: Catholic Primary
- generic [ref=f4e161]:
- generic [ref=f4e162]: Reading, Writing & Maths
- generic [ref=f4e163]: 70%
- generic [ref=f4e164]: 64%
- generic [ref=f4e165]:
- generic [ref=f4e166]: Ofsted
- generic [ref=f4e167]: Outstanding
- generic [ref=f4e168]: Good
- generic [ref=f4e169]:
- generic [ref=f4e170]: Reading progress
- generic [ref=f4e171]: "+2.1"
- generic [ref=f4e172]: "+0.4"
- generic [ref=f4e173]: + pin up to 5 schools
- generic [ref=f4e174]:
- generic [ref=f4e175]: Compare
- generic [ref=f4e176]: Side-by-side shortlists
- paragraph [ref=f4e177]: Pin up to five schools and every metric aligns in the same columns — works for primary and secondary alike.
- generic [ref=f4e179]:
- generic [ref=f4e180]:
- generic [ref=f4e181]: About school data
- heading "Making UK school performance data actually readable" [level=2] [ref=f4e182]
- paragraph [ref=f4e183]: School performance data in England is rich but fragmented. The Department for Education publishes Key Stage 2 SATs, GCSE attainment, Ofsted outcomes, progress scores, admissions figures and demographics — each in its own table, each with its own jargon.
- paragraph [ref=f4e184]: SchoolCompare brings it all into one place. Every school page shows performance against the national average, explains what the numbers mean, and lets you shortlist schools side by side. Built for parents, governors, journalists, and anyone who wants to understand a school without reading a 40-page inspection report.
- generic [ref=f4e185]:
- heading "Coverage at a glance" [level=3] [ref=f4e186]
- generic [ref=f4e187]:
- generic [ref=f4e188]: Schools covered
- generic [ref=f4e189]: 24,000+
- generic [ref=f4e190]:
- generic [ref=f4e191]: Local authorities
- generic [ref=f4e192]: "182"
- generic [ref=f4e193]:
- generic [ref=f4e194]: Phases
- generic [ref=f4e195]: Primary & Secondary
- generic [ref=f4e196]:
- generic [ref=f4e197]: Latest results year
- generic [ref=f4e198]: 2024/25
- generic [ref=f4e199]:
- generic [ref=f4e200]: Historical data
- generic [ref=f4e201]: 2016–2025
- generic [ref=f4e202]:
- generic [ref=f4e203]: Metrics per school
- generic [ref=f4e204]: 40+
- contentinfo [ref=f4e205]:
- generic [ref=f4e206]:
- generic [ref=f4e207]:
- generic [ref=f4e208]:
- heading "SchoolCompare" [level=3] [ref=f4e209]
- paragraph [ref=f4e210]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f4e211] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f4e212]:
- heading "Product" [level=4] [ref=f4e213]
- list [ref=f4e214]:
- listitem [ref=f4e215]:
- link "Search schools" [ref=f4e216] [cursor=pointer]:
- /url: /
- listitem [ref=f4e217]:
- link "Rankings" [ref=f4e218] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f4e219]:
- link "Compare shortlist" [ref=f4e220] [cursor=pointer]:
- /url: /compare
- listitem [ref=f4e221]:
- link "Admissions guide" [ref=f4e222] [cursor=pointer]:
- /url: /admissions
- generic [ref=f4e223]:
- heading "Resources" [level=4] [ref=f4e224]
- list [ref=f4e225]:
- listitem [ref=f4e226]:
- link "School Performance Tables" [ref=f4e227] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f4e228]:
- link "Ofsted reports" [ref=f4e229] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f4e231]: © 2026 SchoolCompare.co.uk
- alert [ref=f4e232]
@@ -0,0 +1,101 @@
- generic [ref=f4e1]:
- link "Skip to main content" [ref=f4e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f4e3]:
- generic [ref=f4e4]:
- link "SchoolCompare home" [ref=f4e5] [cursor=pointer]:
- /url: /
- img [ref=f4e7]
- generic [ref=f4e11]: SchoolCompare
- navigation "Main navigation" [ref=f4e12]:
- link "Search" [ref=f4e13] [cursor=pointer]:
- /url: /
- link "Compare" [ref=f4e14] [cursor=pointer]:
- /url: /compare
- link "Rankings" [ref=f4e15] [cursor=pointer]:
- /url: /rankings
- link "Admissions" [ref=f4e16] [cursor=pointer]:
- /url: /admissions
- main [ref=f4e17]:
- generic [ref=f4e18]:
- generic [ref=f4e26]:
- generic [ref=f4e28]:
- searchbox "School name or postcode" [active] [ref=f4e29]: Welland Primary
- button "Search" [ref=f4e30] [cursor=pointer]
- generic [ref=f4e233]:
- combobox [ref=f4e234] [cursor=pointer]:
- option "All Phases" [selected]
- option "Primary"
- button "Advanced" [ref=f4e235] [cursor=pointer]: Advanced
- button "Clear" [ref=f4e237] [cursor=pointer]
- generic [ref=f4e238]:
- generic [ref=f4e239]:
- heading "1 school found" [level=2] [ref=f4e240]
- combobox [ref=f4e242] [cursor=pointer]:
- 'option "Sort: Relevance" [selected]'
- option "Highest Reading, Writing & Maths %"
- option "Lowest Reading, Writing & Maths %"
- option "Name A–Z"
- generic [ref=f4e244]:
- text: "Search: Welland Primary"
- link "×" [ref=f4e245] [cursor=pointer]:
- /url: /
- generic [ref=f4e247]:
- generic [ref=f4e248]:
- generic [ref=f4e249]:
- link "Welland Primary School" [ref=f4e250] [cursor=pointer]:
- /url: /school/146678-welland-primary-school
- generic [ref=f4e251]: Good · 2023
- generic [ref=f4e252]:
- generic [ref=f4e253]: Primary
- generic [ref=f4e254]: Academy converter
- generic [ref=f4e255]: Ages 4–11
- generic [ref=f4e256]:
- generic [ref=f4e257]:
- strong [ref=f4e258]: 74%
- 'generic "Previous year: 76.0%" [ref=f4e259]':
- img "Trend down" [ref=f4e260]
- generic [ref=f4e262]: Reading, Writing & Maths
- generic [ref=f4e263]: +12 pts vs national
- generic [ref=f4e264]:
- strong [ref=f4e265]: "131"
- generic [ref=f4e266]: pupils
- generic [ref=f4e268]: Worcestershire
- generic [ref=f4e269]:
- link "View" [ref=f4e270] [cursor=pointer]:
- /url: /school/146678-welland-primary-school
- button "+ Compare" [ref=f4e271] [cursor=pointer]
- contentinfo [ref=f4e205]:
- generic [ref=f4e206]:
- generic [ref=f4e207]:
- generic [ref=f4e208]:
- heading "SchoolCompare" [level=3] [ref=f4e209]
- paragraph [ref=f4e210]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f4e211] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f4e212]:
- heading "Product" [level=4] [ref=f4e213]
- list [ref=f4e214]:
- listitem [ref=f4e215]:
- link "Search schools" [ref=f4e216] [cursor=pointer]:
- /url: /
- listitem [ref=f4e217]:
- link "Rankings" [ref=f4e218] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f4e219]:
- link "Compare shortlist" [ref=f4e220] [cursor=pointer]:
- /url: /compare
- listitem [ref=f4e221]:
- link "Admissions guide" [ref=f4e222] [cursor=pointer]:
- /url: /admissions
- generic [ref=f4e223]:
- heading "Resources" [level=4] [ref=f4e224]
- list [ref=f4e225]:
- listitem [ref=f4e226]:
- link "School Performance Tables" [ref=f4e227] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f4e228]:
- link "Ofsted reports" [ref=f4e229] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f4e231]: © 2026 SchoolCompare.co.uk
- alert [ref=f4e232]
@@ -0,0 +1,229 @@
- generic [active] [ref=f5e1]:
- link "Skip to main content" [ref=f5e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f5e3]:
- generic [ref=f5e4]:
- link "SchoolCompare home" [ref=f5e5] [cursor=pointer]:
- /url: /
- img [ref=f5e7]
- generic [ref=f5e11]: SchoolCompare
- navigation "Main navigation" [ref=f5e12]:
- link "Search" [ref=f5e13] [cursor=pointer]:
- /url: /
- link "Compare" [ref=f5e14] [cursor=pointer]:
- /url: /compare
- link "Rankings" [ref=f5e15] [cursor=pointer]:
- /url: /rankings
- link "Admissions" [ref=f5e16] [cursor=pointer]:
- /url: /admissions
- main [ref=f5e17]:
- generic [ref=f5e18]:
- generic [ref=f5e19]:
- generic [ref=f5e20]: Updated with 2026/2027 admissions results
- heading "Every school in England, compared." [level=1] [ref=f5e22]:
- text: Every school in England,
- emphasis [ref=f5e23]: compared.
- paragraph [ref=f5e24]:
- strong [ref=f5e25]: 24,000+ primary and secondary schools
- text: with Key Stage 2 SATs, GCSE results, Ofsted grades, progress scores and admissions data — side by side, in one place.
- generic [ref=f5e28]:
- searchbox "School name or postcode" [ref=f5e29]
- button "Search" [ref=f5e30] [cursor=pointer]
- button "Schools near me" [ref=f5e33] [cursor=pointer]:
- img [ref=f5e34]
- text: Schools near me
- generic [ref=f5e37]:
- generic [ref=f5e38]:
- generic [ref=f5e39]: Key admissions deadlines
- link "Full admissions guide →" [ref=f5e40] [cursor=pointer]:
- /url: /admissions
- generic [ref=f5e41]:
- generic [ref=f5e42]:
- generic [ref=f5e43]: Secondary · Deadline
- generic [ref=f5e45]: 121days
- generic [ref=f5e46]: Secondary applications close
- generic [ref=f5e47]: Sat, 31 October 2026
- generic [ref=f5e48]:
- generic [ref=f5e49]: Primary · Deadline
- generic [ref=f5e51]: 197days
- generic [ref=f5e52]: Primary applications close
- generic [ref=f5e53]: Fri, 15 January 2027
- generic [ref=f5e54]:
- generic [ref=f5e55]: Secondary · Offer Day
- generic [ref=f5e57]: 242days
- generic [ref=f5e58]: Secondary National Offer Day
- generic [ref=f5e59]: Mon, 1 March 2027
- generic [ref=f5e60]:
- generic [ref=f5e61]: Primary · Offer Day
- generic [ref=f5e63]: 288days
- generic [ref=f5e64]: Primary National Offer Day
- generic [ref=f5e65]: Fri, 16 April 2027
- generic [ref=f5e66]:
- generic [ref=f5e67]: Start exploring
- generic [ref=f5e68]:
- link "Top-rated primary schools" [ref=f5e69] [cursor=pointer]:
- /url: /rankings
- text: Top-rated primary schools
- link "Top-rated secondary schools" [ref=f5e71] [cursor=pointer]:
- /url: /rankings
- text: Top-rated secondary schools
- link "Start a comparison" [ref=f5e73] [cursor=pointer]:
- /url: /compare
- text: Start a comparison
- generic [ref=f5e75]:
- generic [ref=f5e76]:
- heading "What you'll see on every school" [level=2] [ref=f5e77]
- generic [ref=f5e78]: Primary or secondary — the page adapts to the phase
- generic [ref=f5e79]:
- generic [ref=f5e80]:
- generic [ref=f5e81]:
- generic [ref=f5e82]:
- generic [ref=f5e83]:
- text: Primary · Year 6 ·
- strong [ref=f5e84]: Key Stage 2 SATs
- generic [ref=f5e85]:
- generic [ref=f5e86]:
- generic [ref=f5e87]: Reading
- generic [ref=f5e88]:
- generic [ref=f5e89]: Expected
- strong [ref=f5e90]: 96%
- generic [ref=f5e91]:
- generic: 75%
- generic [ref=f5e93]:
- generic [ref=f5e94]: Exceeding
- strong [ref=f5e95]: 73%
- generic [ref=f5e98]:
- generic [ref=f5e99]: Writing
- generic [ref=f5e100]:
- generic [ref=f5e101]: Expected
- strong [ref=f5e102]: 81%
- generic [ref=f5e103]:
- generic: 72%
- generic [ref=f5e105]:
- generic [ref=f5e106]: Exceeding
- strong [ref=f5e107]: 15%
- generic [ref=f5e110]:
- generic [ref=f5e111]: Maths
- generic [ref=f5e112]:
- generic [ref=f5e113]: Expected
- strong [ref=f5e114]: 85%
- generic [ref=f5e115]:
- generic: 74%
- generic [ref=f5e117]:
- generic [ref=f5e118]: Exceeding
- strong [ref=f5e119]: 47%
- generic [ref=f5e122]:
- generic [ref=f5e123]:
- text: Secondary · Year 11 ·
- strong [ref=f5e124]: GCSE Attainment 8
- generic [ref=f5e125]:
- generic [ref=f5e127]:
- generic [ref=f5e128]: This school
- generic [ref=f5e129]: National avg 50.2
- generic [ref=f5e133]:
- generic [ref=f5e134]: "62.4"
- generic [ref=f5e135]: +12.2 vs national
- generic [ref=f5e136]:
- generic [ref=f5e137]: Performance
- generic [ref=f5e138]: Results against the national average
- paragraph [ref=f5e139]: For primary schools, each subject's Expected and Exceeding percentages side by side. For secondary schools, GCSE Attainment 8 with the national benchmark overlaid.
- generic [ref=f5e140]:
- generic [ref=f5e142]:
- generic [ref=f5e145]: Latest Ofsted inspection
- generic [ref=f5e146]: OUTSTANDING
- generic [ref=f5e147]:
- text: Rated
- emphasis [ref=f5e148]: Outstanding
- text: at last inspection.
- generic [ref=f5e149]: Full inspection · March 2024
- generic [ref=f5e150]:
- generic [ref=f5e151]: Judgement
- generic [ref=f5e152]: Ofsted at a glance
- paragraph [ref=f5e153]: Current grade, inspection date, and a plain-English headline — without opening a 40-page report.
- generic [ref=f5e154]:
- generic [ref=f5e156]:
- generic [ref=f5e157]:
- generic [ref=f5e158]: Metric
- generic [ref=f5e159]:
- text: Our Lady
- text: Queen of Heaven
- generic [ref=f5e160]:
- text: St Mary's
- text: Catholic Primary
- generic [ref=f5e161]:
- generic [ref=f5e162]: Reading, Writing & Maths
- generic [ref=f5e163]: 70%
- generic [ref=f5e164]: 64%
- generic [ref=f5e165]:
- generic [ref=f5e166]: Ofsted
- generic [ref=f5e167]: Outstanding
- generic [ref=f5e168]: Good
- generic [ref=f5e169]:
- generic [ref=f5e170]: Reading progress
- generic [ref=f5e171]: "+2.1"
- generic [ref=f5e172]: "+0.4"
- generic [ref=f5e173]: + pin up to 5 schools
- generic [ref=f5e174]:
- generic [ref=f5e175]: Compare
- generic [ref=f5e176]: Side-by-side shortlists
- paragraph [ref=f5e177]: Pin up to five schools and every metric aligns in the same columns — works for primary and secondary alike.
- generic [ref=f5e179]:
- generic [ref=f5e180]:
- generic [ref=f5e181]: About school data
- heading "Making UK school performance data actually readable" [level=2] [ref=f5e182]
- paragraph [ref=f5e183]: School performance data in England is rich but fragmented. The Department for Education publishes Key Stage 2 SATs, GCSE attainment, Ofsted outcomes, progress scores, admissions figures and demographics — each in its own table, each with its own jargon.
- paragraph [ref=f5e184]: SchoolCompare brings it all into one place. Every school page shows performance against the national average, explains what the numbers mean, and lets you shortlist schools side by side. Built for parents, governors, journalists, and anyone who wants to understand a school without reading a 40-page inspection report.
- generic [ref=f5e185]:
- heading "Coverage at a glance" [level=3] [ref=f5e186]
- generic [ref=f5e187]:
- generic [ref=f5e188]: Schools covered
- generic [ref=f5e189]: 24,000+
- generic [ref=f5e190]:
- generic [ref=f5e191]: Local authorities
- generic [ref=f5e192]: "182"
- generic [ref=f5e193]:
- generic [ref=f5e194]: Phases
- generic [ref=f5e195]: Primary & Secondary
- generic [ref=f5e196]:
- generic [ref=f5e197]: Latest results year
- generic [ref=f5e198]: 2024/25
- generic [ref=f5e199]:
- generic [ref=f5e200]: Historical data
- generic [ref=f5e201]: 2016–2025
- generic [ref=f5e202]:
- generic [ref=f5e203]: Metrics per school
- generic [ref=f5e204]: 40+
- contentinfo [ref=f5e205]:
- generic [ref=f5e206]:
- generic [ref=f5e207]:
- generic [ref=f5e208]:
- heading "SchoolCompare" [level=3] [ref=f5e209]
- paragraph [ref=f5e210]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f5e211] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f5e212]:
- heading "Product" [level=4] [ref=f5e213]
- list [ref=f5e214]:
- listitem [ref=f5e215]:
- link "Search schools" [ref=f5e216] [cursor=pointer]:
- /url: /
- listitem [ref=f5e217]:
- link "Rankings" [ref=f5e218] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f5e219]:
- link "Compare shortlist" [ref=f5e220] [cursor=pointer]:
- /url: /compare
- listitem [ref=f5e221]:
- link "Admissions guide" [ref=f5e222] [cursor=pointer]:
- /url: /admissions
- generic [ref=f5e223]:
- heading "Resources" [level=4] [ref=f5e224]
- list [ref=f5e225]:
- listitem [ref=f5e226]:
- link "School Performance Tables" [ref=f5e227] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f5e228]:
- link "Ofsted reports" [ref=f5e229] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f5e231]: © 2026 SchoolCompare.co.uk
- alert [ref=f5e232]
@@ -0,0 +1,214 @@
- generic [active] [ref=f6e1]:
- link "Skip to main content" [ref=f6e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f6e3]:
- link "SchoolCompare home" [ref=f6e5] [cursor=pointer]:
- /url: /
- img [ref=f6e7]
- generic [ref=f6e11]: SchoolCompare
- navigation "Main navigation" [ref=f6e12]:
- link "Search" [ref=f6e13] [cursor=pointer]:
- /url: /
- img [ref=f6e15]
- generic [ref=f6e18]: Search
- link "Compare" [ref=f6e19] [cursor=pointer]:
- /url: /compare
- img [ref=f6e21]
- generic [ref=f6e24]: Compare
- link "Rankings" [ref=f6e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f6e27]
- generic [ref=f6e28]: Rankings
- link "Admissions" [ref=f6e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f6e31]
- generic [ref=f6e34]: Admissions
- main [ref=f6e35]:
- generic [ref=f6e36]:
- button "Back" [ref=f6e37] [cursor=pointer]:
- generic [ref=f6e38]: ←
- text: Back
- generic [ref=f6e39]:
- generic [ref=f6e40]:
- generic [ref=f6e41]:
- img [ref=f6e45] [cursor=pointer]
- generic [ref=f6e48]:
- link "Leaflet" [ref=f6e49] [cursor=pointer]:
- /url: https://leafletjs.com
- img [ref=f6e50]
- text: Leaflet
- text: "| ©"
- link "OpenStreetMap" [ref=f6e54] [cursor=pointer]:
- /url: https://www.openstreetmap.org/copyright
- text: contributors
- button "Open full map" [ref=f6e55] [cursor=pointer]:
- generic [ref=f6e56]:
- img [ref=f6e57]
- text: Open full map
- generic [ref=f6e59]:
- generic [ref=f6e60]:
- heading "The Castle School" [level=1] [ref=f6e61]
- generic [ref=f6e62]:
- generic [ref=f6e63]: Academy converter
- generic [ref=f6e64]: Ages 11–19
- paragraph [ref=f6e65]:
- text: Wellington Road, Taunton, TA1 5AU ·
- button "View on map ↗" [ref=f6e66] [cursor=pointer]
- generic [ref=f6e67]:
- generic [ref=f6e68]:
- strong [ref=f6e69]: "Headteacher:"
- text: Mr James Lamb
- link "School website ↗" [ref=f6e71] [cursor=pointer]:
- /url: http://www.castleschool.co.uk/
- generic [ref=f6e72]:
- strong [ref=f6e73]: "Pupils:"
- text: "1,202 (capacity: 1188)"
- generic [ref=f6e74]:
- text: Part of
- strong [ref=f6e75]: BLACKDOWN EDUCATION PARTNERSHIP
- button "+ Add to Compare" [ref=f6e77] [cursor=pointer]
- navigation "Page sections" [ref=f6e78]:
- generic [ref=f6e79]:
- button "Back to top" [ref=f6e80] [cursor=pointer]: ↑ Top
- link "Ofsted" [ref=f6e82] [cursor=pointer]:
- /url: "#ofsted"
- link "GCSEs" [ref=f6e83] [cursor=pointer]:
- /url: "#gcse"
- link "Admissions" [ref=f6e84] [cursor=pointer]:
- /url: "#admissions"
- link "History" [ref=f6e85] [cursor=pointer]:
- /url: "#history"
- link "Wellbeing" [ref=f6e86] [cursor=pointer]:
- /url: "#wellbeing"
- generic [ref=f6e87]:
- heading "Ofsted Rating Inspected 3 October 2023 Ofsted reports ↗" [level=2] [ref=f6e88]:
- text: Ofsted Rating
- generic [ref=f6e89]: Inspected 3 October 2023
- link "Ofsted reports ↗" [ref=f6e90] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/inspection-reports/find-inspection-report/provider/ELS/136916
- generic [ref=f6e92]: Outstanding
- paragraph [ref=f6e93]: From September 2024, Ofsted no longer makes an overall effectiveness judgement in inspections.
- paragraph [ref=f6e94]:
- text: Rated
- strong [ref=f6e95]: Outstanding
- text: across all inspected areas — Quality of Teaching, Behaviour, Pupils' Development and Leadership.
- generic [ref=f6e96]:
- heading "GCSE Results (2024/25)" [level=2] [ref=f6e97]
- paragraph [ref=f6e98]: GCSE results for Year 11 pupils. National averages shown for comparison.
- generic [ref=f6e99]: Progress 8 scores for 2024/25 are not used for accountability purposes following the KS2 assessment disruption. Treat with caution.
- generic [ref=f6e100]:
- generic [ref=f6e101]:
- generic [ref=f6e102]: Attainment 8 score
- generic [ref=f6e103]: "53.4"
- generic [ref=f6e104]:
- generic [ref=f6e105]: English & Maths Grade 5+
- generic [ref=f6e106]: 57.7%
- generic [ref=f6e107]:
- generic [ref=f6e108]: English & Maths Grade 4+
- generic [ref=f6e109]: 79.5%
- generic [ref=f6e110]:
- generic [ref=f6e111]: Attainment 8 — school vs national
- generic [ref=f6e114]:
- generic [ref=f6e115]: "0"
- generic [ref=f6e116]: "20"
- generic [ref=f6e117]: "40"
- generic [ref=f6e118]: "60"
- generic [ref=f6e119]: "80"
- heading "English Baccalaureate (EBacc)" [level=3] [ref=f6e120]
- generic [ref=f6e121]:
- generic [ref=f6e122]:
- generic [ref=f6e123]: Pupils entered for EBacc
- generic [ref=f6e124]: 30.1%
- generic [ref=f6e125]:
- generic [ref=f6e126]: EBacc Grade 4+
- generic [ref=f6e127]: 25.1%
- generic [ref=f6e128]:
- generic [ref=f6e129]: EBacc Grade 5+
- generic [ref=f6e130]: 20.5%
- generic [ref=f6e131]:
- generic [ref=f6e132]: EBacc average point score
- generic [ref=f6e133]: "4.72"
- generic [ref=f6e134]:
- heading "Admissions" [level=2] [ref=f6e135]
- generic [ref=f6e136]:
- generic [ref=f6e137]:
- generic [ref=f6e138]: Year 7 places offered
- generic [ref=f6e139]: "237"
- generic [ref=f6e140]:
- generic [ref=f6e141]: Total applications
- generic [ref=f6e142]: "707"
- generic [ref=f6e143]:
- generic [ref=f6e144]: 1st preference applications
- generic [ref=f6e145]: "336"
- generic [ref=f6e146]:
- generic [ref=f6e147]: Families who got their first choice
- generic [ref=f6e148]: 69.6%
- generic [ref=f6e149]: ⚠ Applications exceeded places last year
- paragraph [ref=f6e150]: Historical distance cut-off data is not available for this school. Contact the admissions authority for oversubscription criteria details.
- generic [ref=f6e151]:
- heading "Historical Results" [level=2] [ref=f6e152]
- heading "Results Over Time" [level=3] [ref=f6e153]
- generic [ref=f6e155]:
- generic [ref=f6e156]:
- generic [ref=f6e157]: GCSE results · Year 11
- tablist [ref=f6e158]:
- tab [selected] [ref=f6e159] [cursor=pointer]: Attainment 8
- tab [ref=f6e160] [cursor=pointer]: English & Maths grade 4+
- tab [ref=f6e161] [cursor=pointer]: Progress 8
- img [ref=f6e163]
- group [ref=f6e164]:
- generic "▶ View raw year-by-year data" [ref=f6e165] [cursor=pointer]
- generic [ref=f6e166]:
- heading "Wellbeing & Context" [level=2] [ref=f6e167]
- heading "Special Educational Needs (SEN)" [level=3] [ref=f6e168]
- generic [ref=f6e169]:
- generic [ref=f6e170]:
- generic [ref=f6e171]: SEN support
- generic [ref=f6e172]: 5.4%
- generic [ref=f6e173]: Without an EHCP
- generic [ref=f6e174]:
- generic [ref=f6e175]: Pupils with EHCP
- generic [ref=f6e176]: 3.8%
- generic [ref=f6e177]: Education, Health and Care Plan
- generic [ref=f6e178]:
- generic [ref=f6e179]: Total pupils
- generic [ref=f6e180]: 1,207
- 'img "Gender split: 52% girls, 48% boys" [ref=f6e181]'
- generic [ref=f6e184]:
- generic [ref=f6e185]: 52% girls
- text: ·
- generic [ref=f6e186]: 48% boys
- contentinfo [ref=f6e187]:
- generic [ref=f6e188]:
- generic [ref=f6e189]:
- generic [ref=f6e190]:
- heading "SchoolCompare" [level=3] [ref=f6e191]
- paragraph [ref=f6e192]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f6e193] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f6e194]:
- heading "Product" [level=4] [ref=f6e195]
- list [ref=f6e196]:
- listitem [ref=f6e197]:
- link "Search schools" [ref=f6e198] [cursor=pointer]:
- /url: /
- listitem [ref=f6e199]:
- link "Rankings" [ref=f6e200] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f6e201]:
- link "Compare shortlist" [ref=f6e202] [cursor=pointer]:
- /url: /compare
- listitem [ref=f6e203]:
- link "Admissions guide" [ref=f6e204] [cursor=pointer]:
- /url: /admissions
- generic [ref=f6e205]:
- heading "Resources" [level=4] [ref=f6e206]
- list [ref=f6e207]:
- listitem [ref=f6e208]:
- link "School Performance Tables" [ref=f6e209] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f6e210]:
- link "Ofsted reports" [ref=f6e211] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f6e213]: © 2026 SchoolCompare.co.uk
- alert [ref=f6e214]
@@ -0,0 +1,226 @@
- generic [ref=f6e1]:
- link "Skip to main content" [ref=f6e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f6e3]:
- link "SchoolCompare home" [ref=f6e5] [cursor=pointer]:
- /url: /
- img [ref=f6e7]
- generic [ref=f6e11]: SchoolCompare
- navigation "Main navigation" [ref=f6e12]:
- link "Search" [ref=f6e13] [cursor=pointer]:
- /url: /
- img [ref=f6e15]
- generic [ref=f6e18]: Search
- link "1 selected Compare" [ref=f6e227] [cursor=pointer]:
- /url: /compare
- generic [ref=f6e20]:
- img [ref=f6e21]
- generic "1 selected" [ref=f6e228]: "1"
- generic [ref=f6e24]: Compare
- link "Rankings" [ref=f6e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f6e27]
- generic [ref=f6e28]: Rankings
- link "Admissions" [ref=f6e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f6e31]
- generic [ref=f6e34]: Admissions
- main [ref=f6e35]:
- generic [ref=f6e36]:
- button "Back" [ref=f6e37] [cursor=pointer]:
- generic [ref=f6e38]: ←
- text: Back
- generic [ref=f6e39]:
- generic [ref=f6e40]:
- generic [ref=f6e41]:
- img [ref=f6e45] [cursor=pointer]
- generic [ref=f6e48]:
- link "Leaflet" [ref=f6e49] [cursor=pointer]:
- /url: https://leafletjs.com
- img [ref=f6e50]
- text: Leaflet
- text: "| ©"
- link "OpenStreetMap" [ref=f6e54] [cursor=pointer]:
- /url: https://www.openstreetmap.org/copyright
- text: contributors
- button "Open full map" [ref=f6e55] [cursor=pointer]:
- generic [ref=f6e56]:
- img [ref=f6e57]
- text: Open full map
- generic [ref=f6e59]:
- generic [ref=f6e60]:
- heading "The Castle School" [level=1] [ref=f6e61]
- generic [ref=f6e62]:
- generic [ref=f6e63]: Academy converter
- generic [ref=f6e64]: Ages 11–19
- paragraph [ref=f6e65]:
- text: Wellington Road, Taunton, TA1 5AU ·
- button "View on map ↗" [ref=f6e66] [cursor=pointer]
- generic [ref=f6e67]:
- generic [ref=f6e68]:
- strong [ref=f6e69]: "Headteacher:"
- text: Mr James Lamb
- link "School website ↗" [ref=f6e71] [cursor=pointer]:
- /url: http://www.castleschool.co.uk/
- generic [ref=f6e72]:
- strong [ref=f6e73]: "Pupils:"
- text: "1,202 (capacity: 1188)"
- generic [ref=f6e74]:
- text: Part of
- strong [ref=f6e75]: BLACKDOWN EDUCATION PARTNERSHIP
- button "✓ In Comparison" [active] [ref=f6e229] [cursor=pointer]
- navigation "Page sections" [ref=f6e78]:
- generic [ref=f6e79]:
- button "Back to top" [ref=f6e80] [cursor=pointer]: ↑ Top
- link "Ofsted" [ref=f6e82] [cursor=pointer]:
- /url: "#ofsted"
- link "GCSEs" [ref=f6e83] [cursor=pointer]:
- /url: "#gcse"
- link "Admissions" [ref=f6e84] [cursor=pointer]:
- /url: "#admissions"
- link "History" [ref=f6e85] [cursor=pointer]:
- /url: "#history"
- link "Wellbeing" [ref=f6e86] [cursor=pointer]:
- /url: "#wellbeing"
- generic [ref=f6e87]:
- heading "Ofsted Rating Inspected 3 October 2023 Ofsted reports ↗" [level=2] [ref=f6e88]:
- text: Ofsted Rating
- generic [ref=f6e89]: Inspected 3 October 2023
- link "Ofsted reports ↗" [ref=f6e90] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/inspection-reports/find-inspection-report/provider/ELS/136916
- generic [ref=f6e92]: Outstanding
- paragraph [ref=f6e93]: From September 2024, Ofsted no longer makes an overall effectiveness judgement in inspections.
- paragraph [ref=f6e94]:
- text: Rated
- strong [ref=f6e95]: Outstanding
- text: across all inspected areas — Quality of Teaching, Behaviour, Pupils' Development and Leadership.
- generic [ref=f6e96]:
- heading "GCSE Results (2024/25)" [level=2] [ref=f6e97]
- paragraph [ref=f6e98]: GCSE results for Year 11 pupils. National averages shown for comparison.
- generic [ref=f6e99]: Progress 8 scores for 2024/25 are not used for accountability purposes following the KS2 assessment disruption. Treat with caution.
- generic [ref=f6e100]:
- generic [ref=f6e101]:
- generic [ref=f6e102]: Attainment 8 score
- generic [ref=f6e103]:
- text: "53.4"
- generic [ref=f6e215]: +14 pts
- generic [ref=f6e216]: "National avg: 39.1"
- generic [ref=f6e104]:
- generic [ref=f6e105]: English & Maths Grade 5+
- generic [ref=f6e106]:
- text: 57.7%
- generic [ref=f6e217]: +22 pts
- generic [ref=f6e218]: "National avg: 36%"
- generic [ref=f6e107]:
- generic [ref=f6e108]: English & Maths Grade 4+
- generic [ref=f6e109]:
- text: 79.5%
- generic [ref=f6e219]: +28 pts
- generic [ref=f6e220]: "National avg: 51%"
- generic [ref=f6e110]:
- generic [ref=f6e111]: Attainment 8 — school vs national
- generic [ref=f6e222]: Nat avg 39.1
- generic [ref=f6e114]:
- generic [ref=f6e115]: "0"
- generic [ref=f6e116]: "20"
- generic [ref=f6e117]: "40"
- generic [ref=f6e118]: "60"
- generic [ref=f6e119]: "80"
- heading "English Baccalaureate (EBacc)" [level=3] [ref=f6e120]
- generic [ref=f6e121]:
- generic [ref=f6e122]:
- generic [ref=f6e123]: Pupils entered for EBacc
- generic [ref=f6e124]: 30.1%
- generic [ref=f6e125]:
- generic [ref=f6e126]: EBacc Grade 4+
- generic [ref=f6e127]: 25.1%
- generic [ref=f6e128]:
- generic [ref=f6e129]: EBacc Grade 5+
- generic [ref=f6e130]: 20.5%
- generic [ref=f6e131]:
- generic [ref=f6e132]: EBacc average point score
- generic [ref=f6e133]: "4.72"
- generic [ref=f6e134]:
- heading "Admissions" [level=2] [ref=f6e135]
- generic [ref=f6e136]:
- generic [ref=f6e137]:
- generic [ref=f6e138]: Year 7 places offered
- generic [ref=f6e139]: "237"
- generic [ref=f6e140]:
- generic [ref=f6e141]: Total applications
- generic [ref=f6e142]: "707"
- generic [ref=f6e143]:
- generic [ref=f6e144]: 1st preference applications
- generic [ref=f6e145]: "336"
- generic [ref=f6e146]:
- generic [ref=f6e147]: Families who got their first choice
- generic [ref=f6e148]: 69.6%
- generic [ref=f6e149]: ⚠ Applications exceeded places last year
- paragraph [ref=f6e150]: Historical distance cut-off data is not available for this school. Contact the admissions authority for oversubscription criteria details.
- generic [ref=f6e151]:
- heading "Historical Results" [level=2] [ref=f6e152]
- heading "Results Over Time" [level=3] [ref=f6e153]
- generic [ref=f6e155]:
- generic [ref=f6e156]:
- generic [ref=f6e157]: GCSE results · Year 11
- tablist "Select metric" [ref=f6e223]:
- tab "Attainment 8" [selected] [ref=f6e224] [cursor=pointer]
- tab "English & Maths grade 4+" [ref=f6e225] [cursor=pointer]
- tab "Progress 8" [ref=f6e226] [cursor=pointer]
- img [ref=f6e163]
- group [ref=f6e164]:
- generic "▶ View raw year-by-year data" [ref=f6e165] [cursor=pointer]
- generic [ref=f6e166]:
- heading "Wellbeing & Context" [level=2] [ref=f6e167]
- heading "Special Educational Needs (SEN)" [level=3] [ref=f6e168]
- generic [ref=f6e169]:
- generic [ref=f6e170]:
- generic [ref=f6e171]: SEN support
- generic [ref=f6e172]: 5.4%
- generic [ref=f6e173]: Without an EHCP
- generic [ref=f6e174]:
- generic [ref=f6e175]: Pupils with EHCP
- generic [ref=f6e176]: 3.8%
- generic [ref=f6e177]: Education, Health and Care Plan
- generic [ref=f6e178]:
- generic [ref=f6e179]: Total pupils
- generic [ref=f6e180]: 1,207
- 'img "Gender split: 52% girls, 48% boys" [ref=f6e181]'
- generic [ref=f6e184]:
- generic [ref=f6e185]: 52% girls
- text: ·
- generic [ref=f6e186]: 48% boys
- contentinfo [ref=f6e187]:
- generic [ref=f6e188]:
- generic [ref=f6e189]:
- generic [ref=f6e190]:
- heading "SchoolCompare" [level=3] [ref=f6e191]
- paragraph [ref=f6e192]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f6e193] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f6e194]:
- heading "Product" [level=4] [ref=f6e195]
- list [ref=f6e196]:
- listitem [ref=f6e197]:
- link "Search schools" [ref=f6e198] [cursor=pointer]:
- /url: /
- listitem [ref=f6e199]:
- link "Rankings" [ref=f6e200] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f6e201]:
- link "Compare shortlist" [ref=f6e202] [cursor=pointer]:
- /url: /compare
- listitem [ref=f6e203]:
- link "Admissions guide" [ref=f6e204] [cursor=pointer]:
- /url: /admissions
- generic [ref=f6e205]:
- heading "Resources" [level=4] [ref=f6e206]
- list [ref=f6e207]:
- listitem [ref=f6e208]:
- link "School Performance Tables" [ref=f6e209] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f6e210]:
- link "Ofsted reports" [ref=f6e211] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f6e213]: © 2026 SchoolCompare.co.uk
- alert [ref=f6e214]
@@ -0,0 +1,120 @@
- generic [active] [ref=f7e1]:
- link "Skip to main content" [ref=f7e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f7e3]:
- link "SchoolCompare home" [ref=f7e5] [cursor=pointer]:
- /url: /
- img [ref=f7e7]
- generic [ref=f7e11]: SchoolCompare
- navigation "Main navigation" [ref=f7e12]:
- link "Search" [ref=f7e13] [cursor=pointer]:
- /url: /
- img [ref=f7e15]
- generic [ref=f7e18]: Search
- link "1 selected Compare" [ref=f7e19] [cursor=pointer]:
- /url: /compare
- generic [ref=f7e20]:
- img [ref=f7e21]
- generic "1 selected" [ref=f7e24]: "1"
- generic [ref=f7e25]: Compare
- link "Rankings" [ref=f7e26] [cursor=pointer]:
- /url: /rankings
- img [ref=f7e28]
- generic [ref=f7e29]: Rankings
- link "Admissions" [ref=f7e30] [cursor=pointer]:
- /url: /admissions
- img [ref=f7e32]
- generic [ref=f7e35]: Admissions
- main [ref=f7e36]:
- generic [ref=f7e37]:
- generic [ref=f7e39]:
- generic [ref=f7e40]:
- heading "Compare Schools" [level=1] [ref=f7e41]
- paragraph [ref=f7e42]: Comparing 1 school
- generic [ref=f7e43]:
- button "+ Add School" [ref=f7e44] [cursor=pointer]
- button "Share" [ref=f7e45] [cursor=pointer]:
- img [ref=f7e46]
- text: Share
- generic [ref=f7e49]:
- button "Primary (1)" [ref=f7e50] [cursor=pointer]
- button "Secondary (0)" [ref=f7e51] [cursor=pointer]
- generic [ref=f7e52]:
- generic [ref=f7e53]: "Select Metric:"
- combobox "Select Metric:" [ref=f7e54] [cursor=pointer]:
- option "Reading, Writing & Maths Combined %" [selected]
- option "Reading Expected %"
- option "Writing Expected %"
- option "Maths Expected %"
- option "GPS Expected %"
- option "Science Expected %"
- option "Reading, Writing & Maths Combined Higher %"
- option "Reading Higher %"
- option "Writing Higher %"
- option "Maths Higher %"
- option "GPS Higher %"
- option "Reading Progress"
- option "Writing Progress"
- option "Maths Progress"
- option "Reading Average Score"
- option "Maths Average Score"
- option "GPS Average Score"
- option "Reading, Writing & Maths Expected % (Boys)"
- option "Reading, Writing & Maths Expected % (Girls)"
- option "Reading, Writing & Maths Higher % (Boys)"
- option "Reading, Writing & Maths Higher % (Girls)"
- option "Reading, Writing & Maths Expected % (Disadvantaged)"
- option "Reading, Writing & Maths Expected % (Non-Disadvantaged)"
- option "Disadvantaged Gap"
- option "% Disadvantaged Pupils"
- option "% EAL Pupils"
- option "% SEN Support"
- option "% Pupil Stability"
- option "Reading Test Absence %"
- option "GPS Test Absence %"
- option "Maths Test Absence %"
- option "Writing Absence %"
- option "Science Absence %"
- paragraph [ref=f7e55]: "% meeting expected standard in reading, writing and maths"
- generic [ref=f7e58]:
- button "Remove The Castle School" [ref=f7e59] [cursor=pointer]: ×
- heading "The Castle School" [level=2] [ref=f7e60]:
- link "The Castle School" [ref=f7e61] [cursor=pointer]:
- /url: /school/136916-the-castle-school
- generic [ref=f7e62]:
- generic [ref=f7e63]: Somerset
- generic [ref=f7e64]: Academy converter
- contentinfo [ref=f7e76]:
- generic [ref=f7e77]:
- generic [ref=f7e78]:
- generic [ref=f7e79]:
- heading "SchoolCompare" [level=3] [ref=f7e80]
- paragraph [ref=f7e81]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f7e82] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f7e83]:
- heading "Product" [level=4] [ref=f7e84]
- list [ref=f7e85]:
- listitem [ref=f7e86]:
- link "Search schools" [ref=f7e87] [cursor=pointer]:
- /url: /
- listitem [ref=f7e88]:
- link "Rankings" [ref=f7e89] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f7e90]:
- link "Compare shortlist" [ref=f7e91] [cursor=pointer]:
- /url: /compare
- listitem [ref=f7e92]:
- link "Admissions guide" [ref=f7e93] [cursor=pointer]:
- /url: /admissions
- generic [ref=f7e94]:
- heading "Resources" [level=4] [ref=f7e95]
- list [ref=f7e96]:
- listitem [ref=f7e97]:
- link "School Performance Tables" [ref=f7e98] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f7e99]:
- link "Ofsted reports" [ref=f7e100] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f7e102]: © 2026 SchoolCompare.co.uk
- alert [ref=f7e103]
@@ -0,0 +1,270 @@
- generic [active] [ref=f8e1]:
- link "Skip to main content" [ref=f8e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f8e3]:
- link "SchoolCompare home" [ref=f8e5] [cursor=pointer]:
- /url: /
- img [ref=f8e7]
- generic [ref=f8e11]: SchoolCompare
- navigation "Main navigation" [ref=f8e12]:
- link "Search" [ref=f8e13] [cursor=pointer]:
- /url: /
- img [ref=f8e15]
- generic [ref=f8e18]: Search
- link "1 selected Compare" [ref=f8e19] [cursor=pointer]:
- /url: /compare
- generic [ref=f8e20]:
- img [ref=f8e21]
- generic "1 selected" [ref=f8e24]: "1"
- generic [ref=f8e25]: Compare
- link "Rankings" [ref=f8e26] [cursor=pointer]:
- /url: /rankings
- img [ref=f8e28]
- generic [ref=f8e29]: Rankings
- link "Admissions" [ref=f8e30] [cursor=pointer]:
- /url: /admissions
- img [ref=f8e32]
- generic [ref=f8e35]: Admissions
- main [ref=f8e36]:
- generic [ref=f8e37]:
- button "Back" [ref=f8e38] [cursor=pointer]:
- generic [ref=f8e39]: ←
- text: Back
- generic [ref=f8e40]:
- generic [ref=f8e41]:
- generic [ref=f8e42]:
- img [ref=f8e46] [cursor=pointer]
- generic [ref=f8e49]:
- link "Leaflet" [ref=f8e50] [cursor=pointer]:
- /url: https://leafletjs.com
- img [ref=f8e51]
- text: Leaflet
- text: "| ©"
- link "OpenStreetMap" [ref=f8e55] [cursor=pointer]:
- /url: https://www.openstreetmap.org/copyright
- text: contributors
- button "Open full map" [ref=f8e56] [cursor=pointer]:
- generic [ref=f8e57]:
- img [ref=f8e58]
- text: Open full map
- generic [ref=f8e60]:
- generic [ref=f8e61]:
- heading "Welland Primary School" [level=1] [ref=f8e62]
- generic [ref=f8e63]:
- generic [ref=f8e64]: Worcestershire
- generic [ref=f8e65]: Academy converter
- paragraph [ref=f8e66]:
- text: Marlbank Road, Welland, Malvern, WR13 6NE ·
- button "View on map ↗" [ref=f8e67] [cursor=pointer]
- button "+ Add to Compare" [ref=f8e69] [cursor=pointer]
- navigation "Page sections" [ref=f8e70]:
- button "Back to top" [ref=f8e71] [cursor=pointer]:
- generic [ref=f8e72]: ↑
- button "Section Ofsted" [ref=f8e73] [cursor=pointer]:
- generic [ref=f8e74]:
- generic [ref=f8e75]: Section
- generic [ref=f8e76]: Ofsted
- generic [ref=f8e77]: ▾
- generic [ref=f8e78]:
- heading "Ofsted Rating Inspected 6 June 2023 Ofsted reports ↗" [level=2] [ref=f8e79]:
- text: Ofsted Rating
- generic [ref=f8e80]: Inspected 6 June 2023
- link "Ofsted reports ↗" [ref=f8e81] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/inspection-reports/find-inspection-report/provider/ELS/146678
- generic [ref=f8e83]: Good
- paragraph [ref=f8e84]: From September 2024, Ofsted no longer makes an overall effectiveness judgement in inspections of state-funded schools.
- paragraph [ref=f8e85]:
- text: Rated
- strong [ref=f8e86]: Good
- text: across all inspected areas — Quality of Teaching, Behaviour, Pupils' Development and Leadership.
- generic [ref=f8e87]:
- heading "SATs Results (2024/25)" [level=2] [ref=f8e88]
- paragraph [ref=f8e89]: End-of-primary-school tests taken by Year 6 pupils. National averages shown for comparison.
- generic [ref=f8e90]:
- generic [ref=f8e91]:
- generic [ref=f8e92]: Reading, Writing & Maths combined
- generic [ref=f8e93]:
- text: 74.0%
- generic [ref=f8e94]: +12 pts
- generic [ref=f8e95]: "National avg: 62%"
- generic [ref=f8e96]:
- generic [ref=f8e97]: Exceeding expected level (Reading, Writing & Maths)
- generic [ref=f8e98]:
- text: 11.0%
- generic [ref=f8e99]: +3 pts
- generic [ref=f8e100]: "National avg: 8%"
- generic [ref=f8e101]:
- generic [ref=f8e102]: "?"
- generic [ref=f8e103]:
- generic [ref=f8e104]:
- text: Why is combined lower? A pupil is only counted if they met the bar in
- strong [ref=f8e105]: all three
- text: subjects. Some passed reading but not writing; some passed writing but not maths.
- generic [ref=f8e106]:
- generic [ref=f8e107]:
- text: Reading
- strong [ref=f8e108]: 74%
- generic [ref=f8e109]: ·
- generic [ref=f8e110]:
- text: Writing
- strong [ref=f8e111]: 74%
- generic [ref=f8e112]: ·
- generic [ref=f8e113]:
- text: Maths
- strong [ref=f8e114]: 81%
- generic [ref=f8e115]: →
- generic [ref=f8e116]:
- text: All three
- strong [ref=f8e117]: 74%
- generic [ref=f8e118]:
- generic [ref=f8e119]:
- generic [ref=f8e120]:
- generic [ref=f8e121]: Reading
- generic [ref=f8e122]:
- generic:
- generic: 75%
- generic [ref=f8e123]:
- generic [ref=f8e125]:
- generic [ref=f8e126]: Expected
- generic [ref=f8e127]: 74%
- generic [ref=f8e131]:
- generic [ref=f8e132]: Exceeding
- generic [ref=f8e133]: 48%
- generic [ref=f8e136]:
- generic [ref=f8e138]: 0%
- generic [ref=f8e140]: 25%
- generic [ref=f8e142]: 50%
- generic [ref=f8e144]: 75%
- generic [ref=f8e146]: 100%
- generic [ref=f8e147]:
- generic [ref=f8e148]: Writing
- generic [ref=f8e149]:
- generic:
- generic: 72%
- generic [ref=f8e150]:
- generic [ref=f8e152]:
- generic [ref=f8e153]: Expected
- generic [ref=f8e154]: 74%
- generic [ref=f8e158]:
- generic [ref=f8e159]: Exceeding
- generic [ref=f8e160]: 11%
- generic [ref=f8e163]:
- generic [ref=f8e165]: 0%
- generic [ref=f8e167]: 25%
- generic [ref=f8e169]: 50%
- generic [ref=f8e171]: 75%
- generic [ref=f8e173]: 100%
- generic [ref=f8e174]:
- generic [ref=f8e175]: Maths
- generic [ref=f8e176]:
- generic:
- generic: 74%
- generic [ref=f8e177]:
- generic [ref=f8e179]:
- generic [ref=f8e180]: Expected
- generic [ref=f8e181]: 81%
- generic [ref=f8e185]:
- generic [ref=f8e186]: Exceeding
- generic [ref=f8e187]: 33%
- generic [ref=f8e190]:
- generic [ref=f8e192]: 0%
- generic [ref=f8e194]: 25%
- generic [ref=f8e196]: 50%
- generic [ref=f8e198]: 75%
- generic [ref=f8e200]: 100%
- generic [ref=f8e201]:
- generic [ref=f8e202]: Expected standard
- generic [ref=f8e204]: Exceeding / high score
- generic [ref=f8e206]: National average
- generic [ref=f8e208]:
- generic [ref=f8e209]:
- heading "Admissions" [level=2] [ref=f8e210]
- group "Admissions view" [ref=f8e211]:
- button "This year" [pressed] [ref=f8e212] [cursor=pointer]
- button "8-year trend" [ref=f8e213] [cursor=pointer]
- generic [ref=f8e216]:
- generic [ref=f8e217]:
- definition [ref=f8e218]: "21"
- term [ref=f8e219]: Places offered
- generic [ref=f8e220]:
- definition [ref=f8e221]: "19"
- term [ref=f8e222]: Wanted it first
- generic [ref=f8e223]:
- definition [ref=f8e224]:
- text: "19"
- generic [ref=f8e225]: of 19 · 100.0%
- term [ref=f8e226]: Got their first choice
- generic [ref=f8e227]:
- definition [ref=f8e228]: "45"
- term [ref=f8e229]: Applied in total
- generic [ref=f8e230]:
- heading "Pupils & Inclusion" [level=2] [ref=f8e231]
- generic [ref=f8e232]:
- generic [ref=f8e233]:
- generic [ref=f8e234]: Eligible for pupil premium
- generic [ref=f8e235]: 26.0%
- generic [ref=f8e236]: Pupils from disadvantaged backgrounds
- generic [ref=f8e237]:
- generic [ref=f8e238]: English as an additional language
- generic [ref=f8e239]: 0.0%
- generic [ref=f8e240]:
- generic [ref=f8e241]: Pupils receiving SEN support
- generic [ref=f8e242]: 4.0%
- generic [ref=f8e243]:
- generic [ref=f8e244]: Boys and girls
- generic [ref=f8e245]:
- generic [ref=f8e246]: 48%
- generic [ref=f8e247]: girls
- generic [ref=f8e248]: ·
- generic [ref=f8e249]: 52%
- generic [ref=f8e250]: boys
- 'img "Gender split: 48% girls, 52% boys" [ref=f8e251]'
- generic [ref=f8e254]: 64 girls, 70 boys
- generic [ref=f8e255]:
- heading "Results Over Time" [level=2] [ref=f8e256]
- generic [ref=f8e258]:
- generic [ref=f8e259]: ↓ Reading, Writing & Maths peaked at 81% (2022/23), currently 74%
- generic [ref=f8e260]:
- generic [ref=f8e261]: KS2 SATs · Reading, Writing & Maths
- tablist "Select metric" [ref=f8e262]:
- tab "At expected level" [selected] [ref=f8e263] [cursor=pointer]
- tab "Above expected level" [ref=f8e264] [cursor=pointer]
- tab "Pupil progress" [ref=f8e265] [cursor=pointer]
- img [ref=f8e267]
- paragraph [ref=f8e268]: "* No data for 2019/20 or 2020/21 — national assessments were cancelled due to COVID-19."
- group [ref=f8e269]:
- generic "▸ View raw year-by-year data" [ref=f8e270] [cursor=pointer]
- contentinfo [ref=f8e271]:
- generic [ref=f8e272]:
- generic [ref=f8e273]:
- generic [ref=f8e274]:
- heading "SchoolCompare" [level=3] [ref=f8e275]
- paragraph [ref=f8e276]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f8e277] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f8e278]:
- heading "Product" [level=4] [ref=f8e279]
- list [ref=f8e280]:
- listitem [ref=f8e281]:
- link "Search schools" [ref=f8e282] [cursor=pointer]:
- /url: /
- listitem [ref=f8e283]:
- link "Rankings" [ref=f8e284] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f8e285]:
- link "Compare shortlist" [ref=f8e286] [cursor=pointer]:
- /url: /compare
- listitem [ref=f8e287]:
- link "Admissions guide" [ref=f8e288] [cursor=pointer]:
- /url: /admissions
- generic [ref=f8e289]:
- heading "Resources" [level=4] [ref=f8e290]
- list [ref=f8e291]:
- listitem [ref=f8e292]:
- link "School Performance Tables" [ref=f8e293] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f8e294]:
- link "Ofsted reports" [ref=f8e295] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f8e297]: © 2026 SchoolCompare.co.uk
- alert [ref=f8e298]
@@ -0,0 +1,226 @@
- generic [active] [ref=f9e1]:
- link "Skip to main content" [ref=f9e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f9e3]:
- link "SchoolCompare home" [ref=f9e5] [cursor=pointer]:
- /url: /
- img [ref=f9e7]
- generic [ref=f9e11]: SchoolCompare
- navigation "Main navigation" [ref=f9e12]:
- link "Search" [ref=f9e13] [cursor=pointer]:
- /url: /
- img [ref=f9e15]
- generic [ref=f9e18]: Search
- link "1 selected Compare" [ref=f9e19] [cursor=pointer]:
- /url: /compare
- generic [ref=f9e20]:
- img [ref=f9e21]
- generic "1 selected" [ref=f9e24]: "1"
- generic [ref=f9e25]: Compare
- link "Rankings" [ref=f9e26] [cursor=pointer]:
- /url: /rankings
- img [ref=f9e28]
- generic [ref=f9e29]: Rankings
- link "Admissions" [ref=f9e30] [cursor=pointer]:
- /url: /admissions
- img [ref=f9e32]
- generic [ref=f9e35]: Admissions
- main [ref=f9e36]:
- generic [ref=f9e37]:
- button "Back" [ref=f9e38] [cursor=pointer]:
- generic [ref=f9e39]: ←
- text: Back
- generic [ref=f9e40]:
- generic [ref=f9e41]:
- generic [ref=f9e42]:
- img [ref=f9e46] [cursor=pointer]
- generic [ref=f9e49]:
- link "Leaflet" [ref=f9e50] [cursor=pointer]:
- /url: https://leafletjs.com
- img [ref=f9e51]
- text: Leaflet
- text: "| ©"
- link "OpenStreetMap" [ref=f9e55] [cursor=pointer]:
- /url: https://www.openstreetmap.org/copyright
- text: contributors
- button "Open full map" [ref=f9e56] [cursor=pointer]:
- generic [ref=f9e57]:
- img [ref=f9e58]
- text: Open full map
- generic [ref=f9e60]:
- generic [ref=f9e61]:
- heading "The Castle School" [level=1] [ref=f9e62]
- generic [ref=f9e63]:
- generic [ref=f9e64]: Academy converter
- generic [ref=f9e65]: Ages 11–19
- paragraph [ref=f9e66]:
- text: Wellington Road, Taunton, TA1 5AU ·
- button "View on map ↗" [ref=f9e67] [cursor=pointer]
- generic [ref=f9e68]:
- generic [ref=f9e69]:
- strong [ref=f9e70]: "Headteacher:"
- text: Mr James Lamb
- link "School website ↗" [ref=f9e72] [cursor=pointer]:
- /url: http://www.castleschool.co.uk/
- generic [ref=f9e73]:
- strong [ref=f9e74]: "Pupils:"
- text: "1,202 (capacity: 1188)"
- generic [ref=f9e75]:
- text: Part of
- strong [ref=f9e76]: BLACKDOWN EDUCATION PARTNERSHIP
- button "✓ In Comparison" [ref=f9e78] [cursor=pointer]
- navigation "Page sections" [ref=f9e79]:
- generic [ref=f9e80]:
- button "Back to top" [ref=f9e81] [cursor=pointer]: ↑ Top
- link "Ofsted" [ref=f9e83] [cursor=pointer]:
- /url: "#ofsted"
- link "GCSEs" [ref=f9e84] [cursor=pointer]:
- /url: "#gcse"
- link "Admissions" [ref=f9e85] [cursor=pointer]:
- /url: "#admissions"
- link "History" [ref=f9e86] [cursor=pointer]:
- /url: "#history"
- link "Wellbeing" [ref=f9e87] [cursor=pointer]:
- /url: "#wellbeing"
- generic [ref=f9e88]:
- heading "Ofsted Rating Inspected 3 October 2023 Ofsted reports ↗" [level=2] [ref=f9e89]:
- text: Ofsted Rating
- generic [ref=f9e90]: Inspected 3 October 2023
- link "Ofsted reports ↗" [ref=f9e91] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/inspection-reports/find-inspection-report/provider/ELS/136916
- generic [ref=f9e93]: Outstanding
- paragraph [ref=f9e94]: From September 2024, Ofsted no longer makes an overall effectiveness judgement in inspections.
- paragraph [ref=f9e95]:
- text: Rated
- strong [ref=f9e96]: Outstanding
- text: across all inspected areas — Quality of Teaching, Behaviour, Pupils' Development and Leadership.
- generic [ref=f9e97]:
- heading "GCSE Results (2024/25)" [level=2] [ref=f9e98]
- paragraph [ref=f9e99]: GCSE results for Year 11 pupils. National averages shown for comparison.
- generic [ref=f9e100]: Progress 8 scores for 2024/25 are not used for accountability purposes following the KS2 assessment disruption. Treat with caution.
- generic [ref=f9e101]:
- generic [ref=f9e102]:
- generic [ref=f9e103]: Attainment 8 score
- generic [ref=f9e104]:
- text: "53.4"
- generic [ref=f9e105]: +14 pts
- generic [ref=f9e106]: "National avg: 39.1"
- generic [ref=f9e107]:
- generic [ref=f9e108]: English & Maths Grade 5+
- generic [ref=f9e109]:
- text: 57.7%
- generic [ref=f9e110]: +22 pts
- generic [ref=f9e111]: "National avg: 36%"
- generic [ref=f9e112]:
- generic [ref=f9e113]: English & Maths Grade 4+
- generic [ref=f9e114]:
- text: 79.5%
- generic [ref=f9e115]: +28 pts
- generic [ref=f9e116]: "National avg: 51%"
- generic [ref=f9e117]:
- generic [ref=f9e118]: Attainment 8 — school vs national
- generic [ref=f9e122]: Nat avg 39.1
- generic [ref=f9e123]:
- generic [ref=f9e124]: "0"
- generic [ref=f9e125]: "20"
- generic [ref=f9e126]: "40"
- generic [ref=f9e127]: "60"
- generic [ref=f9e128]: "80"
- heading "English Baccalaureate (EBacc)" [level=3] [ref=f9e129]
- generic [ref=f9e130]:
- generic [ref=f9e131]:
- generic [ref=f9e132]: Pupils entered for EBacc
- generic [ref=f9e133]: 30.1%
- generic [ref=f9e134]:
- generic [ref=f9e135]: EBacc Grade 4+
- generic [ref=f9e136]: 25.1%
- generic [ref=f9e137]:
- generic [ref=f9e138]: EBacc Grade 5+
- generic [ref=f9e139]: 20.5%
- generic [ref=f9e140]:
- generic [ref=f9e141]: EBacc average point score
- generic [ref=f9e142]: "4.72"
- generic [ref=f9e143]:
- heading "Admissions" [level=2] [ref=f9e144]
- generic [ref=f9e145]:
- generic [ref=f9e146]:
- generic [ref=f9e147]: Year 7 places offered
- generic [ref=f9e148]: "237"
- generic [ref=f9e149]:
- generic [ref=f9e150]: Total applications
- generic [ref=f9e151]: "707"
- generic [ref=f9e152]:
- generic [ref=f9e153]: 1st preference applications
- generic [ref=f9e154]: "336"
- generic [ref=f9e155]:
- generic [ref=f9e156]: Families who got their first choice
- generic [ref=f9e157]: 69.6%
- generic [ref=f9e158]: ⚠ Applications exceeded places last year
- paragraph [ref=f9e159]: Historical distance cut-off data is not available for this school. Contact the admissions authority for oversubscription criteria details.
- generic [ref=f9e160]:
- heading "Historical Results" [level=2] [ref=f9e161]
- heading "Results Over Time" [level=3] [ref=f9e162]
- generic [ref=f9e164]:
- generic [ref=f9e165]:
- generic [ref=f9e166]: GCSE results · Year 11
- tablist "Select metric" [ref=f9e167]:
- tab "Attainment 8" [selected] [ref=f9e168] [cursor=pointer]
- tab "English & Maths grade 4+" [ref=f9e169] [cursor=pointer]
- tab "Progress 8" [ref=f9e170] [cursor=pointer]
- img [ref=f9e172]
- group [ref=f9e173]:
- generic "▶ View raw year-by-year data" [ref=f9e174] [cursor=pointer]
- generic [ref=f9e175]:
- heading "Wellbeing & Context" [level=2] [ref=f9e176]
- heading "Special Educational Needs (SEN)" [level=3] [ref=f9e177]
- generic [ref=f9e178]:
- generic [ref=f9e179]:
- generic [ref=f9e180]: SEN support
- generic [ref=f9e181]: 5.4%
- generic [ref=f9e182]: Without an EHCP
- generic [ref=f9e183]:
- generic [ref=f9e184]: Pupils with EHCP
- generic [ref=f9e185]: 3.8%
- generic [ref=f9e186]: Education, Health and Care Plan
- generic [ref=f9e187]:
- generic [ref=f9e188]: Total pupils
- generic [ref=f9e189]: 1,207
- 'img "Gender split: 52% girls, 48% boys" [ref=f9e190]'
- generic [ref=f9e193]:
- generic [ref=f9e194]: 52% girls
- text: ·
- generic [ref=f9e195]: 48% boys
- contentinfo [ref=f9e196]:
- generic [ref=f9e197]:
- generic [ref=f9e198]:
- generic [ref=f9e199]:
- heading "SchoolCompare" [level=3] [ref=f9e200]
- paragraph [ref=f9e201]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f9e202] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f9e203]:
- heading "Product" [level=4] [ref=f9e204]
- list [ref=f9e205]:
- listitem [ref=f9e206]:
- link "Search schools" [ref=f9e207] [cursor=pointer]:
- /url: /
- listitem [ref=f9e208]:
- link "Rankings" [ref=f9e209] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f9e210]:
- link "Compare shortlist" [ref=f9e211] [cursor=pointer]:
- /url: /compare
- listitem [ref=f9e212]:
- link "Admissions guide" [ref=f9e213] [cursor=pointer]:
- /url: /admissions
- generic [ref=f9e214]:
- heading "Resources" [level=4] [ref=f9e215]
- list [ref=f9e216]:
- listitem [ref=f9e217]:
- link "School Performance Tables" [ref=f9e218] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f9e219]:
- link "Ofsted reports" [ref=f9e220] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f9e222]: © 2026 SchoolCompare.co.uk
- alert [ref=f9e223]
@@ -0,0 +1,230 @@
- generic [active] [ref=f10e1]:
- link "Skip to main content" [ref=f10e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f10e3]:
- generic [ref=f10e4]:
- link "SchoolCompare home" [ref=f10e5] [cursor=pointer]:
- /url: /
- img [ref=f10e7]
- generic [ref=f10e11]: SchoolCompare
- navigation "Main navigation" [ref=f10e12]:
- link "Search" [ref=f10e13] [cursor=pointer]:
- /url: /
- link "Compare 1" [ref=f10e14] [cursor=pointer]:
- /url: /compare
- text: Compare
- generic [ref=f10e15]: "1"
- link "Rankings" [ref=f10e16] [cursor=pointer]:
- /url: /rankings
- link "Admissions" [ref=f10e17] [cursor=pointer]:
- /url: /admissions
- main [ref=f10e18]:
- generic [ref=f10e19]:
- button "Back" [ref=f10e20] [cursor=pointer]:
- generic [ref=f10e21]: ←
- text: Back
- generic [ref=f10e22]:
- generic [ref=f10e23]:
- generic [ref=f10e24]:
- img [ref=f10e28] [cursor=pointer]
- generic [ref=f10e31]:
- link "Leaflet" [ref=f10e32] [cursor=pointer]:
- /url: https://leafletjs.com
- img [ref=f10e33]
- text: Leaflet
- text: "| ©"
- link "OpenStreetMap" [ref=f10e37] [cursor=pointer]:
- /url: https://www.openstreetmap.org/copyright
- text: contributors
- button "Open full map" [ref=f10e38] [cursor=pointer]:
- generic [ref=f10e39]:
- img [ref=f10e40]
- text: Open full map
- generic [ref=f10e42]:
- generic [ref=f10e43]:
- heading "The Castle School" [level=1] [ref=f10e44]
- generic [ref=f10e45]:
- generic [ref=f10e46]: Academy converter
- generic [ref=f10e47]: Ages 11–19
- paragraph [ref=f10e48]:
- text: Wellington Road, Taunton, TA1 5AU ·
- button "View on map ↗" [ref=f10e49] [cursor=pointer]
- generic [ref=f10e50]:
- generic [ref=f10e51]:
- strong [ref=f10e52]: "Headteacher:"
- text: Mr James Lamb
- link "School website ↗" [ref=f10e54] [cursor=pointer]:
- /url: http://www.castleschool.co.uk/
- generic [ref=f10e55]:
- strong [ref=f10e56]: "Pupils:"
- text: "1,202 (capacity: 1188)"
- generic [ref=f10e57]:
- text: Part of
- strong [ref=f10e58]: BLACKDOWN EDUCATION PARTNERSHIP
- button "✓ In Comparison" [ref=f10e60] [cursor=pointer]
- navigation "Page sections" [ref=f10e61]:
- generic [ref=f10e62]:
- button "Back to top" [ref=f10e63] [cursor=pointer]: ↑ Top
- link "Ofsted" [ref=f10e65] [cursor=pointer]:
- /url: "#ofsted"
- link "GCSEs" [ref=f10e66] [cursor=pointer]:
- /url: "#gcse"
- link "Admissions" [ref=f10e67] [cursor=pointer]:
- /url: "#admissions"
- link "History" [ref=f10e68] [cursor=pointer]:
- /url: "#history"
- link "Wellbeing" [ref=f10e69] [cursor=pointer]:
- /url: "#wellbeing"
- generic [ref=f10e70]:
- heading "Ofsted Rating Inspected 3 October 2023 Ofsted reports ↗" [level=2] [ref=f10e71]:
- text: Ofsted Rating
- generic [ref=f10e72]: Inspected 3 October 2023
- link "Ofsted reports ↗" [ref=f10e73] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/inspection-reports/find-inspection-report/provider/ELS/136916
- generic [ref=f10e75]: Outstanding
- paragraph [ref=f10e76]: From September 2024, Ofsted no longer makes an overall effectiveness judgement in inspections.
- paragraph [ref=f10e77]:
- text: Rated
- strong [ref=f10e78]: Outstanding
- text: across all inspected areas — Quality of Teaching, Behaviour, Pupils' Development and Leadership.
- generic [ref=f10e79]:
- heading "GCSE Results (2024/25)" [level=2] [ref=f10e80]
- paragraph [ref=f10e81]: GCSE results for Year 11 pupils. National averages shown for comparison.
- generic [ref=f10e82]: Progress 8 scores for 2024/25 are not used for accountability purposes following the KS2 assessment disruption. Treat with caution.
- generic [ref=f10e83]:
- generic [ref=f10e84]:
- generic [ref=f10e85]:
- text: Attainment 8 score
- img "Attainment 8" [ref=f10e87]: ⓘ
- generic [ref=f10e88]:
- text: "53.4"
- generic [ref=f10e89]: +14 pts
- generic [ref=f10e90]: "National avg: 39.1"
- generic [ref=f10e91]:
- generic [ref=f10e92]:
- text: English & Maths Grade 5+
- img "English & Maths — Grade 5+ (Strong Pass)" [ref=f10e94]: ⓘ
- generic [ref=f10e95]:
- text: 57.7%
- generic [ref=f10e96]: +22 pts
- generic [ref=f10e97]: "National avg: 36%"
- generic [ref=f10e98]:
- generic [ref=f10e99]:
- text: English & Maths Grade 4+
- img "English & Maths — Grade 4+ (Standard Pass)" [ref=f10e101]: ⓘ
- generic [ref=f10e102]:
- text: 79.5%
- generic [ref=f10e103]: +28 pts
- generic [ref=f10e104]: "National avg: 51%"
- generic [ref=f10e105]:
- generic [ref=f10e106]: Attainment 8 — school vs national
- generic [ref=f10e110]: Nat avg 39.1
- generic [ref=f10e111]:
- generic [ref=f10e112]: "0"
- generic [ref=f10e113]: "20"
- generic [ref=f10e114]: "40"
- generic [ref=f10e115]: "60"
- generic [ref=f10e116]: "80"
- heading "English Baccalaureate (EBacc) EBacc Entry" [level=3] [ref=f10e117]:
- text: English Baccalaureate (EBacc)
- img "EBacc Entry" [ref=f10e119]: ⓘ
- generic [ref=f10e120]:
- generic [ref=f10e121]:
- generic [ref=f10e122]: Pupils entered for EBacc
- generic [ref=f10e123]: 30.1%
- generic [ref=f10e124]:
- generic [ref=f10e125]: EBacc Grade 4+
- generic [ref=f10e126]: 25.1%
- generic [ref=f10e127]:
- generic [ref=f10e128]: EBacc Grade 5+
- generic [ref=f10e129]: 20.5%
- generic [ref=f10e130]:
- generic [ref=f10e131]: EBacc average point score
- generic [ref=f10e132]: "4.72"
- generic [ref=f10e133]:
- heading "Admissions" [level=2] [ref=f10e134]
- generic [ref=f10e135]:
- generic [ref=f10e136]:
- generic [ref=f10e137]: Year 7 places offered
- generic [ref=f10e138]: "237"
- generic [ref=f10e139]:
- generic [ref=f10e140]: Total applications
- generic [ref=f10e141]: "707"
- generic [ref=f10e142]:
- generic [ref=f10e143]: 1st preference applications
- generic [ref=f10e144]: "336"
- generic [ref=f10e145]:
- generic [ref=f10e146]: Families who got their first choice
- generic [ref=f10e147]: 69.6%
- generic [ref=f10e148]: ⚠ Applications exceeded places last year
- paragraph [ref=f10e149]: Historical distance cut-off data is not available for this school. Contact the admissions authority for oversubscription criteria details.
- generic [ref=f10e150]:
- heading "Historical Results" [level=2] [ref=f10e151]
- heading "Results Over Time" [level=3] [ref=f10e152]
- img [ref=f10e156]
- group [ref=f10e157]:
- generic "▶ View raw year-by-year data" [ref=f10e158] [cursor=pointer]
- generic [ref=f10e159]:
- heading "Wellbeing & Context" [level=2] [ref=f10e160]
- heading "Special Educational Needs (SEN)" [level=3] [ref=f10e161]
- generic [ref=f10e162]:
- generic [ref=f10e163]:
- generic [ref=f10e164]:
- text: SEN support
- img "SEN Support" [ref=f10e166]: ⓘ
- generic [ref=f10e167]: 5.4%
- generic [ref=f10e168]: Without an EHCP
- generic [ref=f10e169]:
- generic [ref=f10e170]:
- text: Pupils with EHCP
- img "Education, Health and Care Plan (EHCP)" [ref=f10e172]: ⓘ
- generic [ref=f10e173]: 3.8%
- generic [ref=f10e174]: Education, Health and Care Plan
- generic [ref=f10e175]:
- generic [ref=f10e176]: Total pupils
- generic [ref=f10e177]: 1,207
- 'img "Gender split: 52% girls, 48% boys" [ref=f10e178]'
- generic [ref=f10e181]:
- generic [ref=f10e182]: 52% girls
- text: ·
- generic [ref=f10e183]: 48% boys
- generic [ref=f10e186]:
- generic [ref=f10e187]:
- generic [ref=f10e188]: "1"
- text: school selected
- button "Expand comparison panel" [ref=f10e189] [cursor=pointer]:
- img [ref=f10e190]
- contentinfo [ref=f10e192]:
- generic [ref=f10e193]:
- generic [ref=f10e194]:
- generic [ref=f10e195]:
- heading "SchoolCompare" [level=3] [ref=f10e196]
- paragraph [ref=f10e197]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f10e198] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f10e199]:
- heading "Product" [level=4] [ref=f10e200]
- list [ref=f10e201]:
- listitem [ref=f10e202]:
- link "Search schools" [ref=f10e203] [cursor=pointer]:
- /url: /
- listitem [ref=f10e204]:
- link "Rankings" [ref=f10e205] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f10e206]:
- link "Compare shortlist" [ref=f10e207] [cursor=pointer]:
- /url: /compare
- listitem [ref=f10e208]:
- link "Admissions guide" [ref=f10e209] [cursor=pointer]:
- /url: /admissions
- generic [ref=f10e210]:
- heading "Resources" [level=4] [ref=f10e211]
- list [ref=f10e212]:
- listitem [ref=f10e213]:
- link "School Performance Tables" [ref=f10e214] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f10e215]:
- link "Ofsted reports" [ref=f10e216] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f10e218]: © 2026 SchoolCompare.co.uk
- alert [ref=f10e219]
@@ -0,0 +1,120 @@
- generic [active] [ref=f11e1]:
- link "Skip to main content" [ref=f11e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f11e3]:
- link "SchoolCompare home" [ref=f11e5] [cursor=pointer]:
- /url: /
- img [ref=f11e7]
- generic [ref=f11e11]: SchoolCompare
- navigation "Main navigation" [ref=f11e12]:
- link "Search" [ref=f11e13] [cursor=pointer]:
- /url: /
- img [ref=f11e15]
- generic [ref=f11e18]: Search
- link "1 selected Compare" [ref=f11e19] [cursor=pointer]:
- /url: /compare
- generic [ref=f11e20]:
- img [ref=f11e21]
- generic "1 selected" [ref=f11e24]: "1"
- generic [ref=f11e25]: Compare
- link "Rankings" [ref=f11e26] [cursor=pointer]:
- /url: /rankings
- img [ref=f11e28]
- generic [ref=f11e29]: Rankings
- link "Admissions" [ref=f11e30] [cursor=pointer]:
- /url: /admissions
- img [ref=f11e32]
- generic [ref=f11e35]: Admissions
- main [ref=f11e36]:
- generic [ref=f11e37]:
- generic [ref=f11e39]:
- generic [ref=f11e40]:
- heading "Compare Schools" [level=1] [ref=f11e41]
- paragraph [ref=f11e42]: Comparing 1 school
- generic [ref=f11e43]:
- button "+ Add School" [ref=f11e44] [cursor=pointer]
- button "Share" [ref=f11e45] [cursor=pointer]:
- img [ref=f11e46]
- text: Share
- generic [ref=f11e49]:
- button "Primary (1)" [ref=f11e50] [cursor=pointer]
- button "Secondary (0)" [ref=f11e51] [cursor=pointer]
- generic [ref=f11e52]:
- generic [ref=f11e53]: "Select Metric:"
- combobox "Select Metric:" [ref=f11e54] [cursor=pointer]:
- option "Reading, Writing & Maths Combined %" [selected]
- option "Reading Expected %"
- option "Writing Expected %"
- option "Maths Expected %"
- option "GPS Expected %"
- option "Science Expected %"
- option "Reading, Writing & Maths Combined Higher %"
- option "Reading Higher %"
- option "Writing Higher %"
- option "Maths Higher %"
- option "GPS Higher %"
- option "Reading Progress"
- option "Writing Progress"
- option "Maths Progress"
- option "Reading Average Score"
- option "Maths Average Score"
- option "GPS Average Score"
- option "Reading, Writing & Maths Expected % (Boys)"
- option "Reading, Writing & Maths Expected % (Girls)"
- option "Reading, Writing & Maths Higher % (Boys)"
- option "Reading, Writing & Maths Higher % (Girls)"
- option "Reading, Writing & Maths Expected % (Disadvantaged)"
- option "Reading, Writing & Maths Expected % (Non-Disadvantaged)"
- option "Disadvantaged Gap"
- option "% Disadvantaged Pupils"
- option "% EAL Pupils"
- option "% SEN Support"
- option "% Pupil Stability"
- option "Reading Test Absence %"
- option "GPS Test Absence %"
- option "Maths Test Absence %"
- option "Writing Absence %"
- option "Science Absence %"
- paragraph [ref=f11e55]: "% meeting expected standard in reading, writing and maths"
- generic [ref=f11e58]:
- button "Remove The Castle School" [ref=f11e59] [cursor=pointer]: ×
- heading "The Castle School" [level=2] [ref=f11e60]:
- link "The Castle School" [ref=f11e61] [cursor=pointer]:
- /url: /school/136916-the-castle-school
- generic [ref=f11e62]:
- generic [ref=f11e63]: Somerset
- generic [ref=f11e64]: Academy converter
- contentinfo [ref=f11e76]:
- generic [ref=f11e77]:
- generic [ref=f11e78]:
- generic [ref=f11e79]:
- heading "SchoolCompare" [level=3] [ref=f11e80]
- paragraph [ref=f11e81]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f11e82] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f11e83]:
- heading "Product" [level=4] [ref=f11e84]
- list [ref=f11e85]:
- listitem [ref=f11e86]:
- link "Search schools" [ref=f11e87] [cursor=pointer]:
- /url: /
- listitem [ref=f11e88]:
- link "Rankings" [ref=f11e89] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f11e90]:
- link "Compare shortlist" [ref=f11e91] [cursor=pointer]:
- /url: /compare
- listitem [ref=f11e92]:
- link "Admissions guide" [ref=f11e93] [cursor=pointer]:
- /url: /admissions
- generic [ref=f11e94]:
- heading "Resources" [level=4] [ref=f11e95]
- list [ref=f11e96]:
- listitem [ref=f11e97]:
- link "School Performance Tables" [ref=f11e98] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f11e99]:
- link "Ofsted reports" [ref=f11e100] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f11e102]: © 2026 SchoolCompare.co.uk
- alert [ref=f11e103]
@@ -0,0 +1,69 @@
- generic [active] [ref=f12e1]:
- link "Skip to main content" [ref=f12e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f12e3]:
- link "SchoolCompare home" [ref=f12e5] [cursor=pointer]:
- /url: /
- img [ref=f12e7]
- generic [ref=f12e11]: SchoolCompare
- navigation "Main navigation" [ref=f12e12]:
- link "Search" [ref=f12e13] [cursor=pointer]:
- /url: /
- img [ref=f12e15]
- generic [ref=f12e18]: Search
- link "Compare" [ref=f12e19] [cursor=pointer]:
- /url: /compare
- img [ref=f12e21]
- generic [ref=f12e24]: Compare
- link "Rankings" [ref=f12e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f12e27]
- generic [ref=f12e28]: Rankings
- link "Admissions" [ref=f12e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f12e31]
- generic [ref=f12e34]: Admissions
- main [ref=f12e35]:
- generic [ref=f12e36]:
- generic [ref=f12e37]:
- heading "Compare Schools" [level=1] [ref=f12e38]
- paragraph [ref=f12e39]: Add schools to your comparison basket to see side-by-side performance data
- generic [ref=f12e40]:
- img [ref=f12e42]
- heading "No schools selected" [level=3] [ref=f12e45]
- paragraph [ref=f12e46]: Add schools from the home page or search to start comparing.
- button "+ Add Schools to Compare" [ref=f12e47] [cursor=pointer]
- contentinfo [ref=f12e48]:
- generic [ref=f12e49]:
- generic [ref=f12e50]:
- generic [ref=f12e51]:
- heading "SchoolCompare" [level=3] [ref=f12e52]
- paragraph [ref=f12e53]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f12e54] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f12e55]:
- heading "Product" [level=4] [ref=f12e56]
- list [ref=f12e57]:
- listitem [ref=f12e58]:
- link "Search schools" [ref=f12e59] [cursor=pointer]:
- /url: /
- listitem [ref=f12e60]:
- link "Rankings" [ref=f12e61] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f12e62]:
- link "Compare shortlist" [ref=f12e63] [cursor=pointer]:
- /url: /compare
- listitem [ref=f12e64]:
- link "Admissions guide" [ref=f12e65] [cursor=pointer]:
- /url: /admissions
- generic [ref=f12e66]:
- heading "Resources" [level=4] [ref=f12e67]
- list [ref=f12e68]:
- listitem [ref=f12e69]:
- link "School Performance Tables" [ref=f12e70] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f12e71]:
- link "Ofsted reports" [ref=f12e72] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f12e74]: © 2026 SchoolCompare.co.uk
- alert [ref=f12e75]
@@ -0,0 +1,76 @@
- generic [ref=f12e1]:
- link "Skip to main content" [ref=f12e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f12e3]:
- link "SchoolCompare home" [ref=f12e5] [cursor=pointer]:
- /url: /
- img [ref=f12e7]
- generic [ref=f12e11]: SchoolCompare
- navigation "Main navigation" [ref=f12e12]:
- link "Search" [ref=f12e13] [cursor=pointer]:
- /url: /
- img [ref=f12e15]
- generic [ref=f12e18]: Search
- link "Compare" [ref=f12e19] [cursor=pointer]:
- /url: /compare
- img [ref=f12e21]
- generic [ref=f12e24]: Compare
- link "Rankings" [ref=f12e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f12e27]
- generic [ref=f12e28]: Rankings
- link "Admissions" [ref=f12e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f12e31]
- generic [ref=f12e34]: Admissions
- main [ref=f12e35]:
- generic [ref=f12e36]:
- generic [ref=f12e37]:
- heading "Compare Schools" [level=1] [ref=f12e38]
- paragraph [ref=f12e39]: Add schools to your comparison basket to see side-by-side performance data
- generic [ref=f12e40]:
- img [ref=f12e42]
- heading "No schools selected" [level=3] [ref=f12e45]
- paragraph [ref=f12e46]: Add schools from the home page or search to start comparing.
- button "+ Add Schools to Compare" [ref=f12e47] [cursor=pointer]
- contentinfo [ref=f12e48]:
- generic [ref=f12e49]:
- generic [ref=f12e50]:
- generic [ref=f12e51]:
- heading "SchoolCompare" [level=3] [ref=f12e52]
- paragraph [ref=f12e53]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f12e54] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f12e55]:
- heading "Product" [level=4] [ref=f12e56]
- list [ref=f12e57]:
- listitem [ref=f12e58]:
- link "Search schools" [ref=f12e59] [cursor=pointer]:
- /url: /
- listitem [ref=f12e60]:
- link "Rankings" [ref=f12e61] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f12e62]:
- link "Compare shortlist" [ref=f12e63] [cursor=pointer]:
- /url: /compare
- listitem [ref=f12e64]:
- link "Admissions guide" [ref=f12e65] [cursor=pointer]:
- /url: /admissions
- generic [ref=f12e66]:
- heading "Resources" [level=4] [ref=f12e67]
- list [ref=f12e68]:
- listitem [ref=f12e69]:
- link "School Performance Tables" [ref=f12e70] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f12e71]:
- link "Ofsted reports" [ref=f12e72] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f12e74]: © 2026 SchoolCompare.co.uk
- alert [ref=f12e75]
- generic [ref=f12e77]:
- button "Close modal" [ref=f12e79] [cursor=pointer]:
- img [ref=f12e80]
- generic [ref=f12e84]:
- heading "Add School to Comparison" [level=2] [ref=f12e85]
- textbox "School name or postcode" [active] [ref=f12e87]
- generic [ref=f12e88]: Start typing to search for schools...
@@ -0,0 +1,162 @@
- generic [ref=f12e1]:
- link "Skip to main content" [ref=f12e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f12e3]:
- link "SchoolCompare home" [ref=f12e5] [cursor=pointer]:
- /url: /
- img [ref=f12e7]
- generic [ref=f12e11]: SchoolCompare
- navigation "Main navigation" [ref=f12e12]:
- link "Search" [ref=f12e13] [cursor=pointer]:
- /url: /
- img [ref=f12e15]
- generic [ref=f12e18]: Search
- link "1 selected Compare" [ref=f12e160] [cursor=pointer]:
- /url: /compare
- generic [ref=f12e20]:
- img [ref=f12e21]
- generic "1 selected" [ref=f12e161]: "1"
- generic [ref=f12e24]: Compare
- link "Rankings" [ref=f12e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f12e27]
- generic [ref=f12e28]: Rankings
- link "Admissions" [ref=f12e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f12e31]
- generic [ref=f12e34]: Admissions
- main [ref=f12e35]:
- generic [ref=f12e36]:
- generic [ref=f12e162]:
- generic [ref=f12e163]:
- heading "Compare Schools" [level=1] [ref=f12e164]
- paragraph [ref=f12e165]: Comparing 1 school
- generic [ref=f12e166]:
- button "+ Add School" [ref=f12e167] [cursor=pointer]
- button "Share" [ref=f12e168] [cursor=pointer]:
- img [ref=f12e169]
- text: Share
- generic [ref=f12e172]:
- button "Primary (1)" [ref=f12e173] [cursor=pointer]
- button "Secondary (0)" [ref=f12e174] [cursor=pointer]
- generic [ref=f12e175]:
- generic [ref=f12e176]: "Select Metric:"
- combobox "Select Metric:" [ref=f12e177] [cursor=pointer]:
- option "Reading, Writing & Maths Combined %" [selected]
- option "Reading Expected %"
- option "Writing Expected %"
- option "Maths Expected %"
- option "GPS Expected %"
- option "Science Expected %"
- option "Reading, Writing & Maths Combined Higher %"
- option "Reading Higher %"
- option "Writing Higher %"
- option "Maths Higher %"
- option "GPS Higher %"
- option "Reading Progress"
- option "Writing Progress"
- option "Maths Progress"
- option "Reading Average Score"
- option "Maths Average Score"
- option "GPS Average Score"
- option "Reading, Writing & Maths Expected % (Boys)"
- option "Reading, Writing & Maths Expected % (Girls)"
- option "Reading, Writing & Maths Higher % (Boys)"
- option "Reading, Writing & Maths Higher % (Girls)"
- option "Reading, Writing & Maths Expected % (Disadvantaged)"
- option "Reading, Writing & Maths Expected % (Non-Disadvantaged)"
- option "Disadvantaged Gap"
- option "% Disadvantaged Pupils"
- option "% EAL Pupils"
- option "% SEN Support"
- option "% Pupil Stability"
- option "Reading Test Absence %"
- option "GPS Test Absence %"
- option "Maths Test Absence %"
- option "Writing Absence %"
- option "Science Absence %"
- paragraph [ref=f12e178]: "% meeting expected standard in reading, writing and maths"
- generic [ref=f12e181]:
- button "Remove St Mary & St Thomas CofE Primary School" [ref=f12e182] [cursor=pointer]: ×
- heading "St Mary & St Thomas CofE Primary School" [level=2] [ref=f12e183]:
- link "St Mary & St Thomas CofE Primary School" [ref=f12e184] [cursor=pointer]:
- /url: /school/142161-st-mary-st-thomas-cofe-primary-school
- generic [ref=f12e185]:
- generic [ref=f12e186]: St. Helens
- generic [ref=f12e187]: Academy converter
- generic [ref=f12e188]:
- generic [ref=f12e189]: Reading, Writing & Maths Combined %
- generic [ref=f12e190]: 77.0%
- generic [ref=f12e192]:
- heading "Performance Over Time" [level=2] [ref=f12e193]
- img [ref=f12e195]
- generic [ref=f12e196]:
- heading "Detailed Comparison" [level=2] [ref=f12e197]
- table [ref=f12e199]:
- rowgroup [ref=f12e200]:
- row "Year St Mary & St Thomas CofE Primary School" [ref=f12e201]:
- columnheader "Year" [ref=f12e202]
- columnheader "St Mary & St Thomas CofE Primary School" [ref=f12e203]
- rowgroup [ref=f12e204]:
- row "2015/16 54.0%" [ref=f12e205]:
- cell "2015/16" [ref=f12e206]
- cell "54.0%" [ref=f12e207]
- row "2016/17 86.0%" [ref=f12e208]:
- cell "2016/17" [ref=f12e209]
- cell "86.0%" [ref=f12e210]
- row "2017/18 50.0%" [ref=f12e211]:
- cell "2017/18" [ref=f12e212]
- cell "50.0%" [ref=f12e213]
- row "2018/19 67.0%" [ref=f12e214]:
- cell "2018/19" [ref=f12e215]
- cell "67.0%" [ref=f12e216]
- row "2022/23 83.0%" [ref=f12e217]:
- cell "2022/23" [ref=f12e218]
- cell "83.0%" [ref=f12e219]
- row "2023/24 89.0%" [ref=f12e220]:
- cell "2023/24" [ref=f12e221]
- cell "89.0%" [ref=f12e222]
- row "2024/25 77.0%" [ref=f12e223]:
- cell "2024/25" [ref=f12e224]
- cell "77.0%" [ref=f12e225]
- contentinfo [ref=f12e48]:
- generic [ref=f12e49]:
- generic [ref=f12e50]:
- generic [ref=f12e51]:
- heading "SchoolCompare" [level=3] [ref=f12e52]
- paragraph [ref=f12e53]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f12e54] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f12e55]:
- heading "Product" [level=4] [ref=f12e56]
- list [ref=f12e57]:
- listitem [ref=f12e58]:
- link "Search schools" [ref=f12e59] [cursor=pointer]:
- /url: /
- listitem [ref=f12e60]:
- link "Rankings" [ref=f12e61] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f12e62]:
- link "Compare shortlist" [ref=f12e63] [cursor=pointer]:
- /url: /compare
- listitem [ref=f12e64]:
- link "Admissions guide" [ref=f12e65] [cursor=pointer]:
- /url: /admissions
- generic [ref=f12e66]:
- heading "Resources" [level=4] [ref=f12e67]
- list [ref=f12e68]:
- listitem [ref=f12e69]:
- link "School Performance Tables" [ref=f12e70] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f12e71]:
- link "Ofsted reports" [ref=f12e72] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f12e74]: © 2026 SchoolCompare.co.uk
- alert [ref=f12e75]
- generic [ref=f12e227]:
- button "Close modal" [ref=f12e229] [cursor=pointer]:
- img [ref=f12e230]
- generic [ref=f12e234]:
- heading "Add School to Comparison" [level=2] [ref=f12e235]
- textbox "School name or postcode" [active] [ref=f12e237]
- generic [ref=f12e238]: Start typing to search for schools...
@@ -0,0 +1,188 @@
- generic [active] [ref=f12e1]:
- link "Skip to main content" [ref=f12e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f12e3]:
- link "SchoolCompare home" [ref=f12e5] [cursor=pointer]:
- /url: /
- img [ref=f12e7]
- generic [ref=f12e11]: SchoolCompare
- navigation "Main navigation" [ref=f12e12]:
- link "Search" [ref=f12e13] [cursor=pointer]:
- /url: /
- img [ref=f12e15]
- generic [ref=f12e18]: Search
- link "2 selected Compare" [ref=f12e247] [cursor=pointer]:
- /url: /compare
- generic [ref=f12e20]:
- img [ref=f12e21]
- generic "2 selected" [ref=f12e248]: "2"
- generic [ref=f12e24]: Compare
- link "Rankings" [ref=f12e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f12e27]
- generic [ref=f12e28]: Rankings
- link "Admissions" [ref=f12e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f12e31]
- generic [ref=f12e34]: Admissions
- main [ref=f12e35]:
- generic [ref=f12e36]:
- generic [ref=f12e162]:
- generic [ref=f12e163]:
- heading "Compare Schools" [level=1] [ref=f12e164]
- paragraph [ref=f12e165]: Comparing 2 schools
- generic [ref=f12e166]:
- button "+ Add School" [ref=f12e167] [cursor=pointer]
- button "Share" [ref=f12e168] [cursor=pointer]:
- img [ref=f12e169]
- text: Share
- generic [ref=f12e172]:
- button "Primary (2)" [ref=f12e249] [cursor=pointer]
- button "Secondary (0)" [ref=f12e174] [cursor=pointer]
- generic [ref=f12e175]:
- generic [ref=f12e176]: "Select Metric:"
- combobox "Select Metric:" [ref=f12e177] [cursor=pointer]:
- option "Reading, Writing & Maths Combined %" [selected]
- option "Reading Expected %"
- option "Writing Expected %"
- option "Maths Expected %"
- option "GPS Expected %"
- option "Science Expected %"
- option "Reading, Writing & Maths Combined Higher %"
- option "Reading Higher %"
- option "Writing Higher %"
- option "Maths Higher %"
- option "GPS Higher %"
- option "Reading Progress"
- option "Writing Progress"
- option "Maths Progress"
- option "Reading Average Score"
- option "Maths Average Score"
- option "GPS Average Score"
- option "Reading, Writing & Maths Expected % (Boys)"
- option "Reading, Writing & Maths Expected % (Girls)"
- option "Reading, Writing & Maths Higher % (Boys)"
- option "Reading, Writing & Maths Higher % (Girls)"
- option "Reading, Writing & Maths Expected % (Disadvantaged)"
- option "Reading, Writing & Maths Expected % (Non-Disadvantaged)"
- option "Disadvantaged Gap"
- option "% Disadvantaged Pupils"
- option "% EAL Pupils"
- option "% SEN Support"
- option "% Pupil Stability"
- option "Reading Test Absence %"
- option "GPS Test Absence %"
- option "Maths Test Absence %"
- option "Writing Absence %"
- option "Science Absence %"
- paragraph [ref=f12e178]: "% meeting expected standard in reading, writing and maths"
- generic [ref=f12e180]:
- generic [ref=f12e181]:
- button "Remove St Mary & St Thomas CofE Primary School" [ref=f12e182] [cursor=pointer]: ×
- heading "St Mary & St Thomas CofE Primary School" [level=2] [ref=f12e183]:
- link "St Mary & St Thomas CofE Primary School" [ref=f12e184] [cursor=pointer]:
- /url: /school/142161-st-mary-st-thomas-cofe-primary-school
- generic [ref=f12e185]:
- generic [ref=f12e186]: St. Helens
- generic [ref=f12e187]: Academy converter
- generic [ref=f12e188]:
- generic [ref=f12e189]: Reading, Writing & Maths Combined %
- generic [ref=f12e190]: 77.0%
- generic [ref=f12e250]:
- button "Remove Ottery St Mary Primary School" [ref=f12e251] [cursor=pointer]: ×
- heading "Ottery St Mary Primary School" [level=2] [ref=f12e252]:
- link "Ottery St Mary Primary School" [ref=f12e253] [cursor=pointer]:
- /url: /school/113105-ottery-st-mary-primary-school
- generic [ref=f12e254]:
- generic [ref=f12e255]: Devon
- generic [ref=f12e256]: Foundation school
- generic [ref=f12e257]:
- generic [ref=f12e258]: Reading, Writing & Maths Combined %
- generic [ref=f12e259]: 51.0%
- generic [ref=f12e192]:
- heading "Performance Over Time" [level=2] [ref=f12e193]
- img [ref=f12e195]
- generic [ref=f12e196]:
- heading "Detailed Comparison" [level=2] [ref=f12e197]
- table [ref=f12e199]:
- rowgroup [ref=f12e200]:
- row "Year St Mary & St Thomas CofE Primary School Ottery St Mary Primary School" [ref=f12e261]:
- columnheader "Year" [ref=f12e202]
- columnheader "St Mary & St Thomas CofE Primary School" [ref=f12e203]
- columnheader "Ottery St Mary Primary School" [ref=f12e262]
- rowgroup [ref=f12e204]:
- row "2015/16 54.0% 53.0%" [ref=f12e263]:
- cell "2015/16" [ref=f12e206]
- cell "54.0%" [ref=f12e207]
- cell "53.0%" [ref=f12e264]
- row "2016/17 86.0% 66.0%" [ref=f12e265]:
- cell "2016/17" [ref=f12e209]
- cell "86.0%" [ref=f12e210]
- cell "66.0%" [ref=f12e266]
- row "2017/18 50.0% 68.0%" [ref=f12e267]:
- cell "2017/18" [ref=f12e212]
- cell "50.0%" [ref=f12e213]
- cell "68.0%" [ref=f12e268]
- row "2018/19 67.0% 73.0%" [ref=f12e269]:
- cell "2018/19" [ref=f12e215]
- cell "67.0%" [ref=f12e216]
- cell "73.0%" [ref=f12e270]
- row "2022/23 83.0% 53.0%" [ref=f12e271]:
- cell "2022/23" [ref=f12e218]
- cell "83.0%" [ref=f12e219]
- cell "53.0%" [ref=f12e272]
- row "2023/24 89.0% 52.0%" [ref=f12e273]:
- cell "2023/24" [ref=f12e221]
- cell "89.0%" [ref=f12e222]
- cell "52.0%" [ref=f12e274]
- row "2024/25 77.0% 51.0%" [ref=f12e275]:
- cell "2024/25" [ref=f12e224]
- cell "77.0%" [ref=f12e225]
- cell "51.0%" [ref=f12e276]
- contentinfo [ref=f12e48]:
- generic [ref=f12e49]:
- generic [ref=f12e50]:
- generic [ref=f12e51]:
- heading "SchoolCompare" [level=3] [ref=f12e52]
- paragraph [ref=f12e53]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f12e54] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f12e55]:
- heading "Product" [level=4] [ref=f12e56]
- list [ref=f12e57]:
- listitem [ref=f12e58]:
- link "Search schools" [ref=f12e59] [cursor=pointer]:
- /url: /
- listitem [ref=f12e60]:
- link "Rankings" [ref=f12e61] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f12e62]:
- link "Compare shortlist" [ref=f12e63] [cursor=pointer]:
- /url: /compare
- listitem [ref=f12e64]:
- link "Admissions guide" [ref=f12e65] [cursor=pointer]:
- /url: /admissions
- generic [ref=f12e66]:
- heading "Resources" [level=4] [ref=f12e67]
- list [ref=f12e68]:
- listitem [ref=f12e69]:
- link "School Performance Tables" [ref=f12e70] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f12e71]:
- link "Ofsted reports" [ref=f12e72] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f12e74]: © 2026 SchoolCompare.co.uk
- alert [ref=f12e75]
- generic [ref=f12e227]:
- button "Close modal" [ref=f12e229] [cursor=pointer]:
- img [ref=f12e230]
- generic [ref=f12e234]:
- heading "Add School to Comparison" [level=2] [ref=f12e235]
- textbox "School name or postcode" [ref=f12e237]: Ottery St Mary
- generic [ref=f12e240]:
- generic [ref=f12e241]:
- generic [ref=f12e242]: Ottery St Mary Primary School
- generic [ref=f12e243]:
- generic [ref=f12e244]: Devon
- generic [ref=f12e245]: Foundation school
- button "✓ Comparing" [disabled] [ref=f12e277]
@@ -0,0 +1,175 @@
- generic [active] [ref=f12e1]:
- link "Skip to main content" [ref=f12e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f12e3]:
- link "SchoolCompare home" [ref=f12e5] [cursor=pointer]:
- /url: /
- img [ref=f12e7]
- generic [ref=f12e11]: SchoolCompare
- navigation "Main navigation" [ref=f12e12]:
- link "Search" [ref=f12e13] [cursor=pointer]:
- /url: /
- img [ref=f12e15]
- generic [ref=f12e18]: Search
- link "2 selected Compare" [ref=f12e247] [cursor=pointer]:
- /url: /compare
- generic [ref=f12e20]:
- img [ref=f12e21]
- generic "2 selected" [ref=f12e248]: "2"
- generic [ref=f12e24]: Compare
- link "Rankings" [ref=f12e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f12e27]
- generic [ref=f12e28]: Rankings
- link "Admissions" [ref=f12e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f12e31]
- generic [ref=f12e34]: Admissions
- main [ref=f12e35]:
- generic [ref=f12e36]:
- generic [ref=f12e162]:
- generic [ref=f12e163]:
- heading "Compare Schools" [level=1] [ref=f12e164]
- paragraph [ref=f12e165]: Comparing 2 schools
- generic [ref=f12e166]:
- button "+ Add School" [ref=f12e167] [cursor=pointer]
- button "Share" [ref=f12e168] [cursor=pointer]:
- img [ref=f12e169]
- text: Share
- generic [ref=f12e172]:
- button "Primary (2)" [ref=f12e249] [cursor=pointer]
- button "Secondary (0)" [ref=f12e174] [cursor=pointer]
- generic [ref=f12e175]:
- generic [ref=f12e176]: "Select Metric:"
- combobox "Select Metric:" [ref=f12e177] [cursor=pointer]:
- option "Reading, Writing & Maths Combined %" [selected]
- option "Reading Expected %"
- option "Writing Expected %"
- option "Maths Expected %"
- option "GPS Expected %"
- option "Science Expected %"
- option "Reading, Writing & Maths Combined Higher %"
- option "Reading Higher %"
- option "Writing Higher %"
- option "Maths Higher %"
- option "GPS Higher %"
- option "Reading Progress"
- option "Writing Progress"
- option "Maths Progress"
- option "Reading Average Score"
- option "Maths Average Score"
- option "GPS Average Score"
- option "Reading, Writing & Maths Expected % (Boys)"
- option "Reading, Writing & Maths Expected % (Girls)"
- option "Reading, Writing & Maths Higher % (Boys)"
- option "Reading, Writing & Maths Higher % (Girls)"
- option "Reading, Writing & Maths Expected % (Disadvantaged)"
- option "Reading, Writing & Maths Expected % (Non-Disadvantaged)"
- option "Disadvantaged Gap"
- option "% Disadvantaged Pupils"
- option "% EAL Pupils"
- option "% SEN Support"
- option "% Pupil Stability"
- option "Reading Test Absence %"
- option "GPS Test Absence %"
- option "Maths Test Absence %"
- option "Writing Absence %"
- option "Science Absence %"
- paragraph [ref=f12e178]: "% meeting expected standard in reading, writing and maths"
- generic [ref=f12e180]:
- generic [ref=f12e181]:
- button "Remove St Mary & St Thomas CofE Primary School" [ref=f12e182] [cursor=pointer]: ×
- heading "St Mary & St Thomas CofE Primary School" [level=2] [ref=f12e183]:
- link "St Mary & St Thomas CofE Primary School" [ref=f12e184] [cursor=pointer]:
- /url: /school/142161-st-mary-st-thomas-cofe-primary-school
- generic [ref=f12e185]:
- generic [ref=f12e186]: St. Helens
- generic [ref=f12e187]: Academy converter
- generic [ref=f12e188]:
- generic [ref=f12e189]: Reading, Writing & Maths Combined %
- generic [ref=f12e190]: 77.0%
- generic [ref=f12e250]:
- button "Remove Ottery St Mary Primary School" [ref=f12e251] [cursor=pointer]: ×
- heading "Ottery St Mary Primary School" [level=2] [ref=f12e252]:
- link "Ottery St Mary Primary School" [ref=f12e253] [cursor=pointer]:
- /url: /school/113105-ottery-st-mary-primary-school
- generic [ref=f12e254]:
- generic [ref=f12e255]: Devon
- generic [ref=f12e256]: Foundation school
- generic [ref=f12e257]:
- generic [ref=f12e258]: Reading, Writing & Maths Combined %
- generic [ref=f12e259]: 51.0%
- generic [ref=f12e192]:
- heading "Performance Over Time" [level=2] [ref=f12e193]
- img [ref=f12e195]
- generic [ref=f12e196]:
- heading "Detailed Comparison" [level=2] [ref=f12e197]
- table [ref=f12e199]:
- rowgroup [ref=f12e200]:
- row "Year St Mary & St Thomas CofE Primary School Ottery St Mary Primary School" [ref=f12e261]:
- columnheader "Year" [ref=f12e202]
- columnheader "St Mary & St Thomas CofE Primary School" [ref=f12e203]
- columnheader "Ottery St Mary Primary School" [ref=f12e262]
- rowgroup [ref=f12e204]:
- row "2015/16 54.0% 53.0%" [ref=f12e263]:
- cell "2015/16" [ref=f12e206]
- cell "54.0%" [ref=f12e207]
- cell "53.0%" [ref=f12e264]
- row "2016/17 86.0% 66.0%" [ref=f12e265]:
- cell "2016/17" [ref=f12e209]
- cell "86.0%" [ref=f12e210]
- cell "66.0%" [ref=f12e266]
- row "2017/18 50.0% 68.0%" [ref=f12e267]:
- cell "2017/18" [ref=f12e212]
- cell "50.0%" [ref=f12e213]
- cell "68.0%" [ref=f12e268]
- row "2018/19 67.0% 73.0%" [ref=f12e269]:
- cell "2018/19" [ref=f12e215]
- cell "67.0%" [ref=f12e216]
- cell "73.0%" [ref=f12e270]
- row "2022/23 83.0% 53.0%" [ref=f12e271]:
- cell "2022/23" [ref=f12e218]
- cell "83.0%" [ref=f12e219]
- cell "53.0%" [ref=f12e272]
- row "2023/24 89.0% 52.0%" [ref=f12e273]:
- cell "2023/24" [ref=f12e221]
- cell "89.0%" [ref=f12e222]
- cell "52.0%" [ref=f12e274]
- row "2024/25 77.0% 51.0%" [ref=f12e275]:
- cell "2024/25" [ref=f12e224]
- cell "77.0%" [ref=f12e225]
- cell "51.0%" [ref=f12e276]
- contentinfo [ref=f12e48]:
- generic [ref=f12e49]:
- generic [ref=f12e50]:
- generic [ref=f12e51]:
- heading "SchoolCompare" [level=3] [ref=f12e52]
- paragraph [ref=f12e53]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f12e54] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f12e55]:
- heading "Product" [level=4] [ref=f12e56]
- list [ref=f12e57]:
- listitem [ref=f12e58]:
- link "Search schools" [ref=f12e59] [cursor=pointer]:
- /url: /
- listitem [ref=f12e60]:
- link "Rankings" [ref=f12e61] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f12e62]:
- link "Compare shortlist" [ref=f12e63] [cursor=pointer]:
- /url: /compare
- listitem [ref=f12e64]:
- link "Admissions guide" [ref=f12e65] [cursor=pointer]:
- /url: /admissions
- generic [ref=f12e66]:
- heading "Resources" [level=4] [ref=f12e67]
- list [ref=f12e68]:
- listitem [ref=f12e69]:
- link "School Performance Tables" [ref=f12e70] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f12e71]:
- link "Ofsted reports" [ref=f12e72] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f12e74]: © 2026 SchoolCompare.co.uk
- alert [ref=f12e75]
Loaded 100 of 415 files, more files were not shown because too many files have changed in this diff. Show more