The codebase survey was blunt: zero i18n infrastructure, roughly 660 user-facing text nodes across 53 files, a dozen alert dialogs, forty toasts, screen titles scattered across layout files. English was load-bearing everywhere.

The reason to fix it then, rather than "after launch", was the closed-test window: Google Play makes you sit in testing for fourteen days regardless, and fourteen days of real people using translated builds is worth more than fourteen days of them using English. So the app learned six languages in one pass, then thirteen more.

TL;DR — i18next + react-i18next + a plural-rules polyfill (the JS engine ships a stub Intl on some platforms, and Arabic needs six plural categories), eight namespaces, static resources so the first frame already has copy. Language is per-user, not per-device — the currency pattern — cached for the first frame, mirrored on the profile so it roams, cleared and restored on account switch; the Cognito locale attribute is written at sign-up so emails can follow later. Arabic flips the shell RTL with a native flag and a one-shot restart prompt, logical direction classes, and a font trick: the Arabic face is registered under the Latin font's names, so every existing style re-faces with zero call-site changes. Two tiers — six human-reviewable launch languages, thirteen machine-translated — generated by a diff-only pipeline that forces structured output because free-form JSON kept breaking on quotes.