# Build the "Example gallery" pattern: `ExampleGallery`

## Stack (edit this block to match your project)
- React 18+ with TypeScript: one function component, typed props, no `any`.
- Tailwind CSS, using your design system's tokens if you have them.
- Presentational only: data comes in through props, decisions go out through callbacks. No fetching or global state inside.
- If your codebase already has conventions (naming, shared components, tokens), follow them over this spec.

## What the pattern is for
Finished outputs shown with the prompt and settings that produced them, teaching by worked example.

Use it when: Generative tools where quality depends on prompt craft the user has not learned yet.

## What to build
A grid of finished outputs, each shown with the exact prompt and settings that produced it and an honest note on how many tries it took. A person can open any example to read its recipe and reuse it in one click, which reproduces it exactly. It renders on a new-item screen or an explore page.

### Props
- `examples`: Array<{ id: string; title: string; preview: ReactNode; prompt: string; params: Record<string, string | number>; attempts: number; edited: boolean; dataNote?: string }>, every example carries its stored prompt and parameters.
- `selectedId?`: string and `onSelect(id: string | null)`, controlled selection of the example whose recipe is open.
- `onUse(example: { prompt: string; params: Record<string, string | number> })`: loads the stored recipe into the editor. The component never runs it itself.
- `onCopyPrompt?(id: string)`: copies only the prompt text.
- `status`: "loading" | "ready" | "empty" | "error".
- `columns?`: 1 | 2 | 3, the grid width hint; the component drops to 1 column in narrow containers.

### States it must render
- Loading: placeholder cards with the same shape as real ones.
- Ready: cards with preview, title and a provenance tag such as "First try, unedited" or "Second try".
- Recipe open: the selected card shows the full prompt, each parameter as a label and value, and Use this and Copy prompt actions.
- Empty: a short line that no examples are available, without placeholder art.
- Error: the gallery failed to load, with retry.

### Interactions
- Selecting a card opens its recipe; selecting it again or pressing Escape closes it.
- Use this calls `onUse` with the stored prompt and parameters verbatim, never a paraphrase.
- Copy prompt calls `onCopyPrompt` and confirms briefly next to the button.

### Edge cases
- An example missing its stored prompt or parameters must not render a Use this button; show "Recipe not available" so the gallery never promises a reproduction it cannot give.
- An example that took several attempts or was edited: say so on the card face, not only inside the recipe.
- An example made from sample data: show `dataNote` (e.g. "Sample workspace data") so a person knows their own results will differ.
- A parameter the current product no longer supports: mark it in the recipe and still pass it in `onUse` for the parent to handle.

## Must avoid
A gallery of cherry-picked hero results that sets an expectation the user's own runs never meet.

## Engineering constraint
Store prompt and parameters with each sample so "use this" reproduces it exactly.

## Accessibility
- Each card is a button with `aria-expanded` labelled by its title and provenance; previews need a text alternative from `title`.
- When a recipe opens, keep focus on the card and make the recipe the next element in tab order.

## House rules
- Real `<button>`/`<input>` elements, full keyboard use, visible focus; announce status changes with `aria-live="polite"`; respect `prefers-reduced-motion`.
- All user-facing text comes from props (or a `labels` prop) so it can be translated.
- One consistent accent marks anything the AI made or is doing; amber means "needs a person", red means risky, green means done. Never rely on colour alone.
- Fits a 360 px wide container without horizontal scrolling.

## Acceptance checks
- [ ] Every state above can be rendered by passing props, with no internal fake data.
- [ ] Every interaction and edge case above behaves as described.
- [ ] Nothing in "Must avoid" can happen with this component.

## Deliver
1. The component file with its exported prop types.
2. A short usage example that renders each state.
