# Audiolog episode creator — smoke test

No automated tests exist for this tool, so this manual checklist is the
regression guard during the refactor. Run it (served, e.g. `npm start` or
`netlify dev` — not `file://`, the tool needs a server) after each phase and
confirm behaviour is unchanged from the previous phase.

## Core flow

1. **Load** — open the tool; no console errors; page is styled (design-system palette).
2. **API key** — paste an OpenAI key; "✓ Saved" appears; reload → key persists (localStorage).
3. **Upload** — drag a folder (or click) containing audio (`.m4a/.mp3/.wav`) + images + metadata; clips appear; clip count updates.
4. **Clip list** — each card shows the **cropped** thumbnail (matching the editor crop), the title/date, and metadata rows (link / source / description / speakers) with missing fields shown muted; names, dates render; drag to reorder; up/down move buttons work; delete (×) removes a clip.
5. **Select clip** — click a clip → editor populates; waveform draws.
6. **Playback** — play/pause; playhead animates; clicking the waveform seeks.
7. **Trim** — drag start/end markers; type times into the trim inputs; trimmed duration updates; "apply trim" preview is correct.
8. **Metadata** — edit title + link + source + description; values persist across clip switches and reload (link/source live in their own `audioLogLinks` / `audioLogSources` localStorage keys).
9. **Thumbnail / crop** — image loads; crop box + sliders adjust; preview updates; reset works; the clip card thumbnail tracks the crop. **Replace screenshot** — click "Replace screenshot" (or drag an image onto the crop area) swaps the source image and resets the crop; a clip with no image shows a dropzone + "Upload screenshot" that adds one.
10. **Transcript** — generate transcript (needs API key); speaker-name mapping applies; formatted output is correct.
11. **Cover art** — TLDraw editor mounts (no console errors); export PNG/JSON works.
12. **Export** — "Generate podcast" builds the zip; downloaded zip contains trimmed audio, images, metadata/YAML, transcript. `episode.yaml` must parse with a strict YAML parser — every chapter key (title/startTime/…/source) sits at the same 4-space column, with `speakers`/`transcript` nested under it.
13. **MP3 chapters** — export as MP3 and inspect the episode file: each clip is a chapter at the right time with its title, link and image. Verify with `ffprobe -i episode-N.mp3 -show_chapters` (or open in Overcast/Forecast). The `episode.yaml` chapters carry a `url:` line for clips with a link, and a `source:` line for clips with a source.
14. **MP3 cover poster** — if cover art was generated, the exported MP3 carries it as the file-level front-cover image (the per-chapter images are kept too). `ffprobe episode-N.mp3` shows an attached-pic video stream; the ZIP still includes `cover-art.png` separately. Both the embedded poster and the ZIP's `cover-art.png` are capped at 1500px (aspect ratio preserved, never upscaled). The `episode.yaml` `thumbnail:` is set to `cover-art.png` when cover art exists, otherwise falls back to the first chapter image.

## Theming

- Toggle OS appearance (or set `data-theme` on `<html>`): light and dark both render correctly, including the **waveform canvas** background/strokes and form inputs.

## Notes

- Persisted state lives in `localStorage` (`openaiApiKey`, saved descriptions/links/titles/trim/crop/transcripts/etc.). Clearing it resets the tool.
- After file splits, also confirm the Network tab shows each module/stylesheet loading with 200 and no MIME/CORS errors.
