HalfSize — a size converter that tells you where the chart is lying
Most size charts print one number and quietly hide the fact that the number is a compromise. HalfSize (halfsize.vercel.app) is a free converter for shoes, clothing and kitchen measurements that shows the number AND the trap behind it.
What it does:
· Shoes — foot length 22–30 cm → EU / US / UK, with Indonesia built in as EU numbering, and the warning that sports shoes usually run half a size larger.
· Apparel — four tables (women/men × tops/bottoms) plus a calculator that starts from your body: 88 cm bust → M (EU 38 / US 6 / UK 10), 76 cm waist → jeans 30.
· Kitchen — volume, weight and oven heat. One US cup is 127 g of flour but 203 g of sugar. 200 °C = 392 °F, fan 180 °C.
The part I care about most: every module ends with "The catch" — a plain-language note about where the standard chart fails. One 88 cm bust is German 38, French 40, Italian 44. Indonesian brands often put M at 86–92 cm, so an Indonesian M reads as an S to a German shopper.
Built in four prompt steps: foundation (Claude), table validation against 3+ sources (Claude), calculator from body measurements (Claude), and moving data out of the page into data/*.json + a build script with an i18n validator (Codex).
Stack: one 130 KB HTML file. No framework, no build step at runtime, no login, 0 external requests, fonts embedded. English + Indonesian.
Honest limitation: shareable URL state, a copy button and a print view are not live yet. They're written into the prompts above, so anyone who forks this gets the more complete version.
What I'd change next: per-pair SEO pages (88 cm to EU size), because that's how people actually search.
Tech stack
- Claude (Sonnet 5.5)
- ChatGPT (GPT-5.6 Sol)
- Vercel
Links
Prompt steps
Step 1
Build HalfSize — an honest size converter — as a single self-contained index.html. No build step, no framework, no npm, zero network requests at runtime: it must open straight from file:// and from a static host. Three modules: 1. Shoes. Foot length 22–27 cm for women and 24–30 cm for men, in 0.5 cm steps, converting to EU, US, UK and Indonesia. Indonesia uses EU numbering, so the Indonesia row equals the EU row — do not invent a separate Indonesian shoe scale. Show one big EU result plus one ruled row per system. 2. Apparel. Four reference tables: - Women tops, XS–XXL: EU 34–44, US 2–12, UK 6–16, bust 78–102 cm, waist 62–85, hip 85–108. - Women bottoms, jeans 25–34: waist 63–86 cm, hip 85–108, EU 32–42, UK 4–14. - Men tops, Indonesian shirt 37–46: international S–XXL, EU 46–54, US/UK 36–44, chest 92–124 cm. - Men bottoms, jeans 28–38: waist 71–97 cm, US/UK 28–38, EU 44–54. Where the sources give gaps between bands, keep the gap. Do not interpolate to fill the table. 3. Kitchen. Volume and weight conversion using real densities (water 1.00, milk 1.03, flour 0.53, sugar 0.845, brown sugar 0.93, butter 0.911, chocolate 0.42, honey 1.42, rice 0.78, salt 1.20 g/ml), with US cup 240 ml, metric cup 250 ml, UK cup 284 ml, tablespoon 15 ml (Australia 20 ml), teaspoon 5 ml. Plus an oven temperature converter with a fan toggle (−20 °C / −36 °F). Every module ends with a callout titled "The catch" stating the trap in plain language: charts print one number but shoes are a range; German, French and Italian sizes disagree on one body; volume is not weight. Bilingual EN + ID with a header toggle. Every user-facing string comes from one dictionary of key → {en, id}, and a missing key must fall back to English — never render the raw key. Visual identity: bright sticker look, cream #FFF6EC canvas, ink #1E1233, 2px borders, hard 4px offset shadows, 18–22px radii, Fredoka for display and Nunito for body embedded as base64 woff2, medium "cheerful but polite" motion (slow drifting shapes, numbers that roll, 2px press nudge), all disabled under prefers-reduced-motion. Do not invent a value or extrapolate outside a table. If an input is out of range, say so explicitly instead of guessing.Step 2
Before we trust the apparel module, verify it. Check the four tables against at least three independent sources — Wikipedia's Clothing sizes article, one major retailer's size chart (ASOS or similar), and at least one Indonesian brand or local size guide — and write a diff table with three columns: current value / proposed value / source URL. Three specific things to settle: 1. EU vs German/French/Italian. The formulas we have are German = bust/2 − 6, French = bust/2 − 4, Italian = bust/2. Test them: an 88 cm bust should land on German 38, French 40, Italian 44. If the table contradicts its own formula, say which one is wrong and which you keep. 2. Indonesia. Local charts appear to place M at 86–92 cm bust, which reads as an S to a German shopper. Confirm the real band and whether Indonesian sizing tracks EU 38 or its own scale. 3. Women's jeans. Confirm the waist-to-number mapping (25 → 63–64 cm … 34 → 86 cm) and flag any row where sources disagree by more than one size. Report disagreements honestly rather than picking a winner silently — the product's whole positioning is that it says when sources conflict. Do not change the code in this step.Step 3
Add a calculator above the apparel tables so people start from a body measurement instead of guessing a letter. Four modes, chosen by women/men and tops/bottoms: - Women tops on bust cm: 78–81 → XS, 82–85 → S, 86–89 → M, 90–93 → L, 94–97 → XL, 98–102 → XXL. - Women bottoms on waist cm: 61–64 → 25, 65–68 → 26, 69–73 → 28, 74–78 → 30, 79–83 → 32, 84–89 → 34. - Men tops on chest cm: 88–96 → S, 96–104 → M, 104–112 → L, 112–120 → XL, 120–128 → XXL. - Men bottoms on waist cm: 69–73 → 28, 74–78 → 30, 79–83 → 32, 84–88 → 34, 89–93 → 36, 94–98 → 38. Rules that matter: - A cm/in toggle. Store the raw centimetres and always derive the displayed inches from that raw value (1 in = 2.54 cm, one decimal). Never store the rounded display value as state, or toggling units will slowly drift the number: 88 cm → 34.6 in must come back as exactly 88. - Values in a gap between bands, or outside the whole range, get an explicit note — nearest size plus "size up", or "out of range". Never round silently. - When a value sits on a shared boundary such as 96 cm for men's chest, resolve to the lower band and mention it. - The big result is the size letter or jeans number; the rest of that row (EU, US, UK, chest/waist/hip) renders underneath. Keep the four reference tables below the calculator exactly as they are — the calculator is an entry point, not a replacement.Step 4
Refactor the project into data, template and build artifact, then prove it still works. 1. Move every number out of the page into data/shoes.json, data/apparel.json, data/measure.json and data/kitchen.json, and every string into data/i18n.json as key → {en, id}. Use "ina" or similar for the Indonesian field name — never the bare key "id", it collides with element ids. 2. Move the markup into src/template.html with __DATA__, __DICT__, __FREDOKA__ and __NUNITO__ placeholders. Write build.js that inlines all of it into public/index.html, the single file served. Vercel builds nothing here: do not add a package.json that triggers a build step, or the deploy will serve an empty directory. 3. Add check-i18n.js and make it fail the build when EN and ID keys diverge, when a dictionary value is an empty string, or when template text is not behind a data-i18n / data-i18n-html attribute. 4. Delete the design-system section from the public page. It was scaffolding for us while building; it does not belong in the product. Verify and report the real output: the page renders all three sections, 88 cm bust → M, 27 cm foot → EU 42, 1 cup sugar → 203 g, the interface string changes when the language toggles, 0 console errors, and 0 external requests in the network panel.
1 like