diff --git a/src/config/sidebar.mjs b/src/config/sidebar.mjs
index 08a06cc..27d069d 100644
--- a/src/config/sidebar.mjs
+++ b/src/config/sidebar.mjs
@@ -38,6 +38,7 @@ export const docsSidebar = [
{ label: 'Teams', slug: 'docs/administration/teams' },
{ label: 'Moderation', slug: 'docs/administration/moderation' },
{ label: 'Notifications and email', slug: 'docs/administration/notifications-and-email' },
+ { label: 'Message templates', slug: 'docs/administration/message-templates' },
{ label: 'Managing modules', slug: 'docs/administration/managing-modules' },
{ label: 'The shard connection', slug: 'docs/administration/the-shard-connection' },
{ label: 'Maintenance and upgrades', slug: 'docs/administration/maintenance-and-upgrades' },
@@ -113,6 +114,7 @@ export const plannedSidebar = {
'Teams',
'Moderation',
'Notifications and email',
+ 'Message templates',
'Managing modules',
'The shard connection',
'Maintenance and upgrades',
diff --git a/src/content/docs/docs/administration/message-templates.mdx b/src/content/docs/docs/administration/message-templates.mdx
new file mode 100644
index 0000000..88b9c39
--- /dev/null
+++ b/src/content/docs/docs/administration/message-templates.mdx
@@ -0,0 +1,132 @@
+---
+title: Message templates
+description: Edit what your site's email actually says — the block editor, the variable palette, the preview, test sends, and the send log that tells you whether a message arrived.
+---
+
+import { Aside } from '@astrojs/starlight/components';
+
+Every message your site sends — password resets, invitations, notifications — is a
+**template** you can edit. They ship working, so a fresh site mails correctly before you
+open this screen at all. You come here when you want it to sound like your shard.
+
+**Admin → Engagement → Templates.**
+
+## What is in the list
+
+Each row is one message. The ones marked **system** are the ones the site itself depends
+on: the password reset, the invitation, the address-confirmation mail. You can edit every
+word of those, but you cannot delete them — a site with no password-reset body is a site
+where nobody can get back in.
+
+The rest are the general-purpose bodies that rules send. Those you can delete, as long as
+no rule is currently pointing at one.
+
+
+
+## Editing a message
+
+The editor has the message on the left and a live preview on the right.
+
+### The body is blocks, not HTML
+
+You build a message out of pieces: a heading, a paragraph, a button, a divider, an image,
+or an item list. Add one from the row of buttons, click it to edit it, and use the arrows
+to move it. There is no HTML to write, which is deliberate — email HTML is a genuinely
+horrible format, and the blocks already produce something that survives Outlook.
+
+### Variables are chosen, never typed
+
+Under most text fields is a row of small grey names: `siteName`, `resetUrl`, `title`. Those
+are the **variables** this particular message is given when it is sent. Click one and it is
+inserted as a token; the message that goes out has the real value in its place.
+
+You cannot invent a variable. If you type one the message is not given — a typo, or a name
+you remembered from a different message — the save is refused and the error names the
+variable. That is on purpose: a variable that does not exist renders as *nothing*, so
+without the check the mistake would be invisible until it reached somebody's inbox as a
+sentence with a hole in it.
+
+To see every variable a given event provides, with an example of each, look at
+**Admin → Engagement → Triggers**.
+
+### Both halves of the message
+
+Every email goes out in two forms: the designed HTML one, and a plain-text one for clients
+that will not show HTML. The plain-text half is generated from your blocks automatically,
+and you can see it under the **Plain text** tab.
+
+If the generated version is not good enough, write your own in **Plain-text part** at the
+bottom of the editor. Whatever you write there replaces the generated text completely.
+
+A published message must have *something* in its text part. If every block you used
+contributes nothing to it — a message made only of dividers and images, say — the save is
+refused.
+
+### Draft and published
+
+A **draft** is not what goes out. While a message is a draft, the site sends the shipped
+default in its place, so you can leave something half-finished without breaking anything.
+Switch it to **Published** when you want your version to be the one people receive.
+
+## The preview
+
+The preview is rendered by the server using the same code that renders the real message, so
+what you see is what will arrive — not an approximation drawn by the browser.
+
+It fills the variables in with example values, so you never need to trigger a real event to
+see what a message looks like.
+
+Three controls are worth knowing:
+
+- **Desktop / Mobile** — the same body at a reading-pane width and a phone width.
+- **Dark mode** — an approximation of what mail clients that invert light messages will do
+ to yours. Worth a glance: a design that relies on a light background can come out as
+ dark-on-dark for a large minority of readers.
+- **Plain text** — the other half of the message, as described above.
+
+## Sending yourself a test
+
+The **Send a test** box sends the message to any address you type, through whatever mail
+transport the site is configured with (**Admin → Settings → Email delivery** — see
+[Notifications and email](/docs/administration/notifications-and-email/)).
+
+It sends **what is on screen**, saved or not. That is the point of it: try a wording, send
+it to yourself, look at it in a real inbox, and only then decide whether to save.
+
+Test sends are recorded in the send log like any other message, including when they fail.
+
+## Making a new template
+
+You do not start from a blank page. Pick a message that is close to what you want, press
+**Duplicate**, and give the copy a key.
+
+The **key** is how a rule refers to the template — `notify.house-idoc`, say. Lowercase
+letters, digits, dots and dashes, and it cannot be changed later, so pick one that will
+still make sense in a year.
+
+The copy always starts as a draft. Once you are happy with it, publish it and point a rule
+at it in **Admin → Engagement → Rules**.
+
+
+
+## Did it arrive?
+
+**Admin → Engagement → Send Log** lists every message the site tried to deliver, newest
+first, successes and failures alike. When mail is not arriving, this is the screen that
+tells you whether the site tried and the relay refused, or whether it never tried at all.
+
+Failures carry the reason the mail server gave, which is usually the actual answer — a
+rejected sender address, a bad password, a relay that will not accept your domain.
+
+The log does not store anybody's email address. It keeps a one-way fingerprint instead, so
+that a bounce can be matched back to a delivery without the log itself becoming a second
+copy of your members' addresses.