Решили: свой курсор красится ГОТОВОЙ КОПИЕЙ текстуры — сервис умножает пиксели скина на мейн-цвет и кэширует результат по «скин + цвет»; текстурам курсоров включён Read/Write. Число оттенков и адрес токена держит один PlayerColors.

Почему: свой курсор системный (Cursor.SetCursor), а системному курсору тинт задать нечем — покрасить можно только то, что отдаёшь движку. Чужие курсоры при этом красились в UI-слое с первого дня, и игрок видел у себя белую стрелку, а напарник у него — цветную. Отвергнуто: (1) рисовать свой курсор в UI поверх мира — он отстаёт от мыши на кадр показа, это и есть «мышь залипает»; (2) хранить покрашенные копии ассетами — набор стал бы 5 скинов × 16 цветов = 80 текстур, которые надо пересобирать при каждой правке палитры; (3) снимать копию через RenderTexture без Read/Write — лишний проход по гамме, и цвет разошёлся бы с тем же цветом в UI.

Сказано: «Цвет курсора должен меняться от выбранного цвета в профиле. И надо добавить больше цветов (около 12-16). Обычный белый в т.ч. можно взять. И назвать цвет “Предпочтительный цвет”» (2026-08-22, QA-заметки Макса, заход 12:00).

Грабли:

  • Гейт мёртвого USS читает классы ТЕКСТОМ, поэтому "gm-cursor--" + PlayerColors.SuffixOf(i) оборвал имя на двойном дефисе, и прежняя запись исключения (gm-cursor--p) перестала совпадать. Исключения в гейте описывают не намерение, а буквальный литерал в коде.
  • Фигура у всех скинов лежит в ЛЕВОМ ВЕРХНЕМ углу холста 320×320 (остриё по построению в нуле), и плитка выбора, вписывавшая холст целиком, показывала фигуру в углу с тремя четвертями пустоты. Замер альфы дал занятую область 196px — отсюда background-size: 163% вместо -unity-background-scale-mode.

Владелец правды: Assets/_Project/Scripts/Core/Players/PlayerColors.cs, Assets/_Project/Scripts/Game/Services/CursorSkinService.cs, Assets/_Project/UI/Theme/tokens.semantic.uss (оттенки), гейт UssDeadCodeTests.