// ── Rendering a block array into a mail body ─────────────────────────────── // // Pure and synchronous: everything that needs a database — the brand values, the // resolved theme, the site title — is resolved by `engagement/templates.js` and // arrives here as a plain object. That split is what lets the whole renderer be // tested without a MariaDB, and it is why the byte-comparison test for the five // transactional bodies (§5a acceptance) is a unit test rather than a live send. // // **The shell contributes structure and NO content.** No appended footer, no // injected logo, no "sent by" line. Two reasons, and the second is the load-bearing // one: // // - A person's mail must say what the operator wrote and nothing else. An // unsubscribe line is a variable inside the template (§4.6.1 lists // `unsubscribeUrl` for exactly the two templates that need one), so an operator // can move it, reword it, or see that a transactional mail correctly has none. // - **The HTML and text parts must say the same things.** A shell that put a // footer only in the HTML would make every message's two parts disagree, which // is a deliverability signal and, worse, means the text reader is told less // than the HTML reader. Every block produces both halves; nothing else does. // // The HTML is table-based and inline-styled throughout, which is not a stylistic // choice: `