fix(reporting): report PDF now fits one clean A4 portrait page

The exported PDF split awkwardly — page 1 half-empty, the EPC + ledger
block pushed wholesale to page 2 — and rendered too wide. Cause: the
print CSS used `@page { margin: 0 }` plus a `transform: scale(0.94);
width: 106.4%` hack on .print-root, which renders wider than the sheet
and paginates badly (a scaled/oversized root can't break cleanly).

- Print CSS: real `@page { size: A4 portrait; margin: 12mm }`, drop the
  transform-scale and width hack. (These classes are used only by the
  report, so no other page is affected.)
- Constrain the report to A4 content width (max-w-190mm, centred) so it
  can never render landscape/oversized, with on-screen padding that
  collapses in print.

Result: cover + headline + KPI tiles + EPC distribution and Investment
ledger (side by side) + footer all fit one portrait page; current-stock
likewise. Verified by generating the real PDFs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-07-20 11:11:13 +01:00
parent 0509836c42
commit 4a91e2e817
2 changed files with 15 additions and 11 deletions

View file

@ -128,20 +128,24 @@
PAGE LAYOUT
--------------------------------- */
/* Real A4 portrait with proper margins the report is designed to this
width, so it never renders landscape/oversized. */
@page {
margin: 0;
size: A4 portrait;
margin: 12mm;
}
/* Outer page padding (NOT scaled) */
/* Margins come from @page now; no extra padding, and NO transform scale
(a scaled root paginates badly it was pushing whole blocks to page 2
and leaving the first page half-empty). */
.print-page {
padding: 20px 24px;
padding: 0;
max-width: none;
}
/* Inner content (scaled slightly) */
.print-root {
transform: scale(0.94);
transform-origin: top left;
width: 106.4%; /* 1 / 0.94 */
width: 100%;
transform: none;
}
/* Keep every colour (EPC chips, ledger bars, tints) when printing

View file

@ -264,8 +264,8 @@ export default async function ReportingPdfPage(props: {
if (segment === null) {
const belowC = countBelowBand(bandCounts, "C");
return (
<div className="print-page">
<div className="print-root space-y-5 p-2 text-[#14163d]">
<div className="print-page mx-auto max-w-[190mm] bg-white">
<div className="print-root space-y-4 p-8 text-[#14163d] print:p-0">
<AutoPrint />
<Cover title="Current stock" subtitle={portfolioName} />
@ -389,8 +389,8 @@ export default async function ReportingPdfPage(props: {
});
return (
<div className="print-page">
<div className="print-root space-y-5 p-2 text-[#14163d]">
<div className="print-page mx-auto max-w-[190mm] bg-white">
<div className="print-root space-y-4 p-8 text-[#14163d] print:p-0">
<AutoPrint />
<Cover title={title} subtitle={portfolioName} />