Innovations

Case Study Detail Template

Full-page case study layout with hero banner, challenge/approach/results overview, stats row, and testimonial quote.

Preview

Source

tsx
"use client";

import { caseStudies, testimonials, stats } from "@/lib/placeholders";
import { Badge } from "@/components/ui/badge";
import { Quote } from "lucide-react";

const cs = caseStudies[0];
const testimonial = testimonials[0];

const overview = [
  {
    label: "Challenge",
    color: "bg-red-500/10 text-red-600 border-red-200",
    icon: "⚡",
    text: "The client was struggling with an outdated brand, low search visibility, and a website that wasn't converting visitors into leads. They needed a complete transformation.",
  },
  {
    label: "Approach",
    color: "bg-blue-500/10 text-blue-600 border-blue-200",
    icon: "🔭",
    text: "We ran a full discovery sprint, rebuilt the brand identity from scratch, redesigned the website with conversion architecture, and launched a targeted SEO strategy.",
  },
  {
    label: "Results",
    color: "bg-green-500/10 text-green-600 border-green-200",
    icon: "🎯",
    text: `Leads increased by ${cs.metric} within 60 days. Organic traffic grew 3x in 90 days. The client expanded their team and raised their prices by 40%.`,
  },
];

export default function CaseStudyDetailTemplate() {
  return (
    <div className="bg-background text-foreground">
      {/* Hero */}
      <div className="relative h-72 sm:h-96 overflow-hidden">
        <img
          src={cs.image}
          alt={cs.client}
          className="h-full w-full object-cover"
        />
        <div className="absolute inset-0 bg-gradient-to-t from-black/80 via-black/40 to-transparent" />
        <div className="absolute bottom-0 left-0 right-0 p-8 sm:p-12">
          <p className="text-xs font-semibold uppercase tracking-widest text-white/70 mb-2">
            {cs.industry} · Case Study
          </p>
          <h1 className="text-2xl sm:text-4xl font-bold text-white max-w-2xl leading-tight">
            {cs.title}
          </h1>
          <div className="mt-4 inline-flex items-center gap-2 rounded-full bg-primary px-4 py-1.5 text-sm font-bold text-primary-foreground">
            {cs.metric} {cs.metricLabel}
          </div>
        </div>
      </div>

      <div className="mx-auto max-w-4xl px-4 sm:px-6 lg:px-8 py-14 space-y-16">
        {/* Overview: Challenge / Approach / Results */}
        <section>
          <h2 className="text-2xl font-bold text-foreground mb-6">Overview</h2>
          <div className="grid grid-cols-1 sm:grid-cols-3 gap-6">
            {overview.map((item) => (
              <div
                key={item.label}
                className={`rounded-xl border p-5 ${item.color}`}
              >
                <div className="text-2xl mb-2">{item.icon}</div>
                <h3 className="font-bold text-base mb-2">{item.label}</h3>
                <p className="text-sm leading-relaxed opacity-90">{item.text}</p>
              </div>
            ))}
          </div>
        </section>

        {/* Results Stats */}
        <section>
          <h2 className="text-2xl font-bold text-foreground mb-6">By the Numbers</h2>
          <div className="grid grid-cols-2 sm:grid-cols-4 gap-4">
            {stats.map((stat) => (
              <div
                key={stat.label}
                className="rounded-xl border border-border bg-card p-5 text-center"
              >
                <div className="text-3xl font-extrabold text-primary mb-1">
                  {stat.value}
                </div>
                <div className="text-xs text-muted-foreground font-medium">
                  {stat.label}
                </div>
              </div>
            ))}
          </div>
        </section>

        {/* Testimonial Quote */}
        <section>
          <div className="relative rounded-2xl border border-border bg-muted p-8 sm:p-10">
            <Quote className="absolute top-6 left-6 h-8 w-8 text-primary/20" />
            <blockquote className="relative z-10 text-lg sm:text-xl font-medium text-foreground leading-relaxed pl-4">
              "{testimonial.text}"
            </blockquote>
            <div className="mt-6 flex items-center gap-3">
              <img
                src={testimonial.avatar}
                alt={testimonial.name}
                className="h-10 w-10 rounded-full object-cover"
              />
              <div>
                <p className="text-sm font-semibold text-foreground">{testimonial.name}</p>
                <p className="text-xs text-muted-foreground">{testimonial.role}</p>
              </div>
            </div>
          </div>
        </section>

        {/* Tags */}
        <section>
          <h2 className="text-lg font-semibold text-foreground mb-3">Services Delivered</h2>
          <div className="flex flex-wrap gap-2">
            {cs.tags.map((tag) => (
              <Badge key={tag} variant="secondary" className="text-sm px-3 py-1">
                {tag}
              </Badge>
            ))}
          </div>
        </section>
      </div>
    </div>
  );
}
Claude Code Instructions

CLI Install

npx innovations add detail-template

Where to use it

Use this as a page layout for individual case study pages. In Next.js App Router: // app/case-studies/[slug]/page.tsx import CaseStudyDetailTemplate from '@/components/innovations/case-studies/detail-template'; export default function Page() { return <CaseStudyDetailTemplate />; } In Astro: // src/pages/case-studies/[slug].astro import CaseStudyDetailTemplate from '../components/innovations/case-studies/detail-template'; <CaseStudyDetailTemplate client:load /> Replace the hardcoded placeholder data with dynamic data fetched by slug from your CMS or data source.