diff --git a/nextjs-app/components/SecondarySchoolDetailView.module.css b/nextjs-app/components/SecondarySchoolDetailView.module.css index 4ae1c12..92bd5fa 100644 --- a/nextjs-app/components/SecondarySchoolDetailView.module.css +++ b/nextjs-app/components/SecondarySchoolDetailView.module.css @@ -802,6 +802,207 @@ color: var(--text-muted, #8a847a); } +/* ── GCSE hero stat cards (mirrors primary heroStatCard) ─ */ +.heroStatGrid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 0.85rem; + margin-bottom: 0.25rem; +} + +.heroStatCard { + background: rgba(45, 125, 125, 0.1); + border: 1px solid rgba(45, 125, 125, 0.2); + border-radius: 12px; + padding: 1rem 1.1rem; + display: flex; + flex-direction: column; + gap: 0.25rem; +} + +.heroStatCard .heroStatLabel { + font-size: 0.6rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--text-muted, #6d685f); +} + +.heroStatCard .heroStatValue { + font-family: var(--font-playfair), 'Playfair Display', serif; + font-size: 2.1rem; + font-weight: 700; + line-height: 1; + color: var(--accent-teal, #2d7d7d); + display: flex; + align-items: baseline; + gap: 0.4rem; + flex-wrap: wrap; +} + +.heroStatCard .heroStatHint { + font-size: 0.7rem; + color: var(--text-muted, #6d685f); + font-style: normal; + margin-top: 0; +} + +/* ── Attainment 8 visual bar ─────────────────────────── */ +.att8Viz { + margin: 1.25rem 0 0.5rem; +} + +.att8VizLabel { + font-size: 0.6875rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.07em; + color: var(--text-muted, #6d685f); + margin-bottom: 0.5rem; +} + +.att8VizTrack { + position: relative; + height: 14px; + background: rgba(45, 125, 125, 0.08); + border: 1px solid var(--border-color, #e5dfd5); + border-radius: 4px; + overflow: visible; +} + +.att8VizFill { + height: 100%; + background: var(--accent-teal, #2d7d7d); + border-radius: 4px 0 0 4px; + transition: width 0.6s ease; +} + +.att8VizNatLine { + position: absolute; + top: -4px; + bottom: -4px; + width: 2px; + background: var(--accent-coral, #e07256); + border-radius: 2px; + z-index: 2; +} + +.att8VizNatPill { + position: absolute; + top: -20px; + transform: translateX(-50%); + background: var(--accent-coral, #e07256); + color: #fff; + font-size: 0.6rem; + font-weight: 700; + padding: 0.1rem 0.3rem; + border-radius: 3px; + white-space: nowrap; +} + +.att8VizTicks { + display: flex; + justify-content: space-between; + margin-top: 0.25rem; + font-size: 0.6rem; + color: var(--text-muted, #6d685f); +} + +/* ── Progress 8 number line ──────────────────────────── */ +.p8Viz { + margin: 1.25rem 0 0.5rem; +} + +.p8VizLabel { + font-size: 0.6875rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.07em; + color: var(--text-muted, #6d685f); + margin-bottom: 0.5rem; +} + +.p8VizTrack { + position: relative; + height: 14px; + background: rgba(45, 125, 125, 0.06); + border: 1px solid var(--border-color, #e5dfd5); + border-radius: 4px; + overflow: visible; +} + +.p8VizCi { + position: absolute; + top: 0; + bottom: 0; + background: rgba(45, 125, 125, 0.18); + border-radius: 3px; +} + +.p8VizZero { + position: absolute; + top: -4px; + bottom: -4px; + width: 2px; + background: var(--border-color, #e5dfd5); + z-index: 1; +} + +.p8VizDot { + position: absolute; + top: 50%; + transform: translate(-50%, -50%); + width: 12px; + height: 12px; + border-radius: 50%; + background: var(--accent-teal, #2d7d7d); + border: 2px solid white; + box-shadow: 0 1px 4px rgba(0,0,0,0.2); + z-index: 3; +} + +.p8VizDotNeg { + background: var(--accent-coral, #e07256); +} + +.p8VizTicks { + display: flex; + justify-content: space-between; + margin-top: 0.25rem; + font-size: 0.6rem; + color: var(--text-muted, #6d685f); +} + +/* ── History accordion ───────────────────────────────── */ +.historyDisclosure { + margin-top: 1rem; +} + +.historyToggle { + list-style: none; + cursor: pointer; + font-size: 0.8125rem; + font-weight: 600; + color: var(--text-muted, #6d685f); + padding: 0.5rem 0; + display: flex; + align-items: center; + gap: 0.375rem; + user-select: none; +} + +.historyToggle::-webkit-details-marker { display: none; } + +.historyToggle::before { + content: '▶'; + font-size: 0.6rem; + transition: transform 0.2s ease; +} + +.historyDisclosure[open] .historyToggle::before { + transform: rotate(90deg); +} + /* ── Responsive ──────────────────────────────────────── */ @media (max-width: 768px) { .header { @@ -848,6 +1049,14 @@ font-size: 1rem; } + .heroStatGrid { + grid-template-columns: 1fr; + } + + .heroStatCard .heroStatValue { + font-size: 1.85rem; + } + .chartContainer { height: 220px; } diff --git a/nextjs-app/components/SecondarySchoolDetailView.tsx b/nextjs-app/components/SecondarySchoolDetailView.tsx index 003b895..ec86bce 100644 --- a/nextjs-app/components/SecondarySchoolDetailView.tsx +++ b/nextjs-app/components/SecondarySchoolDetailView.tsx @@ -494,61 +494,153 @@ export function SecondarySchoolDetailView({ )} -
+ {/* Hero stat cards — top GCSE metrics */} +
{latestResults.attainment_8_score != null && ( -
-
- Attainment 8 +
+
+ Attainment 8 score
-
{latestResults.attainment_8_score.toFixed(1)}
+
+ {latestResults.attainment_8_score.toFixed(1)} + {secondaryAvg.attainment_8_score != null && ( + + )} +
{secondaryAvg.attainment_8_score != null && ( -
National avg: {secondaryAvg.attainment_8_score.toFixed(1)}
+
National avg: {secondaryAvg.attainment_8_score.toFixed(1)}
)}
)} {latestResults.progress_8_score != null && ( -
-
- Progress 8 +
+
+ Progress 8 score
-
+
{formatProgress(latestResults.progress_8_score)}
- {(latestResults.progress_8_lower_ci != null || latestResults.progress_8_upper_ci != null) && ( -
- CI: {latestResults.progress_8_lower_ci?.toFixed(2) ?? '?'} to {latestResults.progress_8_upper_ci?.toFixed(2) ?? '?'} + {(latestResults.progress_8_lower_ci != null && latestResults.progress_8_upper_ci != null) ? ( +
+ CI: {latestResults.progress_8_lower_ci.toFixed(2)} to {latestResults.progress_8_upper_ci.toFixed(2)}
- )} -
- )} - {latestResults.english_maths_standard_pass_pct != null && ( -
-
- English & Maths Grade 4+ - -
-
{formatPercentage(latestResults.english_maths_standard_pass_pct)}
- {secondaryAvg.english_maths_standard_pass_pct != null && ( -
National avg: {secondaryAvg.english_maths_standard_pass_pct.toFixed(0)}%
+ ) : ( +
National baseline: 0.0
)}
)} {latestResults.english_maths_strong_pass_pct != null && ( -
-
+
+
English & Maths Grade 5+
-
{formatPercentage(latestResults.english_maths_strong_pass_pct)}
+
+ {formatPercentage(latestResults.english_maths_strong_pass_pct)} + {secondaryAvg.english_maths_strong_pass_pct != null && ( + + )} +
{secondaryAvg.english_maths_strong_pass_pct != null && ( -
National avg: {secondaryAvg.english_maths_strong_pass_pct.toFixed(0)}%
+
National avg: {secondaryAvg.english_maths_strong_pass_pct.toFixed(0)}%
+ )} +
+ )} + {latestResults.english_maths_standard_pass_pct != null && ( +
+
+ English & Maths Grade 4+ + +
+
+ {formatPercentage(latestResults.english_maths_standard_pass_pct)} + {secondaryAvg.english_maths_standard_pass_pct != null && ( + + )} +
+ {secondaryAvg.english_maths_standard_pass_pct != null && ( +
National avg: {secondaryAvg.english_maths_standard_pass_pct.toFixed(0)}%
)}
)}
+ {/* Attainment 8 visual bar (0–80 scale) */} + {latestResults.attainment_8_score != null && ( +
+
Attainment 8 — school vs national
+
+
+ {secondaryAvg.attainment_8_score != null && ( +
+
+ Nat avg {secondaryAvg.attainment_8_score.toFixed(1)} +
+
+ )} +
+
+ 020406080 +
+
+ )} + + {/* Progress 8 number line with CI */} + {latestResults.progress_8_score != null && !p8Suspended && ( +
+
Progress 8 — relative to national baseline (0)
+ {(() => { + const p8 = latestResults.progress_8_score!; + const lo = latestResults.progress_8_lower_ci ?? p8; + const hi = latestResults.progress_8_upper_ci ?? p8; + const range = 6; // −3 to +3 + const toX = (v: number) => `${Math.min(Math.max(((v + 3) / range) * 100, 0), 100)}%`; + return ( +
+ {/* CI band */} +
+ {/* Zero line */} +
+ {/* Score dot */} +
+
+ ); + })()} +
+ −3−2−10+1+2+3 +
+
+ )} + {/* Progress 8 component breakdown */} {(latestResults.progress_8_english != null || latestResults.progress_8_maths != null || latestResults.progress_8_ebacc != null || latestResults.progress_8_open != null) && ( @@ -608,21 +700,6 @@ export function SecondarySchoolDetailView({ )} - {/* Performance chart */} - {yearlyData.length > 0 && ( - <> -

Results Over Time

-
- -
- - )} )} @@ -695,33 +772,33 @@ export function SecondarySchoolDetailView({ {(latestResults?.sen_support_pct != null || latestResults?.sen_ehcp_pct != null) && ( <>

Special Educational Needs (SEN)

-
+
{latestResults?.sen_support_pct != null && ( -
-
- Pupils receiving SEN support +
+
+ SEN support
-
{formatPercentage(latestResults.sen_support_pct)}
-
SEN support without an EHCP
+
{formatPercentage(latestResults.sen_support_pct)}
+
Without an EHCP
)} {latestResults?.sen_ehcp_pct != null && ( -
-
- Pupils with an EHCP +
+
+ Pupils with EHCP
-
{formatPercentage(latestResults.sen_ehcp_pct)}
-
Education, Health and Care Plan
+
{formatPercentage(latestResults.sen_ehcp_pct)}
+
Education, Health and Care Plan
)} {(schoolInfo.total_pupils != null || latestResults?.total_pupils != null) && ( -
-
Total pupils
-
{(schoolInfo.total_pupils ?? latestResults!.total_pupils!).toLocaleString()}
+
+
Total pupils
+
{(schoolInfo.total_pupils ?? latestResults!.total_pupils!).toLocaleString()}
{schoolInfo.capacity != null && ( -
Capacity: {schoolInfo.capacity}
+
Capacity: {schoolInfo.capacity}
)}
)} @@ -808,30 +885,47 @@ export function SecondarySchoolDetailView({ {yearlyData.length > 1 && (

Historical Results

-
- - - - - - - - - - - - {yearlyData.map((result) => ( - - - - - - + {yearlyData.length > 0 && ( + <> +

Results Over Time

+
+ +
+ + )} +
+ View raw year-by-year data +
+
YearAttainment 8Progress 8Eng & Maths 4+EBacc entry %
{formatAcademicYear(result.year)}{result.attainment_8_score != null ? result.attainment_8_score.toFixed(1) : '-'}{result.progress_8_score != null ? formatProgress(result.progress_8_score) : '-'}{result.english_maths_standard_pass_pct != null ? formatPercentage(result.english_maths_standard_pass_pct) : '-'}{result.ebacc_entry_pct != null ? formatPercentage(result.ebacc_entry_pct) : '-'}
+ + + + + + + - ))} - -
YearAttainment 8Progress 8Eng & Maths 4+EBacc entry %
-
+ + + {yearlyData.map((result) => ( + + {formatAcademicYear(result.year)} + {result.attainment_8_score != null ? result.attainment_8_score.toFixed(1) : '-'} + {result.progress_8_score != null ? formatProgress(result.progress_8_score) : '-'} + {result.english_maths_standard_pass_pct != null ? formatPercentage(result.english_maths_standard_pass_pct) : '-'} + {result.ebacc_entry_pct != null ? formatPercentage(result.ebacc_entry_pct) : '-'} + + ))} + + +
+ )}