Three small omissions in the page shell that a person meets before they read a single card. One run, no new concepts.
What it is like today, checked against main at cd8ab1d:
No language.shell() in src/pages/board.ts emits <!doctype html> and goes straight to <meta charset> — there is no <html> element and no lang anywhere (grep -c 'lang=' src/pages/board.ts → 0). A screen reader picks a voice by guessing, and "Doing" read with the wrong phonetics is the first thing a blind user hears.
No icon.GET /favicon.ico is a 404 text/plain, requested by every browser on every new tab. The board shows up in the tab strip and in a bookmark as a blank page glyph, which for an app whose entry point is a pasted link is the icon people see most.
No theme-color. The app already supports light and dark properly (color-scheme, a stored preference applied before first paint), and then the browser's own chrome stays the default colour around it on a phone.
What done looks like
[ ] The shell emits <html lang="en"> (and closes it), with the attribute rendered once, in one place.
[ ] A tiny inline SVG favicon served from /static/ — the app's own mark, not an emoji in a data URL — named by content like the scripts and cached for a year, referenced with <link rel="icon" type="image/svg+xml"> plus a small PNG or ICO fallback if it costs nothing. GET /favicon.ico stops being a 404, whether by a file or a redirect.
[ ] <meta name="theme-color"> with a light and a dark value via media, matching the page's own two schemes.
[ ] The CSP still allows exactly what these need and nothing more — an SVG file under /static/ is covered by the existing img-src 'self', so the header should not need to change. If it does, say why in the pull.
[ ] No layout shift and no extra render-blocking request: the icon is a link, not an inline blob in the HTML.
[ ] A test asserts lang is present on both pages, that /favicon.ico answers 200 with an image content type, and that the static icon carries the immutable cache header and the security floor.
[ ] bun test passes.
Files I expect to change:src/pages/board.ts, a new file under static/, src/server.ts or src/routes.ts for /favicon.ico, src/pages/board.test.ts, src/server.test.ts.
Risks. Small, and mostly of scope: this is not a visual redesign, and the mark should take minutes, not an afternoon. lang="en" is a claim about the interface's language, not about card titles people write in any language — do not add lang to user text.
Who fits:scout to build it, reviewed by juniper — three things a person sees, judged by looking.
Three small omissions in the page shell that a person meets before they read a single card. One run, no new concepts.
What it is like today, checked against
mainatcd8ab1d:shell()insrc/pages/board.tsemits<!doctype html>and goes straight to<meta charset>— there is no<html>element and nolanganywhere (grep -c 'lang=' src/pages/board.ts→ 0). A screen reader picks a voice by guessing, and "Doing" read with the wrong phonetics is the first thing a blind user hears.GET /favicon.icois a404 text/plain, requested by every browser on every new tab. The board shows up in the tab strip and in a bookmark as a blank page glyph, which for an app whose entry point is a pasted link is the icon people see most.theme-color. The app already supports light and dark properly (color-scheme, a stored preference applied before first paint), and then the browser's own chrome stays the default colour around it on a phone.What done looks like
<html lang="en">(and closes it), with the attribute rendered once, in one place./static/— the app's own mark, not an emoji in a data URL — named by content like the scripts and cached for a year, referenced with<link rel="icon" type="image/svg+xml">plus a small PNG or ICO fallback if it costs nothing.GET /favicon.icostops being a 404, whether by a file or a redirect.<meta name="theme-color">with a light and a dark value viamedia, matching the page's own two schemes./static/is covered by the existingimg-src 'self', so the header should not need to change. If it does, say why in the pull.langis present on both pages, that/favicon.icoanswers 200 with an image content type, and that the static icon carries the immutable cache header and the security floor.bun testpasses.Files I expect to change:
src/pages/board.ts, a new file understatic/,src/server.tsorsrc/routes.tsfor/favicon.ico,src/pages/board.test.ts,src/server.test.ts.Risks. Small, and mostly of scope: this is not a visual redesign, and the mark should take minutes, not an afternoon.
lang="en"is a claim about the interface's language, not about card titles people write in any language — do not addlangto user text.Who fits: scout to build it, reviewed by juniper — three things a person sees, judged by looking.