UIStudio Pro is live - modern UI, powerful animations, zero hassle.
Components
Animated Form Card

Animated Form Card

Modern glassmorphism form card with smooth slide-in animations and floating labels.

Welcome back

Sign in to your account to continue

Or continue with

Don't have an account?

By signing in, you agree to our Terms of Service and Privacy Policy

Installation

1

Install the packages

npm i motion react-icons clsx tailwind-merge lucide-react
2

Add util file

lib/util.ts
import { ClassValue, clsx } from "clsx"; import { twMerge } from "tailwind-merge"; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); }
3

Copy and paste the following code into your project

animated-form-card.tsx
"use client"; import { motion } from "motion/react"; import { useEffect, useState } from "react"; import { cn } from "@/lib/utils"; import { Mail, Lock, Eye, EyeOff, User, ArrowRight } from "lucide-react"; type AnimatedFormCardProps = { delay?: number; title?: string; subtitle?: string; }; const AnimatedFormCard = ({ delay = 6000, title = "Welcome Back", subtitle = "Sign in to your account", }: AnimatedFormCardProps) => { const [animationKey, setAnimationKey] = useState(0); const delayTime = Math.max(delay, 6000); useEffect(() => { const interval = setInterval(() => { setAnimationKey((prev) => prev + 1); }, delayTime); return () => clearInterval(interval); }, [delayTime]); return <AnimatedFormCardComponent key={animationKey} title={title} subtitle={subtitle} />; }; export default AnimatedFormCard; const AnimatedFormCardComponent = ({ title, subtitle }: { title: string; subtitle: string; }) => { const [showPassword, setShowPassword] = useState(false); const formFields = [ { icon: <Mail className="w-4 h-4" />, placeholder: "Enter your email", value: "john.doe@example.com", type: "email", delay: 0.8, }, { icon: <Lock className="w-4 h-4" />, placeholder: "Enter your password", value: "••••••••••", type: "password", delay: 1.6, }, ]; return ( <div className="w-full max-w-md mx-auto"> {/* Background blur effect */} <div className="absolute inset-0 bg-gradient-to-br from-blue-50 to-purple-50 dark:from-blue-950/20 dark:to-purple-950/20 rounded-2xl blur-3xl opacity-60" /> {/* Main card */} <motion.div initial={{ opacity: 0, y: 20, scale: 0.95 }} animate={{ opacity: 1, y: 0, scale: 1 }} transition={{ duration: 0.6, ease: "easeOut" }} className={cn( "relative backdrop-blur-xl bg-white/70 dark:bg-gray-900/70", "border border-white/20 dark:border-gray-700/30", "rounded-2xl p-8 shadow-2xl", "before:absolute before:inset-0 before:rounded-2xl", "before:bg-gradient-to-br before:from-white/10 before:to-transparent", "before:backdrop-blur-sm" )} > {/* Header */} <motion.div initial={{ opacity: 0, y: -10 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 0.2, duration: 0.5 }} className="text-center mb-8" > <motion.div initial={{ scale: 0 }} animate={{ scale: 1 }} transition={{ delay: 0.3, duration: 0.4, type: "spring" }} className="w-16 h-16 mx-auto mb-4 bg-gradient-to-br from-blue-500 to-purple-600 rounded-full flex items-center justify-center" > <User className="w-8 h-8 text-white" /> </motion.div> <motion.h2 initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ delay: 0.4, duration: 0.5 }} className="text-2xl font-bold bg-gradient-to-r from-gray-900 to-gray-600 dark:from-gray-100 dark:to-gray-400 bg-clip-text text-transparent" > {title} </motion.h2> <motion.p initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ delay: 0.5, duration: 0.5 }} className="text-gray-600 dark:text-gray-400 mt-2" > {subtitle} </motion.p> </motion.div> {/* Form fields */} <div className="space-y-4"> {formFields.map((field, index) => ( <motion.div key={index} initial={{ opacity: 0, x: -20 }} animate={{ opacity: 1, x: 0 }} transition={{ delay: field.delay, duration: 0.5, ease: "easeOut" }} className="relative" > <div className={cn( "relative flex items-center", "bg-white/50 dark:bg-gray-800/50", "border border-gray-200/50 dark:border-gray-600/50", "rounded-xl p-4 transition-all duration-300", "hover:bg-white/70 dark:hover:bg-gray-800/70", "hover:border-blue-300/50 dark:hover:border-blue-500/50", "focus-within:bg-white/80 dark:focus-within:bg-gray-800/80", "focus-within:border-blue-500/50", "focus-within:shadow-lg focus-within:shadow-blue-500/10" )}> <div className="text-gray-500 dark:text-gray-400 mr-3"> {field.icon} </div> <div className="flex-1"> <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ delay: field.delay + 0.3, duration: 0.3 }} className="text-xs text-gray-500 dark:text-gray-400 mb-1" > {field.placeholder} </motion.div> <motion.div initial={{ opacity: 0, y: 5 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: field.delay + 0.5, duration: 0.4 }} className="text-gray-900 dark:text-gray-100 font-medium" > {field.value} </motion.div> </div> {field.type === "password" && ( <motion.button initial={{ opacity: 0, scale: 0 }} animate={{ opacity: 1, scale: 1 }} transition={{ delay: field.delay + 0.7, duration: 0.3 }} onClick={() => setShowPassword(!showPassword)} className="text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 ml-2" > {showPassword ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />} </motion.button> )} </div> </motion.div> ))} </div> {/* Sign in button */} <motion.button initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 2.5, duration: 0.5, ease: "easeOut" }} className={cn( "w-full mt-6 bg-gradient-to-r from-blue-500 to-purple-600", "hover:from-blue-600 hover:to-purple-700", "text-white font-semibold py-3 px-6 rounded-xl", "flex items-center justify-center space-x-2", "transform transition-all duration-300", "hover:scale-[1.02] hover:shadow-lg hover:shadow-blue-500/25", "active:scale-[0.98]" )} > <span>Sign In</span> <motion.div animate={{ x: [0, 4, 0] }} transition={{ delay: 3, duration: 1, repeat: Infinity, repeatDelay: 2, ease: "easeInOut" }} > <ArrowRight className="w-4 h-4" /> </motion.div> </motion.button> {/* Footer */} <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ delay: 3.2, duration: 0.5 }} className="text-center mt-6" > <p className="text-sm text-gray-600 dark:text-gray-400"> Don't have an account?{" "} <span className="text-blue-600 dark:text-blue-400 hover:underline cursor-pointer font-medium"> Sign up </span> </p> </motion.div> {/* Decorative elements */} <motion.div animate={{ rotate: 360, scale: [1, 1.1, 1] }} transition={{ rotate: { duration: 20, repeat: Infinity, ease: "linear" }, scale: { duration: 4, repeat: Infinity, ease: "easeInOut" } }} className="absolute -top-4 -right-4 w-8 h-8 bg-gradient-to-br from-blue-400 to-purple-500 rounded-full opacity-20 blur-sm" /> <motion.div animate={{ rotate: -360, scale: [1, 1.2, 1] }} transition={{ rotate: { duration: 15, repeat: Infinity, ease: "linear" }, scale: { duration: 5, repeat: Infinity, ease: "easeInOut" } }} className="absolute -bottom-6 -left-6 w-12 h-12 bg-gradient-to-br from-purple-400 to-pink-500 rounded-full opacity-15 blur-sm" /> </motion.div> </div> ); };
4

Update the import paths to match your project setup

Props

PropTypeDefaultDescription
titlestringWelcome BackThe title to display on the form card.
subtitlestringSign in to your accountThe subtitle text below the main title.
delaynumber6000Time interval (in milliseconds) after which the animation restarts.