Rebuilt de|es/odoo-erp-automation-bootcamp/index.html from the translator's
updated files with work/i18n/build-i18n.py (same recipe as 89bb7b7: lang,
canonical, the four hreflang links, og:url, the top-bar selector kept as-is).
- 2 occurrences per file: the facts-list <dd> and the "Your instructor"
<strong> now read "Oliver - The OC Guy - Arnold, Technical Lead bei/de
ODOO4projects" (the user's alter ego, typed hyphen form).
- Both JSON-LD instructor Person nodes gain alternateName "The OC Guy"
(the translator mirrored the EN page e5e4f5b; name stays Oliver Arnold).
- Buy forms untouched: three POST forms, product_id 12, clear=1, price 465.00
in five places per page.
- git diff --stat e5e4f5b = these two files only (+10/-6).
- add de|es/odoo-erp-automation-bootcamp/index.html (build-i18n.py from the
translator's files; canonical + hreflang cluster + top-bar selector)
- EN bootcamp page gains the four hreflang alternates (was asymmetric)
- price 790 -> 465.00 across all three pages (JSON-LD offers.price, the three
buy-button labels, the bc-price sentence); the three buy forms stay
byte-identical apart from the label language
- sitemap.xml: +/de/ and /es/odoo-erp-automation-bootcamp/; llms.txt: Languages
section names the new pages
Rebuild the two German phase-2 pages from translator/out/de/ with the standard
build recipe (lang, canonical, four hreflang links, top-bar language selector):
em-dashes cut in the German copy (odoo-hosting-2027 30 -> 5 body em-dashes,
support 8 -> 6 body) so the DE pages no longer exceed the EN source. Punctuation
only, no re-translation. ES and EN pages unchanged.
impeccable detect: finding profile unchanged except the [em-dash-overuse]
advisory on de/odoo-hosting-2027.html, which is resolved.
Four new pages, built from the verified translator output with work/i18n/build-i18n.py,
plus the same hreflang cluster and top-bar language selector on the two English pages.
Same recipe as the homepage pilot (main 937dbd4 / 06beab4); nothing else touched.
- de|es/odoo-hosting-2027.html, de|es/support.html: per-language canonical, the full
hreflang cluster (en-US, de, es, x-default -> EN), /static/lang.js, and the switcher
slot placed in the page's own top bar (.cmp-topbar on the 2027 page, .blog-header on
support.html) with the per-shape CSS hook from I18N-BUILD-PLAN.md §3.
- odoo-hosting-2027.html, support.html: same cluster, same selector, so the cluster is
symmetric (asymmetric hreflang is discarded by Google). support.html's canonical and
og:url were still on the capitalised ODOO4projects.com host; the build normalises them
to the lowercase form the rest of the site and sitemap.xml use.
- Internal links: the build's rebase step now also localises a root-absolute page link
(/support.html#contact in the translator's 2027 pages) once that page exists in the
language. /de/support.html, /de/odoo-hosting-2027.html, /de/, /de/#pricing and
/de/#trialCard are local; /legal.html stays on the EN route because the legal pages
are not translated (lawyer review pending).
- sitemap.xml: +4 URLs, lastmod 2026-10-24, priority reused from the EN entry (2027 -> 0.9,
support.html -> 0.6 fallback, it has no EN entry). 17 -> 21 <loc>, no duplicates.
- llms.txt: the ## Languages section now names the mirrored pages.
Checks: verify-html.py PROBLEMS: 0; node --check static/lang.js OK; test-lang.js 31/31;
test-build.py 64/64 (was 43; +21 for the four built pages and the root-absolute rule);
check-links.py on the four new pages BROKEN/MISPLACED: 0.
The EN | DE | ES switcher existed but rendered into the footer slot, so a
visitor had to scroll to the bottom of the page to find it (measured live:
y=5582 on /, y=5498 on /odoo-erp-automation-bootcamp/). The user asked for a
selector a visitor can actually see.
- index.html, de/index.html, es/index.html: the slot is now the first child of
.hero .container, right-aligned in flow above the kicker. In flow, not a
fixed pill, so it cannot collide with the absolute .hero-notice.
- odoo-erp-automation-bootcamp/index.html: the slot is now the last child of
.bc-topbar .container, right of the nav links, behind a hairline brass
divider; .bc-topbar-links gets margin-left:auto so the brand stays left.
- One [data-lang-switcher] per page; the footer slot is removed everywhere.
- Styling follows the CI: Inter 12px / .06em / uppercase codes (the existing
.lang-switch rules), active language in --brass on these midnight surfaces,
the other two in the surrounding text colour. CSS-only, in each page's
inline <style>; lang.js is untouched, so its redirect behaviour is unchanged.
- The rules are recorded in work/i18n/I18N-BUILD-PLAN.md §3 for the phase-2
pages (de|es/odoo-hosting-2027.html, de|es/support.html).
Homepage pilot of the website i18n project. Adds the translated homepage for DE and
ES, the shared selector at /static/lang.js, and the hreflang cluster on all three
language versions (EN included, or the cluster is asymmetric and ignored).
- de/index.html, es/index.html: translator output plus the i18n build (html lang,
self-referencing canonical, hreflang cluster, lang.js tag, switcher slot in the footer).
- index.html: same cluster + lang.js tag + switcher slot; canonical and og:url
normalised to the lowercase host.
- static/lang.js: the tested selector (client-side language choice, auto-detect on the
EN homepage only, once per session; a stored choice or ?lang= always wins).
- sitemap.xml: /de/ and /es/ (priority 1.0, lastmod 2026-10-24).
- llms.txt: new '## Languages' section.
Two gaps in the build recipe were closed while building: a mirrored page cannot use
root-relative source paths (style.css, images/* would resolve to /de/style.css -> 404),
so the build now re-points assets at the site root and keeps page links on the EN route
until the language page exists; and og:url is now this page's own URL instead of the
EN one inherited from the source. Not built yet: support.html, odoo-hosting-2027.html,
the blog, the bootcamp page, the legal pages.