My work/Pantri grocery app

Pantri: cook from what you already have

A self-initiated grocery and pantry app, born from conversations with home cooks I met at a cooking competition in Dallas. It answers the question they kept coming back to: what can I make for dinner tonight with what's actually in my kitchen? This page shows the research, the scope I chose, why it looks the way it does, and how the Figma file is built.

Self-initiatedMobile appFigma variablesComponentsSmart AnimateFigma MotionAI-assisted build

Get the Figma file on Community ↗

Type
Self-initiated concept, 2026
Role
Solo: research, UX, UI, system, motion
Platform
iOS and Android, 390 pt base
Tools
Figma (variables, components, prototyping, Motion), Claude
Pantri cover: three phone screens (pantry, home and shopping list) in a frosted-glass, warm neutral style, with the title Pantri, daily grocery management made calm.
Overview

The problem isn't the shopping list. It's 6 pm.

Most grocery apps help in one moment: the list helps in the store, a pantry tracker asks you to type in everything you own, and a recipe app assumes your kitchen is fully stocked. Real cooking doesn't happen in those moments. It happens at 6 pm, in front of a half-empty cupboard, with kids who want dinner.

The USDA estimates that 30–40% of the US food supply is wasted, and households are the biggest single source. A lot of that waste starts with not knowing what's at home, and with recipes that send you out for ingredients you don't really need.

Problem statement: home cooks need one place that knows what they have, suggests what they can make with it, and offers swaps for what's missing, so they can cook tonight without another store run.

What I delivered
  • Research synthesis from conversations with home cooks
  • A scoped MVP and the loop it follows: plan, shop, store, cook
  • 5 core screens and a substitution concept
  • A Figma file with 80 variables in 4 collections, 20+ components with variants and properties, 13 text styles and 5 effect styles
  • 3 Smart Animate prototypes and timeline animations in Figma Motion
  • A WCAG AA contrast audit of the glass UI, and a test plan
27 → 35primitive colors aliased into semantic tokens
20+components with variants, text, boolean and instance-swap properties
3interaction prototypes, built with Smart Animate
14.6 : 1body-text contrast on glass, measured on the blended color
Research

It started with home cooks, not a feature list

I took part in a cooking competition in Dallas, and the conversations I had with other home cooks there became the starting point. Many of them cook every day for families, often across more than one cuisine. Talk kept coming back to the same frustrations, so I wrote them down and later grouped them into themes.

01Informal conversations with home cooks 02Affinity grouping of what I heard 03Audit of list, pantry and recipe apps 04Assumption mapping

What I heard, and what I designed in response

Heard
The pantry is always messy and incomplete. You only find out what's missing halfway through a recipe.
DesignedA Pantry view grouped by Fridge, Freezer and Cupboard, with quantities and freshness. Receipt scan restocks it, so nobody has to type their whole kitchen in.
Heard
The daily struggle is deciding what to make for dinner, for the kids, and for different cuisines.
DesignedCook from your pantry on Home: dinner ideas built from what you have, filtered by who's eating (kid-friendly) and by cuisine.
Heard
YouTube and cookbooks list specific ingredients. What if you don't have them?
DesignedA recipe match that shows "you have 7 of 9" and suggests a swap for each missing ingredient before it suggests buying anything.
Heard
When something really is missing, it's hard to know where to find it.
DesignedOne tap sends missing items to the shared list, grouped by aisle, with an optional store tag (for example, a specialty grocery for regional spices).
An honest note on the research

These were informal conversations, not structured interviews, so I've paraphrased themes rather than quoting anyone. They gave me a strong direction, not proof. That's why every decision below comes with an assumption to test, and why the next step is a structured round of interviews and a usability test.

AssumptionRisk if wrongHow I'll test it
People will trust dinner ideas that start from their own pantryHigh: it's the core of the appConcept test with 5–6 home cooks: would you cook this tonight?
A suggested swap is more useful than adding the item to a listHigh: drives the recipe matchShow both options on real recipes; record which one people pick
Typing in the pantry is why trackers get abandonedHigh: receipt scan is the betOne-week diary: items logged by hand vs. skipped
Filtering by "who's eating" (kids, adults) matters more than by dietMedium: shapes the filtersCard sort of filter options with parents
Plan & scope

What I built, and what I left out on purpose

A solo concept can grow forever, so I scoped it to one loop: plan, shop, store, cook. Every screen had to move someone to the next step of that loop. Anything that didn't was cut, even if it was trendy.

I also worked within real constraints. On Figma's Starter plan a file gets 3 pages and one mode per variable collection. Instead of fighting that, I structured the file as Cover, Design system and Screens & prototypes, and planned dark mode as a second mode on the same semantic tokens, ready to add on a paid plan.

