Built · v1.0 · Figma set
Action Card
An Action Card pairs a short message with one thing to do about it. It is the component that sells: credits, plans, ad-free, features worth discovering. It is not navigation. If the tap just takes you somewhere, that is a List Row.
Default
Promo
Upsell
Feature
Four types, all 358 wide, all radius/lg (12), all padded 16 with a 16 gap. Flip the theme and
watch the Feature card turn over: it is the one surface in the system that reverses with the
mode, dark on light and light on dark.
Use when
Section titled “Use when”Use when
- Promoting an offer, a plan or a paid feature.
- Surfacing something worth discovering that the user has not asked for.
- Pairing one message with exactly one action.
Don’t use when
- The tap only navigates. That is a List Row.
- The screen already has its one primary action. A card never competes with it.
- You need two actions. Cut one, or it is not a card.
Anatomy
Section titled “Anatomy”A horizontal row, padding 16 on all four sides, gap 16, radius 12.
- Illustration. 48 square, instance-swap, off by default on the selling types.
- Content. A vertical stack with a 4 gap: Title Inter Medium 16 / 24 on
text/primary, Description Inter Regular 14 / 20 ontext/secondary. - Trailing. Either a 16 chevron, or a real Button instance at
Size=XSmall. The card does not draw its own button.
That last point is worth holding onto: Promo and Upsell embed the actual DS Button component, not a copy of it. When the button ladder changed in August 2026, both cards moved with it for free. That is the whole argument for instance-swap slots over redrawn parts (D-010).
Variants
Section titled “Variants”| Type | Fill | Height | Trailing | Reads as |
|---|---|---|---|---|
| Default | scheme/surface | 100 | chevron | a thing you can go do |
| Promo | scheme/background + 1 px stroke/default | 116 | Button XSmall | a new offer |
| Upsell | scheme/surface | 133 | Button XSmall | a paid upgrade, with a price |
| Feature | scheme/inverseSurface | 94 | chevron on scheme/inversePrimary | a capability you already have |
Upsell is the tallest because it carries a third line, the price, on text/tertiary. Promo is
the only one that carries a badge.
The Feature card reverses the mode
Section titled “The Feature card reverses the mode”Feature is the one card that has to stand apart from the whole screen, and the honest way to do that is not a brand colour. No ink works on green across all three modes: Green/400 and Green/500 both sit in the middle of the lightness range, so black fails on one side and white fails on the other. That is the same limit Foundations → Color records: green cannot both read as type and hold light type on top of it.
So Feature fills with scheme/inverseSurface, a surface that reverses with the mode: dark
in Light, light in Carbon and Navy. It is a Material 3 role, so it brought its own partners
rather than inventing anything.
| fill | ink | ratio | |
|---|---|---|---|
| Light | Teal/800 #1B3033 | Teal/50 | 12.71 ✅ |
| Carbon | Neutral/100 #DEDEDE | Neutral/1000 | 15.61 ✅ |
| Navy | Teal/100 #D3DFE1 | Teal/900 | 13.36 ✅ |
The Light fill is Teal/800, which is already the Navy surface, so the card is made of a
colour the system owns rather than a new one. In the dark modes it lands on Teal/100 rather
than a near-white, which matters in an app people read in bed. In Carbon the inverse stays in
Carbon’s own neutral family instead of borrowing a teal tint.
The chevron inverts too
Section titled “The chevron inverts too”This is the part worth understanding, because it generalises. The chevron is one of green’s nine jobs and it is not a button, so it stays green. But the surface under it flipped, so the green has to flip with it.
The neat symmetry does not work. Taking the opposite mode’s scheme/primary would put
Green/500 on the light card at 2.41, under the 3:1 a line icon needs. What works is
scheme/inversePrimary, which takes the opposite mode’s line green, exactly stroke/brand
with its modes swapped:
| card | chevron | ratio | |
|---|---|---|---|
| Light | Teal/800 | Green/400 | 5.49 ✅ |
| Carbon | Neutral/100 | Green/600 | 3.59 ✅ |
| Navy | Teal/100 | Green/600 | 3.54 ✅ |
Green/700 would give more headroom on the light card, but a 1.5 stroke of very dark green
reads as black, which is the failure Foundations → Color already
documents. Green/600 is the most chromatic stop in the ramp and keeps its hue at that weight.
The rule to take away: an inverted surface inverts everything on it, including the accent.
If you put anything else on scheme/inverseSurface, take its colour from the mode the surface
came from, not from the mode you are in.
Design guidelines
Section titled “Design guidelines”One card, one action. If a card needs two buttons, it is two cards or it is a screen.
The card never holds the screen’s primary action. Yellow is rationed one per screen by position, and a promo card is rarely the position that earns it. A card inside a list of content takes an XSmall button; the screen’s real commit stays at the bottom.
Description stays at two lines. At the 360 dp floor a three-line description pushes the button below the fold of the card and the offer stops reading as one object.
The illustration is decoration, not information. It is off by default on Promo and Upsell. If the card only makes sense with the picture, the copy is not doing its job.