D6 · The Fancy Tax

Capstone dossier · which dishes carry the upscale premium, and which refuse to

Author

Dei Martinez Elurbe

Published

July 2, 2026

Dossier, not the essay. Backstage layer for technical readers; the capstone essay is the general-audience artifact. Corpus: Snapshot · June 2026, ~900 priced venues, roughly 4 in 10 of Amsterdam’s ~2,028 restaurants.

The verdict

Upscale venues charge more, but not the way people assume, and they say “upscale” in two different typefaces. Menu fanciness speaks two text registers, and both carry a premium: the florid register (wordy descriptions) adds +2.7% per step of wordiness (95% CI +0.7 to +4.8), and the terse fine-dining register (ingredient-list menus, “word · word · word”) adds +7.1% of its own (95% CI +0.9 to +13.6). The terse register was the project leader’s catch: the original wordiness proxy misfiled exactly the venues that stopped writing sentences, and separating them out made the wordiness effect stronger (Decision #42).

The real finding is the heterogeneity underneath: the premium is not a flat markup, it concentrates in specific dish-types. Across 135 cells (florid register; terse venues set aside) the per-cell fancy tax runs from −21% to +36% per wordiness step (median +5%, interquartile range −2% to +10%). The pattern in which dishes carry it is the insight: the premium lives where there is no reference price, and disappears where there is one. Rice dishes (+20 to +24%) and bread-and-dips starters (+21%) ride it hard; the nominal top cell (generic meat sides, +36%) is retired below as a composition artifact after a dish-level audit. The commodities every diner can price from memory barely move: carpaccio +1%, fish of the day +2% on 860 dishes. An upscale venue extracts its margin through menu composition first (dossier D4) and through the fuzzy-priced corners of the menu second; it does not visibly mark up the dishes you would notice.

One caveat leads everything here, per the data-layer audit: per-cell estimates are noisy. Only 58 of the 135 cells individually resolve a nonzero effect at 95% confidence (51 positive, 7 negative). The aggregates and the pattern are solid; any single cell’s number should be read with its interval.

Why the obvious approach lies

“Fancy places are expensive” is mostly composition: they serve rib-eyes and raw bars, not bitterballen. D4 removes that channel and finds the same-dish premium is small: +2.7% per standard deviation (SD) of florid wordiness, +7.1% for the terse ingredient-list register. This dossier asks the next question: is that premium spread evenly, or does it hide in particular dishes? A flat markup and a targeted one look identical in the aggregate; only within-cell slopes can tell them apart.

The instrument: measuring “fancy” without touching price

Venue fanciness is read from menu text, never from price, so a fancy-tax estimate cannot be circular. And the text turns out to speak two registers:

  • The florid register is proxied by wordiness: the average character length of dish descriptions, log-scaled and standardized. A plain café writes “kipsaté”; this register writes “free-range corn chicken saté, house-made peanut sauce, pickled cucumber”.
  • The terse register is the modern fine-dining idiom: short, separator-built ingredient lists with no function words (“Noordzee krab → groene peper, lavasmayonaise, courgette”). Florid prose needs prepositions; ingredient lists refuse them, which makes the register machine-detectable. A venue is flagged terse when at least half of its described dishes match and descriptions cover at least 30% of its menu; 85 of 861 venues qualify.

The wordiness proxy alone misfiles the terse venues at the plain end of the scale, which attenuated the original estimate. Adoption of the two-register model went through pre-committed probes: the terse premium is sign-stable across a 3×3 grid of detector cuts, survives within all-rounder venues alone (+24%), and moves the café and area coefficients by less than a point. The per-cell slopes below are computed on florid-register venues only, so that the terse register cannot contaminate them the way it contaminated the aggregate.

What it found

Show the code
suppressPackageStartupMessages({library(dplyr); library(ggplot2)})

ft <- readr::read_csv("_data/fancytax_ci.csv", show_col_types = FALSE)

ggplot(ft, aes(tax_pct)) +
  geom_histogram(binwidth = 4, fill = "#d9a08a", colour = "white") +
  geom_vline(xintercept = 2.7, linetype = "dashed", colour = "grey30") +
  annotate("text", x = 2.7, y = Inf, label = "aggregate florid +2.7%/SD",
           hjust = -0.05, vjust = 1.5, size = 3.1, colour = "grey30") +
  labs(x = "Per-cell fancy tax (% per +1 SD fanciness)", y = "cells") +
  theme_minimal()
Histogram of per-cell fancy tax percentages centred near +5 with tails reaching minus 21 and plus 36, and a dashed vertical line at plus 2.7.
Figure 1: The distribution of per-cell fancy-tax slopes (135 cells, florid register). The aggregate same-dish effect (+2.7%/SD, dashed) sits near the median; the spread around it is the finding: some dish-types absorb the upscale premium, most do not.
Show the code
top  <- ft |> arrange(desc(tax_pct)) |> head(8)
flat <- ft |> filter(n >= 100) |> arrange(abs(tax_pct)) |> head(6)

sel <- bind_rows(mutate(top, group = "rides the premium"),
                 mutate(flat, group = "refuses to move")) |>
  mutate(resolved = ci_lo > 0 | ci_hi < 0,
         label = sprintf("%s  (n=%d, €%.1f)", cell, n, typical))

ggplot(sel, aes(x = tax_pct, y = reorder(label, tax_pct), colour = group)) +
  geom_vline(xintercept = 0, linetype = "dashed", colour = "grey50") +
  geom_linerange(aes(xmin = ci_lo, xmax = ci_hi), linewidth = .6) +
  geom_point(aes(shape = resolved), size = 2.6, fill = "white") +
  scale_shape_manual(values = c(`TRUE` = 16, `FALSE` = 21), guide = "none") +
  scale_colour_manual(values = c("rides the premium" = "#b5623f",
                                 "refuses to move" = "#7a9e7e"), name = NULL) +
  labs(x = "Fancy tax (% per +1 SD fanciness), 95% CI", y = NULL) +
  theme_minimal() + theme(legend.position = "top")
Point-and-interval chart of eight fancy-sensitive cells (generic sides, desserts, bread starters, plus 18 to 37 percent) and six flat commodity cells (fish mains, carpaccio, vegan plates, near 0 percent), each with confidence intervals.
Figure 2: The extremes, with 95% confidence intervals. Top: the dish-types that nominally ride the upscale premium hardest (the generic-meat-sides cell at +36% is retired as a composition artifact; see text). Bottom: the commodities that refuse to move. Filled dots mark cells whose interval excludes zero; open dots are individually unresolved.

The reference-price reading. The cells that carry the premium are the ones a diner cannot price from memory: a generic rice dish, the bread course, a house bowl. The cells that refuse are the ones with a city-wide going rate (dossier D3): fish of the day, carpaccio, salads, friet. The economic story writes itself (charge where the customer has no anchor), but it is offered here as an interpretation consistent with the pattern, not an identified mechanism; this design cannot rule out that upscale venues simply differentiate those particular dishes more.

One cell did not survive its audit, and retiring it is the method working. The nominal top slope, generic meat sides (side · meat · none · other, +36%, n=30), was dish-audited after the leader flagged it (2026-07-02): its plain-venue end is snackbar satés (€2.75) and lemper; its fancy-venue end is izakaya bites (aburi chashu, tebasaki) and composed spring rolls. That slope compares different products sharing one catch-all coordinate, not the same side dish marked up. The general lesson: other-form catch-all cells are composition-sensitive, and their slopes should be read as descriptions of what fancier venues stock, not what they charge for the same item. The robust examples (bread, rice dishes) are product-coherent under the same audit; they lead the reading above.

Where the desserts went. Under the old one-register proxy, plated desserts read +24% per fanciness step. Under the two-register model that cell is too thin to estimate: enough of its dishes come from terse-register venues that, once those venues carry their own +7.1% flag, the florid-only remainder falls below the reporting threshold. The dessert premium is real, but it is a fine-dining-register phenomenon (the venues charging it are the ones writing “word · word · word”) rather than a wordiness slope. The remaining sweet cells, at everyday venues, are flat (−6% to +7%).

The stress-test battery

The threat The test The verdict
Circularity (fancy defined by price) both registers built from description text only structurally impossible; the proxies never see a price
The proxy misses the terse fine-dining register leader’s catch → detector + pre-committed adoption probes (3×3 cut grid, all-rounders-only refit, coefficient drift) confirmed and adopted (Decision #42): terse +7.1% [0.9, 13.6] (at adoption the florid slope rose +2.3% → +2.8%; +2.7% on the curated corpus); the one-register proxy was attenuated, so the correction ran the conservative direction
Per-cell noise sold as signal re-derived every slope with standard errors (_prep/fancytax_ci.R) replication exact (135/135 cells, zero drift vs canonical); only 58/135 cells individually resolve, stated up front
Aggregate and cells disagree median per-cell florid slope vs the pooled D4 florid effect +5% vs +2.7%: same sign, pooled effect inside the per-cell IQR
One venue class drives it the pooled model retains venue random effects; slopes are within-cell across many venues qualifying cells require ≥15 venues; the terse premium itself survives within all-rounders alone (+24%)
Cherry-picked extremes the flat list is restricted to cells with n ≥ 100 the flattest cells are the biggest (fish mains n=860, friet n=788), not small-n flukes
The top slope is same-product markup dish-level audit of the +36% cell (leader’s catch, 2026-07-02) REFUTED for that cell: side · meat · other (n=30) mixes satés, chili fries, loaded fries and izakaya bites; its slope is within-cell composition, retired from the headline reading. Bread (+21%) and rice (+20–24%) survive the same audit product-coherent
The continuous scale manufactures the effect four-class re-cut (plain / standard / florid / terse, standard as reference; _prep/fanciness_classes.R) ordering monotone (−2% / 0 / +3.4% / +5.8%); classes are individually noisier than the continuous spec, which is retained

What this is, and what it isn’t

  • Proxies, honestly. Menu wordiness and the terse-register flag track upscale positioning through text; neither is a star rating. The florid +2.7%/SD reads directional and small; the terse +7.1% is a venue-class marker as much as a “tax”.
  • Not quality-adjusted. A flat slope can mean two things: the same product at the same price, or a better product at the same price (the upscale carpaccio may be better beef). The data cannot see inside the plate; either way, the menu price does not move.
  • Noisy at cell level, by construction. 135 separate regressions on 30-to-860 dishes each. The pattern across cells is the finding; individual cells are illustrations.
  • Descriptive, not a pricing manual. “Charge more where there is no anchor” is what the snapshot shows venues doing, not advice.

Lineage

  • Method + brief: docs/m5_typical_menus.md (§5 deliverable 2); audit record docs/m5_data_audit_findings.md (finding 7: lead with uncertainty).
  • Code: R/52_dish_atlas_context.R (two-register model + the canonical slopes); _prep/fancytax_ci.R (exact replication + confidence intervals); _prep/terse_fancy_test.R + _prep/terse_adoption_probes.R (the register diagnostic and its pre-committed adoption gate).
  • Data: dish_atlas_context_effects.csv, dish_atlas_fancytax.csv (canonical), _data/fancytax_ci.csv (with CIs), _data/terse_fancy.csv.
  • Journal trail: 2026-06-30_001 (context effects design), 2026-06-30_005/_006 (audit + the uncertainty carry-forward), 2026-07-02_004/_005 (the terse register: diagnosis, probes, canonical adoption, Decision #42).
  • Sources: restaurant websites (menus), OpenStreetMap (venue universe). All open data. Snapshot · June 2026.