The outcome

A companion app for finding and saving recipes, and snapping a meal to estimate its calories.

3

Data-driven personas built from 6 structured interviews.

10

Testing participants sampled across ages, genders and nationalities.

1

Tap to a calorie estimate: point, shoot, done.

Project Overview

The user problem

The 99kcal website let users locate recipes but was fairly restrictive in the flexibility it gave them: no way to save recipes conveniently, no control over their own data on-device, and no way to customise the experience to their tastes.

The business objective

Extend the 99kcal.com lifestyle project into a companion app where users could easily find recipes tailored to a low-calorie diet, save them conveniently, and understand which ingredients suited a calorie-restricted lifestyle. Beyond that, I wanted to find out how far technology could take the counting itself: where the phone could do the work the user was doing by hand.

My role and scale of ownership

I designed the 99kcal.com lifestyle brand and experience owning research, information architecture, user flows, wireframing, prototyping, guerrilla testing and final mockups, including the app's photography and content.

How I got from insights to product value

01

Discover

Heuristic evaluation of competitor apps and 6 structured interviews shaped 3 core user personas.

02

Define

Expressive scenarios captured user needs and shaped the sitemap and user flows.

03

Design

Hand sketches evolved into high-fidelity wireframes and an interactive prototype.

04

Deliver

Guerrilla-tested mockups, iterated on findings, and produced final photography and content.

Tools used
Hand sketching
Photoshop
Photo editing
Sketch
Mockups
Marvel
Prototypes
Craft & skills applied
Heuristic evaluationStructured interviewsUser personasExpressive scenariosInformation architectureUser flowsLow & high-fidelity wireframingInteractive prototypingGuerrilla testingMockups & style guideContent & photography curationVibe coding

Execution

The problem with the website

The website let users locate recipes, but gave them little control: no way to save data on their own device, personalise the experience, or keep coming back for more than one lookup. The app needed to solve three things: recipes tailored to taste, easy return to what they'd already found, and a reason to open it again.

Who I designed for

A heuristic evaluation of competitor recipe apps set the baseline for table-stakes features. From there, 6 structured interviews on weight-loss routines and recipe habits shaped 3 user personas and the needs behind them.

Three user personas with traits, frustrations, motivations and current behaviourUser stories paired with expressive scenarios

3 personas, each with traits, frustrations, motivations and current behaviour.

The clearest signal: users wanted to search by ingredient or diet, not just recipe name, and to return to recipes they'd already found. Calorie-swapping ingredients and a running shopping list came up just as often. Each need became an expressive scenario, feeding directly into the flows and later testing.

From sketch to flow

The needs research set the entry points for a sitemap covering every feature, with deep linking connecting related journeys across the app. User flows, drafted from the expressive scenarios, mapped every use case and decision point, and from there hand sketches materialised the concept fast and cheap before moving to high-fidelity wireframes and a working prototype to test the interactions directly.

Information architecture sitemap for 99kcalUser flows mapping every use case and decision pointHand-sketched low-fidelity wireframesHigh-fidelity wireframes

Information architecture: sitemap.

Elevating the wireframes to mockups

Before putting anything in front of users I raised the wireframes to full-fidelity mockups: real food photography, final type and colour, and production-ready states. Testing on something that looked like a shipped app meant feedback landed on the experience rather than on missing visuals.

99kcal recipe screen and shopping list mockup closeup

Mockups closeup: recipe screen and shopping list.

Evaluating with real users

Sample: 10 participants across age brackets, genders and nationalities.

Guerrilla testing on navigation, feature definition, CTA placement, affordances and UX copy surfaced concrete iterations and a set of requests for what to build next:

99kcal final mockups on phone devices

Final mockups, incorporating the guerrilla testing iterations.

Testing insights

Grid and landscape views appreciated for flexibility

Need to link ingredient list to saved recipes

Shopping list appreciated for efficiency

Need to snap a picture to extract a calorie count

Need to change units in my profile

Need to filter by allergens and foods I dislike

Calorie count per recipe in explore too small

Need to add a custom ingredient to the shopping list

