From ee4412d91164664f7e96c0f42503b2ee79aad396 Mon Sep 17 00:00:00 2001 From: jmartin Date: Sat, 1 Aug 2026 11:33:02 -0400 Subject: [PATCH] Tighten resume PDF spacing for 1-2 Letter pages --- server/src/routes/resume-pdf.ts | 90 ++++++++++++++++----------------- 1 file changed, 44 insertions(+), 46 deletions(-) diff --git a/server/src/routes/resume-pdf.ts b/server/src/routes/resume-pdf.ts index a85a794..06b234a 100644 --- a/server/src/routes/resume-pdf.ts +++ b/server/src/routes/resume-pdf.ts @@ -10,11 +10,11 @@ function escapeHtml(s: string): string { .replace(/"/g, """); } -/** Compact, professional resume CSS for 1–2 printed pages. */ +/** Compact, professional resume CSS targeted at 1–2 Letter pages. */ const RESUME_CSS = ` @page { size: Letter; - margin: 0.55in 0.6in 0.55in 0.6in; + margin: 0.45in 0.55in 0.45in 0.55in; } * { box-sizing: border-box; } html, body { @@ -23,8 +23,8 @@ const RESUME_CSS = ` color: #1a1a1a; background: #fff; font-family: "Liberation Serif", "Times New Roman", "Nimbus Roman", Times, serif; - font-size: 10.5pt; - line-height: 1.35; + font-size: 9.5pt; + line-height: 1.28; -webkit-print-color-adjust: exact; print-color-adjust: exact; } @@ -37,38 +37,38 @@ const RESUME_CSS = ` header { text-align: center; - margin-bottom: 10pt; - padding-bottom: 8pt; - border-bottom: 1.25pt solid #222; + margin-bottom: 7pt; + padding-bottom: 6pt; + border-bottom: 1.1pt solid #222; break-after: avoid; page-break-after: avoid; } h1 { - margin: 0 0 2pt; + margin: 0 0 1pt; font-family: "Liberation Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 18pt; + font-size: 16pt; font-weight: 700; - letter-spacing: 0.02em; - line-height: 1.15; + letter-spacing: 0.015em; + line-height: 1.12; } .title { - margin: 0 0 4pt; + margin: 0 0 3pt; font-family: "Liberation Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 10.5pt; + font-size: 9.5pt; font-weight: 500; color: #333; } .contact { margin: 0; font-family: "Liberation Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 9pt; + font-size: 8.25pt; color: #444; } .summary { - margin: 0 0 10pt; - font-size: 9.75pt; - line-height: 1.4; + margin: 0 0 7pt; + font-size: 8.75pt; + line-height: 1.32; text-align: justify; hyphens: auto; break-inside: avoid; @@ -76,76 +76,75 @@ const RESUME_CSS = ` } .sec { - margin: 0 0 8pt; - break-inside: avoid-page; + margin: 0 0 5pt; } h2 { - margin: 10pt 0 5pt; - padding-bottom: 2pt; + margin: 7pt 0 3pt; + padding-bottom: 1.5pt; font-family: "Liberation Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 10pt; + font-size: 9pt; font-weight: 700; - letter-spacing: 0.08em; + letter-spacing: 0.07em; text-transform: uppercase; color: #111; - border-bottom: 0.75pt solid #888; + border-bottom: 0.7pt solid #888; break-after: avoid; page-break-after: avoid; } .item { - margin: 0 0 7pt; + margin: 0 0 5pt; break-inside: avoid; page-break-inside: avoid; } .item:last-child { margin-bottom: 0; } h3 { - margin: 0 0 1pt; + margin: 0; font-family: "Liberation Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 10.25pt; + font-size: 9.25pt; font-weight: 700; - line-height: 1.25; + line-height: 1.2; break-after: avoid; page-break-after: avoid; } .meta { - margin: 0 0 3pt; + margin: 0 0 2pt; font-family: "Liberation Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 8.75pt; + font-size: 8pt; color: #555; font-style: italic; break-after: avoid; page-break-after: avoid; } .item p { - margin: 0 0 2pt; - font-size: 9.5pt; - line-height: 1.35; + margin: 0 0 1.5pt; + font-size: 8.75pt; + line-height: 1.28; } ul { - margin: 2pt 0 0 14pt; + margin: 1pt 0 0 12pt; padding: 0; } li { - margin: 0 0 1.5pt; - font-size: 9.5pt; - line-height: 1.32; + margin: 0 0 1pt; + font-size: 8.75pt; + line-height: 1.26; } .skills-line { - margin: 0 0 3pt; - font-size: 9.5pt; - line-height: 1.35; + margin: 0 0 2pt; + font-size: 8.75pt; + line-height: 1.28; break-inside: avoid; page-break-inside: avoid; } .skills-line strong { font-family: "Liberation Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 9.25pt; + font-size: 8.5pt; } .links-list { - margin: 2pt 0 0 14pt; + margin: 1pt 0 0 12pt; columns: 2; - column-gap: 18pt; + column-gap: 14pt; } .links-list li { break-inside: avoid; @@ -162,8 +161,7 @@ const RESUME_CSS = ` break-after: avoid; page-break-after: avoid; } - /* Prefer keeping a heading with at least part of the next block */ - h2 { + p, li { orphans: 3; widows: 3; } @@ -274,7 +272,7 @@ export async function resumePdfRoutes(app: FastifyInstance) { printBackground: true, preferCSSPageSize: true, displayHeaderFooter: false, - margin: { top: "0.55in", bottom: "0.55in", left: "0.6in", right: "0.6in" }, + margin: { top: "0.45in", bottom: "0.45in", left: "0.55in", right: "0.55in" }, }); const filename = `${(resume.fullName || "resume").replace(/\s+/g, "_")}_Resume.pdf`; return reply