Introduce LegacySignupErrorEvent to map backend failures from POST /auth/signup: 400 → emailAlreadyExists, 403 → invalidField, 429 → tooManyAttempts, timeout → network. The view state now separates validationErrorKey (pre-submit i18n keys) from apiErrorEvent (typed API outcomes), and the screen listens to both to show proper i18n messages instead of leaking raw backend text.