Function
The surface to guide, or "none"
The iPhone answer comes from useCanInstallToHomeScreen, which already owns that question and has its own spec. What this adds is the pair the user agent cannot separate on its own.
iPadOS 13 and later send a Macintosh user agent with no iPad token in it, so
an iPad and a Mac are byte-for-byte identical here. navigator.maxTouchPoints
is what tells them apart, and getting it wrong is not cosmetic: it serves one
platform the other's guide, naming controls that are not on the learner's
screen — the exact failure these guides exist to prevent.
A feature test for touch events would not do. ontouchstart is present on
plenty of desktop Chromium builds and absent on some touch hardware;
maxTouchPoints is the signal that actually reads 0 on a Mac and 5 on an
iPad. navigator.userAgentData would be better still, and Safari does not
implement it.
Everything it reads is a property of the browser, so it reports "none"
until hydration commits — rendering anything else during hydration makes the
server and client markup disagree — and "none" again once the app is
running from the home screen, because then the learner has already done it.
Client hook: which Safari install flow, if any, this learner can be shown.