Cards
All cards: 24px radius, 24px inset, --surface on --canvas, 1px --border, no resting shadow.
14. BalanceCard
The hero. One trusted number. This is the component a user opens the product to see.
Layer 1: radius 24 · inset 24 · min-width 280 · height auto Layer 2:
┌─ 24 ────────────────────────────────┐
│ [eyebrow] · [account mark] │ ← row, space-between
│ 8 │
│ [figure] │
│ 8 │
│ [delta] · [as-of] │
│ 16 │
│ ├─ full-bleed sparkline ──────────┤ │ ← optional, bleeds to 3 edges
└──────────────────────────────────────┘
Layer 3: eyebrow (1 line, truncate) · figure (never truncates) · delta (1 line) · media (aspect-[4/1], full-bleed) · actions (max 2)
Layer 4:
| Slot | Token | Weight | Color |
|---|---|---|---|
| eyebrow | label 13/16 |
500 | --text-secondary |
| figure | figure-hero 40/48 |
500 | --text-primary |
| delta | caption 12/16 |
400 | semantic |
3 sizes, 2 weights ✓
Available vs. current. A bank balance has two values and they differ. Show available as the figure; current as a secondary line when they diverge. Conflating them is the most consequential copy error in consumer banking UI.
Motion: none at rest. Value flash when live. Sparkline draws once. Interactive variant gets press scale(0.97) and a 1px hover lift.
Responsive: figure steps 40 → 28 below a 280px container. Sparkline drops below 240px.
Edge cases: negative balance (overdraft — parens and a --negative figure, plus an explicit "Overdrawn" pill) · redacted · stale (dim to 0.7 + StaleIndicator) · very long account name.
15. KpiCard
Label · figure · delta · optional sparkline. The dashboard atom.
- Baselines align across a
KpiRow. Usegridwithauto-rows-frand a shared figure row, or two cards with different label lengths will have their figures at different heights — the most visible alignment failure on any dashboard. - Display family forbidden here. Figures align across the row.
polarityrequired, no default. Forcing the decision is the point.- The comparison basis is always shown:
vs. Aug, never a bare+5.3%.
Loading: skeleton with the figure block at the exact figure width, or the card jumps when data lands.
16. AccountCard
Bank account: institution mark, masked number, type, available and current balances, sync status. Tapping opens the transaction list filtered to it.
Handles disconnected and reauth-required states prominently — a stale bank connection silently showing an old balance is a real financial hazard. Stale accounts dim and surface a "Reconnect" action.
17. PaymentMethodCard
The physical object. Two of the four sanctioned delight moments — the flip and the tilt.
Geometry, from ISO/IEC 7810 ID-1:
aspect-ratio: 1.586 (85.60 × 53.98 mm)
border-radius: 3.7% / 5.9% (3.18mm — 3.7% of width, 5.9% of height)
Real proportions matter — a card at 16:9 with a 24px radius reads as a rectangle, not as a card.
Face: flat, single tint from the issuer color, network mark bottom-right, masked PAN in tnum with ss02 (so a 0 isn't an O), holder name in label uppercase, expiry MM/YY.
Motion:
- Flip to reveal CVV —
rotateY(0→180deg),spring.playful, real 3D withpreserve-3d+backface-visibility: hidden. Not a crossfade. Spec. - Pointer tilt — ±6° from pointer position via
spring.track, plus a specular sheen atopacity 0→0.12. Desktop only, gated behind@media (hover: hover) and (pointer: fine). Springs home on leave. - Reduced motion: instant swap, no tilt.
The tilt is decorative and it's licensed only because the card is decorative. The same effect on a KpiCard is a review failure.
Security: CVV and full PAN are never in the DOM until revealed, never in analytics, never in a screenshot-able state without an explicit user action.
18. RunwayCard
Months of runway, current cash, monthly burn, projected zero date. A burn line with a projection segment rendered dashed, because a projection is not a fact.
polarity="inverted" on burn. Runway under 6 months triggers --warning; under 3, --negative — and the threshold is configurable, because it's a business judgment, not a universal truth.
19. InvoiceCard
Number, customer, amount, due date, aging state (current / 1-30 / 31-60 / 61-90 / 90+). Overdue is --negative with the day count, never color alone. Partial payments show paid vs. outstanding.
20. SubscriptionCard
Vendor mark, amount, cadence, next charge, annualized cost. Annualized is the useful number — $49/mo is $588/yr, and showing it is what makes a spend review actionable.
21. AnomalyCard
A flagged deviation, with the comparison that triggered it and one clear action (approve / flag / create rule). Never a bare alert — an anomaly without its baseline is noise.
22. GoalCard
Target vs. actual with a progress rule (a rule line, not a rounded progress bar — consistent with the statement grammar).
23. StatCard
The minimal unit: label + value. 16px inset, no delta, no media. For dense grids where a KpiCard is too much.