---
title: Team Section
description: A team roster grid — portrait, name, role and links per person.
category: Marketing
related:
  - /components/avatar
  - /components/link
  - /components/testimonial
  - /components/logo-cloud
visibility: guest
draft: false
---

# Team Section

The "meet the team" block: a responsive roster of people, each with a portrait, a
name, a role and optional links.

It is a real **list of people**, so a screen reader announces how many there are
before reading them.

:::preview{title="Team roster"}
<x-wirekit::team-section label="Leadership">
    <x-wirekit::team-member name="Ada Lovelace" role="Chief Technology Officer" />
    <x-wirekit::team-member name="Grace Hopper" role="VP Engineering" />
    <x-wirekit::team-member name="Alan Turing" role="Head of Platform" />
    <x-wirekit::team-member name="Katherine Johnson" role="Principal Engineer" />
</x-wirekit::team-section>
:::

## Portraits and initials

Pass `avatar` for a portrait. Without one, the person's initials are derived and
rendered in a deterministic color — never an empty gray disc:

```blade
{{-- Portrait --}}
<x-wirekit::team-member name="Ada Lovelace" role="CTO" avatar="/team/ada.jpg" />

{{-- No portrait — initials are derived ("AL") --}}
<x-wirekit::team-member name="Ada Lovelace" role="CTO" />

{{-- Override the derived initials --}}
<x-wirekit::team-member name="Björk" initials="B" />
```

## Links

The slot is for a person's links. Put real links in it:

```blade
<x-wirekit::team-member name="Ada Lovelace" role="CTO">
    <x-wirekit::link href="https://example.com/ada" target="_blank">Profile</x-wirekit::link>
</x-wirekit::team-member>
```

::: warning An icon-only link needs its own name
A link containing only an icon has no accessible name — a screen reader announces
"link" and stops. It must carry an `aria-label` that names both the destination
*and* the person: the surrounding name is not part of the link, so "Profile" alone
never says whose profile it is.

```blade
<x-wirekit::link href="https://example.com/ada" aria-label="Ada Lovelace on the web">
    <x-wirekit::icon name="globe" />
</x-wirekit::link>
```

The same applies to visible text: "Profile" repeated four times down a roster
means every person's link sounds identical when tabbed through.
:::

External links get their `rel` attribute handled for you — see the [link component](/components/link).

## Props

### `<x-wirekit::team-section>`

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `label` | `string` | `'Team'` | Accessible name for the roster. |
| `scope` | `string\|null` | `null` | Class-scope override. |

### `<x-wirekit::team-member>`

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `name` | `string` | `''` | The person's name. |
| `role` | `string\|null` | `null` | Their role. |
| `avatar` | `string\|null` | `null` | Portrait URL. Omit to render derived initials. |
| `initials` | `string\|null` | `null` | Override the derived initials. |
| `scope` | `string\|null` | `null` | Class-scope override. |

## Accessibility

- The roster is a `<ul role="list">` of `<li>` people, so the count is announced
  up front.
- Initials are derived with multibyte-safe string handling, so a non-ASCII name is
  never sliced mid-codepoint.
- A person with no links renders no links row at all — an empty row still takes
  gap space and pushes the rows apart.

## Keyboard Interaction

None of its own. Any links you place in a person's slot keep their normal tab
behavior, in the order the people are written.
