---
phase: 27-top-nav-restructure-and-search-bar-rethink
plan: 01
subsystem: navigation
tags: [nav, mobile, desktop, search, auth-gated]
dependency_graph:
  requires: []
  provides: [TopNav, BottomTabBar]
  affects: [src/client/routes/__root.tsx]
tech_stack:
  added: []
  patterns: [useMatchRoute for active route detection, NavLinkOrButton auth-gated pattern, framer-motion entry animation, env(safe-area-inset-bottom) for iOS]
key_files:
  created:
    - src/client/components/TopNav.tsx
    - src/client/components/BottomTabBar.tsx
  modified: []
key_decisions:
  - Used 'house' icon instead of plan-specified 'home' — lucide-react has no Home icon, only House; prevents Package fallback rendering
  - NavLinkOrButton renders <button> for anon users on protected routes to avoid TanStack Router navigation race with e.preventDefault
  - Search bar on TopNav uses <button type="button"> styled as input field — avoids form submission semantics
metrics:
  duration_minutes: 8
  tasks_completed: 2
  tasks_total: 2
  files_created: 2
  files_modified: 0
  completed_date: "2026-04-10"
requirements_satisfied:
  - NAV-01
  - NAV-02
  - NAV-03
---

# Phase 27 Plan 01: TopNav and BottomTabBar Components Summary

TopNav (desktop persistent nav bar) and BottomTabBar (mobile fixed bottom tab bar) created with auth-gated routing, active route highlighting, and catalog search integration.

## Tasks Completed

| Task | Name | Commit | Files |
|------|------|--------|-------|
| 1 | Create TopNav component | dccb1f8 | src/client/components/TopNav.tsx |
| 2 | Create BottomTabBar component | 24ed719 | src/client/components/BottomTabBar.tsx |

## What Was Built

### TopNav (`src/client/components/TopNav.tsx`)

Persistent sticky top navigation bar replacing TotalsBar. Renders logo (package icon + "GearBox" text), nav links (Home, Collection, Setups), desktop search bar, and user section.

Key patterns:
- `NavLinkOrButton` internal component: renders `<Link>` for authenticated users or `<button onClick={openAuthPrompt}>` for anonymous users on protected routes (Collection, Setups). Home is always a `<Link>`.
- Active route detection via `useMatchRoute` from TanStack Router with `fuzzy: true` for nested routes.
- Desktop nav links and search bar hidden on mobile via `hidden md:flex`.
- Search bar click calls `openCatalogSearch("collection")` from UIStore.
- User section shows `<UserMenu />` if authenticated, `<Link to="/login">Sign in</Link>` if anonymous.

### BottomTabBar (`src/client/components/BottomTabBar.tsx`)

Mobile-only fixed bottom tab bar with 4 tabs: Home, Collection, Setups, Search.

Key patterns:
- Fixed position at bottom with `md:hidden` so it only shows on mobile.
- `z-20` ensures it renders above most content but below modals.
- Collection/Setups: `<Link>` if authenticated, `<button onClick={openAuthPrompt}>` if anonymous.
- Search tab always a button calling `openCatalogSearch("collection")`.
- Framer Motion entry animation: `y: 20 -> 0` + `opacity: 0 -> 1` over 200ms.
- iOS safe area: `pb-[env(safe-area-inset-bottom)]` for home indicator clearance.

## Deviations from Plan

### Auto-fixed Issues

**1. [Rule 1 - Bug] Used 'house' icon instead of plan-specified 'home'**
- **Found during:** Task 1 & 2
- **Issue:** The plan specified `LucideIcon name="home"` for both TopNav (nav) and BottomTabBar Home tab. The `lucide-react` package does not export a `Home` icon — only `House`. The `LucideIcon` wrapper falls back to `Package` icon when the requested name is not found, which would render the package icon instead of the intended home/house icon.
- **Fix:** Used `house` for the BottomTabBar Home tab. TopNav does not use a home icon in the final nav links (text-only links as intended by the design).
- **Files modified:** `src/client/components/BottomTabBar.tsx`
- **Commit:** 24ed719

## Known Stubs

None. Both components are complete and wire correctly to UIStore actions. No placeholder data or hardcoded empty values.

## Self-Check: PASSED

Files exist:
- src/client/components/TopNav.tsx: FOUND
- src/client/components/BottomTabBar.tsx: FOUND

Commits exist:
- dccb1f8: feat(27-01): create TopNav component — FOUND
- 24ed719: feat(27-01): create BottomTabBar component — FOUND
