Skip to content

fix(site): the record site no longer scrolls sideways on a phone - #813

Merged
REPPL merged 14 commits into
mainfrom
fix/record-timeline-narrow
Oct 4, 2026
Merged

REPPL merged 14 commits into
mainfrom
fix/record-timeline-narrow

Conversation

@REPPL

@REPPL REPPL commented Oct 4, 2026 •

Copy link
Copy Markdown
Collaborator

The public record site no longer scrolls sideways on a phone. site-screenshots has failed on every pull request since 2026-10-03 23:37Z, at /record/ 360 and 390 px. This fixes the cause, a long-standing sibling of it, and the audit's attribution that hid both.

What changes

  • The "Latest decisions" list: a .list row is a grid (auto 1fr). The two ADRs docs: propose the two records that replace the home folder's spellings #795 added quote a path with no break opportunity (~/.abcd.noindex/transcripts/<root-sha>/), so the title set the row's width. .list li>span:not(.id){overflow-wrap:anywhere;min-width:0} lets a title wrap. That covers every .list on the site: the dashboard, health, status, development and supersessions.
  • Any long unbroken token: body{overflow-wrap:break-word} breaks a token only where a line would otherwise overflow. Tables, grids and flex rows lay out as before. It fixes record pages whose title or source path held such a token: one issue page reached 1569 px even at 1360. That defect existed since timestamp ADRs began, and the audit never saw it because it sampled only the first record of each type.
  • The overflow audit (site-src/audit/overflow-audit.js):
    • It now also samples, per record type, the record with the longest unbroken run.
    • It names only what can widen the page. It no longer blames elements that scroll inside their own container: the sub-navigation links it named before are of that kind, and the misattribution sent the first diagnosis to the timeline, which was never the cause.
  • The seed stylesheet: site-src/site.css and the seed internal/core/site/setupsrc/site.css stay byte-identical. timeline.go is untouched.

Evidence

The audit was run locally (Playwright 1.62.1 in a scratch folder; no npm manifest in the repository):

  • Before: 14 renderings scroll sideways.
  • After: 0 of 104 (13 routes, at 360/390/768/1360 px, in both colour schemes).

Tests parse both stylesheets for the two rules; both were watched failing before the change.

Narrow screens

Under 520 px a .list row stacks its id and date above its title. A title then gets the full row width (322 px at 360, against 89 px before), not a column a few characters wide. The id span wraps between ids, while each id stays whole. Wide screens are unchanged: every .list row and child rectangle on eight routes, with folds open, at 521 to 1360 px is identical to the base build.

Review

The Fable review returned SHIP with two should-fix items: the narrow title column, and the id column's nowrap. Both are fixed here and measured in a browser with every fold open: /record/ and /record/health/ are at viewport width at 360 and 390 px, and stacked. The stylesheet tests now read the cascade the way a browser does: they normalise selectors, keep the last value for each property, and read media blocks.

Records

Resolves: iss-2610040729344770
Resolves: iss-2610040732240935
Resolves: iss-2610040741103264
Refs: iss-2610040744587676

The last record stays open. The workflow's path-filter comment says a record-only edit cannot move the layout, which #795 disproved, so it needs a ruling on whether record-only pull requests are audited too.

Assisted-by: Claude:claude-opus-5-5

REPPL added 14 commits October 4, 2026 08:29
The site-screenshots job has failed on every pull request since
2026-10-03 23:37Z: /record/ scrolls sideways at 360 and 390 px. A local
reproduction names the Latest decisions panel's title spans, not the
genealogy timeline the bisect suspected.

Refs: iss-2610040729344770
Assisted-by: Claude:claude-opus-5-5
Found while reproducing the /record/ overflow: a timestamp-id ADR's source
path and two ADR titles have no break opportunity, and the overflow audit
samples only the lowest-numbered record of each type, so it never sees them.

Refs: iss-2610040732240935
Assisted-by: Claude:claude-opus-5-5
The /record/ dashboard scrolled sideways at 360 and 390 px. The genealogy
timeline was suspected, but its svg sits inside its own overflow-x:auto
panel and never widens the page; the cause is the Latest decisions panel.
A .list row is a grid (auto 1fr), and a grid item's automatic minimum
width is its min-content width, so the two newest ADR titles, which quote
a home-relative path with no break in it, set the width of their rows.

The non-id spans of a .list row now carry overflow-wrap:anywhere (the one
value that also lowers min-content) and min-width:0, the treatment
.links li>span already has. The rule reaches every .list on the site:
the dashboard's decisions, health, status, development and the
supersession list. A Go test holds the rule at the top level of both
stylesheets and the row markup it matches.

