Six portraits in black and white, with the open one in color through `imageClassName`. The role takes the person's accent. On a phone the portraits stack; on a touch screen side by side, drag a finger across them to flip through faces.
@keyframeui
registry/demos/slice-gallery-team-demo.tsx
import { SliceGallery, SliceGalleryItem } from "@/components/ui/slice-gallery";
const people = [
{
name: "Ines Moreau",
role: "Creative Director",
city: "Paris",
note: "Sets the tone for every launch, then argues about kerning.",
photo: "1438761681033-6461ffad8d80",
accent: "#f5b8a8",
},
{
name: "Rafael Santos",
role: "Design Lead",
city: "Lisbon",
note: "Runs the design system and the Friday crits.",
photo: "1507003211169-0a1dd7228f2d",
accent: "#a8d5f5",
},
{
name: "Mei Tanaka",
role: "Motion Designer",
city: "Tokyo",
note: "Makes the product move, and knows when it shouldn't.",
photo: "1534528741775-53994a69daeb",
accent: "#c8b6ff",
},
{
name: "Luca Bianchi",
role: "Engineering Lead",
city: "Milan",
note: "Ships the hard parts and keeps the build under a minute.",
photo: "1500648767791-00dcc994a43e",
accent: "#b4e3c3",
},
{
name: "Amara Okafor",
role: "Strategy Director",
city: "Lagos",
note: "Turns research into the brief everyone else works from.",
photo: "1531123897727-8f129e1688ce",
accent: "#ffd28a",
},
{
name: "Jonas Weber",
role: "Brand Designer",
city: "Berlin",
note: "Draws the logos, then draws them again, smaller.",
photo: "1539571696357-5a69c17a67c6",
accent: "#f7a8cf",
},
];
const photo = (id: string) =>
`https://images.unsplash.com/photo-${id}?auto=format&fit=crop&crop=faces&w=800&h=1000&q=80`;
const slug = (name: string) => name.toLowerCase().replace(/\s+/g, ".");
export function SliceGalleryTeamDemo() {
return (
<section className="w-full max-w-4xl">
<div className="mb-6">
<p className="font-mono text-xs tracking-widest text-zinc-500 uppercase">The studio</p>
<h3 className="mt-2 text-2xl font-semibold tracking-tight text-zinc-900 dark:text-zinc-50">
Six people, four time zones
</h3>
</div>
<SliceGallery grow={4} gap={6} defaultIndex={2} className="h-[36rem] sm:h-[28rem]">
{people.map((person) => (
<SliceGalleryItem
key={person.name}
title={person.name}
label={person.city}
image={photo(person.photo)}
accent={person.accent}
className="rounded-xl"
imageClassName="grayscale transition-[filter] duration-700 group-data-[state=open]/slice:grayscale-0"
>
<p className="text-sm font-medium" style={{ color: person.accent }}>
{person.role}
</p>
<p className="mt-1 max-w-[16rem] text-sm leading-snug text-pretty text-white/85">
{person.note}
</p>
<a
href={`mailto:${slug(person.name)}@studio.example`}
className="mt-3 inline-flex rounded text-xs text-white/70 underline-offset-4 outline-none hover:text-white hover:underline focus-visible:ring-2 focus-visible:ring-white/70"
>
{slug(person.name)}@studio.example
</a>
</SliceGalleryItem>
))}
</SliceGallery>
</section>
);
}
Live preview, examples and props: https://keyframeui.com/components/slice-gallery#slice-gallery-team-demo























