# AI Capture Ratio Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Change the non-mobile AI capture composer to a `70 / 30` text-to-attachments split, stack attachment previews one per row, and render example prompts as a masonry-style cluster. **Architecture:** Keep the page-level AI capture placement unchanged and make the entire change inside `AIToolbar`. Lock the new layout with source-based tests in `tests/ai-toolbar.test.ts`, then make the smallest JSX/class updates needed in `src/components/ai-toolbar.tsx` to satisfy them. **Tech Stack:** Bun test runner, Next.js, React, TypeScript, Tailwind utility classes, Biome, `useIsMobile` --- ### Task 1: Lock the `70 / 30` Desktop Composer Contract **Files:** - Modify: `tests/ai-toolbar.test.ts` - Test: `tests/ai-toolbar.test.ts` - [ ] **Step 1: Write the failing test** Replace the current non-mobile composer assertion so it expects a `70 / 30` split instead of equal-width columns. ```ts test("desktop composer uses a 70 / 30 row when the page gives it full-width space", () => { const source = readToolbarSource(); expect(source).toContain("isMobile"); expect(source).toContain('? "grid gap-3"'); expect(source).toContain( ': "grid gap-3 grid-cols-[minmax(0,0.7fr)_minmax(0,0.3fr)]"', ); }); ``` - [ ] **Step 2: Run test to verify it fails** Run: `bun test tests/ai-toolbar.test.ts` Expected: FAIL because `src/components/ai-toolbar.tsx` still contains the equal-width non-mobile grid. - [ ] **Step 3: Write minimal implementation** Update the non-mobile composer grid in `src/components/ai-toolbar.tsx`. Change this branch: ```ts : "grid gap-3 grid-cols-[minmax(0,1fr)_minmax(0,1fr)]" ``` To: ```ts : "grid gap-3 grid-cols-[minmax(0,0.7fr)_minmax(0,0.3fr)]" ``` - [ ] **Step 4: Run test to verify it passes** Run: `bun test tests/ai-toolbar.test.ts` Expected: PASS for the updated desktop composer test. - [ ] **Step 5: Commit** ```bash git add tests/ai-toolbar.test.ts src/components/ai-toolbar.tsx git commit -m "refactor(ai-toolbar): use 70-30 desktop composer split" ``` ### Task 2: Lock One-Preview-Per-Row Attachments **Files:** - Modify: `tests/ai-toolbar.test.ts` - Modify: `src/components/ai-toolbar.tsx` - Test: `tests/ai-toolbar.test.ts` - [ ] **Step 1: Write the failing test** Add a test that rejects the old desktop `grid-cols-2` preview layout and expects a row-stacked preview container. ```ts test("attachment previews stack one per row instead of using a two-column desktop grid", () => { const source = readToolbarSource(); expect(source).not.toContain('"mt-3 grid gap-2 grid-cols-2"'); expect(source).toContain('"mt-3 grid gap-2"'); }); ``` - [ ] **Step 2: Run test to verify it fails** Run: `bun test tests/ai-toolbar.test.ts` Expected: FAIL because the preview container still uses the desktop `grid-cols-2` branch. - [ ] **Step 3: Write minimal implementation** Simplify the preview container in `src/components/ai-toolbar.tsx` so it uses one shared stacked grid for all widths. Replace: ```ts className={ isMobile ? "mt-3 grid gap-2" : "mt-3 grid gap-2 grid-cols-2" } ``` With: ```ts className="mt-3 grid gap-2" ``` Keep each preview card as-is so the image and remove button behavior do not change. - [ ] **Step 4: Run test to verify it passes** Run: `bun test tests/ai-toolbar.test.ts` Expected: PASS for the stacked-preview contract. - [ ] **Step 5: Commit** ```bash git add tests/ai-toolbar.test.ts src/components/ai-toolbar.tsx git commit -m "refactor(ai-toolbar): stack attachment previews by row" ``` ### Task 3: Lock Masonry-Style Example Prompts **Files:** - Modify: `tests/ai-toolbar.test.ts` - Modify: `src/components/ai-toolbar.tsx` - Test: `tests/ai-toolbar.test.ts` - [ ] **Step 1: Write the failing test** Add a test that locks the example prompt area to a clustered layout instead of a flat single-row strip. ```ts test("example prompts use a masonry-style cluster inside the composer footer", () => { const source = readToolbarSource(); expect(source).toContain("Try:"); expect(source).toContain("columns-2"); expect(source).toContain("break-inside-avoid"); expect(source).toContain("w-full text-left"); }); ``` - [ ] **Step 2: Run test to verify it fails** Run: `bun test tests/ai-toolbar.test.ts` Expected: FAIL because the current prompt chips still live in a flat wrapped flex row. - [ ] **Step 3: Write minimal implementation** Refactor only the example prompt block in `src/components/ai-toolbar.tsx`. Use this structure: ```tsx