Add Ledger and Band template families with decor primitives

Crimson Grid, Tangerine Ledger, Slate Band and Teal Swoosh are rebuilt from
the Canva PDFs with grid and band tables that survive page breaks,
full-bleed fixed bands, pennant tabs, gradient corner swooshes with
keep-outs, Carbon icon circles, and the user's logo in the measured slot
(knockout or white chip on the dark Slate band). Adds static Poppins
500-700 and Inter fonts. Thumbnails regenerated for all eight templates;
the item-count sweeps run in their own test file.
This commit is contained in:
2026-10-04 08:34:18 +05:30
parent 3f7c12b7dd
commit c95514ee8d
62 changed files with 4078 additions and 217 deletions
+19
View File
@@ -126,3 +126,22 @@ Everything can be built with View backgroundColor and borders. Svg is only neede
- 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).
## Implementation notes
Built as `src/pdf/templates/ledger/` (one family component, `Layout.tsx`, shared with Tangerine Ledger; tokens in `crimson.tsx`, planning in `plan.ts`) on the decor primitives in `src/pdf/decor/`. Measured against `7.pdf` with `npm run templates:compare` (`/tmp/invoice-c4/compare-crimson-grid.png`, left Canva, right ours).
**Matches the design (measured, A4):** title baseline 100.6 pt at x 59.5, 43.8 pt Poppins Bold; the 1.5 pt #A00000 rule at y 128.85; meta baselines 173.6 / 192.3; party heading to first line 23.9 pt; BILL TO at x 304.3; table text at x 69.7, header row 42 pt (Canva 40.5 plus the 0.75 pt rules) and 40.5 pt single-line rows; header fill #A00000 with white inner verticals and a black outer box; the 63 pt full-bleed band; all colours exact.
**Intentional deviations, and why:**
- **Margins.** Top 53 and sides 59.55 as designed. The bottom margin floor is 26 pt plus a 53 pt footer reserve, so the flow is at least 79 pt (band 63 + 16) above the page bottom on every margin preset and on Letter. The footer text is placed by `chrome.bottom` (14 pt above the edge), inside the band whatever the preset.
- **Header.** Title and brand block are one row without `alignItems: flex-end` (lint bans it): the brand block is placed from the measured slot offsets. 'TAX INVOICE' (about 281 pt) shrinks to at most 60 % of its size before the brand block (at most 40 % of the width) is squeezed. A wordmark logo replaces the whole flame + name lockup; a mark logo sits left of the vendor name in 15.44 pt caps (13.7 pt gap); without a logo only the name shows.
- **Meta** adds 'Due Date:' and 'PO No:' lines (same 18.7 pt pitch); 'Invoice Number:' keeps the design's wording.
- **Parties.** The vendor block's heading is the vendor name in caps, followed by address, phone, e-mail, PAN and the GSTIN (slot). Canva's PREPARED BY (x 322.4, misaligned) is normalised to the BILL TO column (x 304.3) and renamed AUTHORISED SIGNATORY.
- **Table.** The grid is drawn as per-cell borders (`TableRows` `grid`), not lines over the text, so it survives page breaks: the header repeats with its rules and every row owns its bottom rule. An HSN/SAC column (at least 56 pt) appears on tax invoices. Unit Price shows '₹1,200.00/hr' on one line when it fits, else the amount over 'per hour' at 8.5 pt; the money columns are at least 100 / 45 / 100 pt and grow to their widest amount. Rows grow with wrapped descriptions (padY 12.55).
- **Totals box** is widened (about 210 pt: label at least 96, value at least 100) with 28 pt rows instead of 40.5, so Sub-Total, Discount, Taxable value, CGST/SGST (or UTGST, IGST via `Slot.TaxRows`) and Total fit. The Total row is bold 12 pt without a fill, as designed.
- **Notes / Terms** sit left of the totals box when they are at most 110 pt tall; longer notes flow below the table (a long note must never make the unbreakable totals block unplaceable). Amount in words and the reverse-charge line run full width under the box.
- **Closing.** Bank lines are 10.5 / 14.5 pt (not 12 / 16.5) so six lines fit; the signature is the user's image or the computer-generated line with the signatory name.
- **Footer band.** The contact line is 'email | phone' (no website field exists; the GSTIN is printed through its slot only) at 11 pt with 0.05 em tracking instead of 12.44 pt / 0.064 em, and is fitted to one line. The standard footer (supplier name, 'Generated with Voiced', Page n of N) is added inside the band in cream at 7 pt; the continuation band on pages 2+ is grey so it stays readable on white.
- **Letter.** The 49.9 pt deficit comes out of the rule gap (21.5 to 12), meta (31.4 to 20), party (22.3 to 14), table (27.4 to 16), totals (11.3 to 6) and notes (12 to 8) gaps, 50.4 pt in all; type and row padding are not scaled. The band stays 63 pt at the bottom edge.
- **Grid colour.** The Canva artefact (black top/bottom edges on cells 1 and 3 only) is normalised to a black outer box with white inner verticals in the header, as the doc recommends.