agency-web/app/components/CaseStudies.tsx

67 lines
2.4 KiB
TypeScript

"use client";
/**
* CaseStudies — large film-cell cards. Each is a real <article> with the
* generated capsule visual, a problem -> result narrative, the method, and the
* headline metric. Alternating media side creates an editorial rhythm; refined
* scale-on-hover on the image. Images are explicit-sized + lazy-loaded.
*/
import Reveal from "./Reveal";
import { cases } from "../content";
export default function CaseStudies() {
return (
<section id="work" className="cases" aria-label="Case studies">
<div className="wrap">
<Reveal>
<p className="kicker">Case studies</p>
<h2 className="section__title">Proof, not promises.</h2>
<p className="section__lead">
A few of the businesses we&apos;ve grown. Same approach every time:
tie the work to the revenue, then prove it.
</p>
</Reveal>
<div className="cases__list">
{cases.map((c, i) => (
<Reveal key={c.tag} y={60}>
<article className="case hoverable" data-cursor="view work">
<div className="case__media">
<span className="case__tag">{c.tag}</span>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
src={c.img}
alt={c.alt}
className="case__img"
width={900}
height={760}
loading={i === 0 ? "eager" : "lazy"}
decoding="async"
/>
</div>
<div className="case__body">
<p className="case__problem">{c.problem}</p>
<h3 className="case__result">
<em>{c.result}</em>
</h3>
<p className="case__how">{c.how}</p>
<p className="case__metric">
<span className="case__metric-num">{c.metricNum}</span>
<span className="case__metric-label">{c.metricLabel}</span>
</p>
</div>
</article>
</Reveal>
))}
</div>
<div className="cases__cta">
<a className="btn btn--ghost hoverable" href="#contact">
<span>View all work </span>
</a>
</div>
</div>
</section>
);
}