Skip to content

fix(bidi): keep lists, tables and inline code out of the inherited di…

MacroscopeApp / Macroscope - UI Consistency failed Aug 16, 2026 in 3m 41s

UI Consistency: 1 issue found

apps/web/src/index.css — the direction: ltr added in the latest commit was placed inside the shared margin rule whose selector list is .chat-markdown p, ul, ol, blockquote, pre, .chat-markdown-table-container. It therefore pins p and blockquote (the blocks rehypeAutoTextDirection tags with dir="auto") to an LTR base direction: an author direction declaration outranks the UA rule that dir="auto" resolves through, so Arabic paragraphs lose the direction this PR adds, and the blockquote's new border-inline-start/padding-inline-start can never resolve to the right side. Suggested fix (posted inline): scope the declaration to .chat-markdown .chat-markdown-table-container, since pre and the new ul/ol rule already set their own.

Previously flagged items are addressed on this head: inline-code bidi isolation, table-container (not just table) LTR pinning, the parseRawHtml=false plugin path, the end-side list gutter now gated on data-rtl-item, and dir="auto" reapplied on the CollapsibleTrigger that replaces <summary>.

Details

Note

Your check run agent prompt is: .macroscope/check-run-agents/ui-consistency.md
More information about how Check Run Agents work can be found in our Help Center.

Files examined in scope: apps/web/src/index.css, apps/web/src/markdown-text-direction.ts, apps/web/src/markdown-text-direction.test.tsx, apps/web/src/components/ChatMarkdown.tsx. Mobile files were read as context only (out of the configured include patterns).

Checks performed:

  • Compared merge-base and head CSS to confirm which selectors the new direction declarations attach to, including the last commit (4ccc319) that moved the table pin onto the shared margin rule.
  • Traced logical-property resolution (border-inline-start, padding-inline-start, padding-inline-end, margin-inline) against the computed direction of each owning box, including the data-rtl-item gutter and task-list checkbox offsets.
  • Verified the ul/ol gutter, marker side, and task-list checkbox all resolve consistently with the per-item dir="auto", and that cells keep text-align: start under the LTR table container.
  • Reviewed rehypeAutoTextDirection traversal (outermost-block tagging, list-under-item reset, alert exclusion) against the accompanying tests.

🔍 Agent activity — 1 tool call

