# Build the "Synthetic media disclosure" pattern: `SyntheticMediaBadge`

## 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
Layered disclosure on generated media: visible mark, embedded watermark, signed metadata.

Use it when: Image, video and voice generation, especially anything depicting real people or events.

## What to build
A disclosure overlay for generated images, video or audio that shows all three layers (visible label, signed metadata and embedded watermark) and which ones survived the file's journey. Opening it explains what each layer confirms. It renders on the media in viewers, upload previews and moderation tools.

### Props
- `media`: { kind: "image" | "video" | "audio"; description: string }, what the asset is.
- `layers`: { visibleLabel: "present" | "missing"; metadata: { status: "intact" | "stripped" | "invalid"; generator?: string; createdAt?: Date; edits?: string[] }; watermark: { status: "detected" | "not-detected" | "not-checked"; provider?: string; confidence?: "high" | "medium" | "low" } }, verification results from the intake check.
- `depictsRealPerson?`: boolean, raises emphasis on the disclosure.
- `placement`: "overlay" | "below", where the visible label renders; use "below" for audio.
- `open`: boolean and `onOpenChange(open)`.
- `onShowWatermark?()`: reveal where the watermark sits, if the detector supports it. The component never embeds or detects anything itself.

### States it must render
- All layers intact: a visible "AI-generated" label; the panel says "Confirmed by all 3 layers" with generator and date.
- Label lost (cropped): the panel notes "Visible label missing" while metadata and watermark still confirm.
- Metadata stripped (re-encoded or screenshotted): "Metadata removed"; the watermark alone confirms, with its confidence.
- Only watermark, low confidence: "Possibly AI-generated" with the confidence stated, not a definitive claim.
- No signal: "No AI signals found", with a note that this does not prove the media is authentic.

### Interactions
- Clicking the label opens the panel; the overall verdict is re-rendered as a visible label even when the original corner mark was lost.
- Each layer row expands to show what it records (generator, edits, provider).
- "Show where the watermark is" calls `onShowWatermark`.

### Edge cases
- Layers disagree (metadata says edited, watermark not detected): list both results; never pick one silently.
- Audio: the visible label renders as text by the player and is read before playback controls.
- Media depicting a real person: the label is always shown, never collapsed to an icon.
- Watermark "not-checked": say so, rather than implying it was absent.

## Must avoid
Relying on a corner watermark that a crop removes, with no durable signal underneath.

## Engineering constraint
Provenance is rich but fragile, watermarks sparse but durable — ship both, verify at intake.

## Accessibility
- The verdict is part of the media's accessible description, e.g. "AI-generated image, confirmed by watermark".
- Layer rows use text status ("present", "missing") alongside icons.

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