translate_case_files.ts: per-file localization pass that guarantees a case
file is complete and parallel in EN + PT-BR — translating the missing-language
title, sections, and verbatim blockquotes FROM whatever language exists, with
citations preserved exactly. Validates (two H1s, no dropped citations, PT
accents present) before writing; stamps bilingual_normalized in frontmatter;
idempotent. Ran across all 89 published files (88 via LLM, 1 legacy fixed
deterministically).
bilingual.ts: pickLocaleBody now honors explicit "(EN)"/"(PT-BR)" heading
tags as the primary split signal (above section-number ordering and language
sniffing) and strips those tags + trailing rules from display. Fixes the
legacy "## §N — Title (EN)" format which the reader otherwise showed with
visible language tags.
Verified live: green-fireballs-bilingual, d44, doc-65 render one language per
locale with their own titles.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Case bodies hold EN and PT-BR scenes interleaved (## I. EN, ## I. PT, ...),
but the reader rendered the whole body, so an EN visitor saw every scene
twice — once in English, once in Portuguese — and vice-versa.
Add pickLocaleBody(): split by section-number occurrence (first = EN, second
= PT-BR, the narrator's mandated order), with language sniffing only as a
fallback for unpaired/unnumbered sections, and full-body fallback when a body
can't be split (English-only legacy files). Wire it into the case reader
(body, lead, OG description) and the homepage card openings.
Also fix extractBody: it discarded the English H1 by treating the second
(PT-BR) H1 as "the first real heading". Future narrations keep both titles.
Verified live: d44 and doc-65 render EN-only under locale=en and PT-only
under locale=pt-br. Bulk-checked 89 files: 80 clean, 8 structurally clean
(source-language verbatim quotes retained per spec), 1 English-only legacy.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>