4 Commits

View File

@@ -87,40 +87,81 @@ const TestimonialCard = memo(({
companyClassName = "", companyClassName = "",
}: TestimonialCardProps) => { }: TestimonialCardProps) => {
return ( return (
<div className={cls("relative h-full aspect-[8/10] rounded-theme-capped overflow-hidden group", cardClassName)}> <div className={cls("relative h-full aspect-[8/10] rounded-theme-capped overflow-hidden group", cardClassName)} style={{animation: "cardEntrance 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) forwards"}}>
<MediaContent <style>{`
imageSrc={testimonial.imageSrc} @keyframes cardEntrance {
videoSrc={testimonial.videoSrc} from {
imageAlt={testimonial.imageAlt || testimonial.name} opacity: 0;
videoAriaLabel={testimonial.videoAriaLabel || testimonial.name} transform: translateY(30px) scale(0.95);
imageClassName={cls("relative z-1 w-full h-full object-cover!", imageClassName)} }
/> to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
@keyframes glowPulse {
0%, 100% {
box-shadow: 0 0 20px rgba(var(--accent-rgb), 0.3), 0 20px 40px rgba(0, 0, 0, 0.15);
}
50% {
box-shadow: 0 0 40px rgba(var(--accent-rgb), 0.5), 0 25px 50px rgba(0, 0, 0, 0.2);
}
}
.group:hover .testimonial-inner {
animation: glowPulse 2s ease-in-out infinite;
}
`}</style>
<div className="testimonial-inner relative w-full h-full transition-all duration-500 ease-out group-hover:shadow-2xl group-hover:-translate-y-12 group-hover:scale-105 group-hover:[transform:perspective(1000px)_rotateX(2deg)_rotateY(-3deg)_translateY(-48px)_scale(1.05)]" style={{}}>
{/* Front of card */}
<div className="absolute w-full h-full">
<MediaContent
imageSrc={testimonial.imageSrc}
videoSrc={testimonial.videoSrc}
imageAlt={testimonial.imageAlt || testimonial.name}
videoAriaLabel={testimonial.videoAriaLabel || testimonial.name}
imageClassName={cls("relative z-1 w-full h-full object-cover!", imageClassName)}
/>
<div className={cls("!absolute z-1 bottom-6 left-6 right-6 card backdrop-blur-xs p-6 flex flex-col gap-3 rounded-theme-capped", overlayClassName)}> <div className={cls("!absolute z-1 bottom-6 left-6 right-6 card backdrop-blur-xs p-6 flex flex-col gap-3 rounded-theme-capped", overlayClassName)}>
<div className={cls("relative z-1 flex gap-1", ratingClassName)}> =======
{Array.from({ length: 5 }).map((_, index) => ( <div className={cls("relative z-1 flex gap-1", ratingClassName)}>
<Star {Array.from({ length: 5 }).map((_, index) => (
key={index} <Star
className={cls( key={index}
"h-5 w-auto text-accent", className={cls(
index < testimonial.rating ? "fill-accent" : "fill-transparent" "h-5 w-auto text-accent",
)} index < testimonial.rating ? "fill-accent" : "fill-transparent"
strokeWidth={1.5} )}
/> strokeWidth={1.5}
))} />
))}
</div>
<h3 className={cls("relative z-1 text-2xl font-medium text-foreground leading-[1.1] mt-1", nameClassName)}>
{testimonial.name}
</h3>
<div className="relative z-1 flex flex-col gap-1">
<p className={cls("text-base text-foreground leading-[1.1]", roleClassName)}>
{testimonial.role}
</p>
<p className={cls("text-base text-foreground leading-[1.1]", companyClassName)}>
{testimonial.company}
</p>
</div>
</div>
</div> </div>
<h3 className={cls("relative z-1 text-2xl font-medium text-foreground leading-[1.1] mt-1", nameClassName)}> {/* Back of card */}
{testimonial.name} <div style={{ backfaceVisibility: "hidden", transform: "rotateY(180deg)" }} className="absolute w-full h-full bg-gradient-to-br from-accent/10 to-accent/5 backdrop-blur-xs rounded-theme-capped p-6 flex flex-col justify-center items-center gap-4">
</h3> <div className="text-center">
<p className="text-sm text-foreground/80 mb-4">
<div className="relative z-1 flex flex-col gap-1"> {testimonial.testimonial || "Exceptional results and outstanding service delivery."}
<p className={cls("text-base text-foreground leading-[1.1]", roleClassName)}> </p>
{testimonial.role} <button className="px-6 py-2 bg-accent text-accent-foreground rounded-theme-capped font-medium text-sm hover:bg-accent/90 transition-colors duration-300">
</p> Learn More
<p className={cls("text-base text-foreground leading-[1.1]", companyClassName)}> </button>
{testimonial.company} </div>
</p>
</div> </div>
</div> </div>
</div> </div>