Add the Neutral template family, template picker and text-only logo allowances
Linea (the vendor's original format.pdf design), Monogram and Serenity are rebuilt from the Canva PDFs as one parametric family on the engine, with the user's logo in the measured slot, a home for every GST field and A4/Letter support. Adds static Montserrat, Open Sans and Poppins fonts and a generated Ms Madi outline for Serenity's vertical word. Text-only logo placeholders (Monolith, Tangerine) use a doc-derived allowance box. A Carbon TemplatePicker with committed thumbnails opens from the page setup controls.
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
import { defineRoles } from "../../fonts/roles";
|
||||
import { scriptWordBounds, scriptWordDecor } from "../../decor/ScriptWord";
|
||||
import { FOOTER_RESERVE } from "./constants";
|
||||
import { catalogEntry } from "../catalog";
|
||||
import type { TemplateDefinition } from "../contract";
|
||||
import { slotFor } from "../slots.optin";
|
||||
import { NeutralLayoutFor } from "./layoutFor";
|
||||
import { MONOGRAM_ROLES } from "./monogram";
|
||||
import type { NeutralRoles, NeutralVariant } from "./variant";
|
||||
|
||||
const INK = "#3D3B3A";
|
||||
/** The paper colour measured from Canva's texture (its average); the texture itself is stock and is not bundled. */
|
||||
const PAPER = "#ECE8E1";
|
||||
|
||||
/** Serenity shares Monogram's Open Sans type system (docs/templates/06-serenity.md); its own object so it can drift. */
|
||||
export const SERENITY_ROLES = defineRoles({
|
||||
...MONOGRAM_ROLES,
|
||||
} satisfies NeutralRoles);
|
||||
|
||||
/** Letter keeps the band's top and takes this share of the page-height deficit off its position (docs: shift up about 32 pt). */
|
||||
const BAND_SHIFT_SHARE = 0.64;
|
||||
|
||||
/**
|
||||
* Canva A4 numbers: the rules start on the 162.91 pt left margin (the band occupies x 55-155), the
|
||||
* stamp slot is 82 x 82 at y 131.75 on the right.
|
||||
*/
|
||||
export const SERENITY_VARIANT: NeutralVariant = {
|
||||
id: "serenity",
|
||||
roles: SERENITY_ROLES,
|
||||
ink: INK,
|
||||
margins: { top: 56, right: 64.1, bottom: 60, left: 162.91 },
|
||||
// The left margin never goes under the band's right edge plus 8 pt, whatever the preset.
|
||||
marginFloor: { top: 36, right: 36, bottom: 36, left: 162.91 },
|
||||
ruleInset: 0,
|
||||
padX: 8.9,
|
||||
textInset: { left: 8.9, right: 6.7 },
|
||||
rule: 0.75,
|
||||
topGap: { nominal: 75.75, min: 40 },
|
||||
fromGap: 12,
|
||||
bandToInfo: 156.85,
|
||||
infoMinGap: 14,
|
||||
tableGap: { nominal: 61, min: 28 },
|
||||
headTail: { before: 3.47, after: 6.98 },
|
||||
padY: 5.8,
|
||||
closeGap: 7.9,
|
||||
subtotalPad: 8.06,
|
||||
totalsRowGap: 5.1,
|
||||
labelGap: 8,
|
||||
hsnMode: "subline",
|
||||
cols: { hsn: 0, rate: 90, qty: 36, amount: 80, descMin: 60 },
|
||||
totalsW: 210,
|
||||
amountW: 90,
|
||||
wordsPlacement: "below",
|
||||
notesGap: { nominal: 14, min: 8 },
|
||||
fromW: 250,
|
||||
payTo: { where: "closing", label: "Bank details", inset: 10.9 },
|
||||
signatureW: 150,
|
||||
payGap: 0,
|
||||
chromeInset: 8.9,
|
||||
footerLeftW: 130,
|
||||
signatureImageH: 44,
|
||||
};
|
||||
|
||||
export const serenity: TemplateDefinition = {
|
||||
...catalogEntry("serenity"),
|
||||
version: 1,
|
||||
roles: SERENITY_ROLES,
|
||||
margins: SERENITY_VARIANT.margins,
|
||||
marginFloor: SERENITY_VARIANT.marginFloor,
|
||||
decor: {
|
||||
ink: INK,
|
||||
background: PAPER,
|
||||
everyPage: (frame) => scriptWordDecor(INK, frame.heightDeficit * BAND_SHIFT_SHARE),
|
||||
keepOuts: (frame) => [scriptWordBounds(frame.heightDeficit * BAND_SHIFT_SHARE)],
|
||||
},
|
||||
chrome: {
|
||||
color: INK,
|
||||
rule: null,
|
||||
role: SERENITY_ROLES.footer,
|
||||
inset: { left: SERENITY_VARIANT.chromeInset, right: SERENITY_VARIANT.chromeInset },
|
||||
reserve: FOOTER_RESERVE,
|
||||
leftWidth: SERENITY_VARIANT.footerLeftW,
|
||||
},
|
||||
logo: {
|
||||
box: { w: 82, h: 81.75 },
|
||||
stackBelowTextWidth: 0,
|
||||
defaultOn: true,
|
||||
slotWidth: () => 82,
|
||||
slot: slotFor("serenity"),
|
||||
available: () => ({ w: 82, h: 81.75 }),
|
||||
},
|
||||
Layout: NeutralLayoutFor(SERENITY_VARIANT),
|
||||
};
|
||||
Reference in New Issue
Block a user