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 screensS8·A CommunitiesS8·B Cold startS8·C Create flowS8·D Joined + quietS8·E Activity gatingS8·F hi locale check
S8 · communities · alive

Communities tab — trending rail, then circles & channels

Owner 2026-06-14 (discovery pass): a "Trending near Bheldi" rail leads the tab — a geo-scored mix of the most-active circles + channels across village→block→district (uses the trending backend already built), rich cards with a member-avatar stack (faces = life + social proof), an activity pulse (🔥 Hot / Growing), a level chip, and inline Join/Open. It surfaces what's alive beyond a 3-circle village without leaving the tab. Cards stay 2G-safe — avatar stacks, NO cover images. The lists below gain the same avatar-stack treatment. · Implements C11 last-activity on EVERY circle card — a 47-member dead circle must never look identical to a live one (rural: join→dead→never returns) · C12 the JOINED row is whole-card tappable → ENTERS the circle, subtle chevron (today the Joined button is disabled and there's no way in — comprehension bug); joined floats first (0-cost app sort) · B9 both gating variants on screen: member card carries the last-post teaser, non-member cards show count-only "4 posts this week" / "Active this week" · C13 section label "in Bheldi", never "near you"; localized type badges ≥10.5px · A5 🚫 auto/official place circle — official-CREATED channels get the Official badge + first ordering instead; channel header = announcement framing, "broadcast" banned · C15 keep: inline Join, member count, circles before channels, single REST call (no 20× hydration) · D16 open create entry at bottom, no Seva gate. App-only 🔨: C11 ChannelInfo.lastActivity field absent (M) — channels order by size until it ships · F20 hasMore computed server-side but NOT exposed — 10+10 pagination replaces today's 20+20 silent truncation. G metric: weekly join-or-create per visited place ≥15% in 60d.

3:42
••••

Bheldi Village

Home · Resident
BheldiVillage6 GarkhaBlockquiet SaranDistrict140 BiharState2.1k
6new
Feed →
3open
Issues →
62%
built · Finish
Overview
Feed6
Issues3
Communities
People
Trending near BheldiSee all
RKSDVP+83 Hot
Garkha Kisan Mandal
CircleGarkha · Block
86 members · 9 posts this week
PRAMSK+44 Growing
Bheldi Yuva Manch
CircleBheldi
47 members · joined by you
340 Daily
Saran Jobs & Naukri
ChannelSaran · District
340 members · new posts daily
MKRD+10 Growing
Bheldi Buy & Sell
CircleBheldi
12 members · active this week
Circles — in Bheldi3
YM
Bheldi Yuva ManchCircle
PAS47 members · Joined
Priya: Cricket match Sunday at the school ground
KC
Bheldi Kisan CharchaCircle
RMK31 members
4 posts this week
BS
Bheldi Buy & SellCircle
MR12 members
Active this week
Channels — announcements2
Gram Panchayat BheldiOfficial
112 members · Announcements from the panchayat
MB
Bheldi Mandi BhavChannel
58 members · Daily rate updates
Start a group for Bheldi
S8 · communities · cold start

Zero circles — convert, don't beg

