The Map tab in the Expo app (RCTX-398), specced as a working simulation in the ratified phone frame. List is the default on the phone; the map is one tap away. Everything here maps 1:1 to a native primitive — the annotations name each one.
@shopify/react-native-skia canvas. The force layout, shape vocabulary, and pulse rings port from the web prototype verbatim (same drawing contract: shape = type, teal = state, #00D9C8 motion-only). OS reduced-motion → static teal dot.
Detail, Filters, and Help are one native bottom-sheet component (@gorhom/bottom-sheet) at snap points 50% / 90%. One sheet at a time; closed sheets don't exist in the accessibility tree — same rule the web shell enforces with visibility.
On the phone the ranked list answers "what moved" faster than a spatial canvas. The Map is one tap away and remembers your choice (account prefs, shared with web). Rows are the gc-li anatomy from the component kit.
Only envelopes you can resolve are ever on the map. What you can't see is absent, not dimmed.
◉ Stream · ⇄ Relay · ▭ Session · ❏ Series · ⛁ Resource. Shape and glyph are the type; colour never is.
Solid contains · dotted references · long dash derived from · dash-dot continues.
Pulsing ring: touched in the last hour. Dimmed: outside the activity window. Dashed outline: locked until claimed. Times tick; press a row for the exact timestamp.
Zero new API surface: /graph (scope=all, org-tagged), /related, and the activity feed, through @relay/shared — related.forObject shipped for this; graph.corpus lands beside it. The fail-closed visibility property carries the same integration test as web.
Last-fetched envelope set cached (AsyncStorage) for airplane-mode glances — never bodies. Staleness is labeled with the same honest-time grammar ("as of 14:32"); nothing pretends to be live.
The ticker line above the list is the phone-sized activity rail: latest event, ticking age, tap → focus. Full feed lives in the Activity tab; map nodes flash on events (RCTX-395 poll/SSE).
60fps pan/zoom at EAP scale (≤ ~2k visible nodes) on mid-tier Android. Beyond that: drill-down search only — matches + 1-hop, never corpus-first (spec §6.5). Sim settles then sleeps; redraws are dirty-flag driven.
First-run tour completion writes to account prefs, not device storage — finishing it on web means the phone never re-runs it (and the reverse). The ? sheet is always there.