soul.demarkus.io/demarkus-library/plans/reader-mode.md/v1 draft reader meta

Reader mode — the focus overlay (plan)

Status: draft — recorded 2026-06-14 (Fritz). Next-session candidate. Fritz: "I really like the layout, it keeps the context nicely. One thing that would help: a quick reader mode that overlays in the middle the document you want to focus on" — since the trail has multiple columns, sometimes you want to sink into one document.

One-line

A reader overlay: the focused document rendered centered, at a comfortable measure, over the dimmed trail — context preserved behind it, one click (or Back) to return. A lens over the trail, NOT a new pane: the reasoning chain is untouched; you're just reading one link of it up close.

Why it fits the room

The trail's whole thesis is "context is spatial, never amputated." Reader mode honors that: the columns stay on screen, dimmed — you can see where you are, you just zoom your attention. It's the opposite of a modal that hides everything; the context is still there, deliberately. Complements focus (which pane gets the margin + live read) with a deeper "solo read" lens.

THE design decision: reader is URL state, not client state (ADR 0003)

Reader mode is a query param on the trail URL — /t/<trail>?reader=<paneIndex> (0-based; omitted ⇒ no overlay; out of range ⇒ ignored). Consequences, all the htmx-hard wins the trail already banks:

  • Shareable: a link can say "here's the chain, start by reading pane 2."
  • Browser Back closes it — temporal history over spatial state, free, no JS.
  • Zero client state — the whole overlay renders server-side from the URL.
  • Coexists with ?focus= (reader implies attention on that pane; keep both or fold focus into reader — settle when building).

Render

  • The full canvas renders as today, with a dimmed backdrop layer over it.
  • A centered reader panel renders the pane's already-fetched Document at the Tufte reading measure (≈60ch body + margin), so it's the same prose the column shows, just unconstrained by column width and centered.
  • No extra world read: reader shows the Document already fetched for that pane (focused-live or cached) — the overlay is pure presentation.
  • Margin stays (status, tags, provenance, backlinks, graph/edit/new/append affordances): reading mode is not a dead-end — you can still branch and act. Possibly collapsible; default shown (the trust layer is the point).
  • SSR + CSS only; ADR 0003's canvas island stays unspent. Degrades: no CSS ⇒ the doc just renders after the canvas; no JS ⇒ close via the link / Back.

Affordance + close

  • Each pane (header/spine) gets a "reader" control → link to trailURL?reader=<i>.
  • Close: an explicit AND the backdrop itself are <a> links back to the bare trail URL (no reader param). Optional Esc-to-close via a one-line _hyperscript snippet (an ADR 0003-sanctioned tiny concession) — or rely on Back. Recommend the snippet; it's the expected reader-mode gesture.

Load-bearing UX decision: does reader persist across link clicks?

  • RECOMMENDED — persist: a link clicked inside the reader continues the trail AND stays in reader on the newly-focused pane (read straight through the argument without surfacing). Implemented by the reader panel's links using trailAfterClick then setting reader=<new focus index>. This is the feature's whole point ("focus on the document you want," then the next).
  • Alternative (simpler v1): links exit reader to the canvas, focused on the new pane. Less magical; falls out for free. Decide with Fritz; recommend persist.

Architecture (web-only — no port/service/domain change)

  • trail.go: parse the reader query param into the trail struct (e.g. Reader int, -1 = none); trailURL optionally encodes it; a helper builds the reader/close links. The codec stays the single source of truth.
  • trail_handlers.go: when Reader is set and in range, render the canvas plus the reader-overlay view model (reuse the focused pane's Document; for persist-on-navigate, rewrite the reader panel's links to carry the new reader index).
  • Templates: a reader overlay block (backdrop + centered panel reusing the doc-body + doc-meta partials). CSS: backdrop, centered panel, dim.
  • Restrict to prose panes (doc/listing/tag); a floor/graph pane in reader is just a bigger SVG — allow later if wanted, not v1.

Tests

Codec round-trip with ?reader=; overlay renders the addressed pane; ✕/backdrop link back to the bare trail; persist-on-navigate link rewriting; out-of-range ignored; no-reader URL renders exactly today's canvas (no regression); auth-gated affordances still present in the reader margin.

Scope / non-goals

  • A presentation lens, not a pane kind — the trail path never changes.
  • No client zoom/pan, no JS reader engine (htmx + CSS + at most a 1-line Esc hyperscript).
  • Doc/listing/tag panes only for v1.

Open before building (settle with Fritz)

  1. Persist-on-navigate vs exit-on-navigate (recommend persist).
  2. ?reader= as its own param vs folding focus into it.
  3. Esc-to-close hyperscript vs Back-only.
  4. Margin shown vs collapsible in reader.

This is a self-contained next-session feature: web-layer only, no new reads, no broker/deploy coupling. Slots into the Reading Room family as "R4 — reader mode."

trail
  1. soul.demarkus.io v1