All work Case 04 · Mobile app · In progress · 2026
Passo
Result
No leaderboards, no streaks, and one thing on screen: whose turn it is.
- My part
- Everything, alone: concept, brand book, design contract, visual reference and the app.
- Time
- 27 to 31 July 2026, 12 commits. M1 done, M2 to M4 and the backend open. iOS first is the plan; no TestFlight yet.
- Constraint
- Every consequence hits the creature, never a person: no streak alarms, no message about anyone, one notification per round and day.
Fitness apps reward the person who moved most, and the quiet ones drift away. Passo is for keeping in touch through motion: you do an activity, hand a small cloud on with a word for the next person, and it walks the distance to them.
[What these groups use today to stay in touch.]
Nobody is ahead.
A movement app is expected to keep score, with a leaderboard or a streak. A leaderboard turns friends into a ranking, and whoever is last has a reason to stop opening the app. A streak works by guilt.
The second round of flows, 26 July 2026, turned the idea into rules. Home has five states and one order: an unread greeting always beats “you have been quiet”; when nobody moves for five days the cloud dozes for everyone and stops belonging to anyone; there is no deadline on “your turn”. The notification list is the real product decision: at most one per round and day, never about a person. Not tested with a group yet.
I chose
A relay with no scores: Mara, then Jonas, then Lena, and every handoff carries a message.
It cost
Your own numbers. The free app shows only shared ones.
- Where it is, not who’s ahead Home answers one question: who has the creature right now. Every number on it is shared.
- A relay, not a ranking Mara, then Jonas, then Lena. The order of the handoff, and nothing is scored.
- A word for the next person Every handoff carries a message. The activity is the excuse; the note is the point.
Three codebases, and changes only flow one way.
- passo-handoff/ · The contract tokens.css + spec.md The single source of truth.
- src/ · The reference Every screen, every state Vite and React. Frozen, never shipped.
- passo-app/ · The product Expo, React Native, expo-router iOS first is the plan, Android after. Nothing shipped yet.
Skeletons that don’t move
Loading states hold the finished layout’s exact shape, so the content lands in place instead of pushing the page around.
Two doors, one flow
Most people arrive by an invite link. The link and a typed code now lead into the same onboarding, two steps instead of three.
A roadmap that writes itself
A git hook logs every commit; each change gets a written why beside it. The repo remembers its own decisions.
Five home states, one order.
Home always has the same shape. Only the status card changes, and the first state that applies, from the top, wins. The order exists for the conflicts.
| Prio | State | When | The only action |
|---|---|---|---|
| 1 | The round is forming | The cloud has never been handed on, however many people are in. | Invite friends. Under three people it is the only action. |
| 2 | It is here | You hold the cloud and have not opened the message. Beats the dozing state on purpose: a greeting is never covered by a reminder. | Open the message. |
| 3 | The cloud dozes | Nobody in the round has moved for five days. The holder is released, so the quiet lands on the creature, not on a person. | Wake it together. Everyone sees the same screen. |
| 4 | Your turn | You hold it and the message is read. The only state with a task, so the calmest screen. No deadline. | Set off. |
| 5 | With someone else | The default. In a round of five, about four fifths of the time. | None. Waiting is not a failure. |
What a notification may never do
- Threaten a streak The creature dozes. It does not die.
- Name a person Never “Tom has not been on for a while”. Quiet lands on the creature.
- Come more than once a day Per round. Three rounds are not three times the noise.
- Break quiet hours There is no “important enough” that rings anyway.
Not measured yet.
No groups yet. The design is six boards of flows with empty, loading and error states, dated 26 July 2026. In code, M1 is done; M2 to M4, the backend and invite validation are open, the store is in memory with mock data.
[What you would do differently, concrete enough to be wrong.]