Part 2 of B2 — the CUSTOMER/MIGRANT side: the populated directory, category browse, and the two public business-page variants. Closes the E2E validator's P0-4 (every customer journey converges here) plus P1-7 (Follow CTA), P1-11 (receiving-end call overlay), P1-12 (report wrong-number row). Governed by B-UX-PLAN.md §3-B2 — the remote-trust signal order ①–⑦ is the page's spine — and DECISIONS #15 (NO ratings/stars, ever), #19 (Message primary · Call via locked sheet · WhatsApp demoted into the sheet), #21 ("हमारा चैनल" join CTA), #22a (centroid distances — ruling R2: in-village rows show the village name, never a fake "0.3 km"), #22c (proof = measured enquiries only). The public page is b2's cockpit with the owner chrome removed — same anatomy, pencils gone, toggle becomes a read-only dot. Ghost pages SINK, never hide (L4); business surfaces read like printed notices (L6). DECISIONS #8: frames English + binding Devanagari decision strings; B2P·F = the hi locale check on the store page.
The Overview section once businesses exist — replaces b1a's empty state, same slot after officials (§2 IA, S4 DTO stitch; first 5 rows ride the existing payload). Category chips filter in place (server-driven labels, §6). Row anatomy = the S4 .off vocabulary + three additions: L4 activity dot (green ≤30d · amber 31–90d · red older — same grammar as mandi freshness), centroid distance (#22a — ruling R2: in-village rows say "भेलड़ी", never "0 km"; same-village businesses share ONE centroid so a metre count would be a fabricated number, L7; cross-village shows "~2.1 km" centroid-to-centroid), and ONE action chip. The five rows walk the mix: kirana open-now · medical w/ the structured "doctor: मंगल/शुक्र" chip (§3-B3 schedule renders, never prose) · home-based tailor (village only — no address, no km, by design) · electrician "आपके गांव में सेवा" + available-now pulse (serviceArea match) · and ONE STALE row SUNK to the bottom (R4: sinking beats distance sort; red chip "4 माह पहले", row de-emphasised, never hidden). "सभी देखें (17)" → b2p-b. ⚠️ OWNER FORK P1-8 panel below renders BOTH chip variants.
The full browse screen behind "सभी देखें" and search. Typesense search bar with the mic as the 42px target (L2 — a voice query "बिजली मिस्त्री" IS the search; keyboard is implicit in the field). Category grid = the b1-cgrid anatomy 1:1 (same top-8 + "और देखें", same server-driven labels §6 — the creator and the seeker see the SAME vocabulary, so what she filed under is what he finds under). Tap a tile → filtered list, distance-sorted ($geoNear 5km village / 15km block + serviceArea "serves your village" injection). Ranking v1 per B-PHASES: verified → completeness → followers → distance — with the ghost-rank demotion on top (R4): the red-stale row sinks below greener rows even when it is nearer. The migrant path rides this same screen from anywhere — browse runs against the FOLLOWED place, no location share (B-PHASES B2 feature 8).
The STORE variant as a CUSTOMER sees it — b2a's cockpit with the owner chrome removed (no pencils, no toggle, no "Your page"; the dot is read-only). The page's spine = the §3-B2 remote-trust order, top to bottom: ① activity dot "अभी खुला है" ② hours as a structured line ③ village-qualified followers "6 भेलड़ी लोग follow करते हैं" + the FOLLOW pill (P1-7; R5 — the ONLY engagement affordance, and the line renders ONLY when nonzero, L7) ④ shopfront photo ⑤ MESSAGE primary + Call + lock line (#19) and the "हमारा चैनल" join row (#21 — DM for the question, channel for the offers) ⑥ category signal: products with real ₹ (b5-prod anatomy 1:1 — what a kirana page IS) ⑦ proof: "इस हफ्ते 12 लोगों ने संपर्क किया" (#22c — measured enquiries, never "orders" until order-confirm exists). #15: NO ratings, NO stars, NO review count — anywhere. Beat ②: the ⋯ menu with the P1-12 report row "गलत नंबर / बंद हो गई?" — stale pages get fixed by the village, quietly.
The SERVICE variant (Anil Electric Works). Header carries the "Available now" pulse (the net-new widget, read-only here) + the serves-your-village chip (serviceArea match — the migrant's "will he even come?" answered before the call). Work photos = the b2c grid without the add tile (customer view; photos rank the page — a photo-less page simply sinks, it is never shamed). The rate card renders LOCKED: every row shows the work name + a blurred "₹ ???" — never blank (§3-B2: blank reads "no rates", blur reads "rates exist, one tap away") — and the card foot carries the binding unlock line "रेट देखने के लिए संदेश/कॉल करें". Beat ②: tap Message/Call anywhere → the PRE-CALL rate-reveal sheet (R6) — S4 locked-sheet anatomy 1:1 with the RATES BLOCK ABOVE the connect buttons: तय रेट ₹150 · "₹80/पॉइंट से शुरू" · "कॉल करें" chip (the §3-B2 three modes, rendered exactly as the owner set them in b2c). Rates revealed BEFORE connecting kills the verbal-quote friction; the 🔒 line sits between rates and buttons; WhatsApp lives ONLY in the Call·WhatsApp·Copy row (#19).
What the OWNER's phone shows when a Nyburs business call rings — here the SHG lens: Rekha didi's phone, a call about सत्तू from Santosh in Patna. Without this overlay the loop breaks twice: the family asks "why are Gurgaon numbers calling you?" (surveillance risk for a home-based woman — the listing gets deleted), and the owner rejects unknown numbers (the customer concludes the page is dead). The overlay's one job: the binding line "यह Nyburs से business call है — Santosh, भेलड़ी पेज से · सत्तू के बारे में" — a legible, RESPECTABLE business reason anyone holding the phone can read. Context is assembled from STRUCTURED data only (caller first name · source page · the product whose sheet was open — R7): caller free-text never reaches the lock screen, so the overlay cannot become a spam/abuse vector. The caller's personal number stays masked end to end (the call bridges through Nyburs — the same lock promise both sides). NET-NEW surface — unavoidable (P1-11 validator gap; no S-series equivalent exists); it inherits the official notice grammar (L6), not call-screen exuberance.
DECISIONS #8: one language per screen — this frame renders B2P·C's store page fully in the hi locale as a translation check. Chosen because it is the track's string-heaviest, highest-traffic public surface (every customer journey lands here). Business names stay Latin (proper nouns, S1·F precedent); category labels ("किराना") = server-driven domain vocabulary (§6), NOT ARB keys. The binding Devanagari decision strings are identical in both frames by design ("अभी खुला है", "6 भेलड़ी लोग follow करते हैं", "हमारा चैनल", "नंबर सुरक्षित…", "इस हफ्ते 12 लोगों ने संपर्क किया") — what this frame validates is the structural chrome: hours line, follower subline, CTA labels (संदेश भेजें / कॉल करें / जुड़ें), section headers (सामान और दाम), nav keys (होम/जगह/खोज/डेली/चैट्स). "follow"/"call" stay Latin inside the binding strings — the plan's own orthography.
B2 Part-2 position: the customer/migrant side of the business track — closes E2E P0-4 (directory → browse → public page ×2 → contact) plus P1-7 (Follow), P1-11 (call overlay), P1-12 (report row). The public page IS b2's cockpit minus owner chrome — one anatomy, two render modes. Ruling log: R1 directory rows ship the संदेश chip (strict #19) pending owner fork P1-8 — both variants framed, flip = one class · R2 #22a centroid honesty: in-village rows show the village name, never "0 km"; "~km" only cross-village (centroid↔centroid) · R3 [=b5]/[=b2]/[=b1] re-declared file-local patterns (abar, fresh chips, prod rows, msg/call ladder, lock line, seen line, pulse dot, work grid, category grid) flagged for the lead's journey.css consolidation · R4 ghost-sinking BEATS distance sort — a nearer red-stale row still renders last, never hidden (L4) · R5 Follow pill = the only engagement affordance; the follower line renders only village-qualified + nonzero (L7) · R6 the pre-call reveal sheet is both rate-unlock and contact gate — Message AND Call route through it; rates render verbatim from the owner's b2c modes · R7 the call-overlay context line is structured data only (name · page · product), never caller free-text. Laws honoured: L3 call ≤1 tap from every surface here · L4 one traffic-light grammar across row dots, fresh chips and the page header · L6 printed-notice grammar — zero reactions, zero comment counts, and per #15 zero ratings/stars anywhere · L7 every number real and measured ("इस हफ्ते 12 लोगों ने संपर्क किया" per #22c; zero never renders). Net-new beyond reuse (annotated): the receiving-end call overlay (P1-11, no S-series equivalent — inherits L6 grammar) and the Follow pill (maps to the app's existing follow concept; BusinessFollower entity is the build item). For the lead's eye: the b2p directory rows assume the S4 DTO stitch lands businesses after officials in the Overview payload (first 5 rows free); the b2g/b2h enquiry-composer agent (in flight) owns what happens AFTER the संदेश tap — b2p-d's reveal sheet hands off to it with the rate row attached; b5h (in flight) owns the group-page join CTA — the business-page channel row here (#21) should consolidate to one component with it; P1-8 needs the owner before build.