All work

Case study · 03

Food Origin.

Search a dish and walk backwards through it. Seventeen exhibits, a hundred and thirty-three dated versions, and every single one of them labelled with how sure the research actually is.

Role
Design, front-end and research pipeline — solo
Type
Research product · single-page app
Status
Live — as a fixed collection (see §06)
Scope
17 exhibits · 133 dated versions · a recipe per version
Built with
Next.js, React, TypeScript; a two-pass research pipeline in development
Live at
/foodorigins

What it is

Every dish has a past.

Search a dish. What comes back is not an article about it — it is an exhibit: a timeline of that food’s own versions, newest first, each one a different thing with a different name, a different place, and its own working recipe.

Pizza is eight versions from a dressed flatbread in 600 BCE to the European Union fixing Neapolitan pizza in law in 2009. Bread is eight, starting at roughly 12,400 BCE. Biryani is seven, from a Persian pulao to the most-ordered dish in India. You do not read down a page; you move along a rail, and the whole stage crossfades under you.

A Food Origin exhibit: a round bowl of biryani centred above the headline India's Most-Ordered Dish, with the year 2024 set very large and pale behind it, and a timeline rail of seven dated versions along the bottom.
One version of one dish The year sits behind everything as a ghost. The rail along the bottom is the whole timeline — seven versions, 500 BCE to 2024.
17 Exhibits

Researched, written and sourced in full.

133 Dated versions

Six to twelve per dish, each its own era.

4 Confidence tiers

Documented, well supported, reconstructed, uncertain.

66 Images, typed

Photograph, artefact, illustration or recreation — declared.

Counted from the source, not estimated — 121 authored nodes across 16 dish files, plus the 12-node seeded Ramen exhibit.

The problem.

Food history is one of the most written-about subjects there is, and almost all of it arrives in the same two shapes: a listicle (“ten foods you won’t believe are ancient”) or an academic paper. The first is confident and unsourced. The second is sourced and unreadable.

Between them sits the thing a curious person actually wants, which is neither a fact nor a bibliography: a sense of change. Not “pizza is from Naples” but the eight distinct objects that have carried that name, in order, and what made each one turn into the next.

The other half of the problem is the one every food-history claim has: the record is uneven. Some of it is legislated fact and some of it is a reasonable guess about the Neolithic. A product that flattens those into the same voice is lying, and a product that footnotes every sentence is unreadable. That tension is what §04 is about.

A museum, not a feed

The vocabulary of the whole product is a museum’s. Dishes are exhibits. Eras are versions. A dish that has not been researched yet is a gallery that is closed. That is not decoration — it sets the expectation that what you are looking at was assembled by someone, deliberately, and that some rooms are not open.

Three decisions that follow from it

Backwards, not forwards. The timeline opens on the present and walks into the past. You start with the thing you have eaten, which is the only version you have any purchase on, and each step back takes something away.

One version fills the screen. There is no scrolling list of eras. The stage holds exactly one — portrait, era label, title, place, summary, and the year set enormous and pale behind all of it. Changing era crossfades the image, the text, the recipe and the rail indicator in place; nothing reloads and nothing navigates.

The rail is the map. The bottom of the screen carries every version at once, dated, so the shape of the dish’s history is visible even while you are inside one moment of it. Drag it, or use the arrow keys.

The Food Origin landing page: the headline Every dish has a past above a single search field, with a row of nine round dish thumbnails beneath it. A Bread exhibit showing its most recent version, with the year set large and pale behind a round photograph, and the timeline rail beneath.
Left one field and nine doors — the landing page does not explain itself, it just opens. Right the exhibit, entered.

How sure is this, exactly?

Every version carries its own confidence rating.

The data model has four tiers — documented, well-supported, reconstructed, uncertain — and every one of the 133 versions has one. Across the library they land like this:

  • 45 documented. There is a record. The 2009 EU regulation fixing Pizza Napoletana is one of these.
  • 40 well supported. Not legislated, but not in dispute either.
  • 21 reconstructed. Built from period sources rather than from a surviving recipe.
  • 15 uncertain. Said out loud rather than smoothed over.

Where the label goes

On the era line, in the same breath as the period. Not a footnote, not a tooltip, not an info page:

VERSION 2 OF 8 · NEOLITHIC FERTILE CRESCENT · RECONSTRUCTED

And — the detail that makes it work — documented prints nothing at all. A label on every version would become wallpaper within two clicks. Printing it only when the answer is anything less than documented means the label is always news. The component’s own comment says why: “Historical honesty belongs on the label, not in a footnote — and folding it in here keeps the stage exactly as tall as designed.”

The same discipline on the images

Historical periods do not have photographs. So every image declares what it actually is — photograph, artefact, illustration, recreation or placeholder — alongside its credit and licence. A modern recreation of a Neolithic loaf is never allowed to sit on the page pretending to be evidence.

A Bread exhibit at version 2 of 8, with the era line reading Neolithic Fertile Crescent, Reconstructed, above the title Quernstone Grain Bread. A Tacos exhibit at version 1 of 7, with the era line reading Formative Mesoamerica, Reconstructed, above the title Nixtamalized Maize and the First Tortilla.
The label in place, twice. Both of these are honest admissions, and neither of them interrupts the page to make one.

Every version is cookable

