You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maka.apache.org by ja...@apache.org on 2026/08/21 05:54:05 UTC

(maka) 01/01: fix(ui): reading-column polish — balanced density, conversation radius, flush sticky

This is an automated email from the ASF dual-hosted git repository.

jackwener pushed a commit to branch fix/reading-column-polish
in repository https://gitbox.apache.org/repos/asf/maka.git

commit 07bbe59d6ba372536f8784cd70ce41c5869141af
Author: jackwener <ja...@gmail.com>
AuthorDate: Fri Aug 21 13:53:38 2026 +0800

    fix(ui): reading-column polish — balanced density, conversation radius, flush sticky
    
    Three cuts verified against a live 8-tool fixture session at 57e08d834
    (measured over CDP, before/after screenshots):
    
    - ChatMessageList drops the compact+gap={4} override for Astryx's own
      balanced density. compact with gap={4} was already balanced's gap with
      compact's padding, so the pin bought nothing but tightness. The real
      crowding was inside a turn: .maka-processing-sequence gap --space-1 →
      --space-3 and .maka-assistant-answer-content 8px → 16px take the
      evidence blocks from a measured 12/8px apart to 20/16px — reading
      rhythm instead of a log.
    
    - User bubble moves from the card tier (10px, read as a settings row) to
      a new conversation tier: --radius-conversation 16px, single consumer,
      documented in DESIGN.md §6 as a register exception to the box-height
      ladder. Assistant stays ghost.
    
    - Activity sticky offset --space-2 → 0: the 8px strip above the stuck
      header let the previous row scroll through half-visible. Flush with
      the scrollport, both sticky tiers verified (strip measured 0px).
    
    Tests: @maka/ui 183 pass, renderer tsc clean, prompt-rail e2e 7 pass.
---
 DESIGN.md                                         |  4 +++-
 apps/desktop/src/renderer/maka-tokens.css         |  5 ++++
 apps/desktop/src/renderer/styles/chat-message.css | 28 +++++++++++++++--------
 packages/ui/src/chat-view.tsx                     | 12 ++++++----
 packages/ui/src/styles.css                        |  5 +++-
 5 files changed, 38 insertions(+), 16 deletions(-)

diff --git a/DESIGN.md b/DESIGN.md
index 7eaceec02..69855d2e2 100644
--- a/DESIGN.md
+++ b/DESIGN.md
@@ -121,16 +121,18 @@ Default surfaces are flat. Depth comes first from the surface ladder, then a lin
 
 ## 6. Radius
 
-Nothing interactive is square. One ladder, assigned monotonically by box height:
+Nothing interactive is square. One ladder, assigned monotonically by box height — with one register exception, the conversation tier:
 
 | Radius | Maka tier | Astryx tier | Assign to |
 |---|---|---|---|
 | 6px | control | inner | chips, keycaps, nested inlays, and product-drawn compact controls |
 | 10px | card | element | cards, rows-as-cards, list containers, chat bubbles; Astryx `Button`, `Input`, `SegmentedControl` |
 | 12px | container | container | modals, panels, portal surfaces; Astryx `Card`, `Dialog`, `DropdownMenu` |
+| 16px | conversation | — | the filled user speech bubble, and nothing else |
 | full | pill (999px) | full (9999px) | badges, pills, circular controls |
 
 - **The Two-Name Rule.** These are one ladder under two vocabularies, and the names never line up: Maka's `control` is Astryx's `inner`, Maka's `card` is Astryx's `element`, Maka's `modal` is Astryx's `container`. Resolve a tier from the box, never from the token name that sounds right. The paired values agree *today* but are independent literals, not aliases — an Astryx upgrade can move one side silently, so a mismatch is a real failure mode rather than an impossibility. Astryx's `--rad [...]
+- **The Conversation Exception.** The filled user bubble takes 16px regardless of its box height: it is speech, and at the card tier's 10px a one-line message read as a settings row. The tier has exactly one consumer; anything else claiming it is reaching for a softer look, which is not a role. The assistant side stays a ghost bubble — no fill, no corner to round.
 - **The Full-Bleed Rule.** `border-radius: 0` is legal only on true full-bleed rows — an element flush with its container on both sides. Radius and gap move together: if it has breathing room, it has corners.
 - **Proportional marks.** Product-drawn icon plates use ratio-owned radius (~25–27% of the box edge), recorded in prose because Stitch accepts only absolute units.
 
diff --git a/apps/desktop/src/renderer/maka-tokens.css b/apps/desktop/src/renderer/maka-tokens.css
index 2346bf15e..cba88e49b 100644
--- a/apps/desktop/src/renderer/maka-tokens.css
+++ b/apps/desktop/src/renderer/maka-tokens.css
@@ -686,6 +686,11 @@
   --radius-control: 6px;
   --radius-surface: 10px;
   --radius-modal: 12px;