In scope · MVP
  • Home: the unfinished shop, items to use soon, and dinner ideas
  • Shared, live shopping list grouped by aisle
  • Pantry with freshness, restocked by receipt or barcode scan
  • Cook from your pantry, with swaps for missing ingredients
  • Insights: spend, trips and food saved from waste
Out of scope, and why
  • Grocery delivery and payments: a business partnership problem, not a design one
  • Calorie and macro tracking: a different product with different users
  • Social feed and recipe sharing: adds noise to a daily utility
  • Video recipes: I link out to them; the app's job is matching ingredients
Process

From kitchen conversations to a test-ready file

Listen

Conversations with home cooks; grouped what I heard into four themes.

Frame

Journey map of the grocery loop, problem statement, assumptions and the MVP scope.

Structure

Four tabs that follow the loop, plus one Add button in the middle for the most frequent task.

System first

Variables, styles and components before any screen, so every screen is built from instances.

Prototype

Smart Animate flows, Figma Motion timelines, a contrast audit and a test plan.

StagePlanShopStoreCook
DoingWrites a list from memoryWalks the aisles, guesses quantitiesPushes new food in front of oldDecides dinner at 6 pm from what's visible
FeelingRushedUnsureNeutralStuck
Pain"Do we still have rice?"Two people, two lists, duplicatesNothing records what was boughtThe recipe needs things you don't have
OpportunityA pantry-aware listOne live list, grouped by aisleReceipt scan restocks the pantryCook from your pantry, with swaps
Key decisions

Six decisions, what I rejected, and the trade-offs

DecisionWhat I consideredWhy this oneTrade-off
Swaps before shopping
Research theme 3
Add every missing ingredient straight to the listThe cooks wanted to cook tonight, not go out again. A swap ("use yogurt instead of sour cream") keeps dinner possible.Swaps need good data and can change the dish, so each one says what changes.
One Add button, three ways in
Hick's · Fitts's law
An add field on every screen; separate scan and voice buttonsOne 56 pt target in thumb reach, and three options is a choice you make at a glance.Adding from the List costs a tap, so the List keeps its own inline add bar.
Group the list by aisle
Chunking · Jakob's law
A flat list in the order items were addedMatches how people walk a store; small groups are easy to scan with one hand.Aisles differ by store, so aisle numbers are optional data.
Home opens on the unfinished task
Zeigarnik · goal-gradient
A dashboard of equal tiles; a recipe feed"7 of 12 picked" with a Resume button is what people come back for.With nothing in progress, the slot becomes "Plan dinner".
Color only for urgent items
Von Restorff · WCAG 1.4.1
A traffic-light color on every itemOn a calm screen, the few clay items stand out. Every tag also says "1 day".Fresh and "a week left" look alike; the freshness bar carries that detail.
The scan sorts storage
Tesler's law
Asking people to file every scanned itemThe system holds the complexity, so restocking is one tap.Wrong guesses happen, so Review stays one tap away.
Next iteration

Recipe match with swaps

This screen came straight from the third research theme. Pick a recipe from YouTube or a cookbook, and Pantri checks it against your pantry. Instead of a shopping list, it leads with what you can do right now.

It reuses the existing system: glass panels, the Chip component for "who's eating" and cuisine filters, and the clay token for what's missing, with the label "missing" in text so color never carries the meaning alone.

Concept built in HTML for this page. Ingredients and swaps are illustrative.

Final design

Five screens that follow the loop

Home screen: the unfinished shopping run with 7 of 12 picked, items to use soon, and dinner ideas from the pantry.
HomeResume the run, use what's expiring, get dinner ideas.
Shared shopping list grouped by aisle, with checked items struck through and a running total.
Shared listGrouped by aisle, live with the household.
Pantry screen with item cards showing freshness bars; urgent items marked in clay with days left.
PantryFreshness at a glance; urgency in clay.
Receipt scan screen: scanned items already sorted into fridge, freezer and counter, with an Add all to pantry button.
Receipt scanRestock the pantry in one tap.
Insights screen showing spend against budget, shopping trips and food saved from waste.
InsightsSpend, trips and food saved.
Why this color and design

A kitchen is already loud. The app should be quiet.

Kitchens are full of color: packaging, produce, food photos and recipe thumbnails. A bright, saturated app would compete with all of it. So the palette is warm neutrals, like stone, sand and linen, and the app steps back so the food and the few urgent items stand out.

Only two colors carry meaning. Sage means "go": primary buttons, checked items, progress. Clay means "use soon". I picked clay over red on purpose. Red reads as an error or danger, and an avocado that needs eating tomorrow isn't an emergency. It's a nudge.

