fix(desktop): restore timeline zoom via rem tokens + chat-as-base type scale#1052
Merged
Conversation
Cmd +/- zoom scales the root <html> font-size (rem-only by design), but PR #891 converted the message-timeline + thread render path from rem tokens to hardcoded px (text-[15px]/text-[13px], font-size: 15px), freezing that text against zoom. Preserve Kenny's 15px chat sizing intent but express it in rem so it scales: add rem-based `text-chat` (0.9375rem === 15px) and `text-code` (0.8125rem === 13px) Tailwind tokens, and swap the px classes over in MessageRow, markdown, mentionChip, and globals.css (.mention-highlight). Codify it: add `pnpm check:px-text` CI guard flagging new px text in the timeline/thread render path, wired into `pnpm check`, plus an AGENTS.md note steering future agents to rem tokens. Scoped to the regression footprint — no app-wide sweep. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
tho's reframe: chat text is the app's fundamental building block, so it should *be* the base type size, not a between-the-cracks 15px token wedged between text-sm (14px) and text-base (16px). Bump chat to 16px-as-base and re-anchor the timeline/thread type ramp: - Retire the custom `text-chat` (15px) and `text-code` (13px) rem tokens added in the zoom fix (#1051) — with chat at the stock base they're redundant artifacts of the 15px-wedge era. - Chat body + author → stock `text-base` (16px) in MessageRow, markdown, mentionChip. `.mention-highlight` follows chat to 1rem. - Code (inline + block) → stock `text-sm` (14px) — a deliberate, documented one-notch step down from the 16px base. Satellite elements (timestamps text-xs, system rows text-sm/xs, thread summary, reactions) are deliberately left on their stock tokens: against a 16px base the ratios tighten into the canonical base→sm→xs ramp (16/14/12) instead of the awkward 12/15 they sat at before. Bumping them would inflate the UI for no design gain. Everything stays rem so Cmd +/- zoom keeps scaling it; the check:px-text guard stays green (its guidance updated to point at the stock scale). Net: zero custom font tokens, timeline/thread render path only — no app-wide sweep. Composer chrome (.tiptap pre code) left untouched. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
tellaho
added a commit
that referenced
this pull request
Jun 15, 2026
DiffViewer renders in the message/timeline path via DiffMessage.tsx, so its 3 px font-size rules (.diff, .buzz-diff-gutter, .diff-decoration-content) stayed frozen against Cmd +/- zoom — the same bug class the rem sweep targets. These sat outside the text-[Npx] Tailwind-literal scope (plain CSS) and aren't caught by #1052's px-guard, which scopes CSS to globals.css only. Convert 1:1 with zero pixel shift: 12px -> 0.75rem, 11px -> 0.6875rem. Keeps the app-wide sweep honest. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
tellaho
added a commit
that referenced
this pull request
Jun 15, 2026
The composer's Tiptap .mention-highlight pill used a hardcoded font-size: 15px, freezing it against Cmd +/- zoom (which scales the root rem font-size). Convert to 1rem so it scales, and align to the timeline mention chip's text-base (1rem) sizing per #1052's chat-base type scale. Emoji-mart picker --font-size left as-is per scope. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Cmd +/- zoom scales the root html font-size (rem-only by design), but text-[Npx] font literals froze text in pixels and broke zoom outside the timeline. Convert the 63 non-overlapping UI surfaces to rem so text scales proportionally everywhere. Mapping: 12px -> stock text-xs token; sizes with no clean stock home (7-11px micro-text on avatars, badges, chips) -> 1:1 rem literals to preserve exact visual hierarchy with zero pixel shift. Also converts the 2 stray leading-[100px] line-height literals to rem. Deliberately defers the 3 render-path files (MessageRow.tsx, markdown.tsx, mentionChip.ts) to PR #1052, which already converts them and is awaiting merge — touching them here on a main base would manufacture a conflict. The check:px-text guard lands with #1052; once it merges, the guard covers this branch's 63 files plus #1052's 3. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
DiffViewer renders in the message/timeline path via DiffMessage.tsx, so its 3 px font-size rules (.diff, .buzz-diff-gutter, .diff-decoration-content) stayed frozen against Cmd +/- zoom — the same bug class the rem sweep targets. These sat outside the text-[Npx] Tailwind-literal scope (plain CSS) and aren't caught by #1052's px-guard, which scopes CSS to globals.css only. Convert 1:1 with zero pixel shift: 12px -> 0.75rem, 11px -> 0.6875rem. Keeps the app-wide sweep honest. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
The composer's Tiptap .mention-highlight pill used a hardcoded font-size: 15px, freezing it against Cmd +/- zoom (which scales the root rem font-size). Convert to 1rem so it scales, and align to the timeline mention chip's text-base (1rem) sizing per #1052's chat-base type scale. Emoji-mart picker --font-size left as-is per scope. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
…pp-wide Arbitrary `text-[…rem]` literals had drifted across the desktop app pixel-by-pixel (11/10/9/8/7px), and the px-text guard only covered the message-timeline render path. This mints two named meta-text tokens and sweeps every arbitrary text literal onto the rem-based scale so Cmd +/- zoom keeps scaling and the sizes stay on one consolidated ramp. - Add `text-2xs` (0.6875rem/11px) and `text-3xs` (0.5rem/8px) to `tailwind.config.js` under `theme.extend.fontSize`. - Swap arbitrary literals to named tokens (round-up merges): 0.6875/0.625/0.5625rem -> `text-2xs`, 0.5/0.4375rem -> `text-3xs`. - Odd ducks: 0.8125rem (13px) -> stock `text-sm`, 10.5px -> `text-2xs`. - Leave the `text-[6rem]` avatar emoji glyph (decorative, allowlisted). - Widen the px-text guard: scan all of `desktop/src` and reject any arbitrary text-size literal (px **or** rem/em), not just px in the render path. Allowlist the avatar glyph by `path:line`. - Document the tokens + guard in AGENTS.md. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Update rich-text composer mention highlight styling in desktop/src/shared/styles/globals.css to inherit the editor font size instead of forcing text-base - Reduce chip padding to rem-based values so mention, agent mention, and channel highlights align with the composer line height - Remove the stale comment that tied composer chips to timeline chip sizing, preserving the larger rendered timeline chip style separately
- Remove the compact and tight props from the shared Markdown component API - Collapse MarkdownVariant handling into one default text rhythm with leading-6 body text - Update message, inbox, pulse, recent note, and agent transcript callers to stop passing compact/tight display flags - Simplify Markdown memo comparisons now that sizing variants are no longer part of the public surface
- Move mention chip sizing and hover treatment into shared CSS classes consumed by timeline markdown and composer decorations - Apply shared chip styling to channel links and message links so inline semantic chips use one visual treatment - Keep bot mentions optically balanced with agent-specific right padding and a slightly larger robot mask icon - Align composer text with the chat base type size and reduce mention/code radii by one token for a tighter inline appearance
- Add shared MessageHeaderRow and MessageAuthorText primitives for timeline header spacing and author/title typography - Use the shared header primitives in normal and system message rows so usernames, system titles, and timestamps align consistently - Reduce main timeline username size to match surrounding message surfaces and remove the extra body offset now that header line boxes align - Render system-event participants as profile names instead of mention chips and drop unused agent/persona props from system row plumbing
- Increase timeline message avatars to the 10 spacing token so one-line messages have a clearer visual anchor - Replace the previous negative text-column offset with an explicit gap between the header and body - Set header author and timestamp line-height to leading-4 so the header plus one body line aligns with the avatar height - Apply the same header/body gap treatment to system message rows for consistent vertical rhythm
Reconcile the px->rem / named-token type-scale sweep with main's DM/members modal polish (#1054). Resolved 14 conflicted files plus two silent auto-merge regressions caught by tsc/lint (not by conflict markers): - SystemMessageRow.tsx: auto-merge reverted to pre-main, dropping main's agent-mention feature (normalizePubkey/mentionChip, ProfileName highlight/isAgent, describeSystemEvent personaLookup+agentPubkeys, header restructure). Restored main's version, re-applied branch's text-2xs avatar token swaps, rewired agentPubkeys+personaLookup props. - markdown.tsx: auto-merge took branch side, dropping main's compact/tight MarkdownVariant + runtimeRef refactor (4 callers pass compact). Restored main's compact variant + runtimeRef, re-applied branch's migrations: code-block/inline-code text-[13px]->text-sm, rounded-md->rounded-sm, channel-link/message-link chips -> MENTION_CHIP_BASE/HOVER_CLASSES, compact-variant text-[15px]->text-sm. Combined both sides per the merge theme: kept branch's named-token migrations AND main's functional features. pnpm check + tsc + just ci green (desktop 729/729; mobile-test skipped locally, no dart toolchain and no mobile files touched). Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Reapply the removal of Markdown compact/tight display variants while preserving the merged runtime-ref markdown implementation - Switch markdown body copy to unitless leading-relaxed so timeline text scales proportionally with app zoom - Remove compact Markdown props from forum, feed, and channel canvas callers introduced by the main-branch merge - Restore system-event participant rendering as plain profile names and remove unused agent/persona props from SystemMessageRow plumbing
wesbillman
approved these changes
Jun 16, 2026
- Update shared mention chip CSS to inherit both font-size and line-height from its surrounding text context - Avoid future drift between global chip styling and timeline/forum/body copy wrappers as typography changes
Message bodies felt too heavy at text-base after the type-scale cleanup. Restore stock text-sm on the primary Markdown surfaces so chat and forum content matches the shared Markdown default and surrounding chrome. - MessageRow: change body Markdown override from text-base to text-sm - ForumPostCard: set explicit text-sm on post preview Markdown - ForumThreadPanel: set explicit text-sm on post body and reply Markdown - TimelineMessageList: drop unused personaLookup destructure (build fix)
System event actions were too dim at muted-foreground/70, and Markdown bodies inherited text-foreground/90 from the shared wrapper. Use default foreground for readable copy while timestamps stay muted. - SystemMessageRow: title and action text use text-foreground - markdown.tsx: drop /90 opacity on shared Markdown body wrapper - VideoPlayer: video review comment body uses text-foreground
The Tiptap composer still rendered at 1rem because globals.css overrode the editor's text-sm classes. Align composer body and code with timeline Markdown at text-sm and leading-relaxed. - globals.css: set .rich-text-composer .tiptap to 0.875rem / 1.625 lh - globals.css: bump composer inline and fenced code to 0.875rem - useRichTextEditor: use leading-relaxed on editor attributes
- Scope mention, agent, and inline-code chip CSS under `.message-markdown` so timeline markdown and the TipTap composer render identical chips - Add `MESSAGE_MARKDOWN_CLASS` to the composer editor and drop the legacy `mention-highlight` decoration class in favor of shared `mention-chip` - Restore compact vertical padding with baseline alignment; agent bot icon is absolutely positioned in a left-padded gutter so it no longer affects chip height - Migrate composer typography to Tailwind v4 CSS vars (`--text-sm`, `--text-xs`, `--leading-relaxed`) and route inline code through `INLINE_CODE_CHIP_CLASS` with token-based mono sizing - Update mentions e2e selectors/assertions for the new chip class names
- Replace ad-hoc inline-code sizing with `.message-markdown` CSS vars: one shared chip box (padding + min-height), text-xs labels for inline mono, and named agent-icon offsets - Use inline-flex centering so smaller code labels sit in the same box as mention chips without em-ratio hacks - Bump fenced code blocks and composer pre code to text-sm font-medium (500) so block code matches body weight while inline code stays one step down - Update mentions e2e to expect inline-flex agent chips
Merge origin/main (animated avatars #1031, unread indicators, spoiler formatting, auto-migrations, visual polish) into tho/chat-base-type-scale. Two real conflicts resolved as a combine, dropping neither side: - MessageRow.tsx: keep tho's MessageHeaderRow structure, apply main's bodyOffsetClass for body vertical offset. - ProfileSettingsCard.tsx: take main's avatar-editor superset wholesale, re-apply tho's leading token; px-guard override bumped to :573. Also tokenized two new main violations (MessageTimeline text-[11px]->text-2xs, UnreadDivider text-[10px]->text-2xs) and reordered globals.css inline-chip vs code-block selectors to clear noDescendingSpecificity. Verified: tsc --noEmit clean, biome/pnpm check clean, px-text guard pass, 864/864 desktop unit tests pass, desktop production build succeeds. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Add explicit markdown renderers for h4, h5, and h6 so all heading levels use app-controlled typography instead of browser defaults - Reduce adjacent paragraph spacing to mt-1.5 while preserving larger spacing around other block types - Extend heading spacing rules across h1-h6 and tighten consecutive heading stacks for cleaner markdown previews
The main merge accidentally dropped main's agent-aware rendering from SystemMessageRow.tsx, breaking the mentions.spec.ts smoke test that expects managed-agent names in system add/remove rows to render with [data-mention].agent-mention-highlight. Combined main's agent-mention logic back in (ProfileName highlight/isAgent props + mention-chip classes, describeSystemEvent isTargetAgent detection, agentPubkeys/personaLookup props + pass-through) while keeping the type-scale tokenizations that landed on this branch (avatar text-2xs swaps and system-row text-foreground color tightening). Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
tellaho
added a commit
that referenced
this pull request
Jun 17, 2026
* origin/main: (26 commits) fix(desktop): restore timeline zoom via rem tokens + chat-as-base type scale (#1052) fix(release): format changelog as linked markdown bullets (#1075) chore(release): release version 0.3.24 (#1074) feat(desktop): refine thread-unread badge to two-token form (#1069) fix(buzz): prevent reconnect storms from reaped ephemeral channels (#1071) fix(buzz-acp): trim oversized observer frames to fit instead of dropping (#1072) perf(ci): speed up PR CI wall clock and local dev builds (#1028) chore(deps): update react monorepo (#1048) Polish desktop visual details (#1067) ci: use running postgres for pgschema desired-state planning (#1070) fix(desktop): anchor active-turn badge to skew-corrected agent start (#1068) feat(desktop): add configurable transport reconnect hook (#1059) Add automatic database migrations (#988) Add composer spoiler formatting (#1055) feat(desktop): in-channel and in-thread unread indicators (#1008) perf(timeline): gate heavy message render behind useDeferredValue (#1022) Add animated profile avatars (#1031) Polish direct message and members modals (#1054) Polish huddles UI (#1041) Fix video review comments in threads (#1056) ... Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com> # Conflicts: # desktop/src/features/messages/lib/useRichTextEditor.ts # desktop/src/features/messages/ui/MessageComposer.tsx
tellaho
added a commit
that referenced
this pull request
Jun 25, 2026
…ship model Replay of PR #1061 (tho/activity-ui-polish) onto fresh main: lands the 20 UI-polish commits as one net diff, reconciled with #1229's merged declared-ownership model (viewerIsOwner = isCurrentUserOwner || isOwner) and #1089's content-visibility-auto virtualization. Notable reconciles: - markdown.tsx: ported the compact/tight variant system into main's newer lightbox/spoiler markdown component (rather than overwriting it), layering variant density/leading overrides after the base owl-spacing so tailwind-merge wins. Dropped the branch's hardcoded text-[15px] in favor of main's rem-token text-sm base (post-#1052 zoom-safe scale). - agentSessionTranscript.ts: pass TranscriptItemContext (not channelId). - managed_agents: thread avatar_url through ManagedAgentSummary so the transcript renders the assistant-bubble avatar from the pinned record snapshot; bumped runtime.rs size override 2001 -> 2002 for the +1 line. Observer-seed screenshots intentionally excluded (separate follow-up). Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
tellaho
added a commit
that referenced
this pull request
Jun 30, 2026
…ship model Replay of PR #1061 (tho/activity-ui-polish) onto fresh main: lands the 20 UI-polish commits as one net diff, reconciled with #1229's merged declared-ownership model (viewerIsOwner = isCurrentUserOwner || isOwner) and #1089's content-visibility-auto virtualization. Notable reconciles: - markdown.tsx: ported the compact/tight variant system into main's newer lightbox/spoiler markdown component (rather than overwriting it), layering variant density/leading overrides after the base owl-spacing so tailwind-merge wins. Dropped the branch's hardcoded text-[15px] in favor of main's rem-token text-sm base (post-#1052 zoom-safe scale). - agentSessionTranscript.ts: pass TranscriptItemContext (not channelId). - managed_agents: thread avatar_url through ManagedAgentSummary so the transcript renders the assistant-bubble avatar from the pinned record snapshot; bumped runtime.rs size override 2001 -> 2002 for the +1 line. Observer-seed screenshots intentionally excluded (separate follow-up). Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
tellaho
added a commit
that referenced
this pull request
Jun 30, 2026
…ship model Replay of PR #1061 (tho/activity-ui-polish) onto fresh main: lands the 20 UI-polish commits as one net diff, reconciled with #1229's merged declared-ownership model (viewerIsOwner = isCurrentUserOwner || isOwner) and #1089's content-visibility-auto virtualization. Notable reconciles: - markdown.tsx: ported the compact/tight variant system into main's newer lightbox/spoiler markdown component (rather than overwriting it), layering variant density/leading overrides after the base owl-spacing so tailwind-merge wins. Dropped the branch's hardcoded text-[15px] in favor of main's rem-token text-sm base (post-#1052 zoom-safe scale). - agentSessionTranscript.ts: pass TranscriptItemContext (not channelId). - managed_agents: thread avatar_url through ManagedAgentSummary so the transcript renders the assistant-bubble avatar from the pinned record snapshot; bumped runtime.rs size override 2001 -> 2002 for the +1 line. Observer-seed screenshots intentionally excluded (separate follow-up). Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
tellaho
added a commit
that referenced
this pull request
Jun 30, 2026
…ship model Replay of PR #1061 (tho/activity-ui-polish) onto fresh main: lands the 20 UI-polish commits as one net diff, reconciled with #1229's merged declared-ownership model (viewerIsOwner = isCurrentUserOwner || isOwner) and #1089's content-visibility-auto virtualization. Notable reconciles: - markdown.tsx: ported the compact/tight variant system into main's newer lightbox/spoiler markdown component (rather than overwriting it), layering variant density/leading overrides after the base owl-spacing so tailwind-merge wins. Dropped the branch's hardcoded text-[15px] in favor of main's rem-token text-sm base (post-#1052 zoom-safe scale). - agentSessionTranscript.ts: pass TranscriptItemContext (not channelId). - managed_agents: thread avatar_url through ManagedAgentSummary so the transcript renders the assistant-bubble avatar from the pinned record snapshot; bumped runtime.rs size override 2001 -> 2002 for the +1 line. Observer-seed screenshots intentionally excluded (separate follow-up). Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.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.
Category: fix
User Impact: Browser zoom (Cmd +/-) once again scales text everywhere it should — message timeline, thread UI, diff viewer, and the composer mention pill — chat copy reads at a deliberate
text-smrhythm, and the timeline/composer now render identical mention + code chips. Bundles the latestmain(animated avatars, unread indicators, spoiler formatting, auto-migrations) so this branch ships current.Problem: Zoom scales the root
<html>font-size (rem-only, by design from #573). PR #891 ("Tune chat text sizing") converted timeline + thread text from rem tokens to hardcoded px (text-[15px]/text-[13px]), which froze that text against zoom. The bug was the unit, not the size. Once the render path was fixed, a broader sweep found the same px-vs-rem regression scattered across the rest of the app (DiffViewer, composer mention highlight, and ~65 other text literals). Alongside the unit fix, the chat type scale wanted a deliberate pass: chat shouldn't be a between-the-cracks custom token wedged at 15px. Layered on top,mainmoved fast underneath the branch — animated avatars (#1031), unread indicators, DM/members polish, spoiler formatting, and auto-migrations all landed — so the branch had to absorb twomainmerges and reconcile real conflicts without dropping either side.Solution: One coherent zoom-and-type-scale fix, then a clean merge of current
main, then a post-merge refinement pass that settled the final chat rhythm:check:px-textguard so px text can't be reintroduced.text-chat(15px) /text-code(13px) tokens (→ zero custom font tokens) and route chat onto the stock Tailwind ramp. After the post-merge refinement pass, chat body settles on stocktext-sm(14px) — it felt too heavy attext-base, so the final decision istext-smbody withtext-smblock code andtext-xsinline-code labels.text-2xs(0.6875rem/11px) andtext-3xs(0.5rem/8px) tokens for genuinely sub-xs surfaces (badges, avatar initials, dense meta).DiffViewer.cssfont-size px → rem; scale the composer mention pill with zoom and align it to the timeline mention chip.check:px-textnow rejects any arbitrary text-size literal — px and rem/em — across all ofdesktop/src, so the regression class can't return.main(two merges, conflicts resolved as a combine) —49b6255areconciled the type-scale sweep with main's DM/members polish (Polish direct message and members modals #1054) + restored main'sSystemMessageRowagent-mention feature andmarkdown.tsxcompact/runtimeRef refactor that auto-merge had silently dropped.1b8632cbthen combined main's animated-avatar editor (Add animated profile avatars #1031), unread indicators, and spoiler formatting — keeping tho'sMessageHeaderRowstructure + leading token while taking main'sbodyOffsetClassand avatar-editor superset wholesale..message-markdownchip box; match composer body/code to timeline attext-sm/leading-relaxed; downshift chat + forum bodies totext-sm; give system-event titles/actions full foreground; let mention chips inherit text rhythm from context; and tighten markdown block + heading spacing (explicit h4–h6 renderers,mt-1.5adjacent-paragraph spacing).All commits kept intact (no squash) to preserve the "rem floor → type re-anchor → app-wide sweep → guard → merge current main → refine" trail.
File changes (84 files)
desktop/tailwind.config.js
Net zero between-the-cracks font tokens —
text-chat/text-coderetired; chat + code ride the stock ramp. Adds namedtext-2xs/text-3xsfor sub-xs surfaces (badges, avatar initials, dense meta).desktop/src/features/messages/ui/MessageRow.tsx / MessageHeader.tsx / SystemMessageRow.tsx / desktop/src/shared/ui/markdown.tsx / mentionChip.ts
Render-path text on stock rem tokens: chat body →
text-sm(14px) after the refinement pass, block code →text-sm, inline-code labels →text-xs. SharedMessageHeaderRow/MessageAuthorTextprimitives align header typography across normal + system rows. System-event titles/actions use full foreground. Combine kept tho's header structure + applied main'sbodyOffsetClass.desktop/src/shared/styles/globals.css
Mention/agent/inline-code chips scoped under
.message-markdownso timeline markdown and the TipTap composer render identical chips; composer body/code aligned totext-sm/leading-relaxed; chip line-height inherits from context; inline-chip vs code-block selectors reordered to clear biomenoDescendingSpecificity.desktop/src/features/messages/ui/DiffViewer.css
Diff-viewer font-size px → rem so diff text scales with zoom.
desktop/src/features/settings/ui/ProfileSettingsCard.tsx
Main's animated-avatar editor (#1031) taken wholesale; tho's
leadingtoken re-applied. Editor restructured to 3 tabs (Image / Emoji / Animated) with the preview moved below + enlarged — main's design, not a merge artifact (the Animated tab portals its live camera feed into the top preview slot, so the preview must anchor above the tabs).~65 additional files (px text literals → rem / named tokens)
App-wide sweep converting hardcoded px text sizes to rem and arbitrary
text-[…]literals to named tokens. Sub-xs round-ups:badge.tsx0.625rem(10px)→text-2xs(11px),AgentActivityCardtimestamps unified totext-2xs(fixes an 11px/10px same-role drift),PulseTabBar10.5px→text-2xs,UserAvatar0.5rem→text-3xs/ 0.5625rem→text-2xs. Only thetext-[6rem]avatar glyph remains, explicitly allowlisted bypath:line.desktop/scripts/check-px-text.mjs / scripts/check-px-text-core.mjs / desktop/package.json
check:px-textguard wired intopnpm check. Flags any arbitrary text-size literal (px and rem/em) across all ofdesktop/src, with a fix message pointing at the stock scale.AGENTS.md
"Text sizing & zoom" section steering future agents to rem + named tokens + stock scale, documenting the widened guard.
RESEARCH/TIMELINE_ZOOM_REM_REGRESSION.md / RESEARCH/CHAT_BASE_TYPE_SCALE.md
Findings + decision trees for the regression fix and the type-scale pass.
Reproduction Steps
text-smrhythm and the markdown preview spacing (paragraphs, h1–h6 stacks) is tight and consistent.pnpm check— thecheck:px-textguard passes; reintroducing an arbitrary text-size literal (e.g.text-[0.9rem]ortext-[16px]) anywhere indesktop/srcfails the build with a fix message naming the stock scale.Reviewer notes
Scope: the timeline rem fix, type-scale re-anchor, app-wide px→rem sweep, DiffViewer, composer-highlight, sub-xs token/guard work, two
mainmerges (animated avatars / unread / DM-members polish / spoiler / migrations), and the post-merge chip-unification + spacing refinement all land together in this single PR. The merges resolved real conflicts as a combine (MessageRow header structure + main's body offset; ProfileSettingsCard avatar-editor superset + tho's leading token) and caught two silent auto-merge regressions (SystemMessageRowagent-mention feature,markdown.tsxcompact/runtimeRef refactor) that no conflict marker flagged.Caption, not a bug — avatar editor restructure: the avatar editor changed shape in the combine — before = 2 tabs (Image/Emoji) with the preview above; after = 3 tabs (Image/Emoji/Animated) with the preview below + enlarged. That's main's #1031 animated-avatar rewrite landing as-designed, verified by diffing the merged
ProfileSettingsCard.tsxagainstorigin/main(identical except tho's one-lineleadingtoken). Frame it as "main's editor rewrite + Animated tab landed," not a subtle token tweak.Verification (Marge + Ned, current): full Desktop Core CI gate on the combined diff at the latest merge tip — biome (lint + formatting),
pnpm check(incl. widened guard), typecheck, 864/864 desktop unit tests passing, production build — all green. Zoom behavior confirmed in the running app across timeline, thread, composer pill, and diff viewer. Before/after at 1x (matched viewport) on both conflict surfaces — MessageRow timeline (header alignment + body spacing identical) and ProfileSettingsCard (idle preview pixel-identical, emoji glyph sizing unchanged) — confirmed no regression from the combine. The widened guard was live-tested: a reintroducedtext-[0.9rem]failed the build as designed, then passed clean on restore.Coordination: this work is coordinated in the sprout-message-timeline room —
buzz://message?channel=36411e44-0e2d-4cfe-bd6e-567eb169db9f&thread=6e70b9b429ccd8f99daf00a7f6d211f104c8bb20c72e488d94da62dcb75490ba@tho here you go — 1x only, zoom150 column dropped. Same 6 surfaces, current tip
bba9ce3c. Zoom still verified to hold on every surface; just not shown here per your call.15px→1rem; mention chip → matched scale. Original zoom bug — px froze zoom, rem revives it.DiffViewer.css15px→1rem(gutter + code). Diff content scales at zoom.badge.tsx0.625rem(10px) →text-2xs(11px); count badges + avatar initials → named tokens (UserAvatar0.5rem→text-3xs,0.5625rem→text-2xs).AgentActivityCardtimestamps unified totext-2xs(fixes 11px/10px same-role drift);PulseTabBar10.5px→text-2xs, count badge0.625rem→text-2xs.