The WebUI has a language Radio toggle (en/zh) that updates form labels, but Markdown headers, button text, placeholder text, info tooltips, and advanced option labels remain in the initial language. Translations are scattered inline throughout the 1400-line script with inconsistent patterns (ternary operators, separate dicts in change_language()).
Fix: Extract all 69 translatable strings into a dedicated i18n.py module with complete zh/en dictionaries. Use a t("key") lookup for widget creation and a simple STRINGS[lang]["key"] in change_language(). All UI elements now toggle consistently. Default language controllable via VOXCPM_LANG environment variable.
The WebUI has a language Radio toggle (en/zh) that updates form labels, but Markdown headers, button text, placeholder text, info tooltips, and advanced option labels remain in the initial language. Translations are scattered inline throughout the 1400-line script with inconsistent patterns (ternary operators, separate dicts in change_language()).
Fix: Extract all 69 translatable strings into a dedicated i18n.py module with complete zh/en dictionaries. Use a t("key") lookup for widget creation and a simple STRINGS[lang]["key"] in change_language(). All UI elements now toggle consistently. Default language controllable via VOXCPM_LANG environment variable.