feat(detail): move religious character into header details + mobile reveal

Religious character now sits with the other labelled header details (near
County / Constituency) as "Religious character: <denomination>" ("None" for
Does not apply / None), instead of as an identity chip.

On mobile/tablet (≤768px) the header details block was hidden outright; it's
now collapsed behind a "Show all details" toggle that reveals the full block
(headteacher, website, pupils, trust, phone, religious character, county,
constituency). Applied to both the primary and secondary detail views for
parity. Extends the e2e journey with the mobile toggle behaviour.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Tudor
2026-07-24 12:18:12 +01:00
co-authored by Claude Opus 4.8
parent a102508ef1
commit ed8c396eb9
5 changed files with 124 additions and 20 deletions
@@ -197,6 +197,22 @@
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;
@@ -1205,14 +1221,24 @@
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. */
/* 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);
}
+25 -8
View File
@@ -99,6 +99,9 @@ export function SchoolDetailView({
const heroMapRef = useRef<SchoolHeroMapHandle>(null);
// "All ▾" jump menu listing every section.
const [sectionsOpen, setSectionsOpen] = useState(false);
// Header details (headteacher, contact, trust, area) collapse behind a
// "Show all details" link on mobile/tablet, where they're below the fold.
const [detailsOpen, setDetailsOpen] = useState(false);
// Back returns to wherever the user came from; deep-links (no in-app history)
// fall back to search so the button never dead-ends or leaves the site.
@@ -354,13 +357,6 @@ export function SchoolDetailView({
{schoolInfo.age_range && (
<span className={styles.metaItem}>{formatAgeRange(schoolInfo.age_range)}</span>
)}
{schoolInfo.religious_denomination && (
<span className={styles.metaItem}>
{['Does not apply', 'None'].includes(schoolInfo.religious_denomination)
? 'None'
: schoolInfo.religious_denomination}
</span>
)}
{schoolInfo.nursery_provision && (
<span className={styles.metaItem}>Nursery</span>
)}
@@ -391,7 +387,20 @@ export function SchoolDetailView({
)}
</p>
)}
<div className={styles.headerDetails}>
<button
type="button"
className={styles.detailsToggle}
aria-expanded={detailsOpen}
aria-controls="school-header-details"
onClick={() => setDetailsOpen((o) => !o)}
>
{detailsOpen ? 'Hide details' : 'Show all details'}
<span aria-hidden="true">{detailsOpen ? '▴' : '▾'}</span>
</button>
<div
id="school-header-details"
className={`${styles.headerDetails}${detailsOpen ? ` ${styles.headerDetailsOpen}` : ''}`}
>
{schoolInfo.headteacher_name && (
<span className={styles.headerDetail}>
<strong>Headteacher:</strong> {schoolInfo.headteacher_name}
@@ -433,6 +442,14 @@ export function SchoolDetailView({
</a>
</span>
)}
{schoolInfo.religious_denomination && (
<span className={styles.headerDetail}>
<strong>Religious character:</strong>{' '}
{['Does not apply', 'None'].includes(schoolInfo.religious_denomination)
? 'None'
: schoolInfo.religious_denomination}
</span>
)}
{schoolInfo.county && (
<span className={styles.headerDetail}>
<strong>County:</strong> {schoolInfo.county}
@@ -207,6 +207,22 @@
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;
}
.actions {
display: flex;
gap: 0.5rem;
@@ -1066,7 +1082,18 @@
padding: 0.1rem 0.375rem;
}
/* Collapsed below the fold on phones/tablets; revealed via "Show all
details" so the metrics surface sooner. */
.detailsToggle {
display: inline-flex;
}
.headerDetails {
display: none;
}
.headerDetailsOpen {
display: flex;
flex-direction: column;
gap: 0.375rem;
}
@@ -83,6 +83,8 @@ export function SecondarySchoolDetailView({
const isInComparison = isSelected(schoolInfo.urn);
const [activeSection, setActiveSection] = useState<string>('');
// Header details collapse behind a "Show all details" link on mobile/tablet.
const [detailsOpen, setDetailsOpen] = useState(false);
const latestResults = yearlyData.length > 0 ? yearlyData[yearlyData.length - 1] : null;
@@ -246,13 +248,6 @@ export function SecondarySchoolDetailView({
{schoolInfo.age_range && (
<span className={styles.badge}>{formatAgeRange(schoolInfo.age_range)}</span>
)}
{schoolInfo.religious_denomination && (
<span className={styles.badge}>
{['Does not apply', 'None'].includes(schoolInfo.religious_denomination)
? 'None'
: schoolInfo.religious_denomination}
</span>
)}
{schoolInfo.nursery_provision && (
<span className={styles.badge}>Nursery</span>
)}
@@ -288,7 +283,20 @@ export function SecondarySchoolDetailView({
)}
</p>
)}
<div className={styles.headerDetails}>
<button
type="button"
className={styles.detailsToggle}
aria-expanded={detailsOpen}
aria-controls="school-header-details"
onClick={() => setDetailsOpen((o) => !o)}
>
{detailsOpen ? 'Hide details' : 'Show all details'}
<span aria-hidden="true">{detailsOpen ? '▴' : '▾'}</span>
</button>
<div
id="school-header-details"
className={`${styles.headerDetails}${detailsOpen ? ` ${styles.headerDetailsOpen}` : ''}`}
>
{schoolInfo.headteacher_name && (
<span className={styles.headerDetail}>
<strong>Headteacher:</strong> {schoolInfo.headteacher_name}
@@ -326,6 +334,14 @@ export function SecondarySchoolDetailView({
</a>
</span>
)}
{schoolInfo.religious_denomination && (
<span className={styles.headerDetail}>
<strong>Religious character:</strong>{' '}
{['Does not apply', 'None'].includes(schoolInfo.religious_denomination)
? 'None'
: schoolInfo.religious_denomination}
</span>
)}
{schoolInfo.county && (
<span className={styles.headerDetail}>
<strong>County:</strong> {schoolInfo.county}