Skip to content

fix(packets): keep the Details summary on one line so rows stay bounded - #67

Merged
dborup merged 4 commits into
masterfrom
codex/fix-packets-details-row-clamp
Sep 19, 2026
Merged

dborup merged 4 commits into
masterfrom
codex/fix-packets-details-row-clamp

Conversation

@dborup

@dborup dborup commented Sep 18, 2026

Copy link
Copy Markdown
Owner

Problem

The packets table's Details cell (td.col-details) was allowed to wrap on desktop/tablet (white-space: normal). Whenever table-layout: auto narrowed that column, long summaries (e.g. #wardriving … @[MapperBot] … channel messages) wrapped to 2–4 lines and the whole row grew to 60–104 px. This:

  • breaks the bounded row height asserted by test-issue-1122-packets-filter-ux-e2e.js (Path cell / row < 60px), and
  • breaks the virtual scroller's constant-row-height assumption (the same concern the existing mobile clamp addresses, #1770/#1805 in code comments).

It is what blocks the CI-only integration draft #66: its Playwright job failed Path column row height stays bounded < 60px with rows of 69/84 px. A Linux diagnosis (Ubuntu 24.04.5, Node 22.23.2, Chromium 145.0.7632.6, the workflow's exact fixture/seed/migrate steps) showed this is fixture-age dependent, not caused by #28/#50:

Tree fixture age 670 s fixture age 710 s
master 37d82e8a pass fail (same 84/84/69/84/84 px as CI)
#66 integration 7368310e pass fail (same)

In both failing cases the Details column narrowed from ~184 px to ~135 px and its text wrapped. CI starts that test ~11.5 min after the fixture is freshened (failing runs 696–699 s, passing runs 672–688 s). The exact trigger of the column redistribution around ~690 s is not identified; this PR does not claim to have found it. It fixes the missing bound instead. The same wrapping reproduces deterministically at ordinary widths (1030–1280 px, 900 px).

Fix (CSS only)

  • Line-clamp the inner .col-details-clip to one line (display: -webkit-box; -webkit-line-clamp: 1; overflow: hidden). The <td> keeps white-space: normal, so column intrinsic widths and the table layout are unchanged. That is why the mobile clamp lives on the inner wrapper too. The existing ≤640px inline-block clip still applies on mobile.
  • Focus rings of links in Details are drawn inset (outline-offset: -2px), because anything outside a one-line clip box is clipped.
  • Above 768 px (where the Path chips already make rows ~30 px) the clip gets an 18 px line box, so 17 px .chan-tag pills are not cut. Row heights are unchanged.

No JS, data, API or threshold changes. No other tables use these classes.

Full message access is unchanged. The Details cell has always been a summary (channel text is already truncated to 80 chars). The full message is shown when a row is selected: desktop split pane, SlideOver at ≤1023 px, and the bottom-sheet header on small mobile. The text also stays in the DOM for screen readers. Advert node links in Details stay on the visible first line and remain clickable. No clickable content exists only in the clipped part.

Screenshots (1200 px, same fixture age)

Before (master): Details wraps, rows 60–72 px. After: one line with ellipsis, all rows ≤31 px, pills intact, no remnants of the hidden second line. Captured locally; not attached because GitHub does not accept uploads via the CLI. They can be provided on request.

Tests

New test-issue-1122-details-row-clamp-e2e.js covers desktop 1200, tablet 900 and mobile 375. It requires at least one Details summary wider than its column, so it cannot pass vacuously. It asserts that every summary is one line, every row is < 60px, the full text is visible in the detail surface after selecting a long row, and Details links are hit-testable. It is registered in the existing E2E step directly after the #1122 test (one added line; triggers, permissions, needs and fork guards unchanged).

Run New test test-issue-1122-packets-filter-ux-e2e.js
master CSS 14/18 (fails at 1200 and 900: wrap + rows up to 72 px) —
this PR 18/18 6/6
mutant: this PR without line-clamp 14/18 —

Also run locally against this PR (fixture server, Chromium 1208): packets/layout E2E (1128 ×2, table-fluid, slide-over, gestures, 1692, 1486, 1146, filter-ux), all nav E2E, test-e2e-playwright.js (131/134, 3 skipped), test-a11y-axe-1668.js (net 0 on desktop and mobile), test-issue-1770-mobile-row-clamp.js, test-issue-1415-packets-layout.js, check-css-vars and git diff --check. All pass.

