Place Journey v2 — master-plan SSOT

Fresh journey mockup, premium component system only. Governed by build/place-pages/master-plan/ — each screen implements its council decision sheet verbatim (✅ rulings only; ⏳/🚫 absent by design). C13-amended / DECISIONS #8: ONE language per screen — the app renders a single locale via i18n (12 locales); frames are English, plus one hi-locale reference frame. Currently: S1 Entry + Set-your-place (5 states + locale check), S2 Intro (the carousel is dead — land on the page, a ~40% sheet does the talking; 3 states + locale check) and S3 Adaptive landing + place header (THE HEADER DIET — top bar → counted ladder → Today strip → sticky tabs, ≈230px vs 510px; identity blocks move into Overview; 5 states + locale check) and S4 Overview tab content (identity blocks first; ONE builder/consumer reorder at 60%; ONE consolidated builder card; directory trust anatomy — checkmark only on claimed, no party on administrative roles, no dead call chips; hybrid local places + POI sheet; 4 states + locale check). Later screens land here as their councils rule.

‹ All screensS1·A Village candidateS1·B LocatingS1·C Urban / migrantS1·D Confirm beatS1·E After "Later"S1·F hi locale check
S1 · arrive · village candidate

"Is this your gaon?" — the premium gate

Settlement-class naming (2026-06-12): leaf type village → "gaon" (romanized in en, native per locale), town/city → "shehar", ward/locality → "area". Implements rulings C13-amended QUESTION title, ONE language per screen (single locale via i18n — see S1·F for hi) · B9 trust microline · F24/F25 Material icons + offgrp/off ladder (neutral ancestors, brand leaf) · B7 social proof (LAUNCH GATE RAISED 2026-06-12: shown ONLY when ≥10 people — owner: thin counts read as "no one uses this app"; below 10 the row stays clean, lights up per-place as counts grow; km line only with a fresh GPS fix) + B8 distance on the leaf · F27 pin badge stays · C14 check reworded, PRE-TICKED (fresh in-polygon fix) · C15 Block ≠ Tehsil label fix, all strings i18n keys · C16 sub-district note cut · E20 pick-different = in-branch candidate swap · E19 Later integrated. App-only: A2 key scoping, A3 far-GPS soft confirm, A4 gpsAccuracy + 3/30d rate-limit, F28 funnel events.

3:42
••••
Is this your gaon?
based on your phone's location
State
Bihar
District
Saran
Block
Garkha
Your gaon
Bheldi
14 from Bheldi on Nyburs
~2 km from you
This is my home place
You'll appear on Bheldi's People tab. You can hide this anytime.
S1 · arrive · locating

"Locating…" — loading never strands

A1: GPS permission + fresh fix requested AT MOUNT (kills the stale-cache wrong candidate + mid-tap permission interrupt) — shimmer skeleton ladder + pulsing "Locating…" line. E21: search + Later stay visible & tappable the whole time; fetch timeout → error state with retry + search (app behaviour). CTA shown in the F26 disabled-opacity state while no candidate exists.

3:42
••••
Finding your gaon…
Locating…
This is my home place
S1 · arrive · urban / migrant

"GPS found you in Bengaluru" — search-first

D17: urban candidate (or GPS-state ≠ registration-state) → conditional title (C13-amended, one language), INLINE search field co-equal with the urban ladder; copy invites searching the home village. Urban = 5 rungs where ward/locality data exists (Bengaluru/Delhi pilot: BBMP 243 wards + 1,133 localities, MCD 289 wards); other cities fall back to district candidate + search-first. C14: check UN-ticked — context-sensitive default for urban mismatch — with the visible unchecked box from F26. ADAPTIVE CTA (2026-06-12): while the check is un-ticked the CTA reads "Make Domlur my place" (isHome:false → AWARE residency — anchor + auto-follow, no resident claim); ticking it flips the copy to "Set Domlur as my home". Denied-permission reuses this search-first layout + a soft note (A1).

3:42
••••
GPS found you in Bengaluru
City for work, gaon at heart? Search your gaon and set it as home.
Search your gaon…
State
Karnataka
District
Bangalore
City
Bengaluru (BBMP)
Ward
Domlur Ward
Your area
Domlur
2,140 from Bengaluru on Nyburs
This is my home place
S1 · arrive · confirm beat

"Welcome to Bheldi 🎉" — the 350ms moment

E22: residency is an emotional moment — on confirm, the leaf row pulses in the brand state ~350ms + a welcome bar, THEN lands on Bheldi's own page with the intro sheet (S2·A — the carousel is dead per S2 ruling A1). F28: confirmed(method,residency) funnel event fires here. Mockup loops the pulse so it's visible; the app fires it one-shot. Pick-different/Later disappear at this beat — the choice is made.

3:42
••••
Is this your gaon?
based on your phone's location
State
Bihar
District
Saran
Block
Garkha
Your gaon
Bheldi
You + 14 from Bheldi on Nyburs
This is my home place
Welcome to Bheldi 🎉
~350ms beat → land on Bheldi's page + intro sheet (S2·A)
S1 · arrive · after "Later"

Later ≠ stranded

E19: Skip was DEAD in branch mode (maybePop on a branch root = no-op). Replaced by "Later" (localised per locale), which lands HERE: a minimal Place-tab placeholder — "Set your village to unlock your place" + ONE CTA back into set-your-place, with a deferred re-prompt flag. Not a stranded loop, not a top-right floating skip.

3:42
••••

Set your gaon to unlock your place

Your gaon's feed, issues, offices & people — one tap away.
We'll gently ask again later · deferred re-prompt flag
S1 · hi locale reference — translation check (NOT a design pattern)

