From c49593d4d6b2ef589358444a3f64db3692c1decc Mon Sep 17 00:00:00 2001 From: Tudor Date: Tue, 24 Mar 2026 09:27:22 +0000 Subject: [PATCH] feat(row): redesign to clean 3-line layout with stats on second row MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Line 1: school name (bold) + school type (muted gray) Line 2: R,W&M % · Progress score + band · Pupil count Line 3: local authority · distance (location searches) Actions (View / Add) are vertically centred on the right across all lines. Progress uses reading score, falling back to writing then maths. Removed the old nameScore grouping and separate meta/progress rows in favour of the cleaner 3-line structure. Co-Authored-By: Claude Sonnet 4.6 --- nextjs-app/components/SchoolRow.module.css | 204 ++++++++------------- nextjs-app/components/SchoolRow.tsx | 204 ++++++++++----------- 2 files changed, 171 insertions(+), 237 deletions(-) diff --git a/nextjs-app/components/SchoolRow.module.css b/nextjs-app/components/SchoolRow.module.css index 3538a81..bf0bc16 100644 --- a/nextjs-app/components/SchoolRow.module.css +++ b/nextjs-app/components/SchoolRow.module.css @@ -1,10 +1,12 @@ .row { display: flex; + align-items: center; + gap: 1rem; background: var(--bg-card, white); border: 1px solid var(--border-color, #e5dfd5); border-left: 3px solid transparent; border-radius: 8px; - padding: 0.875rem 1rem; + padding: 0.75rem 1rem; transition: border-color 0.15s ease, box-shadow 0.15s ease; animation: rowFadeIn 0.3s ease-out both; } @@ -20,37 +22,24 @@ } @keyframes rowFadeIn { - from { - opacity: 0; - transform: translateY(8px); - } - to { - opacity: 1; - transform: translateY(0); - } + from { opacity: 0; transform: translateY(6px); } + to { opacity: 1; transform: translateY(0); } } -.rowMain { +/* ── Left content column ─────────────────────────────── */ +.rowContent { flex: 1; min-width: 0; display: flex; flex-direction: column; - gap: 0.3rem; + gap: 0.2rem; } -/* Line 1: name+score on the left, actions pinned right */ -.rowTop { - display: flex; - align-items: center; - gap: 1rem; -} - -/* Name + score grouped together on the left */ -.nameScore { +/* Line 1: name + type */ +.line1 { display: flex; align-items: baseline; - gap: 0.75rem; - flex: 1; + gap: 0.625rem; min-width: 0; } @@ -62,65 +51,89 @@ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - min-width: 0; flex-shrink: 1; + min-width: 0; } .schoolName:hover { color: var(--accent-coral, #e07256); } -/* Score block: value + label inline */ -.scoreBlock { - display: flex; - align-items: baseline; - gap: 0.3rem; - flex-shrink: 0; +.schoolType { + font-size: 0.8rem; + color: var(--text-muted, #8a847a); white-space: nowrap; + flex-shrink: 0; } -.scoreValue { - font-size: 1.0625rem; +/* Line 2: stats */ +.line2 { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 0 1.25rem; +} + +.stat { + display: inline-flex; + align-items: baseline; + gap: 0.3rem; +} + +.statValue { + font-size: 0.9375rem; font-weight: 700; color: var(--text-primary, #1a1612); font-family: var(--font-playfair), 'Playfair Display', serif; - line-height: 1.2; - display: flex; + display: inline-flex; align-items: center; gap: 0.2rem; } -.scoreNA { - font-size: 1rem; - color: var(--text-muted, #8a847a); -} - -.scoreLabel { +.statLabel { font-size: 0.75rem; color: var(--text-muted, #8a847a); white-space: nowrap; } -/* Trend arrow */ +/* Trend arrows */ .trend { display: inline-flex; align-items: center; - margin-left: 2px; + margin-left: 1px; } -.trendUp { - color: var(--accent-teal, #2d7d7d); -} +.trendUp { color: var(--accent-teal, #2d7d7d); } +.trendDown { color: var(--accent-coral, #e07256); } +.trendStable { color: var(--text-muted, #8a847a); } -.trendDown { - color: var(--accent-coral, #e07256); -} - -.trendStable { +/* Line 3: location */ +.line3 { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 0 0; + font-size: 0.8rem; color: var(--text-muted, #8a847a); } -/* Action buttons — pinned right, slightly larger on desktop */ +.line3 span:not(:last-child)::after { + content: '·'; + margin: 0 0.4rem; + color: var(--border-color, #e5dfd5); +} + +.distanceBadge { + display: inline-block; + padding: 0.0625rem 0.375rem; + font-size: 0.75rem; + font-weight: 600; + background: var(--accent-teal, #2d7d7d); + color: white; + border-radius: 3px; +} + +/* ── Right actions column ────────────────────────────── */ .rowActions { display: flex; align-items: center; @@ -128,7 +141,7 @@ flex-shrink: 0; } -/* Equalise and - )} - + {/* Line 1: School name + type */} +
+ + {school.school_name} + + {school.school_type && ( + {school.school_type} + )}
- {/* Line 2: Meta tags */} -
- {school.local_authority && {school.local_authority}} - {school.school_type && {school.school_type}} - {!isLocationSearch && - school.religious_denomination && - school.religious_denomination !== 'Does not apply' && ( - {school.religious_denomination} - )} + {/* Line 2: Key stats */} +
+ {school.rwm_expected_pct != null ? ( + + + {formatPercentage(school.rwm_expected_pct, 0)} + + {school.prev_rwm_expected_pct != null && ( + + {trend === 'up' && ( + + + + )} + {trend === 'down' && ( + + + + )} + {trend === 'stable' && ( + + + + )} + + )} + R, W & M + + ) : ( + + + R, W & M + + )} + + {progressScore != null && ( + + {formatProgress(progressScore)} + + progress · {progressBand(progressScore)} + + + )} + + {school.total_pupils != null && ( + + {school.total_pupils.toLocaleString()} + pupils + + )} +
+ + {/* Line 3: Location + distance */} +
+ {school.local_authority && ( + {school.local_authority} + )} {isLocationSearch && school.distance != null && ( {school.distance.toFixed(1)} mi )} + {!isLocationSearch && + school.religious_denomination && + school.religious_denomination !== 'Does not apply' && ( + {school.religious_denomination} + )}
- {/* Line 3: Progress scores with plain-language bands */} - {hasProgress && ( -
- {school.reading_progress != null && ( - - Reading{' '} - - {formatProgress(school.reading_progress)} - - - {progressBand(school.reading_progress)} - - - )} - {school.writing_progress != null && ( - - Writing{' '} - - {formatProgress(school.writing_progress)} - - - {progressBand(school.writing_progress)} - - - )} - {school.maths_progress != null && ( - - Maths{' '} - - {formatProgress(school.maths_progress)} - - - {progressBand(school.maths_progress)} - - - )} -
+
+ + {/* Right: actions, vertically centred */} +
+ + View + + {(onAddToCompare || onRemoveFromCompare) && ( + )}