What
Every time a CORE-authenticated user visits a town, that town gets stamped onto their passport. The passport accumulates a visible collection of stamps (like a real passport) showing every town they've been to.
Why
- Turns the Passport into a living collection — every visit leaves a permanent mark.
- Creates a social / brag surface: "look at all the towns I've been to."
- Gentle nudge toward CORE login — stamps are gated on auth, so guests don't earn them.
- Feeds discovery: stamps on friends' passports become recommendations.
Gating
- CORE-authenticated only. Guest visits do not earn stamps. First-ever visit surfaces the payoff ("sign in with CORE to start collecting stamps").
- One stamp per town per user (idempotent). First visit stamps; re-visits update `lastVisitedAt` + `visitCount`.
Rough scope
- New model: `PassportStamp` (userId, townSlug, firstVisitedAt, lastVisitedAt, visitCount).
- Hook into existing visit tracking (TownActivity) — write a stamp on first entry for authed users.
- Passport page renders a stamp gallery (visual grid of town thumb + name + date).
- Stamp count on the passport header.
- Optional (later): custom stamp design per town — creator uploads / generates a stamp sprite; falls back to auto-generated.
Dependencies
Notes
- Don't stamp the creator's visits to their own town by default (avoid inflating their own count).
- Consider a rarity signal on stamps (small niche town vs. big public town) so a stamp on a hidden gem feels like a badge, not filler.
What
Every time a CORE-authenticated user visits a town, that town gets stamped onto their passport. The passport accumulates a visible collection of stamps (like a real passport) showing every town they've been to.
Why
Gating
Rough scope
Dependencies
Notes