Under each exhibit there is a full recipe, and it is the part that turns the timeline from a reading experience into something you can act on. It carries more than ingredients and steps:

  • A modern stand-in per ingredient, where the historical one is unavailable or impractical — Mozzarella di Bufala Campana DOP, 250 g followed by TODAY · FIOR DI LATTE, DRAINED OVERNIGHT.
  • Traditional method and modern adaptation, separately. The traditional entry for Pizza Napoletana describes a domed wood-fired oven and a pizzaiolo turning the pizza two or three times in ninety seconds. The modern one admits that a domestic oven cannot reach 485 °C, and tells you what actually gets closest.
  • Historical notes, where the record is contested. Pizza’s says, flatly: “The STG specification is a legal document, not a historical one. It codifies mid-twentieth-century Neapolitan practice, which is not identical to nineteenth-century practice — the dough is wetter and the ovens hotter than they would have been in 1889.”
  • Why it changed — the sentence that connects this version to the next one along the rail.

That last pair is the whole product in miniature. The recipe is usable, and the page tells you what is legislation and what is practice, in the same panel, without making you choose.

A Biryani exhibit on a phone: the round dish photograph, the version label, title and summary stacked, with the timeline rail across the bottom.
On a phone The exhibit stage subtracts the measured navigation height from its full-viewport section rather than assuming 100vh, so the timeline rail stays above the fold on short screens instead of falling off the bottom.
The recipe panel for Pizza Napoletana: ingredients with modern substitutions, four numbered cooking steps, and sections headed Traditional Method, Modern Adaptation and Historical Notes.
The full recipe Ingredients with substitutions, numbered steps, then the three prose blocks that carry the honesty: how it was done, how to do it now, and what the record actually supports.

Two builds, and the difference matters

This is the thing to be exact about, because it is the one claim a project like this can most easily overstate.

  1. What is published at /foodorigins
    static export

    A fixed collection of 17 exhibits. No server, no API route, no key, no research happening anywhere. Every one of the 133 versions was researched, written and sourced before the build, and is bundled as data. Searching for anything outside the 17 cannot produce a new exhibit, and does not pretend to.

  2. What exists in development
    next dev, with a key

    A working research pipeline. Search any dish and it is researched live — web search, a schema-constrained structuring pass, Wikimedia image lookup with real attribution, and the result cached. See §07.

How the deployed build says so

Search for something outside the collection and the empty state does not apologise vaguely or offer to “try again”. It names the situation and then lists every room that is open:

This build of the archive is a fixed collection — 17 exhibits, researched and written in full.
Food Origin · the empty state
The empty state: the heading Gallery Closed, the line The Khichdi exhibit is still being assembled, a paragraph explaining that this build is a fixed collection of 17 exhibits, the full list of available dishes, and a link to view the Ramen exhibit.
Gallery closed It names the dish you asked for, says why there is nothing, lists all 17 that are open, and offers one of them. A dead end that is still a door.
Why it ships this way on purpose

A static export has no server to hold an API key and no per-visit research cost. The build script moves the API route aside for the duration of the build and puts it straight back — including on failure, via a trap — so the source is never edited to make the deploy work.

The trade is real and it is the right way round: the public gets 17 exhibits that are finished, checked and free to serve, instead of an unlimited search that would sometimes be wrong and always cost money.

The research pipeline

In development, a search runs through six stages:

querycacheresearchstructureimagesstorerender

The interesting part is that research and structuring are two separate passes. The first has web search and writes a prose brief. The second has no tools at all, so it can only reformat what the first pass already established, and its output is constrained to a JSON schema. A model that cannot reach the internet cannot invent a source during the tidying-up step.

What the prompt forbids

The accuracy rules are written into the prompt as constraints, not suggestions:

  • “Never invent an event, a date, a person, or a recipe. If the record is thin, say the record is thin.”
  • “Where several theories compete, present the best-supported one and name the others as disputed.”
  • “Distinguish clearly between: an attested recipe, a reconstruction from period sources, and an informed guess. Label which you are giving.” — which is exactly where the four confidence tiers come from.
  • “Popular etymologies and origin stories are usually tidier than the truth. Flag them when you repeat them.”
  • Optional fields with nothing to say take an empty string — never a placeholder like “unknown” or “N/A”.

It also has a refusal path. If the query is not a real food with a traceable history, the first pass replies NOT_A_DISH: <one sentence> and the pipeline stops there rather than producing a confident timeline for something that does not have one.

Images it will not fabricate

Image lookup goes to Wikimedia Commons with real per-image attribution, and falls back in a fixed order: a modern example of the dish, then the design’s own hatched paper texture. It never generates a historical photograph, because there is no such thing as a photograph of Neolithic bread.

What this is and is not

It is an authoring tool — a way for one person to research and draft an exhibit far faster than by hand, with the honesty constraints built into the process rather than remembered afterwards.

It is not what serves the public site, and it is not a claim that the output is unsupervised-safe. All 17 published exhibits are written and checked; the pipeline is the reason there are 17 rather than three.

Where it stands

Live at /foodorigins: 17 exhibits, 133 dated versions, a full recipe under each one, sources per version, typed and credited images, and an empty state that tells the truth.

The data model was built for more than currently exists, and says so in its own comments: nodes already carry country and city for a map, ingredients are structured with substitutions for an ingredient-evolution view, sources is already per-node for a source viewer, and nodes can become a tree without touching the rendering contract, for dishes whose history genuinely branches.

Honestly unfinished

Seventeen dishes is a small museum. It covers the obvious global canon — pizza, ramen, sushi, coffee, tea — and the gaps are exactly where a food archive is most worth having. The pipeline exists to close that gap; nothing has closed it yet.

The built-for-next-phase features are not built. The map, the ingredient view, the source viewer and branching timelines are all shapes the model can carry and none of them exists in the interface.

No public research. Turning the pipeline on for visitors would need a server, a key, a cost model and a review step for anything it produces. That is a product decision, not a technical one, and it has not been made.

If the record is thin, say the record is thin.
Food Origin · the research prompt

The live archive

Search a dish.

Seventeen rooms are open. Bread goes back to roughly 12,400 BCE, and every version of it comes with a recipe.