fix(brand): match the below-average tint to its own hue, and finish the casing
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 6s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 43s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 3m19s
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 6s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 43s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 3m19s
Three review findings. --status-below-bg carried the raw --coral tuple (249,115,96) instead of the hue it belongs to (#A9481F → 169,72,31), so "below average" chips rendered a coral-pink wash behind terracotta text — the one solid/tint pair in the file whose hues disagreed. Alpha drops 0.15 → 0.12 to match --status-above-bg, so the two chips read as equal weight; left at 0.15 the darker terracotta tint takes the label to 4.45:1 on Warm White, under the 4.5 floor. At 0.12 it is 4.86:1 on cards and 4.67:1 on Warm White. Auditing the whole file for the same class of error turned up one more: --action-bg was also a --coral tint while --action is the darkened #BE3C27. It is unused today and the dark-theme value was already correct, but it is aligned so a future coral ghost button gets a matching label and ground. The five phase pairs also "mismatch" by the same test and are deliberately left alone: those pair a pastel ground (sage, sky, mustard, lavender) with a deeper text hue, which is exactly what the guideline's Chips/Tags show. The lowercase wordmark had only reached the visual chrome. Every user-visible occurrence now matches: page title and template, appleWebApp title, authors, OpenGraph and Twitter titles and siteName, the school page's siteName, the PWA manifest name and short_name, the footer copyright line, the nav's aria-label, the Web Share API strings, and the editorial paragraph. Comments in lib/*.ts and AdmissionsView still say "SchoolCompare"; they describe the codebase rather than the mark, so they are left to keep this diff to the reported problem. The comment explaining why the font classes belong on <html> still described --font-schibsted, which no longer exists. It now names --font-manrope and --font-inter, and records that the e2e typeface assertion is the only guard — this failure mode throws nothing and fails no unit test. Verified: tsc clean, 159/159 tests, build green, and the rendered title is now "School Admissions Guide | schoolcompare". Status and phase labels re-checked on their own composited tints over both light grounds — all clear AA.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SchoolCompare — "Find the right school. For their future."
|
* schoolcompare — "Find the right school. For their future."
|
||||||
*
|
*
|
||||||
* Implements the schoolcompare brand guideline. Colour has four jobs and they
|
* Implements the schoolcompare brand guideline. Colour has four jobs and they
|
||||||
* never borrow each other's hues:
|
* never borrow each other's hues:
|
||||||
@@ -51,7 +51,9 @@
|
|||||||
--action: #BE3C27; /* darkened coral — 5.4:1 under a white label */
|
--action: #BE3C27; /* darkened coral — 5.4:1 under a white label */
|
||||||
--action-strong: #A33320;
|
--action-strong: #A33320;
|
||||||
--action-stronger: #8C2B1B;
|
--action-stronger: #8C2B1B;
|
||||||
--action-bg: rgba(249, 115, 96, 0.14);
|
/* Tint of --action, not of --coral, so a coral ghost button's label and
|
||||||
|
ground share a hue. Unused today; the dark value was already correct. */
|
||||||
|
--action-bg: rgba(190, 60, 39, 0.14);
|
||||||
--action-on: #FFFFFF;
|
--action-on: #FFFFFF;
|
||||||
|
|
||||||
/* ── Palette accents: exact brand values, for fills and tints only ── */
|
/* ── Palette accents: exact brand values, for fills and tints only ── */
|
||||||
@@ -67,7 +69,13 @@
|
|||||||
--status-above: #36743F;
|
--status-above: #36743F;
|
||||||
--status-above-bg: rgba(54, 116, 63, 0.12);
|
--status-above-bg: rgba(54, 116, 63, 0.12);
|
||||||
--status-below: #A9481F;
|
--status-below: #A9481F;
|
||||||
--status-below-bg: rgba(249, 115, 96, 0.15);
|
/* The tint is the solid hue at low alpha, exactly as every other pair in
|
||||||
|
this file is. It briefly carried the raw --coral tuple instead, which
|
||||||
|
put a coral-pink wash behind terracotta text — the one mismatched pair
|
||||||
|
in the palette. Alpha matches --status-above-bg so the two chips read
|
||||||
|
as equal weight; at 0.15 the darker terracotta tint drops the label to
|
||||||
|
4.45:1 on Warm White. */
|
||||||
|
--status-below-bg: rgba(169, 72, 31, 0.12);
|
||||||
--status-at: #5F6A75;
|
--status-at: #5F6A75;
|
||||||
--status-at-bg: rgba(95, 106, 117, 0.10);
|
--status-at-bg: rgba(95, 106, 117, 0.10);
|
||||||
|
|
||||||
|
|||||||
+14
-13
@@ -43,16 +43,16 @@ export const viewport: Viewport = {
|
|||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
appleWebApp: {
|
appleWebApp: {
|
||||||
capable: true,
|
capable: true,
|
||||||
title: 'SchoolCompare',
|
title: 'schoolcompare',
|
||||||
statusBarStyle: 'default',
|
statusBarStyle: 'default',
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
default: 'SchoolCompare | Compare School Performance',
|
default: 'schoolcompare | Compare School Performance',
|
||||||
template: '%s | SchoolCompare',
|
template: '%s | schoolcompare',
|
||||||
},
|
},
|
||||||
description: 'Compare primary and secondary school SATs and GCSE performance across England',
|
description: 'Compare primary and secondary school SATs and GCSE performance across England',
|
||||||
keywords: 'school comparison, KS2 results, KS4 results, primary school, secondary school, England schools, SATs results, GCSE results',
|
keywords: 'school comparison, KS2 results, KS4 results, primary school, secondary school, England schools, SATs results, GCSE results',
|
||||||
authors: [{ name: 'SchoolCompare' }],
|
authors: [{ name: 'schoolcompare' }],
|
||||||
manifest: '/manifest.json',
|
manifest: '/manifest.json',
|
||||||
// No `icons` key on purpose: setting it here would override the file
|
// No `icons` key on purpose: setting it here would override the file
|
||||||
// conventions. app/icon.svg and app/apple-icon.tsx are the source, and
|
// conventions. app/icon.svg and app/apple-icon.tsx are the source, and
|
||||||
@@ -60,15 +60,15 @@ export const metadata: Metadata = {
|
|||||||
metadataBase: new URL('https://schoolcompare.co.uk'),
|
metadataBase: new URL('https://schoolcompare.co.uk'),
|
||||||
openGraph: {
|
openGraph: {
|
||||||
type: 'website',
|
type: 'website',
|
||||||
title: 'SchoolCompare | Compare School Performance',
|
title: 'schoolcompare | Compare School Performance',
|
||||||
description: 'Compare primary and secondary school SATs and GCSE performance across England',
|
description: 'Compare primary and secondary school SATs and GCSE performance across England',
|
||||||
url: 'https://schoolcompare.co.uk',
|
url: 'https://schoolcompare.co.uk',
|
||||||
siteName: 'SchoolCompare',
|
siteName: 'schoolcompare',
|
||||||
},
|
},
|
||||||
twitter: {
|
twitter: {
|
||||||
// summary_large_image now that there is an image worth showing.
|
// summary_large_image now that there is an image worth showing.
|
||||||
card: 'summary_large_image',
|
card: 'summary_large_image',
|
||||||
title: 'SchoolCompare | Compare School Performance',
|
title: 'schoolcompare | Compare School Performance',
|
||||||
description: 'Compare primary and secondary school SATs and GCSE performance across England',
|
description: 'Compare primary and secondary school SATs and GCSE performance across England',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -80,12 +80,13 @@ export default function RootLayout({
|
|||||||
}>) {
|
}>) {
|
||||||
return (
|
return (
|
||||||
// The font variable classes must sit on <html>, not <body>. globals.css
|
// The font variable classes must sit on <html>, not <body>. globals.css
|
||||||
// declares --font-display/--font-ui on :root as var(--font-schibsted),
|
// declares --font-display on :root as var(--font-manrope) and --font-ui as
|
||||||
// and a custom property's var() references resolve on the element that
|
// var(--font-inter), and a custom property's var() references resolve on
|
||||||
// declares it. With the classes on <body>, --font-schibsted was undefined
|
// the element that declares it. With the classes on <body>, those two are
|
||||||
// at :root, so --font-display computed to the guaranteed-invalid value and
|
// undefined at :root, so --font-display computes to the guaranteed-invalid
|
||||||
// every font-family that referenced it silently fell back — the whole site
|
// value and every font-family referencing it silently falls back — which
|
||||||
// rendered in Times.
|
// once shipped the whole site in Times. Nothing throws and no unit test
|
||||||
|
// fails, so the e2e typeface assertion is the only guard.
|
||||||
<html lang="en" className={`${manrope.variable} ${inter.variable}`}>
|
<html lang="en" className={`${manrope.variable} ${inter.variable}`}>
|
||||||
<head>
|
<head>
|
||||||
<link rel="preconnect" href="https://analytics.schoolcompare.co.uk" />
|
<link rel="preconnect" href="https://analytics.schoolcompare.co.uk" />
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ export async function generateMetadata({ params }: SchoolPageProps): Promise<Met
|
|||||||
description,
|
description,
|
||||||
type: 'website',
|
type: 'website',
|
||||||
url: `https://schoolcompare.co.uk${canonicalPath}`,
|
url: `https://schoolcompare.co.uk${canonicalPath}`,
|
||||||
siteName: 'SchoolCompare',
|
siteName: 'schoolcompare',
|
||||||
},
|
},
|
||||||
twitter: {
|
twitter: {
|
||||||
card: 'summary',
|
card: 'summary',
|
||||||
|
|||||||
@@ -224,11 +224,11 @@ export function ComparisonView({
|
|||||||
const url = window.location.href;
|
const url = window.location.href;
|
||||||
const count = selectedSchools.length;
|
const count = selectedSchools.length;
|
||||||
const shareData = {
|
const shareData = {
|
||||||
title: 'School comparison · SchoolCompare',
|
title: 'School comparison · schoolcompare',
|
||||||
text:
|
text:
|
||||||
count > 0
|
count > 0
|
||||||
? `Comparing ${count} school${count === 1 ? '' : 's'} on SchoolCompare`
|
? `Comparing ${count} school${count === 1 ? '' : 's'} on schoolcompare`
|
||||||
: 'SchoolCompare',
|
: 'schoolcompare',
|
||||||
url,
|
url,
|
||||||
};
|
};
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export function EditorialSection({ totalSchools, localAuthorityCount }: Editoria
|
|||||||
and demographics — each in its own table, each with its own jargon.
|
and demographics — each in its own table, each with its own jargon.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
SchoolCompare brings it all into one place. Every school page shows performance against the national
|
schoolcompare brings it all into one place. Every school page shows performance against the national
|
||||||
average, explains what the numbers mean, and lets you shortlist schools side by side. Built for
|
average, explains what the numbers mean, and lets you shortlist schools side by side. Built for
|
||||||
parents, governors, journalists, and anyone who wants to understand a school without reading a
|
parents, governors, journalists, and anyone who wants to understand a school without reading a
|
||||||
full inspection report.
|
full inspection report.
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ export function Footer() {
|
|||||||
|
|
||||||
<div className={styles.bottom}>
|
<div className={styles.bottom}>
|
||||||
<p className={styles.copyright}>
|
<p className={styles.copyright}>
|
||||||
© {currentYear} SchoolCompare.co.uk
|
© {currentYear} schoolcompare.co.uk
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ export function Navigation() {
|
|||||||
<>
|
<>
|
||||||
<header className={styles.header}>
|
<header className={styles.header}>
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<Link href="/" className={styles.logo} aria-label="SchoolCompare home">
|
<Link href="/" className={styles.logo} aria-label="schoolcompare home">
|
||||||
{/*
|
{/*
|
||||||
LogoMark's defaults are already correct for this ground: the pin
|
LogoMark's defaults are already correct for this ground: the pin
|
||||||
takes var(--brand) and the leaf is knocked out in var(--bg-card),
|
takes var(--brand) and the leaf is knocked out in var(--bg-card),
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "SchoolCompare",
|
"name": "schoolcompare",
|
||||||
"short_name": "SchoolCompare",
|
"short_name": "schoolcompare",
|
||||||
"description": "Compare primary and secondary school performance across England",
|
"description": "Compare primary and secondary school performance across England",
|
||||||
"start_url": "/",
|
"start_url": "/",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
|
|||||||
Reference in New Issue
Block a user