Capstone dossier · which dishes carry the upscale premium, and which refuse to
Author
Dei M. Elurbe
Published
July 10, 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.3% of its own (95% CI +1.2 to +13.9). The terse register was my 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 +4%, interquartile range −2% to +9%). 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 (+20%) 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 56 of the 135 cells individually resolve a nonzero effect at 95% confidence (50 positive, 6 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.3% 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 849 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()
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")
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 I 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.3% 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
confirmed and adopted (Decision #42): terse +7.4% at adoption, +7.3% [1.2, 13.9] on the curated corpus, stable through the 2026-07-21 breakfast-misfile curation (the florid slope rose +2.3% → +2.8% at adoption; +2.7% curated); 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 56/135 cells individually resolve, stated up front
Package items warp the slopes
the 2026-07-10 item-level curation (Decision #44), full re-derivation
median slope +5% → +4%/SD, 58 → 56 cells resolve, extremes (−21/+36) unchanged: the pattern is stable
Aggregate and cells disagree
median per-cell florid slope vs the pooled D4 florid effect
+4% 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 (+20%) 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
Addendum (2026-08-27): the wordless register, re-read
The verdict. Read on plated dishes only, with the sandwich counters set aside and every uncertain kitchen checked by eye, the wordless register carries about +21% for the same dish (95% CI [+15, +27]), against the +7.3% printed above. The two numbers are not in conflict: the +7.3% is the honest average of everything one simple rule catches, and that rule catches two kinds of kitchen, the tasting menu and the sandwich counter, which lists its fillings for a different reason. The canon number stays as the Snapshot · June 2026 record; this addendum is the closer read, on the same corpus, with the rules written down before the model ran.
Why re-read. The terse flag of Decision #42 was adopted as one pooled coefficient and disclosed as a proxy. Split by concept family (a diagnostic, 2026-08-27) it came apart: raw bars carried a large premium, burger and mezze houses none, and the “uncategorized” bin ran negative, because one sandwich chain with ten branches, a bagel shop and a few lunchrooms had been flagged alongside the tasting menus. The same diagnostic showed the flag missing wordless kitchens for mechanical reasons: a list longer than sixty characters, a trailing “en”, an ingredient name such as “mozzarella di bufala” read as prose.
The net of record, eight rules. All were agreed in plain words before anything was measured; two are judgement calls and are named as such.
A house has one language; its share of wordless lines is the house’s vote.
Houses without tiers to signal do not testify: the café subtypes broodjeszaak and koffie-lunchroom are set aside, by label.
Only lines that had prose as an alternative testify: plates, pasta, soup, rice dishes, noodles, and starters, mains or desserts of no fixed format. Sandwiches, pizza, burgers, bowls, salads, platters, bread, fries, cheese boards, snacks, sides and sushi never do: there, a list is the format, not a choice.
A house is judged only when those testifying formats are at least 30% of what it sells (judgement call: the dominant format writes the menu), when descriptions cover at least 30% of its menu (the canon cut), and when it has at least five voting lines.
A wordless line is a list of two to five items (judgement call: six or more is an ingredient list, not a register), separated by a dot, a pipe or a comma (a slash counts only when it appears twice or more, to keep bilingual lines out), with at most one list connective (en, and, of, or, &) and no sentence word (met, with, served, geserveerd, in, op, uit, and the articles). Two-item lines count only with a dot or a pipe. Name particles inside an ingredient (di, de, van) do not disqualify.
A line votes against when it carries a sentence word or lists six or more items.
Every other line abstains: no separator, a two-item comma line, a lone slash, non-Latin script.
The share is wordless votes over all votes. A house is wordless at 70% or more on at least eight voting lines; between 50% and 70%, or on fewer than eight lines, it goes to a human read; below 50% it is not wordless.
The human layer, disclosed. 67 houses fell in the uncertain band. A blind coder (no names, no prices, a written rubric with four verdicts: one language wordless, one language prose, mixed, artifact) read them first; 12 were escalated to me; I ruled on the lines alone. Outcome: 59 wordless, 3 prose, 5 out (4 genuinely mixed, 1 an artifact: translations of the dish name). The guard against circularity was explicit: a house leaves for its format or for an artifact, never for the company it keeps. A grand café that copied the fine-dining look stays in; the copy is part of the finding.
What the label rests on. 115 wordless houses (56 by the net alone, 59 confirmed by the read), 290 not wordless, 486 not judged (mostly houses whose plates are a minority of the menu, or with too few described plates; 76 counters). Across the corpus 56% of the testifying lines abstain (44% show no separator at all: a single noun, a translation, a short fragment), so the label rests on the lines that show a grammar, not on every line.
The result. The R/52 model as printed above, same dishes, same terms; only the label changes. Five predictions were written down before the run.
Table 1: The wordless premium under the label of record and its robustness twins. Same dish, same café / specialist type, same area, florid wordiness held constant.
label
houses
premium
95% CI
canon flag (Decision #42, as above)
85
+7%
[+1, +14]
the net of record + the human layer
113
+21%
[+15, +27]
the net alone, no human layer
55
+21%
[+13, +30]
counters judged like everyone else (rule 2 off)
114
+21%
[+15, +27]
counters removed from the comparison entirely
113
+16%
[+11, +22]
floor at 0% / at 50% (rule 4)
115 / 57
+21% / +21%
all-rounder restaurants only
42
+22%
[+11, +33]
Prediction 1, confirmed: the premium rises once the counters leave the flagged set. It tripled rather than nudged. The conservative reading is the row with the counters removed from the comparison entirely (+16%): once they stop being “wordless” they sit on the other side of the comparison, and their low prices widen the gap; taking them out of the room altogether is the fair floor. Post-hoc, by kind of house (a question I asked after the run, 2026-08-28): the gap between the two rows lives entirely in the cafés. Wordless restaurants carry +23% with the counters in the frame and +23% without (42 houses); wordless cafés (brunch cafés, brasseries, borrelcafés; 53 houses) carry +22% with and +12% without. The dish is held constant either way; what moves is the model’s yardstick for “a normal café”, which the counters help set (-12% vs restaurants with them in, -4% without). So: for restaurants the premium is about +23% either way; for cafés it is +12% to +22% depending on whether a broodjeszaak counts as a café.
Prediction 2, confirmed: the flagged set is now 56 restaurants, 19 brunch cafés, 16 brasseries and a handful of borrelcafés, bars and eetcafés; no counters, no topping lists.
Prediction 3, the house carries it: with the house label and the dish’s own wordless line in one model, the house carries +20% [+14, +26] and the line itself adds +4% [+2, +6]. The register is a property of the kitchen, with a small per-plate residue.
Prediction 4, the ladder: with wordiness cut into plain, standard and florid houses and the wordless label as the top class (standard as reference): plain -3%, florid +4%, wordless +20% (188 / 304 / 239 / 113 houses). Monotone, and the top step is about five times the florid one.
Prediction 5, by family: raw bars +40% [+25, +56] (19 houses), the burger-brasserie family +27% [+15, +41] (23), pasta +22% [+10, +35] (22), all other families pooled +14% [+5, +24] (33). Mezze (8), pizza
and the uncategorized bin (4) are too thin to read.
Where the wordless houses sit: their price level net of dish mix has a median of +16% (everyone else: +0%), and 22% of them are among the city’s top-10% priciest kitchens (everyone else: 8%).
What this is, and what it isn’t. A signal of price class, not a lever: nobody charges more by deleting verbs. The by-family numbers are illustrations on small sets. Branches of a chain count as separate venues, as everywhere in this corpus. Adjectives lean toward prose (a fixed lexicon of cooking words appears on 22% of wordless lines at the surest wordless houses and on 39% at prose houses) but they are a tendency, not a fence: fine dining repurposes the common word for the rare thing (“dry-aged” for a beet, “cured” for hamachi), my observation, recorded here as an observation. The manual layer is disclosed above; the named rulings stay in the internal working folder.
Lineage for this addendum._prep/wordless_net_v41.R (the net of record, eight rules in the header), _prep/wordless_receipts.R (the pre-registered run), _data/wordless_houses.csv (one row per venue, label and shares, no names), _data/wordless_receipts.csv and _data/wordless_extras.csv (every number on this addendum is read from these at render time); journal 2026-08-27_002; the working ledger in the S-vocabulary post folder.
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.3% 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).