Files
moygroup/app/components/ui/card.tsx
T
2026-06-03 16:13:15 +03:00

67 lines
2.2 KiB
TypeScript

"use client";
import { motion } from "framer-motion";
import { cn } from "@/lib/utils";
/* ── Base Card ── */
interface CardProps {
children: React.ReactNode;
hover?: boolean;
glass?: boolean;
className?: string;
}
export function Card({ children, hover = true, glass = false, className }: CardProps) {
return (
<motion.div
whileHover={hover ? { y: -6 } : undefined}
transition={{ duration: 0.35, ease: [0.16, 1, 0.3, 1] }}
className={cn(
"rounded-2xl overflow-hidden transition-shadow duration-300",
glass
? "bg-white/10 backdrop-blur-md border border-white/20"
: "bg-white border border-gray-100 shadow-[var(--shadow-sm)] hover:shadow-[var(--shadow-lg)]",
className
)}
>
{children}
</motion.div>
);
}
/* ── Image Card ── */
interface ImageCardProps {
src: string;
alt: string;
title: string;
subtitle?: string;
badge?: string;
className?: string;
}
export function ImageCard({ src, alt, title, subtitle, badge, className }: ImageCardProps) {
return (
<Card className={cn("group cursor-pointer", className)}>
<div className="relative h-64 overflow-hidden">
<img
src={src}
alt={alt}
className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-108"
/>
<div className="absolute inset-0 bg-gradient-to-t from-black/50 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-400" />
{badge && (
<span className="absolute top-4 left-4 text-[10px] uppercase tracking-[0.18em] font-semibold px-3 py-1 bg-[var(--color-moy-gold)] text-[var(--color-moy-dark)] rounded-full">
{badge}
</span>
)}
</div>
<div className="p-6 border-t-[1.5px] border-transparent group-hover:border-[var(--color-moy-gold)] transition-[border-color] duration-300">
<h3 className="text-xl font-serif text-[var(--color-moy-dark)] mb-2 leading-snug">{title}</h3>
{subtitle && (
<p className="text-sm text-gray-500 leading-relaxed">{subtitle}</p>
)}
</div>
</Card>
);
}