hotschpotsh/Pottery-website/components/Collections.tsx

118 lines
4.0 KiB
TypeScript

import React from 'react';
import { motion } from 'framer-motion';
import { COLLECTIONS } from '../constants';
import { CollectionItem } from '../types';
const cardVariants = {
hidden: {
opacity: 0,
y: 80,
rotateX: 15,
},
visible: (index: number) => ({
opacity: 1,
y: 0,
rotateX: 0,
transition: {
delay: index * 0.15,
duration: 0.8,
ease: [0.25, 0.46, 0.45, 0.94],
},
}),
};
const Collections: React.FC = () => {
const col1 = [COLLECTIONS[0], COLLECTIONS[1]];
const col2 = [COLLECTIONS[2], COLLECTIONS[3]];
const col3 = [COLLECTIONS[4], COLLECTIONS[5]];
const renderCard = (item: CollectionItem, index: number) => (
<motion.a
key={item.id}
className="group block cursor-pointer"
href="#"
variants={cardVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: "-100px" }}
custom={index}
>
<div className={`relative overflow-hidden ${item.aspectRatio} mb-6`}>
{/* Image with clean hover effect */}
<motion.img
alt={`${item.title} collection`}
className="w-full h-full object-cover"
src={item.image}
whileHover={{ scale: 1.05 }}
transition={{ duration: 0.6, ease: [0.25, 0.46, 0.45, 0.94] }}
/>
{/* Subtle overlay that fades out on hover */}
<motion.div
className="absolute inset-0 bg-black/5"
initial={{ opacity: 1 }}
whileHover={{ opacity: 0 }}
transition={{ duration: 0.4 }}
/>
{/* Clean reveal line effect on hover */}
<motion.div
className="absolute bottom-0 left-0 right-0 h-1 bg-white/80"
initial={{ scaleX: 0 }}
whileHover={{ scaleX: 1 }}
transition={{ duration: 0.5, ease: "easeOut" }}
style={{ transformOrigin: "left" }}
/>
</div>
<motion.div
className="flex justify-between items-center border-t border-gray-400/50 dark:border-gray-800 pt-4"
initial={{ opacity: 0.8 }}
whileHover={{ opacity: 1 }}
>
<h3 className="font-display text-3xl font-light text-text-main dark:text-white group-hover:italic transition-all duration-300">
{item.title}
</h3>
<motion.span
className="text-xs uppercase tracking-widest text-text-muted"
whileHover={{ x: 5 }}
transition={{ duration: 0.3 }}
>
{item.number}
</motion.span>
</motion.div>
</motion.a>
);
return (
<section className="py-32 bg-warm-grey dark:bg-[#141210] transition-colors duration-500">
<div className="max-w-[1920px] mx-auto px-6 md:px-12">
<motion.div
className="flex flex-col md:flex-row justify-between items-end mb-20 md:mb-32 px-4"
initial={{ opacity: 0, y: 40 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.8, ease: "easeOut" }}
>
<h2 className="font-display text-5xl md:text-7xl font-thin text-text-main dark:text-white">
Curated <span className="italic text-text-muted">Editions</span>
</h2>
<p className="hidden md:block font-body text-sm text-text-muted max-w-xs leading-relaxed text-right">
Explore our seasonal collections, fired in small batches.
</p>
</motion.div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 lg:gap-16">
<div className="flex flex-col space-y-16 md:space-y-32">
{col1.map((item, idx) => renderCard(item, idx))}
</div>
<div className="flex flex-col space-y-16 md:space-y-32 md:pt-32">
{col2.map((item, idx) => renderCard(item, idx + 2))}
</div>
<div className="flex flex-col space-y-16 md:space-y-32 md:pt-16 lg:pt-0">
{col3.map((item, idx) => renderCard(item, idx + 4))}
</div>
</div>
</div>
</section>
);
};
export default Collections;