KQ-1707 · INBOX/WAIT

Inbox Wait

A magic-link waiting screen where an envelope rests in a slow breathing glow — a mirrored tween whose strength is glowAmount, running only while waiting, in view and in a visible tab — beside the address, a Resend that counts down and a way to change the address. The page notices the link opening through a BroadcastChannel another tab posts to, an onCheck asked when the tab regains focus, or the host's status; then the flap swings open on springs.snap, the letter rises on springs.glide and grows into the signed-in welcome through a shared layout on glide while the welcome's lines arrive in a cascade. Expired links and links opened on another device each explain the next step.

KQ-1707 · INBOX/WAIT

Check your inbox

We sent a sign-in link to ana@waylight.studio

Link expires in 15 min · this page will notice

waiting · ana@waylight.studio

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/inbox-wait

Props

email
string
default "ana@waylight.studio"
Where the link went.
status / defaultStatus
"waiting" | "verified" | "expired" | "other-device"
default — / "waiting"
The page's state, controlled or initial.
onStatusChange
(status) => void
default —
Fires when the page notices the link opened, the link expires, or a new link goes out.
sentAt
number
default 6 s before now
When the link was sent, in ms.
now
number
default defaultInboxWaitNow
The moment the page first renders, in ms; its timers count on from it.
resendAfter
number
default 30
Seconds before Resend becomes available.
expiresAfter
number
default 15
Minutes a link stays valid; the page turns to expired when it lapses.
onResend
() => void | Promise
default —
Resend was pressed; a promise holds the button.
onChangeEmail
(email) => void
default —
A new address was saved; a fresh link is assumed to have gone to it.
onVerified
(info: { name?, via }) => void
default —
The page noticed the link was opened, and how ("channel", "check" or "host"); fires once per link.
onContinue
() => void
default —
Continue was pressed on the welcome.
channel
string
default —
A BroadcastChannel name; another tab posts { type: "verified", name? } (or "expired", "other-device").
onCheck
() => boolean | Promise<boolean>
default —
Asked when the tab regains focus (and every pollInterval ms while visible); resolve true once the link has been opened.
pollInterval
number
default 0
Milliseconds between checks while visible and on screen; 0 checks only on focus.
name
string
default "Ana"
Who the welcome greets.
product
string
default "Waylight"
The product being signed in to.
envelopeStyle
"flap" | "mailer" | "line"
default "flap"
The envelope: a classic flap, a mailer with a tear strip, or line art.
glowAmount
number
default 0.6
How strongly the resting envelope glows, 0 to 1; 0 is unlit and still.
tone
"calm" | "warm" | "mono"
default "calm"
The glow, the seal and the primary action: cobalt, amber or ink.
disabled
boolean
default false
Resend and Change email are unavailable.
className
string
default —
Classes for the surface; it is max-w-sm unless widened here.