# Plan: Fix Markdown Mobile Overflow

## Objective

Eliminate page-level horizontal overflow in the Markdown viewer on mobile while preserving readable tables, inline code, fenced code blocks, Mermaid diagrams, toolbar behavior, and desktop layout.

## Evidence

The affected deployed page was tested at several viewport widths:

| Viewport | Document width | Result |
|---:|---:|---|
| 320 px | 569 px | Page-level horizontal overflow |
| 375 px | 569 px | Page-level horizontal overflow |
| 390 px | 569 px | Page-level horizontal overflow |
| 768 px | 768 px | No overflow |

The deployed stylesheet fingerprint matches the local `app/static/viewer.css`, so there is no deployment drift.

## Root causes

### 1. Tables escape the article width

Markdown tables use `width: 100%`, but intrinsic column widths can force the rendered table beyond its container. On the inspected page, two of four tables overflow at mobile widths.

### 2. Long inline-code tokens cannot wrap

Inline values such as:

```text
agents.list[].models["provider/model"].agentRuntime
```

have no natural break points. They expand list items and the article beyond the viewport.

### Already working correctly

- Fenced code blocks use local horizontal scrolling.
- Mermaid diagrams are constrained to the content width and rendered as responsive static images.
- The toolbar title truncates with an ellipsis.
- The issue disappears at the 768 px viewport.

## Implementation plan

### Step 1 — Contain wide tables

Update `app/static/viewer.css` so Markdown tables:

- remain constrained to `max-width: 100%`;
- become their own horizontal scroll region when their columns need more space;
- retain the existing borders, cell padding, and semantic `<table>` markup;
- do not increase the width of the article or document.

The intended behavior is local table scrolling: users can swipe across a wide table without horizontally moving the entire page.

### Step 2 — Allow prose tokens to break safely

Add narrowly scoped wrapping rules for:

- inline code outside `<pre>` blocks;
- long URLs or unbroken words in paragraphs and list items.

Use emergency wrapping only where necessary. Explicitly preserve the current behavior of fenced code blocks: they must remain unwrapped and horizontally scrollable.

### Step 3 — Add regression coverage

Extend `tests/test_viewer_css.py` with focused assertions that verify:

- Markdown tables are width-constrained;
- tables provide local horizontal overflow;
- inline code permits emergency wrapping;
- fenced code blocks retain horizontal scrolling;
- Mermaid responsiveness rules remain unchanged.

Keep the renderer and sanitizer unchanged because this is a presentation-layer defect.

### Step 4 — Run automated verification

Run the relevant viewer tests, followed by the complete suite:

```bash
python -m pytest tests/test_viewer_css.py tests/test_viewer_smoke.py
python -m pytest
```

### Step 5 — Validate real layout behavior

Test a representative Markdown page containing:

- a three-column table with long cell content;
- long inline-code tokens in paragraphs and ordered lists;
- a wide fenced code block;
- a Mermaid diagram.

Check at 320, 375, 390, and 768 px in System, Light, and Dark themes.

## Acceptance criteria

- `document.documentElement.scrollWidth === document.documentElement.clientWidth` at 320, 375, and 390 px.
- The page cannot be horizontally panned.
- Every table column remains reachable through table-local scrolling.
- Long inline code wraps without clipping or obscuring adjacent content.
- Long prose links and tokens cannot widen the document.
- Fenced code blocks remain horizontally scrollable and do not wrap.
- Mermaid diagrams and their source fallback remain contained.
- Toolbar behavior and title ellipsis remain unchanged.
- The 768 px and desktop layouts show no visual regression.
- Existing security boundaries, sanitizer behavior, CSP, and sandboxing remain unchanged.

## Files expected to change

- `app/static/viewer.css`
- `tests/test_viewer_css.py`

No template, Markdown renderer, sanitizer, JavaScript, API, storage, or MCP changes should be necessary.

## Risk assessment

This is a low-risk CSS change. The main regression risk is accidentally wrapping fenced code or making tables compress into unreadable columns. The scoped selectors and viewport verification above directly cover those risks.