# Video Trimmer

## Objective

Let someone set a start and end point on an uploaded video and save the trimmed clip.

A trim step on uploaded video, with a scrubbable timeline, in and out handles, and server-side processing of the result.

## 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. Build the trim on top of the app's existing upload path. Size and type limits stay enforced server-side, and if Upload Malware Scanning exists the source file is scanned before any processing job is queued.
2. Keep the interface to what the customer needs: a preview, a scrubbable timeline with thumbnails, draggable in and out handles, and numeric time fields for precision. Multi-clip editing and transitions are a different product and should be deferred.
3. Do the trimming on the server as a background job and report its state through the app's existing job progress surface rather than a bespoke spinner.
4. Keep the source video after trimming, under the app's normal retention and access rules, so a bad cut can be redone without asking the customer to upload again.
5. Do not treat trim points as free-form. Either snap the cut to a keyframe or re-encode the affected segment, because cutting mid-frame produces a clip that opens on a frozen or grey first second.

## 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 cut placed between keyframes gives a clip that starts frozen. Snap to the nearest keyframe and tell the user where the cut actually landed, or re-encode so the requested point is exact.
- Encoding a long video takes minutes, not seconds. Show real progress, let the user cancel, and make cancellation stop the job rather than just hiding the dialog.
- Source video arrives vertical, rotated by metadata, or with a variable frame rate. Read the rotation and honour it, and normalise frame rate rather than producing a clip whose audio drifts out of sync.
- Captions belong to the original timeline. Shift and clip existing caption tracks to the new range, or regenerate them through the app's existing transcription feature if one is present. Leaving the old track attached puts the wrong words on screen.
- A job that fails halfway leaves partial output and temporary files behind. Clean them up on failure and on cancellation, and never leave a half-encoded file where a finished one is expected.
- The customer must not be able to overwrite a clip that something else is already using. Save the trim as a new asset or version, and be explicit about which one existing embeds point at.
- A file the encoder cannot read must fail with a plain explanation of what is unsupported, not a stuck job that sits at zero percent forever.
- The player needs a reserved aspect ratio and a poster frame so the page does not jump when the video loads, and controls that work from the keyboard.

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

- [ ] A user can set in and out points on the timeline and by typing exact times, and preview the result before saving.
- [ ] Trimming runs as a background job with visible progress and working cancellation.
- [ ] Cut points land on keyframes or are re-encoded, and the saved clip opens on a real frame.
- [ ] Rotated, vertical and variable-frame-rate sources produce correctly oriented clips with audio in sync.
- [ ] Captions are shifted to the new timeline or regenerated, never left misaligned.
- [ ] The source file is retained and the trim is saved as a new asset or version.
- [ ] Failed and cancelled jobs leave no partial files behind.
- [ ] 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.
