Mobile App · Surface walkthrough

Home (mobile shell — daypart anchor)

A per-surface walkthrough of the Mobile App mobile surface: layout, states, interactions, data, and cross-references.

drafted
8sections4 minread

On this page

Context. surface mobile · domain shell-routing · route / · auth anon (shell renders for guest; deep launches may gate per-domain) · source apps/oshun/mobile/app/(tabs)/index.tsx

Last walked. not yet walked

Purpose#

Home is the mobile shell's anchor tab: it greets by daypart, leads with the single strongest "return" thread, and offers companion bridges, capture/share intake, calendar sync, Iris hand-off, an Assistant entry, direct domain launches, recommendations, Tara favorites, the mocap studio entry, and a quick-actions tray. It is the (tabs)/index screen rendered inside the tab navigator (OSHUN header, no stack header).

Entry points#

  • Shell nav: the Home tab (shell-tab-home, accessibilityLabel "Home").
  • App cold start (deep-link hydration may land here via useDeepLinkHydration).
  • Return navigation from any pushed domain/mocap/v2/v3 screen.
  • Notification routing bridge can route here.

Layout regions#

  • Header: tab-navigator header titled OSHUN (dark #1f1a14); no back.
  • Hero / above-the-fold: home-daypart-hero — kicker "Daily rhythm", greeting + date, daypart title/body, "Current arc" card (with lead-continuity preview), primary + secondary action, meta chips, and a 3-card daypart rail.
  • Main (vertical ScrollView): sections — Tara quick starts, Return first (continuity), Iris hand-off, Companion bridges, Calendar sync, Capture intake, Share ingest, Active companion, Veritas briefing, Assistant entry, Direct launches (domain switcher + domain rail), Offline continuity, Daily footing, Recommendation carousel, Tara favorites, Capture studio (flagged), Quick actions entry (flagged).
  • Footer / sticky bottom: tab bar; QuickActionsTray bottom sheet (flagged).

States#

  • Loading<350ms shell bootstrap gated in _layout; screen returns empty <View testID="mobile-home-screen"> until currentPrimaryStep resolves. No skeleton on Home itself.
  • Empty — no continuity threads → "No live return journeys" empty card; no favorites → "No favorites yet" empty card.
  • Populated (short) — continuity cards prioritized by current daypart; one lead feature card + supporting lane.
  • Populated (long) — long ScrollView; horizontal favorites strip and recommendation carousel scroll independently.
  • Error (recoverable) — N/A: Home data is in-module fixtures, no fetch.
  • Error (unrecoverable) — caught by OshunErrorBoundary shell-wide.
  • OfflineGlobalOfflineBanner (shell) + ShellOfflineContinuityCard section render; pull-to-refresh still simulates a 900ms refresh.
  • Permissions-denied (camera/mic/photos)MobileCaptureIntakeCard shows per-permission prompt/denied state; handleStartCapture re-asks via grantMobileCapturePermission and warns when blocked.
  • Gated — Home renders for guests; domainSwitcher, quickActionsTray, mocapCaptureStudio flags hide their sections when false.
  • iOS vs Android — safe-area via tab bar height; tab bar 84pt iOS / 72pt Android ((tabs)/_layout). No screen-level inset handling on Home.

Interactions#

  • Pull-to-refresh (RefreshControl)
    • Function: handleRefresh — haptic, 900ms delay, resets lastRefreshedAt.
    • Gesture/touch: pull down at top of scroll.
    • Telemetry: triggerMobileFlowHaptic('home-refresh-start'/'-complete').
  • Daypart primary action (home-daypart-primary-action, Pressable)
    • Function: launchJourney(currentJourney)router.push(step.action.href).
    • Gesture/touch: tap; label = currentJourney.primaryAction.label.
  • Review continuity (home-daypart-secondary-action, Pressable)
    • Function: handleContinue → push to Activity tab.
  • Daypart rail card (home-daypart-card-<id>, Pressable ×3)
    • Function: launchJourney(journey) → push that journey's primary step href.
  • Tara ritual hero (DomainEntryHero, primary + secondary entries)
    • Function: launchHomeTaraRitual(entry) — sets current domain to tara, trackTaraCardTap, haptic, router.push(entry.href).
    • testID: home-tara-ritual-entry-<ritualId>.
  • E2E launch morning opening (button, only when E2E hooks enabled)
    • accessibilityLabel "Launch morning opening"; hint announced; testID home-tara-e2e-launch-morning-opening.
  • Lead continuity card (ContinuityCard feature, "Resume now")
    • Function: card's onPress → set current domain, telemetry, haptic, buildDomainRouteHref(domain, {originTab:'home', params:{path,ref}}).
  • Supporting continuity row (home-continuity-card-<id>, Pressable)
    • Function: same onPress; accessibilityRole button; accessibilityLabel joins eyebrow/title/summary/meta. Shows progress track when present.
  • Iris hand-off card (MobileIrisHandoffCard)
    • Resume → handleResumeIrisHandoff (push resolved route); Send back → handleSendIrisHandoffBack (push Assistant with hand-off token prompt).
  • Companion bridge row (home-companion-bridge-<id>, Pressable)
    • Function: launchJourneyStep(step) → set domain (if domain step), push href.
  • Calendar sync card (MobileCalendarSyncCard)
    • Sync now → Activity tab w/ filter=calendar-sync; Open item → domain route; Review inbound → Assistant w/ change-count prompt.
  • Capture intake card (MobileCaptureIntakeCard)
    • Request permission → grantMobileCapturePermission; Start capture → domain/assistant route when ready, else re-prompt/warn; Review redaction → Assistant route w/ redaction prompt.
  • Share ingest card (MobileShareIngestCard)
    • Open target → Library tab w/ share=open params.
  • Active companion card (MobileActiveCompanionCard)
    • Control press → handleActiveCompanionControl; open/next_step push domain route; complete/skip only fire haptics.
  • Veritas briefing section (VeritasBriefingHomeSection)
    • Featured/Claim → veritas domain route; Action → ask-assistant or veritas route per action.kind.
  • Assistant entry (AssistantEntryCard, mobile-home-assistant-entry)
    • Function: opens Assistant with homeAssistantPrompt.
  • Domain switcher entry (DomainSwitcherEntry, flagged on)
    • Change/Action → openDomain(value).
  • Domain launch row (home-domain-launch-<id>, Pressable ×N)
    • Function: openDomain(card.id); shows "Current focus"/"Planned preview" tag.
  • Recommendation carousel (RecommendationCarousel)
    • Item tap → launchRecommendation (per-domain card build + deep route); feedback hide/less/more → haptic only.
  • Favorite card (Pressable, horizontal strip)
    • Function: launchFavorite → Tara deep route + trackTaraCardTap.
  • Capture studio card (mocapCaptureStudio flag) → handleOpenMocapStudio → push /mocap?entry=home.
  • Quick actions entry (home-quick-actions-entry, MobileMotionPressable)
    • Function: opens QuickActionsTray sheet; haptic quick-actions-open.
    • Tray actions: core action → push href; resume/save/continue/streak/search → respective handlers; save toggles library item.

Data & contracts#

  • Reads: domain registry (getShellNavigationDomains), per-domain card builders (@oshun/domain-tara|veritas|nyx|arete|nisaba), library store, current-domain store, Veritas offline cache, daypart-journey + quick-action models. All fixtures/in-memory; no network fetch on Home.
  • Writes: saveOshunLibraryItem, setOshunCurrentDomain.
  • Realtime: none.
  • Caching: Zustand-style stores; offline caches via @/offline/*.
  • Auth/role check: none on Home; per-domain gating happens in target screen.

Cross-references#

  • Navigation shell: apps/oshun/mobile/app/_layout.tsx, apps/oshun/mobile/app/(tabs)/_layout.tsx.
  • Sibling routes: explore.md, activity.md, library.md, profile.md.
  • Tab tests: apps/oshun/mobile/app/(tabs)/index.test.ts.
  • Component sources: @/components/ContinuityCard, DomainEntryHero, QuickActionsTray, RecommendationCarousel, MobileCaptureIntakeCard.

Open questions / known gaps#

  • ACTIVITY_ITEMS, TARA_FAVORITES, continuity sessions are hardcoded fixtures — confirm whether live data is wired for production builds.
  • No analytics on pull-to-refresh beyond haptics; confirm intended.