feat(school-detail): editorial hero with signal chips, at-a-glance stats, summary
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 15s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 51s
Build and Push Docker Images / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 0s

Elevates the primary school detail hero from a flat report header into a
scannable editorial block. Parents can read the headline signal in seconds.

- A1: bump .schoolName to clamp(2rem, 5vw, 3.25rem) Playfair.
- A2: framework-aware signal chip strip via new buildOfstedHeroChip() helper.
  Branches on ofsted.framework so Report Card schools never show a fake
  overall grade — they get "Ofsted Report Card" + inspection date +
  Safeguarding: Met/Not met. OEIF schools keep the grade word.
- A3: oversized Playfair stats — Reading, Writing & Maths % (primary) or
  Attainment 8 (secondary) with inline DeltaChip vs national, Ofsted
  verdict with tone colouring, and first-choice offer rate.
- B1: italic serif one-sentence summary via buildSchoolSummary() helper,
  also framework-aware so Report Card schools are described by framework,
  not a synthetic grade.
- C1: new DeltaChip component reused in the two headline KS2 metric cards
  (rwm_expected_pct, rwm_high_pct).

All copy uses "Reading, Writing & Maths" in full. Secondary detail view
untouched in this slice.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Tudor Sitaru
2026-04-08 10:32:33 +01:00
parent f053b35c6f
commit c749d72a6a
5 changed files with 563 additions and 6 deletions
@@ -26,11 +26,12 @@
}
.schoolName {
font-size: 1.5rem;
font-size: clamp(2rem, 5vw, 3.25rem);
font-weight: 700;
color: var(--text-primary, #1a1612);
margin-bottom: 0.5rem;
line-height: 1.2;
line-height: 1.1;
letter-spacing: -0.01em;
font-family: var(--font-playfair), 'Playfair Display', serif;
}
@@ -715,3 +716,171 @@
padding: 1rem;
}
}
/* ── Hero signal chip strip (A2) ─────────────────────────────────────── */
.heroChips {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
margin-top: 1.25rem;
}
.heroChip {
min-width: 180px;
flex: 0 1 auto;
padding: 0.75rem 1rem;
border-radius: 8px;
border-left: 3px solid var(--border-color, #e5dfd5);
background: var(--bg-secondary, #f3ede4);
color: var(--text-primary, #1a1612);
display: flex;
flex-direction: column;
gap: 0.15rem;
}
.heroChipTitle {
font-size: 0.9375rem;
font-weight: 700;
line-height: 1.25;
}
.heroChipSub {
font-size: 0.75rem;
color: var(--text-secondary, #5c564d);
line-height: 1.35;
}
.heroChipDetail {
font-size: 0.75rem;
font-weight: 600;
margin-top: 0.15rem;
}
/* Tone variants — keep consistent with .ofstedGrade{N} / .rcGrade{N} */
.heroChip.ofstedGrade1,
.heroChip.rcGrade1,
.heroChip.rcGrade2,
.heroChipGood {
background: var(--accent-teal-bg, rgba(45, 125, 125, 0.08));
border-left-color: var(--accent-teal, #2d7d7d);
}
.heroChip.ofstedGrade2 {
background: rgba(60, 140, 60, 0.08);
border-left-color: #3c8c3c;
}
.heroChip.ofstedGrade3,
.heroChip.rcGrade3,
.heroChipWarn {
background: var(--accent-gold-bg, rgba(201, 162, 39, 0.10));
border-left-color: var(--accent-gold, #c9a227);
}
.heroChip.ofstedGrade4,
.heroChip.rcGrade4,
.heroChip.rcGrade5 {
background: var(--accent-coral-bg, rgba(224, 114, 86, 0.10));
border-left-color: var(--accent-coral, #e07256);
}
.heroChip.heroChipNeutral {
background: var(--bg-secondary, #f3ede4);
border-left-color: var(--border-color, #e5dfd5);
color: var(--text-muted, #8a847a);
}
/* ── Hero at-a-glance stats (A3) ─────────────────────────────────────── */
.heroStats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 1.5rem 2rem;
margin-top: 1.5rem;
padding-top: 1.5rem;
border-top: 1px solid var(--border-color, #e5dfd5);
}
.heroStat {
display: flex;
flex-direction: column;
gap: 0.25rem;
min-width: 0;
}
.heroStatNumber {
font-family: var(--font-playfair), 'Playfair Display', serif;
font-size: clamp(2rem, 4vw, 2.75rem);
font-weight: 700;
line-height: 1;
color: var(--text-primary, #1a1612);
font-variant-numeric: tabular-nums;
}
.heroStatNumberSerif {
font-family: var(--font-playfair), 'Playfair Display', serif;
font-size: clamp(1.5rem, 3vw, 2rem);
font-weight: 700;
line-height: 1.1;
color: var(--text-primary, #1a1612);
}
.heroStatNumberSerif.ofstedGrade1 { color: var(--accent-teal, #2d7d7d); }
.heroStatNumberSerif.ofstedGrade2 { color: #3c8c3c; }
.heroStatNumberSerif.ofstedGrade3 { color: #b8920e; }
.heroStatNumberSerif.ofstedGrade4 { color: var(--accent-coral, #e07256); }
.heroStatNumberSerif.rcGrade1 { color: var(--accent-teal, #2d7d7d); }
.heroStatNumberSerif.rcGrade2 { color: #3c8c3c; }
.heroStatNumberSerif.rcGrade3 { color: #b8920e; }
.heroStatNumberSerif.rcGrade4 { color: #c2410c; }
.heroStatNumberSerif.rcGrade5 { color: var(--accent-coral, #e07256); }
.heroStatLabel {
font-size: 0.6875rem;
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--text-secondary, #5c564d);
}
.heroStatFoot {
font-size: 0.75rem;
color: var(--text-muted, #8a847a);
}
/* ── Hero summary sentence (B1) ──────────────────────────────────────── */
.heroSummary {
margin: 1.5rem 0 0;
font-family: var(--font-playfair), 'Playfair Display', serif;
font-size: clamp(1.0625rem, 1.6vw, 1.25rem);
font-style: italic;
line-height: 1.5;
color: var(--text-primary, #1a1612);
max-width: 64ch;
}
.heroDataNote {
margin: 0.5rem 0 0;
font-size: 0.75rem;
color: var(--text-muted, #8a847a);
}
@media (max-width: 640px) {
.heroChips {
gap: 0.5rem;
margin-top: 1rem;
}
.heroChip {
min-width: 100%;
}
.heroStats {
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
.heroSummary {
font-size: 1rem;
margin-top: 1rem;
}
}