Files
Voiced/docs/templates/03-monolith.md
T
xavierk 385d7974cb Add the Monolith and Cobalt Stripe templates
Standalone layouts for Canva templates 3 and 8, with the user's logo sized to the
placeholder box, a CapRule decor primitive, optional TableRows rule/heading options,
and a separate 1..45-row sweep test file.
2026-10-04 11:25:19 +05:30

17 KiB

Template 3: Monolith (monolith)

Source: templates/Modern Neutral Invoice Template/3.pdf. All coordinates are in points from the top-left of the Canva page (595.5 x 842.25). Measured from the PDF content streams during design analysis.

Style

Stark monochrome Poppins. An oversized 60pt black INVOICE, a right-aligned vendor/date/number stack, black hairline section rules, a thick-ruled table header, centred number columns, a compact right-hand totals block, and a two-column footer (payment info / vendor contact) framed by rules.

Fonts

All OFL (Poppins v4.004, 'Copyright 2020 The Poppins Project Authors'); bundle static TTF at 400/500/700. upm 1000, hhea 1050 / -350 / lineGap 100; capHeight Bold 705, Medium 697, Regular 698. Tracking is 0 throughout and everything is #000.

  • Poppins Bold:
  • 'INVOICE' at 60.02pt
  • 'BILLED TO:' and 'PAYMENT INFORMATION :' at 14.5pt
  • at 12.5pt: the vendor names ('CAVEIN', 'SUDIUM LOVRA'), 'INVOICE NO.15325', the table heads, the Subtotal/Tax/Total labels and the Total value
  • Poppins Medium 12.5pt: client lines, item descriptions and values, Subtotal/Tax values, payment and vendor lines. Pitch 17.25 (lineHeight 1.38).
  • Poppins Regular 12.5pt: the date '15 March 2025' and the ':' separators in the payment grid. 'INVOICE' at 60.02pt measures 249.75pt of advance, i.e. 4.161 x fontSize. Rupee sign: cannot be checked from the Poppins subset, so use fontFamily ['Poppins','IBM Plex Sans'].

Colours

Strict monochrome: #000000 for text and every rule, #FFFFFF page. No fills and no greys. Optionally expose an accent token for the title and the 1.5pt table rules so a brand colour can be applied.

Layout

Coordinates are pt from the top-left; y is the baseline unless noted. Content box x about 35 to 560.5 (about 35pt side margins).

  1. Header row:
  • Left: 'INVOICE', Poppins Bold 60.02. Glyph origin at x 50.7, about 16pt in from the 35pt content edge; baseline 96.3; cap top 54.0; advance 249.8, ending at x 300.5.
  • Right, right-aligned to x 560.6: 'CAVEIN' (Bold 12.5) baseline 63.7, with its cap top 54.9 lined up with the title's cap top; '15 March 2025' (Regular 12.5) 84.7; 'INVOICE NO.15325' (Bold 12.5) 105.7. Pitch 21 (lineHeight 1.68).
  1. Rule 0.75 at y 116.75, x 35.5 to 560.0.
  2. 'BILLED TO:' (Bold 14.5) at x 34.4, baseline 153.0, 36.2 below the rule. Client lines (Medium 12.5) at x 35.5, baselines 178.1 / 195.4 / 212.6 (pitch 17.25).
  3. Rule 0.75 at y 238.3 (x 34.4 to 559.0), 25.7 below the last line.
  4. Free band from 238 to 326 (88pt), empty.
  5. Table: 1.5pt rule at y 326.2; header baseline 350.4 (Bold 12.5); 1.5pt rule at y 365.5 (x 36.1 to 560.0). The header band is 39.3pt.
  6. Item rows: descriptions on baselines 389.9 / 442.1 / 491.1 (Medium 12.5, x 44.4); numbers on 396.9 / 449.2 / 498.5. The numbers sit about 7pt lower, a Canva misalignment to fix rather than copy. Pitch is about 52 / 49pt.
  7. Rule 0.75 at y 521.6 (x 36.4 to 560.3).
  8. Totals block on the right, x 344.5 to 560: Subtotal baseline 541.6, Tax 564.6 (pitch 23), a 0.75 rule at y 577.5 (x 344.5 to 560.0), Total 597.7.
  9. Empty from 598 to 705 (107pt).
  10. Footer:
  • Rule 0.75 at y 705.1 (x 36.4 to 560.3).
  • Left: 'PAYMENT INFORMATION :' (Bold 14.5) at x 34.4, baseline 728.0. Payment lines (Medium 12.5): account name 758.9; 'Bank : Pinky Bank' 776.1; 'Account No. : 0123 4567 8901' 793.4. Labels at x 35.5, ':' at x 149.4 (Regular), values at x 170.8.
  • Right: vendor name 'SUDIUM LOVRA' (Bold 12.5) at x 395.2, baseline 726.0. Lines (Medium 12.5) at x 396.3: address 758.7, phone 776.0, website 793.2.
  1. Rule 0.75 at y 812.45 (x 36.4 to 560.3), about 30pt above the page bottom.

