40.7°N  73.8°W
CardStory · iOS · 2026

A marketplace collectors can trust.

A mobile marketplace that helps trading card collectors buy with confidence, from finding the right card to trusting the seller.

I led the UX research and interaction design for the marketplace. This project shows how I turn user research and product data into a buying experience people trust.

CardStory splash screen
CardStory Marketplace tab with Trending Now
RoleUX Designer
UX Researcher
Timeline8 weeks
Team2 UX · 1 UI
1 Research lead
SkillsUsability testing
Prototyping

Collectors had an app, not a marketplace.

Cards for sale sat next to cards people were only tracking, prices had no context, and nothing said whether a seller could be trusted. Collectors found the card they wanted, then left without buying it. I had 8 weeks, launch was two months out, and any trust signals had to come from data the app already collected.

FIG. 01Where buyers got stuck
Before: CardStory home screen with Recommend and New Listings rowsZoomed nav bar: Home, Story, add, Portfolio, Profile, with no Marketplace tabNo marketplace tab in the nav
Before: home screen where cards for sale sit beside tracked cardsZoomed card row: $250 and $550 listings mixed with $0.00 cards, no seller shownFor-sale and tracked cards mixed, no seller
Before: search results for charizard exZoomed search results: every price reads $0.00$0.00 prices with no context

Every session came back to one word: trust.

I ran moderated usability sessions with 5 collectors, from casual fans to serious traders, and affinity-mapped everything we heard.

FIG. 02Affinity map from 5 sessions

“I don’t even know who I’m buying from. There’s no name, no rating, nothing.” — P2, serious trader

Four findings came out of the sessions:

No clear way to buy

Cards for sale sat next to cards people were only tracking, and nothing in the nav said “buy.”

Prices without meaning

5 of 5 misread a price. Many showed $0.00 with no context.

No reason to trust sellers

With no seller name, rating or verification, buyers didn’t know who they were paying.

Condition was a guess

One photo per listing made it impossible to judge a card’s grade.

Four findings, four fixes.

Each decision answers one finding, in the same order.

Collectors need one place where every card is for sale.

Filters were the fast fix, but they can’t fix a mental-model problem. I moved buying into its own tab, so collecting and shopping stopped competing for the same space.

Why it works · Jakob’s LawCollectors already know what a marketplace tab means from eBay and TCGPlayer.
How it gets built · SwiftUI
RootView.swiftSwift
TabView {
CollectionView().tabItem { … }
MarketplaceView().tabItem { … }
}

Marketplace becomes its own tab in the existing TabView, so buying lives in a separate stack from the collection and each keeps its own scroll position.

A price only builds confidence when buyers know what it means.

5 of 5 users misread a price. Making it bigger wasn’t the answer, so I paired every price with its 30-day change and where it came from.

How it gets built · API + SwiftUI
Price.swiftSwift
struct Price {
let value: Decimal
let change30d: Double // trend
let source: String // e.g. PSA
}

Every listing returns price, 30-day change and source together, so the tag can show whether a price is up or down and where it came from without a second request.

Buyers need to trust the seller before they trust the price.

A star rating alone couldn’t answer whether the platform was safe. I designed seller spotlights, verified badges and full profiles to work together.

Why it works · Social proofSeveral signals that agree build more confidence than one number doing all the work.
How it gets built · SwiftUI
ListingCard.swiftSwift
SellerBadge(rating: seller.rating,
sales: seller.sales)
.accessibilityElement(children: .combine)

Seller trust is one reusable badge fed by rating and sales count, placed on every listing card and the seller profile, with a VoiceOver label that reads it out in full.

Buyers need to inspect a card before they pay for it.

A one-point grading difference can cost hundreds. I added multiple angles and full-screen zoom so buyers can check a card like it’s in their hand.

How it gets built · SwiftUI
PhotoGallery.swiftSwift
TabView {
ForEach(listing.images) { ZoomableImage($0) }
}
.tabViewStyle(.page)

One paging gallery takes however many photos a seller uploads. Each image supports pinch-to-zoom so buyers can check corners and edges before they pay.

Round one called it “a wall of cards.”

Three cards per row left touch targets cramped and details fighting for space. I moved to two per row, and round two with the same collectors confirmed it.

FIG. 03Round 1 vs. round 2
Version 1 Marketplace with three small cards per rowVersion 2 Marketplace with two larger cards per rowv1 · Wall of cardsv2 · Easier to scan
1Three cards per row felt cramped
2Prices and trends too small to read
3Save and cart icons under 44pt
4Two per row, big enough to judge condition
5Price pill shows the 30-day trend
6Saved and cart get real tap targets

Every decision, working together.

Try it: tap a card to zoom in, flip to the back, follow a seller, save a card or add one to your cart.

FIG. 04Interactive prototype

Success metrics

Conversion80%collectors completed a purchase
Scannability94%found v2 easier to scan
Trust87%said v2 felt more trustworthy

✓  Approved by the founder to go straight into development.

What I learned

The obvious answer was usually wrong.

Filters, bigger numbers and a star rating were all fast fixes. The slower answers took longer to justify, and they held up every time we tested them.

Design and engineering aren’t separate.

My CS background showed up in the structure underneath. Knowing what data the app already had and what could ship in eight weeks made every decision easier to defend.

NEXT  I’d measure purchase completion in the live app to see if the testing results hold after launch.

next case studyWikipedia iOS auditWCAG 2.1/2.2 audit for the Wikimedia FoundationView case studynext case studyAetherPlayA gesture-based AR music instrumentView case study