diff --git a/nextjs-app/components/school/schoolSections.module.css b/nextjs-app/components/school/schoolSections.module.css new file mode 100644 index 0000000..8ec039a --- /dev/null +++ b/nextjs-app/components/school/schoolSections.module.css @@ -0,0 +1,1945 @@ +.container { + width: 100%; + min-width: 0; + max-width: 100%; +} + +/* Standalone back link, sits above the header card on the page background. */ +.topBack { + display: inline-flex; + align-items: center; + gap: 0.4rem; + margin: 0 0 0.75rem; + padding: 0.25rem 0; + font-size: 1.0625rem; + font-weight: 600; + color: var(--accent-coral-dark, #b04a2e); + background: none; + border: none; + cursor: pointer; + line-height: 1.2; + transition: color 0.15s ease; +} + +.topBack:hover { + color: var(--accent-coral-dark, #c85a3e); + text-decoration: underline; + text-underline-offset: 2px; +} + +/* Header Section */ +.header { + position: relative; + background: var(--bg-card, white); + border: 1px solid var(--border-color, #e5dfd5); + border-radius: 10px; + /* Padding lives on .headerContent so the map band can bleed to the edges. */ + padding: 0; + margin-bottom: 0; + box-shadow: var(--shadow-soft); + overflow: hidden; +} + +.headerContent { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 1.5rem; + padding: 1.25rem 1.5rem; +} + +/* With a map band above, slide the title up under the fade so map and title + read as one object; the Compare button floats glassy over the map. */ +.headerHasMap .headerContent { + padding-top: 0; + margin-top: -0.5rem; +} + +/* The title (not the whole content row) rises above the map fade. Keeping + .headerContent unpositioned matters: .actions must anchor to .header so it + floats over the map band, not over the title. */ +.headerHasMap .titleSection { + position: relative; + z-index: 3; +} + +.headerHasMap .actions { + position: absolute; + top: 14px; + right: 14px; + z-index: 6; + margin: 0; + /* Beat the mobile `.actions { width: 100% }` rule — a floating button + must never stretch across the title. */ + width: auto; +} + +.headerHasMap .actions .btnAdd { + background: rgba(255, 255, 255, 0.9); + color: var(--accent-coral-dark, #b04a2e); + border-color: transparent; + -webkit-backdrop-filter: blur(6px); + backdrop-filter: blur(6px); + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.16); +} + +.headerHasMap .actions .btnAdd:hover { + background: #fff; +} + +/* Full label by default; phones over the map get an icon-only button + (same compact treatment as the section-nav compare icon). */ +.btnCompareGlyph { + display: none; +} + +@media (max-width: 640px) { + .headerHasMap .actions .btnCompareLabel { + display: none; + } + + .headerHasMap .actions .btnCompareGlyph { + display: inline; + } + + .headerHasMap .actions .btnAdd, + .headerHasMap .actions .btnRemove { + display: inline-flex; + align-items: center; + justify-content: center; + flex: none; + width: 40px; + height: 40px; + padding: 0; + border-radius: 999px; + font-size: 1.375rem; + line-height: 1; + } +} + +/* Inline "View on map ↗" trigger next to the address. */ +.mapLink { + border: none; + background: none; + padding: 0; + font: inherit; + font-weight: 600; + color: var(--accent-coral-dark, #b04a2e); + cursor: pointer; + white-space: nowrap; +} + +.mapLink:hover { + color: var(--accent-coral-dark, #c45a3f); + text-decoration: underline; + text-underline-offset: 2px; +} + +.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; + overflow-wrap: break-word; +} + +.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; + overflow-wrap: break-word; +} + +/* 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; +} + +/* "Show all details" reveal — only rendered on mobile/tablet, where the + header details block is collapsed below the fold. Hidden on desktop. */ +.detailsToggle { + display: none; + align-items: center; + gap: 0.25rem; + margin-top: 0.5rem; + padding: 0; + background: none; + border: none; + font-size: 0.8125rem; + font-weight: 600; + color: var(--accent-teal, #2d7d7d); + cursor: pointer; +} + +/* 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: #a04a68; +} + +.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: #a04a68; +} + +.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-dark, #b04a2e); + color: white; +} + +.btnAdd:hover { + background: var(--accent-coral-darker, #9c3f26); + 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-dark, #b04a2e); + 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-dark, #b04a2e); + 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-dark, #b04a2e); + background: var(--accent-coral-dark, #b04a2e); + 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); +} + +/* 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-dark, #b04a2e); + border: 1px solid var(--accent-coral-dark, #b04a2e); + border-radius: 999px; + cursor: pointer; + white-space: nowrap; + transition: all 0.15s ease; +} + +.sectionNavCompare:hover { + background: var(--accent-coral-darker, #9c3f26); + border-color: var(--accent-coral-darker, #9c3f26); +} + +.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-dark, #b04a2e); +} + +/* 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; + } +} + +/* Swap which controls show at the mobile breakpoint. Declared last so these + display rules win over the base (equal-specificity) declarations above. */ +@media (max-width: 640px) { + .sectionNavLinks, + .sectionNavCompare, + .sectionNavAll, + .sectionNavBackLabel { + display: none; + } + + .sectionNavMenu { + display: flex; + } + + .sectionNavCompareIcon { + display: inline-flex; + } +} + +/* 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; + overflow-wrap: break-word; + min-width: 0; +} + +.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; +} + +.subSectionTitle { + font-size: 0.875rem; + font-weight: 600; + color: var(--text-secondary, #5c564d); + margin: 1.25rem 0 0.75rem; +} + +/* 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; + overflow-wrap: break-word; + word-break: break-word; +} + +.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-dark, #b04a2e); + 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: var(--accent-gold-text, #7a6800); +} + +.statusBad { + background: var(--accent-coral-bg); + color: var(--accent-coral-dark, #b04a2e); +} + +/* Charts Section */ +.chartContainer { + width: 100%; + /* Taller on desktop so the trend lines have vertical room to separate + and read clearly. Mobile overrides this to height:auto below (the + max-width:768px query), so this only affects desktop. */ + height: 380px; + 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); +} + +/* 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: #2f7a2f; +} +.ofstedGrade3 { + background: var(--accent-gold-bg); + color: var(--accent-gold-text, #7a6800); +} +.ofstedGrade4 { + background: var(--accent-coral-bg); + color: var(--accent-coral-dark, #b04a2e); +} + +/* 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: #2f7a2f; +} /* Strong */ +.rcGrade3 { + background: var(--accent-gold-bg); + color: var(--accent-gold-text, #7a6800); +} /* Expected standard */ +.rcGrade4 { + background: rgba(249, 115, 22, 0.12); + color: #c2410c; +} /* Needs attention */ +.rcGrade5 { + background: var(--accent-coral-bg); + color: var(--accent-coral-dark, #b04a2e); +} /* 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-dark, #b04a2e); +} + +/* ── Ofsted grade grids (Report Card + OEIF) ── + Uniform, vertically-aligned grade chips. Labels reserve two lines so + single- and double-line labels put their chips on the same baseline; + every chip (Met, Strong, Expected standard, …) shares one font size, + padding and min-height regardless of how many lines its text wraps to. */ +.gradeGrid .metricCard { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.5rem; + padding: 0.85rem 0.75rem; +} +.gradeGrid .metricLabel { + min-height: 2.6em; + margin: 0; + display: flex; + align-items: center; + justify-content: center; + text-align: center; +} +.gradeGrid .metricValue { + margin-top: auto; + display: inline-flex; + align-items: center; + justify-content: center; + max-width: 100%; + min-height: 2.6em; + padding: 0.3rem 0.7rem; + border-radius: 5px; + font-size: 1rem; + font-weight: 700; + line-height: 1.25; + text-align: center; +} + +.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; +} + +/* 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; + word-break: break-word; + } + + /* 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, + contact, area) isn't needed above the fold on phones/tablets, so it's + collapsed by default and revealed on demand via the "Show all details" + link — reclaiming the vertical space so the metrics surface sooner. */ + .detailsToggle { + display: inline-flex; + } + + .headerDetails { + display: none; + } + + .headerDetailsOpen { + display: flex; + flex-direction: column; + gap: 0.375rem; + } + + .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; + } + + .dataTable { + font-size: 0.75rem; + } + + .dataTable th, + .dataTable td { + padding: 0.5rem 0.375rem; + } +} + +@media (max-width: 480px) { + .card { + padding: 1rem; + } +} + +/* .heroStatLabel is shared by the SATs / Pupils stat cards below. */ +.heroStatLabel { + font-size: 0.6875rem; + font-weight: 600; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--text-secondary, #5c564d); +} + +@media (max-width: 640px) { + .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; + user-select: none; +} + +.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); +} + +/* GIAS "Open, but proposed to close" notice strip */ +.closingStrip { + background: #fdf6e3; + border-left: 4px solid #e2c96f; + border-radius: 0 6px 6px 0; + padding: 0.55rem 0.9rem; + margin: 0.5rem 0; + font-size: 0.88rem; + color: #6e5a00; + max-width: 68ch; +} +.closingStrip strong { + color: #8a6200; +} +/* ── Secondary-only rules, merged from SecondarySchoolDetailView.module.css ── */ +.badges { + display: flex; + flex-wrap: wrap; + gap: 0.375rem; + margin-bottom: 0.5rem; +} +.badge { + font-size: 0.8125rem; + color: var(--text-secondary, #5c564d); + padding: 0.125rem 0.5rem; + background: var(--bg-secondary, #f3ede4); + border-radius: 3px; +} +.badgeSelective { + background: rgba(180, 120, 0, 0.1); + color: #8a6200; +} +.badgeFaith { + background: rgba(45, 125, 125, 0.1); + color: var(--accent-teal, #2d7d7d); +} +/* ── Tab Navigation (sticky) ─────────────────────────── */ +.tabNav { + position: sticky; + top: 4rem; + 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 1rem; + margin-bottom: 1rem; + overflow-x: auto; + white-space: nowrap; + -webkit-overflow-scrolling: touch; + scrollbar-width: none; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04); +} +.tabNav::-webkit-scrollbar { + display: none; +} +.tabNavInner { + display: inline-flex; + gap: 0.25rem; + align-items: center; +} +.backBtn { + display: inline-flex; + align-items: center; + padding: 0.3rem 0.625rem; + font-size: 0.75rem; + font-weight: 600; + color: var(--accent-coral-dark, #b04a2e); + background: none; + border: 1px solid var(--border-color, #e5dfd5); + border-radius: 4px; + cursor: pointer; + white-space: nowrap; + transition: all 0.15s ease; + margin-right: 0.25rem; +} +.backBtn:hover { + background: var(--bg-secondary, #f3ede4); + border-color: var(--accent-coral, #e07256); +} +.tabNavDivider { + width: 1px; + height: 1rem; + background: var(--border-color, #e5dfd5); + margin: 0 0.25rem; + flex-shrink: 0; +} +.tabBtn { + display: inline-block; + padding: 0.3rem 0.75rem; + font-size: 0.75rem; + font-weight: 500; + color: var(--text-secondary, #5c564d); + background: none; + border: none; + border-radius: 4px; + cursor: pointer; + transition: all 0.15s ease; + white-space: nowrap; + text-decoration: none; +} +.tabBtn:hover { + background: var(--bg-secondary, #f3ede4); + color: var(--text-primary, #1a1612); +} +.tabBtnActive { + background: var(--accent-coral-dark, #b04a2e); + color: white; + font-weight: 600; +} +.tabBtnActive:hover { + background: var(--accent-coral-darker, #9c3f26); + color: white; +} +/* ── Progress 8 suspension banner ───────────────────── */ +.p8Banner { + background: rgba(180, 120, 0, 0.1); + border: 1px solid rgba(180, 120, 0, 0.3); + color: #8a6200; + border-radius: 6px; + padding: 0.625rem 0.875rem; + font-size: 0.825rem; + margin-bottom: 1rem; + line-height: 1.5; +} +/* ── Admissions ──────────────────────────────────────── */ +.admissionsTypeBadge { + border-radius: 6px; + padding: 0.5rem 0.875rem; + font-size: 0.8125rem; + margin-bottom: 1rem; + line-height: 1.5; +} +.admissionsSelective { + background: rgba(180, 120, 0, 0.1); + color: #8a6200; + border: 1px solid rgba(180, 120, 0, 0.25); +} +.admissionsFaith { + background: rgba(45, 125, 125, 0.08); + color: var(--accent-teal, #2d7d7d); + border: 1px solid rgba(45, 125, 125, 0.2); +} +.sixthFormNote { + margin-top: 1rem; + padding: 0.625rem 0.875rem; + background: var(--bg-secondary, #f3ede4); + border-radius: 6px; + font-size: 0.825rem; + color: var(--text-secondary, #5c564d); + border-left: 3px solid var(--accent-teal, #2d7d7d); +} +.genderSplitHint { + font-size: 0.7rem; + color: var(--text-muted, #6d685f); + margin-top: 0.35rem; + font-weight: 500; +} +/* ── Attainment 8 visual bar ─────────────────────────── */ +.att8Viz { + margin: 1.25rem 0 0.5rem; +} +.att8VizLabel { + font-size: 0.6875rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.07em; + color: var(--text-muted, #6d685f); + margin-bottom: 0.5rem; +} +.att8VizTrack { + position: relative; + height: 14px; + background: rgba(45, 125, 125, 0.08); + border: 1px solid var(--border-color, #e5dfd5); + border-radius: 4px; + overflow: visible; +} +.att8VizFill { + height: 100%; + background: var(--accent-teal, #2d7d7d); + border-radius: 4px 0 0 4px; + transition: width 0.6s ease; +} +.att8VizNatLine { + position: absolute; + top: -4px; + bottom: -4px; + width: 2px; + background: var(--accent-coral, #e07256); + border-radius: 2px; + z-index: 2; +} +.att8VizNatPill { + position: absolute; + top: -20px; + transform: translateX(-50%); + background: var(--accent-coral-dark, #b04a2e); + color: #fff; + font-size: 0.6rem; + font-weight: 700; + padding: 0.1rem 0.3rem; + border-radius: 3px; + white-space: nowrap; +} +.att8VizTicks { + display: flex; + justify-content: space-between; + margin-top: 0.25rem; + font-size: 0.6rem; + color: var(--text-muted, #6d685f); +} +/* ── Progress 8 number line ──────────────────────────── */ +.p8Viz { + margin: 1.25rem 0 0.5rem; +} +.p8VizLabel { + font-size: 0.6875rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.07em; + color: var(--text-muted, #6d685f); + margin-bottom: 0.5rem; +} +.p8VizTrack { + position: relative; + height: 14px; + background: rgba(45, 125, 125, 0.06); + border: 1px solid var(--border-color, #e5dfd5); + border-radius: 4px; + overflow: visible; +} +.p8VizCi { + position: absolute; + top: 0; + bottom: 0; + background: rgba(45, 125, 125, 0.18); + border-radius: 3px; +} +.p8VizZero { + position: absolute; + top: -4px; + bottom: -4px; + width: 2px; + background: var(--border-color, #e5dfd5); + z-index: 1; +} +.p8VizDot { + position: absolute; + top: 50%; + transform: translate(-50%, -50%); + width: 12px; + height: 12px; + border-radius: 50%; + background: var(--accent-teal, #2d7d7d); + border: 2px solid white; + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); + z-index: 3; +} +.p8VizDotNeg { + background: var(--accent-coral, #e07256); +} +.p8VizTicks { + display: flex; + justify-content: space-between; + margin-top: 0.25rem; + font-size: 0.6rem; + color: var(--text-muted, #6d685f); +} + +/* ── Secondary variants ─────────────────────────────────────────────────── + Three rules differ between the primary and secondary detail pages in ways + that are genuinely visual rather than incidental drift. Rather than pick a + winner (which would change one of the two pages) they are kept as explicit + variant classes, so the divergence is deliberate and reviewable instead of + accidental. Sections select them via a `variant` prop. */ + +/* Secondary renders a slimmer gender bar on a translucent track. */ +.genderBarSecondary { + height: 4px; + background: rgba(0, 0, 0, 0.08); + margin-top: 0.45rem; +} + +/* Secondary emphasises the split figures. */ +.genderSplitBoysSecondary { + font-weight: 600; +} + +.genderSplitGirlsSecondary { + font-weight: 600; +} + +/* Secondary hero stats sit tighter and omit the Georgia fallback. */ +.heroStatValueSecondary { + gap: 0.4rem; + font-family: var(--font-playfair), "Playfair Display", serif; +} + +/* ── Secondary-scoped overrides ────────────────────────────────────────── + These rules exist only in the secondary stylesheet but target class names + the primary page also uses (.card, .sectionTitle, .metricCard …). Applied + flat they would restyle the primary page, so they are scoped to a wrapper + class that only SecondarySchoolSections carries. Same principle as the + variant classes above, applied at rule scope. */ + +.secondaryScope .heroStatCard .heroStatLabel { font-size: 0.6rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted, #6d685f); } +.secondaryScope .heroStatCard .heroStatValue { font-family: var(--font-playfair), "Playfair Display", serif; font-size: 2.1rem; font-weight: 700; line-height: 1; color: var(--accent-teal, #2d7d7d); display: flex; align-items: baseline; gap: 0.4rem; flex-wrap: wrap; } +.secondaryScope .heroStatCard .heroStatHint { font-size: 0.7rem; color: var(--text-muted, #6d685f); font-style: normal; margin-top: 0; } +.secondaryScope .historyDisclosure[open] .historyToggle::before { transform: rotate(90deg); } +@media (max-width: 480px) { + .secondaryScope .metricsGrid { grid-template-columns: 1fr 1fr; gap: 0.5rem; } + .secondaryScope .metricCard { padding: 0.5rem; } + .secondaryScope .metricLabel { font-size: 0.625rem; } +} +@media (max-width: 768px) { + .secondaryScope .header { padding: 1rem; } + .secondaryScope .badges { gap: 0.25rem; } + .secondaryScope .badge { font-size: 0.75rem; padding: 0.1rem 0.375rem; } + .secondaryScope .metricValue { font-size: 1rem; } + .secondaryScope .heroStatGrid { grid-template-columns: 1fr; } + .secondaryScope .heroStatCard .heroStatValue { font-size: 1.85rem; } + .secondaryScope .card { padding: 1rem; } + .secondaryScope .sectionTitle { font-size: 1rem; } + .secondaryScope .ofstedReportLink { margin-left: 0; display: block; margin-top: 0.25rem; } + .secondaryScope .admissionsTypeBadge { font-size: 0.75rem; } +}