You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add scoped .katex-display CSS in app/globals.css so each display equation becomes its own horizontal scroll region and stays within max-width: 100%.
Add min-w-0 (desktop) and min-width: 0 plus overflow-x: hidden (mobile) to the chat layout containers so wide content cannot stretch the message column or leak into the vertical scroll.
Keep the existing overflow-x-auto wrapper and KaTeX stylesheet import unchanged as a fallback for other wide content.
Add a viewport-driven Playwright regression test for horizontal overflow with math content.
Implementation Steps
Phase 1: Constrain display math to its own scroll region
This phase makes each display equation the horizontal scroll container. It prevents a wide equation from expanding its parent width. This is the primary, targeted fix for the overflow described in the ticket.
Task 1: Add KaTeX overflow rules to global styles
Add math-specific CSS so display math clips and scrolls inside its own bounds.
Add rules for .katex-display in app/globals.css.
Set max-width: 100%, overflow-x: auto, and overflow-y: hidden on .katex-display so wide block equations scroll horizontally inside their own box instead of stretching the message.
Add max-width: 100% on .katex-display > .katex to keep the inner KaTeX element bounded.
Scope the rules under the markdown container (for example .prose .katex-display) to avoid affecting unrelated KaTeX usage, and to align with the existing prose styling in BotMessage.
Keep the existing katex/dist/katex.min.css import unchanged. The new rules extend the vendor stylesheet.
Task 2: Verify the per-message scroll wrapper still applies
Confirm the existing wrapper in BotMessage continues to work with the new math rules.
Keep the overflow-x-auto wrapper in components/message.tsx as a fallback for other wide content (tables, code blocks).
No code change is required here. The .katex-display rules from Task 1.1 now handle math overflow before the outer wrapper engages.
🤖 Prompt for AI agents
Implement CSS-only overflow containment for KaTeX display math so wide equations
do not expand their parent container.
- In `app/globals.css`, add rules for `.katex-display` scoped under the markdown
container (for example `.prose .katex-display`).
- On `.katex-display`, set `max-width: 100%`, `overflow-x: auto`, and
`overflow-y: hidden` so wide block equations scroll horizontally inside their
own box instead of stretching the message.
- On `.katex-display > .katex`, set `max-width: 100%` to keep the inner KaTeX
element bounded.
- Keep the existing `katex/dist/katex.min.css` import in place. Treat the new
rules as an extension of the vendor stylesheet, not a replacement.
- Do not change `components/message.tsx`. Keep the existing `overflow-x-auto`
wrapper on the markdown tree as a fallback for other wide content, such as
tables and code blocks. The new `.katex-display` rules handle math overflow
before that wrapper engages, so no code change is needed there.
Phase 2: Add width containment to the chat layout chain
This phase prevents any residual wide content from propagating horizontal growth up through the flex layout. Flex items default to min-width: auto, so intrinsically wide children can stretch the column. This phase makes the containment reliable across desktop and mobile.
Task 1: Contain the desktop message column
Prevent the desktop chat column from growing past its intended width.
Update components/chat.tsx desktop layout.
Add min-w-0 to the w-1/2 flex flex-col ... overflow-y-auto message column so a wide child cannot force it past 50% width.
Add min-w-0 to the outer flex justify-start items-start row that contains the message column and the map panel.
Add min-w-0 to the intermediate wrapper divs (relative min-h-[100px] and the transition-all duration-300 wrapper) so intrinsic width does not propagate through nested block containers.
Task 2: Contain the mobile message area
Prevent the mobile chat area from allowing horizontal growth.
Update the .mobile-chat-messages-area rule in app/globals.css.
Add min-width: 0 next to the existing min-height: 0.
Add overflow-x: hidden so horizontal overflow cannot leak into the mobile vertical scroll region.
🤖 Prompt for AI agents
Add flex-layout width containment across the desktop and mobile chat layout
chain so wide content cannot stretch the chat column, on top of the
math-specific fix from Phase 1.
- In `components/chat.tsx`, on the desktop layout:
- Add `min-w-0` to the `w-1/2 flex flex-col ... overflow-y-auto` message column
so a wide child cannot force it past 50% width.
- Add `min-w-0` to the outer `flex justify-start items-start` row that contains
the message column and the map panel.
- Add `min-w-0` to the intermediate wrapper divs, specifically the `relative
min-h-[100px]` wrapper and the `transition-all duration-300` wrapper, so
intrinsic width does not propagate through nested block containers.
- In `app/globals.css`, update the `.mobile-chat-messages-area` rule:
- Add `min-width: 0` next to the existing `min-height: 0`.
- Add `overflow-x: hidden` so horizontal overflow cannot leak into the mobile
vertical scroll region.
Phase 3: Add a regression test for horizontal overflow
This phase adds an automated check so the overflow does not return. It follows the existing viewport-driven test conventions.
Add an overflow assertion for math content
Add a Playwright test that sends a message with a wide equation and checks that no horizontal page overflow occurs.
Add the test in tests/responsive.spec.ts, next to the existing should prevent horizontal scroll test.
Reuse the existing pattern that compares document.body.scrollWidth to the hardcoded viewport width.
Run the check at the mobile viewport 375×667 and at least one desktop viewport, matching existing test.use({ viewport }) usage.
Use the existing data-testid selectors for the chat input and submit control to send a message that contains a long inline and display equation.
Assert that the message column boundingBox().width stays within the viewport width, matching the existing overflow-proxy assertions in the file.
🤖 Prompt for AI agents
Add a Playwright regression test that verifies math content does not cause
horizontal page overflow.
- Add the test in `tests/responsive.spec.ts`, next to the existing `should
prevent horizontal scroll` test.
- Reuse the existing pattern that compares `document.body.scrollWidth` to the
hardcoded viewport width.
- Run the check at the mobile viewport `375×667` and at least one desktop
viewport, matching the existing `test.use({ viewport })` usage in the file.
- Use the existing `data-testid` selectors for the chat input and submit control
to send a message that contains a long inline equation and a long display
equation.
- Assert that the message column `boundingBox().width` stays within the viewport
width, matching the existing overflow-proxy assertions in the file.
- Confirm the `data-testid` selectors used in this test resolve against the
current components. Some existing test IDs may be stale. Add any missing
required `data-testid` attributes, but keep that change minimal and limited to
what this test needs.
- Do not add math plugins to `components/skyfi-section.tsx` or
`components/report-template.tsx`. They do not render math and are out of scope.
Research
The application renders bot chat output in components/message.tsx (BotMessage). BotMessage uses MemoizedReactMarkdown (from components/ui/markdown.tsx) with remark-math and rehype-katex, and imports katex/dist/katex.min.css. It wraps the whole markdown tree in a single overflow-x-auto div.
The chat layout chain is components/chat.tsx → components/chat-messages.tsx → components/collapsible-message.tsx → BotMessage. The vertical scroll boundary is set in components/chat.tsx (desktop w-1/2 flex flex-col ... overflow-y-auto) and in app/globals.css (.mobile-chat-messages-area).
No ancestor sets min-w-0 or overflow-x-hidden. app/globals.css has no .katex or .katex-display rules.
The only other markdown consumer, components/skyfi-section.tsx, does not render math and is out of scope.
🚀 Next Steps
🤖 All AI agent prompts combined
Task: 1
Implement CSS-only overflow containment for KaTeX display math so wide equations
do not expand their parent container.
- In `app/globals.css`, add rules for `.katex-display` scoped under the markdown
container (for example `.prose .katex-display`).
- On `.katex-display`, set `max-width: 100%`, `overflow-x: auto`, and
`overflow-y: hidden` so wide block equations scroll horizontally inside their
own box instead of stretching the message.
- On `.katex-display > .katex`, set `max-width: 100%` to keep the inner KaTeX
element bounded.
- Keep the existing `katex/dist/katex.min.css` import in place. Treat the new
rules as an extension of the vendor stylesheet, not a replacement.
- Do not change `components/message.tsx`. Keep the existing `overflow-x-auto`
wrapper on the markdown tree as a fallback for other wide content, such as
tables and code blocks. The new `.katex-display` rules handle math overflow
before that wrapper engages, so no code change is needed there.
===============================================================================
Task: 2
Add flex-layout width containment across the desktop and mobile chat layout
chain so wide content cannot stretch the chat column, on top of the
math-specific fix from Phase 1.
- In `components/chat.tsx`, on the desktop layout:
- Add `min-w-0` to the `w-1/2 flex flex-col ... overflow-y-auto` message column
so a wide child cannot force it past 50% width.
- Add `min-w-0` to the outer `flex justify-start items-start` row that contains
the message column and the map panel.
- Add `min-w-0` to the intermediate wrapper divs, specifically the `relative
min-h-[100px]` wrapper and the `transition-all duration-300` wrapper, so
intrinsic width does not propagate through nested block containers.
- In `app/globals.css`, update the `.mobile-chat-messages-area` rule:
- Add `min-width: 0` next to the existing `min-height: 0`.
- Add `overflow-x: hidden` so horizontal overflow cannot leak into the mobile
vertical scroll region.
===============================================================================
Task: 3
Add a Playwright regression test that verifies math content does not cause
horizontal page overflow.
- Add the test in `tests/responsive.spec.ts`, next to the existing `should
prevent horizontal scroll` test.
- Reuse the existing pattern that compares `document.body.scrollWidth` to the
hardcoded viewport width.
- Run the check at the mobile viewport `375×667` and at least one desktop
viewport, matching the existing `test.use({ viewport })` usage in the file.
- Use the existing `data-testid` selectors for the chat input and submit control
to send a message that contains a long inline equation and a long display
equation.
- Assert that the message column `boundingBox().width` stays within the viewport
width, matching the existing overflow-proxy assertions in the file.
- Confirm the `data-testid` selectors used in this test resolve against the
current components. Some existing test IDs may be stale. Add any missing
required `data-testid` attributes, but keep that change minimal and limited to
what this test needs.
- Do not add math plugins to `components/skyfi-section.tsx` or
`components/report-template.tsx`. They do not render math and are out of scope.
💡 Iterate on the plan with:
`@coderabbitai` <feedback>
Example Feedback
- `@coderabbitai` You can skip phase 3. Add a simple unit test case for phase 2.
- `@coderabbitai` For design choice 1 go ahead with option 3 and replan.
Activity
ngoiyaeric commentedon Sep 2, 2026
@coderabbitai plan
coderabbitai commentedon Sep 2, 2026
Coding Plan
Summary
.katex-displayCSS inapp/globals.cssso each display equation becomes its own horizontal scroll region and stays withinmax-width: 100%.min-w-0(desktop) andmin-width: 0plusoverflow-x: hidden(mobile) to the chat layout containers so wide content cannot stretch the message column or leak into the vertical scroll.overflow-x-autowrapper and KaTeX stylesheet import unchanged as a fallback for other wide content.Implementation Steps
Phase 1: Constrain display math to its own scroll region
This phase makes each display equation the horizontal scroll container. It prevents a wide equation from expanding its parent width. This is the primary, targeted fix for the overflow described in the ticket.
Task 1: Add KaTeX overflow rules to global styles
Add math-specific CSS so display math clips and scrolls inside its own bounds.
.katex-displayinapp/globals.css.max-width: 100%,overflow-x: auto, andoverflow-y: hiddenon.katex-displayso wide block equations scroll horizontally inside their own box instead of stretching the message.max-width: 100%on.katex-display > .katexto keep the inner KaTeX element bounded..prose .katex-display) to avoid affecting unrelated KaTeX usage, and to align with the existingprosestyling inBotMessage.katex/dist/katex.min.cssimport unchanged. The new rules extend the vendor stylesheet.Task 2: Verify the per-message scroll wrapper still applies
Confirm the existing wrapper in
BotMessagecontinues to work with the new math rules.overflow-x-autowrapper incomponents/message.tsxas a fallback for other wide content (tables, code blocks)..katex-displayrules from Task 1.1 now handle math overflow before the outer wrapper engages.🤖 Prompt for AI agents
Phase 2: Add width containment to the chat layout chain
This phase prevents any residual wide content from propagating horizontal growth up through the flex layout. Flex items default to
min-width: auto, so intrinsically wide children can stretch the column. This phase makes the containment reliable across desktop and mobile.Task 1: Contain the desktop message column
Prevent the desktop chat column from growing past its intended width.
components/chat.tsxdesktop layout.min-w-0to thew-1/2 flex flex-col ... overflow-y-automessage column so a wide child cannot force it past 50% width.min-w-0to the outerflex justify-start items-startrow that contains the message column and the map panel.min-w-0to the intermediate wrapper divs (relative min-h-[100px]and thetransition-all duration-300wrapper) so intrinsic width does not propagate through nested block containers.Task 2: Contain the mobile message area
Prevent the mobile chat area from allowing horizontal growth.
.mobile-chat-messages-arearule inapp/globals.css.min-width: 0next to the existingmin-height: 0.overflow-x: hiddenso horizontal overflow cannot leak into the mobile vertical scroll region.🤖 Prompt for AI agents
Phase 3: Add a regression test for horizontal overflow
This phase adds an automated check so the overflow does not return. It follows the existing viewport-driven test conventions.
Add an overflow assertion for math content
Add a Playwright test that sends a message with a wide equation and checks that no horizontal page overflow occurs.
tests/responsive.spec.ts, next to the existingshould prevent horizontal scrolltest.document.body.scrollWidthto the hardcoded viewport width.375×667and at least one desktop viewport, matching existingtest.use({ viewport })usage.data-testidselectors for the chat input and submit control to send a message that contains a long inline and display equation.boundingBox().widthstays within the viewport width, matching the existing overflow-proxy assertions in the file.🤖 Prompt for AI agents
Research
The application renders bot chat output in
components/message.tsx(BotMessage).BotMessageusesMemoizedReactMarkdown(fromcomponents/ui/markdown.tsx) withremark-mathandrehype-katex, and importskatex/dist/katex.min.css. It wraps the whole markdown tree in a singleoverflow-x-autodiv.The chat layout chain is
components/chat.tsx→components/chat-messages.tsx→components/collapsible-message.tsx→BotMessage. The vertical scroll boundary is set incomponents/chat.tsx(desktopw-1/2 flex flex-col ... overflow-y-auto) and inapp/globals.css(.mobile-chat-messages-area).No ancestor sets
min-w-0oroverflow-x-hidden.app/globals.csshas no.katexor.katex-displayrules.The only other markdown consumer,
components/skyfi-section.tsx, does not render math and is out of scope.🚀 Next Steps
🤖 All AI agent prompts combined
💡 Iterate on the plan with:
`@coderabbitai` <feedback>