Files
--- the footer), so no string is declared for an HTML and a text version; user text is escaped for Markdown, which the welcome body didn't do for usernames, whose _ read as emphasis. paint() set colors before a border-top shorthand that reset them, so every divider was black. The review also gave one home to what was written twice: the locale list (shared/locale.ts, read by lingui.config, the client, the server and its catalog loader), the base style and default scheme (shared/theme.ts), an email's look (lookOf, which digest-service, welcome and reset share), whether email is on (EMAIL_ENABLED, read by email-service and index.html), a setting's column and its default in the digests' SQL (SETTINGS_COLUMNS, DEFAULT_SETTINGS), the unsubscribe token (made once, not parsed back from a URL), AuthProvider's compare-and-store, ThemeProvider's twin style and scheme code (useThemeChoice), the test JWT encoder, and duplicate digest messages. The email palettes stay a flattened copy of the themes' tokens, now under a test that caught Times' secondary and link colors drifting. The Dockerfile copies api/mail and locales so the build extracts the emails' messages and the server finds its catalogs, and deno.json maps @lingui/core for the runtime image. 236 backend tests (new: digest building, sending, catch-up, scheduling and unsubscribing; the Markdown renderer; French from the catalog; palettes against themes; the stagger migration; unsubscribe tokens) and 661 frontend tests (new: the unsubscribe page) pass, and tsc, eslint, doc:lint, deno check, deno lint and deno fmt are clean.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>