Card
The stream-level container drawn as a code window: a step off the page, a 7% hairline, never a shadow; a window variant with a title bar.
import { Card, CardHeader, CardTitle, … } from "@arcadia/ui"A card is a code window: one step off the page on --bg-card, framed by a 7% hairline with continuous corners, and it never casts a shadow: it is part of the page, not floating over it. Put rows in CardRows (ListRows inset 6px), prose in CardBody, a title and meta in CardHeader, and actions in CardFooter.
Examples
Interactive header
With interactive, the whole header is one button: a disclosure, or a way to open the plan. Don't nest other buttons in it; a static header with CardMeta can hold them instead.
A form
render turns the card into the <form> itself, so the footer's buttons submit and reset it natively.
Window
variant="window" makes the first header a title bar: the file in mono (its name in text-1, the folder in text-3), stats and actions at the end and always shown, and a hairline below.
A file and its diff read as one object.
rootStyle takes where the card sits and these knobs; the header, body, rows and footer read them too, so --card-px moves every part's padding at once.
| Knob | Takes | Default | Sets |
|---|---|---|---|
Paint | var(--bg-card) | The card's surface. | |
Paint | HAIRLINE | The 1px frame. | |
Ref<Radius> | var(--radius-frame-card) | Corner radius (the card frame, 15; a nested card takes its rows' corner). | |
Ref<"--corner"> | "round" | var(--corner) | Corner shape: continuous where supported, round on a nested card. | |
Ref<Space> | var(--space-3) | Inline padding of the header, body and footer. | |
Ref<Control> | var(--control-lg) | A window's title bar height. |
Rows inside CardRows subtract their 6px inset and the border from the card radius, keeping the same corner shape.
A card is a plain <div> with no role; its parts are text and the controls you put in them. The one exception is an interactive header, which renders a <button>: give it aria-expanded when it discloses the body, as above, and keep its text short, because the whole header is its name.
When a card is a section people navigate to, give it a heading or role="region" with aria-labelledby on its title. Diff counts are colour and text, so "+14 −3" still reads without the colour.
- EnterSpace
- Activates an interactive header
- Tab
- Moves through the controls inside
Card
level- "stream" | "nested"Default"stream"
stream: a turn-level card,--radius-frame-card(15) with continuous corners.nested: a detail inside a card or row, round, concentric with its rows.variant- "default" | "inset" | "window"Default"default"
inset: a well (diff body, shell output): the page seen through the card's 7 % frame.window: a code window whose firstCardHeaderis its title bar (path in mono, stats and actions at the end, a hairline below).rootStyle- CardStyle
- Typed StyleX override: where the card sits and its
--card-*knobs.
Rest props go to <div> props and render.
interactive- booleanDefaultfalse
- The whole header is one control (a disclosure, "open plan"): renders a
buttonwith a hover fill. Don't put other buttons inside an interactive header; use CardMeta on a static one. divided- booleanDefaultfalse
- Hairline under the header (a body follows).
Rest props go to <div> props and render.
divided- booleanDefaultfalse
Rest props go to <div> props and render.
No props of its own. Rest props go to <span> props and render.
No props of its own. Rest props go to <span> props and render.
No props of its own. Rest props go to <div> props and render.
No props of its own. Rest props go to <div> props and render.