Repository navigation
Shade a Chat row's whole height, so neighbouring rows' shades meet, and keep thread rows inside their panel - #882
Merged
Merged
Conversation
In Chat's workflow runs card, the hairline between two runs was the lower run's row border, outside its line. A hovered line's shade stopped under it, and a pointer on that pixel was on no line, so moving down the card crossed a 1px unshaded band between every two lines. The hairline is now the line's own top border, so the pointer on it is on the line, and the line's shade runs under it from the card's left edge to its right. The hairline is drawn over the shade, as before, at the same contrast against what is behind it. Nothing moves: the border is where the row's was, and the card keeps its box. run-card's hover test now checks that the second run's shade meets the run above it and that the hairline finds its line. Offsets are read from inside the line's border. It fails on b8bf8eb with a 1px gap. Assistant-model: Claude Opus 5.5 Assistant-workflow: inline (subagent) Assistant-verification: bun run types Assistant-verification: bun run ci Assistant-verification: playwright run-card (passes; the new check fails on b8bf8eb) User-preference: "why don't the containers for the message hover still not encapsulate the entire box? I still see a gap ... with some margin or padding" Co-authored-by: Alex Lavaee <lavaman131@github.com>
A shown Chat row was shaded edge to edge but not top to bottom. Its shade reached 4px above a message (32px over a group's first, its name line and 8px) and 4px or 8px below, while messages in a group are 4px apart and the transcript's rows 16px. So neighbouring shades overlapped by 2px to 4px, and, more visibly, the pointer found the row only in the message's own box: in every gap, and over every avatar, it was on no row at all. Moving a mouse down Chat crossed unshaded bands of 6px to 8px between rows, and the shaded box looked inset. Each message's shade now reaches to the middle of the gap on both sides: 2px in a group, 8px between rows (over the name line for a group's first message, which stands 2px above its row). So neighbouring shades meet with no band and no overlap, past notices and other rows that are not messages, at a thread's lead and at both ends of the transcript. Under a mouse, inside a transcript, the shade itself and the avatar are where the pointer finds the row, so the pointer passes from one row's shade straight into the next one's. A touch screen keeps the rows' own boxes, so a reaction's 44px target that stands past its row still takes the tap. Every shaded state (hover, keyboard focus, menu or picker open, a long press, a jumped-to wash, an open thread's root) uses the same pitch, and a long-pressed row's toolbar lane is part of its own. Content does not move; the toolbar keeps standing 16px above its row's shade, 2px lower than before. With a thread open and the document folded to its bar, the thread's rows were shaded 20px past the thread panel, to the window's edge and past the header above them. They now stop at the panel's edge, where its header's rule ends: the folded pane's clip path and the thread's reach into the gutter after it are gone. The pane's clip keeps its unbounded top and foot, so lazy images above Chat still load (chat-images passes). chat-row-edges measures every message's shade against its pitch and sweeps a mouse's hit test down the container's start, the avatars and the text, in Chat and in the thread, at 1440 (folded), 1920, 1100, 640 and on a phone (extents only there), with a notice, a grouped pair, the agent's rows and an image row. It also hovers 4px into the gaps above and below a row, checks a jumped-to wash covers the shade's pitch, and measures a folded thread's rows against the thread panel. These fail on b8bf8eb. Assistant-model: Claude Opus 5.5 Assistant-workflow: inline (subagent) Assistant-verification: bun run types Assistant-verification: bun run ci Assistant-verification: playwright chat-row-edges, run-card, chat-hover-contrast, chat-images, chat-motion, chat-phone, chat-threads, chat-toolbar-in-view, message-actions, message-toolbar-layout, pane-resize, pane-work (136 passed) Assistant-verification: playwright chat-row-edges and run-card on b8bf8eb (6 of the extended tests fail there) Assistant-verification: bun run design:behavior (106 passed) Assistant-verification: bun run build (initial JS 259,958 B raw / 82,474 B gzip; CSS 184,261 B raw / 32,644 B gzip) User-preference: "why don't the containers for the message hover still not encapsulate the entire box? I still see a gap ... with some margin or padding" Co-authored-by: Alex Lavaee <lavaman131@github.com>
…rule A thread's root is now drawn as Chat draws a message, inside the thread's lead, between the provenance line and the replies' rule, 12px from each. Its shade took the transcript's half gap of 8px, so it reached 2px over each of them. It now takes half of the lead's gap (6px), through one custom property for the half of the gap between rows (`--chat-row-half`), which a group's first and last messages and the name line's reach read. chat-row-edges reads the lead's rows one by one, so the root's row is measured against its pitch and swept for bands like any other; it failed on the rebased branch before this change, with the root found 2px into the lead's rows. Assistant-model: Claude Opus 5.5 Assistant-workflow: inline (subagent) Assistant-verification: bun run types Assistant-verification: bun run ci Assistant-verification: playwright chat-row-edges, chat-threads, chat-thread-reactions, message-toolbar-layout, chat-toolbar-in-view (43 passed) Assistant-verification: playwright run-card, chat-hover-contrast, chat-images, chat-motion, chat-phone, message-actions, pane-resize, pane-work (97 passed) User-preference: "why don't the containers for the message hover still not encapsulate the entire box? I still see a gap ... with some margin or padding" Co-authored-by: Alex Lavaee <lavaman131@github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Shade a Chat row over its whole pitch, as Slack's rows tile its pane
What the maintainer saw
After the change that took the hover shade to Chat's side edges went live: "why don't the containers
for the message hover still not encapsulate the entire box? I still see a gap ... with some margin or
padding".
Measured on a hosted deployment, side to side was already 0px on message rows. Three things were
still wrong:
4px above its message (32px over a group's first message) and 4px or 8px below. So:
avatar, it was on no row at all. Moving a mouse down Chat crossed unshaded bands of 6px to 8px,
and the shaded box looked inset.
20px past the thread panel, to the window's edge and past the header card above it.
stopped under it, and the pointer on it was on no line.
The cause
--chat-highlight-top, then-var(--spacing)or-2 * var(--spacing)below)were set as "a little room around the message", not as the middle of the gap to each neighbour.
:hoverwas the message's own box. The shade hadpointer-events: none, so it was never where thepointer found the row.
thread's transcript reached 20px past its panel into it.
.run-row + .run-row { border-top }: the row's border, outsidethe line (
.run-head) that is hovered and shaded.The fix
Chat rows (
message-actions.css):8px between rows (
--chat-gap-above,--chat-gap-below). A group's first message reaches over itsname line, which stands 2px above its row, to the same middle.
that are not messages, at a thread's lead, and at both ends of the transcript.
the avatar (
@media (hover: hover) and (pointer: fine)). The pointer passes from one row's shadestraight into the next one's, as in Slack.
and must still take the tap (message-toolbar-layout caught this in a first version).
a jumped-to wash, and an open thread's root. A long-pressed row's toolbar lane is part of its own
pitch.
to the provenance line and the replies' rule, which are 12px from it (
thread-panel.css, through--chat-row-half).Folded thread (
theme.css,workspace-sizing.css):stop where the thread's header rule ends.
(chat-images passes).
Run card (
run-card.css,run-row.css):shade runs under it. The card and its lines do not move.
DESIGN.mdrecords the pitch, the folded thread's edge and the run card's hairline.Evidence
Synthetic documents only. Chopin has one theme:
.darkand the system preference read the sametokens, and this change adds no colour.
In the gap shots, the pointer is 4px above the agent's row. Before, it is on no row and nothing is
shaded. After, the agent's row is shaded with its toolbar. In the folded thread, the shade ran to the
window's edge; now it ends with the thread's header rule. The run card's change is one pixel: the
hairline above the hovered line is drawn over the shade.
What the tests check
e2e/chat-row-edges.e2e.tsgainspitches(). For every message in a transcript it checks:shades meet with no gap and no overlap;
the row whose pitch it is in at every pixel, and no message between rows that are not messages.
It runs in Chat and in the thread at 1440 (document folded), 1920 (thread beside the document), 1100
and 640, and on a phone (extents only: a touch screen has no pointer moving down it). Those layouts
include a notice, a grouped pair, the agent's rows, an image row and a thread's lead. The tests also:
e2e/run-card.e2e.tschecks that the second run's shade meets the run above it and that the hairlinefinds its line.
On b8bf8eb, 6 of these tests fail. They report every shade 2px off its pitch, unshaded bands at
every gap and avatar, and a 1px gap in the run card. All pass here.
Contrast
chat-hover-contrast passes. It reads the time, links, the replies count and the toolbar icons
against the rendered shade.
screenshots' pixels:
The hairline keeps its contrast against what is behind it. It is a decorative divider, unchanged
in colour.
Checks run
bun run types: passes.bun run ci: passes.chat-toolbar-in-view: 43 passed;
pane-resize and pane-work: 97 passed.
bun run design:behavioron the final head: 103 passed. Three tests (build-blockers, the darkcontrast plate and cursors) timed out waiting for the audit page to load, and passed when run again
(22 passed). The dev server was run with
CHOKIDAR_USEPOLLING=1, because the shared machine wasout of inotify instances. Before the rebase, the whole suite passed (106).
bun run build:The initial stylesheet is 290 B smaller than on b8bf8eb.
Judgement calls
into row padding, because that would change every row's box, the toolbar's anchor and the
transcript's layout, and pane-work's counts with them. Only the shade's insets and its hit area
changed.
column's
-mt-0.5), so the shade reaches 6px above the name line and 8px above the row.must win over the next row. Outside a transcript (the design audit's plates), nothing clips the
shade's 100vw sides, so a hit area there would cover other controls.
it shades the row.
[data-thread-panel]), whereits header rule ends. I did not choose the frame's edge 8px further, under the header card's corner.
The maintainer's report named the panel's edge. With the document open, the thread still reaches
the sheet, over the 8px where Resize chat is taken, as main Chat does.
above its row. So it sits 2px lower than before, or 4px higher for a group resumed after an offer
card. The offer card is the only row that splits a group; that case is covered by CSS and not by a
test.
hairline too, and the hairline stays drawn over the shade. An open run's stages are not part of its
line, and are not shaded, as before.
Impeccable passes
The audit (interaction states), polish and the critique against Slack are in
critique.mdbeside thisfile. In short: