{r.title}
{r.meta}
diff --git a/tradein-mvp/frontend/src/app/mera-public/_components/v3/deal-view.ts b/tradein-mvp/frontend/src/app/mera-public/_components/v3/deal-view.ts
index 33a868ae..624da3f6 100644
--- a/tradein-mvp/frontend/src/app/mera-public/_components/v3/deal-view.ts
+++ b/tradein-mvp/frontend/src/app/mera-public/_components/v3/deal-view.ts
@@ -1,10 +1,15 @@
/**
* Форматирование строк витрины `/showcase` — общее для ленты, таблицы сверок и
* игры. Держится в одном месте, потому что «объект» в этих данных описывается
- * ТОЛЬКО так: комнаты, площадь, этаж, район (может отсутствовать). Улицы и
- * дома в данных нет вовсе — номер дома известен у 2.7% сделок, — и три
- * компонента, каждый со своей склейкой, рано или поздно разъехались бы в том,
- * что именно они выдают за адрес.
+ * ТОЛЬКО так: комнаты, площадь, этаж, район (может отсутствовать). НАЗВАНИЯ
+ * улицы и номера дома в данных нет — номер дома известен у 2.7% сделок, — и
+ * три компонента, каждый со своей склейкой, рано или поздно разъехались бы в
+ * том, что именно они выдают за адрес.
+ *
+ * С 29.08.2026 у строки есть координата, но адресом она не становится: это
+ * центроид УЛИЦЫ (около тридцати сделок в одной точке), он годится карте
+ * масштаба района и не годится подписи «объект находится здесь». Поэтому
+ * координата уезжает только в карту, а в текстовые склейки — нет.
*/
import type { ShowcaseDeal } from "../../public-api";
@@ -51,6 +56,15 @@ export interface GameRound {
readonly meta: string;
/** Район или прямое «район не указан» — подстановки нет. */
readonly districtLabel: string;
+ /**
+ * Район как он записан в данных — им карта ищет полигон, и подставлять
+ * вместо `null` подпись «район не указан» нельзя: совпадений с именами
+ * районов у неё не будет, но выглядеть это будет как поиск.
+ */
+ readonly district: string | null;
+ /** Центроид УЛИЦЫ сделки, не дом (см. `note` строки витрины). */
+ readonly lat: number | null;
+ readonly lon: number | null;
readonly quarter: string;
/** Границы слайдера, млн ₽. */
readonly min: number;
@@ -86,6 +100,9 @@ export function toGameRound(deal: ShowcaseDeal, index: number): GameRound {
title: dealTitle(deal),
meta: dealMeta(deal),
districtLabel: deal.district ?? "район не указан",
+ district: deal.district,
+ lat: deal.lat,
+ lon: deal.lon,
quarter: deal.deal_quarter,
min,
max,
diff --git a/tradein-mvp/frontend/src/app/mera-public/b2c-tokens.ts b/tradein-mvp/frontend/src/app/mera-public/b2c-tokens.ts
index 77f98dc5..dfcbe336 100644
--- a/tradein-mvp/frontend/src/app/mera-public/b2c-tokens.ts
+++ b/tradein-mvp/frontend/src/app/mera-public/b2c-tokens.ts
@@ -47,6 +47,13 @@ export const b2c = {
line: "#CBD7DA",
/** Тонкие внутренние разделители. */
lineSoft: "#EAF5F7",
+ /**
+ * Линия НА ТЁМНОЙ плашке (`surfaceDark`): рамки тегов, контуры соседних
+ * районов на карте сделки. Тот же оттенок, что уже стоял литералом в
+ * `landing-v3.module.css`; заведён токеном, когда карта потребовала его
+ * второй раз — правило «hex только здесь» иначе разъезжается.
+ */
+ lineDark: "#2C3A3F",
/** Акцент — заливки/обводки/декор. НЕ для текста, см. шапку. */
accent: "#16A9BC",
diff --git a/tradein-mvp/frontend/src/app/mera-public/landing-v3.module.css b/tradein-mvp/frontend/src/app/mera-public/landing-v3.module.css
index 0d7d137c..15829739 100644
--- a/tradein-mvp/frontend/src/app/mera-public/landing-v3.module.css
+++ b/tradein-mvp/frontend/src/app/mera-public/landing-v3.module.css
@@ -1643,58 +1643,36 @@
.gameMapGrid {
position: absolute;
inset: 0;
- opacity: 0.16;
+ opacity: 0.08;
background-image:
linear-gradient(var(--b2c-accent) 1px, transparent 1px),
linear-gradient(90deg, var(--b2c-accent) 1px, transparent 1px);
background-size: 44px 44px;
}
-.gameMapRoadH {
- position: absolute;
- left: 0;
- right: 0;
- top: 38%;
- height: 14px;
- background: #2c3a3f;
- opacity: 0.7;
-}
-.gameMapRoadV {
- position: absolute;
- top: 0;
- bottom: 0;
- left: 62%;
- width: 12px;
- background: #2c3a3f;
- opacity: 0.7;
-}
-.gameMapDot {
- position: absolute;
- width: 16px;
- height: 16px;
- margin: -8px 0 0 -8px;
-}
-.gameMapPing {
+.gameMapSvg {
position: absolute;
inset: 0;
- display: block;
- border-radius: 50%;
- background: var(--b2c-accent);
- animation: gamePing 2.4s ease-out infinite;
+ width: 100%;
+ height: 100%;
+}
+/* Район сделки: заливка акцентом поверх фон-сетки плюс сплошная обводка. */
+.gameMapHome {
+ fill: var(--b2c-accent);
+ fill-opacity: 0.16;
+ stroke: var(--b2c-accent);
+}
+/* Соседние районы — контекст, а не содержание: только контур на тёмном. */
+.gameMapAround {
+ fill: none;
+ stroke: var(--b2c-line-dark);
+}
+.gameMapHalo {
+ fill: var(--b2c-accent);
+ fill-opacity: 0.28;
}
.gameMapCore {
- position: absolute;
- inset: 0;
- display: block;
- border-radius: 50%;
- background: var(--b2c-accent);
- border: 3px solid var(--b2c-surface-dark);
-}
-@keyframes gamePing {
- 0% { transform: scale(1); opacity: 0.55; }
- 70%, 100% { transform: scale(2.6); opacity: 0; }
-}
-@media (prefers-reduced-motion: reduce) {
- .gameMapPing { animation: none; }
+ fill: var(--b2c-accent);
+ stroke: var(--b2c-surface-dark);
}
.gameMapLabel {
position: relative;
@@ -1727,7 +1705,7 @@
font-family: var(--b2c-font-mono);
font-size: 10.5px;
color: #9fb0b4;
- border: 1px solid #2c3a3f;
+ border: 1px solid var(--b2c-line-dark);
border-radius: 4px;
padding: 5px 10px;
}
diff --git a/tradein-mvp/frontend/src/app/mera-public/public-api.ts b/tradein-mvp/frontend/src/app/mera-public/public-api.ts
index 48236aea..959f116e 100644
--- a/tradein-mvp/frontend/src/app/mera-public/public-api.ts
+++ b/tradein-mvp/frontend/src/app/mera-public/public-api.ts
@@ -206,6 +206,13 @@ export interface ShowcaseDeal {
err_pct: number;
n_analogs: number;
note: string;
+ /**
+ * Координата сделки — ЦЕНТРОИД УЛИЦЫ, не дом (граница честности записана в
+ * `note` каждой строки и в COMMENT колонок). `null` — координаты нет;
+ * подставлять на её место соседнюю строку или центр района нельзя.
+ */
+ lat: number | null;
+ lon: number | null;
}
/** Подпись под витриной: из чего отобраны показанные строки. */
diff --git a/tradein-mvp/frontend/src/app/mera-public/theme.ts b/tradein-mvp/frontend/src/app/mera-public/theme.ts
index a3678aef..2a4803af 100644
--- a/tradein-mvp/frontend/src/app/mera-public/theme.ts
+++ b/tradein-mvp/frontend/src/app/mera-public/theme.ts
@@ -98,6 +98,7 @@ export const b2cVars = {
"--b2c-line": b2c.line,
"--b2c-line-soft": b2c.lineSoft,
+ "--b2c-line-dark": b2c.lineDark,
// accent — только заливки/обводки; текст красится accentText (5.8:1).
// Разбор контраста — в шапке b2c-tokens.ts.