Text is a warm near-black (#1F1E1C), not pure black, which is softer on a warm background and still gives 14.6 : 1 contrast.

Why glass? Glassmorphism is a trend, but here it does a job: it shows layers. The tab bar, sheets and cards float over a soft, blurred background, so you can tell what sits on top without heavy borders or shadows. That keeps the UI calm.

The trend version usually fails accessibility: transparent panels on bright gradients. I set rules instead. Glass is only for grouping surfaces, never behind text without a solid floor. Panels stay 45–60% white over a low-contrast neutral background, and I measured contrast on the blended color, which is what people actually see.

Type pairs Fraunces, a soft serif for headings that feels like a cookbook, with Manrope, a clear sans for everything you read quickly.

bg/canvasWarm stone base
text/primaryWarm near-black
bg/accent · sageGo: actions, progress
text/warn · clayUse soon, never alarm
text/secondaryQuantities, meta
blob/sandBlurred background
blob/sageBlurred background
bg/glassWhite 45–60%, blur 24
Figma craft

The design system, and what made it easy

I built the system before any screen. Every screen is assembled from component instances, and every component binds its fills, strokes, gaps and corner radius to variables. That's what made the rest of the project fast: one change to a token updates every component and every screen.

CollectionCountWhat it holdsSet-up detail
Primitives27The raw palette: ink, stone, sand, sage, clay, alpha whitesHidden from pickers (no scopes), so nobody can apply a raw hex by mistake
Color35Semantic roles: bg/glass, text/secondary, border/glass, icon/inverse…Every value aliases a primitive; scoped to fills, text or strokes only
Spacing11A 4 pt scale, space/4 to space/32Scoped to Gap; bound to padding and item spacing in auto layout
Radius7radius/sm 9 to radius/full 999Scoped to Corner radius; bound per corner

How one token travels from palette to code

ink/600Primitive · hidden→ text/secondarySemantic · Text fill scope→ var(--color-text-secondary)Web code syntax→ ListRow · QtyBound in the component

Each semantic variable carries web code syntax, so a developer inspecting a layer in Dev Mode sees the CSS variable name, not a hex value.

ComponentVariantsPropertiesUX rule in its description
ListRowChecked = True / FalseName, Qty, Price (text); nested Checkbox instanceLaw of similarity: every row reads the same way
PantryCardStatus = Urgent / FreshName, Location, Qty, Days; nested ProgressBar and Expiry BadgeVon Restorff: only urgent cards use clay
TabBarActive = Home / Lists / Pantry / InsightsBuilt from TabItem instances plus the FABJakob's law: a familiar bottom bar
IconButtonGlass / Tonal / FABIcon: instance swap from a 15-icon setFitts's law: 44 pt minimum, FAB 56 pt
SectionHeader—Title (text); Show link (boolean)Proximity: label sits with its group
ProgressBar15 / 35 / 60 / 80 / 100%Fill uses a Scale constraint, so it resizes with the barGoal-gradient: visible progress
Button · Chip · Badge3 · 2 · 2 stylesLabel (text)One primary action per screen
What made it easy · 1

Aliasing

Semantic tokens point at primitives. To warm the whole palette, I only edit the 27 primitives; all 35 semantic colors follow, across every screen.

What made it easy · 2

Scopes

Text colors only show up in the text picker, gaps only in gap fields. Fewer wrong choices meant fewer fixes, and it would help anyone else using the file.

What made it easy · 3

Properties over variants

Text, boolean and instance-swap properties keep the variant count small. TabItem has 2 variants, not 2 × 4 icons × 4 labels.

What made it easy · 4

Nested instances

PantryCard nests ProgressBar and Badge. Fixing the bar once fixed every card in the pantry.

What made it easy · 5

Styles for recipes

The glass look is one effect style (background blur 24 + soft shadow). Applying it is one click, and tuning it updates every panel.

What made it easy · 6

The why travels

Each component description states the UX rule it follows, so the reasoning shows up in Dev Mode and in reviews, not in a separate deck.

How I used AI

I worked with Claude, connected to Figma, to script the repetitive set-up: creating the variable collections, generating component variants and placing keyframes. The research, scope, palette, rules, layouts and every design decision are mine, and I reviewed and adjusted everything it built. It saved hours of clicking, not thinking.

Inspect the file

Click around a slice of the Figma file

A small, interactive copy of the components page. Select a layer or click anything on the canvas to see its variables, auto layout and properties, the way they're set up in the real file. Purple fields are bound to variables.

Pantri · app / Design system
100%
# Color tokens
text/secondary
bg/accent
text/warn
bg/glass
❖ Components
✓Spinach1 bag$3.49
Greek yogurtFridge · 1 tub
1 day
Add all to pantryReview
HomeLists+PantryInsights
Interactive fileClick a layer or anything on the canvas to inspect it
Prototyping & motion

Motion that confirms, never decorates

I prototyped the three moments where feedback matters most: first as Smart Animate flows for testing, then as timeline animations in Figma Motion for handoff. Each one confirms an action within the 400 ms the Doherty threshold suggests.

MomentWhat movesHow it's builtWhy
Check off an itemCheckbox springs 1 → 1.18 → 1, the line strikes through, the counter and bar updateSmart Animate between ListRow variants; spring easingInstant confirmation; progress pulls toward finishing
Scan to pantryScan line sweeps, items pop in a 120 ms stagger, the sheet risesAfter-delay trigger (1.6 s), then Smart AnimateShows the system is working, then hands back control
Quick addThe + button grows into the sheet: width, height, radius and position togetherMatching layer names so Smart Animate morphs one into the otherThe sheet visibly comes from what you tapped
Figma Motion timeline with keyframe tracks for scale, position and opacity.
Keyframes in Figma Motion: each track is one property change, so timing is visible and easy to hand off.
Frame from the check-off motion study, exported from Figma Motion.
The check-off study, exported to MP4 straight from Figma.
  • Spring easing only for confirmations; standard ease-out for layout changes.
  • Every duration is between 180 and 600 ms.
  • With Reduce Motion on, every animation falls back to a simple fade.
New in Figma · Config 2026

The newest Figma features, each tied to a Pantri problem

Instead of demoing features for their own sake, I used Pantri as a test bed and asked what each new tool could do for this product. Some became part of the work, others are experiments I'd keep exploring.

Custom shader experiment: an animated aurora fill behind a glass card.
Shaders

A living background for the glass

I wrote two custom WebGPU shaders: an animated "Liquid Aurora" fill and a cursor-following "Glass Ripple". The glass needs something soft behind it; a shader does that without heavy image files.

Generative plugin panel filling list rows with grocery data.
Generative plugins

Real-looking data, instantly

A working plugin that fills list rows with realistic grocery items, quantities and prices. Testing a list full of "Item 1" hides real problems like long names.

Figma agent experiment working on the Pantri file.
Figma agent

Busywork, not decisions

An experiment handing the agent repetitive tasks like making variants and renaming layers, while layout and judgment stay with me.

Weave experiment generating food imagery.
Weave

Imagery for dinner ideas

Exploring generated food images for recipe cards, so concepts don't depend on stock photos that never match the dish.

Code layer experiment rendering a live component on the canvas.
Code layers

Closer to what ships

A live code layer on the canvas, to check how a component behaves with real interaction before handoff.

3D transform experiment with tilted phone screens.
3D transforms

Presentation without leaving Figma

Tilted device layouts for the cover and Behance shots, built natively instead of in a separate 3D tool.

Accessibility

Glass that still passes WCAG AA

Glassmorphism is known for failing contrast. I measured every text pairing against the blended glass color, not the raw token, because that is what people actually see.

PairingRatioNeedsResult
Primary text on glass14.6 : 14.5 : 1AA pass
Secondary text on glass6.7 : 14.5 : 1AA pass
Clay "1 day" tag5.4 : 14.5 : 1AA pass
Light text on sage button7.3 : 14.5 : 1AA pass
Checkbox border on glass3.2 : 13 : 1 (non-text)Pass, narrow margin
  • Every touch target is at least 44 × 44 pt; the Add button is 56 pt.
  • Status is never color alone: urgency tags always say how many days are left.
  • Icon-only buttons have labels such as "Add by voice" for screen readers.
  • Planned: Reduce Transparency swaps glass for solid surfaces, and text styles map to Dynamic Type sizes.
Validation plan

How I'd prove it works

The prototype is ready for a moderated test with 5–6 home cooks, ideally including the people whose stories started this. I set the targets before testing, so the results can prove the design wrong.

TaskMetricTargetTests which decision
"Find something for dinner tonight the kids will eat"Time and successUnder 60 s, 5 of 6Cook from your pantry, filters
"This recipe needs heavy cream. What can you do?"Picks swap vs. buySwap found unaidedSwaps before shopping
Add "2 lemons" to the listTime on taskUnder 5 sOne Add button
Restock the pantry after a shopTask success5 of 6 unaidedReceipt scan sorting
OverallSUS score80 or moreThe whole experience

After launch I'd track meals cooked from pantry suggestions, swaps accepted, and items marked "used" before expiry. The north star is food saved from waste per household.

Reflection

What I learned, and what's next

Learned

Listen in the real setting

Talking to cooks at a competition, not in a meeting room, showed me the real question is "what's for dinner?", not "how do I organize my list?". That shifted the whole product toward cooking.

Learned

Write the rule into the component

Putting the UX reasoning in each component's description made reviews faster. The why travelled with every instance.

Next

Test, then cut

Run structured interviews and the test above. Validate the swap and scan bets first, since everything downstream depends on them. Then add dark mode as a second token mode.

Open the Figma files

Duplicate on Figma Community ↗

Pantri is a self-initiated concept by Shivani Harode, 2026. Research came from informal conversations and is treated as direction to validate. The food-waste figure is the USDA's estimate.