# Mobile UX audit Scope: chat.0ff.space, with mobile installed-PWA use taking priority. Prepared 2026-10-07. Browser findings and the implementation proposal are in [UX-AUDIT-REPORT.md](UX-AUDIT-REPORT.md). Extended direct-chat and simulated PWA checks supplement the remaining real-device checks. ## Execution 1. Confirm the primary phone/OS, browser runner and test accounts. 2. Record deployed client revision, browser/OS versions and viewport. 3. Compare the tasks below with Telegram, WhatsApp and Signal. Record platform, version, source and observation; label untested comparisons. 4. Explore the deployed chat using dedicated accounts and a test room. 5. Repeat critical tasks in Playwright: Chromium/Android profile, WebKit/iPhone profile, narrow phone viewport and desktop viewport. 6. Run the real-device checklist in the installed PWA. 7. Rank findings and propose small implementation batches. Add regression tests for confirmed bugs when implementing fixes. Recommended agent: GPT-6.1 Sol with high reasoning for research, browser exploration and test development. GPT-6 Astra is optional for a second assessment of ambiguous findings. The operator selected Sol High for the continuation on 2026-10-07. Primary device: iPhone 17 Pro, iOS 26.6 (operator confirmed). The operator explicitly requested checking blunix as the browser runner, overriding the earlier development-guide default for this investigation. Host inspection on 2026-10-07: 2 CPUs, 3.7 GiB RAM, about 2.0 GiB available, 404 MiB swap occupied, load averages 0.67/0.36/0.19 and 12 GiB disk free. No Chromium executable was found on PATH or at the checked Nix-store glob. These readings support a trial with one headless browser and one worker, with Chromium and WebKit runs sequentially. Measure peak memory, CPU and swap activity during the trial before declaring this runner suitable. Avoid simultaneous builds and stop the trial if production is affected. Secure HTTPS is required for real PWA/media/push checks; the plain-HTTP Vite server cannot validate those capabilities. Keep credentials, browser authentication state and private message captures outside Git. Use synthetic messages, media and dedicated test accounts for actions that send data or alter room membership. Production observation and fixture-only tests must be identified separately. ## Task matrix | ID | Task | Expected observable result | | --- | --- | --- | | G01 | Tap group name or participant count | Discoverable group information and participant list; return preserves chat position | | G02 | Inspect membership with one test account offline | Distinguish present occupants from all members; explain unavailable data/permissions | | G03 | Select a group participant | Discoverable supported actions with correct identity and permission handling | | G04 | Invite a test account; leave/rejoin test room | Clear feedback, membership state and recovery path | | N01 | Open a chat, scroll back, return and reopen | Predictable navigation and preserved reading position | | N02 | Draft text, switch chats and return | Draft behavior is consistent and understandable | | M01 | Send and receive text between test accounts | Sending/delivery/read states match actual behavior | | M02 | Find message actions by tap/long press/menu | Supported actions are discoverable and touch-accessible | | M03 | Send image/file/voice recording and cancel an upload | Preview, progress, cancellation and errors are understandable | | R01 | Interrupt network, then reconnect | Connection status is clear; draft survives; no silent loss or duplicate sending | | A01 | Use large text, light/dark mode and narrow viewport | Readable content, reachable controls, no unwanted horizontal scrolling | | A02 | Navigate controls using keyboard and inspect accessible names | Focus is visible, dialogs manage focus, controls have useful labels | Unsupported actions are feature gaps to assess, not automatically bugs. Initial code observation for G01/G02: Chat.svelte displays an occupant count; sync/muc.ts tracks present nicknames internally. Full offline membership and a usable list still require investigation. This has not been verified at the planning stage; the completed authenticated browser and protocol observations are in the report. ## Real-device PWA checklist - Record phone model, OS, installed-PWA mode and client revision. - Open/close the software keyboard; verify composer and latest messages remain reachable. Repeat with multiline text and an open dialog. - Check safe areas, portrait/landscape and increased system text size. - Switch apps, lock/unlock, reopen the PWA and verify session recovery. - Receive a test notification with the app in background/closed; open it and verify the destination chat and unread state. - Test photo/file selection, microphone permission, recording and playback. - Test offline/reconnect and navigation without losing drafts or position. Playwright device emulation provides repeatable layout/touch checks but does not prove real iOS keyboard, installed-PWA, background or push behavior. ## Findings format For each finding record: - ID, title, status: confirmed / code observation / hypothesis / not tested. - Client revision, device/browser/OS, PWA/tab mode and test data setup. - Reproduction steps, expected behavior and observed behavior. - Sanitized screenshot or trace reference where useful. - Frequency, user impact and priority: P0 blocks core use or loses data; P1 obstructs a frequent task; P2 adds friction; P3 visual polish. - Relevant comparison evidence, proposed change and acceptance criteria. - Technical cause or protocol constraint only when supported by evidence. Deliverables: prioritized findings, comparison matrix, sanitized evidence, repeatable browser checks and a real-device result sheet. Record skipped tests and limitations explicitly. Completion requires reporting results, not merely creating test scripts. ## First browser trial — 2026-10-07 Executed against https://chat.0ff.space with Chromium 152.0.7977.82, 402 × 874 CSS-pixel viewport, touch/mobile emulation and scale factor 3. This is Chromium mobile emulation, not iPhone Safari or installed-PWA validation. Local source checkout: 4eb726340a6448fba81fc91ec10bbeee65863d6b; the deployed source revision was not established in this trial. Created dedicated LLDAP accounts `ux-audit-20261007-a@0ff.space` and `ux-audit-20261007-b@0ff.space`, and room `ux-audit-20261007@muc.0ff.space`. Both LLDAP and chat authentication were verified. The first account invited the second through the UI; both joined and a synthetic group message was received by the second account. Existing test-account passwords were not changed. The audit accounts and test room remain available for subsequent checks. | Finding | Status | Priority | Evidence and acceptance criterion | | --- | --- | --- | --- | | G01: group header does not open participants | Confirmed in Chromium trial | P1 | Clicking the group title produces no visible change; header markup has no action. Provide an accessible entry to group info and a participant/member list with explicit semantics. | | N02: draft lost when returning to list | Confirmed in Chromium trial | P1 | Enter text, use Back to chats, reopen the same room: composer is empty. Preserve unsent text for each conversation across navigation. | | A01: compact touch controls | Measured; usability assessment pending | P2 candidate | Back/attach/record are 36 × 36 CSS px; More actions is 34 × 34. Evaluate spacing and actual hit areas on the phone before deciding severity. | No horizontal overflow was observed in the tested group view (document width and viewport both 402 px), and no page JavaScript errors were caught. This does not establish correctness of untested screens or flows. During the approximately ten-second trial, sampled available memory never fell below 1,639 MiB; one-minute load reached 1.38 on two CPUs. Sampled swap-free memory was effectively stable during the browser run. Summed browser process RSS peaked at 1,385 MiB, which double-counts shared pages and is not a measurement of unique physical memory. After browser exit, available memory returned to about 2.0 GiB. The short trial supports continuing sequential tests, not a guarantee for long sessions or parallel workers. Production service latency was not measured. The exploratory runner is `ux-audit-runner.cjs`. It records observations, including gaps, rather than treating an observed UX gap as runner failure. It uses one browser with two isolated account contexts. Run on blunix: ```bash npm install --prefix /tmp/chat-ux-runner --no-audit --no-fund playwright node ux-audit-runner.cjs ``` Private credentials: `/tmp/chat-ux-runner/accounts.json` (mode 0600). Screenshots and JSON report: `/tmp/chat-ux-runner/results/`. These runtime files are outside Git and may disappear when /tmp is cleaned. Overrides: `UX_PLAYWRIGHT_MODULE`, `UX_ACCOUNTS_FILE`, `UX_RESULTS_DIR`, `UX_CHROMIUM_PATH`. The default Chromium path is the fetched Nix package; no NixOS activation was performed. Installing the runner's npm packages does not itself install a browser. Continuation completed: Chromium and WebKit exploration, narrow/landscape/ desktop layouts, dark settings, uploads, injected connection interruption, reading-position checks, protocol membership queries and official-source comparison research. Results and remaining limitations are in the report. On the operator's request, `ux-pwa-direct-runner.cjs` extends the audit to contact acceptance, encrypted direct text, delivery/read status, typing, new browser devices, image/file selection, synthetic voice recording, drafts and reading position. PWA simulations cover standalone indicators, actual worker/cache state, keyboard-size viewport changes, Chromium freeze/ resume and push/click injection, update checks, persistent-profile restart and offline cold start. No iOS installation or OS push delivery is implied. The new-device probe intentionally caches B's existing devices before creating a new B browser. Later healthy-path checks explicitly invalidate that one stale cache entry in the private A test profile; the report distinguishes this diagnostic intervention from normal application behavior.