The problem
Two people, two diets, one kitchen and one grocery order. One eater is vegetarian, the other omnivorous, each with their own macro targets and their own habits. Most meals are eaten alone, a few at the weekend are shared, and cooking happens in batches on Sunday.
Planning that by hand means juggling the diets, the week’s Migros promotions and whatever is already in the cupboard, then typing the basket in line by line.
The product
Popote plans one week of lunches and dinners for a household of two. Every meal has a recipe and per-person macros (kcal, protein, fat, carbs). Meals are grouped into cook sessions, so a few Sunday batches feed several days.
Shared dinners are split meals: one common base, animal protein for one plate, plant protein for the other. Each slot is shared or solo, chosen per slot.
Changes are made by saying them, by text or voice: « change Thursday dinner to something faster ». The app shows a diff, then re-totals the day, the week, the list and the basket in one pass.
The shopping list is matched to real Migros products, prices and promotions, and added to the Migros Online basket. Checkout, pickup slot and payment stay with the user. The interface is in French.
How it’s made
Popote is a Next.js App Router application in TypeScript on Postgres, with Drizzle migrations and pg-boss for background jobs. It runs in Docker, self-hosted on a Coolify instance, and installs as a PWA with push notifications and an offline page.
The language model sits behind a gateway with Anthropic, DeepSeek and OpenAI providers, switchable from a settings page, with a soft monthly budget and a cost panel. Speech-to-text and read-aloud in cook mode have their own ports. The pure domain code lives in src/core, and the linter fails the build if it imports from the rest of the app.
The Migros side is an adapter over unofficial endpoints. A fake adapter and a scripted fake model drive the tests, so the main paths run offline. Popote is independent and not affiliated with Migros.
The product was built with Claude Code agents working from GitHub issues, each in its own git worktree, merged only when CI is green.
Details
The visual direction, Surimpression, comes from Zurich-school posters and process-ink printing: paper, a key black, two person inks, their violet overprint, and one spot orange taken from the logo. Square corners, hairline rules, no shadows, no gradients. Archivo is used on its width axis, condensed for data and normal for reading.
The logo is a cloche over a shopping cart with a lightning bolt. It is animated as a glyph: it simmers while a week is composed, drops its lid when ready, and drives along a road on the landing page as you scroll. A motion gate in the test suite rejects raw durations and animated layout properties.
The 30-second film is built only from this system, on 128 BPM bars. The names in it are invented for the example.