Files
school_compare/nextjs-app/components/SchoolRow.module.css
T
TudorandClaude Opus 5.5 ad9d3b67f7 feat(search): print the school page's type and flags in search rows
Both rows now take their type label and tags from lib/schoolFacts, so a
parent reads the same words in the list and on the page: "State school"
instead of "Academy converter", "Girls' school" instead of "Girls", the
religious character instead of "Faith priority", and a Nursery class flag
on primaries. Who-can-apply tags are outlined with an inset ring, which
keeps them the size of their neighbours; the Selective tag no longer
borrows the status colour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 22:59:45 +01:00

287 lines
7.4 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
.row {
display: flex;
align-items: center;
gap: 1rem;
background: var(--bg-card);
border: 1px solid var(--border);
border-left: 3px solid transparent;
border-radius: 8px;
padding: 1rem 1.25rem;
transition: border-color 0.15s ease, box-shadow 0.15s ease;
animation: rowFadeIn 0.3s ease-out both;
}
.row:hover {
box-shadow: 0 2px 8px rgba(var(--shadow-rgb), 0.06);
}
/* Phase border colours */
.phasePrimary { border-left-color: var(--phase-primary); }
.phaseAllThrough { border-left-color: var(--phase-all-through); }
.phaseNursery { border-left-color: var(--phase-nursery); }
.rowInCompare {
border-left-color: var(--brand);
background: var(--bg-secondary);
}
@keyframes rowFadeIn {
from { opacity: 0; transform: translateY(6px); }
to { opacity: 1; transform: translateY(0); }
}
/* ── Left content column ─────────────────────────────── */
.rowContent {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 0.35rem;
}
/* Line 1: name + ofsted */
.line1 {
display: flex;
align-items: baseline;
gap: 0.625rem;
min-width: 0;
}
.schoolName {
font-size: 0.9375rem;
font-weight: 600;
color: var(--text-primary);
text-decoration: none;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex-shrink: 1;
min-width: 0;
}
.schoolName:hover {
color: var(--brand);
}
/* Phase label pill */
.phaseLabel {
display: inline-block;
padding: 0.0625rem 0.4rem;
font-size: 0.75rem;
font-weight: 600;
line-height: 1.4;
border-radius: 4px;
white-space: nowrap;
}
.phaseLabelPrimary { background: var(--phase-primary-bg); color: var(--phase-primary-text); }
.phaseLabelAllThrough { background: var(--phase-all-through-bg); color: var(--phase-all-through-text); }
.phaseLabelNursery { background: var(--phase-nursery-bg); color: var(--phase-nursery-text); }
/* Line 2: context tags */
.line2 {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 0.35rem;
}
/* Quiet chip — one shared size/weight for every attribute (Ages, faith, etc.);
the phase pill keeps its colour but matches this sizing. */
.attr {
display: inline-block;
padding: 0.0625rem 0.4rem;
font-size: 0.75rem;
font-weight: 600;
line-height: 1.4;
border-radius: 4px;
white-space: nowrap;
background: rgba(var(--shadow-rgb), 0.05);
color: var(--text-secondary);
}
/* Changes who can apply or what it costs. Outlined, not tinted: a fact, not
a verdict. An inset ring keeps the box the size of its neighbours. */
.conditionTag {
display: inline-block;
padding: 0.0625rem 0.4rem;
font-size: 0.75rem;
font-weight: 600;
line-height: 1.4;
border-radius: 4px;
box-shadow: inset 0 0 0 1px rgba(var(--ink-rgb), 0.4);
color: var(--text-primary);
}
/* Line 3: stats */
.line3 {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 0 1.25rem;
}
.stat {
display: inline-flex;
align-items: baseline;
gap: 0.3rem;
}
.statValue {
font-variant-numeric: tabular-nums;
font-size: 0.9375rem;
font-weight: 700;
color: var(--text-primary);
font-family: var(--font-display);
display: inline-flex;
align-items: center;
gap: 0.2rem;
}
.statLabel {
font-size: 0.75rem;
color: var(--text-muted);
white-space: nowrap;
}
/* Trend arrows */
.trend {
display: inline-flex;
align-items: center;
margin-left: 1px;
}
.trendUp { color: var(--status-above); }
.trendDown { color: var(--status-below); }
.trendStable { color: var(--text-muted); }
/* Line 4: location */
.line4 {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 0;
font-size: 0.8rem;
color: var(--text-muted);
}
.line4 span:not(:last-child)::after {
content: '·';
margin: 0 0.4rem;
color: var(--border);
}
.distanceBadge {
display: inline-block;
padding: 0.0625rem 0.375rem;
font-size: 0.75rem;
font-weight: 600;
background: var(--brand);
color: var(--brand-on);
border-radius: 3px;
}
/* ── Right actions column ────────────────────────────── */
.rowActions {
display: flex;
align-items: center;
gap: 0.5rem;
flex-shrink: 0;
}
/* Equalise <a> and <button> */
.rowActions > * {
height: 2rem;
line-height: 1;
font-family: inherit;
box-sizing: border-box;
}
/* ── Ofsted badge ────────────────────────────────────── */
.ofstedBadge {
display: inline-block;
padding: 0.0625rem 0.375rem;
font-size: 0.6875rem;
font-weight: 600;
border-radius: 3px;
white-space: nowrap;
flex-shrink: 0;
line-height: 1.4;
}
.ofstedDate {
font-weight: 400;
}
.ofsted1 { background: var(--status-above-bg); color: var(--status-above); }
.ofsted2 { background: rgba(var(--status-above-rgb), 0.12); color: var(--status-above); }
.ofsted3 { background: var(--status-below-bg); color: var(--status-below); }
.ofsted4 { background: var(--status-below); color: var(--text-inverse); }
/* ── Ofsted badge variants ──────────────────────────────────────────────── */
/* ofsted1–4 already defined above; these cover the two new framework states */
.ofstedRc { background: var(--phase-secondary-text); color: var(--text-inverse); }
/* Inspected but with no overall grade (OEIF post-Sept-2024) — neutral slate,
distinct from the grey "Not yet inspected" pending state. */
.ofstedInspected { background: var(--phase-primary-bg); color: var(--phase-primary-text); }
.ofstedPending { background: var(--border); color: var(--text-muted); }
/* ── vs-national delta line (under RWM metric) ──────────────────────────── */
.vsNational { font-size: 0.7rem; color: var(--status-above); font-weight: 600; }
.vsNationalNeg { font-size: 0.7rem; color: var(--brand); font-weight: 600; }
.vsNationalFlat { font-size: 0.7rem; color: var(--text-muted); }
/* ── Mobile ──────────────────────────────────────────── */
/*
* Narrow: content full width, actions in a row beneath. Keyed to the list the
* row sits in, not the screen, because the same row fills the phone list and
* the ~430px list beside the map on desktop. HomeView makes its lists a
* `results` container; outside one, the row keeps its wide layout, which is
* why rowContainerGuard.test.ts fails if anything else renders this row.
* 608px is exact: below 769px the page pads 1rem each side, so a 640px screen
* gives a 608px list, matching the old max-width: 640px media query.
*/
@container results (max-width: 608px) {
.row {
flex-wrap: wrap;
padding: 0.875rem;
gap: 0.625rem;
}
.rowContent {
flex-basis: 100%;
}
.schoolName {
white-space: normal;
}
/* Promote the headline metric onto its own line; secondary stats
(delta vs LA, pupils) wrap below with a visible row gap. */
.line3 {
row-gap: 0.25rem;
column-gap: 1rem;
}
.line3 > .stat:first-child {
flex-basis: 100%;
}
.rowActions {
width: 100%;
gap: 0.375rem;
}
.rowActions > * {
flex: 1;
justify-content: center;
}
}
/* GIAS "Open, but proposed to close" marker */
.attrClosing {
background: var(--status-below-bg);
color: var(--status-below);
border: 1px solid var(--status-below-bg);
}