# Fee Table (Moonarc)

What a practice charges, as tables a reader can trust: one a group, each row a service, its price and a note, and where insurance applies a column that says in words whether it is covered, partly or not, with a mark that repeats it in shape. Under the tables, the insurers it works with, the ways to pay and the notes a price needs. Real tables with captions and row headers, so a screen reader reads a price with its service; three columns fit a phone without scrolling sideways. Zero JavaScript.

- Pro block. Install: `npx shadcn@latest add @moonarc-pro/fee-table` (license key required)
- Tier B · category section · trigger scroll
- Readout: `<FeeTable groups={[{ name, rows: [{ service, price, covered }] }]} insurers={{ label, names }} />`
- Browser support: widely (every browser); elsewhere: nothing to fall back from
- Measured cost: 0 B JS of its own · uses Reveal + runtime (with dependencies 3.0 kB raw; CSS 10.5 kB raw)
- Page: https://moonarc.dev/components/fee-table/

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `headline` | `string` | none | The heading. Slot "headline" wins and may hold an <em>. |
| `eyebrow` | `string` | none | A short line above the heading. |
| `copy` | `string` | none | A line under the heading. |
| `groups` | `{ name; rows: { service; price; note?; covered?: 'yes' | 'part' | 'no' }[] }[]` | none | One table a group, its name the caption. The insurance column shows when any row sets covered. |
| `words` | `{ service?; price?; covered?; yes?; part?; no? }` | none | The column heads and the three answers of the insurance column. |
| `insurers` | `{ label; names: string[] }` | none | The insurers it works with, as chips. |
| `payment` | `{ label; methods: string[] }` | none | The ways to pay, as chips. |
| `notes` | `string[]` | none | The notes under the tables. |
| `level` | `1 | 2 | 3` | `2` | Heading level of the heading; the side's labels are one below. |
| `tone` | `'surface' | 'muted' | 'ink' | 'brand'` | `unset (paints nothing)` | The section's ground. |
| `density` | `'compact' | 'cozy' | 'roomy'` | `'cozy'` | Block padding ×0.8 / ×1 / ×1.25 through --ma-density. |

## Usage

```astro
---
import FeeTable from '@/components/moonarc/pro/FeeTable.astro';
---
<FeeTable
  headline="What it costs"
  groups={[{ name: 'Check-ups', rows: [{ service: 'Check-up', price: '$85', covered: 'yes' }, { service: 'Hygiene clean', price: '$95', note: '45 minutes', covered: 'part' }] }]}
  insurers={{ label: 'Insurers we work with', names: ['Insurer A', 'Insurer B'] }}
  payment={{ label: 'Ways to pay', methods: ['Card', 'Bank transfer'] }}
  notes={['A price from is the least it costs: the dentist gives you the full price before any treatment.']}
/>
```

## Reduced motion

The tables arrive at once.

## With ClientRouter

CSS and Reveal.

## Craft

- Each service is a row header (th scope="row"), so a screen reader announces the service with its price and its cover.
- Cover is a word first; the mark before it, full, half or empty, repeats it for a reader scanning down the column, never colour alone.
- The price column never wraps and the service column does, which is how three columns fit 320 px.

## Replaces

- Price list tables

## Source

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