Index: code-docs/main.scrbl
==================================================================
--- code-docs/main.scrbl
+++ code-docs/main.scrbl
@@ -15,11 +15,12 @@
 
 @author{Joel Dueck}
 
 These are my notes about the internals of the Local Yarn source code. In other words, a personal
 reference, rather than a tutorial. These pages concern only the source code itself. Refer to the
-wiki for anything else.
+wiki for info about deployment, etc.
+
 
 You’ll get the most out of these notes if you have read @other-doc['(lib
 "pollen/scribblings/pollen.scrbl")], and worked through the tutorials by hand.
 
 If you’re viewing these notes on the Fossil repository, note that these pages are heavily
@@ -33,5 +34,7 @@
 @local-table-of-contents[]
 
 @include-section["pollen.scrbl"]  @; pollen.rkt
 @include-section["dust.scrbl"]    @; dust.rkt
 @include-section["sqlite-tools.scrbl"] @; sqlite-tools.rkt
+@include-section["snippets-html.scrbl"] @; you get the idea
+

Index: code-docs/pollen.scrbl
==================================================================
--- code-docs/pollen.scrbl
+++ code-docs/pollen.scrbl
@@ -9,10 +9,12 @@
 
 @(require "scribble-helpers.rkt")
 @(require (for-label "../pollen.rkt"
                      "../dust.rkt"
                      racket/base
+                     racket/contract
+                     racket/string
                      txexpr
                      pollen/tag
                      pollen/setup
                      pollen/core
                      sugar/coerce))

ADDED   code-docs/snippets-html.scrbl
Index: code-docs/snippets-html.scrbl
==================================================================
--- code-docs/snippets-html.scrbl
+++ code-docs/snippets-html.scrbl
@@ -0,0 +1,124 @@
+#lang scribble/manual
+
+@; Copyright (c) 2019 Joel Dueck
+@;
+@; Copying and distribution of this file, with or without modification,
+@; are permitted in any medium without royalty provided the copyright
+@; notice and this notice are preserved.  This file is offered as-is,
+@; without any warranty.
+
+@(require "scribble-helpers.rkt")
+
+@(require (for-label "../pollen.rkt"
+                     "../dust.rkt"
+                     "../snippets-html.rkt"
+                     racket/base
+                     racket/contract
+                     racket/string
+                     pollen/template
+                     pollen/pagetree
+                     sugar/coerce))
+
+@title{@filepath{snippets-html.rkt}}
+
+@defmodule["snippets-html.rkt" #:packages ()]
+
+Each “snippet” module provides all the document- and article-level blocks of structural markup
+necessary for a particular target output format; this one is for HTML. The idea is that any block of
+markup that might be reused across more than one template should be a function.
+
+The functions in the snippets modules follow two conventions in this project:
+
+@itemlist[
+  @item{Functions that return strings of HTML have the prefix @tt{html$-}.}
+  @item{Such functions do not do any parsing or destructuring of complex objects; every separate
+  piece that will be inserted into the template is passed in as a separate argument. This makes it
+  harder to change the scope of what a snippet does, but makes things faster since all the parsing
+  can happen in one place, before the snippet functions are called.} ]
+
+@section{Using @tt{pollen/mode}}
+
+It’s worth looking at the source for this file to see how @racketmodname[pollen/mode] can be used to
+make it easy to write “mini-template” functions:
+
+@codeblock{
+#lang pollen/mode racket/base
+
+(define (html$-my-article title body-tx)
+  ◊string-append{
+    <p><b>◊|title|</b><p>
+    ◊(->html body-tx)
+  })
+}
+
+@section{HTML Snippet functions}
+
+@defproc[(html$-page-head [title (or/c string? #f) #f]) non-empty-string?]
+
+Returns the @tt{<head>} section of an HTML document.
+
+@defproc[(html$-page-body-open) non-empty-string?]
+
+Returns the opening @tt{<body>} and @tt{<main>} tags and elements that immediately follow, such as
+site header, logo and navigation.
+
+@defproc[(html$-article-open [title? boolean?] [title-html-flow string?] [pubdate string?])
+non-empty-string?]
+
+Returns the opening @tt{<article>} tag and elements that immediately follow: permlink, publish date,
+and opening @tt{<section>} tag.
+
+This function could be smarter, but for now @racket[_title?] determines which HTML markup structure
+to use for the article regardless of whether @racket[_title-html-flow] is empty or not.
+
+@defproc[(html$-article-close [footertext string?]) non-empty-string?]
+
+Returns a string containing a closing @tt{<section>} tag, a @tt{<footer>} element containing
+@racket[_footertext], and a closing @tt{<article>} tag. If @racket[_footertext] is empty, the
+@tt{<footer>} element will be omitted.
+
+@defproc[(html$-page-body-close) non-empty-string?]
+
+Returns a string containing the page’s @tt{<footer>} and closing tags.
+
+@defproc[(html$-note-title [author string?] [pagenode pagenode?] [parent-title string?])
+non-empty-string?]
+
+Returns a string containing the HTML for a note’s title. The title is used when the note is
+displayed in a separate context from its parent article.
+
+If @racket[_author] is empty, then @racket[default-authorname] is used. The @racket[_pagenode] and
+@racket[_parent-title] values are for generating a link to the parent article.
+
+@defproc[(html$-note-contents [disposition-mark string?] [elems (listof xexpr?)]) non-empty-string?]
+
+Returns a string containing the body-elements of a note converted to HTML. If
+@racket[_disposition-mark] is not empty, a @tt{<span>} containing it will be inserted as the first
+element of the first block-level element.
+
+@defproc[(html$-note-listing-full [pagenode pagenode?]
+                                  [note-id string?] 
+                                  [title-html-flow string?]
+                                  [date string?]
+                                  [contents string?] 
+                                  [author string? (default-authorname)] 
+                                  [author-url string? ""])
+          non-empty-string?]
+
+Returns a string containing the complete HTML markup for a @racket[note], including title, permlink,
+date, contents and author, suitable for display outside the context of its parent article.
+
+@defproc[(html$-note-in-article [id string?] 
+                                [date string?] 
+                                [contents string?] 
+                                [author string?]
+                                [author-url string?]) non-empty-string?]
+
+Like @racket[html$-note-listing-full], but returns HTML for a @racket[note] suitable for display
+inside its parent article.
+
+@defproc[(html$-notes-section [note-htmls string?]) non-empty-string?]
+
+Returns the complete HTML for the @italic{Further Notes} section of an article.
+
+