Introduce full i18n for the Svelte client_v2 using svelte-i18n (ICU/formatjs),
mirroring the old client's language support.
- i18n setup in src/lib/i18n/ (lazy per-language loaders, init + waitLocale boot
guard, setLocale persisted to localStorage, Intl locale helper); 26-language
registry ported from the old client.
- Language picker on the Settings page.
- scripts/convert-locales.mjs seeds static/locales/<lang>/common.json from the
old client's Weblate files: {{var}} -> {var}, escapes literal braces, merges
i18next plural suffixes into ICU plurals. Existing translations are reused via
the same keys; new v2-only strings are added to en/common.json only and fall
back to English until Weblate fills them.
- Extracted all hardcoded UI strings across routes and components to $_ lookups;
DateTimeField derives month/weekday names from Intl in the active locale.
- static/locales is prettier-ignored (mirrors the old client's public/locales).
Follow-up (maintainer): add a Weblate component pointing at
client_v2/static/locales (nested JSON, ICU MessageFormat, English source).
Claude-Session: https://claude.ai/code/session_01Ne7RsfHejKZX97uAq3aVMn