# 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
<div className="columns-2 gap-2">
	{examplePrompts.map((prompt) => (
		<Button
			key={prompt}
			type="button"
			variant="secondary"
			size="sm"
			className="mb-2 h-auto w-full break-inside-avoid whitespace-normal rounded-2xl px-3 py-2 text-left text-[11px]"
			onClick={() => onAiTemplateSelect(prompt)}
			disabled={aiLoading || !canUseAi}
		>
			{prompt}
		</Button>
	))}
</div>
```

Keep the surrounding footer copy and disabled behavior intact. Do not add new helper components.

- [ ] **Step 4: Run test to verify it passes**

Run: `bun test tests/ai-toolbar.test.ts`

Expected: PASS for the prompt-cluster contract.

- [ ] **Step 5: Commit**

```bash
git add tests/ai-toolbar.test.ts src/components/ai-toolbar.tsx
git commit -m "refactor(ai-toolbar): cluster example prompts in masonry layout"
```

### Task 4: Full Verification

**Files:**
- Test: `tests/ai-toolbar.test.ts`
- Test: `tests/home-page-layout.test.ts`
- Verify: `src/components/ai-toolbar.tsx`

- [ ] **Step 1: Run targeted layout tests**

Run: `bun test tests/ai-toolbar.test.ts tests/home-page-layout.test.ts`

Expected: PASS with the AI toolbar and page layout contracts still green.

- [ ] **Step 2: Run the full test suite**

Run: `bun test`

Expected: PASS with no new failures.

- [ ] **Step 3: Run typecheck**

Run: `bun run type:check`

Expected: PASS.

- [ ] **Step 4: Run lint**

Run: `bun run lint`

Expected: PASS, with only the pre-existing `src/lib/compose-refs.ts` warning if it still appears.

- [ ] **Step 5: Commit**

If Task 4 introduced no code changes, skip a commit here. If a tiny verification-driven tweak was required, commit only that tweak:

```bash
git add src/components/ai-toolbar.tsx tests/ai-toolbar.test.ts
git commit -m "test(ai-toolbar): verify desktop composer layout contracts"
```
