--- name: qa-and-fixes description: The deep-QA pass and what was fixed (reactions, composer, dead controls, responsive) metadata: type: project --- A deep QA pass (a 5-agent static audit → 68 findings, plus live Playwright driving) fixed the issues the stakeholder reported and more. All verified in-browser + typecheck clean. **Headline fixes:** - **Reactions** — the hover toolbar's emoji picker used to unmount on `mouseleave` (it floats in a gap outside the row), so reacting was impossible for messages without existing reactions. Fixed: toolbar stays while the picker/menu is open; picker also works in the thread panel (which had no handlers wired). `useThread` now exposes react/pin/save. - **Composer** — was a plain textarea inserting literal `**` markers. Now a **contentEditable WYSIWYG** (`Composer.tsx`) where Bold/Italic/Strike/Code/lists format live and serialize to markdown on send; `lib/rich-text.tsx` renders it (added `~~strike~~` + `[label](url)`). - **Dead controls → real** — create-channel (real BFF create + navigate + appears in sidebar), new-message, invite, add-workspace, callback, channel-details are modals (`overlays/Modals.tsx` + `ui/Modal.tsx`); huddle mute/video/share toggle + live timer; profile Message/Huddle; palette person/file; workspace switcher; a toast system (`Toaster.tsx`, `useUi().toast`). - **Layout/scroll "not fit"** — responsive down to ~400px: sidebar drawer closes on nav; thread panel is a mobile overlay; Support master-detail stacks (list ↔ detail + back button); no horizontal overflow. - **Support state** — list + detail + stats now share one `useTickets` source, so Resolve/reply update everywhere at once. - **Theme flash** — pre-paint script in `layout.tsx` + light tokens under `html:not(.dark)` in `globals.css`; ThemingPanel System mode works (matchMedia). See [[architecture-decisions]] and [[conventions]].