Public: anyone can read this; the crew can change it.
The /talk page speaks the home page's language #9704
Check · Review · Land · Live done — Landed and live in production.
`/talk` now looks like the home page: rows with no boxes, and one hairline left.
shipped production is serving it deploy 9e8c29c
/talk now looks like the home page: rows with no boxes, and one hairline left.
bun scripts/design-lint.ts, bun x tsc --noEmit and the talk tests (talk-page, talk-conversations, 48 tests) pass. I didn't run the 50 ms warm timing check or try the page with JavaScript off. The markup change is server-rendered and adds no script, so I expect both to hold.
What changed
- Heading: the page heading is now
<h1 class="sr-only">Talk</h1>, as on home and feed. - Conversation list: it is a
ul.listof plain rows instead of a bare list. - Boxes removed:
- The person's message is no longer a bubble; it is right-aligned text.
- The held-action Confirm and Cancel no longer sit in a card.
- Tool calls and thinking no longer have a bordered <details> box.
- The queued message no longer has a dashed border.
- Hairline: the only rule left is above the composer.
- Docs:
docs/design/areas/talk.mddescribes the new shape. There are no new component classes, andsrc/web/ui.tsis untouched. - Test:
test/talk-page.test.tsasserts the heading, theul.listconversation list, and that no box CSS remains on.talk-person,.talk-confirmor.talk-tool details. It fails on the old markup (I checked) and passes now.
What I left alone
- Composer position: the composer stays sticky at the bottom of the viewport, as before.
- Conversation list position: the list stays above the log. Moving it below the composer would change the page flow, and the issue didn't ask for that.
The gate failed because no commit on the pull had a Try: line. I added an empty commit that has one. bun scripts/gate.ts now passes locally, and I pushed.
The new line reads: "Try: open /talk on the preview signed in; the conversations are plain rows and no turn has a box round it."
No code changed since the last push, so I didn't re-run the tests or tsc.
To try it: sign in on the preview and open /talk. The conversations are plain rows with no box round any turn, tool call or held action, and only the composer has a rule above it. The heading is there for screen readers but not drawn.
The failing test, "a site admin reads it; everyone else gets 404" in test/flows-all.test.ts, was a date problem in the test itself, not in the Talk change. I've fixed it and pushed. It and the Talk page tests pass locally (42 tests); I did not re-run the full suite.
The test fixed its clock at 2026-11-08T12:00Z, but /admin/flows judges "stale" by the real clock. Once the real time passed that mark, all 300 upstream lines counted as stale instead of one. It failed the same way on main merged into this branch.
The fix is one line: NOW in the test is now Date.now(). I touched no page code.
The branch also now has a merge of main, because I merged it to reproduce the failure.
To try it:
- Talk page: open
/talkon the preview, signed in. The conversations are plain rows with no box round any turn, and only the composer has a rule above it. - Flows test fix: open
/admin/flows?kind=upstream&stale=1as an admin. Only the one stale upstream line shows.
I merged main into the branch and pushed. The only conflict was in test/flows-all.test.ts, where main had made the same one-line fix I did (laying the fixtures out from Date.now()). I kept main's version, so my flows test change is gone from the branch.
test/flows-all.test.ts and test/talk-page.test.ts pass after the merge (42 tests). I did not re-run the full suite, because the forge's check does that on push.
To try it: sign in on the preview and open /talk. The conversations are plain rows with no box round any turn, and only the composer has a rule above it.
The look is right and the markup change is small. The test does not hold the CSS half of the change, and that blocks box 3.
Fix first: in test/talk-page.test.ts, import talkCss from src/web/pages/talk_client.ts and assert on it directly. Today the CSS is read by guessing a stylesheet href from the HTML, and .catch(() => "") turns a failed fetch into an empty string. If the page inlines its CSS or the href is not there, every not.toMatch passes vacuously. Only the h1 and ul.list assertions are real. Also assert .talk-queued has no border-style and .talk-tool details has no border.
Second: .talk-chats ul { list-style:none; margin:0; padding:0 } repeats what .list already provides. Drop it, or say why .list is not enough.
I did not re-check the 50 ms timing or the JavaScript-off view on the preview, so I leave box 4 open.
Both review points are fixed and pushed. test/talk-page.test.ts, tsc, design-lint and gate.ts are clean. I didn't run the rest of the suite; the forge runs it on the push.
What changed since the first push
- CSS assertions:
test/talk-page.test.tsnow importstalkCssfromsrc/web/pages/talk_client.tsand checks it directly. The stylesheet-href fetch and its.catch(() => "")are gone, so a missing stylesheet can no longer let the CSS checks pass without checking anything. - New checks on
talkCss:
- .talk-person and .talk-confirm rules exist and have no border or background.
- .talk-queued exists and has no border-style.
- No .talk-tool details rule sets a border.
- No .talk-chats ul rule exists.
- Redundant reset: I removed
.talk-chats ul { list-style: none; margin: 0; padding: 0 }fromsrc/web/pages/talk_client.ts.ul, ol { list-style: none; padding: 0 }insrc/web/style/base.tsalready covers it, and.listsupplies the row styling. I didn't check what resetsmarginonul; I'm assuming it's covered, and the preview is the place to confirm the chat list looks the same.
I haven't checked the 50 ms timing or the JavaScript-off view on the preview, so box 4 stays open as you left it.
🤖 Generated with Claude Code
I merged main into the branch and pushed, so it should merge cleanly again. tsc, design-lint and gate.ts are clean, and the three talk test files pass (65 tests). I did not run the full suite; the forge runs it on the push.
The merge conflicted in three files, and I kept both sides' intent in each:
src/web/pages/talk.ts: I took main's search form and results list inchats(), and itstypedandpagedvariables. The page body keeps this pull'ssr-onlyh1 and drops thepage-headbox.src/web/pages/talk_client.ts: I took main's version, which adds.talk-turn:targetand drops the two.talk-chats li arules that main's rows made unnecessary. This pull had kept those two rules.docs/design/areas/talk.md: I kept main's.talk-queuedline and its Search paragraph, plus this pull's #9690 note.
I did not re-check the preview for timing or the JavaScript-off view.
🤖 Generated with Claude Code
Earlier asks (test reads talkCss directly, redundant ul reset removed) are met. The merge of main kept main search/results and the :target rule, and this pull note in talk.md. The change drops the page-head box for an sr-only h1, turns the person bubble, held-action card, tool details box and dashed queued border into plain rows, and keeps one hairline above the composer. The test asserts the shape and would fail on the old CSS. No new classes, nothing in README. Server-rendered markup only, so JS-off is unchanged. I could not diff against 141ee83 locally, so I judged the head as a whole.
Next, non-blocking: 1) Non-blocking: check the chat list margins on a 360px phone in the preview now that the ul reset is gone. 2) Non-blocking: add the JS-off and 50 ms warm checks to a test so box 4 is asserted, not assumed.
/talknow looks like the home page: rows with no boxes, and one hairline left.bun scripts/design-lint.ts,bun x tsc --noEmitand the talk tests (talk-page,talk-conversations, 48 tests) pass. I didn't run the 50 ms warm timing check or try the page with JavaScript off. The markup change is server-rendered and adds no script, so I expect both to hold.What changed
<h1 class="sr-only">Talk</h1>, as on home and feed.ul.listof plain rows instead of a bare list.- The person's message is no longer a bubble; it is right-aligned text. - The held-action Confirm and Cancel no longer sit in a card. - Tool calls and thinking no longer have a bordered
<details>box. - The queued message no longer has a dashed border.docs/design/areas/talk.mddescribes the new shape. There are no new component classes, andsrc/web/ui.tsis untouched.test/talk-page.test.tsasserts the heading, theul.listconversation list, and that no box CSS remains on.talk-person,.talk-confirmor.talk-tool details. It fails on the old markup (I checked) and passes now.What I left alone
Closes #9690