# Stat card

A KPI card with a headline number, a coloured delta and a dithered trend along the bottom.

> For the complete documentation index, see [llms.txt](/llms.txt). Markdown variants are available by appending `.md` to any URL or sending an `Accept: text/markdown` header. The dithercn agent skill, for building any dither on the engine, is at [/.well-known/agent-skills/dithercn/SKILL.md](/.well-known/agent-skills/dithercn/SKILL.md).

<ComponentPreview src="examples/stat-card-demo.tsx" controls="statCardControls">
  <StatCardDemo />
</ComponentPreview>

## Installation [#installation]

<InstallBlock name="stat-card" />

## Usage [#usage]

```tsx
import { StatCard } from "@/components/dithercn/stat-card";

export function Revenue() {
  return (
    <StatCard
      label="Monthly recurring revenue"
      value="$48,210"
      delta={12.4}
      deltaLabel="vs last month"
      trend={[31.2, 34.6, 37.8, 41.2, 45.1, 48.2]}
    />
  );
}
```

`delta` is a percentage: `12.4` reads as +12.4%. It is green when it moves the `good` way and red when it doesn't, using the palette's green and red pulled slightly toward the text colour so the small text keeps its contrast. `trend` takes recent values, oldest first, and draws them as a line with a square marker on the latest value. Under it, `fill="gradient"` draws bands that thin out below the line in dither steps; `dotted`, `hatched` and `solid` fill the area evenly. `color` takes a palette name such as `"blue"`, and `bloom` adds a soft glow behind the trend.

The card uses `bg-card` and a faint dot surface in the ink colour that fades out from the top right corner. Pass a `className` to change its background or width.

## Examples [#examples]

### KPI row [#kpi-row]

Four cards in a grid. Latency and error rate set `good="down"`, so latency going up is red and error rate going down is green. Each card has its own `color`, and latency, the one moving the wrong way, uses `color="red"` with `fill="hatched"` and a low bloom.

<ComponentPreview src="examples/stat-card-grid.tsx" size="lg">
  <StatCardGrid />
</ComponentPreview>

### Without a trend [#without-a-trend]

Leave `trend` out for a compact card, and `delta` out when there is nothing to compare. A delta of 0 is grey with no arrow.

<ComponentPreview src="examples/stat-card-compact.tsx" size="sm">
  <StatCardCompact />
</ComponentPreview>

## Props [#props]

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `label` (required) | `string` |  | What the number is. |
| `value` (required) | `number \| string` |  | The headline number. Numbers get thousands separators; strings show as given. |
| `delta` | `number` | `–` | Change since the last period, in percent. |
| `deltaLabel` | `string` | `–` | What the change compares with, such as "vs last month". |
| `good` | `"up" \| "down"` | `"up"` | Which direction counts as good, for the delta colour. |
| `trend` | `number[]` | `–` | Recent values, oldest first. Needs at least two. |
| `color` | `DitherColor` | `"ink"` | Colour of the trend and the dot surface, a palette name or any CSS colour. |
| `fill` | `"gradient" \| "dotted" \| "hatched" \| "solid"` | `"gradient"` | Texture under the trend line. |
| `bloom` | `"off" \| "low" \| "high"` | `"off"` | Soft glow in the colour behind the trend. |
| `matrix` | `"bayer2" \| "bayer4" \| "bayer8" \| "blue-noise"` | `"bayer4"` | Threshold pattern of the gradient fill. |
| `cell` | `number` | `--dither-cell` | Size of one dither cell in CSS pixels. |

## Notes [#notes]

* Screen readers hear the label, the value and the delta in words, such as "Up 12.4% vs last month". The trend and the surface are decorative and hidden.
* The trend is drawn at the card's real width in CSS pixels, so cells stay square and crisp at any size. It redraws when the card resizes.
* Nothing moves, so there is nothing to reduce.