feat(legal): bilingual (RU + EN) legal pages with a language + theme switcher
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 21s
CI / ui (pull_request) Successful in 1m14s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m48s

Add English versions of the privacy policy, EULA and offer (ui/legal/*_en.md) and render each legal page as one self-contained bilingual document: both language bodies plus a header language toggle and theme toggle (no back), a small inline ES5 script that switches language client-side (no reload, default Russian + persisted) and applies the theme (system default + persisted override) — mirroring the landing. The offer's English view transliterates the Russian product names spliced from the live catalog.

renderLegalHtml now takes both language sources; renderOffer splices the price list into both; the renderer bakes and reads the _en sources and pre-renders the static pages at boot. Also wrap the /offer/ contour probe in the same retry+timeout as the legal probe (the offer page is now bilingual and larger). Docs + renderer/ui tests updated.
This commit is contained in:
Ilia Denisov
2026-07-13 13:22:56 +02:00
parent 7df078f5ed
commit de5ab9186c
16 changed files with 1018 additions and 140 deletions
+4 -3
View File
@@ -33,9 +33,10 @@ pinned to the production origin, JSON-LD, the favicon set and `robots.txt`), whi
shell is `noindex` — the landing is the only indexable page. The footer links to the three **legal
documents** — the **user agreement** (`/eula/`), the **privacy policy** (`/privacy/`) and the
**public offer** (`/offer/`) — and, beside them, **feedback** (the Telegram bot the documents name as
the seller's contact). Each is rendered on demand from its `ui/legal/*_ru.md` source by the render
sidecar; the offer additionally splices in its **price list** (§4.4) generated from the live product
catalog, so the published prices always match what is currently on sale — no redeploy to update them.
the seller's contact). Each is **bilingual (RU/EN)** with a language + theme switcher and is rendered
from its `ui/legal/*_{ru,en}.md` sources by the render sidecar; the offer additionally splices in its
**price list** (§4.4) generated from the live product catalog, so the published prices always match
what is currently on sale — no redeploy to update them.
On the plain web the client is an **installable PWA**: a logged-out player sees an install
call-to-action under the login form (and at the bottom of Settings) that installs the app to the