# Card

> A bordered surface that groups related content, with header, title, description, content, and footer parts.

- Name: `card`
- Status: beta
- Categories: layout
- File: the install writes `card.tsx` to your `ui` alias, `@/components/ui` by default.
- Gallery: https://arbokui.com/components/card
- Registry item: https://arbokui.com/r/card.json

## Install

1. Add the registry to `components.json`. Do this first, once:

   ```bash
   npx shadcn@latest registry add "@arbokui=https://arbokui.com/r/{name}.json"
   ```

   The command writes this entry. You can also add it by hand:

   ```json
   {
     "registries": {
       "@arbokui": "https://arbokui.com/r/{name}.json"
     }
   }
   ```

   Without this step, the shadcn CLI looks up `@arbokui` in a public list that Arbokui does not control.

2. Add the theme once per app. It replaces your color tokens with ones checked for contrast:

   ```bash
   npx shadcn@latest add @arbokui/theme
   ```

3. Add the component:

   ```bash
   npx shadcn@latest add @arbokui/card
   ```

## Use it for

- Grouping one topic so it reads as a unit: a plan, a stat, a settings section, a list item with actions.
- Laying out several items of the same kind in a grid.
- Use only the parts you need. A card with just CardContent is fine.
- Density sets the padding and the space between parts, so cards tighten and loosen with the rest of the app.

## Avoid it for

- Wrapping the whole page, or putting cards inside cards. Use headings and spacing instead.
- Important messages. Use an Alert, so the message has a tone.
- Making the whole card a click target with onClick on the div. Put a real link or button inside it.
- Rows of a table. Use a table, so screen readers can move by row and column.

## Props

- `className`: `string`. Extra classes on any part. Later classes win, so className='px-0' on CardContent lets a table run edge to edge.
- `Card`: `ComponentProps<"div">`. The surface. Pads top and bottom with --space-inset and spaces its parts with --space-stack.
- `CardHeader`: `ComponentProps<"div">`. Part. Stacks the title and description.
- `CardTitle`: `ComponentProps<"div">`. Part. Semibold title. A div, so put an \<h2> or \<h3> inside when the card needs a heading.
- `CardDescription`: `ComponentProps<"div">`. Part. Secondary text in muted-foreground.
- `CardContent`: `ComponentProps<"div">`. Part. The body. Pads its sides with --space-inset.
- `CardFooter`: `ComponentProps<"div">`. Part. A row for actions or a summary. It wraps on small screens.

## Accessibility

- Every part is a plain \<div> with no role, so a card adds no noise for screen readers.
- CardTitle is not a heading. Put an \<h2> or \<h3> inside it at the right level when people should be able to jump between cards.
- Keep links and buttons inside the card. A clickable div is not reachable by keyboard.
- The theme tests hold card-foreground and muted-foreground to 4.5:1 on the card color, in light and dark.

## Examples

### Header, content, and footer (needs @arbokui/button)

```tsx
import { Button } from "@/components/ui/button";

<Card className="max-w-sm">
  <CardHeader>
    <CardTitle>Pro plan</CardTitle>
    <CardDescription>For teams that ship every week.</CardDescription>
  </CardHeader>
  <CardContent>
    <p className="text-2xl font-semibold">$24 per month</p>
  </CardContent>
  <CardFooter>
    <Button tone="brand">Upgrade</Button>
    <Button emphasis="ghost">Compare plans</Button>
  </CardFooter>
</Card>
```

### A stat with only content

```tsx
<Card>
  <CardContent>
    <p className="text-sm text-muted-foreground">Active users</p>
    <p className="text-3xl font-semibold tabular-nums">12,480</p>
  </CardContent>
</Card>
```

### A heading inside the title

```tsx
<Card>
  <CardHeader>
    <CardTitle>
      <h2>Billing</h2>
    </CardTitle>
    <CardDescription>Your next invoice is on 1 November.</CardDescription>
  </CardHeader>
</Card>
```

### A list that runs edge to edge

```tsx
<Card>
  <CardHeader>
    <CardTitle>Recent deploys</CardTitle>
  </CardHeader>
  <CardContent className="px-0">
    <ul className="divide-y border-y text-sm">
      <li className="px-(--space-inset) py-2">main · 2 minutes ago</li>
      <li className="px-(--space-inset) py-2">fix-login · 1 hour ago</li>
    </ul>
  </CardContent>
</Card>
```
