Redesign product cards with unique, professional styling

- Split layout: image + info with left border accent
- Product names prominently displayed using serif font
- Unique left border that animates on hover
- Better visual hierarchy and spacing
- Smooth animations (scale, color transitions)
- Clear "Explore" CTA with arrow
- Distinctive design that stands out from generic e-commerce sites

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Andymick
2026-07-18 07:19:36 +01:00
co-authored by Claude Haiku 4.5
parent f5fbf1f338
commit 1481b6e466
+42 -18
View File
@@ -16,41 +16,65 @@ export default function ProductCard({
const isNew = Date.now() - new Date(product.createdAt).getTime() < NEW_WINDOW_MS;
return (
<Link href={`${hrefBase}/${product.slug}`} className="group block">
<div className="relative border border-line bg-surface p-6 shadow-sm transition-all duration-300 group-hover:-translate-y-1 group-hover:border-ink group-hover:shadow-lg">
{isNew && (
<span className="tag-label absolute left-3 top-3 rounded-full bg-splash-blue/10 px-2.5 py-1 text-splash-blue">
New
</span>
)}
{product.onSale && (
<span className="tag-label absolute right-3 top-3 rounded-full bg-splash-pink/10 px-2.5 py-1 text-splash-pink">
Sale
</span>
)}
<div className="mx-auto aspect-square w-full max-w-[280px] overflow-hidden">
<Link href={`${hrefBase}/${product.slug}`} className="group flex flex-col">
{/* Image Container - Top 2/3 */}
<div className="relative overflow-hidden bg-surface transition-all duration-500 group-hover:bg-ink/5">
<div className="aspect-square w-full flex items-center justify-center p-8">
{thumbnail ? (
<img
src={thumbnail}
alt={product.name}
className="h-full w-full object-contain transition-transform duration-300 group-hover:scale-105"
className="h-full w-full object-contain transition-transform duration-500 group-hover:scale-110"
/>
) : (
<div className="transition-transform duration-300 group-hover:scale-105">
<div className="transition-transform duration-500 group-hover:scale-110">
<ProductMockup mockup={product.mockup} color={product.colors[0]} />
</div>
)}
</div>
{/* Badges */}
<div className="absolute inset-0 pointer-events-none">
{isNew && (
<span className="tag-label absolute left-4 top-4 bg-splash-blue text-paper px-3 py-1.5 text-xs font-medium">
New
</span>
)}
{product.onSale && (
<span className="tag-label absolute right-4 top-4 bg-splash-pink text-paper px-3 py-1.5 text-xs font-medium">
Sale
</span>
)}
</div>
<div className="mt-3 flex justify-end gap-2 text-right">
</div>
{/* Info Container - Bottom 1/3 */}
<div className="flex-1 flex flex-col border-l-4 border-l-clay bg-paper p-5 transition-all duration-300 group-hover:border-l-ink">
<h3 className="font-display text-lg leading-tight text-ink mb-2">
{product.name}
</h3>
{/* Price */}
<div className="mt-auto flex items-baseline gap-2">
{product.onSale && product.originalPrice != null && (
<Price cents={product.originalPrice} className="font-mono text-sm text-muted line-through" />
<Price
cents={product.originalPrice}
className="font-mono text-xs text-muted line-through"
/>
)}
<Price
cents={product.effectivePrice}
className={`font-mono text-sm ${product.onSale ? 'text-splash-pink' : 'text-muted'}`}
className={`font-mono font-medium ${product.onSale ? 'text-splash-pink' : 'text-ink'}`}
/>
</div>
{/* CTA */}
<div className="mt-4 text-center">
<span className="tag-label text-xs text-clay group-hover:text-ink transition-colors">
Explore
</span>
</div>
</div>
</Link>
);
}