Mobile foundation & navigation
How the mobile app shell works.
The bottom tab bar
Four tabs, always visible on the list view of every section:
| Tab | What it shows | Active color |
|---|---|---|
| Pulse | Today's tasks, unanswered threads, booking calendar | plum |
| Inbox | All guest threads, with unread badge count | plum |
| Locks | All properties with smart-lock state | plum |
| AI | Pulse Copilot conversational assistant | plum |
The Inbox tab carries a badge with the count of unread / unanswered threads. The badge sources its number from the same query as the desktop Pulse "UNANSWERED" cluster — if you reply on desktop, the mobile badge drops.
Large-title headers
Each tab opens to a list with a large-title header on top. The title uses Source Serif 4 italic for accent words (the same display treatment as desktop Pulse).
The header is sticky: as you scroll, the title shrinks into a compact bar so you don't lose orientation.
Drill-in / detail views
Opening any list row (a thread in Inbox, a property in Locks) takes over the screen:
- The bottom tab bar hides so the detail view gets full vertical space.
- A back chevron
<appears top-left to return to the list. - The list scroll position is preserved — when you come back, you land on the same row.
The detail view manages its own internal scroll: the chat thread in Inbox, the tabbed panels in Locks. The outer page does not scroll.
Safe areas
The shell respects iOS / Android safe areas:
- 50 px reserved at the top for the status bar.
- The bottom tab bar adds
padding-bottomfor the home-indicator strip.
This means the tab bar sits above the home indicator on iPhones with no notch, and clears the camera cutout on Pixels.
Switching back to desktop
There is no in-app "switch to desktop" toggle — desktop and mobile are two views of the same data. To use desktop features (reports, task template editor, admin tools), open the same URL in a desktop browser. You stay logged in.
Implements: gh#105 (mobile foundation: app shell + tab nav + design system port).