Product Art
BackgroundsA product drawn flat, for a shop slot that has no photograph yet: 29 drawings in six sets (clothes, ceramics, coffee, skincare, furniture and objects, bakery).
The first screen of a maker's site: the heading, a line, two actions and three facts on one side; on the other, the products themselves, each drawn on its plate (ProductArt) with its name, a spec line in the mono face and its price. The plates take turns: one product rises in as the last fades, and the plate's colour changes with it. Small plates under them pick one (radio buttons, so the arrow keys move along them), which stops the turning; a Pause switch, a pointer or the focus on the plates stop it too. Zero JavaScript.
Firing 08 is on the shelf
Cups, bowls and vases thrown by hand and fired a few dozen at a time.
Tall vase32 cm · StonewarePrice: $86
Morning cup300 ml · Two glazesPrice: $24
Breakfast bowl16 cm · Speckled clayPrice: $32
Live, from the library itself, at full size: scroll, hover, navigate away and back. The demo is never gated.
Variants · each row writes the attribute the prop writes; the section's own CSS answers
JavaScript of its own
0 B
CSS 22.6 kB raw including the base tokens. Measured from a production build, and again in CI for every change that can move it.
Browser support
Chrome 105 · Firefox 121 · Safari 15.4; needs has. Elsewhere: the plates turn and the pause switch works; picking a small plate does not hold one.
The demo above is never gated; the source is. With a key in components.json (see account), the registry serves it like any other item:
npx shadcn@latest add @moonarc-pro/hero-specimen---
import HeroSpecimen from '@/components/moonarc/pro/HeroSpecimen.astro';
---
<HeroSpecimen
eyebrow="Firing 08 is on the shelf"
lede="Cups, bowls and vases thrown by hand and fired a few dozen at a time."
primary={{ href: '/pieces/', label: 'See the pieces' }}
secondary={{ href: '/studio/', label: 'How we make them' }}
facts={[{ label: 'Fired', value: 'Every six weeks' }, { label: 'Batch', value: 'About 120 pieces' }]}
items={[
{ name: 'Tall vase', art: { name: 'vase', colour: 'var(--ma-block-2)', block: 1 }, spec: '32 cm · Stoneware', price: '$86' },
{ name: 'Morning cup', art: { name: 'cup', colour: 'var(--ma-block-1)', block: 2 }, spec: '300 ml', price: '$24' },
{ name: 'Breakfast bowl', art: { name: 'bowl', colour: 'var(--ma-block-2)', block: 3 }, spec: '16 cm', price: '$32' },
]}
>
<span slot="headline">Clay for the table, <em>thrown slowly</em></span>
</HeroSpecimen>Without a key the registry answers 401 with an upgrade message. Everything this section composes is free: product-art.
| Prop | Type | Default | Description |
|---|---|---|---|
items | { name, art: { name, colour?, accent?, block? }, spec?, price? }[] | none | Two to five products. art.name is a ProductArt drawing; colour and accent any CSS colour (var(--ma-block-2) follows the palette); block the plate's colour block (the first four in turn when unset). |
eyebrow | string | none | A short line above the heading, after a dot. |
headline | string | none | The heading. Slot "headline" wins and may hold an <em>, set in the emphasis face and colour. |
lede | string | none | A line under the heading. |
primary | { href: string; label: string } | none | The main action. |
secondary | { href: string; label: string } | none | The second action, outlined. |
facts | { label: string; value: string }[] | none | Up to three short facts under the actions: a label in the mono face and its value. |
step | number | 4.5 | Seconds each product stands before the next. |
listLabel | string | 'Featured pieces' | Accessible name of the list of products. |
pickLabel | string | 'Show a piece' | Accessible name of the row of small plates. |
pauseLabel | string | 'Pause' | The pause switch's words. |
priceLabel | string | 'Price' | The words a screen reader hears before each price. |
level | 1 | 2 | 1 | Heading level: 1 as the page's hero, 2 under another h1. |
tone | 'surface' | 'muted' | 'ink' | 'brand' | unset (paints nothing) | The section's ground; the plates keep their blocks on every tone. |
density | 'compact' | 'cozy' | 'roomy' | 'cozy' | Block padding ×0.8 / ×1 / ×1.25 through --ma-density. |
The section reads the theme contract (shadcn's variable names with the base tokens as fallback), so a pasted theme or one --ma-brand recolours it. Its class names are the override surface and stay stable; a named slot replaces the matching prop with your own markup.
.ma-specimen.ma-specimen__actions.ma-specimen__art.ma-specimen__btn.ma-specimen__btn--primary.ma-specimen__btn--secondary.ma-specimen__caption.ma-specimen__controls.ma-specimen__copy.ma-specimen__eyebrow.ma-specimen__fact.ma-specimen__facts.ma-specimen__headline.ma-specimen__inner.ma-specimen__lede.ma-specimen__mini.ma-specimen__name.ma-specimen__pause.ma-specimen__pause-icon.ma-specimen__pick.ma-specimen__plate.ma-specimen__plates.ma-specimen__price.ma-specimen__spec.ma-specimen__stage.ma-specimen__thumb
slot="eyebrow"slot="headline"
The plates stand still on the first product and the pause switch is not shown; the small plates still pick one.
ClientRouterCSS only; nothing to rebind. Each swap starts the turning from the first product.
Replaces: Shop hero sliders (Shopify themes) · Product carousels. See the migration table.
A product drawn flat, for a shop slot that has no photograph yet: 29 drawings in six sets (clothes, ceramics, coffee, skincare, furniture and objects, bakery).
The opening of a colour-block site: the headline rises line by line out of its masks, its last word turns through a few in the emphasis face (RotatingText), a round badge with text running around it links further down the page, the lede and two pill actions sit under it, and a strip of tiles in the palette's blocks runs across the bottom (Marquee), each a drawing (Motif) or a picture with a caption.
The next batch, as one colour block: the product drawn large (ProductArt) under a round date stamp, and beside it the heading, a line, how many of the batch are spoken for (a count, and a bar that fills as the panel comes into view), three facts in the mono face and two actions.
A row of products that runs off the page's edge: each drawn on its plate (ProductArt) with a hang tag for the price, the name as the card's link and a spec line in the mono face.
Also: view transitions · how costs are measured · browser support · accessibility policy · five-minute setup · MCP for agents · this page as Markdown