* fix(website): keep text inside small screens and tidy small type and spacing From a layout audit of the built pages: - Long terminal prompts and code-header buttons wrap instead of being cut off at 320px (WCAG 1.4.10). - Headings and table cells break long words, so the 1.4.12 text-spacing test no longer widens pages past 320px. - Header and footer links get a 24px minimum height (2.5.8). - Labels that rendered under 12px now render at 12px or more, and inline code never drops under 0.75rem. - The home page's hero and definition rows share one column gap and align on the first baseline, and stacked boxes share one corner size. - Highlight chips get room around the text, and the active run in a step listing is one band instead of a box per line. Colors are unchanged. 🤖 Generated with Claude Code (Sonnet 5.5) 🦊 * feat(website): follow the system dark mode The site was light only, so a reader with a dark system still got a white page. Add one prefers-color-scheme: dark block to the stylesheet that swaps the six color variables to Catppuccin Mocha (MIT) and overrides the fixed colors that would break on a dark page: selection, buttons, tinted highlights, flow nodes and arrows, and a visible border on the agent terminal. Add a dark theme-color tag beside the light one in the page template and the 17 pages, and a Dark column to the style guide's color table. Light colors are unchanged. The SVG figures follow in the next commit; the blog page's inline strokes, the dinosaur game and the social card are left as they are. 🤖 Generated with Claude Code (Sonnet 5.5) 🦊 * feat(website): give the five SVG figures a dark scheme Pages load the figures with <img>, so page CSS cannot reach inside them. Each figure now carries its own @media (prefers-color-scheme: dark) block of attribute-selector overrides that map every light color to a Catppuccin Mocha color, with one shared map across all five. No markup, labels, shapes or positions change, and nothing uses !important. Four figures also paint a mantle canvas so "Open figure" works on its own; analyst-thinking.svg stays transparent, since it sits on the page rather than in a figure box. 🤖 Generated with Claude Code (Sonnet 5.5) 🦊 * chore(website): refresh translation source references The theme-color tags move the page lines that the catalogs cite, so python3 scripts/website.py translations extract rewrites the source references in messages.pot and the 18 PO files. No message text changes. The same run moves the "Main navigation" entry to its new position in each catalog. 🤖 Generated with Claude Code (Sonnet 5.5) 🦊 * fix(website): keep inline step highlights inline The full-width band for the active step now applies only to code-step blocks. The inline parameter highlights in the dx-ball and th04 signatures stay inline again. 🤖 Generated with Claude Code (Opus 5.5) 🦊 * test(website): check every page offers light and dark theme colors Each authored reading page, and its built copy in every language, must carry one theme-color tag for light and one for dark. The stylesheet must keep its dark color scheme block. On the commit before dark mode, this test fails on every page. 🤖 Generated with Claude Code (Opus 5.5) 🦊 * fix(website): draw the dinosaur game in the page colors In dark mode the game box turned dark, but the game still drew with its light colors, so the dinosaur, cacti and text fell to about 2:1 contrast. The canvas now reads five colors from CSS variables on .dino-stage. Light values are the old ones, so light mode draws the same pixels. Dark values are Catppuccin Mocha: 8.3:1 for the dinosaur, 7.9:1 for cacti and text, 7.6:1 for the crash color. The moved lines in dino-demo.js shift the translation catalog references, so the catalogs are refreshed too (reference comments only). 🤖 Generated with Claude Code (Opus 5.5) 🦊 * fix(website): recolor the Touhou flywheel arrows in dark mode The inline flywheel SVG on the Touhou article hard-codes its stroke colors, so on the dark page its connectors fell to about 2:1. Two dark-only rules map those strokes to the page accent and muted colors (7.8:1 and 7.4:1). Light mode is unchanged. 🤖 Generated with Claude Code (Opus 5.5) 🦊 * fix(website): redraw the dinosaur game when the system theme changes The canvas reads its colors only when it draws, so an idle, paused or crashed game kept the old palette after a theme switch. Each demo now redraws on a prefers-color-scheme change. The added lines shift the translation catalog references, so the catalogs are refreshed too (reference comments only). 🤖 Generated with Claude Code (Opus 5.5) 🦊 --------- Co-authored-by: Claude Sonnet 5.5 <sonnet@cassie-pc> Co-authored-by: Claude Opus 5.5 <opus@cassie-pc>
Website translations
A good website is like a good paper: easy to follow, clear and concise, with a clean, refined presentation.
— N0zoM1z0
The same standard applies in every language. A translation should help someone understand the example and try it. Clear, accurate wording matters more than a literal imitation of English sentences.
Edit a translation
Use the Python environment in the website README. Pick a language
from languages.json, then edit its messages.po in a text editor, Poedit or
another gettext editor. Each entry includes its source page and line:
#: website/public/faq/index.html:200
msgctxt "page:faq/index.html"
msgid "How do I install REA?"
msgstr "如何安装 REA?"
Change msgstr. Keep msgid and msgctxt. Add reviewer notes with # comments
when useful. Shared navigation uses the shared context; page-specific wording
has its own context. The same English sentence may need different wording in a
different case study.
python3 scripts/website.py translations status --language zh-CN
python3 scripts/website.py translations check --language zh-CN
python3 scripts/website.py serve
Open http://127.0.0.1:4173/zh-CN/. The language selector opens the equivalent
page in another edition. Check the page you edited, its figures and its copy
buttons. Rebuild a running preview with python3 scripts/prepare-website.py.
Before submitting a change, run python3 scripts/website.py check.
Use translations check --strict to require every message to be translated.
Keep complete sentences and protected evidence
Paragraphs remain complete translation units. Inline emphasis, links, code and literal commands use named placeholders:
#. {ph0}: <a href="guides/">
#. {ph1}: </a>
msgctxt "page:index.html"
msgid "Already know RE? {ph0}Skip to analysis guides →{ph1}"
msgstr "已经了解逆向工程?{ph0}直接看分析指南 →{ph1}"
Move a linked or emphasized phrase when your language needs a different sentence
order. Keep its opening and closing placeholders around that phrase. Preserve
each placeholder exactly once per occurrence. Checks reject missing placeholders
and broken tag nesting. Interaction messages use names such as {speed} and
{seconds}; keep those names too.
Code blocks, inline code and translate="no" spans are copied from the source.
Commands, filenames, paths, URLs, hashes and observed values must retain their
meaning. Never translate npx rea-agents@latest setup into prose. Preserve product
names such as REA, Codex, Claude Code, Ghidra and Homebrew. Explain technical terms
in the surrounding text when needed.
In these articles, an agent is the reader's AI coding assistant. A call is a function call; a library is a software library. A port means adapting a program to another platform. An oracle is a concrete reference or checker used to verify a reconstruction. Translate those meanings rather than unrelated dictionary senses. Distinguish native machine-code analysis from local analysis, and .NET assemblies from assembly instructions. Android names the operating system; C names the programming language. Read the whole sentence when a dictionary sense would change what the software does.
Review the question, REA's findings, the agent's reasoning and the verification result together. Keep recorded versions, milestone counts, unknowns and source attribution accurate. Blog essays can use a personal voice. Translated quotes should be identifiable as translations and retain a link to the original.
Update the English source
python3 scripts/website.py sync
python3 scripts/website.py translations extract
python3 scripts/website.py translations status
python3 scripts/website.py check
Extraction generates messages.pot and merges it into each PO catalog. Unchanged
sentences keep their translations and reviewer comments. Changed sentences start
empty; removed entries are retained as obsolete translation memory. Nothing
silently accepts a guessed match. An editor's fuzzy entry remains pending until
someone reviews it and removes the flag.
If a page needs a missing or fuzzy message, its language route temporarily shows
the complete English page with a visible notice. It has noindex and stays out
of the sitemap and translated hreflang alternatives. Links from ready pages
lead to ready editions or the English source. Completing the required entries
restores the translated page and its search metadata at the next build. Runtime
messages affect only pages that use their script; an untranslated dinosaur status
does not turn the FAQ into an English fallback.
public/ remains the authored English site. _site/ is disposable generated
output. The sitemap discovers every ready edition automatically. Pages and
Cloudflare publish this same artifact. No translation API runs during a build
or in a reader's browser.
Figure labels and accessibility descriptions are included in the catalogs under
figure:<filename>. Keep labels short enough for the diagram. Interaction text
is extracted directly from t("message") calls in public/assets/*.js, with
source locations in the catalog. Keep named values instead of concatenating
translated fragments.
Language coverage and initial translations
languages.json lists the same editions as the root README, with native names,
standard language tags and text direction. English keeps its existing routes;
other editions use a language prefix such as /ja/ or /pt-BR/. Arabic and
Persian use right-to-left page layouts; code and numeric demos remain left to
right. The two Notes target applications and the downloadable source archive
remain the original investigation inputs.
The first catalogs started with machine-assisted drafts. They include editorial corrections to navigation, prompts and technical terminology. Traditional Chinese started from the Simplified Chinese draft and is maintained independently. Further language review and more natural phrasing are welcome. Submit the PO changes with the page and language you checked; a screenshot can help explain a layout issue.
Why gettext
PO catalogs have source references, reviewer comments and explicit pending translations. They can be edited locally and can later be connected to Weblate without replacing the site's translation format. This keeps one authored layout and a small offline build instead of maintaining nineteen HTML trees.
See GNU gettext's PO format, Weblate's translation workflows and Google's localized-page guidance.