feat(brand): adopt the schoolcompare identity across the site #89

Merged
tudor merged 2 commits from feat/schoolcompare-brand into main 2026-08-07 17:58:56 +00:00
Owner

Implements the supplied brand guideline across the site: the pin-and-leaf mark, the lowercase schoolcompare wordmark, Manrope for headings and Inter for body copy and every figure, the deep-teal / coral / mustard / sage palette, and the rounder geometry the guideline asks for.

The landing hero is rebuilt to the concept — a Sand panel carrying the proposition, the search and a trust line, with the brand landscape bleeding to the panel's right edge, followed by the four value props.

Concept vs reality

Where the guideline describes something this product does not have, the real feature takes its place. Each decision is recorded in a code comment next to the thing it affects, so the next person does not "fix" it back:

Guideline Shipped Why
Thriving Score (9.2, five sub-scores) Real KS2/KS4 measures Four of five sub-scores — pastoral, enrichment, community, facilities — have no source in DfE or Ofsted data. Its band names are also Ofsted's own, so 9.2 Outstanding would sit beside the real Ofsted · Outstanding and be indistinguishable from it.
Guides, About, Favourites, Sign in Rankings, Admissions No such pages, and no accounts system. Rankings and Admissions are omitted by the guideline but are real.
"Save & revisit" value prop "Never miss a deadline" Shortlisting does not exist; the admissions countdown does.
Comparison radar not included One sourced dimension of five would be a pentagon with a single real corner.

Two deviations from the swatches, both forced by contrast

Both are confined to text and fills; the original values survive wherever they are not carrying a label.

  • Coral #F97360 under a white label is 2.75:1 against a 4.5 floor. --action is a darkened #BE3C27 (5.4:1); --coral keeps the exact brand value for tints, borders and illustration.
  • Mustard #F2C94C is 1.5:1 as text. --mustard-ink #806200 carries labels; --mustard stays exact for fills, rings and badges.

Every token clears WCAG AA on all three light grounds. Sand is the binding one — several values sit a step darker than white alone would require.

The guideline is light-only, but the site already ships a dark theme, so it is rebuilt from the same tokens rather than dropped.

Verification

  • tsc --noEmit clean, 159/159 unit tests, production build green.
  • /opengraph-image and /apple-icon prerender successfully, so the vendored Manrope and the new mark render in Satori. Both were opened and checked.
  • The hero and the site chrome were rendered from the compiled CSS and the prerendered markup to confirm Manrope and Inter actually resolve. A font token that silently falls back has shipped in this repo before, and it does not fail a build or a unit test.
  • E2E: the typeface assertion now checks Inter for body and Manrope for headings, and a new test asserts the header lockup reads schoolcompare with the mark present.

Not covered here

The guideline's photography and the score donuts / radar are not implemented — the first needs assets, the second needs the data question above settled. The illustration keeps a fixed light palette in both themes by design; it reads as a framed image on the dark ground.

🤖 Generated with Claude Code

Implements the supplied brand guideline across the site: the pin-and-leaf mark, the lowercase `schoolcompare` wordmark, Manrope for headings and Inter for body copy and every figure, the deep-teal / coral / mustard / sage palette, and the rounder geometry the guideline asks for. The landing hero is rebuilt to the concept — a Sand panel carrying the proposition, the search and a trust line, with the brand landscape bleeding to the panel's right edge, followed by the four value props. ## Concept vs reality Where the guideline describes something this product does not have, the real feature takes its place. Each decision is recorded in a code comment next to the thing it affects, so the next person does not "fix" it back: | Guideline | Shipped | Why | |---|---|---| | Thriving Score (9.2, five sub-scores) | Real KS2/KS4 measures | Four of five sub-scores — pastoral, enrichment, community, facilities — have **no source** in DfE or Ofsted data. Its band names are also Ofsted's own, so `9.2 Outstanding` would sit beside the real `Ofsted · Outstanding` and be indistinguishable from it. | | Guides, About, Favourites, Sign in | Rankings, Admissions | No such pages, and no accounts system. Rankings and Admissions are omitted by the guideline but are real. | | "Save & revisit" value prop | "Never miss a deadline" | Shortlisting does not exist; the admissions countdown does. | | Comparison radar | not included | One sourced dimension of five would be a pentagon with a single real corner. | ## Two deviations from the swatches, both forced by contrast Both are confined to text and fills; the original values survive wherever they are not carrying a label. - **Coral `#F97360` under a white label is 2.75:1** against a 4.5 floor. `--action` is a darkened `#BE3C27` (5.4:1); `--coral` keeps the exact brand value for tints, borders and illustration. - **Mustard `#F2C94C` is 1.5:1 as text.** `--mustard-ink` `#806200` carries labels; `--mustard` stays exact for fills, rings and badges. Every token clears WCAG AA on all three light grounds. Sand is the binding one — several values sit a step darker than white alone would require. The guideline is light-only, but the site already ships a dark theme, so it is rebuilt from the same tokens rather than dropped. ## Verification - `tsc --noEmit` clean, **159/159** unit tests, production build green. - `/opengraph-image` and `/apple-icon` prerender successfully, so the vendored Manrope and the new mark render in Satori. Both were opened and checked. - The hero and the site chrome were rendered from the **compiled CSS and the prerendered markup** to confirm Manrope and Inter actually resolve. A font token that silently falls back has shipped in this repo before, and it does not fail a build or a unit test. - E2E: the typeface assertion now checks Inter for body and Manrope for headings, and a new test asserts the header lockup reads `schoolcompare` with the mark present. ## Not covered here The guideline's **photography** and the **score donuts / radar** are not implemented — the first needs assets, the second needs the data question above settled. The illustration keeps a fixed light palette in both themes by design; it reads as a framed image on the dark ground. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
tudor added 1 commit 2026-08-07 17:06:31 +00:00
feat(brand): adopt the schoolcompare identity across the site
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 13s
PR Checks / Build Frontend (no push) (pull_request) Successful in 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 4m29s
accc562b90
Implements the supplied brand guideline: the pin-and-leaf mark, the lowercase
schoolcompare wordmark, Manrope for headings and Inter for everything a person
reads a number from, the deep-teal/coral/mustard/sage palette, and the rounder
geometry the guideline asks for.

