Files
GearBox/.planning/phases/35-bug-fixes/35-03-PLAN.md

10 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
35-bug-fixes 03 execute 1
src/client/components/ItemCard.tsx
src/client/components/FabMenu.tsx
src/client/components/BottomTabBar.tsx
true
FIX-05
truths artifacts key_links
ItemCard outer button shows cursor-pointer when linkTo is not null
ItemCard outer button shows cursor-default when linkTo === null (existing correct behavior, preserved)
FabMenu menu item buttons explicitly have cursor-pointer
FabMenu main FAB button explicitly has cursor-pointer
BottomTabBar anonymous tab buttons have cursor-pointer
path provides contains
src/client/components/ItemCard.tsx ItemCard with correct conditional cursor cursor-pointer
path provides contains
src/client/components/FabMenu.tsx FabMenu buttons with explicit cursor-pointer cursor-pointer
path provides contains
src/client/components/BottomTabBar.tsx BottomTabBar buttons with cursor-pointer cursor-pointer
from to via pattern
ItemCard outer button cursor-pointer class linkTo !== null conditional class cursor-pointer.*hover:border-gray-200
Audit and fix cursor-pointer coverage across interactive elements. The Tailwind utility cursor-pointer must be explicitly applied to all clickable elements that currently lack it.

Purpose: Resolve FIX-05 — the pointer cursor must appear on hover over every interactive element to meet basic UX expectations. Output: Updated ItemCard, FabMenu, BottomTabBar with explicit cursor-pointer.

<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/phases/35-bug-fixes/35-CONTEXT.md @.planning/phases/35-bug-fixes/35-UI-SPEC.md

Current cursor state by component (from codebase audit):

ItemCard (src/client/components/ItemCard.tsx, line 76):

// Current — missing cursor-pointer in the navigable case:
className={`relative w-full text-left bg-white rounded-xl border border-gray-100 transition-all overflow-hidden group ${
  linkTo === null
    ? "cursor-default"
    : "hover:border-gray-200 hover:shadow-sm"   // ← cursor-pointer MISSING here
}`}
// Target — add cursor-pointer to the navigable case:
className={`relative w-full text-left bg-white rounded-xl border border-gray-100 transition-all overflow-hidden group ${
  linkTo === null
    ? "cursor-default"
    : "cursor-pointer hover:border-gray-200 hover:shadow-sm"
}`}

ItemCard action span buttons (lines 106, 138, 170): already have cursor-pointer — DO NOT CHANGE. ClassificationBadge: already has cursor-pointer — DO NOT CHANGE. CandidateCard action spans: already have cursor-pointer — DO NOT CHANGE.

FabMenu (src/client/components/FabMenu.tsx):

  • Line 85: menu item motion.button className — "flex items-center gap-3 bg-white shadow-lg rounded-full px-4 py-3 hover:bg-gray-50 transition-colors" — missing cursor-pointer
  • Line 108: main FAB motion.button className — "fixed bottom-6 right-6 z-20 w-14 h-14 bg-gray-700 hover:bg-gray-800 text-white rounded-full shadow-lg hover:shadow-xl transition-colors flex items-center justify-center" — missing cursor-pointer

BottomTabBar (src/client/components/BottomTabBar.tsx):

  • Lines 68, 87, 97: <button type="button"> wrappers — no explicit cursor-pointer class
  • Link elements (lines 50, 60, 79): Links get pointer from browser default — add cursor-pointer explicitly for consistency

Already correct (no changes needed):

  • StatusBadge: has cursor-pointer
  • CategoryPicker: has cursor-pointer
  • PublicSetupCard: has cursor-pointer
  • CategoryFilterDropdown: has cursor-pointer
  • CatalogSearchOverlay interactive items: has cursor-pointer where needed
  • ImageUpload: has cursor-pointer
  • ProfileSection avatar: has cursor-pointer
Task 1: Add cursor-pointer to ItemCard navigable case (FIX-05) src/client/components/ItemCard.tsx - src/client/components/ItemCard.tsx (read the outer button element at line 73-77 to confirm the current conditional class string) In src/client/components/ItemCard.tsx, update the outer `` element's className conditional string (per D-11, D-12, UI-SPEC Cursor Contract).

Find the className on the outer button (line ~76):

className={`relative w-full text-left bg-white rounded-xl border border-gray-100 transition-all overflow-hidden group ${linkTo === null ? "cursor-default" : "hover:border-gray-200 hover:shadow-sm"}`}

Change to:

className={`relative w-full text-left bg-white rounded-xl border border-gray-100 transition-all overflow-hidden group ${linkTo === null ? "cursor-default" : "cursor-pointer hover:border-gray-200 hover:shadow-sm"}`}

