# Product Detail (Moonarc)

The top of a product's page: the product drawn large on its plate (ProductArt), with its colourways under it as small swatches (radio buttons) that recolour the drawing in place; beside it the trail back to the shop, the name, the price, a line, how many of the batch are left, two actions, the specifications in the mono face and a few notes that open (care, delivery). On a wide screen the picture holds while the details scroll past it. Zero JavaScript.

- Pro block. Install: `npx shadcn@latest add @moonarc-pro/product-detail` (license key required)
- Tier B · category section · trigger click
- Readout: `<ProductDetail name art={{ name, block }} ways={[{ name, colour }]} />`
- Browser support: newly (Chrome 105 · Firefox 121 · Safari 15.4); elsewhere: the first colourway shows and the swatches do not recolour it
- Measured cost: 0 B JS (CSS 20.6 kB raw)
- Page: https://moonarc.dev/components/product-detail/

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `name` | `string` | none | The product's name: the page's heading (level), and the picture's label. |
| `art` | `{ name: string; block?: 1 | 2 | 3 | 4 | 5 }` | none | The ProductArt drawing and the colour block of its plate. |
| `ways` | `{ name: string; colour: string; accent?: string }[]` | none | One to six colourways; the first is shown first. colour and accent are any CSS colour (var(--ma-block-2) follows the palette). |
| `price` | `string` | none | The price, in the mono face. |
| `unit` | `string` | none | After the price, smaller: per bag, each. |
| `lede` | `string` | none | A line under the price. |
| `trail` | `{ href: string; label: string }[]` | none | The trail back: the shop, a kind. A nav named by trailLabel. |
| `batch` | `{ made: number; left: number; text?: string }` | none | How many the batch makes and how many are left; text is the sentence with {left} and {made}. |
| `primary` | `{ href: string; label: string }` | none | The main action, e.g. to the pre-order form. |
| `secondary` | `{ href: string; label: string }` | none | The second action, outlined. |
| `specs` | `{ label: string; value: string }[]` | none | The specifications, as a description list. |
| `notes` | `{ title: string; body: string }[]` | none | Short notes under the specifications, each a details element that opens on its title. |
| `transition` | `string` | none | A view-transition-name for the picture, unique on the page: a card that names its picture the same way hands it over. |
| `waysLabel` | `string` | `'Colour'` | The colourways' legend. |
| `trailLabel` | `string` | `'Breadcrumb'` | Accessible name of the trail. |
| `priceLabel` | `string` | `'Price'` | The words a screen reader hears before the price. |
| `level` | `1 | 2` | `1` | The name's heading level: 1 as the product page's own heading, 2 under another h1. |
| `density` | `'compact' | 'cozy' | 'roomy'` | `'cozy'` | Block padding ×0.8 / ×1 / ×1.25 through --ma-density. |

## Usage

```astro
---
import ProductDetail from '@/components/moonarc/pro/ProductDetail.astro';
---
<ProductDetail
  name="Tall vase"
  art={{ name: 'vase', block: 1 }}
  ways={[
    { name: 'Sage', colour: 'var(--ma-block-2)', accent: 'var(--ma-block-3)' },
    { name: 'Ochre', colour: 'var(--ma-block-3)' },
  ]}
  price="$86"
  lede="A tall vase for branches and long stems."
  trail={[{ href: '/pieces/', label: 'Pieces' }]}
  batch={{ made: 24, left: 9 }}
  primary={{ href: '#reserve', label: 'Reserve one' }}
  specs={[{ label: 'Size', value: '32 cm tall' }, { label: 'Clay', value: 'Stoneware' }]}
  notes={[{ title: 'Delivery', body: 'Sent the week after it comes out of the kiln.' }]}
  transition="art-tall-vase"
/>
```

## Reduced motion

A new colourway paints at once instead of easing in, and the batch bar stands at its value.

## With ClientRouter

CSS only; nothing to rebind.

## Craft

- Each colourway's colours are custom properties on the section; the checked swatch picks which pair the drawing reads, and the drawing's fills ease to it.
- The swatches are radio buttons with their names beside them, so the colour is never told by the dot alone.
- The picture holds (sticky) while the specifications scroll past it on a wide box, and comes first on a phone.
- The notes are details elements: they open with a keyboard and stay open for find-in-page.

## Replaces

- Product pages (Shopify themes)
- Variant pickers

## Source

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