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

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

> A KPI tile — mono uppercase label, big tabular value, optional unit, delta, and sparkline on a bordered surface. Also exported as KpiStat.

## When to use it

Use **StatCard** for a *single* metric that needs a bordered container — a dashboard KPI with a label, a delta, and maybe a trend line. It's imported as `KpiStat` too, for admin-console code that prefers that name. For a *row of headline figures with no border* (the marketing metrics band), use **StatStrip**. For just the *change number* on its own, use **MetricDelta**; for just the *trend line*, use **Sparkline**. StatCard is the composed tile that hosts those primitives.

## Props

### StatCard

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `className` | `string` | no | — | — |
| `delta` | `ReactNode` | no | — | Optional metric-delta slot, rendered beside the value (e.g. a MetricDelta). |
| `footer` | `ReactNode` | no | — | Optional muted footer line (context, timestamp…). |
| `icon` | `ReactNode` | no | — | Optional leading icon slot in the label row. |
| `label` | `ReactNode` | yes | — | Metric label — rendered mono, UPPERCASE, muted. |
| `sparkline` | `ReactNode` | no | — | Optional sparkline slot beneath the value row. |
| `style` | `CSSProperties` | no | — | — |
| `unit` | `ReactNode` | no | — | Optional trailing unit beside the value (e.g. "ms", "%"). |
| `value` | `ReactNode` | yes | — | The headline figure — big mono, tabular. |

### KpiStat

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `className` | `string` | no | — | — |
| `delta` | `ReactNode` | no | — | Optional metric-delta slot, rendered beside the value (e.g. a MetricDelta). |
| `footer` | `ReactNode` | no | — | Optional muted footer line (context, timestamp…). |
| `icon` | `ReactNode` | no | — | Optional leading icon slot in the label row. |
| `label` | `ReactNode` | yes | — | Metric label — rendered mono, UPPERCASE, muted. |
| `sparkline` | `ReactNode` | no | — | Optional sparkline slot beneath the value row. |
| `style` | `CSSProperties` | no | — | — |
| `unit` | `ReactNode` | no | — | Optional trailing unit beside the value (e.g. "ms", "%"). |
| `value` | `ReactNode` | yes | — | The headline figure — big mono, tabular. |

## Examples

### Basics

A `label` (mono, uppercase, muted) over a big tabular `value`, with an optional trailing `unit` and a muted `footer` line for context.

```tsx
import { StatCard } from "@protocore/pds";

export default function StatCardBasics() {
  return (
    <div style={{ maxWidth: 240 }}>
      <StatCard
        label="p99 latency"
        value="184"
        unit="ms"
        footer="Rolling 5-minute window"
      />
    </div>
  );
}
```

### With delta & sparkline

Slot a `<MetricDelta>` into `delta` for the change indicator and a `<Sparkline>` into `sparkline` for the trend. An `icon` sits in the label row. The sparkline's `signal` dot is the single accent point.

```tsx
import { StatCard, MetricDelta, Sparkline } from "@protocore/pds";
import { Activity } from "lucide-react";

export default function StatCardRich() {
  return (
    <div style={{ maxWidth: 280 }}>
      <StatCard
        icon={<Activity size={14} />}
        label="Throughput"
        value="1,284"
        unit="msg/s"
        delta={<MetricDelta value={4.2} />}
        sparkline={
          <Sparkline
            data={[820, 910, 880, 1040, 1120, 1180, 1284]}
            area
            signal
            ariaLabel="Throughput trend, last 7 epochs"
          />
        }
        footer="vs. previous epoch"
      />
    </div>
  );
}
```

## Usage

**Do**

- Keep the `label` short and consistent-case — it renders mono uppercase by contract.
- Put the number in `value` and the unit in `unit` so the tabular figure stays clean and alignable.
- Compose `delta` from `<MetricDelta>` and `sparkline` from `<Sparkline>` rather than hand-rolling markup.
- Align precision and units across a KPI row so the numbers compare at a glance.

**Don't**

- Don't bake the unit into the `value` string — you lose the tabular alignment the separate `unit` slot gives.
- Don't put more than one trend line in a card; StatCard shows one metric.
- Don't use StatCard for a borderless marketing figure band — that's StatStrip.
- Don't color the value manually to signal direction; that's what the `delta` slot's MetricDelta does.

## Accessibility

**Notes**

- StatCard is a static `<div>`; the `icon` in the label row is `aria-hidden` — its meaning is carried by the visible `label` text.
- A `<MetricDelta>` conveys direction with a glyph (▲/▼/—) plus the signed number, not color alone, so the trend survives for color-blind users.
- Give the `<Sparkline>` an `ariaLabel` when the trend itself is informative; otherwise it stays hidden as decoration.

## Related

`stat-strip`, `metric-delta`, `sparkline`, `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/
