From 9c4b768982bc09ddbb250db2df2f5c6966dce214 Mon Sep 17 00:00:00 2001 From: Steffen Becker Date: Mon, 17 Aug 2026 13:27:46 +0200 Subject: [PATCH] fix: a page is the paper's exact height, not the pixel it rounds to MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sheet boxes rounded cm × PX_PER_CM where --user-page-height keeps it exact, and pageBreaks builds its grid from the rounded value they publish as --pb-section-page: A4 came out 1123px against 1122.52, so every page ran 0.127mm long and the text crept down the flow — 1.8mm by the sixteenth page, 6.0mm by the forty-eighth, against a reference whose footer sits at the same height on every page. Corpus 1772 -> 1108, eight fixtures improved, none rose. --- src/lib/components/CLAUDE.md | 3 +++ src/lib/components/Editor.svelte | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/lib/components/CLAUDE.md b/src/lib/components/CLAUDE.md index 1c063b2..cae8902 100644 --- a/src/lib/components/CLAUDE.md +++ b/src/lib/components/CLAUDE.md @@ -110,6 +110,9 @@ a 177-page document. Word and LibreOffice draw only the visible pages; we can't. - `min-width: 0` on the row and its scroller: a flex item's automatic minimum is its content, so without it the grid widens the whole app instead of scrolling. - No ruler here: it would repeat per column and eat into the page's own box. +- **`sectionPaper` stays unrounded.** `pageBreaks` builds its grid from the height this + publishes as `--pb-section-page`, so rounding A4's 1122.52px to 1123 ran every page + 0.127mm long — 6mm of drift by page 48, against a reference page that never moves. ## Zoom (`Editor.svelte`) diff --git a/src/lib/components/Editor.svelte b/src/lib/components/Editor.svelte index 8b5a271..8ab1b4c 100644 --- a/src/lib/components/Editor.svelte +++ b/src/lib/components/Editor.svelte @@ -197,11 +197,12 @@ import { EMPTY_PAGE_DECOR, type PageDecor } from '../storage/pageDecor'; ].map((g) => g.map((n) => Math.round(n)).join('|')).join(',')); // Each section's own paper (px). A section that names neither format nor orientation - // is on the document's, so its entry is the document's box. + // is on the document's, so its entry is the document's box. Unrounded: this is the + // grid pageBreaks places against, and half a pixel per page accumulates down the document. let sectionPaper = $derived([ pageDimsCm(pageFormat, orientation), ...extraHfSections.map((s) => pageDimsCm(s.format ?? pageFormat, s.orientation ?? orientation)), - ].map((d) => ({ w: Math.round(d.w * PX_PER_CM), h: Math.round(d.h * PX_PER_CM) }))); + ].map((d) => ({ w: d.w * PX_PER_CM, h: d.h * PX_PER_CM }))); // The sheet .paper reserves is the widest of them: a landscape section is wider than // the portrait ones around it and would otherwise be cut at the page edge. let paperWidth = $derived(Math.max(...sectionPaper.map((p) => p.w)));