# Live Captions

## Objective

Show captions during a live call or stream, close enough to real time to follow.

A real-time caption track over live audio, with interim text that settles as recognition corrects itself and a saved transcript at the end.

## 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. Stream audio to recognition continuously and render text as it arrives, in two visual tiers: settled text that will not change, and interim text that still might.
2. Set an explicit latency budget and hold to it. If recognition falls behind, discard the oldest pending audio and carry on rather than showing captions that lag the speaker by half a minute.
3. Give viewers control over caption size, position, background opacity, and contrast, and persist that choice using the app's existing per-user preference storage.
4. When the session ends, write the settled text to the app's existing transcript record so the recording and the transcript stay together. Do not create a separate captions-only artefact.
5. Do not present live captions as an accessibility guarantee. State that they are automatic and may be wrong, and keep any existing path to a human captioner or a corrected transcript.

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

- End-to-end latency must be bounded. When recognition or the network cannot keep pace, drop the backlog and resume at the live edge, because captions that are minutes behind are worse than a visible gap.
- Interim text will be rewritten as recognition revises it. Replace the interim tier in place so words settle smoothly, rather than deleting and reprinting whole lines in a way that makes the caption area flicker.
- The caption connection will drop on a network blip. Reconnect automatically, resume at the current live position rather than replaying, and show the viewer that captions are reconnecting instead of leaving a frozen last line.
- Viewers need size, position, and contrast controls, because default captions land over faces, slides, or the stream's own lower third for someone on a small screen.
- When the stream ends, the accumulated settled text must be saved as a transcript, including for a session that ended by disconnection rather than a clean stop.
- Captions must not cover the player controls or any on-screen text the stream is presenting, and must reflow rather than overflow when the window is narrow.
- Silence, music, and background noise must produce nothing at all rather than hallucinated words. An empty caption area is honest; invented text is not.
- A live stream may be public. Apply the app's existing content moderation to what is displayed, and give the host a way to turn captions off mid-session.

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

- [ ] Captions appear during a live session within a stated latency budget.
- [ ] Interim text is visually distinct from settled text and is revised in place.
- [ ] A dropped caption connection reconnects at the live edge and shows its state to the viewer.
- [ ] Viewers can change caption size, position, and contrast, and the choice persists.
- [ ] The settled text is saved to the existing transcript record when the session ends, including on an unclean end.
- [ ] Captions never obscure player controls and reflow on narrow screens.
- [ ] Silence produces no caption text.
- [ ] 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.
