Divyansh Mishra
pnpm add motion motionCreate components/book-card.tsx and paste the code below:
"use client";
import { cn } from "@/lib/utils";
import { motion } from "motion/react";
interface BookCardProps {
title?: string;
author?: string;
width?: string;
themeColor?: string;
}
const BookCard = ({
title = "My Book",
author = "Author",
width = "200px",
themeColor = "#e74c3c",
}: BookCardProps) => {
return (
<div
className={cn("@container flex flex-col items-center justify-center p-4")}
style={{ width }}
>
<motion.div
className="relative aspect-[3/4.5] w-full cursor-pointer"
initial="rest"
whileHover="hover"
animate="rest"
style={{ perspective: "1200px", transformStyle: "preserve-3d" }}
>
<div
className="absolute inset-0 rounded-l-[4cqw] rounded-r-[12cqw] shadow-2xl"
style={{ backgroundColor: themeColor }}
>
<div className="absolute inset-y-0 left-0 w-[15%] rounded-l-[4cqw] bg-black/20" />
</div>
<div className="absolute inset-y-[2%] right-[2%] left-[12%] flex flex-col rounded-r-[8cqw] bg-white shadow-inner">
<div className="h-[5%] w-full border-b border-black/5" />
<div className="relative w-full flex-1 overflow-hidden bg-white">
<div className="absolute inset-0 bg-[repeating-linear-gradient(transparent,transparent_4%,#000_5%)] opacity-10" />
</div>
<div className="flex h-[10%] w-full items-center border-t border-black/5 px-2">
<div className="h-1 w-full rounded-full bg-black/5" />
</div>
<div className="absolute right-[20%] -bottom-[8%] z-10 h-[30%] w-[18%]">
<div
className="h-full w-full bg-[#f1c40f] shadow-md"
style={{
clipPath: "polygon(0 0, 100% 0, 100% 100%, 50% 85%, 0 100%)",
}}
/>
</div>
</div>
<motion.div
variants={{
rest: { rotateY: 0 },
hover: { rotateY: -30 },
}}
transition={{ type: "spring", stiffness: 60, damping: 20 }}
style={{
transformOrigin: "left center",
zIndex: 40,
transformStyle: "preserve-3d",
backgroundColor: themeColor,
}}
className="absolute inset-0 rounded-l-[4cqw] rounded-r-[12cqw] border-l border-black/10 shadow-lg"
>
<div className="absolute inset-y-0 left-[12%] w-0.5 bg-black/10 shadow-[1px_0_2px_rgba(0,0,0,0.1)]" />
<div className="pointer-events-none flex h-full w-full flex-col items-center justify-center px-[15%] text-center text-white uppercase">
<h2 className="my-[10%] flex flex-col text-[11cqw] leading-[0.9] font-black tracking-tighter">
{title.split(" ").map((word, i) => (
<span key={i}>{word}</span>
))}
</h2>
<div className="h-[0.5cqw] w-[25%] bg-white/30" />
<span className="mt-[15%] text-[5cqw] font-bold tracking-[0.2em] opacity-80">
{author}
</span>
</div>
</motion.div>
</motion.div>
<div className="mt-8 flex flex-col items-center gap-1">
<h3 className="text-sm font-bold tracking-tight text-neutral-800 dark:text-neutral-200">
{title}
</h3>
<p className="text-[10px] font-semibold tracking-[0.2em] text-neutral-400 uppercase">
{author}
</p>
</div>
</div>
);
};
export default BookCard;
import BookCard from "@/components/book-card";
export default function MyComponent() {
return (
<BookCard
title="The Design"
author="D. Mishra"
width="160px"
themeColor="#471396"
/>
);
}