// Savings calculator + Packages + Video + Contact + Footer const Calculator = () => { const [area, setArea] = React.useState(60); const [billing, setBilling] = React.useState(7000); // monthly utility bill const [risk, setRisk] = React.useState(true); // Heuristic savings (purely illustrative, conservative): const heatingShare = 0.45; // share of utility going to heat/electricity const climateSavings = Math.round(billing * heatingShare * 0.15); // 15% saved by smart climate const lightSavings = Math.round(area * 25); // 25 ₽ per m² per month from auto light const leakAvoidance = risk ? 3300 : 0; // amortized risk-adjusted const monthly = climateSavings + lightSavings + leakAvoidance; const yearly = monthly * 12; return (
Сколько экономит

Экономия складывается
из трёх привычек.

Климат держится только когда нужно. Свет не горит впустую. А вовремя замеченная протечка экономит десятки тысяч на ремонте. Это консервативная оценка — реальные цифры обычно выше.

В год можно сэкономить
{yearly.toLocaleString("ru-RU")}
{monthly.toLocaleString("ru-RU")} ₽ В МЕСЯЦ · ОЦЕНКА

Это базовая оценка. На реальном объекте экономия складывается из десятков мелочей: ночные тарифы, контроль приборов в режиме ожидания, уход в эко-режим при отсутствии — расскажем при осмотре.
); }; const Line = ({ label, value, hint }) => (
{label}
{hint}
{value ? `+${value.toLocaleString("ru-RU")} ₽` : "0 ₽"}
); const Slider = ({ label, value, min, max, step, suffix, onChange }) => (
{label} {value.toLocaleString("ru-RU")}{suffix}
onChange(Number(e.target.value))} style={{ width: "100%", marginTop: 10, accentColor: "#1E3A2F" }} />
); // ----- Packages ----- const Packages = ({ onSelect, onRequest, onConsult, activeName }) => { const { PACKAGES, computeQuote, money } = window.RD; return (
Готовые пакеты

Готовые пакеты с чётким составом.

Выберите пакет — оставьте заявку или дособерите состав в конструкторе. К любой заявке автоматически прикрепляются КП и счёт.

{PACKAGES.map(p => { const quote = computeQuote(p.compose); const isActive = activeName === p.name; return (
{p.flagship && ( Флагман )}
{p.tagline}

{p.name}

{money(quote.total)}

{p.blurb}

Состав · {quote.pieces} шт.
    {quote.items.map(it => (
  • {it.name} ×{it.qty}
  • ))}
); })}
); }; // ----- Video ----- const VideoDemo = () => (
Видео-демо

Посмотрите, как РазумДом
работает на объекте.

Короткое видео с реального объекта в Иркутске. Показываем, как срабатывает защита от протечки, как греется пол по утрам, как один сценарий выключает всю квартиру.

Запросить ссылку
video · 1:42 · placeholder
Объект · Иркутск
); // ----- Contact ----- const Contact = ({ picked, presetName, kpNumber, consult, setConsult }) => { const { computeQuote, matchPackage, money, submitLead } = window.RD; const quote = computeQuote(picked || {}); const configName = presetName || matchPackage(picked || {}) || "Индивидуальная конфигурация"; const interest = consult ? "Бесплатная консультация" : configName; const [name, setName] = React.useState(""); const [contact, setContact] = React.useState(""); const [objectType, setObjectType] = React.useState("Квартира в новостройке"); const [comment, setComment] = React.useState(""); const [status, setStatus] = React.useState("idle"); // idle | sending | done | error const [valErr, setValErr] = React.useState(""); const submit = async (e) => { e.preventDefault(); if (status === "sending") return; if (name.trim().length < 2) { setValErr("Напишите, как к вам обращаться."); return; } if (contact.trim().length < 3) { setValErr("Укажите телефон или Telegram — как с вами связаться."); return; } setValErr(""); setStatus("sending"); const payload = window.RD.buildLeadPayload({ name, contact, objectType, comment, picked, configName, kpNumber, interest, }); const res = await submitLead(payload); setStatus(res.ok ? "done" : "error"); }; return (
Связаться

Оставьте заявку —
ответим в течение дня.

Бесплатная консультация — 0 ₽

Поможем понять, что можно автоматизировать в вашей квартире или частном доме, и подскажем оптимальный состав. К заявке автоматически прикрепляется собранная комплектация и КП. Работаем по Иркутску и области.

{/* Прикреплённый блок: КП — или карточка бесплатной консультации */} {consult ? (
Тип заявки
Бесплатная консультация 0 ₽
Подберём состав под вашу квартиру или дом
{ e.preventDefault(); setConsult && setConsult(false); window.RD.scrollTo("builder"); }} style={{ display: "inline-flex", gap: 6, alignItems: "center", marginTop: 12, fontSize: 13, color: "var(--accent)" }}> Собрать пакет самостоятельно
) : (
Прикреплено к заявке
КП № {kpNumber}
{interest} {money(quote.total)}
{quote.pieces} устройств · монтаж и настройка включены
{ e.preventDefault(); window.RD.scrollTo("builder"); }} style={{ display: "inline-flex", gap: 6, alignItems: "center", marginTop: 12, fontSize: 13, color: "var(--accent)" }}> Изменить состав
)}
{status === "done" ? (

Заявка отправлена

{consult ? "Заявка на бесплатную консультацию принята. Свяжемся с вами в ближайшее время." : `КП № ${kpNumber} на ${money(quote.total)} принят. Свяжемся с вами в ближайшее время.`}

) : (
setName(e.target.value)} placeholder="Имя" autoComplete="name" style={inputStyle} /> setContact(e.target.value)} placeholder="+7 ___ ___-__-__ или @username" inputMode="tel" autoComplete="tel" style={inputStyle} />
{["Квартира в новостройке", "Квартира в обжитом фонде", "Частный дом", "Другое"].map((o) => ( ))}