Add per-template specifications measured from the reference PDFs
This commit is contained in:
Vendored
+162
@@ -0,0 +1,162 @@
|
|||||||
|
# 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: <rupee amount>' 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 <Image style={{objectFit:'cover'}}>
|
||||||
|
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: <state> (<code>)' / '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):
|
||||||
|
<Page size={size /* 'A4' | 'LETTER' */} style={{ paddingTop: 64 + 30, paddingBottom: BAND + 20, paddingHorizontal: m, fontFamily: BODY, fontSize: 11.55, lineHeight: 1.55, color: '#000' }}>
|
||||||
|
<View fixed style={{ position: 'absolute', top: 0, left: 0, right: 0, height: 64, backgroundColor: '#F2F1F3' }} />
|
||||||
|
(or <Image fixed src={marbleTop} style={{ position: 'absolute', top: 0, left: 0, right: 0, height: 64, objectFit: 'cover' }} />)
|
||||||
|
<View fixed style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: BAND, paddingTop: 30, paddingHorizontal: m + 4, flexDirection: 'row' }}> 3 footer columns </View>
|
||||||
|
- 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) => <View wrap={false} style={{ flexDirection: 'row', minHeight: 32, alignItems: 'center', paddingHorizontal: 9.5, backgroundColor: i % 2 === 0 ? '#F7F7F8' : undefined }}>)
|
||||||
|
- Wrap the totals stack, AMOUNT DUE and the words line in one <View wrap={false}>.
|
||||||
|
- Absolute children of <Page> 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.
|
||||||
Vendored
+157
@@ -0,0 +1,157 @@
|
|||||||
|
# Template 2: Highlighter (`highlighter`)
|
||||||
|
|
||||||
|
Source: `templates/reference/2.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
|
||||||
|
|
||||||
|
Bold form-style invoice. Tight-tracked Poppins Bold 'Invoice', underlined fill-in fields, a signal-yellow header bar, a heavy 3pt black-framed grid table with indigo hairlines, a yellow 'total' cell, and a THANK YOU sign-off with icon-led contact lines.
|
||||||
|
|
||||||
|
## Fonts
|
||||||
|
|
||||||
|
All OFL; bundle as static TTF.
|
||||||
|
1) Poppins Bold ('Copyright 2020 The Poppins Project Authors', v4.004). upm 1000, hhea 1050 / -350 / lineGap 100, capHeight 705. Used for:
|
||||||
|
- 'Invoice': 45.68pt, letterSpacing -2.83pt (-0.062em), #1C2120
|
||||||
|
- Table heads 'Description / Qty / Price / Total': 13pt, tracking 0, #1C2120
|
||||||
|
- 'total :': 12pt, #000
|
||||||
|
- 'Bank Name : ...' and 'Account No : ...': 12pt, #1C2120, pitch 16.5 (lineHeight 1.375)
|
||||||
|
- 'THANK YOU': 25.01pt, #1C2120
|
||||||
|
2) Poppins Regular (capHeight 698). Used for the field labels 'Date:', 'Invoice number:', 'Billed to:' at 13pt with -0.37pt (-0.028em), and 'Payment Method:' at 13pt with tracking 0.
|
||||||
|
3) Montserrat Regular ('Copyright 2011 The Montserrat Project Authors', v7.200). upm 1000, hhea 968 / -251, capHeight 700. Used for the contact lines at 11.67pt, #000, pitch 22.5 (lineHeight 1.93).
|
||||||
|
The template has no item text (rows are empty); suggest Poppins Regular 11pt #1C2120.
|
||||||
|
Rupee sign: present in Montserrat (verified in the local TTF cmap). Poppins is likely to have it (ITF Devanagari family) but this is unverified, so use fontFamily ['Poppins','IBM Plex Sans'] for money.
|
||||||
|
|
||||||
|
## Colours
|
||||||
|
|
||||||
|
#1C2120 near-black ink: title, labels, header text, 3pt table frames, icons, THANK YOU.
|
||||||
|
#423869 deep indigo hairlines, 0.75pt: field underlines, table grid, the 4 lines at bottom right.
|
||||||
|
#FFE535 signal yellow: table header bar and the 'total :' cell.
|
||||||
|
#000000: contact text and the 'total :' label.
|
||||||
|
#FFFFFF: page and table body.
|
||||||
|
Expose #FFE535 as a swappable accent token.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
Coordinates are pt from the top-left; y is the baseline unless noted. Content box x 59.6 to 536.0 (about 60pt side margins).
|
||||||
|
1. Title 'Invoice' at x 60.3, baseline 98.0 (cap top about 65.8). The right half (x 352 to 536, y 50 to 114) is empty.
|
||||||
|
2. Field stack, labels at x 60.3-61.8 in Poppins Regular 13:
|
||||||
|
- 'Date:' baseline 132.2; underline y 137.4, x 97.6 to 266.0 (168.3 wide)
|
||||||
|
- 'Invoice number:' baseline 166.0; underline y 170.4, x 165.5 to 266.0 (100.5 wide)
|
||||||
|
- 'Billed to:' baseline 200.4; underline y 204.8, x 115.8 to 266.0 (150.1 wide)
|
||||||
|
Pitch 34. Each underline sits about 4.6pt below the baseline and starts 4-6pt after the label.
|
||||||
|
3. Right block at x 352.5, left-aligned: 'Payment Method:' baseline 162.9; 'Bank Name : Wealth Banking' 185.1; 'Account No : 123 4567 8901' 201.6.
|
||||||
|
4. Header bar: y 269.7 to 305.1 (h 35.4), x 59.6 to 536.0. The stroke is centred, so the outer edge runs 58.1 to 537.5. Fill #FFE535, 3pt #1C2120 frame, dividers 0.75 #423869 at x 245.5 / 309.4 / 412.2. Labels are centred on baseline 290.9: Qty centre 277.4, Price 360.8, Total 471.7, 'Description' 144.2.
|
||||||
|
5. Gap of 7.5.
|
||||||
|
6. Body: y 312.6 to 559.9 (h 247.3), same x, white, 3pt frame. Full-height dividers at x 245.5 / 309.4 / 412.2. Row rules at y 343.8, 375.3, 405.3, 436.8, 466.8, 498.3, 528.3, giving 8 rows of about 30.9.
|
||||||
|
7. Gap of 7.5, then the totals row at y 567.4 to 595.5 (h 28.1): a yellow cell at x 309.4 to 412.2 ('total :' baseline 585.2, x 333.8-368.8) plus a white value cell at x 411.0 to 535.3. Each cell has a 3pt frame.
|
||||||
|
8. Gap from 595 to 670.
|
||||||
|
9. Sign-off, left: 'THANK YOU' at x 61.8, baseline 695.0. Contact rows have an icon column at x 59.6-74.3 and text at x 81.9, baselines 732.6 / 755.1 / 777.6.
|
||||||
|
10. Right: 4 rules, 0.75 #423869, x about 323.7 to 536.0 (about 212 long), at y 694.0 / 723.3 / 752.5 / 781.5 (pitch about 29.2).
|
||||||
|
About 64pt of whitespace below the last baseline.
|
||||||
|
|
||||||
|
## Items table
|
||||||
|
|
||||||
|
Outer width 476.4 (x 59.6 to 536.0). Columns:
|
||||||
|
- Description 59.6-245.5 (185.9, 39.0%)
|
||||||
|
- Qty 245.5-309.4 (63.9, 13.4%)
|
||||||
|
- Price 309.4-412.2 (102.8, 21.6%)
|
||||||
|
- Total 412.2-536.0 (123.8, 26.0%)
|
||||||
|
Header: a separate bar, 7.5pt above the body. #FFE535 fill, 3pt #1C2120 frame, 35.4 tall, Poppins Bold 13 #1C2120 labels centred, internal dividers 0.75 #423869. 'Description' measures 144.2 at its centre, about 8pt left of the column centre; just centre it.
|
||||||
|
Body: white, 3pt #1C2120 outer frame, 0.75 #423869 grid lines both ways, 8 empty rows of about 30.9 (31.1 / 31.5 / 30.0 / 31.5 / 30.0 / 31.5 / 30.0 / 31.6). The reference file is a blank fill-in form.
|
||||||
|
Suggested cells: Poppins Regular 11 #1C2120. Description left with 9pt padding; Qty centred; Rate and Amount right-aligned with 9pt right padding (reference only centres the headers).
|
||||||
|
Option: 'pad to N empty rows' (default 8 on A4, 7 on Letter) keeps the form look when there are few items.
|
||||||
|
|
||||||
|
## Totals and payment
|
||||||
|
|
||||||
|
reference:
|
||||||
|
- One 'total :' row: a yellow label cell under the Price column and a white value cell under the Total column, 28.1pt tall, 3pt frames, 7.5pt below the body. The label is Poppins Bold 12 #000; the value cell is empty.
|
||||||
|
- Payment, top right: 'Payment Method:' (Regular 13), then 'Bank Name : ...' and 'Account No : ...' (Bold 12, label : value inline).
|
||||||
|
- Sign-off: 'THANK YOU' (Bold 25) with icon-led phone / email / address rows (Montserrat 11.67).
|
||||||
|
- 4 unlabelled ruled lines at bottom right, for notes or a signature.
|
||||||
|
- No subtotal or tax rows, no amount in words, no notes label, no signature caption.
|
||||||
|
Voiced version:
|
||||||
|
- Build the totals as a stack of the same 2-cell row (label cell at the Price column x, value cell at the Total column x), 24-28pt per row. Merge the frames: 3pt outside, 0.75 #423869 between rows.
|
||||||
|
- Rows: Subtotal, Discount (if > 0), CGST @x% + SGST @x% or IGST @x%, then Total. Total keeps the yellow label cell with a bold value; the value cell can also go yellow for emphasis.
|
||||||
|
- Amount in words to the left of the stack: x 60 to 300, Poppins Regular 10.5, top-aligned with the first totals row.
|
||||||
|
|
||||||
|
## Decoration and images
|
||||||
|
|
||||||
|
No raster images (41 KB, all vector). Everything can be rebuilt in react-pdf:
|
||||||
|
- Filled rects: header bar #FFE535 476.4 x 35.4; total label cell #FFE535 102.8 x 28.1.
|
||||||
|
- 3pt #1C2120 frames on the header bar, the body and both total cells. PDF strokes are centred on the edge (1.5pt outside), while react-pdf borders sit inside the box, so place those Views at the outer edge (x 58.1, width 479.4).
|
||||||
|
- 0.75pt #423869 hairlines: 3 field underlines, 3+3 column dividers, 7 row rules and the 4 bottom-right lines.
|
||||||
|
- 3 icons, fill #1C2120, drawn with <Svg><Path>:
|
||||||
|
- Phone: bbox x 59.6, y 721.9, 14.75 x 14.75. Native path (about 36 units, y-down), viewBox '0 0 36 36', drawn at 14.75pt:
|
||||||
|
'M34.06 26.407L30.564 22.911C28.634 20.981 25.504 20.981 23.575 22.911C22.856 23.629 22.408 24.514 22.224 25.439C16.459 24.361 10.852 18.777 10.503 13.786C11.45 13.61 12.357 13.159 13.089 12.426C15.019 10.496 15.019 7.366 13.089 5.436L9.594 1.94C7.664 0.01 4.534 0.01 2.604 1.94C-7.882 12.426 23.574 43.882 34.06 33.396C35.989 31.467 35.989 28.337 34.06 26.407Z'
|
||||||
|
- Mail: this is Material Icons 'mail' (Apache-2.0), viewBox 0 0 48 48. Drawn area 11.58 x 9.26 at x 62.5, y 746.9, so the 48-unit box is about 13.9pt:
|
||||||
|
'M40 8H8c-2.21 0-3.98 1.79-3.98 4L4 36c0 2.21 1.79 4 4 4h32c2.21 0 4-1.79 4-4V12c0-2.21-1.79-4-4-4zm0 8L24 26 8 16v-4l16 10 16-10v4z'
|
||||||
|
- Pin: this is Material Icons 'place' (Apache-2.0), viewBox 0 0 48 48. Drawn area 8.46 x 12.09 at x 64.05, y 766.4, so the 48-unit box is about 14.5pt:
|
||||||
|
'M24 4c-7.73 0-14 6.27-14 14 0 10.5 14 26 14 26s14-15.5 14-26c0-7.73-6.27-14-14-14zm0 19c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5z'
|
||||||
|
The icons' visual centres sit about 4pt above each text baseline (729.3 / 751.5 / 772.5).
|
||||||
|
Alternative: the Carbon icons Phone / Email / Location (Apache-2.0; @carbon/icons is already a dependency) would keep one icon set across the app.
|
||||||
|
|
||||||
|
## Mapping to Voiced fields
|
||||||
|
|
||||||
|
- 'Invoice': 'Invoice' or 'Tax Invoice'. 'Tax Invoice' is about 237pt at 45.68pt and fits the left half.
|
||||||
|
- Empty top right (x 352 to 536, y 50 to 114): vendor logo (3:1, fit 150x50, right-aligned) plus vendorName (Poppins Bold 13), with 'GSTIN ... / PAN ...' (Poppins Regular 10) under it.
|
||||||
|
- 'Date:': invoiceDate. Add a 'Due date:' field in the same underline style (pitch 34) for dueDate.
|
||||||
|
- 'Invoice number:': number.
|
||||||
|
- 'Billed to:': clientName on the line. Sub-lines underneath at x 60.3, Poppins Regular 11, pitch 15: clientAddress, 'GSTIN: ...', 'Place of supply: ...', 'PO: ...'.
|
||||||
|
- 'Payment Method:': 'Bank Name : bankName (branch)', 'Account Name : accountName', 'Account No : accountNo', 'IFSC : ifsc', 'UPI : ...' (planned).
|
||||||
|
- Table to items: Description / Qty (with unit such as 'hr' or 'session') / Price becomes Rate (a dash when mode is fixed) / Total becomes Amount.
|
||||||
|
- 'total :': the Subtotal / Discount / CGST / SGST or IGST / Total stack.
|
||||||
|
- 'THANK YOU': keep as a static string. The icon rows take vendorPhone / vendorEmail / vendorAddress.
|
||||||
|
- The 4 ruled lines:
|
||||||
|
- Lines 1-3: notes written on the lines (Poppins Regular 10.5, baseline about 3pt above each rule), or the amount in words if there are no notes.
|
||||||
|
- Line 4: the signature line. Put the signature image above it (140x40 max) with the caption 'Authorised signatory, <vendorName>'. Without a signature, write 'Computer-generated invoice; no signature required.' on that line.
|
||||||
|
Voiced fields with no reference slot, and where they go:
|
||||||
|
- Vendor name, logo, GSTIN and PAN: top right
|
||||||
|
- Place of supply: Billed-to sub-lines
|
||||||
|
- Tax rows: totals stack
|
||||||
|
- Amount in words: left of the totals
|
||||||
|
- Notes and signature: the ruled lines
|
||||||
|
- HSN/SAC (not in types.ts): a 52pt column between Description and Qty (Description shrinks to about 134pt), or a grey 9pt sub-line
|
||||||
|
- 'Generated with Voiced': a 7pt line under the sign-off
|
||||||
|
|
||||||
|
## Overflow risks
|
||||||
|
|
||||||
|
- The underlined fields have fixed widths: Invoice number 100.5pt (about 14 chars of Poppins 12, so 'INV/2026-27/0042' at about 105pt overflows), Billed to 150pt (about 22 chars), Date 168pt. Build each as a row of label plus a value View with flexGrow 1 and a bottom border, so the value wraps (the underline moves down) or shrinks to 11pt.
|
||||||
|
- Billed-to sub-lines: only 65pt (about 4 lines at 15pt) sits between the last underline (204.8) and the header bar (269.7). Longer addresses must push the table down, so use flow layout, not absolute positions.
|
||||||
|
- Payment block: 183.5pt wide at Bold 12, so long bank or branch names wrap. 5-6 lines at 16.5 pitch from 185 reach about 268, which is the header bar's top. Put the fields and the payment block in one flow row and start the table 30pt below the taller of the two.
|
||||||
|
- Rows: reference uses fixed 30.9pt rows with page-tall dividers. Use per-row cells with borderRight instead. The description column is 186pt, about 30 chars per line at 11pt, so rows will go multi-line.
|
||||||
|
- More than 8 items breaks onto a second page, and the 3pt frame must close on each page's fragment: rows carry 3pt left/right borders, the first row a 3pt top, the last row a 3pt bottom, and every row is wrap={false}.
|
||||||
|
- Totals: the 102.8pt label cell fits 'IGST @ 18%'; the 123.8pt value cell at Bold 12 fits up to about Rs 99,99,99,999.00 (with the rupee sign).
|
||||||
|
- Contacts: the address has about 228pt on one line (81.9 to 310, before the ruled lines at 323.7), about 38 chars at 11.67pt. Indian addresses wrap to 2-3 lines; at 22.5 pitch, two extra lines end around 823, inside the bottom margin. Use a 16pt pitch for wrapped continuation lines, and let the sign-off block flow instead of pinning it at 695.
|
||||||
|
- Notes longer than 3 lines overflow the ruled area. Generate the ruled lines from the wrapped line count, or cap the notes length.
|
||||||
|
|
||||||
|
## US Letter adaptation
|
||||||
|
|
||||||
|
- Keep the 60pt side margins (template default, user-overridable). Content width goes from 476.4 to 492 on Letter; set columns by percentage.
|
||||||
|
- Absorb the 50pt height loss: collapse the 75pt gap between the totals (595) and THANK YOU (670) to about 30pt, and the 64pt gap between the field stack and the header bar to about 40pt. With row padding on, pad to 7 empty rows on Letter.
|
||||||
|
- The sign-off block (THANK YOU, contacts, ruled lines) appears once, at the end. Anchor it to the bottom of the last page with a flexGrow spacer, not with fixed.
|
||||||
|
|
||||||
|
## react-pdf notes
|
||||||
|
|
||||||
|
- Page: <Page size={size} style={{ paddingTop: 50, paddingBottom: 60, paddingHorizontal: 60, fontFamily: 'Poppins', color: '#1C2120' }}>.
|
||||||
|
- Title: <Text style={{ fontWeight: 700, fontSize: 45.68, letterSpacing: -2.83, lineHeight: 1 }}>. Negative letterSpacing is fine.
|
||||||
|
- Field:
|
||||||
|
<View style={{ flexDirection: 'row', alignItems: 'flex-end', marginTop: 21 }}>
|
||||||
|
<Text style={{ fontSize: 13, letterSpacing: -0.37 }}>{label}</Text>
|
||||||
|
<View style={{ flexGrow: 1, flexShrink: 1, marginLeft: 4, borderBottomWidth: 0.75, borderBottomColor: '#423869', paddingBottom: 1 }}>
|
||||||
|
<Text style={{ fontSize: 12 }}>{value}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
The field column is about 206 wide (60 to 266).
|
||||||
|
- Top row: flexDirection 'row', justifyContent 'space-between'. Left fields 206 wide; right payment/vendor column 183.5 wide.
|
||||||
|
- Header bar:
|
||||||
|
<View minPresenceAhead={62} style={{ flexDirection: 'row', height: 35.4, backgroundColor: '#FFE535', borderWidth: 3, borderColor: '#1C2120', marginBottom: 7.5 }}>
|
||||||
|
Cells use % widths with borderRightWidth 0.75, borderRightColor '#423869', justifyContent 'center'.
|
||||||
|
- Body rows:
|
||||||
|
<View wrap={false} style={{ flexDirection: 'row', minHeight: 30.9, borderLeftWidth: 3, borderRightWidth: 3, borderBottomWidth: 0.75, borderLeftColor: '#1C2120', borderRightColor: '#1C2120', borderBottomColor: '#423869' }}>
|
||||||
|
The first row adds borderTopWidth 3; the last row uses borderBottomWidth 3 with borderBottomColor '#1C2120'. Per-side border colours are supported.
|
||||||
|
- Totals: a column of 2-cell rows, lined up with the Price/Total columns by a left spacer equal to Description% + Qty% of the width.
|
||||||
|
- Icons: import { Svg, Path } from '@react-pdf/renderer'; then <Svg viewBox='0 0 48 48' style={{ width: 14, height: 14 }}><Path d={MAIL} fill='#1C2120' /></Svg>.
|
||||||
|
- Fonts: register Poppins 400/500/700 and Montserrat 400 from static TTF/WOFF. For money use fontFamily ['Poppins','IBM Plex Sans'].
|
||||||
|
|
||||||
|
## Similarity to other templates
|
||||||
|
|
||||||
|
Closest siblings are 7 and 11 (Poppins, a colour-filled header on a boxed grid table, boxed totals) and 8 (filled blue header plus an icon contact row). Only 2 has underlined fill-in fields, a detached header bar and 3pt frames. It is unrelated to the in-app template and to format.pdf/4.pdf. If 7 and 11 are built too, share one 'boxed grid table' component with accent colour and frame weight as parameters.
|
||||||
Vendored
+141
@@ -0,0 +1,141 @@
|
|||||||
|
# Template 3: Monolith (`monolith`)
|
||||||
|
|
||||||
|
Source: `templates/reference/3.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
|
||||||
|
|
||||||
|
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).
|
||||||
|
2. Rule 0.75 at y 116.75, x 35.5 to 560.0.
|
||||||
|
3. '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).
|
||||||
|
4. Rule 0.75 at y 238.3 (x 34.4 to 559.0), 25.7 below the last line.
|
||||||
|
5. Free band from 238 to 326 (88pt), empty.
|
||||||
|
6. 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.
|
||||||
|
7. 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 reference misalignment to fix rather than copy. Pitch is about 52 / 49pt.
|
||||||
|
8. Rule 0.75 at y 521.6 (x 36.4 to 560.3).
|
||||||
|
9. 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.
|
||||||
|
10. Empty from 598 to 705 (107pt).
|
||||||
|
11. 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.
|
||||||
|
12. 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. Reference 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
|
||||||
|
|
||||||
|
reference:
|
||||||
|
- 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 reference 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: reference 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 reference 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: reference 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 }}>...</Text>
|
||||||
|
<View style={{ width: 200, flexShrink: 0, alignItems: 'flex-end' }}> 3 lines, lineHeight 1.68 </View>
|
||||||
|
</View>
|
||||||
|
- 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 <View wrap={false}> 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>
|
||||||
|
<Text style={{ width: 21, fontWeight: 400 }}>:</Text>
|
||||||
|
<Text style={{ flex: 1 }}>...</Text>
|
||||||
|
</View>
|
||||||
|
- 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.
|
||||||
Vendored
+141
@@ -0,0 +1,141 @@
|
|||||||
|
# Template 4: Linea (could also be labelled 'Original': this is the vendor's own format.pdf design) (`linea`)
|
||||||
|
|
||||||
|
Source: `templates/reference/4.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, all-charcoal minimalism. A very large letter-spaced Montserrat 'INVOICE' is followed by a hairline rule. Everything else is 10pt Montserrat. The item table has no borders between two hairlines, and a script signature sits bottom-right. There is no logo, no colour and no boxes.
|
||||||
|
|
||||||
|
## Fonts
|
||||||
|
|
||||||
|
- Montserrat Regular (400): the title 'INVOICE' is 38.01pt, letterSpacing 7.6pt (0.20em), uppercase. All other regular text is 10pt, letterSpacing 0.5pt (0.05em), with a 13.5pt line pitch (lineHeight 1.35). That covers client lines, bank lines, DATE:/DUE DATE: labels and values, the table header (uppercase, NOT bold), item rows, the SUBTOTAL label and value, and 'Tax' with its rate.
|
||||||
|
- Montserrat Bold (700), 10pt, letterSpacing 0.5pt: 'ISSUED TO:', 'PAY TO:', 'INVOICE NO:' and its value, and the grand-total label 'TOTAL' and its value.
|
||||||
|
- BuongiornoRastellinoCyr-Script, 60.02pt, no tracking: the signature 'DanielGallego'. It is live text, not an image. The font is reference-licensed and cannot be redistributed, so replace it with the uploaded signature image.
|
||||||
|
- Metrics from the embedded descriptors: Montserrat ascent 968, descent -251, capHeight 700 per 1000 em. Cap height is 7.0pt at 10pt and 26.6pt at 38pt.
|
||||||
|
- Montserrat is OFL. The local copies ~/.local/share/fonts/Montserrat-Regular.ttf and Montserrat-Bold.ttf are Version 9.000 and include U+20B9 (₹), which I checked by parsing the cmap. Bundle these two TTFs plus OFL.txt in public/fonts.
|
||||||
|
|
||||||
|
## Colours
|
||||||
|
|
||||||
|
Single colour only. All text and every rule is #3D3B3A (PDF rg 0.2392 0.2314 0.2275 = rgb 61,59,58, a warm charcoal). There are no other greys and no accent. The page background is #FFFFFF, set by an explicit full-page white fill. Reference also writes three invisible (alpha 0) tagged rectangles that duplicate the rules for accessibility. Ignore them.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
Page is 595.5 x 842.25pt (the reference design's A4). In react-pdf use A4 (595.28 x 841.89); the difference is under 0.05%. y is measured from the top edge.
|
||||||
|
**Grid:** hairline rules span x 69.64-525.86 (456.2pt wide, centred on the page). Body text starts at x 77.4, 7.8pt inside the rule ends. The right text edge is 519.2 for headers and meta values, and 514.4 for money values. Implied margins: left/right 69.6 for rules; 77.4 (left) and 76.3 (right) for text; top 135 to the title cap-top; bottom about 70 below the signature ink.
|
||||||
|
1. **Empty top band**, y 0-135.
|
||||||
|
2. **Title row**, y 135-162. 'INVOICE' spans x 59.55-270.2, baseline 161.65, cap-top 135.0. It starts 18pt LEFT of the text column and 10pt left of the rule start. A 0.75pt hairline runs from x 290.05 to 535.57 at y about 148.7, the vertical middle of the capitals, with a 20pt gap after the title. The rule overshoots the table's right edge by about 10pt, mirroring the title's overhang, so the row (59.5-535.6) is centred on the page.
|
||||||
|
3. **Empty space**, y 162-262 (about 100pt).
|
||||||
|
4. **Info row**: two columns sharing the first baseline 269.22.
|
||||||
|
- Left, at x 77.4: 'ISSUED TO:' (Bold) at baseline 269.22, then 3 lines at 285.19 / 298.69 / 312.20. That is 15.97 from label to first line, then a 13.5 pitch.
|
||||||
|
- Right, meta block with 2 sub-columns. Labels are right-aligned at x about 447: 'INVOICE NO:' (Bold) x 376.2-447.7, 'DATE:' 414.6-446.6, 'DUE DATE:' 387.3-446.8. Values are right-aligned at x about 518.1-519.2: '01234' (Bold) 487.8-519.2, dates 465.3-518.1. Baselines are 269.22 / 284.69 / 299.40. The label-to-value gap is about 18.7pt. The meta block spans x 376-519 (143pt).
|
||||||
|
5. **PAY TO**, left column at x 77.6: 'PAY TO:' (Bold) at baseline 337.73, 25.5pt below the last client line. Then 3 lines at 353.98 / 367.49 / 380.99.
|
||||||
|
6. **Empty space**, y 381-441.
|
||||||
|
7. **Items table**, x 69.64-525.86. Header baseline 447.93; rule at y 461.15; rows start at baseline 484.25 with a 21.46 pitch (7 rows, last at 613.33); closing rule at y 631.44.
|
||||||
|
8. **Totals**, no box. SUBTOTAL at baseline 649.82, with the label at x 77.45 and the value right-aligned at 514.4. 'Tax' (baseline 665.04) and 'TOTAL' (baseline 680.09) form a right-anchored label/value pair: labels right-aligned at 460.3, values right-aligned at 514.4, 15pt pitch.
|
||||||
|
9. **Signature**, bottom-right: script text x 352.7-526.2, baseline 757.37, ink about y 712-772.
|
||||||
|
10. About 70pt empty at the bottom. No header, footer or page number.
|
||||||
|
|
||||||
|
## Items table
|
||||||
|
|
||||||
|
- **Columns (x):**
|
||||||
|
- DESCRIPTION: left-aligned; header at 77.45, cells at 81.6. The 4pt indent is a reference artefact and optional.
|
||||||
|
- UNIT PRICE: centred on x 325.2 (header 293.6-356.8; cell '100' 316.3-334.2).
|
||||||
|
- QTY: centred on x 416.4 (header 405.7-427.1).
|
||||||
|
- TOTAL: right-aligned; header right edge 519.2, money cells right edge 514.4.
|
||||||
|
- Unit price shows a bare number; the currency symbol appears only in TOTAL.
|
||||||
|
- **Header:** Montserrat Regular 10pt, UPPERCASE, letterSpacing 0.5pt, #3D3B3A. No fill, no top border. ONE 0.75pt #3D3B3A rule 13.2pt below the header baseline (y 461.15), spanning x 69.64-525.86, which is 7.8pt beyond the text on both sides.
|
||||||
|
- **Body:** Montserrat Regular 10pt, letterSpacing 0.5pt. First baseline is 23.1pt below the rule. Pitch is 21.46pt (13.5 line plus about 4pt padding top and bottom). No row dividers, no zebra, no column borders. A closing 0.75pt rule sits 18.1pt below the last baseline (y 631.44).
|
||||||
|
- **Numeric alignment:** unit price and qty centred, amount right-aligned. The sample has no decimals.
|
||||||
|
- **Suggested Voiced widths** (440.6-441.8pt between text edges): description flex:1 (about 210pt, wraps); rate 96pt centred; qty 48pt centred; amount 86pt right. Column centres stay within about 12pt of the design while fitting '₹1,500.00/hr' and '₹1,00,000.00'.
|
||||||
|
|
||||||
|
## Totals and payment
|
||||||
|
|
||||||
|
- **SUBTOTAL:** a full-width row. The label 'SUBTOTAL' (Regular, caps) sits at the left text edge, x 77.45. The value (Regular) is right-aligned at 514.4. Baseline 649.82, 18.4pt below the closing rule.
|
||||||
|
- **Tax row:** 'Tax' label right-aligned at 460.3, value '10%' right-aligned at 514.4, baseline 665.04. The value is the RATE only; the sample never prints a tax amount.
|
||||||
|
- **Grand total:** 'TOTAL' (Bold) right-aligned at 460.3 and '$770' (Bold) right-aligned at 514.4, baseline 680.09. There are no rules, boxes or size change; only the weight sets the total apart.
|
||||||
|
- **Payment info:** NOT at the bottom. The 'PAY TO:' bank block sits in the left column directly under 'ISSUED TO:', with bank name, 'Account Name: …' and 'Account No.: …'.
|
||||||
|
- **Signature:** a script-font name bottom-right (60pt, right edge 526.2).
|
||||||
|
- No notes, terms, thank-you line or footer.
|
||||||
|
|
||||||
|
## Decoration and images
|
||||||
|
|
||||||
|
- **Title hairline:** 0.75pt #3D3B3A, x 290.05-535.57, y about 148.7, the vertical centre of the 38pt capitals.
|
||||||
|
- **Table hairlines:** two 0.75pt #3D3B3A rules, x 69.64-525.86, at y 461.15 and 631.44.
|
||||||
|
- **No raster images at all.** The 42 KB file is just three font subsets. The signature is live text in BuongiornoRastellinoCyr-Script.
|
||||||
|
- Reference wraps everything in one Form XObject scaled by 0.24 (2482x3510 design units). This doesn't matter for the re-implementation.
|
||||||
|
- **Fully reproducible in react-pdf** with Views: height 0.75 plus backgroundColor, or borderBottomWidth 0.75.
|
||||||
|
|
||||||
|
## Mapping to Voiced fields
|
||||||
|
|
||||||
|
**Design slots mapped to Voiced fields:**
|
||||||
|
- **Title 'INVOICE':** 'INVOICE', or 'TAX INVOICE' when taxType !== 'none'.
|
||||||
|
- **ISSUED TO block:** clientName; clientAddress (wrap, keep line breaks); 'GSTIN: {clientGstin}' only if set; 'Place of Supply: {state name} ({placeOfSupplyStateCode})'.
|
||||||
|
- **Meta block (right):** 'INVOICE NO:' with the number (Bold); 'DATE:' invoiceDate; 'DUE DATE:' dueDate, omitting the row if empty; an optional 'PO NO:' poNumber row.
|
||||||
|
- **PAY TO block:** bank.bankName; 'Account Name: …'; 'Account No.: …'; then 'IFSC: …', 'Branch: …' and the planned 'UPI: …'. The block grows from 3 to 6 lines.
|
||||||
|
- **Table:**
|
||||||
|
- Description.
|
||||||
|
- UNIT PRICE: in rate mode, money(rate) plus a short unit ('/hr', '/min', '/sec', '/session', '/unit'); otherwise '—'.
|
||||||
|
- QTY: quantity in rate mode, else 1.
|
||||||
|
- TOTAL: computeLineAmount.
|
||||||
|
- **Tax row:** replace '10%' with real rows that carry amounts: 'CGST @ 9%' and 'SGST @ 9%', or 'IGST @ 18%'. Put a 'DISCOUNT' row (when greater than 0) before the tax rows, styled like them.
|
||||||
|
- **Signature slot:** the signature image, in a box of about x 352-526 / y 712-772, max 170x56pt, right-aligned, with 'Authorised Signatory' at 8pt. With no image, print 'Computer-generated invoice; no signature is required.' at 8pt, right-aligned, in the same spot. Never render the vendor name in a script font as a stand-in signature.
|
||||||
|
|
||||||
|
**Voiced fields with NO slot, and where to put them:**
|
||||||
|
- **Vendor name, address, phone, email, GSTIN, PAN.** The design has no vendor identity at all. Add a 'FROM' block right-aligned under the title rule, in the empty band x 290-535 / y about 170-255. Name in Bold 10pt; lines in Regular 9.5-10pt at a 13.5 pitch; 'GSTIN … · PAN …' on one line; maxWidth 245pt. It is in its own row below the title, so a long address can only push content down. It can never overlap the title, which is the reported header bug.
|
||||||
|
- **Vendor logo:** optional, in the empty top band above the title (x 59.5, y about 56-120, max 150x48pt).
|
||||||
|
- **Amount in words:** on the left side of the totals block (x 77.4, width at most 300pt) beside the Tax/TOTAL rows, or full width under TOTAL. 9pt, with the label 'AMOUNT IN WORDS' in Bold 8pt caps.
|
||||||
|
- **Notes:** full width below the amount in words, above the signature row.
|
||||||
|
- **HSN/SAC:** not in the data model. If added, use an 8pt second line under each description ('SAC 998314') or a 44pt column between DESCRIPTION and UNIT PRICE.
|
||||||
|
- **Footer:** 'Generated with Voiced — a Bongbetic product' plus 'Page n / N', fixed, 7pt, #3D3B3A, at y about 818.
|
||||||
|
|
||||||
|
## Overflow risks
|
||||||
|
|
||||||
|
- **Title:** 'TAX INVOICE' at 38pt with 7.6pt tracking is about 326pt wide, ending near x 386. That is 96pt past the fixed rule start (290). The rule must be a flex filler (minimum about 40pt), or the tracking must drop to about 0.12em for 'TAX INVOICE'.
|
||||||
|
- **Meta block:** only 143pt wide (x 376-519). A number like 'INV/2026-27/0001' in Bold 10pt with 0.5pt tracking is about 105pt, plus the 72pt label and 18pt gap, about 195pt in total. The block must grow leftwards: give the client column flex:1 with at least a 24pt gap, and the meta column flexShrink:0.
|
||||||
|
- **Client and bank column:** about 260pt from x 77.4 to the meta block, so long names and addresses wrap at roughly 45 characters per line. PAY TO grows to 6 lines (+40pt) and pushes the table down.
|
||||||
|
- **UNIT PRICE column:** about 70pt in the design, too narrow for '₹1,500.00 per hour' (about 100pt). Use short units or a second 8pt line.
|
||||||
|
- **Totals values:** they sit in only a 54pt gap after the labels (460.3 to 514.4). '₹12,34,567.89' (about 85pt) would run into 'CGST @ 9%'. Use a fixed value column of about 90pt; labels then end around x 420.
|
||||||
|
- **Descriptions:** they wrap at about 210pt (about 36 characters). The fixed 21.46 pitch must become padding (4pt top and bottom) so multi-line rows grow.
|
||||||
|
- **Rows per page:** page 1 holds about 7-8 rows before the totals and signature (about 150pt) spill to page 2. That needs a repeating header and totals/signature blocks that never split.
|
||||||
|
- **Amount in words:** up to about 100 characters, so 2 lines at a 300pt width.
|
||||||
|
- **Hyphenation:** react-pdf hyphenates by default. Register a no-op hyphenation callback so GSTINs, account numbers and URLs never get a stray hyphen.
|
||||||
|
|
||||||
|
## US Letter adaptation
|
||||||
|
|
||||||
|
- **US Letter (612x792):** 16.5pt wider and 50.25pt shorter than A4.
|
||||||
|
- **Horizontal:** keep the 69.6pt rule margins with the 7.8pt text inset, so content width grows from 456.2 to 472.8. Anchor meta, totals and signature to the right margin; anchor ISSUED TO, PAY TO and the table's left edge to the left margin. The title overhang (-18pt) and rule overshoot (+10pt) stay relative to the margins.
|
||||||
|
- **Vertical:** take the 50pt from the empty space. Cut the top band from 135 to about 100 before the title cap-top, and the title-to-ISSUED TO gap from about 100 to about 80. Nothing else changes, and the 7 sample rows still fit on Letter page 1.
|
||||||
|
- **Configurable margins:**
|
||||||
|
- Express every x as marginLeft + offset, or pageWidth - marginRight - offset. Keep the 7.8pt text inset inside the rule margin.
|
||||||
|
- Clamp the title (-18pt) and rule (+10pt) overhangs to stay at least 12pt from the paper edge.
|
||||||
|
- Express vertical anchors as marginTop + offset. Content flows, so smaller margins simply give more rows per page.
|
||||||
|
|
||||||
|
## react-pdf notes
|
||||||
|
|
||||||
|
- **Fonts:** Font.register({family:'Montserrat', fonts:[{src:'/fonts/Montserrat-Regular.ttf', fontWeight:400},{src:'/fonts/Montserrat-Bold.ttf', fontWeight:700}]}). Page style: {fontFamily:['Montserrat','IBM Plex Sans'], fontSize:10, letterSpacing:0.5, lineHeight:1.35, color:'#3D3B3A'}. Array fallback in fontFamily is supported in react-pdf v4; I checked the docs.
|
||||||
|
- **Page:** size A4 or LETTER, paddingHorizontal 77.4 (the text column). Rules use marginHorizontal -7.8 to reach 69.6 and 525.9.
|
||||||
|
- **Header:** the optional logo band, then the title row: View {flexDirection:'row', alignItems:'center', marginLeft:-18, marginRight:-16} holding Text {fontSize:38, letterSpacing:7.6} and a rule View {flex:1, height:0.75, backgroundColor:'#3D3B3A', marginLeft:12.4}.
|
||||||
|
- marginLeft is 12.4 because react-pdf, like CSS, adds the 7.6pt tracking after the last glyph; 12.4 + 7.6 gives the design's 20pt visual gap.
|
||||||
|
- For Montserrat the middle of the text box is within 0.3pt of the cap middle, so alignItems 'center' places the rule correctly.
|
||||||
|
- **Vendor FROM block:** a separate View {alignSelf:'flex-end', maxWidth:245, marginTop:≈10} with textAlign right.
|
||||||
|
- **Info row:**
|
||||||
|
- Row View {flexDirection:'row', marginTop:≈100 for the design's empty space}.
|
||||||
|
- Left View {flex:1, paddingRight:24}; right meta View {flexShrink:0}.
|
||||||
|
- Each meta row is a row View: label Text (textAlign right, width 90) and value Text (textAlign right, minWidth 54, marginLeft 18).
|
||||||
|
- PAY TO is an in-flow View with marginTop 17 under ISSUED TO.
|
||||||
|
- **Table:**
|
||||||
|
- Header row: View {flexDirection:'row', paddingBottom:8.5, borderBottomWidth:0.75, borderBottomColor:'#3D3B3A', marginHorizontal:-7.8, paddingHorizontal:7.8}. Give it the `fixed` prop so it repeats on continuation pages. Verify this; if it doesn't repeat, draw it on later pages through the page-level render prop.
|
||||||
|
- Rows: View {flexDirection:'row', paddingVertical:4} with wrap={false}.
|
||||||
|
- The table container's borderBottomWidth 0.75 plus paddingBottom 9 gives the closing rule.
|
||||||
|
- **Totals:** View wrap={false}, with minPresenceAhead about 60 on the preceding element so the totals never end up alone on a page.
|
||||||
|
- SUBTOTAL row: justifyContent 'space-between'.
|
||||||
|
- Then View {alignSelf:'flex-end', width:≈230} with rows of label (flex:1, right-aligned) and value (width 90, right-aligned). TOTAL uses fontWeight 700.
|
||||||
|
- **Signature:** View wrap={false}, alignSelf 'flex-end', marginTop about 30. The Image needs an explicit width/height box plus objectFit 'contain' and objectPosition 'right'.
|
||||||
|
- **Footer:** View fixed, absolute, bottom 20, left/right 77.4, fontSize 7, using render={({pageNumber,totalPages}) => …}.
|
||||||
|
- **Hyphenation:** Font.registerHyphenationCallback(w => [w]).
|
||||||
|
|
||||||
|
## Similarity to other templates
|
||||||
|
|
||||||
|
- **Byte-identical page content to /media/Toto/Documents/bongbetic/invoice/format.pdf.** It is the same reference page; only the Info/XMP title, export timestamps, reference design ID, xref offsets and trailer /ID differ. So this IS the vendor's original format, still carrying the reference design's sample data (Daniel Gallego / Richard Sanchez / Borcele Bank).
|
||||||
|
- **Not a duplicate of the in-app template.** The current src/pdf/InvoiceDocument.tsx only loosely adapts it (see group_notes).
|
||||||
|
- **Sibling of 5.pdf and 6.pdf.** They share the grid: rules 69.64-525.86, column centres 325.2 / 416.4, money right edge 514.4, meta label/value anchors about 447 / 519, totals label anchor 460.3. 5 changes fonts and decoration; 6 shifts the grid right. Build 4, 5 and 6 as one configurable 'Neutral' component family.
|
||||||
Vendored
+147
@@ -0,0 +1,147 @@
|
|||||||
|
# Template 5: Monogram (`monogram`)
|
||||||
|
|
||||||
|
Source: `templates/reference/5.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
|
||||||
|
|
||||||
|
The Linea grid restyled in Open Sans. A heavy, tracked 'INVOICE' faces a circular script-monogram logo. Labels and table headers are bold and tracked, and payment info shares the bottom row with a script signature.
|
||||||
|
|
||||||
|
## Fonts
|
||||||
|
|
||||||
|
- **Open Sans Bold (700):**
|
||||||
|
- Title 'INVOICE': 38.01pt, letterSpacing 3.8pt (0.10em).
|
||||||
|
- 10pt labels with letterSpacing 1.0pt (0.10em): 'ISSUED TO:', 'INVOICE NO:' and its value, the table header 'DESCRIPTION/RATE/QTY/TOTAL', 'SUBTOTAL' and its value, 'TOTAL' and its value, 'PAYMENT INFO:'.
|
||||||
|
- Logo caption 'MORGAN MAXWELL': 9.31pt, letterSpacing 0.47pt (0.05em).
|
||||||
|
- **Open Sans Medium (500)**, 10pt, letterSpacing 1pt: client lines and bank lines (address-type text).
|
||||||
|
- **Open Sans Regular (400)**, 10pt, letterSpacing 1pt: 'DATE:'/'DUE DATE:' labels and values, the table body, and 'Tax' with its rate. Stacked lines use a 13.5pt pitch (lineHeight 1.35).
|
||||||
|
- **reference-licensed fonts, not to be shipped:**
|
||||||
|
- TheBigmaker 325.55pt: the monogram 'm.' (logo art).
|
||||||
|
- BuongiornoRastellinoCyr-Script 70.02pt: the signature 'Maxwell'.
|
||||||
|
- The vendor's logo and signature images replace both.
|
||||||
|
- **Metrics** from the descriptors: Open Sans ascent 1069, descent -293, capHeight 714 per 1000; cap height is 7.1pt at 10pt.
|
||||||
|
- **Bundling:** Open Sans is OFL; download static TTFs for 400/500/700 from Google Fonts. It isn't installed on this machine, so I couldn't check U+20B9 (₹) coverage. Verify the chosen TTF, and keep fontFamily ['Open Sans','IBM Plex Sans'] so ₹ falls back to Plex if it's missing.
|
||||||
|
|
||||||
|
## Colours
|
||||||
|
|
||||||
|
Single colour only. Every glyph, rule and the monogram ring is #3D3B3A (rgb 61,59,58). The page is #FFFFFF. The monogram's gap comes from a #FFFFFF rotated rectangle painted over the ring, so that trick only works on white.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
Page is 595.5x842.25 (A4). Same grid as Linea: rules x 69.64-525.86; text column 77.4 to 519.2; money right edge 514.4.
|
||||||
|
1. **Header band**, y about 58-200.
|
||||||
|
- Title 'INVOICE': x 69.3-248.6, baseline 143.98, cap-top 116.8. It sits flush with the rule start (69.6), not the text column.
|
||||||
|
- Monogram logo, top-right; group bounding box about x 387-531 / y 58-198.
|
||||||
|
- Ring: outer diameter 116.4 (x 414.2-530.6, y 81.3-197.7), centre 472.4/139.5, visible stroke 3.75pt.
|
||||||
|
- About 84° of the ring is missing on the left (roughly 7:20 to 10:10 o'clock), where a script 'm.' crosses it (baseline 195.75, advance x 398.5-496.9).
|
||||||
|
- Caption 'MORGAN MAXWELL' is centred at x about 448, baseline 169.81 (x 399.3-496.9).
|
||||||
|
- The ring centre sits about 4.5pt above the title baseline.
|
||||||
|
2. **Empty space**, y 200-318 (about 118pt).
|
||||||
|
3. **Info row**, first baseline 325.42.
|
||||||
|
- Left, at x 77.6: 'ISSUED TO:' plus 3 Medium lines at 341.38 / 354.89 / 368.39.
|
||||||
|
- Right, meta block. Labels right-aligned at about 447.7: 'INVOICE NO:' 375.0-447.75, 'DATE:' starts 415.3, 'DUE DATE:' starts 388.8. Values: '01234' 486.6-519.2; dates 458.1-518.1. Baselines 325.42 / 340.88 / 355.60.
|
||||||
|
4. **Empty space**, y 368-428.
|
||||||
|
5. **Table:** header baseline 435.09; rule at y 447.56; rows at baseline 471.41 + n × 24.94 (5 rows, last at 570.58); closing rule at y 587.46.
|
||||||
|
6. **Totals:**
|
||||||
|
- SUBTOTAL at 606.59: Bold, label x 77.45, value right-aligned at 514.4.
|
||||||
|
- Tax at 625.98: label right-aligned at 460.3, '10%' right-aligned at 514.4.
|
||||||
|
- TOTAL at 643.86: Bold.
|
||||||
|
7. **Empty space**, y 644-700.
|
||||||
|
8. **Bottom row:**
|
||||||
|
- Left: 'PAYMENT INFO:' (Bold) at baseline 708.85, x 77.6, plus 3 Medium lines at 725.11 / 738.61 / 752.12.
|
||||||
|
- Right: signature (script, 70pt) x 392.3-518.1, baseline 759.31, ink about y 705-775.
|
||||||
|
9. About 65pt empty at the bottom; no footer.
|
||||||
|
|
||||||
|
## Items table
|
||||||
|
|
||||||
|
- **Columns:** same geometry as Linea.
|
||||||
|
- DESCRIPTION: left; header at 77.45, cells at 78.0.
|
||||||
|
- RATE: centred on 325.2 (header 311.3-339.2; cell '100' 315.7-334.8).
|
||||||
|
- QTY: centred on 416.4 (header 405.4-427.4).
|
||||||
|
- TOTAL: right-aligned; header right edge 519.2, cells right edge 514.4.
|
||||||
|
- **Header:** Open Sans Bold 10pt, UPPERCASE, letterSpacing 1pt, no fill. A single 0.75pt #3D3B3A rule 12.5pt below the header baseline (y 447.56), x 69.64-525.86.
|
||||||
|
- **Body:** Open Sans Regular 10pt, letterSpacing 1pt. First baseline is 23.85pt below the rule. Pitch is 24.94pt (13.5 line plus about 5.7pt padding top and bottom). No dividers or zebra striping. A closing 0.75pt rule sits 16.9pt below the last baseline (y 587.46).
|
||||||
|
- **Alignment:** rate and qty centred, amount right-aligned. '$' appears only in the TOTAL column.
|
||||||
|
- **Suggested Voiced widths:** description flex:1, rate 96 centred, qty 48 centred, amount 86 right. Open Sans with 1pt tracking averages about 5.6pt per character, so descriptions fit about 36 characters per line.
|
||||||
|
|
||||||
|
## Totals and payment
|
||||||
|
|
||||||
|
- **SUBTOTAL:** a full-width row with label AND value in Bold (Linea uses Regular here). Baseline 606.59, 19.1pt below the closing rule. Label at x 77.45, value right-aligned at 514.4.
|
||||||
|
- **Tax:** 'Tax' (Regular) right-aligned at 460.3, '10%' right-aligned at 514.4, baseline 625.98. Rate only, no amount.
|
||||||
|
- **TOTAL:** Bold label right-aligned at 460.35 and Bold value right-aligned at 514.4, baseline 643.86. No rules, boxes or size change; rows are about 18-19pt apart.
|
||||||
|
- **Payment:** the 'PAYMENT INFO:' block sits bottom-left (baseline 708.85; bank name, Account Name and Account No. in Medium). It shares a row with the signature on the right, and their bottoms roughly line up: last bank line 752.1, signature baseline 759.3.
|
||||||
|
- No notes, terms, thank-you line or footer.
|
||||||
|
|
||||||
|
## Decoration and images
|
||||||
|
|
||||||
|
- **Rules:** two 0.75pt table rules at y 447.56 and 587.46, x 69.64-525.86.
|
||||||
|
- **No raster images** (the file is 54 KB).
|
||||||
|
- **Monogram construction (vector plus text):**
|
||||||
|
- A circle path stroked at 7.5pt but clipped to its own interior, so the visible ring is 3.75pt (outer r 58.2, inner r 54.45, centre 472.43/139.50).
|
||||||
|
- A white rectangle, 134.4x77.8pt and rotated 34.5°, is painted over it. Its corners are about (356.7,58.8), (467.5,135.0), (423.4,199.1) and (312.6,122.9).
|
||||||
|
- The rectangle erases the arc from about 144.6° to 229° (maths angles), i.e. 84° on the left.
|
||||||
|
- The script 'm.' (TheBigmaker 325.6pt) and the caption text sit on top.
|
||||||
|
- **To draw the ring as vector without masking**, use an SVG arc only. Centre-relative path 'M -45.9 -32.6 A 56.33 56.33 0 1 1 -37.0 42.5' (y-down, large-arc 1, sweep 1), stroke #3D3B3A, strokeWidth 3.75, fill none.
|
||||||
|
- **Signature:** live script text at 70pt.
|
||||||
|
|
||||||
|
## Mapping to Voiced fields
|
||||||
|
|
||||||
|
- **Title:** 'INVOICE' or 'TAX INVOICE'. At 38pt with 3.8pt tracking, 'TAX INVOICE' is about 277pt wide and ends at x about 346, so it clears a logo that starts at x 387 or later.
|
||||||
|
- **Monogram slot** (x 387-531, y 58-198): the vendor logo Image in a box of about 130x116pt, objectFit contain, right-aligned, vertically centred on y about 139.5. Optional fallback when there is no logo: the ring arc above, the vendor's initial in an OFL script (e.g. Great Vibes or Allura, or simply Montserrat), and a vendor-name caption in Open Sans Bold 9.3pt, letterSpacing 0.47.
|
||||||
|
- **Vendor name, address, phone, email, GSTIN, PAN: no slot in the design.** Put a right-aligned FROM block directly under the logo: right edge at x 519-526, y about 205-305, maxWidth about 240pt. Name in Bold 10pt; lines in Medium 10pt or 9pt, letterSpacing 1pt. It is its own row below the header, so it cannot overlap the title.
|
||||||
|
- **ISSUED TO:** clientName, clientAddress, 'GSTIN: …' (optional), 'Place of Supply: …'.
|
||||||
|
- **Meta:** INVOICE NO / DATE / DUE DATE, plus an optional PO NO row.
|
||||||
|
- **Table:** DESCRIPTION; RATE (money(rate) plus '/hr' etc., '—' for fixed lines); QTY; TOTAL (line amount).
|
||||||
|
- **Totals:** SUBTOTAL; DISCOUNT when present; then 'CGST @ x%' and 'SGST @ x%', or 'IGST @ x%', each WITH its amount, replacing the 'Tax 10%' row; TOTAL.
|
||||||
|
- **PAYMENT INFO:** bank name, Account Name, Account No., IFSC, Branch, and the planned UPI.
|
||||||
|
- **Signature slot** (bottom-right, right edge 518): the signature image in a box of about 150x60pt, plus 'Authorised Signatory' at 8pt. Without an image, use the computer-generated note.
|
||||||
|
- **Fields with no slot:**
|
||||||
|
- Amount in words: on the left of the totals block beside Tax/TOTAL (x 77.4, at most 300pt wide), or full width below TOTAL.
|
||||||
|
- Notes: between the totals and the bottom row, full width, 9pt Regular.
|
||||||
|
- HSN/SAC: an 8pt sub-line under the description (not in the data model yet).
|
||||||
|
- Footer and page numbers: fixed, 7pt, at y about 818.
|
||||||
|
|
||||||
|
## Overflow risks
|
||||||
|
|
||||||
|
- **Header:** a wide wordmark logo (say 200pt) would collide with 'TAX INVOICE', which ends at about 346. Lay the header out as a row: title with flexShrink:1, logo box with maxWidth 140pt.
|
||||||
|
- **FROM block:** at most 240pt wide under the logo. Long addresses wrap to 3-4 lines (about 36 characters per line at Open Sans 10pt with 1pt tracking). It may push 'ISSUED TO' down, which is fine in flow layout.
|
||||||
|
- **Meta block** (x 375-519 = 144pt): long invoice numbers need the same grow-leftwards fix as Linea.
|
||||||
|
- **RATE column:** about 70pt in the design. Abbreviate unit labels or put them on a second 8pt line.
|
||||||
|
- **Totals:** labels end at 460.3 and values at 514.4, leaving only 54pt for amounts. Use a 90pt value column.
|
||||||
|
- **Description width:** Open Sans with 1pt tracking is wide, so the roughly 210pt description column holds about 36 characters per line. Rows must grow via padding (5.7pt) instead of a fixed 24.94 pitch.
|
||||||
|
- **Page 1 capacity:** about 6-8 rows. After that the totals (about 60pt) and the bottom row (payment plus signature, about 80-110pt with a 6-line bank block) spill to page 2. Keep the bottom row wrap={false}.
|
||||||
|
- **PAYMENT INFO** grows from 3 to 6 lines (+40pt). Keep the signature bottom-aligned with it (alignItems flex-end).
|
||||||
|
|
||||||
|
## US Letter adaptation
|
||||||
|
|
||||||
|
- **Width:** keep the 69.6pt rule margins, so content width goes from 456.2 to 472.8. Anchor the title to the left margin (x = marginLeft). Anchor the logo, FROM block, meta, totals and signature to the right margin; the logo may overshoot the rule end by 5pt.
|
||||||
|
- **Height (50pt shorter):** move the header band up (top from 58 to about 40) and cut the header-to-ISSUED TO gap from about 118 to about 85. The bottom row stays right after the totals plus about 56pt of space. When page 1 has little content, a flex spacer can push the bottom row to the page bottom.
|
||||||
|
- **Configurable margins:** the header band's top equals marginTop. The logo box keeps its 130x116 size but shrinks proportionally if pageWidth minus margins is under 440.
|
||||||
|
|
||||||
|
## react-pdf notes
|
||||||
|
|
||||||
|
- **Fonts:** register Open Sans 400/500/700 (static TTFs). Base style: {fontFamily:['Open Sans','IBM Plex Sans'], fontSize:10, letterSpacing:1, lineHeight:1.35, color:'#3D3B3A'}. Labels use fontWeight 700; address lines use 500.
|
||||||
|
- **Page:** paddingHorizontal 77.4. Give the title marginLeft -8 so it sits flush with the 69.6 rule start.
|
||||||
|
- **Header:** View {flexDirection:'row', justifyContent:'space-between', alignItems:'center', minHeight:140}.
|
||||||
|
- Title Text {fontSize:38, fontWeight:700, letterSpacing:3.8}.
|
||||||
|
- Logo View {width:144, height:140, alignItems:'center', justifyContent:'center', marginRight:-12}.
|
||||||
|
- The Image needs an explicit width/height box for objectFit 'contain' to work.
|
||||||
|
- **Optional monogram fallback:** <Svg width={120} height={120} viewBox='-60 -60 120 120'><Path d='M -45.9 -32.6 A 56.33 56.33 0 1 1 -37.0 42.5' stroke='#3D3B3A' strokeWidth={3.75} fill='none'/></Svg>, plus an absolutely positioned initial and caption. react-pdf Views have no clip or mask, so draw the arc rather than masking a full circle.
|
||||||
|
- **FROM block:** View {alignSelf:'flex-end', maxWidth:240, marginTop:8}, textAlign right.
|
||||||
|
- **Info row, table and totals:** exactly as Linea, except:
|
||||||
|
- Row paddingVertical 5.7 and header paddingBottom 7.5.
|
||||||
|
- SUBTOTAL is bold.
|
||||||
|
- letterSpacing is 1. react-pdf also adds tracking after the last glyph, so right-aligned columns end 1pt short; add marginRight:-1 if matching exactly.
|
||||||
|
- **Bottom row:** View {flexDirection:'row', justifyContent:'space-between', alignItems:'flex-end', marginTop:56}, wrap={false}. Left payment View {maxWidth:'55%'}; right signature box about 150x60.
|
||||||
|
- **Pagination:** table header row `fixed`; item rows wrap={false}; footer fixed with page numbers; hyphenation callback as in Linea.
|
||||||
|
|
||||||
|
## Similarity to other templates
|
||||||
|
|
||||||
|
- **Same reference design and grid as 4.pdf.** It is page 5 of design and shares 4.pdf's rules, column centres 325.2 / 416.4, money right edge 514.4, meta anchors about 447.7 / 519 and totals label anchor 460.3. It is a typography-and-decoration variant of Linea:
|
||||||
|
- Open Sans instead of Montserrat.
|
||||||
|
- Bold labels and header with 0.1em tracking.
|
||||||
|
- Row pitch 24.94 instead of 21.46.
|
||||||
|
- A monogram logo.
|
||||||
|
- The payment block moved to the bottom row.
|
||||||
|
- 'RATE' instead of 'UNIT PRICE', and a bold SUBTOTAL.
|
||||||
|
- **Not similar to the current in-app template** beyond normal invoice structure.
|
||||||
|
- **Shares its type system with 6.pdf:** Open Sans sizes and weights, 1pt tracking, Medium address lines.
|
||||||
Vendored
+160
@@ -0,0 +1,160 @@
|
|||||||
|
# Template 6: Serenity (`serenity`)
|
||||||
|
|
||||||
|
Source: `templates/reference/6.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
|
||||||
|
|
||||||
|
A boutique-stationery look. A warm cream paper texture, with a giant handwritten 'invoice' running up the left edge into a long swash. A circular-text stamp logo sits top-right, and a narrow Open Sans content column has hairline rules.
|
||||||
|
|
||||||
|
## Fonts
|
||||||
|
|
||||||
|
- **Open Sans Bold**, 10pt, letterSpacing 1pt (0.1em): 'ISSUED TO:', 'INVOICE NO:' and its value, the table header 'DESCRIPTION/UNIT PRICE/QTY/TOTAL', 'SUBTOTAL' and its value, 'TOTAL' and its value, 'BANK DETAILS', 'THANK YOU'.
|
||||||
|
- **Open Sans Medium**, 10pt, letterSpacing 1pt: client lines and bank lines.
|
||||||
|
- **Open Sans Regular**, 10pt, letterSpacing 1pt: DATE/DUE DATE labels and values, the table body, and 'Tax' with its rate. Line pitch 13.5 (lineHeight 1.35).
|
||||||
|
- **SimpleSerenityScript**, 279.48pt: the lowercase 'invoice', rotated 90° counter-clockwise. A reference-licensed decorative script; ascent 767, descent -454 per 1000.
|
||||||
|
- **Poppins Regular**, 7.98pt, uppercase, tracked about 0.17em: the circular stamp text 'DESIGN BY NATALIE • DESIGN BY NATALIE •'.
|
||||||
|
- **Montserrat Regular**, 16.61pt: the stamp's centre letter 'N'.
|
||||||
|
- **No signature font:** the signature is vector artwork.
|
||||||
|
- **Bundling:**
|
||||||
|
- Open Sans, Poppins and Montserrat are OFL. Bundle Open Sans 400/500/700; Poppins and Montserrat only if the stamp is recreated.
|
||||||
|
- SimpleSerenityScript can't be redistributed. Ship the 'invoice' lettering as an SVG asset (outlines), or reset it in an OFL script such as Ms Madi, Allison or Great Vibes.
|
||||||
|
|
||||||
|
## Colours
|
||||||
|
|
||||||
|
- **Ink:** text, rules, the script word, the flourish, the stamp and the signature are all #3D3B3A (rgb 61,59,58).
|
||||||
|
- **Background:** a full-bleed paper texture. Its measured average is #ECE8E1 (sRGB about 236,232,225), from decoding the JPEG's DC coefficients (Y 232.4 / Cb 123.9 / Cr 130.7).
|
||||||
|
- The grain is only in brightness: 8x8 block means range Y 228-236, with darker fibres down to about 203.
|
||||||
|
- No gradient or vignette: 12 page regions match within ±1.
|
||||||
|
- The image dictionary says /ColorTransform 0, but that is a producer quirk; the data is YCbCr. The ICC profile is a 536-byte Google/Skia profile, close to sRGB.
|
||||||
|
- **Page fill:** #FFFFFF underneath, fully covered.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
Page is 595.5x842.25. Two zones:
|
||||||
|
- A decorative band on the left (x about 55-155).
|
||||||
|
- A content column: rules x 162.91-531.39 (368.5pt); text from x 171.8 to a right edge of 524.7; money right edge 519.9.
|
||||||
|
Implied margins: left 162.9 (rules) / 171.8 (text); right 64.1 / 70.8; top about 128 (stamp); bottom about 59.
|
||||||
|
1. **Background:** the texture covers the page; the image bleeds to x -9.2..604.5, y -72.8..915.3.
|
||||||
|
2. **Left band:** script 'invoice' rotated 90° counter-clockwise, reading bottom to top.
|
||||||
|
- Baseline at about x 150, tilted 1.1°. The first glyph is at y 771.7; the last glyph ends at y about 409.8. Ink extends left to x about 60.
|
||||||
|
- A swash flourish continues upward from y about 411 to y about 142.5 (x 56-82).
|
||||||
|
- Band bounding box about x 55-155, y 142-772.
|
||||||
|
3. **Stamp**, top-right: centre (485.5, 172.7), bounding box about x 441-531, y 128-218.
|
||||||
|
- Ring text on radius 35.3pt (to the glyph baselines). Letters are upright at the top and read clockwise.
|
||||||
|
- Two round dots of 1.96pt diameter at (454.0,194.1) and (516.3,151.2) separate the two repeats.
|
||||||
|
- Inner ring: 30.9pt diameter, 0.75pt line, at (486.0,172.4).
|
||||||
|
- 'N' at baseline 178.53, x 478.8-492.3.
|
||||||
|
4. **Empty space**, y 218-313.
|
||||||
|
5. **Info row**, first baseline about 320.3/321.0.
|
||||||
|
- Left: 'ISSUED TO:' at x 172.0, baseline 320.29, plus Medium lines at 336.25 / 349.76 / 363.26.
|
||||||
|
- Right, meta block. Labels right-aligned at about 451.8: 'INVOICE NO:' 379.0-451.7, 'DATE:' 420.5-451.8, 'DUE DATE:' 394.1-452.0. Values right-aligned at 524.7: '01234' 492.1-524.7, dates 464.8-524.8. Baselines 321.04 / 335.75 / 350.47.
|
||||||
|
6. **Table:** header baseline 443.63; rule at y 456.09; rows at baseline 479.94 + n × 25.09 (5 rows, last at 580.32); closing rule at y 597.20.
|
||||||
|
7. **Totals:**
|
||||||
|
- SUBTOTAL at 616.33: label x 173.8, value right-aligned at 519.9.
|
||||||
|
- Tax at 636.86: label right-aligned at 465.9.
|
||||||
|
- TOTAL at 653.54.
|
||||||
|
8. **Empty space**, y 654-730.
|
||||||
|
9. **Bottom row**, baseline 736.98.
|
||||||
|
- Left: 'BANK DETAILS' at x 182.7, an 11pt inset from the column, plus Medium lines at 753.24 / 766.74 / 780.25.
|
||||||
|
- Right: 'THANK YOU' right-aligned at 532.4 (x 464.9-532.4), with the drawn signature below it (x 441.9-542.7, y 749.8-783.0).
|
||||||
|
10. About 59pt empty at the bottom.
|
||||||
|
|
||||||
|
## Items table
|
||||||
|
|
||||||
|
- **Columns:**
|
||||||
|
- DESCRIPTION: left at x 171.8 for both header and cells. It is only about 160pt wide (171.8 to about 335).
|
||||||
|
- UNIT PRICE: centred on 370.4 (header 338.1-402.6; cell '100' 360.8-379.9).
|
||||||
|
- QTY: centred on 441.8 (header 430.8-452.8).
|
||||||
|
- TOTAL: right-aligned; header right edge 524.8, cells right edge 519.9.
|
||||||
|
- **Header:** Open Sans Bold 10pt, caps, letterSpacing 1pt, no fill. A single 0.75pt #3D3B3A rule 12.5pt below (y 456.09), x 162.91-531.39.
|
||||||
|
- **Body:** Open Sans Regular 10pt, letterSpacing 1pt. The sample text is lowercase, but that is content, not a style rule.
|
||||||
|
- First baseline is 23.85pt below the rule.
|
||||||
|
- Pitch is 25.09, about 5.8pt padding top and bottom.
|
||||||
|
- No dividers or zebra striping.
|
||||||
|
- A closing rule sits 16.9pt below the last baseline (y 597.20).
|
||||||
|
- **Alignment:** unit price and qty centred, amount right-aligned.
|
||||||
|
- **Suggested Voiced widths** (352.9pt text column): description flex:1 (about 149pt); rate 84 centred (centre about 363); qty 40 centred (about 425); amount 80 right. Centres stay within about 17pt of the design.
|
||||||
|
|
||||||
|
## Totals and payment
|
||||||
|
|
||||||
|
- **Totals** (no rules or boxes):
|
||||||
|
- SUBTOTAL: Bold, label x 173.8, value right-aligned at 519.9, baseline 616.33.
|
||||||
|
- 'Tax': Regular label right-aligned at 465.9, '10%' right-aligned at 519.9, baseline 636.86.
|
||||||
|
- 'TOTAL': Bold label right-aligned at 465.9, Bold value right-aligned at 519.9, baseline 653.54.
|
||||||
|
- **Payment:** a 'BANK DETAILS' block bottom-left, with bank name, Account Name and Account No. in Medium.
|
||||||
|
- **Thank-you:** 'THANK YOU' in Bold caps, right-aligned on the same baseline as 'BANK DETAILS' (736.98), with a hand-drawn signature under it.
|
||||||
|
- No notes, terms or footer.
|
||||||
|
|
||||||
|
## Decoration and images
|
||||||
|
|
||||||
|
- **Background raster:** one JPEG, 2304x1384px (DCTDecode, ICC-based RGB, 988,001 bytes, 94% of the file). Its placement matrix rotates it 90° and stretches it unevenly to 613.7x988.1pt (about 165-168 dpi), bleeding past every edge.
|
||||||
|
- Recommendation: don't ship it. Use Page backgroundColor '#ECE8E1', optionally plus a downsampled or tiled texture (at most 150 KB, objectFit cover, fixed).
|
||||||
|
- **Vertical script word:** live text (SimpleSerenityScript 279.5pt, rotated +91.1° in PDF space).
|
||||||
|
- **Flourish:** 2 filled vector paths (142 and 40 points), x 56.1-82.1, y 142.5-411.0, clipped to x -66.8..188.3 / y 142.4..411.5. They live inside Form X23 (object 16), right after 'X9 Do'.
|
||||||
|
- **Stamp:** 39 individually rotated Poppins glyphs on a circle (r 35.3), plus two 1.96pt round dots (squares clipped to circles), an inner ring (1.5pt stroke clipped inside, so 0.75pt visible) and the 'N'.
|
||||||
|
- **Signature:** 6 filled vector subpaths (Form X15), x 441.9-542.7, y 749.8-783.0.
|
||||||
|
- **Rules:** two 0.75pt rules, x 162.91-531.39, at y 456.09 and 597.20.
|
||||||
|
- **Reproducibility in react-pdf:**
|
||||||
|
- Rules, the texture colour, rotated text and SVG paths are all possible.
|
||||||
|
- Circular text is not native, since Svg has no textPath; it would need 39 absolutely positioned, rotated Text glyphs. Best to treat the stamp as the logo slot.
|
||||||
|
- The simplest faithful route for the band is one static SVG of 'invoice' plus the flourish. Convert the text to paths at implementation time (e.g. with mutool or Inkscape). viewBox about x 50-160 / y 138-776, drawn with react-pdf <Svg><Path/>.
|
||||||
|
|
||||||
|
## Mapping to Voiced fields
|
||||||
|
|
||||||
|
- **Decorative 'invoice' script:** static art, never data.
|
||||||
|
- Always add a real-text 'INVOICE' or 'TAX INVOICE' label so the document is searchable and compliant.
|
||||||
|
- Place it above the meta block: Open Sans Bold 10pt, letterSpacing 1pt, right-aligned at 524.7, baseline about 300.
|
||||||
|
- **Stamp slot** (about 90x90pt, centre 485.5/172.7): the vendor logo Image, objectFit contain. A circular vendor-name ring around it (per-glyph rotated Text) is a nice-to-have only.
|
||||||
|
- **Vendor name, address, phone, email, GSTIN, PAN: no slot.** Put a FROM block in the space between the stamp and ISSUED TO (y about 225-305).
|
||||||
|
- Right-aligned at 524.7 under the stamp, maxWidth about 250pt; or left at 171.8 if the address is long.
|
||||||
|
- Open Sans Bold name plus Medium lines.
|
||||||
|
- **ISSUED TO:** clientName, clientAddress, GSTIN (optional), Place of Supply.
|
||||||
|
- **Meta:** INVOICE NO / DATE / DUE DATE, plus an optional PO NO.
|
||||||
|
- **Table:** description; UNIT PRICE (money(rate) plus '/hr', '—' for fixed lines); QTY; TOTAL.
|
||||||
|
- **Totals:** SUBTOTAL, DISCOUNT, CGST+SGST or IGST rows with amounts, TOTAL.
|
||||||
|
- **BANK DETAILS:** bank name, Account Name, Account No., IFSC, Branch, UPI.
|
||||||
|
- **THANK YOU and drawn signature:** keep 'THANK YOU' (or 'FOR {VENDOR}'). Put the signature image under it (box about 100x40pt, right-aligned at 532); otherwise the computer-generated note at 8pt.
|
||||||
|
- **Fields with no slot:**
|
||||||
|
- Amount in words: left part of the totals block beside Tax/TOTAL (x 171.8, at most 200pt wide), or full width under TOTAL.
|
||||||
|
- Notes: full width between the totals and the bottom row.
|
||||||
|
- HSN/SAC: an 8pt sub-line under the description.
|
||||||
|
- Footer and page numbers: fixed, 7pt, at y about 818, left edge 171.8.
|
||||||
|
|
||||||
|
## Overflow risks
|
||||||
|
|
||||||
|
- **Narrowest of the three:** 352.9pt of text width, so the description column is only about 150pt (about 25 characters per line at Open Sans 10pt with 1pt tracking). Most real descriptions will wrap to 2-3 lines. Consider letterSpacing 0.5 for the body in this template.
|
||||||
|
- **ISSUED TO column:** about 200pt (171.8 to the meta block at about 379), so long client names and addresses wrap heavily.
|
||||||
|
- **Meta block:** only 146pt (379-524.7). Long invoice numbers need it to grow leftwards; cap the client column with flex:1 and a 20pt gap.
|
||||||
|
- **Totals:** only 54pt between the labels (465.9) and the money edge (519.9). Use a 90pt value column.
|
||||||
|
- **Stamp slot:** square, about 90pt, so wide wordmark logos come out tiny. Offer a 140x60 landscape box variant.
|
||||||
|
- **Bottom row:** BANK DETAILS grows to 6 lines (+40pt) next to the signature box. With many items, the bottom row (about 90pt) and the totals move to page 2.
|
||||||
|
- **Decorative band:** 630pt tall. On continuation pages it should repeat (fixed); either way the content must keep its 162.9pt left offset.
|
||||||
|
- **Hyphenation:** same as the other templates.
|
||||||
|
|
||||||
|
## US Letter adaptation
|
||||||
|
|
||||||
|
- **Width (+16.5pt):** keep the band anchored to the page's left edge (x about 55-155). The content column becomes [max(marginLeft, 162.9) … pageWidth - marginRight (about 64)], i.e. 162.9-548 on Letter (385pt, 16.5pt wider).
|
||||||
|
- **Height (-50pt):** the band (y 142-772) would end only 20pt from the Letter bottom edge. Shift it up about 32pt (to y 110-740) or scale it by 0.94. Move the stamp up to top about 96, and cut the stamp-to-ISSUED TO gap from about 95 to about 70.
|
||||||
|
- **Texture:** a background colour, or an image with objectFit 'cover', adapts automatically.
|
||||||
|
- **Configurable margins:** the band is decoration anchored to the page edge, outside the margin system. Even so, the content column's left padding must stay at least the band's right edge + 8pt (about 163), whatever the user's left margin. Right, top and bottom margins apply normally.
|
||||||
|
|
||||||
|
## react-pdf notes
|
||||||
|
|
||||||
|
- **Page style:** {backgroundColor:'#ECE8E1', paddingLeft:171.8, paddingRight:70.8, paddingTop:≈128, paddingBottom:≈60, fontFamily:['Open Sans','IBM Plex Sans'], fontSize:10, letterSpacing:1, lineHeight:1.35, color:'#3D3B3A'}. Rules use marginLeft -8.9 and marginRight -6.7 to span 162.9-531.4.
|
||||||
|
- **Optional texture:** <Image fixed src={paperTexture} style={{position:'absolute', top:0, left:0, width:'100%', height:'100%', objectFit:'cover'}}/> as the FIRST child. Absolute children are placed against the page box, ignoring padding.
|
||||||
|
- **Band:** <View fixed style={{position:'absolute', left:50, top:138, width:110, height:640}}><Svg viewBox='…'><Path d=…/></Svg></View>.
|
||||||
|
- If you reset the word in a font instead, use Text {position:'absolute', fontFamily:<OFL script>, fontSize:≈280, transform:'rotate(-90deg)', transformOrigin:'left top'}. Place it so its baseline lies on x about 150, starting at y about 772. react-pdf's rotate() is positive clockwise, so -90 reads bottom to top. Tune visually, and draw the flourish as an Svg Path.
|
||||||
|
- **Stamp → logo:** View {position:'absolute', top:128, right:64, width:90, height:90} with an Image, objectFit contain. Alternatively keep it in flow at the top of the column (alignSelf flex-end).
|
||||||
|
- **Everything else:** Monogram's components with the narrower column.
|
||||||
|
- **Bottom row:** View {flexDirection:'row', justifyContent:'space-between', alignItems:'flex-start'}, wrap={false}.
|
||||||
|
- Left: bank block, with paddingLeft 10.9 to match the design's 182.7 inset, or 0 to align with the column.
|
||||||
|
- Right: a column {alignItems:'flex-end'} holding 'THANK YOU' and the signature Image (about 100x40).
|
||||||
|
- **Print-friendly toggle:** drop the background colour and texture, since beige floods toner.
|
||||||
|
|
||||||
|
## Similarity to other templates
|
||||||
|
|
||||||
|
- **Same reference design** (ID, page 6).
|
||||||
|
- **Typography identical to 5.pdf:** Open Sans 10pt, 1pt tracking, Bold labels, Medium address lines. The table and totals spacing also matches: header to rule 12.5, rule to first row 23.85, last row to rule 16.9, rule to SUBTOTAL 19.1.
|
||||||
|
- **Same internal grid as 4 and 5, shifted right:** rules 162.91-531.39 instead of 69.64-525.86 (left edge +93.3, right edge +5.5).
|
||||||
|
- **Unique within the trio:** the paper texture, vertical script title, circular-text stamp, drawn signature, and the 'BANK DETAILS' / 'THANK YOU' bottom row.
|
||||||
|
- **No resemblance to the in-app template.**
|
||||||
Vendored
+128
@@ -0,0 +1,128 @@
|
|||||||
|
# Template 7: Crimson Grid (`crimson-grid`)
|
||||||
|
|
||||||
|
Source: `templates/reference/7.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
|
||||||
|
|
||||||
|
Bold corporate boxed grid. A huge black Poppins INVOICE sits top-left, with the logo and a 2-line name top-right. Below: a 1.5pt crimson rule, a table fully ruled in 0.75pt black with a crimson header row, a ruled totals box, and a full-bleed crimson footer band carrying a cream contact line.
|
||||||
|
|
||||||
|
## Fonts
|
||||||
|
|
||||||
|
One family: Poppins, static weights 400/600/700. Metrics per 1000 units: ascent 1050, descent -350, cap ~700.
|
||||||
|
- Poppins Bold 700: title 'INVOICE' 43.8pt #000000, tracking +0.37pt (~0.0085em). Total-row label and value 12pt.
|
||||||
|
- Poppins SemiBold 600: brand lockup 'STUDIO'/'SHODWE' 15.44pt uppercase, baselines 80.75 and 95.22 (pitch 14.47, i.e. lineHeight 0.94). Section headings 12pt uppercase (vendor name, 'BILL TO', 'NOTES / TERMS:', 'PAYMENT METHOD', 'PREPARED BY'). Table header labels 11pt #FFFFFF.
|
||||||
|
- Poppins Regular 400: body 12pt (meta, party lines, notes, bank lines, prepared-by). Table cells and totals 11pt. Footer contact line 12.44pt #EFEDDF, tracking +0.8pt (~0.064em).
|
||||||
|
- Line pitch: 12pt body lines 16.5pt (lineHeight 1.375). Meta lines 18.68pt. Heading baseline to first body baseline: 23.98 (party and payment blocks), 20.8 (notes).
|
||||||
|
- Any other measured tracking (~0.1pt) is rounding in the reference design's per-glyph placement. Use letterSpacing 0.
|
||||||
|
- The embedded subsets have no U+20B9 (₹). Check that the full Poppins TTFs include it before bundling.
|
||||||
|
|
||||||
|
## Colours
|
||||||
|
|
||||||
|
Exact fill operators:
|
||||||
|
- #A00000 (rg 0.6275 0 0), crimson: header rule, table header row fill, footer band.
|
||||||
|
- #000000: title, all body text, table and totals grid lines.
|
||||||
|
- #FFFFFF: page background, table header labels, separators between header cells.
|
||||||
|
- #EFEDDF (0.9373 0.9294 0.8745), cream: footer contact text.
|
||||||
|
- #ED1C24 (0.9294 0.1098 0.1412): placeholder flame logo only. Drop it; the vendor logo replaces it.
|
||||||
|
No transparency: every ExtGState has ca/CA 1. The ca=0 rectangles are invisible accessibility tag boxes.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
A4 595.5x842.25pt, y measured from the page top. Side margins 59.55 (= 10% of width) and 58.8. Content x 59.55-536.70 (477.15 wide).
|
||||||
|
| Region | Geometry (pt) |
|
||||||
|
|---|---|
|
||||||
|
| Title INVOICE | x 59.55, baseline 100.58 (cap top ~69.7), text box ~186 wide |
|
||||||
|
| Logo mark | x 420.0-452.4, y 53.0-98.7 (32x46) |
|
||||||
|
| Brand name | x 466.1 (13.7 right of logo), baselines 80.75/95.22, right edge <= 536.7 |
|
||||||
|
| Header rule | y 128.85, x 59.55-536.70, 1.5pt #A00000 |
|
||||||
|
| Meta | x 59.55, baselines 173.58 'Invoice Number: #...' and 192.26 'Invoice Date: ...' |
|
||||||
|
| Party row | 2 columns: vendor at x 59.55, BILL TO at x 304.31 (51.3% split). Heading baseline 231.07; lines 255.05/271.55/288.06/304.56 |
|
||||||
|
| Items table | y 335.84-497.90 (40.5 header + 3 rows of 40.52) |
|
||||||
|
| Notes (left) | heading baseline 523.33, body 544.12/560.62, wraps at ~182 wide |
|
||||||
|
| Totals box (right) | x 353.59-536.70, y 509.21-632.26 |
|
||||||
|
| Payment (left, x 59.55) and Prepared by (right, x 322.44, misaligned with 304.31; normalise) | heading baselines 686.95; lines 711.72/728.23/744.74 |
|
||||||
|
| Footer band | full bleed, y 779.26-842.25 (63 tall), text centred, baseline 815.88 |
|
||||||
|
Vertical gaps: rule to meta cap top ~36. Last meta baseline to party heading cap top ~30. Last party baseline to table 31.3. Table to totals box 11.3. Totals bottom to payment cap top ~46. Last payment baseline to band 34.5. In the title/brand row the bottoms roughly align (title baseline 100.6, logo bottom 98.7), so use alignItems flex-end.
|
||||||
|
|
||||||
|
## Items table
|
||||||
|
|
||||||
|
4 columns, fully ruled. Grid-line centres at x 59.93 | 308.96 | 406.84 | 447.86 | 536.33, giving widths 249.0 / 97.9 / 41.0 / 88.5 (52.3% / 20.5% / 8.6% / 18.6%).
|
||||||
|
- Header row: 40.5 tall, fill #A00000. Poppins SemiBold 11 #FFFFFF. 'Item & Description' left-aligned; 'Unit Price', 'Qty', 'Amount' right-aligned. 0.75pt #FFFFFF separators between header cells. Reference artefact: cells 1 and 3 have black top/bottom edges while cells 2 and 4 have white ones. Normalise to a black 0.75 outer box with white inner verticals.
|
||||||
|
- Body rows: 40.52 tall, white, 0.75pt #000000 on every cell edge (outer box, verticals, row lines). Poppins Regular 11 #000. Description left-aligned; unit price, qty and amount right-aligned. Horizontal padding 9.4 on both sides.
|
||||||
|
- Vertical: baseline is 23.64 below the row top. In react-pdf (natural line 15.4 at 11pt) that is paddingTop 12.1 and paddingBottom 13.0, or minHeight 40.5 with alignItems center.
|
||||||
|
- No zebra striping. Keep numbers right-aligned. The Qty column is only 41 wide (~4 digits), so put the unit with the rate (e.g. '/hr').
|
||||||
|
- Recommendation: make each money column at least 95-100pt for en-IN amounts (see overflow_risks).
|
||||||
|
|
||||||
|
## Totals and payment
|
||||||
|
|
||||||
|
- Totals box, right side: x 353.59-536.70 (183.1 wide = 38.4% of content). 2 columns: label 93.45 | value 88.9. The value-column edge at 447.41 lines up with the table's Qty|Amount line at 447.86. Rows: 'Sub-Total' 40.52, 'Tax (6%)' 40.52, 'Total' 42.02. Full 0.75pt black grid. Labels Regular 11 left-aligned (padding 9.4), values right-aligned. Total row is Poppins Bold 12 in both cells.
|
||||||
|
- Notes/Terms sit left of the totals box, top-aligned with it (heading baseline 523.33; box top 509.21).
|
||||||
|
- PAYMENT METHOD: SemiBold 12 heading, then Regular 12 lines 'Bank:', 'Account Name:', 'Account Number:'.
|
||||||
|
- PREPARED BY: heading, then a name line and a 'title, company' line. No signature graphic.
|
||||||
|
- Footer band: one centred line 'email | website | phone'.
|
||||||
|
- Missing from the template: amount in words, signature, thank-you line, due date, page number.
|
||||||
|
|
||||||
|
## Decoration and images
|
||||||
|
|
||||||
|
No raster XObjects. Everything is vector shapes plus live text.
|
||||||
|
- Logo: flame made of 3 bezier subpaths, #ED1C24, 32x46. Replace with a vendor logo Image.
|
||||||
|
- Header rule: 1.5pt #A00000 line.
|
||||||
|
- Table header: 4 #A00000 rectangles (one per cell). Grid strokes 0.75pt.
|
||||||
|
- Footer band: #A00000 rectangle drawn with bleed (x -30..626, y 779.3..872). Implement as a View, absolute, left 0, right 0, bottom 0, height 63.
|
||||||
|
- 3 invisible (ca=0) rectangles tagged 'Image' over the logo, rule and band are accessibility tags. Ignore them.
|
||||||
|
Everything can be built with View backgroundColor and borders. Svg is only needed for an optional vector logo.
|
||||||
|
|
||||||
|
## Mapping to Voiced fields
|
||||||
|
|
||||||
|
- Logo slot: vendor logo (Image maxHeight 46, maxWidth ~110, objectFit contain). If the logo is a wordmark (e.g. public/brand/sample-wordmark-logo.png), hide the text lockup.
|
||||||
|
- Brand lockup: vendorName (SemiBold 15.4 uppercase, wraps, right-aligned).
|
||||||
|
- 'INVOICE': show 'TAX INVOICE' when taxType != none, else 'INVOICE'.
|
||||||
|
- Meta lines: 'Invoice No: {number}', 'Invoice Date: {date}', NEW 'Due Date: {dueDate}' (3rd line, same 18.68 pitch), optional 'PO No: {poNumber}'.
|
||||||
|
- Left party block (heading = vendor name): vendorAddress (multi-line), vendorPhone, vendorEmail, NEW 'PAN: {vendorPan}', NEW 'GSTIN: {vendorGstin}'.
|
||||||
|
- BILL TO: clientName, clientAddress, 'GSTIN: {clientGstin}' (optional), NEW 'Place of Supply: {state} ({code})'.
|
||||||
|
- Table: Item & Description = description. Unit Price = rate with unit (e.g. '₹1,500.00 / hr'); em dash for fixed-mode lines. Qty = quantity (1 for fixed mode). Amount = line amount.
|
||||||
|
- HSN/SAC (no slot): grey 9pt sub-line under the description, or an optional 5th column (~55pt) taken from the description width.
|
||||||
|
- Totals box: Sub-Total, Discount (if > 0), then CGST (r/2 %) and SGST (r/2 %) or IGST (r %), then Total (bold). This makes 4-6 rows.
|
||||||
|
- Amount in words (no slot): full-width line under the notes/totals row, SemiBold 11 'Amount in words:' followed by Regular 11 text. Indian-system strings run 60-110 chars, so 1-2 lines.
|
||||||
|
- Notes/Terms: notes, with a default 'Payment due within {paymentTermsDays} days'.
|
||||||
|
- PAYMENT METHOD: bank fields Bank, Account Name, Account No, IFSC, Branch, UPI (planned). Up to 6 lines.
|
||||||
|
- PREPARED BY: rename to 'AUTHORISED SIGNATORY'. Show the signature Image (maxHeight ~36) and vendorName, or Regular 9 fine print 'Computer-generated invoice; no signature required.'
|
||||||
|
- Footer band: 'vendorEmail | vendorPhone', optionally ' | GSTIN ...'. Voiced has no website field. A page number 'n / N' can sit at the band's right end.
|
||||||
|
|
||||||
|
## Overflow risks
|
||||||
|
|
||||||
|
- Header (same class as the reported INVOICE overlap bug): the brand area is only 420-536.7 (116pt). A long vendorName wraps to 3+ lines and pushes into the rule at 128.85. 'TAX INVOICE' at 43.8pt is ~285pt wide (59.6 to ~345), leaving ~75pt before the logo. Use a flex row, never absolute positioning: title flexShrink 0; brand View flex 1, maxWidth ~40%, alignItems flex-end; rule below in normal flow.
|
||||||
|
- Party blocks: the template ends at baseline 304.56 (4 lines) and the table starts at 335.84. A Voiced vendor block (address 2-3 lines, phone, email, PAN, GSTIN = 6-8 lines) adds 33-66pt, so the table must flow, not sit at a fixed y.
|
||||||
|
- BILL TO column is 232pt (~36 chars per line at 12pt). Long addresses wrap, which is fine in flow.
|
||||||
|
- Items: with 40.5pt rows only ~6 fit before the totals on page 1. The 249pt description column holds ~40 chars per line at 11pt, so long text grows the row. More than 8 rows go to page 2, which needs the header row repeated.
|
||||||
|
- Money: the Amount column's inner width is 69.7pt, and '₹10,00,000.00' at 11pt Poppins is ~72pt, so it overflows from 10 lakh up. Unit Price (79pt inner) is fine up to ~99 lakh. Widen Amount to ~100pt (taking from description) or set numbers at 10pt.
|
||||||
|
- Totals box: with Discount, CGST and SGST it has 5-6 rows x 40.5 = 200-245pt, which reaches the PAYMENT block (686.95) and the band (779) on A4. Use compact rows (~26pt) and flow.
|
||||||
|
- Payment block: 6 bank lines x 16.5 = 99pt from 711.7 ends at ~810, past the band top at 779. Let it flow to page 2 or tighten it. Page paddingBottom must be >= 63 + 16.
|
||||||
|
- Footer line: about 60 chars fit in 477pt at 12.44pt with 0.8 tracking. Email + phone + GSTIN can exceed that: use fontSize 10, or maxLines 1 with ellipsis, or 2 lines (the 63pt band fits 2).
|
||||||
|
|
||||||
|
## US Letter adaptation
|
||||||
|
|
||||||
|
- US Letter 612x792 is 16.5pt wider and 50.25pt shorter. Keep side margin M (default 59.55 = 10% of A4 width, or the user's setting). Content width = 612 - 2M (492.9 at the default). Column percentages from items_table scale with it. Keep the totals box at 183pt (or 38.4%), right-aligned.
|
||||||
|
- Footer band stays fixed at 63pt at the bottom (top at 729 on Letter). To recover ~50pt: rule-to-meta gap 36 -> 26; meta-to-party gap 30 -> 22; table rows 40.5 -> 32 (header 34); totals rows 40.5 -> 30; totals-to-payment gap 46 -> 28.
|
||||||
|
- Configurable margins: top margin = logo top (53 by default); title baseline = top + 47.6. The band ignores side margins (full bleed) but its text uses M. Page paddingBottom = 63 + bottom gap (16-24).
|
||||||
|
- the reference design's 595.5x842.25 page differs from react-pdf A4 (595.28x841.89) by under 0.05%; ignore it.
|
||||||
|
|
||||||
|
## react-pdf notes
|
||||||
|
|
||||||
|
- Font.register Poppins 400/600/700 from bundled .ttf files. react-pdf takes TTF/WOFF only, not WOFF2 or variable fonts.
|
||||||
|
- <Page size={'A4'|'LETTER'} style={{fontFamily:'Poppins', paddingTop:53, paddingBottom:83, paddingHorizontal:M}}>.
|
||||||
|
- Footer band: <View fixed style={{position:'absolute', left:0, right:0, bottom:0, height:63, backgroundColor:'#A00000', justifyContent:'center', paddingHorizontal:M}}> containing <Text style={{color:'#EFEDDF', fontSize:11, letterSpacing:0.8, textAlign:'center'}}>. Absolute offsets are relative to the page edge; the existing InvoiceDocument footer already relies on this. This is the template's only absolute element.
|
||||||
|
- Header: View row, justifyContent space-between, alignItems flex-end. Title Text (fontSize 43.8, fontWeight 700, flexShrink 0) plus a brand View (row, alignItems center, flexShrink 1, maxWidth '40%') holding Image and Text.
|
||||||
|
- Rule: View with borderBottomWidth 1.5, borderBottomColor '#A00000', marginTop ~28.
|
||||||
|
- Party and payment rows: View row with two Views at width '51%' and '49%' (or flex 1 each with gap 16).
|
||||||
|
- Table: outer View {borderLeftWidth:.75, borderTopWidth:.75, borderColor:'#000'}. Header row <View fixed style={{flexDirection:'row', backgroundColor:'#A00000'}}>. In @react-pdf/layout 5.2 splitNodes copies a fixed child into the table's continuation fragment (checked in source), so the header repeats on following pages; confirm in a render. Body rows <View wrap={false} style={{flexDirection:'row', borderBottomWidth:.75}}>; cells padding 12/9.4 with borderRightWidth .75 (white in the header).
|
||||||
|
- Bottom row: left View flex 1 (notes, amount in words); right totals View width 183, wrap={false}, same cell borders.
|
||||||
|
- Payment/Prepared-by row: wrap={false} plus minPresenceAhead so it never orphans.
|
||||||
|
- Baselines: react-pdf's renderLine draws the baseline at line top + ascent, with no half-leading. So Text top = reference baseline - 1.05 x size for Poppins.
|
||||||
|
- Emails and GSTINs: Font.registerHyphenationCallback(w => [w]) stops '-' being inserted. Tokens wider than the column still need a character-split fallback.
|
||||||
|
|
||||||
|
## Similarity to other templates
|
||||||
|
|
||||||
|
- Near-duplicate: 11.pdf ('Rimberio'). Same structure and placeholder copy: Invoice Number/Date, vendor and BILL TO columns, 4-column ruled grid with a coloured header row, NOTES/TERMS beside a ruled totals box, PAYMENT METHOD and PREPARED BY. Differences: orange accent, Inter body with a Poppins Bold title, mirrored header (name left, INVOICE right), filled Total row, corner shapes instead of the rule and footer band. Build 7 and 11 as one ruled-grid component with theme props (accent, fontFamily, headerMirror, totalRowFill, decoration set).
|
||||||
|
- Weaker resemblance: 2.pdf (ruled grid with a yellow header and a ruled total cell).
|
||||||
|
- None of 7/8/9 resembles the in-app InvoiceDocument.tsx (IBM Plex, hairline rules, title-left/meta-right). The closest in the set is 3.pdf. Not similar to format.pdf (identical to 4.pdf).
|
||||||
Vendored
+142
@@ -0,0 +1,142 @@
|
|||||||
|
# Template 8: Cobalt Stripe (`cobalt-stripe`)
|
||||||
|
|
||||||
|
Source: `templates/reference/8.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
|
||||||
|
|
||||||
|
Friendly cobalt-blue business style. Swoosh logo and bold name on the left, a large cobalt INVOICE on the right, and a grey rule with sky-blue accent ends. A cobalt header bar sits over light-blue zebra rows. Cobalt label bars mark PAYMENT METHOD and GRAND TOTAL. Script signature; footer of icon contacts.
|
||||||
|
|
||||||
|
## Fonts
|
||||||
|
|
||||||
|
Families: Open Sans 400/700 for body text; Poppins 400/700 for name, title and footer; BD Script for the placeholder signature. Metrics per 1000 units: Open Sans ascent 1068.85, descent -292.97, cap 714; Poppins 1050/-350.
|
||||||
|
- Poppins Bold: vendor name 17.38pt #1B1B1B, tracking -0.49pt (-0.028em). 'INVOICE' 31.45pt #3871C1, tracking +1.35pt (+0.043em).
|
||||||
|
- Poppins Regular: footer contact text 10pt #1B1B1B.
|
||||||
|
- Open Sans Regular: tagline 10pt uppercase #1B1B1B; website text beside the header rule 10pt uppercase #000000; 'Invoice to :' 11pt; client contact lines 10pt #595A5A; date 12pt; table body 10pt; 'Sub Total :'/'Tax 15% :' and their values 11pt; bank lines 11pt; terms body 10pt #595A5A.
|
||||||
|
- Open Sans Bold: client name 15pt; 'Invoice no : 12345' 12pt; table header 11pt #FFFFFF uppercase; bar labels and values 11pt #FFFFFF; 'Thank you for business with us!' 11pt; 'Term and Conditions :' 11pt; signer name 13pt; signer title 11pt.
|
||||||
|
- BD Script Regular: signature 25pt #1B1B1B. Licensed by reference, so do not bundle it; this slot becomes the signature image.
|
||||||
|
- Pitches: name to tagline baseline 15.66. Client contact lines 10pt at ~19pt (lineHeight ~1.9, airy). Right-hand meta 19.2. Bank lines 11pt at 15.76 (1.43). Terms 10pt at 14.25 (1.425). Table rows 17.82. Totals rows 20.76.
|
||||||
|
- All other tracking is ~0.
|
||||||
|
|
||||||
|
## Colours
|
||||||
|
|
||||||
|
Exact fill operators:
|
||||||
|
- #3871C1 (0.2196 0.4431 0.7569), cobalt: INVOICE, table header bar, PAYMENT METHOD bar, GRAND TOTAL bar, middle logo swoosh.
|
||||||
|
- #BEDEF1 (0.7451 0.8706 0.9451), light blue: even zebra rows and the 1.5pt column separators.
|
||||||
|
- #51ADE5 (0.3176 0.6784 0.898), sky: 3pt rule accents, footer icons, one logo swoosh.
|
||||||
|
- #2C3892 (0.1725 0.2196 0.5725), navy: logo swoosh only.
|
||||||
|
- #1B1B1B (0.1059 grey), near-black: primary text.
|
||||||
|
- #595A5A (0.349 0.3529 0.3529): secondary text (client contact lines, terms body).
|
||||||
|
- #A6A6A6 (0.651 grey): 1.5pt grey rules.
|
||||||
|
- #000000: website text beside the header rule.
|
||||||
|
- #FFFFFF: page background, odd rows, text on bars.
|
||||||
|
No transparency.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
A4, y measured from the top. Content x 59.55-535.95 (476.4 wide).
|
||||||
|
| Region | Geometry (pt) |
|
||||||
|
|---|---|
|
||||||
|
| Logo | x 59.5-93.8, y 59.5-93.7 (34x34) |
|
||||||
|
| Vendor name | x 102.25 (8.5 right of logo), baseline 74.56 |
|
||||||
|
| Tagline | x 102.25, baseline 90.22 |
|
||||||
|
| INVOICE | right-aligned to 535.94, baseline 87.26 (starts at x 395.65; cap top ~65.1) |
|
||||||
|
| Header rule | y 113.77: grey 1.5pt round-cap line x 60.3-414.9, with a sky 3pt accent x 61.0-96.7 over its left end |
|
||||||
|
| Rule text | right-aligned to 535.94, baseline 117.07 (vertically centred on the rule), starts at 425.85 (11pt after the rule ends) |
|
||||||
|
| Bill-to (left) | 'Invoice to :' baseline 173.83; name 195.91; lines 219.92/239.49/257.94 |
|
||||||
|
| Meta (right) | 'Invoice no : ...' baseline 175.18; date 194.41; right edge 535.94 |
|
||||||
|
| Table | header bar 292.18-312.95; rows 312.95-455.54 (8 x 17.82) |
|
||||||
|
| Sub/Tax | baselines 477.03/497.79; labels' right edge 417.36; values' right edge 532.82 |
|
||||||
|
| Bars | y 514.00-534.76: PAYMENT METHOD x 59.46-193.28; GRAND TOTAL x 321.46-535.98 |
|
||||||
|
| Bank lines | x 60.95, baselines 561.79/577.55 |
|
||||||
|
| Divider | y ~600.5, x 60.2-236.8, grey 1.5 round caps (drawn with a 0.75pt slope; treat as horizontal) |
|
||||||
|
| Thank-you | x 60.95, baseline 624.52 |
|
||||||
|
| Terms | heading baseline 666.91; body 684.63/698.88/713.14/727.39; box ~185 wide |
|
||||||
|
| Signature (right) | script baseline 688.52; name 710.57; title 728.14; right edge 530.45 |
|
||||||
|
| Footer rule | y 747.02: grey 1.5 x 74.9-520.6; sky 3pt accents x 61.05-96.75 and 498.75-534.45 |
|
||||||
|
| Footer contacts | icons y ~760-783 at x 59.55 (phone 21x21), 186.57 (mail 21x16), 376.15 (pin 18x23); text baseline 774.49 at x 85.17/212.41/398.09 |
|
||||||
|
Whitespace below the footer is ~59.6, equal to the side margin. Gaps: header rule to 'Invoice to' cap top 52.2; last client line to table 34.2.
|
||||||
|
|
||||||
|
## Items table
|
||||||
|
|
||||||
|
5 columns across the full content width 59.55-535.95. Boundaries at x 59.55 | 84.42 | 256.25 | 341.19 | 446.62 | 535.95, giving NO 24.9 (5.2%), DESCRIPTION 171.8 (36.1%), QTY 84.9 (17.8%), PRICE 105.4 (22.1%), TOTAL 89.3 (18.8%).
|
||||||
|
- Header bar: #3871C1, 20.76 tall, no border. Open Sans Bold 11 #FFFFFF uppercase. NO, DESCRIPTION, QTY and TOTAL centred; PRICE right-aligned to ~415 so it lines up with the price values.
|
||||||
|
- Body rows: 17.82 tall, single line. Zebra: odd rows #FFFFFF, even rows #BEDEF1. No horizontal rules and no outer border. Vertical separators 1.5pt #BEDEF1 at the 4 inner boundaries (visible only on white rows).
|
||||||
|
- Body text Open Sans Regular 10 #1B1B1B. NO centred. Description left-aligned at 91.23 (6.8 inset). QTY centred (~298.5). PRICE right-aligned at 414.9, which is 31.7 short of the column edge. TOTAL right-aligned at 532.82 (3.1 inset).
|
||||||
|
- Vertical: baseline is 12.29 below the row top. The react-pdf natural line is 13.6 at 10pt, so paddingTop ~1.6 and paddingBottom ~2.6. For wrapping text use paddingVertical 3 with minHeight 17.82.
|
||||||
|
- Recommendation: right-align PRICE and TOTAL with an even 6-8pt inset. Set the zebra colour as a row backgroundColor by index. Draw separators as cell borderRight, not absolute lines, so they grow with wrapped rows.
|
||||||
|
|
||||||
|
## Totals and payment
|
||||||
|
|
||||||
|
- Sub-totals (right side, no box): 'Sub Total :' and 'Tax 15% :' in Open Sans 11 #1B1B1B. Labels' right edge 417.36, values' right edge 532.82, pitch 20.76.
|
||||||
|
- GRAND TOTAL bar: #3871C1, x 321.46-535.98 (214.5 wide = 45% of content), 20.76 tall. Label Open Sans Bold 11 white, right-aligned to 417.36 (starts at 333.33). Value bold white, right-aligned at 532.82. Reference sets the value baseline 1.2pt higher; use one baseline.
|
||||||
|
- PAYMENT METHOD bar: #3871C1, x 59.46-193.28 (133.8 wide), same row as GRAND TOTAL. Bold white label at x 60.95 (only 1.5 inset; use ~6). Bank lines below: 'Bank Name : ...' and 'Account Number : ...' in Open Sans 11.
|
||||||
|
- Grey divider (176.6 long), then 'Thank you for business with us!' bold 11.
|
||||||
|
- 'Term and Conditions :' bold 11, then the grey 10pt body.
|
||||||
|
- Signature block right-aligned at 530.45: BD Script 25 signature, Open Sans Bold 13 name, Bold 11 title.
|
||||||
|
- Footer: rule with sky accent ends, then 3 icon-and-text contact items.
|
||||||
|
- Missing from the template: amount in words, due date, GST/PAN, page number.
|
||||||
|
|
||||||
|
## Decoration and images
|
||||||
|
|
||||||
|
No raster XObjects. Everything is vector shapes plus live text.
|
||||||
|
- Placeholder logo: 3 bezier swooshes (#2C3892, #3871C1, #51ADE5) plus 2 tiny #1B1B1B specks, 34x34. Replace with a vendor logo Image.
|
||||||
|
- Rules: grey 1.5pt round-cap lines with sky 3pt round-cap accent segments 35.7 long, at the left end (header) and at both ends (footer).
|
||||||
|
- Bars: plain cobalt rectangles (table header, PAYMENT METHOD, GRAND TOTAL).
|
||||||
|
- Zebra rectangles and 1.5pt light-blue vertical separators.
|
||||||
|
- Icons: outline-style phone (with signal arcs), envelope and map pin, #51ADE5, 16-23pt. Render with react-pdf <Svg><Path/></Svg>. Copy the path data of Carbon 'Phone', 'Email' and 'Location' (32px viewBox) from @carbon/icons-react, which is already a dependency, and draw them at 14-16pt.
|
||||||
|
- Many invisible (ca=0) rectangles tagged 'Image' are accessibility tags. Ignore them.
|
||||||
|
|
||||||
|
## Mapping to Voiced fields
|
||||||
|
|
||||||
|
- Logo: vendor logo (height <= 34-40, width <= 120, contain).
|
||||||
|
- Vendor name: vendorName (Poppins Bold 17.4, tracking -0.5).
|
||||||
|
- Tagline 'CREATIVE AGENCY': 'GSTIN {vendorGstin}' in Open Sans 10 uppercase.
|
||||||
|
- 'INVOICE': 'TAX INVOICE' or 'INVOICE'.
|
||||||
|
- Rule text 'REALLYGREATSITE.COM': 'PAN {vendorPan}' or vendorEmail in uppercase (Voiced has no website field).
|
||||||
|
- 'Invoice to :' becomes 'Billed to :'. Name: clientName (bold 15). Grey lines: clientAddress (wrapping), 'GSTIN {clientGstin}', 'Place of supply: {state} ({code})'.
|
||||||
|
- Right-hand meta: 'Invoice no : {number}' and invoiceDate, NEW 'Due date : {dueDate}' (12pt, 19.2 pitch), optional 'PO : {poNumber}'.
|
||||||
|
- Table: NO = row index; DESCRIPTION = description; QTY = quantity (with unit in rate mode); PRICE = rate (e.g. '/hr'); TOTAL = amount. HSN/SAC (no slot): split the 84.9-wide QTY column into HSN/SAC ~50 + QTY ~35, or use a grey sub-line under the description.
|
||||||
|
- Sub/Tax rows: Subtotal, Discount, then CGST x% and SGST x%, or IGST x%.
|
||||||
|
- GRAND TOTAL bar: total.
|
||||||
|
- Amount in words (no slot): 1-2 right-aligned lines directly under the GRAND TOTAL bar, Open Sans 9.5 #595A5A, 214.5 wide.
|
||||||
|
- PAYMENT METHOD bar and lines: bank fields Bank Name, Account Name, Account No, IFSC, Branch, UPI.
|
||||||
|
- Thank-you line: keep it static, or make it configurable.
|
||||||
|
- Terms: notes, plus 'Payment due within {paymentTermsDays} days'.
|
||||||
|
- Signature: the script text becomes the signature Image (height <= 36, right-aligned). Name = vendorName. Title = 'Authorised Signatory'. With no signature, show 'Computer-generated invoice; no signature required.' in Open Sans 9 #595A5A, right-aligned.
|
||||||
|
- Footer: phone = vendorPhone; email = vendorEmail; address = vendorAddress (short form, or 2 lines).
|
||||||
|
|
||||||
|
## Overflow risks
|
||||||
|
|
||||||
|
- Header (same class as the reported overlap bug): the name starts at 102.25 and the right-aligned INVOICE starts at 395.65, leaving ~290pt (~20 chars at 17.4pt). 'TAX INVOICE' is ~230pt wide and starts at ~306, leaving ~200pt (~14 chars). Use a flex row: brand View flex 1 with minWidth 0 so it wraps, title flexShrink 0, gap >= 16.
|
||||||
|
- The header rule has a fixed length of 354.6. Rule text wider than ~110pt (e.g. 'GSTIN 19ABCDE1234F1Z5' is ~115pt) collides. Make the rule a flex 1 View and the text flexShrink 0 with marginLeft 11.
|
||||||
|
- The bill-to and meta columns have no explicit widths; use 55% left and 45% right. Long client addresses wrap at 10pt, and the ~19pt pitch uses height quickly, so use a 14-15 pitch for addresses.
|
||||||
|
- Table rows are drawn single-line at 17.82. Wrapped descriptions make rows taller, so zebra colours and separators must be per-row and per-cell styles.
|
||||||
|
- TOTAL column inner width is ~83pt. '₹12,34,567.00' at 10pt Open Sans is ~65pt and fits; amounts in crores (~85pt) are borderline. PRICE column is fine.
|
||||||
|
- On A4 the bottom area is laid out by fixed positions: bank 561-578, divider 600, thank-you 625, terms 667-727, signature 670-728, footer rule 747. Six bank lines (+63pt) or long notes push into the footer, so the content must flow above a fixed footer.
|
||||||
|
- The footer address slot is only ~138pt (398 to 536) at 10pt, ~27 chars. Indian addresses will overflow. Use a flex row with space-between, the address item flex 1 and maxLines 2.
|
||||||
|
- More than ~20 items spill to page 2, which must repeat the header bar.
|
||||||
|
|
||||||
|
## US Letter adaptation
|
||||||
|
|
||||||
|
- Letter: content width = 612 - 2M (492.9 at M = 59.55). The description column takes the extra 16.5 (flex). Bars keep their proportions (PAYMENT 28%, GRAND TOTAL 45%) or keep fixed widths anchored left/right.
|
||||||
|
- Height is 50.25 shorter. The footer (rule 95pt above the bottom, plus contacts) stays anchored to the bottom (rule at y 697 on Letter). To recover ~50pt: header rule to 'Invoice to' cap top 52 -> 36; client line pitch 19 -> 15; client block to table 34 -> 24; bank to divider 22 -> 14; thank-you to terms 42 -> 28.
|
||||||
|
- Configurable margins: top = logo top (59.5 by default, = M). The footer block's bottom offset = M. Rules span the content width; accent segments stay 35.7.
|
||||||
|
|
||||||
|
## react-pdf notes
|
||||||
|
|
||||||
|
- Register Poppins 400/700 and Open Sans 400/700 as static TTFs. Set the page fontFamily to 'Open Sans'.
|
||||||
|
- Page: paddingTop M, paddingBottom ~110 (room for the footer), paddingHorizontal M.
|
||||||
|
- Header: View row, alignItems center: [Image 34x34] [View marginLeft 8.5, flex 1, minWidth 0, containing the name Text and tagline Text] [Text INVOICE, flexShrink 0, textAlign right, letterSpacing 1.35, marginRight -1.35].
|
||||||
|
- Rule row: View row, alignItems center. Rule = View flex 1, height 1.5, bg #A6A6A6, borderRadius .75, containing an absolute accent child (left 0, top -0.75, width 35.7, height 3, bg #51ADE5, borderRadius 1.5). Absolute positioning is fine here because it is decoration inside a relative box. Then the Text with marginLeft 11.
|
||||||
|
- Table: header row <View fixed style={{flexDirection:'row', backgroundColor:'#3871C1', height:20.76, alignItems:'center'}}>. Body rows <View wrap={false} style={{flexDirection:'row', minHeight:17.82, alignItems:'center', backgroundColor: i%2 ? '#BEDEF1' : '#FFFFFF'}}>. Cells use % widths with borderRightWidth 1.5 and borderRightColor '#BEDEF1' (except the last cell).
|
||||||
|
- Totals: View alignSelf flex-end, width 214.5. Label/value rows use row + space-between. GRAND TOTAL bar is a View of the same width, bg #3871C1, paddingHorizontal 12/3.
|
||||||
|
- Bars and bottom area: use two columns that flow independently. Left column flex 1: PAYMENT bar (width 133.8), bank lines, divider, thank-you, terms. Right column width 214.5: GRAND TOTAL bar, amount in words, then the signature (alignItems flex-end, wrap={false}).
|
||||||
|
- Footer: <View fixed style={{position:'absolute', left:M, right:M, bottom:M}}> holding the rule (accents at both ends) and a row of 3 items (Svg icon 14pt + Poppins 10 Text).
|
||||||
|
- Baselines: Text top = baseline - 1.069 x size for Open Sans, baseline - 1.05 x size for Poppins.
|
||||||
|
- Right-aligned tracked text: textkit 7.0.1 also adds letterSpacing after the last glyph, so add marginRight equal to minus the letterSpacing.
|
||||||
|
|
||||||
|
## Similarity to other templates
|
||||||
|
|
||||||
|
- No near-duplicate in the set. It is the only template with cobalt bars, zebra rows and a swoosh logo. It shares the 'Studio Shodwe' placeholder copy with 7 and 11, but the layout is unrelated.
|
||||||
|
- Shared-component candidate: the icon contact footer (phone/email/address) also appears in 2, 9 (circled icons) and 12/13. The zebra rows loosely echo 1 (grey zebra) and 12/13 (pill rows).
|
||||||
|
- Does not resemble the in-app InvoiceDocument.tsx (closest in the set is 3.pdf), or format.pdf / 4.pdf.
|
||||||
Vendored
+130
@@ -0,0 +1,130 @@
|
|||||||
|
# Template 9: Slate Band (`slate-band`)
|
||||||
|
|
||||||
|
Source: `templates/reference/9.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
|
||||||
|
|
||||||
|
Modern geometric. A full-bleed slate top band (white logo, name, invoice number) sits over an ocean-blue band with a widely letter-spaced white INVOICE. Montserrat throughout; airy rows separated by soft grey rules; letter-spaced TOTAL with a blue dash; footer of circled icons.
|
||||||
|
|
||||||
|
## Fonts
|
||||||
|
|
||||||
|
One family: Montserrat, static weights 400/500/700/800. Metrics per 1000 units: ascent 968, descent -251, cap 700.
|
||||||
|
- ExtraBold 800: 'INVOICE' 30pt #FDFCFD, tracking +6.71pt (0.224em). Labels 'Date:', 'Billed to:', 'From:' 12pt #2D3743. 'Payment method:' and 'Note:' 12pt #4D5869.
|
||||||
|
- Bold 700: table header labels 14pt #4D5869 uppercase, tracking +2.24 to 2.40pt (~0.165em). 'TOTAL' 14pt with tracking 2.24; its value 14pt with tracking ~0.58 (0.04em).
|
||||||
|
- Medium 500: vendor name in the band, 12pt #FFFFFF, tracking ~-0.2.
|
||||||
|
- Regular 400: invoice number 12pt #FFFFFF (tracking 0.27, 0.022em). Date value 13pt #2A2A2A (0.61, 0.047em). Party lines 12pt #2D3743 (~0.28, 0.023em). Table body 12.03pt #4D5869 (~0.3, 0.025em). Payment and note values 12pt #4D5869 (~0.25). Footer contacts 10pt #4D5869 (-0.2, -0.02em).
|
||||||
|
- Pitches: party lines 16.5 (lineHeight 1.375). Heading to first line 21.26. Date row to party headings 23.1. Payment to note 21.6.
|
||||||
|
- Montserrat 9.0 is installed locally as 18 static TTFs in ~/.local/share/fonts. fc-list ':charset=20b9' confirms all of them include ₹.
|
||||||
|
|
||||||
|
## Colours
|
||||||
|
|
||||||
|
Exact fill operators:
|
||||||
|
- #4D5869 (0.302 0.3451 0.4118), slate: top band; table header labels, body, totals, payment/note and footer text.
|
||||||
|
- #0278B2 (0.0078 0.4706 0.698), ocean blue: INVOICE band, 3pt total dash, footer icons.
|
||||||
|
- #FDFCFD (0.9922 0.9882 0.9922): page background (drawn over #FFFFFF) and the INVOICE text.
|
||||||
|
- #FFFFFF: logo mark, vendor name, invoice number.
|
||||||
|
- #54AFE6 (0.3294 0.6863 0.902): logo dot only.
|
||||||
|
- #2D3743 (0.1765 0.2157 0.2627): Date/Billed to/From labels and party text.
|
||||||
|
- #2A2A2A: date value.
|
||||||
|
- #DEE2E5 drawn in a transparency-group XObject at ca 0.5 (/G5 set before Do; the inner /G3 ca 1 does not cancel it). Flattened on #FDFCFD it is #EEEFF1. Used for the table header band.
|
||||||
|
- #8B95A4 drawn in groups at ca 0.53 (/G8). Flattened it is #C1C5CE. Used for the 2.25pt row rules and the footer rule.
|
||||||
|
In react-pdf use the flattened hex values, or opacity on the View.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
A4, y measured from the top. Content x 59.55-535.94. The table content is inset to 69.4-525.95 (9.8 inset).
|
||||||
|
| Region | Geometry (pt) |
|
||||||
|
|---|---|
|
||||||
|
| Slate band | full bleed, y 0-103.52 (#4D5869; drawn down to 111.46 underneath the blue band) |
|
||||||
|
| Logo | x 59.55-84.60, y 55.85-86.98 (25x31): white curved mark + 5.67pt #54AFE6 dot |
|
||||||
|
| Vendor name | x 92.36 (7.8 right of logo), baseline 74.42 |
|
||||||
|
| Invoice number | 'NO. 000001' right-aligned to 535.94, baseline 74.80 |
|
||||||
|
| Blue band | full bleed, y 103.52-157.35 (53.83 tall) |
|
||||||
|
| INVOICE | x 59.55, baseline 139.07 (cap centre ~128.6; band centre 130.4) |
|
||||||
|
| Date row | 'Date:' x 59.55, baseline 193.46 (= band bottom + 36.1); value x 109.16, baseline 193.56 |
|
||||||
|
| Parties | Billed to at x 59.55, From at x 341.96 (59.3% split). Headings baseline 216.57; lines 237.83/254.34/270.84 |
|
||||||
|
| Table header band | full bleed, y 302.07-360.41 (58.34 tall); labels baseline 337.32 |
|
||||||
|
| Rows | baselines 394.00/446.02/498.54/552.66/605.17. 2.25pt rules at 415.24/469.26/521.78/575.89/628.41, x 69.0-525.2 |
|
||||||
|
| Total row | dash x 69.66-111.51 at y 668.50 (3pt). 'TOTAL' at x 371.94; value right-aligned to 525.95; baseline 670.00 |
|
||||||
|
| Payment / Note | x 69.37, baselines 704.44 / 726.02; values inline at x 196.58 / 113.84 |
|
||||||
|
| Footer rule | y 755.58, x 59.04-536.46, 2.25pt |
|
||||||
|
| Footer contacts | ring icons ~19pt at x 69.66/198.30/366.13 (y 771.2-790.4); text baseline 783.81 at x 94.69/223.34/391.41 |
|
||||||
|
Whitespace below the icons is ~52pt. The footer rule is 86.7 above the page bottom.
|
||||||
|
|
||||||
|
## Items table
|
||||||
|
|
||||||
|
4 columns inside the inset box 69.4-525.95 (456.5 wide). Approximate column spans: SERVICE 69.4-270 (44%); QTY 270-350 (17.5%, centre 309.4); PRICE 350-452 (22.3%, centre ~401); TOTAL 452-525.95 (16.2%, right edge).
|
||||||
|
- Header: full-bleed band #DEE2E5 at 50% (~#EEEFF1), 58.34 tall. Montserrat Bold 14 #4D5869 uppercase, tracking ~2.3. SERVICE left-aligned at 69.37, QTY and PRICE centred, TOTAL right-aligned at 525.95. Baseline is 35.25 below the band top and the natural line is 17.1, so react-pdf paddingVertical ~20.
|
||||||
|
- Body: no fill. Montserrat Regular 12.03 #4D5869, tracking 0.3. Each row is ~52.5-54 tall and ends in a 2.25pt rule #C1C5CE (butt caps) spanning the inset box. Text baseline is ~29.3-30.9 below the previous rule and ~21-23 above the next, so paddingTop ~18.4 and paddingBottom ~19-20 (natural line 14.7).
|
||||||
|
- Alignment as drawn: service left (reference jitter between 69.0 and 71.7; use 69.4), qty centred, price centred (right edges drift between 418, 420 and 422), total right.
|
||||||
|
- Recommendation: right-align PRICE and TOTAL. Offer a compact density (rows 30-34), because the default 52.5 fits only 5 rows on page 1.
|
||||||
|
|
||||||
|
## Totals and payment
|
||||||
|
|
||||||
|
- There is only a TOTAL row, with no subtotal or tax rows. A 3pt #0278B2 dash, 41.85 long, at the left (x 69.66, y 668.5, level with the label baseline). 'TOTAL' Bold 14 with tracking 2.24, starting at 371.94 (centred under PRICE). Value Bold 14, right-aligned at 525.95.
|
||||||
|
- 'Payment method:' ExtraBold 12 followed inline by a Regular 12 value ('Cash'). 'Note:' followed inline by its value ('Thank you for choosing us!'). Pitch 21.6.
|
||||||
|
- Missing from the template: bank block, signature, amount in words, due date.
|
||||||
|
- Footer: full-width soft rule, then 3 circled icons (phone, globe, pin) with Montserrat 10 text.
|
||||||
|
|
||||||
|
## Decoration and images
|
||||||
|
|
||||||
|
No raster XObjects. Everything is vector shapes plus live text.
|
||||||
|
- Two full-bleed bands (slate 0-103.5, blue 103.5-157.35) and the full-bleed table header band (50% alpha group).
|
||||||
|
- Soft rules (53% alpha) and the opaque 3pt blue dash.
|
||||||
|
- Placeholder logo: white curved 'G'-like mark (14 beziers) with a light-blue dot. Replace with the vendor logo. It sits on dark slate, so it needs a light/white logo variant or a white rounded chip (padding ~4) behind it.
|
||||||
|
- Footer icons: filled rings ~18.4-19.3 in diameter and 0.6-1.5pt thick, #0278B2, each containing a ~9-10pt glyph (phone, globe, pin). Build as <Svg> with <Circle r stroke='#0278B2' strokeWidth 1.2 fill='none'/> plus <Path d={carbonIcon}/>. Swap the globe for Carbon 'Email', since Voiced has no website field.
|
||||||
|
- Invisible (ca=0) rectangles tagged 'Image' are accessibility tags. Ignore them.
|
||||||
|
|
||||||
|
## Mapping to Voiced fields
|
||||||
|
|
||||||
|
- Logo: vendor logo (height <= 31, width <= 120). Needs a light variant to show on #4D5869.
|
||||||
|
- Vendor name: vendorName (Medium 12, white).
|
||||||
|
- 'NO. 000001': 'NO. {number}'.
|
||||||
|
- 'INVOICE': 'TAX INVOICE' or 'INVOICE' (keep the 6.7 tracking).
|
||||||
|
- Date row: 'Date: {invoiceDate}', NEW 'Due: {dueDate}' on the same baseline in the right column at x 341.96.
|
||||||
|
- Billed to (left): clientName, clientAddress, 'GSTIN {clientGstin}', 'Place of supply: {state} ({code})'.
|
||||||
|
- From (right): vendorName, vendorAddress, vendorPhone, vendorEmail, 'PAN {vendorPan}', 'GSTIN {vendorGstin}'.
|
||||||
|
- Table: SERVICE = description (HSN/SAC as a grey 10pt sub-line); QTY = quantity (with unit); PRICE = rate; TOTAL = amount.
|
||||||
|
- Subtotal / Discount / CGST+SGST / IGST (no slot): right-aligned summary rows above TOTAL. Label Bold 11, tracking 1.5, #4D5869, at x ~372; value Regular 12, right-aligned at 525.95; pitch ~20.
|
||||||
|
- TOTAL: total.
|
||||||
|
- Amount in words (no slot): full-width line under the TOTAL row, 'Amount in words:' ExtraBold 11 followed by Regular 11, #4D5869.
|
||||||
|
- Payment method: label 'Payment details:' with a block of label/value lines (Bank, A/c name, A/c no, IFSC, Branch, UPI). The inline single-value pattern does not scale.
|
||||||
|
- Note: notes.
|
||||||
|
- Signature (no slot): right column beside Payment/Note (x ~372-526) with the signature Image (height <= 36), vendorName and 'Authorised signatory' (Regular 10). With no signature, the computer-generated note.
|
||||||
|
- Footer: vendorPhone, vendorEmail (envelope icon), vendorAddress.
|
||||||
|
|
||||||
|
## Overflow risks
|
||||||
|
|
||||||
|
- Slate band header: the name (12pt from 92.4) and the right-aligned number (starts at 463.7) leave ~360pt free. Still use a flex row: name flex 1, number flexShrink 0. A wordmark logo wider than ~120pt pushes the name along.
|
||||||
|
- 'TAX INVOICE' at 30pt with 6.7 tracking is ~300pt (59.6 to ~360); it fits.
|
||||||
|
- Parties: only 3 lines fit between 237.8 and the table band at 302.07. A Voiced From block is 6-8 lines (+50-80pt) and Billed to is 4-5, so the table band must flow, never sit at a fixed 302.
|
||||||
|
- The right column (341.96-536 = 194pt, ~28 chars at 12pt with tracking) wraps long emails and addresses. Emails with no break points need a character-splitting hyphenation callback.
|
||||||
|
- The TOTAL column is ~74pt. At 12pt Montserrat with 0.3 tracking, '₹1,00,000.00' is ~81pt and '₹12,34,567.00' ~91pt, so amounts overflow from 1 lakh up. Widen TOTAL to ~105 (QTY to ~55, PRICE to ~95), or set the body at 10.5pt.
|
||||||
|
- Centred prices leave ragged right edges when widths vary; right-align them.
|
||||||
|
- With 52.5pt rows, 5 rows reach the bottom of page 1. Descriptions wrap within the ~200pt column, which is fine in flow.
|
||||||
|
- Payment/Note values are inline, so long notes wrap under the label. Use a row with a fixed label width and a flex 1 value.
|
||||||
|
- The footer address slot starting at 391.4 has only ~135-145pt. Use maxLines 2 or a short address.
|
||||||
|
|
||||||
|
## US Letter adaptation
|
||||||
|
|
||||||
|
- Bands and the full-bleed table header band: left 0, right 0, width auto.
|
||||||
|
- Content: side margin M (59.55 by default); table inset M + 9.8.
|
||||||
|
- Height is 50.25 shorter. The footer rule stays anchored 86.7 above the bottom (y 705.3 on Letter). To recover ~50pt: rows 52.5 -> ~42 (saves 10 x 5), or compact rows at 34; optionally slate band 103.5 -> 90 and blue band 53.8 -> 48.
|
||||||
|
- Configurable margins: band content uses M horizontally. Date baseline = band bottom + 36. The footer's bottom offset is ~52 below the icons (about M_bottom).
|
||||||
|
|
||||||
|
## react-pdf notes
|
||||||
|
|
||||||
|
- Register Montserrat 400/500/700/800. Copy the TTFs from ~/.local/share/fonts into the app assets and the xbps; react-pdf never reads fontconfig.
|
||||||
|
- Page style {paddingTop:M, paddingHorizontal:M, paddingBottom:~100}. Bands are normal-flow (not fixed) Views with marginTop -M and marginHorizontal -M; Yoga accepts negative margins. That makes them full bleed on page 1 only, and continuation pages keep their top margin.
|
||||||
|
- Slate band: View height 103.5, bg #4D5869, row, space-between, alignItems center, paddingHorizontal M. Blue band: View height 53.8, bg #0278B2, justifyContent center, paddingHorizontal M, with Text INVOICE (letterSpacing 6.7).
|
||||||
|
- Table header band: <View fixed style={{marginHorizontal:-M, paddingHorizontal:M+9.8, height:58.3, backgroundColor:'#EEEFF1', flexDirection:'row', alignItems:'center'}}> as the first child of the table View. layout 5.2 splitNodes repeats a fixed child in the continuation fragment; confirm visually. Rows: <View wrap={false} style={{marginHorizontal:9.8, flexDirection:'row', paddingTop:18.4, paddingBottom:19.5, borderBottomWidth:2.25, borderBottomColor:'#C1C5CE'}}>.
|
||||||
|
- Total row: View row, alignItems center: dash View (width 41.85, height 3, bg #0278B2), a flex 1 spacer, the label (letterSpacing 2.24), then the value.
|
||||||
|
- Footer: <View fixed style={{position:'absolute', left:M, right:M, bottom:~52}}> holding the rule (borderTopWidth 2.25, #C1C5CE) and a row of Svg ring icons with 10pt Text.
|
||||||
|
- Baselines: Text top = baseline - 0.968 x size.
|
||||||
|
- The tracked header labels have TOTAL right-aligned, so add marginRight -2.3 (textkit 7.0.1 adds letterSpacing after the last glyph).
|
||||||
|
|
||||||
|
## Similarity to other templates
|
||||||
|
|
||||||
|
- Near-duplicate: 10.pdf ('Liceria & Co.'). The body is identical: Date / Billed to / From, the full-bleed grey SERVICE-QTY-PRICE-TOTAL band, rule-separated rows, TOTAL with an accent dash, inline Payment method / Note. The header differs: teal/grey corner swoosh artwork instead of the slate and blue bands, a dark letter-spaced INVOICE on white, and NO. in the right column. 10 also has a 'Contact:' block instead of the icon footer. Build 9 and 10 as one component with header/decoration variants.
|
||||||
|
- Shares Montserrat and letter-spaced uppercase INVOICE/headers with format.pdf (identical to 4.pdf), but the structure is different.
|
||||||
|
- Does not resemble the in-app InvoiceDocument.tsx; the closest in the set is 3.pdf.
|
||||||
Vendored
+199
@@ -0,0 +1,199 @@
|
|||||||
|
# Template 10: Teal Swoosh (`teal-swoosh`)
|
||||||
|
|
||||||
|
Source: `templates/reference/10.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
|
||||||
|
|
||||||
|
A clean corporate Montserrat layout. Headings are wide-tracked caps, the table sits on a full-bleed pale-grey band with soft row rules, and teal, gunmetal and silver swooshes fill the top-right and bottom-left corners (the two corners are 180° rotations of each other).
|
||||||
|
|
||||||
|
## Fonts
|
||||||
|
|
||||||
|
Only Montserrat is used (SIL OFL). Bundle static TTFs at weights 400, 700 and 800.
|
||||||
|
- ExtraBold 800:
|
||||||
|
- Title 'INVOICE': 30pt, letterSpacing 7.83pt (about 0.26em, reference setting 260).
|
||||||
|
- Field labels 'Date:', 'Billed to:', 'From:', 'Payment method:', 'Note:' and 'Contact:': 12pt, letterSpacing 0.30pt (0.025em).
|
||||||
|
- Bold 700:
|
||||||
|
- Table header 'SERVICE QTY PRICE TOTAL': 14pt uppercase, letterSpacing 2.8pt (0.2em).
|
||||||
|
- 'TOTAL' label: 14pt, letterSpacing 2.8.
|
||||||
|
- Total amount: 14pt, letterSpacing 0.7 (0.05em).
|
||||||
|
- Brand name: 10.75pt, no tracking.
|
||||||
|
- Regular 400:
|
||||||
|
- Party and footer lines: 12pt, letterSpacing 0.30, line pitch 16.5pt (lineHeight 1.375).
|
||||||
|
- Date value: 13pt, letterSpacing 0.65.
|
||||||
|
- Table body: 12pt (12.03), letterSpacing 0.36.
|
||||||
|
- Tagline: 7.26pt.
|
||||||
|
All text is one colour, #333132.
|
||||||
|
₹: use fontFamily ['Montserrat','IBM Plex Sans']. Montserrat's U+20B9 still needs checking. IBM Plex Sans has the glyph (confirmed with fc-list).
|
||||||
|
|
||||||
|
## Colours
|
||||||
|
|
||||||
|
- Page: #FFFFFF. All text: #333132 (charcoal).
|
||||||
|
- Accent teal #32B3C7: logo triangle, 3pt accent bar beside TOTAL, corner fills.
|
||||||
|
- Logo dark triangle: #282829.
|
||||||
|
- Table header band: #DEE2E5 at 50% opacity, which is flat #EFF1F2 on white.
|
||||||
|
- Row rules: #8B95A4 at 53% opacity, flat #C2C7CF, 2.25pt thick.
|
||||||
|
- Swoosh gunmetal: raster gradient #343233 to #747474 in diagonal metallic stripes. Approximate stops: #3F3E3F, #747474, #343233, #6A6A6A.
|
||||||
|
- Swoosh silver: raster gradient #BEBCBE to #D8D7D7 in vertical stripes. Stops: #D5D4D4, #C3C0C0, #D6D5D5, #C5C2C2, #D8D7D7, #BEBCBE.
|
||||||
|
- Teal edge shade: #333132 at 32% opacity over teal, flat ≈#328997.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
Units are pt with the origin at the top-left of the 595.5 × 842.25 page. For text, y is the **baseline**.
|
||||||
|
|
||||||
|
Margins: the header and parties run from x 59.5 to 536. The table and footer are inset further, x 69.5 to 526.
|
||||||
|
|
||||||
|
| # | Region | Position / content |
|
||||||
|
|---|---|---|
|
||||||
|
| 1 | Brand row | Logo mark 41×27 at (59.6, 59.5). Brand name Bold 10.75 at x 107, baseline 77.8. Tagline Regular 7.26, baseline 87.2 |
|
||||||
|
| 2 | Title | 'INVOICE' ExtraBold 30, letterSpacing 7.83, at x 59.5, baseline 144.0 (cap top ≈122.5), 182 wide |
|
||||||
|
| 3 | Meta row | 'Date:' ExtraBold 12 at x 59.5, baseline 193.5. Value Regular 13 at x 109.2. 'NO. 000001' Regular 12 at x 342.0, baseline 193.8 |
|
||||||
|
| 4 | Parties (2 columns) | Left column x 59.5–330 'Billed to:'. Right column x 342–536 'From:'. Labels at baseline 216.6. Three lines at 237.8 / 254.3 / 270.8 (16.5 pitch) |
|
||||||
|
| 5 | Table header band | Full bleed, x 0–595.5, y 302.1–360.4 (58.3 tall). Labels at baseline 337.3 |
|
||||||
|
| 6 | Item rows | 5 rows, 52.5–54 rule to rule. Baselines 394.0, 446.0, 498.5, 552.7, 605.2. Rules at y 415.2, 469.3, 521.8, 575.9, 628.4, spanning x 69–525 |
|
||||||
|
| 7 | Total row | Teal bar x 69.7–111.5 at y 668.5 (3pt). 'TOTAL' centred on the PRICE column (x 371.9–431.5), baseline 670.0. Amount right-aligned to 525.9 |
|
||||||
|
| 8 | Footer info | Left at x 69.4: 'Payment method:' baseline 704.4 with its value at x 196.6; 'Note:' baseline 726.0 with its value at x 113.8. Right at x 359.9: 'Contact:' baseline 704.4, then 3 lines at 723.2 / 739.7 / 756.2 |
|
||||||
|
| 9 | Decor | Top-right swoosh cluster at x ≥ 253.6, y ≤ 188.1. Bottom-left cluster at x ≤ 342, y ≥ 654.1 |
|
||||||
|
|
||||||
|
Vertical rhythm:
|
||||||
|
- Title baseline to meta: 50.
|
||||||
|
- Meta to party label: 23.
|
||||||
|
- Last party line to band: 31.
|
||||||
|
- Band bottom to first row baseline: 33.6.
|
||||||
|
- Last rule to TOTAL: 41.6.
|
||||||
|
- TOTAL to footer: 34.4.
|
||||||
|
|
||||||
|
## Items table
|
||||||
|
|
||||||
|
**Columns (A4):**
|
||||||
|
- SERVICE: left-aligned at x≈70. Reference varies between 69.0 and 71.7; normalise to 70.
|
||||||
|
- QTY: centred at ≈309.5.
|
||||||
|
- PRICE: centred at ≈400.5.
|
||||||
|
- TOTAL: right-aligned to 526. The header label's tracked right edge is also at 526.
|
||||||
|
|
||||||
|
**Header:** a full-bleed band, running edge to edge rather than just the table width. Colour #EFF1F2, 58.3 tall. Text is Montserrat Bold 14, uppercase, letterSpacing 2.8, #333132, baseline vertically centred at 337.3.
|
||||||
|
|
||||||
|
**Rows:**
|
||||||
|
- Montserrat Regular 12, letterSpacing 0.36, #333132.
|
||||||
|
- Very airy: about 53pt per row, which is ≈20pt of padding above and below a single line.
|
||||||
|
- A rule sits under every row, including the last: 2.25pt, #C2C7CF, x 69–525.
|
||||||
|
- No zebra striping, vertical lines or outer border.
|
||||||
|
|
||||||
|
**Voiced adaptation:**
|
||||||
|
- Right-align PRICE and TOTAL. A ₹ amount like '₹12,34,567.00' is about 95pt wide at 12pt.
|
||||||
|
- Suggested widths inside x 69.5–526: description flex 1 (at least 200), optional SAC column 50, QTY 50 centred, RATE 100 right, AMOUNT 100 right.
|
||||||
|
- Put the rate unit on a second line under the rate in 8.5pt.
|
||||||
|
- Body text 11pt with row padding of about 10, giving 34–38pt rows, so 10–12 items fit on page 1.
|
||||||
|
- Row heights must grow for multi-line descriptions.
|
||||||
|
|
||||||
|
## Totals and payment
|
||||||
|
|
||||||
|
**Source:**
|
||||||
|
- There is no subtotal or tax row, only TOTAL. The row has a teal 3pt accent bar at the left (x 69.7–111.5, y 668.5), a 'TOTAL' label (Bold 14, letterSpacing 2.8, centred at ≈400 over the PRICE column) and the amount (Bold 14, letterSpacing 0.7, right edge 525.9), all on baseline 670.
|
||||||
|
- The footer has 'Payment method:' with an inline value and 'Note:' with an inline value at left. Labels are ExtraBold 12, values Regular 12, with about an 8pt gap.
|
||||||
|
- At right is 'Contact:' followed by phone, email and address.
|
||||||
|
- There is no signature.
|
||||||
|
|
||||||
|
**Voiced:**
|
||||||
|
- Above TOTAL, in a right-hand block at x 345–526, add rows for SUBTOTAL, an optional DISCOUNT, then CGST @ x% plus SGST @ x%, or IGST @ x%.
|
||||||
|
- Labels: Montserrat Bold 10.5, letterSpacing 1.6, uppercase.
|
||||||
|
- Values: Regular 12, right-aligned at 526, 18–20 pitch.
|
||||||
|
- Then a 0.75pt #C2C7CF rule and the original TOTAL row, with the accent bar kept on that baseline.
|
||||||
|
- Amount in words: one line under TOTAL across x 69.5–526, Montserrat Regular 10, for example 'Amount in words: Rupees … Only'.
|
||||||
|
- Bottom-right ('Contact:' slot): bank details headed 'Payment details:'. Lines are bank, A/c name, A/c no., IFSC, branch and UPI, at 10.5pt with 15 pitch. This area stays clear of the swoosh all the way to the page bottom.
|
||||||
|
- Bottom-left: 'Note:' for notes, at most 3 lines.
|
||||||
|
- Signature or computer-generated note: place it in the right column below the bank details. Signature image up to 140×48, then the vendor name and 'Authorised signatory'.
|
||||||
|
|
||||||
|
## Decoration and images
|
||||||
|
|
||||||
|
**Raster images:** 4 Flate ICC-RGB images, each just a gradient clipped by a vector path. obj137 and obj159 are 310×282 px (gunmetal); obj140 and obj156 are 428×217 px (silver). There are no photos. All of it can be redrawn as vector with react-pdf Svg and LinearGradient.
|
||||||
|
|
||||||
|
**Bottom-left cluster.** Page pt, y down. The paths run past the page edge to y 866 and are clipped. Draw in this order:
|
||||||
|
1. Gunmetal band: `M207.7,866.4 C95.8,813.0 21.1,726.7 -25.4,654.1 L-25.4,866.4 Z`. Fill with a diagonal gradient (0,0 to 1,1): #3F3E3F at 0, #747474 at .35, #343233 at .7, #6A6A6A at 1.
|
||||||
|
2. Silver crescent (curve fit, max error 0.6pt): `M20,703 C78.8,780.4 163.7,834.8 255,866 L342,866 C220.8,849.9 100.9,796.5 20,703 Z`. Fill with a horizontal multi-stop silver gradient. It sits outside the gunmetal band with a white gap between them and is 8–15pt thick where visible.
|
||||||
|
3. Teal corner: `M132.2,866.4 L-25.4,866.4 L-25.4,672.7 C2.0,727.2 56.2,808.8 153.5,866.4 Z`, #32B3C7.
|
||||||
|
4. Teal edge shade: `M153.5,866.4 C56.2,808.8 2.0,727.2 -25.4,672.7 L-25.4,676.7 C-0.1,730.4 48.2,808.5 132.2,866.4 Z`, #333132 at fillOpacity .32.
|
||||||
|
|
||||||
|
**Top-right cluster:** the same four paths rotated 180° about the page centre, so (x, y) becomes (595.5 − x, 842.25 − y). For example:
|
||||||
|
- Gunmetal: `M387.8,-24.2 C499.7,29.2 574.4,115.5 620.9,188.1 L620.9,-24.2 Z`.
|
||||||
|
- Teal: `M463.3,-24.2 L620.9,-24.2 L620.9,169.5 C593.5,115.0 539.3,33.5 441.9,-24.2 Z`.
|
||||||
|
|
||||||
|
On-page footprints:
|
||||||
|
- Bottom-left: about x 0–236, y 690–842. At the bottom edge the gunmetal reaches x≈157 and the crescent x≈236.
|
||||||
|
- Top-right: the mirror of that.
|
||||||
|
|
||||||
|
Other elements:
|
||||||
|
- Logo mark (59.6–100.5 × 59.5–86.4): two overlapping triangles, #282829 and #32B3C7. Reference placeholder; replace with the vendor logo.
|
||||||
|
- Rules and the accent bar are plain strokes with butt caps.
|
||||||
|
|
||||||
|
## Mapping to Voiced fields
|
||||||
|
|
||||||
|
- **Logo mark** → vendor logo. Image with maxHeight 40, maxWidth 120, objectFit contain, at (59.5, ≈55).
|
||||||
|
- **'LICERIA & CO.'** → vendorName, Bold, enlarged to 12–14pt. The 'Travel Agency' tagline slot is optional: leave it empty or use a trade line.
|
||||||
|
- **'INVOICE'** → 'INVOICE', or 'TAX INVOICE' when taxType ≠ none. At 30pt with letterSpacing 7.83, 'TAX INVOICE' is about 330 wide and ends at x≈390. That fits, because the swoosh is at x ≥ 540 on the title line.
|
||||||
|
- **'Date:'** → invoiceDate. **'NO.'** → number.
|
||||||
|
- **Due date (no slot):** add a second meta line 'Due:' at baseline ≈210, with 'PO:' to its right when present. Shift everything below down by 16.5.
|
||||||
|
- **'Billed to:'** → clientName and clientAddress (multi-line). Add 'GSTIN: …' and 'Place of supply: 19 – West Bengal' (no slot) as extra lines.
|
||||||
|
- **'From:'** → vendorName, vendorAddress, vendorPhone, vendorEmail. Add 'PAN: …' and 'GSTIN: …' (no slot) as extra lines; the block grows to 6–8 lines.
|
||||||
|
- **Table** → items. Description in SERVICE, quantity in QTY (1 for fixed lines), rate plus unit in PRICE ('—' for fixed lines), amount in TOTAL.
|
||||||
|
- **HSN/SAC (no slot):** optional 50pt column, or a 9pt grey line under the description.
|
||||||
|
- **Subtotal, discount, CGST/SGST/IGST (no slot):** stacked above TOTAL.
|
||||||
|
- **Total** → the TOTAL row. **Amount in words (no slot):** under TOTAL.
|
||||||
|
- **Bank details (no slot for most lines)** → the bottom-right 'Contact:' area (bank, A/c name, A/c no., IFSC, branch, UPI); vendor phone/email are already in 'From:'.
|
||||||
|
- **'Payment method:' / 'Note:'** → notes stay bottom-left; 'Payment method:' is dropped or reduced to one inline value such as 'Bank transfer / UPI'.
|
||||||
|
- **Signature (no slot)** → right column, below the bank details.
|
||||||
|
|
||||||
|
## Overflow risks
|
||||||
|
|
||||||
|
- **Header vs top-right swoosh.** The silver crescent's inner edge crosses y 0 at x≈360, sits at x≈478–523 for y 56–88, and at x≈550–575 for y 112–139. The gunmetal band starts at x≈432 at y 0 and is at x≈505–540 for y 53–86. Keep brand-row content within x ≈440, so the vendor name is at most about 320 wide and wraps to 2 lines. Keep the title within x 520.
|
||||||
|
- **Header overlap bug.** Vendor contact details sit in 'From:', away from the title, so the address/INVOICE overlap only stays fixed if the two party columns are fixed-width flex children (270.5 and 194) that wrap.
|
||||||
|
- **'From:' column is only ~194 wide.** Long emails and addresses wrap, and with PAN/GSTIN the block is 6–8 lines. It must push the table down rather than use an absolute y.
|
||||||
|
- **Table.** The description column is about 210 wide and wraps. With 53pt rows only about 5 items fit before the totals on page 1. Centred PRICE and TOTAL collide for long ₹ values.
|
||||||
|
- **Bottom-left swoosh.**
|
||||||
|
- Content at x 69 must stay above y ≈745, at x 150 above ≈800, and at x ≥ 250 it is clear to about 835.
|
||||||
|
- The source's left footer ends at baseline 726.
|
||||||
|
- A 6-line bank block plus notes on the left would run into the crescent and gunmetal. That is why the bank block moves to the right (x ≥ 345 is clear to the bottom).
|
||||||
|
- Alternatively, give this template paddingBottom ≈110.
|
||||||
|
- **Existing app footer.** The fixed footer at bottom 24, left 40 would land on the bottom-left teal. Move its text to x ≥ 300 for this template.
|
||||||
|
- **Multi-page.** The band header must repeat on continuation pages, and both swoosh clusters must repeat (fixed).
|
||||||
|
|
||||||
|
## US Letter adaptation
|
||||||
|
|
||||||
|
US Letter is 612 × 792: 16.5pt wider and 50.25pt shorter than the source.
|
||||||
|
- **Width.** Keep margins of 59.5 (header) and 69.5 (table), so content widens to 493 and 473. Give the extra width to the description column and the right party column. The header band stays full-bleed: marginHorizontal = −page paddingX.
|
||||||
|
- **Decorations.** Anchor them to the page corners, not to A4 coordinates:
|
||||||
|
- Top-right: Svg with top 0, right 0, width 342, height 188.1, viewBox '253.5 0 342 188.1'.
|
||||||
|
- Bottom-left: Svg with left 0, bottom 0, width 342, height 188.2, viewBox '0 654.1 342 188.2'.
|
||||||
|
- Both keep their size on Letter.
|
||||||
|
- **Height.** Recover the 50pt by shrinking the band from 58 to 46, the row pitch from 53 to 40, and the title-to-meta gap from 50 to 36.
|
||||||
|
- **Configurable margins.** Map them to Page padding. This template needs a bottom margin of at least about 100 so flowing text never enters the bottom-left swoosh. Decorations ignore the margins.
|
||||||
|
|
||||||
|
## react-pdf notes
|
||||||
|
|
||||||
|
**Page:** `<Page size={'A4'|'LETTER'} style={{paddingTop:55, paddingHorizontal:59.5, paddingBottom:110, fontFamily:['Montserrat','IBM Plex Sans'], color:'#333132'}}>`.
|
||||||
|
|
||||||
|
**Decorations:** the first children are two `<Svg fixed style={{position:'absolute', …}}>` clusters. Check that react-pdf measures absolute offsets from the page edge rather than from inside the padding; the current footer relies on this. If it doesn't, offset by −padding.
|
||||||
|
|
||||||
|
**Flow, top to bottom:**
|
||||||
|
- Header: a row with Image plus a View holding name and tagline, maxWidth 370.
|
||||||
|
- Title: Text with fontWeight 800, fontSize 30, letterSpacing 7.83.
|
||||||
|
- Meta rows: justify space-between. The left cell is 282.5 wide, so the right cell starts at x 342.
|
||||||
|
- Parties: a row of two Views, 270.5 and 194 wide; Text wraps.
|
||||||
|
- Table header band: a View with marginHorizontal −59.5, paddingHorizontal 69.5, paddingVertical ≈20 and backgroundColor '#EFF1F2'. For continuation pages, repeat it with a fixed View whose render function returns it only when pageNumber > 1.
|
||||||
|
- Rows: each row a View with wrap={false}, borderBottomWidth 2.25, borderBottomColor '#C2C7CF', paddingVertical 12–20.
|
||||||
|
- Totals: a View with wrap={false} and minPresenceAhead 80.
|
||||||
|
- Footer: a row with the left part flex 1 and the right part 181 wide.
|
||||||
|
|
||||||
|
**Details:**
|
||||||
|
- react-pdf's letterSpacing adds space after every glyph, including the last. the reference design's measurements here do the same, so right-aligned tracked labels already line up.
|
||||||
|
- No raster assets are needed. Gradients go in `<Defs><LinearGradient id='gun'>…</LinearGradient></Defs>` with fill='url(#gun)'.
|
||||||
|
- Fonts: `Font.register({family:'Montserrat', fonts:[{src:'…/Montserrat-Regular.ttf', fontWeight:400}, {src:'…/Montserrat-Bold.ttf', fontWeight:700}, {src:'…/Montserrat-ExtraBold.ttf', fontWeight:800}]})`. Use static TTFs.
|
||||||
|
|
||||||
|
## Similarity to other templates
|
||||||
|
|
||||||
|
Near-duplicate of 9.pdf. Both use the same Montserrat type scale, and these elements sit in the same positions:
|
||||||
|
- Date and NO.
|
||||||
|
- Billed to and From.
|
||||||
|
- The full-bleed table band, 52.5pt rows with 2.25pt rules, and the accent bar with TOTAL.
|
||||||
|
- Payment method and Note.
|
||||||
|
|
||||||
|
9.pdf swaps the swooshes for a slate top bar (logo plus NO.), a blue full-width 'INVOICE' band and an icon contact footer. 10.pdf has a logo/brand row, swoosh corners and a 'Contact:' block. Build 9 and 10 as one layout component with a header/decor variant. Not related to format.pdf or the current IBM Plex in-app template.
|
||||||
+175
@@ -0,0 +1,175 @@
|
|||||||
|
# Template 11: Tangerine Ledger (`tangerine-ledger`)
|
||||||
|
|
||||||
|
Source: `templates/reference/11.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
|
||||||
|
|
||||||
|
A crisp business ledger with Poppins Bold display text and Inter body. The header row and total cell are filled #FF5F2F, items and totals sit in a fully ruled black 0.75pt grid, and orange pennant tabs bleed off the top-right and bottom-left edges.
|
||||||
|
|
||||||
|
## Fonts
|
||||||
|
|
||||||
|
- **Poppins Bold 700:** brand 'Rimberio' 18pt; 'INVOICE' 33pt; letterSpacing ≈0.
|
||||||
|
- **Inter SemiBold 600:**
|
||||||
|
- Section labels 12pt, caps as typed: 'STUDIO SHODWE', 'BILL TO', 'NOTES / TERMS:', 'PAYMENT METHOD:', 'PREPARED BY:'.
|
||||||
|
- Table header 11pt, white.
|
||||||
|
- **Inter Regular 400:**
|
||||||
|
- Meta and party lines 12pt, line pitch 16.5 (lineHeight 1.375). The two meta lines use a pitch of 18.7.
|
||||||
|
- Table body, totals labels and totals values 11pt.
|
||||||
|
- **Inter Bold 700:** Total row 12pt, white.
|
||||||
|
|
||||||
|
Inter text everywhere carries +0.01em tracking (0.11–0.12pt), which can be omitted.
|
||||||
|
|
||||||
|
Bundle Inter 400/600/700 and Poppins 700 as static TTFs (OFL). For ₹, Poppins is Devanagari-capable and has U+20B9; check the Inter build, and use the fallback ['Inter','IBM Plex Sans'] anyway.
|
||||||
|
|
||||||
|
## Colours
|
||||||
|
|
||||||
|
- Page: #FFFFFF. Text: #000000.
|
||||||
|
- Accent #FF5F2F: table header fill and its 0.75pt outline, Total row fill, both edge tabs.
|
||||||
|
- On accent: text #FFFFFF; column separators inside the header and Total row are #FFFFFF 0.75pt.
|
||||||
|
- Grid lines: #000000 0.75pt, for item rows and the totals box.
|
||||||
|
- A white-on-white leaf shape at 60–90 × 69–111 is an invisible reference logo placeholder. Ignore it.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
Units are pt with the origin at the top-left. For text, y is the **baseline**.
|
||||||
|
|
||||||
|
Margins: left 59.5, right 58.8, so content runs x 59.5–536.7 (477.2 wide). Top ≈60, bottom ≈62.
|
||||||
|
|
||||||
|
| # | Region | Position / content |
|
||||||
|
|---|---|---|
|
||||||
|
| 1 | Header | 'Rimberio' Poppins Bold 18 at x 59.5, baseline 84.3. 'INVOICE' Poppins Bold 33, right-aligned to 536.7 (starts x 399.4), baseline 80.6 |
|
||||||
|
| 2 | Meta | 'Invoice Number: #123456' Inter 12 at x 59.5, baseline 168.7. 'Invoice Date: 24/05/2030' at baseline 187.4 |
|
||||||
|
| 3 | Parties | Left column x 59.5–272: vendor name as label 'STUDIO SHODWE', SemiBold 12, baseline 224.7, then lines at 247.9 / 264.5 / 281.0 / 297.5. Right column x 284.1–536.7: 'BILL TO' plus lines on the same baselines |
|
||||||
|
| 4 | Items table | x 59.5–536.7. Header y 327.8–365.7 (37.9 tall). 3 rows of 37.5 (365.8 to 478.0) |
|
||||||
|
| 5 | Notes (left) | 'NOTES / TERMS:' SemiBold 12 at x 59.5, baseline 511.8. Text 12pt at 536.2 / 552.7, about 180–280 wide |
|
||||||
|
| 6 | Totals box (right) | x 353.6–536.7 (183 wide), split at x 447.6. Rows 501.3–538.9 and 538.9–576.4; Total row 576.6–615.9 |
|
||||||
|
| 7 | Bottom | 'PAYMENT METHOD:' SemiBold 12 at x 60.1, baseline 722.3, with 3 lines at 746.3 / 762.8 / 779.4. 'PREPARED BY:' at x 316.8, baseline 722.3, with 2 lines at 746.3 / 762.8 |
|
||||||
|
| 8 | Edge tabs | Top-right x 560.4–595.5 (bleeds), y 0–230.5. Bottom-left x 0–35.3, y 623.7–842.25 |
|
||||||
|
|
||||||
|
Gaps:
|
||||||
|
- Header to meta: 84.
|
||||||
|
- Parties to table: 30.
|
||||||
|
- Table to notes/totals: 23–34.
|
||||||
|
- Totals to bottom block: about 106. This is generous and can absorb the extra tax rows.
|
||||||
|
|
||||||
|
## Items table
|
||||||
|
|
||||||
|
A grid table with every cell ruled.
|
||||||
|
|
||||||
|
**Columns (A4):**
|
||||||
|
- 'Item & Description': x 59.5–308.6 (249.1 wide). Left-aligned with 9.8 padding, so text starts at x 69.3.
|
||||||
|
- 'Unit Price': 308.6–406.1 (97.5 wide). Right-aligned, text ends at 397.4.
|
||||||
|
- 'Qty': 406.1–448.2 (42.1 wide). Right-aligned, text ends at 438.5.
|
||||||
|
- 'Amount': 448.2–536.7 (88.5 wide). Right-aligned, text ends at 526.9.
|
||||||
|
|
||||||
|
**Header row:** 37.9 tall, fill #FF5F2F, Inter SemiBold 11 white, baseline vertically centred at 350.1. Vertical separators are white 0.75pt and the outline is #FF5F2F.
|
||||||
|
|
||||||
|
**Body rows:** minimum height 37.5. Inter Regular 11 #000, baseline about 21.8 below the row top (vertically centred). Black 0.75pt lines on every row and column boundary plus the outer frame. No zebra striping.
|
||||||
|
|
||||||
|
**Voiced adaptation:**
|
||||||
|
- Widen the money columns: Unit Price to at least 100, with the unit on a second line ('₹2,000.00' over 'per hour' at 8.5pt); Qty to 45; Amount to at least 100. The description column shrinks to about 232.
|
||||||
|
- Optional 'HSN/SAC' column, 50 wide.
|
||||||
|
- Use paddingVertical 11–12 instead of a fixed 37.5 height so rows grow with wrapped descriptions.
|
||||||
|
|
||||||
|
## Totals and payment
|
||||||
|
|
||||||
|
**Source:**
|
||||||
|
- The totals box is a bordered 2-column grid. 'Sub-Total' and 'Tax (6%)' rows use Inter Regular 11, with labels at x 363.3, values right-aligned to 526.9, and rows 37.5 tall.
|
||||||
|
- The Total row is filled #FF5F2F, with Inter Bold 12 white text and a white separator (39.3 tall).
|
||||||
|
- Notes sit to the left of the totals. The bottom block has 'PAYMENT METHOD:' (Bank, Account Name, Account Number) and 'PREPARED BY:' (name and title).
|
||||||
|
- There is no signature image and no footer.
|
||||||
|
|
||||||
|
**Voiced:**
|
||||||
|
- Totals rows: Sub-Total, optional Discount, CGST @ 9% plus SGST @ 9% (or IGST @ 18%), then Total in orange.
|
||||||
|
- Widen the box to about x 316–536.7, with label and value columns of 110 each, to fit ₹ strings. Use 26–30pt rows so 5 rows fit.
|
||||||
|
- Amount in words: below the box, either the box's width or across x 59.5–536.7, Inter Regular 10.
|
||||||
|
- PAYMENT METHOD: Bank, Account Name, Account Number, IFSC, Branch, UPI ID. That is 6 lines at 10.5pt with 14.5–15 pitch.
|
||||||
|
- PREPARED BY becomes the signature: an image (at most 140×48), then the vendor name and 'Authorised Signatory'. Without an image, show the vendor name and 'Computer-generated invoice; no signature required.' in Inter 9, #555.
|
||||||
|
|
||||||
|
## Decoration and images
|
||||||
|
|
||||||
|
There are no raster images; everything is vector.
|
||||||
|
|
||||||
|
**Top-right pennant tab, #FF5F2F.** The full source path is mostly off-page:
|
||||||
|
`M560.4,-6.7 L560.4,172.8 C560.4,177.7 561.9,182.5 564.7,186.5 L605.5,244.8 C606.5,246.2 608.1,247.0 609.8,247.0 C611.5,247.0 613.1,246.2 614.1,244.8 L655.0,186.5 C657.8,182.5 659.3,177.7 659.3,172.8 L659.3,-6.7 C659.3,-10.8 655.9,-14.2 651.8,-14.2 L567.9,-14.2 C563.8,-14.2 560.4,-10.8 560.4,-6.7 Z`
|
||||||
|
The visible part is a 35.1-wide strip from the top down to y≈172.8, ending in a diagonal edge that meets the page edge at y≈230.5. Simplified visible path:
|
||||||
|
`M560.4,0 H595.5 V230.5 L564.7,186.5 Q560.4,180.2 560.4,172.8 Z`
|
||||||
|
|
||||||
|
**Bottom-left pennant tab, #FF5F2F.** It points up, with its apex off-page at (−11.9, 610.9):
|
||||||
|
`M35.2,846.4 L34.5,680.1 C34.5,675.2 33.0,670.5 30.2,666.5 L-7.5,613.1 C-8.5,611.7 -10.1,610.9 -11.9,610.9 C-13.6,610.9 -15.2,611.7 -16.1,613.1 L-53.4,666.8 C-56.2,670.9 -57.7,675.6 -57.7,680.5 L-56.9,846.8 C-56.9,850.9 -53.6,854.3 -49.4,854.3 L27.8,853.9 C31.9,853.9 35.3,850.5 35.2,846.4 Z`
|
||||||
|
Simplified visible path:
|
||||||
|
`M0,623.7 L30.2,666.5 Q34.5,672.6 34.5,680.1 L35.3,842.25 H0 Z`
|
||||||
|
|
||||||
|
**Other elements:**
|
||||||
|
- Grid lines and fills are plain rectangles, drawn as View borders and backgrounds.
|
||||||
|
- The white leaf placeholder is not reproduced.
|
||||||
|
|
||||||
|
## Mapping to Voiced fields
|
||||||
|
|
||||||
|
- **'Rimberio'** → vendor logo (maxHeight 36, at x 59.5, y ≈62) with vendorName beside it in Poppins Bold 18. Use the name alone when there is no logo.
|
||||||
|
- **'INVOICE'** → INVOICE or TAX INVOICE. At 33pt, 'TAX INVOICE' is about 216 wide and spans x 320–536.7. That works as long as the brand block is capped at 240 wide.
|
||||||
|
- **'Invoice Number:'** → number. **'Invoice Date:'** → invoiceDate.
|
||||||
|
- **Due date (no slot):** a third meta line 'Due Date:' at baseline ≈206.1.
|
||||||
|
- **PO number (no slot):** a fourth line 'PO No.:' when present. Shift the parties down accordingly.
|
||||||
|
- **Left party column** (its label is the vendor name in caps) → vendorName, vendorAddress, vendorPhone, vendorEmail. Add 'PAN: …' and 'GSTIN: …' (no slot) as extra lines.
|
||||||
|
- **'BILL TO'** → clientName and clientAddress. Add 'GSTIN: …' and 'Place of supply: 19 – West Bengal' (no slot) as extra lines.
|
||||||
|
- **Table** → items: description / rate plus unit / qty / amount. Fixed-price lines show qty 1 and rate '—'.
|
||||||
|
- **HSN/SAC (no slot):** optional column.
|
||||||
|
- **Totals** → subtotal, discount, CGST/SGST/IGST and total. The tax split has no slot, so it becomes extra rows.
|
||||||
|
- **Amount in words (no slot):** under the totals box.
|
||||||
|
- **'NOTES / TERMS:'** → notes, plus 'Payment due within N days' from paymentTermsDays.
|
||||||
|
- **'PAYMENT METHOD:'** → bank details. IFSC, branch and UPI have no slot and become extra lines.
|
||||||
|
- **'PREPARED BY:'** → signature image, or the computer-generated note.
|
||||||
|
|
||||||
|
## Overflow risks
|
||||||
|
|
||||||
|
- **Header.** A logo plus a long vendor name can collide with 'INVOICE' (starts x 399) or 'TAX INVOICE' (starts x 320). Cap the brand block at about 240 and let it wrap.
|
||||||
|
- **Party columns.** The left column is only about 212 wide (59.5 to 272); the right is about 252. Long addresses and emails wrap, and 6–7 vendor lines push the table down, so this must be flow layout rather than fixed y.
|
||||||
|
- **Description cell.** 249 wide, or about 232 after widening the money columns. Rows with wrapped text grow, so use paddingVertical instead of a fixed 37.5 height.
|
||||||
|
- **Amount cells.** '₹12,34,567.00' at Inter 11 is about 78 wide; with 19.6 of padding it exceeds 88.5. Widen to at least 100. The totals value cell has the same problem: widen from 89 to at least 105.
|
||||||
|
- **Totals box.** 5 rows at 37.5 would be 188 tall; keep rows at 30 or less.
|
||||||
|
- **Bottom block.** Six bank lines at 16.5 pitch from baseline 746 end around 829, past the A4 safe area of about 806. Use 10.5pt with 14.5 pitch or a 2-column bank grid, and place the block in flow after the totals with marginTop ≥30 instead of at the fixed 722 baseline.
|
||||||
|
- **Grid across page breaks.** Each row draws its own bottom, left and right borders, and the header row repeats on continuation pages.
|
||||||
|
- **Edge tabs** never touch content:
|
||||||
|
- The right tab is at x ≥ 560.4 while content ends at 536.7 (for y ≤ 230.5).
|
||||||
|
- The left tab is at x ≤ 35.3 while content starts at 59.5 (for y ≥ 623.7).
|
||||||
|
- The app footer at left 40 clears the left tab by 4.7pt.
|
||||||
|
|
||||||
|
## US Letter adaptation
|
||||||
|
|
||||||
|
US Letter is 612 × 792.
|
||||||
|
- **Width.** Keep margins of 59.5 and 58.8, so content becomes 493.7 wide (16.5 more). Give the extra to the description column, and widen the party columns proportionally (left 220, right 262).
|
||||||
|
- **Tabs.** Anchor them to the page edges:
|
||||||
|
- Right tab: Svg with top 0, right 0, width 35.1, height 230.5.
|
||||||
|
- Left tab: left 0, bottom 0, width 35.3, height 218.6. On Letter it then starts at y ≈573.
|
||||||
|
- Both keep their size.
|
||||||
|
- **Height.** To recover the 50pt, shrink the header-to-meta gap from 84 to 60 and the totals-to-bottom gap from 106 to about 40, or let the bottom block flow.
|
||||||
|
- **Configurable margins.** Map them to Page padding. The tabs ignore margins. Enforce side margins of at least 45 so text never meets the 35pt-wide tabs.
|
||||||
|
|
||||||
|
## react-pdf notes
|
||||||
|
|
||||||
|
**Page:** padding top 60, left 59.5, right 58.8, bottom 60. fontFamily ['Inter','IBM Plex Sans'], fontSize 12, lineHeight 1.375.
|
||||||
|
|
||||||
|
**Tabs:** two `<Svg fixed style={{position:'absolute', top:0, right:0}} width={35.1} height={230.5}>` elements, using the simplified paths translated into local coordinates.
|
||||||
|
|
||||||
|
**Header:** a row with justifyContent space-between and alignItems flex-end. The two baselines (84.3 and 80.6) differ by 3.7.
|
||||||
|
|
||||||
|
**Parties:** a row of two Views, 212 and 252.6 wide, with a 12.6 gap. Labels use Inter 600.
|
||||||
|
|
||||||
|
**Table:**
|
||||||
|
- Container View: borderTopWidth 0.75, borderLeftWidth 0.75, borderColor '#000'.
|
||||||
|
- Header row: backgroundColor '#FF5F2F'; each cell has borderRightWidth 0.75 with borderColor '#FFF'.
|
||||||
|
- Body rows: wrap={false}. Each cell has borderRightWidth 0.75 and each row borderBottomWidth 0.75. Numeric cells use textAlign 'right', paddingHorizontal 9.8, paddingVertical 12.
|
||||||
|
- Continuation pages: repeat the header with `<View fixed render={({pageNumber}) => pageNumber > 1 ? <TableHeader/> : null}/>`.
|
||||||
|
|
||||||
|
**Notes and totals:** a row with notes at flex 1 and totals 220 wide, wrap={false}.
|
||||||
|
|
||||||
|
**Bottom:** a row holding payment and signature, wrap={false}, minPresenceAhead 100.
|
||||||
|
|
||||||
|
## Similarity to other templates
|
||||||
|
|
||||||
|
Near-duplicate of 7.pdf. Both carry the same 'Studio Shodwe' content and the same geometry: big INVOICE title, meta lines, vendor and BILL TO columns, a 4-column ruled grid with a filled header, a 2-column totals box, and PAYMENT METHOD / PREPARED BY.
|
||||||
|
|
||||||
|
Differences: 7.pdf uses Poppins for body text, a dark-red accent, a flame logo at top-right, a red rule under the header and a full-width red contact footer band. 11.pdf uses Inter body, #FF5F2F, brand text at left and edge tabs.
|
||||||
|
|
||||||
|
Build one 'Ledger Grid' component with an accent colour and a decor variant (tabs or footer band). Of 10–13, this is structurally closest to the current in-app template. Unrelated to format.pdf.
|
||||||
Vendored
+218
@@ -0,0 +1,218 @@
|
|||||||
|
# Template 12: Purple Pop (`purple-pop`)
|
||||||
|
|
||||||
|
Source: `templates/reference/12.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
|
||||||
|
|
||||||
|
A playful Memphis style on cream: an oversized purple 'Invoice' wordmark; purple, yellow and grey pill-shaped rows and labels; 8-arm asterisk motifs (solid purple, plus huge pale-pink watermarks); and a yellow dome shape.
|
||||||
|
|
||||||
|
## Fonts
|
||||||
|
|
||||||
|
- **Open Sauce One Bold:** the 'Invoice' wordmark only, 94pt (94.07), letterSpacing −7.44pt (−0.079em), #530895.
|
||||||
|
- **DM Sans Bold:**
|
||||||
|
- Vendor name 17.77pt.
|
||||||
|
- Amount due 32.74pt.
|
||||||
|
- Dates 14.05pt, uppercase, right-aligned.
|
||||||
|
- Table header labels 14pt, uppercase, white.
|
||||||
|
- 'PAYMENT TERMS' 13pt.
|
||||||
|
- **DM Sans Regular:** table body 11.83pt; terms bullets 11pt with 14.2 pitch.
|
||||||
|
- **Gotham Bold (commercial):**
|
||||||
|
- 'BILLED TO:' 12pt.
|
||||||
|
- Client name 14.39pt, caps.
|
||||||
|
- 'INVOICE NO : 012345' 13.39pt, letterSpacing 1.75pt (0.13em).
|
||||||
|
- 'AMOUNT DUE:' 12pt.
|
||||||
|
- SUBTOTAL, TAX and TOTAL labels and the total value, 13pt.
|
||||||
|
- 'PAYMENT METHOD' 10.52pt.
|
||||||
|
- **Gotham Book:** client lines 10.16pt (17.1 pitch); subtotal and tax values 13pt; bank lines 12pt (17.9 pitch); footer contacts 10.14pt (18.4 pitch).
|
||||||
|
|
||||||
|
**Bundling:**
|
||||||
|
- Gotham cannot be redistributed. Substitute Montserrat 400/700 (about 5% wider, so drop about 0.5pt), or use DM Sans 400/700 for all Gotham text, which needs the fewest files.
|
||||||
|
- Open Sauce One is used for one word. Its licence is reportedly OFL but needs checking; otherwise use Poppins ExtraBold or Montserrat ExtraBold at −0.08em.
|
||||||
|
- ₹: fallback ['DM Sans','IBM Plex Sans'].
|
||||||
|
|
||||||
|
## Colours
|
||||||
|
|
||||||
|
- Page background: #FEFFEE (cream).
|
||||||
|
- Primary purple #530895: wordmark, amount due, header pill, total pill, asterisks, client name text, invoice-number text.
|
||||||
|
- Yellow #FFD80B: client-name pill, every second item row, dome shape.
|
||||||
|
- Grey #E5E5E5: invoice-number pill (solid). Item rows use it at 68% opacity, which is flat #EDEDE8 on cream.
|
||||||
|
- Watermark asterisks: #FFF7F7 (pale pink).
|
||||||
|
- Text: #060605, #231F20 and #000000. On purple: #FFFFFF in the header, #FFF4F4 in the total.
|
||||||
|
- Rules #060605, 1.5pt. Icons #231F20 and #060605. Bullets #231F20.
|
||||||
|
- Reference shadow images use black, coral #FF524B and brown #413731 at 30%. Do not reproduce them.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
Units are pt with the origin at the top-left. For text, y is the **baseline**. Content spans x ≈54.8–542.8.
|
||||||
|
|
||||||
|
| # | Region | Position / content |
|
||||||
|
|---|---|---|
|
||||||
|
| 1 | Header | Vendor name DM Sans Bold 17.77 at x 59.5, baseline 98.5. INVOICE NO pill at x 312.8–530.9, y 77.0–110.2 (radius 16.6), text centred at ≈421.9, baseline 96.7 |
|
||||||
|
| 2 | Client (left, x 54.8 to ≈232) | 'BILLED TO:' at x 67.1, baseline 157.8. Yellow name pill x 54.8–201.4, y 173.8–207.0 (radius 16.6), sized to its text with 12.3 left padding; name baseline 195.2. Three lines at x 67.1, baselines 223.9 / 241.0 / 258.2 |
|
||||||
|
| 3 | Wordmark (right) | 'Invoice' 94pt, x 238.2–530.4, baseline 238.4. Glyph tops at ≈172 |
|
||||||
|
| 4 | Rule 1 | x 64.8–533.4, y 279.6, 1.5pt |
|
||||||
|
| 5 | Amount and dates | 'AMOUNT DUE:' at x 71.8, baseline 310.5. Amount 32.74pt at x 73.7, baseline 350.0. Dates right-aligned to 519.7, baselines 315.7 / 335.2 |
|
||||||
|
| 6 | Items | Block x 176.9–539.4. Header pill y 378.2–424.8 (radius 23.3). Rows 424.3–457.0, 457.0–489.7, 489.7–522.5, each a pill (radius ≈16.4). Purple asterisk 71.5 at (57.0, 397.7), to the left |
|
||||||
|
| 7 | Subtotal / Tax | Labels at x 192, baselines 545.9 / 576.7. Values right-aligned to 522.0; source baselines are 550.8 / 576.7, so normalise both to the label baseline. Yellow dome 65.3×62.3 at (57.0, 565.3), to the left |
|
||||||
|
| 8 | Total pill | x 173.4–542.8, y 594.9–635.9 (radius 20.5). 'TOTAL' at x 192, baseline 621.3. Value right-aligned to 529.1, baseline 619.6 |
|
||||||
|
| 9 | Terms row | 'PAYMENT TERMS' DM Sans Bold 13 at x 71.8, baseline 677.2. Bullets are 3.8pt dots at x 208.1–211.9 with centres at y 661.4 / 675.7; text at x 220.8, baselines 665.6 / 679.8. Purple asterisk 29.3 at (495.1, 653.2) |
|
||||||
|
| 10 | Rule 2 | x 67.4–536.0, y 703.3, 1.5pt |
|
||||||
|
| 11 | Footer (3 columns) | A at x 67.4: 'PAYMENT METHOD' baseline 732.1, bank lines at 750.8 / 768.7. B: icons at x 218.5–229.7, text at x 239.0, baselines 734.6 / 753.0. C: icons at x 380.7–392.2, text at x 414.2, baselines 733.6 / 752.0 |
|
||||||
|
| 12 | Watermarks | Pale-pink asterisks 352.4 wide at (255.5, −51.4) and (−58.0, 511.4), clipped by the page |
|
||||||
|
|
||||||
|
## Items table
|
||||||
|
|
||||||
|
**Columns (A4):**
|
||||||
|
- SERVICE: left-aligned. Header text at x 192.0, body at x 196.0, i.e. 15–19 inside the pill.
|
||||||
|
- QTY: centred at ≈354.7.
|
||||||
|
- RATE: centred at ≈421.3.
|
||||||
|
- AMOUNT: centred at ≈495.1.
|
||||||
|
- The block's right edge is 539.4.
|
||||||
|
|
||||||
|
**Header:** a #530895 pill, 46.6 tall (radius 23.3). DM Sans Bold 14, white, uppercase, baseline centred at 405.6.
|
||||||
|
|
||||||
|
**Rows:**
|
||||||
|
- Each row is its own full pill, 32.7 tall (radius ≈16.35), stacked flush.
|
||||||
|
- Fills: row 1 grey #EDEDE8 (flat), row 2 yellow #FFD80B, row 3 grey.
|
||||||
|
- Body text: DM Sans Regular 11.83 #060605, baseline about 18.1 below the row top.
|
||||||
|
- No borders.
|
||||||
|
- For N rows, alternate grey and yellow, with yellow on even rows.
|
||||||
|
|
||||||
|
**Voiced adaptation:**
|
||||||
|
- Right-align RATE and AMOUNT; the source centres them.
|
||||||
|
- Widths: qty 40, rate 90, amount 100. That leaves only about 125 for the description when the block starts at x 176.9.
|
||||||
|
- Recommend a full-width variant (x 59.5–539.4, dropping the 71.5pt asterisk) when there are more than 3 items or any description wraps.
|
||||||
|
- Multi-line rows become rounded rectangles: keep radius 16.35 and use paddingVertical 9.
|
||||||
|
|
||||||
|
## Totals and payment
|
||||||
|
|
||||||
|
**Source:**
|
||||||
|
- Totals (x 192–522, no fill): 'SUBTOTAL' and 'TAX' with values. Labels Gotham Bold 13; values Gotham Book 13, right-aligned at 522; 30.8 pitch.
|
||||||
|
- Then a purple TOTAL pill, 41 tall (radius 20.5), with #FFF4F4 text: label left at 192, value right-aligned to 529.
|
||||||
|
- AMOUNT DUE is a big purple DM Sans Bold 32.74 number at left (y 300–355).
|
||||||
|
- A terms row with bullets, and a footer with PAYMENT METHOD (bank name, account number) and contact rows with icons.
|
||||||
|
- There is no signature.
|
||||||
|
|
||||||
|
**Voiced:**
|
||||||
|
- Rows SUBTOTAL, optional DISCOUNT, then CGST x% plus SGST x% (or IGST x%), in the same label/value style with 25 pitch, then the TOTAL pill.
|
||||||
|
- Amount in words: below the pill, DM Sans Regular 10 #231F20, across x 192–529, at most 2 lines.
|
||||||
|
- AMOUNT DUE shows the total.
|
||||||
|
- PAYMENT TERMS bullets come from notes, one bullet per line, plus 'Payment due within N days.'
|
||||||
|
- PAYMENT METHOD: bank name, A/c name, A/c no., IFSC, branch and UPI, at 10–11pt with 14 pitch. Footer column A grows to about 90 tall.
|
||||||
|
- Signature (no slot): a right-aligned block above rule 2, replacing the 29pt asterisk at 495–524 × 653–682. Image up to 120×40 plus 'Authorised Signatory' in DM Sans 9, or the computer-generated note.
|
||||||
|
|
||||||
|
## Decoration and images
|
||||||
|
|
||||||
|
All vector shapes can be reproduced with react-pdf Svg.
|
||||||
|
|
||||||
|
**8-arm asterisk.** One path, used at 4 sizes, normalised to a 0–100 box:
|
||||||
|
`M100 41.7H69.9L91.1 20.6 79.7 8.9 58.3 30.1V0H41.7V30.1L20.6 8.9 8.9 20.6 30.1 41.7H0V58.3H30.1L8.9 79.4 20.6 91.1 41.7 69.9V100H58.3V69.9L79.4 91.1 91.1 79.4 69.9 58.3H100Z`
|
||||||
|
Each arm is 16.5% of the size; reference rounds the corners by about 0.2%. Instances:
|
||||||
|
- #530895, 71.5pt, at (57.0, 397.7).
|
||||||
|
- #530895, 29.3pt, at (495.1, 653.2).
|
||||||
|
- #FFF7F7, 352.4pt, at (255.5, −51.4) and at (−58.0, 511.4).
|
||||||
|
|
||||||
|
**Yellow dome/bell, #FFD80B, even-odd fill:**
|
||||||
|
`M89.7,565.3 C107.7,565.3 122.3,579.9 122.3,597.9 L103.3,597.9 C114.5,603.1 122.3,614.4 122.3,627.6 L57.0,627.6 C57.0,614.4 64.8,603.1 76.1,597.9 L57.0,597.9 C57.0,579.9 71.7,565.3 89.7,565.3 Z`
|
||||||
|
|
||||||
|
**Pills** are plain rounded rectangles with radius = height/2:
|
||||||
|
- Invoice-number pill: #E5E5E5, 218.1×33.2.
|
||||||
|
- Client-name pill: #FFD80B, 146.6×33.2.
|
||||||
|
- Header: 362.5×46.6.
|
||||||
|
- Rows: 362.5×32.7.
|
||||||
|
- Total: 369.4×41.
|
||||||
|
|
||||||
|
**Icons, about 11pt:** phone and mail are filled #231F20 circles with knocked-out glyphs; globe and map-pin are #060605 outline glyphs. Use @carbon/icons path data (Phone, Email, Earth, Location) inside Svg.
|
||||||
|
|
||||||
|
**Bullets:** 3.8pt #231F20 circles.
|
||||||
|
|
||||||
|
**Raster images.** 17 RGB images with soft masks, about 300 dpi, sizes from 125×69 to 756×69 plus 572×196 and 399×137 px. They are the reference design's 'shadow' effect (30% opacity, about 0 offset, about 1–2pt blur) under:
|
||||||
|
- BILLED TO, the client name and client lines (black).
|
||||||
|
- INVOICE NO and AMOUNT DUE (black).
|
||||||
|
- Table header labels (brown).
|
||||||
|
- Subtotal, tax and total (coral).
|
||||||
|
- Payment method and bank lines (black).
|
||||||
|
|
||||||
|
Each of these strings is also drawn a second time at opacity 0, which is why this PDF's text extracts garbled. Do not reproduce the shadows; react-pdf has no text-shadow. If wanted, fake them with a duplicate Text at opacity .3, offset 0.6pt.
|
||||||
|
|
||||||
|
## Mapping to Voiced fields
|
||||||
|
|
||||||
|
- **'Northline Group'** → vendorName, DM Sans Bold 17.77.
|
||||||
|
- **Logo (no slot):** an Image with maxHeight 34 to the left of the name at x 59.5 (the name shifts right), or replace the name when the logo is a wordmark.
|
||||||
|
- **Vendor address, phone, email, PAN, GSTIN** (no header slot):
|
||||||
|
- GSTIN and PAN as 2 small lines (DM Sans Regular 9) under the vendor name, x 59.5–300, y ≈108–135.
|
||||||
|
- Phone and email in footer column B.
|
||||||
|
- Address (at most 2 lines) and UPI in footer column C, in place of the website.
|
||||||
|
- **INVOICE NO pill** → 'INVOICE NO : {number}'. The pill sizes to its text, with its right edge fixed at 530.9.
|
||||||
|
- **'Invoice' wordmark** → keep 'Invoice'. When taxType ≠ none, add 'TAX', either in the pill ('TAX INVOICE NO : …') or as a DM Sans Bold 14 caption above the wordmark. 'Tax Invoice' at 94pt would be about 450 wide and cannot fit; auto-fit it to about 61pt if one line is required.
|
||||||
|
- **'BILLED TO:' and the yellow pill** → clientName.
|
||||||
|
- **Client lines** → clientAddress. Add 'GSTIN: …' and 'Place of supply: …' (no slot) as extra lines.
|
||||||
|
- **AMOUNT DUE** → total.
|
||||||
|
- **Dates** → 'INVOICE DATE : {invoiceDate}' and 'DUE DATE : {dueDate}' as two explicit lines. PO number (no slot): a third line 'PO : …'.
|
||||||
|
- **Table** → items. HSN/SAC (no slot): a 9pt grey second line under the description.
|
||||||
|
- **SUBTOTAL / TAX** → subtotal, CGST/SGST/IGST and discount.
|
||||||
|
- **TOTAL pill** → total. Amount in words (no slot): under the pill.
|
||||||
|
- **PAYMENT TERMS** → notes.
|
||||||
|
- **PAYMENT METHOD** → bank details. IFSC, branch and UPI have no slot and become extra lines.
|
||||||
|
- **Signature (no slot):** see totals_and_payment.
|
||||||
|
|
||||||
|
## Overflow risks
|
||||||
|
|
||||||
|
- **Vendor name vs INVOICE NO pill.** The name runs into the pill at x 312.8 (y 77–110). Cap it at about 240 wide and let it wrap; 2 lines end around y 125, still above BILLED TO at 148.
|
||||||
|
- **INVOICE NO pill.** Long series numbers grow it leftward. Keep at least 12 between it and the vendor name.
|
||||||
|
- **Client block vs wordmark.**
|
||||||
|
- The client name pill can be at most about 170 wide, because the wordmark starts at x 238.2; longer names wrap to 2 lines.
|
||||||
|
- Client lines (10.16pt) must be capped at about 165 wide beside the 94pt wordmark.
|
||||||
|
- A long address extends below the wordmark, so rule 1 must follow the taller of the client block and the wordmark in the flow.
|
||||||
|
- **AMOUNT DUE.** At 32.74pt, '₹12,34,567.00' is about 230 wide, but only about 210 is free before the right-aligned dates at x 291. Shrink it automatically (for example to 26pt when longer than 9 characters) or stack the dates under it.
|
||||||
|
- **Dates.** The source's first date line already wraps badly ('… 2030 DUE'); render it as two fixed lines.
|
||||||
|
- **Items.**
|
||||||
|
- The description column is only about 125–140 wide, so wrapping is frequent.
|
||||||
|
- More than 3–5 items push totals, terms and footer onto page 2, and the header pill must repeat there.
|
||||||
|
- **Footer.** 6 bank lines plus contacts can pass the bottom margin; the source footer ends at 772. Use 10pt text and a 2-column bank grid.
|
||||||
|
|
||||||
|
## US Letter adaptation
|
||||||
|
|
||||||
|
US Letter is 612 × 792.
|
||||||
|
- **Width.** Keep the x margins (≈55–59.5 left, ≈53 right) and widen the rules, pills and table by 16.5. Right-anchored elements (INVOICE NO pill, wordmark, dates, total pill) move right by 16.5.
|
||||||
|
- **Watermarks.** Anchor them to the corners and let the page clip them:
|
||||||
|
- Top-right: right −12.4, top −51.4.
|
||||||
|
- Bottom-left: left −58, bottom −21.5.
|
||||||
|
- **Height (−50pt).**
|
||||||
|
- Compress the 98pt gap between rule 1 and the table (the amount-due band) to about 75.
|
||||||
|
- Keep row pills at 32.7.
|
||||||
|
- Shrink the totals-to-terms gap from 40 to 24.
|
||||||
|
- Use a bottom padding of 30.
|
||||||
|
- **Configurable margins.** Map them to Page padding; pills and rows are in the flow, so they follow the margins. The asterisk and dome stay in the left gutter only when the left margin leaves at least about 115 beside the table. Otherwise switch to the full-width table variant and hide them.
|
||||||
|
|
||||||
|
## react-pdf notes
|
||||||
|
|
||||||
|
**Page:** style {backgroundColor:'#FEFFEE', paddingTop:70, paddingHorizontal:55, paddingBottom:40}. Watermarks are the first children: fixed, absolutely positioned Svgs.
|
||||||
|
|
||||||
|
**Header:** a row with space-between. The vendor block has maxWidth 240. The pill is a View with backgroundColor '#E5E5E5', borderRadius 16.6, height 33.2, paddingHorizontal 20, justifyContent center.
|
||||||
|
|
||||||
|
**Client and wordmark:** a row.
|
||||||
|
- Left: a View 175 wide holding the label, the pill (alignSelf 'flex-start', borderRadius 16.6, paddingHorizontal 12) and the lines.
|
||||||
|
- Right: Text with fontSize 94, letterSpacing −7.44, lineHeight 1, textAlign right, flex 1.
|
||||||
|
|
||||||
|
**Rules:** a View with height 1.5 and backgroundColor '#060605'.
|
||||||
|
|
||||||
|
**Items:**
|
||||||
|
- Container View with marginLeft 122, or 0 for the full-width variant.
|
||||||
|
- Header: a View with backgroundColor '#530895', borderRadius 23.3, height 46.6, flexDirection row, alignItems center, paddingHorizontal 15.
|
||||||
|
- Rows: Views with wrap={false}, borderRadius 16.35, minHeight 32.7, and backgroundColor '#FFD80B' for even rows or '#EDEDE8' for odd rows.
|
||||||
|
- Use flat colours, not opacity, because opacity also fades the text.
|
||||||
|
|
||||||
|
**Asterisks and dome:** `<Svg viewBox='0 0 100 100' width={71.5} height={71.5}><Path d=… fill='#530895'/></Svg>`, absolutely positioned inside the items/totals section wrappers, which are position relative.
|
||||||
|
|
||||||
|
**Totals:** the label/value rows, then the total pill, with wrap={false} and minPresenceAhead.
|
||||||
|
|
||||||
|
**Footer:** a row of 3 Views (A 150 wide, B 160 wide, C flex 1). Icons are 11×11 Svgs.
|
||||||
|
|
||||||
|
**Fonts:** DM Sans 400/700, Montserrat 400/700 (the Gotham substitute) and the display font at 700. Use fontFamily arrays with 'IBM Plex Sans' for ₹.
|
||||||
|
|
||||||
|
## Similarity to other templates
|
||||||
|
|
||||||
|
Sibling of 13.pdf. They are from the same reference family, with the same placeholder data ('Northline Group', 'Amy Fletcher', 'Intelligent Bank'), the same DM Sans plus Gotham type system, the same raster 30% shadow effects, and the same SERVICE/QTY/RATE/AMOUNT table with SUBTOTAL/TAX/TOTAL.
|
||||||
|
|
||||||
|
The composition is different: pills and asterisks on cream here, versus a split grey column on blush in 13. Keep both and share the data-mapping code. Not similar to 1–11, format.pdf or the in-app template.
|
||||||
Vendored
+184
@@ -0,0 +1,184 @@
|
|||||||
|
# Template 13: Citrus Split (`citrus-split`)
|
||||||
|
|
||||||
|
Source: `templates/reference/13.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
|
||||||
|
|
||||||
|
A modern split layout on blush pink: a heavy 'INVOICE' wordmark, a light-grey right column, an orange SERVICE header cell and TOTAL bar, orange labels, an icon contact list and faint orange halftone-dot chevrons.
|
||||||
|
|
||||||
|
## Fonts
|
||||||
|
|
||||||
|
- **Now Bold:** 'INVOICE' at 48pt (47.94), letterSpacing −3.89pt (−0.081em), #060605.
|
||||||
|
- **DM Sans Bold:**
|
||||||
|
- Vendor name 17.13pt in 2 lines, lineHeight 1.0.
|
||||||
|
- Meta labels 12pt #F96300: 'Invoice No :', 'Invoice Date :', 'Due Date :', 'Amount Due:'.
|
||||||
|
- Amount-due value 12.36pt.
|
||||||
|
- 'BILLED TO:' 12.4pt.
|
||||||
|
- Client name 14.87pt #F96300, caps.
|
||||||
|
- 'PAYMENT METHOD' and 'PAYMENT TERMS' 12pt #F96300.
|
||||||
|
- Tagline 13.23pt, right-aligned.
|
||||||
|
- **DM Sans Regular:** meta values 12pt.
|
||||||
|
- **Gotham Bold:** 'SERVICE' 15.17pt, white, letterSpacing 2.25pt (0.15em). 'QTY RATE AMOUNT' 14.17pt. 'SUBTOTAL', 'TAX', 'TOTAL' and the total value 14.7pt #231F20.
|
||||||
|
- **Gotham Book:**
|
||||||
|
- Item rows 12pt.
|
||||||
|
- Subtotal value 12.7pt, tax value 12.07pt.
|
||||||
|
- Client lines 10.5pt (17.75 pitch).
|
||||||
|
- Bank lines 13.77pt (21 pitch).
|
||||||
|
- Terms 12pt: 16.5 pitch within a bullet, 20.8 between bullets.
|
||||||
|
- Contact list 12.77pt, about 23–27 pitch.
|
||||||
|
|
||||||
|
**Bundling:** DM Sans 400/700 (OFL). Gotham becomes Montserrat 400/700 or DM Sans. Check the licence for 'Now' (Alfredo Marco Pradil) before shipping; otherwise substitute Montserrat ExtraBold or Black at −0.08em. ₹ falls back to IBM Plex Sans.
|
||||||
|
|
||||||
|
## Colours
|
||||||
|
|
||||||
|
- Page: #FFF7F7 (blush). Right column panel: #F1F1F1. Zebra row: #F1F1F1. Numeric header band: #FFFFFF.
|
||||||
|
- Orange fill #FF9220: SERVICE header cell, TOTAL bar, phone icon.
|
||||||
|
- Orange text #F96300: labels and client name. Icon orange: #F39322.
|
||||||
|
- Text: #060605, #231F20, and #000000 for client lines. 'SERVICE' is white on orange.
|
||||||
|
- Separator: #FFF7F7, 1.5pt, drawn over the grey panel.
|
||||||
|
- Logo placeholder: #231F20, #E63631, #FF9220.
|
||||||
|
- Halftone dots: gradient #FF9220 to #F2F2F2 (switching at 14%), at 9% opacity. On the blush page that is ≈#FFEEE4 fading to invisible.
|
||||||
|
- Reference shadow images (not reproduced): coral #FF524B and black at 30%.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
Units are pt with the origin at the top-left. For text, y is the **baseline**.
|
||||||
|
|
||||||
|
Two zones: a left column at x ≈73–298.8, and a grey right column at x 298.8–535.6 (236.8 wide, right margin 59.9).
|
||||||
|
|
||||||
|
| # | Region | Position / content |
|
||||||
|
|---|---|---|
|
||||||
|
| 1 | Grey panel | #F1F1F1 at x 298.8–535.6, from y 0 to 547.0. A second grey block at x 297.7–534.5, y 773.2–842.25 |
|
||||||
|
| 2 | Header | 'INVOICE' Now Bold 48 at x 73.3, baseline 109.7 (cap top ≈75.6). Logo 35×33 at (337.4, 74.5). Vendor name DM Sans Bold 17.13 at x 405.8, baselines 85.8 / 102.9 |
|
||||||
|
| 3 | Meta row (4 cells) | Labels at baseline ≈197: x 87.9 'Invoice No :', x 174.1 'Invoice Date :', x 315.5 'Due Date :', x 423.7 'Amount Due:'. Values at baseline ≈219 (source 217.5–222.3) at the same x |
|
||||||
|
| 4 | Table header | y 240.3–287.5 (47.2 tall). Orange cell x 84.2–298.6 with 'SERVICE' at x 115.9, baseline 269.1. White band x 298.6–536.0 with 'QTY' / 'RATE' / 'AMOUNT' centred at 347.5 / 405.8 / 479.2, baseline 269.9 |
|
||||||
|
| 5 | Rows | Pitch ≈39.3–40. Baselines ≈321, 360, 400.5. Row 2 band #F1F1F1 at x 84.0–536.0, y 337.9–377.2. Descriptions at x ≈100 |
|
||||||
|
| 6 | Separator | x 293.4–533.9, y 420.4, 1.5pt #FFF7F7 |
|
||||||
|
| 7 | Totals (in panel) | 'SUBTOTAL' at x 320.9, baseline 447.7, value right-aligned at ≈505. 'TAX' at baseline 477.7. TOTAL bar #FF9220 at x 299.8–534.4, y 496.5–543.7; 'TOTAL' at x 316.5, baseline 524.4; value right-aligned at 505.0 |
|
||||||
|
| 8 | Left column under table | 'BILLED TO:' at x 85.6, baseline 459.7. Name at baseline 483.1. Lines at 508.6 / 526.3 / 544.1. 'PAYMENT METHOD' at x 81.7, baseline 585.6. Bank lines at x 83.2, baselines 618.2 / 639.2. 'PAYMENT TERMS' at baseline 684.3. Bullet dots at x 89.2–93.0, text at x 102.1, baselines 711.2 / 732.0 / 748.5 |
|
||||||
|
| 9 | Right column under panel | Tagline right-aligned to 522.5, baselines 576.6 / 594.6. Contact list text right-aligned to 495.4, icons at x 507–524, baselines 655.7, 678.9, 705.7, 728.9 |
|
||||||
|
| 10 | Halftone chevrons | Bottom-left (−126 to 172.5 × 516 to 842), bottom-centre (142.5 to 412 × 572 to 842), top-right (477 to 595.5 × 0 to 178) |
|
||||||
|
|
||||||
|
## Items table
|
||||||
|
|
||||||
|
**Header (split):**
|
||||||
|
- The 'SERVICE' cell is filled #FF9220 (x 84.2–298.6, 47.2 tall). Text is Gotham Bold 15.17, white, letterSpacing 2.25, left at x 115.9 (inset ≈31.7).
|
||||||
|
- The numeric headers sit on a white band (x 298.6–536) in Gotham Bold 14.17 #060605.
|
||||||
|
|
||||||
|
**Body:**
|
||||||
|
- The description column (x 84–298.6) sits on the blush page, text at x ≈100 in Gotham Book 12 #060605.
|
||||||
|
- QTY, RATE and AMOUNT sit inside the grey panel, centred at 346.4 / 404.7 / 478.7.
|
||||||
|
- Rows are about 40 pitch with no borders.
|
||||||
|
- Zebra: every second row gets a #F1F1F1 band across x 84–536. It only shows on the left part, since the panel is already grey.
|
||||||
|
- After the last row, a 1.5pt #FFF7F7 separator runs across the panel.
|
||||||
|
|
||||||
|
**Voiced adaptation:**
|
||||||
|
- Right-align RATE and AMOUNT at ≈522; the source centres both the values and the AMOUNT header.
|
||||||
|
- The panel's 236.8 width splits as qty 45, rate 90, amount 100.
|
||||||
|
- Put the unit under the rate in 8.5pt.
|
||||||
|
- Descriptions wrap within 214.
|
||||||
|
- HSN/SAC goes on a 9pt grey line under the description.
|
||||||
|
|
||||||
|
## Totals and payment
|
||||||
|
|
||||||
|
**Source:**
|
||||||
|
- Totals are in the grey panel: SUBTOTAL and TAX label/value pairs. Labels Gotham Bold 14.7 at x 320.9; values Gotham Book ≈12.7, right-aligned at ≈505; 30 pitch.
|
||||||
|
- Then the orange TOTAL bar (234.6 × 47.2) with dark #231F20 text: 'TOTAL' at left (316.5) and the amount at right (505).
|
||||||
|
- Below the panel: a decorative tagline 'PROFESSIONAL SERVICES / BILLING SUMMARY.' and the icon contact list (phone, email, web, address).
|
||||||
|
- Left column: BILLED TO, PAYMENT METHOD (bank and account number), PAYMENT TERMS bullets.
|
||||||
|
- The bottom-right grey block (297.7–534.5 × 773.2–842.25) is empty.
|
||||||
|
|
||||||
|
**Voiced:**
|
||||||
|
- Rows SUBTOTAL, optional DISCOUNT, then CGST x% plus SGST x% (or IGST x%). Use 12.5pt labels and values so 4–5 rows fit. The TOTAL bar is unchanged.
|
||||||
|
- Amount in words replaces the tagline: DM Sans Bold 11, right-aligned, max width 222.
|
||||||
|
- PAYMENT METHOD: bank name, A/c name, A/c no., IFSC, branch, UPI. Use 11pt with 15 pitch instead of 13.77 with 21.
|
||||||
|
- PAYMENT TERMS come from notes.
|
||||||
|
- Signature goes in the bottom-right grey block: image up to 150×40 plus 'Authorised Signatory' in DM Sans 9, or the computer-generated note.
|
||||||
|
|
||||||
|
## Decoration and images
|
||||||
|
|
||||||
|
**Plain rectangles:** the grey column panel and the bottom grey block.
|
||||||
|
|
||||||
|
**Logo placeholder:** 3 arcs (a #231F20 crescent and #E63631 and #FF9220 arcs), 35×33 at (337.4, 74.5). Replace with the vendor logo.
|
||||||
|
|
||||||
|
**Contact icons** (orange, about 14–17pt, right of the text at x 507–524), drawn with Carbon icon paths in Svg:
|
||||||
|
- Phone: solid #FF9220 disc with a knocked-out handset, 15.5pt.
|
||||||
|
- Email: ring plus envelope, #F39322, 17pt.
|
||||||
|
- Web: globe glyph, 14.3pt.
|
||||||
|
- Address: ring plus pin, 13.9pt.
|
||||||
|
|
||||||
|
**Bullets:** 3.8pt #060605 dots.
|
||||||
|
|
||||||
|
**Halftone chevrons:**
|
||||||
|
- Each field is 76 circles on a staggered lattice: 19 rows of 4 dots, with rows shifting diagonally to form a '>' chevron.
|
||||||
|
- Diameters grow from 9.8 to 22.5 local units towards the middle row, then shrink again.
|
||||||
|
- Scale per field:
|
||||||
|
- Bottom-left: 0.842 pt per unit; row pitch 19, in-row spacing 38, diameters 8.3–19.
|
||||||
|
- Bottom-centre: 0.761 pt per unit; diameters 7.5–17.
|
||||||
|
- Top-right: 0.478 pt per unit, rotated 180°; diameters 4.7–10.8.
|
||||||
|
- Fill is a linear gradient #FF9220 to #F2F2F2 at opacity 0.09.
|
||||||
|
- Optional decoration: draw 228 Svg Circles, or omit.
|
||||||
|
|
||||||
|
**Raster images:** 15 RGB images with soft masks (141×77 to 590×202 px). They are the reference design's shadow effect: coral under the header labels and totals, black under the client and bank text. Do not reproduce them; the same strings also have an invisible duplicate text copy underneath.
|
||||||
|
|
||||||
|
## Mapping to Voiced fields
|
||||||
|
|
||||||
|
- **Logo slot** (35×33; allow up to 60×40) → vendor logo.
|
||||||
|
- **Vendor name** → 2-line DM Sans Bold 17.13 at x 405.8, at most 130 wide.
|
||||||
|
- **'INVOICE'** → INVOICE. For TAX INVOICE, 48pt would need about 300, but only 225 is free before the panel. Either stack a DM Sans Bold 14 #F96300 'TAX' above it, or auto-fit to about 34pt.
|
||||||
|
- **Meta row** → number, invoiceDate, dueDate, and total as Amount Due.
|
||||||
|
- **PO (no slot):** under the meta row on the left, or under BILLED TO.
|
||||||
|
- **BILLED TO block** → clientName and clientAddress. Add 'GSTIN' and 'Place of supply' (no slot) as extra lines. Recommend moving the block above the table, as a band at y ≈230, so it stays on page 1.
|
||||||
|
- **Contact list** (right, with icons) → vendorPhone and vendorEmail. Add vendorAddress, right-aligned and multi-line. GSTIN/PAN (otherwise no slot) replace the web line, or go under the vendor name in 9pt.
|
||||||
|
- **Table** → items. HSN/SAC (no slot): 9pt under the description.
|
||||||
|
- **Totals** → subtotal, discount, CGST/SGST/IGST as extra rows, and total. Amount in words takes the tagline slot.
|
||||||
|
- **PAYMENT METHOD** → bank details. IFSC, branch and UPI become extra lines.
|
||||||
|
- **PAYMENT TERMS** → notes.
|
||||||
|
- **Signature** → bottom-right grey block.
|
||||||
|
|
||||||
|
## Overflow risks
|
||||||
|
|
||||||
|
- **BILLED TO below the table.** Structurally, BILLED TO sits below the items table (baseline 459.7). With more than about 3 items it drifts down or onto page 2. Move it above the table for Voiced.
|
||||||
|
- **Grey panel height.** In the source the panel stops at y 547, just under TOTAL. With a variable number of items it must become a full-height stripe (x 298.8–535.6) fixed on every page, instead of a fixed-height rectangle. The separate bottom block can then go, since the stripe covers it.
|
||||||
|
- **Vendor name area.** Only about 130 wide (405.8–535.6). Long names run to 3 or more lines; shrink to 14pt. The logo and name share x 337–535.
|
||||||
|
- **Meta cells.** Each cell is 86–112 wide. A series number like 'BB/2025-26/0012' at 12pt is about 95 wide and overflows cell 1 (87.9–174.1). Use 10.5pt or widen cell 1.
|
||||||
|
- **Numeric columns.** They are confined to the 236.8-wide panel. ₹ amounts of '₹12,34,567.00' or more at 12pt (≈85 wide) are close to the 100 limit.
|
||||||
|
- **Left column under the table.** Six bank lines at 13.77pt with 21 pitch take 126, plus notes. The left stack (billed-to, payment, terms) can exceed the page; reduce to 11pt.
|
||||||
|
- **Contact list.** Text is right-aligned with icons, so long email or address lines grow leftward (fine to about x 300). A multi-line address needs textAlign right with the icon on the first line.
|
||||||
|
- **App footer.** It would sit over the bottom-left dot chevron (visually fine) and under the grey block on the right.
|
||||||
|
|
||||||
|
## US Letter adaptation
|
||||||
|
|
||||||
|
US Letter is 612 × 792.
|
||||||
|
- **Width.** Keep the grey column anchored to the right margin (59.9), which puts it at x 315.3–552.1 on Letter. Give the extra 16.5 to the left column (description, BILLED TO).
|
||||||
|
- **Halftone chevrons:** anchor them to their corners and edges.
|
||||||
|
- **Height (−50pt).**
|
||||||
|
- Shrink the header-to-meta gap (≈88) to 65.
|
||||||
|
- Shrink rows from 40 to 34.
|
||||||
|
- Move the signature from the bottom grey block into the flow above the bottom margin; on Letter that block would be only 19 tall.
|
||||||
|
- **Configurable margins.** Page padding drives the flow. Derive the stripe's x from the right margin (left = page width − right margin − 236.8), never from fixed A4 numbers.
|
||||||
|
|
||||||
|
## react-pdf notes
|
||||||
|
|
||||||
|
**Page:** style {backgroundColor:'#FFF7F7', paddingTop:70, paddingLeft:73, paddingRight:59.9, paddingBottom:40}.
|
||||||
|
|
||||||
|
**Stripe:** `<View fixed style={{position:'absolute', top:0, bottom:0, right:59.9, width:236.8, backgroundColor:'#F1F1F1'}}/>` as the first child. Check how absolute offsets interact with page padding.
|
||||||
|
|
||||||
|
**Table rows:**
|
||||||
|
- Each row is flexDirection 'row'. The first column's width is stripe-left minus content-left (≈214.6 including 16 of padding). The three numeric columns total 236.8, so numbers always sit inside the stripe.
|
||||||
|
- Zebra rows get backgroundColor '#F1F1F1' across the whole row.
|
||||||
|
- Header row: the SERVICE View has backgroundColor '#FF9220', the numeric part '#FFFFFF', height 47.2.
|
||||||
|
|
||||||
|
**After the table:** a two-column row, each block with wrap={false}.
|
||||||
|
- Left: BILLED TO (if not moved above), PAYMENT METHOD, PAYMENT TERMS.
|
||||||
|
- Right, 236.8 wide: totals; the TOTAL bar (a View 47.2 tall, backgroundColor '#FF9220'); amount in words; contact list; signature.
|
||||||
|
|
||||||
|
**Icons:** a 16×16 Svg with a Circle of radius 8, fill '#FF9220', plus a white Carbon glyph path.
|
||||||
|
|
||||||
|
**Halftone (optional):** a fixed Svg of Circles filled '#FFEEE4' (pre-blended). Skip it for flattened exports to keep files small.
|
||||||
|
|
||||||
|
**Fonts:** DM Sans 400/700, Montserrat 400/700 (the Gotham substitute), and Now Bold or its substitute. Use fontFamily arrays with IBM Plex Sans as the ₹ fallback.
|
||||||
|
|
||||||
|
## Similarity to other templates
|
||||||
|
|
||||||
|
Sibling of 12.pdf: the same reference family, data and type system with a different layout. It is distinct from everything else in the set and from format.pdf and the in-app template; the split grey column is unique to it. It can share the 12/13 data-mapping code, though its pill and label components differ.
|
||||||
Vendored
+170
@@ -0,0 +1,170 @@
|
|||||||
|
# Reference template analysis
|
||||||
|
|
||||||
|
Per-template specifications measured from the 13 reference PDFs in `templates/reference/`. They drive the template implementations in `src/pdf/templates/`.
|
||||||
|
|
||||||
|
| # | id | Name | Style |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 1 | `marble` | Marble | Airy editorial invoice |
|
||||||
|
| 2 | `highlighter` | Highlighter | Bold form-style invoice |
|
||||||
|
| 3 | `monolith` | Monolith | Stark monochrome Poppins |
|
||||||
|
| 4 | `linea` | Linea (could also be labelled 'Original': this is the vendor's own format.pdf design) | Airy, all-charcoal minimalism |
|
||||||
|
| 5 | `monogram` | Monogram | The Linea grid restyled in Open Sans |
|
||||||
|
| 6 | `serenity` | Serenity | A boutique-stationery look |
|
||||||
|
| 7 | `crimson-grid` | Crimson Grid | Bold corporate boxed grid |
|
||||||
|
| 8 | `cobalt-stripe` | Cobalt Stripe | Friendly cobalt-blue business style |
|
||||||
|
| 9 | `slate-band` | Slate Band | Modern geometric |
|
||||||
|
| 10 | `teal-swoosh` | Teal Swoosh | A clean corporate Montserrat layout |
|
||||||
|
| 11 | `tangerine-ledger` | Tangerine Ledger | A crisp business ledger with Poppins Bold display text and Inter body |
|
||||||
|
| 12 | `purple-pop` | Purple Pop | A playful Memphis style on cream: an oversized purple 'Invoice' wordmark; purple, yellow and grey pill-shaped rows and labels; 8-arm asterisk motifs (solid purple, plus huge pale-pink watermarks); and a yellow dome shape |
|
||||||
|
| 13 | `citrus-split` | Citrus Split | A modern split layout on blush pink: a heavy 'INVOICE' wordmark, a light-grey right column, an orange SERVICE header cell and TOTAL bar, orange labels, an icon contact list and faint orange halftone-dot chevrons |
|
||||||
|
|
||||||
|
## Group notes
|
||||||
|
|
||||||
|
CONVENTIONS
|
||||||
|
- All coordinates are pt from the top-left of the reference design's 595.5 x 842.25 visible page. The MediaBox is [0 7.83 595.5 850.08]; its y-offset is already subtracted.
|
||||||
|
- Reference lays out in 794 x 1123 CSS px, so pt = px x 0.75.
|
||||||
|
- react-pdf 'A4' is 595.28 x 841.89 (at most 0.4pt smaller), so use size 'A4' directly. 'LETTER' is 612 x 792.
|
||||||
|
- To get the top of a line box from a baseline, subtract ascent x size: Poppins 1.05em, Lustria 0.955em, Now 0.92em, Montserrat 0.968em.
|
||||||
|
|
||||||
|
EXTRACTION FACTS
|
||||||
|
- All text is real Type0/Identity-H text with ToUnicode maps, so it is copy-pasteable.
|
||||||
|
- Letter-spacing is done by per-glyph positioning (Tc=0), so the em values given are measured gaps.
|
||||||
|
- Colours come from the rg/RG operators, sizes from Tf x CTM, and positions from the full form-XObject CTM chain.
|
||||||
|
- Nothing in 1-3 uses blend modes or soft masks. The alpha-0 rectangles are tagged-PDF artefacts. Both selectable-text and rasterised ('flattened') export are therefore straightforward.
|
||||||
|
|
||||||
|
FONTS AND LICENSING (bundling all fonts in the xbps)
|
||||||
|
- Templates 1-3 need Lustria, Poppins 400/500/700 and Montserrat 400. All are OFL; the name tables confirm it. Ship static TTF files plus OFL.txt.
|
||||||
|
- The react-pdf v4 docs say only TTF and WOFF are supported and variable fonts do not work. Google ships Montserrat as a variable font, so take the static instances. The existing code already registers .woff.
|
||||||
|
- 'Now' (template 1) is proprietary ('All rights reserved', fsType 8). Substitute Poppins Regular, or Jost as an optional extra.
|
||||||
|
- The same caution applies across the set. Gotham (12/13) is commercial (H&Co). Check the name tables of TheBigmaker, BuongiornoRastellino, SimpleSerenityScript and BDScript before bundling. DM Sans, Inter, Open Sans and Open Sauce One are OFL.
|
||||||
|
- Rupee sign: verified in the local IBM Plex Sans and Montserrat TTF cmaps. Always render money with fontFamily [templateFont, 'IBM Plex Sans'].
|
||||||
|
- Reference stock rasters (template 1's marble, 6's paper texture) must not be extracted and bundled.
|
||||||
|
|
||||||
|
SET-LEVEL DUPLICATES
|
||||||
|
- 4.pdf and format.pdf are the same design: 9 of 10 inflated streams are byte-identical, and the odd one out is metadata. It is not a new template.
|
||||||
|
- 7 and 11 share one layout (red vs orange accent).
|
||||||
|
- 9 and 10 share one body (slate header band vs teal swoosh corners).
|
||||||
|
- 12 and 13 share content and fonts but have different layouts.
|
||||||
|
- 4, 5 and 6 are one family: tracked-caps title, ISSUED TO / PAY TO, ruled table, right-hand totals, script signature.
|
||||||
|
|
||||||
|
CROSS-CUTTING IMPLEMENTATION RULES
|
||||||
|
(1) Only decorations are positioned absolutely; data always flows.
|
||||||
|
(2) Every text container inside a flexDirection 'row' needs flexShrink 1 (or flex 1, or an explicit width). Yoga's default flexShrink is 0. The vendor text View in the existing InvoiceDocument header (inside the row next to the logo, parent maxWidth 58%) has none of these, which is the likely cause of the reported vendor-address/INVOICE overlap.
|
||||||
|
(3) Headers are a row: a title with auto-fitted size, plus a meta block with a fixed max width.
|
||||||
|
(4) Item rows use wrap={false}; table heads use minPresenceAhead; closing blocks (totals, words, signature) use wrap={false}.
|
||||||
|
(5) Margins come from settings as Page padding; decorations ignore margins. Absolute positions are relative to the page edge, as the existing footer already assumes.
|
||||||
|
(6) types.ts has no client phone/email, vendor website or HSN/SAC. Drop the reference slots for those or add the fields. dueDate already exists.
|
||||||
|
|
||||||
|
SUGGESTED BUILD ORDER (by effort): 3 (closest to the existing component), then 2, then 1.
|
||||||
|
|
||||||
|
**4.pdf vs format.pdf: the same design, not just a similar one.** The two files differ only in metadata:
|
||||||
|
- Info/XMP title: 'a sample title' (format.pdf) vs 'reference' (4.pdf).
|
||||||
|
- Export timestamps: 15:51:57 vs 19:01:44 UTC on 2026-10-03.
|
||||||
|
- Reference design ID in /Keywords: ID vs ID (both share account/brand ID ID).
|
||||||
|
- xref offsets and the trailer /ID.
|
||||||
|
|
||||||
|
Page content streams, font subsets, coordinates and the structure tree are byte-identical: 1500 lines each, 10 differing blocks, all of them metadata. So format.pdf is the same reference page exported from a separate design, and it still carries the reference design's placeholder data (Daniel Gallego / Richard Sanchez / Borcele Bank). The vendor's 'original invoice' is this reference template with nothing customised. All 13 template PDFs are pages of a single reference design (ID, exported 19:01:43-46 UTC).
|
||||||
|
|
||||||
|
**The current in-app src/pdf/InvoiceDocument.tsx loosely adapts that design; it is not a copy.** Differences:
|
||||||
|
1. **Type and colour:** the app uses IBM Plex Sans 9.5pt in several greys (#161616, #393939, #525252, #6f6f6f, #e0e0e0). The design uses Montserrat 10pt in one colour, #3D3B3A, with 0.05em tracking.
|
||||||
|
2. **Header:** the app puts logo plus vendor block (18pt name, address, contact, PAN, GSTIN; maxWidth 58%) on the left, and an 18pt semibold right-aligned 'INVOICE'/'TAX INVOICE' with meta rows (maxWidth 40%) on the right. That shared row is where the reported address-vs-INVOICE overlap happens. 4.pdf has no vendor block at all. It has a 38pt Montserrat Regular 'INVOICE' (0.2em tracking) top-left with a 0.75pt rule running to the right edge, and its meta block sits much lower, opposite ISSUED TO.
|
||||||
|
3. **Client block:** the app adds a 1pt #e0e0e0 divider and a grey 7.5pt 'Billed To' label. The design uses a 10pt bold 'ISSUED TO:'.
|
||||||
|
4. **Bank block:** the app's 'Pay To' sits bottom-left beside the signature. In 4.pdf, 'PAY TO:' sits directly under ISSUED TO.
|
||||||
|
5. **Table:** the app has a 1.4pt top border, a 7.5pt grey header, a 0.6pt divider under every row, and flex 5:2:2:2 columns with right-aligned numbers. The design has no top border, a 10pt caps header, one 0.75pt rule, borderless 21.46pt rows, a closing rule, and centred unit price and qty.
|
||||||
|
6. **Totals:** the app uses a 250pt box on the right with a 13pt semibold total over a 1.4pt rule. The design uses a full-width SUBTOTAL row and a right-anchored Tax/TOTAL pair, all 10pt, with the total set apart only by bold weight.
|
||||||
|
7. **Extra fields in the app:** amount in words (italic), notes, PAN/GSTIN, place of supply, PO, discount, CGST/SGST/IGST, the signature image or 'computer-generated' note, and a fixed 'Generated with Voiced' footer.
|
||||||
|
8. **Signature:** 4.pdf's signature is a 60pt script-font name.
|
||||||
|
|
||||||
|
**Recommendation.** A faithful build of 4.pdf gives the vendor the look of the format he actually chose, so it is not redundant with the in-app template. Keep the existing template as 'Voiced Standard' (IBM Plex), since the request was for the reference templates to be added alongside it. Add 4.pdf as 'Linea' (or label it 'Original') and consider making it the vendor's default. Whether to keep both is a product decision for the parent.
|
||||||
|
|
||||||
|
**4, 5 and 6 are one template family.** They share the grid, rules and spacing. 5 swaps Montserrat for Open Sans and adds a monogram; 6 adds the texture, script and stamp and shifts the grid right. Implement one NeutralTemplate driven by a theme object: fonts, title style, letterSpacing (0.5 or 1), row padding (4 or 5.7), header slot, background and column offset. Share the InfoRow, ItemsTable, Totals and BottomRow components across the three.
|
||||||
|
|
||||||
|
**Applies to all three:**
|
||||||
|
- **Vendor identity:** none of the three has a supplier block, yet supplier name, address and GSTIN are mandatory on a GST invoice. Each entry names a slot in its own row, so long addresses push content down instead of overlapping the title.
|
||||||
|
- **Tax rows:** each design shows 'Tax 10%' (the rate only). Voiced needs CGST+SGST or IGST rows with amounts, plus the amount in words.
|
||||||
|
- **Fonts to bundle** in public/fonts (and so in the xbps):
|
||||||
|
- Montserrat 400/700 (the local v9.000 has ₹), Open Sans 400/500/700, and optionally Poppins 400. All are OFL; ship OFL.txt with them.
|
||||||
|
- BuongiornoRastellinoCyr-Script, TheBigmaker and SimpleSerenityScript are reference-licensed and must not be extracted. Use the vendor's logo and signature images, SVG outlines for 6's decorative word (after confirming the reference licence allows that reuse), or OFL scripts.
|
||||||
|
- Keep IBM Plex Sans as the second entry in fontFamily arrays so ₹ always renders.
|
||||||
|
- **Signatures:** use the image or the computer-generated note. Never a typed name in a script font.
|
||||||
|
- **Page size:** the reference design's 595.5x842.25 is A4 within 0.2-0.4pt, so the coordinates map 1:1 onto react-pdf A4.
|
||||||
|
- **How these numbers were measured:**
|
||||||
|
- I decoded the content streams with a small standard-library PDF interpreter (transform tracking, ToUnicode, CID widths).
|
||||||
|
- All coordinates are in pt from the top-left and accurate to about ±0.1pt.
|
||||||
|
- Letter-spacing comes from the gaps between glyphs, since reference positions every glyph separately.
|
||||||
|
- 6.pdf's background colour comes from decoding the JPEG's DC coefficients as YCbCr.
|
||||||
|
|
||||||
|
Method: I used a read-only content-stream interpreter of my own (tracks CTM and text matrices, nested form XObjects, ToUnicode maps, /W widths and ExtGState alpha) and checked against the rendered pages. Coordinates are accurate to about ±0.3pt. Every y value is measured from the page top: top = 850.08 - y_pdf. the reference design's unit chain: the page cm is 0.24 with a y-flip, and inner forms scale by 3.126178, so 1 reference px = 0.7503pt. That makes Tf 16 = 12pt and Tf 14.66 = 11pt; one form also applies a 3.888 scale (Tf 13.33 -> 12.44pt).
|
||||||
|
|
||||||
|
Shared geometry: 7, 8 and 9 all use a 59.55pt side margin (exactly 10% of the width, about 21mm), giving 476.4pt of content width. That is the natural default for a margin setting.
|
||||||
|
|
||||||
|
Transparency: only 9 uses alpha. Its transparency-group XObjects are drawn at ca 0.5 and 0.53, and the inner /G3 (ca 1) does not cancel that, so flatten to #EEEFF1 and #C1C5CE. All three contain invisible ca=0 rectangles tagged /Image for accessibility; they are not decorations.
|
||||||
|
|
||||||
|
Raster content: 7, 8 and 9 have none (vector shapes and live text only). Selectable-text export is react-pdf's native output. A flattened export means rasterising each rendered page (for example pdf.js to a 300 dpi canvas, then an image-only PDF), which works the same whichever template is chosen.
|
||||||
|
|
||||||
|
Fonts these three need: Poppins 400/600/700, Open Sans 400/700, Montserrat 400/500/700/800. All are SIL OFL. Bundle them as static TTFs in the app assets and in the xbps; react-pdf loads font files by URL, never through fontconfig, and cannot use WOFF2 or variable fonts. BD Script (template 8) is reference-licensed, so do not ship it; the signature slot becomes an image.
|
||||||
|
|
||||||
|
₹ (U+20B9) coverage:
|
||||||
|
- Montserrat 9.0, installed locally: confirmed with fc-list ':charset=20b9'.
|
||||||
|
- Poppins and Open Sans are not installed here, so check them after downloading.
|
||||||
|
- Fallback: render the ₹ glyph in IBM Plex Sans (already registered) through a nested Text with that fontFamily.
|
||||||
|
|
||||||
|
react-pdf 4.9.0 behaviour, checked in node_modules (layout 5.2.0, textkit 7.0.1, render):
|
||||||
|
1. splitNodes puts fixed children into both the current and the next page fragment. Page-level fixed bands and footers therefore repeat, and a fixed header row inside a table View should repeat on continuation pages. Confirm the latter in one render.
|
||||||
|
2. renderLine places the baseline at line top + ascent, with no half-leading, and any extra lineHeight goes below the line. So Text top = baseline - ascent x size (Poppins 1.05, Open Sans 1.069, Montserrat 0.968).
|
||||||
|
3. The style props maxLines and textOverflow: 'ellipsis' are supported.
|
||||||
|
4. Page sizes: 'A4' = [595.28, 841.89], 'LETTER' = [612, 792].
|
||||||
|
5. Font.registerHyphenationCallback exists; the default inserts hyphens.
|
||||||
|
6. textkit bug in scalePositions: the isLast check (i === positions.length) is never true, so letterSpacing is also added after the last glyph. Right-aligned tracked text shifts left by the letterSpacing, and centred text by half of it. Compensate with a negative marginRight.
|
||||||
|
7. wrap={false}, minPresenceAhead, and widows/orphans (default 2) are available.
|
||||||
|
|
||||||
|
Guarding against the header-overlap bug in every template: build the header as a flex row. The title gets flexShrink 0; the vendor or brand block gets flex 1 with minWidth 0 so it wraps; nothing in the header is absolutely positioned. None of 7/8/9 puts the vendor address in the header (7 has it in a body column, 8 in the footer, 9 in the From block), which is worth keeping.
|
||||||
|
|
||||||
|
Voiced fields missing from all three: due date, PAN, both GSTINs, place of supply, HSN/SAC, discount, the CGST/SGST/IGST split (9 has no tax row at all), amount in words, IFSC/branch/UPI, and a real signature. Build shared sub-components (PartyBlock, TaxSummaryRows, AmountInWords, BankBlock, SignatureBlock, and a ContactFooter using Carbon icon paths) and have each template only theme them.
|
||||||
|
|
||||||
|
How the full set groups (from a quick visual look at all 13 plus format.pdf, to avoid duplicate work across workers):
|
||||||
|
- 7 ≈ 11: ruled grid; accent, font and header mirroring differ.
|
||||||
|
- 9 ≈ 10: same body; header artwork differs.
|
||||||
|
- 4 = format.pdf: visually identical but different bytes, i.e. a re-export.
|
||||||
|
- 5 and 6 are siblings of 4/format.pdf: ISSUED TO plus INVOICE NO/DATE/DUE DATE, a minimal ruled table and a script signature. 6 adds a raster paper texture, a vertical script 'invoice' and a round stamp.
|
||||||
|
- 12 and 13 share the Northline Group content model (DM Sans/Gotham) with different looks.
|
||||||
|
- 1 (letter-spaced serif, raster marble bands), 2 (yellow ruled blank form with an icon list), 3 (monochrome Poppins with rules; the closest to the in-app InvoiceDocument.tsx) and 8 have no near-duplicate in the set.
|
||||||
|
About 9 parametric components would cover all 13.
|
||||||
|
|
||||||
|
**Method.** I ran 10–13 through a stdlib-only PDF content-stream interpreter: CTM 0.24/−0.24 (reference px to pt), nested form XObjects, ExtGState alpha and /LW. All numbers are page pt with a top-left origin on the 595.5 × 842.25 reference page (≈A4; the MediaBox y-offset of 7.83 is removed). For text, y is the baseline. Font sizes come from Tf × CTM and are rounded. Letter-spacing is the measured gap between glyphs, which equals the reference design's letter-spacing setting. Colours drawn with opacity are also given as flat pre-blended values.
|
||||||
|
|
||||||
|
**reference quirks.**
|
||||||
|
- Every glyph is positioned individually with no kerning data, so expect width differences of about ±2% under react-pdf's kerning.
|
||||||
|
- 12 and 13 draw every 'effect' string twice (an invisible copy at opacity 0 plus the visible one) and add 30% raster shadow images, which garbles their text extraction. A vector react-pdf re-implementation gives clean selectable text, which suits the copy-pasteable export. A flattened export should rasterise the rendered page rather than reuse reference effects.
|
||||||
|
|
||||||
|
**Template families in the set:**
|
||||||
|
- 9 ≈ 10: Montserrat band layout.
|
||||||
|
- 7 ≈ 11: grid ledger.
|
||||||
|
- 12 ~ 13: Northline family (same data, different layouts).
|
||||||
|
|
||||||
|
Build one component per family with accent and decor props. None of 10–13 duplicates format.pdf or the current IBM Plex in-app template; 11 is the closest structurally.
|
||||||
|
|
||||||
|
**Fonts.** Per fc-list, none of the template fonts are installed on this machine, so all must be bundled in the app (and therefore in the .xbps and the NSIS installer).
|
||||||
|
- Needed: Montserrat 400/700/800, Inter 400/600/700, Poppins 700, DM Sans 400/700.
|
||||||
|
- Display faces Open Sauce One Bold (12) and Now Bold (13): check the licences or substitute.
|
||||||
|
- Gotham Book/Bold (12, 13) is commercial: substitute Montserrat 400/700 or DM Sans.
|
||||||
|
- Use static TTF instances, not variable fonts or WOFF2.
|
||||||
|
|
||||||
|
**₹ glyph.** react-pdf supports fontFamily arrays as a per-glyph fallback (confirmed in the diegomura/react-pdf docs, font-family-fallback example). Use, for example, fontFamily: ['Montserrat','IBM Plex Sans']. IBM Plex Sans is already bundled and contains U+20B9 (confirmed locally with fc-list :charset=20b9).
|
||||||
|
|
||||||
|
**Fields Voiced needs that these templates lack.** No template has slots for GSTIN/PAN lines, place of supply, HSN/SAC, the CGST+SGST vs IGST split, amount in words, IFSC/branch/UPI, a signature or computer-generated note, or a PO number. 10 has no subtotal or tax row at all, and 10 and 11 have no due date. Each template entry says where to put these.
|
||||||
|
|
||||||
|
**Money columns.** Right-align them everywhere; the sources centre them in 10, 12 and 13. Give amounts at least 100pt at 11–12pt type, and put the rate unit on a second small line.
|
||||||
|
|
||||||
|
**Multi-page.**
|
||||||
|
- Decorations: fixed, absolute, anchored to page edges or corners.
|
||||||
|
- Everything else is flow.
|
||||||
|
- Item rows: wrap={false}.
|
||||||
|
- Totals and payment blocks: wrap={false} plus minPresenceAhead.
|
||||||
|
- The table header repeats on pages after the first via a fixed element whose render function checks pageNumber > 1.
|
||||||
|
|
||||||
|
**Header overlap.** Every new template keeps the vendor address out of the title's row, or gives it a fixed-width wrapping column. Apply the same rule when fixing the current template's header overlap.
|
||||||
|
|
||||||
|
**Page sizes.** True A4 is 595.28 × 841.89 versus the reference design's 595.5 × 842.25, a negligible difference. US Letter is 612 × 792 (16.5 wider, 50.25 shorter), so every template needs about 50pt of vertical compression (row pitch, gaps) or extra pages.
|
||||||
|
|
||||||
|
**To check.** Confirm how react-pdf positions absolute children relative to Page padding. The existing footer assumes offsets from the page edge; corner decorations with configurable margins depend on the same behaviour.
|
||||||
Reference in New Issue
Block a user