# Build the "Reasoning trace" pattern: `ReasoningTrace`

## 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
An expandable record of steps, tool calls and intermediate findings behind the answer.

Use it when: Complex multi-step work, and debugging surfaces for power users and engineers.

## What to build
A collapsible, structured record of the steps behind an answer: plans, queries, searches, reads, skipped steps and findings, each as a typed event with a one-line result. It opens as a summary (time, sources, steps skipped) and lets a person drill into any single step's raw detail. It renders under an AI answer or in a debugging panel.

### Props
- `events`: Array<{ id: string; kind: "plan" | "query" | "search" | "read" | "tool" | "skip" | "finding" | "error"; title: string; result: string; durationMs?: number; detail?: React.ReactNode }>, typed events from the run, not free-form text.
- `summary`: { durationLabel: string; sourceCount: number; skippedCount: number }, e.g. "Worked for 14s, 3 sources, 1 step skipped".
- `expanded`: boolean and `onExpandedChange(v: boolean)`, controlled visibility of the step list.
- `openEventId?`: string and `onOpenEvent(id: string | null)`, which step's detail is open.
- `status`: "running" | "done" | "error".
- `filterKinds?`: Array<string>, to show only certain kinds, e.g. only skipped and errors.

### States it must render
- Collapsed: one line under the answer with the summary and "Show 6 steps"; skipped or error counts are in amber or red text.
- Expanded: an ordered list where each event shows a kind label ("Query", "Read", "Skipped"), title and one-line result, e.g. "23 accounts, 19 had fewer than 50 seats".
- Step open: the selected event shows its detail (the query, a table, a quoted passage) below its row.
- Skipped step: marked distinctly with why, e.g. "CRM isn't connected, so sales-side reasons weren't checked", and how that limits the answer.
- Running: events append as they arrive with "Working" in the summary line.
- Error: the failing event is marked and its message shown; earlier events remain.

### Interactions
- The summary line toggles `expanded`; clicking an event row toggles its detail via `onOpenEvent`.
- Arrow keys move between event rows; Enter opens detail.
- A "Show only gaps" control filters to skipped and error events.

### Edge cases
- Never show raw chain-of-thought as the default: free-text narration, if present, lives inside a step's detail, not as the trace itself.
- Very long traces (more than 20 events): group consecutive events of the same kind ("Read 8 documents") with expand.
- Large detail payloads (big tables, long SQL): render on demand when opened, and cap height with internal scrolling.
- No skipped steps: say "Nothing skipped" so absence is explicit.

## Must avoid
Dumping raw chain-of-thought as proof of rigour; long traces read as persuasive, not diagnostic.

## Engineering constraint
Structure the trace as events with types so the UI can summarise and let users drill in.

## Accessibility
- The toggle has `aria-expanded` and controls the list; each event row is a button with `aria-expanded` for its detail.
- Event kind is part of each row's accessible name, e.g. "Skipped: Sales call notes".

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