diff --git a/docs/plans/2026-03-21-upload-inline-subtitle-style-design.md b/docs/plans/2026-03-21-upload-inline-subtitle-style-design.md new file mode 100644 index 0000000..5b6e5a2 --- /dev/null +++ b/docs/plans/2026-03-21-upload-inline-subtitle-style-design.md @@ -0,0 +1,61 @@ +# Upload Inline Subtitle Style Design + +**Goal:** Move the subtitle defaults UI into the lower-left area of the main "Upload & prepare" card so the top section remains a three-card layout while keeping subtitle controls visible in the same primary workspace. + +## Context + +The current three-card top row improves discoverability for upload, mode, and language selection, but the subtitle defaults controls still live as a separate card beneath them. That creates a visual break and makes the upload workbench feel split into a top decision row and a detached lower settings card. + +The user wants the subtitle defaults controls absorbed back into the main upload card, specifically in the lower-left portion of that card. + +## Approved Direction + +- keep the top row as three cards: + - upload and prepare + - mode and workflow + - language and dubbing +- remove the standalone subtitle defaults card +- place subtitle defaults inside the upload card's lower-left region + +## Recommended Layout + +Use a two-part upload card: + +- upper section: + - upload heading + - description + - drag/drop upload area +- lower section: + - left: embedded subtitle defaults module + - right: support text and mode chip + +This keeps the upload card self-contained while preserving the user's requested left-bottom placement. + +## Interaction Rules + +The embedded subtitle defaults module keeps all existing behavior: + +- preview sample remains live +- reset button still restores defaults +- position and size sliders still update preview +- upload contract and trim flow remain unchanged + +## Testing Strategy + +Update upload-screen tests to verify: + +- no standalone subtitle defaults card is required +- the subtitle defaults module is rendered inside the upload card +- existing subtitle preview behavior still works +- language and mode cards remain first-row peers + +## Out of Scope + +- backend changes +- language list changes +- editor redesign +- upload flow changes + +## Success Criteria + +Success means the upload page reads as one compact top workbench, with subtitle style controls clearly attached to the upload card instead of floating below it as a separate panel. diff --git a/docs/plans/2026-03-21-upload-inline-subtitle-style.md b/docs/plans/2026-03-21-upload-inline-subtitle-style.md new file mode 100644 index 0000000..a7c5b30 --- /dev/null +++ b/docs/plans/2026-03-21-upload-inline-subtitle-style.md @@ -0,0 +1,166 @@ +# Upload Inline Subtitle Style Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Embed the subtitle defaults controls into the lower-left area of the upload card while preserving the three-card top-row layout for upload, mode, and language. + +**Architecture:** Keep the existing upload page behavior and TTS/mode card layout, but remove the standalone subtitle defaults card. Move the preview and sliders into a compact embedded module inside `src/components/UploadScreen.tsx`, and update upload-screen tests to lock in the new structure. + +**Tech Stack:** React 19, TypeScript, Tailwind CSS v4 utilities, Vitest, React Testing Library + +--- + +### Task 1: Lock the embedded subtitle module with a failing test + +**Files:** +- Modify: `src/components/UploadScreen.test.tsx` +- Reference: `src/components/UploadScreen.tsx` + +**Step 1: Write the failing test** + +Add a structure test for the new placement: + +```tsx +it('renders subtitle defaults inside the upload card footer area', () => { + renderUploadScreen(); + + expect(screen.getByTestId('upload-dropzone-card')).toContainElement( + screen.getByTestId('upload-subtitle-defaults-panel'), + ); + expect(screen.queryByTestId('subtitle-defaults-card')).not.toBeInTheDocument(); +}); +``` + +**Step 2: Run test to verify it fails** + +Run: + +```bash +node ./node_modules/vitest/vitest.mjs run src/components/UploadScreen.test.tsx +``` + +Expected: FAIL because the subtitle defaults controls still render as a standalone card. + +**Step 3: Write minimal implementation** + +Add the new `data-testid` for the embedded subtitle module and remove the old standalone-card marker. + +**Step 4: Run test to verify it passes** + +Run: + +```bash +node ./node_modules/vitest/vitest.mjs run src/components/UploadScreen.test.tsx +``` + +Expected: PASS for the new inline-module assertion. + +**Step 5: Commit** + +```bash +git add src/components/UploadScreen.tsx src/components/UploadScreen.test.tsx +git commit -m "test: lock inline subtitle defaults layout" +``` + +### Task 2: Move subtitle defaults into the upload card + +**Files:** +- Modify: `src/components/UploadScreen.tsx` +- Modify: `src/components/UploadScreen.test.tsx` + +**Step 1: Write the failing test** + +Add a second focused regression test: + +```tsx +it('keeps subtitle preview controls active after moving them into the upload card', () => { + renderUploadScreen(); + + expect(screen.getByTestId('upload-subtitle-defaults-panel')).toContainElement( + screen.getByTestId('upload-subtitle-preview'), + ); +}); +``` + +**Step 2: Run test to verify it fails** + +Run: + +```bash +node ./node_modules/vitest/vitest.mjs run src/components/UploadScreen.test.tsx +``` + +Expected: FAIL until the subtitle module is actually moved. + +**Step 3: Write minimal implementation** + +Refactor `src/components/UploadScreen.tsx` to: + +- delete the standalone subtitle defaults card +- add a compact subtitle defaults module inside the upload card bottom-left region +- keep support text and mode chip in the upload card bottom-right region +- preserve preview and slider behavior exactly + +**Step 4: Run test to verify it passes** + +Run: + +```bash +node ./node_modules/vitest/vitest.mjs run src/components/UploadScreen.test.tsx +``` + +Expected: PASS for the new structure tests and existing subtitle interaction tests. + +**Step 5: Commit** + +```bash +git add src/components/UploadScreen.tsx src/components/UploadScreen.test.tsx +git commit -m "feat: embed subtitle defaults in upload card" +``` + +### Task 3: Full verification + +**Files:** +- Modify: `src/components/UploadScreen.tsx` +- Modify: `src/components/UploadScreen.test.tsx` + +**Step 1: Write the failing test** + +If any final regression appears after the move, add the smallest targeted test first. + +**Step 2: Run test to verify it fails** + +Run: + +```bash +node ./node_modules/vitest/vitest.mjs run src/components/UploadScreen.test.tsx src/App.test.tsx +``` + +Expected: FAIL only if a real regression remains. + +**Step 3: Write minimal implementation** + +Apply only the final layout polish needed for the regression. + +**Step 4: Run test to verify it passes** + +Run: + +```bash +npm.cmd test +npm.cmd run lint +npm.cmd run build +``` + +Expected: + +- all tests PASS +- typecheck PASS +- build PASS + +**Step 5: Commit** + +```bash +git add src/components/UploadScreen.tsx src/components/UploadScreen.test.tsx src/App.tsx src/App.test.tsx +git commit -m "test: verify inline subtitle defaults layout" +```