Items table

Width 523.9 (x 36.1 to 560.0). The header sits between 1.5pt black rules above (326.2) and below (365.5), and the body is closed by a 0.75pt rule (521.6). No vertical lines, fills or zebra. Measured column centres: DESCRIPTION is left-aligned at x 44.4 (8.3pt inset); PRICE centre 311.5; QTY centre 407.8; TOTAL centre 506.0. Equal 98pt number columns land within 1.5pt of those centres:

  • Description 36.1-261 (about 225, 43%)
  • Price 261-359
  • Qty 359-457
  • Total 457-555, plus 5pt of right padding PRICE comes before QTY here; the others in the set put QTY first. Header labels are Poppins Bold 12.5 caps; cells are Poppins Medium 12.5. Canva centres the numbers. As a deliberate deviation, right-align the rupee amounts with a 10pt right pad and keep qty centred. Rows are about 50pt tall with generous whitespace: the first baseline is 24.4pt below the header rule and the last is 23.1pt above the closing rule. Fix the 7pt description/number offset by aligning every cell to the same first baseline (alignItems 'flex-start', paddingVertical about 14).

Totals and payment

Canva:

  • Totals block: right-aligned, 215.5pt wide (x 344.5 to 560), two 108pt columns with centred text. Labels Poppins Bold 12.5 (centre x 398.5); values Medium 12.5 (centre 505.9). Subtotal and Tax rows at 23pt pitch, then a 0.75pt rule, then Total about 20pt below it with both label and value in Bold.
  • Payment block, footer left: heading 'PAYMENT INFORMATION :' in Bold 14.5, then a 3-column key/value grid: label (x 35.5) | ':' (x 149.4) | value (x 170.8), Medium 12.5, pitch 17.25. The first line is the account holder.
  • Vendor block, footer right: name in Bold 12.5, then address / phone / website in Medium 12.5.
  • No amount in words, notes, signature or thank-you. Voiced version:
  • Totals rows at the same 23pt pitch: Subtotal, Discount, CGST (9%), SGST (9%) or IGST (18%), then the rule, then Total.
  • Amount in words left of the totals block: x 36 to 330, Poppins Medium 10.5, top-aligned with Subtotal. Notes go below it.
  • Signature in the empty 598-705 band on the right (x 396 to 560): an image up to 150x45 plus 'Authorised Signatory' in Medium 10, or the computer-generated note.

Decoration and images

No images and no fills, only black strokes:

  • 0.75pt rules at y 116.75, 238.3, 521.6, 577.5 (totals block only, 215.5pt long), 705.1 and 812.45
  • 1.5pt rules at y 326.2 and 365.5 Every rule except the totals rule spans the full content width. All of it is trivial to rebuild with borderTop/borderBottom on flow Views.

Mapping to Voiced fields

  • 'INVOICE': 'INVOICE' or 'TAX INVOICE', with the font size auto-fitted.
  • 'CAVEIN', top right: vendor logo, right-aligned, at most 28pt tall so the 3-line stack keeps its 21pt pitch (a 3:1 PNG becomes 84x28). Use vendorName (Bold 12.5) when there is no logo.
  • '15 March 2025': invoiceDate in the same format. Add a 'Due: 30 March 2025' line (Regular 12.5) for dueDate.
  • 'INVOICE NO.15325': 'INVOICE NO. ' + number.
  • BILLED TO name / address / phone: clientName / clientAddress (wrapping) / 'GSTIN: ' + clientGstin / 'Place of supply: ...' / 'PO: ' + poNumber. Voiced has no client phone.
  • Free 88pt band (238 to 326): vendor statutory line(s) on the left, 'GSTIN: vendorGstin PAN: vendorPan State: vendorStateCode' in Medium 10.5, with the due date or PO on the right. Or collapse the band.
  • Table: description / rate (a dash when mode is fixed) / qty with unit / amount.
  • Subtotal / Tax / Total: subtotal, discount, CGST + SGST or IGST rows with rates, total.
  • PAYMENT INFORMATION: bank.accountName; 'Bank : ' bankName; 'Branch : ' branch; 'Account No. : ' accountNo; 'IFSC : ' ifsc; 'UPI : ' (planned).
  • Footer right, 'SUDIUM LOVRA' and its lines: vendorName, vendorAddress (wrapping), vendorPhone, vendorEmail. Website is not in Settings. Voiced fields with no Canva slot, and where they go:
  • Logo: top right
  • GSTIN/PAN: the free band or the vendor footer
  • Amount in words: left of the totals
  • CGST/SGST/IGST rows: totals block
  • Signature or computer-generated note: right side of the 598-705 band
  • Notes: left side of that band
  • HSN/SAC (not in types.ts): a grey 10pt sub-line under the description such as 'SAC 998314', or a 60pt column between Description and Price

