Card

A flat, friendly surface with a soft warm shadow. The canonical content container — every contained piece of content in the system (a recommendation, a readiness panel, a metric block, an evidence draft) is a Card. Same flat-and-solid vocabulary as Button and future Input; the three sit together without seams because they share the same flat, opaque register. (No glass here — glass-in-frame is the proposed system's metaphor.)

Three tier variants by accent color. The guiding idea is emphasis — how loudly the card should speak on the eggshell page. Gold is loudest, silver-blue is everyday, bronze is supporting: primary (gold) is for the headline content, secondary (silver-blue, default) is the everyday workhorse panel, tertiary (bronze) is for supporting detail. Plus two semantic variants on a separate axis — caution (warning colors) for review-then-proceed moments and critical (danger colors) for destructive confirmations. Title is display type, body is plain — the title speaks in the system's slab-serif voice with the variant's accent color; the body is your data in friendly body type on a flat, opaque surface. (Engraving belongs to the proposed system — here, type is just type.)

And one plane variant — an overlay is a surface, just not a primary one: sheet is the overlay-plane surface for floating panels (sheets, drawers, dialogs, the command palette). A solid, opaque surface with the deepest shadow in the set — in this system, overlays cover what's underneath rather than blurring it (the frosted-glass read belongs to the proposed system). The consumer owns the positioning, scrim, and slide.

Variants

Audit window

SOC 2 · opens Aug 12

The page's headline content gets the gold treatment — the boldest card in the set, for the one thing on the page that should grab you first.

Controls in scope

127

↑ +8 since last quarter. Across 14 systems and 6 vendors.

Program metadata

SOC 2 · TSC 2017

Window opens

Aug 12, 2026

Lead auditor

R. Okafor

Last sync

12 min ago

Review before continuing

Q3 close-out

This will lock all CC6.x evidence for the quarter. Make sure outstanding items are cleared before continuing.

Confirm

Revoke session?

This will sign the user out of every device. They'll need to re-authenticate. This action cannot be undone.

Overlay plane

Sheet

An overlay is a surface — just not a primary one. A solid, opaque panel with the deepest shadow in the set, so it clearly floats above the page; the scrim behind it does the dimming. The home for sheets, drawers, dialogs, and the command palette (which uses it as a slide-up sheet on mobile). The consumer owns the positioning, scrim, and slide; the variant owns the surface. (The frosted-glass version of this idea lives in the proposed system.)

Compositional parts

Card is a compound component. Each part is optional; the variant propagates via context so the title picks up the right accent color without callers threading it.

<Card>
article

The flat card surface with its soft shadow. Defaults to <article> semantic element; override with `as` for <section>, <div>, or <li>.

<Card.Header>
header

Top section with bottom hairline. Holds Card.Eyebrow + Card.Title; right-aligned children become the badge / plaque slot.

<Card.Eyebrow>
p

Small uppercase category label with leading hairline bar. Composes Text variant=overline.

<Card.Title>
h3

Slab-serif display title in the variant's accent color. Override the heading level with `as`.

<Card.Body>
div

Main content area in friendly body type on the flat surface.

<Card.Footer>
footer

Action row with top hairline. Right-aligned by default.

Minimal

Skip whichever parts aren't needed. A common case is a body-only card — just the surface, no header or footer.

A body-only card. Just the flat surface and its soft shadow — for cases where the content speaks for itself and a header would only add noise.

The footer slot holds action buttons aligned right. Compose canonical Button variants — primary for the committing action, secondary for the alternative.

Vendor risk assessment

Stripe · SOC 2 expires in 14 days

Re-collect their attestation before May 31 to keep CC9.2 passing.

When to use which variant

Pick the tier variant by how much attention the card should ask for. Gold shouts (one per view, ideally), silver-blue talks, bronze whispers. The semantic variants sit on their own axis. (The proximity-to-background ladder is the proposed system's framing — here it's simply emphasis.)

Tier — emphasis

primary
Gold accent. The headline card — bold, warm, impossible to miss. Use when the content is the one thing the page is about.
secondary
Silver-blue accent. The everyday default. A calm, flat panel that gets out of the content's way. Use when no other variant applies.
tertiary
Bronze accent. The supporting player — quieter, for metadata and detail that back up the main story.

Semantic — separate axis

caution
Warning colors, flat and solid — no shimmer, no specular, just an honest amber-toned surface that says "look this over first." Use for warnings the user should pause on but where the action is still safe to proceed with after consideration. Pair with a caution Button in the footer. (Copper lustre is the proposed system's treatment.)
critical
Danger colors, flat and serious — a plain red-toned surface for the moments that can't be undone. Use only for destructive confirmation dialogs and irreversible-action warnings. Pair with a critical Button in the footer. (Rust and chalky matte are the proposed system's treatment — here, danger is plain solid color.)

Anti-patterns

  • Don't nest cards inside cards. A card is one surface; stacking surfaces inside surfaces just adds shadows on shadows. If you need grouped content inside a card, use Card.Body subdivisions (grids, lists) — not another Card.
  • Don't put user data in Card.Title. The title is system voice (slab-serif display, variant accent color). User data lives in Card.Body in body type. If "John Doe" needs to be the most prominent text on the card, that's a sign the page hierarchy is wrong — promote it to the page title via SectionHead.
  • Don't skip the variant decision. The default secondary works in most places, but reaching for primary or tertiary deliberately is part of the card system's job. A page full of identical silver-blue cards reads as "all of this is equally important" — usually not true.
  • Don't ask for an affirm variant. There isn't one, and adding one isn't a gap to close. The cases a green card would serve are already covered by an affirm Button, an affirm badge inside a neutral card, or an affirm toast. In compliance, passing is the expected baseline, not the celebratory one — a green-soaked card on routine passing state reads as the system shouting "GOOD." Recorded in ADR-0029 (variant sets are scoped per component, not synced for symmetry across Button and Card).

Usage

Full compound APItsx
import { Card, Button } from '@halo-compliance/ui'

<Card variant="primary">
  <Card.Header>
    <div>
      <Card.Eyebrow>Halo recommends</Card.Eyebrow>
      <Card.Title>Re-test CC6.1 before audit</Card.Title>
    </div>
  </Card.Header>
  <Card.Body>
    {/* body content — body register */}
  </Card.Body>
  <Card.Footer>
    <Button variant="primary" icon={Send}>Run check</Button>
  </Card.Footer>
</Card>
Critical semantic variant for destructive confirmationstsx
<Card variant="critical">
  <Card.Header>
    <div>
      <Card.Eyebrow>Confirm</Card.Eyebrow>
      <Card.Title>Revoke session?</Card.Title>
    </div>
  </Card.Header>
  <Card.Body>This action cannot be undone.</Card.Body>
  <Card.Footer>
    <Button variant="secondary" icon={X}>Cancel</Button>
    <Button variant="critical" icon={Trash}>Revoke</Button>
  </Card.Footer>
</Card>
  • /button — Button is what Card.Footer hosts.
  • /text — Card.Title and Card.Eyebrow compose Text variants internally.
  • /error-states — section-scope ErrorState renders as a Card variant="critical".
  • /shell — Card is content; ContentWell is the substrate Card lives inside.