A studio's careers section with the team as portrait tiles and three orange open seats. Rest on a face for a name and role.
registry/demos/slide-puzzle-team-demo.tsx
import * as React from "react";
import { SlidePuzzle, type SlidePuzzleTile } from "@/components/ui/slide-puzzle";
const portrait = (id: string) =>
`https://images.unsplash.com/photo-${id}?auto=format&fit=facearea&facepad=2.5&w=128&h=128&q=80`;
// Field & Fold, a small type-tools studio: the team, plus the seats that are open.
const PEOPLE: [string, string, string][] = [
["ines", "Inês Duarte · Design lead", "1438761681033-6461ffad8d80"],
["matteo", "Matteo Ricci · Engineering", "1500648767791-00dcc994a43e"],
["sofia", "Sofia Lindqvist · Type design", "1494790108377-be9c29b29330"],
["dev", "Dev Arora · Founder", "1507003211169-0a1dd7228f2d"],
["hana", "Hana Mori · Product", "1534528741775-53994a69daeb"],
["noor", "Noor Haddad · Research", "1544005313-94ddf0286df2"],
["luca", "Luca Brandt · Engineering", "1506794778202-cad84cf45f1d"],
["ada", "Ada Okafor · Support", "1573496359142-b8d87734a5a2"],
["tomas", "Tomás Vidal · Fonts", "1552058544-f2b08422138a"],
];
const SEATS = ["Product designer", "Rust engineer", "Type engineer"];
const TILES: SlidePuzzleTile[] = [
...PEOPLE.map(([id, label, photo]) => ({
id,
label,
href: `#team-${id}`,
// eslint-disable-next-line @next/next/no-img-element
icon: <img src={portrait(photo)} alt="" draggable={false} className="size-full object-cover" />,
})),
...SEATS.map((role, i) => ({
id: `seat-${i}`,
label: `Open seat · ${role}`,
href: "#roles",
icon: (
<span className="flex size-full items-center justify-center bg-[#ff5a1f]/10 text-[#ff5a1f] dark:bg-[#ff5a1f]/15">
<svg viewBox="0 0 16 16" className="size-4" aria-hidden>
<path d="M8 3v10M3 8h10" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" />
</svg>
</span>
),
})),
];
export function SlidePuzzleTeamDemo() {
return (
<section className="w-full max-w-5xl overflow-hidden rounded-3xl border border-zinc-950/[0.06] bg-zinc-50 text-zinc-950 dark:border-white/10 dark:bg-zinc-950 dark:text-white">
<SlidePuzzle tiles={TILES} cell={68} seed={3}>
<div className="flex max-w-md flex-col items-center text-center">
<p className="text-xs font-medium uppercase tracking-[0.14em] text-[#ff5a1f]">Careers · 3 open seats</p>
<h2 className="mt-3 text-balance text-3xl font-medium tracking-[-0.03em] sm:text-4xl">
Come make small things feel right.
</h2>
<p className="mt-3 text-pretty text-[15px] leading-relaxed text-zinc-500 dark:text-zinc-400">
We're nine people in Lisbon and Oslo building the tools type designers open every morning. The orange
tiles are waiting for someone.
</p>
<div className="mt-6 flex flex-wrap items-center justify-center gap-2">
<a
href="#roles"
className="inline-flex h-9 items-center rounded-full bg-zinc-950 px-4 text-sm font-medium text-white transition-colors hover:bg-zinc-800 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#ff5a1f] dark:bg-white dark:text-zinc-950 dark:hover:bg-zinc-200"
>
See open roles
</a>
<a
href="#studio"
className="inline-flex h-9 items-center rounded-full px-3 text-sm font-medium text-zinc-600 transition-colors hover:text-zinc-950 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#ff5a1f] dark:text-zinc-400 dark:hover:text-white"
>
How we work →
</a>
</div>
</div>
</SlidePuzzle>
</section>
);
}
Live preview, examples and props: https://keyframeui.com/components/slide-puzzle#slide-puzzle-team-demo