- Certificate: Hardcode approval gate — completely removed the auto-issue path;
`certRequiresApproval()` now strictly returns `true`, ignoring DB configuration.
- Certificate: Quiz completion now queues a pending record and triggers a
"Pending approval" notification instead of falsely confirming issuance.
- Certificate: Public endpoints now enforce a guard on `status=issued`; frontend
strips the auto-issue side effect and claim button (issuance restricted to admins).
- Chats tab: Refactor layout into a full-width centered banner above two
equal-height side-by-side panels (`grid-cols-1 lg:grid-cols-2`), utilizing
`max-h` and `overflow-y-auto` to eliminate whitespace bleed.
- Video player: Fix settings flyout prematurely closing on mouse movement (removed
`setSettingsOpen` from `poke`); add a click-outside listener via `mousedown`.
- Video player: Deduplicate controls — the speed pill now directly cycles playback
speed, leaving the gear icon as the single entry point for settings (eliminating
overlapping popovers).
- Video player: Implement full-bleed theater mode using the `-mx-[50vw] w-screen`
technique, keeping the progress strip constrained to `max-w-5xl` below.
- safe-markdown: add `cancelled` flag to async useEffect; no more
setState after unmount when component is destroyed mid-import
- rich-editor: same cleanup for preview tab effect; also remove dead
`prose prose-sm max-w-none` classes (Tailwind Typography not installed)
and replace with explicit arbitrary-selector markdown styling that
actually renders using existing design tokens
- profile-certificate-slot: drop dead `ORDER_LABEL`, `order` variable,
and `physicalOrder` from `MineCertificateResponse`; physical orders
are disabled — these were leftover references causing lint noise
- learning-panel: change `issuingCert: boolean` → `issuingCertFor:
number | null` so only the targeted user's button shows a spinner;
a boolean shared across all users caused the wrong row to animate
when the admin switched selected users mid-request
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>