The mobile build is not a companion app with its own data, it is the same marketplace, on the same Supabase backend, rendering from the same design tokens. The design problem was not what to build. It was how to make two codebases stay honest with each other while giving each platform the ergonomics it deserves.
Most products that ship web and mobile end up with two design systems wearing the same logo. A colour gets nudged on one platform, a spacing scale diverges, a feature lands on web and waits two sprints for mobile. The user notices before the team does, and on a marketplace built on trust, an inconsistency reads as carelessness about everything else.
Relying on the team to keep two clients aligned is a process that fails quietly. The opportunity was to make divergence structurally difficult rather than merely discouraged.
Mobile is not a smaller web. Reviewing what each context is genuinely good at changed which screens got attention and which were allowed to be simple ports.
The mobile design system is not a reinterpretation of the web system, it is the same system, declared in the idiom React Native understands. What changes is layout, navigation and gesture; what never changes is colour, type and voice.
lib/colors.ts and lib/fonts.ts restate the web's globals.css values verbatim. Because they mirror rather than approximate, a reviewer can diff them and see drift immediately.
Bottom tabs with five destinations, a persistent live ticker in the header and thumb-zone primary actions. Patterns that have no web equivalent, rendered entirely in the shared visual language.
Product names, guarantees and seller replies are the same strings on both clients. Voice consistency does as much for brand coherence as colour does.
The rule was simple: anything that carries brand meaning is shared, anything that carries platform expectation is native. Colour, type and copy are identical. Navigation, gestures and input are not.
Every one of these traded short-term speed for the property that matters most on a cross-platform marketplace: the two clients cannot quietly become different products.
Commerce structure in grey, judged on whether price and action survive without colour.
Retail interfaces lean hard on colour: the discount is red, the button is bright, the badge is gold. Take all of it away and you find out whether the layout is doing anything. The product card went through several passes here before price, title and action stopped competing for the same spot.






Five things carry the mobile build. Each one either preserves parity with web or earns its difference by being genuinely better on a phone.
The mobile build reaches feature parity on everything that matters for browsing, negotiating and selling, while diverging deliberately where the phone can do better.
"The temptation with a second client is to treat it as a port. Same screens, smaller. I did the opposite and asked what the phone is genuinely better at. Browsing and haggling turned out to be phone-native activities; checkout largely was not. That reframing is why the cart is shared rather than duplicated: she is supposed to start on the phone and finish wherever she likes, and the architecture should make that free instead of impressive."
"Mirroring the token files felt redundant while I was writing them. The same hex values typed a second time in a different syntax. It is the cheapest insurance in the project. Two months later anyone can diff those files against the web source and see instantly whether the brand has started to drift. Consistency you can verify beats consistency you have to trust."
Every screen below is captured from the running Expo build on device, against the same live Supabase backend the web app uses.