diff --git a/frontend/src/components/site-finder/analysis/MassingEconomics.tsx b/frontend/src/components/site-finder/analysis/MassingEconomics.tsx
index 59fb7687..272c6239 100644
--- a/frontend/src/components/site-finder/analysis/MassingEconomics.tsx
+++ b/frontend/src/components/site-finder/analysis/MassingEconomics.tsx
@@ -114,16 +114,19 @@ function KpiGrid({
label="Общая площадь (GFA)"
value={formatInt(teap.total_floor_area_sqm)}
unit="м²"
+ hint="Поэтажная площадь всех корпусов = пятно застройки × этажность."
/>
@@ -149,10 +153,12 @@ function KpiGrid({
@@ -253,9 +266,20 @@ interface Props {
farTarget: number;
/** True when факт-КСИТ exceeds the cap (model.over, computed scene-side). */
ksitOver: boolean;
+ /**
+ * True when the parcel is regulatorily constrained for МКД (gate-blocked /
+ * non-residential / ЗОУИТ-СЗЗ) — drives the honest «условный расчёт» caveat
+ * below the strip alongside the negative-economics case.
+ */
+ gateConstrained?: boolean;
}
-export function MassingEconomics({ program, farTarget, ksitOver }: Props) {
+export function MassingEconomics({
+ program,
+ farTarget,
+ ksitOver,
+ gateConstrained = false,
+}: Props) {
const recompute = useRecomputeMassing();
// Last successful result kept locally so a failed/stale recompute never blanks
@@ -316,6 +340,13 @@ export function MassingEconomics({ program, farTarget, ksitOver }: Props) {
// A fresher request is in flight over the last-good values.
const stale = recompute.isPending;
+ // Honest «условный расчёт» caveat: when the economics turn negative OR the
+ // parcel is regulatorily constrained (gate-blocked / ЗОУИТ-СЗЗ / нежилое),
+ // we say so plainly rather than presenting the figures as a viable project.
+ const economicsNegative =
+ result.financial.net_profit_rub < 0 || result.financial.npv_rub < 0;
+ const showConditionalNote = economicsNegative || gateConstrained;
+
return (
+ {showConditionalNote ? (
+
+
+
+ Расчёт условный: участок ограничен регламентом (см. блокеры выше)
+ и/или экономика отрицательна при текущих вводных. Измените
+ этажность, число секций или класс — модель пересчитается.
+
+
+ ) : null}
+
{errored ? (
{/* Collapsed by default (above-the-fold rule) — form + button inside;
@@ -358,7 +369,7 @@ export function Section7Concept({ analysis }: Props) {
>
@@ -397,9 +409,20 @@ export function Section7Concept({ analysis }: Props) {
color: "var(--fg-primary)",
}}
>
- Кадастровый номер {analysis.cad_num} · площадь ≈{" "}
- {ha(parcelAreaSqm)} га.
+ Кадастровый номер {analysis.cad_num} · площадь пятна по
+ геометрии ≈ {ha(parcelAreaSqm)} га.
+
+ Массинг и КСИТ считаются от площади застраиваемого пятна по
+ геометрии участка (контур НСПД), поэтому она может
+ отличаться от площади по ЕГРН в карточке участка.
+