Summary
The new Home is a collecting-first replacement for the field-guide Home, on the same route (scout://, mobile/app/(drawer)/index.tsx). It puts patch art at the centre and, since 2026-10-08, it is one screen: nothing scrolls. From top to bottom:
-
The top bar, "Corners": a glass menu button in the left corner, the place you are in as one quiet centred line ("Cupertino, CA"), and a glass bell with its unread count in the right corner. Profile is not on Home; it is the avatar at the top of the drawer.
-
The hero, which aims for 80% of the screen's height and gives some back on a phone too short for everything. It asks one question first: are you standing in a City Challenge?
- In a City Challenge (within
placeModeRadiusMiles, default 2, of one of its stops), the hero is that city: the city's own ring, the same one its City Challenge page draws, sized to the room the hero leaves it (358pt at most, about 200pt on an iPhone SE). The next stop's patch floats in the middle of the ring, its place photo lies behind it, and a satin arc runs over what you hold. Under the ring: "You're in a City Challenge", the city's name, "5 of 15 collected · 10 to go", then one line, Next stop and the stop's name, and its facts. Once the city is done, the ring says "Complete" and the line reads Your next patch: the nearest uncollected patch anywhere. - Anywhere else, the hero is the nearest patch you have not collected, in the ring header's own look without the ring: the place's photograph behind it (tinted, fading into the black, the same
RingHeaderField), and the patch, floating, like the unlock celebration's patch, at most 30% of the screen's height. Under it the ring header's centred title: the patch's campaign motif over its campaign name in that campaign's accent, then the name (two lines at most) and the facts.
- In a City Challenge (within
-
Go collect it · info, one row under either hero. Go collect it opens the Compass aimed at the patch, so there is no separate compass button (removed 2026-10-09). It is a flat button in the next patch's campaign colour (a State Parks patch is green, a Ghost Adventures one lavender). A patch's themed campaign wins over the City Challenge it sits in: Winchester Mystery House is lavender even from San Jose. Only a patch with no themed campaign wears the City Challenge brass.
-
The action bar: four doors, the same four for everyone, each an icon in a ring of that same campaign accent, its name, and one live line:
- Map: "14 within 10 mi" (uncollected real stops within 10 miles), "None within 10 mi", or "Explore nearby" with no location.
- Collections: "12 in progress" (collections started and not finished), or "Start one".
- Patches: "41 collected" (every patch you hold, imports included), or "Collect your first". It opens My Patches, the same place as the drawer's My Patches row. (Until 2026-10-09 this door was Badges, "32 one visit away"; Alan swapped it so your collected patches are one tap from Home.)
- Trips: "Plan a day trip". It opens
/trips, the same place as the drawer's Trips row (the new Trips, or Day Trip withtrips_v2off).
The bar sits in the middle of what the buttons leave and never shrinks. On a short phone, the hero gives the room back instead.
The 2026-10-08 one-screen layout follows mobile/research/home-fit-lab.html (bar A, Corners, Liquid glass, hero 80% and patch 30%; the picks are recorded on the page). Before it, the same day, the City Challenge ring and the full-bleed hero came from home-ring-lab-r2.html and home-ring-lab.html round 5 (variant B3). The very first version was built to home-gamified-lab.html, variant B. The field-guide Home it replaces is kept intact as the flag-off path (see discovery-surfaces).
Status
Built, behind new_home_screen, default ON. The flag is in both registries (mobile/src/config/feature-flags.ts:39, backend/src/admin/feature-flag-definitions.ts:40). The route picks the screen on every render (mobile/app/(drawer)/index.tsx:19). Because the client default is also ON, a cold start draws the new Home before the server answers. Only a server that has turned the flag OFF swaps to the field-guide Home, once, when flags land.
The 2026-10-08 work shipped in v1.1.103 (7c62da12, 26f715b2; live on the App Store in 1.1.107): the City Challenge mode, the floating hero, and then the one-screen layout with the action bar. Builds before 1.1.103 show the earlier scrolling new Home. It changed the new Home in place, with no new flag: new_home_screen still chooses between this screen and the field-guide Home.
The rarity in the hero's facts renders only for a patch with a tier. Rarity is live on prod (patch-rarity), and almost every real place carries one, so it almost always shows, usually as Common.
User-facing surfaces
| Surface | Where | testID |
|---|---|---|
| Top bar (Corners): menu, the place line, the bell with its count ("9+" past nine) | mobile/src/components/home-new/CornersTopBar.tsx:24 — Scout.TopBar with glass IconButtons; the count is MessageBell's own UnreadBadge |
nh-topbar, fg-menu, nh-place, fg-messages, fg-messages-badge |
| City Challenge hero: the city's ring fitted to its box, "You're in a City Challenge", the city's name, "5 of 15 collected · 10 to go" / "All 15 patches collected", the Next stop / Your next patch line and its facts | mobile/src/components/home-new/CityHero.tsx:110 |
nh-city-hero, nh-city-ring, nh-city-kicker, nh-city-title, nh-city-progress, nh-city-next, nh-city-facts |
| A patch on the city's ring | opens that patch (/patch-modal/<id>) |
cc-ring-patch-<id> |
| The Next stop line | opens that stop (/patch-modal/<id>) |
nh-city-next |
| Full-bleed hero (outside a city): photo, the patch floating on it, the campaign motif and name, the patch's name, rarity + facts ("1.0 mi SE · 3 min drive · State Park"). Tapping it opens the patch | mobile/src/components/home-new/HuntHero.tsx:48 |
nh-hero, nh-hero-art-box, nh-hero-art, nh-hero-kicker, nh-hero-title, nh-hero-facts |
| Go collect it (Collect it standing on it) · info, under either hero | HuntHero.tsx:110 (HeroCtas). Go collect it opens the Compass on that patch (/compass?patchId=); info opens its detail. No compass button: Go collect it is the compass |
nh-hero-collect, nh-hero-info outside a city; nh-next-collect, nh-next-info in one |
Action bar: Map → /map, Collections → /campaigns, Patches → /my-patches (my-patches; /browse-patches?status=collected with my_patches_screen off), Trips → /trips |
mobile/src/components/home-new/ActionBar.tsx:17; routes NewHome.tsx:68 |
nh-action-bar, nh-door-map, nh-door-collections, nh-door-patches, nh-door-trips |
| Empty hero (permission off / nothing to collect) | the field-guide Home's HeroEmpty, shared, in the hero's place |
fg-hero-empty |
| Screen mock gallery | scout://dev-screen-mock/new-home: seven states, including in a City Challenge, the city complete, first day and location off (mobile/src/dev/mocks/new-home.tsx) |
— |
The root keeps fg-home / fg-home-skeleton, the Maestro "home loaded / still loading" anchors, so a flow that waits for home works under either flag value.
How it works
Everything is derived on the device from synced content and your collected set, with no request of its own, in the view model NewHomeViewModelImpl (mobile/src/components/home-new/NewHome.tsx:120). The derivations are pure functions in mobile/src/components/home-new/selectors.ts, fit.ts and CityHero.tsx:
- Where you stand: the field-guide Home's own proximity selector,
selectHomeContext(NewHome.tsx:162). It returnsplacewhen the nearest City Challenge stop is withinplaceModeRadiusMiles, and Home takes the city as its hero (NewHome.tsx:185). Within the widercityChallengeRadiusMilesband, the city only ranks first among the collections that colour a patch. There is no park mode, so no containment check. - Open patches:
rankOpenPatches(selectors.ts:45) ranks every uncollected patch in the whole catalog, nearest first, with no radius. Everything the screen sends you to or counts as a destination (the hero, the next stop, the Map door) is narrowed to real stops withfilterRealStops; see Edge cases. - The City Challenge hero:
buildCityHero(CityHero.tsx:68) builds the ring with the City Challenge page's own pure builder (buildCampaignRingScreenData,mobile/src/components/campaign/CampaignRingScreen.tsx) and draws it with the page's own dial (RingDial), so the two can't disagree. The next stop is the nearest uncollected real stop among the city's members. Once the city is done, or only city/state containers are left, it is the nearest real stop anywhere, labelled "Your next patch". With nothing open anywhere there is no line and no button row. - A target:
targetFor(selectors.ts:209) is the one shape both heroes and the button row read: name, art, photo, rarity, facts (heroFacts,selectors.ts:94: distance + heading, walk or drive time, type, or just "You're here"), and its campaign (themeOfPatch,selectors.ts:188: the family, motif and kicker that colour it). - The doors:
selectHomeDoors(selectors.ts:250, called atNewHome.tsx:210). Map counts real stops within 10 miles; Collections counts collections with0 < collected < patchCount; Patches counts your collected set (useCollectedPatchIds, imports included, as My Patches lists them); Trips is fixed. No location fix → Map says "Explore nearby". - The fit:
homeFit(fit.ts:10) turns the window height into the hero's flex basis (80%) and the patch's cap (30%). The hero slot may shrink (flexShrink: 1,minHeight: 0); the action area may not, and its bar slot keeps 22pt above and below (NewHome.tsx:308). Those slot styles live in one place,mobile/src/components/home-new/layout.ts, which the loading skeleton uses too. So on a phone where everything does not fit, the hero gives the room back, the patch shrinks inside it, and the doors keep their air. The City Challenge ring measures the box the title leaves and is sized byringFit(fit.ts:16): as big as the box allows inside the screen gutters, never past the ring screen's own 358pt frame. Nothing is drawn until that box is measured, so a ring is never guessed too big for a short phone.
The patch floats. It drifts 6pt up and down every 5 seconds — the unlock celebration's idle float, one shared definition (mobile/src/components/celebration/idleFloat.ts, used at HuntHero.tsx:67 and by both celebration stages). Only while Home is the screen you see; under another screen, or with reduced motion, it holds still. There is no progress arc and no family atmosphere on this hero: those belong to the campaign pages.
The glass is the app's one glass. The menu and bell are IconButton variant="glass", which draws on Scout.GlassSurface: clear Liquid Glass on iOS 26+, a light blur with a rim on older iOS, a translucent stand-in on Android, solid under Reduce Transparency (see design-system). The bar itself is transparent, like the ring screens' chrome.
Home's side effects are shared, not copied. The intro beat, the throttled syncNow() on focus, the 10-second unlock check, the permission prompt, the bell refresh and the app-load-complete signal all live in useHomeLifecycle (mobile/src/components/home-v3/useHomeLifecycle.ts:37). Both Homes call it. The new Home's first paint waits on content and the location fix only; it no longer fetches achievements (2026-10-09).
Loading uses the house page loader: NewHomeSkeleton (NewHomeSkeleton.tsx:22: a hero block at its share of the screen, the button row, four doors, in the screen's own slots) crossfades into the screen. The top bar is not part of either: it is drawn once over both, outside the loader, because Liquid Glass under the crossfade's animated opacity draws plain until something lays it out again (seen on a 17 Pro, 2026-10-08). The bell is there while loading too. Which hero you get is only known once content lands, so the skeleton's hero block serves both. A failed first content load with no cache shows the shared HomeErrorState ("Unable to load content / Try Again").
Data model
No new tables. It reads the synced catalog (patches, collections, campaigns, patchCollections, patchTypes), the user's collected set, and AppConfig.placeModeRadiusMiles / cityChallengeRadiusMiles.
API surface
GET /api/notifications/unread-count: the bell's count.GET /api/feature-flags: servesnew_home_screen.GET /api/app-config:placeModeRadiusMiles(default 2) decides City Challenge mode.
No new endpoint.
Key files
mobile/app/(drawer)/index.tsx:19: the flag switch.mobile/src/components/home-new/NewHome.tsx: view model (:120), the door routes (:68), the pure one-screen layout (:255).mobile/src/components/home-new/layout.ts: the hero, button and bar slots, shared with the skeleton.mobile/src/components/home-new/selectors.ts: every derivation above.mobile/src/components/home-new/fit.ts: the hero and patch shares, and the ring fit.mobile/src/components/home-new/CornersTopBar.tsx: the top bar.mobile/src/components/home-new/CityHero.tsx:buildCityHero(:68) and the City Challenge hero (:110).mobile/src/components/home-new/HuntHero.tsx: the full-bleed hero and its float, andHeroCtas, the button row both heroes share. Patch art is never dimmed or tinted.mobile/src/components/home-new/ActionBar.tsx: the four doors.mobile/src/components/campaign/ring/RingDial.tsx: shared with the City Challenge page (CampaignRingScreen).RING_FRAMElives inmobile/src/components/campaign/cityRing.ts.mobile/src/scout/primitives/TopBar.tsx,GlassSurface.tsx: the bar and the glass, shared with the ring screens.mobile/src/components/home-v3/selectors.ts(selectHomeContext),useHomeLifecycle.ts,HomeErrorState.tsx,Hero.tsx(HeroSquareButton,HeroEmpty),MessageBell.tsx(UnreadBadge,messagesLabel): shared with the field-guide Home.
Configuration and flags
new_home_screen: default ON on both sides. Off mounts the field-guide Home.AppConfig.placeModeRadiusMiles(default 2): within this of a City Challenge stop, Home is the city.AppConfig.cityChallengeRadiusMiles(default 25): within this, the city ranks first among a patch's collections.- The shares are code constants, not config:
HERO_SHARE = 0.8,PATCH_SHARE = 0.3(fit.ts:7).
Edge cases and known limits
- Nothing collectable (everything collected, or no fix): the shared empty hero sits in the hero's place, and the doors still show. Location permission off: its "Continue" permission pitch, and the Map door reads "Explore nearby". City Challenge mode needs a fix, so it never shows without one.
- A city you have finished still takes the screen (the ring says "Complete"); the line under it offers the nearest patch anywhere. If nothing is open anywhere, the line and the button row are omitted.
- City, state and region patches are never a destination. The hero, the next stop and the Map count use real stops only (
filterRealStops). A City Challenge collection can list its own city patch, 0 ft away; the ring draws it, but Home's next stop skips it for the nearest real stop, and the Map door does not count it. Those patches still unlock by containment exactly as before. - The hero has no radius outside a city. The nearest uncollected patch may be far away; the facts then say "N min drive".
- A short phone (iPhone SE, 667pt): the hero gives back what the buttons and the bar need, the patch shrinks inside it, and the City Challenge ring is drawn smaller (about 200pt). A patch name stops at two lines and a city name at one, so neither can push the buttons off. Very large accessibility text can still overflow, because nothing scrolls: the hero shrinks first, but text set far larger than the default is not re-laid out for. This has not been checked on a device.
- Badges are no longer on Home at all. Neither the patch-count milestone ("Perfect Ten 2/10") nor "one visit away" is shown; both live on Achievements, reached from the drawer.
- Patch art is never dimmed to say "uncollected". "Your next patch" and the facts say it.
What this feature does NOT do
- It does NOT scroll. Everything is on one screen. There is no "more below".
- It does NOT show what a collect pays. The "Collect it and you get" pills are gone (2026-10-08). The badge a patch earns and the collections it moves are on the patch's own page, one tap away (info).
- It does NOT show your collections or badges as rows. The collections rail, the badges rail and "Also within a walk" are gone. Map, Collections and Patches are doors to their own screens, each with one live number.
- It does NOT show badges or badge progress. There is no Badges door (it became Patches on 2026-10-09) and Home makes no achievements request. Achievements are in the drawer.
- It does NOT have a profile button. Profile is the avatar at the top of the drawer.
- It does NOT show level, XP or a streak. The server still computes them (see achievements), and no screen shows them, this one included. Do not describe levelling up or streaks.
- It does NOT have a national-park mode or the City Challenge band. Standing inside a national park, Home is still the nearest patch, not the park. Near (but more than 2 miles from) a City Challenge, the city only ranks first in a patch's collections; there is no band.
- It does NOT turn into a City Challenge from more than
placeModeRadiusMilesaway, and it does not check whether you are inside the city's boundary. It measures the distance to the nearest stop. - It does NOT reward finishing a city. The ring says "Complete"; nothing is earned for it.
- It does NOT show the trip-resume card. An active Day Trip or Road Trip is not resumable from the new Home. The Trips door opens the trip planner; resume from the trip screens.
- It does NOT carry the camera-roll import band, the Journeys carousel, the day-trip marquee, or the decorative explorer-map card.
- It does NOT unlock anything. It is a browse surface. Collecting happens through the normal unlock (the Compass / location check), exactly as before. "Collect it" opens the Compass; it does not collect for you.
- It does NOT replace the field-guide Home's code. That screen ships unchanged behind the flag being off, with its own top bar.
Tests that cover it
mobile/screen-tests/new-home.test.tsx(51 tests, real catalog rows: Boston stops, the Statue of Liberty, and Walden Pond with Massachusetts State Parks from a Concord, MA fix). It covers:- the flag (new by default, field-guide when off)
- the top bar: the place line, the bell's count and "9+", no profile button, the bell opening notifications, and the menu and bell as clear Liquid Glass (falsified with a solid menu button, and with nothing unread)
- in a City Challenge: the ring as the hero (kicker, name, progress), no ring until its box is measured (falsified by guessing a size), the ring fitted to a short box by height, to a narrow one inside the gutters, and never past 358pt, the next stop's art in the ring over its photo, Next stop folded into the title with its facts, Go collect it and info (and no compass button), "Collect it" standing on it, a finished city → "Complete" + "Your next patch", and a finished city with nothing open → no line, no buttons
- outside a city: the hero's facts, the patch floating on its own with no arcs, capped at 30% of the screen (falsified at 38%), no pills, moving on once collected, art undimmed, the buttons, the empty hero
- containers are never a destination: not as the next stop even when the city's collection lists its city patch, and the Map door counts the three real stops, not the two containers too (falsified by counting all open patches)
- the action bar: the four doors and their lines from the seed, the Patches door's "1 collected" (falsified with a 0 count), a brand-new user's "Start one" / "Collect your first", location off → "Explore nearby", each door's route, Patches to My Patches and Trips to
/tripslike the drawer (falsified by routing a door elsewhere), their screen-reader names, their accent - one screen: no
RCTScrollViewanywhere on screen (falsified by adding one back), the hero's 80% basis, no rails or walk row, the bar never squeezed (the 17 Pro spacing bug; seen failing first), the glass bar drawn outside the loader's fade (the plain-glass bug; seen failing first), and loading: the skeleton under the real bar with its bell, in the screen's own bar slot - motion only while Home is in view; the shared error state
mobile/src/components/home-new/__tests__/selectors.test.tsandfit.test.ts: every selector, includingselectHomeDoors(all four lines and their fallbacks, the 192-mile patch outside the radius; falsified with a 1000-mile radius),collectionMovesFor,targetFor, andhomeFit/ringFit.mobile/screen-tests/screen-mocks.test.tsx: all sevennew-homegallery states render their expected content.mobile/screen-tests/campaign-ring.test.tsx,campaign-id.test.tsx: the City Challenge page, sharingRingDial.mobile/screen-tests/index.test.tsx: the field-guide Home's full suite, pinned to the flag off, including its bell (which now sharesUnreadBadge).
Open questions
- Should an active trip surface on the new Home? The agreed design has no trip-resume card, so it is not here (see "does NOT do").
- Should Home have a national-park mode, as the field-guide Home does? Not in the agreed design.
- The Maestro flows that drive the field-guide Home's day-trip marquee, Journeys and trip "Resume" (
maestro/tests/home.yaml,day-trip.yaml,day-trip-driving.yaml,map.yaml) assume the field-guide Home. With the flag ON they need either the flag off or rewriting against this screen. Not yet decided. - Very large accessibility text on a screen that cannot scroll (see Edge cases).