The landing hero is rebuilt to the concept: a Sand panel carrying the
proposition, the search and a trust line, with the brand landscape bleeding to
the panel's right edge, followed by the four value props.

Concept vs reality — where the guideline describes something this product does
not have, the real feature takes its place and the decision is recorded in a
code comment next to it:

- The Thriving Score is not implemented. Four of its five sub-scores (pastoral,
  enrichment, community, facilities) have no source in DfE or Ofsted data, and
  its band names are Ofsted's own, which would sit beside the real Ofsted grade
  and be indistinguishable from it.
- Guides, About, Favourites and Sign in are not added to the nav — there are no
  such pages and no accounts system. Rankings and Admissions, which the
  guideline omits, keep their places because they exist.
- The fourth value prop is "Never miss a deadline" rather than "Save & revisit",
  which would need shortlisting.

Two deviations from the supplied swatches, both forced by contrast and both
confined to text and fills. Coral #F97360 under a white label measures 2.75:1
against a 4.5 floor, so --action is a darkened #BE3C27 and the original coral
survives as --coral for tints, borders and illustration. Mustard #F2C94C is
1.5:1 as text, so --mustard-ink carries labels while --mustard stays exact for
fills and rings. Every token clears AA on all three light grounds; Sand is the
binding one, so several values sit a step darker than white alone would need.

The guideline is light-only, but the site already ships a dark theme, so it is
rebuilt from the same tokens rather than dropped.

Verified: tsc clean, 159/159 unit tests, production build green, and the
generated share card and app icon render from the new mark. The hero and the
site chrome were rendered from the compiled CSS and the prerendered markup to
confirm Manrope and Inter actually resolve — a font token that silently falls
back has shipped here before.

🤖 AI Code Review (Claude Code)

This PR rebrands the Next.js frontend from the purple/iris "SchoolCompare" identity to a teal/coral "schoolcompare" identity: new color tokens, new Manrope/Inter fonts, a new pin+leaf logo mark shared across favicon/apple-icon/OG image, a redesigned hero, and updated e2e tests. It's a large but self-contained visual change with no backend, CI, or deploy files touched; the implementation is generally careful (contrast-ratio comments were verified to match the actual hex values, the shared mark geometry is reused consistently), but the rebrand is incomplete in a few places and one color token has a copy-paste mismatch.

