Add installable PWA (Option A — iPhone-first, no service worker)

Make the app installable to the iOS home screen and launch standalone
(full-screen, no browser chrome, dark status bar). Add manifest.webmanifest,
square app icons (ten31-app-icon.svg -> 192/512/apple-touch-icon), the
apple-mobile-web-app + manifest <head> tags, viewport-fit=cover, and a
pre-auth /manifest.webmanifest route. No service worker by design.
This commit is contained in:
Keysat
2026-06-20 08:42:29 -05:00
parent 81ed6cbbab
commit 0490910687
10 changed files with 78 additions and 5 deletions
+4 -3
View File
@@ -107,11 +107,12 @@ Subsystem rules live in `docs/guides/` and lazy-load in Claude Code via `.claude
## Current state
_**Box live at v0.1.0:94**; `main` ahead by mobile Phases 07 + P3b + drag-reorder + **8a8i — Phase 8 complete** — **all deploy-pending** (no s9pk built). **The fundraising grid + email capture is the canonical system of record.** Active thread: **mobile-first redesign — feature-complete; next is deploy + real-phone device-test** (nothing verified on a real phone yet). Build reference: `design/phase8-conformance.md` (the 8a8i spec; now fully landed — archive-eligible). **Plan (Grant, 2026-06-19): finish features first → then Grant device-tests + deploys.** History: git log + `start9/0.4/startos/versions/`._
_**Box live at v0.1.0:94**; `main` ahead by mobile Phases 07 + P3b + drag-reorder + **8a8i — Phase 8 complete** + **installable PWA (Option A)** — **all deploy-pending** (no s9pk built). **The fundraising grid + email capture is the canonical system of record.** Active thread: **mobile-first redesign — feature-complete; next is deploy + real-phone device-test** (nothing verified on a real phone yet). Build reference: `design/phase8-conformance.md` (the 8a8i spec; now fully landed — archive-eligible). **Plan (Grant, 2026-06-19): finish features first → then Grant device-tests + deploys.** History: git log + `start9/0.4/startos/versions/`._
- **Mobile redesign — 4 core surfaces built (Grid · Contacts · Pipeline · Reminders), each a rules-of-hooks-safe `useIsMobile()``Mobile*`/`Desktop*` pair (desktop untouched).** Foundation: bottom-tab bar + `:root` mobile vars; 4-stage enum; derived grid signals injected-on-GET/stripped-on-write at both points; mobile writes use **one-row endpoints only** (log-communication, pipeline link/stage, reminders, `update-row`) — never whole-grid PUT.
- **Phase 8 done (8a8i — complete)** — cards/details/sheets/shell re-authored to the dc anatomy. The durable per-primitive record is the **Design convention's primitives list**; per-phase "what changed" is in git log. Recent: **8h** Grid-detail loose ends (G4 tappable stage card, G5 dedicated Reminder card, Open-in-Grid deep-link on all three detail surfaces); **8i** shell — `BottomTabIcon` SVG line-icons replace the bottom-tab emoji glyphs + the `·Ten31·` `.mobile-wordmark` in the top bar (page title now `desktop-only`); the dc top bar's quick-log/theme/account cluster already existed. jsdom-verified (throwaway 375px harness).
- **Live (deployed):** W2 NL query (v94); W1 reminders (v93); grid Pipeline (v88); Matrix intake + Gmail capture (DWD) + daily digest; Thesis/Architect (dual-approval); outreach — all draft-only.
- **Tests:** **40/40 backend green** (`python3 backend/run_tests.py`), `py_compile` clean. Mobile surfaces interaction-verified via throwaway 375px jsdom harnesses (deleted after); harness recipe + the `Simulate.change` input gotcha live in the `mobile-surface-verification` memory.
- **Next — feature-complete; deploy + device-test:** Phase 8 is fully landed (8i closed S1/S2; **Pipeline accordion skipped** per Grant). Remaining is **deploy P0P8 + P3b in one s9pk** (**authorize + version-bump first**, per `docs/guides/packaging.md`) and **device-test light/dark on a real phone** — nothing mobile has run on a real device yet (smoke/jsdom only).
- **Open / risks:** all mobile work + light theme **built but never deployed or device-tested** (smoke/jsdom only); `MobileDetailRow` unused-but-retained (legacy-usage sweep); Pipeline detail "Committed" tile shows grid-committed not deal-expected (forecast in a footnote); `handle_get_opportunity` (single-opp GET) deliberately does NOT inject `existing_investor`/`last_contact_date` — no surface needs it (the card uses the list injection; the detail derives `existing` from the contact fetch); W2 happy-path only; **Claude/Architect path unverified live on the box**; v2.0 reserve-asset spine **not canonical**; doc drift — `crm-overview.md`/`EVALUATION.md` still call `lp_profiles` live.
- **Installable PWA — BUILT 2026-06-20 (Option A, iPhone-first, no service worker):** `frontend/manifest.webmanifest` (standalone, `theme_color` `#0b1118`) + square icons (`ten31-app-icon.svg``icon-192`/`icon-512`/`apple-touch-icon`) + `<head>` manifest/`apple-mobile-web-app-*`/`viewport-fit=cover` metas + one pre-auth `/manifest.webmanifest` route (`application/manifest+json`). Adds to home screen → full-screen standalone, dark status bar. No SW by design (iOS A2HS needs none; avoids the stale-shell class). render-smoke + live-curl verified. Detail in `ROADMAP.md` "Mobile PWA". **Deploy:** rides the same s9pk.
- **Next — feature-complete; deploy + device-test:** Phase 8 is fully landed (8i closed S1/S2; **Pipeline accordion skipped** per Grant) + the installable PWA. Remaining is **deploy P0P8 + P3b + PWA in one s9pk** (**authorize + version-bump first**, per `docs/guides/packaging.md`) and **device-test light/dark on a real phone** (incl. installing to the iOS home screen + standalone launch) — nothing mobile has run on a real device yet (smoke/jsdom only).
- **Open / risks:** all mobile work + light theme **built but never deployed or device-tested** (smoke/jsdom only); `MobileDetailRow` unused-but-retained (legacy-usage sweep); Pipeline detail "Committed" tile shows grid-committed not deal-expected (forecast in a footnote); `handle_get_opportunity` (single-opp GET) deliberately does NOT inject `existing_investor`/`last_contact_date` — no surface needs it (the card uses the list injection; the detail derives `existing` from the contact fetch); W2 happy-path only; **Claude/Architect path unverified live on the box**; v2.0 reserve-asset spine **not canonical**; doc drift — `crm-overview.md`/`EVALUATION.md` still call `lp_profiles` live; **PWA iOS status bar is fixed `black` at launch** (`apple-mobile-web-app-status-bar-style`) — in *light* theme it's a black strip above the light header (proper fix = `black-translucent` + header top-safe-area padding + theme-synced `theme-color`; deferred, validate on-device; dark is default so low-priority); PWA manifest/icons sent with no `Cache-Control` (consistent with all static routes — a manifest change post-install may be served stale by iOS until it re-fetches).