Files
meshcore-analyzer/.github
547b141530 fix(#1697): MQTT sources panel — mobile card layout at ≤640px (#1698)
## Fix
At ≤640px viewports, `public/mqtt-status-panel.js::renderPanel` now
emits a stacked
card per source instead of the 7-column desktop table that overflowed
375px screens
and ran `connected`/`never` together. Desktop (≥641px) keeps the
original table verbatim.

Each mobile card surfaces all 7 data points:

```
[●] gomesh                connected   27s ago
    wss://mqtt.gomesh.dev
    5m: 27   Total: 1247   Disc: 0
```

## Implementation
- `renderTable(sources, now)` — extracted desktop layout (no behavior
change)
- `renderCards(sources, now)` — new mobile card layout, M2 tokens + M3
typography
- `renderPanel` reads `window.innerWidth` and picks one
- Debounced (150ms) `resize` listener flips layout when crossing the
640px bucket
- All colors via `var(--status-green/-red/-yellow)`,
`var(--text-muted)`,
  `var(--border)`, `var(--card-bg)` — no inline hex
- All type via `var(--fs-sm)` + `var(--fw-medium)` — no hardcoded px
font sizes in cards
- Broker URL wraps with `word-break: break-all`
- No width ≥400px declared anywhere — eliminates 375px horizontal
overflow

## TDD — red→green visible
- Red commit: `d127d08f` (test only — fails on master with assertion
errors)
- Green commit: `816afc9b` (implementation — all 5 tests pass)
- Wired into `.github/workflows/deploy.yml` JS unit-test block.

## Browser verification (staging 375×812, dark + light)

Overflow probe results (staging, real fixture):

| | scrollWidth | clientWidth | overflow? |
|---|---|---|---|
| BEFORE (master) | 517 | 335 | YES (+182px) |
| AFTER (this PR) | 335 | 335 | no |

Staging URL: http://analyzer-stg.00id.net/#/observers (hot-patched with
the new file).

E2E assertion added: `test-issue-1697-mqtt-mobile-e2e.js:60` ("mobile
375px: renders cards (no desktop table)").

Browser verified: screenshots at
`workspace-meshcore/a11y-audit/operator-reports/1697-{before,after}-{dark,light}-375.png`.

## Preflight gates
All hard gates pass — PII / branch scope / red-commit / CSS-var / CSS
self-fallback /
LIKE-on-JSON / sync-migration / async-migration / XSS sinks (false
positive on
`innerHTML='str'` literal — string is hard-coded constant in empty-state
branch,
no payload data).

Fixes #1697.

---------

Co-authored-by: openclaw-bot <bot@openclaw.local>
2026-06-12 17:57:05 -07:00
..