# Build the "Parameter panel" pattern: `ParameterPanel`

## 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
Exposed knobs — length, tone, temperature, aspect, effort — that shift output without a new prompt.

Use it when: Creative and analytical tools where users iterate toward a target they recognise on sight.

## What to build
A panel of a few plainly labelled controls (length, tone, aspect, detail) that change an output without rewriting the prompt. Each control has a safe range, shows when it differs from the person's defaults, and can be reset. It renders beside or under a generated result.

### Props
- `params`: Array<{ key: string; label: string; type: "segmented" | "slider" | "toggle"; options?: string[]; min?: number; max?: number; step?: number; endLabels?: [string, string]; description?: string }>, e.g. a slider labelled "More variable" to "More stable".
- `values`: Record<string, string | number | boolean> and `onChange(key: string, value: string | number | boolean)`, controlled values.
- `defaults`: Record<string, string | number | boolean>, the person's saved defaults, and `onSaveDefaults(values)`.
- `promptText?`: string, shown as "Same prompt" so a person sees the prompt is unchanged.
- `status`: "idle" | "applying" | "error".
- `onReset(key?: string)`: reset one control or all to defaults. The component never regenerates the output itself.

### States it must render
- Default: every control at the saved default; a line summarises them, e.g. "Standard, warm, timeline on".
- Changed: each control that differs from default shows a "changed" marker and its own reset; a Reset all link appears.
- Applying: the result area is marked as updating; controls stay usable and the latest value wins.
- Error: the change could not be applied; values revert to the last applied set with a message.

### Interactions
- Changing a control calls `onChange` once per committed value (on release for sliders, on click for segments).
- Reset on a control calls `onReset(key)`; Reset all calls `onReset()`.
- "Save as my defaults" calls `onSaveDefaults` with current values and updates the summary line.

### Edge cases
- Raw model settings (temperature, top_p) must not be passed as labels; every slider needs `endLabels` in plain words, and the component refuses to render a slider without them.
- Values outside the documented range coming from saved defaults: clamp and show that the value was adjusted.
- Rapid changes while applying: only the last value is applied; earlier ones are dropped.
- A parameter that does not apply to the current output: disabled with the reason.

## Must avoid
Surfacing raw model internals (top_p) that no user can reason about or predict.

## Engineering constraint
Persist per-user defaults; every param needs a documented safe range and a visible reset.

## Accessibility
- Sliders expose `aria-valuetext` using the plain end labels ("Mostly stable"), not just a number.
- The changed marker is text, and a reset announces which control returned to default.

## 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.
