fix(brand): give both logo colourways one canvas so the aspect hint is right
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 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 50s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 9s

LogoMark derived width from a single hardcoded 153/189, taken from mark.png,
while mark-on-dark.png was 98×112. Both call sites size the mark with
height:100%/width:auto, so the rendered size came out right in the end — but
the width/height attributes are the pre-load aspect hint, so the on-dark
artwork reserved the wrong box and reflowed on load. Any future call site
without that CSS would have rendered it stretched outright.

Per-variant attributes would not have fixed it. variant="auto" is a single
<img> whose srcset swaps the file underneath it, so one set of attributes has
to serve both colourways; the only correct fix is for the two files to share
a ratio.

They also had different artwork ratios (0.810 against 0.833) and different
padding, which the review did not reach: the logo changed size slightly
whenever the OS theme flipped. Both are now written onto one 176×208 canvas
with the artwork at the same height, centred, so they are drop-in swappable.

Measured on the built output, header mark, before → after:
  light   attr 31×38, rendered 30.75×38   →   attr 32×38, rendered 32.15×38
  dark    attr 31×38, rendered 33.25×38   →   attr 32×38, rendered 32.15×38
A 2.25px reflow and a cross-theme size jump both become 0.15px of rounding.

The share card reads the same file and had its own hardcoded 45×56, which the
re-crop would have stretched; it is now 47×56, with a comment tying it to the
canvas. The comment on ASPECT records that re-cropping either file means
re-normalising both.

Verified: tsc clean, 159/159 tests, build green, and both files report
naturalWidth 176 × naturalHeight 208 in the browser.
This commit is contained in:
Tudor
2026-08-08 22:39:28 +01:00
parent b11ee3c8de
commit 9ee4d45a94
4 changed files with 23 additions and 3 deletions
+3 -1
View File
@@ -31,6 +31,8 @@ async function font(file: string) {
* The mark, as a data URI. Satori has no access to the public/ URL space, so
* the artwork is read off disk and inlined. This is the same file the header
* serves — public/brand/mark.png — so the card can never drift from the site.
* The 47×56 box below is that file's 176:208 ratio; re-crop the artwork and
* this has to move with it, or Satori will stretch it.
*/
async function markDataUri() {
const png = await readFile(join(process.cwd(), 'public', 'brand', 'mark.png'));
@@ -72,7 +74,7 @@ export default async function OpengraphImage() {
{/* Lockup */}
<div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src={mark} width={45} height={56} alt="" />
<img src={mark} width={47} height={56} alt="" />
<div style={{ display: 'flex', fontSize: 34, fontWeight: 700, letterSpacing: '-0.04em' }}>
<span style={{ color: INK }}>school</span>
<span style={{ color: TEAL }}>compare</span>