# DEV TASK: Terrain UI — фикс попапа и видимости слоёв **Статус:** Ready for dev **Проект:** enduro-trails **Фаза:** 5.4 --- ## Цель > Исправить 3 бага terrain UI: невидимые подписи чекбоксов в попапе, невидимый слой гипсометрии, отсутствие подсказки "Зум 10+" для hillshade. ## Контекст UI-тесты (13.05.2026) выявили проблемы: - **TC-T-02, TC-T-06:** Попап terrain открывается, но подписи "Гипсометрия" и "Отмывка" не видны (vision-анализ не различает текст) - **TC-T-03, TC-T-07:** Гипсометрия включается, но визуально не отличима от базовой карты (тёмно-зелёный overlay сливается) - **TC-T-04:** На зуме < 10 hillshade чекбокс не disabled, подсказка "Зум 10+" не отображается Что работает: - Hillshade на зуме 11+ — тени видны ✅ (TC-T-08) - Кнопка terrain, открытие/закрытие попапа ✅ - Нет артефактов тайлов ✅ ## Стек - Vanilla JS + MapLibre GL - CSS custom properties (dark/light theme) - Raster tile layers (PNG, TMS scheme) --- ## Инфраструктура | Параметр | Значение | |----------|----------| | Сервер | `slin@82.22.50.71` (пароль: `motoZ@yaz2010`) | | SSH | через ssh2 Node.js модуль (бинарный ssh сломан — GLIBC mismatch) | | Рабочая директория | `/home/slin/enduro-trails/prototype/static/` | | URL | `https://openclaw.mva154.duckdns.org/enduro/` | | Nginx | проксирует `/enduro/` → static files | --- ## Файловая карта | Действие | Файл | Ответственность | |----------|------|-----------------| | Изменить | `/home/slin/enduro-trails/prototype/static/app.css` (строки 784-860) | Стили terrain popup | | Изменить | `/home/slin/enduro-trails/prototype/static/app.js` (строки 2630-2792) | Логика terrain layers | | Изменить | `/home/slin/enduro-trails/prototype/static/index.html` (строки 36-47) | HTML попапа terrain | --- ## Задачи ### Task 1: Фикс видимости подписей в попапе **Проблема:** Подписи `Гипсометрия` и `Отмывка` не видны в headless-рендере и, вероятно, в реальном браузере тоже плохо читаемы. **Диагностика:** CSS задаёт `color: var(--text, #fff)` для `.terrain-checkbox`, но: - Попап `position: fixed` без `top/left` — рендерится в (0,0), может быть слишком маленьким - Нет явного `font-family` — может наследовать что-то нечитаемое - `min-width: 160px` может быть мало **Шаги:** - [ ] **1.1** Добавить позиционирование попапа (привязать к кнопке terrain-toggle): ```css .terrain-popup { position: fixed; top: 60px; right: 60px; z-index: 500; /* ... остальное без изменений */ } ``` Или лучше — позиционировать через JS относительно кнопки `#terrain-toggle`. - [ ] **1.2** Увеличить font-size подписей и добавить явный font-family: ```css .terrain-checkbox { display: flex; align-items: center; gap: 10px; padding: 8px 4px; cursor: pointer; font-size: 15px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: var(--text, #fff); border-radius: 6px; } .terrain-checkbox span { font-size: 15px; line-height: 1.3; } ``` - [ ] **1.3** Проверить: открыть попап → подписи "Гипсометрия" и "Отмывка" читаемы **Критерий готовности:** Vision-анализ скриншота видит текст подписей чекбоксов. --- ### Task 2: Фикс видимости гипсометрии **Проблема:** Слой `terrain-hypso` добавляется с `opacity: 0.55`, но визуально не отличим от базовой карты. Тайлы грузятся (нет 404), но цвета сливаются. **Возможные причины:** 1. Тайлы гипсометрии слишком тёмные / низкоконтрастные 2. Opacity 0.55 недостаточно для заметности поверх тёмной базовой карты 3. `scheme: 'tms'` может быть неправильным (тайлы перевёрнуты) **Шаги:** - [ ] **2.1** Проверить что тайлы гипсометрии реально существуют и содержат цвет: ```bash # На сервере — проверить что тайлы не пустые/чёрные file /home/slin/enduro-trails/data/terrain/hypso/10/600/350.png identify /home/slin/enduro-trails/data/terrain/hypso/10/600/350.png # Проверить размер — если 0 байт или < 1KB, тайлы битые find /home/slin/enduro-trails/data/terrain/hypso/10/ -name "*.png" -size +1k | wc -l ``` - [ ] **2.2** Если тайлы ОК — увеличить opacity до 0.7 и проверить визуально: В `app.js` строка 2678: ```javascript // Было: applyTerrainLayer('terrain-hypso', TERRAIN_BASE_URL + '/hypso/{z}/{x}/{y}.png', hypsoChecked, 0.55, 5, 15); // Стало: applyTerrainLayer('terrain-hypso', TERRAIN_BASE_URL + '/hypso/{z}/{x}/{y}.png', hypsoChecked, 0.70, 5, 15); ``` - [ ] **2.3** Проверить `scheme: 'tms'` — если тайлы генерились gdal2tiles с дефолтными настройками, они TMS. Но если XYZ — нужно убрать `scheme: 'tms'`. ```bash # Проверить структуру: TMS = Y растёт снизу вверх, XYZ = сверху вниз ls /home/slin/enduro-trails/data/terrain/hypso/10/ | sort -n | head -5 ls /home/slin/enduro-trails/data/terrain/hypso/10/ | sort -n | tail -5 # Если папки Y начинаются с 0 и растут — это XYZ, убрать scheme:'tms' ``` - [ ] **2.4** Проверить nginx — тайлы доступны по URL: ```bash curl -sI https://openclaw.mva154.duckdns.org/enduro/terrain/hypso/10/600/350.png | head -5 ``` **Критерий готовности:** При включении гипсометрии на зуме 8-10 виден цветной overlay (зелёные/жёлтые/коричневые тона), отличимый от базовой карты. --- ### Task 3: Фикс подсказки "Зум 10+" для hillshade **Проблема:** Функция `updateHillshadeAvailability()` вызывается на `zoomend`, но при первом открытии попапа на зуме < 10 подсказка не видна. **Код (app.js:2730-2740):** ```javascript function updateHillshadeAvailability() { const map = window._map; if (!map) return; const zoom = map.getZoom(); const cb = document.getElementById('terrain-hillshade-cb'); const hint = document.getElementById('terrain-hillshade-hint'); const label = cb ? cb.closest('.terrain-checkbox') : null; if (zoom < 10) { if (cb) cb.disabled = true; if (label) label.classList.add('disabled'); if (hint) hint.style.display = 'inline'; } else { if (cb) cb.disabled = false; if (label) label.classList.remove('disabled'); if (hint) hint.style.display = 'none'; } } ``` **Шаги:** - [ ] **3.1** Вызывать `updateHillshadeAvailability()` также при открытии попапа: В `toggleTerrainPopup()` (app.js:2632) добавить вызов после показа: ```javascript function toggleTerrainPopup() { const popup = document.getElementById('terrain-popup'); const btn = document.getElementById('terrain-toggle'); if (!popup || !btn) return; const isVisible = popup.style.display !== 'none'; popup.style.display = isVisible ? 'none' : 'block'; btn.classList.toggle('active', !isVisible); // Update hillshade availability when popup opens if (!isVisible) { updateHillshadeAvailability(); // <-- ДОБАВИТЬ setTimeout(() => { document.addEventListener('click', closeTerrainOnOutside); }, 10); } else { document.removeEventListener('click', closeTerrainOnOutside); } } ``` - [ ] **3.2** Сделать подсказку более заметной в CSS: ```css .terrain-hint { display: block; font-size: 11px; color: var(--accent, #4CAF50); /* Было: var(--text3, rgba(255,255,255,0.4)) */ padding: 4px 0 2px 28px; line-height: 1.2; font-style: italic; } ``` **Критерий готовности:** При открытии попапа на зуме < 10 — чекбокс hillshade disabled, подсказка "Зум 10+" видна. --- ## Проверка (Acceptance) | # | Проверка | Команда / Действие | Ожидаемый результат | |---|----------|-------------------|---------------------| | 1 | Подписи видны | Открыть попап terrain | Текст "Гипсометрия" и "Отмывка" читаем | | 2 | Гипсометрия видна | Включить чекбокс на зуме 8 | Цветной overlay на карте | | 3 | Hillshade hint | Открыть попап на зуме 7 | "Зум 10+" видна, чекбокс disabled | | 4 | Hillshade работает | Зум 11, включить оба | Тени рельефа видны | | 5 | Мобильный | 375x812, открыть попап | Попап не обрезан, подписи видны | --- ## Ограничения и контекст - ⚠️ SSH только через Node.js `ssh2` модуль (бинарный ssh сломан — GLIBC_2.38 not found) - ⚠️ Файлы на сервере: `/home/slin/enduro-trails/prototype/static/` — правки делать НАПРЯМУЮ там - ⚠️ Nginx отдаёт статику — после правки файлов перезапуск НЕ нужен (просто Ctrl+F5 в браузере) - ⚠️ Локальная копия в workspace УСТАРЕЛА — не синхронизировать обратно без проверки - 🚫 Не трогать nginx конфиг - 🚫 Не менять другие слои карты (trails, POI) --- ## Деплой-чеклист - [ ] Правки сделаны на сервере через ssh2 - [ ] Проверка по URL — попап с подписями виден - [ ] Гипсометрия визуально отличима - [ ] Hillshade hint работает на зуме < 10 - [ ] Нет регрессий (кнопки, тема, маршруты) --- *Создано: 2026-05-13 | Автор ТЗ: Стрим | Исполнитель: Dev-агент*