Linux, same environment as the diagnosis. Fixture age was simulated by shifting the freshened timestamps back in separate scratch DB copies. Seed rows with absolute dates were left alone and the host clock was not changed. The method was validated on unfixed master: fail at 710 s, pass at 670 s.

Tree 670 s 710 s
this PR on master pass (+ new test 18/18) pass (+ 18/18)
this PR merged onto #66's integration — pass (+ 18/18)

An independent reviewer (not the implementer) checked CSS scope, cascade against the mobile rule, column widths, row heights, message access, links and test quality, with pixel checks at DPR 3. Its findings (clipped focus rings/pills, a vacuous line-count check, a click landing in the expand column, and an accidental nav-breakpoint edit) were fixed in the follow-up commits and re-verified.

Limitations

  • At 641–768 px, .chan-tag pills keep a ~1 px bottom cut, the same as at ≤640 px on master.
  • An advert node name that is itself wider than the column shows only its first fragment (the link stays clickable).
  • On desktop, the full preview (up to 80 chars) now needs a click, as on mobile since #1770. No title tooltip was added.
  • Verified in Chromium only; WebKit/Firefox not tested.

#66 stays a draft CI integration; combining it with this fix is a separate step.

🤖 Generated with Claude Code

dborup and others added 4 commits September 18, 2026 16:31
The packets "Details" cell is a summary; the full message is shown in the
detail pane (desktop), SlideOver (<=1023px) or the mobile bottom sheet. On
desktop/tablet the cell was allowed to wrap, so whenever table-layout:auto
narrowed the column the row grew to 2-4 lines. That breaks the bounded row
height asserted by test-issue-1122-packets-filter-ux-e2e.js (seen on Linux
CI at 1400px once the fixture was ~11.5 min old: 69/84px rows) and the
virtual scroller's constant-row-height assumption (Kpa-clawbot#1770). The same
wrapping happens deterministically at 1030-1280px and 900px widths.

Clamp the inner .col-details-clip to one line with line-clamp. The td
keeps white-space:normal, so column intrinsic widths -- and therefore the
table layout -- are unchanged (the reason Kpa-clawbot#1805 moved the mobile clamp to
the inner wrapper). The existing <=640px inline-block/nowrap clamp still
overrides it on mobile. No JS, data or test-threshold changes.

Adds test-issue-1122-details-row-clamp-e2e.js (desktop 1200, tablet 900,
mobile 375): overflowing summaries stay on one line, rows stay < 60px,
the full message is visible in the detail surface, and Details links stay
hit-testable. Registered in the E2E step after the Kpa-clawbot#1122 test.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…etails

Review follow-up to the one-line Details clamp. overflow:hidden on a
one-line box clipped the 2px focus-visible outline (+2px offset) of advert
links and the bottom of .chan-tag pills. Give the clip 4px block padding
offset by a -4px block margin: room for the ring and pill padding, row
heights unchanged (verified at 375-1920px against the previous commit).

Test: judge wrapping by the clip's content-box height for every row (the
getClientRects() line count could never exceed 1 for a block clip), and
select rows by clicking the Time cell instead of a fixed x offset that
landed in the expand column. Clarify the Kpa-clawbot#1770 note in the mobile block.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…e box

The 4px block padding added for focus rings exposed the top 4px of the
clamped (hidden) second line below the summary: slivers of text/pills
under long Details. overflow:hidden clips at the padding box, and any room
below line 1 is where line 2 lives, so padding cannot work.

Instead:
- draw focus rings of links inside the Details clip inset (outline-offset
  -2px); the link box always fits in the one-line clip box;
- above 768px, where the Path chips already make rows ~30px, give the clip
  an 18px line box so baseline-aligned 17px .chan-tag pills are not cut.
  Row heights are unchanged at 375-1920px vs the first clamp commit.
At 641-768px pills keep the 1px bottom cut they already have at <=640px.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The previous commit's 768px -> 769px substitution also hit the unrelated
Priority+ nav block. Restore it to (min-width: 768px); only the Details
line-box rule uses 769px.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@dborup
dborup marked this pull request as ready for review September 19, 2026 04:55
@dborup
dborup merged commit 31c2aa8 into master Sep 19, 2026
11 of 12 checks passed
dborup added a commit that referenced this pull request Sep 19, 2026
dborup added a commit that referenced this pull request Sep 19, 2026
dborup added a commit that referenced this pull request Sep 19, 2026
dborup added a commit that referenced this pull request Sep 19, 2026
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