Files
enduro-trails/src/web/index.html
claude-bot 8d36f38be6
All checks were successful
CI / lint (push) Successful in 5s
CI / test (push) Successful in 9s
CI / build (push) Successful in 18s
CI / lint (pull_request) Successful in 5s
CI / test (pull_request) Successful in 9s
CI / build (pull_request) Successful in 2s
fix: restore UI to phase 5.4 (terrain, scale bar, zoom controls)
2026-05-16 22:17:10 +03:00

403 lines
30 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover, user-scalable=no">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<title>Enduro Trails</title>
<link rel="stylesheet" href="https://unpkg.com/maplibre-gl@4.7.0/dist/maplibre-gl.css">
<link rel="stylesheet" href="app.css">
</head>
<body class="theme-dark">
<!-- Map -->
<div id="map"></div>
<!-- Sheet backdrop -->
<div id="sheet-backdrop" onclick="closeAllSheets()"></div>
<!-- ── Ruler info ─────────────────────────── -->
<div id="ruler-info">
<span id="ruler-dist">0 км</span>
<button class="ruler-action-btn" onclick="exitRulerMode()" title="Завершить">✓ Завершить</button>
<button class="ruler-action-btn ruler-action-btn--danger" onclick="deleteRuler()" title="Удалить линейку"></button>
</div>
<!-- ── Ruler toast hint ───────────────────── -->
<div id="ruler-toast">Тапни на карту чтобы добавить точку</div>
<!-- ── No data warning ───────────────────── -->
<div id="no-data-warning">⚠️ База данных недоступна</div>
<!-- ── Terrain popup ────────────────────── -->
<div id="terrain-popup" class="terrain-popup" style="display:none">
<div class="terrain-popup-title">Эндуро</div>
<label class="terrain-checkbox">
<input type="checkbox" id="terrain-hillshade-cb" onchange="onTerrainCheckbox()">
<span>Тени рельефа</span>
</label>
<span class="terrain-hint" id="terrain-hillshade-hint" style="display:none">Зум 10+</span>
<label class="terrain-checkbox">
<input type="checkbox" id="terrain-tri-cb" onchange="onTerrainCheckbox()">
<span>Перепады</span>
</label>
<hr style="margin:6px 0;border-color:rgba(128,128,128,0.3)">
<label class="terrain-checkbox">
<input type="checkbox" id="trails-track-cb" onchange="onTrailsCheckbox()" checked>
<span>Грунтовки</span>
</label>
<label class="terrain-checkbox">
<input type="checkbox" id="trails-path-cb" onchange="onTrailsCheckbox()" checked>
<span>Тропы</span>
</label>
</div>
<!-- ── Map Buttons (right) ───────────────── -->
<div id="map-controls-r">
<button class="map-btn" id="btn-compass" onclick="toggleCompass()" title="Компас">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m16.24 7.76-2.12 6.36-6.36 2.12 2.12-6.36 6.36-2.12z"/></svg>
</button>
<button class="map-btn" onclick="locateMe()" title="Моё местоположение">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="3 11 22 2 13 21 11 13 3 11"/></svg>
</button>
<button class="map-btn" id="terrain-toggle" onclick="toggleTerrainPopup()" title="Рельеф">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m8 3 4 8 5-5 5 15H2L8 3z"/></svg>
</button>
<button class="map-btn" id="btn-theme" onclick="toggleTheme()" title="Переключить тему">
<svg id="theme-icon-sun" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display:none"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/></svg>
<svg id="theme-icon-moon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/></svg>
</button>
</div>
<!-- ════════════════════════════════════════════
BOTTOM SHEETS
════════════════════════════════════════════ -->
<!-- ── Sheet: Маршрут ────────────────────── -->
<div class="bottom-sheet" id="sheet-route">
<div class="sheet-handle"></div>
<div class="sheet-header">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 10c-.83 0-1.5-.67-1.5-1.5v-5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5v5c0 .83-.67 1.5-1.5 1.5z"/><path d="M20.5 10H19V8.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/><path d="M9.5 14c.83 0 1.5.67 1.5 1.5v5c0 .83-.67 1.5-1.5 1.5S8 21.33 8 20.5v-5c0-.83.67-1.5 1.5-1.5z"/><path d="M3.5 14H5v1.5c0 .83-.67 1.5-1.5 1.5S2 16.33 2 15.5 2.67 14 3.5 14z"/><path d="M14 5H4a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-3"/></svg>
<h2>Маршрут</h2>
<!-- Скачать GPX -->
<button class="sheet-icon-btn" onclick="downloadGPX()" title="Скачать GPX">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/>
</svg>
</button>
<!-- Сброс -->
<button class="sheet-icon-btn danger" onclick="resetRouteFromSheet()" title="Сбросить маршрут">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M3 6h18M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/>
</svg>
</button>
<!-- Свернуть -->
<button class="sheet-close" onclick="minimizeSheet('sheet-route')" title="Свернуть">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="6 9 12 15 18 9"/>
</svg>
</button>
</div>
<div class="sheet-body">
<div id="waypoints-list"></div>
<div id="route-status" class="text-muted">Тапни точку старта на карте</div>
<div id="route-cards"></div>
</div>
</div>
<!-- ── Sheet: Разведка ───────────────────── -->
<div class="bottom-sheet" id="sheet-recon">
<div class="sheet-handle"></div>
<div class="sheet-header">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12C2 6.5 6.5 2 12 2a10 10 0 0 1 8 4"/><path d="M5 19.5C5.5 18 6 15 6 12c0-.7.12-1.37.34-2"/><path d="M17.29 21.02c.12-.6.43-2.3.5-3.02"/><path d="M12 10a2 2 0 0 0-2 2c0 1.02-.1 2.51-.26 4"/><path d="M8.65 22c.21-.66.45-1.32.57-2"/><path d="M14 13.12c0 2.38 0 6.38-1 8.88"/><path d="M2 16h.01"/><path d="M21.8 16c.2-2 .131-5.354 0-6"/><path d="M9 6.8a6 6 0 0 1 9 5.2c0 .47 0 1.17-.02 2"/></svg>
<h2>Разведка</h2>
<button class="sheet-close" onclick="minimizeSheet('sheet-recon')">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18M6 6l12 12"/></svg>
</button>
</div>
<div class="sheet-body">
<p class="sheet-hint" id="recon-hint">Тапни точку на карте — узнаешь сколько грунтовок рядом</p>
<div class="section-label">РАДИУС</div>
<div class="seg-control">
<button class="seg-btn active" data-km="20" onclick="setReconRadius(20)">20 км</button>
<button class="seg-btn" data-km="50" onclick="setReconRadius(50)">50 км</button>
<button class="seg-btn" data-km="100" onclick="setReconRadius(100)">100 км</button>
</div>
<div id="recon-results" style="display:none">
<div class="section-label">ГРУНТОВКИ</div>
<div class="recon-grid">
<div class="recon-stat">
<div class="rs-value" id="r-total-km"></div>
<div class="rs-label">км всего</div>
</div>
<div class="recon-stat">
<div class="rs-value gold" id="r-lev12-km"></div>
<div class="rs-label">км Lev 1-2</div>
</div>
<div class="recon-stat">
<div class="rs-value red" id="r-lev345-km"></div>
<div class="rs-label">км Lev 3-5</div>
</div>
<div class="recon-stat">
<div class="rs-value" id="r-path-km"></div>
<div class="rs-label">км тропы</div>
</div>
</div>
<div class="section-label">ИНТЕРЕСНОЕ</div>
<div id="r-poi-list"></div>
</div>
</div>
</div>
<!-- ── Sheet: Красивый маршрут ───────────── -->
<div class="bottom-sheet" id="sheet-scenic">
<div class="sheet-handle"></div>
<div class="sheet-header">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z"/><path d="M5 3v4M19 17v4M3 5h4M17 19h4"/></svg>
<h2>Красивый маршрут</h2>
<button class="sheet-close" onclick="minimizeSheet('sheet-scenic')">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18M6 6l12 12"/></svg>
</button>
</div>
<div class="sheet-body">
<div id="scenic-status" class="text-muted">Тапни точку старта на карте</div>
<div class="section-label mt-8">ДИСТАНЦИЯ</div>
<div class="dist-row">
<div class="seg-control" style="flex:1">
<button class="seg-btn" data-km="50" onclick="setScenicKm(50)">50</button>
<button class="seg-btn active" data-km="100" onclick="setScenicKm(100)">100</button>
<button class="seg-btn" data-km="150" onclick="setScenicKm(150)">150</button>
<button class="seg-btn" data-km="200" onclick="setScenicKm(200)">200</button>
</div>
<input type="number" id="scenic-custom-km" class="dist-custom" placeholder="км" min="20" max="500" onchange="setScenicKm(+this.value||100)">
</div>
<button class="btn-primary" id="btn-build-scenic" onclick="buildScenicRoute()" style="display:none">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z"/></svg>
Построить маршрут
</button>
<div id="scenic-cards" class="mt-8"></div>
</div>
</div>
<!-- ── Sheet: Связка ─────────────────────── -->
<div class="bottom-sheet" id="sheet-link">
<div class="sheet-handle"></div>
<div class="sheet-header">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg>
<h2>Связка</h2>
<button class="sheet-close" onclick="minimizeSheet('sheet-link')">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18M6 6l12 12"/></svg>
</button>
</div>
<div class="sheet-body">
<p class="sheet-hint" style="text-align:left;padding-top:0">Соедини два трека — найду оптимальную грунтовую связку</p>
<div class="link-points">
<div class="link-pt empty" id="link-pt-1">
<div class="link-pt-num">1</div>
<div class="link-pt-label">Конец первого трека</div>
</div>
<div class="link-pt empty" id="link-pt-2">
<div class="link-pt-num">2</div>
<div class="link-pt-label">Начало второго трека</div>
</div>
</div>
<div id="link-status" class="text-muted">Тапни первую точку на карте</div>
<div id="link-cards"></div>
</div>
</div>
<!-- ── Marker type dialog ─────────────────── -->
<div id="marker-dialog">
<div class="marker-dialog-inner">
<div class="sheet-handle"></div>
<div style="padding:8px 0 4px;font-size:13px;font-weight:700;color:var(--text)">Тип метки</div>
<div class="marker-type-grid" id="marker-type-grid"></div>
<button onclick="closeMarkerDialog()" style="width:100%;height:44px;background:var(--surface2);border:1px solid var(--border);border-radius:12px;color:var(--text2);font-size:14px;font-weight:600;cursor:pointer;margin-top:4px">Отмена</button>
</div>
</div>
<!-- Search panel -->
<div id="search-panel" style="display:none">
<div class="search-panel-inner">
<input id="standalone-search-input" type="text" placeholder="Поиск места..." autocomplete="off" autocorrect="off">
<button id="search-close-btn" onclick="toggleSearchMode()"></button>
</div>
<div id="standalone-search-results"></div>
</div>
<!-- ════════════════════════════════════════════
BOTTOM TOOLBAR
════════════════════════════════════════════ -->
<nav id="toolbar">
<button class="tb-btn" id="tb-route" onclick="toggleRouteMode()">
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3h5l2 9h10l-1.5 7H6.5"/><circle cx="10" cy="20" r="1"/><circle cx="18" cy="20" r="1"/></svg>
<span>Маршрут</span>
</button>
<button class="tb-btn" id="tb-link" onclick="toggleLinkMode()">
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg>
<span>Связка</span>
</button>
<button class="tb-btn" id="tb-scenic" onclick="toggleScenicMode()">
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z"/></svg>
<span>Красивый</span>
</button>
<button class="tb-btn" id="tb-recon" onclick="toggleReconMode()">
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12C2 6.5 6.5 2 12 2a10 10 0 0 1 8 4"/><path d="M5 19.5C5.5 18 6 15 6 12c0-.7.12-1.37.34-2"/><path d="M17.29 21.02c.12-.6.43-2.3.5-3.02"/><path d="M12 10a2 2 0 0 0-2 2c0 1.02-.1 2.51-.26 4"/><path d="M8.65 22c.21-.66.45-1.32.57-2"/><path d="M14 13.12c0 2.38 0 6.38-1 8.88"/><path d="M2 16h.01"/><path d="M21.8 16c.2-2 .131-5.354 0-6"/><path d="M9 6.8a6 6 0 0 1 9 5.2c0 .47 0 1.17-.02 2"/></svg>
<span>Разведка</span>
</button>
<button class="tb-btn" id="tb-ruler" onclick="toggleRuler()">
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.3 15.3a2.4 2.4 0 0 1 0 3.4l-2.6 2.6a2.4 2.4 0 0 1-3.4 0L2.7 8.7a2.41 2.41 0 0 1 0-3.4l2.6-2.6a2.41 2.41 0 0 1 3.4 0Z"/><path d="m14.5 12.5 2-2"/><path d="m11.5 9.5 2-2"/><path d="m8.5 6.5 2-2"/><path d="m17.5 15.5 2-2"/></svg>
<span>Линейка</span>
</button>
<button class="tb-btn" id="tb-search" onclick="toggleSearchMode()">
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
<span>Поиск</span>
</button>
<button class="tb-btn" id="tb-marker" onclick="toggleMarkerMode()">
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"/><circle cx="12" cy="10" r="3"/></svg>
<span>Метка</span>
</button>
</nav>
<!-- Mini route sheet -->
<div id="sheet-route-mini">
<div class="mini-handle" id="mini-route-handle"></div>
<div class="mini-route-info">
<!-- Onboarding panel (shown before both waypoints are set) -->
<div id="mini-onboard" style="display:none; align-items:center; gap:8px; width:100%;">
<div id="mini-onboard-pin"></div>
<span id="mini-onboard-hint" style="flex:1; font-size:13px; color:var(--text2);"></span>
<button id="mini-onboard-search-btn" style="background:none;border:none;padding:4px 8px;cursor:pointer;color:var(--text2);">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
</button>
<!-- Кнопка отмены — показывается только в режиме добавления точки -->
<button id="mini-onboard-cancel-btn" style="display:none;background:none;border:none;padding:4px 8px;cursor:pointer;color:var(--text3);font-size:20px;line-height:1;" onclick="cancelAddWaypoint()" title="Отмена"></button>
</div>
<!-- Inline search panel for onboarding -->
<div id="mini-onboard-search-panel" style="display:none; position:absolute; bottom:100%; left:0; right:0; background:var(--surface); border:1px solid var(--border); border-radius:8px 8px 0 0; padding:8px; z-index:300;">
<input id="mini-onboard-search-input" type="text" placeholder="Поиск места..." autocomplete="off" autocorrect="off"
style="width:100%; box-sizing:border-box; padding:8px 10px; border:1px solid var(--border); border-radius:6px; background:var(--surface2); color:var(--text); font-size:14px;">
<div id="mini-onboard-search-results" style="max-height:200px; overflow-y:auto; margin-top:4px;"></div>
</div>
<!-- Moto wheel loading indicator -->
<svg id="mini-wheel" class="moto-wheel" width="22" height="22" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Кноблинг: 36 зубцов по внешнему краю -->
<rect x="92.50" y="47.50" width="3" height="5" fill="currentColor" transform="rotate(0,94.00,50.00)"/>
<rect x="91.83" y="55.14" width="3" height="5" fill="currentColor" transform="rotate(10,93.33,57.64)"/>
<rect x="89.85" y="62.55" width="3" height="5" fill="currentColor" transform="rotate(20,91.35,65.05)"/>
<rect x="86.61" y="69.50" width="3" height="5" fill="currentColor" transform="rotate(30,88.11,72.00)"/>
<rect x="82.21" y="75.78" width="3" height="5" fill="currentColor" transform="rotate(40,83.71,78.28)"/>
<rect x="76.78" y="81.21" width="3" height="5" fill="currentColor" transform="rotate(50,78.28,83.71)"/>
<rect x="70.50" y="85.61" width="3" height="5" fill="currentColor" transform="rotate(60,72.00,88.11)"/>
<rect x="63.55" y="88.85" width="3" height="5" fill="currentColor" transform="rotate(70,65.05,91.35)"/>
<rect x="56.14" y="90.83" width="3" height="5" fill="currentColor" transform="rotate(80,57.64,93.33)"/>
<rect x="48.50" y="91.50" width="3" height="5" fill="currentColor" transform="rotate(90,50.00,94.00)"/>
<rect x="40.86" y="90.83" width="3" height="5" fill="currentColor" transform="rotate(100,42.36,93.33)"/>
<rect x="33.45" y="88.85" width="3" height="5" fill="currentColor" transform="rotate(110,34.95,91.35)"/>
<rect x="26.50" y="85.61" width="3" height="5" fill="currentColor" transform="rotate(120,28.00,88.11)"/>
<rect x="20.22" y="81.21" width="3" height="5" fill="currentColor" transform="rotate(130,21.72,83.71)"/>
<rect x="14.79" y="75.78" width="3" height="5" fill="currentColor" transform="rotate(140,16.29,78.28)"/>
<rect x="10.39" y="69.50" width="3" height="5" fill="currentColor" transform="rotate(150,11.89,72.00)"/>
<rect x="7.15" y="62.55" width="3" height="5" fill="currentColor" transform="rotate(160,8.65,65.05)"/>
<rect x="5.17" y="55.14" width="3" height="5" fill="currentColor" transform="rotate(170,6.67,57.64)"/>
<rect x="4.50" y="47.50" width="3" height="5" fill="currentColor" transform="rotate(180,6.00,50.00)"/>
<rect x="5.17" y="39.86" width="3" height="5" fill="currentColor" transform="rotate(190,6.67,42.36)"/>
<rect x="7.15" y="32.45" width="3" height="5" fill="currentColor" transform="rotate(200,8.65,34.95)"/>
<rect x="10.39" y="25.50" width="3" height="5" fill="currentColor" transform="rotate(210,11.89,28.00)"/>
<rect x="14.79" y="19.22" width="3" height="5" fill="currentColor" transform="rotate(220,16.29,21.72)"/>
<rect x="20.22" y="13.79" width="3" height="5" fill="currentColor" transform="rotate(230,21.72,16.29)"/>
<rect x="26.50" y="9.39" width="3" height="5" fill="currentColor" transform="rotate(240,28.00,11.89)"/>
<rect x="33.45" y="6.15" width="3" height="5" fill="currentColor" transform="rotate(250,34.95,8.65)"/>
<rect x="40.86" y="4.17" width="3" height="5" fill="currentColor" transform="rotate(260,42.36,6.67)"/>
<rect x="48.50" y="3.50" width="3" height="5" fill="currentColor" transform="rotate(270,50.00,6.00)"/>
<rect x="56.14" y="4.17" width="3" height="5" fill="currentColor" transform="rotate(280,57.64,6.67)"/>
<rect x="63.55" y="6.15" width="3" height="5" fill="currentColor" transform="rotate(290,65.05,8.65)"/>
<rect x="70.50" y="9.39" width="3" height="5" fill="currentColor" transform="rotate(300,72.00,11.89)"/>
<rect x="76.78" y="13.79" width="3" height="5" fill="currentColor" transform="rotate(310,78.28,16.29)"/>
<rect x="82.21" y="19.22" width="3" height="5" fill="currentColor" transform="rotate(320,83.71,21.72)"/>
<rect x="86.61" y="25.50" width="3" height="5" fill="currentColor" transform="rotate(330,88.11,28.00)"/>
<rect x="89.85" y="32.45" width="3" height="5" fill="currentColor" transform="rotate(340,91.35,34.95)"/>
<rect x="91.83" y="39.86" width="3" height="5" fill="currentColor" transform="rotate(350,93.33,42.36)"/>
<!-- Шина -->
<circle cx="50" cy="50" r="45" fill="currentColor" opacity="0.1"/>
<circle cx="50" cy="50" r="42" fill="none" stroke="currentColor" stroke-width="6"/>
<!-- Обод: двойное кольцо -->
<circle cx="50" cy="50" r="34" fill="none" stroke="currentColor" stroke-width="2"/>
<circle cx="50" cy="50" r="31" fill="none" stroke="currentColor" stroke-width="1"/>
<!-- Спицы: 32 штуки -->
<line x1="57.00" y1="50.00" x2="80.00" y2="50.00" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="56.87" y1="51.37" x2="79.42" y2="55.85" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="56.47" y1="52.68" x2="77.72" y2="61.48" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="55.82" y1="53.89" x2="74.94" y2="66.67" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="54.95" y1="54.95" x2="71.21" y2="71.21" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="53.89" y1="55.82" x2="66.67" y2="74.94" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="52.68" y1="56.47" x2="61.48" y2="77.72" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="51.37" y1="56.87" x2="55.85" y2="79.42" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="50.00" y1="57.00" x2="50.00" y2="80.00" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="48.63" y1="56.87" x2="44.15" y2="79.42" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="47.32" y1="56.47" x2="38.52" y2="77.72" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="46.11" y1="55.82" x2="33.33" y2="74.94" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="45.05" y1="54.95" x2="28.79" y2="71.21" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="44.18" y1="53.89" x2="25.06" y2="66.67" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="43.53" y1="52.68" x2="22.28" y2="61.48" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="43.13" y1="51.37" x2="20.58" y2="55.85" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="43.00" y1="50.00" x2="20.00" y2="50.00" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="43.13" y1="48.63" x2="20.58" y2="44.15" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="43.53" y1="47.32" x2="22.28" y2="38.52" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="44.18" y1="46.11" x2="25.06" y2="33.33" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="45.05" y1="45.05" x2="28.79" y2="28.79" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="46.11" y1="44.18" x2="33.33" y2="25.06" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="47.32" y1="43.53" x2="38.52" y2="22.28" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="48.63" y1="43.13" x2="44.15" y2="20.58" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="50.00" y1="43.00" x2="50.00" y2="20.00" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="51.37" y1="43.13" x2="55.85" y2="20.58" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="52.68" y1="43.53" x2="61.48" y2="22.28" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="53.89" y1="44.18" x2="66.67" y2="25.06" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="54.95" y1="45.05" x2="71.21" y2="28.79" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="55.82" y1="46.11" x2="74.94" y2="33.33" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="56.47" y1="47.32" x2="77.72" y2="38.52" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<line x1="56.87" y1="48.63" x2="79.42" y2="44.15" stroke="currentColor" stroke-width="0.8" opacity="0.7"/>
<!-- Ступица -->
<circle cx="50" cy="50" r="8" fill="currentColor" opacity="0.3"/>
<circle cx="50" cy="50" r="8" fill="none" stroke="currentColor" stroke-width="1.5"/>
<!-- Болты ступицы: 8 штук -->
<circle cx="62.00" cy="50.00" r="1.5" fill="currentColor"/>
<circle cx="58.49" cy="58.49" r="1.5" fill="currentColor"/>
<circle cx="50.00" cy="62.00" r="1.5" fill="currentColor"/>
<circle cx="41.51" cy="58.49" r="1.5" fill="currentColor"/>
<circle cx="38.00" cy="50.00" r="1.5" fill="currentColor"/>
<circle cx="41.51" cy="41.51" r="1.5" fill="currentColor"/>
<circle cx="50.00" cy="38.00" r="1.5" fill="currentColor"/>
<circle cx="58.49" cy="41.51" r="1.5" fill="currentColor"/>
<!-- Центр -->
<circle cx="50" cy="50" r="3" fill="currentColor"/>
</svg>
<div class="mini-route-dot" id="mini-dot"></div>
<div class="mini-route-text">
<div class="mini-route-label" id="mini-label">Вариант 1</div>
<div class="mini-route-stats" id="mini-stats">— км · —% грунт</div>
</div>
<div class="mini-route-arrows">
<span class="mini-arrow" id="mini-prev"></span>
<span class="mini-arrow" id="mini-next"></span>
</div>
<button class="mini-add-btn" id="mini-add-btn" onclick="miniAddWaypoint()" title="Добавить точку">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14M5 12h14"/></svg>
</button>
</div>
</div>
<!-- Scripts -->
<script src="https://unpkg.com/maplibre-gl@4.7.0/dist/maplibre-gl.js"></script>
<script src="https://unpkg.com/suncalc@1.9.0/suncalc.min.js"></script>
<script src="app.js"></script>
</body>
</html>