"use client"; import { useId, type CSSProperties, type ElementType, type ReactNode } from "react"; import { motion, useReducedMotion } from "motion/react"; export type TeamGridMember = { name: string; role: string; /** Picture URL. Without one the card shows the initials. */ photo?: string; /** Opens on hover or focus. Always open on touch screens. */ bio?: string; /** Social or profile links, under the bio. */ links?: { label: string; href: string }[]; }; type TeamGridProps = { members: TeamGridMember[]; title?: string; /** Small line above the title. */ eyebrow?: string; subtitle?: string; /** Goes under the grid: a hiring note or a link. */ children?: ReactNode; /** Smallest card width in pixels. Sets how many fit in a row. */ minWidth?: number; /** Card colour. */ tile?: string; /** Card edge colour on hover. */ color?: string; /** h2 by default. */ headingAs?: ElementType; /** Set padding and colours here. */ className?: string; }; const initials = (name: string) => name .split(/\s+/) .slice(0, 2) .map((word) => word[0]) .join("") .toUpperCase(); /* TeamGrid: people cards that rise in on scroll. Hover or focus a card and its bio opens while the others dim. On touch screens the bios stay open. */ export function TeamGrid({ members, title, eyebrow, subtitle, children, minWidth = 210, tile = "#15122a", color = "#a78bfa", headingAs: Heading = "h2", className = "bg-[#0b0a14] px-5 py-16 text-white", }: TeamGridProps) { const reduce = useReducedMotion(); const id = useId(); return (
{title && (
{eyebrow &&

{eyebrow}

} {title} {subtitle &&

{subtitle}

}
)} {children &&
{children}
}
); }