Overflow risks

  • Header collision, the same class as the reported bug. 'INVOICE' already ends at x 300.5. 'TAX INVOICE' at 60pt is about 385pt and would end near 436, while the right stack's widest line starts at 447.5 ('INVOICE NO.15325'). A realistic number such as 'INVOICE NO. INV/2026-27/0042' is about 190pt in Bold 12.5 and would start near 370, overlapping the title. Fix: make the header a flex row with a fixed max width on the right stack (about 200pt, text wraps, alignItems flex-end), and set the title size to min(60, fit-to-available-width), measured with fontkit or a precomputed width table. Alternatively drop to 44pt for 'TAX INVOICE'.
  • Client block: Canva has a single 162pt address line. Long addresses wrap (524pt of content width allows about 80 chars per line at 12.5pt), which is fine in flow layout, but the rule at 238.3 must be a border after the content.
  • Items: descriptions sit in a column of about 217pt (about 33 chars per line in Medium 12.5) and wrap, so rows grow. Rows are about 50pt tall and Canva fits only 3, so 4-5 items or more push onto page 2. Reduce paddingVertical to about 9 when there are more than 5 items.
  • Totals values are centred in a 108pt column. 'Rs 12,34,567.00' (with the rupee sign) in Medium 12.5 is about 95pt and fits; Rs 1 crore and above is about 110pt and overflows. Right-align the values and let the column grow (flexShrink 0, minWidth 108).
  • Footer: Canva anchors it at the page bottom (705 to 812). With IFSC/Branch/UPI the payment grid grows to 6 lines (104pt at 17.25 pitch). The vendor column is 164pt wide and with a wrapped address, phone, email, GSTIN and PAN it reaches about 7 lines (about 120pt). The footer then needs about 150pt; starting at 705 it would end near 855, past the 842pt page. Make it a flow block after the totals with wrap={false} so it moves to the next page whole, or move GSTIN/PAN up into the free band.
  • Payment grid: the label column is fixed at 114pt (35.5 to 149.4), which suits the labels. The value column is about 225pt, so long bank names wrap.

US Letter adaptation

  • Keep the 35pt side margins (user-overridable). Content width goes from 524 to 541 on Letter; the number columns stay at 98pt and Description takes the extra 17pt.
  • The 50pt height loss is absorbed by collapsing the free 88pt band to about 38pt, or removing it when empty. The footer's bottom rule stays about 30pt above the page bottom.
  • The title auto-fit works from available width, so Letter's extra width helps 'TAX INVOICE' slightly.

react-pdf notes

  • Page: <Page size={size} style={{ paddingTop: 30, paddingBottom: 30, paddingHorizontal: 35, fontFamily: 'Poppins', fontWeight: 500, fontSize: 12.5, lineHeight: 1.38, color: '#000' }}>
  • Header: <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-start', paddingBottom: 11, borderBottomWidth: 0.75 }}> <Text style={{ fontWeight: 700, fontSize: titleSize, lineHeight: 1, marginLeft: 16, flexShrink: 1 }}>... <View style={{ width: 200, flexShrink: 0, alignItems: 'flex-end' }}> 3 lines, lineHeight 1.68
  • Rules as borders: the client block is a View with borderBottomWidth 0.75 and paddingVertical 14. The table header is a View with borderTopWidth 1.5, borderBottomWidth 1.5, height 39.3, alignItems 'center', and minPresenceAhead about 60.
  • Rows: <View wrap={false} style={{ flexDirection: 'row', paddingVertical: 14, alignItems: 'flex-start' }}> The rows container ends with borderBottomWidth 0.75.
  • Totals: <View wrap={false} style={{ alignSelf: 'flex-end', width: 215.5 }}> Each row is flexDirection row with two 108-wide columns, textAlign center. The Total row has borderTopWidth 0.75 and paddingTop 8.
  • Footer: a with borderTopWidth 0.75 and borderBottomWidth 0.75. Two columns: flex 1 on the left, width 164 on the right. Payment grid rows: <View style={{ flexDirection: 'row' }}> <Text style={{ width: 114 }}>Bank <Text style={{ width: 21, fontWeight: 400 }}>: <Text style={{ flex: 1 }}>...
  • To push the footer to the bottom of the last page, put a <View style={{ flexGrow: 1 }} /> spacer between the totals and the footer. Do not use fixed; the footer should appear once.
  • Title auto-fit: width = font.layout(text).advanceWidth / unitsPerEm x size via fontkit. Poppins Bold 'INVOICE' is 4.161 x size; precompute 'TAX INVOICE' the same way.
  • Fonts: Poppins 400/500/700 as static TTF/WOFF. Money fallback: ['Poppins','IBM Plex Sans'].

