Card
A composable card component for displaying content with flexible layout.
#OP-6894
Variants
Card takes a self-scoped variant (soft, surface, outline, ghost) and color (neutral, accent). These style the card's own chrome only; they never cascade into the controls inside it. neutral (default) tracks the app theme's neutral color; accent tints the chrome with the brand accent. Set an app-wide default with <Theme cardVariant cardColor>; a per-card prop overrides it.
color=neutral
soft
surface
outline
ghost
color=accent
soft
surface
outline
ghost
Usage
import {
Card,
CardHeader,
CardIcon,
CardTitle,
CardDescription,
CardContent,
CardFooter,
CardSkeleton,
} from '@epilot/spark-ui/card'<Card>
<CardHeader>
<CardIcon>
<ClockIcon />
</CardIcon>
<CardTitle>#OP-6894</CardTitle>
</CardHeader>
</Card>Wrapping content that has no header, title, description, or footer shape? Reach for Box instead. It's the same chrome, with none of Card's content slots.
Examples
With Icon and Description
#OP-6894
Pending approval
With Content and Footer
Order Summary
Review your order details
2x Items · Total: €487.00
Radius
none
md
2xl
full
Loading Skeleton
Interactive
Pass render with an <a href/> or <button/> to make the whole card the
click target: it gains a hover tint, focus ring, and disabled styles. Don't
nest other interactive controls inside an interactive card.
<Card color="accent" render={<a href="/meters" />} variant="soft">
<CardIcon>
<MaterialSymbol name="speed" />
</CardIcon>
<CardTitle>Submit meter reading</CardTitle>
<CardDescription>Takes about a minute</CardDescription>
</Card>API Reference
Components
Card- Root container; takesvariant+color(see props below)CardHeader- Header section with horizontal layout for icon and titleCardIcon- Slot for icon or avatarCardTitle- Primary heading textCardDescription- Secondary descriptive textCardContent- Main content areaCardFooter- Footer section for actionsCardSkeleton- Loading placeholder with animated skeleton
Card props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'soft' | 'surface' | 'outline' | 'ghost' | knob/soft | Container chrome, scoped to the card (never cascades into child controls). Unset follows the app-level data-card-variant. |
color | 'neutral' | 'accent' | 'neutral' | Chrome palette. neutral tracks the app theme's neutral color; accent tints the chrome with the brand accent. |
radius | 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full' | '2xl' | Corner radius for this card instance. Each step maps to the matching Tailwind rounded-* utility, so it still scales with the page-wide Roundness knob. |
render | ReactElement | — | Base UI polymorphism. Pass <a href/> or <button/> to make the card interactive (hover tint, focus ring, disabled styles). |
Set app-wide defaults with the Theme provider's cardVariant / cardColor props; a per-card prop overrides them. variant/color style only the card's own chrome: a Button or field inside the card keeps its own styling.