# Interactive Transcript

## Objective

Put the transcript next to the player so clicking any line jumps playback to that moment.

A time-aligned transcript panel beside the audio or video player, with click-to-seek, a moving highlight, and in-transcript search.

## Before You Begin

This feature is being added to an application that already exists and already
works. Do not scaffold a new project, and do not assume a blank slate.

Inspect the codebase first and establish:

- The existing application structure and where code of this kind already lives.
- The framework and version in use.
- The existing design system — colours, spacing, typography, and component conventions.
- Existing UI components you can reuse instead of writing new ones.
- The existing database structure, if this feature needs to persist anything.
- The existing authentication and authorization system, if this feature is user-scoped.
- Dependencies already installed, so you don't add a library that duplicates one.
- The existing test setup and conventions.

Only start writing code once you understand the above. If the application
already implements part of this feature, extend it rather than replacing it.

## Implementation Instructions

1. Render the transcript from the timestamps the app already stores. If Voice Transcription exists, extend its output and its data model rather than producing a second transcript with its own timings.
2. Make every line a real seek target: clicking or pressing enter on a line moves playback to that time and keeps focus where the user left it.
3. Highlight the line currently being spoken and keep it in view as playback advances, using the player's own time updates rather than a separate timer.
4. Add a search box over the transcript that lists matches and jumps playback to any of them. Reuse the app's existing search match highlighting so results look the same as everywhere else.
5. Do not render thousands of lines into the page at once. Virtualise the list, and make sure seeking to a far-off match still works when the target line has not been rendered yet.

## UI and UX Requirements

Match the application's existing design system exactly. Reuse its components,
spacing, and typography. This feature should look like it was always there.

## Responsive Requirements

Works on mobile, tablet, and desktop. Touch targets are large enough to hit on a
phone, and nothing overflows horizontally at 320px.

## Accessibility Requirements

- Fully keyboard navigable.
- Correct semantic elements and ARIA roles.
- Visible focus states.
- Meets WCAG AA contrast.
- Dynamic changes are announced to screen readers.
- Respects prefers-reduced-motion.

## Edge Cases

- Auto-scrolling the active line into view fights a user who is scrolling by hand. Suspend follow mode as soon as they scroll away, and offer a visible control to jump back to the current position.
- A transcript of several thousand lines will stall the page if every line is mounted and every line re-renders on each time update. Virtualise, and update only the lines whose highlight state actually changed.
- In-transcript search must show how many matches there are and let the user step between them, jumping playback to each. A search that only dims non-matching text is not enough on a long recording.
- Changing playback speed must not drift the highlight. Derive the active line from the player's reported current time, never from an interval that assumes real-time playback.
- On a narrow screen the side-by-side layout has to stack, with the player pinned so it stays visible while the user scrolls the transcript. A transcript that scrolls the player off the top is unusable.
- Lines with missing or overlapping timestamps must still render as text and simply not be clickable, rather than seeking to zero.
- Seeking must survive the media not being loaded yet: queue the seek and apply it once the player is ready.
- The transcript must remain selectable and copyable as plain continuous text, including across the boundaries of virtualised lines.

## Testing

Exercise the feature end to end in the running application. Cover every edge case
above, then run the existing test suite and confirm nothing regressed.

## Acceptance Criteria

- [ ] Clicking or keyboard-activating any line seeks playback to that moment.
- [ ] The active line is highlighted and follows playback, and manual scrolling suspends follow until the user returns.
- [ ] A transcript of several thousand lines scrolls and highlights without visible lag.
- [ ] In-transcript search reports match counts and jumps playback to each match.
- [ ] The highlight stays correct at every supported playback rate.
- [ ] The layout stacks on narrow screens with the player still visible.
- [ ] Transcript text can be selected and copied as continuous prose.
- [ ] The feature matches the existing design system.
- [ ] No existing functionality is broken.

## Adaptation Rules

- Match the existing design system. Do not introduce a new colour palette,
  spacing scale, or component library.
- Reuse existing components and utilities wherever they fit.
- Follow the naming, file layout, and code style already present.
- Do not upgrade, replace, or remove existing dependencies to make this
  feature fit. Adapt the feature to the app, not the app to the feature.
- Do not break existing functionality. If a change is genuinely required in
  existing code, make the smallest one that works and say so.
- If something in these instructions conflicts with how the application is
  built, follow the application and explain the deviation.

## Final Verification

Before you report the work as done:

1. Re-read the acceptance criteria above and check each one against what you
   actually built.
2. Run the application and exercise the feature end to end.
3. Run the existing test suite and confirm you have broken nothing.
4. Check the feature on mobile, tablet, and desktop widths.
5. Check keyboard navigation and focus handling.
6. Summarize what changed: files added, files modified, and anything you
   deliberately did differently because of how this application is built.

If any acceptance criterion is unmet, fix it before reporting completion.
