DEV Community

Cover image for Sobremesa: Six meals in Mexico, heritage without an address.
L. Cordero
L. Cordero Subscriber

Posted on

Sobremesa: Six meals in Mexico, heritage without an address.

Frontend Challenge Perfect Landing Submission 🍲🥧

This is a submission for Frontend Challenge - Comfort Food Edition, Perfect Landing

Mexico is our heritage. Yet, we have no family there to visit.

That sounds sadder than it is. What it actually meant, for the years before my wife and I were married and most of our time off since, is that we had to go find it ourselves. No family kitchen waiting. No grandmother's recipe with an address attached. Just the two of us and a country that is ours and that we did not know.

So we did what every hungry person in a new city does...we ate.

Six cities, six completely different cuisines, and somewhere in there it stopped feeling like traveling. A tlayuda from a stand outside Santo Domingo in Oaxaca. An hour in line at El Yaqui with a michelada in Rosarito. Different food every time. Same feeling every time, and there is no English word for that feeling.

There is a Spanish one.

What I Built

Sobremesa is the time you stay at the table after the food is gone, still talking. Not the meal. The part after the meal.

That is the whole site. Six meals across six Mexican cities, and the thing it measures is not how good the food was. It is how long we stayed.

Tijuana, one hour. Rosarito, two. Ensenada, one. Guadalajara, ninety minutes. Mexico City, two hours. Oaxaca, two. The page adds them up at the end. Nine hours and thirty minutes at six tables.

Comfort food usually means a kitchen you can go back to. We do not have one over there. So the six tables became it. The stand at Plaza Santo Domingo is the family table. The hour in line at Tacos El Yaqui is the Sunday afternoon table.

Each entry has the dish, where we ate it, one verified fact about the food, and one line that is just ours, from our experience. There is a form at the bottom where you add your own table and download a card of it, generated in your browser. Nothing gets sent anywhere.

One static HTML file. No framework, no build step, no tracking, no cookies, no storage. Two fonts off Google Fonts and nothing else. Designed and built in Claude Design, with the research, the fact-checking and the accessibility spec done in Claude, and the illustrations generated in ChatGPT.

Demo

Live site: https://sobremesa-dev.vercel.app/

Source: https://github.com/earlgreyhot1701D/sobremesa (MIT)

GitHub logo earlgreyhot1701D / sobremesa

DEV.to Frontend Challenge entry, Comfort Food Edition. Sobremesa is Spanish for the time you stay at the table after the food is gone. Six meals, six Mexican cities, fourteen years, measured in minutes. Single static HTML page, zero dependencies, zero tracking, WCAG AA contrast computed rather than eyeballed.

Sobremesa

Sobremesa banner — illustrated Mexican dishes on hand-painted talavera plates

Six meals, six cities, one country.

Sobremesa is the Spanish word for the time you stay at the table after the food is gone, talking. There is no English equivalent.

This is a record of six meals eaten in six Mexican cities over fourteen years, organized around one number: how long I stayed at each table.

Live: https://sobremesa-dev.vercel.app/ Write-up: [add your dev.to post URL]

Submitted to the DEV Frontend Challenge, Comfort Food Edition, Perfect Landing prompt.


What it is

A single static page. No framework, no build step, no dependencies, no tracking, no cookies, no storage.

Six entries, each with a dish, a place, a verified fact, a personal note, and a duration. The durations are summed at runtime. At the end, a form lets you enter your own table and download a card of it, generated entirely in your browser.

Running it

There is nothing to install.

Enter fullscreen mode Exit fullscreen mode

Try it with the keyboard. Tab through it, open a few tables with Enter or Space, and turn JavaScript off if you want to see the whole thing still read.

Sobremesa: the hero, the word, its definition, and the six meals below it

Journey

Planning and research handed me a dish I had never eaten

San Miguel de Allende is one of my favorite places in the world. But when I built this I realized it does not really have a signature dish. Most of what gets served there belongs to the wider Bajío. Research turned up fiambre sanmiguelense, a cold plate of pickled vegetables and shredded meat that shows up around Christmas and then vanishes for a year. It fit the slot perfectly.

I have never eaten it.

So instead I happily pivoted to Rosarito, along with Tacos El Yaqui where I have waited in line for an hour. I can tell you the line takes you past the wood fire where the carne is grilled and that they sell micheladas while you wait in it. Sobremesa started before the food did.

Placeholder data is sneaky

Early on I dropped fake durations into the array so I could see the layout. One hour five. Two hours twenty. Forty-five minutes. They looked plausible, and they survived about six rounds of design work before I noticed that five of my six headline numbers were invented.

Every duration on the live site is a real estimate now. Mexico City is two hours because we sat there for two hours.

Half the good food facts turned out to be folklore

I fact-checked every claim about every dish, and a lot of the best-sounding ones did not survive.

The Baja fish taco was not invented by Japanese immigrants adapting tempura. There is no documented evidence chain, only the fact that Ensenada had Japanese fishing families in the early twentieth century. Adjacency is not a source.

Birote salado, the bread a torta ahogada depends on, absolutely can be baked outside Guadalajara. Bakers abroad publish working formulas. The impossible-to-reproduce line is tourism copy that everyone repeats and nobody supports.

