@@ -204,7 +204,7 @@ rather than a transport, which is a dozen lines. Three things it settled:
204204 shoulder than a terminal, and a line that was never stored with a connection string in it cannot leak one
205205 through a future endpoint.
206206
207- ### Phase 6 — Polish (~ 1 week) — ** partly done**
207+ ### Phase 6 — Polish (~ 1 week) — ** done, bar what needs a person or a Docker daemon **
208208
209209Terms and privacy pages are built, and they sit ** outside** ` RequireAuth ` : somebody deciding whether to add the
210210bot has to be able to read them before signing in. Both are written for a self-hosted bot — the operator is
@@ -234,8 +234,19 @@ pinning the four claims the code has to keep true.
234234 own loopback and a published port reaches nothing. The image has ** not been built** — the environment it was
235235 written in has no Docker daemon — though the production-only install, the compiled layout and
236236 ` docker compose config ` were each verified directly.
237- - README screenshots; ` CONTRIBUTING.md ` section.
238- - Light theme, if wanted — cheap now that everything is tokens, but re-verify every contrast ratio.
237+ - ** README screenshots — done.** Five, in [ ` ../screenshots/ ` ] ( ../screenshots/README.md ) , captured from the
238+ built bundle against stub responses so no real server or account is in one. Both themes appear deliberately.
239+ ` docs/contributing.md ` already carries the dashboard section, including how to add a language.
240+ - ** Light theme — done** , and it is not an afterthought: every colour in ` index.css ` is one ` light-dark() ` line
241+ holding both schemes, and ` contrast.test.ts ` reads ** both halves** and checks each against WCAG, so a light
242+ value nobody looked at fails the build. The switch is ` color-scheme ` and nothing else.
243+ - ** Appearance customisation — done** , beyond what this phase asked for: six accents, a motion override that
244+ wins in both directions, and the language picker. All three are one ` Preference ` mechanism — an attribute on
245+ the root element, a ` localStorage ` key, and a fallback that _ removes_ the attribute so the CSS answers before
246+ any script runs. Every accent is measured against both backgrounds.
247+ - ** Narrow widths — done.** Ten routes at 390 and 820 CSS px carry no horizontal overflow and no page error.
248+ Two defects that only exist on a phone were fixed there: the owner console's eight-tab strip cut with nothing
249+ saying five tabs sat past the edge, and landing on a later tab left the strip at its start with none marked.
239250
240251Roughly eight to nine weeks of evenings. Phases 0–2 are the ones that must not be rushed; 3 is mechanical.
241252
@@ -272,8 +283,12 @@ Worth deciding before phase 2, because each changes work later.
272283 "someone says it broke" and "here is the stack". Phase 5, or earlier if support load justifies it.
2732844 . ** Kick and ban.** Deliberately excluded (` 05-API.md ` ). Softban covers the reversible case. If you want them,
274285 they need a stronger confirmation than typing a name.
275- 5 . ** Light theme.** Phase 6 or never. Cheap to add, but every contrast ratio in ` 08-DESIGN.md ` needs recomputing
276- against a light background, and an unverified light theme is worse than none.
286+ 5 . ** Light theme.** ~~ Phase 6 or never.~~ ** Answered: built.** The worry was right — an unverified light theme
287+ is worse than none — so ` contrast.test.ts ` reads both halves of every token out of ` index.css ` and checks
288+ each against WCAG. Two things it caught are worth keeping in mind: a pair can pass for the wrong reason
289+ (check the colour the component actually draws, not the token you assume it uses), and elevation cannot
290+ simply be recoloured — a drop shadow reads as a smudge on near-black, an inset highlight is invisible on
291+ paper, so ` surface-edge ` switches technique by theme.
2772926 . ** Realtime.** Everything here is request/response. Live member counts or a live audit feed would want SSE
278293 (simpler than WebSockets, and one-directional is all this needs). Not in the POC; the polling in TanStack
279294 Query is enough.
0 commit comments