Cold start fires at <3 local circles (invariant: effectiveCount=max(affiliated,discovered) flips it off at 3 organic regionIds-tagged circles). A4 residents banner answers the unasked WhatsApp question with PERMANENCE framing — "stays with the village, doesn't die with a group number"; 🔨 banner hidden when the place has 0 on-app users (currently always shown) · A2 🔨 suggestion chips become SERVER-canonical — app currently ignores state.suggestedToCreate and hardcodes its own list; "Bheldi ke log" added to the seed list; region-aware topic order server-side · A3 ONE primary CTA "Start a group for Bheldi" — channel creation demoted to a small secondary link, 🚫 equal-weight dual buttons (paralysis); the Buy & Sell chip skips the picker straight to Circle creation · A1 LABELED nearby section "Nearby — in Garkha Block": own header, max 5, NEVER mixed into the local list (one parent-region query, S) — rural discovery wins, the explicit parent label answers the false-social-proof objection; 🚫 bare "see what's active nearby" link · A6 memberCount 0 → "New" chip, never "0 members" (Law #7).

3:42
••••

Bheldi Village

Home · Resident
BheldiVillage6 GarkhaBlockquiet SaranDistrict140 BiharState2.1k
6new
Feed →
3open
Issues →
62%
built · Finish
Overview
Feed6
Issues3
Communities
People
12 from Bheldi are on Nyburs
A group here stays with the village — it doesn't vanish when one phone number changes.
Bheldi ke log Buy & Sell Kisan charcha Yuva Manch Mandi bhav
You become the founding steward and earn +20 Seva.
Nearby — in Garkha Block3
GK
Garkha Kisan MandalCircle
86 members
9 posts this week
MM
Garkha Mahila MandalCircle
34 members
Active this week
YC
Garkha Yuva ClubCircle
New
S8 · communities · create flow

Picker, pre-fill, founder beat

Implements D17 Circle/Channel picker — Circle PRE-SELECTED on chip flows; comprehension subtitles localized for a rural first-timer (hi: "सभी लिख सकते हैं, मिलकर बात करें" / channel = you write, neighbours read); "admin" never renders in hi — mukhiya/pramukh framing (the word "admin" reads as liability, not honor); "Founding Steward" title localized · D18 initialName + initialDescription pre-filled from the chip topic (halves blank fields); place-prefix names kept, server slugs stay stable; the Buy & Sell chip SKIPS this picker straight to Circle creation (A3) · D16 OPEN creation for circles AND channels — NO Seva gate ever: the cold-start flywheel depends on a zero-Seva first visitor founding the first group; Seva is the REWARD, never the key — founder beat "★ +20 Seva" (already built), DECISIONS #10: Seva, never "karma". Moderation lever if needed later = steward approval on AFFILIATION, not creation.

3:42
••••
Create — the 3 beatsD16–D18
Tap "Start a group" → picker sheet. Tap a topic CHIP → picker with Circle pre-selected + fields pre-filled; Buy & Sell skips the picker entirely.
1 · Picker sheet — Circle pre-selected (D17)
Start for Bheldi
Circle
Everyone can write — talk together
Channel
You write updates — neighbours read
D17: subtitles are comprehension, not feature copy. hi renders "सभी लिख सकते हैं, मिलकर बात करें" / channel framed as the mukhiya writing — "admin" is banned in hi (E19).
2 · Creator — pre-filled from the chip (D18)
Group name
Bheldi Buy & Sell
What is it for?
Buy and sell within Bheldi — grain, tools, cattle, kirana.
D18: initialName + initialDescription ride the chip topic — blank fields halve. Place-prefix names kept; server slugs stay stable.
3 · Founder beat — the pride moment (D16 · DECISIONS #10)
You founded Bheldi Buy & Sell

You're the Founding Steward — the first to start a group that stays with the village, not one phone number.

+20 Seva earned
D16: open creation, no Seva gate — the +20 founder Seva (built) is the reward that starts the flywheel, surfaced as a real pride moment (not a passing toast). "Founding Steward" + "stays with the village" ship localized (D17/A4); 🚫 confetti, but founding the village's FIRST group earns a genuine beat.
S8 · communities · joined + quiet states

Quiet, loading, broken — all honest

Implements C14 empty-but-joined circle STAYS LISTED with a "No recent posts" sub-label — never silently dropped (⏳ unread pills deferred: circles = S via existing pipeline stage not wired, channels = L via chat infra; Join conversion is the goal now) · F20 2G kit: skeleton shimmer ROWS on load — a lone spinner reads as 8–12s of nothing and bounces; error state gets an explicit RETRY (today errors fall through to the cold-start banner — a lie); optimistic Join = instant swap to Joined + revert on error, never a spinner on the button. App-only 🔨: F20 limit 20+20 → 10+10 with hasMore pagination (computed server-side, NOT exposed — silent truncation past 20) · verify groups compound index {groupType, isDeleted, regionIds} via explain() before district scale · q:60 imgproxy hint on avatars.

3:42
••••
List states4
1 · Joined but quiet — stays listed (C14)
BM
Bheldi Bhajan MandaliCircle
9 members · Joined
No recent posts
C14: a quiet circle you joined is still YOURS — listed, tappable, honest about silence. ⏳ unread pills deferred.
2 · Loading — skeleton rows, never a lone spinner (F20)
3 · Couldn't load — retry, never the empty banner (F20)
Groups couldn't load. Check your connection.
🔨 Today a fetch error falls through to the cold-start banner — "no groups here" is a LIE on a network blip. Distinct error state + retry.
4 · Optimistic Join — instant swap (F20)
KC
Bheldi Kisan CharchaCircle
32 members
Joined
F20: the button swaps to Joined on TAP — state reverts with a toast if the call fails. No spinner on the button, ever.
S8 · communities · activity gating

Same circle, two truths — and a hard wall

Implements B9 activity signal ON the community card, content gated: a MEMBER sees the last-post teaser + timestamp; a NON-member sees count only ("4 posts this week") — activity visible, content gated → join incentive (lastPostCreatedAt already in the payload, ~0 cost) · B7 CIRCLE POSTS NEVER REACH THE PLACE FEED — unanimous ruling: the WhatsApp mental model is ironclad, posted "in the circle" ≠ "to the village"; one betrayal = never posts in a circle again; S6's !circleId filters stand · B8 channels are the exception (broadcast = public is the author's intent): labeled channel cards in the place feed = design ACCEPTED, ⏳ BUILD AT S14 (additive groupId query, same mechanism as events-in-feed); feed-tab digest row also revisits at S14 · 🔴 B10 P0 SECURITY (standing, pre-dates S8): getPostV2 has NO circle-membership check — private-circle posts readable by ANY authed user with the postId (posts.service.ts:4220; settings.isPrivate never enforced) — 🔨 enforce isPrivate at getPostV2 (M); and CIRCLE_POSTS_IN_TIMELINE flag does NOT cover the DB fallback (posts.repo.ts:3938 hardcodes the exclusion) — both paths move together if ever flipped.

3:42
••••
One circle, two viewsB9
Member view — sees inside
KC
Bheldi Kisan CharchaCircle
31 members · Joined
Suresh: DAP stock aaya block godam mein, jaldi le lo
Active this week · 2h ago
Member: last-post TEASER + timestamp — the circle feels alive from the list. Whole row taps into the circle (C12).
Non-member view — the same circle
KC
Bheldi Kisan CharchaCircle
31 members
4 posts this week
Non-member: COUNT only — activity visible, content gated. The gap between "4 posts this week" and reading them is the join incentive (B9).
The wall — circle ≠ village (B7)
Circle posts never appear in the place Feed — what's said in the group stays in the group. Channels (B8) are the only exception, at S14.
🔴 B10: the design promise above is currently breakable server-side — getPostV2 serves private-circle posts to any authed user. P0 fix rides the standing security list, independent of this tab.
S8 · hi locale reference — translation check (NOT a design pattern)

The Communities tab, rendered in the hi locale

DECISIONS #8: ONE language per screen via i18n — this frame renders S8·A end-to-end in hi. E19 🔨 P0 i18n sweep: EVERY communities_* key in hi.i18n.json is untranslated English today — a Hindi-set phone sees English across this whole tab — plus hardcoded EN strings not even keyed (_StartCommunityBlock RichText, _ResidentsBanner, _TrustNote, picker subtitles); banned in hi: "broadcast", "admin" (→मुखिया/प्रमुख), "steward karma" (→सेवा) · C13 type badges localized — समूह (Samuh) for circles, ख़बर (Khabar) for channels, ≥10.5px ("CIRCLE" 9px uppercase is invisible on a Redmi); section label "भेल्दी में", never "near you"; channel header = announcement framing घोषणाएँ · joined sub "जुड़े हुए", activity lines "इस हफ़्ते सक्रिय" / "इस हफ़्ते 4 पोस्ट" (B9 gating identical), create entry "भेल्दी के लिए समूह शुरू करें". Numerals, handles and the brand "Nyburs" stay Latin. Layout, components and ordering identical to S8·A.

3:42
••••

भेल्दी गाँव

घर · निवासी
भेल्दीगाँव6 गढ़खाप्रखंडशांत सारणज़िला140 बिहारराज्य2.1k
6नई
फ़ीड →
3खुली
समस्याएँ →
62%
बना · पूरा करें
ओवरव्यू
फ़ीड6
समस्याएँ3
समुदाय
लोग
समूह — भेल्दी में3निवासियों द्वारा
यु
भेल्दी युवा मंचसमूह
47 सदस्य · जुड़े हुए
प्रिया: रविवार को स्कूल मैदान में क्रिकेट मैच
कि
भेल्दी किसान चर्चासमूह
31 सदस्य
इस हफ़्ते 4 पोस्ट
ख़
भेल्दी ख़रीद-बिक्रीसमूह
12 सदस्य
इस हफ़्ते सक्रिय
ख़बर चैनल — घोषणाएँ2
ग्राम पंचायत भेल्दीआधिकारिक
112 सदस्य · पंचायत की घोषणाएँ
मं
भेल्दी मंडी भावख़बर
58 सदस्य · रोज़ के भाव
भेल्दी के लिए समूह शुरू करें

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.