These frames demonstrate the MFA management experience before any feature UI is
implemented: enrolling an authenticator app (TOTP), adding a phone for text-message codes, one-time
recovery codes, removing a method, and the step-up challenge shown mid sign-in. Approving them freezes
the visual + interaction contract the implementation and frontend-test-engineer's
Playwright checks are verified against. Built in the fuse-seam design system (tokens only). No provider
name appears anywhere in the UI.
Reached from the Account security hub (sibling feature) → Two-factor authentication.
Route base /account/security/mfa. The sign-in step-up lives on the login path /login/mfa.
Enrolled methods list, add-a-method menu, recovery-codes status. Authenticator is available; text-message codes are offered only when the channel can deliver.
Scan the QR (or copy the setup key), then confirm with a 6-digit code. Fail-closed on a wrong or expired code.
Enter a phone, receive a code, confirm. Honest degrade: when text messages can't be delivered the option is disabled with a reason — never offered as if it works.
Shown once, never retrievable again. Copy/download, then regenerate (which invalidates the old set).
Login returned mfa_required. Pick a factor, enter the code, complete sign-in. Fail-closed on bad/expired code; delivery failure is surfaced.
Confirm removal. Fail-closed: removing your only remaining factor while two-factor is required is blocked (409) — you can't lock yourself out.
@fuzefront/design-system. Named here for frontend-engineer to add as a
foundation primitive; not styled one-off.