diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7cf543b..d3d3970 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,81 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## [3.15.0] - 2026-05-18
+
+Theme: **page authoring + reach copy.** Wave-4 of log.1mb.dev feedback
+closes the v3.13.0 / v3.14.0 deferred threads. Pages become authorable
+through the compose UI rather than markdown-drop only (#79), and the
+`/about` reach section's section heading + email card copy join the
+existing operator-voiced AMA card via three new `ABOUT_REACH_*` env
+vars (#78). A new exported `article.ValidateSlug` contract keeps
+operator-supplied slugs consistent with the codebase-wide URL gate.
+
+### Added
+
+- **`/compose/new-page` authoring affordance (closes #79).** Separate
+ GET route renders the compose form in page mode via `data-mode="page"`:
+ required slug input, hidden `type=page`, banner/tags/categories/link_url
+ hidden. Header "New page →" link surfaces the route from default
+ `/compose`. Edit of an existing `type:page` article surfaces the same
+ mode (header copy + hidden fields) while keeping the slug immutable.
+ Page-mode `CreatePost` branches on `TypePage`: explicit operator-supplied
+ slug, no `date:` frontmatter, no tags/categories. FAB quick-capture
+ stays thought-scoped — pages need a slug and considered authoring;
+ the full `/compose` surface is correct.
+- **`article.ValidateSlug` — exported strict slug contract.** Used by
+ the compose handler before write. Charset
+ `^[a-z0-9]([a-z0-9-]*[a-z0-9])?$`, 100-char cap, reserved set
+ `{index, feed, rss, atom}`. Mirrors the codebase-wide `validSlug`
+ gate at compose handlers so a slug accepted at create-time is also
+ accepted at edit/publish-draft time. Path-traversal guard preserved.
+ `FileSystemRepository.validateSlug` stays permissive for
+ already-stored slugs at admin surfaces — two distinct contracts.
+- **Three env vars for `/about` reach section copy (closes #78).**
+ `ABOUT_REACH_HEADING` (section `
`), `ABOUT_EMAIL_HEADING` (email
+ card ``), `ABOUT_EMAIL_INTRO` (email card descriptive text).
+ Defaults match the pre-v3.15.0 hardcoded literals byte-for-byte so
+ `/about` renders identically without operator override. Pattern
+ parity with the v3.14.0 `about_ama_*` wiring.
+
+### Changed
+
+- **Compose form Cancel link routes through `.canonicalPath`.**
+ Previously hardcoded `/writing/{{ .slug }}`, which on `type:page`
+ edits triggered the v3.13.0 301 to `/p/`. Now the handler
+ threads `canonicalPathForSlug` into a `canonicalPath` data field
+ consumed by the template, closing one more straggler in the
+ `CanonicalURLFor` sweep.
+- **Title required server-side for `type:page` submissions.** The
+ template hint previously said "(required for pages)" without
+ enforcement — empty-title page submissions silently created the
+ file and redirected to `/`, stranding the operator. Now
+ `validatePageInput` rejects empty title with a 400 + error banner;
+ the template gains a `required` HTML attribute on title for
+ page mode.
+
+### Fixed
+
+- **Compose hidden `type` field plumbed through `HandleSubmit` +
+ `HandleEdit`.** Setup for the new `/compose/new-page` POST path;
+ harmless for existing `/compose` flows because `UpdateArticle`'s
+ generic-map frontmatter round-trip already preserved unknown keys
+ (locked by `TestUpdateArticle_PreservesAMAFields` and a new
+ `TestHandleEdit_PageRoundTrip` regression).
+
+### Notes
+
+- The originally-planned Phase 1 (claimed "edit-loses-type" bug fix)
+ was dropped at execution after verifying the premise was wrong:
+ `UpdateArticle` already preserves unknown frontmatter via generic-map
+ round-trip; no regression existed to fix. Plumbing absorbed into the
+ page-affordance commit. Fifth consecutive full-ritual release
+ reinforces the value of test-first contract-locking before
+ implementing claimed bug fixes.
+- #80 (`BLOG_AUTHOR_EMAIL` placeholder default — surfaced during
+ `/pb-think`) is deferred to its own change as a config-default
+ behavior shift with separate review scope.
+
## [3.14.0] - 2026-05-18
Theme: **dedicated-route polish.** v3.13.0 made dedicated-route content