--- phase: 31-mobile-polish plan: 01 type: execute wave: 1 depends_on: [] files_modified: - src/client/routes/items/$itemId.tsx - src/client/routes/threads/$threadId/candidates/$candidateId.tsx autonomous: true requirements: [D-01, D-02, D-03, D-04] must_haves: truths: - Item detail shows icon-only action buttons below md breakpoint - Item detail shows text action buttons at md and above - Candidate detail shows icon-only action buttons below md breakpoint - Candidate detail shows text action buttons at md and above - All icon-only buttons have aria-label attributes - All icon-only buttons have minimum 44px touch targets artifacts: - src/client/routes/items/$itemId.tsx (modified) - src/client/routes/threads/$threadId/candidates/$candidateId.tsx (modified) key_links: - LucideIcon component used for all icons (not inline SVGs) - md: breakpoint matches BottomTabBar responsive pattern --- Add responsive icon-based action buttons to item detail and candidate detail pages. Purpose: Replace text-label action buttons with icon-only buttons on mobile viewports (below md: breakpoint) for better mobile UX. Desktop retains full text buttons. Output: Modified item detail and candidate detail pages with responsive action buttons. @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/31-mobile-polish/31-CONTEXT.md @.planning/phases/31-mobile-polish/31-UI-SPEC.md @src/client/components/BottomTabBar.tsx @src/client/lib/iconData.tsx From src/client/lib/iconData.tsx: ```typescript export function LucideIcon({ name, size, className, strokeWidth }: { name: string; size?: number; className?: string; strokeWidth?: number; }): React.ReactElement; ``` From src/client/components/BottomTabBar.tsx: ``` // Responsive breakpoint reference: md:hidden (mobile), hidden md:flex (desktop) ``` Task 1: Add responsive icon buttons to item detail page src/client/routes/items/$itemId.tsx - src/client/routes/items/$itemId.tsx (current action button implementation, lines ~189-213) - src/client/components/BottomTabBar.tsx (responsive breakpoint pattern reference) - src/client/lib/iconData.tsx (LucideIcon component API) - .planning/phases/31-mobile-polish/31-UI-SPEC.md (icon mapping and color contract) In src/client/routes/items/$itemId.tsx, modify the action button group (the `div` with `flex items-center gap-2` containing Duplicate, Delete, and Edit buttons, visible when `!isEditing`). For each button, create a paired desktop/mobile pattern: **Duplicate button:** - Desktop (hidden on mobile): `` - Mobile (hidden on desktop): `` **Delete/Remove button:** - Desktop: `` - Mobile: `` **Edit button:** - Desktop: `` - Mobile: `` Ensure LucideIcon is already imported (it is — check line ~8). Keep all existing onClick handlers and disabled states. The Cancel/Save buttons in edit mode remain unchanged (text buttons on all viewports). Per D-01: Apply icon-based action buttons on mobile to item detail page. Per D-02: Desktop keeps text buttons, mobile switches to icons at md: breakpoint. Per D-03: Standard icon mapping — pencil for Edit, trash-2 for Delete, copy for Duplicate. - `$itemId.tsx` contains `aria-label="Duplicate"` on an icon button - `$itemId.tsx` contains `aria-label="Edit"` on an icon button with `md:hidden` class - `$itemId.tsx` contains ` grep -c "aria-label" src/client/routes/items/\$itemId.tsx | grep -q "[3-9]" && grep -c "md:hidden" src/client/routes/items/\$itemId.tsx | grep -q "[3-9]" && echo "PASS" || echo "FAIL" Item detail page shows icon-only Duplicate/Delete/Edit buttons on mobile, full text buttons on desktop. All icon buttons have aria-label and 44px minimum touch targets. Task 2: Add responsive icon buttons to candidate detail page src/client/routes/threads/$threadId/candidates/$candidateId.tsx - src/client/routes/threads/$threadId/candidates/$candidateId.tsx (current action buttons — header Edit at line ~282, bottom actions at lines ~530-548) - .planning/phases/31-mobile-polish/31-UI-SPEC.md (icon mapping and color contract) In src/client/routes/threads/$threadId/candidates/$candidateId.tsx, modify action buttons in two locations: **Location 1: Header Edit button (line ~282-289)** Currently shows `` + "Edit" text. Split into: - Desktop: `` - Mobile: `` **Location 2: Bottom action buttons (lines ~530-548)** Currently shows "Pick as winner" with trophy icon and "Delete" with trash-2 icon. Split each: **Pick as Winner:** - Desktop: `` - Mobile: `` **Delete:** - Desktop: `` - Mobile: `` Keep all existing onClick handlers. The edit mode buttons (Cancel, Save) remain unchanged. Per D-01: Apply to candidate detail page. Per D-02: Desktop text, mobile icons at md: breakpoint. Per D-03: Standard icon mapping — pencil for Edit, trash-2 for Delete, trophy for Pick as winner. - `$candidateId.tsx` contains `aria-label="Edit"` on an icon button with `md:hidden` - `$candidateId.tsx` contains `aria-label="Pick as winner"` on an icon button - `$candidateId.tsx` contains `aria-label="Delete"` on an icon button - `$candidateId.tsx` contains `min-w-[44px]` for touch target sizing (at least 3 occurrences) - `$candidateId.tsx` contains `hidden md:inline-flex` on desktop text buttons (at least 3 occurrences) - Edit mode Cancel/Save buttons do NOT have responsive splitting grep -c "aria-label" src/client/routes/threads/\$threadId/candidates/\$candidateId.tsx | grep -q "[3-9]" && grep -c "md:hidden" src/client/routes/threads/\$threadId/candidates/\$candidateId.tsx | grep -q "[3-9]" && echo "PASS" || echo "FAIL" Candidate detail page shows icon-only Edit/Pick as winner/Delete buttons on mobile, full text+icon buttons on desktop. All icon buttons have aria-label and 44px minimum touch targets. ## Trust Boundaries No new trust boundaries introduced. This plan only modifies client-side rendering of existing buttons. No new API calls, no new data flows, no new authentication paths. ## STRIDE Threat Register | Threat ID | Category | Component | Disposition | Mitigation Plan | |-----------|----------|-----------|-------------|-----------------| | T-31-01 | Information Disclosure | Icon buttons | accept | Icon buttons show same actions as existing text buttons — no new information exposed. aria-label text matches existing button text. | - `bun run lint` passes with no errors in modified files - `bun test` passes (no test regressions) - Manual: Open item detail at mobile viewport (< 768px) — see icon-only buttons - Manual: Open item detail at desktop viewport (>= 768px) — see text buttons - Manual: Open candidate detail at mobile viewport — see icon-only buttons - Item detail page renders icon-only Duplicate/Delete/Edit buttons on mobile - Candidate detail page renders icon-only Edit/Pick as winner/Delete buttons on mobile - Desktop rendering unchanged (text buttons with optional icons) - All icon buttons have aria-label for accessibility - All icon buttons have min-w-[44px] min-h-[44px] for comfortable touch targets - md: breakpoint used consistently (matching BottomTabBar pattern) After completion, create `.planning/phases/31-mobile-polish/31-01-SUMMARY.md`