PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 18s
PR Checks / Build Frontend (no push) (pull_request) Successful in 45s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 1m14s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 9s
The Share column keyed off `percentage === null`, which is true for not_applicable as well as suppressed, so a destination that does not apply to the school was labelled as one DfE withheld — while the Pupils column in the same row rendered blank. Two columns, one row, disagreeing about what the row was, and one of them making a claim about DfE that wasn't true. Both columns now derive from `status`, which is the distinction the mart, the SQLAlchemy model and the serialiser all preserve deliberately: published shows the figure, suppressed shows the withheld badge, not_applicable shows an em-dash with a title saying so. A published count with no published percentage now derives its share from the cohort rather than falling through to a marker — both halves are published, so nothing withheld is involved, and it is the same derivation the bar widths already use. Verified the new tests fail against the old logic before keeping them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BvdDKvFFSZuMVDH5fEyTob
308 lines
7.8 KiB
CSS
308 lines
7.8 KiB
CSS
/*
|
|
* Destination sections.
|
|
*
|
|
* Every colour comes from the --dest-* tokens in globals.css, which are
|
|
* defined in both themes. Nothing here is a literal colour — see
|
|
* __tests__/components/darkThemeSafety.test.ts for why.
|
|
*/
|
|
|
|
.view {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 1.5rem;
|
|
}
|
|
|
|
/* ── Cohort switch ─────────────────────────────────────────────────────── */
|
|
|
|
.switchRow {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.switchLabel {
|
|
font-size: var(--step--2);
|
|
font-weight: 600;
|
|
letter-spacing: 0.06em;
|
|
text-transform: uppercase;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.switchButtons {
|
|
display: inline-flex;
|
|
flex-wrap: wrap;
|
|
gap: 2px;
|
|
padding: 2px;
|
|
background: var(--bg-secondary);
|
|
border-radius: var(--radius-md);
|
|
align-self: flex-start;
|
|
}
|
|
|
|
.switchButton {
|
|
appearance: none;
|
|
border: none;
|
|
background: transparent;
|
|
font: inherit;
|
|
font-size: var(--step--1);
|
|
font-weight: 600;
|
|
color: var(--text-secondary);
|
|
padding: 0.5rem 0.9rem;
|
|
border-radius: calc(var(--radius-md) - 2px);
|
|
cursor: pointer;
|
|
white-space: nowrap;
|
|
transition: background var(--transition), color var(--transition);
|
|
}
|
|
|
|
.switchButton:hover { color: var(--text-primary); }
|
|
.switchButton:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
|
|
|
|
.switchButton[aria-checked='true'] {
|
|
background: var(--bg-card);
|
|
color: var(--text-primary);
|
|
box-shadow: var(--shadow-soft);
|
|
}
|
|
|
|
.switchCount {
|
|
margin-left: 0.4rem;
|
|
font-weight: 500;
|
|
color: var(--text-muted);
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
/* ── Question cards ────────────────────────────────────────────────────── */
|
|
|
|
.cards {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
|
|
gap: 0.75rem;
|
|
}
|
|
|
|
.card {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.35rem;
|
|
text-align: left;
|
|
font: inherit;
|
|
background: var(--brand-bg);
|
|
border: 1px solid transparent;
|
|
border-radius: var(--radius-md);
|
|
padding: 1.15rem 1.25rem;
|
|
cursor: pointer;
|
|
transition: border-color var(--transition), opacity var(--transition);
|
|
}
|
|
|
|
.card:hover { border-color: var(--brand); }
|
|
.card:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
|
|
|
|
.cardWithheld {
|
|
background: var(--bg-secondary);
|
|
border-style: dashed;
|
|
border-color: var(--border-strong);
|
|
cursor: default;
|
|
}
|
|
|
|
.cardQuestion {
|
|
font-family: var(--font-display);
|
|
font-size: var(--step--1);
|
|
font-weight: 700;
|
|
color: var(--text-primary);
|
|
text-wrap: balance;
|
|
}
|
|
|
|
.cardValue {
|
|
font-family: var(--font-display);
|
|
font-size: var(--step-3);
|
|
font-weight: 800;
|
|
line-height: 1.05;
|
|
letter-spacing: -0.02em;
|
|
font-variant-numeric: tabular-nums;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.cardWithheldValue {
|
|
font-family: var(--font-display);
|
|
font-size: var(--step-1);
|
|
font-weight: 700;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.cardHint {
|
|
font-size: var(--step--2);
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.cardKeys {
|
|
display: flex;
|
|
gap: 0.3rem;
|
|
margin-top: 0.2rem;
|
|
}
|
|
|
|
.cardKeys .swatch {
|
|
width: 1.5rem;
|
|
height: 0.35rem;
|
|
border-radius: 2px;
|
|
}
|
|
|
|
/* ── Bar ───────────────────────────────────────────────────────────────── */
|
|
|
|
.barBlock {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
/* 2px surface gaps between segments so adjacent fills stay distinguishable
|
|
without a border darkening the palette. */
|
|
.bar {
|
|
display: flex;
|
|
gap: 2px;
|
|
height: 3rem;
|
|
border-radius: var(--radius-sm);
|
|
overflow: hidden;
|
|
background: var(--bg-card);
|
|
}
|
|
|
|
.segment {
|
|
display: grid;
|
|
place-items: center;
|
|
min-width: 2px;
|
|
overflow: hidden;
|
|
color: var(--text-inverse);
|
|
font-size: var(--step--2);
|
|
font-weight: 700;
|
|
font-variant-numeric: tabular-nums;
|
|
transition: opacity var(--transition);
|
|
}
|
|
|
|
.barScale {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
font-size: var(--step--2);
|
|
color: var(--text-muted);
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
/* ── Category colours ──────────────────────────────────────────────────── */
|
|
|
|
.higher_education,
|
|
.school_sixth_form { background: var(--dest-sixthform); }
|
|
.sixth_form_college { background: var(--dest-sfcollege); }
|
|
.further_education,
|
|
.other_education { background: var(--dest-fecollege); color: var(--text-primary); }
|
|
.apprenticeship { background: var(--dest-apprentice); }
|
|
.employment { background: var(--dest-employment); }
|
|
|
|
/* The absence is hatched neutral, never a colour: "activity not captured"
|
|
covers independent schools, moving abroad and training the department holds
|
|
no data on, so a red segment would state something false. The hatch is also
|
|
the secondary encoding that separates it from the employment blue. */
|
|
.not_sustained,
|
|
.not_captured {
|
|
background-color: var(--bg-card);
|
|
background-image: repeating-linear-gradient(
|
|
45deg,
|
|
var(--dest-none-hatch) 0 3px,
|
|
transparent 3px 7px
|
|
);
|
|
box-shadow: inset 0 0 0 1px var(--dest-none);
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.swatch {
|
|
display: inline-block;
|
|
width: 0.9rem;
|
|
height: 0.9rem;
|
|
border-radius: 3px;
|
|
flex: none;
|
|
}
|
|
|
|
/* ── Dimming, for the card-to-bar linkage ──────────────────────────────── */
|
|
|
|
.dim { opacity: 0.3; }
|
|
|
|
/* ── Withheld panel ────────────────────────────────────────────────────── */
|
|
|
|
.withheldPanel {
|
|
background: var(--bg-secondary);
|
|
border-radius: var(--radius-md);
|
|
padding: 1.15rem 1.25rem;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.withheldTitle {
|
|
font-family: var(--font-display);
|
|
font-size: var(--step--1);
|
|
font-weight: 700;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.withheldBody {
|
|
margin: 0;
|
|
font-size: var(--step--1);
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.withheldMark {
|
|
display: inline-block;
|
|
font-size: var(--step--2);
|
|
font-weight: 700;
|
|
color: var(--text-muted);
|
|
background: var(--bg-secondary);
|
|
border: 1px dashed var(--border-strong);
|
|
border-radius: 999px;
|
|
padding: 0.1rem 0.5rem;
|
|
}
|
|
|
|
/* ── Table ─────────────────────────────────────────────────────────────── */
|
|
|
|
.tableWrap { overflow-x: auto; }
|
|
|
|
.table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
font-size: var(--step--1);
|
|
}
|
|
|
|
.table th,
|
|
.table td {
|
|
padding: 0.55rem 0;
|
|
border-bottom: 1px solid var(--border);
|
|
text-align: right;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
.table thead th {
|
|
font-size: var(--step--2);
|
|
font-weight: 600;
|
|
letter-spacing: 0.05em;
|
|
text-transform: uppercase;
|
|
color: var(--text-muted);
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.table th:first-child { text-align: left; }
|
|
|
|
.rowName {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.6rem;
|
|
font-weight: 500;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.footnote {
|
|
margin: 0;
|
|
font-size: var(--step--2);
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
/* A destination that does not apply to this school. Deliberately not the
|
|
withheld badge: "we are not told" and "there is nothing to tell" are
|
|
different statements, and the rest of the pipeline keeps them apart. */
|
|
.notApplicable {
|
|
color: var(--text-muted);
|
|
cursor: help;
|
|
}
|