soul.demarkus.io:6309/journal/2026-07-04.md
soul.demarkus.io:6309/demarkus-library/adr/0007-pane-scroll-room.md accepted reader meta

ADR 0007 — The pane-scroll room is the reading room

Status: accepted (2026-07-04) · Decider: Fritz · Supersedes: the page-scroll canvas presentation of ADR 0005 (the trail model itself is unchanged)

Context

Since R2 the trail canvas was one page-level scroller: panes laid left→right, the page scrolling vertically as a unit. Reading deep into one document dragged every neighbor with it; the margin column (ADR 0005 R1) reserved ~290px per focused pane for metadata that is consulted occasionally, not continuously. The sliding-panes alternative was parked as "ADR territory" until prototyped behind DEMARKUS_PANE_SCROLL (v0.16.0) and walked.

Decision

The pane-scroll room becomes the default presentation of the trail canvas:

  1. Fixed-viewport room — 100dvh flex column (nav / canvas / dock); the page never scrolls vertically.
  2. Every pane is its own scroller — reading depth is per-pane; neighbors, nav, and dock never move. Sticky paper-backed pane heads keep the address rail visible; interior column rules separate reading columns; scrollbars are thin and hover-only. Spines run floor-to-ceiling.
  3. The margin is summoned, not docked — the catalog record (status, tags, OKF, provenance, hashes, backlinks, escape links) opens as the metadata lens: ?meta=<paneIndex> URL state, the reader lens's record twin (pane-head "meta" affordance; scrim/✕/Esc/Back close; ordinary clicks dismiss). Doc panes only.
  4. Reading columns share the screen — expanded panes flex: 1 1 60ch, bounded 46–82ch so measure survives; the freed margin width goes to text.
  5. At-rest trust signal — the status chip rides the pane head (the room's one color signal), since the margin badge now waits behind the lens.
  6. The flag inverts — DEMARKUS_PANE_SCROLL defaults true and is the opt-out back to the page-scroll room, retained until that room is retired.

Presentation only: same markup contract, same trail URLs, same no-JS behavior (the lens is URL state; <details>/PRG idioms unchanged).

Consequences

  • Sidenotes are hidden in the room (their float needs the margin); they remain in the reader overlay, which keeps the full Tufte pane. If sidenote use grows, revisit (e.g. inline expansion).
  • Preview cards must escape pane clips — solved by CSS anchor positioning (position: fixed + per-pair inline anchor names + flip fallbacks). Browsers without it (Firefox today) keep absolute upward cards that clip near a pane top — an accepted degrade until anchor positioning ships there.
  • Librarian transcript keeps its own bounded scroller — it is what pins the view to the newest exchange while streaming and keeps the ask form in reach inside a scrolling pane.
  • Mobile is unresolved — 46ch min columns on a phone mean horizontal panning; neither room was designed for small screens. Open follow-up.
  • Dock/margin rework is now unblocked: the page-scroll room's margin CSS (grid columns, sidenote floats) stays for the reader overlay and the opt-out room; retire with the flag.
  • Rejected: keeping the experiment opt-in indefinitely (two first-class rooms to maintain); JS-measured card positioning (anchor positioning does it declaratively).

History

Prototype + verdict walk: journal 2026-07-03-ux. Shipped as the default in the release after v0.16.0.

trail
  1. soul.demarkus.io:6309 graph: 2026-07-04
  2. 0007-pane-scroll-room