Under Construction — this site is actively being built. Check back soon.
All Work
iPhone card list + Watch complication (filled, geofence-active state) + Apple Wallet pass with barcode — three surfaces in one composed frame. Optionally, show a small inset diagram of the QR-at-register interaction model. Dark background so all three devices read clearly.
CraftBuildStrategyResearch·iOSAndroid·3 weeksIn Beta

Hopscotch

A digital loyalty card wallet. Invisible until the moment it matters.

A plastic loyalty card is a solved problem until you forget it or lose it. Hopscotch puts your cards on your phone, your watch, your lock screen, and your digital wallet — then uses your location to surface the right one automatically.

The guiding principle is a zero-friction, integrated experience — after setup, a user should never have to think about the app. It just appears the moment they need it. Hopscotch spans both iOS and Android, and works on the surface a user prefers: phone, watch, widget, or wallet.

3 weeks

Field observation to shipped

2 platforms

iOS + Android

8 surfaces

Phone, watch, wallet, widget — on each

1 + 11

Human + AI agent team

I used Stocard for years — until Klarna bought it and put everything I relied on behind a password wall that made me the slow person at the door. I wanted something that worked like a plastic key card: always with me, no friction, no app to find, no account to remember.

My role

Product lead and sole designer. Took Hopscotch from a field observation to shipping across every surface — directing an 11-agent AI team across engineering, marketing, legal, and design exploration.

Where judgment was required

The moments that shaped the product.

A first-person view at a gym front desk: a phone held up, barcode on screen, the staff member leaning forward with a curious expression. Caption overlay: 'What is that?' Composition frames the moment as the origin of the business model, not just a nice anecdote.

Validation

The product pivoted when the cashier looked up

Product-market fit signals aren't always quantitative. When gym staff interrupted a scan to ask 'wait, what is that?' — that was the moment I stopped treating it as a personal tool and started treating it as a product. If the simplicity read from across a counter — to people who scan barcodes all day — the problem was shared, not just mine. That reaction is what led me to contact the gym about partnering, and to reframe the consumer app as the front end of a two-sided marketplace.

A split composition. Left: an overflowing email inbox, muted, tagged 'lost in noise.' Right: a phone on a counter showing Hopscotch's discovery feed with a featured local business promo at the top. Caption beneath: 'The channel small brands couldn't buy anywhere else.'

Product Strategy

Email is cluttered. Hopscotch is a direct line to customers who already walked in.

Small businesses can't outbid big brands in the inbox. Hopscotch gives them a channel the incumbents don't have — the moment a customer is already at the door. One included promo push per month turns a punch card into a direct-to-customer channel at $19/month — 58% under Square Loyalty, with no hardware and no POS integration. Featured placement ($49/month, capped at 3–5 per geographic area for scarcity) is the leveling mechanism: a local coffee shop can buy prime discovery real estate that a national chain would only get through a full ad campaign. The business model is the design decision.

A two-sided marketplace diagram. Left side labeled 'Consumer' — free, no account, no tracking — with a thick arrow pointing to the center. Right side labeled 'Business' — $19/month, punch program, promo push — with an arrow pointing to the center. The center is a single node labeled 'Hopscotch.' Annotation beneath: 'The free side is what makes the paid side work.'

Product Strategy

The consumer app is free forever. That's not generosity — it's strategy.

Consumer adoption is the supply side of the marketplace. Any friction to consumer adoption — a paywall, an account requirement, ad tracking — is friction to business value. The business side pays $19/month precisely because the consumer side is frictionless and trustworthy. Pricing, privacy, and positioning are the same decision.

A three-screen flow on iPhone. Screen 1: explanation screen ('Location is used only to surface your card at the right moment'). Screen 2: iOS system location permission prompt. Screen 3: 'Always Allow' escalation with the 'Save Anyway' escape hatch button visible below. Connected by arrows. The escape hatch is annotated.

Interaction Model

iOS gives you one shot at the system prompt. I built three stages.

iOS gives you one shot at the system location prompt. I built a three-stage escalation: explain -> request When In Use -> request Always. The 'Save Anyway' escape hatch means users who decline location access aren't blocked from the core product. A user who chooses 'When In Use only' can still save a geofence — the app works with what it has and tells the user exactly what they're getting. The system never punishes a cautious permission choice.