Reduce noise from bold number counts

Need to share a recipe with others

Need to sort recipes by popular and quickest

Post-testing iterations

The photo-based calorie counter became the strongest signal for what to build next: it addressed a real point of friction guerrilla testing exposed, not a guess.

The final flow allows the user to point the camera at a plate or a recipe page, shoot once, and get an estimate back with what the app recognised and how confident it was.

Capture
Point at your food or at a recipe page and shoot
OR PICK FROM YOUR LIBRARY
Where it starts
Capture
Point, shoot, done
Estimating a meal had to cost one tap. The viewfinder is full bleed with four green corner guides and a single instruction, a strip of recent shots sits underneath for anything already on the camera roll, and one shutter is the only control on the screen.
Everything after this screen is the answer, and the answer took six passes.
Analysis
ESTIMATED FROM YOUR PHOTO
112
kcal
Goat cheese with sprouts & almonds
1 stack · approx 75gr
Match confidence88%
An estimate, not a measurement, adjust the portion if your plate is bigger.
WHAT 99KCAL RECOGNISED
Goat cheese slices ×271 kcal
Add to shopping list
Shoot another photo
What changed
Pass 1 of 6
Everything on the photograph
The first build stacked the whole answer into the photo's scrim: green eyebrow, a 62px Ostrich Light figure, the dish name and the portion, all over an 80% black gradient. Confidence was stated three separate ways — a percentage, a bar and a sentence — and two buttons competed at the foot.
The food is the evidence, and half of it was blacked out to hold text.
Analysis
Goat cheese with sprouts & almonds
1 stack · approx 75gr
ESTIMATED FROM YOUR PHOTO
112
kcal
Match confidence88%
An estimate, not a measurement, adjust the portion if your plate is bigger.
WHAT 99KCAL RECOGNISED
Goat cheese slices ×271 kcal
Add to shopping list
Shoot another photo
What changed
Pass 2 of 6
The number comes off the image
The eyebrow and the kcal figure moved down onto the white panel, directly above Match confidence. The dish name and portion stayed on the photograph for now.
Ostrich Light at 62px turned out far too thin on white — legible over a dark scrim, weak on paper-white.
Analysis
ESTIMATED FROM YOUR PHOTO
Goat cheese with sprouts & almonds
1 stack · approx 75gr
112
kcal
Match confidence88%
WHAT 99KCAL RECOGNISED
Goat cheese slices ×271 kcal
Add to shopping list
Shoot another photo
What changed
Pass 3 of 6
A photograph with nothing on it
The dish name and portion followed the number down, so the food shows undarkened — the scrim and its empty caption wrapper were deleted outright. The figure went to Ostrich Medium with a 0.5px hairline stroke, and "kcal" to Bold with light tracking, so the pair holds together on white.
Three left-aligned lines then read as three competing headlines.
Analysis
ESTIMATED FROM YOUR PHOTO
Goat cheese with sprouts & almonds
1 stack · approx 75gr
112
KCAL
Match confidence88%
WHAT 99KCAL RECOGNISED
Goat cheese slices ×271 kcal
Add to shopping list
Shoot another photo
What changed
Pass 4 of 6
Name left, number right
The figure moved to the right of the panel, top-aligned with the dish name, with KCAL stacked beneath it — and both turned Apple Green to match the primary button. Two columns instead of a stack.
The eyebrow was still Ostrich at 15px, shouting at the same volume as the name.
Analysis
Estimated from your photo
Goat cheese with sprouts & almonds
1 stack · approx 75gr
112
KCAL
Match confidence88%
WHAT 99KCAL RECOGNISED
Goat cheese slices ×271 kcal
Add to shopping list
Shoot another photo
What changed
Pass 5 of 6
The eyebrow learns its place
Ostrich gave way to Oxygen Bold 12, and the all-caps went to sentence case with the tracking eased to 0.02em. The number's block now starts at the eyebrow's top edge rather than below it, so the two columns share one top line.
Confidence was still said three ways, and the caveat asked for a portion change the screen could not make.
Analysis
Goat cheese with sprouts & almonds
88% confidence
112
KCAL
Estimated from your photo
One plate
1 stack · approx 75gr
WHAT 99KCAL RECOGNISED
Goat cheese slices ×2
71 kcal
Shoot another photo
What changed
Pass 6 of 6 · shipped
One claim, one control
Confidence collapsed from a percentage, a bar and a sentence into a single "88% confidence" chip beside the name. The eyebrow became a caption under the number. A portion stepper replaced the caveat that asked for something the screen could not do — half a plate to two plates, recalculating the total and every recognised item live. Each recognised row gained a green bar showing its share of the 112, and one green button remains.
Number down to 52px, chip bottom-aligned with the caption, green dot dropped.
Replay

