Case Study — 2022

Client

Zorzal Cacao · Reserva Zorzal, Dominican Republic

Role

Product Design & Front-End · UX/UI, wireframing, responsive CSS, Spanish localization

Timeline

Jan–Jun 2022 · ~six months, two phases

Stack

React · TypeScript · Firebase · Material-UI · Figma

Outcome

Shipped a mobile-responsive, Spanish-localized version of the tracker. Zorzal adopted it.

The client

Why tracking cacao is worth doing well

There are levels to chocolate.

Some chocolate makers just get their cacao [REDACTED] and [REDACTED], but Zorzal's cacao goes to artisan chocolate makers. So they're a little bit more avant garde. They grow cacao on a bird sanctuary in the Dominican Republic. It's a delicate process: how long the cacao ferments, how long it dries out in the sun, which part of the farm it's coming from. Even slight adjustments change how the chocolate looks, tastes, and smells. But alas, that's the difference between speciality and commodity.

Zorzal's original system for capturing it was paper slips attached to shipment boxes. The slips were handwritten in a hurry and hard to read. They'd end up poorly attached and lost. Shipments passed through production untracked; records and reports came out wrong; and the transparency Zorzal wanted to offer its customers didn't exist yet.

Two prior cohorts of engineers had already built the fix: a React/Firebase web app that gives every box a barcode and logs it through each physical checkpoint — fermentation, drying, warehouse, containers. The architecture was genuinely clever. By the time I joined, the hard backend problems were solved. The app worked.

It just didn't work where the work happened.

Image — The "before"

Drop in: the tracker's roomy desktop layout next to the same screen crushed onto a phone — buttons overflowing, forms unreadable.

The inheritance

Inheriting someone else's system

Before deciding anything, we spent our first weeks doing two things: learning React (none of us knew it well on day one — we ground through a crash course together before touching the repo), and interrogating the two engineers who'd built the thing. That call reshaped how we understood the app. The design decisions we'd inherited weren't arbitrary:

Checkpoints are places, not steps

Fermentation, drying, warehouse, containers — each is a different physical location on the reserve. The app's structure mirrors the geography.

The data model mirrors the supply chain

Boxes get UIDs; UIDs get aggregated into lots; lots into containers. Every scan is a transaction attached to a UID. To add a new production step, you create one new object in the database — no code changes. The previous team once got a diagram of the supply chain and had a running app the next day, because everything plugs and plays.

Search exists mostly to prove the app works

Floor workers only record; they almost never look anything up. Search was built so Chuck — Zorzal's founder — could see the big picture, and so data you entered didn't vanish into a void.

The app is the first thing to go

The single most important thing they told us: shipments arrive in unpredictable bursts — nothing for two weeks, then a flood of boxes. When workers are slammed and something about the app fails or annoys, they don't troubleshoot. They put the phone down and move cacao. Recording loses to the actual work, every time. That became our design constraint for everything that followed: the tool has to cost the worker almost nothing, or it doesn't get used at all.

We also asked the awkward question directly: why does Zorzal use student engineers instead of off-the-shelf agtech? Cost. The SAP-tier tools in this space run six-figure annual contracts. A small conservation-first cacao company can't carry that, so Chuck outsources to universities. It's worth being honest that this is the economic context of the whole project.

Image — The inherited system

Drop in: the supply-chain diagram — farms → fermentation → drying → warehouse (boxes → lots) → containers, with a barcode UID riding along each step.

The problem

The problem, measured against reality

The app had been designed for a desktop browser. Zorzal's employees used it almost exclusively on phones — one-handed, mid-task, in the heat, during harvest bursts. On a phone, the layout genuinely fell apart: horizontal forms overflowed the screen, buttons became hard to press, and the checkpoint navigation — a fixed sidebar — ate the viewport. And the whole interface was in English, for a Spanish-speaking team.

For a while the working "fix" was literally telling the browser to render the desktop site zoomed to 75%. That's not a mobile product; that's a desktop product held at arm's length.

So the brief for our six months was narrow and unglamorous: make the existing tracker genuinely usable on the devices and in the language of the people it was built for. The interesting part is how close we came to doing something much flashier instead — and why we didn't.

Phase one — deciding what to build

Five brains, five wireframes

We each sketched a wireframe of how a mobile-first Zorzal app should feel, and the five sketches mapped how differently five people read the same problem. One teammate built around a master menu with long-hold shortcuts. Another went color-first — a circular palette to flick between checkpoints. Our captain obsessed over orientation: always knowing where you are and moving between levels fast. Another leaned on visual cues and a tucked-away menu.

