From 634fc4260f279e506a70ccf5d8c46f267b1b99e3 Mon Sep 17 00:00:00 2001 From: Keysat Date: Fri, 19 Jun 2026 13:15:53 -0500 Subject: [PATCH] Mobile foundation (Phase 1) + harden opportunity stage validation Phase 1 mobile foundation (additive, no desktop change): :root mobile vars, a 4-tab bottom nav bar + mobile account/logout popover wired into App, a bottom-sheet CSS primitive, and .mobile-only/.desktop-only utilities -- all display:none >=768px. The React component + useIsMobile() + the per-surface 15px type bump are deferred to Phase 2 (first use); light theme to Phase 6. Review hardening (fresh-eyes pass on the Phase 0+1 diff): validate stage in handle_create_opportunity + handle_update_opportunity against PIPELINE_STAGES -- the narrower 4-stage enum makes a stale-client write of a legacy value invisible to the report ORDER BY CASEs and unsettable from the UI. Use the canonical pipelineStageLabel in the opportunity detail select; document the intentional graveyard omission in the existing_investor / staleness helpers. Tests: stage-validation regression in test_grid_pipeline_link.py + empty source_row_id guard in test_pipeline_stages_v2.py; 36/36 green, render-smoke green. --- AGENTS.md | 8 +- ROADMAP.md | 21 +++- backend/server.py | 17 ++- backend/test_grid_pipeline_link.py | 10 ++ backend/test_pipeline_stages_v2.py | 6 +- frontend/index.html | 174 ++++++++++++++++++++++++++++- 6 files changed, 221 insertions(+), 15 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 1fb8032..7fcb6a8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -107,14 +107,14 @@ Subsystem rules live in `docs/guides/` and lazy-load in Claude Code via `.claude ## Current state -_Phase 0 + Phase 1 built; **box + repo live at v0.1.0:94** (`main` ahead by docs/design-only commits since). **The fundraising grid + email capture is the canonical system of record.** Active threads: **mobile-first redesign** (design DONE → scoped + **Phase 0 data layer BUILT 2026-06-19**, deploy pending; mobile foundation next) and **W2 NL query** (live; web "Ask" box outstanding). History: git log + `start9/0.4/startos/versions/`; backlog/debt: `ROADMAP.md` / `EVALUATION.md`._ +_Phase 0 + Phase 1 built; **box + repo live at v0.1.0:94** (`main` ahead by docs/design-only commits since). **The fundraising grid + email capture is the canonical system of record.** Active threads: **mobile-first redesign** (design DONE → scoped + **Phase 0 data layer + Phase 1 mobile foundation BUILT 2026-06-19**, deploy pending; Contacts surface next) and **W2 NL query** (live; web "Ask" box outstanding). History: git log + `start9/0.4/startos/versions/`; backlog/debt: `ROADMAP.md` / `EVALUATION.md`._ - **Mobile-first redesign — design phase COMPLETE; implementation not started.** This session ran the `/design` round-trip Phase C/D: distilled the Claude Design cloud output ("Venture-CRM mobile redesign") into the contract — `DESIGN.md` §8 (responsive) + §4 (mobile component states) + §3 (15px scale), tokens `mobile` group + `color.light`, provenance + per-surface interaction reference in `design/_imports/2026-06-19/`. **Light theme adopted as a planned, toggle-gated feature** (dark default). Comps are Claude Design **runtime prototypes** — re-author each surface in React against the real API, not drop-in. Process learnings pushed to `standards/guides/design.md`. -- **Mobile implementation — SCOPED 2026-06-19 (plan in `ROADMAP.md` "Mobile-first implementation").** Key finding: the inline-style→CSS "blocker" is **~114 inline styles across the 4 surfaces + shell** (Grid 70 / Reminders 18 / Contacts 17 / Pipeline 7 / shell 2), **not ~1,300** — the app is already majority class-based (1,861-line ` @@ -4387,7 +4520,7 @@ style={{ width: '100%' }} > {stages.map(s => ( - + ))} @@ -11198,6 +11331,7 @@ const App = () => { const { token, user, logout } = useAuth(); const [page, setPage] = useState('fundraising-grid'); + const [accountMenuOpen, setAccountMenuOpen] = useState(false); // mobile top-bar account popover const [toasts, setToasts] = useState([]); const [sidebarHidden, setSidebarHidden] = useState(false); const [gridViews, setGridViews] = useState(loadGridViews()); @@ -11466,9 +11600,23 @@ {page === 'settings' && 'Settings'} -
+
{user?.full_name || user?.username}{MOCK_MODE ? ' · Mock Mode' : ''}
+
+ + {accountMenuOpen && ( + <> +
setAccountMenuOpen(false)} /> +
+
{user?.full_name || user?.username}
+ +
+ + )} +
@@ -11533,6 +11681,28 @@ )}
)} + + {/* Mobile primary navigation — the four mobile surfaces. CSS-hidden on + desktop (.bottom-tab-bar display:none until <768px); the sidebar is the + desktop nav. Other destinations are intentionally absent on mobile. */} +
); };