I rebuilt my 2018 design capstone to integrate AI into my workflow, and to watch which parts of the process it automated, which it only augmented, and where the designer had to stay in the loop. Having the 2018 research behind me meant I could check the output against something already known to be true. What came out: a nine-screen prototype, a design system, and one written spec that drove both.
01 · Why this project
Foodies was my Interaction Design capstone for UC San Diego, taken through Coursera in 2018. It is a group dining app for the situation where a table has mixed dietary requirements and somebody still has to pick a restaurant. The main finding was that most of the constraints when choosing a restaurant came from religion, allergies and lifestyle, and that in unplanned work or social meals those requirements quietly got ignored.
I picked it over a new project because 2018 left evidence behind. Real interviews, a real heuristic evaluation, four usability sessions, an A/B test with a documented result, and a designer who still remembers building it.
AI output always sounds right. Having the 2018 research meant I could tell when it wasn’t.
02 · The process at a glance
The 2018 project was created during the 10 weeks that the module lasted. With the AI workflow every stage ran again in days rather than in weeks. The sequence did not fundamentally change: in 2018 I was gathering and producing, and in 2026 I was directing and checking. This is the workflow we followed:
Research
AIPopulation data, competitive scan, source synthesis
MeAdjudicated two prevalence figures that differed by 6x
Define
AIDrafted personas and problem statements
MeRejected a persona the evidence didn’t support
Ideate
AIGenerated on constraints I set
MeWrote the constraints; volume isn’t divergence
Flows
AIDiagram generation from written logic
MeSplit one lane into two
UI
AIDesign system and nine screens from a written spec
MeCalibrated the spec; caught two rule breaks
Prototype
AIBuilt the coded prototype from the same spec
MeVerified by click-through, not screenshot
03 · What changed in the design
The 2018 “Foodies” project was a manual design effort focused on organiser management. The 2026 reframe was a designer decision, not an AI output. It maintains this goal but pivots to a guest-focused model. By separating venue suitability (“match”) from the reliability of dietary claims (“confidence”) and replacing vague percentages with specific exclusions, the new model tells you who a venue excludes and how well that claim is sourced.
| 2018 | 2026 | |
|---|---|---|
| Structure | Eleven screens, one actor | Eight screens, two actors |
| Primary focus | Organiser-centric management | Organiser and guest, separate lanes |
| The guest | A row in a list to be selected | Declares privately, in their own flow |
| Matching logic | Percentage-based (85% match) | Named exclusion (“Excludes: 1 coeliac”) |
| Data integrity | Combined match score | Separate: match, and how we know |
| Non-response | Not represented | A visible gap, never counted as fine |
The flows were generated by Figma Make from the written scenarios, not drawn by hand. The win here is how fast they arrived: pulled straight from the written source, use-case.md, created in Claude. They still needed fine-tuning. Splitting them into two lanes was my call, one for each of the two personas, where the 2018 version had a single one. Figma Make sped up the drawing, but the fine-tuning was still mine.
Every path belongs to the organiser: create an event, add friends, pick a restaurant, send the invitation. There is no screen where a guest does anything. It is a navigational skeleton with no logic behind it, so the links move between screens but nothing is computed.
2026: eight screens, two actors. The requirement enters the system through someone who isn't the primary user.
04 · The eight moments
Eight moments across the process needed a designer in the loop. Six ran designer to AI, where I caught the model being confidently wrong. One ran the other way, where it caught me. One was a plausible convenience I turned down. None of them would have been caught by a faster process. Each needed someone who knew the domain, remembered the original work, and held the discipline when there was nothing forcing them to.
| # | Where | What happened | Direction |
|---|---|---|---|
| 01 | Research | Reproduced the framing it was given and missed that the 2018 app's own taxonomy put medical, religious and lifestyle requirements on one flat list | designer → AI |
| 02 | Define | Built a detailed persona the evidence didn't support. Caught by asking where the evidence came from | designer → AI |
| 03 | Ideation | Over-engineered a mechanism the 2018 profile screen already contained | designer → AI |
| 04 | Ideation | Drove past the stage gate into interface decisions two stages early | designer → AI |
| 05 | Design system | Turned a clarity principle into a visual language, producing a spec that was correct and lifeless | designer → AI |
| 06 | Screens | Broke the disclosure rule on the two screens where listing people is the strongest convention | designer → AI |
| 07 | Code build | Flagged that my own instruction had reintroduced the problem it was written to fix | AI → designer |
| 08 | Sample data | Offered a one-line change that would have made the prototype prettier and less true | declined |
05 · Three key decisions worth telling properly
The process above is where the work happened, stage by stage. There were specific moments where the model broke the rules, and they are the ones worth more detailed explanation.
DESIGN.md served as a single specification driving two different engines: Figma Make for visual assets and Claude Code for prototype logic.
In the prompt: design tokens vs. human intent
Figma Make followed the spec exactly. Every rule held, and nothing about the result made you want to open it.
I narrowed the rule instead of loosening it. Colour carries meaning in two places, the exclusion line and the confidence panel, and everywhere else it’s free.
The interface loses visual consistency. A sober line reads as serious because everything around it isn’t.
First run
Same tool, same designer, eight days apart. The difference is the spec.
First run
The tokens behind those screens. Same document, same seven roles, rewritten between runs.
The system Figma Make produced from the written tokens. Live, scroll inside the frame.
Open the design system full size →
View the source file in Figma (needs Figma access)
DESIGN.md is one written specification holding two different things: the design tokens, and the reasoning behind them. It drove Figma Make for the design system and screens, and Claude Code for the prototype, from a single file.
The tokens describe what it should look like. These describe what it must never do.
1. Never show a single percentage match. Named exclusion only. 2. Never let a preference match compensate for a medical or religious miss. 3. Never render non-response as "no requirements." 4. Never show who holds a requirement unless that person chose to. 5. Never infer a constraint the system was not told. 6. Never gate the survey behind sign-up. 7. Never return an empty result list. 8. Never use colour alone to signal exclusion or confidence.
Eight prohibitions did more work than the tokens.
Coeliac disease is a medical condition. Halal and kosher are religious observances. At a work dinner the organiser may be your manager, so the cost of a requirement becoming visible isn’t shared evenly around the table.
It held on three screens and broke on two:
Nobody told it to name anyone. It applied a summary convention on one screen and a roster convention on the other.
Rule broken
Every guest named against their requirement.
Counts only, with one guest shown by name because she opted in.
I explained why the rule existed rather than just what to change. It was applied. It didn’t carry to Waiting. That had to be found and fixed separately. Someone has to check every screen, already knowing what to look for.
Telling it what to fix gets you the instance. Telling it why the rule exists is what makes the rule portable, and even that did not carry it to the second screen.
This must not happen. It exposes medical and religious information
about named individuals to the organiser.
WHY THIS MATTERS
Dietary requirements here include medical conditions (coeliac, nut
allergy) and religious observance (halal, kosher). In a work context
the organiser may be the person's manager. A guest declares privately,
and on Screen 4 the "Show my name to the group" toggle is OFF by
default. That default must hold all the way through the flow.
Constraints don't fail where they're stated. They fail where a convention is strongest.
Authority was split across three sources: Figma for visuals, DESIGN.md for logic, and the brief for time-based interaction.
Problem: The Figma screen celebrates “Works for all 8” while its own header says two guests haven’t responded. I reviewed that frame and approved it.
Fix: DESIGN.md says celebration requires that everyone has answered, so the prototype ignored the drawing.
Takeaway: The writing caught what the picture couldn’t, and what I hadn’t.
Problem: It opened the austere palette first, on a page called “Design system”. That palette had been rejected weeks earlier and nothing in Figma said so.
Fix: Marked the dead version as dead, in writing.
Takeaway: A model reading your design files can’t tell a live decision from an abandoned one.
Problem: Taps stopped working on the exclusion links, and a vertical swipe inside a horizontal row of cards did nothing. Both looked fine in a still.
Fix: Checked the prototype with a script that actually tapped the elements at phone size.
Takeaway: A screenshot proves an interface looks right. It can’t prove it works.
06 · The prototype
A single self-contained file, built by Claude Code from the written spec. Nine screens, two actors. Every rule lives in one function, so no render path can break one:
Foodies2026/ ├── CLAUDE.md the build brief ├── DESIGN.md tokens, and the reasoning behind them ├── CASE-STUDY.md the working document └── index.html the prototype, one self-contained file
Press the control at the bottom to send a late reply from one of the guests.
The top result, the accredited venue, the one you’d trust most, is the card that gains an exclusion when that reply lands, and the list reorders around it. That’s the whole argument about non-response, and you can’t see it in a screenshot.
The green celebration state exists in the code and nothing in the demo reaches it. Priya’s late reply is kosher, and none of the five venues can accommodate it. One line would make it reachable. But a London venue that is halal, kosher and coeliac-safe at once is close to nonexistent, so leaving it unreachable is the honest version. Not a bug in the demo. The research finding, rendered.
Interactive prototype
Fully interactive. The control on the waiting screen fires a late response.
07 · Testing
Confidence works on exclusions but not on what a venue can do. A venue that’s genuinely accredited and one that just says it is look identical on the card. I found that by building it, not by thinking about it, and it’s the first thing I’d fix.
Then three things would need testing with people, and not the way I tested in 2018. Those sessions asked whether someone could complete a flow. This asks whether an interface communicates a risk honestly.
Read more
This page is the edited version. The full account, with the working notes behind each of the eight moments, is on Medium.
More work