Mine was the minimalist one: a floating back button (borrowed deliberately from Android's native UI, which the workers already knew), a home button in the corner, oversized buttons that fill the screen width so a thumb can't miss, a muted gray-and-blue palette, and as little on screen as I could get away with. Utility over information density. I was, frankly, excited to make this thing beautiful. That instinct is going to matter later.

We synthesized the five into a single direction — a full redesign — and built it as an interactive Figma prototype.

Image — The five wireframes

Drop in: a row of all five hand-drawn concepts, each captioned with its one organizing idea. Then my minimalist concept close-up.

Research

Testing it: what we learned, finding by finding

We wanted to test with Zorzal's employees. We couldn't — communication with the DR was intermittent at best, and none of us spoke Spanish well enough to run a fair session anyway. So we tested the prototype with people who'd never seen it, plus a teaching assistant from a human-centered-design course, using three tasks drawn from the app's real core loop: create a box in fermentation, create a lot in the warehouse, fill out the FCCI quality form. People completed the tasks and warmed up fast. But the specific failures taught us more than the successes:

Finding 1 — Everyone expected Search to search everything

First move on "create a box"? Several testers went straight to Search and typed "fermentation" — and were visibly disappointed it only looked up barcodes. ("I would assume that you can search for fermentation.") The mental model of search-as-universal-navigation is stronger than any layout.

Finding 2 — "Add to Lot" vs. "Create Lot" was a coin flip

On the warehouse task, testers repeatedly hesitated between the two adjacent options. Two near-identical verbs, side by side, guarding different actions — a naming problem masquerading as a layout problem.

Finding 3 — Pages needed to announce themselves

Testers landed on screens and paused: "kind of confused on what I was supposed to do — not too many words, but maybe a heading." Minimalism had crossed into ambiguity.

Finding 4 — The forms button was invisible

On the FCCI task, testers went to Settings first. The TA didn't notice the forms button at the bottom at all. Forms, it turned out, were misplaced in the hierarchy: they belong inside each checkpoint's context, not in a global bucket.

Finding 5 — People wanted more life

Nearly every tester, unprompted: more color, some pictures, maybe animation. (Hold that thought — it gets overruled by someone with more standing.)

Image — Testing

Drop in: the Figma prototype's Aggregate screen with "Add to Lot" / "Create Lot" circled — the exact two buttons that split our testers.

The turn

The critique that killed our favorite design

Then we put the redesign in front of the design TA, and she took it apart — correctly.

Her first hit: we'd designed the wrong genre of thing. Our prototype behaved like a native mobile app — bottom bars, app-like navigation — when the brief was a web app that works on every device. (You can't even do a bottom bar properly in a mobile web context.) We'd drifted into designing what was fun instead of what was asked.

Her second hit was the deep one: we had no right to change this much. The workers were fluent in the existing layout. We had almost no visibility into how they actually used it, and only a secondhand understanding of the supply chain itself. Every layout change we made was a bet placed with someone else's money — and if the app annoys a worker during a harvest burst, it's the first thing to go. She told us to keep the existing layout wherever possible, and to change something only when we could articulate a strong reason it was an improvement.

She also gave us the sharpest single heuristic of the project: Record is where the money is. Specialized workers filling out checkpoint data is the entire job of this tool. So count the clicks. Our beautiful redesign took four screens to get from Home to Create Box — the single most common action in the system. If workers never use Search or Settings, don't make them walk past them every time: make search a bar, tuck settings in a corner, and put Record's options on the home screen.

Our beautiful redesign took four screens to reach the most common action in the app. The "ugly" original took fewer. That's not a style problem. That's the whole problem.

The decision

Rebuild, buy, or modify: running the decision honestly

The critique forced the real question into the open. We had three paths, and we ran them as an actual evaluation instead of a vibe:

Rebuild from scratch (our redesign)

Best-looking, best-flowing — and the riskiest. Unvalidated with real users, genre-confused (app vs. web app), and slower to reach the common actions. Timeline: well beyond our two quarters.

Move to a no-code platform

We seriously evaluated Retool, and it earned a real look: it has a native camera barcode-scanning component and some Firebase integration. But the concerns stacked up fast. Retool apps are single-page — every checkpoint and sub-checkpoint would need its own separate app, stitched together with query strings and local storage, with real questions about how data syncs across them. It's a back-end/internal-tools product, which kills the long-term dream of a customer-facing interface. It's drag-and-drop in name but JavaScript-heavy in practice, so it wouldn't actually be easier for Chuck to maintain. And one more consideration we wrote down in exactly these words: does this do justice to the work previous teams already put in? Two years of a clean, modular, plug-and-play codebase, traded for vendor lock-in.

