# Comparison Table (Moonarc)

Compares your product with others in an "us versus them" table. The first column is highlighted, rows reveal with a stagger, and a thin bar under each numeric cell shows a byte count or a score at a glance. A semantic table with zero JavaScript of its own.

- Pro block. Install: `npx shadcn@latest add @moonarc-pro/compare-table` (license key required)
- Tier B · category section · trigger scroll
- Readout: `<CompareTable columns={[…]} rows={[…]}>`
- Browser support: newly (Chrome 85 · Firefox 128 · Safari 16.4); elsewhere: bars fill without animating
- Measured cost: 0 B JS of its own · uses Reveal + runtime (with dependencies 3.0 kB raw; CSS 12.0 kB raw)
- Page: https://moonarc.dev/components/compare-table/

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `columns` | `string[]` | none | Column headers; the first is "us". |
| `rows` | `{ label, cells: { text, value?, good? }[] }[]` | none | Rows; a numeric value draws a bar; good bolds the cell and adds goodLabel for screen readers. |
| `max` | `number` | `100` | Maximum for the bars, shared by every row. |
| `tone` | `'surface' | 'muted' | 'ink' | 'brand'` | `unset (paints nothing)` | The ground: the page surface, a muted band, an always-dark ink panel, or a deep brand panel. Each paints --background, --ma-tone-muted (over --muted, with a --border hairline), --ma-tone-ink or --ma-tone-brand (over --primary) with the matching text. With theme.css, a painted tone also re-declares --card, --border, --input and --ring inside the section, so cards and fields follow the ground. Decoration is strongest on brand. |
| `density` | `'compact' | 'cozy' | 'roomy'` | `'cozy'` | Cell padding ×0.8 / ×1 / ×1.25 through --ma-density. |
| `label` | `string` | `'Comparison'` | Accessible name of the table, which scrolls sideways when a narrow screen cuts it: the section takes a tab stop, so a keyboard can reach and scroll it. Make it unique per page. |
| `goodLabel` | `string` | `'better'` | Screen-reader text after a good cell's text, in parentheses, since bold alone says nothing to a screen reader. |

## Usage

```astro
---
import CompareTable from '@/components/moonarc/pro/CompareTable.astro';
---
<CompareTable
  columns={['Ours', 'Product A', 'Product B']}
  max={10}
  rows={[
    { label: 'Setup steps', cells: [{ text: '2', value: 2, good: true }, { text: '9', value: 9 }, { text: '6', value: 6 }] },
  ]}
/>
```

## Reduced motion

Rows fade in without stagger; bars are full at once.

## With ClientRouter

Inherits Reveal and Progress; nothing to wire.

## Craft

- Bars share one max, the max prop, across the table, so 2 next to 9 is a short bar next to a long one. The difference is visible before the numbers are read.
- The highlighted column is a 6% tint, so the table still looks neutral. A comparison table has to look fair to be believed.
- Let a competitor win the rows it wins. A table where every cell is green reads as an advert.
- The bars are aria-hidden: the cell's text already says the number, and a screen reader should hear it once. The corner cell is a td, not an empty header, and the table scrolls inside itself from the keyboard as well (a tab stop) on a phone.

## Replaces

- Comparison sections (Tailwind Plus)

## Source

Pro block. The source is served by the license-gated registry: `npx shadcn@latest add @moonarc-pro/compare-table` with a key in components.json (https://moonarc.dev/account/). Everything it composes is free: reveal, progress.
