78436cecc2
- FOUNDATIONS-v1.0.md: - Freeze contract for Landvex Design System - Scope: Motion, AI Principles, Semantic Colors, Grid, Elevation, Typography, RFC Template, Definition of Done - Reference components: Button, Input, Select, Card (all ~83%) - Invariants: token rules, component rules, accessibility rules, AI rules - Change policy: no new foundation concepts without v2.0 RFC - Versioning: 1.0.x patches, 1.x.0 new components, 2.0.0 new foundations - Compatibility matrix for all foundations and components - Directory reorganization: - docs/design/foundations/ → frozen foundation documents - docs/design/components/ → component RFCs - docs/design/README.md → navigation and structure - Foundation documents moved: - TOKEN_PHILOSOPHY, SEMANTIC_COLOR_SYSTEM, GRID_ELEVATION - AI_DESIGN_PRINCIPLES, COMPONENT_TEMPLATE, RFC_DEFINITION_OF_DONE - DESIGN_ANTI_PATTERNS, COMPONENT_DECISION_TREE, GLOSSARY - BRAND_PALETTE, RELEASE_DEFINITION, SEMANTIC_COLOR_SYSTEM_REVIEW - Component RFCs moved: - RFC-002-Input, RFC-003-Select, RFC-004-Card Rationale: Clear separation between foundations (stable platform) and components (built on top). Foundations v1.0 frozen — components can be added freely within v1.x, but foundations require v2.0 RFC to change. This prevents gradual erosion of the design system architecture.
266 lines
8.9 KiB
Markdown
266 lines
8.9 KiB
Markdown
# RFC-004: Canonical Card Component
|
|
|
|
**Status:** 🟡 Draft — Under review
|
|
**Tier:** 1 (Canonical)
|
|
**Inherits From:** — (root component)
|
|
**Author:** AI Agent
|
|
**Date:** 2026-07-02
|
|
|
|
---
|
|
|
|
## 1. COGNITIVE PURPOSE
|
|
|
|
Card exists to group related information into a bounded, scannable unit. It creates visual hierarchy by separating content from its surroundings without requiring explicit borders or dividers.
|
|
|
|
**Design Goal:** The user can scan, compare, and act on grouped information as a single unit.
|
|
|
|
---
|
|
|
|
## 2. WHEN TO USE
|
|
|
|
- Grouping related data (KPI, dataset, asset summary)
|
|
- Presenting actionable items that need context
|
|
- Creating scannable lists of heterogeneous content
|
|
- Elevating content above the page background
|
|
- Containing forms or workflows in a bounded area
|
|
|
|
## 3. WHEN NOT TO USE
|
|
|
|
- Single line of text (use plain text or List Item)
|
|
- Simple navigation (use Link or Navigation)
|
|
- Modal content (use Modal)
|
|
- Full-page content (use Page layout)
|
|
- When elevation is unnecessary (use flat surface)
|
|
|
|
---
|
|
|
|
## 4. USER EXPECTATION
|
|
|
|
- Card is visually distinct from background
|
|
- Card content is related and scannable
|
|
- Card may be clickable (if actionable)
|
|
- Card maintains consistent internal spacing
|
|
- Card adapts to container width
|
|
- Multiple cards align in grids or lists
|
|
|
|
---
|
|
|
|
## 5. INTERACTION CONTRACT
|
|
|
|
| Event | Response |
|
|
|-------|----------|
|
|
| Click (actionable) | Navigate or trigger primary action |
|
|
| Hover (actionable) | Elevation increases, cursor changes |
|
|
| Focus (actionable) | Focus ring appears |
|
|
| None (static) | No interaction, purely presentational |
|
|
|
|
---
|
|
|
|
## 6. FAILURE BEHAVIOUR
|
|
|
|
| Scenario | Response |
|
|
|----------|----------|
|
|
| Content overflows | Scroll internally or truncate with ellipsis |
|
|
| Image fails to load | Show placeholder or fallback icon |
|
|
| Action fails | Show error state on card or in adjacent area |
|
|
| Card is loading | Show skeleton state |
|
|
| Card is empty | Show empty state with guidance |
|
|
|
|
---
|
|
|
|
## 7. ACCESSIBILITY CONTRACT
|
|
|
|
- **Role:** Static cards use no ARIA role. Actionable cards use `role="button"` or `role="link"`.
|
|
- **Focus:** Actionable cards MUST have visible focus ring
|
|
- **Label:** Actionable cards MUST have accessible name (aria-label or visible text)
|
|
- **Screen reader:** MUST announce card as group or link/button
|
|
- **Keyboard:** Actionable cards MUST be activatable with Enter or Space
|
|
- **Color:** MUST NOT rely on color alone to indicate actionability
|
|
|
|
---
|
|
|
|
## 8. AI CONTRACT
|
|
|
|
| Scenario | AI Choice |
|
|
|----------|-----------|
|
|
| Group related data with actions | Card |
|
|
| Single data point with label | List Item |
|
|
| Navigation to another page | Link |
|
|
| Modal content | Modal |
|
|
| Full-page layout | Page |
|
|
| Simple text without grouping | Plain text |
|
|
|
|
---
|
|
|
|
## 9. TOKEN DEPENDENCIES
|
|
|
|
| Token | Semantic Alias | Primitive | Usage |
|
|
|-------|---------------|-----------|-------|
|
|
| `card-bg` | `color.surface.raised` | `gray-50` | Background |
|
|
| `card-border` | `color.border.default` | `gray-200` | Border (optional) |
|
|
| `card-radius` | `radius-lg` | `12px` | Border radius |
|
|
| `card-padding` | `space-4` | `16px` | Internal padding |
|
|
| `card-shadow` | `shadow-sm` | `0 1px 2px rgba(0,0,0,0.05)` | Default elevation |
|
|
| `card-shadow-hover` | `shadow-md` | `0 4px 6px rgba(0,0,0,0.07)` | Hover elevation (actionable) |
|
|
| `card-shadow-active` | `shadow-sm` | `0 1px 2px rgba(0,0,0,0.05)` | Active elevation |
|
|
| `card-divider` | `color.border.default` | `gray-200` | Divider between sections |
|
|
| `card-header-text` | `color.text.primary` | `gray-900` | Header text |
|
|
| `card-body-text` | `color.text.secondary` | `gray-600` | Body text |
|
|
| `card-footer-text` | `color.text.muted` | `gray-400` | Footer text |
|
|
| `card-loading-bg` | `color.surface.default` | `gray-0` | Skeleton background |
|
|
|
|
---
|
|
|
|
## 10. LAYOUT
|
|
|
|
```
|
|
┌─────────────────────────────────────┐
|
|
│ ┌─────────────────────────────────┐ │
|
|
│ │ Header (title, action) │ │
|
|
│ ├─────────────────────────────────┤ │
|
|
│ │ │ │
|
|
│ │ Body (content, data, media) │ │
|
|
│ │ │ │
|
|
│ ├─────────────────────────────────┤ │
|
|
│ │ Footer (metadata, actions) │ │
|
|
│ └─────────────────────────────────┘ │
|
|
└─────────────────────────────────────┘
|
|
```
|
|
|
|
- **Header:** Top section, title + optional action, padding `space-4`
|
|
- **Body:** Main content, padding `space-4`, flexible height
|
|
- **Footer:** Bottom section, metadata or actions, padding `space-4`, top border `card-divider`
|
|
- **Divider:** 1px line between sections, `card-divider`
|
|
- **Gap:** No gap between sections (padding handles spacing)
|
|
|
|
---
|
|
|
|
## 11. SIZES
|
|
|
|
| Size | Width | Padding | Usage |
|
|
|------|-------|---------|-------|
|
|
| Small | 240px | `space-3` | Dense grids, compact data |
|
|
| Medium | 320px | `space-4` | Default, most content |
|
|
| Large | 480px | `space-5` | Featured content, dashboards |
|
|
| Fluid | 100% | `space-4` | Responsive, full-width |
|
|
|
|
---
|
|
|
|
## 12. VARIANTS
|
|
|
|
| Variant | Visual | Usage |
|
|
|---------|--------|-------|
|
|
| Default | Border, subtle shadow | Standard content grouping |
|
|
| Elevated | No border, stronger shadow | Featured content, dashboards |
|
|
| Outlined | Border, no shadow | Dense layouts, tables |
|
|
| Interactive | Hover elevation, cursor pointer | Clickable cards |
|
|
|
|
---
|
|
|
|
## 13. STATES
|
|
|
|
| State | Visual | Motion |
|
|
|-------|--------|--------|
|
|
| Default | `card-bg`, `card-shadow` | — |
|
|
| Hover (interactive) | `card-shadow-hover`, cursor pointer | `duration-interaction` |
|
|
| Active (interactive) | `card-shadow-active` | `duration-instant` |
|
|
| Focus (interactive) | Focus ring | `duration-instant` |
|
|
| Loading | Skeleton state | `duration-background` |
|
|
| Empty | Empty state illustration + text | — |
|
|
| Error | Error border or error message | `duration-interaction` |
|
|
|
|
---
|
|
|
|
## 14. KEYBOARD
|
|
|
|
| Key | Action |
|
|
|-----|--------|
|
|
| `Tab` | Move focus to next focusable element |
|
|
| `Enter` / `Space` | Activate actionable card |
|
|
| `Arrow keys` | Navigate between cards in grid/list |
|
|
|
|
---
|
|
|
|
## 15. TOUCH
|
|
|
|
- Touch target: Entire card if actionable
|
|
- Active state: Brief elevation reduction
|
|
- No gesture support (no swipe, pinch)
|
|
- Scroll: Card content scrolls internally if overflow
|
|
|
|
---
|
|
|
|
## 16. MOTION
|
|
|
|
| Transition | Animation | Duration | Easing |
|
|
|-----------|-----------|----------|--------|
|
|
| Hover (interactive) | Elevation increase | `duration-interaction` | `ease-out` |
|
|
| Active (interactive) | Elevation decrease | `duration-instant` | `ease-in` |
|
|
| Focus | Focus ring appear | `duration-instant` | `ease-out` |
|
|
| Loading skeleton | Shimmer animation | `duration-background` | `linear` |
|
|
| Error appear | Border color change | `duration-interaction` | `ease-out` |
|
|
|
|
**Reduced Motion:** No elevation animation. Focus ring appears instantly.
|
|
|
|
---
|
|
|
|
## 17. ANTI-PATTERNS
|
|
|
|
- ❌ **Nested cards:** Cards inside cards create visual confusion
|
|
- ❌ **Too much padding:** Wastes space, reduces information density
|
|
- ❌ **No visual distinction from background:** Defeats purpose of card
|
|
- ❌ **Inconsistent internal spacing:** Breaks scannability
|
|
- ❌ **Actionable without focus ring:** Accessibility failure
|
|
- ❌ **Clickable entire card with internal buttons:** Event collision
|
|
- ❌ **Card as only layout tool:** Use grid or flexbox for layout, card for grouping
|
|
- ❌ **Excessive elevation:** Competes with modals and overlays
|
|
|
|
---
|
|
|
|
## 18. RELATED COMPONENTS
|
|
|
|
- **Modal** — Overlay content, not inline
|
|
- **Panel** — Larger container, often full-height
|
|
- **List Item** — Single row, no grouping
|
|
- **Tile** — Image-first card variant
|
|
- **KPI Card** — Domain-specific card (Tier 3)
|
|
- **Dataset Card** — Domain-specific card (Tier 3)
|
|
|
|
---
|
|
|
|
## 19. DDR REFERENCES
|
|
|
|
- **DDR-001:** Device Adaptive over Desktop First (affects sizing and grid)
|
|
- **DDR-002:** Information-level typography (affects header and body text)
|
|
- **DDR-003:** Semantic color system (affects states)
|
|
- **DDR-005:** Elevation system (affects shadow tokens)
|
|
|
|
---
|
|
|
|
## 20. ACCEPTANCE CRITERIA
|
|
|
|
- [ ] All 12 Definition of Done criteria met
|
|
- [ ] Works with screen reader (announces as group or link/button)
|
|
- [ ] Keyboard navigation works (Tab, Enter, Space, Arrow keys)
|
|
- [ ] Touch target minimum 44px for actionable cards
|
|
- [ ] Focus ring visible on actionable cards
|
|
- [ ] Loading skeleton state implemented
|
|
- [ ] Empty state with guidance
|
|
- [ ] Error state handled
|
|
- [ ] Reduced motion respected
|
|
- [ ] No nested cards
|
|
|
|
---
|
|
|
|
## ÄNDRINGSHISTORIA
|
|
|
|
| Version | Datum | Beskrivning |
|
|
|---------|-------|-------------|
|
|
| 1.0 | 2026-07-02 | Initial RFC-004 following RFC-001 structure |
|
|
|
|
---
|
|
|
|
## STATUS
|
|
|
|
**DRAFT — Awaiting review**
|