A forum page carries its subforums and its topics in tables of their own,
each with a header. Rebuilding the page into one stream of cards dissolves
that separation: both kinds render identically, so where the subforums end
and the topics begin was no longer visible, and a single card gave no hint
whether tapping it opens a forum or a thread.
A header naming the kind and its count is therefore inserted wherever the
kind changes, and forum cards are tinted and edged. Directly below a
category heading the header is suppressed — on the forum root that heading
already introduces the forums under it, and repeating the kind there adds
a strip per category for nothing.
Counting requires knowing how many cards a block actually yields, which is
not the number of rows: rows that turn out to be layout or fail conversion
drop out. The cards are therefore built completely before any of them is
emitted.
A viewforum page is not always a list of topics — a category page lists
forums, and a forum page can carry both. Every row was treated as a topic,
so on those pages the only link the row offered was the icon in its last-post
column: the forum name was dropped, its description ended up in the muted
footer line, and nothing was left to tap. Moving between forums on a phone
was impossible.
Rows are now classified by their first usable link, which relies on document
order: a forum row names the forum before it links the last post. Detection
prefers phpBB's own classes and falls back to the shape of the row, because
the board runs a custom theme whose markup could not be verified — the page
requires a login.
That fallback needs a brake. The page scaffolding is itself a table, so a
link outside any list row resolves to a row containing the whole document,
which passed for a forum row and turned the page header, a stylesheet and
inline scripts into a forum description. Rows carrying nested tables, forms
or scripts are therefore rejected, and descriptions are read only from the
title cell's own text.
Replacing the page hides the forum's own trail along with everything else,
so a thread became a dead end: the only ways back to the parent forum were
the browser's back button or editing the URL by hand. Deep in a long thread
neither is workable.
The bar has to be fixed rather than sticky. The view root carries
overflow:hidden to contain phantom horizontal overflow, which would make it
the scrollport a sticky bar sticks to — one that never scrolls. Its top
clearance hangs off a body class so pages without a trail keep their full
height instead of an empty strip.
Board index still leads to a page the script does not rebuild; that would
need a forum overview of its own.
Debug flag off for daily use.
The list script matched the whole forum, thread pages included, and injected its
stylesheet there before bailing out of its own build. Both stylesheets were
therefore live on every thread, and rules sharing a class name resolved by
userscript load order rather than by intent — a layout that could differ between
two machines with the same files installed. One of those clashes was already
costing the clearance behind the fixed bar.
A single script picks its view from the page type instead, which turns the
shared class namespace from a hazard into a plain fact of the file, resolved
with a modifier on the root element. Pages outside either view now stay
untouched, where before they still received a full stylesheet.
Two things the merge brought to light: the global image rule was overriding the
avatar dimensions, which only went unnoticed because square avatars happen to
scale to the same result, and a zero-width space had been sitting in the source
as a literal character rather than an escape.
Installations carrying the old thread script have to remove it; the remaining
one keeps its name and updates in place.
Claude-Session: https://claude.ai/code/session_0158owAAsXAfFiT3hGkQt1Xk
The project instructions describe testing against a saved forum page without
mentioning that the ignore rules exclude it. A fresh clone therefore has no
fixture, and obtaining one requires a logged-in session — not something that
becomes apparent from a missing file alone.
Claude-Session: https://claude.ai/code/session_0158owAAsXAfFiT3hGkQt1Xk
Several traits of this codebase cost time to rediscover and are invisible in
the source: both scripts share a stylesheet namespace on thread pages, the page
indicator in the forum markup is split across inline tags so searching the raw
HTML for it comes up empty, and anything appended to the body has to come after
the original content is hidden.
The file also records the throwaway jsdom harness used to check the thread
script against a saved page, since the project deliberately carries no test
dependencies and the setup is easy to get wrong.
Claude-Session: https://claude.ai/code/session_0158owAAsXAfFiT3hGkQt1Xk