How I Designed a Digital Invitation That Opens Like a Real Card
When I got married last year, we wanted to do something more personal than the typical wedding site with a few lines of text and an RSVP button. Inspired by traditional invitations, I built a digital card that mimics the physical experience: an envelope that opens, and a card that slides out with a smooth animation.
The Email
The first, but most crucial part to this process was delivering the invites to the recipients. Unfortunately, Email is an outdated and quite restrictive standard, so we stuck with a simple image and button for the emails. The email might look simple, but under the hood, it includes a magic link that logs users in automatically via Clerk.
const token = await clerkClient.signInTokens.createSignInToken({
userId: clerkUser.id,
expiresInSeconds: 2592000,
});
Once they got the email and logged in, they were ready to be amazed by the animated invite.
The Animations
We designed a multi-step animation for the actual invite.
- Envelope opens
- Card comes out
- Card rotates

I will skip over all the details of finding the right images for the envelope and designing the cards, and focus on implementing the custom CSS animations in my project that uses TailwindCSS. For the initial animation, I can trigger it to begin immediately as the page loads but for additional cards we can trigger them after a button press.
card: {
"50%": {
transform: "translateY(-80%) rotate(-90deg)",
transformStyle: "flat",
},
"25%": {
transform: "translateY(-40%) rotate(-90deg)",
transformStyle: "flat",
},
"0%": {
transform: "translateY(0%) rotate(0deg)",
transformStyle: "flat",
zIndex: "30",
},
},
flap: {
"0%": {
transform: "rotateX(180deg)",
transformOrigin: "center top",
zIndex: "0",
},
"33%": {
transform: "rotateX(120deg)",
transformOrigin: "center top",
},
"66%": { transform: "rotateX(60deg)", transformOrigin: "center top" },
"100%": { transform: "rotateX(0deg)", transformOrigin: "center top" },
}
Once the animation played, users could RSVP directly from the page. While the functionality was simple, the experience felt more personal, and we got a lot of nice messages about how thoughtful the card felt.