The circular complication at 40pt in three states side by side. State 1: default — outline icon on teal circle. State 2: nearby — outline icon, category label visible. State 3: geofence active — filled icon, teal ring border. Shown on an actual Watch face background.

Information Design

Watch complications: outline = available, filled = relevant now

A 40pt circular complication has room for exactly one piece of information. The outline/filled distinction uses Apple's own visual grammar to encode two states: the card exists, or the card is relevant right now. When you enter a geofenced location, the complication fills and earns a relevance boost in Smart Stack. The right card surfaces without scrolling. One binary, correctly chosen, does the work of a notification without interrupting anyone.

Two side-by-side Watch screenshots in the barcode detail view. Left: dark mode — barcode bars rendered but hard to read, scanner icon in red indicating failure. Right: forced light mode — dark bars on white background, scanner icon in green. Caption: 'Functional requirement, not aesthetic choice.'

Platform Constraint

Dark mode aesthetics yield to a physical constraint. Every time.

Barcode scanners require dark bars on a light background. The Watch barcode view forces .colorScheme(.light) regardless of the user's Watch face setting. This is a functional requirement, not a preference. The design decision to sacrifice dark mode aesthetics for functional reliability was made once and applied consistently across every surface that renders a scannable barcode. Platform constraint as a design clarifier.

Three widget sizes — small, medium, large — displayed side by side on a home screen background. Each has consistent visual padding despite different system margin baselines. A small code annotation below: max(0, targetPadding - systemMargins.top). The visual shows consistency; the annotation explains the mechanism.

Systems Thinking

I wrote one formula. It works on every device Apple hasn't shipped yet.

Instead of hardcoding padding values, the formula reads system-provided margins (which vary by widget size and device) and adds only the delta needed. If Apple ships new widget sizes, the padding adapts automatically without a code change. This is the correct response to a variable design constraint: encode the principle, not the current values. The design doesn't need a maintainer every time hardware changes.

Process

1
Observation

Paper punch card at a coffee shop — a market failure hiding as nostalgia.

2
Architecture

Zero-dependency stack: SwiftData, CoreLocation, PassKit, WatchConnectivity. Apple frameworks only.

3
Build

4 phases: card management -> geofencing -> Watch companion -> widgets.

4
Ship

Two platforms, eight surfaces. One design system. Zero dependencies at submit.

What Shipped

2

Platforms

8

Surfaces

0

Dependencies

7

Barcode formats

iOS and Android, each across phone, watch, wallet, and widget — eight surfaces in total, built from zero third-party dependencies. In beta now. Business-side marketplace platform in active development. Seven barcode formats supported.

  • Two platforms, eight surfaces: iOS and Android, each with phone, watch, wallet, and widget
  • Zero third-party dependencies — runs entirely on first-party platform frameworks
  • Seven barcode formats supported, four Watch complication families
  • Two-sided marketplace business model active: consumer app ships, business platform in development

What I Learned

Designing for three surfaces teaches you something that designing for one surface can't: the same design principle produces completely different solutions depending on what the surface can do. 'The right card at the right time' is the same principle on iPhone, Watch, and Wallet. On iPhone it's a geofence notification. On Watch it's a complication that fills when you're nearby. On Wallet it's the actual barcode on your lock screen. Same principle, three different interaction models. Flattening those differences — making the Watch app a shrunken phone app — would have violated the principle it was trying to serve. The more uncomfortable lesson: complexity is not the enemy of good UX. Hidden complexity is. The barcode format picker is genuinely hard. Pretending otherwise produces an app that fails silently. Making the complexity navigable — surfacing the auto-detected answer, showing all options with real previews, keeping the recommendation visible after the user explores — is what 'designed' actually means.

What this demonstrates

Four-surface native design: platform conventions respected on every surface, not adapted from oneProduct strategy embedded in UX: the interaction model is the business modelResearch-to-ship in three weeks: a field observation became a shipped appPlatform constraint as creative fuel: forced light mode on Watch is a functional decision, not aesthetic