💭 Checking what's changed in the latest commit compared to the previous runs—looking at the diff to see which issues have been addressed, like the inline code isolation, table container direction, and the ChatMarkdown parsing settings. Now I'm examining the specific CSS and markup patterns in detail, particularly how the list direction interacts with individual item directions and the padding calculations for RTL items, plus how the task list checkbox margins are being handled when items have dir=auto. I need to pull up the actual web files to verify the text-align: start selector and check what other patterns might need attention. Let me look at the CSS changes in that section. I'm spotting a potential conflict with the CSS direction property. The markdown elements are getting direction: ltr applied through the stylesheet, but the plugin is also adding dir="auto" attributes to these same elements in the HTML. Since the dir attribute creates a presentational hint in the browser's default styles, I need to figure out which one takes precedence—whether the CSS rule overrides the HTML attribute or vice versa. So with unicode-bidi: plaintext, the paragraph's own base direction determines how text-align: start and text-align: end resolve, rather than the element's direction property — this means dir=auto elements get per-paragraph text alignment based on their content's detected directionality, not a fixed ltr/rtl setting. The real issue is whether applying direction: ltr via CSS breaks this behavior — for a p with dir=auto, the plaintext bidi algorithm still runs on the inline content so an Arabic paragraph displays RTL with correct alignment, but for a blockquote with dir=auto, logical properties like border-inline-start resolve against the computed direction property, which would be ltr, potentially breaking the intended layout. I need to verify what the actual selector list is in the merge base version before the PR, since the diff is adding direction: ltr to a shared margin rule that affects multiple elements including blockquote. Let me check the original CSS to confirm whether this rule really applies to all those selectors. .getComputedStyle().direction returns "rtl"? I believe browsers implement dir=auto by resolving the directionality and applying it. Per HTML spec: "The dir attribute... The directionality of an element is used to determine ... and CSS direction via the rendering rules". Let me recall the HTML Rendering spec section 15.3.4 "Bidirectional text": Writing CSS rules... Author styles override UA styles regardless of specificity, so a .chat-markdown blockquote { direction: ltr } rule would override the computed directionality from dir=auto. But the unicode-bidi: plaintext rule still applies, so the paragraph's base direction for inline layout comes from the content itself, and text-align: start resolves per paragraph to maintain correct right-to-left text flow. The question is whether logical properties like border-inline-start respect the content-derived direction or the author-set direction. accidental over-application of the direction rule. I'm noticing there's also a duplicate declaration — .chat-markdown ul, ol gets direction: ltr applied twice at different points in the stylesheet with identical specificity and values, which is genuinely redundant. The bigger concern is whether blanking direction: ltr on p elements causes issues in RTL contexts. Since blockquote is also set to ltr, that's consistent, but li isn't in that list, so RTL list items would still resolve to rtl from dir=auto, which affects marker positioning and padding behavior. For task-list checkboxes, the margin-inline calculation on the input respects the inherited direction from the parent li, so in Arabic text the negative margin correctly hangs into the right gutter, and the ul padding handles the spacing properly. The direction: ltr forced on p works fine with unicode-bidi: plaintext for handling text directionality within paragraphs. But there's a question about whether forcing direction: ltr on a paragraph breaks its own alignment—specifically how text-align: start behaves. According to the CSS specs, when unicode-bidi: plaintext is set, the paragraph's base direction is determined by the Unicode bidirectional algorithm heuristics rather than the direction property, and text-align: start is computed per-paragraph based on that paragraph's own base direction. The risk is real: if an author's direction: ltr override causes text-align to fall back to left for an RTL Arabic paragraph, that's a visible regression where Arabic text would be left-aligned instead of right-aligned. Chrome does implement the plaintext alignment rule for textarea dir=auto, so it's not entirely theoretical, but I should verify how this actually plays out in the HTML rendering spec. Looking at the spec, I can see the UA stylesheet rules that set direction based on the dir attribute and :dir() pseudo-class... Writing UA stylesheet rules... via the:dir(rtl)selector. But here's the problem: if an author stylesheet declares.chat-markdown p { direction: ltr }, that overrides the user-agent rule entirely because author styles win in the cascade regardless of specificity. So the Arabic paragraph gets forced to LTR layout, breaking the intended right-to-left rendering and bringing back those trailing punctuation issues. The unicode-bidi: isolateproperty alone can't fix this — it only isolates the content, but the actual base direction still comes from thedirectionproperty, which is now locked to LTR. Whendirection: ltris forced on Arabic text, it renders as a single RTL run within an LTR paragraph, which means the text aligns left and punctuation gets misplaced. For example, "مرحبا بالعالم." would have the period appear on the right side of the run instead of the left, which is incorrect for Arabic. That's precisely the bug the PR is trying to address. So the real question is whether addingdirection: ltrto the sharedpandblockquoterule actually defeats the entire purpose of the feature for those elements. Looking at the diff more carefully, thedirection: ltrproperty was added to a shared rule that applies to multiple elements including paragraphs and blockquotes, which would be a critical problem if true. Let me verify this is actually what happened by checking the merge base file to confirm the selector list at that location. At the current head, lines 1595-1607 show the rule clearly as.chat-markdown p, ul, ol, blockquote, pre, .chat-markdown-table-container { direction: ltr; margin: 0.65rem 0; }, so yes — .chat-markdown pis gettingdirection: ltr. This seems unintended since it would break the feature for paragraphs, unless they verified it works in the browser. Let me check Chrome's default behavior — the UA stylesheet sets unicode-bidi: isolateon elements withdir="auto", and in Blink's implementation, dir=autodirectionality is resolved throughHTMLElement::AdjustDirectionalityIfNeededandStyleAdjuster, which applies the computed direction to the element's style. Handling the dir attribute in different contexts... specify the paragraph's inline base direction, so Arabic text still renders RTL and text-align:start resolves correctly per-paragraph. Under the newer :dir()approach, the author'sdirection: ltrdeclaration takes precedence on that property itself, though the implementation details differ between the plaintext model and the modern CSS pseudo-class approach. In current Chrome (2026), the:dir()-based UA rules are the standard, with plaintext limited to form inputs and preformatted text. This means applying direction: ltrto.chat-markdown pwould actually break the intended feature for paragraphs in modern Chrome and Electron. It's surprising the author wouldn't have caught this during testing, but let me check the actual diff to see if the rule was applied to those elements or if the structure was changed differently. The last commit addeddirection: ltrto a shared CSS rule affecting multiple elements including paragraphs, lists, blockquotes, and the markdown table container. I should check the actual diff to see the exact changes. The latest commit addeddirection: ltrto a shared CSS rule that affects.chat-markdown p, ul, ol, blockquote, pre, and the table container. The commit message suggests the intent was only for the table container and lists, but it's also applying to pandblockquoteelements—the exact ones the plugin marks withdir="auto". This is causing a conflict where the browser's directionality resolution from dir=autois being overridden by the explicitltrdirection. I'm checking how modern browsers actually handle this. Looking at Chromium's implementation, I need to verify whether the UA stylesheet rules for[dir]and:dir()pseudo-classes are taking precedence or if the author-leveldirection: ltris winning out. Examining the HTML rendering spec and Chrome 120+ behavior with the:dir()selector support. So forcingdirection: ltronpelements actually breaks the feature entirely in the current spec and Chrome implementation — it kills the plaintext directionality fallback. The same issue applies toblockquote: the border-inline-startandpadding-inline-startproperties become ineffective since the text direction is locked to LTR, and the quote rail can never mirror as intended. Plus,direction: ltronpalso breaks paragraph text alignment. I'm also noticing a second issue with list styling that's being cut off. I need to figure out which lines in the diff I can actually comment on. The added lines are 1601-1605 in the new file, so I can safely target line 1605 wheredirection: ltr;appears. For the inline suggestion, I'd replace the entire selector block (lines 1595-1605) with a split version that moves the direction property only to the table container rule. I need to fetch the actual PR patch for the CSS file to determine which lines are commentable within the diff hunk range. I'm identifying the core issue: thedirection: ltrCSS rule being applied to.chat-markdown pand.chat-markdown blockquoteelements, which are the same elements receivingdir="auto"from the plugin. I'm checking the HTML Standard's bidirectional text rendering rules to verify the browser behavior and make sure my explanation is technically sound. The real issue is that.chat-markdown-table-containeris the only selector in that shared rule that actually needs thedirection: ltrdeclaration, so I should move it out and create a dedicated rule just for the table container. I'm considering how to structure this as an inline suggestion — I could replace the lines containing the shared declaration with nothing and add a separate rule, but that's tricky within a single inline suggestion block since the new rule needs to come after the shared rule closes. Writing CSS rules... The sanitizer runs after the plugin so it won't strip the new attributes, and the non-raw path doesn't use sanitization anyway. TheMarkdownDetailscomponent spreads props to the button trigger, sodir="auto"should apply correctly. With flexbox,dir="auto"on an RTL title would reverse the row order and move the chevron right, which is probably the right behavior. I don't think there are other direction-related interactions to worry about. Now I'm reconsidering whether forcingdirection: ltron the paragraph is actually a regression or just no visible change. The old plaintext approach would still render correctly, but the current spec-based implementation breaks it—either way, forcing direction is wrong. I should check how Electron/Chromium handles this and phrase the comment to explain that the authordirectionproperty overrides the UA rule fordir=auto, causing the paragraph to fall back to LTR. The blockquote's logical border also can't resolve to the right side under this constraint. Even in the plaintext model, border-inline-starton blockquote resolves against thedirectionproperty, so the border stays pinned left regardless of implementation—that's a solid, engine-independent finding. The change fromborder-lefttoborder-inline-startandpadding-lefttopadding-inline-startgets neutralized, and the plugin'sdir="auto"on blockquote can't move the rail either. I think one combined comment on line 1605 works best, and I could briefly mention the ul/ol duplication in the same place since it only becomes redundant under certain conditions. Let me verify the line number and draft the comment explaining howdirection: ltronpandblockquoteoverrides the UA rule that resolvesdir="auto"`, causing Arabic paragraphs to revert to LTR base direction—which is exactly what this PR is meant to fix. Writing the suggestion block...

1. modify_pr — One finding on the latest commit: the new direction: ltr intended for the table container also lands on p and blockquote, which are the blocks this PR tags with dir="auto".


Agent Credits: 105 credits