The favicon that never caught up with its own script
The 6-in-1 sent a screenshot of an AI chat already recognising the site by its address, but with light corners on the icon. favicon.ico was still drawn the old way (a Playwright page screenshot, opaque) from 2026-09-20, even though scripts/icons.ts moved to sharp - honestly transparent corners - back on 2026-09-24/26; nobody had regenerated the file.
What the screenshot showed
The 6-in-1 sent a screenshot: an AI chat already recognises the site’s link and shows it with an icon - exactly what had been discussed earlier the same day (favicon, og:title, structured data already in place). But the icon itself had a light gap at each corner, where the rounding onto the dark background should have been.
Where exactly
Measured pixel by pixel (fetch plus canvas.getImageData on live production, not by eye):
| file | corner |
|---|---|
/favicon.ico |
[255,255,255,255] - solid, opaque white |
/icon-192.png, /icon-512.png |
[0,0,0,0] - transparent |
/apple-touch-icon.png, /icon-maskable-512.png |
opaque dark green (square, no rounding - by design) |
Only favicon.ico was broken, and not by a little: a solid white square where there should have been transparency.
Why
git log on public/favicon.ico and on scripts/icons.ts had drifted apart: the icon was last regenerated on 2026-09-20 (d335574a), while the script itself changed twice since, on 2026-09-24 and 2026-09-26 (68cedf58, d6955e53). Before 2026-09-20 the artwork was photographed as a Playwright page - an HTML page’s default background, opaque, filled whatever the rounded rect left uncovered at the corners. Since 2026-09-24/26 the script rasterises the SVG directly through sharp, which honestly leaves those corners transparent by default. The new code was run for the PWA icons (they were the point of that commit, and came out right straight away), but not for favicon.ico or apple-touch-icon.png - npm run icons simply was not run again.
Reproduced locally with sharp on its own: the same draw(), on the current favicon.svg, at every size checked (16, 32, 48, 192, 512), gives a transparent corner - meaning a regenerated file would have been correct the whole time, had anyone run the script.
The fix
npm run icons. Only what should have changed did: favicon.ico (937 to 735 bytes) and apple-touch-icon.png (3560 to 2507 bytes, the same artwork, encoded more efficiently). The PWA icons came out byte-identical, confirming they were already current.
The comment in scripts/icons.ts is corrected too: it claimed no transparency in either variant, which stays true only of the square one (apple-touch-icon, maskable) - the rounded one deliberately keeps transparent corners instead, so whatever shows it composites the icon onto its own background rather than a foreign square at each corner.
What was checked
A worktree of its own from origin/main, in the session’s scratchpad (the shared working copy held two other commits not yet pushed, left untouched). Pixels checked with sharp directly, not by eye: a transparent corner on the rounded variants, a solid dark green one on the square variant, at every size checked. npm run verify:code passed in full. No change under src/ui/** or a route, so no separate Playwright run.
Entry written September 29, 2026
Commits this entry accounts for
863f716