# Resume Where You Left Off

## Objective

Offer returning viewers the chance to continue a video from where they stopped.

Per-viewer playback position tracking with a resume prompt and a start-over option on return.

## 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. Record the playback position against the viewer and the video, using the app's existing per-user preference or profile storage rather than a new parallel store. Fall back to device-local storage for signed-out visitors.
2. Offer the resume rather than performing it. Show where they stopped and let them continue or start from the beginning, with a clear default and a few seconds to choose.
3. Write progress on a throttle and on the meaningful moments: pause, seek, tab hidden, and page unload. Continuous writes during playback will hammer the server for no benefit.
4. Clear the stored position when the video finishes, so a rewatch starts at the beginning instead of at the credits.
5. Do not treat a position as a completion record. If the app reports watch completion for courses or analytics, keep that separate; a viewer who scrubs to the end has not watched the video.

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

- A position inside the first few seconds is not worth resuming, and a position inside the last few seconds should be treated as finished. Ignore both rather than prompting someone to resume at four seconds in.
- The same viewer on a phone and a laptop will produce two positions. Decide the reconciliation rule, prefer the most recently written one, and make sure a stale write from a device that was offline cannot overwrite a newer position.
- Once a video has been watched to the end, the saved position must be cleared, or every rewatch opens on a resume prompt for the final frame.
- Throttle progress writes so a playing video does not issue a request per second. Batch them, and coalesce anything queued while the connection is down.
- Never force the resume point. Some viewers deliberately restart, and a player that silently jumps them forward with no way back reads as a bug.
- If the video is replaced or re-encoded and its duration changes, discard positions recorded against the old version rather than seeking to a timestamp that no longer means anything.
- A signed-out visitor who later signs in should have their local position carried across once, not silently discarded and not allowed to overwrite a newer signed-in position.
- Saved positions are viewing history and need a retention rule and a way for the viewer to clear them.

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

- [ ] Returning viewers are offered a resume with a visible start-over option.
- [ ] Positions near the very start or very end are not offered as resume points.
- [ ] Finishing a video clears its stored position.
- [ ] Progress writes are throttled and also fire on pause, seek, and unload.
- [ ] Positions from multiple devices reconcile to the most recent write without stale overwrites.
- [ ] A replaced or re-encoded video discards positions from the previous version.
- [ ] Viewers can clear their saved positions, and a retention rule exists.
- [ ] 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.