🟡 Minor

  • nextjs-app/app/globals.css: --status-below-bg: rgba(249, 115, 96, 0.15) uses the coral RGB tuple (249,115,96, i.e. --coral) instead of the status-below hue itself (#A9481F → rgb(169,72,31), which is exactly what --status-below-rgb further down and the dark-theme --status-below-bg both correctly use). Every other status/phase pair in this file matches solid-color-to-tint hue exactly; this one alone doesn't, so "below average" badges render a coral-pink tint behind terracotta text/icons instead of the intended matching terracotta tint.
  • nextjs-app/app/layout.tsx: Title/OpenGraph/Twitter metadata (title: 'SchoolCompare | ...', siteName: 'SchoolCompare'), public/manifest.json (name/short_name: "SchoolCompare"), Footer.tsx's copyright line ("© {year} SchoolCompare.co.uk"), and Navigation.tsx's aria-label="SchoolCompare home" were not updated to the new lowercase "schoolcompare" branding introduced everywhere else in this PR (header wordmark, footer lockup, OG image copy, Logo.tsx comments), leaving the browser tab title, PWA install prompt, and link sharing previews inconsistent with the new visual identity.
  • nextjs-app/app/layout.tsx: The comment explaining why the font-variable classes must sit on <html> still refers to the old --font-schibsted custom property ("globals.css declares --font-display/--font-ui on :root as var(--font-schibsted)... --font-schibsted was undefined"), which no longer exists now that globals.css defines --font-display via var(--font-manrope). Harmless but misleading for future readers.
## 🤖 AI Code Review (Claude Code) This PR rebrands the Next.js frontend from the purple/iris "SchoolCompare" identity to a teal/coral "schoolcompare" identity: new color tokens, new Manrope/Inter fonts, a new pin+leaf logo mark shared across favicon/apple-icon/OG image, a redesigned hero, and updated e2e tests. It's a large but self-contained visual change with no backend, CI, or deploy files touched; the implementation is generally careful (contrast-ratio comments were verified to match the actual hex values, the shared mark geometry is reused consistently), but the rebrand is incomplete in a few places and one color token has a copy-paste mismatch. ### 🟡 Minor - **nextjs-app/app/globals.css**: `--status-below-bg: rgba(249, 115, 96, 0.15)` uses the coral RGB tuple (249,115,96, i.e. --coral) instead of the status-below hue itself (#A9481F → rgb(169,72,31), which is exactly what `--status-below-rgb` further down and the dark-theme `--status-below-bg` both correctly use). Every other status/phase pair in this file matches solid-color-to-tint hue exactly; this one alone doesn't, so "below average" badges render a coral-pink tint behind terracotta text/icons instead of the intended matching terracotta tint. - **nextjs-app/app/layout.tsx**: Title/OpenGraph/Twitter metadata (`title: 'SchoolCompare | ...'`, `siteName: 'SchoolCompare'`), `public/manifest.json` (`name`/`short_name: "SchoolCompare"`), `Footer.tsx`'s copyright line ("© {year} SchoolCompare.co.uk"), and `Navigation.tsx`'s `aria-label="SchoolCompare home"` were not updated to the new lowercase "schoolcompare" branding introduced everywhere else in this PR (header wordmark, footer lockup, OG image copy, Logo.tsx comments), leaving the browser tab title, PWA install prompt, and link sharing previews inconsistent with the new visual identity. - **nextjs-app/app/layout.tsx**: The comment explaining why the font-variable classes must sit on `<html>` still refers to the old `--font-schibsted` custom property ("globals.css declares --font-display/--font-ui on :root as var(--font-schibsted)... --font-schibsted was undefined"), which no longer exists now that globals.css defines `--font-display` via `var(--font-manrope)`. Harmless but misleading for future readers.
tudor added 1 commit 2026-08-07 17:33:37 +00:00
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
39e5c11274
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.

🤖 AI Code Review (Claude Code)

This PR rebrands the site from "SchoolCompare" (iris/serif identity) to "schoolcompare" (deep teal/coral, Manrope+Inter), touching global CSS tokens, the logo/icon generation, hero/footer/nav layout, and e2e tests. The change is broad but mechanical and internally consistent (font vars, contrast comments, dark theme) with no CI/deploy or backend changes; only one real inconsistency was found.

🟡 Minor

  • nextjs-app/lib/theme.ts: FALLBACK['--status-below-bg'] is 'rgba(249, 115, 96, 0.15)' — the raw --coral-rgb tuple (249,115,96) at 0.15 alpha — instead of the terracotta --status-below-rgb tuple (169,72,31) at 0.12 alpha that globals.css was fixed to use. This is exactly the bug the globals.css comment describes as previously shipped and fixed (coral-pink wash behind terracotta text, and 0.15 alpha dropping contrast below AA), but the JS fallback wasn't updated to match, so any consumer reading this token via theme.ts before hydration/in a non-DOM context gets the old, wrong value back.
## 🤖 AI Code Review (Claude Code) This PR rebrands the site from "SchoolCompare" (iris/serif identity) to "schoolcompare" (deep teal/coral, Manrope+Inter), touching global CSS tokens, the logo/icon generation, hero/footer/nav layout, and e2e tests. The change is broad but mechanical and internally consistent (font vars, contrast comments, dark theme) with no CI/deploy or backend changes; only one real inconsistency was found. ### 🟡 Minor - **nextjs-app/lib/theme.ts**: FALLBACK['--status-below-bg'] is 'rgba(249, 115, 96, 0.15)' — the raw --coral-rgb tuple (249,115,96) at 0.15 alpha — instead of the terracotta --status-below-rgb tuple (169,72,31) at 0.12 alpha that globals.css was fixed to use. This is exactly the bug the globals.css comment describes as previously shipped and fixed (coral-pink wash behind terracotta text, and 0.15 alpha dropping contrast below AA), but the JS fallback wasn't updated to match, so any consumer reading this token via theme.ts before hydration/in a non-DOM context gets the old, wrong value back.
tudor merged commit eecb84fb35 into main 2026-08-07 17:58:56 +00:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: tudor/school_compare#89