From d2e7ccb48cca355988441d158d65e1cb6fd7a046 Mon Sep 17 00:00:00 2001 From: Steffen Becker Date: Mon, 24 Aug 2026 17:00:42 +0000 Subject: [PATCH] fix: pin the letter template's mm geometry, measured headlessly The return-address paragraph gets fontSize 8pt so its line box is 8pt tall (a 12pt paragraph mark pushed the address zone 1.6mm low), and an info line with no address half indents 10cm instead of leading with a tab (a leading tab stays on the default grid). Measured in Chromium: return address 44.97mm, address zone 49.98mm, info column 124.98mm, fold marks 87/148.5/192mm. --- CLAUDE.md | 1 + src/lib/components/CLAUDE.md | 9 +++++++++ src/lib/templates/din5008b.ts | 9 +++++++-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index bb4221f..92d03df 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -92,6 +92,7 @@ src/ orderedListTypes, historyLog, colorDebug) math/ – formula AST: LaTeX parser/serializer, MathML, OMML export/ import/ spell/ storage/ styles/ – ODF+DOCX I/O, spell-check, persistence, named styles + templates/ – built-in document templates: registry + one localized module each styles/ – global.css + editor.css ``` diff --git a/src/lib/components/CLAUDE.md b/src/lib/components/CLAUDE.md index 6d0fa69..d3aa281 100644 --- a/src/lib/components/CLAUDE.md +++ b/src/lib/components/CLAUDE.md @@ -199,6 +199,15 @@ per page in unscaled document px. The watermark is an `` b fontwork shape **stretches** its text to its box instead of setting it at a size — a font size alone makes a short word far too small and a long one overflow the page. +## Built-in templates (`TemplateGalleryDialog.svelte`, `lib/templates/`) + +"New from template" in both chromes opens the gallery; a card applies its entry via +`App.svelte`'s `applyTemplate` — `resetDocumentState()` (the extracted body of New), +then the template's content, margins, styles and fold marks. `documentName` becomes the +localized template name and no file handle is bound, so the first Save asks where. The +DIN letter's mm positions were verified headlessly (45mm address field, 125mm info +column); its module documents the arithmetic. + ## Fold marks (`FoldMarkLayer.svelte`, `storage/foldMarks.ts`) Fold + punch marks at the DIN 5008 positions, drawn per page in the left margin from diff --git a/src/lib/templates/din5008b.ts b/src/lib/templates/din5008b.ts index a9f6590..9cfff65 100644 --- a/src/lib/templates/din5008b.ts +++ b/src/lib/templates/din5008b.ts @@ -25,8 +25,12 @@ const BOLD = { type: 'bold' }; function buildLetter(): TemplateData { const L = t().templates.letter; + // An info line with no address half indents to the column instead of leading with + // a tab (a tab with nothing before it stays on the default grid). const addressRow = (attrs: N | null, addr: N[], info: N[]): N => - P({ ...(attrs ?? {}), tabStops: INFO_TAB }, ...addr, T('\t'), ...info); + addr.length + ? P({ ...(attrs ?? {}), tabStops: INFO_TAB }, ...addr, T('\t'), ...info) + : P({ ...(attrs ?? {}), indent: 10 }, ...info); const date: N = { type: 'dateTimeField', attrs: { kind: 'date', format: DEFAULT_DATE_FORMAT, fixed: true, value: toDateValue(new Date()) } }; return { margins: { top: 2, bottom: 2, left: 2.5, right: 2 }, @@ -36,7 +40,8 @@ function buildLetter(): TemplateData { content: [ P(null, PLH(L.companyName, BOLD)), // The one-line return address opens the address field at 45mm from the top. - P({ spaceBefore: RETURN_SPACE_BEFORE_PT, spaceAfter: RETURN_SPACE_AFTER_PT }, PLH(L.returnAddress, SMALL)), + // fontSize also shrinks the paragraph mark, so the line box is 8pt tall. + P({ spaceBefore: RETURN_SPACE_BEFORE_PT, spaceAfter: RETURN_SPACE_AFTER_PT, fontSize: '8pt' }, PLH(L.returnAddress, SMALL)), addressRow(null, [PLH(L.recipientCompany)], [T(L.yourRef), PLH(L.reference)]), addressRow(null, [PLH(L.recipientName)], [T(L.yourMessage), PLH(L.date)]), addressRow(null, [PLH(L.recipientStreet)], [T(L.ourRef), PLH(L.reference)]),