diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -4,6 +4,10 @@
 
 ## Functional Versions
 
+### 0.7.8.6 -- 2026-10-21
+* Fixed README links so they resolve on Hackage.
+* Removed the top horizontal rule from the demo header.
+
 ### 0.7.8.5 -- 2026-10-20
 * Added PVP upper bounds to the directory dependency of the test suite.
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,15 +1,16 @@
 # Ansiform
 
 [![CI](https://github.com/Tralen/ansiform/actions/workflows/ci.yml/badge.svg)](https://github.com/Tralen/ansiform/actions/workflows/ci.yml)
+[![Hackage](https://img.shields.io/hackage/v/ansiform.svg)](https://hackage.haskell.org/package/ansiform)
 [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/Tralen/ansiform/blob/master/LICENSE)
 
 Ansiform is a small Haskell library for building visual command line interfaces. It provides a declarative format DSL for styled text, rules, aligned lines, lists, groups, tables, paragraphs and multi-section pages.
 
 Builders are pure and produce immutable values. A thin drawing layer writes those values to the terminal and keeps track of how many lines were printed, so a page can be amended, replaced or redrawn in place.
 
-> **Formerly known as Vis.** Ansiform is a terminal formatting library, unrelated to the JavaScript `vis-network` graph visualization library or to the Hackage package [`Vis`](https://hackage.haskell.org/package/Vis) (3D graphics). See [Naming](docs/naming.md).
+> **Formerly known as Vis.** Ansiform is a terminal formatting library, unrelated to the JavaScript `vis-network` graph visualization library or to the Hackage package [`Vis`](https://hackage.haskell.org/package/Vis) (3D graphics). See [Naming](https://github.com/Tralen/ansiform/blob/master/docs/naming.md).
 
-Current version: **0.7.8.5**.
+Current version: **0.7.8.6**.
 
 Repository: <https://github.com/Tralen/ansiform>.
 
@@ -83,21 +84,21 @@
 
 ## Documentation
 
-- [Architecture](docs/architecture.md): module layout, invariants and the pure/IO boundary.
-- [Content](docs/content.md): items, blocks, groups, tables, paragraphs and their builders.
-- [Styles](docs/style.md): colors, formats and reusable text styles.
-- [Theme](docs/theme.md): reusable styles for headers, footers, menus and tables.
-- [Printers](docs/printers.md): every printer function and its arguments.
-- [Table formatting](docs/table-format.md): per-column alignment, maximum widths, truncation and borders.
-- [Sections](docs/sections.md): grouping printers and reserving minimum line counts.
-- [Pages and drawing](docs/pages.md): pages, state and the drawing lifecycle.
-- [Input](docs/input.md): immediate and line input, and the standard interaction loop.
-- [Render](docs/render.md): rendering pages, sections and printers to a `Handle` or a `String`.
-- [Settings](docs/settings.md): width, spacing and group overflow configuration.
-- [Demo](docs/demo.md): what the executable showcases.
-- [Naming](docs/naming.md): name rationale and disambiguation.
-- [Releasing](docs/releasing.md): Hackage and GitHub publication checklist.
-- [Roadmap](docs/roadmap.md): prioritized feature suggestions.
+- [Architecture](https://github.com/Tralen/ansiform/blob/master/docs/architecture.md): module layout, invariants and the pure/IO boundary.
+- [Content](https://github.com/Tralen/ansiform/blob/master/docs/content.md): items, blocks, groups, tables, paragraphs and their builders.
+- [Styles](https://github.com/Tralen/ansiform/blob/master/docs/style.md): colors, formats and reusable text styles.
+- [Theme](https://github.com/Tralen/ansiform/blob/master/docs/theme.md): reusable styles for headers, footers, menus and tables.
+- [Printers](https://github.com/Tralen/ansiform/blob/master/docs/printers.md): every printer function and its arguments.
+- [Table formatting](https://github.com/Tralen/ansiform/blob/master/docs/table-format.md): per-column alignment, maximum widths, truncation and borders.
+- [Sections](https://github.com/Tralen/ansiform/blob/master/docs/sections.md): grouping printers and reserving minimum line counts.
+- [Pages and drawing](https://github.com/Tralen/ansiform/blob/master/docs/pages.md): pages, state and the drawing lifecycle.
+- [Input](https://github.com/Tralen/ansiform/blob/master/docs/input.md): immediate and line input, and the standard interaction loop.
+- [Render](https://github.com/Tralen/ansiform/blob/master/docs/render.md): rendering pages, sections and printers to a `Handle` or a `String`.
+- [Settings](https://github.com/Tralen/ansiform/blob/master/docs/settings.md): width, spacing and group overflow configuration.
+- [Demo](https://github.com/Tralen/ansiform/blob/master/docs/demo.md): what the executable showcases.
+- [Naming](https://github.com/Tralen/ansiform/blob/master/docs/naming.md): name rationale and disambiguation.
+- [Releasing](https://github.com/Tralen/ansiform/blob/master/docs/releasing.md): Hackage and GitHub publication checklist.
+- [Roadmap](https://github.com/Tralen/ansiform/blob/master/docs/roadmap.md): prioritized feature suggestions.
 
 ## Design principles
 
@@ -106,8 +107,8 @@
 3. **Errors as data.** Table builders return `Maybe Table`. There are no exceptions in the public API.
 4. **Immediate interaction.** The standard interaction is a single key press, handled by `Ansiform.Input` without Enter.
 5. **Reusable components.** Screens are assembled from shared builders such as `header`, `footer` and `rule`, keeping behavior and theming consistent.
-6. **Explicit versioning.** The package follows the PVP and every release is recorded in [ChangeLog.md](ChangeLog.md).
+6. **Explicit versioning.** The package follows the PVP and every release is recorded in [ChangeLog.md](https://hackage.haskell.org/package/ansiform/changelog).
 
 ## License
 
-MIT. See [LICENSE](LICENSE).
+MIT. See [LICENSE](https://github.com/Tralen/ansiform/blob/master/LICENSE).
diff --git a/ansiform.cabal b/ansiform.cabal
--- a/ansiform.cabal
+++ b/ansiform.cabal
@@ -1,6 +1,6 @@
 cabal-version:       3.0
 name:                ansiform
-version:             0.7.8.5
+version:             0.7.8.6
 synopsis:            Display formatting for command line interfaces.
 description:         Basic format DSL for building an ANSI command line interface
                      with colors, alignment, tables, paragraphs and more.
diff --git a/docs/releasing.md b/docs/releasing.md
--- a/docs/releasing.md
+++ b/docs/releasing.md
@@ -5,7 +5,7 @@
 ## Current status
 
 - Package: `ansiform`. The name appears to be available on Hackage; check again immediately before uploading.
-- Version: 0.7.8.5.
+- Version: 0.7.8.6.
 - License: MIT.
 - `cabal sdist` produces a complete source distribution with sources, docs, examples, tests, README, ChangeLog and LICENSE.
 - Haddock builds with 100% coverage for the public functions and types. The remaining warnings are only about module re-exports.
@@ -13,8 +13,9 @@
 - GitHub: public at <https://github.com/Tralen/ansiform>; the local remote is `git@github.com:Tralen/ansiform.git`.
 - `source-repository`, `homepage` and `bug-reports` are set to the GitHub URL.
 - The history has been rewritten and contains no personal paths.
-- Tag `0.7.8.5` and its GitHub release are published.
-- The roadmap is complete. GitHub publication is done; the Hackage upload is pending.
+- Tag `0.7.8.6` and its GitHub release are published.
+- Hackage: published at <https://hackage.haskell.org/package/ansiform>.
+- The roadmap is complete. GitHub and Hackage publication are done.
 
 ## Credentials
 
@@ -126,16 +127,17 @@
    ```
 
 6. Inspect the candidate page at `https://hackage.haskell.org/package/ansiform/candidates`. Check the rendered documentation, the dependency bounds and the build report. A candidate that fails verification can be deleted from that page.
-7. After the candidate is verified, publish the package and its documentation:
+7. Stop and wait for explicit approval from the maintainer before publishing. The candidate is reversible; publication is not.
+8. After approval, publish the package and its documentation:
 
    ```sh
    cabal upload --token "$HACKAGE_TOKEN" --publish dist-newstyle/sdist/ansiform-<version>.tar.gz
    cabal upload --token "$HACKAGE_TOKEN" --documentation --publish dist-newstyle/ansiform-<version>-docs.tar.gz
    ```
 
-8. Check the public package page, the documentation links and the dependency bounds.
+9. Check the public package page, the documentation links and the dependency bounds.
 
-Publishing cannot be undone easily. Use the candidate stage to catch metadata, documentation and dependency problems before publishing.
+Publishing cannot be undone easily. Never run `--publish` without explicit approval after the candidate review. Use the candidate stage to catch metadata, documentation and dependency problems before publishing.
 
 ## GitHub release
 
@@ -149,7 +151,7 @@
    ```
 
 3. Create a GitHub release from the tag, using the relevant ChangeLog section as the description.
-4. Add the Hackage badge to the README once the package page exists. The CI and license badges are already present.
+4. The Hackage badge is already present in the README.
 
 ## Notes
 
diff --git a/examples/Demo.hs b/examples/Demo.hs
--- a/examples/Demo.hs
+++ b/examples/Demo.hs
@@ -15,7 +15,7 @@
 
 -- Version of this demo, following the package version.
 demoVersion :: String
-demoVersion = "0.7.8.5"
+demoVersion = "0.7.8.6"
 
 -- The philosophers shown in the Groups screen.
 data Philosopher
@@ -86,7 +86,7 @@
 demoTheme = defaultTheme
 
 header :: Section
-header = sectionTopRule 1 ruleHeader
+header = sectionTop 1
   [ printerSolidLineCenter 0 1 (themeBar demoTheme)
       [ blockSimple "Ansiform" (themeHeader demoTheme)
       , blockSimple demoVersion (themeHeader demoTheme) ]
@@ -129,8 +129,7 @@
 promptRowsUp :: Number
 promptRowsUp = formNumber (length pageCommands + 4)
 
-ruleHeader, ruleBody, ruleFooter, ruleBottom :: Rule
-ruleHeader = rule '=' (themeRule demoTheme)
+ruleBody, ruleFooter, ruleBottom :: Rule
 ruleBody = rule '%' (themeRule demoTheme)
 ruleFooter = rule ':' (themeRule demoTheme)
 ruleBottom = ruleDefault (themeRule demoTheme)
