Mobile UA but the primary pointer is fine / a hovering pointer exists (desktop pointer surface)
br.mobile_pointer_hover_desktop · convicts
What it catches
Pointer/hover realism for a mobile UA — the mobile-side inverse of br.hover_none_desktop. A real phone/tablet has NO hovering pointer: its PRIMARY pointer is COARSE (touch) and (hover: none). A UA claiming Mobile/Android/iPhone/iPad whose CSS (pointer: fine) matches OR (hover: hover) matches is a DESKTOP wearing a mobile UA without emulating the touch device — the lazy UA-only mobile spoof (CDP/JS Network.setUserAgentOverride sets the UA string but not isMobile/hasTouch, so the CSS pointer surface still describes a mouse). This catches a no-device mobile spoof that the model/font/screen rungs (which need a real Chromium device or fire on emptiness) do not; it complements br.pointer_touch_incoherent (any-pointer coarse vs maxTouchPoints) by testing the PRIMARY pointer + hover. FP-SAFE: every real phone reports (pointer: coarse)+(hover: none); a full Playwright/CDP device emulation (KS_DEVICE=Pixel) sets both media, so it stays SILENT — the check fires only on the UA-only spoof. GROUNDED LIVE: SPOOF_UA=<a Pixel 5 mobile UA> with NO device emulation trips mobile_pointer_hover_desktop (desktop pointer under a mobile UA); KS_DEVICE='Pixel 5' (full emulation, pointer coarse + hover none) is SILENT.
Signals it reads
browser.mobile_pointer_hover_desktop
How it fires
present
Bypassed by 10
Frontier evaders that reach the detector uncaught (scored only suspicious, defeating every convicting tell) — this check is not one that stops them. The red-team frontier this detection still has to convict.