The only change is adding cursor-pointer before hover:border-gray-200 in the non-null branch.

Do NOT change:

  • The cursor-default branch (correct behavior when linkTo === null)
  • Any action span buttons on the card (lines 106, 138, 170 — already have cursor-pointer) cd /home/jlmak/Projects/jlmak/GearBox && grep -n "cursor-pointer hover:border-gray-200" src/client/components/ItemCard.tsx <acceptance_criteria>
    • grep -n "cursor-pointer hover:border-gray-200" src/client/components/ItemCard.tsx returns exactly one match on the outer button className
    • grep -n "cursor-default" src/client/components/ItemCard.tsx still returns one match (the linkTo === null branch is preserved)
    • bun run lint passes with no errors </acceptance_criteria> ItemCard outer button shows cursor-pointer when linkTo is not null, and cursor-default when linkTo === null. Both branches are correctly covered.
Task 2: Add cursor-pointer to FabMenu and BottomTabBar buttons (FIX-05) src/client/components/FabMenu.tsx, src/client/components/BottomTabBar.tsx - src/client/components/FabMenu.tsx (read fully — locate motion.button at lines 82-99 and 106-114) - src/client/components/BottomTabBar.tsx (read fully — locate button elements at lines 68, 87, 97) **FabMenu changes** (per D-12, UI-SPEC Cursor Contract §FAB menu items):
  1. Menu item buttons (motion.button, currently line ~85) — add cursor-pointer to className: Current: "flex items-center gap-3 bg-white shadow-lg rounded-full px-4 py-3 hover:bg-gray-50 transition-colors" Target: "flex items-center gap-3 bg-white shadow-lg rounded-full px-4 py-3 hover:bg-gray-50 transition-colors cursor-pointer"

  2. Main FAB button (motion.button, currently line ~108) — add cursor-pointer to className: Current: "fixed bottom-6 right-6 z-20 w-14 h-14 bg-gray-700 hover:bg-gray-800 text-white rounded-full shadow-lg hover:shadow-xl transition-colors flex items-center justify-center" Target: "fixed bottom-6 right-6 z-20 w-14 h-14 bg-gray-700 hover:bg-gray-800 text-white rounded-full shadow-lg hover:shadow-xl transition-colors flex items-center justify-center cursor-pointer"

BottomTabBar changes (per D-12, UI-SPEC Cursor Contract §All role="button" elements):

For all three <button type="button"> elements (anonymous user collection tab at line ~68, anonymous setups tab at ~87, search tab at ~97), add cursor-pointer to each button element:

Line ~68:

<button type="button" onClick={openAuthPrompt} className="cursor-pointer">

Line ~87:

<button type="button" onClick={openAuthPrompt} className="cursor-pointer">

Line ~97:

<button type="button" onClick={() => openCatalogSearch("collection")} className="cursor-pointer">
cd /home/jlmak/Projects/jlmak/GearBox && grep -c "cursor-pointer" src/client/components/FabMenu.tsx src/client/components/BottomTabBar.tsx - `grep -c "cursor-pointer" src/client/components/FabMenu.tsx` outputs `2` (menu items button + main FAB button) - `grep -c "cursor-pointer" src/client/components/BottomTabBar.tsx` outputs `3` (one per anonymous button) - `bun run lint` passes with no errors across both files FabMenu menu item buttons and main FAB button have explicit cursor-pointer. BottomTabBar's three button elements each have cursor-pointer. All known interactive elements now have correct cursor behavior.

<threat_model>

Trust Boundaries

Boundary Description
none Pure CSS/class changes — no trust boundary implications

STRIDE Threat Register

Threat ID Category Component Disposition Mitigation Plan
T-35-04 none cursor-pointer audit accept CSS-only change. No logic, data flow, or auth boundary touched. No threat surface.
</threat_model>
After both tasks complete:
  1. Open collection overview — hover over an item card (with linkTo set): cursor must be pointer
  2. Hover over a card in a setup (linkTo === null): cursor must be default (not pointer) — preserved
  3. Open FAB menu — hover over menu items and FAB button: cursor must be pointer
  4. On mobile viewport (or DevTools mobile mode), hover/tap BottomTabBar anonymous tabs: buttons must show pointer

Run: bun run lint — zero errors Run: bun test — all existing tests pass

<success_criteria>

  • ItemCard outer button has cursor-pointer in the non-null linkTo branch, cursor-default in the null branch
  • FabMenu has cursor-pointer on both motion.button elements (menu items + FAB)
  • BottomTabBar has cursor-pointer on all three button elements
  • No previously-correct cursor-pointer usage is removed
  • bun run lint passes with zero errors </success_criteria>
After completion, create `.planning/phases/35-bug-fixes/35-03-SUMMARY.md`