The same screen, rendered in the hi locale

C13-amended / DECISIONS #8: the app shows ONE language per screen via i18n (12 locales) — the dual-line Hindi+English treatment is dead. This frame is the village-candidate screen rendered end-to-end in hi to validate every S1 translation key: title, trust microline, rung labels (राज्य/ज़िला/ब्लॉक/आपका गाँव), social proof, distance, check card, CTA, pick-different, Later, nav. Brand name "Nyburs" stays Latin. Layout, components and states are identical to S1·A.

3:42
••••
क्या यही आपका गाँव है?
आपके फ़ोन की लोकेशन के आधार पर
राज्य
बिहार
ज़िला
सारण
ब्लॉक
गढ़खा
आपका गाँव
भेल्दी
भेल्दी के 14 लोग Nyburs पर
आपसे ~2 किमी दूर
मेरा घर यहाँ है
आप भेल्दी के People टैब पर दिखेंगे। आप इसे कभी भी छुपा सकते हैं।

Naming (2026-06-12 ruling): settlement-class word family by leaf type — village → Gaon (native per locale, romanized in en) · town/city → Shehar · ward/locality → area (→ Mohalla once the locality layer lands). Resolved client-side from place.type in v1; graduates to server-driven settlementClass + ULB tier (same machinery as Mukhiya/Pradhan/Sarpanch). isHome wiring: the home-check now rides ConfirmHomePlaceInput.isHome — un-ticked = AWARE residency + adaptive CTA "Make {place} my place". Journey position: S1 confirm → LAND on the home-village page + intro sheet (S2 — the carousel gate is dead per S2·A1/A2; adaptive landing starts from the SECOND session) → S3+. All frames render inline in the Place branch (root tab, no back chevron). One language per screen (C13-amended / DECISIONS #8): en frames + one hi-locale translation check per screen (S1·F, S2·D). S1 app-only rulings (A2 key scoping, A3 far-GPS soft confirm, A4 gpsAccuracy + 3/30d rate-limit, E21 timeout→retry, F28 events) ship in set_your_place.page.dart + nybursapi. S2 app-only rulings: A3 PlaceIntroRoute/PlaceIntroExtra deleted — the sheet lives in place-page logic reading the loaded PlaceDetail, placeIntroSeen + double-show guard, ~1.2s rise · D13 funnel events · D14 kill criterion (D1-return uplift ≥ +4pp or the intro is removed) · D15 post-first-contribution share card — part of the S2 design set, designed & built with the profile/share wave · E16 interim carousel bugs die with the carousel. C12's ⏳ rename is RESOLVED by DECISIONS #10: points = "Seva" — UI renders "★ +N Seva" / "Seva score" ("सेवा" in hi); "karma" survives only as internal code identifiers. S3 (header diet) app-only/build-phase rulings cited in captions: A3 first-arrival = client skips the landing call when placeIntroSeen unset + lazy ladder after paint (zero API change) · D12 auto-follow home wired as an UpdatePinnedRegions side-effect of confirmHomePlace · E15 invalidatePlaceDetail also busts places#landing#<id> (15-min banner lag), 10-min remount refresh gate, isFollowedByViewer pre-warm/fold, landing cache key gains a userId prefix BEFORE any personal cell ships (cross-user leak), open-issues count added to the landing payload · E16 personal-delta cells (Seva delta / issue-moved / per-rung rank) are deferred — the ③ Today slot is DESIGNED for them · F17/F18 mechanical-AA + i18n batches: ≥11px sublabels, kPlaceWarn light variant, chip maxWidth/ellipsis/scroll-to-active wiring, home icon on active chip, "1 contributor" singular, onAppCount stats gate ≥3, Material icons for stats, hide the "Nearby" stub tab, 44px back-chevron, "Page completeness" → "{place} info" (hi: jaankari), live "karma" string → Seva. Banner mechanics: "Go to" = pushReplacement; orientation state capped at 3 impressions in the first 2 weeks. S4 (Overview tab content) app-only/build-phase rulings cited in captions: A1 identity blocks structurally relocate from pre-tab slivers into the Overview tab + sticky TabBar via SliverPersistentHeader · B6 expose verifiedCivic in DTOs (the checkmark currently renders on ALL rows — must become claimed-only) · B8 _ContactChip currently has NO onTap — wire the locked Call·WhatsApp·Copy sheet · B10 attribution = batched revision join on directoryTemplate (M); the ⏳ confirm-counts mechanism ("6 logon ne sahi maana") + confirm-gated call = slot designed, built later · B11 new REPORT contribution kind (S) · B14 election-staleness refresh mechanics ride the election runbook · B16 POI lat/lng is currently silently dropped — plumb it (S) for distance + open-in-maps · D ledger: onAppCount display DEPENDS on the primaryLocation sync flag (currently OFF — everything reads 0; launch-blocking) + ≥3 gate, emoji stats → icons, "1 contributors" singular, helpChipMeta missing keys (popularPlace/co/civil_surgeon/chief_secretary/dgp/panchayat_secretary = invisible chips), hardcoded-strings batch (hero fallback, completeness card, "Add a place", empty states, "karma" in _LeaderRow → Seva ×2), placeText3 ≥11px/text-2, party+seat 320px overflow guards, breadcrumb › RTL, rank width, _SectionLabel merge, canRevert role-gate, kPlaceWarn light #D9641B, "View all" 44px tap targets, steward card tap + role label. The S4·A/S4·B/S4·E tall frames render the FULL Overview scroll in one device frame — in app the same content scrolls under the sticky tab bar.