Product app UI
When to update: App shell, navigation, shared components, breakpoints, or accent usage changes.
Purpose
Section titled “Purpose”Both product SPAs (apps/personal-web, apps/business-web) share a common UI foundation in packages/ui. The goal is a calm, Apple-like experience: clear hierarchy, grouped content, predictable navigation, and layouts optimized for mobile and desktop.
Shared package (packages/ui)
Section titled “Shared package (packages/ui)”| Export | Role |
|---|---|
tokens.css | CSS variables — surfaces, accents, spacing, radii, motion |
AppShell | Page frame: sidebar (desktop), header + bottom nav (mobile) |
SidebarNav / BottomNav | React Router NavLink navigation |
PageHeader | Title, description, optional actions |
Card, Button, EmptyState, Spinner | Core primitives |
Apps import components from @keepintracks/ui and bridge tokens in src/styles/global.css via Tailwind @theme inline. tokens.css includes @source so Tailwind scans shared component classes in the monorepo.
Product accents
Section titled “Product accents”| App | Accent token | Use |
|---|---|---|
| Personal | --color-personal | Nav active state, primary buttons, empty-state icons |
| Business | --color-business | Same pattern for business plane |
Do not mix accents across apps.
Responsive layout
Section titled “Responsive layout”| Breakpoint | Navigation | Content |
|---|---|---|
< md (mobile) | Fixed bottom tab bar + compact top header | Full width, bottom padding for safe area |
≥ md (desktop) | Fixed left sidebar (~15rem) | Centered column, max ~48rem |
Navigation items are defined per app in src/nav.ts.
Page structure
Section titled “Page structure”Every route should follow:
PageHeader— title, one-line description, optional primary CTA- Primary content — cards, lists, or
EmptyStatewith a single obvious next step - Forms — open via header CTA, FAB, or empty-state button (not as a permanent top section)
API calls from the SPA
Section titled “API calls from the SPA”Production builds use VITE_API_URL (see DEPLOYMENT.md). Local dev uses Vite proxy for /health.
Key paths
Section titled “Key paths”| App | Layout | Routes (foundation) |
|---|---|---|
| Personal | src/layouts/AppLayout.tsx | /, /activity, /journal, /settings |
| Business | src/layouts/AppLayout.tsx | /, /employees, /schedule, /invoices, /settings |
SPA routing on Pages
Section titled “SPA routing on Pages”Each app includes public/_redirects:
/* /index.html 200Required for client-side routes after deploy.
Related
Section titled “Related”- ARCHITECTURE.md — Frontend section
- DEPLOYMENT.md — Pages env vars (
VITE_API_URL)