Cards
components specs/components/cards.kmd
Card — a container of related content + actions, typically clickable as a whole. Material parity (`/components/cards`). 3 variants (elevated, filled, outlined), uniform anatomy, and rules for composition with images, lists, and feeds.
Quando esta spec se aplica
Triggers primários
- Add a card anywhere in Koder UI
Todos os triggers
- Group related content into a discrete unit
- Build a feed of items (per `canonical-layouts.kmd` L1)
- Render a product/article/profile tile
Corpo da especificação
Spec — Cards
Facet Visual do Koder Design. Material parity: https://m3.material.io/components/cards.
3 card variants
| Variant | Visual | Use |
|---|---|---|
| Elevated | Surface bg + shadow level 1 | Default — slight depth, draws attention |
| Filled | Surface-variant bg + no shadow | Less emphasis; for embedded cards within a denser context |
| Outlined | Transparent bg + 1px accent border | High structure, low visual weight (forms with grouped fields) |
Anatomy
┌──────────────────────────────┐
│ [Optional media] │ ← image / video / illustration
│ │
│ Title (title-large) │
│ Subtitle (body-medium muted)│
│ │
│ Body content │
│ │
│ [Action 1] [Action 2] │ ← optional actions
└──────────────────────────────┘
- Container: radius-md, padding 16-24 px
- Media (optional): full-width image, aspect 16:9 default
- Title:
title-large(22/28, weight 600) - Subtitle:
body-medium(14/20) intext-muted - Body:
body-medium - Actions: button row, right-aligned (or left in RTL)
R1 — Card density
| Density | Padding | Use |
|---|---|---|
| Comfortable | 24 px | Default — feeds, dashboards |
| Compact | 16 px | Dense lists (table cards, multi-column grids) |
| Spacious | 32 px | Hero cards (single card per fold) |
Density follows themes/ui-style.kmd preset's density token; can be
explicitly overridden per card via class modifier.
R2 — Clickable card
Most cards are clickable as a whole (navigate to detail).
- Entire card surface is the hit area
- Hover state: subtle elevation boost (+1 level) OR background tint
- Focus ring: 2 px on outer container (per
interaction/states.kmd) role="link"if it navigates;role="button"if it triggers an action- Inner buttons are stop-propagation: clicking them doesn't trigger the card's main action
- Cursor: pointer on whole card
R3 — Compositions
Feed item card
Used in vertical scrollable feeds (per canonical-layouts.kmd L1).
- Compact density
- Title + subtitle + 1-3 lines of body
- Optional avatar (40 px) + author name + timestamp
- Click navigates to detail
Product card
- Elevated variant
- Hero image (16:9 or 1:1)
- Title + price + rating
- "Add to cart" or similar primary action
- Hover: shadow boost + slight scale (1.02)
List-detail card
- Outlined or Filled variant
- Selected state: accent-tinted bg + accent border (1.5 px)
- Used in list-detail layout (per L2)
Stats card (dashboard)
- Outlined variant
- Large numeric value (
headline-large) - Label (
title-smallmuted) - Optional sparkline / mini-chart
R4 — Cards within cards
Anti-pattern. A card MUST NOT contain another card. If nesting feels needed, the inner content should be a list-item, expansion-panel, or embedded section — not a card.
Exception: a card containing one image-card preview (e.g., a tweet embed inside a notification card) — allowed because the inner is a quoted/embedded artifact, not a peer container.
R5 — Media handling
- Aspect ratio: 16:9 (default), 1:1 (square avatar/product), 4:3 (legacy)
- Loading: skeleton placeholder matches final aspect (no layout shift)
- Failure: fallback to
surface-variantbg + icon - Alt text:
altattribute REQUIRED for non-decorative images - Lazy-loading:
loading="lazy"for cards below the fold
R6 — Per-preset variation
| Preset | Variant emphasis |
|---|---|
material3 | Elevated default (subtle shadow) |
material2 | Stronger shadows, sharper corners |
windows_11 | Mica backdrop blur on Elevated |
windows_95 | 3D bevel border instead of shadow; sharp corners |
glassmorphism | Translucent + backdrop blur |
brutalist | Outlined only (no shadows, thick border) |
neumorphism | Soft inverse shadow (looks "pressed into" surface) |
dieter_rams | Outlined default; minimal ornament |
R7 — Accessibility
- Card title is a heading (
<h2>-<h4>depending on page level) - Clickable card focus ring on outer container only (not on title)
- Inner buttons reachable by Tab (separately from card focus)
- Reading order matches visual order (DOM = visual)
R8 — Forbidden patterns
- ❌ Card without title (just a body of text) — use a
<section>instead - ❌ Multiple primary actions in card actions row (1 primary, N secondary)
- ❌ Card with no border + no shadow + no bg variation (use a plain
<div>) - ❌ Animations that change card height on hover (causes feed shift)
Cross-link
app-layout/canonical-layouts.kmd— feed (L1) uses cardsthemes/elevation.kmd— Elevated variant level 1 defaultthemes/shape.kmd— radius-md containerinteraction/states.kmd— hover/focus per card typefoundations/elements.kmd— Container family
Referências
specs/foundations/elements.kmdspecs/app-layout/canonical-layouts.kmdspecs/themes/shape.kmdspecs/themes/elevation.kmd