A card is a boundary: it groups one subject's picture, heading, sentence of context and actions
on a surface that says these belong together, so a page can show several of them without
inventing a layout each time.

It is not a layout primitive, the arrangement inside it comes from `Stack` and `Grid`, and the
card supplies the surface, the spacing scale and, when it is interactive, the semantics. Nor is
it a container for other cards: the surface is drawn once, by the outer one. Its siblings state
one fact each: `Badge` and `Chip` label, `Avatar` represents, and a card is where all of them
are put.

```tsx demo="data-display/card-preview"
```

## Usage

```tsx
import { Card } from "@asheeui/web";

<Card title="Invoice INV-1041" description="Northwind Traders · due 31 March">
  £4,280.00 outstanding across twelve line items.
</Card>
```

`children` is the body, and `body` states it explicitly when the card's content is not the
element's children. `header` sits above the title, `title` and `description` are rendered for
you, and `footer` sits at the bottom of the content column, which is where a price and its
actions usually go.

## Pictures

An image has three placements. `top` and `bottom` draw it outside the padded content, so it is
full-bleed and clipped by the card's radius; `background` draws it under the content instead,
for a card that is a cover rather than a row.

```tsx demo="data-display/card-images"
```

In the `image` object, `ratio` locks the frame the picture is fitted into and `fit` decides how it
fills that frame, `video` and `cover` when nothing states otherwise, and both resolve through the
cascade, so `components.card.image.ratio` retunes every card at once. `loading` resolves the same
way and falls back to `lazy`. `loading` and `priority` that the picture's own component states are
forwarded as given: the card does not overrule a framework's loader.

`image.component` and `image.componentProps` keep a framework's own image working inside the
card, the intrinsic size, the loader, the allowed host, and `link.component` does the same for
the element the whole card renders as. Both are the framework's one seam:
[links and substitution](/concepts/substitution).

## Cards that go somewhere

A card becomes interactive when `link` or `onClick` is given, or when `isClickable` says so. A
`link` makes the root the link itself rather than a handler on a `div`, so it is announced as a
link and opens like one, and `link.component` renders a router's own link in its place. An
`onClick` without a link keeps the card a `div` but gives it button semantics, so
<kbd>Enter</kbd> and <kbd>Space</kbd> both work.

```tsx demo="data-display/card-interactive"
```

`link.componentProps` is spread onto the card's root last, so its `href` and its own `onClick` win
over the props the framework passes, and the card's `onClick` still runs beside the link's.
`className` is the one exception: it is merged into the card's classes through `cn` rather than
spread last, because spreading it last would replace the surface the card drew. `isDisabled` dims the
card, refuses the press and takes it out of the tab order: an unavailable card is drawn but
cannot be reached, the opposite of a disabled `Button`, which stays focusable so a reader can
find out why it will not press. A card that renders a real link stays reachable even when
`isClickable` is `false`, the card's own affordance and the link are separate things, and a
destination should not become unreachable because a prop described the surface.

## Props

```props Card
```

`size`, `animate` and `image.position` are registered as `md`, `true` and `top`, so density, the
press animation and the default picture placement resolve from the instance or from
`components.card`. `variant` and `radius` are not registered: `radius` resolves from the
application's `defaultRadius`, the framework's own is `xs`, so a card is only slightly rounded
until the product rounds more, and `variant` resolves from the application's `defaultVariant`
through a map onto the four surfaces a card draws, so `solid` becomes `elevated` and `faded` or
`underlined` land on the resting `bordered`. A page with no configuration gets a `bordered` card
on the application's radius.

`image.ratio` and `image.fit` resolve from the instance, then `components.card.image`, then the
`video` and `cover` fallbacks; `image.loading` resolves the same way. `titleAs` changes the
heading level and is instance-only. `link`, `isClickable`, `isDisabled`, the four content slots
and the image's `src`, `alt` and `component` are instance-only too, because they state this
card's subject rather than the design's.

## Accessibility

- `title` is rendered as a level-three heading by default, so a card belongs under a level-two
  heading; `titleAs` states the level when the card sits somewhere else in the outline.
- A card with `onClick` renders `role="button"` and answers <kbd>Enter</kbd> and <kbd>Space</kbd>.
  A card with a `link` renders the link element instead and keeps that element's own activation,
  so it is announced as a link, opens in a new tab, and its destination can be copied.
- `isDisabled` sets `aria-disabled`, dims the card, removes it from the pointer
  (`pointer-events-none`) and from the tab order (`tabindex="-1"`).
- The picture is the only part with alternative text: state `image.alt`, or pass an empty one
  for a decorative cover whose title already says what it is.

## Related

```related badge, image, stack
```
