BoardConsentCard
Hero example
When to use
Reach for BoardConsentCard when a Resolution of type board_written_consent is in partially_signed state and the founder, board secretary, or an agent on a tier_3 token needs to see signing progress at a glance — who has signed, who hasn't, what the document is. The card belongs in three surfaces: the dashboard's board-consent inbox row, an inline reply from an agent in the composer ("Here's the status of the SAFE-authorization consent"), and the consent-detail page header.
Don't reach for BoardConsentCard when the consent is already executed (Document.execution_status: executed) — at that point the signing flow is history and the right surface is a static SignatureStack showing the audit trail, not a live tracker. Don't use it for non-board signatures either; investor side-letters and indemnification agreements have their own document state machine and belong in dedicated cards.
tier_3 agent answers "what's the status of the next-round SAFE authorization?"Anatomy
Five structural parts:
- Header.
Docicon + "Board Consent —{title}" + the awaiting-signatures Pill. The pill flips totone="green"when every signer has signed (consumer responsibility — pass the rightsignersarray). - Signer rows. One per
BoardSigner. Each row: 24px circular initials avatar (color from the signer'scolorprop or--fg-softfallback), name + role stacked, signed/pending pill aligned right. - Avatar. Initials only. The
colorprop accepts any CSS color string; if absent, the avatar falls back to--fg-soft. Avatars are decorative (aria-hidden); the signer's name carries the accessible identity. - Per-signer pill.
tone="green"forsigned: true,tone="amber"for the pending default. Geometry matches the announcement-pill shape — 20px height, mono font, 6px dot. - Footer. CardsKit footer — primary
Send reminderaction plus a secondaryView documentlink.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| titlerequired | string | — | — |
| signersrequired | BoardSigner[] | — | — |
States
The card has three semantic states driven by the signers array:
| State | Signer condition | Header pill |
|---|---|---|
| Partially signed | Some signed: true, some signed: false | Awaiting signatures (amber) |
| Fully signed | Every signer signed: true | Executed (green) — consumer flips header pill |
| Awaiting first signature | Every signer signed: false | Awaiting signatures (amber) |
The internal pill for each row reads directly from signer.signed — no consumer logic needed for the per-row state.
Density
In compact, signer-row padding drops from 10/14px to 6/10px and the row gap from 8px to 4px. The avatar stays 24px (touch target) and the per-row pill stays full size (legibility floor).
Themes
The card surface uses .glass-card, which composes the Glass backdrop in light and a flat translucent panel in dark. In forced-colors, the glass collapses to Canvas and the row borders inherit ButtonBorder.
Tokens consumed
The signer-row background reads --paper-50 (or fully transparent if absent), the row border reads --ink-5, and each pill reads its tone family (--status-green-bg / --status-amber-bg and matching foregrounds).
Accessibility
- Keyboard interactions. The primary
Send reminderbutton is the first focusable element;View documentfollows. Signer rows themselves are non-interactive — Tab skips past them. - ARIA roles and properties. The card is a generic region; no role override. Each per-row pill uses no
roleand relies on its text content for the accessible name. - Focus order. Footer primary → footer secondary. There is no focusable element within the signer list by design — the live signing flow happens on the document detail page, not inline.
- Screen-reader expectations. Reading order: card title, "awaiting signatures", then each row in DOM order as "name, role, signed | pending". Avatars are
aria-hidden. - Reduced motion. No keyframes inside this card. The footer button inherits the Matter motion contract — hover lift collapses to opacity when
prefers-reduced-motion: reduce. - Forced colors. Avatar fill maps to
Highlight, pill dot toButtonText. Glass surface collapses toCanvas. - WIG rules. Footer button respects icon-only
aria-label, the card is a<div>(not abusing semantic elements), and theDocicon carriesaria-hidden="true"per the decorative-icon rule.
Do / Don't
initials (two characters max) and a color derived from a stable hash of the signer's email so the avatar is consistent across renders.initials. The avatar caps at 24px and clips beyond two characters.signers array as a placeholder. Use a CardSkeleton until the data resolves.title short (≤ 60 chars). It composes with the "Board Consent — " prefix and should fit on one line at desktop widths.Recipes
This card appears in:
- Board recipe — the full board surface with pending consents, recent resolutions, and the next-meeting agenda.
- Docs corpus recipe — when a consent is rendered inline as part of an agent reply.
Code example
import { BoardConsentCard } from "@matter/components";
export function PendingConsentInline({ resolution }: { resolution: Resolution }) {
return (
<BoardConsentCard
title={resolution.title}
signers={resolution.authorized_signers.map((s) => ({
name: s.full_name,
role: s.board_role,
initials: s.initials,
color: s.avatar_color,
signed: s.signature_state === "signed",
}))}
/>
);
}A complete worked example, including the API call that produces resolution, lives in the Board recipe.
Source
packages/components/src/InlineCard/BoardConsentCardSection
Vertical-rhythm wrapper for page sections — pairs with Container for max-width body content. `bloom` paints a tinted backdrop AND propagates --btn-glow to nested buttons. `glow` propagates the cascade without the painted background.
FilingStatusCard
Read-only summary of a single compliance filing — title, status pill, jurisdiction, due date, and a checklist of sub-items. Use when the dashboard or an agent needs to surface 'where does this filing stand right now.'