Overview
Afterlight is my concert diary on the iPhone App Store. The released version (1.2.1) already scans tickets and imports past shows from photos, Spotify hints and Setlist.fm. This case study covers the Recovery Desk I'm building on top of that: calendar scans, Gmail receipts and share targets added to the same review queue. Every source turns into a clue to review, and a clue never becomes a night you were at until you confirm it.
The Challenge
Concert memories end up scattered across camera rolls, ticket receipts, calendar events, Wallet passes, files, setlists and half-remembered nights, and those sources deserve very different trust: a Spotify play is a hint, while a ticket plus a dated photo at the venue is strong evidence. So the real problem wasn't importing data. It was reconciling messy evidence without letting software invent that someone was there.
Constraints
- •The canonical diary and recovery queue must work on-device; optional connected services cannot become the source of truth.
- •Low-confidence evidence can suggest a night but can never auto-confirm attendance.
- •Calendar, photo, and email access must be permission-gated, purpose-limited, and reduced to concert fields rather than retained source content.
- •Solo build — every feature competes with finishing.
How it works
Problem
Each import source originally behaved like its own workflow, and some hints could move too close to diary creation.
Decision
Put every source behind one versioned candidate model with provenance, confidence, deduplication, dismissal, editing, and explicit confirmation.
Tradeoff
Every integration has to translate into the shared evidence vocabulary instead of taking a shortcut to the diary.
Impact
The app can add new recovery sources without weakening the trust boundary: evidence proposes, the person decides.
Problem
Music apps default to streaming-service aesthetics — gradients, glass, glow.
Decision
Authored a design system from gig poster modernism instead: Factory Records palette, Swiss type discipline, grain, true black.
Tradeoff
A strong aesthetic position will alienate some users.
Impact
Palette, type and grain come from gig posters and tickets rather than streaming apps.
Problem
Spring animation invites spectacle.
Decision
Built a small motion grammar — a handful of springs used consistently, nothing animating from scale(0), nothing over 300ms.
Tradeoff
Restraint reads as less impressive in a screen recording.
Impact
Every transition draws on the same few springs, so the same kind of change always moves the same way.
Approach
1. One desk for scattered evidence
Shares, uploads, calendar scans, photo clusters, Gmail receipts, Setlist.fm attendance, and Spotify hints all land in the same Recovery Desk. Provenance survives merging, so a candidate can explain why it exists.
2. Confirmation is the write boundary
Recovery candidates remain separate from confirmed concerts. People can review, correct, dismiss, or complete them; only completion calls the existing local concert-creation path.
3. Native reach, local core
iOS and Android share targets, calendar and photo access, and native Gmail OAuth reach evidence where it already lives. The canonical diary and candidate queue stay on-device, while optional network lookups enrich rather than own the record.
4. Gig poster modernism
The interface borrows from the printed history of live music — FAC blue, true black, grain textures, and Swiss type discipline — with a restrained motion grammar used to clarify state.
Outcome
Ticket scanning and photo, Spotify and Setlist.fm import ship in the App Store release. Calendar scans, Gmail receipts and share targets run in development builds with regression tests around evidence parsing and confirmation, and aren't released yet.
At a glance
iPhone App Store
Published
In development
Calendar & Gmail
User-confirmed only
Diary writes
On-device
Canonical data
Learnings
- →Import is a trust problem before it is a parsing problem; provenance and confirmation belong in the data model.
- →Local-first does not mean banning the network. It means connected services can enrich the product without owning its canonical record.
- →Native extensions fail in platform-specific ways, so simulator compilation is not enough; the share handoff itself needs end-to-end exercise.
Anti-patterns avoided
- ×Treating listening history, a photo cluster, or a ticket receipt as proof of attendance.
- ×Retaining Gmail message bodies or calendar content after extracting candidate fields.
- ×Making a hosted database the canonical source for a private concert diary.
Next iterations
- →Complete Google restricted-scope verification before broad Gmail recovery access.
- →Ship the updated native targets after same-build physical-device verification.
- →Expand the versioned archive into a plain, durable export and restore workflow.
Next project
Default Index