Files
school_compare/docs/superpowers/specs/mockups/compare-mobile.html
T

438 lines
32 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<title>Compare screen — mobile mockup</title>
<style>
:root {
--bg: #faf7f2; --bg-2: #f3ede4; --card: #ffffff;
--ink: #1a1612; --ink-2: #5c564d; --ink-3: #6d685f;
--border: #e5dfd5; --accent: #b04a2e; --accent-bg: rgba(224,114,86,0.12);
--s1: #e07256; --s1-text: #b04a2e;
--s2: #00949b; --s2-text: #006a70;
--s3: #8664c9; --s3-text: #6a4bab;
--eng: #6d685f;
--good-bg: #e3efe6; --good-text: #1a6b34;
--warn-bg: #f6ecd4; --warn-text: #7a5d00;
--neutral-bg: #efeae1; --neutral-text: #5c564d;
--shadow: 0 2px 8px rgba(26,22,18,0.06);
--display: 'Playfair Display', Georgia, 'Times New Roman', serif;
--body: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #16130f; --bg-2: #201c16; --card: #241f19;
--ink: #f2ede4; --ink-2: #bdb5a8; --ink-3: #9a927f;
--border: #3a342b; --accent: #f08b6e; --accent-bg: rgba(224,114,86,0.16);
--s1: #f08b6e; --s1-text: #f4a58e;
--s2: #2fb8ae; --s2-text: #5fd0c8;
--s3: #a98fe0; --s3-text: #c0abec;
--eng: #9a927f;
--good-bg: #1e3325; --good-text: #7fd39a;
--warn-bg: #38301a; --warn-text: #e4c268;
--neutral-bg: #2b2620; --neutral-text: #bdb5a8;
--shadow: 0 2px 8px rgba(0,0,0,0.35);
}
}
:root[data-theme="dark"] {
--bg: #16130f; --bg-2: #201c16; --card: #241f19;
--ink: #f2ede4; --ink-2: #bdb5a8; --ink-3: #9a927f;
--border: #3a342b; --accent: #f08b6e; --accent-bg: rgba(224,114,86,0.16);
--s1: #f08b6e; --s1-text: #f4a58e;
--s2: #2fb8ae; --s2-text: #5fd0c8;
--s3: #a98fe0; --s3-text: #c0abec;
--eng: #9a927f;
--good-bg: #1e3325; --good-text: #7fd39a;
--warn-bg: #38301a; --warn-text: #e4c268;
--neutral-bg: #2b2620; --neutral-text: #bdb5a8;
--shadow: 0 2px 8px rgba(0,0,0,0.35);
}
:root[data-theme="light"] {
--bg: #faf7f2; --bg-2: #f3ede4; --card: #ffffff;
--ink: #1a1612; --ink-2: #5c564d; --ink-3: #6d685f;
--border: #e5dfd5; --accent: #b04a2e; --accent-bg: rgba(224,114,86,0.12);
--s1: #e07256; --s1-text: #b04a2e;
--s2: #00949b; --s2-text: #006a70;
--s3: #8664c9; --s3-text: #6a4bab;
--eng: #6d685f;
--good-bg: #e3efe6; --good-text: #1a6b34;
--warn-bg: #f6ecd4; --warn-text: #7a5d00;
--neutral-bg: #efeae1; --neutral-text: #5c564d;
--shadow: 0 2px 8px rgba(26,22,18,0.06);
}
body { background: var(--bg-2); color: var(--ink); font-family: var(--body); line-height: 1.45; }
/* Phone canvas: true mobile width, framed on larger screens */
.phone { max-width: 400px; margin: 0 auto; background: var(--bg); min-height: 100vh; }
@media (min-width: 480px) {
.phone { margin: 1.5rem auto; border: 1px solid var(--border); border-radius: 24px; overflow: hidden; box-shadow: var(--shadow); }
}
.inner { padding: 1rem 0.9rem 3rem; }
.mock-note {
background: var(--accent-bg); border: 1px solid var(--border); border-radius: 8px;
padding: 0.5rem 0.75rem; font-size: 0.78rem; color: var(--ink-2); margin-bottom: 1rem;
}
.mock-note strong { color: var(--accent); }
h1 { font-family: var(--display); font-size: 1.7rem; font-weight: 700; margin: 0 0 0.2rem; }
.sub { color: var(--ink-2); margin: 0 0 1rem; font-size: 0.88rem; }
/* Sticky school chip bar — horizontal scroll */
.chipbar {
position: sticky; top: 0; z-index: 10; background: var(--bg);
display: flex; gap: 0.5rem; overflow-x: auto; padding: 0.6rem 0.9rem;
border-bottom: 1px solid var(--border); margin: 0 -0.9rem 1rem; -webkit-overflow-scrolling: touch;
}
.chipbar::-webkit-scrollbar { display: none; }
.schip {
flex: none; display: inline-flex; align-items: center; gap: 0.4rem;
background: var(--card); border: 1px solid var(--border); border-radius: 999px;
padding: 0.35rem 0.7rem; font-size: 0.8rem; font-weight: 600; white-space: nowrap;
}
.schip .dot { width: 9px; height: 9px; border-radius: 50%; }
.schip .x { border: none; background: var(--bg-2); color: var(--ink-3); border-radius: 50%; width: 17px; height: 17px; font-size: 0.7rem; line-height: 1; }
.schip.add { color: var(--accent); border-style: dashed; }
h2.section-title {
font-family: var(--display); font-size: 1.2rem; font-weight: 700;
margin: 1.6rem 0 0; padding-left: 0.6rem; border-left: 3px solid var(--accent);
}
.how { font-size: 0.78rem; color: var(--ink-3); margin: 0.3rem 0 0.75rem 0.8rem; }
/* Measure-first block: one measure, all schools under it */
.measure { background: var(--card); border: 1px solid var(--border); border-radius: 12px; padding: 0.75rem 0.85rem; margin-bottom: 0.6rem; box-shadow: var(--shadow); }
.measure .mt { font-size: 0.85rem; font-weight: 600; display: flex; align-items: center; gap: 0.35rem; }
.measure .mh { font-size: 0.75rem; color: var(--ink-3); margin-top: 0.05rem; }
.srow { display: flex; align-items: center; gap: 0.5rem; padding: 0.45rem 0; border-top: 1px solid var(--border); margin-top: 0.45rem; flex-wrap: wrap; }
.srow:first-of-type { border-top: none; }
.srow .dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.srow .sn { font-size: 0.8rem; font-weight: 600; color: var(--ink-2); width: 4.6rem; flex: none; }
.srow .val { font-weight: 700; font-variant-numeric: tabular-nums; font-size: 0.95rem; }
.srow .note { font-size: 0.74rem; color: var(--ink-3); flex-basis: 100%; padding-left: 1.1rem; margin-top: -0.15rem; }
.chip { display: inline-block; font-size: 0.68rem; font-weight: 600; border-radius: 999px; padding: 0.12rem 0.5rem; white-space: nowrap; }
.chip.good { background: var(--good-bg); color: var(--good-text); }
.chip.warn { background: var(--warn-bg); color: var(--warn-text); }
.chip.neutral { background: var(--neutral-bg); color: var(--neutral-text); }
.ofsted-badge { display: inline-block; font-weight: 700; border-radius: 6px; padding: 0.14rem 0.5rem; font-size: 0.78rem; }
.ofsted-1 { background: var(--good-bg); color: var(--good-text); }
.illus { display: inline-block; font-size: 0.62rem; font-weight: 600; color: var(--accent); border: 1px dashed var(--accent); border-radius: 4px; padding: 0 0.3rem; }
.help { display: inline-flex; width: 14px; height: 14px; border-radius: 50%; border: 1px solid var(--ink-3); color: var(--ink-3); font-size: 0.6rem; align-items: center; justify-content: center; flex: none; }
/* Dot strips */
.strip-row { margin: 0.9rem 0 1.3rem; }
.strip-row .t { font-weight: 600; font-size: 0.82rem; }
.strip { position: relative; height: 32px; margin-top: 0.4rem; }
.strip .track { position: absolute; left: 0; right: 0; top: 14px; height: 4px; border-radius: 2px; background: var(--bg-2); }
.strip .eng-tick { position: absolute; top: 4px; width: 2px; height: 24px; background: var(--eng); }
.strip .eng-lbl { position: absolute; top: -12px; transform: translateX(-50%); font-size: 0.62rem; color: var(--ink-3); white-space: nowrap; }
.strip .pt { position: absolute; top: 9px; width: 14px; height: 14px; border-radius: 50%; transform: translateX(-50%); border: 2px solid var(--card); box-shadow: 0 0 0 1px rgba(0,0,0,0.08); }
.strip .pt-lbl { position: absolute; top: 25px; transform: translateX(-50%); font-size: 0.64rem; font-weight: 600; }
.legend { display: flex; gap: 0.8rem; flex-wrap: wrap; font-size: 0.72rem; color: var(--ink-2); margin-top: 0.4rem; }
.legend .li { display: inline-flex; align-items: center; gap: 0.3rem; }
.legend .sw { width: 9px; height: 9px; border-radius: 50%; }
.legend .engsw { width: 2px; height: 11px; background: var(--eng); }
.rc-list { display: flex; flex-direction: column; gap: 0.25rem; width: 100%; padding-left: 1.1rem; }
.rc-row { display: flex; justify-content: space-between; align-items: center; font-size: 0.74rem; }
.rc-row .a { color: var(--ink-2); }
details.more-measures { margin-bottom: 0.6rem; }
details.more-measures summary { cursor: pointer; font-weight: 600; font-size: 0.82rem; color: var(--accent); padding: 0.2rem 0.2rem 0.5rem; }
.strip-note { font-size: 0.72rem; color: var(--ink-3); margin: 0.4rem 0.2rem 0; }
.metric-picker { margin-bottom: 0.6rem; }
.metric-picker select { width: 100%; font-family: inherit; font-size: 0.85rem; padding: 0.45rem 0.6rem; border-radius: 8px; border: 1px solid var(--border); background: var(--card); color: var(--ink); }
.chart-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; background: var(--card); border: 1px solid var(--border); border-radius: 12px; padding: 0.75rem; }
.swipe-hint { font-size: 0.7rem; color: var(--ink-3); text-align: center; margin-top: 0.3rem; }
.covid { fill: var(--bg-2); }
.covid-lbl { font-size: 0.6rem; fill: var(--ink-3); }
.footnote { font-size: 0.7rem; color: var(--ink-3); margin-top: 2rem; border-top: 1px solid var(--border); padding-top: 0.8rem; }
</style>
<div class="phone"><div class="inner">
<p class="mock-note"><strong>Mobile mockup — proposed /compare.</strong> Mobile-first layout: measures stack vertically with all schools under each, so nothing needs horizontal swiping. Same live data as the desktop mockup.</p>
<h1>Compare schools</h1>
<p class="sub">Anchored against the England average — the grey tick — so you can tell what's typical at a glance.</p>
<div class="chipbar" aria-label="Schools in this comparison">
<span class="schip"><span class="dot" style="background:var(--s1)"></span>Barclay <button class="x" aria-label="Remove Barclay">×</button></span>
<span class="schip"><span class="dot" style="background:var(--s2)"></span>Elmhurst <button class="x" aria-label="Remove Elmhurst">×</button></span>
<span class="schip"><span class="dot" style="background:var(--s3)"></span>Plumcroft <button class="x" aria-label="Remove Plumcroft">×</button></span>
<span class="schip add">+ Add</span>
</div>
<h2 class="section-title">At a glance</h2>
<p class="how">The short version — each measure is explained in its own section below.</p>
<div class="measure">
<div class="mt">Latest Ofsted inspection</div>
<div class="srow"><span class="dot" style="background:var(--s1)"></span><span class="sn">Barclay</span><span class="ofsted-badge ofsted-1">Outstanding</span><span class="note">Older-style inspection, Oct 2021</span></div>
<div class="srow"><span class="dot" style="background:var(--s2)"></span><span class="sn">Elmhurst</span><span class="ofsted-badge ofsted-1">Outstanding</span><span class="note">Older-style inspection, Oct 2021</span></div>
<div class="srow"><span class="dot" style="background:var(--s3)"></span><span class="sn">Plumcroft</span><span><span class="chip good">4 areas Strong standard</span> <span class="chip neutral">2 areas Expected</span> <span class="chip warn">Attendance &amp; behaviour: Attention needed</span> <span class="illus">illustrative</span></span><span class="note">New-style report card, Nov 2025 · safeguarding met · full detail in the Ofsted section below</span></div>
</div>
<div class="measure">
<div class="mt">Children reaching the expected standard <span class="help" title="% of Year 6 pupils reaching the expected standard in reading, writing and maths (2024/25).">?</span></div>
<div class="mh">England average: 62%</div>
<div class="srow"><span class="dot" style="background:var(--s1)"></span><span class="sn">Barclay</span><span class="val" style="color:var(--s1-text)">87%</span> <span class="chip good">Above average</span></div>
<div class="srow"><span class="dot" style="background:var(--s2)"></span><span class="sn">Elmhurst</span><span class="val" style="color:var(--s2-text)">92%</span> <span class="chip good">Above average</span></div>
<div class="srow"><span class="dot" style="background:var(--s3)"></span><span class="sn">Plumcroft</span><span class="val" style="color:var(--s3-text)">79%</span> <span class="chip good">Above average</span></div>
</div>
<div class="measure">
<div class="mt">Getting a place</div>
<div class="srow"><span class="dot" style="background:var(--s1)"></span><span class="sn">Barclay</span><span class="chip good">97% of first choices offered</span><span class="note">Named on 457 forms · 180 places</span></div>
<div class="srow"><span class="dot" style="background:var(--s2)"></span><span class="sn">Elmhurst</span><span class="chip warn">73% of first choices offered</span><span class="note">Named on 342 forms · 120 places</span></div>
<div class="srow"><span class="dot" style="background:var(--s3)"></span><span class="sn">Plumcroft</span><span class="chip good">All first choices offered</span><span class="note">Named on 185 forms · 80 places</span></div>
</div>
<h2 class="section-title">Ofsted inspection</h2>
<p class="how">Ofsted stopped giving a single overall grade in September 2024 (inspections until November 2025 kept the area-by-area judgements); from November 2025 new inspections produce a report card rating each area of school life (Exceptional · Strong standard · Expected standard · Attention needed · Urgent improvement). A report card and an older grade aren't directly comparable. Ofsted's "Expected standard" rating is unrelated to the KS2 test measure below.</p>
<div class="measure">
<div class="mt">Latest inspection</div>
<div class="srow"><span class="dot" style="background:var(--s1)"></span><span class="sn">Barclay</span><span class="ofsted-badge ofsted-1">Outstanding</span><span class="chip neutral">4+ years ago</span><span class="note">7 Oct 2021 · we don't hold area-by-area detail for this inspection · <a href="https://reports.ofsted.gov.uk/provider/21/138690" style="color:var(--accent)">Ofsted page →</a></span></div>
<div class="srow" style="align-items:flex-start"><span class="dot" style="background:var(--s2);margin-top:4px"></span><span class="sn">Elmhurst</span><span><span class="ofsted-badge ofsted-1">Outstanding</span> <span class="chip neutral">4+ years ago</span> <span style="font-size:0.72rem;color:var(--ink-3)">6 Oct 2021</span></span>
<div class="rc-list">
<div class="rc-row"><span class="a">Quality of education</span><span class="chip good">Outstanding</span></div>
<div class="rc-row"><span class="a">Behaviour &amp; attitudes</span><span class="chip good">Outstanding</span></div>
<div class="rc-row"><span class="a">Personal development</span><span class="chip good">Outstanding</span></div>
<div class="rc-row"><span class="a">Leadership &amp; management</span><span class="chip good">Outstanding</span></div>
</div>
<span class="note"><a href="https://reports.ofsted.gov.uk/provider/21/145362" style="color:var(--accent)">Ofsted page →</a></span>
</div>
<div class="srow" style="align-items:flex-start"><span class="dot" style="background:var(--s3);margin-top:4px"></span><span class="sn">Plumcroft</span><span><strong style="font-size:0.85rem">Report card</strong> <span class="illus">illustrative</span> <span style="font-size:0.72rem;color:var(--ink-3)">14 Nov 2025</span></span>
<div class="rc-list">
<div class="rc-row"><span class="a">Achievement</span><span class="chip good">Strong standard</span></div>
<div class="rc-row"><span class="a">Curriculum &amp; teaching</span><span class="chip good">Strong standard</span></div>
<div class="rc-row"><span class="a">Attendance &amp; behaviour</span><span class="chip warn">Attention needed</span></div>
<div class="rc-row"><span class="a">Personal development</span><span class="chip good">Strong standard</span></div>
<div class="rc-row"><span class="a">Inclusion</span><span class="chip neutral">Expected standard</span></div>
<div class="rc-row"><span class="a">Leadership &amp; governance</span><span class="chip good">Strong standard</span></div>
<div class="rc-row"><span class="a">Early years</span><span class="chip neutral">Expected standard</span></div>
<div class="rc-row"><span class="a">Safeguarding</span><span class="chip good">Met</span></div>
</div>
<span class="note"><a href="https://reports.ofsted.gov.uk/provider/21/100140" style="color:var(--accent)">Ofsted page →</a></span>
</div>
</div>
<h2 class="section-title">How children do academically</h2>
<p class="how">End of Year 6 national tests and teacher assessments (2024/25) — writing is teacher-assessed. Each line runs 0100%; the grey tick is the England average.</p>
<div class="measure" id="strips"></div>
<details class="more-measures">
<summary>More measures — grammar, punctuation &amp; spelling, science, scaled scores</summary>
<div class="measure" id="strips-more" style="margin-top:0.5rem"></div>
<p class="strip-note">Strips show the 100120 window of the full 80120 scaled-score range; 100 is the expected standard (the strip widens if a school averages below it). England ticks for GPS and science aren't in our dataset yet, and the scaled-score ticks are indicative — official DfE figures will be loaded before launch.</p>
</details>
<div class="legend" id="strip-legend" style="padding:0 0.2rem 0"></div>
<div class="measure" style="margin-top:0.9rem">
<div class="mt">Children from lower-income families <span class="help" title="% of disadvantaged pupils (free school meals in the last 6 years, or looked after by the local authority) reaching the expected standard. State-school average: 46% (computed from our dataset). Small pupil groups — single pupils can move a school's figure noticeably.">?</span></div>
<div class="mh">State-school average: 46%</div>
<div class="srow"><span class="dot" style="background:var(--s1)"></span><span class="sn">Barclay</span><span class="val">86%</span> <span class="chip good">Well above average</span></div>
<div class="srow"><span class="dot" style="background:var(--s2)"></span><span class="sn">Elmhurst</span><span class="val">93%</span> <span class="chip good">Well above average</span></div>
<div class="srow"><span class="dot" style="background:var(--s3)"></span><span class="sn">Plumcroft</span><span class="val">72%</span> <span class="chip good">Above average</span></div>
</div>
<h2 class="section-title">Getting a place</h2>
<p class="how">September 2026 entry. "First choice" = families who ranked the school top of their form (officially a "first preference"). Schools never see your ranking — places go by the admission criteria alone. Figures are National Offer Day offers; waiting lists and appeals can change the final intake.</p>
<div class="measure">
<div class="mt">First-choice families offered a place</div>
<div class="srow"><span class="dot" style="background:var(--s1)"></span><span class="sn">Barclay</span><span class="val">97%</span><span class="note">Named on 457 forms · 180 places</span></div>
<div class="srow"><span class="dot" style="background:var(--s2)"></span><span class="sn">Elmhurst</span><span class="val">73%</span> <span class="chip warn">Over 1 in 4 missed out</span><span class="note">Named on 342 forms · 120 places — check the school's admission criteria (for most non-faith primaries, distance decides)</span></div>
<div class="srow"><span class="dot" style="background:var(--s3)"></span><span class="sn">Plumcroft</span><span class="val">100%</span><span class="note">Named on 185 forms · 80 places · every first choice offered</span></div>
</div>
<h2 class="section-title">Who goes there</h2>
<p class="how">From the latest school census (2025/26). No "right" numbers here — just context.</p>
<div class="measure">
<div class="mt">Pupils on roll</div>
<div class="srow"><span class="dot" style="background:var(--s1)"></span><span class="sn">Barclay</span><span class="val">1,273</span><span class="note">At or above capacity · much larger than average · girls 51% / boys 49%</span></div>
<div class="srow"><span class="dot" style="background:var(--s2)"></span><span class="sn">Elmhurst</span><span class="val">980</span><span class="note">98% full · much larger than average · girls 48% / boys 52%</span></div>
<div class="srow"><span class="dot" style="background:var(--s3)"></span><span class="sn">Plumcroft</span><span class="val">1,056</span><span class="note">At or above capacity · much larger than average · girls 51% / boys 49%</span></div>
</div>
<div class="measure">
<div class="mt">Free school meals <span class="help" title="% eligible for free school meals. State-school average: 25% (computed from our dataset).">?</span></div>
<div class="mh">State-school average: 25% (our dataset)</div>
<div class="srow"><span class="dot" style="background:var(--s1)"></span><span class="sn">Barclay</span><span class="val">26%</span> <span class="chip neutral">About average</span></div>
<div class="srow"><span class="dot" style="background:var(--s2)"></span><span class="sn">Elmhurst</span><span class="val">25%</span> <span class="chip neutral">About average</span></div>
<div class="srow"><span class="dot" style="background:var(--s3)"></span><span class="sn">Plumcroft</span><span class="val">30%</span> <span class="chip neutral">A little above</span></div>
</div>
<div class="measure">
<div class="mt">English as an additional language · extra learning support (SEN) <span class="help" title="SEN = pupils receiving SEN support, not including EHC plans. State-school average: ≈14% (computed from our dataset). A high figure can mean the school hosts specialist provision — often a strength, not a warning sign.">?</span></div>
<div class="srow"><span class="dot" style="background:var(--s1)"></span><span class="sn">Barclay</span><span style="font-size:0.85rem">EAL 62% · SEN 6%</span></div>
<div class="srow"><span class="dot" style="background:var(--s2)"></span><span class="sn">Elmhurst</span><span style="font-size:0.85rem">EAL 84% · SEN 8%</span></div>
<div class="srow"><span class="dot" style="background:var(--s3)"></span><span class="sn">Plumcroft</span><span style="font-size:0.85rem">EAL 20% · SEN 28% <span class="chip neutral">SEN well above avg</span></span></div>
</div>
<div class="measure">
<div class="mt">Basics</div>
<div class="srow"><span class="dot" style="background:var(--s1)"></span><span class="sn">Barclay</span><span style="font-size:0.85rem">Ages 311 · nursery · no faith · Lion Academy Trust</span></div>
<div class="srow"><span class="dot" style="background:var(--s2)"></span><span class="sn">Elmhurst</span><span style="font-size:0.85rem">Ages 311 · nursery · no faith · New Vision Trust</span></div>
<div class="srow"><span class="dot" style="background:var(--s3)"></span><span class="sn">Plumcroft</span><span style="font-size:0.85rem">Ages 311 · nursery · no faith · Greenwich council</span></div>
</div>
<h2 class="section-title">Explore trends</h2>
<p class="how">Every measure from the current compare page lives on here, grouped. Three are wired up in this mockup. School lines break where a year isn't in our dataset.</p>
<div class="metric-picker">
<select id="metric-select" aria-label="Measure">
<optgroup label="Expected standard">
<option value="rwm" selected>Reading, writing &amp; maths (combined)</option>
<option value="reading">Reading</option>
<option value="maths">Maths</option>
<option disabled>Writing (TA) · GPS · Science (TA)</option>
</optgroup>
<optgroup label="Higher standard"><option disabled>RWM · Reading · Maths · GPS</option><option disabled>Writing — greater depth (TA)</option></optgroup>
<optgroup label="Average scaled scores"><option disabled>Reading · Maths · GPS</option></optgroup>
<optgroup label="Equity"><option disabled>Disadvantaged pupils — expected standard</option></optgroup>
<optgroup label="School context"><option disabled>FSM % · EAL % · SEN support %</option></optgroup>
</select>
</div>
<div class="chart-wrap">
<svg id="trendchart" width="620" height="240" role="img" aria-label="Line chart: selected measure by year for three schools and England average"></svg>
<div class="legend" id="trend-legend"></div>
</div>
<p class="swipe-hint">← swipe the chart →</p>
<p class="footnote">
Sources: DfE Compare School Performance, Ofsted inspection outcomes, DfE admissions data, school census — all from datasets SchoolCompare already collects. England averages for test results are official DfE figures; FSM, language, SEN, size and disadvantaged-pupil benchmarks are computed across state schools in our dataset. Plumcroft's Ofsted report card is a made-up example of the November 2025 format (its real latest inspection is Good, June 2023). Following DfE practice, figures based on 5 or fewer pupils are suppressed and shown as "no data". Static mockup — tooltips and "+ Add" are illustrative.
</p>
</div></div>
<script>
(function () {
const css = (v) => getComputedStyle(document.documentElement).getPropertyValue(v).trim();
const schools = [
{ name: 'Barclay', color: () => css('--s1'), text: () => css('--s1-text') },
{ name: 'Elmhurst', color: () => css('--s2'), text: () => css('--s2-text') },
{ name: 'Plumcroft', color: () => css('--s3'), text: () => css('--s3-text') },
];
const strips = [
{ label: 'Reading, writing & maths', eng: 62, vals: [87, 92, 79] },
{ label: 'Reading', eng: 75, vals: [91, 92, 87] },
{ label: 'Writing', eng: 72, vals: [94, 92, 83] },
{ label: 'Maths', eng: 74, vals: [91, 95, 84] },
{ label: 'Higher standard', eng: 8, vals: [22, 27, 12], tip: 'A high score in the reading and maths tests plus \u201cgreater depth\u201d in teacher-assessed writing.' },
];
function renderStrips(list, el) {
list.forEach((s) => {
const min = s.min ?? 0, max = s.max ?? 100, unit = s.unit ?? '%';
const pos = v => (v - min) / (max - min) * 100;
const row = document.createElement('div');
row.className = 'strip-row';
let pts = '';
const sorted = s.vals.map((v, i) => ({ v, i })).sort((a, b) => a.v - b.v);
let lastBelow = -Infinity;
const nudge = (max - min) * 0.08;
sorted.forEach(({ v, i }) => {
const above = (v - lastBelow) < nudge;
if (!above) lastBelow = v;
pts += `<span class="pt" style="left:${pos(v)}%;background:${schools[i].color()}" title="${schools[i].name}: ${v}${unit}"></span>`
+ `<span class="pt-lbl" style="left:${pos(v)}%;color:${schools[i].text()};${above ? 'top:-6px' : ''}">${v}</span>`;
});
const eng = s.eng != null
? `<span class="eng-tick" style="left:${pos(s.eng)}%"></span><span class="eng-lbl" style="left:${pos(s.eng)}%">Eng ${s.eng}${unit}</span>`
: '';
row.innerHTML = `
<div class="t"${s.tip ? ` title="${s.tip}"` : ''}>${s.label}</div>
<div class="strip" role="img" aria-label="${s.label}: ${s.eng != null ? 'England average ' + s.eng + unit + ', ' : ''}${s.vals.map((v, i) => schools[i].name + ' ' + v + unit).join(', ')}">
<div class="track"></div>
${eng}
${pts}
</div>`;
el.appendChild(row);
});
}
renderStrips(strips, document.getElementById('strips'));
renderStrips([
{ label: 'Grammar, punctuation & spelling', eng: null, vals: [86, 94, 82] },
{ label: 'Science (teacher-assessed)', eng: null, vals: [95, 91, 83], tip: 'Teacher-assessed, like writing — no KS2 science test since 2009; comparisons are indicative.' },
{ label: 'Avg scaled score — reading', eng: 106, vals: [107, 110, 109], min: 100, max: 120, unit: '' },
{ label: 'Avg scaled score — maths', eng: 105, vals: [108, 113, 108], min: 100, max: 120, unit: '' },
{ label: 'Avg scaled score — GPS', eng: 105, vals: [107, 114, 109], min: 100, max: 120, unit: '' },
], document.getElementById('strips-more'));
document.getElementById('strip-legend').innerHTML =
schools.map(s => `<span class="li"><span class="sw" style="background:${s.color()}"></span>${s.name}</span>`).join('')
+ '<span class="li"><span class="engsw"></span>England average</span>';
/* Metric-driven trend chart. Lines always break across the covid band
(2019/20-2020/21, cancelled tests); other nulls are dataset gaps. */
const years = ['2015/16','2016/17','2017/18','2018/19','2021/22','2022/23','2023/24','2024/25'];
const METRICS = {
rwm: { school: { Barclay: [52,76,65,87,null,87,75,87], Elmhurst: [80,81,86,88,null,88,88,92], Plumcroft: [58,64,57,69,null,62,72,79] },
england: [null,61.1,64.3,64.9,58.7,59.5,60.6,62.1] },
reading: { school: { Barclay: [57,84,76,87,null,null,79,91], Elmhurst: [88,91,92,91,null,null,92,92], Plumcroft: [59,68,72,79,null,null,82,87] },
england: [null,71.6,75.3,73.2,74.6,72.8,74.4,75.0] },
maths: { school: { Barclay: [81,82,74,90,null,null,88,91], Elmhurst: [96,89,97,97,null,null,96,95], Plumcroft: [80,80,69,90,null,null,84,84] },
england: [null,74.8,75.5,78.7,71.5,73.0,73.2,74.0] },
};
const schoolColor = { Barclay: () => css('--s1'), Elmhurst: () => css('--s2'), Plumcroft: () => css('--s3') };
const svg = document.getElementById('trendchart');
const W = 620, H = 240, L = 38, R = 44, T = 14, B = 34;
const slots = [0,1,2,3,6,7,8,9]; const maxSlot = 9;
const X = i => L + slots[i] * (W - L - R) / maxSlot;
const Y = v => T + (100 - v) * (H - T - B) / 60;
function runs(vals) {
const out = []; let cur = [];
vals.forEach((v, i) => {
if (v == null) { if (cur.length) out.push(cur); cur = []; return; }
if (i === 4 && cur.length && cur[cur.length - 1] === 3) { out.push(cur); cur = []; }
cur.push(i);
});
if (cur.length) out.push(cur);
return out;
}
function renderChart(key) {
const m = METRICS[key];
const ink3 = css('--ink-3'), border = css('--border');
let g = '';
const bx1 = X(3) + 12, bx2 = X(4) - 12;
g += `<rect class="covid" x="${bx1}" y="${T}" width="${bx2 - bx1}" height="${H - T - B}" rx="4"/>`;
g += `<text class="covid-lbl" x="${(bx1 + bx2) / 2}" y="${T + 14}" text-anchor="middle">tests cancelled</text>`;
g += `<text class="covid-lbl" x="${(bx1 + bx2) / 2}" y="${T + 26}" text-anchor="middle">'19/20-'20/21</text>`;
for (let v = 40; v <= 100; v += 20) {
g += `<line x1="${L}" y1="${Y(v)}" x2="${W - R}" y2="${Y(v)}" stroke="${border}" stroke-width="1"/>`;
g += `<text x="${L - 6}" y="${Y(v) + 4}" text-anchor="end" font-size="10" fill="${ink3}">${v}%</text>`;
}
years.forEach((yr, i) => {
g += `<text x="${X(i)}" y="${H - B + 18}" text-anchor="middle" font-size="9.5" fill="${ink3}">${yr}</text>`;
});
const path = (vals, idx) => idx.map((i, k) => (k ? 'L' : 'M') + X(i) + ' ' + Y(vals[i])).join(' ');
runs(m.england).forEach(idx => {
if (idx.length > 1) g += `<path d="${path(m.england, idx)}" fill="none" stroke="${ink3}" stroke-width="1.5" stroke-dasharray="5 4"/>`;
else g += `<circle cx="${X(idx[0])}" cy="${Y(m.england[idx[0]])}" r="2" fill="${ink3}"><title>England ${years[idx[0]]}: ${Math.round(m.england[idx[0]])}%</title></circle>`;
});
Object.entries(m.school).forEach(([name, vals]) => {
const color = schoolColor[name]();
runs(vals).forEach(idx => {
if (idx.length > 1) g += `<path d="${path(vals, idx)}" fill="none" stroke="${color}" stroke-width="2" stroke-linecap="round"/>`;
});
vals.forEach((v, i) => {
if (v == null) return;
g += `<circle cx="${X(i)}" cy="${Y(v)}" r="3" fill="${color}" stroke="${css('--card')}" stroke-width="1.5"><title>${name} ${years[i]}: ${v}%</title></circle>`;
});
});
const ends = Object.entries(m.school)
.map(([name, vals]) => ({ v: vals[vals.length - 1], i: vals.length - 1 }))
.filter(e => e.v != null)
.sort((a, b) => a.v - b.v);
let prevY = Infinity;
ends.forEach(e => {
let y = Y(e.v) + 3.5;
if (prevY - y < 12) y = prevY - 12;
prevY = y;
g += `<text x="${X(e.i) + 7}" y="${y}" font-size="10" font-weight="600" fill="${ink3}">${e.v}%</text>`;
});
svg.innerHTML = g;
document.getElementById('trend-legend').innerHTML =
Object.keys(m.school).map(name => `<span class="li"><span class="sw" style="background:${schoolColor[name]()}"></span>${name}</span>`).join('')
+ `<span class="li"><span class="sw" style="background:none;border-top:2px dashed ${ink3};border-radius:0;height:0"></span>England avg</span>`;
}
renderChart('rwm');
document.getElementById('metric-select').addEventListener('change', e => renderChart(e.target.value));
new MutationObserver(muts => { if (muts.some(m => m.attributeName === 'data-theme')) location.reload(); })
.observe(document.documentElement, { attributes: true });
})();
</script>