diff --git a/astro.config.mjs b/astro.config.mjs
index 84005a1..944a2b0 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -189,6 +189,8 @@ export default defineConfig({
{ label: "Channel ACL", link: "/admin/acl/" },
{ label: "Groups", link: "/admin/groups/" },
{ label: "Ban list", link: "/admin/bans/" },
+ { label: "Audit log", link: "/admin/audit-log/" },
+ { label: "Welcome message", link: "/admin/welcome-message/" },
{ label: "Custom emotes", link: "/admin/emotes/" },
{ label: "Onboarding workflow", link: "/admin/onboarding/" },
{ label: "Server Plugins", link: "/admin/server-plugins/" },
diff --git a/public/screenshot-admin-audit-dashboard-dark.png b/public/screenshot-admin-audit-dashboard-dark.png
new file mode 100644
index 0000000..afaa733
Binary files /dev/null and b/public/screenshot-admin-audit-dashboard-dark.png differ
diff --git a/public/screenshot-admin-audit-dashboard.png b/public/screenshot-admin-audit-dashboard.png
new file mode 100644
index 0000000..4b8eb2a
Binary files /dev/null and b/public/screenshot-admin-audit-dashboard.png differ
diff --git a/public/screenshot-admin-audit-results-dark.png b/public/screenshot-admin-audit-results-dark.png
new file mode 100644
index 0000000..cd4cc82
Binary files /dev/null and b/public/screenshot-admin-audit-results-dark.png differ
diff --git a/public/screenshot-admin-audit-results.png b/public/screenshot-admin-audit-results.png
new file mode 100644
index 0000000..adc6760
Binary files /dev/null and b/public/screenshot-admin-audit-results.png differ
diff --git a/public/screenshot-admin-welcome-nodes-dark.png b/public/screenshot-admin-welcome-nodes-dark.png
new file mode 100644
index 0000000..52666cf
Binary files /dev/null and b/public/screenshot-admin-welcome-nodes-dark.png differ
diff --git a/public/screenshot-admin-welcome-nodes.png b/public/screenshot-admin-welcome-nodes.png
new file mode 100644
index 0000000..8693fb8
Binary files /dev/null and b/public/screenshot-admin-welcome-nodes.png differ
diff --git a/src/content/docs/admin/audit-log.mdx b/src/content/docs/admin/audit-log.mdx
new file mode 100644
index 0000000..4384ed5
--- /dev/null
+++ b/src/content/docs/admin/audit-log.mdx
@@ -0,0 +1,54 @@
+---
+title: Audit log
+description: Find server actions, inspect their details, export results, and check audit retention and integrity.
+---
+
+Open **Settings**, select your connected server's administration section, then **Audit log**. Starling must have its audit service enabled. Reading and configuring the audit log currently require **Write** permission on the root channel; being able to moderate one child channel does not grant access to the whole server's log.
+
+## Dashboard
+
+The dashboard summarizes the **loaded results**: recent actions, warnings, reports, actors, and charts by time, category, and severity. These are not totals for every entry ever stored. Run a search to change the result set before comparing incidents.
+
+
+
+## Find an action
+
+1. Select **Results** and choose a time range under **Since**.
+2. Narrow **Source**, **Severity**, **Actor**, **Target**, or **Categories**. For example, select `audit.ban` to investigate a ban, or `audit.acl` for permission changes.
+3. Press **Search** after editing the query text. The quick filters and simple query describe the same search.
+4. Select a row to inspect the structured detail and any related entry. For profile changes, a kept copy is available only if the server retained it.
+
+
+
+Simple query examples:
+
+~~~text
+category = "audit.ban" and ts > now-7d
+source = "server" and actor = 1
+category in ("audit.kick", "audit.ban") and target = 2
+~~~
+
+Actor and target numbers are registered user IDs. A name can be resolved when the client knows that user; use an ID if a historical name is ambiguous or unavailable. A **client** source is a reported client claim, while **server** records an authoritative server action and **plugin** records a plugin-originated action. Inspect the source before treating a report as proof of a moderator action.
+
+Column sorting affects the loaded rows. Use **Next** or endless scrolling to load more history. An empty page can mean the selected filters match nothing; clear them and widen the time range before concluding that no event was recorded.
+
+## Live updates and export
+
+**Live** subscribes to new matching entries. **CSV** and **JSON** export the entries currently loaded, not the entire server database. Load the required time range before exporting. Include the query, timezone, and export time when sharing an incident record.
+
+## Configuration and integrity
+
+In **Configuration**, the server provides the available audit settings. Category switches control new recording; switching one off does not delete existing entries. Retention determines how long history and kept profile copies remain available.
+
+**Verify chain** checks the retained hash chain. A failure needs investigation: retention can leave a gap, and a broken chain is not by itself proof of malicious editing. Preserve the error and affected range, then compare retention settings and server logs. A successful check establishes chain consistency; it does not establish that every real-world action was recorded.
+
+Advanced SQL queries beginning with `SELECT` or `WITH` are available only when the server advertises that capability. If the page reports it unavailable, use the ordinary filters instead.
+
+## Missing entries or access errors
+
+- **Access denied:** check root-channel Write permission and reconnect after permissions change.
+- **No audit capability:** ask the owner to enable the Starling audit service.
+- **Older entries missing:** check retention and whether the event category was enabled at the time.
+- **Kept copy unavailable:** profile-history limits or retention may have removed the stored image or comment.
+
+The client audit log and the operator API's own audit file are separate records. For infrastructure actions, the owner may need both. For client or service failures, see [Collect useful logs](/troubleshooting/debug-logging/).
diff --git a/src/content/docs/admin/welcome-message.mdx b/src/content/docs/admin/welcome-message.mdx
new file mode 100644
index 0000000..f95779c
--- /dev/null
+++ b/src/content/docs/admin/welcome-message.mdx
@@ -0,0 +1,53 @@
+---
+title: Welcome message editor
+description: Build welcome messages with conditions, reusable text, previews, and the node canvas.
+---
+
+Open **Settings**, choose the connected server's administration section, then **Welcome message**. The node editor controls which greeting an arriving member receives and what it contains.
+
+This editor reads and saves through Starling's operator API using a short-lived credential granted to your existing session. The server must expose that API to the client and grant `server-config:read` and `server-config:write`. If loading fails, use the displayed error to check permissions and API reachability; saving is blocked until the existing graph has loaded.
+
+## Start with a template
+
+1. Open **Templates** and choose a greeting close to your intended rule. **Warm welcome, with the rules** includes a newcomer condition and a reusable rules snippet.
+2. Edit the message in its greeting node. Use **Plain** for unformatted text, **Rich** for the visual editor, or **HTML** for source markup.
+3. Check the condition, its connecting wire, and the preview beneath the greeting.
+4. Use **Test greeting** to inspect the result, then **Save & broadcast** to apply it to the server. Editing the canvas alone does not save your changes.
+
+
+
+## Read the wires
+
+| Block or input | Purpose |
+| --- | --- |
+| Condition | Tests a visitor fact, such as account status, time on the server, group, country, OS, or client version. |
+| AND, OR, XOR gate | Combines condition outputs. AND requires both; OR accepts either; XOR accepts exactly one. |
+| Filter | Decides how an unknown condition is treated. **unknown → yes** admits it; **unknown → no** does not. |
+| Greeting **WHEN** | The condition controlling whether this greeting is shown. |
+| Reusable text → **PLUS** | Appends a shared snippet, such as house rules, to a greeting. |
+
+For a greeting shown to everyone, use the **Everyone** filter connected to **WHEN**. For a newcomer-only greeting, connect the time-on-server condition through a filter and check the resulting sentence in the status bar. An unavailable visitor fact is not automatically false: the filter's unknown choice matters.
+
+## Edit the layout and message
+
+**Node canvas** shows the blocks and wires; **Blocks** gives a readable summary of the same graph. **Browse blocks** adds another condition, gate, greeting, or reusable text block. Use **Undo** and **Redo** after wiring or moving nodes.
+
+A greeting's **Screen** view builds a welcome screen from sections, while **Classic** provides its legacy-compatible layout. Inspect the preview after changing views. Rich formatting requires the server's `allow_html` setting; plain text remains useful for clients that cannot render the formatted version.
+
+The server limits each message body to **4096 characters**. Keep rules short and link to longer community information. Unsupported HTML may need to remain in the HTML source view to avoid losing formatting that the rich editor cannot represent.
+
+## Validate before saving
+
+The status reports whether the graph is complete. Finish required connections and inspect any conflicting greetings before saving. The footer describes who will receive the selected greeting; compare that sentence with your intended audience.
+
+**Shown once, centered** makes a greeting dismissible for good rather than showing it on every connection. Check both a fresh visitor and a returning member when testing. A user's own [welcome-message notification preference](/users/notifications/) can also affect whether they see the popup.
+
+Use the **enabled** switch to control whether the graph is active, then save the change. Keep onboarding questions and role assignment in the separate [Onboarding workflow](/admin/onboarding/); this editor supplies the greeting.
+
+## When a greeting does not appear
+
+- Confirm the graph is enabled and **Save & broadcast** succeeded.
+- Inspect the condition and unknown handling; test with the intended visitor type.
+- Check whether the member already dismissed a shown-once greeting or disabled welcome popups.
+- If only formatting is missing, check `allow_html` and the receiving client's supported layout.
+- For load/save failures, record the exact error and check the operator API and granted scopes.