Magic Link Sent
The dead-end screen after a passwordless login, doing the only three jobs it can: quote the address, prove the mail left, and hold the resend.
Check your inbox
A one-time link is on its way to
sam@acme.co
Build the confirmation screen shown after sending a passwordless magic link. This screen is a dead end by construction - the next step happens in another app - so it has exactly three jobs, and most implementations do only one. Structure: a centered card with a circular icon badge (an envelope on a tinted accent disc), a heading, an address line, and a resend button. 1. Quote the address back. Print the actual email the link went to, in a mono font, on its own line. A large share of magic-link failures are a typo the user never gets to see. 2. Prove it was sent. When the request resolves, spring a small green check badge onto the corner of the envelope disc (stiffness ~620, damping ~20) with a ring of the card background around it so it reads as attached. Without this, "sent" and "not yet sent" look identical. 3. Hold the resend, visibly. Disable the resend button for about 8 seconds and put the countdown INSIDE the button ("resend in 6s"), not in a caption underneath. The control and its own availability are one object. Style the disabled state as genuinely disabled - muted text, hairline border, mono font, cursor not-allowed - because a button that looks live but does nothing teaches people to hammer it. Do not hide the resend instead; a hidden resend makes people reload the page, which loses the pending session. Accessibility: the button carries aria-live="polite" so the countdown and its release are announced. Under prefers-reduced-motion, render the sent state with the check in place and the resend already available. Colors as tokens: paper card, one accent for the envelope disc, semantic green for the sent check. Use a placeholder address, not a real one. Build the component, not this demo of it. - Ambient motion that IS the component may loop: a drifting background, a marquee, a spinner while something is genuinely loading. - Do not add any timer, interval, loop or script that performs a person's action by itself. No auto-hover, no auto-click, no cycling through states, no pretend submitting, no replaying the interaction on a schedule. - Every state that answers a person waits for a real event from that person. - Placeholder copy and sample content are welcome. Simulated behaviour is not.