Login Flow — Email-First with Conditional Passkey

Two-phase login: email check → password/passkey

Phase 1: Email Entry

Login — Initial Screen
Welcome back
Sign in to DeckyVault
or continue with email
Don't have an account? Create one

Key: Only email field is shown initially. The autocomplete="username webauthn" attribute enables passkey conditional UI — browsers with passkey support will offer to autofill passkey credentials.

Phase 2a: Email Exists → Password Entry

Login — Password Step (email exists)
Welcome back
Signing in as user@example.com change
Forgot password?
🔑 Your browser may offer to sign in with a passkey

Conditional UI: The password field has autocomplete="current-password webauthn". On mount, we call authClient.signIn.passkey({ autoFill: true }) to preload passkeys. Browsers that support Conditional UI (Chrome, Safari, Edge) will show a passkey autofill dropdown when the user interacts with the password field.

Phase 2b: Email NOT Found → Error + Signup Link

Login — Email Not Found
Welcome back
Sign in to DeckyVault
No account found with this email. Create one →

How Email Check Works

  1. User enters email and clicks "Continue"
  2. Client calls authClient.signIn.email() with email + empty password
  3. Better-auth returns an error if email doesn't exist
  4. If error: show "No account found" with signup link
  5. If email exists: transition to password field with email displayed

Note: We use signIn.email() as the check mechanism rather than a separate endpoint. This avoids leaking whether an email exists via a dedicated check API.