Case Study Card Grid
Grid of case study cards with metrics, client details, and image previews.
Preview
Source
tsx
"use client";
import { caseStudies } from "@/lib/placeholders";
import { Badge } from "@/components/ui/badge";
import { ArrowRight } from "lucide-react";
export default function CaseStudyCardGrid() {
return (
<section className="bg-background py-16 px-4 sm:px-6 lg:px-8">
<div className="mx-auto max-w-6xl">
<div className="mb-10 text-center">
<p className="text-sm font-semibold uppercase tracking-widest text-primary mb-2">
Client Results
</p>
<h2 className="text-3xl font-bold text-foreground sm:text-4xl">
Real work. Real outcomes.
</h2>
</div>
<div className="grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3">
{caseStudies.map((cs) => (
<article
key={cs.id}
className="group relative flex flex-col rounded-2xl border border-border bg-card overflow-hidden shadow-sm transition-all duration-300 hover:-translate-y-1 hover:shadow-xl"
>
{/* Image + metric badge */}
<div className="relative h-48 overflow-hidden">
<img
src={cs.image}
alt={cs.client}
className="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105"
/>
<div className="absolute inset-0 bg-gradient-to-t from-black/40 to-transparent" />
<span className="absolute top-3 right-3 rounded-full bg-primary px-3 py-1 text-sm font-bold text-primary-foreground shadow-md">
{cs.metric}
</span>
<span className="absolute bottom-3 left-3 text-xs text-white/90 font-medium bg-black/30 rounded-full px-2 py-0.5">
{cs.metricLabel}
</span>
</div>
{/* Content */}
<div className="flex flex-1 flex-col p-5 gap-3">
{/* Client + industry */}
<div className="flex items-center gap-2 flex-wrap">
<span className="text-sm font-semibold text-foreground">{cs.client}</span>
<span className="text-muted-foreground text-xs">·</span>
<span className="text-xs text-muted-foreground">{cs.industry}</span>
</div>
{/* Title */}
<h3 className="text-base font-bold text-foreground leading-snug">
{cs.title}
</h3>
{/* Summary */}
<p className="text-sm text-muted-foreground leading-relaxed flex-1">
{cs.summary}
</p>
{/* Tags */}
<div className="flex flex-wrap gap-1.5 pt-1">
{cs.tags.map((tag) => (
<Badge key={tag} variant="secondary" className="text-xs">
{tag}
</Badge>
))}
</div>
{/* Link */}
<a
href={`#case-study-${cs.id}`}
className="mt-2 inline-flex items-center gap-1 text-sm font-semibold text-primary hover:underline group/link"
>
Read case study
<ArrowRight className="h-4 w-4 transition-transform group-hover/link:translate-x-1" />
</a>
</div>
</article>
))}
</div>
</div>
</section>
);
} Claude Code Instructions
CLI Install
npx innovations add card-gridWhere to use it
Place this section on your portfolio or services pages to showcase client results.
In Astro:
import CaseStudyCardGrid from '../components/innovations/case-studies/card-grid';
<CaseStudyCardGrid client:visible />
In Next.js:
import CaseStudyCardGrid from '@/components/innovations/case-studies/card-grid';
Replace the imported caseStudies data with your actual client case studies.
Each case study needs: client, industry, image (URL), metric, metricLabel, title, summary, tags[].