feat(admissions): replace sparse Q&A list with 2×2 stat tiles
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 58s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m2s
Build and Push Docker Images / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 2m4s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 0s

The "How Hard to Get Into This School" this-year view rendered four
question/answer rows stretched to fill the trend chart's height, leaving
tall gaps and a long horizontal jump from a small muted question to its
number. Replace with a 2×2 grid of stat tiles — each number paired with
its label directly beneath — so the panel reads quickly and fills the
reserved height without artificial spacing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Tudor
2026-06-30 16:07:54 +01:00
co-authored by Claude Opus 4.8
parent 2de1c4e766
commit c40a6a949c
2 changed files with 61 additions and 61 deletions
@@ -1203,55 +1203,58 @@
} }
/* ── Admissions Q&A list ── */ /* ── Admissions Q&A list ── */
.admissionsQa { /* 2×2 stat tiles — number and label grouped together so the eye
doesn't travel the full card width. Hairline grid via gap + bg. */
.admissionsTiles {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1px;
background: var(--border-color, #e5dfd5);
border: 1px solid var(--border-color, #e5dfd5);
border-radius: 10px;
overflow: hidden;
margin: 0;
}
.admissionsTile {
background: var(--bg-card, #fff);
padding: 1.15rem 1.25rem;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin: 0;
} }
.admissionsQaRow { .admissionsTileNum {
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);
line-height: 1.35;
margin: 0;
}
.admissionsQaAnswer {
font-family: var(--font-playfair), "Playfair Display", Georgia, serif; font-family: var(--font-playfair), "Playfair Display", Georgia, serif;
font-size: 1.4rem; font-size: 2.4rem;
font-weight: 700; font-weight: 700;
color: var(--text-primary, #1a1612);
line-height: 1; line-height: 1;
white-space: nowrap; color: var(--text-primary, #1a1612);
flex-shrink: 0;
font-variant-numeric: tabular-nums; font-variant-numeric: tabular-nums;
margin: 0; margin: 0;
display: flex;
align-items: baseline;
gap: 0.4rem;
flex-wrap: wrap;
} }
.admissionsQaAnswerSub { .admissionsTileSub {
font-size: 0.7rem; font-family: var(--font-dm-sans), "DM Sans", sans-serif;
font-size: 0.85rem;
font-weight: 500; font-weight: 500;
color: var(--text-muted, #6d685f); color: var(--text-muted, #6d685f);
margin-left: 0.35rem; }
font-family: var(--font-dm-sans), "DM Sans", sans-serif;
.admissionsTileLabel {
margin: 0.55rem 0 0;
font-size: 0.78rem;
font-weight: 600;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--text-muted, #6d685f);
}
.admissionsTileAccent .admissionsTileNum {
color: var(--accent-coral-dark, #c45a3f);
} }
.admissionsVerdict { .admissionsVerdict {
@@ -1283,15 +1286,12 @@
} }
@media (max-width: 480px) { @media (max-width: 480px) {
.admissionsQaRow { .admissionsTile {
flex-direction: column; padding: 0.95rem 1rem;
align-items: flex-start;
gap: 0.25rem;
padding: 0.7rem 0;
} }
.admissionsQaAnswer { .admissionsTileNum {
white-space: normal; font-size: 2rem;
} }
} }
@@ -1361,15 +1361,15 @@
pointer-events: none; pointer-events: none;
} }
/* The this-year rows spread to fill the height reserved by the taller view. */ /* The tile grid fills the height reserved by the taller (trend) view. */
.admissionsViewYear { .admissionsViewYear {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.admissionsViewYear .admissionsQa { .admissionsViewYear .admissionsTiles {
flex: 1; flex: 1;
justify-content: space-between; grid-template-rows: 1fr 1fr;
} }
.admissionsChartCap { .admissionsChartCap {
+15 -15
View File
@@ -905,40 +905,40 @@ export function SchoolDetailView({
<div className={styles.admissionsViewport}> <div className={styles.admissionsViewport}>
{/* This-year Q&A */} {/* This-year Q&A */}
<div className={styles.admissionsViewYear} hidden={showAdmissionsTrend && admissionsView !== 'year'}> <div className={styles.admissionsViewYear} hidden={showAdmissionsTrend && admissionsView !== 'year'}>
<dl className={styles.admissionsQa}> <dl className={styles.admissionsTiles}>
{admissions.places_offered != null && ( {admissions.places_offered != null && (
<div className={styles.admissionsQaRow}> <div className={styles.admissionsTile}>
<dt className={styles.admissionsQaQuestion}>How many places were offered?</dt> <dd className={styles.admissionsTileNum}>{admissions.places_offered}</dd>
<dd className={styles.admissionsQaAnswer}>{admissions.places_offered}</dd> <dt className={styles.admissionsTileLabel}>Places offered</dt>
</div> </div>
)} )}
{admissions.first_preference_applications != null && ( {admissions.first_preference_applications != null && (
<div className={styles.admissionsQaRow}> <div className={styles.admissionsTile}>
<dt className={styles.admissionsQaQuestion}>How many families wanted this school first?</dt> <dd className={styles.admissionsTileNum}>{admissions.first_preference_applications}</dd>
<dd className={styles.admissionsQaAnswer}>{admissions.first_preference_applications}</dd> <dt className={styles.admissionsTileLabel}>Wanted it first</dt>
</div> </div>
)} )}
{admissions.first_preference_offer_pct != null && ( {admissions.first_preference_offer_pct != null && (
<div className={styles.admissionsQaRow}> <div className={`${styles.admissionsTile} ${styles.admissionsTileAccent}`}>
<dt className={styles.admissionsQaQuestion}>How many got their first choice?</dt> <dd className={styles.admissionsTileNum}>
<dd className={styles.admissionsQaAnswer}>
{admissions.first_preference_offers != null && admissions.first_preference_applications != null ? ( {admissions.first_preference_offers != null && admissions.first_preference_applications != null ? (
<> <>
{admissions.first_preference_offers} {admissions.first_preference_offers}
<span className={styles.admissionsQaAnswerSub}> <span className={styles.admissionsTileSub}>
of {admissions.first_preference_applications} ({formatPercentage(admissions.first_preference_offer_pct)}) of {admissions.first_preference_applications} · {formatPercentage(admissions.first_preference_offer_pct)}
</span> </span>
</> </>
) : ( ) : (
formatPercentage(admissions.first_preference_offer_pct) formatPercentage(admissions.first_preference_offer_pct)
)} )}
</dd> </dd>
<dt className={styles.admissionsTileLabel}>Got their first choice</dt>
</div> </div>
)} )}
{admissions.total_applications != null && ( {admissions.total_applications != null && (
<div className={styles.admissionsQaRow}> <div className={styles.admissionsTile}>
<dt className={styles.admissionsQaQuestion}>How many applied in total?</dt> <dd className={styles.admissionsTileNum}>{admissions.total_applications.toLocaleString()}</dd>
<dd className={styles.admissionsQaAnswer}>{admissions.total_applications.toLocaleString()}</dd> <dt className={styles.admissionsTileLabel}>Applied in total</dt>
</div> </div>
)} )}
</dl> </dl>