OPEN PANEL — Mobile App Spec (`SPEC_MOBILE.md`)
OPEN PANEL — Mobile App Spec (SPEC_MOBILE.md)
Section titled “OPEN PANEL — Mobile App Spec (SPEC_MOBILE.md)”Surface spec for the OPEN PANEL mobile client. Subordinate to
CANON.md(esp. §3 §4 §6). Stack is locked by canon: React Native (Expo), shared@openpanel/readerengine, Supabase + Rust (axum) backend, Cloudflare R2 + CDN, CPF media format. Status: DRAFT v0.1 — 2026-06-13. Not legal advice; IAP/store-policy items flagged for counsel.
1. Goals & role of mobile
Section titled “1. Goals & role of mobile”Mobile is the daily-reading and offline-download surface — the widest-audience client in the OPEN PANEL fleet. Where the Web app optimizes for reach/SEO and Desktop for the “collector’s library”, mobile optimizes for read-it-on-the-couch / read-it-on-the-train.
Primary jobs:
- Read free STANDARD ISSUES comfortably on a phone (page view + guided view).
- Download for offline — the headline differentiator vs. the PWA; trains, planes, low-data.
- Re-engage readers via push when a followed series/creator ships a new issue.
- Stay one identity — same account as Web/Desktop (reader context; buyer context for VARIANT).
Non-goals (v1): creator tooling (Desktop hosts that), the VARIANT licensing portal, and any admin/moderation surface. Mobile is a reader + light commerce client only.
Success = a free, fast, accessible reader that works with no signal and brings people back.
2. Platforms, OS targets, build & update strategy
Section titled “2. Platforms, OS targets, build & update strategy”- iOS (iPhone primary; iPad supported, not optimized in v1) — min iOS 16.
- Android (phones primary; tablets supported) — min API 26 / Android 8.0.
- Expo (managed) + EAS for build & submit. One TypeScript codebase;
@openpanel/readerconsumed as a workspace package shared with Web/Desktop. - EAS Build produces store binaries (App Store / Play). EAS Submit automates upload.
- OTA updates via EAS Update for JS/asset-only changes (reader tweaks, copy, bugfixes):
staged rollout, channel per release track (
production,beta,dev). Native changes (new permissions, SDK bumps) still require a store submission — OTA never ships native code. - Update policy: OTA is opt-out-safe (atomic, rollback to last-known-good on launch crash). Pin a minimum-supported-build gate from backend config → force-upgrade prompt when a build is below the floor (used for CPF-version or API-contract breaks).
- Crash/quality: Sentry (or equivalent) wired through Expo; no third-party ad SDKs (canon §4).
3. Screen inventory & navigation
Section titled “3. Screen inventory & navigation”Bottom tab bar (4 tabs) + a full-screen reader modal presented over any tab.
| Tab | Purpose | Key elements |
|---|---|---|
| Discover | Browse the free catalog | Featured, new STANDARD ISSUES, followed-series feed, genres, staff picks |
| Library | The reader’s shelf | Continue-reading, followed series, Downloads manager, finished |
| Search | Find anything | Postgres-FTS-backed query; filters: genre, creator, rating, locale |
| Account | Identity & settings | Profile, entitlements, reading prefs, downloads/storage, notifications, age gate, legal |
- Reader modal — opened from any cover/continue card; immersive, not a tab. Owns its own gesture surface and dismiss-to-shelf affordance.
- Series / Issue detail — pushed screens: synopsis, credits, rating, issue list, follow, download, “read”, and (where applicable) a VARIANT-edition upsell link (see §8).
- Navigation: React Navigation — native-stack within tabs, modal stack for reader. Deep links
(
openpanel://series/:id,…/issue/:id) drive push-notification and share-link routing.
4. The mobile reader
Section titled “4. The mobile reader”Built on @openpanel/reader; mobile supplies the gesture + native-perf shell. Consumes CPF
(pages, panels, guided-view regions & order, alt-text, locale, rating) per canon §6.
Two reading modes (toggle persists per reader, default = guided on phones):
- Page view — one (portrait) or two-up (landscape) full pages.
- Guided view — panel-by-panel pan/zoom along the authored reading path from CPF.
Gesture model:
- Swipe L/R — next/previous (page in page view; next panel/page along guided path in guided view). Respects locale reading direction (LTR / RTL manga) from CPF metadata.
- Pinch — free zoom; pan with one finger while zoomed.
- Double-tap — in guided view, snap-zoom to the tapped panel; in page view, toggle fit↔fill.
- Single tap (center) — toggle immersive mode (chrome on/off). Tap edges = page turn (a11y fallback).
- Long-press a panel — surface panel alt-text + share/report actions.
- Swipe-down from top — dismiss reader back to shelf (progress saved).
Display & comfort:
- Portrait & landscape both supported; orientation lock available in reader settings.
- Immersive mode — hides status/nav chrome; system gesture-edge protection on.
- Brightness — in-reader brightness slider (app-scoped, restores on exit) + system “night” tint; optional auto-dim. Honors OS dark mode for all chrome.
- Resume — exact page and guided-panel index persisted; resumes mid-issue across devices (synced via backend) and offline (local first, reconciled on reconnect).
- Pre-render next 1–2 pages/panels for instant turns; release far pages (see §9 memory).
5. Offline downloads
Section titled “5. Offline downloads”The flagship mobile capability. Free STANDARD ISSUES download with minimal/no DRM (canon §4).
- Download manager (Library → Downloads): per-issue and download-whole-series; queue with pause/resume/retry; Wi-Fi-only toggle (default on); shows size before committing.
- Storage budget — user-set cap (e.g. 1/2/5/10 GB or “no limit”); live usage meter; LRU eviction of finished/least-recently-read issues when near cap (with confirm); per-issue “keep”.
- CPF caching — store the CPF manifest + page/tiled image assets fetched from R2/CDN in app sandbox storage; integrity-checked; quality tier chosen by device class (see §9).
- Progress sync — reading position written locally first; queued and synced to backend on reconnect; last-write-wins with timestamp, conflicts resolved toward furthest-read.
- Expiry for licensed content — STANDARD ISSUES are perpetual (no expiry). Any licensed/ premium (VARIANT) or time-limited content carries an entitlement TTL: cached with an expiry stamp, periodic online re-check, content locked (not silently deleted) when entitlement lapses, with a clear “renew/restore” path. Entitlement checks per canon §6 (not hard DRM).
6. Push notifications
Section titled “6. Push notifications”- Trigger: new issue from a followed series or creator; optional weekly “new this week”. Backend fan-out → Expo Push (APNs/FCM under the hood). Payload deep-links into issue detail.
- Consent: explicit OS permission prompt deferred to a contextual moment (first follow), never on cold start. Granular in-app toggles per category (new-issue / digest / account).
- COPPA: push disabled by default for accounts flagged under-13 (age gate, §10); no behavioral/marketing pushes to minors — transactional/new-content only, parent-gated.
- Quiet hours + per-series mute respected. No third-party push analytics SDKs.
7. Auth & entitlements
Section titled “7. Auth & entitlements”- One identity via Supabase Auth (email + OAuth providers); same account across surfaces (reader vs. buyer context, not separate logins) per canon §4/§6.
- Free access is always granted — STANDARD ISSUES need no entitlement; a logged-out guest can read & download free content, with an account prompt to sync progress and follow.
- Premium/VARIANT entitlements fetched via the Identity & Entitlements contract (canon §6); cached for offline with TTL (§5). Entitlement checks, not DRM.
8. In-app purchase consideration (VARIANT editions) — POLICY FLAG
Section titled “8. In-app purchase consideration (VARIANT editions) — POLICY FLAG”Decision flagged for operator + counsel. Store policy materially shapes what mobile can sell.
- Physical merch / collectibles = real-world goods → may be sold via external commerce (Stripe), outside Apple/Google IAP. Mobile can browse/deep-link to the VARIANT store for these.
- Digital VARIANT editions (premium digital comics, digital collectibles) = digital goods → Apple App Store and Google Play generally require IAP for in-app purchase/unlock of digital content, taking the ~30% commission (lower tiers/small-business rates may apply). “Reader”-app carve-outs and external-link-entitlement programs exist but are conditional and shifting — must be validated against current store rules before relying on them.
- v1 stance: mobile does not sell digital VARIANT editions in-app. It (a) sells nothing digital that would trigger IAP, (b) surfaces physical-merch via external commerce where policy allows, and (c) lets users consume premium entitlements they already own (purchased on Web). Revisit IAP only with an explicit margin decision (30% fee) and a current store-policy review.
9. Accessibility, i18n, performance
Section titled “9. Accessibility, i18n, performance”Accessibility:
- Dynamic Type — all chrome/text scales with OS font-size setting.
- Screen reader (VoiceOver / TalkBack) — every control labeled; per-panel alt-text from CPF read in authored reading order in guided view (the core a11y win for comics).
- Dyslexia-friendly mode — opt-in font + spacing for all app text (canon §3).
- Reduce-motion honored (disable page-turn animations); minimum tap targets; sufficient contrast; edge-tap navigation as a non-gesture fallback.
i18n:
- App UI localized; reader renders the locale-appropriate CPF (translated pages/alt-text) when available; reading direction (LTR/RTL) driven by CPF metadata. Locale picker in Account.
Performance (low-end devices):
- Image memory management — never hold the full issue in memory; window of 1–2 pages/panels pre-rendered, the rest released; downscale/tile large pages by device class; bitmap reuse; aggressive recycling on memory-warning.
- Quality tiers — fetch a CDN tier appropriate to screen DPI + connection; upgrade on Wi-Fi.
- Cold-start budget and smooth 60fps page turns on a representative low-end Android device are acceptance gates (§11). Lazy-load tabs; virtualized catalog lists.
10. Analytics, privacy & store compliance
Section titled “10. Analytics, privacy & store compliance”- Analytics — privacy-respecting event pipeline only (canon §4/§6 Event contract); no third-party
ad trackers. Core events:
issue_open,page_turn,guided_panel_advance,issue_complete,download_start/complete/evict,follow,search,push_open. Aggregated, pseudonymous. - Privacy / COPPA — comics skew young (canon §7.7). Age gate at account creation; under-13 accounts get a COPPA-compliant minimal-data mode: no behavioral analytics, no marketing push, no public profile, parent-gated where required. GDPR/CCPA data-export & delete honored. App Tracking Transparency (iOS): we do not track across apps → no ATT prompt needed by design.
- Content ratings — store-listing age rating set from catalog rating ceiling; per-issue ratings from CPF surfaced on detail screens; mature content gated behind age/account checks.
- Store compliance — privacy nutrition labels (Apple) + Data Safety form (Google) kept accurate; account-deletion path in-app (Apple requirement); no hidden/undisclosed data collection.
11. Acceptance criteria (MVP)
Section titled “11. Acceptance criteria (MVP)”- Read free comics offline — install, browse Discover, download a STANDARD ISSUE (whole series queueable), go airplane-mode, open and read it end to end in both page and guided view.
- Guided view works — swipe advances along the authored CPF path; double-tap snap-zooms a panel; RTL titles read correctly.
- Resume & sync — close mid-issue, reopen → exact page+panel restored; reconnect → progress reflected on Web/Desktop (and vice-versa).
- Storage budget enforced — cap respected; LRU eviction with confirm; usage meter accurate.
- Push — follow a series, backend publishes a new issue → device receives push → tap deep-links to that issue. Disabled by default for under-13 accounts.
- One identity — same account across surfaces; logged-out guest can read/download free content and is prompted to sign in to sync.
- No IAP-triggering digital sale in v1 — app ships no in-app digital purchase; physical-merch links route to external commerce only.
- Accessibility — VoiceOver/TalkBack reads per-panel alt-text in order; Dynamic Type + dyslexia mode apply app-wide; reduce-motion honored.
- Performance — smooth page turns and bounded memory (no OOM on a representative low-end Android) reading a large issue; cold start within budget.
- Builds & ships — EAS Build produces signed iOS + Android binaries; EAS Update delivers an
OTA JS fix to the
productionchannel with working rollback; min-build gate enforces force-upgrade. - Compliance — accurate Apple privacy labels + Google Data Safety; in-app account deletion; age gate present; no third-party ad/track SDKs.