And every accidental-discovery origin story is legend, not history. A vendor in Guadalajara drops a sandwich in salsa and invents the torta ahogada. A girl in Oaxaca over-curdles the milk and invents quesillo. Caesar Cardini runs out of ingredients in Tijuana and invents the Caesar salad. Three cities on this page, one folk template.

The legends stayed off the page, which made the entries shorter and better. What is left is checkable. The beef for a Tijuana asada taco comes up from Ciudad Obregón, Sonora. El Huequito opened in 1959 and El Tizoncito in 1966, both claim tacos al pastor, and the page says plainly that neither claim is settled.

The prettiest thing on the page was quietly breaking it

I had a paper grain texture over the whole page. Multiply blend, low opacity, the thing that makes flat cream look printed instead of rendered. It looked great.

It was also multiplying my text. Not just the backgrounds. Every glyph, dragged down by a texture whose darkest pixels were pure black. Three color pairs fell below WCAG AA and nothing on screen looked wrong. You cannot see a 4.35 contrast ratio. You can only compute it.

The fix was moving the grain from an overlay above the content to a per-surface background layer, so it multiplies against the background color only and never touches a glyph. The texture got regenerated with bounded alpha so the worst-case pixel is computable rather than pure black.

Then every foreground and background pair was recomputed as composited under the grain. Twelve pairs, all passing, with the tightest one landing just above the 4.5 line. That pair has no headroom left, so it is written down in the README where future me will trip over it.

The rest of the accessibility work is baked in. One h1, no skipped levels. Real buttons, never a clickable div. aria-expanded verified in the accessibility tree instead of trusted from the source. Focus that never gets lost. Every Spanish word wrapped in lang="es" so a screen reader does not pronounce micheladas with English phonics, which matters a great deal on this particular page. Every entry, fact and note present in the HTML, with JavaScript collapsing the panels on load rather than rendering the content, so the whole thing reads with JS off.

About the illustrations

The six dish illustrations are AI-generated, and the page says so in the footer:

Illustrated from memory. Fourteen years, and we photographed almost none of it consistently.

Which is true. We were eating, not documenting. An illustration that announces itself as one is fine. A render pretending to be a photograph is not.

How it was built

Multi-LLM, split by what each one is good at, which is what works for me.

Claude did the research and the architecture. Six cities of food history, fact-checked against sources, with a written record of every claim that got cut and why. It also wrote the requirements spec, which turned out to be the single highest-leverage document in the project. Numbered requirements, testable acceptance criteria, zero visual direction. Handing a builder "make it accessible" gets you nothing. Handing it "every disclosure has aria-expanded reflecting real state and aria-controls pointing at a real id, verified in the accessibility tree" gets you something you can check.

Claude Design built the page. I fed it the requirements doc with no aesthetic direction at all, deliberately, because my own art direction had been the problem for two days straight. Left to solve the spec on its own it produced something better than what I had been pushing toward. It also caught things I would not have: the empty photo slots had alt="" without aria-hidden once the 404 fired, and it fixed that unprompted.

ChatGPT generated the six dish illustrations. One shared style block, then the first accepted image attached as the reference for the other five, which is the trick that stops a set of six from drifting into six different styles.

I direct. The agents generate. I validate and decide. Every fact on that page was verified against a source and every design call was made by a human (me!), including the ones where the human was wrong for a while.

The code itself is small. All six entries render from one array. DOM gets built with createElement and textContent, never innerHTML. Every color and spacing value comes from a token, so nothing is hardcoded in a component rule.

Attribution: index.html is original to this submission and contains no third-party code. The repo also carries the Claude Design component it was authored in, under /design, which is not deployed. Type is Alfa Slab One, Crimson Pro and Oswald, all SIL Open Font License. The six dish illustrations and the hero were generated for this project. MIT licensed.

Frontend is freedom

Most of what I build has a backend behind it. Auth, data models, an API that can fail in twelve different ways, a schema I will regret in a month. This had none of that. One HTML file, no server, nothing to deploy but a folder.

What that bought me was room to be wrong and keep iterating. I rewrote the visual direction twice and the cost was a git checkout. No migration to undo, no state to reason about, no data to corrupt. Being able to throw out a whole design at ten at night and start over is a luxury I do not usually get.

I went in thinking of the no-backend part as a constraint. It was a break and allowed me to be more creative when I skew utilitarian.

What I would do differently

The type scale is in pixels, so browser text-only zoom will not enlarge it. Page zoom works, so it is not a strict AA failure, but it is a real gap for anyone who sets a minimum font size. A rem conversion is first on the list.

The part that is not about code

We are still going strong. There are now more than six meals I'd love to share: Valle de Guadalupe, Querétaro, Guanajuato y más, y más, y más!

But these are the six where we sat down and did not want to get up, in a country that is ours and where we know almost no one, and the food is how we got there.

Six out of many. Provecho.


Quick context if you are new here: I came to code from the courtroom. Jury services to AI builder since July 2025, self-taught, learning in public. I direct, the agents generate, I validate and decide.

AI Assisted. Human Approved. Powered by NLP.

Top comments (0)