Refs: iss-2610040729344770
Assisted-by: Claude:claude-opus-5-5
Its culprit list counts elements inside their own scroll containers, so on
/record/ it named the sub-navigation links and the timeline svg rather than
the title span that widened the page, and it is silent on a text run.

Refs: iss-2610040741103264
Assisted-by: Claude:claude-opus-5-5
…st case

Record pages scrolled sideways at 360 px wherever a record's title or
source path held a long unbroken run: a timestamp-id ADR's path in the
side panel (about fifty characters to its first hyphen), and the two
newest ADR titles, which quote a home-relative path, in the page heading.
An issue page measured scrollWidth 1569 even at 1360 px.

body now carries overflow-wrap:break-word, inherited by every block. It
breaks a token only where a line would otherwise overflow, and unlike
anywhere it leaves min-content sizing alone, so tables, grids and flex
rows lay out as before. A Go test holds the rule at the top level of
both stylesheets.

The overflow audit sampled only the lowest-numbered record of each type,
whose path and title are short, so it never saw these pages. It now also
samples, per type, the record whose title or source path holds the
longest run without a space or hyphen; against the unfixed site that
sample fails at 360 px for an ADR and at every width for an issue.

Refs: iss-2610040732240935
Assisted-by: Claude:claude-opus-5-5
The audit's culprit list counted elements inside their own scroll
containers. On /record/ it named the sub-navigation links and the
genealogy svg, which scroll in their own windows, and never the title
span that set scrollWidth 482, so the bisect went after the timeline
renderer. It skips any element or text run whose ancestor has a
non-visible overflow-x, and it measures text runs by their Range, so a
heading whose words cannot break is named rather than reported bare.

Against the unfixed site it names the .list title span on /record/, the
source-path span on a timestamp-id ADR page and the h1 text of an issue
page; against the fixed site it passes all 104 renderings.

Refs: iss-2610040741103264
Assisted-by: Claude:claude-opus-5-5
Resolves: iss-2610040729344770
Assisted-by: Claude:claude-opus-5-5
…token

Resolves: iss-2610040732240935
Assisted-by: Claude:claude-opus-5-5
…ulprits

Resolves: iss-2610040741103264
Assisted-by: Claude:claude-opus-5-5
A record-only pull request moved the /record/ layout and was not audited;
the fix waits on a ruling on audit cost.

Refs: iss-2610040744587676
Assisted-by: Claude:claude-opus-5-5
The stylesheet tests keyed a rule by its selector as written and
concatenated every rule for one selector. A spaced combinator
(`.list li > span:not(.id)`) read as a different rule, and a weaker rule
further down the file still passed, because the stronger token was
somewhere in the concatenation while a browser applies the later value.

The helper now normalises selectors and values, keeps the last value of
each property, and also reads the rules inside each media query. A copy
of the stylesheet with a later `overflow-wrap:break-word` title rule and
`body{overflow-wrap:normal}` passes the old helper and fails the new one.

Refs: iss-2610040729344770
Assisted-by: Claude:claude-opus-5-5
On a 360 px phone the id column of a .list row (a timestamp id and its
date, about 220 px) left the title a column 89 px wide on /record/, a few
words to a line, and on /record/health/ a supersession row's two ids and
arrow (314 px in a 322 px row) squeezed its title to 0 px and pushed it
2 px past the row.

Below 520 px a row is now one column: the id above, the title below at
the full width of the row (322 px at 360, 352 px at 390). 520 px is where
the dashboard's title column falls below about 240 px when two columns
share the row. The id span wraps at its spaces while each id link, stub
and date stays whole (`.list .id>*{white-space:nowrap}`), so a pair of
ids gives on a narrower screen instead of pushing the row.

Above 520 px nothing moves: every .list row and child rect on eight
routes, every fold open, is identical between the two builds at 521,
600, 768, 1024 and 1360 px. Both stylesheets stay byte-identical.

Refs: iss-2610040729344770
Assisted-by: Claude:claude-opus-5-5
…imit

longestRun splits on spaces and hyphens only, while a browser also breaks
after some punctuation and never between a hyphen and a digit: the comment
now says it picks a likely worst case, and that pass or fail rests on
scrollWidth alone. The culprit walk skips anything with a clipping DOM
ancestor, so an absolutely positioned element whose containing block lies
outside that clip would widen the page unnamed; the page still fails, and
no page of the site has one today.

Refs: iss-2610040729344770
Assisted-by: Claude:claude-opus-5-5
Assisted-by: Claude:claude-opus-5-5
@REPPL
REPPL enabled auto-merge October 4, 2026 09:24
@REPPL
REPPL added this pull request to the merge queue Oct 4, 2026
Merged via the queue into main with commit 5c87433 Oct 4, 2026
14 of 16 checks passed
@REPPL
REPPL deleted the fix/record-timeline-narrow branch October 4, 2026 12:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant