Team Grid
Team cards with social links that slide up on hover.
components/ui/team-grid.tsx
"use client";
import { motion } from "motion/react";
import { Github, Linkedin, Twitter } from "lucide-react";
type Member = { name: string; role: string; color: string };
const defaultTeam: Member[] = [
{ name: "Ava Chen", role: "CEO & Co-founder", color: "from-blue-400 to-indigo-600" },
{ name: "Liam Patel", role: "CTO & Co-founder", color: "from-violet-400 to-fuchsia-600" },
{ name: "Noah Kim", role: "Head of Design", color: "from-emerald-400 to-teal-600" },
{ name: "Mia Rossi", role: "Lead Engineer", color: "from-amber-400 to-orange-600" },
];
export function TeamGrid({ team = defaultTeam }: { team?: Member[] }) {
return (
<div className="grid gap-5 sm:grid-cols-2 lg:grid-cols-4">
{team.map((m, i) => (
<motion.div
key={m.name}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ delay: i * 0.08, duration: 0.5 }}
className="group text-center"
>
<div className={`relative mx-auto aspect-square overflow-hidden rounded-3xl bg-gradient-to-br ${m.color}`}>
<span className="absolute inset-0 grid place-items-center text-5xl font-semibold text-white/90 transition-transform duration-500 group-hover:scale-110">
{m.name.split(" ").map((n) => n[0]).join("")}
</span>
<div className="absolute inset-x-0 bottom-0 flex translate-y-full justify-center gap-2 bg-gradient-to-t from-black/40 to-transparent p-4 transition-transform duration-300 group-hover:translate-y-0">
{[Twitter, Linkedin, Github].map((Icon, k) => (
<a key={k} href="#" aria-label={`${m.name} profile`} className="grid size-9 place-items-center rounded-full bg-white/90 text-zinc-800 transition hover:bg-white">
<Icon className="size-4" />
</a>
))}
</div>
</div>
<p className="mt-4 font-semibold text-zinc-900">{m.name}</p>
<p className="text-sm text-zinc-500">{m.role}</p>
</motion.div>
))}
</div>
);
}
export default function Demo() {
return (
<div className="w-full max-w-4xl">
<TeamGrid />
</div>
);
}
Installation
Install the dependencies
$ npm i motion lucide-reactCopy the source into
components/ui/team-grid.tsxcomponents/ui/team-grid.tsx"use client"; import { motion } from "motion/react"; import { Github, Linkedin, Twitter } from "lucide-react"; type Member = { name: string; role: string; color: string }; const defaultTeam: Member[] = [ { name: "Ava Chen", role: "CEO & Co-founder", color: "from-blue-400 to-indigo-600" }, { name: "Liam Patel", role: "CTO & Co-founder", color: "from-violet-400 to-fuchsia-600" }, { name: "Noah Kim", role: "Head of Design", color: "from-emerald-400 to-teal-600" }, { name: "Mia Rossi", role: "Lead Engineer", color: "from-amber-400 to-orange-600" }, ]; export function TeamGrid({ team = defaultTeam }: { team?: Member[] }) { return ( <div className="grid gap-5 sm:grid-cols-2 lg:grid-cols-4"> {team.map((m, i) => ( <motion.div key={m.name} initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ delay: i * 0.08, duration: 0.5 }} className="group text-center" > <div className={`relative mx-auto aspect-square overflow-hidden rounded-3xl bg-gradient-to-br ${m.color}`}> <span className="absolute inset-0 grid place-items-center text-5xl font-semibold text-white/90 transition-transform duration-500 group-hover:scale-110"> {m.name.split(" ").map((n) => n[0]).join("")} </span> <div className="absolute inset-x-0 bottom-0 flex translate-y-full justify-center gap-2 bg-gradient-to-t from-black/40 to-transparent p-4 transition-transform duration-300 group-hover:translate-y-0"> {[Twitter, Linkedin, Github].map((Icon, k) => ( <a key={k} href="#" aria-label={`${m.name} profile`} className="grid size-9 place-items-center rounded-full bg-white/90 text-zinc-800 transition hover:bg-white"> <Icon className="size-4" /> </a> ))} </div> </div> <p className="mt-4 font-semibold text-zinc-900">{m.name}</p> <p className="text-sm text-zinc-500">{m.role}</p> </motion.div> ))} </div> ); } export default function Demo() { return ( <div className="w-full max-w-4xl"> <TeamGrid /> </div> ); }Use it
The file exports the component and a
Demoshowing typical usage. Import whichever you need.