Card
A generic, shadcn-style content surface. Compose the parts explicitly so each card can carry its own header layout, body shape, or action row without per-prop overrides on the Root.
Bloom the aromatics
~3 min · medium effort
Warm the oil over medium heat, then add the spices and stir until they smell like themselves.
Footer actions sit here.
Customize
Variant
default
Slots
Installation
npx shadcn@latest add https://craftbits.dev/r/card.jsonUsage
import { Card } from "@craft-bits/core";
<Card.Root variant="elevated">
<Card.Header>
<Card.Title>Bloom the aromatics</Card.Title>
<Card.Description>~3 min · medium effort</Card.Description>
</Card.Header>
<Card.Content>
Warm the oil over medium heat, then add the spices and stir until they
smell like themselves.
</Card.Content>
<Card.Footer>
<button>Mark done</button>
</Card.Footer>
</Card.Root>Anatomy
- Card.Root — outer surface. Owns the
variant(border + lift) and the vertical-stack rhythm (gap-4) between Header, Content, and Footer. - Card.Header — tight stack (
gap-1) forTitle+ optionalDescription. - Card.Title — primary heading. Renders as
<h3>. Serif,[text-wrap:balance]. - Card.Description — supporting copy.
<p>, muted tone,[text-wrap:pretty]. - Card.Content — body slot.
- Card.Footer — bottom row.
flex items-center gap-2so a row of buttons baselines cleanly.
Variants
- default — 1px border on the elevated surface, no shadow. The base.
- elevated — same border + soft two-layer lift shadow (neutral RGB at low alpha — never pure black). Use when the card is the page's primary read.
- ghost — no border, transparent surface. Composes inside other chrome without doubling the frame.
Props
Card.Root
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'default' | 'elevated' | 'ghost' | 'default' | Surface treatment. |
className | string | — | Merged onto the root <div> via cn(). |
Card.Header / Card.Content / Card.Footer each accept HTMLAttributes<HTMLDivElement>. Card.Title renders <h3>. Card.Description renders <p>.
Accessibility
Card.Rootrenders a plain<div>— no implicit role. Wrap a grid of cards in<ul>/<li>(or supplyrole="list"/role="listitem") when the order is semantically meaningful.Card.Titleis an<h3>. Keep the document outline correct by placing the card under an<h2>section.Card.Descriptionis a<p>, not a heading.- The lift shadow on
variant="elevated"is decorative; the border still carries the affordance at high-contrast / forced-colors. - No motion — safe for users with
prefers-reduced-motion: reduce.
Credits
- Extracted from:
algoflashcards(src/platform/ui/card.tsx). The source was a flat 6-slot shadcn card with asizeprop androunded-4xlbaked in. The library extract dropsCardAction(compose your own button row insideCard.Footer), replacesbg-card/text-card-foreground/ring-foreground/8withcb-*semantic tokens, and exposes the size knob as avariantmatrix (default/elevated/ghost) so the shadow story stays explicit.