+  /* Conversation tier (DESIGN.md §6): the filled user speech bubble only.
+     The box-height ladder put the 44px bubble on the card tier, where it
+     read as a settings row; speech rounds by register, not by height. Not
+     a general rung — chrome and cards stay on the ladder above. */
+  --radius-conversation: 16px;
   --radius-pill: 999px;
   /* Square icon plates (provider logo, about logo, feature status) are
      governed by RATIO, not by tier: their roundness must read the same
diff --git a/apps/desktop/src/renderer/styles/chat-message.css b/apps/desktop/src/renderer/styles/chat-message.css
index d9c12e890..5d4030178 100644
--- a/apps/desktop/src/renderer/styles/chat-message.css
+++ b/apps/desktop/src/renderer/styles/chat-message.css
@@ -67,13 +67,12 @@
    rule (Maka renders user input as typed, which the primitive has no opinion
    about) — and, since Visual System 2.0 (T3), the radius TIER.
 
-   The primitive resolves `--radius-container` (12px). DESIGN.md §6 assigns
-   radius by box height, and container is scoped to "modals, panels, portal
-   surfaces" — a message bubble is none of those. Measured in the chat fixture
-   the filled user bubble is 44px tall, which lands it in the card tier (10px,
-   "cards, rows-as-cards, list containers"). Astryx publishes no radius prop on
-   this component (only `variant`), so the tier is expressed on Maka's own
-   class rather than by reaching into the primitive's internals.
+   The primitive resolves `--radius-container` (12px). DESIGN.md §6 gives the
+   filled user bubble the conversation tier (16px): the bubble is speech, not
+   chrome, and at the card tier's 10px it read as a settings row instead of a
+   message. Astryx publishes no radius prop on this component (only
+   `variant`), so the tier is expressed on Maka's own class rather than by
+   reaching into the primitive's internals.
 
    Scoped to the filled bubble on purpose: the assistant bubble is `ghost` (no
    fill, measured transparent), so it has no corner to round and inherits
@@ -81,7 +80,7 @@
 .maka-chat-message-bubble-user {
   background: var(--chat-user-bg);
   color: var(--chat-user-foreground, var(--foreground));
-  border-radius: var(--radius-surface);
+  border-radius: var(--radius-conversation);
   white-space: pre-wrap;
 }
 
@@ -91,19 +90,28 @@
   padding: var(--space-0-5) 0 0;
 }
 
+/* Reading rhythm between a turn's evidence blocks (reasoning row, tool group,
+   prose). At --space-1 the blocks measured 8-12px apart and read as one dense
+   log; --space-3 lands them at ~16-20px, the reading tier DESIGN.md asks for
+   ("spacious around reading"). Turn-to-turn spacing is ChatMessageList's own
+   balanced gap and is not declared here. */
 .maka-processing-sequence {
   display: flex;
   min-width: 0;
   flex-direction: column;
-  gap: var(--space-1);
+  gap: var(--space-3);
 }
 
 /* Expanded activity headers stay reachable while their own detail is being
    read. Native sticky positioning keeps the header in the transcript flow,
    so it leaves naturally at the card boundary and does not disturb ChatLayout
    scroll anchoring while reasoning or tool output continues to stream. */
+/* Sticky offset 0, not a breathing gap: any positive offset opens a strip
+   above the stuck header through which the previous row scrolls half-visible
+   (measured 8px of bleed-through at --space-2). Flush with the scrollport is
+   what sticky headers look like everywhere else in the product. */
 .maka-turn :is(.maka-deep-thinking, .maka-tool-activity-card) {
-  --maka-activity-sticky-top: var(--space-2);
+  --maka-activity-sticky-top: 0px;
   --maka-activity-header-height: var(--h-control-sm);
 }
 
diff --git a/packages/ui/src/chat-view.tsx b/packages/ui/src/chat-view.tsx
index fe34b080d..311b5702d 100644
--- a/packages/ui/src/chat-view.tsx
+++ b/packages/ui/src/chat-view.tsx
@@ -477,10 +477,13 @@ export function ChatView(props: {
             header used to be rendered here anyway, holding a lone spacer, to
             occupy the window titlebar line — which the shell's titlebar row now
             owns. */}
+        {/* `balanced`, Astryx's own reading density. The list used to force
+            `compact` with a `gap={4}` override that already restored the
+            balanced gap — so compact bought nothing but the tighter padding,
+            against DESIGN.md's "spacious around reading". */}
         <ChatMessageList
           className="maka-chat-message-list maka-chatContent"
-          density="compact"
-          gap={4}
+          density="balanced"
           emptyState={conversationItems.length === 0 ? emptyContent : undefined}
         >
           {conversationItems.length > 0 ? (
@@ -578,11 +581,12 @@ export function ChatView(props: {
           onNavigateFallback={navigatePromptRailFallback}
           onNavigateStart={chatLayout.unlockAutoFollow}
         />
+        {/* `balanced` for the same reason as the empty-session list above:
+            compact + `gap={4}` was balanced's gap with compact's padding. */}
         <ChatMessageList
           className="maka-chat-message-list maka-chatContent"
           data-turn-source-count={turns.length}
-          density="compact"
-          gap={4}
+          density="balanced"
           isStreaming={streamingActive}
           emptyState={showEmptyState ? emptyContent : undefined}
         >
diff --git a/packages/ui/src/styles.css b/packages/ui/src/styles.css
index 63bb5dcca..e2e04ddca 100644
--- a/packages/ui/src/styles.css
+++ b/packages/ui/src/styles.css
@@ -131,7 +131,10 @@
   opacity: 1;
 }
 .maka-user-quotes { display: flex; max-width: 100%; flex-wrap: wrap; align-items: flex-start; gap: 4px; }
-.maka-assistant-answer-content { display: flex; width: 100%; min-width: 0; flex-direction: column; gap: 8px; }
+/* 16px, the same reading rhythm as .maka-processing-sequence's --space-3 +
+   the tool group's own 8px margin: evidence and answer are separate thoughts,
+   and at 8px the prose sat glued to the last tool row. */
+.maka-assistant-answer-content { display: flex; width: 100%; min-width: 0; flex-direction: column; gap: 16px; }
 .maka-subagent-session-label,
 .maka-subagent-session-end {
   display: flex;


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org