From eb817dea65700815167d06720d1d37660ced5c70 Mon Sep 17 00:00:00 2001 From: Maurice Date: Wed, 29 Jul 2026 20:05:25 +0200 Subject: [PATCH] fix(pdf): keep a stay whole across a page edge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An accommodation could be cut in half by a page break — the check-in time at the foot of one sheet, the hotel name and address at the head of the next, under a repeated day header that read like a duplicate day. Place and note cards have carried break-inside: avoid all along; this one never did. It could always happen to a day that overflowed its page. Letting the days flow means content meets a page edge far more often, which is how it turned up. Printing the same trip through Chromium: two torn stays before, none after. --- client/src/components/PDF/TripPDF.test.ts | 10 ++++++++++ client/src/components/PDF/TripPDF.tsx | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/client/src/components/PDF/TripPDF.test.ts b/client/src/components/PDF/TripPDF.test.ts index 02b487a67..e790275ec 100644 --- a/client/src/components/PDF/TripPDF.test.ts +++ b/client/src/components/PDF/TripPDF.test.ts @@ -1004,4 +1004,14 @@ describe('page breaks between days (#1292)', () => { expect(() => toggle()!.click()).not.toThrow() }) + + // Verified against a real print engine: without this rule Chromium tore a stay + // across the page edge, the check-in time on one sheet and the hotel name on + // the next. Place and note cards already carried it. + it('FE-PDF-BREAK-007: a stay may not be split by a page edge', async () => { + await downloadTripPDF(twoDays) + const html = getIframe()!.srcdoc + const rule = html.slice(html.indexOf('.day-accommodation {')) + expect(rule.slice(0, rule.indexOf('}'))).toContain('break-inside: avoid') + }) }) diff --git a/client/src/components/PDF/TripPDF.tsx b/client/src/components/PDF/TripPDF.tsx index e1e019f66..174b20dc5 100644 --- a/client/src/components/PDF/TripPDF.tsx +++ b/client/src/components/PDF/TripPDF.tsx @@ -565,6 +565,10 @@ export async function downloadTripPDF({ trip, days, places, assignments = {}, ca flex: 1 1 45%; min-width: 200px; margin: 4px 0; padding: 10px; border: 2px solid #e2e8f0; border-radius: 12px; display: flex; flex-direction: column; + /* Place and note cards have said this all along; without it a stay is torn + in half by a page edge, its check-in time on one sheet and the hotel name + on the next. Rare while every day started a page, common once they flow. */ + break-inside: avoid; page-break-inside: avoid; } .day-accommodation-title { font-size: 16px; font-weight: 600; text-align: center;