/** * Замена фона — фича ТОЛЬКО для десктопа (решение оператора от 09.08.2026). * * Причина не в верстке, а в цене: сегментация силуэта считается нейросетью на * КАЖДОМ кадре, пока фон включён. На телефоне это греет устройство, ест * батарею и просаживает FPS в самой встрече — портить основное ради украшения * нельзя. * * ⚠️ Поэтому «десктоп» здесь определяется по ВОЗМОЖНОСТЯМ УСТРОЙСТВА, а не по * ширине окна. `useIsCompactViewport` (мобильный брейкпоинт 600px) для этого * не годится принципиально: узкое окно на десктопе — это по-прежнему десктоп с * его процессором, и прятать там фичу неправильно, а планшет с широким экраном * остаётся устройством, которое сегментация нагреет. */ /** * Признаки указывающего устройства: * - `pointer: fine` — точный указатель (мышь/трекпад), у пальца он `coarse`; * - `hover: hover` — указатель может «зависать» над элементом, чего тач не умеет. * * Проверяются ОБА: гибриды вроде ноутбука с сенсорным экраном сообщают * `any-pointer: coarse`, но основным указателем у них остаётся мышь — такое * устройство десктопное, и фича на нём должна быть. */ const DESKTOP_POINTER_QUERY = '(pointer: fine) and (hover: hover)' /** * Является ли устройство десктопным (и, значит, можно ли предлагать замену фона). * * Второе условие — `maxTouchPoints`: iPad в Safari по умолчанию притворяется * десктопом (десктопный user-agent, `pointer: fine` при подключённом * трекпаде), но остаётся планшетом с планшетным теплопакетом. Больше двух * точек касания — это тач-устройство, сколько бы мышей к нему ни подключили. */ export function isDesktopDevice(): boolean { if (typeof window === 'undefined') return false if (!window.matchMedia(DESKTOP_POINTER_QUERY).matches) return false return navigator.maxTouchPoints <= 2 }