Similarity to other templates

Structurally this is the closest of the three to the existing in-app InvoiceDocument: a title with a meta stack, rule dividers, a ruled table with a heavy top rule, right-hand totals with a rule above Total, and bank details at bottom left. It is also close to format.pdf/4.pdf (rules, a column-header row with a rule, right-hand totals). It is the cheapest to build, as a restyle of the existing component: Poppins, a 60pt auto-fit title, 1.5pt table rules, centred numbers and a two-column footer. Within the set, 7 and 11 share the big Poppins Bold INVOICE with the brand at top right; 3 is the monochrome, rules-only variant.

Implementation notes

Built as src/pdf/templates/monolith/: a standalone template (tokens.ts the type roles and Canva distances, plan.ts the pure planner, Layout.tsx the body, monolith.tsx the definition), on the shared blocks and the AccentRule decor primitive. Measured against 3.pdf with npm run templates:compare -- monolith (/tmp/invoice-c6a/compare-monolith.png, left Canva, right ours; --numbers prints the baselines).

Matches the design (measured, A4, no due date so the stack is the design's three lines): INVOICE origin x 50.7 with its baseline at 96.0 (Canva 96.2); the vendor name, date and INVOICE NO. lines at baselines 63.7 / 84.7 / 105.7 with their right edge at x 560.3 (Canva 560.6); BILLED TO at baseline 153.0 and x 35 (Canva 153.0, 34.4); client lines at 178.1 with the 17.25 pitch; Poppins 400/500/700 at the design's sizes (60.02 / 14.5 / 12.5 / 10.5), black only (a test scans the sources for any other colour); 0.75 pt rules, the table between two 1.5 pt rules around a 39.3 pt header; the totals block 215.5 pt wide with centred labels, a 0.75 pt rule over Total and the 23 pt row pitch; the footer grid with its 114 pt label column and the colon column at x 149; the vendor column at x 395.

The logo. The slot is the text-only "CAVEIN" placeholder (46.8 x 9 pt), so the logo is fitted to its 160 x 28 pt allowance, right-anchored, and the brand zone of the right-hand stack reserves the logo's whole box: the date and number lines are laid out under it, never over it (the earlier contact sheet showed a 28 pt logo covering the date line). A wordmark replaces the vendor name, a mark keeps it to its left, a tall logo is held to 28 pt, and with no logo the vendor name is printed in Bold 12.5 at the design's position. The zone is the SUPPLIER_ID box and the date and number lines the META_ID box, so the harness proves they do not meet.

Intentional deviations, and why:

  • Title. The design's 60 pt is shrunk (to 30 pt at the least) when the right-hand stack leaves less than the title needs: TAX INVOICE comes out at about 51 pt on A4, and a long invoice number shrinks first (IdText) before the title does.
  • Right-hand stack. The design's three lines plus a "Due:" line (Regular 12.5) when the invoice has a due date, and a red CANCELLED line on a cancelled one. The rule under it follows the stack, so an invoice with a logo or a due date starts 13 to 34 pt lower than the design.
  • Supplier identifiers. The design's empty band under the client holds a SUPPLIER heading with the GSTIN (through Slot.Gstin) and PAN, in the footer's right-hand column x. They are on page 1 whatever the length of the invoice. The supplier's address, phone and e-mail are the footer's vendor block, as in the design, so on a multi-page invoice they appear on the last page only.
  • Table. Numbers are right-aligned with a 10 pt pad (the design centres them; the doc's recommendation) except QTY, which stays centred; the cells of a row share one baseline (Canva's description and numbers are 7 pt apart); the rate's unit is /hr or a second line, HSN/SAC a 10 pt sub-line. Row padding is 16 pt for up to 3 rows, 12 for up to 5 and 8 beyond, then the elastic gaps take over.
  • Elastic gaps. The 88 pt band under the client (down to 24), the row padding (down to 6), the gaps above BILLED TO and under the client block (down to 14) and the two gaps in the footer (down to 8) give back Letter's missing 50 pt, and the overflow of an invoice that is a little too long for one page. A 2-item tax invoice with a bank block fits one A4 page that way; with 3 rows and a signature image the closing block moves to page 2 (the items and totals stay together on page 1).
  • Amount in words and reverse charge are the totals' left column (Medium 10.5, x 35..329). Notes and the signature (an image up to 150 x 45, or the signatory name and designation and the computer-generated line) form the band above the footer's top rule; notes taller than 110 pt flow as their own block before the closing.
  • Footer position. The closing block ends 24 pt above the "Generated with Voiced" line, so its bottom rule is at y 804 where Canva's is at 812.