Modify the existing codebase

Least glamorous. Keeps the layout workers already know, keeps the modular architecture, keeps the customer-interface future open, fits the timeline, and — the criterion we kept coming back to — first, do no harm to a workflow we couldn't test directly.

Modify won on paper. Then it won in the room: when we finally got Chuck on a call early in phase two, we showed him both prototypes. He reacted exactly the way our testers had — he found the flashy redesign clearer and more user-friendly — and then declined it anyway, because we projected the rebuild would run past two quarters and he wanted something his team could use now. He pointed at the modified-existing version. The person who'd actually have to live with the decision made the same call we had, for the same reason, independently.

Shelving my minimalist redesign stung. It was also the first time this project taught me the lesson it would keep teaching: I came in wanting to make it beautiful, and the work kept asking me to make it invisible.

Phase two — the build

The false start that taught us the codebase

With full repo and Firebase access, we turned "do no harm" into screens. Our first weeks of implementation went sideways, and the turnaround is my favorite artifact of the whole project — a debugging memo that opens, verbatim: "WE OVERCOMPLICATED THE WHOLE CONVERTING-TO-MOBILE PROCESS!"

We'd assumed the app was globally unresponsive and had been trying to fix everything. Actually auditing it page by page revealed the truth: most pages responded to screen size just fine. The breakage was concentrated in the checkpoint components — fermentation's Create Box and drying especially — plus a handful of specific sins: sub-checkpoints failing to load, and text-entry fields with hard-coded pixel widths that ignored the screen they were on.

