# Build the "Verification handoff" pattern: `VerificationChecklist`

## 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
The system names exactly what a human should double-check, turning blanket doubt into one task.

Use it when: Outputs that are mostly right but carry a specific risky element — a figure, a name, a legal clause.

## What to build
A short, specific list of the items in an AI output that a person should check, each tied to the exact phrase or value, with the reason it is uncertain and one-click resolutions. It also states what the system already checked, and enables the dependent action once every item is resolved. It renders beside a draft message, document or form before it is sent or submitted.

### Props
- `items`: Array<{ id: string; quote: string; anchorId: string; reason: string; resolutions: Array<{ id: string; label: string; kind: "keep" | "change" | "remove"; replacement?: string }> }>, derived from low-confidence or unsupported parts of the output.
- `alreadyChecked?`: string, what passed automatic checks, e.g. "Amount matches invoice #2210, card ending 5521".
- `resolved`: Record<string, { resolutionId: string; by: string }>, controlled.
- `onResolve(itemId: string, resolutionId: string)`: the parent applies any text change. The component never edits the output itself.
- `activeItemId?`: string and `onActivate(itemId: string | null)`, to highlight the matching phrase in the output.
- `action`: { label: string; onConfirm(): void }, e.g. "Send reply", enabled when all items are resolved.

### States it must render
- Open items: a header "2 things to check" and numbered items, each quoting the phrase ("3 to 5 business days"), the specific reason ("The card was issued in Canada; the source only covers US cards"), and resolution buttons; the action is disabled.
- Item active: the quoted phrase is highlighted in the output and the item is outlined.
- Item resolved: the item collapses to "Checked by you" or "Changed by you" and the phrase shows its new state in the output.
- All resolved: the header turns green "Ready to send" and the action enables.
- Nothing to check: a single green line with `alreadyChecked`, and the action enabled; no generic disclaimer.

### Interactions
- Clicking an item or hovering its phrase in the output calls `onActivate` to link the two.
- Each resolution button calls `onResolve`; "keep" resolutions are labelled as a claim of checking, e.g. "I checked, keep it".
- Arrow keys move between items; the next unresolved item gets focus after one is resolved.

### Edge cases
- More than 5 items means the output is not "mostly right": show a notice suggesting a full review instead of a long checklist.
- The parent regenerates the output: items whose quote no longer appears are dropped, and new ones appear unresolved.
- Two items on overlapping text: highlight each separately and resolve independently.
- A resolution that changes text creates new uncertainty: the parent may add a new item, which appears unresolved.

## Must avoid
A generic "AI can make mistakes" footer that shifts responsibility without directing attention.

## Engineering constraint
Derive the check list from low-confidence fields, not from a static template.

## Accessibility
- Each item is linked to its phrase with `aria-describedby`; the phrase is focusable and announces "needs checking".
- Announce the remaining count after each resolution and when the action becomes available.

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