<!-- Protocore Design System — Card -->
# Card

- **Category:** Cards (`cards`)
- **Slug:** `cards/card`
- **Status:** stable
- **Platforms:** web, mobile
- **Import:** `import { Card } from "@protocore/pds";`
- **Docs:** https://pds.protocore.io/components/cards/card

> A surface block with a hairline border and sharp corners — flat title/subtitle/action props or compound Card.Header/Body/Footer.

## When to use it

Reach for **Card** when you need a self-contained surface that groups a heading with body content and optional actions — a feature block, a settings panel, a summary tile. For a *tone-tinted note* (success/warning/danger), use **Callout** instead; it carries the colored left rule that Card deliberately omits. For a *media-led* block with an art panel and eyebrow, use **Tile** (or its ports **ProductCard** / **PrincipleTile**). For a *single labelled metric*, use **StatCard**. Card is the neutral, un-tinted container the others specialise.

## Mobile (React Native)

**Preview.** `@protocore/pds-mobile` ships the React Native sibling of **Card**. It mirrors the web API where React Native allows; the package is a **preview** with no device-level QA yet, so pin it and expect small changes.

Import it from the mobile package (not `@protocore/pds`), inside a `<PdsProvider>` — there is no stylesheet, so `style` (a `ViewStyle`) replaces `className` and every value comes from the theme:

```tsx
import { Card } from "@protocore/pds-mobile";
```

**Parity with web.** The surface / feature block — hairline border, sharp corners, no shadow — with the same flat props and compound parts as web.

- Flat props `index` / `title` / `subtitle` / `action`, plus compound `Card.Header` / `Card.Body` / `Card.Footer`.
- String / number children render as 14dp secondary body copy.

```tsx
<Card index={1} title="Payments API" subtitle="v2.4.0" action={<Button>Open</Button>}>
  Handles checkout and refunds.
</Card>
```

## Props

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `action` | `ReactNode` | no | — | Footer action slot, usually a Button; separated from the body by 24px. |
| `children` | `ReactNode` | no | — | Body content — rendered at 14px / secondary / 1.6 line-height. |
| `className` | `string` | no | — | — |
| `index` | `number` | no | — | Optional bracket index pinned top-right, zero-padded to two digits (`1` → `[ 01 ]`). |
| `style` | `CSSProperties` | no | — | — |
| `subtitle` | `ReactNode` | no | — | Secondary line under the title — 15px, muted. |
| `title` | `ReactNode` | no | — | Card title — 22px / 500 / -0.01em, ink. |

## Examples

### Basics

The flat API covers the common case: an optional bracket `index`, a `title`, a muted `subtitle`, body copy as children, and an `action` slot pinned to the footer.

```tsx
import { Card, Button } from "@protocore/pds";

export default function CardBasics() {
  return (
    <Card
      index={1}
      title="Value Transfer"
      subtitle="Move native assets across networks"
      action={<Button size="sm">Connect</Button>}
    >
      Issue any asset on chain and extend its reach to new ecosystems without fragmenting liquidity
      or wrapping tokens.
    </Card>
  );
}
```

### Composition

When the layout is richer than the flat props allow, drop into `Card.Header`, `Card.Body`, and `Card.Footer`. The header and footer are flex rows, so a title sits left and controls or a status Badge sit right.

```tsx
import { Card, Button, Badge } from "@protocore/pds";

export default function CardComposition() {
  return (
    <Card>
      <Card.Header>
        <div style={{ fontSize: 22, fontWeight: 500, letterSpacing: "-0.01em" }}>eu-central-1</div>
        <Badge tone="success" dot>
          Healthy
        </Badge>
      </Card.Header>
      <Card.Body>
        Four verifier nodes online, all reporting within the 200ms finality budget. Last epoch
        settled 1,284 messages with zero reverts.
      </Card.Body>
      <Card.Footer>
        <Button variant="secondary" size="sm">
          View region
        </Button>
        <Button variant="ghost" size="sm">
          Logs
        </Button>
      </Card.Footer>
    </Card>
  );
}
```

## Usage

**Do**

- Use the flat `title`/`subtitle`/`action` props for simple cards, and only reach for the compound parts when you need a two-sided header or multiple footer rows.
- Keep body copy to a comfortable measure (~60ch) so grids of cards stay even.
- Put the primary control in `action` (flat) or `Card.Footer` (compound) — one clear next step per card.
- Use `index` to enumerate a sequence of cards (steps, principles, features).

**Don't**

- Don't add a box-shadow or rounded corners — Card is a flat hairline surface by contract.
- Don't tint the whole card to signal status; that's Callout's job.
- Don't mix the flat `title` prop and a `Card.Header` in the same card — pick one model.
- Don't stuff multiple unrelated actions into the footer; if the card does many things it should be several cards.

## Accessibility

**Notes**

- Card is a plain `<div>` surface — it renders no interactive semantics of its own. Any buttons or links you place in `action`/`Card.Footer` keep their native keyboard behavior.
- The bracket `index` is decorative (`aria-hidden`); put any meaning the number carries into the visible `title` as well.
- Give the card a heading element or `aria-labelledby` if it acts as a landmark region in a larger layout; by default it is not announced as a region.

## Related

`tile`, `callout`, `stat-card`, `product-card`

---

© Protocore. All rights reserved. Use of the Protocore Design System requires prior written authorization from Protocore (contact@protocore.io). These machine-readable materials must not be ingested into ML-training datasets or derivative design systems. See https://pds.protocore.io/legal/
