From f7e20e10156221d133a45148b8469469a4c85f75 Mon Sep 17 00:00:00 2001 From: grabowski Date: Fri, 16 Oct 2026 22:03:50 +0700 Subject: [PATCH] Make a record: USD / THB / EUR selector and English / Thai language switch User (October 2026): currency selector on the first page (USD / THB / EUR) and a language selector for Thai on the make-a-record demo. - Top bar: one currency control (replaces the THB/USD switch on the price step) and an EN / Thai control, visible from step 1; both persist (localStorage, #cur= / #lang= in the URL, hash wins). Prices stay computed in THB: USD = THB / 33, EUR = THB / 38.115 (1 EUR = 1.155 USD); the fan price is entered in the chosen currency and stored in THB, the campaign rule max(100, break-even) unchanged. - Thai: every visible string, tooltip, aria label, file check, quote line, production update, passport, investor note and tour caption (dictionary T = {en, th}, t(key, vars), data-i18n attributes; 636 keys), system Thai fonts, Thai dates with Gregorian years, and a footer note that the Thai is a draft translation for review. Template PDFs stay English (Helvetica has no Thai glyphs). - Top bar wraps to two rows below 1000 px (steps were cut off between 761 and 990 px before). - README and landing entries mention the currencies and Thai. Checks (headless Edge): doc example unchanged in THB (37,836 per title, 232 per copy at 100, break-even 41, goal 100, ~548 kept, 640 hint); conversions exact; 390 / 768 / 1024 / 1440 px, light and dark, EN and TH, all currencies, steps 1 to 5: no page errors, overflow or untranslated leftovers; tour in Thai; node --check; no em dashes. --- README.md | 5 +- docs/make-a-record.html | 1186 +++++++++++++++++++++++++++------------ site/public/index.html | 3 +- 3 files changed, 844 insertions(+), 350 deletions(-) diff --git a/README.md b/README.md index 1f7ef5b..ffc11ec 100644 --- a/README.md +++ b/README.md @@ -200,8 +200,9 @@ The detail lives in dedicated documents: platform as a customer sees it, in one polished flow: design the record against a to-scale mock-up, check the music and artwork, see the price, let fans fund it, follow the production and open the record passport - (the traceability record of one copy); investor notes on every step and - a one-minute guided tour (`#tour`) + (the traceability record of one copy); investor notes on every step, a + one-minute guided tour (`#tour`), prices in THB, USD or EUR and the whole + page in English or Thai (draft translation, `#cur=EUR&lang=th`) - [Factory console and order status](docs/factory-console.html): the factory application of the [digital factory](docs/digital-factory.md) plan as a demo on a simulated plant day: the press floor with live diff --git a/docs/make-a-record.html b/docs/make-a-record.html index e5fb810..f2d16e1 100644 --- a/docs/make-a-record.html +++ b/docs/make-a-record.html @@ -398,10 +398,36 @@ document.documentElement.setAttribute("data-theme",t);})(); .tour #tourT { flex: 1; } .toast { position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%); background: var(--card); border: 1px solid var(--acc); border-radius: 12px; padding: 9px 16px; font-size: 14px; z-index: 70; box-shadow: var(--shadow); max-width: calc(100% - 28px); } footer { max-width: 1320px; margin: 0 auto; padding: 0 24px 50px; color: var(--mute); font-size: 13px; } + footer .draft { font-size: 12px; color: var(--faint); } footer p { max-width: 900px; margin: 6px 0; } /* narrow screens */ + /* top bar: currency and language next to the theme button */ + .prefs { display: flex; align-items: center; gap: 6px; } + .seg.cmp { padding: 2px; gap: 1px; flex-wrap: nowrap; } + .seg.cmp button { padding: 4px 9px; font-size: 12.5px; font-weight: 650; } + .kpi b.wr { white-space: normal; } + @media (max-width: 640px) { .kpi.span2 { grid-column: 1 / -1; } } + .seg.cmp button[lang=th], html[lang=th] body { font-family: system-ui, -apple-system, "Segoe UI", "Leelawadee UI", "Noto Sans Thai", Thonburi, Tahoma, sans-serif; } + /* Thai: system Thai faces, more line height for tone marks, no wide tracking */ + html[lang=th] body { line-height: 1.6; } + html[lang=th] h1 { line-height: 1.28; letter-spacing: 0; } + html[lang=th] .eyebrow, html[lang=th] .inv .il, html[lang=th] .ptag, html[lang=th] th, html[lang=th] .gtag, html[lang=th] .mini, html[lang=th] .pp-key span, html[lang=th] .brand .pill { letter-spacing: 0.02em; } + html[lang=th] .mock text[font-family^="system-ui"] { font-family: system-ui, "Leelawadee UI", "Noto Sans Thai", Thonburi, Tahoma, sans-serif; } + @media (max-width: 1300px) { + nav.steps .lb { display: none; } + nav.steps button { padding: 6px; } + nav.steps button.on .lb { display: inline; } + nav.steps button.on { padding-right: 12px; } + } + @media (max-width: 1000px) { + .top .in { flex-wrap: wrap; row-gap: 4px; } + .tools { flex: 1 1 100%; } + .prefs { margin-left: auto; } + .block, .pgrid, .passport { scroll-margin-top: 118px; } + } @media (max-width: 1080px) { + #tourBtn .tl { display: none; } .app { grid-template-columns: minmax(0, 1fr); gap: 20px; padding-top: 18px; padding-bottom: 110px; } .stage { position: static; order: -1; } .stagecard { display: grid; grid-template-columns: minmax(0, 220px) minmax(0, 1fr); gap: 4px 16px; align-items: center; padding: 12px 14px; border-radius: 18px; } @@ -418,8 +444,6 @@ document.documentElement.setAttribute("data-theme",t);})(); } @media (max-width: 760px) { nav.steps .lb { display: none; } - nav.steps button { padding: 6px; } - nav.steps button.on .lb { display: inline; } .sw .lbl { display: none; } .top .in { padding: 8px 14px; gap: 10px; } .app { padding-left: 14px; padding-right: 14px; } @@ -432,25 +456,39 @@ document.documentElement.setAttribute("data-theme",t);})(); .lead { font-size: 15.5px; } .panel { padding: 16px; } .tour { flex-wrap: wrap; } - nav.steps button.on .lb, #tourBtn .tl { display: none; } + nav.steps button.on .lb { display: inline-block; max-width: 11em; overflow: hidden; text-overflow: ellipsis; vertical-align: middle; } .top .in { gap: 8px; } + .seg.cmp button { padding: 4px 8px; } } + @media (max-width: 400px) { + .tools, .top .in { gap: 6px; } + .prefs { gap: 4px; } + .seg.cmp button { padding: 4px 6px; } + #tourBtn { padding: 6px 10px; } + .tools .ib { width: 32px; height: 32px; } + nav.steps button.on .lb { max-width: 7.5em; } + } + @media (max-width: 350px) { nav.steps button.on .lb { display: none; } }
-
CNX VinylDemo
-
@@ -461,65 +499,65 @@ document.documentElement.setAttribute("data-theme",t);})();
-
Step 1 of 5
-

