Transcript: reply footer at ChatGPT size, 8 under the reply
Reply footer, part 2 of 3: ChatGPT's sizing and spacing for a finished reply's buttons and time.
Leo, 2026-11-02: "compared to claude code our bottom thing looks bad is sized bad all around spaced bad + the useless text at the front + didn't i always say we can do it like chatgpt ... notice how on hover it reveals the exact timestamp. let's follow those."
Part 1 (#31609) put the buttons first, moved the time to hover and kept the last reply's buttons visible at rest. This PR changes the sizes and the rhythm:
- A finished reply's footer is now a row of its own, as ChatGPT's is: a 20 glyph in a 32 button, buttons touching (pitch 32, gap 0), radius 8. The first glyph's box stays on the prose's left edge.
- It sits 8 under the reply's last line box (new grid token
gap-footer), and the block gap (24), or a prompt's turn gap, follows it. New tokenstranscript-footer-control(32) andtranscript-footer-icon(20) are in layout-grid.json, desktop.css (regenerated) and LayoutGrid.swift. - The hover time uses the caption size (claude.ai's 11/17), 6 after the last button.
- The running turn's live line drawn as its last row takes the footer's slot (transcriptGrid.ts
MARK_FOOTER_SLOT): 8 under the reply and 32 tall. When the turn ends, the footer replaces it in place and nothing moves. - An empty footer (nothing at rest, turns.ts
isEmptyFooter) still takes no height. Its hover controls keep the compact size and lie in the gap, as on base.
The compact 24 footer line came from #22754, and the old sizing lived there.
Tests: TurnFooter, rowEstimates, continuationSpacing, footerActions, agent-pane-transcript-spacing, reply-footer, agent-pane-composer-rest-gap and transcript-continuation-spacing were updated to the new rhythm and run on the Linux pool. agent-pane-turn-footer ("no footer shows at rest…", "the footer is one row…") and plainUserHeight fail the same way on base.
Follow-up: drop the pending marks on prose-to-footer, footer-to-next and FOOTER in transcriptSpacing.ts once #31614 lands.
Viewed after image: yes (2x captures from test/reply-footer.test.ts, light and dark, rest and hover: 32 buttons touching, 20 glyphs, the first glyph on the prose edge, the time 6 after the last button).
Agent session: agent session
🤖 Generated with Claude Code
Summary by cubic
A finished reply's footer now matches ChatGPT's sizing and rhythm: a 32px row of 32px buttons around 20px glyphs, sitting 8px under the reply's last line, followed by the normal block gap.
- The live line of a running turn reserves the footer's slot, so the end-of-turn swap moves nothing.
- The hover timestamp uses the caption size, 6px after the last button.
- An empty footer (no content at rest) still takes no height; its hover controls keep the compact size in the gap.