Capture, recognition and confirmation, reworked pass by pass.

The final flow for snapping a picture and extracting a calorie count, shown full screen and across the full range of device sizes.

Vibe-coded in Claude, one source of truth

Changes were centralised in the design system rather than patched screen by screen. A comment left directly on a component - or on the prototype itself - is sent to Claude, which applies the change at the token or component level and propagates it back across every screen and device size. Editing in context and editing the system became the same action, so the prototype and the system never drifted apart.

Comment on a search input inside the 99kcal design system asking for the input radius to change to 8px

Edit made in the design system: a comment on the component itself.

Comment left on a recipe card in the prototype asking for the change to be reflected in the design system

Edit made in context on the prototype, then centralised back into the design system.

The design system is not a document about the app, it is the app's parts: two typefaces with one job each, a single spacing scale, one radius and one stroke weight, and the components and patterns the prototype actually renders. Because every screen is assembled from it, a decision made once - a colour, a radius, a label - lands everywhere at every breakpoint, which is what kept eight principles and four device sizes from drifting apart.

The design system every edit lands in: principles, foundations, components, patterns and motion.

The final flows

Five flows carry the app: signup and login, navigation across the tab bar, favourites and the shopping list, the calorie counter and the profile. Each one was built as a working prototype rather than a static screen, so the interactions, states and transitions could be checked in the hand before anything was called finished, and each was drawn at the largest device size and proved at the smallest.

Every screen was designed across the full range of device sizes, from iPhone SE (320 x 568) to iPhone 15 Pro Max (430 x 932)

Signup and Login

Navigation

Favourites and Shopping list

Calorie counter and My profile

Results & Business Impact

Overall impact

Tested, iterated and polished from one source of truth.

Guerrilla testing confirmed the app served the needs it was built for, and set the queue for what came next. The strongest signal, estimating calories from a photograph, was designed through six passes, with every flow assembled from a design system that stayed in step with the prototype.

3

Data-driven personas built from 6 structured interviews.

10

Testing participants sampled across ages, genders and nationalities.

1

Tap to a calorie estimate: point, shoot, done.

User & experience outcomes

Core needs, validated

Users could search, find and save a recipe without hesitation, and the shopping list and grid views were called out as the things that made it efficient. The smaller asks that came out of testing, units in the profile, allergen filters, sharing, sorting by popular and quickest, were logged and prioritised rather than guessed at.

One tap to an estimate

Searching a fixed ingredient library was the friction testing exposed, so the counter was rebuilt around the camera: point at a plate or a recipe page, shoot once, and the estimate returns with what was recognised and how confident it is. Six passes moved the answer off the photograph, cut confidence from three statements to one chip, and replaced a caveat with a portion control.

Business & team impact

A path beyond the website

The app gave 99kcal.com the flexibility, data control and personalisation a browsing-only website could not offer, with five flows built as working prototypes and proved from iPhone SE to iPhone 15 Pro Max.

One system, every screen

A comment left on a component, or on the prototype itself, is applied at the token level in Claude and propagates across every screen and device size. Editing in context and editing the system became the same action, so the prototype and the system never drifted apart.

A backlog grounded in evidence

Testing translated straight into a ranked queue, from grid and landscape views and deep linking through to the photo-based counter, so the backlog was grounded in evidence rather than opinion.