Design

Twenty-five menu boards from one stylesheet

OlloVue·5 min read

A taqueria and a coffee shop want different menu boards. So does the same taqueria, on the screen over the bar versus the one at the counter. The usual answer is templates, and templates are a trap.

Once a product ships "designs," every new one is a new file. They drift. A fix applied to one doesn't reach the other nine. Eventually nobody dares touch the old ones, and the design system becomes a museum.

The way out is to notice that "what a menu board looks like" is really two independent questions that got tangled together.

Layout is not colour

Layout is how the dishes are arranged: photo tiles, a typographic list with dotted leaders, one hero photo beside a rail of names, three dense columns.

Colour is the ground it sits on: near-black, bright, a chalkboard slate, warm paper stock.

These have nothing to do with each other. A chalkboard is not a layout. A three-column grid is not a colour. But most template systems fuse them — "Chalkboard Menu" is one template, "Dark Grid" is another — and the moment you do that, you need one file per combination, and adding a fifth ground means building four new templates.

Keep the two axes apart and they multiply instead of adding. Five layouts and five grounds is twenty-five boards, not ten.

The rule that keeps it honest

The whole thing holds together on one constraint, written at the top of the stylesheet:

Layouts never declare a colour. Grounds never declare a layout.

Every colour in the board comes from a small set of tokens — background, text, dimmed text, the accent that prices use, the mark that rules and dots use, the card fill, the hairline. A layout may say "this row is a flexible dotted leader" but may never say "this row is grey." A ground redefines the tokens and nothing else.

Break that rule once and you're back to templates, because now one combination needs a special case, and special cases are how twenty-five becomes twenty-four working and one broken.

A three-column menu board on a warm paper background
Grid layout, paper ground. Neither knows the other exists.

What it costs to add one

A new ground — say a deep green slate for a place that wants a cantina feel — is seven or eight token values. No markup, no JavaScript, no new endpoint. It appears on every layout at once, and on every venue.

A new layout is a block of CSS and one number: how many dishes fit before the rows stop being legible across a room. Cards hold six. The typographic list holds eight. Single-column holds twelve.

That number matters more than it sounds. It's the difference between a board that looks designed and one that looks crammed, and it's the only thing a layout genuinely needs to tell the rest of the system.

One thing a system like this can't fix

We built the whole grid, rendered every combination, and then looked at them — which is the step people skip.

The dish names were being cut off. "La Única Mexican Street Corn Ribs" was rendering as "La Única Mexican St…". Not in some exotic new combination — in the default one, the one already on the wall in a real restaurant.

A guest cannot order a dish whose name is cut off. No amount of architectural elegance rescues that; it's just a bug, and it was found by rendering the actual output and reading it, not by reasoning about the CSS.

The system made the fix cheap: one rule, applied once, correct in every layout and every ground immediately. That's the real return on separating the axes — not the twenty-five combinations, but that the twenty-sixth improvement lands everywhere at once.

← All notes

Pick a look per screen.

Photo tiles at the counter, a chalkboard over the bar. Same menu, same prices.

Start free trial