# Template 1: Marble (`marble`) Source: `templates/reference/1.pdf`. All coordinates are in points from the top-left of the reference page (595.5 x 842.25). Measured from the PDF content streams during design analysis. ## Style Airy editorial invoice. Letter-spaced Lustria serif caps (right-aligned 'INVOICE #1234', column heads, 'AMOUNT DUE'), a light geometric sans body (Now), pale-grey zebra rows, two mauve-grey hairlines around the parties band, and photographic white-marble bands at the top (56pt) and bottom (130pt). The bottom band carries the vendor contact footer. All text is pure black with no accent colour. ## Fonts Measured from the embedded subsets. Tracking is built into per-glyph Td moves (Tc=0), so the em values below are measured gaps. 1) Lustria Regular. OFL 1.1 (name table: 'Copyright (c) 2011, Matthew Desmond ... with Reserved Font Name Lustria'; on Google Fonts), so it is safe to bundle. upm 1000, hhea ascent 955 / descent -327 / lineGap 0, capHeight 704. Used in ALL CAPS only: - Title 'INVOICE #1234': 25.18pt, letterSpacing 4.83pt (0.192em) - Table heads DESCRIPTION / HOURS / PRICE / TOTAL: 11.68pt, 2.24pt (0.192em) - 'BILL TO:' / 'PAYABLE TO:': 12.65pt, 1.39pt (0.110em) - 'AMOUNT DUE: $3500': 14.60pt, 2.80pt (0.192em) 2) Now Regular. PROPRIETARY. Name table reads '(c)2015 Now Typeface is a trademark of Alfredo Marco Pradil. All rights reserved.', fsType 8. It is not OFL, so it cannot go into the xbps without a licence. upm 800, ascent 736 / descent -240 (0.92 / -0.30em), capHeight 0.75em. Used for: - Issued/Due lines and the BILL TO / PAYABLE TO blocks: 11.55pt, 0.48pt (0.042em). Pitch is 17.5 for the meta lines and 18.2 for the blocks, so lineHeight 1.52 / 1.58. - Table cells: 10.57pt, 0.46pt (0.044em) - Footer: 9.60pt, 0.61pt (0.064em), pitch 15.3-15.4, so lineHeight 1.6 Substitute for Now: Poppins Regular (OFL, already needed by templates 2/3/7/8/11), about 0.5pt smaller with about 0.02em tracking. Advance widths per 1000 units, Now vs Poppins: n 560 vs 640, m 840 vs 1030, s 414 vs 534, u 524 vs 640, O 894 (round geometric). Poppins therefore sets typical strings 3-5% wider ('reallygreatsite.com' 9414 vs 9823 in Poppins Medium) and lowercase-heavy runs up to about 15% wider, so columns must flex. If one more family is acceptable, Jost (OFL, Futura-like, narrow s, circular O) is a closer look-alike. Rupee sign: Lustria (2011, Latin only) almost certainly lacks U+20B9. Any amount set in Lustria needs fontFamily ['Lustria','IBM Plex Sans']; the sign is verified present in the IBM Plex Sans and Montserrat TTF cmaps. ## Colours #FFFFFF page background. #000000 for all text (no greys anywhere). #F7F7F8 zebra row bands (rows 1, 3, 5, 7). #E7E1E6 hairline rules (mauve-grey, 0.75pt). Marble raster: very light warm grey with lilac-grey veins. Visual estimate only: base about #EEEDEF, veins about #CFCAD0. For a flat replacement band use #F2F1F3 or the zebra #F7F7F8. No accent colour. A brand accent could optionally replace #E7E1E6 on the rules. ## Layout Coordinates are pt from the top-left of the 595.5 x 842.25 visible page. y is the text baseline unless noted. 1. Top marble band: y 7.6 to 63.8 (h 56.3), x 0 to 595.5. The 7.6pt white sliver above it comes from the reference design's clip rectangle (starts at 7.56). Render it full-bleed from 0 to 64. 2. Header, y 64 to 200. The left half (x 31 to 300) is empty and becomes the logo slot. The right column is right-aligned at x 549.0: - 'INVOICE #1234', baseline 124.9. Reference box x 312.7-554.4, top 101.5; glyph run x 313.4-549.0, w 235.6. - 'Issued: 06/09/2021' baseline 159.6 and 'Due: On Receipt' baseline 177.1 (pitch 17.5). Right edge 549.0, box x 426-550. 3. Rule 1: y 219.4, x 31.5 to 549.8, 0.75pt #E7E1E6. 4. Parties band, 3 columns with 2 used: - Col A at x 38.5: 'BILL TO:' baseline 247.9, then lines at 269.0 / 287.2 / 305.4. - Col B at x 211.4: 'PAYABLE TO:' baseline 247.9, same 3 line baselines. - Col C (x about 380 to 549) is empty. Spacing: rule to label baseline 28.5, label to first line 21.1, last line to rule 17.8. 5. Rule 2: y 323.2, same style. The band is 103.8pt between rules. 6. Gap from 323 to 375 (about 52pt). 7. Table header baseline 384.9, with no fill or rule. The first row band starts at 398.6, 13.7pt below the header baseline. 8. 7 item rows, table x 31.2 to 549.6 (w 518.4). Zebra bands (h 32.0) start at 398.6 / 462.6 / 529.5 / 597.2. Row baselines are 417.2 / 448.7 / 481.2 / 515.7 / 548.1 / 583.3 / 615.8, an irregular 31.5-35.2pt pitch; normalise to 32. 9. 'AMOUNT DUE: $3500' baseline 668.7. Glyph run x 337.2-531.8, box right edge 535.4, so it is right-aligned about 14pt inside the table edge, 29pt below the last band. 10. Gap from 669 to 712. 11. Bottom marble band: y 712.0 to 842.25 (h 130.3), full-bleed. Footer text starts about 35pt below the band top: - col 1 at x 40.7: name / address line 1 / address line 2, baselines 746.9 / 762.2 / 777.6 - col 2 at x 197.8: phone / email / web, same baselines - col 3 (x about 360 to 549) is empty Effective margins: bands and rules start at x 31.2 with text inset to 38.5-40.7. The right edge is 549.0-549.8, giving a 45.7pt right margin, so the reference design's placement is asymmetric. Recommend symmetric 36pt page padding plus an 8pt text inset. ## Items table Column centres, measured from the header and value glyphs (reference centres the numbers): - DESCRIPTION: left-aligned (header x 38.5, cells x 40.7) - HOURS: centre x about 355.5 - PRICE: centre x about 438.4 - TOTAL: centre x about 512.1 Column boxes inside table x 31.2 to 549.6 (w 518.4) that reproduce those centres: - Description 31.2-309.2 (278.0, 53.6%) - Hours 309.2-401.8 (92.6, 17.9%) - Price 401.8-474.7 (72.9, 14.1%) - Total 474.7-549.6 (74.9, 14.4%) Header: Lustria 11.68pt caps, tracking 2.24pt, #000, no background, no border. Rows: Now 10.57pt #000, tracking 0.46pt, height 32 (31.98). Zebra #F7F7F8 on the 1st/3rd/5th/7th rows (0-based even), white otherwise. No borders. Text is vertically centred (baseline 18.6pt below the band top) and the description is inset 9.5pt from the band's left edge. The reference sample has 7 rows with values '5', '$100', '$500'. Recommendation: use minHeight 32 (not a fixed height) with paddingVertical about 9, and alternate the zebra by index. Keep qty centred, but right-align the rupee amounts (Rate and Amount) with a 9.5pt right inset so Indian-format numbers line up on the decimal. This is a deliberate deviation from reference. ## Totals and payment reference has one totals line: 'AMOUNT DUE: $3500' (Lustria 14.60pt caps, tracking 2.80pt, black), right-aligned at x about 535, baseline 668.7. It has no subtotal or tax rows, no bank block ('PAYABLE TO:' holds name/email/website), no notes, no amount in words, no signature and no thank-you. The footer band repeats the vendor name and address (col 1) and phone/email/web (col 2) in Now 9.6pt. Voiced version, keeping the same idiom: - Add a right-aligned stack above AMOUNT DUE. Labels in Lustria 9pt caps (tracking 0.192em), values in the 10.57pt body font, pitch about 16pt, values right-aligned to x about 535. Rows: SUBTOTAL, DISCOUNT (if > 0), then CGST 9% + SGST 9% or IGST 18%. - Then 'AMOUNT DUE: ' at 14.6pt, with the rupee sign from the fallback font. - Amount in words on the left, on the AMOUNT DUE row: x 38.5, max width about 280, body 9.6pt, 'Rupees ... Only'. - Notes under the words, 9.6pt. - Signature or the computer-generated note in footer col 3, or just above the bottom band on the right. ## Decoration and images Raster: a single image XObject (X8), a 1321 x 1321px JPEG (DCTDecode, ICCBased sRGB, 286,646 bytes) showing light grey/white marble (reference stock). It is drawn twice as a 700 x 700pt square and clipped: (a) Top band: clip x 0-595.5, y 7.56-63.83; image placed x -48.4 to 651.7, y -218.9 to 481.1. (b) Bottom band: clip x 0-595.5, y 711.97-842.25; image placed x -55.2 to 644.8, y 406.7 to 1106.7. That is about 1.9px/pt (about 136 dpi). It cannot be rebuilt as vector, and the reference design's content licence does not allow redistributing stock media extracted into a template, so do NOT bundle the extracted JPEG. Options: - a flat band in #F2F1F3 or #F7F7F8 (zero cost) - an Svg LinearGradient (#F4F3F5 to #ECEAEE) for a soft sheen - a self-sourced CC0 marble JPEG, pre-cropped to two strips (about 1600x150px top, 1600x350px bottom, 80 KB or less each), placed with Vector parts are trivial: 4 zebra rects #F7F7F8 at 518.4 x 32.0, and 2 hairlines #E7E1E6 0.75pt, 518.3 long. The alpha-0 rectangles in the page stream are tagged-PDF layout artefacts; ignore them. ## Mapping to Voiced fields Template region to Voiced field: - Empty header-left (x 38.5 to 300, y about 92 to 136, bottom-aligned with the title baseline 124.9): vendor logo. The logo is a 3:1 PNG (2172x724); fit it in 150x50 with objectFit contain. vendorName can optionally go under it in Lustria 12.65 caps, tracking 0.11em. - 'INVOICE #1234': 'INVOICE', or 'TAX INVOICE' when taxType is not none, as the 25.18pt title. Move the number to its own right-aligned line above 'Issued:', for example 'No. INV/2026-27/0042' in the 11.55pt body font, so the tracked title stays short. - 'Issued:': invoiceDate. - 'Due:': dueDate (already in types.ts); show 'On Receipt' when empty. - BILL TO: clientName / clientAddress (multi-line) / 'GSTIN: ' + clientGstin (optional) / 'Place of supply: ()' / 'PO: ' + poNumber. - PAYABLE TO: bank.accountName (fallback vendorName), bankName + branch, 'A/c ' + accountNo, 'IFSC ' + ifsc, 'UPI ' (planned). - Empty parties col C (x about 380 to 549): vendor statutory IDs (GSTIN vendorGstin, PAN vendorPan, state code), with Lustria 9pt caps labels and body-font values. - Table to items: - description - HOURS becomes 'QTY': quantity + unit; the header can stay HOURS when every unit is hour - PRICE becomes 'RATE': rate, or a dash when mode = fixed - TOTAL becomes 'AMOUNT': computeLineAmount - AMOUNT DUE: total, preceded by the subtotal / discount / CGST / SGST / IGST rows. - Footer col 1: vendorName + vendorAddress. - Footer col 2: vendorPhone, vendorEmail. Website is not in Settings; drop it or add a field. - Footer col 3 (empty): signature image (120x40 max) + 'Authorised signatory', or 'Computer-generated invoice; no signature required.' at 8pt. Put the 'Generated with Voiced' credit at 7pt along the band bottom. Voiced fields with no reference slot, and where they go: - GSTIN/PAN: parties col C - Bank details: PAYABLE TO - Place of supply: BILL TO - CGST/SGST/IGST: totals stack - Amount in words: left of AMOUNT DUE - Notes: below the words - Signature: footer col 3 - HSN/SAC (not in the current types.ts): a grey 9pt second line under the description ('SAC 998314'), or a 50pt column taken from Description ## Overflow risks - Title: right-aligned, tracked 25pt. 'INVOICE #1234' already fills 235.6pt of its 241pt box. 'TAX INVOICE #INV/2026-27/0042' (about 28 glyphs at about 19pt) is about 520pt and would run left across the logo zone. This is the same class of bug as the reported vendor-address/INVOICE overlap. Fix: put the number on its own line, auto-fit the font size, or both. - Parties band: col A is 173pt wide (38.5 to 211.4), so long client names and addresses wrap, and PAYABLE TO grows from 3 lines to 5-6 (about 110pt). The rules must be borders of a flow View, not absolutely placed at 219.4/323.2. - Unbreakable tokens at 11.55pt (emails, UPI IDs, 15-character GSTINs, websites): 'accounts@longcompanyname.co.in' is about 175pt, wider than the column. Add a hyphenation callback that allows breaks at @ . / - or shrink the text. - Description column is about 278pt (about 45 chars per line at 10.57pt), so rows go multi-line; use minHeight 32. - Vertical budget: the last row ends at 629, AMOUNT DUE sits at 669, the bottom band starts at 712. Adding Subtotal plus two tax rows (+48pt) and the words line means 6 or more items no longer fit on page 1 of an A4. Page 2 must still reserve the fixed bands: paddingTop at least 64 + gap, paddingBottom at least 130 + gap. - Footer col 1 is about 150pt wide at 9.6pt. An Indian address (door no., street, area, city, state, PIN) wraps to 4-6 lines. From baseline 746.9 at 15.4pt pitch, 6 lines end at 823.9 (18pt from the edge), and 7 or more leave the page. Widen col 1 to about 210pt (shift col 2 to x about 260) and cap it at maxLines 5 with an ellipsis. - Rupee sign in Lustria: the glyph is missing unless a fallback font is set. ## US Letter adaptation Letter is 612x792 against the reference design's 595.5x842.25: 16.5pt wider and 50.25pt shorter. Do not scale the type. - Horizontal: Page paddingHorizontal comes from the user margin, with a template default of 36. the reference design's effective 31.2 left / 45.7 right is an asymmetry to normalise. Content width goes from 518.4 on A4 to 540 on Letter at 36. Set column widths as percentages (53.6 / 17.9 / 14.1 / 14.4). - Bands: absolute, full-bleed and fixed. The top band is 0 to 64 on both sizes. The bottom band is 130pt on A4 and about 100-110pt on Letter (the footer text block is about 46pt plus about 30pt of top padding). - Vertical: on Letter, shrink the 52pt gap above the table head to about 30 and the 43pt gap above the bottom band to about 24. Page paddingTop = 64 + userTop (about 28); paddingBottom = band height + userBottom (about 16). - The margin setting changes only Page padding; decorations always ignore margins. ## react-pdf notes Structure (react-pdf 4.9 with yoga 3): (or ) 3 footer columns - Header: a row View with justifyContent 'space-between' and alignItems 'flex-end'. Left logo View: flexShrink 0, maxWidth '45%'. Right meta View: flexShrink 1, alignItems 'flex-end'. - Parties: a row View with borderTopWidth and borderBottomWidth 0.75 in #E7E1E6, paddingTop 18, paddingBottom 16. Its 3 columns each need flex 1 with flexShrink 1, otherwise text in a row will not wrap. - Table: give the header row minPresenceAhead of about 64 so it is never left alone at a page bottom. Rows: items.map((it, i) => ) - Wrap the totals stack, AMOUNT DUE and the words line in one . - Absolute children of resolve against the page edge (padding ignored). The existing InvoiceDocument footer already relies on this (position absolute, bottom 24, left/right 40, with paddingHorizontal 40). The fixed bands must be matched by Page paddingTop/paddingBottom, or continuation pages will draw over them. - Tracked caps: { fontFamily: 'Lustria', fontSize: 25.18, letterSpacing: 4.83, textTransform: 'uppercase' }. react-pdf adds letterSpacing to every glyph advance, including the last (verify in preview), so right-aligned tracked text sits one letterSpacing short of the edge. Compensate with marginRight: -4.83 (-2.80 for AMOUNT DUE, -2.24 for the table heads). - Fonts: Font.register Lustria and the substitute from static TTF (or WOFF). The v4 docs list only TTF/WOFF and no variable fonts. Money: fontFamily: ['Lustria', 'IBM Plex Sans']; array fallback is supported in v4 and Helvetica is appended automatically. - Continuation pages: a fixed element is cloned onto every page. Check in preview that a fixed table-header row lands correctly; if it does not, chunk the items per page and render the header for each chunk. - Font.registerHyphenationCallback(word => splitAt(word, /[@./-]/)) lets emails, GSTINs and UPI IDs break instead of overflowing. ## Similarity to other templates No near-duplicate in the set. This is the only template that combines photographic texture bands, zebra rows and a right-aligned tracked serif title (6 also uses a raster paper texture, with a different layout). It shares the tracked-caps title idea with 4/format.pdf and 9/10, and the grey-band idea with 9/10. It has nothing in common with the in-app IBM Plex template beyond the data blocks. Effort is medium: new header, parties band, zebra table, band decorations and a font substitution.