Design your record

-

Cut, plated and pressed under one roof near Chiang Mai, from 100 copies. Pay for the run yourself, or let your fans fund it.

-
Investor note

The configurator is also market research. Every configuration, logged anonymously, is a data point on run size, colour, packaging and the price at which people walk away: the run-size question the revenue model leaves open. It goes public with indicative prices and an interest list long before the plant opens.

+
Step 1 of 5
+

Design your record

+

Cut, plated and pressed under one roof near Chiang Mai, from 100 copies. Pay for the run yourself, or let your fans fund it.

+
Investor note

The configurator is also market research. Every configuration, logged anonymously, is a data point on run size, colour, packaging and the price at which people walk away: the run-size question the revenue model leaves open. It goes public with indicative prices and an interest list long before the plant opens.

-

Format

+

Format

- +
-
Speed
-
Discs
-
Weight
-
Centre hole
+
Speed
+
Discs
+
Weight
+
Centre hole
-

Vinyl

+

Vinyl

- - - - + + + +
-
Colour
-
Second colour
+
Colour
+
Second colour
-
Clean the press before your colour
+
Clean the press before your colour

-

Packaging

+

Packaging

- - - - + + + +
-
Labels
-
Inner sleeve
-
Spine
-
Extras
+
Labels
+
Inner sleeve
+
Spine
+
Extras
-

Sound

-
Your audio arrives as
+

Sound

+
Your audio arrives as
- - + +
-
Test pressings for you
5
+
Test pressings for you
5

You hear and approve a real pressing before the run. The father and mother are archived, so a repress later skips cutting.

@@ -527,65 +565,64 @@ document.documentElement.setAttribute("data-theme",t);})();