[{"data":1,"prerenderedAt":3050},["ShallowReactive",2],{"navigation_docs":3,"-rendering-config-and-renderer":191,"-rendering-config-and-renderer-surround":3045},[4,31,67,103,129,155,175],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":30},"Getting started","i-lucide-rocket","\u002Fgetting-started","1.getting-started",[10,15,20,25],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Quick start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start","i-lucide-play",{"title":26,"path":27,"stem":28,"icon":29},"Agent Skill","\u002Fgetting-started\u002Fagent-skill","1.getting-started\u002F4.agent-skill","i-lucide-sparkles",false,{"title":32,"icon":33,"path":34,"stem":35,"children":36,"page":30},"Authoring","i-lucide-pen-line","\u002Fauthoring","2.authoring",[37,42,47,52,57,62],{"title":38,"path":39,"stem":40,"icon":41},"Comark syntax","\u002Fauthoring\u002Fcomark-syntax","2.authoring\u002F1.comark-syntax","i-lucide-file-code",{"title":43,"path":44,"stem":45,"icon":46},"Frontmatter","\u002Fauthoring\u002Ffrontmatter","2.authoring\u002F2.frontmatter","i-lucide-heading",{"title":48,"path":49,"stem":50,"icon":51},"Modules","\u002Fauthoring\u002Fmodules","2.authoring\u002F3.modules","i-lucide-blocks",{"title":53,"path":54,"stem":55,"icon":56},"Merge tags and bindings","\u002Fauthoring\u002Fmerge-tags-and-bindings","2.authoring\u002F4.merge-tags-and-bindings","i-lucide-braces",{"title":58,"path":59,"stem":60,"icon":61},"Actions and spans","\u002Fauthoring\u002Factions-and-spans","2.authoring\u002F5.actions-and-spans","i-lucide-mouse-pointer-click",{"title":63,"path":64,"stem":65,"icon":66},"Compile errors","\u002Fauthoring\u002Fcompile-errors","2.authoring\u002F6.compile-errors","i-lucide-circle-alert",{"title":68,"icon":69,"path":70,"stem":71,"children":72,"page":30},"Rendering","i-lucide-layout-template","\u002Frendering","3.rendering",[73,78,83,88,93,98],{"title":74,"path":75,"stem":76,"icon":77},"Families and streams","\u002Frendering\u002Ffamilies-and-streams","3.rendering\u002F1.families-and-streams","i-lucide-users",{"title":79,"path":80,"stem":81,"icon":82},"Themes","\u002Frendering\u002Fthemes","3.rendering\u002F2.themes","i-lucide-palette",{"title":84,"path":85,"stem":86,"icon":87},"Config and the renderer","\u002Frendering\u002Fconfig-and-renderer","3.rendering\u002F3.config-and-renderer","i-lucide-settings",{"title":89,"path":90,"stem":91,"icon":92},"Layout and spacing","\u002Frendering\u002Flayout-and-spacing","3.rendering\u002F4.layout-and-spacing","i-lucide-ruler",{"title":94,"path":95,"stem":96,"icon":97},"HTML output","\u002Frendering\u002Fhtml-output","3.rendering\u002F5.html-output","i-lucide-code-xml",{"title":99,"path":100,"stem":101,"icon":102},"Plain text","\u002Frendering\u002Fplain-text","3.rendering\u002F6.plain-text","i-lucide-file-text",{"title":104,"icon":105,"path":106,"stem":107,"children":108,"page":30},"Sending","i-lucide-send","\u002Fsending","4.sending",[109,114,119,124],{"title":110,"path":111,"stem":112,"icon":113},"Message and MIME","\u002Fsending\u002Fmessage-and-mime","4.sending\u002F1.message-and-mime","i-lucide-mail",{"title":115,"path":116,"stem":117,"icon":118},"Router and streams","\u002Fsending\u002Frouter-and-streams","4.sending\u002F2.router-and-streams","i-lucide-route",{"title":120,"path":121,"stem":122,"icon":123},"SMTP","\u002Fsending\u002Fsmtp","4.sending\u002F3.smtp","i-lucide-server",{"title":125,"path":126,"stem":127,"icon":128},"Maps","\u002Fsending\u002Fmaps","4.sending\u002F4.maps","i-lucide-map",{"title":130,"icon":131,"path":132,"stem":133,"children":134,"page":30},"Tooling","i-lucide-wrench","\u002Ftooling","5.tooling",[135,140,145,150],{"title":136,"path":137,"stem":138,"icon":139},"The lttr CLI","\u002Ftooling\u002Fcli","5.tooling\u002F1.cli","i-lucide-terminal",{"title":141,"path":142,"stem":143,"icon":144},"Live preview","\u002Ftooling\u002Flive-preview","5.tooling\u002F2.live-preview","i-lucide-eye",{"title":146,"path":147,"stem":148,"icon":149},"Screenshots","\u002Ftooling\u002Fscreenshots","5.tooling\u002F3.screenshots","i-lucide-camera",{"title":151,"path":152,"stem":153,"icon":154},"Goldens and testing","\u002Ftooling\u002Fgoldens-and-testing","5.tooling\u002F4.goldens-and-testing","i-lucide-flask-conical",{"title":156,"icon":157,"path":158,"stem":159,"children":160,"page":30},"Guides","i-lucide-book-open","\u002Fguides","6.guides",[161,166,170],{"title":162,"path":163,"stem":164,"icon":165},"The Quiet example","\u002Fguides\u002Fthe-quiet-example","6.guides\u002F1.the-quiet-example","i-lucide-mail-open",{"title":167,"path":168,"stem":169,"icon":82},"Your own family and theme","\u002Fguides\u002Fyour-own-family-and-theme","6.guides\u002F2.your-own-family-and-theme",{"title":171,"path":172,"stem":173,"icon":174},"Releasing","\u002Fguides\u002Freleasing","6.guides\u002F3.releasing","i-lucide-tag",{"title":176,"icon":177,"path":178,"stem":179,"children":180,"page":30},"Reference","i-lucide-library","\u002Freference","7.reference",[181,186],{"title":182,"path":183,"stem":184,"icon":185},"API reference","\u002Freference\u002Fapi-reference","7.reference\u002F1.api-reference","i-lucide-list-tree",{"title":187,"path":188,"stem":189,"icon":190},"Gallery","\u002Freference\u002Fgallery","7.reference\u002F2.gallery","i-lucide-images",{"id":192,"title":84,"body":193,"description":3038,"extension":3039,"links":3040,"meta":3041,"navigation":3042,"path":85,"seo":3043,"stem":86,"__hash__":3044},"docs\u002F3.rendering\u002F3.config-and-renderer.md",{"type":194,"value":195,"toc":3026},"minimark",[196,221,226,1319,1328,1331,1335,1460,1629,1640,1644,1650,1747,1777,1780,1881,1902,1906,1925,1993,1996,2000,2028,2032,2069,2074,2276,2283,2304,2313,2317,2431,2465,2470,2537,2543,2547,2607,2613,2691,2720,2724,2786,2805,2808,2956,2962,2966,2972,3019,3022],[197,198,199,200,204,205,208,209,212,213,216,217,220],"p",{},"Rendering takes three pieces: a ",[201,202,203],"code",{},"Config"," you fill once, a ",[201,206,207],{},"*Renderer"," that ",[201,210,211],{},"NewRenderer"," builds from it, and compiled templates. ",[201,214,215],{},"Template.Render"," combines them with a recipient and the template's data and returns a ",[201,218,219],{},"*Message",".",[222,223,225],"h2",{"id":224},"render-a-template-end-to-end","Render a template end to end",[227,228,234],"pre",{"className":229,"code":230,"filename":231,"language":232,"meta":233,"style":233},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","package main\n\nimport (\n    \"fmt\"\n    \"log\"\n    \"net\u002Fmail\"\n\n    \"github.com\u002Fsulv-io\u002Flttr\"\n    \"github.com\u002Fsulv-io\u002Flttr\u002Fexamples\u002Fquiet\"\n)\n\n\u002F\u002F Welcome is the template's data.\ntype Welcome struct {\n    DashboardURL string `json:\"dashboard_url\"`\n}\n\nvar families = lttr.NewRegistry(lttr.Family{\n    Name:   \"account\",\n    From:   mail.Address{Name: \"Acme\", Address: \"hello@acme.example\"},\n    Stream: lttr.Transactional,\n    Header: lttr.H1,\n    Footer: lttr.F2,\n    Copy: lttr.FooterCopy{\n        Note:      \"Questions? Reply to this email.\",\n        About:     \"your Acme account\",\n        Service:   \"This is a service email about {about}. [Notification settings]({prefs})\",\n        Address:   \"{brand} · {address}\",\n        TextLinks: []lttr.TextLink{{Label: \"Notification settings\", URL: \"{prefs}\"}},\n    },\n    Tracking: true,\n})\n\nvar welcome = lttr.MustCompile[Welcome](families, \"account.welcome\", []byte(`---\ntemplate: account.welcome\nfamily: account\nsubject: \"Welcome to Acme, {{first_name}}\"\npreheader: Your account is ready.\n---\n\n::statement\n# Welcome aboard.\n\nYour account is ready whenever you are.\n\n:button[Open your dashboard]{href=\"{{dashboard_url}}\"}\n::\n`))\n\nfunc main() {\n    th := quiet.Theme() \u002F\u002F palettes and fonts; use your own theme.Theme\n    th.Brand.Name = \"Acme\"\n\n    r, err := lttr.NewRenderer(lttr.Config{\n        Domain:        \"acme.example\",\n        SiteURL:       \"https:\u002F\u002Facme.example\",\n        AssetBase:     \"https:\u002F\u002Fcdn.acme.example\u002Femail\",\n        Theme:         th,\n        Families:      families,\n        Entities:      map[string]lttr.Entity{\"UK\": {Address: \"1 High Street, London\"}},\n        DefaultRegion: \"UK\",\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    to := lttr.Recipient{Address: \"ada@example.com\", FirstName: \"Ada\"}\n    msg, err := welcome.Render(r, to, Welcome{DashboardURL: \"https:\u002F\u002Facme.example\u002Fdashboard\"})\n    if err != nil {\n        log.Fatal(err)\n    }\n    fmt.Println(msg.Subject)\n    fmt.Print(msg.Text)\n}\n","main.go","go","",[201,235,236,249,256,266,278,288,298,303,313,323,329,334,341,356,377,383,388,423,444,494,511,528,545,562,580,598,615,632,682,688,702,708,713,766,772,778,784,790,795,800,806,812,817,823,828,834,840,848,853,867,889,913,918,947,965,983,1000,1013,1026,1076,1092,1098,1114,1132,1138,1143,1187,1237,1250,1265,1270,1293,1314],{"__ignoreMap":233},[237,238,241,245],"span",{"class":239,"line":240},"line",1,[237,242,244],{"class":243},"sMK4o","package",[237,246,248],{"class":247},"sBMFI"," main\n",[237,250,252],{"class":239,"line":251},2,[237,253,255],{"emptyLinePlaceholder":254},true,"\n",[237,257,259,263],{"class":239,"line":258},3,[237,260,262],{"class":261},"s7zQu","import",[237,264,265],{"class":243}," (\n",[237,267,269,272,275],{"class":239,"line":268},4,[237,270,271],{"class":243},"    \"",[237,273,274],{"class":247},"fmt",[237,276,277],{"class":243},"\"\n",[237,279,281,283,286],{"class":239,"line":280},5,[237,282,271],{"class":243},[237,284,285],{"class":247},"log",[237,287,277],{"class":243},[237,289,291,293,296],{"class":239,"line":290},6,[237,292,271],{"class":243},[237,294,295],{"class":247},"net\u002Fmail",[237,297,277],{"class":243},[237,299,301],{"class":239,"line":300},7,[237,302,255],{"emptyLinePlaceholder":254},[237,304,306,308,311],{"class":239,"line":305},8,[237,307,271],{"class":243},[237,309,310],{"class":247},"github.com\u002Fsulv-io\u002Flttr",[237,312,277],{"class":243},[237,314,316,318,321],{"class":239,"line":315},9,[237,317,271],{"class":243},[237,319,320],{"class":247},"github.com\u002Fsulv-io\u002Flttr\u002Fexamples\u002Fquiet",[237,322,277],{"class":243},[237,324,326],{"class":239,"line":325},10,[237,327,328],{"class":243},")\n",[237,330,332],{"class":239,"line":331},11,[237,333,255],{"emptyLinePlaceholder":254},[237,335,337],{"class":239,"line":336},12,[237,338,340],{"class":339},"sHwdD","\u002F\u002F Welcome is the template's data.\n",[237,342,344,347,350,353],{"class":239,"line":343},13,[237,345,346],{"class":243},"type",[237,348,349],{"class":247}," Welcome",[237,351,352],{"class":243}," struct",[237,354,355],{"class":243}," {\n",[237,357,359,363,367,370,374],{"class":239,"line":358},14,[237,360,362],{"class":361},"sTEyZ","    DashboardURL ",[237,364,366],{"class":365},"spNyl","string",[237,368,369],{"class":243}," `",[237,371,373],{"class":372},"sfazB","json:\"dashboard_url\"",[237,375,376],{"class":243},"`\n",[237,378,380],{"class":239,"line":379},15,[237,381,382],{"class":243},"}\n",[237,384,386],{"class":239,"line":385},16,[237,387,255],{"emptyLinePlaceholder":254},[237,389,391,394,397,400,403,405,409,412,415,417,420],{"class":239,"line":390},17,[237,392,393],{"class":243},"var",[237,395,396],{"class":361}," families ",[237,398,399],{"class":243},"=",[237,401,402],{"class":361}," lttr",[237,404,220],{"class":243},[237,406,408],{"class":407},"s2Zo4","NewRegistry",[237,410,411],{"class":243},"(",[237,413,414],{"class":247},"lttr",[237,416,220],{"class":243},[237,418,419],{"class":247},"Family",[237,421,422],{"class":243},"{\n",[237,424,426,429,432,435,438,441],{"class":239,"line":425},18,[237,427,428],{"class":361},"    Name",[237,430,431],{"class":243},":",[237,433,434],{"class":243},"   \"",[237,436,437],{"class":372},"account",[237,439,440],{"class":243},"\"",[237,442,443],{"class":243},",\n",[237,445,447,450,452,455,457,460,463,466,468,471,474,476,479,482,484,486,489,491],{"class":239,"line":446},19,[237,448,449],{"class":361},"    From",[237,451,431],{"class":243},[237,453,454],{"class":247},"   mail",[237,456,220],{"class":243},[237,458,459],{"class":247},"Address",[237,461,462],{"class":243},"{",[237,464,465],{"class":361},"Name",[237,467,431],{"class":243},[237,469,470],{"class":243}," \"",[237,472,473],{"class":372},"Acme",[237,475,440],{"class":243},[237,477,478],{"class":243},",",[237,480,481],{"class":361}," Address",[237,483,431],{"class":243},[237,485,470],{"class":243},[237,487,488],{"class":372},"hello@acme.example",[237,490,440],{"class":243},[237,492,493],{"class":243},"},\n",[237,495,497,500,502,504,506,509],{"class":239,"line":496},20,[237,498,499],{"class":361},"    Stream",[237,501,431],{"class":243},[237,503,402],{"class":361},[237,505,220],{"class":243},[237,507,508],{"class":361},"Transactional",[237,510,443],{"class":243},[237,512,514,517,519,521,523,526],{"class":239,"line":513},21,[237,515,516],{"class":361},"    Header",[237,518,431],{"class":243},[237,520,402],{"class":361},[237,522,220],{"class":243},[237,524,525],{"class":361},"H1",[237,527,443],{"class":243},[237,529,531,534,536,538,540,543],{"class":239,"line":530},22,[237,532,533],{"class":361},"    Footer",[237,535,431],{"class":243},[237,537,402],{"class":361},[237,539,220],{"class":243},[237,541,542],{"class":361},"F2",[237,544,443],{"class":243},[237,546,548,551,553,555,557,560],{"class":239,"line":547},23,[237,549,550],{"class":361},"    Copy",[237,552,431],{"class":243},[237,554,402],{"class":247},[237,556,220],{"class":243},[237,558,559],{"class":247},"FooterCopy",[237,561,422],{"class":243},[237,563,565,568,570,573,576,578],{"class":239,"line":564},24,[237,566,567],{"class":361},"        Note",[237,569,431],{"class":243},[237,571,572],{"class":243},"      \"",[237,574,575],{"class":372},"Questions? Reply to this email.",[237,577,440],{"class":243},[237,579,443],{"class":243},[237,581,583,586,588,591,594,596],{"class":239,"line":582},25,[237,584,585],{"class":361},"        About",[237,587,431],{"class":243},[237,589,590],{"class":243},"     \"",[237,592,593],{"class":372},"your Acme account",[237,595,440],{"class":243},[237,597,443],{"class":243},[237,599,601,604,606,608,611,613],{"class":239,"line":600},26,[237,602,603],{"class":361},"        Service",[237,605,431],{"class":243},[237,607,434],{"class":243},[237,609,610],{"class":372},"This is a service email about {about}. [Notification settings]({prefs})",[237,612,440],{"class":243},[237,614,443],{"class":243},[237,616,618,621,623,625,628,630],{"class":239,"line":617},27,[237,619,620],{"class":361},"        Address",[237,622,431],{"class":243},[237,624,434],{"class":243},[237,626,627],{"class":372},"{brand} · {address}",[237,629,440],{"class":243},[237,631,443],{"class":243},[237,633,635,638,640,643,645,647,650,653,656,658,660,663,665,667,670,672,674,677,679],{"class":239,"line":634},28,[237,636,637],{"class":361},"        TextLinks",[237,639,431],{"class":243},[237,641,642],{"class":243}," []",[237,644,414],{"class":247},[237,646,220],{"class":243},[237,648,649],{"class":247},"TextLink",[237,651,652],{"class":243},"{{",[237,654,655],{"class":361},"Label",[237,657,431],{"class":243},[237,659,470],{"class":243},[237,661,662],{"class":372},"Notification settings",[237,664,440],{"class":243},[237,666,478],{"class":243},[237,668,669],{"class":361}," URL",[237,671,431],{"class":243},[237,673,470],{"class":243},[237,675,676],{"class":372},"{prefs}",[237,678,440],{"class":243},[237,680,681],{"class":243},"}},\n",[237,683,685],{"class":239,"line":684},29,[237,686,687],{"class":243},"    },\n",[237,689,691,694,696,700],{"class":239,"line":690},30,[237,692,693],{"class":361},"    Tracking",[237,695,431],{"class":243},[237,697,699],{"class":698},"sfNiH"," true",[237,701,443],{"class":243},[237,703,705],{"class":239,"line":704},31,[237,706,707],{"class":243},"})\n",[237,709,711],{"class":239,"line":710},32,[237,712,255],{"emptyLinePlaceholder":254},[237,714,716,718,721,723,725,727,730,733,736,739,742,744,746,749,751,753,755,758,760,763],{"class":239,"line":715},33,[237,717,393],{"class":243},[237,719,720],{"class":361}," welcome ",[237,722,399],{"class":243},[237,724,402],{"class":361},[237,726,220],{"class":243},[237,728,729],{"class":407},"MustCompile",[237,731,732],{"class":243},"[",[237,734,735],{"class":247},"Welcome",[237,737,738],{"class":243},"](",[237,740,741],{"class":361},"families",[237,743,478],{"class":243},[237,745,470],{"class":243},[237,747,748],{"class":372},"account.welcome",[237,750,440],{"class":243},[237,752,478],{"class":243},[237,754,642],{"class":243},[237,756,757],{"class":365},"byte",[237,759,411],{"class":243},[237,761,762],{"class":243},"`",[237,764,765],{"class":372},"---\n",[237,767,769],{"class":239,"line":768},34,[237,770,771],{"class":372},"template: account.welcome\n",[237,773,775],{"class":239,"line":774},35,[237,776,777],{"class":372},"family: account\n",[237,779,781],{"class":239,"line":780},36,[237,782,783],{"class":372},"subject: \"Welcome to Acme, {{first_name}}\"\n",[237,785,787],{"class":239,"line":786},37,[237,788,789],{"class":372},"preheader: Your account is ready.\n",[237,791,793],{"class":239,"line":792},38,[237,794,765],{"class":372},[237,796,798],{"class":239,"line":797},39,[237,799,255],{"emptyLinePlaceholder":254},[237,801,803],{"class":239,"line":802},40,[237,804,805],{"class":372},"::statement\n",[237,807,809],{"class":239,"line":808},41,[237,810,811],{"class":372},"# Welcome aboard.\n",[237,813,815],{"class":239,"line":814},42,[237,816,255],{"emptyLinePlaceholder":254},[237,818,820],{"class":239,"line":819},43,[237,821,822],{"class":372},"Your account is ready whenever you are.\n",[237,824,826],{"class":239,"line":825},44,[237,827,255],{"emptyLinePlaceholder":254},[237,829,831],{"class":239,"line":830},45,[237,832,833],{"class":372},":button[Open your dashboard]{href=\"{{dashboard_url}}\"}\n",[237,835,837],{"class":239,"line":836},46,[237,838,839],{"class":372},"::\n",[237,841,843,845],{"class":239,"line":842},47,[237,844,762],{"class":243},[237,846,847],{"class":243},"))\n",[237,849,851],{"class":239,"line":850},48,[237,852,255],{"emptyLinePlaceholder":254},[237,854,856,859,862,865],{"class":239,"line":855},49,[237,857,858],{"class":243},"func",[237,860,861],{"class":407}," main",[237,863,864],{"class":243},"()",[237,866,355],{"class":243},[237,868,870,873,876,879,881,884,886],{"class":239,"line":869},50,[237,871,872],{"class":361},"    th ",[237,874,875],{"class":243},":=",[237,877,878],{"class":361}," quiet",[237,880,220],{"class":243},[237,882,883],{"class":407},"Theme",[237,885,864],{"class":243},[237,887,888],{"class":339}," \u002F\u002F palettes and fonts; use your own theme.Theme\n",[237,890,892,895,897,900,902,905,907,909,911],{"class":239,"line":891},51,[237,893,894],{"class":361},"    th",[237,896,220],{"class":243},[237,898,899],{"class":361},"Brand",[237,901,220],{"class":243},[237,903,904],{"class":361},"Name ",[237,906,399],{"class":243},[237,908,470],{"class":243},[237,910,473],{"class":372},[237,912,277],{"class":243},[237,914,916],{"class":239,"line":915},52,[237,917,255],{"emptyLinePlaceholder":254},[237,919,921,924,926,929,931,933,935,937,939,941,943,945],{"class":239,"line":920},53,[237,922,923],{"class":361},"    r",[237,925,478],{"class":243},[237,927,928],{"class":361}," err ",[237,930,875],{"class":243},[237,932,402],{"class":361},[237,934,220],{"class":243},[237,936,211],{"class":407},[237,938,411],{"class":243},[237,940,414],{"class":247},[237,942,220],{"class":243},[237,944,203],{"class":247},[237,946,422],{"class":243},[237,948,950,953,955,958,961,963],{"class":239,"line":949},54,[237,951,952],{"class":361},"        Domain",[237,954,431],{"class":243},[237,956,957],{"class":243},"        \"",[237,959,960],{"class":372},"acme.example",[237,962,440],{"class":243},[237,964,443],{"class":243},[237,966,968,971,973,976,979,981],{"class":239,"line":967},55,[237,969,970],{"class":361},"        SiteURL",[237,972,431],{"class":243},[237,974,975],{"class":243},"       \"",[237,977,978],{"class":372},"https:\u002F\u002Facme.example",[237,980,440],{"class":243},[237,982,443],{"class":243},[237,984,986,989,991,993,996,998],{"class":239,"line":985},56,[237,987,988],{"class":361},"        AssetBase",[237,990,431],{"class":243},[237,992,590],{"class":243},[237,994,995],{"class":372},"https:\u002F\u002Fcdn.acme.example\u002Femail",[237,997,440],{"class":243},[237,999,443],{"class":243},[237,1001,1003,1006,1008,1011],{"class":239,"line":1002},57,[237,1004,1005],{"class":361},"        Theme",[237,1007,431],{"class":243},[237,1009,1010],{"class":361},"         th",[237,1012,443],{"class":243},[237,1014,1016,1019,1021,1024],{"class":239,"line":1015},58,[237,1017,1018],{"class":361},"        Families",[237,1020,431],{"class":243},[237,1022,1023],{"class":361},"      families",[237,1025,443],{"class":243},[237,1027,1029,1032,1034,1037,1039,1042,1044,1046,1049,1051,1053,1056,1058,1060,1063,1065,1067,1069,1072,1074],{"class":239,"line":1028},59,[237,1030,1031],{"class":361},"        Entities",[237,1033,431],{"class":243},[237,1035,1036],{"class":243},"      map[",[237,1038,366],{"class":365},[237,1040,1041],{"class":243},"]",[237,1043,414],{"class":247},[237,1045,220],{"class":243},[237,1047,1048],{"class":247},"Entity",[237,1050,462],{"class":243},[237,1052,440],{"class":243},[237,1054,1055],{"class":372},"UK",[237,1057,440],{"class":243},[237,1059,431],{"class":243},[237,1061,1062],{"class":243}," {",[237,1064,459],{"class":361},[237,1066,431],{"class":243},[237,1068,470],{"class":243},[237,1070,1071],{"class":372},"1 High Street, London",[237,1073,440],{"class":243},[237,1075,681],{"class":243},[237,1077,1079,1082,1084,1086,1088,1090],{"class":239,"line":1078},60,[237,1080,1081],{"class":361},"        DefaultRegion",[237,1083,431],{"class":243},[237,1085,470],{"class":243},[237,1087,1055],{"class":372},[237,1089,440],{"class":243},[237,1091,443],{"class":243},[237,1093,1095],{"class":239,"line":1094},61,[237,1096,1097],{"class":243},"    })\n",[237,1099,1101,1104,1106,1109,1112],{"class":239,"line":1100},62,[237,1102,1103],{"class":261},"    if",[237,1105,928],{"class":361},[237,1107,1108],{"class":243},"!=",[237,1110,1111],{"class":243}," nil",[237,1113,355],{"class":243},[237,1115,1117,1120,1122,1125,1127,1130],{"class":239,"line":1116},63,[237,1118,1119],{"class":361},"        log",[237,1121,220],{"class":243},[237,1123,1124],{"class":407},"Fatal",[237,1126,411],{"class":243},[237,1128,1129],{"class":361},"err",[237,1131,328],{"class":243},[237,1133,1135],{"class":239,"line":1134},64,[237,1136,1137],{"class":243},"    }\n",[237,1139,1141],{"class":239,"line":1140},65,[237,1142,255],{"emptyLinePlaceholder":254},[237,1144,1146,1149,1151,1153,1155,1158,1160,1162,1164,1166,1169,1171,1173,1176,1178,1180,1183,1185],{"class":239,"line":1145},66,[237,1147,1148],{"class":361},"    to ",[237,1150,875],{"class":243},[237,1152,402],{"class":247},[237,1154,220],{"class":243},[237,1156,1157],{"class":247},"Recipient",[237,1159,462],{"class":243},[237,1161,459],{"class":361},[237,1163,431],{"class":243},[237,1165,470],{"class":243},[237,1167,1168],{"class":372},"ada@example.com",[237,1170,440],{"class":243},[237,1172,478],{"class":243},[237,1174,1175],{"class":361}," FirstName",[237,1177,431],{"class":243},[237,1179,470],{"class":243},[237,1181,1182],{"class":372},"Ada",[237,1184,440],{"class":243},[237,1186,382],{"class":243},[237,1188,1190,1193,1195,1197,1199,1202,1204,1207,1209,1212,1214,1217,1219,1221,1223,1226,1228,1230,1233,1235],{"class":239,"line":1189},67,[237,1191,1192],{"class":361},"    msg",[237,1194,478],{"class":243},[237,1196,928],{"class":361},[237,1198,875],{"class":243},[237,1200,1201],{"class":361}," welcome",[237,1203,220],{"class":243},[237,1205,1206],{"class":407},"Render",[237,1208,411],{"class":243},[237,1210,1211],{"class":361},"r",[237,1213,478],{"class":243},[237,1215,1216],{"class":361}," to",[237,1218,478],{"class":243},[237,1220,349],{"class":247},[237,1222,462],{"class":243},[237,1224,1225],{"class":361},"DashboardURL",[237,1227,431],{"class":243},[237,1229,470],{"class":243},[237,1231,1232],{"class":372},"https:\u002F\u002Facme.example\u002Fdashboard",[237,1234,440],{"class":243},[237,1236,707],{"class":243},[237,1238,1240,1242,1244,1246,1248],{"class":239,"line":1239},68,[237,1241,1103],{"class":261},[237,1243,928],{"class":361},[237,1245,1108],{"class":243},[237,1247,1111],{"class":243},[237,1249,355],{"class":243},[237,1251,1253,1255,1257,1259,1261,1263],{"class":239,"line":1252},69,[237,1254,1119],{"class":361},[237,1256,220],{"class":243},[237,1258,1124],{"class":407},[237,1260,411],{"class":243},[237,1262,1129],{"class":361},[237,1264,328],{"class":243},[237,1266,1268],{"class":239,"line":1267},70,[237,1269,1137],{"class":243},[237,1271,1273,1276,1278,1281,1283,1286,1288,1291],{"class":239,"line":1272},71,[237,1274,1275],{"class":361},"    fmt",[237,1277,220],{"class":243},[237,1279,1280],{"class":407},"Println",[237,1282,411],{"class":243},[237,1284,1285],{"class":361},"msg",[237,1287,220],{"class":243},[237,1289,1290],{"class":361},"Subject",[237,1292,328],{"class":243},[237,1294,1296,1298,1300,1303,1305,1307,1309,1312],{"class":239,"line":1295},72,[237,1297,1275],{"class":361},[237,1299,220],{"class":243},[237,1301,1302],{"class":407},"Print",[237,1304,411],{"class":243},[237,1306,1285],{"class":361},[237,1308,220],{"class":243},[237,1310,1311],{"class":361},"Text",[237,1313,328],{"class":243},[237,1315,1317],{"class":239,"line":1316},73,[237,1318,382],{"class":243},[227,1320,1326],{"className":1321,"code":1323,"filename":1324,"language":1325,"meta":233},[1322],"language-text","Welcome to Acme, Ada\nACME\n\nWelcome aboard.\n\nYour account is ready whenever you are.\n\nOpen your dashboard:\nhttps:\u002F\u002Facme.example\u002Fdashboard\n\nQuestions? Reply to this email.\n\n--\nAcme · 1 High Street, London\nNotification settings: https:\u002F\u002Facme.example\u002Fpreferences\n","Output","text",[201,1327,1323],{"__ignoreMap":233},[197,1329,1330],{},"The rest of this page takes the pieces one at a time.",[222,1332,1334],{"id":1333},"fill-the-config","Fill the config",[227,1336,1339],{"className":229,"code":1337,"filename":1338,"language":232,"meta":233,"style":233},"type Config struct {\n    Domain    string \u002F\u002F sending domain, e.g. \"example.com\"; the {domain} placeholder\n    SiteURL   string \u002F\u002F absolute https URL; the {site} placeholder\n    AssetBase string \u002F\u002F base URL of the logo files (absolute https, or relative when AllowRelativeURLs)\n\n    Theme    Theme     \u002F\u002F palettes, fonts and brand mark\n    Families *Registry \u002F\u002F the family registry templates are compiled against\n\n    Entities      map[string]Entity \u002F\u002F region → entity, for the footer address\n    DefaultRegion string            \u002F\u002F region used when a recipient has none; must be in Entities\n\n    AllowRelativeURLs bool \u002F\u002F previews only: relative asset and link URLs are allowed\n}\n","config.go",[201,1340,1341,1352,1362,1372,1382,1386,1396,1410,1414,1431,1441,1445,1456],{"__ignoreMap":233},[237,1342,1343,1345,1348,1350],{"class":239,"line":240},[237,1344,346],{"class":243},[237,1346,1347],{"class":247}," Config",[237,1349,352],{"class":243},[237,1351,355],{"class":243},[237,1353,1354,1357,1359],{"class":239,"line":251},[237,1355,1356],{"class":361},"    Domain    ",[237,1358,366],{"class":365},[237,1360,1361],{"class":339}," \u002F\u002F sending domain, e.g. \"example.com\"; the {domain} placeholder\n",[237,1363,1364,1367,1369],{"class":239,"line":258},[237,1365,1366],{"class":361},"    SiteURL   ",[237,1368,366],{"class":365},[237,1370,1371],{"class":339}," \u002F\u002F absolute https URL; the {site} placeholder\n",[237,1373,1374,1377,1379],{"class":239,"line":268},[237,1375,1376],{"class":361},"    AssetBase ",[237,1378,366],{"class":365},[237,1380,1381],{"class":339}," \u002F\u002F base URL of the logo files (absolute https, or relative when AllowRelativeURLs)\n",[237,1383,1384],{"class":239,"line":280},[237,1385,255],{"emptyLinePlaceholder":254},[237,1387,1388,1391,1393],{"class":239,"line":290},[237,1389,1390],{"class":361},"    Theme    ",[237,1392,883],{"class":247},[237,1394,1395],{"class":339},"     \u002F\u002F palettes, fonts and brand mark\n",[237,1397,1398,1401,1404,1407],{"class":239,"line":300},[237,1399,1400],{"class":361},"    Families ",[237,1402,1403],{"class":243},"*",[237,1405,1406],{"class":247},"Registry",[237,1408,1409],{"class":339}," \u002F\u002F the family registry templates are compiled against\n",[237,1411,1412],{"class":239,"line":305},[237,1413,255],{"emptyLinePlaceholder":254},[237,1415,1416,1419,1422,1424,1426,1428],{"class":239,"line":315},[237,1417,1418],{"class":361},"    Entities      ",[237,1420,1421],{"class":243},"map[",[237,1423,366],{"class":365},[237,1425,1041],{"class":243},[237,1427,1048],{"class":247},[237,1429,1430],{"class":339}," \u002F\u002F region → entity, for the footer address\n",[237,1432,1433,1436,1438],{"class":239,"line":325},[237,1434,1435],{"class":361},"    DefaultRegion ",[237,1437,366],{"class":365},[237,1439,1440],{"class":339},"            \u002F\u002F region used when a recipient has none; must be in Entities\n",[237,1442,1443],{"class":239,"line":331},[237,1444,255],{"emptyLinePlaceholder":254},[237,1446,1447,1450,1453],{"class":239,"line":336},[237,1448,1449],{"class":361},"    AllowRelativeURLs ",[237,1451,1452],{"class":365},"bool",[237,1454,1455],{"class":339}," \u002F\u002F previews only: relative asset and link URLs are allowed\n",[237,1457,1458],{"class":239,"line":343},[237,1459,382],{"class":243},[1461,1462,1463,1479],"table",{},[1464,1465,1466],"thead",{},[1467,1468,1469,1473,1476],"tr",{},[1470,1471,1472],"th",{},"Field",[1470,1474,1475],{},"Rule",[1470,1477,1478],{},"Used for",[1480,1481,1482,1502,1526,1544,1562,1579,1596,1617],"tbody",{},[1467,1483,1484,1490,1493],{},[1485,1486,1487],"td",{},[201,1488,1489],{},"Domain",[1485,1491,1492],{},"Non-empty",[1485,1494,1495,1498,1499],{},[201,1496,1497],{},"{domain}","; the sender domain of families without ",[201,1500,1501],{},"SenderDomain",[1467,1503,1504,1509,1516],{},[1485,1505,1506],{},[201,1507,1508],{},"SiteURL",[1485,1510,1511,1512,1515],{},"An absolute ",[201,1513,1514],{},"https"," URL with a host",[1485,1517,1518,1521,1522,1525],{},[201,1519,1520],{},"{site}","; the default preferences URL, ",[201,1523,1524],{},"SiteURL + \"\u002Fpreferences\""," (so leave off the trailing slash)",[1467,1527,1528,1533,1541],{},[1485,1529,1530],{},[201,1531,1532],{},"AssetBase",[1485,1534,1511,1535,1537,1538],{},[201,1536,1514],{}," URL, or a relative URL with ",[201,1539,1540],{},"AllowRelativeURLs",[1485,1542,1543],{},"The logo URLs",[1467,1545,1546,1550,1556],{},[1485,1547,1548],{},[201,1549,883],{},[1485,1551,1552,1555],{},[201,1553,1554],{},"Theme.Validate"," passes",[1485,1557,1558,1559],{},"See ",[1560,1561,79],"a",{"href":80},[1467,1563,1564,1569,1575],{},[1485,1565,1566],{},[201,1567,1568],{},"Families",[1485,1570,1571,1572,1555],{},"Not nil; ",[201,1573,1574],{},"Families.Validate(Domain)",[1485,1576,1558,1577],{},[1560,1578,74],{"href":75},[1467,1580,1581,1586,1591],{},[1485,1582,1583],{},[201,1584,1585],{},"Entities",[1485,1587,1588,1589],{},"Every entity has a non-empty ",[201,1590,459],{},[1485,1592,1593],{},[201,1594,1595],{},"{address}",[1467,1597,1598,1603,1608],{},[1485,1599,1600],{},[201,1601,1602],{},"DefaultRegion",[1485,1604,1605,1606],{},"A key of ",[201,1607,1585],{},[1485,1609,1610,1613,1614,1616],{},[201,1611,1612],{},"{region}"," and ",[201,1615,1595],{}," when the recipient has no region",[1467,1618,1619,1623,1626],{},[1485,1620,1621],{},[201,1622,1540],{},[1485,1624,1625],{},"—",[1485,1627,1628],{},"Previews only",[197,1630,1631,1632,1635,1636,1639],{},"There is no ",[201,1633,1634],{},"DefaultConfig",": every value is yours (D15). ",[201,1637,1638],{},"examples\u002Fquiet.Config(assetBase)"," returns the Quiet one.",[222,1641,1643],{"id":1642},"resolve-the-entity-address","Resolve the entity address",[197,1645,1646,1647,1649],{},"The footer's ",[201,1648,1595],{}," is the legal entity the mail is sent on behalf of. You list one per region:",[227,1651,1653],{"className":229,"code":1652,"filename":1338,"language":232,"meta":233,"style":233},"Entities: map[string]lttr.Entity{\n    \"St Kitts & Nevis\":  {Address: \"Basseterre, St Kitts\"},\n    \"Antigua & Barbuda\": {Address: \"St John's, Antigua\"},\n},\nDefaultRegion: \"St Kitts & Nevis\",\n",[201,1654,1655,1676,1703,1729,1733],{"__ignoreMap":233},[237,1656,1657,1659,1661,1664,1666,1668,1670,1672,1674],{"class":239,"line":240},[237,1658,1585],{"class":361},[237,1660,431],{"class":243},[237,1662,1663],{"class":243}," map[",[237,1665,366],{"class":365},[237,1667,1041],{"class":243},[237,1669,414],{"class":247},[237,1671,220],{"class":243},[237,1673,1048],{"class":247},[237,1675,422],{"class":243},[237,1677,1678,1680,1683,1685,1687,1690,1692,1694,1696,1699,1701],{"class":239,"line":251},[237,1679,271],{"class":243},[237,1681,1682],{"class":372},"St Kitts & Nevis",[237,1684,440],{"class":243},[237,1686,431],{"class":243},[237,1688,1689],{"class":243},"  {",[237,1691,459],{"class":361},[237,1693,431],{"class":243},[237,1695,470],{"class":243},[237,1697,1698],{"class":372},"Basseterre, St Kitts",[237,1700,440],{"class":243},[237,1702,493],{"class":243},[237,1704,1705,1707,1710,1712,1714,1716,1718,1720,1722,1725,1727],{"class":239,"line":258},[237,1706,271],{"class":243},[237,1708,1709],{"class":372},"Antigua & Barbuda",[237,1711,440],{"class":243},[237,1713,431],{"class":243},[237,1715,1062],{"class":243},[237,1717,459],{"class":361},[237,1719,431],{"class":243},[237,1721,470],{"class":243},[237,1723,1724],{"class":372},"St John's, Antigua",[237,1726,440],{"class":243},[237,1728,493],{"class":243},[237,1730,1731],{"class":239,"line":268},[237,1732,493],{"class":243},[237,1734,1735,1737,1739,1741,1743,1745],{"class":239,"line":280},[237,1736,1602],{"class":361},[237,1738,431],{"class":243},[237,1740,470],{"class":243},[237,1742,1682],{"class":372},[237,1744,440],{"class":243},[237,1746,443],{"class":243},[197,1748,1749,1750,1752,1753,1756,1757,1759,1760,1762,1763,1766,1767,1769,1770,1773,1774,220],{},"For each message, ",[201,1751,1206],{}," takes the region from ",[201,1754,1755],{},"Recipient.Region",", or ",[201,1758,1602],{}," when that is empty; that is ",[201,1761,1612],{},". The address is ",[201,1764,1765],{},"Recipient.EntityAddress"," when set, otherwise the address of that region's entity. A recipient whose region is not in ",[201,1768,1585],{}," and who has no ",[201,1771,1772],{},"EntityAddress"," fails with ",[201,1775,1776],{},"render: no entity address for region \"FR\"",[197,1778,1779],{},"The recipient carries the rest of the per-person values:",[227,1781,1784],{"className":229,"code":1782,"filename":1783,"language":232,"meta":233,"style":233},"type Recipient struct {\n    Address        string \u002F\u002F RFC 5322 address\n    FirstName      string `json:\"first_name\"`\n    Region         string `json:\"region\"`\n    EntityAddress  string `json:\"entity_address\"`\n    PreferencesURL string `json:\"preferences_url\"`\n    UnsubscribeURL string `json:\"unsubscribe_url\"`\n}\n","data\u002Ftypes.go",[201,1785,1786,1797,1807,1821,1835,1849,1863,1877],{"__ignoreMap":233},[237,1787,1788,1790,1793,1795],{"class":239,"line":240},[237,1789,346],{"class":243},[237,1791,1792],{"class":247}," Recipient",[237,1794,352],{"class":243},[237,1796,355],{"class":243},[237,1798,1799,1802,1804],{"class":239,"line":251},[237,1800,1801],{"class":361},"    Address        ",[237,1803,366],{"class":365},[237,1805,1806],{"class":339}," \u002F\u002F RFC 5322 address\n",[237,1808,1809,1812,1814,1816,1819],{"class":239,"line":258},[237,1810,1811],{"class":361},"    FirstName      ",[237,1813,366],{"class":365},[237,1815,369],{"class":243},[237,1817,1818],{"class":372},"json:\"first_name\"",[237,1820,376],{"class":243},[237,1822,1823,1826,1828,1830,1833],{"class":239,"line":268},[237,1824,1825],{"class":361},"    Region         ",[237,1827,366],{"class":365},[237,1829,369],{"class":243},[237,1831,1832],{"class":372},"json:\"region\"",[237,1834,376],{"class":243},[237,1836,1837,1840,1842,1844,1847],{"class":239,"line":280},[237,1838,1839],{"class":361},"    EntityAddress  ",[237,1841,366],{"class":365},[237,1843,369],{"class":243},[237,1845,1846],{"class":372},"json:\"entity_address\"",[237,1848,376],{"class":243},[237,1850,1851,1854,1856,1858,1861],{"class":239,"line":290},[237,1852,1853],{"class":361},"    PreferencesURL ",[237,1855,366],{"class":365},[237,1857,369],{"class":243},[237,1859,1860],{"class":372},"json:\"preferences_url\"",[237,1862,376],{"class":243},[237,1864,1865,1868,1870,1872,1875],{"class":239,"line":300},[237,1866,1867],{"class":361},"    UnsubscribeURL ",[237,1869,366],{"class":365},[237,1871,369],{"class":243},[237,1873,1874],{"class":372},"json:\"unsubscribe_url\"",[237,1876,376],{"class":243},[237,1878,1879],{"class":239,"line":305},[237,1880,382],{"class":243},[197,1882,1883,1886,1887,1889,1890,1893,1894,1898,1899,220],{},[201,1884,1885],{},"PreferencesURL"," falls back to ",[201,1888,1524],{},". ",[201,1891,1892],{},"UnsubscribeURL"," has no fallback: marketing mail needs it (see ",[1560,1895,1897],{"href":1896},"\u002Frendering\u002Ffamilies-and-streams#choose-a-stream","streams","). Templates can use these fields as merge tags, such as ",[201,1900,1901],{},"{{first_name}}",[222,1903,1905],{"id":1904},"serve-the-logos","Serve the logos",[197,1907,1908,1910,1911,1913,1914,1613,1917,1920,1921,1924],{},[201,1909,1532],{}," is where your logo files live. The header's logo URLs are ",[201,1912,1532],{}," with a single ",[201,1915,1916],{},"\u002F",[201,1918,1919],{},"Theme.Brand.Logo"," or ",[201,1922,1923],{},"Theme.Brand.LogoDark"," appended:",[1461,1926,1927,1943],{},[1464,1928,1929],{},[1467,1930,1931,1935,1940],{},[1470,1932,1933],{},[201,1934,1532],{},[1470,1936,1937],{},[201,1938,1939],{},"Brand.Logo",[1470,1941,1942],{},"Logo URL",[1480,1944,1945,1961,1976],{},[1467,1946,1947,1951,1956],{},[1485,1948,1949],{},[201,1950,995],{},[1485,1952,1953],{},[201,1954,1955],{},"logo.png",[1485,1957,1958],{},[201,1959,1960],{},"https:\u002F\u002Fcdn.acme.example\u002Femail\u002Flogo.png",[1467,1962,1963,1968,1972],{},[1485,1964,1965],{},[201,1966,1967],{},"https:\u002F\u002Fcdn.acme.example\u002Femail\u002F",[1485,1969,1970],{},[201,1971,1955],{},[1485,1973,1974],{},[201,1975,1960],{},[1467,1977,1978,1984,1988],{},[1485,1979,1980,1983],{},[201,1981,1982],{},"\u002Fgallery\u002Fassets"," (preview only)",[1485,1985,1986],{},[201,1987,1955],{},[1485,1989,1990],{},[201,1991,1992],{},"\u002Fgallery\u002Fassets\u002Flogo.png",[197,1994,1995],{},"Host the files where mail clients can fetch them over https. lttr links to them; it does not attach them to the message.",[222,1997,1999],{"id":1998},"allow-relative-urls-in-previews","Allow relative URLs in previews",[197,2001,2002,2005,2006,2008,2009,2012,2013,2016,2017,2019,2020,1613,2022,2024,2025,220],{},[201,2003,2004],{},"AllowRelativeURLs: true"," lets ",[201,2007,1532],{},", and every link and image in a template, be relative. It exists for local previews, where the logos are served next to the HTML (",[201,2010,2011],{},"lttr preview -assets",", ",[201,2014,2015],{},"lttr serve","). Never set it for mail you send: a relative URL means nothing in an inbox. Without it, ",[201,2018,211],{}," refuses a relative ",[201,2021,1532],{},[201,2023,1206],{}," refuses a relative link with ",[201,2026,2027],{},"relative url not allowed",[222,2029,2031],{"id":2030},"build-the-renderer","Build the renderer",[227,2033,2036],{"className":229,"code":2034,"filename":2035,"language":232,"meta":233,"style":233},"func NewRenderer(cfg Config) (*Renderer, error)\n","renderer.go",[201,2037,2038],{"__ignoreMap":233},[237,2039,2040,2042,2045,2047,2051,2053,2056,2059,2062,2064,2067],{"class":239,"line":240},[237,2041,858],{"class":243},[237,2043,2044],{"class":407}," NewRenderer",[237,2046,411],{"class":243},[237,2048,2050],{"class":2049},"sHdIc","cfg",[237,2052,1347],{"class":247},[237,2054,2055],{"class":243},")",[237,2057,2058],{"class":243}," (*",[237,2060,2061],{"class":247},"Renderer",[237,2063,478],{"class":243},[237,2065,2066],{"class":365}," error",[237,2068,328],{"class":243},[197,2070,2071,2073],{},[201,2072,211],{}," validates the whole config and compiles every family's copy once. It reports every problem together, one per line. For this config:",[227,2075,2077],{"className":229,"code":2076,"filename":1338,"language":232,"meta":233,"style":233},"th := quiet.Theme()\nth.Light.Ink = \"red\"\n_, err := lttr.NewRenderer(lttr.Config{\n    Domain: \"acme.example\", SiteURL: \"http:\u002F\u002Facme.example\", AssetBase: \"assets\",\n    Theme: th, Families: news, \u002F\u002F one H3 family: no Masthead, Reason \"You subscribed. {nope}\"\n    Entities:      map[string]lttr.Entity{\"UK\": {Address: \"1 High Street, London\"}},\n    DefaultRegion: \"GB\",\n})\n",[201,2078,2079,2095,2118,2145,2188,2213,2256,2272],{"__ignoreMap":233},[237,2080,2081,2084,2086,2088,2090,2092],{"class":239,"line":240},[237,2082,2083],{"class":361},"th ",[237,2085,875],{"class":243},[237,2087,878],{"class":361},[237,2089,220],{"class":243},[237,2091,883],{"class":407},[237,2093,2094],{"class":243},"()\n",[237,2096,2097,2099,2101,2104,2106,2109,2111,2113,2116],{"class":239,"line":251},[237,2098,1470],{"class":361},[237,2100,220],{"class":243},[237,2102,2103],{"class":361},"Light",[237,2105,220],{"class":243},[237,2107,2108],{"class":361},"Ink ",[237,2110,399],{"class":243},[237,2112,470],{"class":243},[237,2114,2115],{"class":372},"red",[237,2117,277],{"class":243},[237,2119,2120,2123,2125,2127,2129,2131,2133,2135,2137,2139,2141,2143],{"class":239,"line":258},[237,2121,2122],{"class":361},"_",[237,2124,478],{"class":243},[237,2126,928],{"class":361},[237,2128,875],{"class":243},[237,2130,402],{"class":361},[237,2132,220],{"class":243},[237,2134,211],{"class":407},[237,2136,411],{"class":243},[237,2138,414],{"class":247},[237,2140,220],{"class":243},[237,2142,203],{"class":247},[237,2144,422],{"class":243},[237,2146,2147,2150,2152,2154,2156,2158,2160,2163,2165,2167,2170,2172,2174,2177,2179,2181,2184,2186],{"class":239,"line":268},[237,2148,2149],{"class":361},"    Domain",[237,2151,431],{"class":243},[237,2153,470],{"class":243},[237,2155,960],{"class":372},[237,2157,440],{"class":243},[237,2159,478],{"class":243},[237,2161,2162],{"class":361}," SiteURL",[237,2164,431],{"class":243},[237,2166,470],{"class":243},[237,2168,2169],{"class":372},"http:\u002F\u002Facme.example",[237,2171,440],{"class":243},[237,2173,478],{"class":243},[237,2175,2176],{"class":361}," AssetBase",[237,2178,431],{"class":243},[237,2180,470],{"class":243},[237,2182,2183],{"class":372},"assets",[237,2185,440],{"class":243},[237,2187,443],{"class":243},[237,2189,2190,2193,2195,2198,2200,2203,2205,2208,2210],{"class":239,"line":280},[237,2191,2192],{"class":361},"    Theme",[237,2194,431],{"class":243},[237,2196,2197],{"class":361}," th",[237,2199,478],{"class":243},[237,2201,2202],{"class":361}," Families",[237,2204,431],{"class":243},[237,2206,2207],{"class":361}," news",[237,2209,478],{"class":243},[237,2211,2212],{"class":339}," \u002F\u002F one H3 family: no Masthead, Reason \"You subscribed. {nope}\"\n",[237,2214,2215,2218,2220,2222,2224,2226,2228,2230,2232,2234,2236,2238,2240,2242,2244,2246,2248,2250,2252,2254],{"class":239,"line":290},[237,2216,2217],{"class":361},"    Entities",[237,2219,431],{"class":243},[237,2221,1036],{"class":243},[237,2223,366],{"class":365},[237,2225,1041],{"class":243},[237,2227,414],{"class":247},[237,2229,220],{"class":243},[237,2231,1048],{"class":247},[237,2233,462],{"class":243},[237,2235,440],{"class":243},[237,2237,1055],{"class":372},[237,2239,440],{"class":243},[237,2241,431],{"class":243},[237,2243,1062],{"class":243},[237,2245,459],{"class":361},[237,2247,431],{"class":243},[237,2249,470],{"class":243},[237,2251,1071],{"class":372},[237,2253,440],{"class":243},[237,2255,681],{"class":243},[237,2257,2258,2261,2263,2265,2268,2270],{"class":239,"line":300},[237,2259,2260],{"class":361},"    DefaultRegion",[237,2262,431],{"class":243},[237,2264,470],{"class":243},[237,2266,2267],{"class":372},"GB",[237,2269,440],{"class":243},[237,2271,443],{"class":243},[237,2273,2274],{"class":239,"line":305},[237,2275,707],{"class":243},[227,2277,2281],{"className":2278,"code":2279,"filename":2280,"language":1325,"meta":233},[1322],"config: SiteURL \"http:\u002F\u002Facme.example\" must be an absolute https URL\nconfig: AssetBase \"assets\" must be an absolute https URL\ntheme: Light.Ink: invalid colour \"red\" (want #RRGGBB)\nconfig: DefaultRegion \"GB\" is not in Entities\nfamily \"news\": header H3 requires a masthead\nfamily \"news\" Copy.Reason:1:17: unknown placeholder \"{nope}\"\n","Error",[201,2282,2279],{"__ignoreMap":233},[197,2284,2285,2286,2288,2289,2291,2292,2294,2295,2297,2298,2300,2301,2303],{},"It refuses an empty ",[201,2287,1489],{},"; a ",[201,2290,1508],{}," that is not an absolute https URL; an empty or invalid ",[201,2293,1532],{},"; an invalid theme; a nil ",[201,2296,1568],{}," or one that does not validate; a ",[201,2299,1602],{}," that is not in ",[201,2302,1585],{},"; and an entity with an empty address.",[197,2305,2306,2307,2309,2310,2312],{},"A ",[201,2308,207],{}," is immutable and safe for concurrent use. It keeps its own copy of ",[201,2311,1585],{},". Build one at start-up and share it.",[222,2314,2316],{"id":2315},"compile-templates","Compile templates",[227,2318,2321],{"className":229,"code":2319,"filename":2320,"language":232,"meta":233,"style":233},"func Compile[T any](reg *Registry, name string, src []byte) (*Template[T], error)\nfunc MustCompile[T any](reg *Registry, name string, src []byte) *Template[T]\n","template.go",[201,2322,2323,2383],{"__ignoreMap":233},[237,2324,2325,2327,2330,2332,2335,2338,2340,2343,2346,2348,2350,2353,2356,2358,2361,2363,2365,2367,2369,2372,2374,2376,2379,2381],{"class":239,"line":240},[237,2326,858],{"class":243},[237,2328,2329],{"class":407}," Compile",[237,2331,732],{"class":243},[237,2333,2334],{"class":2049},"T",[237,2336,2337],{"class":247}," any",[237,2339,738],{"class":243},[237,2341,2342],{"class":2049},"reg",[237,2344,2345],{"class":243}," *",[237,2347,1406],{"class":247},[237,2349,478],{"class":243},[237,2351,2352],{"class":2049}," name",[237,2354,2355],{"class":365}," string",[237,2357,478],{"class":243},[237,2359,2360],{"class":2049}," src",[237,2362,642],{"class":243},[237,2364,757],{"class":365},[237,2366,2055],{"class":243},[237,2368,2058],{"class":243},[237,2370,2371],{"class":247},"Template",[237,2373,732],{"class":243},[237,2375,2334],{"class":247},[237,2377,2378],{"class":243},"],",[237,2380,2066],{"class":365},[237,2382,328],{"class":243},[237,2384,2385,2387,2390,2392,2394,2396,2398,2400,2402,2404,2406,2408,2410,2412,2414,2416,2418,2420,2422,2424,2426,2428],{"class":239,"line":251},[237,2386,858],{"class":243},[237,2388,2389],{"class":407}," MustCompile",[237,2391,732],{"class":243},[237,2393,2334],{"class":2049},[237,2395,2337],{"class":247},[237,2397,738],{"class":243},[237,2399,2342],{"class":2049},[237,2401,2345],{"class":243},[237,2403,1406],{"class":247},[237,2405,478],{"class":243},[237,2407,2352],{"class":2049},[237,2409,2355],{"class":365},[237,2411,478],{"class":243},[237,2413,2360],{"class":2049},[237,2415,642],{"class":243},[237,2417,757],{"class":365},[237,2419,2055],{"class":243},[237,2421,2345],{"class":243},[237,2423,2371],{"class":247},[237,2425,732],{"class":243},[237,2427,2334],{"class":247},[237,2429,2430],{"class":243},"]\n",[197,2432,2433,2436,2437,2439,2440,2442,2443,1889,2447,2450,2451,2454,2455,2458,2459,2462,2463,220],{},[201,2434,2435],{},"Compile"," checks the template against its data type ",[201,2438,2334],{}," (which must be a struct) and the families in ",[201,2441,2342],{},": the Comark source, the frontmatter, every module and prop, every merge tag and binding, and the ",[1560,2444,2446],{"href":2445},"\u002Frendering\u002Ffamilies-and-streams#know-what-compile-checks","family rules",[201,2448,2449],{},"name"," must equal the frontmatter's ",[201,2452,2453],{},"template:",". On failure it returns every error joined; each is an ",[201,2456,2457],{},"*ir.Error"," carrying ",[201,2460,2461],{},"name:line:col",". See ",[1560,2464,63],{"href":64},[197,2466,2467,2469],{},[201,2468,729],{}," panics instead. Use it for package-level templates, so a broken template stops the program at start-up rather than at the first send:",[227,2471,2474],{"className":229,"code":2472,"filename":2473,"language":232,"meta":233,"style":233},"\u002F\u002Fgo:embed templates\u002Fwelcome.md\nvar welcomeSrc []byte\n\nvar Welcome = lttr.MustCompile[WelcomeData](Families, \"account.welcome\", welcomeSrc)\n","templates.go",[201,2475,2476,2481,2494,2498],{"__ignoreMap":233},[237,2477,2478],{"class":239,"line":240},[237,2479,2480],{"class":339},"\u002F\u002Fgo:embed templates\u002Fwelcome.md\n",[237,2482,2483,2485,2488,2491],{"class":239,"line":251},[237,2484,393],{"class":243},[237,2486,2487],{"class":361}," welcomeSrc ",[237,2489,2490],{"class":243},"[]",[237,2492,2493],{"class":365},"byte\n",[237,2495,2496],{"class":239,"line":258},[237,2497,255],{"emptyLinePlaceholder":254},[237,2499,2500,2502,2505,2507,2509,2511,2513,2515,2518,2520,2522,2524,2526,2528,2530,2532,2535],{"class":239,"line":268},[237,2501,393],{"class":243},[237,2503,2504],{"class":361}," Welcome ",[237,2506,399],{"class":243},[237,2508,402],{"class":361},[237,2510,220],{"class":243},[237,2512,729],{"class":407},[237,2514,732],{"class":243},[237,2516,2517],{"class":247},"WelcomeData",[237,2519,738],{"class":243},[237,2521,1568],{"class":361},[237,2523,478],{"class":243},[237,2525,470],{"class":243},[237,2527,748],{"class":372},[237,2529,440],{"class":243},[237,2531,478],{"class":243},[237,2533,2534],{"class":361}," welcomeSrc",[237,2536,328],{"class":243},[197,2538,2306,2539,2542],{},[201,2540,2541],{},"*Template[T]"," is immutable and safe for concurrent use.",[222,2544,2546],{"id":2545},"inspect-a-template","Inspect a template",[227,2548,2550],{"className":229,"code":2549,"filename":2320,"language":232,"meta":233,"style":233},"func (t *Template[T]) Name() string\nfunc (t *Template[T]) Meta() TemplateMeta\n",[201,2551,2552,2581],{"__ignoreMap":233},[237,2553,2554,2556,2559,2562,2564,2566,2568,2570,2573,2576,2578],{"class":239,"line":240},[237,2555,858],{"class":243},[237,2557,2558],{"class":243}," (",[237,2560,2561],{"class":2049},"t ",[237,2563,1403],{"class":243},[237,2565,2371],{"class":247},[237,2567,732],{"class":243},[237,2569,2334],{"class":247},[237,2571,2572],{"class":243},"])",[237,2574,2575],{"class":407}," Name",[237,2577,864],{"class":243},[237,2579,2580],{"class":365}," string\n",[237,2582,2583,2585,2587,2589,2591,2593,2595,2597,2599,2602,2604],{"class":239,"line":251},[237,2584,858],{"class":243},[237,2586,2558],{"class":243},[237,2588,2561],{"class":2049},[237,2590,1403],{"class":243},[237,2592,2371],{"class":247},[237,2594,732],{"class":243},[237,2596,2334],{"class":247},[237,2598,2572],{"class":243},[237,2600,2601],{"class":407}," Meta",[237,2603,864],{"class":243},[237,2605,2606],{"class":247}," TemplateMeta\n",[197,2608,2609,2612],{},[201,2610,2611],{},"Meta"," returns a copy of what the compiler learned:",[1461,2614,2615,2624],{},[1464,2616,2617],{},[1467,2618,2619,2621],{},[1470,2620,1472],{},[1470,2622,2623],{},"Meaning",[1480,2625,2626,2637,2650,2663,2678],{},[1467,2627,2628,2634],{},[1485,2629,2630,2012,2632],{},[201,2631,465],{},[201,2633,419],{},[1485,2635,2636],{},"The template and family names",[1467,2638,2639,2644],{},[1485,2640,2641],{},[201,2642,2643],{},"Stream",[1485,2645,2646,2647],{},"The family's stream, or its legal stream with ",[201,2648,2649],{},"legal: true",[1467,2651,2652,2657],{},[1485,2653,2654],{},[201,2655,2656],{},"Tags",[1485,2658,2659,2660],{},"Every merge tag and binding in source order, as ",[201,2661,2662],{},"TagInfo{Path, Type, Pos, Binding}",[1467,2664,2665,2669],{},[1485,2666,2667],{},[201,2668,48],{},[1485,2670,2671,2672,2012,2675],{},"The module kinds in order, e.g. ",[201,2673,2674],{},"statement",[201,2676,2677],{},"receipt",[1467,2679,2680,2685],{},[1485,2681,2682],{},[201,2683,2684],{},"Warnings",[1485,2686,2687,2688],{},"Compile warnings, formatted ",[201,2689,2690],{},"name:line:col: warning: msg",[197,2692,2693,2694,2697,2698,2558,2701,2012,2703,2706,2707,2558,2710,2012,2712,2715,2716,2719],{},"For the welcome template above, ",[201,2695,2696],{},"Meta().Tags"," is ",[201,2699,2700],{},"first_name",[201,2702,366],{},[201,2704,2705],{},"4:28",") and ",[201,2708,2709],{},"dashboard_url",[201,2711,366],{},[201,2713,2714],{},"13:36","). For the Quiet examples, ",[201,2717,2718],{},"lttr tags -t order.out_for_delivery"," prints the same list from the command line.",[222,2721,2723],{"id":2722},"render-a-message","Render a message",[227,2725,2728],{"className":229,"code":2726,"filename":2727,"language":232,"meta":233,"style":233},"func (t *Template[T]) Render(r *Renderer, to Recipient, v T) (*Message, error)\n","render.go",[201,2729,2730],{"__ignoreMap":233},[237,2731,2732,2734,2736,2738,2740,2742,2744,2746,2748,2751,2753,2755,2757,2759,2761,2763,2765,2767,2770,2773,2775,2777,2780,2782,2784],{"class":239,"line":240},[237,2733,858],{"class":243},[237,2735,2558],{"class":243},[237,2737,2561],{"class":2049},[237,2739,1403],{"class":243},[237,2741,2371],{"class":247},[237,2743,732],{"class":243},[237,2745,2334],{"class":247},[237,2747,2572],{"class":243},[237,2749,2750],{"class":407}," Render",[237,2752,411],{"class":243},[237,2754,1211],{"class":2049},[237,2756,2345],{"class":243},[237,2758,2061],{"class":247},[237,2760,478],{"class":243},[237,2762,1216],{"class":2049},[237,2764,1792],{"class":247},[237,2766,478],{"class":243},[237,2768,2769],{"class":2049}," v",[237,2771,2772],{"class":247}," T",[237,2774,2055],{"class":243},[237,2776,2058],{"class":243},[237,2778,2779],{"class":247},"Message",[237,2781,478],{"class":243},[237,2783,2066],{"class":365},[237,2785,328],{"class":243},[197,2787,2788,2790,2791,1613,2794,2797,2798,2800,2801,2804],{},[201,2789,1206],{}," evaluates the template with ",[201,2792,2793],{},"v",[201,2795,2796],{},"to",", lays it out, renders the HTML and plain-text parts, and returns a ",[201,2799,219],{}," holding the envelope, subject, preheader, both bodies, the stream, the tracking flag and any warnings. On a marketing stream it also sets the one-click ",[201,2802,2803],{},"List-Unsubscribe"," headers. On error the message is nil. It is safe for concurrent use.",[197,2806,2807],{},"Everything that depends on data is checked here, and any failure is an error rather than a broken email:",[2809,2810,2811,2822,2831,2856,2866,2876,2889,2903,2917,2925,2937,2950],"ul",{},[2812,2813,2814,2818,2819,220],"li",{},[2815,2816,2817],"strong",{},"The family"," must be in the renderer's registry: ",[201,2820,2821],{},"render: family \"x\" is not in this renderer's registry",[2812,2823,2824,2827,2828,220],{},[2815,2825,2826],{},"Merge tags"," without a fallback need a value (D8: a nil pointer on the path, a missing map key or an empty formatted value count as none): ",[201,2829,2830],{},"account.welcome:13:36: no value for {{dashboard_url}}",[2812,2832,2833,2836,2837,2840,2841,2012,2843,2012,2846,1920,2849,2852,2853,220],{},[2815,2834,2835],{},"URLs"," must pass ",[201,2838,2839],{},"CheckURL",": ",[201,2842,1514],{},[201,2844,2845],{},"http",[201,2847,2848],{},"mailto",[201,2850,2851],{},"tel",", no whitespace or control characters, a host for http(s), an address for mailto and tel, never empty. This covers links, buttons, logos, images, tiles, thumbnails, footer nav and the text-only footer URLs (D31, D34): ",[201,2854,2855],{},"account.welcome:13:1: url \"javascript:alert(1)\": scheme \"javascript\" not allowed",[2812,2857,2858,2861,2862,2865],{},[2815,2859,2860],{},"URL merge values"," are escaped. Only a merge tag or placeholder that opens a URL is inserted as it is; any later value is percent-escaped, so a value cannot add a query parameter or move the host (D34). Pass whole URLs as data (",[201,2863,2864],{},"href=\"{{track_url}}\"",") rather than assembling them from parts.",[2812,2867,2868,2871,2872,2875],{},[2815,2869,2870],{},"Images"," with a source need alt text: ",[201,2873,2874],{},"image: alt is empty for src",", likewise for maps, stories, products and receipt thumbnails.",[2812,2877,2878,2881,2882,1920,2885,2888],{},[2815,2879,2880],{},"Lists"," bound to ",[201,2883,2884],{},"stock",[201,2886,2887],{},"products"," must not be empty, and every action, story and product link must evaluate to a URL (D31).",[2812,2890,2891,2894,2895,2898,2899,2902],{},[2815,2892,2893],{},"The subject"," must not be empty or contain CR, LF or NUL: ",[201,2896,2897],{},"subject is empty",", reported at the ",[201,2900,2901],{},"subject"," key.",[2812,2904,2905,2908,2909,2912,2913,2916],{},[2815,2906,2907],{},"The recipient"," address must parse and be a plain ",[201,2910,2911],{},"local@domain"," address, and ",[201,2914,2915],{},"FirstName",", which becomes the display name, must not contain CR, LF or NUL (D34).",[2812,2918,2919,2922,2923,220],{},[2815,2920,2921],{},"The region"," must have an entity address: ",[201,2924,1776],{},[2812,2926,2927,2933,2934,220],{},[2815,2928,2929,2930],{},"A frontmatter ",[201,2931,2932],{},"from"," must be a plain address on the family's sender domain: ",[201,2935,2936],{},"from \"x@elsewhere.com\" is not on partners.acme.example",[2812,2938,2939,2942,2943,2840,2946,2949],{},[2815,2940,2941],{},"Marketing mail"," needs an https ",[201,2944,2945],{},"Recipient.UnsubscribeURL",[201,2947,2948],{},"render: marketing mail needs an unsubscribe url"," with an F1 footer.",[2812,2951,2952,2955],{},[2815,2953,2954],{},"The HTML"," must stay under 100 KB.",[197,2957,2958,2959,2961],{},"Errors that come from the template carry ",[201,2960,2461],{},", so they read like compile errors.",[222,2963,2965],{"id":2964},"stay-under-the-size-limit","Stay under the size limit",[197,2967,2968,2969,2971],{},"Gmail clips a message whose HTML is over 102 KB and hides the rest behind a link. ",[201,2970,1206],{}," enforces a margin below that:",[1461,2973,2974,2984],{},[1464,2975,2976],{},[1467,2977,2978,2981],{},[1470,2979,2980],{},"Rendered HTML",[1470,2982,2983],{},"Result",[1480,2985,2986,2994,3008],{},[1467,2987,2988,2991],{},[1485,2989,2990],{},"90 KB (92,160 bytes) or less",[1485,2992,2993],{},"Nothing",[1467,2995,2996,2999],{},[1485,2997,2998],{},"Over 90 KB",[1485,3000,3001,3002,2840,3005],{},"A warning in ",[201,3003,3004],{},"Message.Warnings",[201,3006,3007],{},"name: warning: html is N bytes; gmail clips at 102 KB",[1467,3009,3010,3013],{},[1485,3011,3012],{},"100 KB (102,400 bytes) or more",[1485,3014,3015,3016],{},"An error: ",[201,3017,3018],{},"render: html is N bytes; gmail clips at 102 KB",[197,3020,3021],{},"The Quiet examples render between 9 and 16 KB. A long bound list (products, stock, a big table) is the usual way to grow past the limit.",[3023,3024,3025],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"title":233,"searchDepth":251,"depth":251,"links":3027},[3028,3029,3030,3031,3032,3033,3034,3035,3036,3037],{"id":224,"depth":251,"text":225},{"id":1333,"depth":251,"text":1334},{"id":1642,"depth":251,"text":1643},{"id":1904,"depth":251,"text":1905},{"id":1998,"depth":251,"text":1999},{"id":2030,"depth":251,"text":2031},{"id":2315,"depth":251,"text":2316},{"id":2545,"depth":251,"text":2546},{"id":2722,"depth":251,"text":2723},{"id":2964,"depth":251,"text":2965},"Build a Renderer from a Config, compile templates against your families, and render them for a recipient.","md",null,{},{"icon":87},{"title":84,"description":3038},"Y63sYTaSq1vWnaziZMbEOQtmBb3PNdtGKqyZPrOlkow",[3046,3048],{"title":79,"path":80,"stem":81,"description":3047,"icon":82,"children":-1},"Give lttr your colours, font stacks and logo with theme.Theme, and see where each value ends up in the email.",{"title":89,"path":90,"stem":91,"description":3049,"icon":92,"children":-1},"How lttr decides the space above and below every module, from class defaults, pair rules and position rules.",1790309827691]