Modern Info Card

A high-performance interactive profile component built with Framer Motion, featuring smooth hover-driven layout expansion, layered image scaling, and immersive audio feedback. This card demonstrates how motion, depth, and subtle micro-interactions can transform a simple layout into a polished, engaging user experience tailored for the modern web.

framer-motionlucide-react
profile

Mritunjay Rai

Designing Smooth, Interactive Interfaces For The Modern Web That Inspire

320
40

Installation

Install the required dependencies:

npm install framer-motion lucide-react
components/ui/modern-info-card.tsx
"use client";
  import { Plus, Repeat2, User } from "lucide-react";
  import { motion } from "framer-motion";
  import React, { useRef, useState } from "react";
  
  function ModernInfoCard() {
    const [hover, setHover] = useState(false);
    const audioRef = useRef<HTMLAudioElement | null>(null);
  
    return (
      <motion.div
        onHoverStart={() => {
          setHover(true);
          if (audioRef.current) {
            audioRef.current.currentTime = 0; // restart sound
            audioRef.current.play();
          }
        }}
        onHoverEnd={() => {
          setHover(false);
          if (audioRef.current) {
            audioRef.current.currentTime = 0; // restart sound
            audioRef.current.play();
          }
        }}
        whileHover={{ y: -12 }}
        transition={{ type: "spring", stiffness: 200, damping: 15 }}
        className="relative w-[22rem] h-[35rem] rounded-[3rem] bg-[#FFFDF1] overflow-hidden p-3 shadow-[0_40px_80px_rgba(0,0,0,0.25)]"
      >
        <audio ref={audioRef} src="/whoosh.wav" preload="auto" />
        {/* Image Section */}
        <motion.div
          animate={{ height: hover ? "100%" : "50%" }}
          transition={{ duration: 0.5, ease: "easeInOut" }}
          className="relative w-full overflow-hidden rounded-[2.5rem]"
        >
          <motion.img
            src="https://res.cloudinary.com/dmqwpwo6c/image/upload/v1776147234/myimg2_rfavkf.jpg"
            alt="profile"
            className="w-full h-full object-cover"
            animate={{ scale: hover ? 1.1 : 1 }}
            transition={{ duration: 0.6 }}
          />
  
          {/* Gradient Overlay */}
          <motion.div
            animate={{ opacity: hover ? 1 : 0 }}
            transition={{ duration: 0.4 }}
            className="absolute inset-0 bg-gradient-to-t from-white/100 via-transparent to-transparent"
          />
        </motion.div>
  
        {/* Content Section */}
        <motion.div
          animate={{
            color: hover ? "#ffffff" : "#111111",
          }}
          transition={{ duration: 0.4 }}
          className={`w-full mt-8  px-6 ${hover ? "absolute bottom-6 left-0" : ""}`}
        >
          <div className="w-full">
            <motion.h3
              layout
              className="text-3xl font-bold tracking-tight text-black"
            >
              Mritunjay Rai
            </motion.h3>
  
            <motion.p
              layout
              className="mt-4 text-lg opacity-80 leading-relaxed text-black"
            >
              Designing Smooth, Interactive Interfaces For The Modern Web That
              Inspire
            </motion.p>
          </div>
  
          {/* Stats & Button */}
          <motion.div
            layout
            className={`mt-6 w-full flex gap-5 items-end h-full text-black`}
          >
            <div className="flex items-center text-lg font-semibold gap-2">
              <User size={20} />
              320
            </div>
  
            <div className="flex items-center text-lg font-semibold gap-2">
              <Repeat2 size={20} />
              40
            </div>
  
            {/* Follow Button */}
            <motion.button
              whileTap={{ scale: 0.9 }}
              whileHover={{ scale: 1.1 }}
              transition={{ type: "spring", stiffness: 300 }}
              className="ml-auto flex items-center gap-2 bg-black text-white rounded-full px-5 py-3 shadow-lg"
            >
              Follow <Plus size={18} />
            </motion.button>
          </motion.div>
        </motion.div>
      </motion.div>
    );
  }
  
  export default ModernInfoCard;