From 99b769ca9edfaf1ee9f5425a2c618b8bb5a73467 Mon Sep 17 00:00:00 2001 From: Tudor Date: Thu, 16 Jul 2026 21:27:25 +0100 Subject: [PATCH] feat(compare): fill the sticky bar's label rail with a comparison caption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'COMPARING / 3 primary schools' — 0.72rem uppercase eyebrow over a 0.95rem semibold count, sized to sit alongside the 0.92rem chip names without dominating. Desktop only; mobile pills unchanged. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB --- e2e/tests/journeys.spec.ts | 2 ++ .../components/ComparisonView.phase.test.tsx | 2 ++ .../components/ComparisonView.module.css | 33 +++++++++++++++++-- nextjs-app/components/ComparisonView.tsx | 8 +++++ 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/e2e/tests/journeys.spec.ts b/e2e/tests/journeys.spec.ts index 7b01cf7..b9261e5 100644 --- a/e2e/tests/journeys.spec.ts +++ b/e2e/tests/journeys.spec.ts @@ -204,6 +204,8 @@ test('comparing two schools shows the parent-first sections side by side', async .locator('[aria-label="Schools in this comparison"]') .evaluate((el) => getComputedStyle(el).gridTemplateColumns); expect(barTemplate).toMatch(/^200px /); + // ...and its label rail carries the comparison caption. + await expect(page.getByText(/^\d+ (primary|secondary) schools?$/)).toBeVisible(); // Ofsted linkout goes to the school's provider page, never a report deep-link const ofstedLink = page.getByRole('link', { name: /Ofsted page/i }).first(); diff --git a/nextjs-app/__tests__/components/ComparisonView.phase.test.tsx b/nextjs-app/__tests__/components/ComparisonView.phase.test.tsx index 4fd5716..1bf7938 100644 --- a/nextjs-app/__tests__/components/ComparisonView.phase.test.tsx +++ b/nextjs-app/__tests__/components/ComparisonView.phase.test.tsx @@ -72,5 +72,7 @@ test('an all-secondary comparison renders the sections, not an empty primary tab }); expect(screen.getAllByText('Gamma High').length).toBeGreaterThan(0); expect(screen.queryByText(/No primary schools in your comparison/)).toBeNull(); + // The sticky bar's rail caption reflects the active phase and count. + expect(screen.getByText('2 secondary schools')).toBeInTheDocument(); expect(fetchComparison).not.toHaveBeenCalled(); }); diff --git a/nextjs-app/components/ComparisonView.module.css b/nextjs-app/components/ComparisonView.module.css index d4de534..932b132 100644 --- a/nextjs-app/components/ComparisonView.module.css +++ b/nextjs-app/components/ComparisonView.module.css @@ -148,10 +148,16 @@ text-overflow: ellipsis; } +/* Caption filling the label rail on desktop ("Comparing / 3 primary + schools"). Hidden on mobile, where the bar is a row of compact pills. */ +.barCaption { + display: none; +} + /* Desktop (matches the sections' 761px breakpoint): the bar adopts the same grid template as compareSections' .grid — a 200px row-label rail plus one column per school — so each chip sits exactly over the column it labels. - The first chip starts after the empty label rail. */ + The caption occupies the rail; chips flow into the school columns. */ @media (min-width: 761px) { .schoolBar { display: grid; @@ -164,8 +170,29 @@ min-width: 0; } - .schoolChip:first-child { - grid-column: 2; + .barCaption { + grid-column: 1; + display: flex; + flex-direction: column; + justify-content: center; + gap: 0.1rem; + padding-right: 0.5rem; + min-width: 0; + } + + .barCaptionEyebrow { + font-size: 0.72rem; + font-weight: 600; + letter-spacing: 0.06em; + text-transform: uppercase; + color: var(--text-muted, #6d685f); + } + + .barCaptionCount { + font-size: 0.95rem; + font-weight: 600; + line-height: 1.3; + color: var(--text-primary, #1a1612); } } diff --git a/nextjs-app/components/ComparisonView.tsx b/nextjs-app/components/ComparisonView.tsx index 1733a5e..e1e2c0e 100644 --- a/nextjs-app/components/ComparisonView.tsx +++ b/nextjs-app/components/ComparisonView.tsx @@ -350,6 +350,14 @@ export function ComparisonView({ style={{ '--school-count': activeSchools.length } as CSSProperties} aria-label="Schools in this comparison" > + {/* Fills the 200px label rail on desktop (hidden on mobile). */} +
+ Comparing + + {activeSchools.length} {comparePhase} school + {activeSchools.length === 1 ? '' : 's'} + +
{activeSchools.map((school, index) => (