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-grid

Where 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[].