From cf23d47e2d46a34281c1c2885e133c80ea43c01d Mon Sep 17 00:00:00 2001 From: nesquena-hermes Date: Sat, 16 May 2026 22:22:38 +0000 Subject: [PATCH] =?UTF-8?q?fix(stage-371):=20apply=20Opus=20SHOULD-FIX=20?= =?UTF-8?q?=E2=80=94=20KaTeX/CSV/diff=20stay=20LTR=20+=20chip=201px=20boun?= =?UTF-8?q?dary?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Opus advisor on stage-371 caught three issues during pre-release review: 1. RTL salvage missed KaTeX math (display equations + inline LaTeX), diff blocks, CSV tables (column order must read left-to-right regardless of chat direction), and .skill-file-path. The first salvage commit only covered pre/code/kbd/samp/tt and tool-call bodies. Added a second force-LTR block covering: .katex, .katex-block, .katex-display, .katex-html, .katex-inline, .diff-block (+children), .csv-table-wrap, .csv-table (+children), .skill-file-path. Severity: KaTeX is the most user-visible gap — any user rendering math under RTL would see flipped equations. 2. Quota chip @media (max-width:1400px) hide rule conflicted at exactly 1400px with the existing @media (min-width:1400px) .messages-inner rule — chip was hidden AT the wide-desktop boundary where it should first appear. Changed to (max-width:1399.98px). Visually verified at 1400px: chip now correctly visible there. 3. Dead .icon-btn.provider-quota-chip selector — chip never has icon-btn class. Removed. Test added: test_rtl_math_and_tables_stay_ltr (pins the 4 new LTR surfaces). Also removed dead code in test_rtl_code_blocks_stay_ltr (unused code_block variable). Per stage-fix protocol: SHIP-with-followup applied on the stage rather than the source PR, since #2409 is already merged-into-stage and nesquena-approved. Stage-371 review-bypass batch path still holds. --- static/style.css | 29 ++++++++++++++++++++++++++--- tests/test_pr1721_rtl_salvage.py | 21 ++++++++++++++++++--- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/static/style.css b/static/style.css index d4092f15..d76c1039 100644 --- a/static/style.css +++ b/static/style.css @@ -1154,9 +1154,13 @@ mobile-config drawer; laptop desktop users can find quota in Settings → Providers (the chip's onclick target). Show only on wide desktop where there's genuine room. Aron's standing position on - composer real estate (PR #1721, May 13 2026) reinforces this. */ - @media (max-width:1400px){ - .icon-btn.provider-quota-chip, + composer real estate (PR #1721, May 13 2026) reinforces this. + + Using 1399.98px rather than 1400px to avoid the one-pixel boundary + overlap with the existing @media (min-width:1400px) `.messages-inner` + rule at line 893 — at exactly 1400px both would fire, so the chip + was hidden AT the wide-desktop boundary where it should first appear. */ + @media (max-width:1399.98px){ .provider-quota-chip{display:none!important;} } /* Increased specificity (.icon-btn.composer-mobile-config-btn) to win the cascade @@ -4086,6 +4090,25 @@ main.main.showing-logs > #mainLogs{display:flex;} text-align:left; unicode-bidi:isolate; } +/* Force LTR for content classes that render English-by-design even in chat: + KaTeX equations (math is LTR-only in standard notation), diff hunks + (file paths + line numbers), CSV tables (column order must stay + left-to-right), and skill file paths. */ +.chat-content-rtl .msg-body .katex, +.chat-content-rtl .msg-body .katex-block, +.chat-content-rtl .msg-body .katex-display, +.chat-content-rtl .msg-body .katex-html, +.chat-content-rtl .msg-body .katex-inline, +.chat-content-rtl .msg-body .diff-block, +.chat-content-rtl .msg-body .diff-block *, +.chat-content-rtl .msg-body .csv-table-wrap, +.chat-content-rtl .msg-body .csv-table, +.chat-content-rtl .msg-body .csv-table *, +.chat-content-rtl .msg-body .skill-file-path{ + direction:ltr; + text-align:left; + unicode-bidi:isolate; +} /* Tool-call content (commands, paths, JSON) stays LTR. */ .chat-content-rtl .tool-call-group-body, .chat-content-rtl .tool-call-group-body *, diff --git a/tests/test_pr1721_rtl_salvage.py b/tests/test_pr1721_rtl_salvage.py index e16486bd..f7cd1d7a 100644 --- a/tests/test_pr1721_rtl_salvage.py +++ b/tests/test_pr1721_rtl_salvage.py @@ -61,9 +61,6 @@ def test_rtl_code_blocks_stay_ltr(): assert ".chat-content-rtl .msg-body pre" in css assert ".chat-content-rtl .msg-body code" in css # Must force direction:ltr inside code containers - code_block = css.split(".chat-content-rtl .msg-body pre")[1].split("}")[0] - # The chain ends in a single declaration block — find the closest declaration - # to confirm direction:ltr is present in the code-scoped rule code_section_start = css.index(".chat-content-rtl .msg-body pre,") code_section_end = css.index("}", code_section_start) code_section = css[code_section_start:code_section_end] @@ -76,6 +73,24 @@ def test_rtl_code_blocks_stay_ltr(): assert "direction:ltr" in tool_section +def test_rtl_math_and_tables_stay_ltr(): + """KaTeX math, diff blocks, CSV tables, and file paths stay LTR even under RTL. + Opus advisor catch on stage-371 (2026-05-16): math is LTR-only in standard + notation, CSV columns must read left-to-right regardless of locale.""" + css = STYLE.read_text(encoding="utf-8") + katex_section_start = css.index(".chat-content-rtl .msg-body .katex,") + katex_section_end = css.index("}", katex_section_start) + katex_section = css[katex_section_start:katex_section_end] + # Must include all four key surfaces + assert ".katex-display" in katex_section + assert ".diff-block" in katex_section + assert ".csv-table" in katex_section + assert ".skill-file-path" in katex_section + # Must force direction:ltr + assert "direction:ltr" in katex_section + assert "text-align:left" in katex_section + + def test_rtl_setting_round_trips_through_panels_js(): js = PANELS.read_text(encoding="utf-8") # Load path: read from settings + localStorage, apply class