Files
school_compare/nextjs-app/components/SchoolDetailView.module.css
T
TudorandClaude Opus 4.8 2fb7faf659
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 12s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 48s
Build and Push Docker Images / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
feat(school-detail): mobile section nav becomes a menu; Compare shrinks to an icon
Fixes the cramped mobile bar where Back, the carried Compare pill and All ▾ all
competed with the scrolling section links:

- On mobile the horizontal swipe strip collapses into a single "Section: <current> ▾"
  button that opens the existing jump-to-section sheet — no fragile horizontal
  swipe, and it doubles as a "you are here" indicator.
- The carried Compare CTA becomes a compact 38px icon on mobile (compare-arrows +
  "add" badge; flips to a teal check when in the comparison), so it no longer
  crowds the section control. Desktop keeps the labelled pill.
- Back is icon-only on mobile (label hidden), text on desktop.
- Desktop is unchanged: horizontal links + All ▾, full CTA in the hero.

Both the mobile section menu and the desktop All ▾ open the same sheet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lh7Js5xSetKNzLVr9ArXLF
2026-06-30 23:27:03 +01:00

1695 lines
36 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.
.container {
width: 100%;
min-width: 0;
max-width: 100%;
}
/* Header Section */
.header {
background: var(--bg-card, white);
border: 1px solid var(--border-color, #e5dfd5);
border-radius: 10px;
padding: 1.25rem 1.5rem;
margin-bottom: 0;
box-shadow: var(--shadow-soft);
}
.headerContent {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 1.5rem;
}
.titleSection {
flex: 1;
}
.schoolName {
font-size: clamp(2rem, 5vw, 3.25rem);
font-weight: 700;
color: var(--text-primary, #1a1612);
margin-bottom: 0.5rem;
line-height: 1.1;
letter-spacing: -0.01em;
font-family: var(--font-playfair), "Playfair Display", serif;
}
.meta {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin-bottom: 0.5rem;
}
.metaItem {
font-size: 0.8125rem;
color: var(--text-secondary, #5c564d);
padding: 0.125rem 0.5rem;
background: var(--bg-secondary, #f3ede4);
border-radius: 3px;
}
.address {
font-size: 0.875rem;
color: var(--text-muted, #8a847a);
margin: 0 0 0.75rem;
}
/* Expanded header details (headteacher, website, trust, pupils) */
.headerDetails {
display: flex;
flex-wrap: wrap;
gap: 0.5rem 1.25rem;
margin-top: 0.5rem;
}
.headerDetail {
font-size: 0.8125rem;
color: var(--text-secondary, #5c564d);
}
.headerDetail strong {
color: var(--text-primary, #1a1612);
font-weight: 600;
}
.headerDetail a {
color: var(--accent-teal, #2d7d7d);
text-decoration: none;
}
.headerDetail a:hover {
text-decoration: underline;
}
/* Gender split card — sits in the Pupils & Inclusion heroStatGrid */
.genderSplitValue {
display: flex;
align-items: baseline;
gap: 0.3rem;
font-family: var(--font-playfair), "Playfair Display", Georgia, serif;
font-size: 1.55rem;
font-weight: 700;
line-height: 1;
flex-wrap: wrap;
}
.genderSplitGirls {
color: #b45778;
}
.genderSplitBoys {
color: var(--accent-teal, #2d7d7d);
}
.genderSplitLabel {
font-family: var(--font-body, inherit);
font-size: 0.78rem;
font-weight: 500;
color: var(--text-muted, #6d685f);
letter-spacing: 0;
}
.genderSplitSep {
color: var(--border-color, #c8beb0);
font-weight: 400;
font-size: 1.2rem;
padding: 0 0.1rem;
}
.genderBar {
display: flex;
height: 6px;
border-radius: 999px;
overflow: hidden;
background: var(--border-color, #e5dfd5);
width: 100%;
}
.genderBarGirls {
background: #b45778;
}
.genderBarBoys {
background: var(--accent-teal, #2d7d7d);
}
.actions {
display: flex;
gap: 0.5rem;
flex-shrink: 0;
align-self: center;
}
.btnAdd,
.btnRemove {
padding: 0.75rem 1.25rem;
font-size: 0.9375rem;
font-weight: 600;
border: none;
border-radius: 8px;
cursor: pointer;
transition: all 0.2s ease;
white-space: nowrap;
box-shadow: var(--shadow-soft, 0 2px 8px rgba(26, 22, 18, 0.08));
}
.btnAdd {
background: var(--accent-coral, #e07256);
color: white;
}
.btnAdd:hover {
background: var(--accent-coral-dark, #c45a3f);
transform: translateY(-1px);
}
.btnRemove {
background: var(--accent-teal, #2d7d7d);
color: white;
}
.btnRemove:hover {
opacity: 0.9;
}
/* ── Sticky Section Navigation ──────────────────────── */
/* Docks directly under the global header; Back and "All" stay pinned while
only the section links scroll. */
.sectionNav {
position: sticky;
top: 64px; /* global header height on desktop */
z-index: 10;
background: var(--bg-card, white);
border: 1px solid var(--border-color, #e5dfd5);
border-top: none;
border-radius: 0 0 10px 10px;
padding: 0.5rem 0.75rem;
margin-bottom: 1rem;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
display: flex;
align-items: center;
gap: 0.5rem;
}
@media (max-width: 640px) {
.sectionNav {
top: 56px; /* global header is shorter on mobile */
padding: 0.4rem 0.6rem;
gap: 0.375rem;
}
}
.sectionNavBack {
flex: none;
display: inline-flex;
align-items: center;
gap: 0.3rem;
padding: 0.3rem 0.625rem;
font-size: 0.75rem;
font-weight: 600;
color: var(--accent-coral, #e07256);
background: none;
border: 1px solid var(--border-color, #e5dfd5);
border-radius: 4px;
cursor: pointer;
white-space: nowrap;
transition: all 0.15s ease;
}
.sectionNavBack:hover {
background: var(--bg-secondary, #f3ede4);
border-color: var(--accent-coral, #e07256);
}
/* The scrolling middle: section links only. */
.sectionNavLinks {
flex: 1;
min-width: 0;
display: flex;
align-items: center;
gap: 0.375rem;
overflow-x: auto;
white-space: nowrap;
-webkit-overflow-scrolling: touch;
scrollbar-width: none;
scroll-snap-type: x proximity;
scroll-padding-inline: 0.5rem;
}
.sectionNavLinks::-webkit-scrollbar {
display: none;
}
/* Right-edge fade so users see there's more to scroll to. */
@media (max-width: 640px) {
.sectionNavLinks {
-webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
}
/* When scrolled to the end, drop the fade so the last item isn't dimmed. */
.sectionNavLinks.atEnd {
-webkit-mask-image: none;
mask-image: none;
}
}
.sectionNavLink {
display: inline-flex;
align-items: center;
padding: 0.3rem 0.625rem;
font-size: 0.75rem;
font-weight: 500;
color: var(--text-secondary, #5c564d);
text-decoration: none;
border-radius: 4px;
transition: all 0.15s ease;
white-space: nowrap;
scroll-snap-align: start;
}
@media (max-width: 640px) {
.sectionNavLink,
.sectionNavBack {
min-height: 36px;
padding: 0.5rem 0.75rem;
font-size: 0.8125rem;
}
}
.sectionNavLink:hover {
background: var(--bg-secondary, #f3ede4);
color: var(--text-primary, #1a1612);
}
.sectionNavLinkActive {
background: var(--accent-coral, #e07256);
color: white;
font-weight: 600;
}
.sectionNavLinkActive:hover {
background: var(--accent-coral-dark, #c45a3f);
color: white;
}
/* ── Mobile: the scrolling links collapse into one "section" menu button ──
(hidden on desktop, where the links fit). */
.sectionNavMenu {
display: none; /* shown only ≤640px */
flex: 1;
min-width: 0;
align-items: center;
justify-content: space-between;
gap: 0.5rem;
min-height: 38px;
padding: 0.34rem 0.7rem;
background: var(--bg-secondary, #f3ede4);
border: 1px solid var(--border-color, #e5dfd5);
border-radius: 8px;
cursor: pointer;
font-family: var(--font-dm-sans), "DM Sans", sans-serif;
color: var(--text-primary, #1a1612);
}
.sectionNavMenuCur {
display: flex;
align-items: center;
gap: 0.45rem;
min-width: 0;
}
.sectionNavMenuEyebrow {
flex: none;
font-size: 0.64rem;
font-weight: 600;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--text-muted, #6d685f);
}
.sectionNavMenuNow {
font-size: 0.85rem;
font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.sectionNavMenuChev {
flex: none;
color: var(--text-muted, #6d685f);
font-size: 0.7rem;
}
/* Compact icon version of the Compare CTA, used on mobile. */
.sectionNavCompareIcon {
display: none; /* shown only ≤640px */
position: relative;
flex: none;
align-items: center;
justify-content: center;
width: 38px;
height: 38px;
border-radius: 9px;
border: 1px solid var(--accent-coral, #e07256);
background: var(--accent-coral, #e07256);
color: white;
cursor: pointer;
transition: background 0.15s ease, border-color 0.15s ease;
}
.sectionNavCompareIcon svg {
width: 19px;
height: 19px;
}
.sectionNavCompareBadge {
position: absolute;
top: -5px;
right: -5px;
width: 16px;
height: 16px;
border-radius: 50%;
background: var(--bg-card, white);
color: var(--accent-coral-dark, #c45a3f);
border: 1.5px solid var(--accent-coral, #e07256);
display: flex;
align-items: center;
justify-content: center;
font-size: 0.7rem;
font-weight: 800;
line-height: 1;
}
.sectionNavCompareIconIn {
background: var(--bg-card, white);
border-color: var(--accent-teal, #2d7d7d);
color: var(--accent-teal, #2d7d7d);
}
/* Swap which controls show at the mobile breakpoint. */
@media (max-width: 640px) {
.sectionNavLinks,
.sectionNavCompare,
.sectionNavAll,
.sectionNavBackLabel {
display: none;
}
.sectionNavMenu {
display: flex;
}
.sectionNavCompareIcon {
display: inline-flex;
}
}
/* Compare CTA carried into the bar once the hero's button scrolls away. */
.sectionNavCompare {
flex: none;
display: inline-flex;
align-items: center;
padding: 0.34rem 0.7rem;
font-size: 0.75rem;
font-weight: 600;
color: white;
background: var(--accent-coral, #e07256);
border: 1px solid var(--accent-coral, #e07256);
border-radius: 999px;
cursor: pointer;
white-space: nowrap;
transition: all 0.15s ease;
}
.sectionNavCompare:hover {
background: var(--accent-coral-dark, #c45a3f);
border-color: var(--accent-coral-dark, #c45a3f);
}
.sectionNavCompareIn {
background: var(--bg-card, white);
color: var(--accent-teal, #2d7d7d);
border-color: var(--accent-teal, #2d7d7d);
}
.sectionNavCompareIn:hover {
background: var(--bg-secondary, #f3ede4);
border-color: var(--accent-teal, #2d7d7d);
}
@media (max-width: 640px) {
.sectionNavCompare {
min-height: 36px;
}
}
/* "All ▾" jump menu (desktop). */
.sectionNavAll {
flex: none;
display: inline-flex;
align-items: center;
gap: 0.25rem;
padding: 0.34rem 0.65rem;
font-size: 0.75rem;
font-weight: 600;
color: var(--text-primary, #1a1612);
background: var(--bg-secondary, #f3ede4);
border: none;
border-radius: 999px;
cursor: pointer;
white-space: nowrap;
transition: background 0.15s ease;
}
.sectionNavAll:hover {
background: var(--border-color, #e5dfd5);
}
@media (max-width: 640px) {
.sectionNavAll {
min-height: 36px;
}
}
.sectionsBackdrop {
position: fixed;
inset: 0;
z-index: 1500;
background: rgba(26, 22, 18, 0.28);
}
.sectionsPanel {
position: absolute;
top: calc(100% + 6px);
right: 0;
z-index: 1600;
width: 230px;
max-height: min(70vh, 460px);
overflow-y: auto;
background: var(--bg-card, white);
border: 1px solid var(--border-color, #e5dfd5);
border-radius: 12px;
box-shadow: 0 18px 44px rgba(26, 22, 18, 0.2);
padding: 0.35rem;
}
.sectionsPanelHead {
font-family: var(--font-playfair), "Playfair Display", Georgia, serif;
font-size: 0.9rem;
font-weight: 600;
color: var(--text-primary, #1a1612);
padding: 0.4rem 0.6rem 0.5rem;
}
.sectionsItem {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.5rem;
padding: 0.55rem 0.6rem;
border-radius: 8px;
font-size: 0.85rem;
color: var(--text-secondary, #5c564d);
text-decoration: none;
transition: background 0.12s ease;
}
.sectionsItem:hover {
background: var(--bg-secondary, #f3ede4);
color: var(--text-primary, #1a1612);
}
.sectionsItemActive {
background: var(--accent-coral-bg, rgba(224, 114, 86, 0.12));
color: var(--accent-coral-dark, #c45a3f);
font-weight: 600;
}
.sectionsTick {
color: var(--accent-coral, #e07256);
}
/* On phones the menu becomes a bottom sheet. */
@media (max-width: 640px) {
.sectionsPanel {
position: fixed;
top: auto;
left: 0;
right: 0;
bottom: 0;
width: auto;
max-height: 74vh;
border-radius: 16px 16px 0 0;
padding: 0.5rem 0.6rem calc(0.8rem + env(safe-area-inset-bottom, 0));
box-shadow: 0 -10px 40px rgba(26, 22, 18, 0.25);
}
.sectionsItem {
padding: 0.7rem 0.6rem;
font-size: 0.9rem;
}
}
/* Unified card for all content sections */
.card {
background: var(--bg-card, white);
border: 1px solid var(--border-color, #e5dfd5);
border-radius: 10px;
padding: 1.25rem 1.5rem;
margin-bottom: 1rem;
box-shadow: var(--shadow-soft);
scroll-margin-top: 6rem;
min-width: 0;
max-width: 100%;
}
/* Section Title */
.sectionTitle {
font-size: 1.125rem;
font-weight: 600;
color: var(--text-primary, #1a1612);
margin-bottom: 0.875rem;
padding-bottom: 0.5rem;
border-bottom: 2px solid var(--border-color, #e5dfd5);
font-family: var(--font-playfair), "Playfair Display", serif;
display: flex;
align-items: center;
gap: 0.375rem;
flex-wrap: wrap;
}
.sectionTitle::before {
content: "";
display: inline-block;
width: 3px;
height: 1em;
background: var(--accent-coral, #e07256);
border-radius: 2px;
flex-shrink: 0;
}
.sectionSubtitle {
font-size: 0.85rem;
color: var(--text-muted, #8a847a);
margin: -0.5rem 0 1rem;
}
/* Response count badge */
.responseBadge {
font-size: 0.75rem;
font-weight: 500;
font-family: var(--font-dm-sans), sans-serif;
color: var(--text-muted, #8a847a);
background: var(--bg-secondary, #f3ede4);
padding: 0.1rem 0.5rem;
border-radius: 999px;
margin-left: auto;
}
.subSectionTitle {
font-size: 0.875rem;
font-weight: 600;
color: var(--text-secondary, #5c564d);
margin: 1.25rem 0 0.75rem;
}
/* Parent recommendation line in Ofsted section */
.parentRecommendLine {
font-size: 0.85rem;
color: var(--text-secondary, #5c564d);
margin: 0.5rem 0 0;
}
.parentRecommendLine strong {
color: var(--accent-teal, #2d7d7d);
font-weight: 700;
}
/* Metrics Grid & Cards */
.metricsGrid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 0.75rem;
}
.metricCard {
background: var(--bg-secondary, #f3ede4);
border: 1px solid var(--border-color, #e5dfd5);
border-radius: 6px;
padding: 0.75rem;
text-align: center;
}
.metricLabel {
font-size: 0.6875rem;
color: var(--text-muted, #8a847a);
margin-bottom: 0.25rem;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.03em;
}
.metricValue {
font-size: 1.25rem;
font-weight: 700;
color: var(--text-primary, #1a1612);
display: flex;
align-items: center;
justify-content: center;
gap: 0.25rem;
}
.metricHint {
font-size: 0.7rem;
color: var(--text-muted, #8a847a);
margin-top: 0.3rem;
font-style: italic;
}
/* ── Hero stat cards (RWM combined, Pupils & Inclusion, etc.) ── */
/* Larger teal-tinted cards with Playfair serif numbers — reserved for
the top-of-section headline metrics. Use .metricCard for denser
secondary metrics. */
.heroStatGrid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 0.85rem;
margin-bottom: 0.25rem;
}
.heroStatCard {
background: var(--accent-teal-bg, rgba(45, 125, 125, 0.12));
border: 1px solid rgba(45, 125, 125, 0.2);
border-radius: 12px;
padding: 1rem 1.1rem;
display: flex;
flex-direction: column;
gap: 0.4rem;
text-align: left;
}
.heroStatLabel {
font-size: 0.6rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--text-muted, #6d685f);
display: flex;
align-items: center;
gap: 0.3rem;
line-height: 1.3;
}
.heroStatValue {
font-family: var(--font-playfair), "Playfair Display", Georgia, serif;
font-size: 2.1rem;
font-weight: 700;
line-height: 1;
color: var(--accent-teal, #2d7d7d);
display: flex;
align-items: baseline;
gap: 0.5rem;
flex-wrap: wrap;
justify-content: flex-start;
}
.heroStatHint {
font-size: 0.7rem;
color: var(--text-muted, #6d685f);
font-style: normal;
margin-top: 0;
}
@media (max-width: 480px) {
.heroStatGrid {
grid-template-columns: 1fr;
}
.heroStatValue {
font-size: 1.85rem;
}
}
/* Progress score colour coding */
.progressPositive {
color: var(--accent-teal, #2d7d7d);
font-weight: 700;
}
.progressNegative {
color: var(--accent-coral, #e07256);
font-weight: 700;
}
/* ── Semantic status colours (unified) ────────────── */
.statusGood {
background: var(--accent-teal-bg);
color: var(--accent-teal, #2d7d7d);
}
.statusWarn {
background: var(--accent-gold-bg);
color: #b8920e;
}
.statusBad {
background: var(--accent-coral-bg);
color: var(--accent-coral, #e07256);
}
/* Charts Section */
.chartContainer {
width: 100%;
height: 280px;
position: relative;
}
/* Detailed Metrics - Compact Grid Layout */
.metricGroupsGrid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
.metricGroup {
margin-bottom: 0;
}
.metricGroupTitle {
font-size: 0.875rem;
font-weight: 600;
color: var(--text-primary, #1a1612);
margin-bottom: 0.5rem;
padding-bottom: 0.375rem;
border-bottom: 1px solid var(--border-color, #e5dfd5);
display: flex;
align-items: center;
gap: 0.375rem;
}
.metricTable {
display: flex;
flex-direction: column;
gap: 0.375rem;
}
.metricRow {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.375rem 0.625rem;
background: var(--bg-secondary, #f3ede4);
border-radius: 4px;
}
.metricName {
font-size: 0.75rem;
color: var(--text-secondary, #5c564d);
}
.metricRow .metricValue {
font-size: 0.875rem;
font-weight: 600;
color: var(--accent-teal, #2d7d7d);
}
/* Map */
.mapContainer {
width: 100%;
height: 250px;
border-radius: 8px;
overflow: hidden;
border: 1px solid var(--border-color, #e5dfd5);
isolation: isolate;
z-index: 0;
position: relative;
}
/* History Table */
.tableWrapper {
overflow-x: auto;
max-width: 100%;
margin-top: 0.5rem;
-webkit-overflow-scrolling: touch;
}
.historicalSubtitle {
font-size: 0.8rem;
color: var(--text-muted, #8a847a);
margin: 1.25rem 0 0.25rem;
}
.dataTable {
width: 100%;
border-collapse: collapse;
font-size: 0.8125rem;
}
.dataTable thead {
background: var(--bg-secondary, #f3ede4);
}
.dataTable th {
padding: 0.625rem 0.75rem;
text-align: left;
font-weight: 600;
font-size: 0.6875rem;
text-transform: uppercase;
letter-spacing: 0.03em;
color: var(--text-primary, #1a1612);
border-bottom: 2px solid var(--border-color, #e5dfd5);
}
.dataTable td {
padding: 0.5rem 0.75rem;
border-bottom: 1px solid var(--border-color, #e5dfd5);
color: var(--text-secondary, #5c564d);
}
.dataTable tbody tr:last-child td {
border-bottom: none;
}
.dataTable tbody tr:hover {
background: var(--bg-secondary, #f3ede4);
}
.yearCell {
font-weight: 600;
color: var(--accent-gold, #c9a227);
}
/* Ofsted */
.ofstedHeader {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 0.75rem;
margin-bottom: 1rem;
}
.ofstedGrade {
display: inline-block;
padding: 0.35rem 0.75rem;
font-size: 1rem;
line-height: 1.4;
font-weight: 700;
border-radius: 6px;
white-space: nowrap;
}
.ofstedGrade1 {
background: var(--accent-teal-bg);
color: var(--accent-teal, #2d7d7d);
}
.ofstedGrade2 {
background: rgba(60, 140, 60, 0.12);
color: #3c8c3c;
}
.ofstedGrade3 {
background: var(--accent-gold-bg);
color: #b8920e;
}
.ofstedGrade4 {
background: var(--accent-coral-bg);
color: var(--accent-coral, #e07256);
}
/* Report Card grade colours (5-level scale, lower = better) */
.rcGrade1 {
background: var(--accent-teal-bg);
color: var(--accent-teal, #2d7d7d);
} /* Exceptional */
.rcGrade2 {
background: rgba(60, 140, 60, 0.12);
color: #3c8c3c;
} /* Strong */
.rcGrade3 {
background: var(--accent-gold-bg);
color: #b8920e;
} /* Expected standard */
.rcGrade4 {
background: rgba(249, 115, 22, 0.12);
color: #c2410c;
} /* Needs attention */
.rcGrade5 {
background: var(--accent-coral-bg);
color: var(--accent-coral, #e07256);
} /* Urgent improvement */
/* Safeguarding value (used inside a standard metricCard) */
.safeguardingMet {
display: inline-block;
padding: 0.2rem 0.6rem;
border-radius: 4px;
font-size: 0.8125rem;
font-weight: 600;
background: var(--accent-teal-bg);
color: var(--accent-teal, #2d7d7d);
}
.safeguardingNotMet {
display: inline-block;
padding: 0.2rem 0.6rem;
border-radius: 4px;
font-size: 0.8125rem;
font-weight: 700;
background: var(--accent-coral-bg);
color: var(--accent-coral, #e07256);
}
.ofstedDisclaimer {
font-size: 0.8rem;
color: var(--text-muted, #8a847a);
font-style: italic;
margin: 0 0 1rem;
}
.ofstedDate {
font-size: 0.85rem;
color: var(--text-muted, #8a847a);
}
.ofstedPrevious {
font-size: 0.8125rem;
color: var(--text-muted, #8a847a);
font-style: italic;
}
.ofstedReportLink {
font-size: 0.8125rem;
color: var(--accent-teal, #2d7d7d);
text-decoration: none;
margin-left: auto;
white-space: nowrap;
}
.ofstedReportLink:hover {
text-decoration: underline;
}
/* Parent View */
.parentViewGrid {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.parentViewRow {
display: flex;
align-items: center;
gap: 0.75rem;
font-size: 0.875rem;
}
.parentViewLabel {
flex: 0 0 18rem;
color: var(--text-secondary, #5c564d);
font-size: 0.8125rem;
}
.parentViewBar {
flex: 1;
height: 0.5rem;
background: var(--bg-secondary, #f3ede4);
border-radius: 4px;
overflow: hidden;
}
.parentViewFill {
height: 100%;
background: var(--accent-teal, #2d7d7d);
border-radius: 4px;
transition: width 0.4s ease;
}
.parentViewPct {
flex: 0 0 2.75rem;
text-align: right;
font-size: 0.8125rem;
font-weight: 600;
color: var(--text-primary, #1a1612);
}
/* Admissions badge — uses unified status colours */
.admissionsBadge {
display: inline-flex;
align-items: center;
gap: 0.35rem;
padding: 0.3rem 0.75rem;
border-radius: 6px;
font-size: 0.8125rem;
font-weight: 600;
margin-top: 0.75rem;
}
/* Deprivation dot scale */
.deprivationDots {
display: flex;
gap: 0.375rem;
margin: 0.75rem 0 0.5rem;
align-items: center;
}
.deprivationDot {
width: 1.25rem;
height: 1.25rem;
border-radius: 50%;
background: var(--bg-secondary, #f3ede4);
border: 2px solid var(--border-color, #e5dfd5);
flex-shrink: 0;
}
.deprivationDotFilled {
background: var(--accent-teal, #2d7d7d);
border-color: var(--accent-teal, #2d7d7d);
}
.deprivationDesc {
font-size: 0.875rem;
color: var(--text-secondary, #5c564d);
line-height: 1.5;
margin: 0;
}
.deprivationScaleLabel {
display: flex;
justify-content: space-between;
font-size: 0.7rem;
color: var(--text-muted, #8a847a);
margin-top: 0.25rem;
}
/* Progress note */
.ofstedAllSame {
font-size: 0.9375rem;
color: var(--text-secondary, #5c564d);
margin: 0.5rem 0 0;
line-height: 1.5;
}
.ofstedAllSame strong {
color: var(--text-primary, #1a1612);
}
.progressNote {
margin-top: 0.75rem;
font-size: 0.8rem;
color: var(--text-muted);
font-style: italic;
}
/* ── Responsive ──────────────────────────────────────── */
@media (max-width: 768px) {
.headerContent {
flex-direction: column;
gap: 1rem;
}
.actions {
width: 100%;
}
.btnAdd,
.btnRemove {
flex: 1;
}
.schoolName {
font-size: 1.25rem;
}
/* Pills wrap horizontally instead of stacking — short tokens like
"Manchester" / "Voluntary aided" fit 2 per row instead of 3 full
rows of empty horizontal space. */
.meta {
flex-direction: row;
flex-wrap: wrap;
gap: 0.375rem;
}
/* Secondary header info (headteacher, website, pupil count, trust)
isn't needed above the fold on phones — pupil count lives in the
Pupils & Inclusion section, website is one scroll away. Reclaim
the ~3 vertical lines so the actual metrics surface sooner. */
.headerDetails {
display: none;
}
.metricsGrid {
grid-template-columns: repeat(2, 1fr);
}
.metricGroupsGrid {
grid-template-columns: 1fr;
}
/* PerformanceChart on mobile now stacks: trend banner → chip subtitle →
chip row → canvas → mini-legend → COVID footnote. The container must
flow naturally instead of clipping to a fixed 220px — PerformanceChart's
own .chartWrapper carries the canvas height. */
.chartContainer {
height: auto;
}
.mapContainer {
height: 200px;
}
.dataTable {
font-size: 0.75rem;
}
.dataTable th,
.dataTable td {
padding: 0.5rem 0.375rem;
}
}
@media (max-width: 480px) {
.parentViewRow {
flex-direction: column;
align-items: flex-start;
gap: 0.25rem;
}
.parentViewLabel {
flex: none;
max-width: 100%;
}
.parentViewBar {
width: 100%;
}
.parentViewPct {
flex: none;
}
.card {
padding: 1rem;
}
}
/* ── Hero signal chip strip (A2) ─────────────────────────────────────── */
.heroChips {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
margin-top: 1.25rem;
}
.heroChip {
flex: 0 0 240px;
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.3;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.heroChipSub {
font-size: 0.75rem;
color: var(--text-secondary, #5c564d);
line-height: 1.4;
}
.heroChipDetail {
font-size: 0.75rem;
font-weight: 600;
line-height: 1.4;
margin-top: 0.1rem;
}
/* Hero tone scheme — independent of the .ofstedGrade{N} / .rcGrade{N} badges
so the same tone class can be applied to a chip (background tint + border)
or a serif number (colour only) without one bleeding into the other. */
.tone-teal {
--hero-tone: var(--accent-teal, #2d7d7d);
}
.tone-green {
--hero-tone: #3c8c3c;
}
.tone-gold {
--hero-tone: var(--accent-gold, #c9a227);
}
.tone-coral {
--hero-tone: var(--accent-coral, #e07256);
}
.tone-neutral {
--hero-tone: var(--text-muted, #8a847a);
}
.heroChip.tone-teal,
.heroChip.tone-green,
.heroChip.tone-gold,
.heroChip.tone-coral,
.heroChip.tone-neutral {
border-left-color: var(--hero-tone);
background: color-mix(in srgb, var(--hero-tone) 10%, var(--bg-card, white));
}
.heroChip.tone-neutral {
background: var(--bg-secondary, #f3ede4);
}
/* ── Hero at-a-glance stats (A3) ─────────────────────────────────────── */
.heroStats {
display: flex;
flex-wrap: wrap;
gap: 1.25rem 3rem;
margin-top: 1.5rem;
padding-top: 1.5rem;
border-top: 1px solid var(--border-color, #e5dfd5);
}
.heroStat {
display: flex;
flex-direction: column;
gap: 0.35rem;
min-width: 0;
flex: 0 0 auto;
}
.heroStatNumber,
.heroStatNumberSerif {
font-family: var(--font-playfair), "Playfair Display", serif;
font-weight: 700;
line-height: 1;
color: var(--text-primary, #1a1612);
/* Fixed height so every stat's label row sits at the same Y, regardless
of whether the content is a short numeral or a longer word. Each
stat's content is bottom-aligned within this box. */
min-height: clamp(2rem, 4vw, 2.75rem);
display: flex;
align-items: flex-end;
}
.heroStatNumber {
font-size: clamp(2rem, 4vw, 2.75rem);
font-variant-numeric: tabular-nums;
}
.heroStatNumberSerif {
/* Slightly smaller so long words like "Requires Improvement" still fit,
but aligned on the same bottom baseline as the numeric stats. */
font-size: clamp(1.75rem, 3.5vw, 2.25rem);
}
.heroStatNumberSerif.tone-teal,
.heroStatNumberSerif.tone-green,
.heroStatNumberSerif.tone-gold,
.heroStatNumberSerif.tone-coral,
.heroStatNumberSerif.tone-neutral {
color: var(--hero-tone);
}
.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);
}
.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%;
}
/* Collapse the "Ofsted pending / No inspection on record" empty state
into a single compact line on phones — it's a non-result, not worth
a full hero card. */
.heroChip[data-ofsted-state="none"] {
padding: 0.5rem 0.75rem;
}
.heroChip[data-ofsted-state="none"] .heroChipSub {
display: none;
}
.heroChip[data-ofsted-state="none"] .heroChipTitle {
font-size: 0.85rem;
color: var(--text-muted, #6d685f);
}
.heroStats {
gap: 1rem 1.5rem;
}
.heroSummary {
font-size: 1rem;
margin-top: 1rem;
}
}
/* ── RWM bridge ("Why is combined lower?") ── */
.rwmBridge {
display: flex;
align-items: flex-start;
gap: 0.75rem;
margin: 0.5rem 0 1.5rem;
padding: 0.9rem 1rem;
background: var(--bg-secondary, #f3ede4);
border-radius: 8px;
}
.rwmBridgeIcon {
flex-shrink: 0;
width: 22px;
height: 22px;
border-radius: 50%;
background: var(--accent-coral, #e07256);
color: #fff;
display: inline-flex;
align-items: center;
justify-content: center;
font-weight: 700;
font-size: 0.8rem;
font-family: var(--font-playfair), "Playfair Display", Georgia, serif;
margin-top: 0.05rem;
}
.rwmBridgeBody {
flex: 1;
min-width: 0;
}
.rwmBridgeText {
font-size: 0.85rem;
color: var(--text-secondary, #5c564d);
line-height: 1.5;
}
.rwmBridgeText strong {
color: var(--text-primary, #1a1612);
font-weight: 700;
}
.rwmBridgeMath {
display: flex;
gap: 0.35rem;
margin-top: 0.35rem;
flex-wrap: wrap;
font-family: var(--font-playfair), "Playfair Display", Georgia, serif;
color: var(--text-muted, #6d685f);
font-size: 0.78rem;
font-style: italic;
align-items: baseline;
}
.rwmBridgeMath strong {
color: var(--text-primary, #1a1612);
font-weight: 700;
font-style: normal;
}
.rwmBridgeMathSep {
opacity: 0.5;
}
/* ── Progress scores row (below SatsChart) ── */
.progressScoresRow {
margin-top: 1.25rem;
padding-top: 1rem;
border-top: 1px solid var(--border-color, #e5dfd5);
}
.progressScoresGrid {
display: flex;
gap: 1.5rem;
flex-wrap: wrap;
}
.progressScoreItem {
display: flex;
align-items: baseline;
gap: 0.4rem;
}
.progressScoreLabel {
font-size: 0.78rem;
font-weight: 500;
color: var(--text-muted, #6d685f);
}
.progressScoreValue {
font-size: 0.9rem;
font-weight: 700;
color: var(--text-primary, #1a1612);
font-variant-numeric: tabular-nums;
}
/* ── Admissions Q&A list ── */
/* 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;
flex-direction: column;
}
.admissionsTileNum {
font-family: var(--font-playfair), "Playfair Display", Georgia, serif;
font-size: 2.4rem;
font-weight: 700;
line-height: 1;
color: var(--text-primary, #1a1612);
font-variant-numeric: tabular-nums;
margin: 0;
display: flex;
align-items: baseline;
gap: 0.4rem;
flex-wrap: wrap;
}
.admissionsTileSub {
font-family: var(--font-dm-sans), "DM Sans", sans-serif;
font-size: 0.85rem;
font-weight: 500;
color: var(--text-muted, #6d685f);
}
.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 {
margin-top: 0.75rem;
margin-bottom: 0.25rem;
}
.admissionsVerdictHeadline {
font-family: var(--font-playfair), "Playfair Display", Georgia, serif;
font-size: 1.35rem;
font-weight: 700;
line-height: 1.2;
color: var(--text-primary, #1a1612);
}
.admissionsVerdictOver {
color: var(--accent-coral-dark, #c45a3f);
}
.admissionsVerdictUnder {
color: var(--accent-teal, #2d7d7d);
}
.admissionsVerdictSub {
font-size: 0.8rem;
color: var(--text-muted, #6d685f);
line-height: 1.4;
margin-top: 0.2rem;
}
@media (max-width: 480px) {
.admissionsTile {
padding: 0.95rem 1rem;
}
.admissionsTileNum {
font-size: 2rem;
}
}
/* ── Admissions: header + view toggle ── */
.admissionsHeader {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
flex-wrap: wrap;
margin-bottom: 1.25rem;
}
.admissionsHeader .sectionTitle {
margin-bottom: 0;
}
.admissionsSeg {
display: inline-flex;
background: var(--bg-secondary, #f3ede4);
border-radius: 999px;
padding: 3px;
gap: 2px;
flex: none;
}
.admissionsSeg button {
appearance: none;
border: none;
background: none;
cursor: pointer;
font: inherit;
font-size: 0.8125rem;
font-weight: 600;
color: var(--text-muted, #6d685f);
padding: 0.4rem 0.9rem;
border-radius: 999px;
white-space: nowrap;
transition: background 0.15s ease, color 0.15s ease;
}
.admissionsSeg button[aria-pressed="true"] {
background: var(--bg-card, #fff);
color: var(--text-primary, #1a1612);
box-shadow: var(--shadow-soft, 0 2px 8px rgba(26, 22, 18, 0.06));
}
.admissionsSeg button:hover[aria-pressed="false"] {
color: var(--text-secondary, #5c564d);
}
/* Stack both views in one grid cell so the card sizes to the taller view —
toggling modes never shifts layout. */
.admissionsViewport {
display: grid;
}
.admissionsViewYear,
.admissionsViewTrend {
grid-area: 1 / 1;
}
.admissionsViewYear[hidden],
.admissionsViewTrend[hidden] {
display: block;
visibility: hidden;
pointer-events: none;
}
/* The tile grid fills the height reserved by the taller (trend) view. */
.admissionsViewYear {
display: flex;
flex-direction: column;
}
.admissionsViewYear .admissionsTiles {
flex: 1;
grid-template-rows: 1fr 1fr;
}
.admissionsChartCap {
font-size: 0.8125rem;
font-weight: 600;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--text-muted, #6d685f);
margin-bottom: 0.5rem;
}
.admissionsTrendSummary {
font-size: 1rem;
color: var(--text-secondary, #5c564d);
margin: 1.25rem 0 0;
padding-top: 1.1rem;
border-top: 1px solid var(--border-color, #e5dfd5);
line-height: 1.5;
}
.admissionsTrendSummary strong {
color: var(--text-primary, #1a1612);
}
/* ── History accordion ── */
.historyDisclosure {
margin-top: 1rem;
}
.historyToggle {
font-size: 0.8125rem;
font-weight: 600;
color: var(--text-muted, #6d685f);
cursor: pointer;
padding: 0.5rem 0;
list-style: none;
display: flex;
align-items: center;
gap: 0.4rem;
}
.historyToggle::-webkit-details-marker {
display: none;
}
.historyToggle::before {
content: "▸";
display: inline-block;
transition: transform 0.2s ease;
font-size: 0.7rem;
}
.historyDisclosure[open] > .historyToggle::before {
transform: rotate(90deg);
}