Centred logo header, badges, the live-app link, feature overview,
licensing and CLA pointers. README.md leaves .gitignore — it used to
be a private scratch file, now it is the repo's front page.
.claude, .devcontainer, .github/prompts, README.md and the two root
Playwright scratch scripts are local tooling. They stay on disk and are
ignored, so no `git add -A` sweeps them back in.
The parity findings named the six files the corpus is built from, so every
measurement carried a document title into the history. They move to a
gitignored FINDINGS.md beside the corpus itself; the README keeps the harness.
A test that needs a document builds one, so nothing under src/ or tests/
reads the gitignored corpus — CI greps for exactly that.
ODF text:anchor-type="page" is a cover graphic or a watermark: out of
flow, placed from its page's corner, behind the text. In flow, the two
full-page frames of a fixture's covers cost three pages.
Everything else in tests/ compares documents at the model level; nothing checked
what a page actually looks like. run.mjs renders the same file through soffice
and through the real app in Chromium, reads both back as word boxes, and diffs
page count, line count, line text and line position.
The corpus stays out of the repo: make-fixtures.mjs authors the baseline .docx
files, and real-world documents are whatever you drop into the gitignored
fixtures/ yourself.