The audit also surfaced something stranger: some forms displayed the same fields in a different order on mobile versus desktop — which told us prior contributors had, in places, effectively coded two divergent UIs. (Tellingly, the only form that wasn't reshuffled, FCCI, was also the only one not yet translated — the untouched one was the consistent one.)

That memo turned a vague mandate ("make it responsive") into a target list: fix the checkpoint selectors, collapse the navigation, stack the layouts vertically, and replace every hard-coded width with a relative one. Weeks of flailing became a checklist.

Image — The memo

Drop in: the actual "WE OVERCOMPLICATED..." note, mess and all. Real process looks like this.

The build, decision by decision

Decision: the sliding belt

The single worst offender on mobile was checkpoint navigation — a wide horizontal button bar that either overflowed the screen or crushed itself illegible. The options were: hide the checkpoints behind a hamburger menu (cheap, but buries the app's primary structure two taps deep), a drawer (same problem), or something that keeps every checkpoint visible and reachable at all sizes. We built the third: the button bar became a horizontal sliding "belt" across the top of the screen. Every checkpoint — Fermentación, Secado, Almacén, Contenedores — stays on screen and thumb-reachable; overflow slides instead of breaking. It preserved the mental model workers already had while surviving a four-inch screen.

Decision: stack everything vertically

The forms had been laid out horizontally — Farm · Quantity · Submit across the row — which is fine at 1280px and chaos at 375px. We rebuilt them vertically: every label above its field, one column, in source order (the fix lives in form.tsx and quick-scan.tsx, restructured into per-element table rows). On the Aggregate page, the "Complete Lot" button moved below the running table of scanned boxes — matching the actual sequence of the task (scan, scan, scan, complete) and killing a class of misclicks.

Decision: breakpoints, not a zoom hack

The responsiveness itself came down to CSS breakpoints — rules that resize the checkpoint and action selectors by screen width — plus converting fixed pixel widths to relative percentage units so text fields size to the screen they're on. Unsexy, and the difference between "genuinely mobile" and "desktop at 75% zoom," which — again, honestly — had been the interim hack. I owned a lot of this layer.

Decision: Spanish first, not Spanish eventually

The localization ran through the codebase in passes — navigation and checkpoints first (down to renaming route paths to match the Spanish names), then notifications, then forms. I owned this alongside the responsive work, pushing changes through Kristy and Alice's review on the dev side — on this team Simi and I ran design and they ran development, and the line was one you crossed both ways. One honest boundary: full translation eventually reaches into Firebase itself, because every action, checkpoint, and form name lives as data, not code. We translated the interface layer and documented the database layer as a thread for the next team, explicitly, rather than pretending it was done.

Decision: test on real phones, not simulators

To see the app break the way phones actually break it, we ran local Firebase emulators and tunneled localhost out through ngrok — so the in-progress build could be opened on a physical Android and a physical iPhone without deploying anything. Watching a real thumb miss a real button beats a resized browser window every time.

Decision: fix Create Box before adding anything

Create Box is the front door of the entire system — the first action in fermentation, the moment a batch of cacao enters the digital record. It was also buggy, and its sub-checkpoints sometimes failed to load. We prioritized making that one function boringly reliable over shipping anything new, because of the constraint from week one: if the app fails a worker mid-burst, the app is what gets abandoned, not the cacao.

Decision: meet Chuck where he already is

Chuck is the person who actually analyzes this data, and midway through the build we learned something that redirected the roadmap: he has serious spreadsheet skills. The "right" product answer — a dashboards-and-charts reporting layer in the app — would have taken longer than we had and been maintained by no one. So instead we wired Firebase to a Google Sheet and added a Report section with a one-click export. He gets live production data in the tool he's already fluent in; future teams can look at the charts he builds there and automate the ones that matter. Building less, on purpose, because the user's existing skills were the better platform.

Image — On-device

Drop in: the app running live on a physical phone via ngrok, plus a before/after of a form going from horizontal overflow to a clean vertical stack, and the sliding belt.

Whose voice wins

The feedback we deliberately overruled

Remember Finding 5 — testers wanted more color, pictures, animation? What came back from the DR said otherwise. Midway through the build, half the team went down to work alongside Zorzal in person; Simi and I held the remote half from the US, syncing over Zoom and folding what they learned into the build. What came back, through Chuck and the team on site, was blunt: the workers didn't want bells and whistles. The bells and whistles were the problem. People doing this work fast, all day, in the heat, wanted the fewest taps between them and "box logged," in their language, on the phone already in their hand.

Chuck works the floor as much as he runs the company, so when it came through him it wasn't an opinion — it was the room. Our testers were design-fluent students who wanted delight; our users were people for whom the app competes with actual cacao. When those two audiences disagree, the users win. We kept the visual refresh modest — swapping placeholder grays for a warm chocolate palette drawn from Zorzal's own brand — and spent the saved effort on reliability.

Our test users asked for more color and animation. Our real users asked for fewer taps. Knowing which audience to listen to was the most important design decision of the project.

The result

What shipped

By the end: the tracker, responsive across screen sizes, in Spanish, with Create Box stabilized, the FCCI form no longer sliding off the edge, checkpoint and action selectors that compress cleanly through breakpoints, the belt navigation, vertically stacked forms, the chocolate-brand palette, and the Google Sheets export for Chuck. A mobile visitor now lands directly on Record — the screen where the money is — greeted by "Select a Checkpoint" and the belt: exactly the fewest-clicks principle from the critique, made real.

Chuck adopted it. Per the project's final report, key forms like Entrega and Fermentation Information were seeing completion rates above 96%. I'll be honest about the limits of that number: the engagement wrapped, and as remote client work sometimes does, the line went quiet — we don't have a clean long-term before/after. What we could control was the handoff: a documented codebase, an operations manual covering the repo structure, the Firebase emulator workflow, and the database schema — so the next team starts with a map instead of an archaeology project, the way we did.

We also left them a direction, not a blank page: Simi and I sketched the first customer-facing interface — scan a code on your chocolate, see the farms of origin and time spent in each checkpoint — the transparency dream this whole system was always pointed at.

For what it's worth, Zorzal is thriving now — new space, new hires, new collaborations. I won't pretend a mobile-responsive form tool did that; they did that. But it's a good feeling to have built a small working piece of a company you'd want to see win.

Image — Final product + future-facing

Drop in: Record, Create Box, and Warehouse screens in the chocolate palette, on a phone — plus the customer-interface sketches (a batch's journey from farm through fermentation, drying, and warehouse).

Takeaways

What it taught me

Count the clicks to the money screen

Every interface has one action that is the entire job. Our redesign was prettier and made that action four screens away. Distance-to-core-action is the metric that disciplines taste.

The loudest feedback isn't the truest

Test users asked for color and animation; real users needed fewer taps and their own language. Learning whose voice outranks whose — and letting the actual humans on the other end outvote my eye — was worth more than any pattern library.

Restraint is a deliverable

The best design decision we made was a rebuild we didn't do, and the most useful thing I built is something nobody who uses it will ever notice.

I've come to think that's most of the job.

Zorzal

Case study — Zorzal Cacao, 2022

← Back to all work