diff --git a/frontend/src/app/site-finder/analysis/[cad]/v2/v2.module.css b/frontend/src/app/site-finder/analysis/[cad]/v2/v2.module.css
index 59c2be75..02bff111 100644
--- a/frontend/src/app/site-finder/analysis/[cad]/v2/v2.module.css
+++ b/frontend/src/app/site-finder/analysis/[cad]/v2/v2.module.css
@@ -1910,64 +1910,6 @@
display: inline;
}
-/* Resource legend (bottom-left of the map card) — compact 5-row panel.
- Placed bottom-left, above Leaflet attribution, to avoid overlap with the
- existing PticaMapInner POI/category legend that lives in the top-left. */
-.mapLegend {
- position: absolute;
- left: 11px;
- bottom: 28px;
- z-index: 6;
- min-width: 168px;
- max-width: 200px;
- background: var(--surface-strong);
- border: 1px solid var(--border);
- border-radius: var(--radius-xs);
- padding: 8px 9px;
- backdrop-filter: blur(3px);
- pointer-events: none;
-}
-.mapLegendTitle {
- font-family: var(--font-mono);
- font-size: 7.5px;
- letter-spacing: 0.1em;
- text-transform: uppercase;
- color: var(--text-soft);
- margin: 0 0 5px;
-}
-.mapLegendRow {
- display: flex;
- align-items: center;
- gap: 6px;
- height: 15px;
- font-size: 9px;
-}
-.mapLegendDot {
- width: 8px;
- height: 8px;
- border-radius: 50%;
- flex: 0 0 auto;
- box-shadow: 0 0 5px currentColor;
-}
-.mapLegendLabel {
- font-family: var(--font-mono);
- letter-spacing: 0.04em;
- text-transform: uppercase;
- color: var(--text);
- font-size: 8.5px;
-}
-.mapLegendDist {
- margin-left: auto;
- font-family: var(--font-mono);
- font-size: 8.5px;
- color: var(--text-muted);
- font-variant-numeric: tabular-nums;
-}
-.mapLegendDistEmpty {
- color: var(--text-soft);
- opacity: 0.7;
-}
-
/* =====================================================================
* LIGHT THEME — targeted contrast polish
* Tokens stay; just bump the value-side text and the cyan accents that
@@ -1990,16 +1932,7 @@
}
/* Map-legend value column — same readability bump on white. */
-.v2Root[data-theme="light"] .mapLegendDist {
- color: var(--text-strong);
-}
-.v2Root[data-theme="light"] .mapLegendLabel {
- color: var(--text-strong);
-}
-.v2Root[data-theme="light"] .mapLegendDot {
- box-shadow: none;
-}
-/* Map title (light): drop the dark text-shadow that makes thin uppercase
+.v2Root[data-theme="light"] .v2Root[data-theme="light"] .v2Root[data-theme="light"] /* Map title (light): drop the dark text-shadow that makes thin uppercase
look smudgy on a satellite-light map base. */
.v2Root[data-theme="light"] .mapHead .ttl {
text-shadow: 0 1px 2px rgba(255, 255, 255, 0.6);
diff --git a/frontend/src/components/site-finder/ptica-v2/V2Map.tsx b/frontend/src/components/site-finder/ptica-v2/V2Map.tsx
index 3d5d25df..b9b60a38 100644
--- a/frontend/src/components/site-finder/ptica-v2/V2Map.tsx
+++ b/frontend/src/components/site-finder/ptica-v2/V2Map.tsx
@@ -19,7 +19,6 @@ import styles from "@/app/site-finder/analysis/[cad]/v2/v2.module.css";
import type { ParcelAnalysis } from "@/types/site-finder";
import { useConnectionPoints } from "@/hooks/useConnectionPoints";
import { useCustomPois } from "@/hooks/useCustomPois";
-import { V2MapLegend } from "@/components/site-finder/ptica-v2/V2MapLegend";
const PticaMapInner = dynamic(
() => import("@/components/site-finder/ptica/PticaMapInner"),
@@ -61,9 +60,6 @@ export function V2Map({ analysis }: Props) {
СПУТНИК · СХЕМА ПОДКЛЮЧЕНИЙ
- {/* Resource legend overlay (sibling of PticaMapInner, sits on top of the
- map via absolute positioning — does not touch the shared inner map). */}
-
);
}
diff --git a/frontend/src/components/site-finder/ptica-v2/V2MapLegend.tsx b/frontend/src/components/site-finder/ptica-v2/V2MapLegend.tsx
deleted file mode 100644
index b4a64329..00000000
--- a/frontend/src/components/site-finder/ptica-v2/V2MapLegend.tsx
+++ /dev/null
@@ -1,133 +0,0 @@
-"use client";
-
-/**
- * V2MapLegend — compact resource legend overlay rendered ON TOP of the cockpit
- * map card (prototype `ptica-v2/index.html`, block `.legend > .lg-block.lg-res`).
- *
- * Five rows — ЭЛЕКТРИЧЕСТВО / ВОДА / КАНАЛИЗАЦИЯ / ТЕПЛОСНАБЖЕНИЕ / ГАЗ — each
- * showing the distance to the nearest engineering node + a status-dot (green when
- * the узел is within ~1 km, orange when further). Data comes from
- * `analysis.utilities.summary[]` whose `subtype` values are the OSM `road_class`
- * tags produced by the backend (see `noise_loader._NOISE_QUERIES` + `parcels.py`
- * `_nearest()` aliases) — we aggregate them into the 5 prototype buckets.
- *
- * The legend is a SIBLING of `PticaMapInner` inside `V2Map` (the inner Leaflet
- * mount is shared with the старый ptica route and must NOT be touched). All
- * styles live in the scoped v2 module so the overlay never leaks into the
- * application chrome.
- */
-
-import styles from "@/app/site-finder/analysis/[cad]/v2/v2.module.css";
-import type { ParcelAnalysis } from "@/types/site-finder";
-
-type ResourceKey = "electric" | "water" | "sewer" | "heat" | "gas";
-
-interface ResourceDef {
- key: ResourceKey;
- label: string;
- /** OSM road_class values that count toward this bucket. */
- subtypes: readonly string[];
- /** CSS var for the dot accent color (matches prototype --res-* tokens). */
- color: string;
-}
-
-// Aliases mirror backend `_nearest()` in `backend/app/api/v1/parcels.py`:
-// electric ← substation | transformer | power_line
-// water ← water_main | water_works | water_tower
-// sewer ← sewerage
-// heat ← heat_substation
-// gas ← gas_pipeline (legacy generic «pipeline» falls under gas)
-const RESOURCES: readonly ResourceDef[] = [
- {
- key: "electric",
- label: "ЭЛЕКТРИЧЕСТВО",
- subtypes: ["substation", "transformer", "power_line"],
- color: "var(--res-electric)",
- },
- {
- key: "water",
- label: "ВОДА",
- subtypes: ["water_main", "water_works", "water_tower"],
- color: "var(--res-water)",
- },
- {
- key: "sewer",
- label: "КАНАЛИЗАЦИЯ",
- subtypes: ["sewerage"],
- color: "var(--res-sewer)",
- },
- {
- key: "heat",
- label: "ТЕПЛОСНАБЖЕНИЕ",
- subtypes: ["heat_substation"],
- color: "var(--res-heat)",
- },
- {
- key: "gas",
- label: "ГАЗ",
- subtypes: ["gas_pipeline", "pipeline"],
- color: "var(--res-gas)",
- },
-] as const;
-
-const OK_THRESHOLD_M = 1000;
-
-function formatDistanceMeters(m: number): string {
- // Prototype uses tabular-num, single-line «1 240 м». Round to whole meters.
- return `${Math.round(m).toLocaleString("ru-RU")} м`;
-}
-
-function nearestForResource(
- summary: ReadonlyArray<{ subtype: string; nearest_m: number }>,
- subtypes: readonly string[],
-): number | null {
- let best: number | null = null;
- for (const u of summary) {
- if (!subtypes.includes(u.subtype)) continue;
- if (best === null || u.nearest_m < best) best = u.nearest_m;
- }
- return best;
-}
-
-interface Props {
- analysis: ParcelAnalysis;
-}
-
-export function V2MapLegend({ analysis }: Props) {
- const summary = analysis.utilities?.summary ?? [];
-
- return (
-
-
ТОЧКИ ПОДКЛЮЧЕНИЯ РЕСУРСОВ
- {RESOURCES.map((res) => {
- const nearest = nearestForResource(summary, res.subtypes);
- const hasData = nearest !== null;
- const ok = hasData && nearest! <= OK_THRESHOLD_M;
- const dotColor = hasData
- ? ok
- ? "var(--accent-green)"
- : "var(--accent-orange)"
- : "var(--text-soft)";
- return (
-
-
- {res.label}
-
- {hasData ? formatDistanceMeters(nearest!) : "—"}
-
-
- );
- })}
-
- );
-}