Passwordless sign-in now emails a 6-digit code the user types in, replacing the clickable magic link.
Changed
lib/auth.tsx—signInWithEmaildropsemailRedirectTo(so no link is generated) and addsverifyOtp(email, code)→supabase.auth.verifyOtp({ email, token, type: "email" }).components/AuthButton.tsx— two-step popover: enter email → "Send code", then a 6-digit code input → "Verify & sign in", with Resend code / Use a different email. Replaces the "magic link sent — check your email" screen.supabase/config.toml+supabase/templates/{magic_link,confirmation}.html— branded (Notion warm-monochrome, Space/Host Grotesk), code-only email templates: just the 6-digit{{ .Token }}code, no{{ .ConfirmationURL }}link. Omitting the URL prevents mail security scanners from pre-fetching and consuming the single-use token (which surfaced asotp_expiredat verify time). Including{{ .Token }}is what makes Supabase send a code. Table-based + inline styles for client compatibility.otp_lengthwas already 6.app/auth/confirm/route.ts— demoted to a fallback (nothing links to it now); kept so any still-link-style email resolves during the template switch.
Action required on hosted Supabase: set the same {{ .Token }} content under
Authentication → Email Templates → Magic Link and Confirm signup (the
dashboard overrides config.toml, which only applies to the local CLI stack).