Person chip

An interactive member chip combining an avatar with a name. Used in the WITH row of the expense form to select who's in a split. Chips toggle selection on tap, show a dismiss button when selected, and go into a settled state when a member has fully paid up.

Variants

AA
Aarav
PR
Priya
RK
Rohan

Default — unselected, tappable. Paper surface with hairline border. Shows avatar and name. No remove button.

Selected — teal surface with teal border. The avatar turns teal. A remove button (×) appears to the right of the name, letting the user deselect without tapping the whole chip.

Settled — muted, non-interactive. Strikethrough on the name, desaturated avatar. Communicates that this person's balance is zero and they can't be added to a new split.

Sizes

KA
Kabir
KA
Kabir
KA
Kabir
SizeAvatarFontPaddingUse case
Small22px12px4px 10px 4px 4pxDense lists, compact split rows
Default28px14px6px 12px 6px 6pxExpense form WITH row — standard
Large34px15px8px 16px 8px 8pxFull-screen member picker

States

AA
Default
AA
Hover
AA
Pressed
AA
Selected
AA
Settled
StateVisual changeTransition
DefaultPaper surface, hairline border
HoverBackground shifts to --s-warm, text to --ink140ms ease-out
Pressedscale(0.97)140ms ease-out
Focused2px outline in --teal, 2px offsetInstant
SelectedTeal surface + border, × button appears140ms ease-out
SettledMuted, strikethrough name, non-interactive

On dark surfaces

AA
Aarav
PR
Priya
RK
Rohan

On dark surfaces (moments section, dark cards), the chip uses the elevated dark surface with a dark border. The selected teal state stays consistent — low-opacity teal wash with a teal border ring. The settled chip becomes even more recessed at reduced opacity.

Group layout

PR
Priya
AA
Aarav
KA
Kabir
RK
Rohan
SN
Sneha

Use .person-chip-group as a flex-wrap container with 8px gap. Selected chips bubble to the front via JS — the DOM order should reflect selection order. Settled chips always go last.

Avatar colors

YO
You (ink)
PR
Coral
AA
Teal
KA
Butter
RK
Mute

Avatar colors cycle through the avatar palette. The logged-in user always gets --av-you (ink). Colors are assigned deterministically by user ID so a person always has the same color across sessions and devices.

Anatomy

PR
Avatar
Priya
Name
×
Remove
Container (pill, teal-pale bg)
PartElementNotes
Containerdiv[role="button"] or buttonPill shape. Handles the toggle click. Entire chip is the tap target.
Avatar.person-chip__avatar28px circle. Initials, 2 chars max. Color from palette.
Name.person-chip__nameFirst name only. Strikethrough in settled state.
Remove button.person-chip__removeOnly visible in selected state. Separate tap target from chip toggle. Requires aria-label="Remove [name]".

Usage

Do Use person chips in the WITH row of the expense form for multi-select member picking. Show the whole group — let users toggle individually. Selected chips get the teal treatment.
Don't Don't use person chips for single-select flows — use a radio list instead. Don't truncate names inside the chip; use first name only to keep chips compact.
Do Use the settled state to communicate that a member has a zero balance and is not in the current debt graph. Settled chips are read-only.
Don't Don't hide settled members — show them greyed out so the user knows who's in the group. Don't put the remove (×) button on default chips — it only appears when selected.

Accessibility

Keyboard Chips are focusable via Tab. Space or Enter toggles selection. When selected, the remove button (×) is a separate focusable element. Tab from the chip body reaches the remove button.
Screen readers The chip container should be a <button> with aria-pressed="true|false" to announce selection state. The remove button needs aria-label="Remove [name]". Settled chips use aria-disabled="true" and should be skipped from the tab order.
Touch targets The chip's minimum height is 40px on mobile — pad vertically as needed. The remove button (18px visual) gets a 32px minimum touch target via negative margin or pseudo-element expansion.

Code

HTML

<!-- Default (unselected) -->
<button class="person-chip" aria-pressed="false">
  <div class="person-chip__avatar" aria-hidden="true">AA</div>
  <span class="person-chip__name">Aarav</span>
</button>

<!-- Selected (with remove button) -->
<button class="person-chip person-chip--selected" aria-pressed="true">
  <div class="person-chip__avatar" aria-hidden="true">PR</div>
  <span class="person-chip__name">Priya</span>
  <span class="person-chip__remove" role="button" aria-label="Remove Priya" tabindex="0">×</span>
</button>

<!-- Settled -->
<div class="person-chip person-chip--settled" aria-disabled="true">
  <div class="person-chip__avatar person-chip__avatar--mute" aria-hidden="true">RK</div>
  <span class="person-chip__name">Rohan</span>
</div>

<!-- Group layout -->
<div class="person-chip-group" role="group" aria-label="Split with">
  <!-- chips here -->
</div>

CSS classes

ClassPurpose
.person-chipBase — pill shape, avatar + name layout, press state
.person-chip--selectedTeal surface, teal border, shows remove button
.person-chip--settledMuted, strikethrough name, non-interactive
.person-chip__avatar28px circle, initials
.person-chip__avatar--coralCoral avatar color
.person-chip__avatar--tealTeal avatar color
.person-chip__avatar--butterButter avatar color
.person-chip__avatar--muteMuted avatar color
.person-chip__nameName text — gets strikethrough in settled state
.person-chip__remove× dismiss button — shown only in selected state
.person-chip-groupFlex-wrap container with 8px gap

Design tokens used

TokenValueRole
--teal-pale#D6EAE2Selected chip background
--teal#0E7C66Selected chip border, selected avatar
--teal-deep#0A5F4FSelected chip text
--s-warm#F1E9D5Settled chip background, hover
--ink-line#DDD2B8Default chip border
--ink-mute#8A8276Settled text + avatar
--r-pill999pxChip border radius