Components · Lists

List rows

The dense-row family — the building block of the portal's grouped lists, the “Go to” shortcut block and the tool menus. Every row is the same anatomy: a leading icon chip (h-9 w-9 rounded bg-surface-2), a title / meta stack that truncates before it shoves the right edge, and a trailing affordance — an auto chevron on a link row, or a Badge, a count or a real Button. Below it ships two ways: stacked inside a CompactCard divide-y body (the dividers belong to the card), and as a card-per-row surface. The heavier CompactListItem row swaps the medium title for a semibold one and pairs it with a Button.

Divided · CompactCard — header band + divide-y body
Go to 6 shortcuts
Your teams2 active communities · 38 volunteers Upcoming eventsNext · Saturday neighborhood march Your representativesBy your registered address
Data-access agreementRequired before exporting a roster To sign
NotificationsUnread alerts in your inbox 3 new
Downtown organizers128 members · very active

Row 1 is pinned :hover (the whole link lifts to surface-2, its chevron tints accent); row 3 is pinned :focus-visible (the accent ring). Hover / tab the rest live. The last row is a CompactListItem — semibold title, an icon that's required, a real Button that wraps below the text on mobile. The hairlines between rows are the card's divide-y, not the rows'.

Card style · one bordered surface per row

Same anatomy, no shared card: each row is its own --radius-lg surface with a --card-glow and an 8px gap between. On hover the border steps border → border-strong and the fill lifts to surface-2 (row 1 pinned). Reach for this when rows are cards in their own right — an events list, a group directory — rather than a tight nav block.

icon chip
An h-9 w-9 (36px) rounded-lg bg-surface-2 text-muted square holding a sized lucide glyph (h-4 w-4). Optional on ListRow, required on CompactListItem.
title / meta
Title text-sm font-medium (semibold on CompactListItem) over a text-xs muted subtitle. Both truncate inside a min-w-0 flex-1 column so a long name never pushes the trailing edge off-row.
trailing
One of: the auto chevron (link row, no explicit action), a Badge, a plain count/meta string, or a real Button. Held in a shrink-0 box on the right.
divided vs card
Divided → rows sit in a CompactCard whose divide-y divide-[--color-rule] body owns the hairlines + the corner clip. Card → each row is its own bordered surface with a gap.
states
A link row lifts to hover:bg-surface-2 (chevron → accent); focus-visible shows the accent ring; a card row also steps its border to border-strong. Colour reinforces, never replaces, the affordance.

Source · ui/ListRow.tsx (icon / title / subtitle / action / href · density) · ui/CompactListItem.tsx (semibold + Button, responsive stack) · ui/CompactCard.tsx (header band + divide-y body) · ui/SectionHeader.tsx · --color-rule from globals.css.