/
mubarak
/
MB
Обзор
Документация
Войти
/
mubarak
/
MB
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
index.html
458 строк
22 KB
mubarak
Update: index.html
01 авг 2026, 17:23
Верифицирован
01 авг 2026, 17:23
aae03d2
Код
Авторство
О чём код?
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> <meta name="theme-color" content="#1a2a20"> <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate"> <meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Expires" content="0"> <title>Мубарака — Рассрочка</title> <link rel="manifest" href="manifest.json"> <style> * { margin: 0; padding: 0; box-sizing: border-box; } :root { --bg: #1a2a20; --card-bg: #f8f6f0; --text: #1e2b1f; --muted: #6b7a6d; --accent: #1f4d3a; --accent-light: #e2efe6; --gold: #b8862d; --gold-light: #faf3e6; --border: #d8e0d6; --input-bg: #f0f3ef; --range-track: #dce3da; --range-fill: #1f4d3a; --shadow: 0 14px 40px rgba(0,0,0,0.22); } html, body { height: 100%; width: 100%; position: fixed; top: 0; left: 0; background: var(--bg); overflow: hidden; overscroll-behavior: none; } body { font-family: 'Inter', -apple-system, sans-serif; color: var(--text); display: flex; justify-content: center; align-items: center; -webkit-tap-highlight-color: transparent; padding: env(safe-area-inset-top, 0) 10px env(safe-area-inset-bottom, 0) 10px; } .app { width: 100%; height: 100%; max-width: 430px; display: flex; flex-direction: column; background: var(--card-bg); border-radius: 28px; box-shadow: var(--shadow); overflow: hidden; } .scroll-area { overflow-y: auto; -webkit-overflow-scrolling: touch; flex: 1; display: flex; flex-direction: column; overscroll-behavior: contain; } .header { display: flex; justify-content: space-between; align-items: center; padding: 20px 20px 14px; flex-shrink: 0; } .brand { display: flex; align-items: center; gap: 10px; font-size: 22px; font-weight: 800; color: var(--text); letter-spacing: -0.4px; } .brand-icon { width: 42px; height: 42px; background: linear-gradient(135deg, var(--accent), #153828); border-radius: 14px; display: flex; align-items: center; justify-content: center; color: #fff; font-size: 22px; box-shadow: 0 4px 12px rgba(0,0,0,0.2); } .info-btn { width: 38px; height: 38px; border-radius: 12px; background: var(--input-bg); border: none; color: var(--muted); font-size: 17px; font-weight: 600; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s; } .info-btn:active { background: var(--accent-light); color: var(--accent); } .tariff-card { margin: 0 18px 8px; padding: 14px 18px; display: flex; align-items: center; justify-content: space-between; border-radius: 16px; flex-shrink: 0; background: var(--accent-light); border: 1px solid rgba(31,77,58,0.1); transition: background 0.35s; } .tariff-card.exclusive { background: var(--gold-light); border-color: rgba(184,134,45,0.15); } .tariff-left { display: flex; align-items: center; gap: 12px; } .tariff-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 4px rgba(31,77,58,0.12); flex-shrink: 0; } .tariff-card.exclusive .tariff-dot { background: var(--gold); box-shadow: 0 0 0 4px rgba(184,134,45,0.12); } .tariff-name { font-weight: 700; font-size: 15px; color: var(--accent); } .tariff-card.exclusive .tariff-name { color: var(--gold); } .tariff-rate-badge { font-weight: 800; font-size: 17px; color: var(--accent); transition: transform 0.3s; } .tariff-card.exclusive .tariff-rate-badge { color: var(--gold); } .tariff-rate-badge.pulse { transform: scale(1.2); } .content { padding: 4px 18px 6px; display: flex; flex-direction: column; gap: 14px; flex-shrink: 0; } .field { margin-bottom: 0; } .label-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; } label { font-size: 11px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.7px; } .limit-toggle { background: var(--input-bg); border: 1px solid var(--border); border-radius: 8px; padding: 5px 10px; font-size: 10px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px; cursor: pointer; transition: all 0.2s ease; font-family: inherit; } .limit-toggle:active { background: var(--accent); color: #fff; border-color: var(--accent); } .val { font-weight: 700; font-size: 13px; color: var(--accent); } .input-box { display: flex; align-items: center; background: var(--input-bg); border: 2px solid transparent; border-radius: 14px; padding: 12px 15px; transition: all 0.2s; } .input-box:focus-within { border-color: var(--accent); background: #fff; } .input-box input { width: 100%; border: none; background: transparent; font-size: 18px; font-weight: 700; color: var(--text); outline: none; } .input-box .currency { font-size: 16px; font-weight: 600; color: var(--muted); margin-left: 7px; } input[type="range"] { -webkit-appearance: none; width: 100%; height: 5px; background: var(--range-track); border-radius: 3px; outline: none; margin: 11px 0 5px; cursor: pointer; touch-action: none; } input[type="range"]::-webkit-slider-runnable-track { height: 5px; background: transparent; border-radius: 3px; } input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 26px; height: 26px; border-radius: 50%; background: #fff; border: 2.5px solid var(--range-fill); box-shadow: 0 2px 8px rgba(0,0,0,0.12); cursor: pointer; margin-top: -10.5px; transition: transform 0.1s; } input[type="range"]::-webkit-slider-thumb:active { transform: scale(1.1); } .limits { display: flex; justify-content: space-between; font-size: 9px; font-weight: 500; color: var(--muted); padding: 0 2px; } .pct-btns { display: flex; gap: 7px; margin-top: 9px; } .pct-btn { flex: 1; background: var(--input-bg); border: 2px solid transparent; border-radius: 12px; padding: 11px 4px; font-weight: 700; font-size: 12px; color: var(--text); text-align: center; cursor: pointer; transition: all 0.15s; } .pct-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); } .pct-btn.semi-disabled { opacity: 0.4; pointer-events: none; background: var(--input-bg); color: var(--muted); } .info-text { background: var(--accent-light); color: var(--accent); padding: 8px 12px; border-radius: 10px; font-size: 11px; font-weight: 600; margin-top: 8px; display: none; } .info-text.show { display: block; } .receipt { padding: 16px 18px 20px; flex-shrink: 0; border-top: 1px solid var(--border); margin-top: 4px; } .receipt h3 { font-size: 11px; font-weight: 700; margin-bottom: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.7px; } .check-row { display: flex; align-items: baseline; margin-bottom: 9px; font-size: 13px; color: var(--muted); font-weight: 500; } .check-row.bold { font-size: 14px; color: var(--text); font-weight: 700; } .check-row .dots { flex: 1; border-bottom: 2px dotted var(--border); margin: 0 10px; } .check-row .value { white-space: nowrap; font-weight: 600; } .total-zone { padding-top: 10px; margin-top: 6px; display: flex; justify-content: space-between; align-items: center; font-size: 15px; font-weight: 700; border-top: 2px solid var(--border); } .total-zone .total-value { font-size: 24px; font-weight: 800; color: var(--accent); letter-spacing: -0.5px; } .share-btn { width: 100%; background: var(--input-bg); border: none; border-radius: 13px; padding: 12px; font-weight: 700; font-size: 13px; color: var(--accent); cursor: pointer; margin-top: 11px; transition: all 0.2s; font-family: inherit; } .share-btn:active { background: var(--accent-light); } .partner-banner { display: flex; align-items: center; justify-content: space-between; background: linear-gradient(135deg, #1f4d3a 0%, #2c5e3a 100%); border-radius: 16px; padding: 14px 16px; margin-top: 16px; text-decoration: none; box-shadow: 0 10px 24px rgba(31, 77, 58, 0.25); transition: transform 0.2s, box-shadow 0.2s; width: 100%; position: relative; overflow: hidden; } .partner-banner:active { transform: scale(0.97); box-shadow: 0 4px 12px rgba(31, 77, 58, 0.15); } .partner-banner::after { content: ''; position: absolute; top: 0; left: -100%; width: 50%; height: 100%; background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0) 100%); transform: skewX(-20deg); animation: shine 6s infinite; } @keyframes shine { 0% { left: -100%; } 20% { left: 200%; } 100% { left: 200%; } } .pb-content { display: flex; align-items: center; gap: 12px; position: relative; z-index: 2; } .pb-icon { width: 44px; height: 44px; background: rgba(255, 255, 255, 0.15); border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 22px; box-shadow: 0 4px 10px rgba(0,0,0,0.1); flex-shrink: 0; } .pb-text { display: flex; flex-direction: column; gap: 2px; } .pb-title { font-weight: 800; font-size: 15px; color: #ffffff; letter-spacing: -0.3px; } .pb-sub { font-weight: 600; font-size: 11px; color: rgba(255, 255, 255, 0.85); text-transform: uppercase; letter-spacing: 0.5px; } .pb-arrow { width: 32px; height: 32px; background: #ffffff; color: #1f4d3a; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 16px; font-weight: bold; flex-shrink: 0; position: relative; z-index: 2; box-shadow: 0 4px 12px rgba(0,0,0,0.1); } .modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 200; display: flex; align-items: center; justify-content: center; opacity: 0; pointer-events: none; transition: opacity 0.25s; } .modal-overlay.active { opacity: 1; pointer-events: auto; } .modal-card { background: #fff; border-radius: 22px; padding: 28px 22px; max-width: 350px; width: 90%; text-align: center; box-shadow: 0 20px 40px rgba(0,0,0,0.3); } .modal-card h3 { font-size: 18px; font-weight: 800; margin-bottom: 4px; color: var(--accent); } .modal-card .subtitle { font-size: 13px; color: var(--muted); margin-bottom: 16px; } .modal-card .rate-box { background: var(--accent-light); border-radius: 14px; padding: 14px; margin-bottom: 10px; border: 1px solid rgba(31,77,58,0.12); } .modal-card .rate-box.gold { background: var(--gold-light); border-color: rgba(184,134,45,0.2); } .modal-card .rate-box .range { font-weight: 700; font-size: 14px; margin-bottom: 4px; } .modal-card .rate-box .value { font-size: 15px; font-weight: 800; color: var(--gold); } .modal-card .modal-close { background: var(--accent); color: #fff; border: none; padding: 14px 30px; border-radius: 15px; font-weight: 700; font-size: 14px; cursor: pointer; font-family: inherit; width: 100%; margin-top: 14px; } </style> </head> <body> <div class="app"> <div class="scroll-area" id="scrollArea"> <div class="header"> <div class="brand"> <div class="brand-icon">☪</div> Мубарака </div> <button class="info-btn" id="infoBtn">i</button> </div> <div class="tariff-card standard" id="tariffCard"> <div class="tariff-left"> <div class="tariff-dot"></div> <div class="tariff-name" id="tariffName">Стандарт</div> </div> <span class="tariff-rate-badge" id="tariffEffRate">3,0%</span> </div> <div class="content"> <div class="field"> <div class="label-row"> <label>Стоимость товара</label> <button class="limit-toggle" id="limitToggle">до 5 млн ₽</button> </div> <div class="input-box"> <input type="text" inputmode="numeric" id="price-input" value="110 000"> <span class="currency">₽</span> </div> <input type="range" id="price-slider" min="6000" max="500000" value="110000" step="1000"> <div class="limits"><span>6 000</span><span id="max-limit-label">500 000</span></div> </div> <div class="field"> <div class="label-row"><label>Срок рассрочки</label><span class="val" id="months-val">3 мес.</span></div> <input type="range" id="months-slider" min="3" max="12" value="3" step="1"> <div class="limits"><span>3</span><span>12</span></div> </div> <div class="field"> <div class="label-row"><label>Первоначальный взнос</label><span class="val" id="dp-badge">25%</span></div> <div class="input-box"> <input type="text" inputmode="numeric" id="dp-input" value="27 500"> <span class="currency">₽</span> </div> <input type="range" id="dp-slider" min="0" max="80" value="25" step="1"> <div class="limits"><span id="dp-min-lbl">0%</span><span>80%</span></div> <div class="pct-btns" id="dp-pct-btns"> <button class="pct-btn" data-pct="0">0%</button> <button class="pct-btn active" data-pct="25">25%</button> <button class="pct-btn" data-pct="50">50%</button> <button class="pct-btn" data-pct="80">80%</button> </div> <div class="info-text" id="warning">ℹ️ Минимальный взнос: 0 ₽</div> </div> </div> <div class="receipt" id="receipt"> <h3>Результат</h3> <div class="check-row bold"><span>Ежемесячный платёж</span><span class="dots"></span><span class="value" id="res-monthly">0 руб.</span></div> <div class="check-row bold" id="res-dp-row"><span>Первоначальный взнос</span><span class="dots"></span><span class="value" id="res-dp-rub">0 руб.</span></div> <div class="check-row"><span>Торговая наценка</span><span class="dots"></span><span class="value" id="res-markup">0 руб.</span></div> <div class="total-zone"><span>Итого к оплате</span><span class="total-value" id="res-total">0 ₽</span></div> <button class="share-btn" id="shareBtn">📤 Поделиться расчётом</button> <a href="https://mubarak.gitverse.site/mubarakapartn/" class="partner-banner"> <div class="pb-content"> <div class="pb-icon">🛍️</div> <div class="pb-text"> <span class="pb-title">Магазины партнёров</span> <span class="pb-sub">Выбрать товар</span> </div> </div> <div class="pb-arrow">➔</div> </a> </div> </div> </div> <div class="modal-overlay" id="infoModal"> <div class="modal-card"> <h3>📋 Тарифы Мубарака</h3> <p class="subtitle">С обязательным первым взносом 25%</p> <div class="rate-box"> <p class="range" style="color:var(--accent);">💎 6 000 – 99 999 ₽</p> <p class="value">3% в месяц</p> </div> <div class="rate-box gold"> <p class="range" style="color:var(--gold);">🌟 100 000 – 5 000 000 ₽</p> <p class="value">2,5% в месяц</p> </div> <p style="font-size:11px; color:var(--muted); margin-top:8px;">Специальные условия для наших партнёров</p> <button class="modal-close" onclick="document.getElementById('infoModal').classList.remove('active')">Понятно</button> </div> </div> <script> function formatNumber(value) { const num = value.replace(/\s/g, '').replace(/[^\d]/g, ''); if (!num) return ''; return num.replace(/\B(?=(\d{3})+(?!\d))/g, ' '); } document.addEventListener('DOMContentLoaded', () => { const limitToggle = document.getElementById('limitToggle'); const priceSlider = document.getElementById('price-slider'); const maxLimitLabel = document.getElementById('max-limit-label'); const priceInput = document.getElementById('price-input'); const dpInput = document.getElementById('dp-input'); let maxChangedProgrammatically = false; function updateSliderVisual(slider, value) { const style = getComputedStyle(document.documentElement); const fillColor = style.getPropertyValue('--range-fill').trim(); const trackColor = style.getPropertyValue('--range-track').trim(); const min = parseFloat(slider.min); const max = parseFloat(slider.max); const pct = ((value - min) / (max - min)) * 100; slider.style.background = `linear-gradient(to right, ${fillColor} 0%, ${fillColor} ${pct}%, ${trackColor} ${pct}%)`; } limitToggle.addEventListener('click', () => { if (priceSlider.max === "500000") { priceSlider.max = "5000000"; limitToggle.textContent = "до 500 тыс ₽"; maxLimitLabel.textContent = "5 000 000"; } else { priceSlider.max = "500000"; limitToggle.textContent = "до 5 млн ₽"; maxLimitLabel.textContent = "500 000"; const currentVal = parseInt(priceSlider.value); if (currentVal > 500000) { priceSlider.value = 500000; priceInput.value = "500 000"; updateSliderVisual(priceSlider, 500000); priceSlider.dispatchEvent(new Event('input')); } } updateSliderVisual(priceSlider, parseInt(priceSlider.value)); maxChangedProgrammatically = true; setTimeout(() => { maxChangedProgrammatically = false; }, 50); }); priceSlider.addEventListener('change', () => { updateSliderVisual(priceSlider, parseInt(priceSlider.value)); }); const observer = new MutationObserver(() => { if (!maxChangedProgrammatically) { updateSliderVisual(priceSlider, parseInt(priceSlider.value)); } }); observer.observe(priceSlider, { attributes: true, attributeFilter: ['max', 'value'] }); priceInput.addEventListener('input', function() { const cursor = this.selectionStart; const before = this.value.length; this.value = formatNumber(this.value); const after = this.value.length; this.setSelectionRange(cursor + (after - before), cursor + (after - before)); }); dpInput.addEventListener('input', function() { const cursor = this.selectionStart; const before = this.value.length; this.value = formatNumber(this.value); const after = this.value.length; this.setSelectionRange(cursor + (after - before), cursor + (after - before)); }); }); </script> <script src="app.js"></script> <script> if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('sw.js').catch(() => {}); }); } </script> </body> </html>