# Team Grid

> Team member cards with gradient initials avatars, roles and social icon buttons.

- Author: Atelier UI
- License: MIT
- Page: https://chromotion.dev/en/components/team-grid
- Site: Atelier UI (https://chromotion.dev)

## Install

```bash
npx shadcn@latest add https://chromotion.dev/r/team-grid.json
```

Stack: React + TypeScript + Tailwind CSS v4, shadcn/ui conventions. `cn` comes from `@/lib/utils`.

## Dependencies

```bash
npm install lucide-react
```

## Usage

```tsx title="components/team-grid-demo.tsx"
import { TeamGrid } from "@/components/team-grid"

export default function TeamGridDemo() {
  return (
    <div className="w-full max-w-5xl">
      <TeamGrid
        members={[
          { name: "Elena Rossi", role: "Co-founder & CEO", bio: "Former product lead who believes good tools disappear into the work.", email: "elena@example.com", link: "#", website: "#" },
          { name: "Marcus Webb", role: "Head of Engineering", bio: "Builds fast, boring infrastructure so everyone else can be creative.", email: "marcus@example.com", link: "#", website: "#" },
          { name: "Aiko Tanaka", role: "Principal Designer", bio: "Obsessed with spacing, type and the small details nobody notices.", email: "aiko@example.com", link: "#", website: "#" },
        ]}
      />
    </div>
  )
}
```

## Source

```tsx title="components/team-grid.tsx"
import * as React from "react"
import { Globe, Link as LinkIcon, Mail } from "lucide-react"

import { cn } from "@/lib/utils"

export interface TeamMember {
  name: string
  role: string
  bio?: string
  email?: string
  /** Profile or social link */
  link?: string
  website?: string
}

export interface TeamGridProps extends React.ComponentProps<"section"> {
  members: TeamMember[]
}

const gradients = [
  "from-rose-400 to-orange-400",
  "from-sky-400 to-indigo-500",
  "from-emerald-400 to-teal-500",
  "from-amber-400 to-pink-500",
  "from-violet-400 to-fuchsia-500",
  "from-cyan-400 to-blue-500",
]

const socialClass =
  "inline-flex size-9 items-center justify-center rounded-full border bg-background text-muted-foreground outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:ring-4 focus-visible:ring-ring/40"

function initials(name: string) {
  return name
    .split(/\s+/)
    .filter(Boolean)
    .slice(0, 2)
    .map((part) => part[0]?.toUpperCase())
    .join("")
}

export function TeamGrid({ members, className, ...props }: TeamGridProps) {
  return (
    <section className={cn("w-full px-6 py-12", className)} {...props}>
      <ul className="mx-auto grid max-w-5xl gap-5 sm:grid-cols-2 lg:grid-cols-3">
        {members.map((m, i) => (
          <li
            key={m.name}
            className="flex flex-col items-center rounded-2xl border bg-card p-6 text-center text-card-foreground shadow-sm"
          >
            <span
              aria-hidden
              className={cn(
                "flex size-20 items-center justify-center rounded-full bg-linear-to-br text-xl font-semibold text-white shadow-inner",
                gradients[i % gradients.length]
              )}
            >
              {initials(m.name)}
            </span>
            <h3 className="mt-4 text-base font-semibold">{m.name}</h3>
            <p className="text-sm text-muted-foreground">{m.role}</p>
            {m.bio && <p className="mt-3 text-sm leading-relaxed text-muted-foreground">{m.bio}</p>}
            <div className="mt-4 flex items-center gap-2">
              {m.email && (
                <a href={`mailto:${m.email}`} aria-label={`Email ${m.name}`} className={socialClass}>
                  <Mail className="size-4" aria-hidden />
                </a>
              )}
              {m.link && (
                <a href={m.link} aria-label={`${m.name} on the web`} className={socialClass}>
                  <LinkIcon className="size-4" aria-hidden />
                </a>
              )}
              {m.website && (
                <a href={m.website} aria-label={`${m.name}'s website`} className={socialClass}>
                  <Globe className="size-4" aria-hidden />
                </a>
              )}
            </div>
          </li>
        ))}
      </ul>
    </section>
  )
}
```
