[{"data":1,"prerenderedAt":687},["ShallowReactive",2],{"navigation_docs":3,"-tooling-live-preview":191,"-tooling-live-preview-surround":682},[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":141,"body":193,"description":675,"extension":676,"links":677,"meta":678,"navigation":679,"path":142,"seo":680,"stem":143,"__hash__":681},"docs\u002F5.tooling\u002F2.live-preview.md",{"type":194,"value":195,"toc":667},"minimark",[196,204,261,268,273,301,315,337,353,357,368,399,413,417,434,545,558,582,589,601,644,648,663],[197,198,199,203],"p",{},[200,201,202],"code",{},"lttr serve"," (D17) is the day-to-day way to see templates while editing them: it compiles from disk on every request, so a save shows up on the next load with no restart.",[205,206,212],"pre",{"className":207,"code":208,"filename":209,"language":210,"meta":211,"style":211},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","make serve\n# or directly:\ngo run .\u002Fcmd\u002Flttr serve -addr localhost:7070 -dir examples\u002Fquiet\u002Ftemplates\n","Terminal","bash","",[200,213,214,227,234],{"__ignoreMap":211},[215,216,219,223],"span",{"class":217,"line":218},"line",1,[215,220,222],{"class":221},"sBMFI","make",[215,224,226],{"class":225},"sfazB"," serve\n",[215,228,230],{"class":217,"line":229},2,[215,231,233],{"class":232},"sHwdD","# or directly:\n",[215,235,237,240,243,246,249,252,255,258],{"class":217,"line":236},3,[215,238,239],{"class":221},"go",[215,241,242],{"class":225}," run",[215,244,245],{"class":225}," .\u002Fcmd\u002Flttr",[215,247,248],{"class":225}," serve",[215,250,251],{"class":225}," -addr",[215,253,254],{"class":225}," localhost:7070",[215,256,257],{"class":225}," -dir",[215,259,260],{"class":225}," examples\u002Fquiet\u002Ftemplates\n",[197,262,263,264,267],{},"opens ",[200,265,266],{},"http:\u002F\u002Flocalhost:7070",".",[269,270,272],"h2",{"id":271},"watch-the-reload-loop","Watch the reload loop",[197,274,275,276,279,280,284,285,288,289,292,293,296,297,300],{},"Unlike ",[200,277,278],{},"lttr preview",", which renders the nine ",[281,282,283],"strong",{},"embedded"," sources once into static files, ",[200,286,287],{},"serve"," reads each template's file from ",[200,290,291],{},"-dir"," (default ",[200,294,295],{},"examples\u002Fquiet\u002Ftemplates",") fresh on every request — so editing ",[200,298,299],{},"examples\u002Fquiet\u002Ftemplates\u002F01-order-shipped.md"," and reloading shows the change immediately, no rebuild.",[197,302,303,304,307,308,311,312,314],{},"The index page itself polls ",[200,305,306],{},"GET \u002F_version"," once a second. ",[200,309,310],{},"\u002F_version"," hashes the name, size and modification time of every file in ",[200,313,291],{},"; when the hash changes, the page:",[316,317,318,330],"ol",{},[319,320,321,322,325,326,329],"li",{},"Fetches ",[200,323,324],{},"\u002F"," again and swaps in the refreshed sidebar list and detail sections (",[200,327,328],{},"innerHTML",", not a full page reload).",[319,331,332,333,336],{},"Re-selects whatever template was open and reloads its preview frames from ",[200,334,335],{},"\u002Ft\u002F{base}.html?v={version}"," — the version query string busts the browser's cache for that frame.",[197,338,339,340,343,344,346,347,349,350,352],{},"The ",[200,341,342],{},"live"," badge in the header shows this is happening (green dot, \"live\"); if ",[200,345,310],{}," fails to answer, it flips to \"offline\" (grey) until polling succeeds again. This loop is what makes ",[200,348,202],{}," a live preview and ",[200,351,278],{},"'s output a one-shot snapshot.",[269,354,356],{"id":355},"read-errors-in-the-preview","Read errors in the preview",[197,358,359,360,363,364,367],{},"A compile or render error never breaks the page. Errors are formatted as ",[200,361,362],{},"file:line:col: message"," (or ",[200,365,366],{},"file: message"," for one with no position) and shown two places:",[369,370,371,381],"ul",{},[319,372,373,376,377,380],{},[281,374,375],{},"The sidebar"," replaces that template's family\u002Fstream\u002Fsubject line with a red ",[200,378,379],{},"N error(s)"," badge.",[319,382,383,386,387,390,391,394,395,398],{},[281,384,385],{},"Its preview frame"," (",[200,388,389],{},"\u002Ft\u002F{base}.html",") serves a small standalone error page — dark red on a light red background, monospace, one ",[200,392,393],{},"\u003Cli>"," per error line — in place of the rendered HTML, with HTTP status ",[281,396,397],{},"200"," (not 500), so it renders inside the iframe instead of showing the browser's own error page.",[197,400,401,404,405,408,409,412],{},[200,402,403],{},"\u002Ft\u002F{base}.txt"," and ",[200,406,407],{},"\u002Ft\u002F{base}.eml"," return the same error lines as plain text when the template fails, rather than a broken text part or a ",[200,410,411],{},".eml"," that can't parse.",[269,414,416],{"id":415},"use-the-index-controls","Use the index controls",[197,418,419,420,423,424,427,428,404,431,433],{},"The same ",[200,421,422],{},"index.html"," (embedded via ",[200,425,426],{},"\u002F\u002Fgo:embed index.tmpl",", shared by ",[200,429,430],{},"preview",[200,432,287],{},") has a header with three control groups plus a standalone page-theme button, and keyboard shortcuts:",[435,436,437,456],"table",{},[438,439,440],"thead",{},[441,442,443,447,450,453],"tr",{},[444,445,446],"th",{},"Control",[444,448,449],{},"Values",[444,451,452],{},"Keyboard",[444,454,455],{},"What it does",[457,458,459,495,511,527],"tbody",{},[441,460,461,465,468,473],{},[462,463,464],"td",{},"Email colour scheme",[462,466,467],{},"Light \u002F Dark",[462,469,470],{},[200,471,472],{},"d",[462,474,475,476,479,480,483,484,487,488,491,492,494],{},"Sets ",[200,477,478],{},"color-scheme"," on each preview ",[200,481,482],{},"\u003Ciframe>"," ",[281,485,486],{},"and",", when the frame's document is readable, flips the email's own ",[200,489,490],{},"prefers-color-scheme"," media rules directly through the CSSOM — some browsers don't propagate the iframe's ",[200,493,478],{}," into the frame, so this is the belt-and-braces fix (D18, amended by D32).",[441,496,497,500,503,508],{},[462,498,499],{},"Preview width",[462,501,502],{},"Both \u002F 600 \u002F 375",[462,504,505],{},[200,506,507],{},"w",[462,509,510],{},"Shows one or both size frames (the templates are built for 600px desktop and 375px mobile).",[441,512,513,516,519,524],{},[462,514,515],{},"Part",[462,517,518],{},"HTML \u002F Plain text",[462,520,521],{},[200,522,523],{},"t",[462,525,526],{},"Toggles between the rendered HTML frames and the plain-text body shown as preformatted text.",[441,528,529,532,535,538],{},[462,530,531],{},"Page theme",[462,533,534],{},"(button, no group)",[462,536,537],{},"—",[462,539,540,541,544],{},"Switches the ",[281,542,543],{},"page's own"," chrome between light and dark — independent of the email colour scheme above, and unrelated to it.",[197,546,547,324,550,553,554,557],{},[200,548,549],{},"j",[200,551,552],{},"k"," (or the arrow keys) move to the next\u002Fprevious template in the sidebar. Every choice is remembered in ",[200,555,556],{},"localStorage"," and restored on the next visit; the page theme choice is applied before first paint via an inline script, so the chrome never flashes light-then-dark.",[197,559,560,561,563,564,567,568,571,572,575,576,578,579,581],{},"The static ",[200,562,278],{}," output embeds each rendered email into its frame with ",[200,565,566],{},"srcdoc"," (rather than an iframe ",[200,569,570],{},"src"," URL) precisely so the page still works when opened directly as a ",[200,573,574],{},"file:\u002F\u002F"," document, with no server behind it (D32); ",[200,577,202],{}," instead points frames at ",[200,580,389],{},", since it has a server to load from and wants each reload to hit it.",[269,583,585,586],{"id":584},"run-make-preview","Run ",[200,587,588],{},"make preview",[205,590,592],{"className":207,"code":591,"filename":209,"language":210,"meta":211,"style":211},"make preview\n",[200,593,594],{"__ignoreMap":211},[215,595,596,598],{"class":217,"line":218},[215,597,222],{"class":221},[215,599,600],{"class":225}," preview\n",[197,602,603,604,607,608,612,613,616,617,616,620,616,622,616,625,616,628,616,631,633,634,637,638,643],{},"runs ",[200,605,606],{},"go run .\u002Fcmd\u002Flttr preview -out preview",", the static, one-shot equivalent — see ",[609,610,136],"a",{"href":611},"\u002Ftooling\u002Fcli#preview-every-example"," for exactly what it writes (",[200,614,615],{},".html",", ",[200,618,619],{},".txt",[200,621,411],{},[200,623,624],{},".md.txt",[200,626,627],{},"assets\u002F",[200,629,630],{},"manifest.json",[200,632,422],{},"). Open ",[200,635,636],{},"preview\u002Findex.html"," directly in a browser; there's no server and no reload loop, so it's the form to hand someone for a one-off review, or to feed to ",[609,639,640],{"href":147},[200,641,642],{},"make shoot"," for the screenshot pass.",[269,645,647],{"id":646},"next-steps","Next steps",[369,649,650,655],{},[319,651,652,654],{},[609,653,136],{"href":137}," for every command's flags.",[319,656,657,659,660,662],{},[609,658,146],{"href":147}," for the automated pass that runs on top of ",[200,661,430],{},"'s output.",[664,665,666],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .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);}",{"title":211,"searchDepth":229,"depth":229,"links":668},[669,670,671,672,674],{"id":271,"depth":229,"text":272},{"id":355,"depth":229,"text":356},{"id":415,"depth":229,"text":416},{"id":584,"depth":229,"text":673},"Run make preview",{"id":646,"depth":229,"text":647},"lttr serve's reload loop, its error display, the index page's controls, and how make preview differs.","md",null,{},{"icon":144},{"title":141,"description":675},"e0DrKdC9gS4HhEJ1tBN6xipdP-W4k7w5HziDWPFfKuk",[683,685],{"title":136,"path":137,"stem":138,"description":684,"icon":139,"children":-1},"Every lttr subcommand, its flags straight from -h, and its exit codes.",{"title":146,"path":147,"stem":148,"description":686,"icon":149,"children":-1},"make shoot, tools\u002Fshoot's flags, the contact sheet it builds, and why a horizontal scroll fails the run.",1790309825446]