View

The work, at a glance.

AI-native

They asked me to redesign a meal page. I built the machine underneath it.

Livin is a personal chef platform run by a small team. Nobody owned product, so I took the seat: product lead, designer, and design engineer in one. They brought me problems. I wrote the PRDs and built what came out of them.

ROLE · Product Design, Design Engineering, GrowthCLIENT · LivinYEAR · 2026

Role and team

Embedded with the team. On their side: a founder, a lead engineer, and a customer service lead. On mine: me, plus a product designer from my studio through Q1. Built on Next.js, Sanity, Tailwind, Vercel and PostHog, alongside their Rails app.

How it started

Chefs cook in your home and people love it. Then they open the app.

The in-person experience was the whole company. The product around it wasn't close. The founder came from marketing, one engineer held the entire codebase, and product had no owner. I came in Q1 2026 to be that owner, brought a product designer from my studio, and started by auditing everything a customer touches. By Q2 the team was smaller. Marketing had left, my designer had rolled off, and what shipped after that shipped with four people on it.

Q2

The menu was eating whole weeks

On paper, Q2 was a marketing site. Probably Framer. But the meal page wasn't the problem. Every menu update crawled through a Rails dev cycle, and a seasonal menu cost the founder weeks of manual work. A prettier page wouldn't touch that. So I pitched the machine instead: the menu as structured data in Sanity, a Next.js front end on Vercel, and every future surface inheriting both. They said yes. Everything below this line comes from that yes.

One content model

Dish catalog
630 dishes
Ingredient graph
1,073 ingredients, macros derive
Label vocabulary
45 computed labels
One query layer
buildDishQuery(labels[], operator)
  • Local/[city]/[neighborhood]86 liveSomeone searching their own zip.
  • Search/meals/[slug]36 liveA stranger finds it on Google, months from now.
  • Identity/for/[slug]24 liveSomeone who already knows what they need.
  • Comparison/alternatives/[slug]10 liveSomeone weighing us against someone else.
  • Partner/with/[slug]3 liveA partner's audience, attributed.
Onboarding
the door you came through picks the flow
Add a dish and every surface above inherits it.

The menu

630 dishes, modeled once, reused everywhere

Every dish became structured data. 1,073 ingredients carrying nutrition profiles in a relational graph, macros that derive instead of getting typed in, 45 health labels that fire against clinical thresholds. Add a dish and it inherits all of it. A menu drop went from weeks of manual work to a day or two, and every dish page came out the other side as a landing page, shareable and indexable on its own.

Filter down, then expand a dish. The nutrition is computed, not typed.

Demand

Four ways in. One vocabulary.

With the menu as a base, the site fanned out. Four ways people actually arrive: a search, a neighborhood, an identity, a partner. All of them generated from the same tagged data, about 160 pages in total. But a lander that drops you into generic signup wastes the click. So every identity lander, all 24 of them, hands off to its own onboarding written to that person's real problem. Someone landing on diabetic meal delivery gets asked about diabetes, not about their zip code.

Fitness, cancer, fertility. Three doors, three different first questions.

The bet

Diabetic, dinner already fits the diet, so they stop cooking

becomes a querydiabetic-friendlylow-sugarAND

from 630 dishes · 45 shared labels

/meals/diabetic-meal-delivery

×36

A stranger finds it on Google, months from now.

labels[] + labelOperator

/onboarding/diabetes

×24

The same person, already clicked, guided.

dishQuery

already liveNew parentsGLP-1CaregiversCancerSurgery recovery

159

landing pages live

$0 paid traffic

One vocabulary. Two surfaces. A new persona is a query, not a build.

Supply

The recipe engine

The doors outpaced the catalog. 160 pages want more than the kitchen can write recipes for, and nobody writes at lander speed. So I built the tool nobody asked for. Describe a dish in plain language and it comes back a chef can actually cook: recipe, computed nutrition, and menu copy, all verified before it can publish. It feeds the internal menu tool, the customer plan AI, and the landers from one source.

doesn't ship
Brief
plain language
Generate
recipe + nutrition + copy
Verify
checked against the goal
Publish
chef-ready

Marathon training, mostly plant-based, kid only eats mild food.

Charred Lamb Kebabs
Lamb kebabs · Whipped hummus · Cucumber salad & rice
44g proteinGluten-freeHigh-protein
Charred lamb kebabs with whipped hummus, roasted butternut squash, and herbed quinoa.High-protein
Charred Lamb Kebabs
Whipped hummus, rice & cucumber salad.
Brief to verified dish.
The pipeline as five tools. Check dish is the gate every dish has to pass.

The foundation

They said no to my stack twice

My first question on day one was whether I could ship React. No. Rails, and a contract dev shop. So we did it the traditional way: design in Figma, buy dev seats, hand it over. Features took 30 to 90 days, and most of that was waiting. I pitched Next.js again when we took the menu to existing customers. No again. That's when I stopped asking. The React system I'd been building since Q1 compiles to livin-tokens.css and standalone HTML, and HTML drops into Rails without touching their stack. Now an idea on Monday can be a working prototype by Friday.

The React design system, compiled into their Rails app.

In numbers

630
dishes
modeled in Sanity, 463 live to customers
1,073
ingredients
with nutrition profiles, in a relational graph
45
health labels
computed against clinical thresholds
159
landing pages
across four ways in, plus comparison pages
150+
design tokens
shared across every surface
30–90 → 5–14 days
feature cycle
before / after the prototype pipeline

Numbers as of July 2026.

Odds and ends

A few other things I made

A few things that didn't fit anywhere above, and are worth looking at anyway.

Also built

The receipts

Everything that shipped

  • July 202610 shipped
  • June 20267 shipped
  • April 20264 shipped

+ 210 smaller fixes & improvements

Switch to Details for every entry.

The meal page shipped, fast. So did the machine around it. Four people move like a department now, because the system underneath them compounds. The menu feeds the landers, the landers open onto onboarding built for that exact person, the recipe engine keeps the catalog ahead of both, and design leaves my hands as working code. That's the work I want to keep doing. Find the bottleneck under the ask, then build the thing that removes it for good.