<section class="vb-k4m" id="vb-k4m-mortgage" data-section-name="Ипотечный калькулятор" data-vibeblock-unique-section="yes" aria-labelledby="vb-k4m-title" style="padding-bottom: 150px;">
<style>
.vb-k4m,
.vb-k4m * { box-sizing: border-box; }
.vb-k4m input,
.vb-k4m textarea,
.vb-k4m select { font: inherit; }
.vb-k4m { --ink:rgba(0,0,0,.87); --muted:rgba(0,0,0,.62); --line:#d8d6d1; --cream:#f2f0eb; --ceramic:#edebe9; --green:#006241; --accent:#00754a; --house:#1e3932; width:100%; padding:clamp(36px,6vw,72px) 20px; background:var(--cream); color:var(--ink); font-family:var(--t-text-font); letter-spacing:-.01em; }
.vb-k4m .vb-k4m__shell { max-width:1120px; margin:0 auto; }
.vb-k4m .vb-k4m__heading { max-width:780px; margin:0 0 36px; color:var(--green); font:600 clamp(32px,4.2vw,48px)/1.2 var(--t-headline-font); letter-spacing:-.01em; text-wrap:balance; }
.vb-k4m .vb-k4m__layout { display:grid; grid-template-columns:minmax(0,1.05fr) minmax(320px,.95fr); gap:24px; align-items:stretch; }
.vb-k4m .vb-k4m__controls { display:grid; gap:14px; padding:24px; border-radius:12px; background:#fff; border:1px solid rgba(0,0,0,.07); box-shadow:0 0 .5px rgba(0,0,0,.14),0 1px 1px rgba(0,0,0,.12); }
.vb-k4m .vb-k4m__field { min-width:0; padding:16px; border-radius:12px; background:#f9f9f9; border:1px solid #e4e2de; transition:background .2s ease,border-color .2s ease,box-shadow .2s ease; }
.vb-k4m .vb-k4m__field:focus-within { background:#fff; border-color:var(--accent); box-shadow:0 0 0 2px rgba(0,117,74,.10); }
.vb-k4m .vb-k4m__label-row { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:10px; }
.vb-k4m .vb-k4m__label { font:600 16px/1.4 var(--t-headline-font); color:var(--ink); letter-spacing:-.01em; }
.vb-k4m .vb-k4m__input-wrap { position:relative; }
.vb-k4m .vb-k4m__number { width:100%; height:54px; padding:10px 54px 10px 16px; border:1px solid #d6dbde; border-radius:8px; color:var(--ink); background:#fff; font:500 19px/1.4 var(--t-text-font); letter-spacing:-.01em; transition:border-color .2s ease,background .2s ease,box-shadow .2s ease; }
.vb-k4m .vb-k4m__number:focus-visible { outline:2px solid var(--accent); outline-offset:2px; border-color:var(--accent); box-shadow:0 0 0 4px rgba(0,117,74,.10); }
.vb-k4m .vb-k4m__unit { position:absolute; right:16px; top:50%; transform:translateY(-50%); color:var(--muted); font:500 16px/1.3 var(--t-text-font); pointer-events:none; }
.vb-k4m .vb-k4m__range { display:block; width:100%; height:24px; margin:12px 0 0; cursor:pointer; touch-action:pan-y; -webkit-appearance:none; appearance:none; border-radius:999px; background:#e2e4e1; border:none; }
.vb-k4m .vb-k4m__range::-webkit-slider-runnable-track { width:100%; height:6px; border-radius:999px; background:transparent; }
.vb-k4m .vb-k4m__range::-webkit-slider-thumb { -webkit-appearance:none; appearance:none; height:20px; width:20px; border-radius:50%; background:var(--accent); margin-top:-7px; box-shadow:0 1px 3px rgba(0,0,0,.18); border:2px solid #fff; transition:transform .15s ease; }
.vb-k4m .vb-k4m__range::-webkit-slider-thumb:hover { transform:scale(1.12); }
.vb-k4m .vb-k4m__range::-moz-range-track { width:100%; height:6px; border-radius:999px; background:transparent; border:0; }
.vb-k4m .vb-k4m__range::-moz-range-thumb { height:20px; width:20px; border-radius:50%; background:var(--accent); border:2px solid #fff; box-shadow:0 1px 3px rgba(0,0,0,.18); }
.vb-k4m .vb-k4m__range:focus-visible { outline:2px solid var(--accent); outline-offset:4px; }
.vb-k4m .vb-k4m__hint { display:none; margin:10px 0 0; color:#a51d13; font:400 14px/1.45 var(--t-text-font); }
.vb-k4m .vb-k4m__hint--visible { display:block; }
.vb-k4m .vb-k4m__result { display:flex; flex-direction:column; justify-content:center; min-width:0; padding:clamp(26px,4vw,42px); border-radius:12px; background:var(--house); border:1px solid var(--house); color:#fff; }
.vb-k4m .vb-k4m__result-label { margin:0 0 12px; font:500 19px/1.4 var(--t-headline-font); color:rgba(255,255,255,.82); }
.vb-k4m .vb-k4m__payment { margin:0; font:600 clamp(42px,5.2vw,64px)/1.08 var(--t-headline-font); letter-spacing:-.02em; overflow-wrap:anywhere; color:#fff; }
.vb-k4m .vb-k4m__payment-unit { margin:8px 0 26px; font:400 16px/1.45 var(--t-text-font); color:rgba(255,255,255,.72); }
.vb-k4m .vb-k4m__stats { display:grid; gap:0; margin:0 0 24px; border-top:1px solid rgba(255,255,255,.2); }
.vb-k4m .vb-k4m__stat { display:flex; justify-content:space-between; align-items:baseline; gap:14px; padding:15px 0; border-bottom:1px solid rgba(255,255,255,.2); font:400 16px/1.45 var(--t-text-font); }
.vb-k4m .vb-k4m__stat dt { color:rgba(255,255,255,.76); }
.vb-k4m .vb-k4m__stat dd { margin:0; font-weight:600; text-align:right; color:#fff; }
.vb-k4m .vb-k4m__cta { display:inline-flex; align-items:center; justify-content:center; min-height:50px; width:max-content; max-width:100%; padding:12px 22px; border:1px solid #fff; border-radius:50px; background:#fff; color:var(--accent); text-decoration:none; font:600 16px/1.2 var(--t-text-font); letter-spacing:-.01em; text-align:center; transition:transform .2s ease,background-color .2s ease; }
.vb-k4m .vb-k4m__cta:hover { background:#f2f0eb; }
.vb-k4m .vb-k4m__cta:active { transform:scale(.95); }
.vb-k4m .vb-k4m__cta:focus-visible { outline:3px solid #d4e9e2; outline-offset:3px; }
.vb-k4m .vb-k4m__disclaimer { margin:15px 0 0; max-width:58ch; color:rgba(255,255,255,.72); font:400 12px/1.5 var(--t-text-font); text-wrap:pretty; }
@media (max-width:960px) {
.vb-k4m .vb-k4m__layout { grid-template-columns:minmax(0,1fr) minmax(300px,.9fr); gap:18px; }
.vb-k4m .vb-k4m__controls { padding:18px; }
.vb-k4m .vb-k4m__field { padding:14px; }
}
@media (max-width:760px) {
.vb-k4m .vb-k4m__layout { grid-template-columns:1fr; }
.vb-k4m .vb-k4m__controls { padding:20px; gap:12px; }
.vb-k4m .vb-k4m__result { padding:26px 22px; }
.vb-k4m .vb-k4m__heading { margin-bottom:28px; }
}
@media (max-width:640px) {
.vb-k4m { padding-right:14px; padding-left:14px; }
.vb-k4m .vb-k4m__label-row { align-items:flex-start; }
.vb-k4m .vb-k4m__stat { align-items:flex-start; flex-direction:column; gap:4px; padding:12px 0; font-size:15px; }
.vb-k4m .vb-k4m__stat dd { text-align:left; }
.vb-k4m .vb-k4m__heading { font-size:clamp(32px,8vw,42px); }
.vb-k4m .vb-k4m__label { font-size:15px; }
.vb-k4m .vb-k4m__number { height:54px; font-size:18px; }
.vb-k4m .vb-k4m__result-label { font-size:18px; }
.vb-k4m .vb-k4m__payment { font-size:clamp(40px,10vw,54px); }
.vb-k4m .vb-k4m__cta { width:100%; min-height:50px; padding:12px 20px; font-size:16px; }
}
@media (prefers-reduced-motion:reduce) {
.vb-k4m *, .vb-k4m *::before, .vb-k4m *::after { scroll-behavior:auto !important; transition:none !important; }
}
</style>
<div class="vb-k4m__shell">
<h2 class="vb-k4m__heading" id="vb-k4m-title">Рассчитайте ипотеку</h2>
<div class="vb-k4m__layout">
<div class="vb-k4m__controls" aria-label="Параметры расчёта">
<div class="vb-k4m__field"><div class="vb-k4m__label-row"><label class="vb-k4m__label" for="vb-k4m-price">Стоимость недвижимости</label></div><div class="vb-k4m__input-wrap"><input class="vb-k4m__number" id="vb-k4m-price" type="number" min="1000000" max="100000000" step="100000" value="12000000" inputmode="numeric"><span class="vb-k4m__unit">₽</span></div><input class="vb-k4m__range" id="vb-k4m-price-range" type="range" min="1000000" max="100000000" step="100000" value="12000000" aria-label="Стоимость недвижимости, ползунок"></div>
<div class="vb-k4m__field"><div class="vb-k4m__label-row"><label class="vb-k4m__label" for="vb-k4m-down">Первоначальный взнос</label></div><div class="vb-k4m__input-wrap"><input class="vb-k4m__number" id="vb-k4m-down" type="number" min="0" max="12000000" step="50000" value="2400000" inputmode="numeric" aria-describedby="vb-k4m-hint"><span class="vb-k4m__unit">₽</span></div><input class="vb-k4m__range" id="vb-k4m-down-range" type="range" min="0" max="12000000" step="50000" value="2400000" aria-label="Первоначальный взнос, ползунок"><p class="vb-k4m__hint" id="vb-k4m-hint" role="alert"></p></div>
<div class="vb-k4m__field"><div class="vb-k4m__label-row"><label class="vb-k4m__label" for="vb-k4m-rate">Годовая процентная ставка</label></div><div class="vb-k4m__input-wrap"><input class="vb-k4m__number" id="vb-k4m-rate" type="number" min="0" max="30" step="0.1" value="8" inputmode="decimal"><span class="vb-k4m__unit">%</span></div><input class="vb-k4m__range" id="vb-k4m-rate-range" type="range" min="0" max="30" step="0.1" value="8" aria-label="Годовая процентная ставка, ползунок"></div>
<div class="vb-k4m__field"><div class="vb-k4m__label-row"><label class="vb-k4m__label" for="vb-k4m-years">Срок кредита</label></div><div class="vb-k4m__input-wrap"><input class="vb-k4m__number" id="vb-k4m-years" type="number" min="1" max="30" step="1" value="20" inputmode="numeric"><span class="vb-k4m__unit">лет</span></div><input class="vb-k4m__range" id="vb-k4m-years-range" type="range" min="1" max="30" step="1" value="20" aria-label="Срок кредита, ползунок"></div>
</div>
<aside class="vb-k4m__result" aria-label="Результат расчёта" aria-live="polite">
<p class="vb-k4m__result-label">Ежемесячный платёж</p><p class="vb-k4m__payment" id="vb-k4m-payment">—</p>
<dl class="vb-k4m__stats"><div class="vb-k4m__stat"><dt>Сумма кредита</dt><dd id="vb-k4m-principal">—</dd></div><div class="vb-k4m__stat"><dt>Общая сумма выплат</dt><dd id="vb-k4m-total">—</dd></div><div class="vb-k4m__stat"><dt>Переплата по процентам</dt><dd id="vb-k4m-overpay">—</dd></div></dl>
<a class="vb-k4m__cta" href="#consultation">Получить консультацию</a>
<p class="vb-k4m__disclaimer">Расчёт предварительный и не является предложением банка или гарантией одобрения. Фактические условия определяет кредитор; комиссии, страховки и дополнительные расходы не включены.</p>
</aside>
</div>
</div>
<script>
(function(){
'use strict';
var root=document.getElementById('vb-k4m-mortgage');
if(!root)return;
var fields={
price:{input:root.querySelector('#vb-k4m-price'),range:root.querySelector('#vb-k4m-price-range')},
down:{input:root.querySelector('#vb-k4m-down'),range:root.querySelector('#vb-k4m-down-range')},
rate:{input:root.querySelector('#vb-k4m-rate'),range:root.querySelector('#vb-k4m-rate-range')},
years:{input:root.querySelector('#vb-k4m-years'),range:root.querySelector('#vb-k4m-years-range')}
};
var hint=root.querySelector('#vb-k4m-hint');
var output={payment:root.querySelector('#vb-k4m-payment'),principal:root.querySelector('#vb-k4m-principal'),total:root.querySelector('#vb-k4m-total'),overpay:root.querySelector('#vb-k4m-overpay')};
var money=new Intl.NumberFormat('ru-RU',{maximumFractionDigits:0});
function rub(value){return money.format(Math.round(value))+' ₽';}
function bounds(field){return {min:Number(field.input.min),max:Number(field.input.max),step:Number(field.input.step)||1};}
function clamp(value,field){var b=bounds(field);return Math.min(b.max,Math.max(b.min,value));}
function update(){
var price=Number(fields.price.input.value),down=Number(fields.down.input.value),annual=Number(fields.rate.input.value),years=Number(fields.years.input.value);
var invalidDown=down<0||down>price;
hint.textContent=invalidDown?(down>price?'Первоначальный взнос не может превышать стоимость недвижимости.':'Первоначальный взнос не может быть отрицательным.') : '';
hint.classList.toggle('vb-k4m__hint--visible',invalidDown);
fields.down.input.setAttribute('aria-invalid',invalidDown?'true':'false');
if(!Number.isFinite(price)||!Number.isFinite(down)||!Number.isFinite(annual)||!Number.isFinite(years)||price<=0||down<0||down>price||annual<0||years<=0){output.payment.textContent='—';output.principal.textContent='—';output.total.textContent='—';output.overpay.textContent='—';return;}
var principal=price-down,n=years*12,r=annual/12/100,payment=r===0?principal/n:principal*r*Math.pow(1+r,n)/(Math.pow(1+r,n)-1),total=payment*n;
output.payment.textContent=rub(payment);output.principal.textContent=rub(principal);output.total.textContent=rub(total);output.overpay.textContent=rub(total-principal);
}
Object.keys(fields).forEach(function(key){
var pair=fields[key],input=pair.input,range=pair.range;
range.addEventListener('input',function(){input.value=range.value;if(key==='price'){fields.down.input.max=range.value;fields.down.range.max=range.value;}update();});
input.addEventListener('input',function(){
if(input.value===''){update();return;}
var value=Number(input.value),b=bounds(pair);
if(!Number.isFinite(value)||value<b.min||value>b.max){update();return;}
range.value=String(value);
if(key==='price'){fields.down.input.max=String(value);fields.down.range.max=String(value);}
update();
});
input.addEventListener('change',function(){
if(input.value===''){input.value=String(input.min);}
var value=clamp(Number(input.value),pair);input.value=String(value);range.value=String(value);
if(key==='price'){fields.down.input.max=String(value);fields.down.range.max=String(value);}
update();
});
});
update();
})();
</script>
</section><style data-vb-overrides="true">
#vb-k4m-payment {
padding: 0px 0px 40px;
}
.vb-k4m__cta {
margin: 20px 0px 0px;
}
</style>