# Build the "AI visual language" pattern: `AiMarker`

## 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
A consistent color, icon and motion vocabulary that marks AI surfaces as distinct from deterministic ones.

Use it when: Products where AI features are woven through an existing interface.

## What to build
A small set of primitives (an inline marker, a surface wrapper and a legend) that apply the product's AI accent and icon only to things a model produced or is doing, and plain styling to rule-based automation. It enforces one documented rule for when the AI treatment applies. It renders across existing screens wherever AI and deterministic output sit side by side.

### Props
- `source`: "model" | "rule" | "person", required; only "model" receives the AI accent and icon, "rule" gets a neutral automation icon, "person" gets nothing.
- `variant`: "inline" | "surface" | "legend", the chip beside a value, the frame around a generated block, or the key that explains the marks.
- `state?`: "idle" | "working" | "done", for model surfaces only; "working" adds the AI motion cue.
- `label?`: string, accessible and tooltip text, e.g. "Written by AI" or "Set by rule: overdue > 30 days".
- `tokens?`: { accent: string; icon: ReactNode; motion: string }, the design tokens, so one definition drives every marker.
- `highlight?`: "model" | "rule" | null, set by the legend to light up every marker of one source on screen.
- `onHighlightChange?(source | null)`: callback from the legend.

### States it must render
- Model inline: AI icon plus accent tint on a small chip next to the value.
- Model surface: a block framed with the accent edge and a header label "Generated by AI".
- Model working: the same surface with a subtle motion cue (static under reduced motion) and "Writing".
- Rule: a neutral icon (e.g. a cog) with "Automatic" text, no accent and no AI icon.
- Legend: two keys ("Written by AI", "Set by a rule") that, when pressed, highlight the matching markers and dim the rest.

### Interactions
- Pressing a legend key calls `onHighlightChange`; pressing it again clears the highlight.
- Hovering or focusing a marker shows its `label` as a tooltip.
- Markers are not buttons unless they have an action; the legend keys are toggle buttons.

### Edge cases
- `source` omitted: a type error, not a default, so AI styling cannot be applied by accident.
- A rule that calls a model internally: pass "model"; the rule is about how the value was produced, not the feature name.
- Several AI blocks nested: only the outermost surface gets the frame; inner items use the inline marker.
- Buttons that trigger AI (e.g. "Summarise"): use the AI icon only on that action, never across a whole toolbar.

## Must avoid
Sparkles on every button until the signal is noise, or AI styling on features that are plain automation.

## Engineering constraint
Define the AI accent and icon set as design tokens with a documented rule for when they apply.

## Accessibility
- Every marker exposes its source in text (visually hidden if needed), e.g. "AI-written", so the distinction does not rely on colour or icon alone.
- Legend keys use `aria-pressed` and announce how many items are highlighted.

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