The CAS / OIDC / SAML callbacks now redirect to `/login?error=<code>`
on failure instead of letting the browser land on a raw JSON error
page, so the actionable copy reaches the user. Two codes are
recognised:
* `source_conflict` — incoming SSO username collides with an existing
account from a different source. Message points the user at an
administrator to link or convert.
* `auth_failed` — anything else (bad ticket, expired state, IdP
unreachable, malformed response). Generic message: try again or
contact the administrator.
On mount the login form picks up the `?error=` query param, maps it
through a small `messageIdByCode` table to an i18n key, and routes
the result through the existing auth-error toast. Unknown codes are
silently ignored so a future server release adding a code doesn't
render a bare key. The query param is cleared via
`history.replaceState` so a refresh doesn't re-fire the toast.
Strings added to all five locales.