From 5abab067a114c316b552180e2d08c8d951b1218a Mon Sep 17 00:00:00 2001 From: Tudor Sitaru Date: Tue, 14 Apr 2026 10:01:19 +0100 Subject: [PATCH] feat(admissions): replace bar + metric cards with Q&A tile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "How Hard to Get Into This School" tile mixed a progress bar (places vs first-choice) with three text metric cards, making the data feel fragmented and hiding the real narrative. The progress bar also broke visually when undersubscribed and didn't scale to different school sizes. Replace with a typographic Q&A list that answers the questions parents actually ask — "How many places were offered?", "How many families wanted this school first?", "How many got their first choice?", "How many applied in total?" — with a verdict footer (Oversubscribed / Not oversubscribed + one-sentence explanation). The third row now uses first_preference_offers (already in the API response) to show "27 of 42 (64.3%)" instead of just the percentage, giving the raw count parents actually want. Each row is independently null-gated; rows stack vertically under 480px so the Playfair numeral stays legible. Co-Authored-By: Claude Opus 4.6 --- .../components/SchoolDetailView.module.css | 87 ++++++++++++++----- nextjs-app/components/SchoolDetailView.tsx | 73 +++++++++------- 2 files changed, 106 insertions(+), 54 deletions(-) diff --git a/nextjs-app/components/SchoolDetailView.module.css b/nextjs-app/components/SchoolDetailView.module.css index e9270d0..9520bd5 100644 --- a/nextjs-app/components/SchoolDetailView.module.css +++ b/nextjs-app/components/SchoolDetailView.module.css @@ -927,42 +927,85 @@ font-variant-numeric: tabular-nums; } -/* ── Admissions progress bar ── */ -.admissionsBarWrap { - margin-bottom: 1rem; +/* ── Admissions Q&A list ── */ +.admissionsQa { + display: flex; + flex-direction: column; + margin: 0; } -.admissionsBarLabel { - font-size: 0.8125rem; +.admissionsQaRow { + display: flex; + justify-content: space-between; + align-items: baseline; + padding: 0.85rem 0; + border-bottom: 1px solid var(--border-color, #e5dfd5); + gap: 1rem; +} + +.admissionsQaRow:first-child { + padding-top: 0.35rem; +} + +.admissionsQaRow:last-child { + border-bottom: none; + padding-bottom: 0.35rem; +} + +.admissionsQaQuestion { + font-size: 0.92rem; color: var(--text-secondary, #5c564d); - margin-bottom: 0.4rem; + line-height: 1.35; + margin: 0; } -.admissionsBarLabel strong { - color: var(--text-primary, #1a1612); +.admissionsQaAnswer { + font-family: var(--font-playfair), 'Playfair Display', Georgia, serif; + font-size: 1.4rem; font-weight: 700; + color: var(--text-primary, #1a1612); + line-height: 1; + white-space: nowrap; + flex-shrink: 0; + font-variant-numeric: tabular-nums; + margin: 0; } -.admissionsBarTrack { - height: 20px; - background: var(--bg-secondary, #f3ede4); - border-radius: 10px; - overflow: hidden; - position: relative; +.admissionsQaAnswerSub { + font-size: 0.7rem; + font-weight: 500; + color: var(--text-muted, #6d685f); + margin-left: 0.35rem; + font-family: var(--font-dm-sans), 'DM Sans', sans-serif; } -.admissionsBarFill { - height: 100%; - border-radius: 10px; - transition: width 0.6s ease; +.admissionsVerdict { + margin-top: 1rem; + padding-top: 0.9rem; + border-top: 1px solid var(--border-color, #e5dfd5); + display: flex; + align-items: center; + gap: 0.6rem; + font-size: 0.85rem; + color: var(--text-secondary, #5c564d); + flex-wrap: wrap; } -.admissionsBarOversubscribed { - background: var(--accent-coral, #e07256); +.admissionsVerdictText { + line-height: 1.4; } -.admissionsBarUndersubscribed { - background: var(--accent-teal, #2d7d7d); +@media (max-width: 480px) { + .admissionsQaRow { + flex-direction: column; + align-items: flex-start; + gap: 0.25rem; + padding: 0.7rem 0; + } + + .admissionsQaAnswer { + white-space: normal; + } } /* ── History accordion ── */ diff --git a/nextjs-app/components/SchoolDetailView.tsx b/nextjs-app/components/SchoolDetailView.tsx index 971158b..27464fc 100644 --- a/nextjs-app/components/SchoolDetailView.tsx +++ b/nextjs-app/components/SchoolDetailView.tsx @@ -787,46 +787,55 @@ export function SchoolDetailView({ {admissions && (

How Hard to Get Into This School ({formatAcademicYear(admissions.year)})

- {admissions.first_preference_applications != null && admissions.places_offered != null && ( -
-
- {admissions.places_offered} places offered for {admissions.first_preference_applications} first-choice applications -
-
-
-
-
- )} - {admissions.first_preference_applications == null && admissions.oversubscribed != null && ( -
- {admissions.oversubscribed - ? '⚠ Oversubscribed' - : '✓ Not Oversubscribed'} -
- )} -
+ +
{admissions.places_offered != null && ( -
-
{isSecondary ? 'Year 7' : 'Reception'} places offered
-
{admissions.places_offered}
+
+
How many places were offered?
+
{admissions.places_offered}
)} - {admissions.total_applications != null && ( -
-
Applications received
-
{admissions.total_applications.toLocaleString()}
+ {admissions.first_preference_applications != null && ( +
+
How many families wanted this school first?
+
{admissions.first_preference_applications}
)} {admissions.first_preference_offer_pct != null && ( -
-
Families who got their first-choice
-
{formatPercentage(admissions.first_preference_offer_pct)}
+
+
How many got their first choice?
+
+ {admissions.first_preference_offers != null && admissions.first_preference_applications != null ? ( + <> + {admissions.first_preference_offers} + + of {admissions.first_preference_applications} ({formatPercentage(admissions.first_preference_offer_pct)}) + + + ) : ( + formatPercentage(admissions.first_preference_offer_pct) + )} +
)} -
+ {admissions.total_applications != null && ( +
+
How many applied in total?
+
{admissions.total_applications.toLocaleString()}
+
+ )} +
+ + {admissions.oversubscribed != null && ( +
+ + {admissions.oversubscribed ? 'Oversubscribed' : 'Not oversubscribed'} + + + {admissions.oversubscribed ? 'Demand exceeds capacity.' : 'Supply meets demand.'} + +
+ )}
)}