zashita-brandbook/mockup.html

3403 lines
265 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="ru"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>ЗАЩИТА — прототип (весь путь)</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Montserrat:wght@700&display=swap" rel="stylesheet" media="print" onload="this.media='all'">
<script src="https://telegram.org/js/telegram-web-app.js"></script>
<script>
(function(){
var tg = window.Telegram && window.Telegram.WebApp;
if(tg){
tg.ready();
tg.expand();
document.documentElement.classList.add('tma');
// Нативная кнопка «назад» TG
tg.BackButton.onClick(function(){
var screens = document.querySelectorAll('.screen.on');
if(screens.length && screens[0].id !== 'start'){ window.go('start'); }
});
}
})();
</script>
<link rel="stylesheet" href="tokens.css">
<style>
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:var(--font-ui);background:var(--surf);color:var(--ink);line-height:1.5}
.screen{display:none;min-height:100vh}
.screen.on{display:block}
.brand{font-family:var(--font-logo);font-weight:700;letter-spacing:2px}
.btn{border:none;border-radius:11px;padding:13px 20px;font-size:15px;font-weight:700;cursor:pointer;font-family:inherit}
.btn-p{background:var(--bg);color:#fff} .btn-p:hover{background:var(--bghv)}
.btn-o{background:#fff;color:var(--bg);border:1.5px solid var(--bg)}
.chip{font-size:11px;font-weight:700;padding:3px 9px;border-radius:20px}
.chip.d{background:var(--dngbg);color:var(--dng)} .chip.w{background:var(--warnbg);color:var(--warn)} .chip.n{background:var(--surf);color:var(--mut)} .chip.ok{background:var(--okbg);color:var(--ok)}
/* ── 1. СТАРТ ── */
#start{background:linear-gradient(150deg,#2A020D,var(--bg));color:#fff;display:none;align-items:center}
#start.on{display:flex}
.hero{max-width:1000px;margin:0 auto;padding:50px 32px;display:grid;grid-template-columns:1.2fr .8fr;grid-template-rows:auto 1fr;gap:0 40px;align-items:start}
.hero-logo{grid-column:1;grid-row:1;display:flex;align-items:center;gap:0;margin-bottom:28px}
.hero-logomark{height:34px;filter:brightness(0) invert(1);flex-shrink:0}
.hero-logo-sep{width:1.5px;height:26px;background:rgba(255,255,255,.35);margin:0 16px;flex-shrink:0}
.hero-wordmark{height:17px;filter:brightness(0) invert(1);flex-shrink:0}
.hero-body{grid-column:1;grid-row:2}
.hero .face{grid-column:2;grid-row:1/3;align-self:stretch}
.hero h1{font-size:40px;font-weight:800;letter-spacing:-1px;line-height:1.1;margin-bottom:16px}
.hero p{font-size:17px;color:rgba(255,255,255,.75);margin-bottom:28px;max-width:460px}
.hero .cta{display:flex;gap:12px;flex-wrap:wrap}
.hero .priv{margin-top:20px;font-size:12px;color:rgba(255,255,255,.5)}
.hero .face img{width:100%;height:100%;min-height:380px;object-fit:cover;object-position:center 18%;border-radius:20px;display:block;box-shadow:0 20px 50px rgba(0,0,0,.4)}
.hero .face .cap{text-align:center;font-size:13px;color:rgba(255,255,255,.7);margin-top:10px}
/* ── общий чат (Елена) ── */
.topbar{background:linear-gradient(90deg,var(--shell),var(--shell2));color:#fff;display:flex;align-items:center;gap:12px;padding:12px 22px}
.topbar .w{font-size:14px;color:#fff} .topbar .sep{width:1.5px;height:16px;background:rgba(255,255,255,.3)}
.topbar-wm{height:13px;filter:brightness(0) invert(1);vertical-align:middle;flex-shrink:0}
.topbar .ttl{font-size:13px;color:rgba(255,255,255,.8);margin-left:6px}
.back{margin-left:auto;font-size:12px;color:rgba(255,255,255,.6);cursor:pointer}
.chatwrap{max-width:660px;margin:0 auto;padding:24px 18px 120px}
.msg{display:flex;gap:11px;margin-bottom:16px;align-items:flex-start}
.av{width:40px;height:40px;border-radius:50%;overflow:hidden;flex-shrink:0;border:1.5px solid var(--line)}
.av img{width:100%;height:100%;object-fit:cover;object-position:center 16%}
.bubble{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:13px 16px;font-size:14px;max-width:80%;box-shadow:0 1px 2px rgba(0,0,0,.04)}
.bubble .nm{font-size:11px;font-weight:700;color:var(--bg);margin-bottom:4px}
.bubble b{color:var(--bg)}
.risk-mini{border-top:1px dashed var(--line);padding:8px 0 0;margin-top:8px;font-size:12.5px}
.risk-mini .rn{color:var(--bg);font-weight:600;font-size:11px}
.lock{background:var(--tint);border:1px dashed var(--bg);border-radius:10px;padding:10px 12px;margin-top:10px;font-size:12.5px;color:var(--dark)}
.forks{display:flex;gap:10px;margin:4px 0 4px 51px;flex-wrap:wrap}
.fork{background:var(--card);border:1.5px solid var(--line);border-radius:13px;padding:12px 14px;cursor:pointer;font-size:13px;font-weight:700;flex:1;min-width:180px}
.fork:hover{border-color:var(--bg);transform:translateY(-1px)} .fork .ds{font-weight:400;color:var(--mut);font-size:12px;margin-top:3px}
.actbar{position:fixed;bottom:0;left:0;right:0;background:linear-gradient(180deg,transparent,var(--surf) 30%);padding:18px;display:flex;justify-content:center}
.actbar .inner{max-width:660px;width:100%;display:flex;gap:10px}
/* ── 3. ОПЛАТА ── */
.pay{max-width:560px;margin:0 auto;padding:40px 22px}
.pay h2{font-size:24px;font-weight:800;margin-bottom:6px} .pay .s{color:var(--mut);font-size:14px;margin-bottom:24px}
.plan{background:var(--card);border:1.5px solid var(--line);border-radius:16px;padding:18px;margin-bottom:14px}
.plan.sel{border-color:var(--bg);box-shadow:0 4px 16px rgba(159,18,57,.12)}
.plan .pn{font-weight:800;font-size:16px} .plan .pp{font-weight:800;font-size:20px;color:var(--bg);float:right}
.plan .pd{font-size:13px;color:var(--mut);margin-top:4px}
.field{margin:14px 0}.field label{font-size:12px;font-weight:600;display:block;margin-bottom:5px}
.field input{width:100%;border:1.5px solid var(--line);border-radius:10px;padding:11px 13px;font-size:14px;font-family:inherit}
.pdn{font-size:11px;color:var(--mut);margin:10px 0 16px}.pdn a{color:var(--bg)}
/* ── кабинет (общий каркас) ── */
.app{display:flex;min-height:100vh;background:#f4f5f7}
/* ── Сайдбар ── */
.side{width:224px;background:#0C0608;color:#cbb;display:flex;flex-direction:column;flex-shrink:0;min-height:100vh}
.side-logo{padding:20px 20px 16px;border-bottom:1px solid rgba(255,255,255,.07)}
.side-logo img{height:16px;filter:brightness(0) invert(1)}
.side-nav{padding:10px 0;flex:1}
.side-section{font-size:10px;font-weight:700;letter-spacing:.8px;color:rgba(255,255,255,.25);padding:14px 20px 5px;text-transform:uppercase}
.side a{display:flex;align-items:center;gap:10px;padding:9px 20px;color:rgba(255,255,255,.55);font-size:13px;font-weight:500;cursor:pointer;border-left:3px solid transparent;transition:all .15s;text-decoration:none}
.side a:hover{color:#fff;background:rgba(255,255,255,.05)}
.side a.on{color:#fff;background:rgba(159,18,57,.25);border-left-color:var(--bg)}
.side a .sico{font-size:15px;width:20px;text-align:center;flex-shrink:0}
.side a .sbadge{margin-left:auto;background:var(--bg);color:#fff;font-size:10px;font-weight:700;border-radius:10px;padding:1px 6px;min-width:18px;text-align:center}
.side-new{margin:8px 12px 4px;background:var(--bg);color:#fff;border:none;border-radius:10px;padding:10px 14px;font-size:13px;font-weight:700;cursor:pointer;font-family:inherit;width:calc(100% - 24px);display:flex;align-items:center;gap:8px;transition:background .15s}
.side-new:hover{background:var(--bghv)}
.side .prof{padding:14px 16px;border-top:1px solid rgba(255,255,255,.07);display:flex;gap:10px;align-items:center}
.side .prof .pa{width:34px;height:34px;border-radius:10px;background:var(--bg);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:12px;flex-shrink:0}
.side .prof .pn{font-size:12px;color:#fff;font-weight:600}
.side .prof .pt{font-size:10px;color:rgba(255,255,255,.4);margin-top:1px}
/* ── Основная область ── */
.main{flex:1;display:flex;flex-direction:column;min-width:0;min-height:100vh}
.main-hdr{background:#fff;border-bottom:1px solid #e5e7eb;padding:0 28px;height:56px;display:flex;align-items:center;gap:16px;flex-shrink:0;position:sticky;top:0;z-index:50}
.main-hdr h2{font-size:17px;font-weight:800;margin:0;flex-shrink:0}
.main-hdr-search{flex:1;max-width:340px;position:relative}
.main-hdr-search input{width:100%;border:1.5px solid #e5e7eb;border-radius:9px;padding:7px 12px 7px 34px;font-size:13px;font-family:inherit;outline:none;background:#f9fafb;color:var(--ink);box-sizing:border-box}
.main-hdr-search input:focus{border-color:var(--bg);background:#fff}
.main-hdr-search::before{content:'🔍';position:absolute;left:10px;top:50%;transform:translateY(-50%);font-size:13px;pointer-events:none}
.main-hdr-actions{margin-left:auto;display:flex;gap:8px;align-items:center}
.main-body{padding:24px 28px;flex:1}
.main-body .crumb{font-size:12px;color:var(--mut);margin-bottom:6px}
.main-body h1{font-size:20px;font-weight:800;margin:0 0 18px}
/* ── KPI карточки ── */
.kpi-row{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:22px}
.kpi-card{background:#fff;border:1px solid #e5e7eb;border-radius:13px;padding:16px 18px;display:flex;align-items:center;gap:14px}
.kpi-card .kc-ico{width:42px;height:42px;border-radius:11px;display:flex;align-items:center;justify-content:center;font-size:20px;flex-shrink:0}
.kpi-card .kc-num{font-size:24px;font-weight:800;line-height:1}
.kpi-card .kc-lbl{font-size:12px;color:var(--mut);margin-top:2px}
.kpi-card.kpi-total .kc-ico{background:#ede9fe}
.kpi-card.kpi-work .kc-ico{background:#dbeafe}
.kpi-card.kpi-urg .kc-ico{background:#fee2e2}
.kpi-card.kpi-done .kc-ico{background:#dcfce7}
.enote{display:flex;gap:11px;align-items:center;background:var(--card);border:1px solid var(--line);border-left:3px solid var(--bg);border-radius:12px;padding:12px 14px;max-width:760px;margin:14px 0 16px}
.enote img{width:40px;height:40px;border-radius:50%;object-fit:cover;object-position:center 16%}
.enote .et{font-size:13px}
.cases{display:flex;flex-direction:column;gap:11px;max-width:760px}
.case{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:14px 16px;display:flex;align-items:center;gap:13px;cursor:pointer;box-shadow:0 1px 2px rgba(0,0,0,.04)}
.case:hover{border-color:var(--bg);transform:translateY(-1px);box-shadow:0 6px 18px rgba(0,0,0,.08)}
.case .ci{width:44px;height:44px;border-radius:11px;background:var(--tint);display:flex;align-items:center;justify-content:center;font-size:21px}
.case .cb{flex:1}.case .ct{font-weight:700;font-size:14px}.case .cs{font-size:12px;color:var(--mut);margin-top:2px}
.case .cm{display:flex;gap:6px;margin-top:6px;flex-wrap:wrap}.case .cg{color:var(--bg);font-weight:700;font-size:13px}
.tabpane{display:none}.tabpane.on{display:block}
.docrow{display:flex;align-items:center;gap:9px;font-size:13px;padding:9px 0;border-top:1px dashed var(--line);max-width:760px}
.docrow:first-of-type{border-top:none}.docrow .ver{font-size:10px;font-weight:700;color:var(--bg);background:var(--tint);border-radius:6px;padding:2px 6px;margin-left:auto}
.dlx{background:var(--card);border:1px solid var(--line);border-radius:13px;padding:12px 15px;display:flex;align-items:center;gap:13px;max-width:760px;margin-bottom:9px}
.dlx .dd{min-width:50px;height:50px;border-radius:11px;display:flex;flex-direction:column;align-items:center;justify-content:center;font-weight:800}
.dd.dd{background:var(--dngbg);color:var(--dng)}.dd.dw{background:var(--warnbg);color:var(--warn)}.dd.dn{background:var(--surf);color:var(--mut)}
.dlx .n{font-size:18px;line-height:1}.dlx .u{font-size:9px}
.tpls{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px;max-width:760px}
.tpl{background:var(--card);border:1px solid var(--line);border-radius:13px;padding:15px;cursor:pointer}.tpl:hover{border-color:var(--bg)}
.tpl .ti{font-size:22px}.tpl .tn{font-weight:700;font-size:13.5px;margin:7px 0 3px}.tpl .td{font-size:12px;color:var(--mut)}
.steps{font-size:12px;color:var(--mut);margin:24px 0;display:flex;gap:8px;flex-wrap:wrap}
.steps b{color:var(--bg)}
/* ── выбор deliverable ── */
.deliverables{display:flex;flex-direction:column;gap:9px;margin:4px 0 4px 51px;max-width:520px}
.deliv{background:var(--card);border:1.5px solid var(--line);border-radius:13px;padding:13px 16px;cursor:pointer;display:flex;align-items:flex-start;gap:12px;transition:border-color .15s,box-shadow .15s}
.deliv:hover{border-color:var(--bg);box-shadow:0 4px 14px rgba(159,18,57,.1)}
.deliv .di{font-size:20px;flex-shrink:0;margin-top:1px}
.deliv .dn{font-size:13.5px;font-weight:700}
.deliv .dd2{font-size:12.5px;color:var(--mut);margin-top:4px;line-height:1.55}
.deliv-top{border-color:rgba(159,18,57,.3);background:var(--tint)}
.deliv-top .dn{color:var(--bg)}
.deliv-badge{font-size:10px;font-weight:700;background:var(--bg);color:#fff;border-radius:6px;padding:2px 7px;margin-left:auto;flex-shrink:0}
.deliv-highlighted{border-color:var(--bg)!important;background:linear-gradient(135deg,#fff 0%,rgba(159,18,57,.06) 100%)!important;box-shadow:0 0 0 2px rgba(159,18,57,.15)!important}
.deliv-highlighted .dn{color:var(--bg)!important}
.ctype-note{display:block;font-size:13px;color:var(--mut);line-height:1.5;margin-bottom:6px;padding:8px 10px;background:var(--surf);border-radius:8px;border-left:3px solid var(--bg)}
.sample-link{display:inline-block;margin-top:7px;font-size:11px;font-weight:600;color:var(--bg);text-decoration:none;border:1px solid rgba(159,18,57,.3);border-radius:5px;padding:2px 9px;transition:background .15s}
.sample-link:hover{background:var(--tint)}
.deliv-sep{font-size:11px;color:var(--mut);text-align:center;padding:6px 0 2px;letter-spacing:.3px;display:flex;align-items:center;gap:8px}
.deliv-sep::before,.deliv-sep::after{content:'';flex:1;height:1px;background:var(--line)}
/* ── свой запрос ── */
.custom-req-row{margin:14px 0 0 51px}
.custom-req-toggle{background:none;border:1.5px dashed var(--line);border-radius:11px;padding:9px 14px;font-size:13px;color:var(--mut);cursor:pointer;font-family:inherit;transition:all .15s;width:100%;max-width:520px;text-align:left}
.custom-req-toggle:hover{border-color:var(--bg);color:var(--bg);background:var(--tint)}
.custom-req-area{margin-top:4px}
.custom-input-block{margin:0 0 12px 51px;max-width:520px}
.custom-input-block textarea{width:100%;border:1.5px solid var(--line);border-radius:11px;padding:11px 13px;font-size:14px;font-family:inherit;color:var(--ink);resize:none;background:var(--card);transition:border .15s;line-height:1.5}
.custom-input-block textarea:focus{outline:none;border-color:var(--bg)}
.custom-input-btns{display:flex;gap:8px;margin-top:8px;align-items:stretch}
.custom-voice-btn{background:var(--surf);border:1.5px solid var(--line);border-radius:11px;width:46px;height:46px;font-size:20px;cursor:pointer;flex-shrink:0;transition:all .15s;display:flex;align-items:center;justify-content:center}
.custom-voice-btn:hover{border-color:var(--bg);background:var(--tint)}
.custom-voice-btn.recording{background:#fee2e2;border-color:#ef4444;animation:crpulse 1s infinite}
@keyframes crpulse{0%,100%{box-shadow:0 0 0 0 rgba(239,68,68,.3)}50%{box-shadow:0 0 0 6px rgba(239,68,68,0)}}
/* ── план после выбора ── */
.plan-what{background:var(--surf);border-radius:12px;padding:14px 16px;margin:16px 0;max-width:600px}
.plan-what-title{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:1.2px;color:var(--mut);margin-bottom:10px}
.plan-what li{font-size:13px;color:var(--dark);padding:4px 0;list-style:none;display:flex;gap:8px;align-items:flex-start}
.plan-what li::before{content:'✓';color:var(--ok);font-weight:700;flex-shrink:0}
.plan-pitch{background:var(--tint);border:1.5px solid rgba(159,18,57,.2);border-radius:13px;padding:14px 16px;margin:20px 0;display:flex;gap:11px;align-items:flex-start;max-width:600px}
.plan-pitch img{width:38px;height:38px;border-radius:50%;object-fit:cover;object-position:center 16%;flex-shrink:0}
.plan-pitch-body{font-size:13px;line-height:1.6}
.plan-pitch-body b{color:var(--bg)}
.plan-pitch-body .pi-step{display:flex;gap:10px;margin:5px 0;align-items:flex-start;font-size:13px;line-height:1.6}
.plan-pitch-body .pi-n{background:var(--bg);color:#fff;border-radius:50%;width:20px;height:20px;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:1px}
.plan-pitch-body .pi-meta{font-size:11.5px;color:var(--mut);background:var(--surf);border-radius:7px;padding:5px 10px;margin-top:8px;line-height:1.5}
.plan-pitch-body .pi-tag{display:inline-block;font-size:10px;font-weight:700;padding:2px 7px;border-radius:8px;margin-right:5px;margin-top:2px}
.plan-pitch-body .pi-incl{background:var(--okbg);color:var(--ok)}.plan-pitch-body .pi-warn{background:var(--warnbg);color:var(--warn)}
/* ── intake-вопрос ── */
.intake{display:flex;flex-direction:column;gap:9px;margin:4px 0 4px 51px}
.intake-opt{background:var(--card);border:1.5px solid var(--line);border-radius:13px;padding:12px 16px;cursor:pointer;font-size:13.5px;font-weight:600;display:flex;align-items:center;gap:10px;transition:border-color .15s,box-shadow .15s}
.intake-opt:hover{border-color:var(--bg);box-shadow:0 4px 14px rgba(159,18,57,.1)}
.intake-opt .io{font-size:18px;pointer-events:none}
.intake-opt .id{font-weight:400;color:var(--mut);font-size:12px;margin-top:2px;pointer-events:none}
.intake-opt>div{pointer-events:none}
.intake-other{display:flex;gap:8px;margin-top:2px}
.intake-other input{flex:1;border:1.5px solid var(--line);border-radius:11px;padding:10px 13px;font-size:13.5px;font-family:inherit;outline:none}
.intake-other input:focus{border-color:var(--bg)}
/* цитата из договора */
.risk-quote{background:var(--surf);border-left:3px solid var(--bg);border-radius:0 8px 8px 0;padding:7px 10px;font-size:12px;color:var(--mut);font-style:italic;margin:6px 0 5px;line-height:1.5}
.intake-other button{background:var(--bg);color:#fff;border:none;border-radius:11px;padding:10px 16px;font-size:13px;font-weight:700;cursor:pointer;font-family:inherit}
/* режим — полоска под topbar */
.mode-badge{font-size:11px;font-weight:700;padding:4px 12px;border-radius:0 0 10px 10px;display:inline-block;margin-left:22px;letter-spacing:.5px}
.mode-novice{background:rgba(159,18,57,.1);color:var(--bg)}
.mode-mid{background:rgba(245,158,11,.12);color:#92400E}
.mode-pro{background:rgba(16,185,129,.1);color:#065F46}
/* stats dev-panel */
.stats-pill{position:fixed;bottom:70px;right:18px;background:#0C0608;color:#fff;border-radius:12px;padding:10px 14px;font-size:11px;z-index:9999;cursor:pointer;line-height:1.6;min-width:160px;box-shadow:0 6px 20px rgba(0,0,0,.25)}
.stats-pill b{color:#FECDD3}
/* ── GANTT ── */
.gantt-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;margin-top:4px;padding-bottom:16px}
.gantt{min-width:580px;font-family:var(--font-ui)}
.gantt-hdr{display:grid;grid-template-columns:170px 1fr;align-items:end;margin-bottom:6px;padding-bottom:8px;border-bottom:1.5px solid var(--line)}
.gantt-hdr-lbl{font-size:11px;font-weight:700;color:var(--mut);text-transform:uppercase;letter-spacing:.5px}
.gantt-dates{position:relative;height:22px}
.gantt-tick{position:absolute;transform:translateX(-50%);font-size:10px;color:var(--mut);font-weight:500;white-space:nowrap}
.gantt-today-hdr{position:absolute;transform:translateX(-50%);font-size:10px;font-weight:800;color:var(--bg);white-space:nowrap;top:-2px}
.gantt-row{display:grid;grid-template-columns:170px 1fr;align-items:center;margin-bottom:8px;cursor:pointer}
.gantt-row:hover .gantt-lbl{color:var(--bg)}
.gantt-lbl{padding-right:12px;overflow:hidden}
.gantt-lbl-name{font-size:13px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gantt-lbl-sub{font-size:11px;color:var(--mut);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gantt-track{position:relative;height:32px;background:var(--surf);border-radius:6px;overflow:visible}
.gantt-bar{position:absolute;height:100%;border-radius:6px;display:flex;align-items:center;padding:0 10px;font-size:11px;font-weight:700;color:#fff;white-space:nowrap;overflow:hidden;box-shadow:0 2px 8px rgba(0,0,0,.18);transition:filter .15s}
.gantt-bar:hover{filter:brightness(1.1)}
.gantt-bar.g-overdue{background:linear-gradient(90deg,#7f1d1d,#dc2626)}
.gantt-bar.g-urgent{background:linear-gradient(90deg,#9f1239,#e11d48)}
.gantt-bar.g-warn{background:linear-gradient(90deg,#92400e,#d97706)}
.gantt-bar.g-ok{background:linear-gradient(90deg,#1e3a8a,#3b82f6)}
.gantt-bar.g-done{background:linear-gradient(90deg,#14532d,#16a34a);opacity:.7}
.gantt-today-line{position:absolute;top:-4px;bottom:-4px;width:2px;background:var(--bg);border-radius:1px;z-index:10;pointer-events:none}
.gantt-today-line::after{content:'';position:absolute;top:0;left:50%;transform:translateX(-50%);width:8px;height:8px;background:var(--bg);border-radius:50%;margin-top:-3px}
.gantt-legend{display:flex;gap:14px;flex-wrap:wrap;margin-top:16px;padding-top:12px;border-top:1px solid var(--line)}
.gantt-leg-item{display:flex;align-items:center;gap:5px;font-size:11px;color:var(--mut)}
.gantt-leg-dot{width:10px;height:10px;border-radius:3px;flex-shrink:0}
/* ── GANTT ── */
(function() {
// Дата-хелперы
function d(str) { return new Date(str + 'T00:00:00'); }
function addDays(dt, n) { var r = new Date(dt); r.setDate(r.getDate()+n); return r; }
function daysBetween(a, b) { return Math.round((b-a)/86400000); }
function fmt(dt) {
var m = ['янв','фев','мар','апр','май','июн','июл','авг','сен','окт','ноя','дек'];
return dt.getDate() + ' ' + m[dt.getMonth()];
}
var CASES = [
{ ico:'🍽', name:'Кухня агентский', sub:'Протокол разногласий · ст.22 ЗоЗПП', start:'2025-05-19', end:'2025-05-26', cls:'g-urgent', go:"tab('case')" },
{ ico:'💼', name:'Трудовой договор', sub:'Допсоглашение (испыт. срок)', start:'2025-05-21', end:'2025-05-30', cls:'g-warn', go:"tab('case')" },
{ ico:'🏠', name:'ДДУ (новая редакция)',sub:'Сверка версий с застройщиком', start:'2025-05-19', end:'2025-06-05', cls:'g-ok', go:"tab('case')" },
{ ico:'📄', name:'Квартира · ДДУ', sub:'Передача квартиры · 214-ФЗ', start:'2025-05-27', end:'2025-06-22', cls:'g-ok', go:"toast('📅 Открываю дело')" },
];
function render() {
var root = document.getElementById('gantt-root');
if (!root) return;
var today = new Date(); today.setHours(0,0,0,0);
var rangeStart = d('2025-05-17');
var rangeEnd = d('2025-06-25');
var totalDays = daysBetween(rangeStart, rangeEnd);
function pct(dt) { return Math.max(0, Math.min(100, daysBetween(rangeStart, dt) / totalDays * 100)); }
// Шапка с датами
var tickDates = [];
var cur = new Date(rangeStart);
while (cur <= rangeEnd) {
tickDates.push(new Date(cur));
cur.setDate(cur.getDate() + 7);
}
var ticksHTML = tickDates.map(function(dt) {
var p = pct(dt);
return '<span class="gantt-tick" style="left:' + p.toFixed(1) + '%">' + fmt(dt) + '</span>';
}).join('');
var todayPct = pct(today);
var todayHdrHTML = '<span class="gantt-today-hdr" style="left:' + todayPct.toFixed(1) + '%">сегодня </span>';
var hdrHTML = '<div class="gantt-hdr"><div class="gantt-hdr-lbl">Договор / дело</div><div class="gantt-dates">' + ticksHTML + todayHdrHTML + '</div></div>';
// Строки
var rowsHTML = CASES.map(function(c) {
var startPct = pct(d(c.start));
var endPct = pct(d(c.end));
var width = Math.max(4, endPct - startPct);
var daysLeft = daysBetween(today, d(c.end));
var lbl = daysLeft < 0 ? ' просрочен' : daysLeft === 0 ? 'сегодня' : daysLeft + ' дн.';
var cls = c.cls;
if (daysLeft < 0) cls = 'g-overdue';
var todayLine = '<div class="gantt-today-line" style="left:' + todayPct.toFixed(1) + '%"></div>';
return '<div class="gantt-row" onclick="' + c.go + '">' +
'<div class="gantt-lbl"><div class="gantt-lbl-name">' + c.ico + ' ' + c.name + '</div><div class="gantt-lbl-sub">' + c.sub + '</div></div>' +
'<div class="gantt-track">' +
todayLine +
'<div class="gantt-bar ' + cls + '" style="left:' + startPct.toFixed(1) + '%;width:' + width.toFixed(1) + '%">' + fmt(d(c.end)) + ' · ' + lbl + '</div>' +
'</div>' +
'</div>';
}).join('');
// Легенда
var legend = '<div class="gantt-legend">' +
'<div class="gantt-leg-item"><div class="gantt-leg-dot" style="background:#dc2626"></div>Просрочен</div>' +
'<div class="gantt-leg-item"><div class="gantt-leg-dot" style="background:#e11d48"></div>Срочно (3 дня)</div>' +
'<div class="gantt-leg-item"><div class="gantt-leg-dot" style="background:#d97706"></div>Скоро (7 дней)</div>' +
'<div class="gantt-leg-item"><div class="gantt-leg-dot" style="background:#3b82f6"></div>В работе</div>' +
'<div class="gantt-leg-item"><div class="gantt-leg-dot" style="background:#16a34a;opacity:.7"></div>Завершён</div>' +
'</div>';
root.innerHTML = hdrHTML + rowsHTML + legend;
}
// Запускаем при открытии вкладки
var _origTab = window.tab;
window.tab = function(id) {
if (_origTab) _origTab(id);
if (id === 'sroki') setTimeout(render, 50);
};
window.addEventListener('DOMContentLoaded', function() {
// Если уже на вкладке sroki
var el = document.getElementById('p-sroki');
if (el && el.classList.contains('on')) render();
});
})();
/* ── ТАБЛИЦА ДОГОВОРОВ ── */
.ct-filters{display:flex;align-items:center;gap:0;margin-bottom:18px;background:#fff;border:1.5px solid #e5e7eb;border-radius:10px;padding:4px;width:fit-content}
.ct-filter-sep{width:1px;height:20px;background:#e5e7eb;margin:0 4px;flex-shrink:0}
.ct-fbtn{background:transparent;border:none;border-radius:7px;padding:6px 14px;font-size:12px;font-weight:600;cursor:pointer;color:#6b7280;font-family:inherit;transition:all .15s;white-space:nowrap}
.ct-fbtn:hover{color:var(--ink);background:#f3f4f6}
.ct-fbtn.act{background:var(--bg);color:#fff;box-shadow:0 1px 4px rgba(159,18,57,.25)}
.ct-add{margin-left:auto;background:var(--bg);color:#fff;border:none;border-radius:8px;padding:6px 14px;font-size:12px;font-weight:700;cursor:pointer;font-family:inherit}
.ct-add:hover{background:var(--bghv)}
.ct-table{width:100%;border-collapse:collapse;font-size:13px}
.ct-table thead tr{background:#f3f4f6;border-bottom:2px solid var(--line)}
.ct-table thead th{padding:8px 10px;text-align:left;font-size:11px;font-weight:700;color:var(--mut);text-transform:uppercase;letter-spacing:.4px;cursor:pointer;white-space:nowrap;user-select:none}
.ct-table thead th:hover{color:var(--bg)}
.ct-table thead th.sort-asc::after{content:' '}
.ct-table thead th.sort-desc::after{content:' '}
.ct-table tbody tr{border-bottom:1px solid var(--line);cursor:pointer;transition:background .12s}
.ct-table tbody tr:hover{background:#f8f8ff}
.ct-table tbody tr.ct-closed{opacity:.55}
.ct-table tbody td{padding:9px 10px;white-space:nowrap;vertical-align:middle}
.ct-table tbody td.ct-name{font-weight:600;max-width:220px;overflow:hidden;text-overflow:ellipsis}
.ct-table tbody td.ct-open{color:var(--bg);font-weight:700;font-size:13px;text-align:right}
.ct-type-badge{background:var(--surf);border:1px solid var(--line);border-radius:6px;padding:2px 7px;font-size:11px;color:var(--mut);font-weight:500}
/* ── MS-PROJECT GANTT ── */
.msp-section{margin-top:28px;border-top:2px solid var(--line);padding-top:16px}
.msp-title{font-size:13px;font-weight:800;color:var(--mut);text-transform:uppercase;letter-spacing:.6px;margin-bottom:12px}
.msp-outer{border:1.5px solid #d1d5db;border-radius:10px;overflow:hidden;font-size:12px;font-family:var(--font-ui)}
.msp-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.msp-table{display:grid;min-width:820px}
/* Шапка */
.msp-head{display:flex;background:#e8e8f0;border-bottom:2px solid #b0b0c8;font-weight:700;font-size:11px;color:#444}
.msp-head .msp-left{display:flex;border-right:2px solid #b0b0c8;flex-shrink:0}
.msp-head .msp-right{flex:1;position:relative;overflow:hidden}
.msp-hcol{padding:6px 8px;border-right:1px solid #c8c8d8;white-space:nowrap;color:#333}
.msp-hcol.msp-c-num{width:32px;text-align:center}
.msp-hcol.msp-c-name{width:200px}
.msp-hcol.msp-c-dur{width:56px;text-align:center}
.msp-hcol.msp-c-start{width:72px;text-align:center}
.msp-hcol.msp-c-end{width:72px;text-align:center}
/* Строки */
.msp-row{display:flex;border-bottom:1px solid #e5e7eb;cursor:pointer}
.msp-row:hover{background:#f0f0ff}
.msp-row.msp-group{background:#f3f4f8;font-weight:700}
.msp-row.msp-done .msp-cell{color:#9ca3af}
.msp-row.msp-done .msp-c-name{text-decoration:line-through;color:#9ca3af}
.msp-row.msp-group.msp-done .msp-c-name{text-decoration:none;color:#6b7280}
.msp-bar.b-done{background:linear-gradient(180deg,#16a34a,#14532d)}
.msp-bar.b-done::after{content:' ';font-size:10px}
.msp-row.msp-active-row{background:#fffbf0}
.msp-row.msp-active-row:hover{background:#fff7e0}
.msp-bar.b-active::after{content:' '}
.msp-bar.b-urgent::after{content:' '}
.msp-soa{display:flex;align-items:center;gap:8px;margin-bottom:10px;font-size:12px;color:var(--mut)}
.msp-soa-item{display:flex;align-items:center;gap:4px}
.msp-soa-dot{width:12px;height:12px;border-radius:2px;flex-shrink:0}
.msp-elena-note{display:flex;align-items:flex-start;gap:8px;background:#fffbf0;border:1px solid #fde68a;border-radius:10px;padding:10px 14px;margin-bottom:12px;font-size:12px;color:#92400e}
.msp-elena-note img{width:28px;height:28px;border-radius:50%;object-fit:cover;object-position:center 16%;flex-shrink:0}
.msp-row.msp-group:hover{background:#ebebf8}
.msp-row:last-child{border-bottom:none}
.msp-left{display:flex;border-right:2px solid #b0b0c8;flex-shrink:0}
.msp-right{flex:1;position:relative;height:28px;overflow:hidden}
.msp-cell{padding:6px 8px;border-right:1px solid #e5e7eb;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center}
.msp-cell.msp-c-num{width:32px;justify-content:center;color:#888;font-size:10px}
.msp-cell.msp-c-name{width:200px}
.msp-cell.msp-c-name.ind{padding-left:20px;font-weight:400;color:#333}
.msp-cell.msp-c-dur{width:56px;justify-content:center;color:#555}
.msp-cell.msp-c-start{width:72px;justify-content:center;color:#555;font-size:11px}
.msp-cell.msp-c-end{width:72px;justify-content:center;color:#555;font-size:11px}
/* Сетка и бары */
.msp-grid-bg{position:absolute;inset:0;display:flex}
.msp-grid-col{flex:1;border-right:1px solid #e8e8f0;height:100%}
.msp-grid-col.weekend{background:#f5f5fb}
.msp-bar-wrap{position:absolute;inset:0;pointer-events:none}
.msp-bar{position:absolute;top:5px;height:18px;border-radius:3px;display:flex;align-items:center;padding:0 6px;font-size:10px;font-weight:700;color:#fff;white-space:nowrap;overflow:hidden}
.msp-bar.b-group{background:linear-gradient(180deg,#4a4a8a,#2d2d6a);height:8px;top:10px;border-radius:1px}
.msp-bar.b-done{background:linear-gradient(180deg,#2d7a2d,#1a5c1a)}
.msp-bar.b-active{background:linear-gradient(180deg,#1a56db,#1e40af)}
.msp-bar.b-urgent{background:linear-gradient(180deg,#c81e1e,#991b1b)}
.msp-bar.b-pending{background:linear-gradient(180deg,#6b7280,#4b5563)}
.msp-today{position:absolute;top:0;bottom:0;width:2px;background:#c81e1e;z-index:5;pointer-events:none}
.msp-today::before{content:'';position:absolute;top:-1px;left:50%;transform:translateX(-50%);color:#c81e1e;font-size:9px;line-height:1}
/* Дата-шапка на сетке */
.msp-date-hdr{height:28px;position:relative;border-bottom:1px solid #c8c8d8;background:#e8e8f0}
.msp-date-tick{position:absolute;top:0;bottom:0;display:flex;align-items:center;font-size:10px;font-weight:700;color:#555;padding-left:4px;border-left:1px solid #c8c8d8;white-space:nowrap}
/* ── ELENA INTAKE v2 ── */
.intake-v2{margin:0 0 80px}
.intent-chips{display:flex;gap:10px;margin:4px 0 4px 51px;flex-wrap:wrap}
.intent-chip{background:var(--card);border:1.5px solid var(--line);border-radius:13px;padding:12px 16px;cursor:pointer;font-size:13px;font-weight:700;flex:1;min-width:160px;transition:border-color .15s,transform .1s}
.intent-chip:hover{border-color:var(--bg);transform:translateY(-1px)}
.intent-chip:active{transform:translateY(0)}
.intent-chip .ic-ico{font-size:20px;margin-bottom:4px}
.intent-chip .ic-lbl{font-weight:700;color:var(--ink)}
.intent-chip .ic-sub{font-size:11px;color:var(--mut);font-weight:400;margin-top:2px}
.voice-input-row{display:flex;gap:8px;margin:12px 0 12px 51px;align-items:center}
.voice-input-row input{flex:1;border:1.5px solid var(--line);border-radius:11px;padding:11px 14px;font-size:14px;font-family:inherit;outline:none;background:#fff;color:var(--ink)}
.voice-input-row input:focus{border-color:var(--bg)}
.voice-btn{width:44px;height:44px;border-radius:50%;border:1.5px solid var(--line);background:#fff;cursor:pointer;font-size:18px;display:flex;align-items:center;justify-content:center;transition:all .15s;flex-shrink:0}
.voice-btn:hover{border-color:var(--bg);background:var(--tint)}
.voice-btn.recording{background:#fee2e2;border-color:#ef4444;animation:voicePulse .8s ease infinite}
@keyframes voicePulse{0%,100%{box-shadow:0 0 0 0 rgba(239,68,68,.4)}50%{box-shadow:0 0 0 8px rgba(239,68,68,0)}}
.voice-btn.no-support{display:none}
.send-btn{width:44px;height:44px;border-radius:11px;border:none;background:var(--bg);color:#fff;cursor:pointer;font-size:16px;font-weight:700;flex-shrink:0}
.send-btn:hover{background:var(--bghv)}
.voice-hint{font-size:11px;color:var(--mut);margin:0 0 8px 51px}
/* Шаг составления */
.create-step{margin:8px 0 80px 0}
.create-type-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:4px 0 16px 51px}
.create-type-card{background:var(--card);border:1.5px solid var(--line);border-radius:13px;padding:14px;cursor:pointer;transition:border-color .15s}
.create-type-card:hover{border-color:var(--bg)}
.create-type-card .ctc-ico{font-size:24px;margin-bottom:6px}
.create-type-card .ctc-name{font-weight:700;font-size:13px}
.create-type-card .ctc-sub{font-size:11px;color:var(--mut);margin-top:2px}
/* ── КАРТОЧКА ДЕЛА CRM ── */
.case-hdr{background:#fff;border:1px solid #e5e7eb;border-radius:14px;padding:20px 22px;margin-bottom:20px;display:flex;align-items:flex-start;gap:18px}
.case-hdr-ico{width:52px;height:52px;border-radius:13px;background:var(--tint);display:flex;align-items:center;justify-content:center;font-size:26px;flex-shrink:0}
.case-hdr-info{flex:1;min-width:0}
.case-hdr-name{font-size:18px;font-weight:800;margin-bottom:6px;line-height:1.2}
.case-hdr-meta{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.case-hdr-actions{display:flex;gap:8px;flex-shrink:0;align-items:flex-start}
.next-step-v2{background:linear-gradient(135deg,#fff7f8,#fff);border:2px solid var(--bg);border-radius:16px;padding:20px 22px;margin-bottom:22px;display:flex;align-items:center;gap:16px;cursor:pointer;transition:box-shadow .15s}
.next-step-v2:hover{box-shadow:0 4px 20px rgba(159,18,57,.12)}
.ns2-pulse{width:48px;height:48px;border-radius:13px;background:var(--bg);display:flex;align-items:center;justify-content:center;font-size:22px;flex-shrink:0;animation:nsPulse 2s ease-in-out infinite}
@keyframes nsPulse{0%,100%{box-shadow:0 0 0 0 rgba(159,18,57,.3)}50%{box-shadow:0 0 0 8px rgba(159,18,57,0)}}
.ns2-body{flex:1;min-width:0}
.ns2-label{font-size:11px;font-weight:700;color:var(--bg);text-transform:uppercase;letter-spacing:.6px;margin-bottom:4px}
.ns2-action{font-size:16px;font-weight:800;color:var(--ink);margin-bottom:4px}
.ns2-meta{font-size:12px;color:var(--mut)}
.ns2-deadline{background:#fee2e2;color:#991b1b;border-radius:7px;padding:2px 9px;font-size:11px;font-weight:700;margin-left:8px}
.ns2-btn{background:var(--bg);color:#fff;border:none;border-radius:10px;padding:10px 18px;font-size:13px;font-weight:700;cursor:pointer;font-family:inherit;flex-shrink:0;white-space:nowrap}
.ns2-btn:hover{background:var(--bghv)}
.case-tabs{display:flex;gap:0;border-bottom:2px solid #e5e7eb;margin-bottom:20px}
.case-tab{padding:10px 18px;font-size:13px;font-weight:600;color:#6b7280;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-2px;transition:all .15s}
.case-tab:hover{color:var(--ink)}
.case-tab.on{color:var(--bg);border-bottom-color:var(--bg);font-weight:700}
.case-pane{display:none}.case-pane.on{display:block}
.overview-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:20px}
.ov-card{background:#fff;border:1px solid #e5e7eb;border-radius:12px;padding:16px 18px}
.ov-card-ttl{font-size:11px;font-weight:700;color:var(--mut);text-transform:uppercase;letter-spacing:.5px;margin-bottom:10px}
.ov-row{display:flex;justify-content:space-between;align-items:center;padding:5px 0;border-bottom:1px solid #f3f4f6;font-size:13px}
.ov-row:last-child{border-bottom:none}
.ov-row .ov-k{color:var(--mut)}
.ov-row .ov-v{font-weight:600}
/* ── ELENA INTENT v3 ── */
.elena-q{font-size:15px;font-weight:700;color:var(--ink);margin:4px 0 14px 51px;line-height:1.4}
.intent-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:0 0 12px 51px;max-width:580px}
.int-card{background:#fff;border:2px solid #e5e7eb;border-radius:14px;padding:16px 14px;cursor:pointer;transition:all .15s;display:flex;align-items:flex-start;gap:12px}
.int-card:hover{border-color:var(--bg);background:var(--tint);transform:translateY(-1px);box-shadow:0 4px 14px rgba(159,18,57,.08)}
.int-card:active{transform:none}
.int-ico{font-size:24px;flex-shrink:0;line-height:1}
.int-body{}
.int-lbl{font-size:13px;font-weight:700;color:var(--ink);margin-bottom:2px}
.int-sub{font-size:11px;color:var(--mut);line-height:1.4}
.elena-voice-row{display:flex;align-items:center;gap:10px;margin:0 0 4px 51px}
.elena-voice-input{flex:1;border:1.5px solid var(--line);border-radius:10px;padding:10px 14px;font-size:13px;font-family:inherit;outline:none;max-width:440px}
.elena-voice-input:focus{border-color:var(--bg)}
.voice-btn-sm{background:var(--bg);color:#fff;border:none;border-radius:10px;padding:10px 14px;font-size:16px;cursor:pointer;flex-shrink:0;transition:background .15s}
.voice-btn-sm:hover{background:var(--bghv)}
.voice-btn-sm.pulse{animation:vPulse 1s ease-in-out infinite}
@keyframes vPulse{0%,100%{box-shadow:0 0 0 0 rgba(159,18,57,.4)}50%{box-shadow:0 0 0 8px rgba(159,18,57,0)}}
/* Стартовый экран — усиление Елены */
.hero-elena-hint{background:rgba(255,255,255,.08);border-radius:12px;padding:12px 14px;margin:14px 0;font-size:12px;color:rgba(255,255,255,.7);line-height:1.5}
.hero-elena-hint b{color:#fff}
.hero-services{display:flex;flex-wrap:wrap;gap:6px;margin:12px 0}
.hero-svc{background:rgba(255,255,255,.12);border:1px solid rgba(255,255,255,.2);border-radius:20px;padding:5px 13px;font-size:11px;font-weight:600;color:rgba(255,255,255,.85);white-space:nowrap}
/* ── СОСТАВИТЬ ДОКУМЕНТ ── */
.create-steps{display:flex;align-items:center;gap:0;margin-bottom:28px}
.cstep{display:flex;align-items:center;gap:8px;padding:9px 16px;border-radius:10px;font-size:13px;font-weight:600;color:var(--mut);border:1.5px solid #e5e7eb;background:#fff;transition:all .2s}
.cstep.act{background:var(--bg);color:#fff;border-color:var(--bg)}
.cstep.done{background:var(--tint);color:var(--bg);border-color:var(--bg)}
.cstep-num{width:20px;height:20px;border-radius:50%;background:rgba(0,0,0,.08);display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:800}
.cstep.act .cstep-num{background:rgba(255,255,255,.25)}
.cstep.done .cstep-num{background:var(--bg);color:#fff}
.cstep-arrow{color:#d1d5db;font-size:18px;margin:0 6px;flex-shrink:0}
.create-pane{display:none}.create-pane.on{display:block}
/* Тип документа */
.doc-type-intro{font-size:14px;color:var(--mut);margin-bottom:20px;line-height:1.5}
.doc-type-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;max-width:800px;margin-bottom:24px}
.doc-type-card{background:#fff;border:2px solid #e5e7eb;border-radius:14px;padding:18px 14px;cursor:pointer;transition:all .15s;text-align:center}
.doc-type-card:hover{border-color:var(--bg);background:var(--tint);transform:translateY(-2px);box-shadow:0 4px 14px rgba(159,18,57,.1)}
.doc-type-card.sel{border-color:var(--bg);background:var(--tint);box-shadow:0 2px 10px rgba(159,18,57,.15)}
.dtc-ico{font-size:30px;margin-bottom:8px}
.dtc-name{font-size:12px;font-weight:700;color:var(--ink);line-height:1.3}
.dtc-desc{font-size:10px;color:var(--mut);margin-top:3px}
.doc-type-next{background:var(--bg);color:#fff;border:none;border-radius:11px;padding:12px 28px;font-size:14px;font-weight:700;cursor:pointer;font-family:inherit;transition:background .15s;display:none}
.doc-type-next.show{display:inline-flex;align-items:center;gap:8px}
.doc-type-next:hover{background:var(--bghv)}
/* Форма параметров */
.create-form-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px;max-width:740px;margin-bottom:20px}
.cf-group{display:flex;flex-direction:column;gap:5px}
.cf-group.wide{grid-column:1/-1}
.cf-label{font-size:11px;font-weight:700;color:var(--mut);text-transform:uppercase;letter-spacing:.4px}
.cf-input{border:1.5px solid #e5e7eb;border-radius:9px;padding:10px 13px;font-size:13px;font-family:inherit;color:var(--ink);outline:none;transition:border-color .15s;background:#fff}
.cf-input:focus{border-color:var(--bg)}
.cf-select{border:1.5px solid #e5e7eb;border-radius:9px;padding:10px 13px;font-size:13px;font-family:inherit;color:var(--ink);outline:none;background:#fff;cursor:pointer}
.cf-hint{font-size:11px;color:var(--mut);margin-top:2px;line-height:1.4}
.create-form-actions{display:flex;gap:10px;margin-top:8px;max-width:740px}
.cf-back{background:#fff;color:var(--bg);border:1.5px solid var(--bg);border-radius:11px;padding:11px 22px;font-size:13px;font-weight:700;cursor:pointer;font-family:inherit}
.cf-generate{background:var(--bg);color:#fff;border:none;border-radius:11px;padding:11px 26px;font-size:14px;font-weight:700;cursor:pointer;font-family:inherit;display:flex;align-items:center;gap:8px}
.cf-generate:hover{background:var(--bghv)}
/* Превью документа */
.doc-generating{text-align:center;padding:40px 20px;display:none}
.doc-generating.show{display:block}
.dg-spinner{width:48px;height:48px;border:4px solid var(--tint);border-top-color:var(--bg);border-radius:50%;animation:spin .8s linear infinite;margin:0 auto 16px}
@keyframes spin{to{transform:rotate(360deg)}}
.dg-text{font-size:15px;font-weight:700;color:var(--ink);margin-bottom:6px}
.dg-sub{font-size:13px;color:var(--mut)}
.doc-preview-wrap{display:none;max-width:700px}
.doc-preview-wrap.show{display:block}
.doc-preview-actions{display:flex;gap:10px;margin-bottom:16px;flex-wrap:wrap}
.dpa-btn{display:flex;align-items:center;gap:7px;border-radius:10px;padding:10px 18px;font-size:13px;font-weight:700;cursor:pointer;font-family:inherit;border:none;transition:all .15s}
.dpa-dl{background:var(--bg);color:#fff}
.dpa-dl:hover{background:var(--bghv)}
.dpa-copy{background:#fff;color:var(--bg);border:1.5px solid var(--bg)}
.dpa-add{background:#f0fdf4;color:#166534;border:1.5px solid #86efac}
.doc-preview{background:#fff;border:1px solid #e5e7eb;border-radius:14px;padding:32px 36px;font-size:13px;line-height:1.8;color:#374151;font-family:Georgia,serif}
.doc-preview h3{font-family:var(--font-ui);font-size:15px;font-weight:800;text-align:center;margin-bottom:6px;color:var(--ink)}
.doc-preview .doc-city{text-align:right;font-size:12px;color:var(--mut);margin-bottom:20px}
.doc-preview .doc-p{margin-bottom:10px}
.doc-preview .doc-article{font-weight:700;margin-top:16px;margin-bottom:6px;font-family:var(--font-ui);font-size:12px;text-transform:uppercase;letter-spacing:.5px;color:var(--bg)}
.doc-preview .doc-clause{margin-bottom:6px;padding-left:12px;border-left:2px solid #e5e7eb}
.doc-preview .doc-highlight{background:#fef9c3;border-radius:3px;padding:1px 3px}
.doc-preview .doc-blank{background:#e5e7eb;border-radius:3px;padding:1px 8px;color:var(--mut);font-style:italic}
.doc-preview .doc-parties{background:#f8f9fa;border-radius:10px;padding:14px 16px;margin-bottom:16px;font-size:12px}
.doc-preview .doc-parties b{display:block;margin-bottom:4px;font-family:var(--font-ui)}
/* ── ЧАСЫ В САЙДБАРЕ ── */
.side-clock{padding:10px 16px 6px;border-top:1px solid rgba(255,255,255,.07);margin-top:auto}
.side-clock-day{font-size:10px;font-weight:600;color:rgba(255,255,255,.45);text-transform:uppercase;letter-spacing:.5px;margin-bottom:2px}
.side-clock-date{font-size:13px;font-weight:700;color:rgba(255,255,255,.85);margin-bottom:2px}
.side-clock-time{font-size:18px;font-weight:800;color:#fff;letter-spacing:.5px;font-variant-numeric:tabular-nums}
/* ── ПАНЕЛЬ ПРОТОКОЛА ── */
.protocol-bar{display:none;align-items:center;gap:14px;background:linear-gradient(135deg,#fff7f8,#fff);border:2px solid var(--bg);border-radius:14px;padding:14px 18px;margin-bottom:18px;animation:slideIn .25s ease}
.protocol-bar.show{display:flex}
@keyframes slideIn{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
.pb-ico{font-size:22px;flex-shrink:0}
.pb-body{flex:1;min-width:0}
.pb-title{font-size:13px;font-weight:800;color:var(--ink)}
.pb-sub{font-size:11px;color:var(--mut);margin-top:1px}
.pb-btn{background:var(--bg);color:#fff;border:none;border-radius:10px;padding:10px 20px;font-size:13px;font-weight:700;cursor:pointer;font-family:inherit;white-space:nowrap;flex-shrink:0}
.pb-btn:hover{background:var(--bghv)}
/* ── ПЕРЕПИСКА ── */
.chat-compose{background:#fff;border:1.5px solid var(--line);border-radius:14px;padding:18px 20px;margin-bottom:18px;max-width:700px}
.chat-compose-ttl{font-size:13px;font-weight:700;margin-bottom:12px;color:var(--ink)}
.chat-field{margin-bottom:10px}
.chat-field label{font-size:11px;font-weight:600;color:var(--mut);text-transform:uppercase;letter-spacing:.4px;display:block;margin-bottom:4px}
.chat-field input,.chat-field textarea{width:100%;border:1px solid var(--line);border-radius:8px;padding:9px 12px;font-size:13px;font-family:inherit;color:var(--ink);resize:vertical;outline:none;transition:border-color .15s}
.chat-field input:focus,.chat-field textarea:focus{border-color:var(--bg)}
.chat-actions{display:flex;gap:8px;margin-top:4px}
.chat-send-btn{background:var(--bg);color:#fff;border:none;border-radius:9px;padding:9px 20px;font-size:13px;font-weight:700;cursor:pointer;font-family:inherit}
.chat-send-btn:hover{background:var(--bghv)}
.chat-copy-btn{background:#fff;color:var(--bg);border:1.5px solid var(--bg);border-radius:9px;padding:9px 16px;font-size:13px;font-weight:600;cursor:pointer;font-family:inherit}
.chat-list{max-width:700px}
.chat-list-ttl{font-size:11px;font-weight:700;color:var(--mut);text-transform:uppercase;letter-spacing:.4px;margin-bottom:10px}
.chat-item{display:flex;gap:12px;align-items:flex-start;padding:12px 14px;background:#fff;border:1px solid var(--line);border-radius:12px;margin-bottom:8px;cursor:pointer;transition:box-shadow .12s}
.chat-item:hover{box-shadow:0 2px 10px rgba(0,0,0,.07)}
.chat-item.out .chat-arrow{color:var(--bg);font-size:16px;flex-shrink:0;margin-top:2px}
.chat-item.inc .chat-arrow{color:#16a34a;font-size:16px;flex-shrink:0;margin-top:2px}
.chat-item-body{flex:1;min-width:0}
.chat-item-hdr{display:flex;justify-content:space-between;align-items:center;margin-bottom:3px}
.chat-item-subj{font-size:13px;font-weight:700;color:var(--ink)}
.chat-item-date{font-size:11px;color:var(--mut);flex-shrink:0;margin-left:8px}
.chat-item-prev{font-size:12px;color:var(--mut);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.chat-status{font-size:10px;font-weight:700;padding:2px 7px;border-radius:6px;flex-shrink:0}
.chat-status.sent{background:#dbeafe;color:#1d4ed8}
.chat-status.read{background:#dcfce7;color:#166534}
.chat-status.new{background:#fee2e2;color:#991b1b}
/* ── РИСКИ АККОРДЕОН ── */
.risk-item{cursor:pointer}
.risk-toggle{margin-left:auto;color:var(--mut);font-size:11px;transition:transform .2s;flex-shrink:0;padding-left:8px}
.risk-item.expanded .risk-toggle{transform:rotate(180deg)}
.risk-expand{display:none;margin-top:12px;border-top:1px solid #f3f4f6;padding-top:12px}
.risk-item.expanded .risk-expand{display:block}
.risk-quote{background:#fff5f5;border:1px solid #fecaca;border-radius:8px;padding:10px 13px;margin-bottom:8px}
.risk-quote-lbl{font-size:10px;font-weight:700;color:#991b1b;text-transform:uppercase;letter-spacing:.4px;margin-bottom:5px}
.risk-quote-txt{font-size:12px;color:#374151;font-style:italic;line-height:1.6}
.risk-fix{background:#f0fdf4;border:1px solid #86efac;border-radius:8px;padding:10px 13px;margin-bottom:10px}
.risk-fix-lbl{font-size:10px;font-weight:700;color:#166534;text-transform:uppercase;letter-spacing:.4px;margin-bottom:5px}
.risk-fix-txt{font-size:12px;color:#374151;line-height:1.6}
.risk-apply-btn{background:var(--bg);color:#fff;border:none;border-radius:8px;padding:8px 18px;font-size:12px;font-weight:700;cursor:pointer;font-family:inherit;transition:background .15s}
.risk-apply-btn:hover{background:var(--bghv)}
/* ── КАРТОЧКА ДЕЛА v2 ── */
/* Прогресс-шаги */
.case-progress{display:flex;align-items:flex-start;gap:0;margin-bottom:20px;overflow-x:auto;padding-bottom:4px}
.cp-step{display:flex;flex-direction:column;align-items:center;flex:1;min-width:90px;position:relative}
.cp-step:not(:last-child)::after{content:'';position:absolute;top:14px;left:calc(50% + 16px);right:calc(-50% + 16px);height:2px;background:#e5e7eb;z-index:0}
.cp-step.done .cp-step:not(:last-child)::after,.cp-step.act::after,.cp-step.done::after{background:var(--bg)}
.cps-dot{width:28px;height:28px;border-radius:50%;border:2px solid #e5e7eb;background:#fff;display:flex;align-items:center;justify-content:center;font-size:13px;z-index:1;position:relative;flex-shrink:0}
.cp-step.done .cps-dot{background:var(--bg);border-color:var(--bg);color:#fff}
.cp-step.act .cps-dot{background:#fff;border-color:var(--bg);box-shadow:0 0 0 3px rgba(159,18,57,.15)}
.cp-step.pend .cps-dot{background:#f9fafb;border-color:#d1d5db;color:#9ca3af}
.cps-lbl{font-size:10px;font-weight:600;margin-top:6px;text-align:center;color:var(--mut);max-width:80px;line-height:1.3}
.cp-step.done .cps-lbl{color:var(--bg)}
.cp-step.act .cps-lbl{color:var(--ink);font-weight:700}
.cps-date{font-size:9px;color:var(--mut);margin-top:2px;text-align:center}
.cp-step.act .cps-date{color:var(--bg)}
/* Риски */
.risk-summary{display:flex;gap:10px;margin-bottom:16px;flex-wrap:wrap}
.risk-sum-item{display:flex;align-items:center;gap:6px;background:#fff;border:1px solid #e5e7eb;border-radius:10px;padding:7px 14px;font-size:13px;font-weight:700}
.risk-sum-item.crit{border-color:#fecaca;background:#fff5f5;color:#991b1b}
.risk-sum-item.mid{border-color:#fde68a;background:#fffbeb;color:#92400e}
.risk-sum-item.low{border-color:#bbf7d0;background:#f0fdf4;color:#166534}
.risk-list{display:flex;flex-direction:column;gap:8px;max-width:760px}
.risk-item{background:#fff;border:1px solid #e5e7eb;border-radius:12px;padding:14px 16px;cursor:pointer;transition:box-shadow .12s}
.risk-item:hover{box-shadow:0 2px 12px rgba(0,0,0,.07)}
.risk-item.crit{border-left:4px solid #ef4444}
.risk-item.mid{border-left:4px solid #f59e0b}
.risk-item.low{border-left:4px solid #22c55e}
.risk-item-hdr{display:flex;align-items:center;gap:10px;margin-bottom:6px}
.risk-badge{font-size:10px;font-weight:700;padding:2px 8px;border-radius:6px;flex-shrink:0;white-space:nowrap}
.risk-badge.crit{background:#fee2e2;color:#991b1b}
.risk-badge.mid{background:#fef3c7;color:#92400e}
.risk-badge.low{background:#dcfce7;color:#166534}
.risk-num{font-size:11px;color:var(--mut);flex-shrink:0}
.risk-title{font-size:13px;font-weight:700;color:var(--ink);flex:1}
.risk-norm{font-size:11px;color:var(--mut);margin-bottom:6px}
.risk-rec{font-size:12px;color:var(--ink);line-height:1.5;background:#f8f9fa;border-radius:7px;padding:7px 10px}
/* Документы: upload zone */
.doc-upload-btn{display:flex;align-items:center;gap:10px;border:2px dashed #d1d5db;border-radius:12px;padding:14px 18px;margin-bottom:14px;cursor:pointer;transition:border-color .15s;max-width:700px;background:#fafafa}
.doc-upload-btn:hover{border-color:var(--bg);background:#fff7f8}
.doc-upload-ico{font-size:22px}
.doc-upload-txt{font-size:13px;font-weight:600;color:var(--mut)}
.doc-upload-txt span{display:block;font-size:11px;font-weight:400;margin-top:1px}
/* ── RETURNING CLIENT ── */
.ret-greet{font-size:30px;font-weight:800;line-height:1.2;margin-bottom:24px;letter-spacing:-.5px}
.ret-sub{font-size:16px;color:rgba(255,255,255,.7);margin-bottom:22px}
.ret-card{background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.2);border-radius:14px;padding:16px 18px;margin-bottom:22px}
.ret-card:empty{display:none}
.ret-ord-lbl{font-size:11px;font-weight:700;color:rgba(255,255,255,.45);text-transform:uppercase;letter-spacing:.6px;margin-bottom:7px}
.ret-ord-name{font-size:15px;font-weight:700;margin-bottom:3px}
.ret-ord-price{font-size:22px;font-weight:800;color:#ffaaaa}
/* ── ЮKASSA ВИДЖЕТ ── */
.yk-overlay{position:fixed;inset:0;background:rgba(0,0,0,.55);z-index:99990;display:none;align-items:flex-end;justify-content:center}
.yk-overlay.open{display:flex}
@media(min-width:520px){.yk-overlay{align-items:center}}
.yk-sheet{background:#fff;border-radius:20px 20px 0 0;width:100%;max-width:420px;padding:24px 20px 32px;position:relative;box-shadow:0 -8px 40px rgba(0,0,0,.18);animation:ykUp .25s ease}
@media(min-width:520px){.yk-sheet{border-radius:20px}}
@keyframes ykUp{from{transform:translateY(60px);opacity:0}to{transform:none;opacity:1}}
.yk-close{position:absolute;top:14px;right:16px;background:none;border:none;font-size:20px;cursor:pointer;color:#9ca3af;line-height:1}
.yk-header{display:flex;align-items:center;gap:10px;margin-bottom:20px}
.yk-logo{font-size:13px;font-weight:800;color:#0057FF;letter-spacing:-.5px}
.yk-logo span{color:#FF3D00}
.yk-amount{margin-left:auto;font-size:18px;font-weight:800;color:#111}
.yk-field{margin-bottom:14px}
.yk-field label{display:block;font-size:12px;color:#6b7280;font-weight:600;margin-bottom:5px;font-family:inherit}
.yk-field input{width:100%;border:1.5px solid #e5e7eb;border-radius:10px;padding:11px 14px;font-size:15px;font-family:inherit;outline:none;color:#111;background:#fff;box-sizing:border-box;transition:border-color .15s}
.yk-field input:focus{border-color:#0057FF}
.yk-field input.yk-error{border-color:#ef4444}
.yk-row{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.yk-sbp{display:flex;align-items:center;justify-content:center;gap:8px;border:1.5px solid #e5e7eb;border-radius:10px;padding:11px 14px;cursor:pointer;font-size:14px;font-weight:600;color:#111;margin-bottom:14px;transition:border-color .15s;font-family:inherit;background:#fff;width:100%;box-sizing:border-box}
.yk-sbp:hover{border-color:#0057FF;color:#0057FF}
.yk-sbp-icon{width:24px;height:14px;background:linear-gradient(90deg,#1D63D8 33%,#fff 33% 66%,#ED1C24 66%);border-radius:3px;font-size:9px;display:flex;align-items:center;justify-content:center;color:#fff;font-weight:900;letter-spacing:-.5px}
.yk-sep{display:flex;align-items:center;gap:8px;color:#9ca3af;font-size:12px;margin:12px 0}
.yk-sep::before,.yk-sep::after{content:'';flex:1;height:1px;background:#e5e7eb}
.yk-pay-btn{width:100%;background:#0057FF;color:#fff;border:none;border-radius:12px;padding:15px;font-size:16px;font-weight:800;cursor:pointer;font-family:inherit;margin-top:4px;transition:background .15s}
.yk-pay-btn:hover{background:#0046CC}
.yk-pay-btn:disabled{background:#9ca3af;cursor:default}
.yk-footer{text-align:center;font-size:11px;color:#9ca3af;margin-top:12px}
.yk-footer a{color:#9ca3af}
.yk-spinner{display:none;width:20px;height:20px;border:3px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:ykSpin .7s linear infinite;margin:0 auto}
@keyframes ykSpin{to{transform:rotate(360deg)}}
.yk-success{display:none;text-align:center;padding:20px 0 8px}
.yk-success .yk-check{font-size:48px;margin-bottom:12px}
.yk-success .yk-sttl{font-size:18px;font-weight:800;color:#111;margin-bottom:6px}
.yk-success .yk-ssub{font-size:13px;color:#6b7280}
/* ── ЭКРАН СТАТУСА ЗАКАЗА ── */
.os-wrap{max-width:560px;margin:0 auto;padding:24px 20px 60px}
.os-ok{text-align:center;margin:8px 0 20px}
.os-ok-icon{font-size:44px;margin-bottom:8px}
.os-ok-ttl{font-size:20px;font-weight:800;color:var(--bg)}
.os-ok-sub{font-size:13px;color:var(--mut);margin-top:4px}
.os-card{background:var(--card);border:1.5px solid var(--line);border-radius:14px;padding:16px 18px;margin-bottom:20px}
.os-card .oc-ttl{font-size:16px;font-weight:800;margin-bottom:4px}
.os-card .oc-plan{font-size:13px;color:var(--mut);margin-bottom:10px}
.os-card .oc-price{font-size:22px;font-weight:800;color:var(--bg)}
.os-card .oc-id{font-size:11px;color:var(--mut);margin-top:4px;letter-spacing:.3px}
.os-steps{display:flex;align-items:flex-start;gap:0;margin:0 0 20px;position:relative}
.os-steps::before{content:'';position:absolute;top:13px;left:13px;right:13px;height:2px;background:var(--line);z-index:0}
.os-step{flex:1;display:flex;flex-direction:column;align-items:center;gap:6px;position:relative;z-index:1}
.os-dot{width:26px;height:26px;border-radius:50%;border:2.5px solid var(--line);background:var(--surf);display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;color:var(--mut);flex-shrink:0}
.os-step.done .os-dot{background:var(--ok);border-color:var(--ok);color:#fff;font-size:13px}
.os-step.active .os-dot{background:var(--bg);border-color:var(--bg);color:#fff;font-size:13px}
.os-step-lbl{font-size:11px;color:var(--mut);text-align:center;line-height:1.35;max-width:80px}
.os-step.done .os-step-lbl{color:var(--ok);font-weight:600}
.os-step.active .os-step-lbl{color:var(--bg);font-weight:700}
.os-deadline{background:var(--tint);border:1.5px solid rgba(159,18,57,.2);border-radius:10px;padding:10px 14px;font-size:13px;margin:0 0 16px;display:flex;align-items:center;gap:8px}
.os-deadline .od-icon{font-size:16px}
.os-deadline .od-text strong{display:block;font-weight:700;color:var(--bg);font-size:13px}
.os-deadline .od-text span{font-size:12px;color:var(--mut)}
.os-actions{display:flex;gap:10px;flex-wrap:wrap}
.os-tg{display:flex;align-items:center;gap:8px;background:var(--card);border:1.5px solid var(--line);border-radius:10px;padding:10px 16px;font-size:13px;font-weight:700;cursor:pointer;color:var(--ink);text-decoration:none;font-family:inherit}
.os-tg:hover{border-color:var(--bg);color:var(--bg)}
/* ── АНАЛИТИКА CUSTOM-ЗАПРОСОВ ── */
#custom-admin{background:var(--surf)}
.ca-wrap{max-width:780px;margin:0 auto;padding:28px 20px 60px}
.ca-title{font-size:20px;font-weight:800;margin-bottom:4px}
.ca-sub{font-size:13px;color:var(--mut);margin-bottom:24px}
.ca-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:24px}
.ca-stat{background:var(--card);border:1px solid var(--line);border-radius:13px;padding:14px 16px}
.ca-stat .sv{font-size:26px;font-weight:800;color:var(--bg)}
.ca-stat .sl{font-size:11px;color:var(--mut);margin-top:2px;text-transform:uppercase;letter-spacing:.5px}
.ca-section{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:1.5px;color:var(--mut);margin:20px 0 10px}
.ca-words{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:24px}
.ca-word{background:var(--card);border:1.5px solid var(--line);border-radius:20px;padding:5px 12px;font-size:13px;font-weight:600;display:flex;align-items:center;gap:6px;cursor:default}
.ca-word .wc{background:var(--bg);color:#fff;border-radius:10px;font-size:10px;padding:1px 6px;font-weight:700}
.ca-word.w-top{border-color:rgba(159,18,57,.4);background:var(--tint)}
.ca-card{background:var(--card);border:1px solid var(--line);border-radius:13px;padding:14px 16px;margin-bottom:10px}
.ca-card.ca-done{opacity:.5;border-style:dashed}
.ca-card .cc-head{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.ca-card .cc-ctype{font-size:11px;font-weight:700;background:var(--tint);color:var(--bg);padding:2px 8px;border-radius:8px}
.ca-card .cc-ts{font-size:11px;color:var(--mut);margin-left:auto}
.ca-card .cc-text{font-size:13.5px;line-height:1.6;color:var(--ink);margin-bottom:10px}
.ca-card .cc-actions{display:flex;gap:8px}
.ca-card .cc-add{background:var(--bg);color:#fff;border:none;border-radius:8px;padding:6px 14px;font-size:12px;font-weight:700;cursor:pointer;font-family:inherit}
.ca-card .cc-add:disabled{background:var(--ok);cursor:default}
.ca-card .cc-copy{background:none;border:1.5px solid var(--line);border-radius:8px;padding:6px 12px;font-size:12px;cursor:pointer;font-family:inherit;color:var(--mut)}
.ca-card .cc-copy:hover{border-color:var(--bg);color:var(--bg)}
.ca-export{display:flex;gap:10px;margin-top:20px;flex-wrap:wrap}
.ca-export button{background:var(--card);border:1.5px solid var(--line);border-radius:10px;padding:10px 18px;font-size:13px;font-weight:700;cursor:pointer;font-family:inherit;color:var(--ink)}
.ca-export button:hover{border-color:var(--bg);color:var(--bg)}
.ca-empty{text-align:center;padding:60px 20px;color:var(--mut);font-size:14px}
.ca-empty .ce-icon{font-size:40px;margin-bottom:12px}
@media(max-width:600px){.ca-stats{grid-template-columns:1fr 1fr}.ca-stat:last-child{grid-column:1/-1}}
/* тост-подтверждение действий без отдельного экрана */
.toast{position:fixed;left:50%;bottom:28px;transform:translateX(-50%) translateY(20px);background:#0C0608;color:#fff;padding:13px 20px;border-radius:13px;font-size:13.5px;font-weight:600;box-shadow:0 10px 30px rgba(0,0,0,.3);opacity:0;pointer-events:none;transition:all .25s;z-index:999;max-width:min(90vw,520px);display:flex;align-items:center;gap:9px}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
.toast .tk{color:#FECDD3}
.docrow{cursor:pointer}.docrow:hover{color:var(--bg)}
/* ── дедлайн-виджет / следующий шаг ── */
.next-step{background:var(--tint);border:1.5px solid rgba(159,18,57,.25);border-radius:13px;padding:13px 16px;display:flex;align-items:center;gap:13px;max-width:760px;margin:14px 0 16px;cursor:pointer}
.next-step:hover{border-color:var(--bg);box-shadow:0 4px 14px rgba(159,18,57,.12)}
.ns-icon{font-size:22px;flex-shrink:0}
.ns-body{flex:1}
.ns-title{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:1.2px;color:var(--bg);margin-bottom:2px}
.ns-text{font-size:13.5px;font-weight:600;color:var(--dark)}
.ns-sub{font-size:12px;color:var(--mut);margin-top:1px}
.ns-btn{background:var(--bg);color:#fff;border:none;border-radius:9px;padding:9px 16px;font-size:13px;font-weight:700;cursor:pointer;flex-shrink:0;font-family:inherit}
.ns-btn:hover{background:var(--bghv)}
/* ── таймлайн дела ── */
.tl-section{max-width:760px;margin:22px 0 0}
.tl-label{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:1.2px;color:var(--mut);margin-bottom:14px}
.tl{display:flex;flex-direction:column;gap:0;position:relative;padding-left:22px}
.tl::before{content:'';position:absolute;left:7px;top:6px;bottom:6px;width:2px;background:var(--line)}
.tl-item{position:relative;padding:0 0 18px 18px}
.tl-item:last-child{padding-bottom:0}
.tl-dot{position:absolute;left:-8px;top:5px;width:14px;height:14px;border-radius:50%;background:var(--line);border:2px solid #fff;z-index:1;box-sizing:border-box}
.tl-item.done .tl-dot{background:var(--ok);border-color:#fff}
.tl-item.active .tl-dot{background:var(--bg);border-color:#fff;box-shadow:0 0 0 3px rgba(159,18,57,.18)}
.tl-item.pending .tl-dot{background:#fff;border:2px solid var(--line)}
.tl-date{font-size:11px;color:var(--mut);font-weight:600;margin-bottom:1px}
.tl-title{font-size:13px;font-weight:700;color:var(--dark)}
.tl-item.active .tl-title{color:var(--bg)}
.tl-item.pending .tl-title{color:var(--mut)}
.tl-ev{font-size:12px;color:var(--mut);margin-top:2px}
/* ── RESPONSIVE · MOBILE / TELEGRAM MINIAPP ── */
@media (max-width:600px){
/* HERO — мобиль: лого → фото → текст */
.hero{grid-template-columns:1fr;grid-template-rows:auto auto auto;padding:0 0 32px;gap:0;align-items:start}
.hero-logo{grid-column:1;grid-row:1;padding:20px 18px 0;margin-bottom:0}
.hero .face{grid-column:1;grid-row:2;margin:14px 0 0}
.hero-body{grid-column:1;grid-row:3;padding:20px 18px 0}
.hero .face img{height:240px;min-height:unset;border-radius:0;object-position:center 12%}
.hero .face .cap{padding:0 18px;color:rgba(255,255,255,.6)}
.hero h1{font-size:26px;letter-spacing:-.5px}
.hero p{font-size:14px;margin-bottom:20px}
.hero .cta{flex-direction:column}
.hero .cta .btn{width:100%;text-align:center}
/* TOPBAR */
.topbar{padding:10px 14px}
.topbar .ttl{font-size:12px;max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.topbar a{font-size:12px}
/* CHAT — убираем левый отступ под аватар на мобиле */
.chatwrap{padding:14px 12px 100px}
.intake{margin:4px 0 4px 0}
.deliverables{margin:4px 0 4px 0;max-width:100%}
.mode-badge{margin-left:0}
/* TOUCH TARGETS ≥ 48px */
.intake-opt{padding:14px 14px;min-height:52px}
.deliv{padding:14px 14px;min-height:56px}
.btn{min-height:48px}
/* ACTBAR — кнопки в колонку */
.actbar .inner{flex-direction:column;gap:8px}
.actbar .inner .btn{width:100%;text-align:center}
/* NEXT-STEP WIDGET — стек на мобиле */
.next-step{flex-wrap:wrap;gap:10px}
.ns-btn{width:100%;text-align:center}
.ns-body{min-width:0;width:100%}
/* PAY */
.pay{padding:20px 14px}
.pay h2{font-size:20px}
.plan-what{padding:12px 13px}
.plan-pitch{padding:12px 13px;flex-direction:row;align-items:flex-start}
/* STAT PILL — не перекрывает actbar */
.stats-pill{bottom:100px;right:10px;font-size:10px;min-width:140px}
/* ДОКУМЕНТЫ / КЕЙСЫ */
.tab-content{padding:14px 0}
/* КАБИНЕТ — мобиль: сайдбар скрыть, контент на всю ширину */
.app{flex-direction:column}
.side{width:100%;flex-direction:row;flex-wrap:wrap;padding:8px 0 0;gap:0;min-height:unset}
.side .lg{display:none}
.side .prof{display:none}
.side a{padding:8px 12px;font-size:12px;flex-direction:column;gap:2px;border-left:none;border-bottom:2px solid transparent;text-align:center;flex:1}
.side a.on{background:rgba(159,18,57,.2);border-left:none;border-bottom-color:var(--bg)}
.main{padding:16px 14px}
}
/* ── TELEGRAM MINIAPP ── */
/* Класс .tma навешивается JS-слоем ниже если запущен внутри TG */
.tma .actbar{padding-bottom:calc(16px + env(safe-area-inset-bottom,0px))}
.tma .topbar a.back-link{display:none} /* кнопка «назад» — нативная TG BackButton */
/* ── UPLOAD STEP ── */
.upload-zone{border:2px dashed rgba(159,18,57,.25);border-radius:16px;padding:28px 20px;text-align:center;background:var(--card);cursor:pointer;transition:border-color .2s,background .2s;margin:12px 0}
.upload-zone:hover{border-color:var(--bg);background:var(--tint)}
.uz-icon{font-size:32px;margin-bottom:10px}
.uz-title{font-size:15px;font-weight:700;color:var(--dark);margin-bottom:4px}
.uz-sub{font-size:12px;color:var(--mut)}
.upload-paste{width:100%;border:1.5px solid var(--line);border-radius:12px;padding:14px 16px;font-family:inherit;font-size:14px;color:var(--ink);background:var(--card);resize:vertical;min-height:90px;margin:8px 0;display:block}
.upload-paste:focus{outline:none;border-color:var(--bg)}
.upload-or{display:flex;align-items:center;gap:12px;color:var(--mut);font-size:12px;margin:4px 0}
.upload-or::before,.upload-or::after{content:'';flex:1;height:1px;background:var(--line)}
.upload-box{max-width:560px;margin:0 auto;padding:0 0 24px}
/* ── SCAN ANIMATION ── */
.scan-wrap{display:flex;flex-direction:column;align-items:center;padding:48px 24px 56px;text-align:center}
.scan-doc-outer{position:relative;width:170px;height:220px;margin:0 auto 32px}
.scan-doc-card{width:170px;height:220px;background:var(--card);border:1.5px solid var(--line);border-radius:14px;overflow:hidden;position:relative;box-shadow:0 12px 40px rgba(0,0,0,.12)}
.scan-doc-card::before{content:'';position:absolute;left:22px;right:22px;top:22px;height:7px;background:var(--line);border-radius:4px;
box-shadow:0 16px 0 var(--line),0 29px 0 var(--line),0 42px 0 var(--line),0 55px 0 rgba(159,18,57,.15),0 68px 0 var(--line),0 81px 0 var(--line),0 94px 0 var(--line),0 107px 0 rgba(159,18,57,.1),0 120px 0 var(--line),0 133px 0 rgba(159,18,57,.08)}
.scan-beam{position:absolute;left:0;right:0;height:3px;background:linear-gradient(90deg,transparent 0%,rgba(159,18,57,.2) 10%,var(--bg) 50%,rgba(159,18,57,.2) 90%,transparent 100%);box-shadow:0 0 14px 5px rgba(159,18,57,.28);animation:beamDown 2s ease-in-out infinite;z-index:2}
@keyframes beamDown{0%{top:-3px;opacity:0}6%{opacity:1}94%{opacity:1}100%{top:223px;opacity:0}}
.scan-av{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:68px;height:68px;border-radius:50%;border:4px solid #fff;object-fit:cover;object-position:center 12%;box-shadow:0 4px 16px rgba(0,0,0,.18);z-index:3;animation:avPulse 2.2s ease-in-out infinite}
@keyframes avPulse{0%,100%{box-shadow:0 4px 16px rgba(0,0,0,.18),0 0 0 0 rgba(159,18,57,.4)}60%{box-shadow:0 4px 16px rgba(0,0,0,.18),0 0 0 10px rgba(159,18,57,0)}}
.scan-label{font-size:18px;font-weight:700;color:var(--dark);min-height:28px;margin-bottom:7px;transition:opacity .25s}
.scan-hint{font-size:13px;color:var(--mut);margin-bottom:20px}
.scan-dots{display:flex;gap:8px;justify-content:center}
.scan-dot{width:7px;height:7px;border-radius:50%;background:var(--bg);opacity:.3;animation:dotB 1.4s ease-in-out infinite}
.scan-dot:nth-child(2){animation-delay:.22s}.scan-dot:nth-child(3){animation-delay:.44s}
@keyframes dotB{0%,100%{opacity:.25;transform:scale(1)}50%{opacity:1;transform:scale(1.35)}}
</style></head>
<body>
<!-- ═ 1. СТАРТ / ОФФЕР ═ -->
<section class="screen on" id="start">
<div class="hero">
<div class="hero-logo">
<img class="hero-logomark" src="logos/logo-wasrusgen1-real.svg" alt="@wasrusgen1">
<div class="hero-logo-sep"></div>
<img class="hero-wordmark" src="logos/logo-zashita-word.svg" alt="ЗАЩИТА">
</div>
<div class="hero-body">
<!-- Новый клиент -->
<div id="hero-new">
<h1>Договор пишут юристы другой стороны. Кто защищает вас?</h1>
<p>Елена — ваш персональный юридический ИИ. Работает 24/7, без почасовой оплаты.</p>
<div class="hero-services">
<span class="hero-svc">📄 Проверить договор</span>
<span class="hero-svc">✍️ Составить документ</span>
<span class="hero-svc">📋 Протокол разногласий</span>
<span class="hero-svc">📑 Доверенность</span>
<span class="hero-svc">✉️ Претензия</span>
</div>
<div class="hero-elena-hint">
<b>Как это работает:</b> нажмите кнопку → Елена спросит что вам нужно → вы загружаете документ или заполняете форму → результат за 2 минуты
</div>
<div class="cta"><button class="btn btn-p" onclick="go('elena')">Начать с Еленой →</button></div>
<div class="priv">🔒 Без регистрации · данные у вас · первые 3 риска бесплатно</div>
<div style="margin-top:12px"><button class="btn btn-o" style="font-size:13px;padding:8px 18px" onclick="go('cabinet')">📂 Войти в кабинет</button></div>
</div>
<!-- Вернувшийся клиент -->
<div id="hero-returning" style="display:none">
<div class="ret-greet">Добро пожаловать обратно —<br>вы в надёжных руках 🤝</div>
<div class="ret-card" id="ret-last-order"></div>
<div class="cta">
<button class="btn btn-p" style="min-width:160px" onclick="go('cabinet')">Мои дела →</button>
<button class="btn btn-o" style="font-size:14px" onclick="go('elena')">+ Новый договор</button>
</div>
<div class="priv" style="margin-top:16px">🔒 Данные только у вас</div>
</div>
</div>
<div class="face"><img src="logos/elena-photo.jpg" alt="Елена"><div class="cap">Елена — ваш референт</div></div>
</div>
</section>
<!-- ═ 2. ЕЛЕНА / ТИЗЕР ═ -->
<section class="screen" id="elena">
<div class="topbar"><img class="topbar-wm" src="logos/logo-zashita-word.svg" alt="ЗАЩИТА"><span class="sep"></span><span class="ttl" id="elena-ttl">Знакомство · Елена</span><span class="back back-link" onclick="go('start')">← в начало</span></div>
<div id="elena-mode-badge"></div>
<div class="chatwrap">
<!-- ШАГ 1: Чем могу помочь? — намерение клиента -->
<div id="el-step1">
<div class="msg"><div class="av"><img src="logos/elena-photo.jpg"></div><div class="bubble"><div class="nm">Елена</div>Здравствуйте 💛 Я Елена — ваш персональный юридический ассистент. Проверяю договоры, составляю документы, защищаю ваши интересы. Что вам нужно прямо сейчас?</div></div>
<div class="elena-q">Чем могу помочь?</div>
<div class="intent-grid">
<div class="int-card" onclick="elenaIntent('check')">
<div class="int-ico">📄</div>
<div class="int-body"><div class="int-lbl">Проверить договор</div><div class="int-sub">Найду риски и объясню каждый пункт простым языком</div></div>
</div>
<div class="int-card" onclick="elenaIntent('create')">
<div class="int-ico">✍️</div>
<div class="int-body"><div class="int-lbl">Составить документ</div><div class="int-sub">Договор, доверенность, претензию — под ваши параметры</div></div>
</div>
<div class="int-card" onclick="elenaIntent('dispute')">
<div class="int-ico">📋</div>
<div class="int-body"><div class="int-lbl">Убрать невыгодные пункты</div><div class="int-sub">Подготовлю протокол разногласий — загрузите договор</div></div>
</div>
<div class="int-card" onclick="elenaIntent('question')">
<div class="int-ico">💬</div>
<div class="int-body"><div class="int-lbl">Есть вопрос</div><div class="int-sub">Отвечу без загрузки документа — спросите текстом или голосом</div></div>
</div>
<div class="int-card" onclick="elenaIntent('power')">
<div class="int-ico">📑</div>
<div class="int-body"><div class="int-lbl">Нужна доверенность</div><div class="int-sub">Скажите кому и какие полномочия — составлю за 2 минуты</div></div>
</div>
<div class="int-card" onclick="elenaIntent('cabinet')">
<div class="int-ico">🗂️</div>
<div class="int-body"><div class="int-lbl">Я уже клиент</div><div class="int-sub">Войти в кабинет и посмотреть мои дела</div></div>
</div>
</div>
<div class="elena-voice-row">
<input class="elena-voice-input" id="intake-custom" placeholder="Или напишите своими словами..." onkeydown="if(event.key==='Enter')elenaIntent('custom')">
<button class="voice-btn-sm" id="voice-btn-elena" onclick="toggleVoice('intake-custom')" title="Голосовой ввод">🎙</button>
</div>
</div>
<!-- ШАГ 1б: загрузка договора -->
<div id="el-step-upload" style="display:none">
<div class="msg"><div class="av"><img src="logos/elena-photo.jpg"></div><div class="bubble"><div class="nm">Елена</div><span id="el-ack"></span></div></div>
<div class="msg"><div class="av"><img src="logos/elena-photo.jpg"></div><div class="bubble"><div class="nm">Елена</div>
Отлично. Загрузите договор или вставьте текст — посмотрю и сразу скажу с чем имеем дело 📄
</div></div>
<div class="upload-box">
<div class="upload-zone" onclick="document.getElementById('el-paste').focus()">
<div class="uz-icon">📂</div>
<div class="uz-title">Перетащите файл сюда</div>
<div class="uz-sub">PDF · DOCX · TXT · данные остаются на вашем устройстве 🔒</div>
</div>
<div class="upload-or">или вставьте текст</div>
<textarea class="upload-paste" id="el-paste" placeholder="Вставьте текст договора..."></textarea>
<button class="btn btn-p" style="width:100%;margin-top:4px" onclick="startScan()">Проанализировать →</button>
</div>
</div>
<!-- ШАГ 1в: анимация сканирования -->
<div id="el-step-scan" style="display:none">
<div class="scan-wrap">
<div class="scan-doc-outer">
<div class="scan-doc-card"><div class="scan-beam"></div></div>
<img class="scan-av" src="logos/elena-photo.jpg" alt="Елена">
</div>
<div class="scan-label" id="scan-label">Читаю договор...</div>
<div class="scan-hint">Ищу риски и спорные условия</div>
<div class="scan-dots">
<div class="scan-dot"></div><div class="scan-dot"></div><div class="scan-dot"></div>
</div>
</div>
</div>
<!-- ШАГ 2: результаты анализа (скрыт до сканирования) -->
<div id="el-step2" style="display:none">
<div class="msg"><div class="av"><img src="logos/elena-photo.jpg"></div><div class="bubble"><div class="nm">Елена</div>
Прочитала ваш договор 📄 Это <b id="el-scan-type">агентский договор</b>.<br>
<span id="el-ctype-note" class="ctype-note"></span>
Нашла <b>12 моментов</b>, из них <b>5 критичных</b>. <span id="el-intro-tail"></span> Показываю 3:
<div class="risk-mini">
<div class="rn">п.1.1 · ст. 429 ЗоЗПП</div>
<div id="r1-quote" class="risk-quote"></div>
<span id="r1-text"></span>
</div>
<div class="risk-mini">
<div class="rn">п.4.6 · ст. 330 ГК</div>
<div id="r2-quote" class="risk-quote"></div>
<span id="r2-text"></span>
</div>
<div class="risk-mini">
<div class="rn">ст. 19.1 ТК</div>
<div id="r3-quote" class="risk-quote"></div>
<span id="r3-text"></span>
</div>
<div class="lock" id="el-lock"></div>
</div></div>
<div id="el-pitch-msg" class="msg" style="display:none"><div class="av"><img src="logos/elena-photo.jpg"></div><div class="bubble"><div class="nm">Елена</div><span id="el-ctype-pitch"></span></div></div>
<span id="el-fork-q" style="display:none"></span>
<div class="deliverables">
<div id="deliv-protocol" class="deliv" onclick="selectDeliv('protocol')">
<span class="di">📋</span>
<div><div class="dn">Протокол разногласий</div><div class="dd2" id="dd2-protocol">Список спорных пунктов + зачем менять каждый</div><a class="sample-link" href="sample-protocol.html" target="_blank" onclick="event.stopPropagation()">📄 Образец →</a></div>
</div>
<div id="deliv-redact" class="deliv" onclick="selectDeliv('redact')">
<span class="di">✏️</span>
<div><div class="dn">Переработка с комментариями</div><div class="dd2" id="dd2-redact">Новая редакция каждого пункта + пояснение изменений</div><a class="sample-link" href="sample-redact.html" target="_blank" onclick="event.stopPropagation()">📄 Образец →</a></div>
</div>
<div id="deliv-clean" class="deliv" onclick="selectDeliv('clean')">
<span class="di"></span>
<div><div class="dn">Чистая редакция</div><div class="dd2" id="dd2-clean">Договор готов к подписанию — без лишних пояснений</div><a class="sample-link" href="sample-clean.html" target="_blank" onclick="event.stopPropagation()">📄 Образец →</a></div>
</div>
<div id="deliv-partner" class="deliv deliv-top" onclick="selectDeliv('partner')">
<span class="di">🤝</span>
<div><div class="dn">Партнёрская редакция</div><div class="dd2" id="dd2-partner">Вариант, который устроит обе стороны — без конфликта</div><a class="sample-link" href="sample-partner.html" target="_blank" onclick="event.stopPropagation()">📄 Образец →</a></div>
<span class="deliv-badge" id="deliv-rec-badge">Рекомендуем</span>
</div>
</div>
<div class="deliv-sep">или другой формат</div>
<div id="deliv-consult" class="deliv" onclick="selectDeliv('consult')">
<span class="di">💬</span>
<div><div class="dn">Консультация по договору</div><div class="dd2" id="dd2-consult">Задаёте вопросы — AI разбирает ваш договор и отвечает по вашей ситуации. Быстро, конкретно, без лишнего</div><span class="sample-link" style="cursor:default;border-color:transparent;color:var(--mut)">💬 чат · ответ за 2 часа</span></div>
</div>
<div id="deliv-reply" class="deliv" onclick="selectDeliv('reply')">
<span class="di">📨</span>
<div><div class="dn">Ответ контрагенту</div><div class="dd2" id="dd2-reply">Готовый текст ответа на отказ или встречные возражения — с аргументами и правовой позицией</div></div>
</div>
<!-- ── СВОЙ ЗАПРОС ── -->
<div class="custom-req-row">
<button class="custom-req-toggle" id="custom-req-btn" onclick="toggleCustomReq()">✏️ Нужен другой формат? Опишите задачу →</button>
</div>
<div id="custom-req-area" class="custom-req-area" style="display:none">
<div class="msg" style="margin-top:10px">
<div class="av"><img src="logos/elena-photo.jpg"></div>
<div class="bubble"><div class="nm">Елена</div>Опишите что нужно — голосом или текстом. Я передам юристу и мы свяжемся с вами в течение 24 часов.</div>
</div>
<div class="custom-input-block">
<textarea id="custom-text" placeholder="Например: мне нужна только таблица рисков без переработки текста, или нужен разбор одного конкретного пункта…" rows="3"></textarea>
<div class="custom-input-btns">
<button class="custom-voice-btn" id="custom-voice-btn" onclick="toggleVoice()" title="Диктовать голосом">🎤</button>
<button class="btn btn-p" onclick="submitCustomReq()" style="flex:1;font-size:14px">Отправить запрос</button>
</div>
</div>
<div id="custom-confirm" class="msg" style="display:none">
<div class="av"><img src="logos/elena-photo.jpg"></div>
<div class="bubble"><div class="nm">Елена</div><span id="custom-confirm-text"></span></div>
</div>
</div>
</div>
</div>
<div class="actbar" id="el-actbar" style="display:none"><div class="inner"><button class="btn btn-p" style="flex:1" onclick="go('pay')">Получить полный разбор</button></div></div>
</section>
<!-- ═ 3. ОПЛАТА ═ -->
<section class="screen" id="pay">
<div class="topbar"><img class="topbar-wm" src="logos/logo-zashita-word.svg" alt="ЗАЩИТА"><span class="ttl" id="pay-ttl">Выбор варианта</span><span class="back back-link" onclick="go('elena')">← назад</span></div>
<div class="pay">
<h2 id="pay-h2">Что сделаем по вашему договору</h2>
<div class="s" id="pay-sub">Агентский договор · риск 4/5 · 12 пунктов · цена под ваш случай</div>
<!-- Что конкретно делаем -->
<div class="plan-what">
<div class="plan-what-title">Что войдёт в работу по вашему договору</div>
<ul id="pay-what-list">
<li>п.1.1 — снять личную ответственность перед потребителем (ст. 429 ЗоЗПП)</li>
<li>п.4.6 — установить потолок ответственности = сумма вознаграждения</li>
<li>п.п. о режиме работы — переформулировать признаки самостоятельности (ст. 19.1 ТК)</li>
<li>+ ещё 9 пунктов из полного заключения</li>
</ul>
</div>
<!-- 3 плана -->
<div id="pay-plan-1" class="plan" onclick="selectPlan(1)">
<span class="pp" id="p1-price">1 490 ₽</span>
<div class="pn" id="p1-name">Без комментариев</div>
<div class="pd" id="p1-desc">Все спорные пункты — готовый список изменений без пояснений</div>
</div>
<div id="pay-plan-2" class="plan sel" onclick="selectPlan(2)">
<span class="pp" id="p2-price">2 480 ₽</span>
<div class="pn" id="p2-name">С комментариями</div>
<div class="pd" id="p2-desc">Все 12 пунктов + пояснение зачем каждое изменение. Контрагент понимает логику — меньше споров.</div>
</div>
<div id="pay-plan-3" class="plan" onclick="selectPlan(3)">
<span class="pp" id="p3-price">от 3 900 ₽</span>
<div class="pn" id="p3-name">Партнёрская редакция</div>
<div class="pd" id="p3-desc">Чистый договор, учитывающий интересы обеих сторон. Контрагент подпишет без лишних раундов переговоров + Елена сопровождает до подписания.</div>
</div>
<!-- Аргументация Елены за 2 дорогих -->
<div class="plan-pitch">
<img src="logos/elena-photo.jpg">
<div class="plan-pitch-body" id="pay-pitch">
Протокол без обоснования — это список требований. Контрагент вправе просто отказать: ему не нужно объяснять почему.<br><br>
<b>С обоснованием</b> каждое требование опирается на закон или стандарт отрасли. Это не ваш каприз — это норма. По опыту, такие протоколы принимают в первом же раунде.<br><br>
<b>Партнёрская версия</b> идёт дальше: мы формулируем так, чтобы контрагенту тоже было выгодно согласиться. Договор, который хочется выполнять 💛
</div>
</div>
<div class="field"><label>Куда прислать результат</label><input placeholder="Telegram или телефон"></div>
<div class="pdn">Нажимая «Оплатить», вы соглашаетесь с <a href="oferta.html" target="_blank">офертой</a> и <a href="privacy.html" target="_blank">обработкой ПДн</a>. Данные договора остаются на вашем устройстве.</div>
<button class="btn btn-p" id="pay-price-btn" style="width:100%" onclick="ykOpen()">Оплатить 2 480 ₽</button>
</div>
</section>
<!--СТАТУС ЗАКАЗА-->
<section class="screen" id="order-status">
<div class="topbar">
<img class="topbar-wm" src="logos/logo-zashita-word.svg" alt="ЗАЩИТА">
<span class="ttl">Заказ принят</span>
<span class="back-link" onclick="go('cabinet')" style="font-size:13px;color:var(--bg);font-weight:600;cursor:pointer">Мои дела →</span>
</div>
<div class="os-wrap">
<div class="os-ok">
<div class="os-ok-icon"></div>
<div class="os-ok-ttl">Оплата подтверждена</div>
<div class="os-ok-sub" id="os-ok-sub">Заказ передан в работу</div>
</div>
<div class="os-card">
<div class="oc-ttl" id="os-svc">Экспертиза договора</div>
<div class="oc-plan" id="os-plan-name">Стандарт</div>
<div class="oc-price" id="os-price">2 480 ₽</div>
<div class="oc-id" id="os-orderid">Заказ #—</div>
</div>
<div class="os-steps">
<div class="os-step done">
<div class="os-dot"></div>
<div class="os-step-lbl">Оплата<br>получена</div>
</div>
<div class="os-step active" id="os-step2">
<div class="os-dot"></div>
<div class="os-step-lbl" id="os-step2-lbl">Юрист<br>работает</div>
</div>
<div class="os-step pending">
<div class="os-dot">3</div>
<div class="os-step-lbl" id="os-step3-lbl">Готово</div>
</div>
</div>
<div class="os-deadline">
<div class="od-icon"></div>
<div class="od-text">
<strong id="os-deadline-ttl">Срок: до 24 часов</strong>
<span id="os-deadline-sub">после получения файла договора</span>
</div>
</div>
<div class="enote" style="margin-bottom:20px">
<img src="logos/elena-photo.jpg">
<div class="et" id="os-elena-msg">
Заказ получен — уже передала юристу. <b>Пришлите договор</b> в Telegram
<a href="https://t.me/wasrusgen1" target="_blank">@wasrusgen1</a>
без него начать не получится. Как только файл придёт — сразу приступаем 💛
</div>
</div>
<div class="os-actions">
<a class="os-tg" href="https://t.me/wasrusgen1" target="_blank">💬 Написать в Telegram</a>
<button class="btn btn-o" onclick="go('cabinet')">📂 Мои дела</button>
</div>
</div>
</section>
<!-- ═ АНАЛИТИКА CUSTOM-ЗАПРОСОВ ═ -->
<section class="screen" id="custom-admin">
<div class="topbar">
<img class="topbar-wm" src="logos/logo-zashita-word.svg" alt="ЗАЩИТА">
<span class="ttl">Аналитика: свои запросы</span>
<span class="back back-link" onclick="history.back();go('start')">← назад</span>
</div>
<div class="ca-wrap">
<div class="ca-title">Нестандартные запросы</div>
<div class="ca-sub">Что клиенты просят, чего нет в системе — основа для расширения CTYPES и deliverables</div>
<div id="ca-body"></div>
</div>
</section>
<!-- ═ 47. КАБИНЕТ (вкладки) ═ -->
<section class="screen" id="cabinet">
<div class="app">
<aside class="side">
<div class="lg"><img class="topbar-wm" src="logos/logo-zashita-word.svg" alt="ЗАЩИТА"></div>
<a id="t-cases" class="on" onclick="tab('cases')">🗂️ Мои дела</a>
<a id="t-case" onclick="tab('case')">📄 Дело: Кухня</a>
<a id="t-sroki" onclick="tab('sroki')">⏱️ Сроки</a>
<a id="t-shab" onclick="tab('shab')">📋 Шаблоны</a>
<a id="t-create" onclick="tab('create')">✍️ Составить документ</a>
<a onclick="go('start')">↩ Выйти (в начало)</a>
<div class="side-clock">
<div class="side-clock-day" id="sc-day">Среда</div>
<div class="side-clock-date" id="sc-date">28 мая 2025</div>
<div class="side-clock-time" id="sc-time">10:52:00</div>
</div>
<div class="prof"><div class="pa">РВ</div><div><div class="pn">Руслан Васильев</div><div class="pt">Тариф: Старт</div></div></div>
</aside>
<main class="main">
<!-- Мои дела -->
<div class="tabpane on" id="p-cases">
<div class="main-body">
<div class="crumb">Кабинет</div><h1>Мои дела</h1>
<!-- KPI -->
<div class="kpi-row">
<div class="kpi-card kpi-total"><div class="kc-ico">📁</div><div><div class="kc-num" id="kpi-total">5</div><div class="kc-lbl">Всего дел</div></div></div>
<div class="kpi-card kpi-work"><div class="kc-ico">🔵</div><div><div class="kc-num" id="kpi-work">3</div><div class="kc-lbl">В работе</div></div></div>
<div class="kpi-card kpi-urg"><div class="kc-ico">⚠️</div><div><div class="kc-num" id="kpi-urg">1</div><div class="kc-lbl">Срочных</div></div></div>
<div class="kpi-card kpi-done"><div class="kc-ico"></div><div><div class="kc-num" id="kpi-done">2</div><div class="kc-lbl">Завершено</div></div></div>
</div>
<!-- Фильтры -->
<div class="ct-filters">
<button class="ct-fbtn act" onclick="ctFilter('all',this)">Все</button>
<button class="ct-fbtn" onclick="ctFilter('open',this)">Открытые</button>
<button class="ct-fbtn" onclick="ctFilter('closed',this)">Закрытые</button>
<div class="ct-filter-sep"></div>
<button class="ct-fbtn" onclick="ctFilter('risk',this)">⚠ Срочные</button>
</div>
<!-- Таблица -->
<table class="ct-table" id="ct-table">
<thead>
<tr>
<th onclick="ctSort('name',this)">Договор</th>
<th onclick="ctSort('type',this)">Тип</th>
<th onclick="ctSort('date',this)">Дата</th>
<th onclick="ctSort('risk',this)">Риск</th>
<th onclick="ctSort('status',this)">Статус</th>
<th></th>
</tr>
</thead>
<tbody id="ct-tbody"></tbody>
</table>
</div><!-- /main-body -->
</div>
<!-- Внутри дела — CRM -->
<div class="tabpane" id="p-case"><div class="main-body">
<div class="crumb" style="margin-bottom:14px">Кабинет / <span style="cursor:pointer;color:var(--bg)" onclick="tab('cases')">Мои дела</span> / Кухня — агентский</div>
<!-- Шапка дела -->
<div class="case-hdr">
<div class="case-hdr-ico">🍽️</div>
<div class="case-hdr-info">
<div class="case-hdr-name">Кухня — агентский договор (ЗОВ)</div>
<div class="case-hdr-meta">
<span class="chip d">⚠ Высокий риск</span>
<span class="chip w">🔵 В работе</span>
<span class="chip n">12 рисков</span>
<span class="chip n">Агентский · 23.05.2025</span>
</div>
</div>
<div class="case-hdr-actions">
<button class="btn btn-o" style="font-size:12px;padding:7px 14px" onclick="toast('⬇️ PDF экспортируется')">⬇ PDF</button>
<button class="btn btn-p" style="font-size:12px;padding:7px 14px" onclick="toast('💬 Открываю чат с Еленой')">💬 Елена</button>
</div>
</div>
<!-- ⚡ Следующий шаг — ГЛАВНЫЙ БЛОК -->
<div class="next-step-v2" onclick="toast('📋 Открываю протокол разногласий для согласования')">
<div class="ns2-pulse"></div>
<div class="ns2-body">
<div class="ns2-label">Следующий шаг</div>
<div class="ns2-action">Отправить протокол разногласий контрагенту<span class="ns2-deadline">до 29.05</span></div>
<div class="ns2-meta">Протокол готов · 5 пунктов · ст. 22 ЗоЗПП · осталось 1 день</div>
</div>
<button class="ns2-btn" onclick="event.stopPropagation();toast('✅ Протокол согласован и готов к отправке')">Согласовать →</button>
</div>
<!-- Панель протокола (появляется когда выбраны пункты) -->
<div class="protocol-bar" id="protocol-bar">
<div class="pb-ico">📋</div>
<div class="pb-body">
<div class="pb-title">Протокол разногласий</div>
<div class="pb-sub" id="pb-sub">Выберите пункты во вкладке Риски</div>
</div>
<button class="pb-btn" id="pb-generate" onclick="toast('📋 Протокол разногласий формируется — Елена подготовит документ в течение 2 минут')">Сформировать протокол →</button>
</div>
<!-- Вкладки -->
<div class="case-tabs">
<div class="case-tab on" onclick="caseTab('overview',this)">Обзор</div>
<div class="case-tab" onclick="caseTab('risks',this)">Риски <span style="background:#fee2e2;color:#991b1b;border-radius:8px;padding:1px 6px;font-size:10px;font-weight:700">12</span></div>
<div class="case-tab" onclick="caseTab('docs',this)">Документы <span style="background:#e5e7eb;border-radius:8px;padding:1px 6px;font-size:10px">5</span></div>
<div class="case-tab" onclick="caseTab('timeline',this)">История</div>
<div class="case-tab" onclick="caseTab('chat',this)">Переписка <span style="background:#dbeafe;color:#1d4ed8;border-radius:8px;padding:1px 6px;font-size:10px;font-weight:700">1</span></div>
</div>
<!-- Обзор -->
<div class="case-pane on" id="cp-overview">
<!-- Прогресс дела -->
<div class="case-progress">
<div class="cp-step done">
<div class="cps-dot"></div>
<div class="cps-lbl">Загружен</div>
<div class="cps-date">23.05</div>
</div>
<div class="cp-step done">
<div class="cps-dot"></div>
<div class="cps-lbl">Экспертиза</div>
<div class="cps-date">23.05</div>
</div>
<div class="cp-step done">
<div class="cps-dot"></div>
<div class="cps-lbl">Новая редакция</div>
<div class="cps-date">24.05</div>
</div>
<div class="cp-step act">
<div class="cps-dot"></div>
<div class="cps-lbl">Протокол</div>
<div class="cps-date">сейчас</div>
</div>
<div class="cp-step pend">
<div class="cps-dot"></div>
<div class="cps-lbl">Ответ контрагенту</div>
<div class="cps-date">до 29.05</div>
</div>
<div class="cp-step pend">
<div class="cps-dot"></div>
<div class="cps-lbl">Подписание</div>
<div class="cps-date"></div>
</div>
</div>
<div class="overview-grid">
<div class="ov-card">
<div class="ov-card-ttl">Параметры дела</div>
<div class="ov-row"><span class="ov-k">Тип договора</span><span class="ov-v">Агентский</span></div>
<div class="ov-row"><span class="ov-k">Дата загрузки</span><span class="ov-v">23.05.2025</span></div>
<div class="ov-row"><span class="ov-k">Риск</span><span class="ov-v"><span class="chip d" style="font-size:11px">⚠ Высокий · 3/5</span></span></div>
<div class="ov-row"><span class="ov-k">Рисков найдено</span><span class="ov-v">12 (5 критичных)</span></div>
<div class="ov-row"><span class="ov-k">Статус</span><span class="ov-v">🔵 В работе</span></div>
</div>
<div class="ov-card">
<div class="ov-card-ttl">Текущий этап</div>
<div class="ov-row"><span class="ov-k">✅ Экспертиза</span><span class="ov-v" style="color:#16a34a">Готово</span></div>
<div class="ov-row"><span class="ov-k">✅ Новая редакция</span><span class="ov-v" style="color:#16a34a">Получена</span></div>
<div class="ov-row"><span class="ov-k">⏳ Протокол</span><span class="ov-v" style="color:#d97706">На согласовании</span></div>
<div class="ov-row"><span class="ov-k">⬜ Ответ контрагенту</span><span class="ov-v" style="color:#9ca3af">Ожидает</span></div>
<div class="ov-row"><span class="ov-k">⬜ Подписание</span><span class="ov-v" style="color:#9ca3af">Ожидает</span></div>
</div>
</div>
<div class="enote" style="margin-top:4px"><img src="logos/elena-photo.jpg"><div class="et">Протокол разногласий готов — осталось согласовать и отправить контрагенту до 29.05. Я напомню накануне 💛</div></div>
</div>
<!-- Риски -->
<div class="case-pane" id="cp-risks">
<div class="risk-summary">
<div class="risk-sum-item crit">🔴 5 критических</div>
<div class="risk-sum-item mid">🟡 4 средних</div>
<div class="risk-sum-item low">🟢 3 низких</div>
</div>
<div class="risk-list">
<div class="risk-item crit" onclick="toggleRisk(this)">
<div class="risk-item-hdr">
<span class="risk-badge crit">🔴 Критический</span>
<span class="risk-num">#1</span>
<span class="risk-title">Одностороннее изменение условий</span>
<span class="risk-toggle"></span>
</div>
<div class="risk-norm">п. 4.2 договора · ст. 450 ГК РФ</div>
<div class="risk-rec">Агент вправе менять вознаграждение без вашего согласования.</div>
<div class="risk-expand">
<div class="risk-quote"><div class="risk-quote-lbl">📄 Как написано сейчас</div><div class="risk-quote-txt">«Агент вправе в одностороннем порядке изменять размер агентского вознаграждения, уведомив Принципала не менее чем за 3 (три) календарных дня»</div></div>
<div class="risk-fix"><div class="risk-fix-lbl">✅ Рекомендуемая формулировка</div><div class="risk-fix-txt">«Изменение размера агентского вознаграждения допускается исключительно по письменному соглашению сторон, подписанному обеими сторонами»</div></div>
<button class="risk-apply-btn" onclick="event.stopPropagation();applyRisk(1,this)">Применить в протоколе →</button>
</div>
</div>
<div class="risk-item crit" onclick="toggleRisk(this)">
<div class="risk-item-hdr">
<span class="risk-badge crit">🔴 Критический</span>
<span class="risk-num">#2</span>
<span class="risk-title">Неограниченная ответственность принципала</span>
<span class="risk-toggle"></span>
</div>
<div class="risk-norm">п. 8.1 договора · ст. 393 ГК РФ</div>
<div class="risk-rec">Размер убытков, которые агент может взыскать с вас, не ограничен.</div>
<div class="risk-expand">
<div class="risk-quote"><div class="risk-quote-lbl">📄 Как написано сейчас</div><div class="risk-quote-txt">«Принципал возмещает Агенту убытки в полном объёме, включая упущенную выгоду, понесённые вследствие ненадлежащего исполнения обязательств»</div></div>
<div class="risk-fix"><div class="risk-fix-lbl">✅ Рекомендуемая формулировка</div><div class="risk-fix-txt">«Ответственность Принципала ограничена суммой агентского вознаграждения за 3 (три) последних месяца. Упущенная выгода возмещению не подлежит»</div></div>
<button class="risk-apply-btn" onclick="event.stopPropagation();applyRisk(2,this)">Применить в протоколе →</button>
</div>
</div>
<div class="risk-item crit" onclick="toggleRisk(this)">
<div class="risk-item-hdr">
<span class="risk-badge crit">🔴 Критический</span>
<span class="risk-num">#3</span>
<span class="risk-title">Автопролонгация без уведомления</span>
<span class="risk-toggle"></span>
</div>
<div class="risk-norm">п. 9.3 договора · ст. 621 ГК РФ</div>
<div class="risk-rec">Договор продлевается на год автоматически — без явного согласия.</div>
<div class="risk-expand">
<div class="risk-quote"><div class="risk-quote-lbl">📄 Как написано сейчас</div><div class="risk-quote-txt">«Договор считается пролонгированным на аналогичный срок, если ни одна из сторон не заявила письменного отказа»</div></div>
<div class="risk-fix"><div class="risk-fix-lbl">✅ Рекомендуемая формулировка</div><div class="risk-fix-txt">«Пролонгация допускается только при наличии письменного согласия обеих сторон, подписанного не позднее чем за 30 дней до окончания срока договора»</div></div>
<button class="risk-apply-btn" onclick="event.stopPropagation();applyRisk(3,this)">Применить в протоколе →</button>
</div>
</div>
<div class="risk-item crit" onclick="toggleRisk(this)">
<div class="risk-item-hdr">
<span class="risk-badge crit">🔴 Критический</span>
<span class="risk-num">#4</span>
<span class="risk-title">Отсутствие порядка сдачи-приёмки</span>
<span class="risk-toggle"></span>
</div>
<div class="risk-norm">п. 5 договора · ст. 720 ГК РФ</div>
<div class="risk-rec">Нет формы акта и сроков — суд может признать услугу принятой по умолчанию.</div>
<div class="risk-expand">
<div class="risk-quote"><div class="risk-quote-lbl">📄 Как написано сейчас</div><div class="risk-quote-txt">«Результат исполнения агентского поручения считается принятым по истечении 5 рабочих дней с момента получения отчёта при отсутствии замечаний»</div></div>
<div class="risk-fix"><div class="risk-fix-lbl">✅ Рекомендуемая формулировка</div><div class="risk-fix-txt">«Приёмка исполнения оформляется актом по форме Приложения №2. Акт подписывается в течение 3 рабочих дней. При наличии замечаний составляется мотивированный отказ в той же форме»</div></div>
<button class="risk-apply-btn" onclick="event.stopPropagation();applyRisk(4,this)">Применить в протоколе →</button>
</div>
</div>
<div class="risk-item crit" onclick="toggleRisk(this)">
<div class="risk-item-hdr">
<span class="risk-badge crit">🔴 Критический</span>
<span class="risk-num">#5</span>
<span class="risk-title">Невыгодная подсудность</span>
<span class="risk-toggle"></span>
</div>
<div class="risk-norm">п. 11.2 договора · ст. 37 АПК РФ</div>
<div class="risk-rec">Споры рассматриваются по месту агента — вам придётся судиться в другом городе.</div>
<div class="risk-expand">
<div class="risk-quote"><div class="risk-quote-lbl">📄 Как написано сейчас</div><div class="risk-quote-txt">«Все споры, вытекающие из настоящего договора, рассматриваются в Арбитражном суде города Москвы»</div></div>
<div class="risk-fix"><div class="risk-fix-lbl">✅ Рекомендуемая формулировка</div><div class="risk-fix-txt">«Все споры, вытекающие из настоящего договора, рассматриваются в арбитражном суде по месту нахождения Принципала»</div></div>
<button class="risk-apply-btn" onclick="event.stopPropagation();applyRisk(5,this)">Применить в протоколе →</button>
</div>
</div>
<div class="risk-item mid" onclick="toggleRisk(this)">
<div class="risk-item-hdr">
<span class="risk-badge mid">🟡 Средний</span>
<span class="risk-num">#6</span>
<span class="risk-title">Размытые сроки отчётности агента</span>
<span class="risk-toggle"></span>
</div>
<div class="risk-norm">п. 6.1 договора · ст. 1008 ГК РФ</div>
<div class="risk-rec">«В разумный срок» — нет конкретной даты предоставления отчётов.</div>
<div class="risk-expand">
<div class="risk-quote"><div class="risk-quote-lbl">📄 Как написано сейчас</div><div class="risk-quote-txt">«Агент представляет отчёт об исполнении поручения в разумный срок после окончания отчётного периода»</div></div>
<div class="risk-fix"><div class="risk-fix-lbl">✅ Рекомендуемая формулировка</div><div class="risk-fix-txt">«Агент представляет отчёт не позднее 5-го числа месяца, следующего за отчётным, с приложением первичных документов»</div></div>
<button class="risk-apply-btn" onclick="event.stopPropagation();applyRisk(6,this)">Применить в протоколе →</button>
</div>
</div>
<div class="risk-item mid" onclick="toggleRisk(this)">
<div class="risk-item-hdr">
<span class="risk-badge mid">🟡 Средний</span>
<span class="risk-num">#7</span>
<span class="risk-title">Нет срока уведомления при расторжении</span>
<span class="risk-toggle"></span>
</div>
<div class="risk-norm">п. 9.2 договора · ст. 1010 ГК РФ</div>
<div class="risk-rec">Порядок уведомления не прописан — расторжение может прийти в любой момент.</div>
<div class="risk-expand">
<div class="risk-quote"><div class="risk-quote-lbl">📄 Как написано сейчас</div><div class="risk-quote-txt">«Каждая из сторон вправе отказаться от договора, уведомив другую сторону о своём намерении»</div></div>
<div class="risk-fix"><div class="risk-fix-lbl">✅ Рекомендуемая формулировка</div><div class="risk-fix-txt">«Каждая из сторон вправе отказаться от договора, направив письменное уведомление не менее чем за 30 (тридцать) календарных дней до предполагаемой даты расторжения»</div></div>
<button class="risk-apply-btn" onclick="event.stopPropagation();applyRisk(7,this)">Применить в протоколе →</button>
</div>
</div>
<div class="risk-item mid" onclick="toggleRisk(this)">
<div class="risk-item-hdr">
<span class="risk-badge mid">🟡 Средний</span>
<span class="risk-num">#8</span>
<span class="risk-title">Вознаграждение без указания НДС</span>
<span class="risk-toggle"></span>
</div>
<div class="risk-norm">п. 3.1 договора · НК РФ ст. 168</div>
<div class="risk-rec">Риск доначисления НДС и штрафов при налоговой проверке.</div>
<div class="risk-expand">
<div class="risk-quote"><div class="risk-quote-lbl">📄 Как написано сейчас</div><div class="risk-quote-txt">«Размер агентского вознаграждения составляет 150 000 (сто пятьдесят тысяч) рублей ежемесячно»</div></div>
<div class="risk-fix"><div class="risk-fix-lbl">✅ Рекомендуемая формулировка</div><div class="risk-fix-txt">«Размер агентского вознаграждения составляет 150 000 (сто пятьдесят тысяч) рублей ежемесячно, в том числе НДС 20% — 25 000 рублей» <i>(или: «НДС не облагается — основание: применение УСН»)</i></div></div>
<button class="risk-apply-btn" onclick="event.stopPropagation();applyRisk(8,this)">Применить в протоколе →</button>
</div>
</div>
<div class="risk-item mid" onclick="toggleRisk(this)">
<div class="risk-item-hdr">
<span class="risk-badge mid">🟡 Средний</span>
<span class="risk-num">#9</span>
<span class="risk-title">Право субагентирования без согласования</span>
<span class="risk-toggle"></span>
</div>
<div class="risk-norm">п. 3.4 договора · ст. 1009 ГК РФ</div>
<div class="risk-rec">Агент привлекает субагентов без вашего ведома — вы теряете контроль.</div>
<div class="risk-expand">
<div class="risk-quote"><div class="risk-quote-lbl">📄 Как написано сейчас</div><div class="risk-quote-txt">«Агент вправе для исполнения поручения привлекать третьих лиц (субагентов) с уведомлением Принципала»</div></div>
<div class="risk-fix"><div class="risk-fix-lbl">✅ Рекомендуемая формулировка</div><div class="risk-fix-txt">«Привлечение субагентов допускается исключительно с предварительного письменного согласия Принципала в каждом конкретном случае»</div></div>
<button class="risk-apply-btn" onclick="event.stopPropagation();applyRisk(9,this)">Применить в протоколе →</button>
</div>
</div>
<div class="risk-item low" onclick="toggleRisk(this)">
<div class="risk-item-hdr">
<span class="risk-badge low">🟢 Низкий</span>
<span class="risk-num">#10</span>
<span class="risk-title">Расплывчатый перечень форс-мажора</span>
<span class="risk-toggle"></span>
</div>
<div class="risk-norm">п. 10 договора · ст. 401 ГК РФ</div>
<div class="risk-rec">Перечень открытый — контрагент может сослаться на любое «чрезвычайное обстоятельство».</div>
<div class="risk-expand">
<div class="risk-quote"><div class="risk-quote-lbl">📄 Как написано сейчас</div><div class="risk-quote-txt">«Стороны освобождаются от ответственности при наступлении обстоятельств непреодолимой силы и иных чрезвычайных обстоятельств»</div></div>
<div class="risk-fix"><div class="risk-fix-lbl">✅ Рекомендуемая формулировка</div><div class="risk-fix-txt">«Форс-мажорными признаются исключительно: стихийные бедствия, военные действия, режим ЧС, эпидемия по решению ВОЗ, запретительные акты органов государственной власти. Перечень является исчерпывающим»</div></div>
<button class="risk-apply-btn" onclick="event.stopPropagation();applyRisk(10,this)">Применить в протоколе →</button>
</div>
</div>
<div class="risk-item low" onclick="toggleRisk(this)">
<div class="risk-item-hdr">
<span class="risk-badge low">🟢 Низкий</span>
<span class="risk-num">#11</span>
<span class="risk-title">Нет упоминания ЭДО и ЭЦП</span>
<span class="risk-toggle"></span>
</div>
<div class="risk-norm">п. 12 договора · 63-ФЗ</div>
<div class="risk-rec">При дистанционной работе электронные документы могут не иметь юридической силы.</div>
<div class="risk-expand">
<div class="risk-quote"><div class="risk-quote-lbl">📄 Как написано сейчас</div><div class="risk-quote-txt">«Уведомления и документы направляются сторонами по почте заказным письмом или курьерской службой»</div></div>
<div class="risk-fix"><div class="risk-fix-lbl">✅ Рекомендуемая формулировка</div><div class="risk-fix-txt">«Стороны вправе использовать электронный документооборот с применением квалифицированной электронной подписи (КЭП) в соответствии с 63-ФЗ. Документы в ЭДО имеют равную юридическую силу с бумажными оригиналами»</div></div>
<button class="risk-apply-btn" onclick="event.stopPropagation();applyRisk(11,this)">Применить в протоколе →</button>
</div>
</div>
<div class="risk-item low" onclick="toggleRisk(this)">
<div class="risk-item-hdr">
<span class="risk-badge low">🟢 Низкий</span>
<span class="risk-num">#12</span>
<span class="risk-title">Нет обязанности уведомлять об изменении реквизитов</span>
<span class="risk-toggle"></span>
</div>
<div class="risk-norm">п. 12.3 договора</div>
<div class="risk-rec">Смена реквизитов без предупреждения — оплата уйдёт не туда, но вы останетесь должником.</div>
<div class="risk-expand">
<div class="risk-quote"><div class="risk-quote-lbl">📄 Как написано сейчас</div><div class="risk-quote-txt">«Стороны используют реквизиты, указанные в разделе 12 настоящего договора»</div></div>
<div class="risk-fix"><div class="risk-fix-lbl">✅ Рекомендуемая формулировка</div><div class="risk-fix-txt">«При изменении банковских реквизитов сторона обязана письменно уведомить контрагента не менее чем за 5 (пять) рабочих дней. Платёж по старым реквизитам после получения уведомления не признаётся надлежащим исполнением»</div></div>
<button class="risk-apply-btn" onclick="event.stopPropagation();applyRisk(12,this)">Применить в протоколе →</button>
</div>
</div>
</div>
</div>
<!-- Документы -->
<div class="case-pane" id="cp-docs">
<div class="doc-upload-btn" onclick="toast('📎 Выберите файл — договор, письмо или любой документ по делу. Данные остаются на вашем устройстве')">
<div class="doc-upload-ico">📎</div>
<div class="doc-upload-txt">Загрузить документ в дело
<span>PDF, DOCX, JPG · до 50 МБ · данные остаются на вашем устройстве</span>
</div>
</div>
<div style="max-width:700px">
<div class="docrow" onclick="toast('Открываю исходный договор v1')">📄 Исходный договор <span class="ver">v1</span></div>
<div class="docrow" onclick="toast('Открываю редакцию v2')">📝 Новая редакция <span class="ver">v2</span></div>
<div class="docrow" onclick="toast('Открываю заключение экспертизы — 12 рисков')">🔍 Заключение экспертизы <span class="ver">готово</span></div>
<div class="docrow" onclick="toast('Открываю протокол разногласий')">📋 Протокол разногласий <span class="ver">черновик</span></div>
<div class="docrow" onclick="toast('Открываю ответ контрагента')">⬇️ Ответ контрагента <span class="ver">входящее</span></div>
</div>
</div>
<!-- Переписка -->
<div class="case-pane" id="cp-chat">
<!-- Форма составления письма -->
<div class="chat-compose">
<div class="chat-compose-ttl">✉️ Составить письмо контрагенту</div>
<div class="chat-field">
<label>Кому</label>
<input type="text" value="ООО «Зов Ресторанс» — info@zov-rest.ru" readonly style="color:var(--mut);background:#f9fafb">
</div>
<div class="chat-field">
<label>Тема</label>
<input type="text" id="chat-subject" value="Протокол разногласий к агентскому договору от 20.05.2025">
</div>
<div class="chat-field">
<label>Текст письма</label>
<textarea id="chat-body" rows="6" style="font-size:12px;line-height:1.6">Уважаемые коллеги,
Направляем протокол разногласий к агентскому договору от 20.05.2025 г. Просим рассмотреть предложенные изменения и сообщить о Вашем решении в срок до 29.05.2025.
Прилагаем: протокол разногласий (1 л.).
С уважением,
Васильев Руслан Геннадьевич
ИП Васильев Р.Г.</textarea>
</div>
<div class="chat-actions">
<button class="chat-send-btn" onclick="toast('📧 Письмо подготовлено — скопируйте и отправьте из вашей почты. Запись о письме сохранена в истории дела')">Подготовить к отправке</button>
<button class="chat-copy-btn" onclick="toast('📋 Текст письма скопирован в буфер обмена')">Копировать текст</button>
</div>
</div>
<!-- История переписки -->
<div class="chat-list">
<div class="chat-list-ttl">История переписки</div>
<div class="chat-item inc" onclick="toast('📥 Открываю входящее письмо от контрагента')">
<div class="chat-arrow"></div>
<div class="chat-item-body">
<div class="chat-item-hdr">
<span class="chat-item-subj">Ответ на протокол разногласий</span>
<span class="chat-status new">Новое</span>
<span class="chat-item-date">24.05</span>
</div>
<div class="chat-item-prev">ООО Зов Ресторанс: «Готовы согласовать пп. 1,3,5. По п. 2 просим сохранить текущую редакцию...»</div>
</div>
</div>
<div class="chat-item out" onclick="toast('📤 Открываю отправленное письмо')">
<div class="chat-arrow"></div>
<div class="chat-item-body">
<div class="chat-item-hdr">
<span class="chat-item-subj">Протокол разногласий (черновик)</span>
<span class="chat-status sent">Отправлено</span>
<span class="chat-item-date">23.05</span>
</div>
<div class="chat-item-prev">Направляем протокол разногласий к агентскому договору от 20.05.2025...</div>
</div>
</div>
<div class="chat-item out" onclick="toast('📤 Открываю запрос реквизитов')">
<div class="chat-arrow"></div>
<div class="chat-item-body">
<div class="chat-item-hdr">
<span class="chat-item-subj">Запрос реквизитов и ИНН</span>
<span class="chat-status read">Прочитано</span>
<span class="chat-item-date">21.05</span>
</div>
<div class="chat-item-prev">В целях проверки контрагента просим предоставить полные реквизиты...</div>
</div>
</div>
</div>
</div>
<!-- История -->
<div class="case-pane" id="cp-timeline">
<div class="tl-section" style="margin-top:0">
<div class="tl">
<div class="tl-item done"><div class="tl-dot"></div><div class="tl-date">23.05</div><div class="tl-title">Договор загружен</div><div class="tl-ev">Агентский договор ЗОВ — v1</div></div>
<div class="tl-item done"><div class="tl-dot"></div><div class="tl-date">23.05</div><div class="tl-title">Экспертиза завершена</div><div class="tl-ev">12 рисков, 5 критичных — заключение готово</div></div>
<div class="tl-item done"><div class="tl-dot"></div><div class="tl-date">24.05</div><div class="tl-title">Получена новая редакция</div><div class="tl-ev">Контрагент прислал v2 — сверка выполнена</div></div>
<div class="tl-item active"><div class="tl-dot"></div><div class="tl-date">сейчас</div><div class="tl-title">Протокол разногласий</div><div class="tl-ev">Черновик готов · ждёт согласования</div></div>
<div class="tl-item pending"><div class="tl-dot"></div><div class="tl-date">до 29.05</div><div class="tl-title">Ответ контрагенту</div><div class="tl-ev">Направить протокол разногласий</div></div>
<div class="tl-item pending"><div class="tl-dot"></div><div class="tl-date"></div><div class="tl-title">Итоговое подписание</div><div class="tl-ev">После согласования всех пунктов</div></div>
</div>
</div>
</div>
</div>
</div>
<!-- Сроки — Gantt -->
<div class="tabpane" id="p-sroki"><div class="main-body"><div class="crumb">Кабинет</div><h1>Сроки</h1>
<div class="enote"><img src="logos/elena-photo.jpg"><div class="et"><b>Слежу за всеми сроками</b> — диаграмма обновляется в реальном времени. Нажмите на дело чтобы открыть 💛</div></div>
<div class="gantt-wrap"><div class="gantt" id="gantt-root"></div></div>
</div>
<!-- Шаблоны -->
<div class="tabpane" id="p-shab"><div class="main-body"><div class="crumb">Кабинет</div><h1>Шаблоны</h1>
<div class="enote"><img src="logos/elena-photo.jpg"><div class="et"><b>Готовые документы — заполню под ваш случай.</b> Составлять с нуля не нужно 💛</div></div>
<div class="tpls">
<div class="tpl" onclick="toast('✍️ Заполняю «Протокол разногласий» под ваш договор — Елена рядом')"><div class="ti">📝</div><div class="tn">Протокол разногласий</div><div class="td">убрать невыгодные пункты</div></div>
<div class="tpl" onclick="toast('✍️ Заполняю «Претензию» под ваш случай — оплата / неустойка')"><div class="ti">✉️</div><div class="tn">Претензия</div><div class="td">оплата / неустойка</div></div>
<div class="tpl" onclick="toast('✍️ Заполняю «Ответ на претензию» — отобьём требование по закону')"><div class="ti">🛡️</div><div class="tn">Ответ на претензию</div><div class="td">отбить требование</div></div>
<div class="tpl" onclick="toast('✍️ Заполняю «Расторжение» — выйдем без потерь')"><div class="ti">🚪</div><div class="tn">Расторжение</div><div class="td">выйти без потерь</div></div>
</div>
</div>
<!-- Составить документ -->
<div class="tabpane" id="p-create"><div class="main-body">
<div class="crumb">Кабинет</div><h1>Составить документ</h1>
<div class="enote" style="margin-bottom:20px"><img src="logos/elena-photo.jpg"><div class="et"><b>Составлю любой документ под ваши параметры.</b> Выберите тип, заполните ключевые данные — черновик будет готов за 2 минуты. Сохранено на вашем устройстве 💛</div></div>
<!-- Шаги -->
<div class="create-steps">
<div class="cstep act" id="cstep-1"><div class="cstep-num">1</div>Тип документа</div>
<div class="cstep-arrow"></div>
<div class="cstep" id="cstep-2"><div class="cstep-num">2</div>Параметры</div>
<div class="cstep-arrow"></div>
<div class="cstep" id="cstep-3"><div class="cstep-num">3</div>Черновик готов</div>
</div>
<!-- Шаг 1: Тип документа -->
<div class="create-pane on" id="cp-type">
<div class="doc-type-intro">Выберите тип — Елена подберёт структуру и заполнит шаблон под ваши данные</div>
<div class="doc-type-grid">
<div class="doc-type-card sel" onclick="selectDocType('agent',this)">
<div class="dtc-ico">🤝</div>
<div class="dtc-name">Агентский договор</div>
<div class="dtc-desc">поручение + вознаграждение</div>
</div>
<div class="doc-type-card" onclick="selectDocType('trust',this)">
<div class="dtc-ico">📑</div>
<div class="dtc-name">Доверенность</div>
<div class="dtc-desc">полномочия представителя</div>
</div>
<div class="doc-type-card" onclick="selectDocType('claim',this)">
<div class="dtc-ico">✉️</div>
<div class="dtc-name">Претензия</div>
<div class="dtc-desc">оплата / неустойка</div>
</div>
<div class="doc-type-card" onclick="selectDocType('supply',this)">
<div class="dtc-ico">📦</div>
<div class="dtc-name">Договор поставки</div>
<div class="dtc-desc">товар + сроки + ответственность</div>
</div>
<div class="doc-type-card" onclick="selectDocType('rent',this)">
<div class="dtc-ico">🏠</div>
<div class="dtc-name">Аренда</div>
<div class="dtc-desc">помещение / оборудование</div>
</div>
<div class="doc-type-card" onclick="selectDocType('nda',this)">
<div class="dtc-ico">🔒</div>
<div class="dtc-name">NDA / Конфиденциальность</div>
<div class="dtc-desc">защита данных и ноу-хау</div>
</div>
<div class="doc-type-card" onclick="selectDocType('labor',this)">
<div class="dtc-ico">💼</div>
<div class="dtc-name">Трудовой договор</div>
<div class="dtc-desc">оформление сотрудника</div>
</div>
<div class="doc-type-card" onclick="selectDocType('dismiss',this)">
<div class="dtc-ico">🚪</div>
<div class="dtc-name">Расторжение</div>
<div class="dtc-desc">выйти без потерь</div>
</div>
</div>
<button class="doc-type-next show" id="doc-type-next" onclick="goCreateStep(2)">Заполнить параметры →</button>
</div>
<!-- Шаг 2: Параметры -->
<div class="create-pane" id="cp-form">
<div style="font-size:14px;font-weight:700;color:var(--ink);margin-bottom:16px" id="cf-doc-title">Агентский договор</div>
<div class="create-form-grid" id="create-form-fields">
<!-- Поля строятся через JS buildCreateForm() -->
<div class="cf-group"><label class="cf-label">Принципал (вы)</label><input class="cf-input" placeholder="ИП Васильев Руслан Геннадьевич"><span class="cf-hint">Полное наименование или ФИО</span></div>
<div class="cf-group"><label class="cf-label">Агент (контрагент)</label><input class="cf-input" placeholder="ООО «Зов Ресторанс»"><span class="cf-hint">Полное наименование</span></div>
<div class="cf-group wide"><label class="cf-label">Предмет поручения</label><input class="cf-input" placeholder="Поиск и привлечение клиентов для ресторана"><span class="cf-hint">Что именно делает агент</span></div>
<div class="cf-group"><label class="cf-label">Вознаграждение</label><input class="cf-input" placeholder="150 000 руб./мес."><span class="cf-hint">Сумма и периодичность</span></div>
<div class="cf-group"><label class="cf-label">Срок договора</label><input class="cf-input" placeholder="1 год с даты подписания"><span class="cf-hint">Начало и окончание</span></div>
<div class="cf-group"><label class="cf-label">Подсудность</label><input class="cf-input" placeholder="По месту нахождения Принципала"><span class="cf-hint">Суд при спорах</span></div>
<div class="cf-group"><label class="cf-label">НДС</label><input class="cf-input" placeholder="Не облагается — УСН"><span class="cf-hint">Или: в т.ч. НДС 20%</span></div>
</div>
<div class="enote" style="margin-bottom:16px;max-width:740px"><img src="logos/elena-photo.jpg"><div class="et">Заполните ключевые параметры — остальное (нумерацию, ссылки на нормы, форс-мажор, реквизиты) я добавлю автоматически 💛</div></div>
<div class="create-form-actions">
<button class="cf-back" onclick="goCreateStep(1)">← Назад</button>
<button class="cf-generate" onclick="goCreateStep(3)">⚡ Сгенерировать черновик</button>
</div>
</div>
<!-- Шаг 3: Черновик готов -->
<div class="create-pane" id="cp-preview">
<!-- Спиннер генерации -->
<div class="doc-generating" id="doc-generating">
<div class="dg-spinner"></div>
<div class="dg-text">Елена составляет черновик…</div>
<div class="dg-sub">Проверяю нормы ГК РФ · подбираю формулировки · 23 секунды</div>
</div>
<!-- Превью документа -->
<div class="doc-preview-wrap" id="doc-preview-wrap">
<div class="doc-preview-actions">
<button class="dpa-btn dpa-dl" onclick="toast('⬇️ Скачиваю агентский договор в формате DOCX — файл будет готов через секунду')">⬇ Скачать DOCX</button>
<button class="dpa-btn dpa-copy" onclick="toast('📋 Текст договора скопирован в буфер обмена')">📋 Копировать</button>
<button class="dpa-btn dpa-add" onclick="toast('📁 Черновик добавлен в дело «Кухня — агентский (ЗОВ)»')"> В дело</button>
<button class="cf-back" style="border-radius:10px;padding:10px 16px;font-size:13px" onclick="goCreateStep(1)">← Новый</button>
</div>
<div class="doc-preview">
<h3>АГЕНТСКИЙ ДОГОВОР № <span class="doc-blank">___</span></h3>
<div class="doc-city">г. Краснодар &nbsp;&nbsp;&nbsp; <span class="doc-highlight">28 мая 2025 г.</span></div>
<div class="doc-parties">
<b>ПРИНЦИПАЛ:</b> <span class="doc-highlight">ИП Васильев Руслан Геннадьевич</span>, ОГРНИП <span class="doc-blank">____________</span>, ИНН <span class="doc-blank">____________</span>, именуемый в дальнейшем «Принципал»,<br><br>
<b>АГЕНТ:</b> <span class="doc-highlight">ООО «Зов Ресторанс»</span>, ИНН <span class="doc-blank">____________</span>, КПП <span class="doc-blank">____________</span>, именуемое в дальнейшем «Агент»,<br><br>
совместно именуемые «Стороны», заключили настоящий договор о нижеследующем:
</div>
<div class="doc-article">1. Предмет договора</div>
<div class="doc-clause">1.1. Принципал поручает, а Агент обязуется за вознаграждение совершать от имени и за счёт Принципала следующие действия: <span class="doc-highlight">поиск и привлечение клиентов для ресторана</span>.</div>
<div class="doc-clause">1.2. Агент действует в пределах полномочий, предоставленных настоящим договором и доверенностью (при необходимости).</div>
<div class="doc-article">2. Вознаграждение агента</div>
<div class="doc-clause">2.1. Вознаграждение Агента составляет <span class="doc-highlight">150 000 (сто пятьдесят тысяч) рублей</span> ежемесячно. <span class="doc-highlight">НДС не облагается — Агент применяет УСН.</span></div>
<div class="doc-clause">2.2. Изменение размера вознаграждения допускается исключительно по письменному соглашению Сторон.</div>
<div class="doc-clause">2.3. Оплата производится в течение 5 (пяти) рабочих дней с момента подписания акта за отчётный период.</div>
<div class="doc-article">3. Порядок исполнения</div>
<div class="doc-clause">3.1. Агент представляет отчёт не позднее <span class="doc-highlight">5-го числа</span> месяца, следующего за отчётным, с приложением первичных документов.</div>
<div class="doc-clause">3.2. Принципал вправе заявить возражения по отчёту в течение 3 (трёх) рабочих дней. По истечении данного срока отчёт считается принятым.</div>
<div class="doc-clause">3.3. Привлечение субагентов допускается исключительно с письменного согласия Принципала.</div>
<div class="doc-article">4. Ответственность сторон</div>
<div class="doc-clause">4.1. Ответственность Принципала ограничена суммой вознаграждения за 3 (три) последних месяца. Упущенная выгода возмещению не подлежит.</div>
<div class="doc-clause">4.2. За просрочку оплаты Принципал уплачивает пеню в размере 0,1% от суммы за каждый день просрочки.</div>
<div class="doc-article">5. Срок и расторжение</div>
<div class="doc-clause">5.1. Договор вступает в силу с даты подписания и действует <span class="doc-highlight">1 (один) год</span>.</div>
<div class="doc-clause">5.2. Каждая из Сторон вправе расторгнуть договор, уведомив другую сторону письменно не менее чем за 30 (тридцать) дней.</div>
<div class="doc-clause">5.3. Пролонгация допускается только при наличии письменного согласия обеих Сторон не позднее 30 дней до окончания срока.</div>
<div class="doc-article">6. Разрешение споров</div>
<div class="doc-clause">6.1. Все споры рассматриваются в арбитражном суде <span class="doc-highlight">по месту нахождения Принципала</span>.</div>
<div style="margin-top:24px;font-size:11px;color:var(--mut);border-top:1px solid #e5e7eb;padding-top:12px">
📌 Черновик сгенерирован ЗАЩИТА · требует проверки перед подписанием · данные хранятся на вашем устройстве
</div>
</div>
</div>
</div>
</div></div>
</main>
</div>
</section>
<script>
/* ── СТАТИСТИКА ── */
function statTrack(mode, custom) {
const key = 'zashita_intake_stats';
const stats = JSON.parse(localStorage.getItem(key) || '[]');
stats.push({ mode, custom: custom||null, ts: new Date().toISOString() });
localStorage.setItem(key, JSON.stringify(stats));
renderStats();
}
function statGet() {
const raw = JSON.parse(localStorage.getItem('zashita_intake_stats') || '[]');
const counts = { novice:0, mid:0, pro:0, custom:0 };
raw.forEach(r => { if(counts[r.mode]!==undefined) counts[r.mode]++; else counts.custom++; });
return { counts, total: raw.length, customs: raw.filter(r=>r.mode==='custom').map(r=>r.custom) };
}
function renderStats() {
let el = document.getElementById('stats-pill');
if (!el) { el = document.createElement('div'); el.id='stats-pill'; el.className='stats-pill'; el.title='Нажать — очистить'; el.onclick=()=>{localStorage.removeItem('zashita_intake_stats');renderStats();}; document.body.appendChild(el); }
const s = statGet();
if (!s.total) { el.style.display='none'; return; }
el.style.display='block';
el.innerHTML = `<b>Intake-статистика</b> (${s.total})<br>`
+ `🙋 Новичок: ${s.counts.novice} · 📖 Средний: ${s.counts.mid}<br>`
+ `⚖️ Юрист: ${s.counts.pro} · ✏️ Другое: ${s.counts.custom}`
+ (s.customs.length ? `<br><span style="color:rgba(255,255,255,.5);font-size:10px">${s.customs.slice(-2).join(' / ')}</span>` : '');
}
/* ── КОНТЕНТ ПО РЕЖИМУ ── */
const MODES = {
novice: {
badge: '🙋 Режим: объясняем с нуля',
badgeCls: 'mode-novice',
ack: 'Хорошо, что сказали 💛 Буду рядом — объясню всё простым языком, без страшных слов. Если что-то непонятно — просто спросите, не стесняйтесь.',
introTail: 'Не пугайтесь —',
r1q: '«Агент несёт полную ответственность за качество выполненных работ перед конечным потребителем»',
r1: 'Смотрите: это значит, что если у клиента сломается мебель или он пожалуется — по этому пункту отвечаете <b>вы лично</b>, а не компания-заказчик. То есть возвраты и штрафы могут прийти на ваш карман. Это типовая ловушка — не переживайте, мы её аккуратно перепишем.',
r2q: '«Агент обязуется возместить Принципалу все финансовые потери, возникшие вследствие ненадлежащего исполнения обязательств»',
r2: 'О чём это говорит: вы соглашаетесь покрыть «все финансовые потери компании» — и <b>без верхней границы суммы</b>. По сути это открытый кошелёк. Звучит пугающе, понимаю — но от этого защититься просто, я покажу как.',
r3q: '«Агент выполняет работы лично, в установленные часы, на оборудовании Принципала, по его инструкциям»',
r3: 'Это значит что: договор назван агентским, но по описанию работы — он похож на трудовой. Налоговая вправе это заметить и <b>доначислить НДФЛ и взносы задним числом</b>. Звучит тревожно — но от этого реально защититься.',
lock: '🔒 Это только 3 момента из 12. Есть ещё — и там тоже важное. В полном разборе я объясню каждый пункт простым языком, скажу что именно нужно изменить и почему другая сторона обязана на это согласиться. <b>Вы уйдёте с чётким пониманием что подписываете — и уверенностью, что вас защитили</b> 💛',
forkQ: 'Чего бы вам хотелось? Объясню каждый путь — выберем вместе:'
},
mid: {
badge: '📖 Режим: по делу, без лишнего',
badgeCls: 'mode-mid',
ack: 'Принято. Работаем по делу — цитата из договора, риск, что делать. Без воды.',
introTail: 'Фиксируем критичные.',
r1q: '«Агент несёт полную ответственность за качество выполненных работ перед конечным потребителем»',
r1: '<b>Риск:</b> ответственность перед конечным потребителем переложена на вас. По ЗоЗПП ст. 429 — это влечёт прямые претензии и штрафы в ваш адрес, минуя Принципала. <b>Решение:</b> ограничить ответственность агента пределами вознаграждения.',
r2q: '«Агент обязуется возместить Принципалу все финансовые потери, возникшие вследствие ненадлежащего исполнения»',
r2: '<b>Риск:</b> неограниченная финансовая ответственность — ст. 330 ГК не требует устанавливать потолок, но без него сумма ничем не ограничена. <b>Решение:</b> добавить cap = сумма вознаграждения по договору.',
r3q: '«Агент выполняет работы лично, в установленные часы, на оборудовании Принципала, по его инструкциям»',
r3: '<b>Риск:</b> признаки трудовых отношений по ст. 19.1 ТК. При налоговой проверке — переквалификация и доначисление НДФЛ + взносов. <b>Решение:</b> переформулировать признаки самостоятельности.',
lock: '🔒 Ещё 9 рисков, из них 2 критичных — в полном заключении с нормами и готовыми формулировками.',
forkQ: 'Как будем действовать?'
},
pro: {
badge: '⚖️ Профессиональный режим',
badgeCls: 'mode-pro',
ack: 'Принял. Цитата → норма → квалификация → рекомендация. Поехали.',
introTail: 'Выявлено 5 критических.',
r1q: '«Агент несёт полную ответственность за качество выполненных работ перед конечным потребителем»',
r1: '<b>Квалификация:</b> прямое возложение ответственности исполнителя перед третьим лицом (потребителем) в нарушение ст. 4, 18, 29 ЗоЗПП — ответственность принципала не исключается, а дублируется. <b>Рекомендация:</b> п.1.1 изложить в редакции: «Агент несёт ответственность перед Принципалом в пределах суммы агентского вознаграждения».',
r2q: '«Агент обязуется возместить Принципалу все финансовые потери, возникшие вследствие ненадлежащего исполнения»',
r2: '<b>Квалификация:</b> неограниченная договорная ответственность, ст. 330333 ГК РФ. Судебная практика: без cap суд снижает по ст. 333 ГК, но только по заявлению. <b>Рекомендация:</b> установить cap = агентское вознаграждение × 2.',
r3q: '«Агент выполняет работы лично, в установленные часы, на оборудовании Принципала, по его инструкциям»',
r3: '<b>Квалификация:</b> признаки трудовых отношений по ст. 15, 19.1 ТК РФ: личное исполнение, режим рабочего времени, инструктаж, материально-техническое обеспечение. Риск: переквалификация + ст. 122 НК РФ (недоимка + пени + штраф 20%). <b>Рекомендация:</b> исключить нормы п.п. о личном исполнении и режиме.',
lock: '📋 Полное заключение: 12 рисков, нормативная база, альтернативные формулировки, протокол разногласий.',
forkQ: 'Стратегия:'
}
};
function setMode(mode) {
const custom = mode === 'custom' ? (document.getElementById('intake-custom').value.trim() || 'не указано') : null;
if (mode === 'custom' && !custom) { document.getElementById('intake-custom').focus(); return; }
statTrack(mode, custom);
const cfg = MODES[mode] || MODES.mid;
// badge
const badge = document.getElementById('elena-mode-badge');
badge.innerHTML = `<span class="mode-badge ${cfg.badgeCls}">${cfg.badge}</span>`;
// step2 content
document.getElementById('el-ack').innerHTML = custom
? `Понял: «${custom}». Подстроюсь под вас — буду объяснять по ходу.`
: cfg.ack;
document.getElementById('el-intro-tail').textContent = cfg.introTail;
document.getElementById('r1-quote').textContent = cfg.r1q;
document.getElementById('r1-text').innerHTML = cfg.r1;
document.getElementById('r2-quote').textContent = cfg.r2q;
document.getElementById('r2-text').innerHTML = cfg.r2;
document.getElementById('r3-quote').textContent = cfg.r3q;
document.getElementById('r3-text').innerHTML = cfg.r3;
document.getElementById('el-lock').innerHTML = cfg.lock;
document.getElementById('el-fork-q').textContent = cfg.forkQ;
// show upload step
document.getElementById('el-step1').style.display = 'none';
document.getElementById('el-step-upload').style.display = 'block';
window.scrollTo(0, 0);
}
/* ── ТИПЫ ДОГОВОРОВ ── */
const CTYPES = {
agent: {
emoji:'🤝', name:'агентский договор',
comment:'Агент действует от имени или за счёт другой стороны. Главные риски здесь — объём ответственности перед третьими лицами и признаки трудовых отношений.',
delivRec:'partner',
intro:'С учётом выявленных нарушений потенциальный ущерб — от <b>120 000 до 350 000 ₽</b>: налоговые доначисления, штрафы от потребителей, неограниченная ответственность перед Принципалом. Три варианта:',
delivDesc:{
protocol:'Список требований с нормой закона под каждым. Не «хочу изменить», а «данная редакция противоречит ст. 330 ГК». Контрагенту придётся либо согласиться, либо объяснить почему закон неважен.',
redact:'Новая редакция каждого спорного пункта + объяснение логики изменений. Контрагент видит аргументы, а не давление — меньше возражений, быстрее к подписи.',
clean:'Все спорные пункты переписаны и готовы к подписанию — без пояснений для контрагента. Подходит если другая сторона уже согласна на правки.',
partner:'Договор написан так, чтобы обе стороны видели свою выгоду. Контрагент сам не захочет его менять — его интересы уже учтены. Подписывают без торга 💛'
}
},
realty: {
emoji:'🏠', name:'договор купли-продажи недвижимости',
comment:'В недвижимости цена ошибки особенно высока. Проверяю обременения, условия передачи объекта и ответственность за скрытые дефекты.',
delivRec:'partner',
intro:'В сделках с недвижимостью любая неточность стоит дорого — вплоть до <b>потери аванса или расторжения сделки</b>. Три варианта:',
delivDesc:{
protocol:'Фиксируем спорные условия по передаче, дефектам и срокам — со ссылками. Основа для предметного разговора. Хорошо работает с частными продавцами.',
redact:'Переписываем проблемные пункты с объяснением зачем. Особенно эффективно с застройщиком — они реагируют на аргументы, а не на просьбы.',
clean:'Договор полностью переписан и готов к подписанию. Все риски закрыты, формулировки чёткие.',
partner:'Договор сбалансирован: другая сторона видит, что её интересы учтены. Сделки закрываются быстрее и без претензий после регистрации 💛'
}
},
auto: {
emoji:'🚗', name:'договор купли-продажи автомобиля',
comment:'Смотрю на гарантии состояния, скрытые дефекты и условия передачи.',
delivRec:'clean',
intro:'Главные риски — <b>скрытые дефекты без гарантии возврата</b>. Потенциальные потери: от стоимости ремонта до полной цены автомобиля. Три пути:',
delivDesc:{
protocol:'Гарантии состояния, ответственность за скрытые дефекты, порядок расторжения — со ссылками. Основа для переговоров до подписания.',
redact:'Новая редакция с объяснением зачем. Продавец понимает логику — реже отказывает. Подходит если продавец настроен на диалог.',
clean:'Договор полностью готов к подписанию — скрытые дефекты закрыты, условия передачи чёткие. Приходите с текстом, а не со списком претензий 💛',
partner:'Вариант, где продавец тоже видит свою защиту. Снижает напряжение — подписывают быстро и без претензий.'
}
},
construction: {
emoji:'🛋️', name:'договор подряда',
comment:'Договор подряда — здесь критичны сроки, критерии качества результата и ответственность за задержки.',
delivRec:'redact',
intro:'Основные риски — <b>штрафы за просрочку без верхней границы</b> и размытые критерии качества. Потенциальные потери: от устранения недостатков до полной переделки. Три варианта:',
delivDesc:{
protocol:'Требования к срокам, критериям приёмки и порядку устранения дефектов — с нормами. Заказчику сложнее отказать без обоснования.',
redact:'Переписываем спорные пункты, объясняем зачем. Обе стороны понимают что подписывают — меньше споров при сдаче. Оптимальный выбор для подряда 💛',
clean:'Договор переписан и готов к подписанию. Сроки зафиксированы, критерии приёмки чёткие, ответственность ограничена.',
partner:'Договор учитывает риски заказчика и подрядчика. Заказчик видит защиту своих интересов — соглашается быстрее.'
}
},
services: {
emoji:'🎯', name:'договор оказания услуг',
comment:'В услугах часто размыт сам результат и ответственность исполнителя.',
delivRec:'redact',
intro:'Главные риски — <b>размытый результат и ответственность за то, что не зависит от вас</b>. Потенциальные потери: от возврата всей суммы до штрафных санкций. Три пути:',
delivDesc:{
protocol:'Чёткие требования к тому, что считается результатом, срокам и основаниям для расторжения. Снимает частые точки споров до старта работ.',
redact:'Новая редакция с объяснением логики. Заказчик понимает условия — меньше конфликтов при сдаче. Лучший выбор для услуг 💛',
clean:'Договор полностью готов к подписанию — результат зафиксирован, критерии приёмки прописаны, ответственность ограничена.',
partner:'Договор балансирует интересы исполнителя и заказчика. Работают без конфликтов и платят без задержек.'
}
},
labor: {
emoji:'📋', name:'трудовой договор',
comment:'Трудовой договор — смотрю на режим работы, зоны ответственности и условия расторжения.',
delivRec:'consult',
intro:'Потенциальные потери — <b>от нескольких окладов до судебного восстановления</b>. Работодатель может переложить ответственность сверх нормы ТК. Три варианта:',
delivDesc:{
protocol:'Пункты, противоречащие ТК, с нормами. Основа для переговоров с HR: работодатель видит закон, а не просьбу. Большинство соглашаются на правки 💛',
redact:'Новые формулировки спорных условий с объяснением. Работодатель понимает запрос — проще найти компромисс.',
clean:'Договор приведён в соответствие с ТК и готов к подписанию. Ваши права зафиксированы.',
partner:'Договор учитывает интересы работника и работодателя. Подписывают без споров и работают без неожиданных претензий.'
}
},
loan: {
emoji:'💰', name:'договор займа',
comment:'Ключевые риски займа — скрытые проценты, штрафные санкции и условия досрочного требования.',
delivRec:'redact',
intro:'При наихудшем сценарии <b>задолженность вырастет в несколько раз</b> от первоначальной суммы. Скрытые проценты и неограниченные штрафы — основной инструмент давления. Три пути:',
delivDesc:{
protocol:'Требования по процентам, порядку штрафов и условиям погашения — со ссылками. Кредитору сложнее отказать без объяснений.',
redact:'Новая редакция ключевых пунктов с объяснением — снимает инструменты давления на заёмщика. Оптимальный выбор для займов с физлицами и МФО 💛',
clean:'Договор готов к подписанию. Проценты зафиксированы, штрафы ограничены, условия прозрачны.',
partner:'Договор сбалансирован: кредитор защищён, заёмщик знает точные условия без скрытых ловушек.'
}
},
supply: {
emoji:'📦', name:'договор поставки',
comment:'Поставка — проверяю условия приёмки, ответственность за качество и что происходит при просрочке.',
delivRec:'reply',
intro:'Основные риски — <b>неограниченная неустойка за просрочку и ответственность за качество без потолка</b>. Потенциальные потери: от стоимости партии до срыва цепочки поставок. Три варианта:',
delivDesc:{
protocol:'Требования по приёмке, критериям качества и ограничению неустойки — со ссылками. Контрагент видит закон, а не просьбу.',
redact:'Новая редакция спорных условий с объяснением. Обе стороны знают правила до старта — меньше споров при исполнении 💛',
clean:'Договор готов к подписанию. Порядок приёмки чёткий, неустойка ограничена, ответственность зафиксирована.',
partner:'Договор учитывает интересы поставщика и покупателя. Подписывают быстро и работают без задержек.'
}
},
other: {
emoji:'📄', name:'договор',
comment:'Изучила структуру. Нашла пункты, которые стоит проверить внимательнее.',
delivRec:'consult',
intro:'Формальные нарушения дешевле устранить <b>до подписания</b>, чем оспаривать потом. Три варианта:',
delivDesc:{
protocol:'Список требований с правовым обоснованием. Основа для переговоров если знаете что именно изменить.',
redact:'Новая редакция спорных пунктов с объяснением. Контрагент понимает зачем — меньше возражений.',
clean:'Договор полностью готов к подписанию. Риски закрыты, формулировки чёткие 💛',
partner:'Договор учитывает интересы обеих сторон. Подписывают без торга и выполняют без претензий.'
}
}
};
const CTYPES_KEYWORDS = {
agent: ['агент','принципал','агентск','от имени и за счёт','за счёт принципала'],
realty: ['квартир','недвижим','жиль','комнат','нежилое','земельн','ипотек','объект недвижим','жилой дом'],
auto: ['автомобил','транспортн средств','машин','птс','пробег','кузов'],
construction: ['подряд','мебел','изготовл','монтаж','строител','ремонт','подрядчик','заказчик','результат работ'],
services: ['оказани','услуг','исполнител','заказчик','сервис','консульт','разработ','дизайн'],
labor: ['трудов','работодател','работник','должност','оклад','отпуск','увольнен','рабочее время'],
loan: ['займ','заём','кредит','процент годов','долг','заемщик','заёмщик','сумма займа'],
supply: ['поставщик','покупател','товар','партия','поставка','отгрузк','накладн']
};
let _demoCtypeIdx = 0;
const _demoSeq = ['agent','realty','auto','construction','services','labor','loan','supply'];
function detectCtype(text) {
if (text && text.length > 30) {
const t = text.toLowerCase();
for (const [key, kws] of Object.entries(CTYPES_KEYWORDS)) {
if (kws.some(kw => t.includes(kw))) return key;
}
return 'other';
}
// демо-режим: каждый клик — новый тип
const key = _demoSeq[_demoCtypeIdx % _demoSeq.length];
_demoCtypeIdx++;
return key;
}
function showResults(ctypeKey) {
_curCtypeKey = ctypeKey || 'other';
// спрятать предыдущие шаги на случай прямого вызова
['el-step-upload','el-step-scan','el-step1'].forEach(id => {
const el = document.getElementById(id);
if (el) el.style.display = 'none';
});
const ctype = CTYPES[ctypeKey] || CTYPES.other;
// тип договора в первой реплике
document.getElementById('el-scan-type').textContent = ctype.emoji + ' ' + ctype.name;
const noteEl = document.getElementById('el-ctype-note');
noteEl.textContent = ctype.comment;
noteEl.style.display = ctype.comment ? 'block' : 'none';
// убрать старую подсветку, поставить новую
document.querySelectorAll('.deliv').forEach(el => {
el.classList.remove('deliv-highlighted');
});
// вступление Елены (оценка ущерба)
const pitchEl = document.getElementById('el-ctype-pitch');
const pitchMsg = document.getElementById('el-pitch-msg');
if (ctype.intro) {
pitchEl.innerHTML = ctype.intro;
pitchMsg.style.display = '';
} else {
pitchMsg.style.display = 'none';
}
// описания на карточках
if (ctype.delivDesc) {
['protocol','redact','clean','partner'].forEach(key => {
const el = document.getElementById('dd2-' + key);
if (el && ctype.delivDesc[key]) el.textContent = ctype.delivDesc[key];
});
}
// убрать badge у всех, потом поставить на нужный
document.querySelectorAll('.deliv-badge').forEach(b => b.style.display = 'none');
if (ctype.delivRec) {
const recEl = document.getElementById('deliv-' + ctype.delivRec);
if (recEl) {
recEl.classList.add('deliv-highlighted');
let badge = recEl.querySelector('.deliv-badge');
if (!badge) {
badge = document.createElement('span');
badge.className = 'deliv-badge';
recEl.appendChild(badge);
}
badge.textContent = 'Рекомендуем';
badge.style.display = '';
}
}
// показать результаты
document.getElementById('el-step-scan').style.display = 'none';
document.getElementById('el-step2').style.display = 'block';
document.getElementById('el-actbar').style.display = 'flex';
document.getElementById('el-step2').scrollIntoView({ behavior: 'smooth' });
}
/* ── СКАНИРОВАНИЕ ── */
const SCAN_PHRASES = [
'Читаю договор...',
'Проверяю условия сторон...',
'Ищу скрытые риски...',
'Анализирую ответственность...',
'Оцениваю сроки и санкции...',
'Формирую заключение...'
];
function startScan() {
const text = (document.getElementById('el-paste').value || '').trim();
const ctypeKey = detectCtype(text);
document.getElementById('el-step-upload').style.display = 'none';
document.getElementById('el-step-scan').style.display = 'block';
window.scrollTo(0, 0);
let i = 0;
const lbl = document.getElementById('scan-label');
const interval = setInterval(() => {
i = (i + 1) % SCAN_PHRASES.length;
lbl.style.opacity = '0';
setTimeout(() => { lbl.textContent = SCAN_PHRASES[i]; lbl.style.opacity = '1'; }, 180);
}, 800);
setTimeout(() => {
clearInterval(interval);
lbl.style.opacity = '0';
setTimeout(() => { showResults(ctypeKey); }, 200);
}, 4000);
}
/* ── ВЫБОР DELIVERABLE ── */
const DELIVS = {
protocol: {
ttl:'Протокол разногласий', h2:'Протокол разногласий по вашему договору',
p1:['1 490 ₽','Без комментариев','Все спорные пункты — готовый список изменений без пояснений'],
p2:['2 190 ₽','С обоснованием','Те же пункты + правовое обоснование каждого требования'],
p3:['от 3 490 ₽','Партнёрская версия','Протокол с формулировками, выгодными обеим сторонам + Елена сопровождает'],
pitch:'Когда другая сторона получает просто список требований без объяснений — первая реакция почти всегда «нет». Это не злой умысел, так работает психология переговоров.<br><br><b>С обоснованием</b> каждое требование превращается из вашей «хотелки» в правовую норму. Контрагент уже не может просто отказать — ему придётся объяснить, почему закон не имеет значения. Практически никто не идёт на это.<br><br><b>Партнёрская версия</b> — Елена составляет текст так, чтобы контрагент сам хотел согласиться. Договор, где обе стороны видят свою выгоду, подписывают быстро и выполняют честно 💛',
def:'2 190 ₽'
},
redact: {
ttl:'Переработка с комментариями', h2:'Переработанный договор по вашему случаю',
p1:['1 990 ₽','Без комментариев','Новая редакция всех спорных пунктов — чистый текст без объяснений'],
p2:['2 990 ₽','С комментариями','Та же редакция + пояснение что изменено и зачем по каждому пункту'],
p3:['от 4 490 ₽','Партнёрская редакция','Договор учитывает интересы обеих сторон + Елена сопровождает до подписи'],
pitch:'Молча прийти с переделанным договором — контрагент чувствует давление и начинает защищаться. Переписка растягивается на недели.<br><br><b>С комментариями</b> вы открываете диалог: вот что изменено, вот почему это справедливо. Люди принимают изменения, когда понимают логику. Меньше раундов — быстрее к подписи.<br><br><b>Партнёрская редакция</b> — Елена рядом до финала. Если контрагент выдвигает встречные возражения, она держит вашу позицию и не даёт потерять то, что важно 💛',
def:'2 990 ₽'
},
clean: {
ttl:'Чистая редакция', h2:'Договор готов к подписанию',
p1:['1 790 ₽','Чистая редакция','Все пункты переписаны — договор готов к подписанию, без пояснений'],
p2:['2 690 ₽','Редакция с пояснениями','Тот же результат + объяснение каждого изменения для вас и контрагента'],
p3:['от 3 990 ₽','Партнёрская редакция','Чистый договор с балансом интересов + Елена рядом на переговорах'],
pitch:'Договор уже защищает вас — осталось только подписать. Но у контрагента будут вопросы: «почему именно так?» Без ответов на них переговоры затягиваются.<br><br><b>С пояснениями</b> он получает и текст, и понимание: что изменено, почему это честно. Вопросы снимаются до того, как возникли. Путь к подписи становится короче.<br><br><b>Партнёрская редакция</b> — Елена пишет так, что контрагент видит баланс, а не давление. Такие договоры подписывают без торга и выполняют без претензий 💛',
def:'2 690 ₽'
},
partner: {
ttl:'Партнёрская редакция', h2:'Договор, который устроит обе стороны',
p1:['2 990 ₽','Партнёрская редакция','Все пункты переработаны с учётом интересов обеих сторон, без сопровождения'],
p2:['3 990 ₽','Редакция с обоснованием','Тот же результат + аргументы для переговоров по каждому пункту'],
p3:['от 5 900 ₽','Полное сопровождение','Договор + Елена ведёт переписку и переговоры до финальной подписи'],
pitch:'Партнёрский подход — это не уступки. Это когда текст уже содержит ответ на главный вопрос контрагента: «почему мне это выгодно?». Когда ответ уже в договоре — не о чём торговаться.<br><br><b>С обоснованием</b> у вас есть готовые аргументы на любые встречные возражения. Вы входите в переговоры спокойно — Елена уже предусмотрела ходы за другую сторону.<br><br><b>Полное сопровождение</b> — Елена ведёт переписку сама, держит вашу позицию и доводит до финальной подписи. Ваша задача: согласовать итоговый текст 💛',
def:'3 990 ₽'
},
consult: {
ttl:'Консультация по договору', h2:'Разбор договора — ответы на ваши вопросы',
p1:['790 ₽','Базовый разбор','Задаёте до 5 вопросов по договору — AI отвечает развёрнуто по каждому пункту в течение 2 часов'],
p2:['1 490 ₽','Полный разбор','AI анализирует весь договор, находит все риски и отвечает на любые ваши вопросы без ограничений'],
p3:['от 2 490 ₽','Разбор + заключение','Полный AI-анализ + письменное заключение с перечнем рисков и конкретными рекомендациями'],
pitch:'Иногда важнее не документ, а понять — что именно подписываешь и почему это опасно.<br><br><b>Консультация в чате</b> — конкретные вопросы, чёткие ответы письменно. Всё сохраняется, можно перечитать.<br><br><b>Голосовой разбор</b> — живой разговор, юрист читает договор вместе с вами. 30 минут меняют картину полностью.<br><br><b>С заключением</b> — получаете и понимание, и документ на руках. Можно показать другой стороне как независимое правовое мнение 💛',
def:'1 490 ₽'
},
reply: {
ttl:'Ответ контрагенту', h2:'Ответ на возражения другой стороны',
p1:['990 ₽','Шаблон ответа','Готовый текст ответа на конкретный отказ — с вашей правовой позицией и нужным тоном'],
p2:['1 690 ₽','Развёрнутый ответ','Тот же ответ + аргументы на 23 хода вперёд: закрываем типичные встречные возражения заранее'],
p3:['от 2 990 ₽','Переговорное сопровождение','Елена ведёт переписку с контрагентом вместо вас — до момента согласия или официального отказа'],
pitch:'Когда контрагент отказывает — первый импульс: уступить или спорить наугад. Оба пути проигрышные.<br><br><b>Шаблон ответа</b> — правильная позиция в нужном тоне. Со ссылкой на норму. Контрагент понимает: вы знаете о чём говорите.<br><br><b>Развёрнутый ответ</b> — мы предусматриваем их следующий ход заранее. Вы входите в переписку с ответами на возражения, которые ещё не прозвучали.<br><br><b>Сопровождение</b> — Елена ведёт всю переписку. Вы только согласуете финальные ходы 💛',
def:'1 690 ₽'
}
};
function selectDeliv(key) {
_selDeliv = key;
const d = DELIVS[key];
document.getElementById('pay-ttl').textContent = d.ttl;
document.getElementById('pay-h2').textContent = d.h2;
document.getElementById('p1-price').textContent = d.p1[0];
document.getElementById('p1-name').textContent = d.p1[1];
document.getElementById('p1-desc').textContent = d.p1[2];
document.getElementById('p2-price').textContent = d.p2[0];
document.getElementById('p2-name').textContent = d.p2[1];
document.getElementById('p2-desc').textContent = d.p2[2];
document.getElementById('p3-price').textContent = d.p3[0];
document.getElementById('p3-name').textContent = d.p3[1];
document.getElementById('p3-desc').textContent = d.p3[2];
document.getElementById('pay-pitch').innerHTML = d.pitch;
// субтитр: тип договора из детекции
const ct = CTYPES[_curCtypeKey] || CTYPES.other;
const ctName = ct.name.charAt(0).toUpperCase() + ct.name.slice(1);
document.getElementById('pay-sub').textContent = ct.emoji + ' ' + ctName + ' · цена под ваш случай';
// сбросить выбор на средний план и показать инструкции
selectPlan(2);
go('pay');
}
/* ── ТОСТ ── */
let _toastT;
function toast(msg){
let el=document.getElementById('toast');
if(!el){el=document.createElement('div');el.id='toast';el.className='toast';document.body.appendChild(el);}
el.innerHTML='<span class="tk">✓</span>'+msg;
el.classList.add('show'); clearTimeout(_toastT);
_toastT=setTimeout(()=>el.classList.remove('show'),2600);
}
function go(id){document.querySelectorAll('.screen').forEach(s=>s.classList.toggle('on',s.id===id));window.scrollTo(0,0);}
/* ── СВОЙ ЗАПРОС ── */
let _customOpen = false;
let _voiceRec = null;
function toggleCustomReq() {
_customOpen = !_customOpen;
const area = document.getElementById('custom-req-area');
const btn = document.getElementById('custom-req-btn');
area.style.display = _customOpen ? 'block' : 'none';
btn.textContent = _customOpen ? '✕ Закрыть' : '✏️ Нужен другой формат? Опишите задачу →';
if (_customOpen) {
area.scrollIntoView({ behavior: 'smooth' });
setTimeout(() => document.getElementById('custom-text').focus(), 350);
}
}
function toggleVoice() {
const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
const btn = document.getElementById('custom-voice-btn');
if (!SR) { btn.title='Не поддерживается — введите текстом'; btn.style.opacity='.4'; return; }
if (_voiceRec) { _voiceRec.stop(); return; }
_voiceRec = new SR();
_voiceRec.lang = 'ru-RU';
_voiceRec.continuous = true;
_voiceRec.interimResults = true;
const ta = document.getElementById('custom-text');
const base = ta.value;
_voiceRec.onresult = e => {
let t = '';
for (let i = e.resultIndex; i < e.results.length; i++) t += e.results[i][0].transcript;
ta.value = (base ? base + ' ' : '') + t;
};
_voiceRec.onerror = _voiceRec.onend = () => {
_voiceRec = null;
btn.classList.remove('recording');
btn.innerHTML = '🎤';
};
_voiceRec.start();
btn.classList.add('recording');
btn.innerHTML = '⏹';
}
function submitCustomReq() {
const text = (document.getElementById('custom-text').value || '').trim();
if (!text) { document.getElementById('custom-text').focus(); return; }
if (_voiceRec) { _voiceRec.stop(); }
// Сохраняем в localStorage для анализа
const key = 'zashita_custom_delivs';
const arr = JSON.parse(localStorage.getItem(key) || '[]');
arr.push({
ts: new Date().toISOString(),
ctype: (document.getElementById('el-scan-type') || {}).textContent || '',
text: text
});
localStorage.setItem(key, JSON.stringify(arr));
renderCustomStats();
// Скрываем форму, показываем подтверждение
document.querySelector('.custom-input-block').style.display = 'none';
document.getElementById('custom-req-btn').style.display = 'none';
const short = text.length > 90 ? text.slice(0, 90) + '…' : text;
document.getElementById('custom-confirm-text').innerHTML =
`Записала! Передам юристу:<br><b>«${short}»</b><br><br>Свяжемся с вами в течение 24 часов. Обычно — быстрее 🙂`;
const conf = document.getElementById('custom-confirm');
conf.style.display = 'flex';
conf.scrollIntoView({ behavior: 'smooth' });
}
function renderCustomStats() {
const arr = JSON.parse(localStorage.getItem('zashita_custom_delivs') || '[]');
let el = document.getElementById('custom-stats-pill');
if (!arr.length) { if (el) el.style.display = 'none'; return; }
if (!el) {
el = document.createElement('div'); el.id = 'custom-stats-pill';
el.className = 'stats-pill'; el.style.bottom = '52px';
el.title = 'Открыть аналитику';
el.onclick = () => { renderCustomAdmin(); go('custom-admin'); };
document.body.appendChild(el);
}
el.style.display = 'block';
el.innerHTML = `<b>Свои запросы (${arr.length})</b><br>`
+ arr.slice(-3).map(r =>
`<span style="color:rgba(255,255,255,.6);font-size:10px">· ${(r.ctype||'').trim().slice(0,20)}${(r.text||'').slice(0,38)}</span>`
).join('<br>');
}
/* ── ПОДРОБНЫЕ ИНСТРУКЦИИ ПО ПЛАНУ ── */
let _selDeliv = 'protocol';
let _selPlan = 2;
let _curCtypeKey = 'other';
const PLAN_PITCH = {
protocol: {
1: `<b>Что вы получите</b><br>Готовый протокол разногласий — наши формулировки вместо ваших проблемных пунктов. Чистый файл, без пояснений.<br><br><b>Как использовать:</b><div class="pi-step"><span class="pi-n">1</span><span>Отправьте файл контрагенту — мессенджер, e-mail или распечатка.</span></div><div class="pi-step"><span class="pi-n">2</span><span>Добавьте текст: <i>«Направляю протокол разногласий к договору. Прошу подтвердить принятие или предоставить мотивированный отказ в течение 5 рабочих дней».</i></span></div><div class="pi-step"><span class="pi-n">3</span><span>Если откажут без обоснования — потребуйте письменный мотивированный ответ. Чаще всего его не дают, и переговоры возобновляются на ваших условиях.</span></div><div class="pi-meta">⏱ Готово через 24 часа · При вопросах пишите Елене в чат</div>`,
2: `<b>Что вы получите</b><br>Протокол разногласий + к каждому пункту — ссылка на норму закона. Это превращает ваши требования из «хотелок» в правовые обязанности.<br><br><b>Как использовать:</b><div class="pi-step"><span class="pi-n">1</span><span>Отправьте протокол с сопроводительным текстом: <i>«Каждая позиция основана на нормах действующего законодательства, указанных в документе».</i></span></div><div class="pi-step"><span class="pi-n">2</span><span>Если возражают — один вопрос: <i>«Укажите норму права, на основании которой вы отклоняете это требование».</i> Практически никто не отвечает — это уже победа.</span></div><div class="pi-step"><span class="pi-n">3</span><span>Если сложный ответ всё же пришёл — пришлите Елене, она подготовит вашу следующую реплику.</span></div><div class="pi-meta">⏱ Готово через 24 часа · Поддержка по ответам контрагента включена</div>`,
3: `<b>Что вы получите</b><br>Протокол, сформулированный так, чтобы контрагент сам захотел согласиться — без ощущения давления с вашей стороны.<br><br><span class="pi-tag pi-incl">✓ Включено</span><b>Что входит:</b><div class="pi-step"><span class="pi-n">1</span><span>Протокол с формулировками win-win по всем спорным пунктам.</span></div><div class="pi-step"><span class="pi-n">2</span><span>Готовое сопроводительное письмо от вашего имени.</span></div><div class="pi-step"><span class="pi-n">3</span><span>Елена отвечает на любые встречные возражения контрагента — вы пересылаете их нам, мы готовим вашу реплику.</span></div><div class="pi-step"><span class="pi-n">4</span><span>Помогаем зафиксировать итоговую редакцию — до финальной подписи.</span></div><div class="pi-meta">⏱ Первый ответ: 4 часа · Финал: 4872 часа · Елена рядом на каждом шаге 💛</div>`
},
redact: {
1: `<b>Что вы получите</b><br>Новая редакция всех спорных пунктов договора — чистый текст, готовый заменить проблемные формулировки. Без пояснений.<br><br><b>Как использовать:</b><div class="pi-step"><span class="pi-n">1</span><span>Откройте оригинал договора. Замените помеченные пункты на наши формулировки.</span></div><div class="pi-step"><span class="pi-n">2</span><span>Направьте обновлённый договор контрагенту: <i>«Прошу рассмотреть актуализированную редакцию договора и подтвердить согласие».</i></span></div><div class="pi-step"><span class="pi-n">3</span><span>Если контрагент запросит объяснения — закажите версию «С комментариями» или обратитесь к Елене отдельно.</span></div><div class="pi-meta">⏱ Готово через 24 часа · Подходит если контрагент уже готов к диалогу</div>`,
2: `<b>Что вы получите</b><br>Переработанный договор + к каждому изменённому пункту — короткое пояснение: что изменено, почему это справедливо, на какой закон опирается.<br><br><b>Как использовать:</b><div class="pi-step"><span class="pi-n">1</span><span>Отправьте документ контрагенту со словами: <i>«К каждому изменению приложено обоснование — это поможет нам быстрее прийти к согласию».</i></span></div><div class="pi-step"><span class="pi-n">2</span><span>Если контрагент не согласен с конкретным пунктом — пришлите его возражение Елене. Она подготовит контраргумент.</span></div><div class="pi-step"><span class="pi-n">3</span><span>Комментарии снимают большинство вопросов до того, как они превращаются в споры — переписка сокращается в разы.</span></div><div class="pi-meta">⏱ Готово через 24 часа · По опыту: 70% договоров с комментариями подписывают с первого раунда</div>`,
3: `<b>Что вы получите</b><br>Договор, переработанный с учётом интересов обеих сторон — контрагент видит не давление, а честное предложение. Плюс Елена рядом до финала.<br><br><span class="pi-tag pi-incl">✓ Включено</span><b>Что входит:</b><div class="pi-step"><span class="pi-n">1</span><span>Полная переработка всех спорных пунктов — с балансом интересов.</span></div><div class="pi-step"><span class="pi-n">2</span><span>Готовое сопроводительное письмо с нужной тональностью.</span></div><div class="pi-step"><span class="pi-n">3</span><span>Елена держит вашу позицию при встречных возражениях — вы не теряете важное в процессе переговоров.</span></div><div class="pi-step"><span class="pi-n">4</span><span>Финальная сверка перед подписанием: убеждаемся, что итоговая редакция вас защищает.</span></div><div class="pi-meta">⏱ Первый ответ: 4 часа · Поддержка до подписи включена 💛</div>`
},
clean: {
1: `<b>Что вы получите</b><br>Договор с переписанными спорными пунктами — готов к подписанию. Никаких пояснений, только чистый текст.<br><br><b>Как использовать:</b><div class="pi-step"><span class="pi-n">1</span><span>Получаете файл → сравниваете с оригиналом по выделенным пунктам → убеждаетесь, что всё устраивает.</span></div><div class="pi-step"><span class="pi-n">2</span><span>Направляете контрагенту: <i>«Предлагаю подписать актуальную редакцию договора».</i></span></div><div class="pi-step"><span class="pi-n">3</span><span>Если контрагент спросит «почему изменено?» — вы можете дозаказать пояснения к уже готовому тексту. Или воспользоваться версией с обоснованием сразу.</span></div><div class="pi-meta">⏱ Готово через 24 часа · Подходит если контрагент уже согласен на изменения</div>`,
2: `<b>Что вы получите</b><br>Готовый к подписанию договор + пояснения к каждому изменению — для вас и для контрагента. Вы понимаете каждый пункт, контрагент понимает логику.<br><br><b>Как использовать:</b><div class="pi-step"><span class="pi-n">1</span><span>Изучите пояснения сами — убедитесь, что всё отражает ваши интересы.</span></div><div class="pi-step"><span class="pi-n">2</span><span>Отправьте контрагенту договор вместе с пояснительной частью: <i>«К каждому изменению есть обоснование — посмотрите, это справедливо для обеих сторон».</i></span></div><div class="pi-step"><span class="pi-n">3</span><span>Вопросов по тексту практически не остаётся — путь к подписи короткий.</span></div><div class="pi-step"><span class="pi-n">4</span><span>Если всё же есть спорный момент — напишите Елене, она поможет с ответом.</span></div><div class="pi-meta">⏱ Готово через 24 часа · Пояснения снимают 80% возражений на старте</div>`,
3: `<b>Что вы получите</b><br>Договор с балансом интересов, где контрагент видит свою выгоду — и соглашается без торга. Плюс Елена ведёт вас до подписи.<br><br><span class="pi-tag pi-incl">✓ Включено</span><b>Что входит:</b><div class="pi-step"><span class="pi-n">1</span><span>Договор переписан так, чтобы обе стороны видели: условия честные.</span></div><div class="pi-step"><span class="pi-n">2</span><span>Сопроводительное письмо с нужной тональностью для переговоров.</span></div><div class="pi-step"><span class="pi-n">3</span><span>Если контрагент возражает — Елена готовит ответ за вас. Вы только согласуете финальный текст.</span></div><div class="pi-step"><span class="pi-n">4</span><span>Перед подписанием — финальная проверка: убеждаемся, что ничего важного не потеряно в процессе переговоров.</span></div><div class="pi-meta">⏱ Первый ответ: 4 часа · Договоры с балансом подписывают и выполняют честно 💛</div>`
},
consult: {
1: `<b>Что вы получите</b><br>Письменный разбор: задаёте до 5 вопросов по договору — AI отвечает на каждый развёрнуто в течение 2 часов.<br><br><b>Как работает:</b><div class="pi-step"><span class="pi-n">1</span><span>После оплаты Елена откроет чат и пришлёт инструкцию.</span></div><div class="pi-step"><span class="pi-n">2</span><span>Отправляете текст договора + список вопросов (или пишете «найди риски сам»).</span></div><div class="pi-step"><span class="pi-n">3</span><span>AI разбирает каждый вопрос письменно — конкретно, со ссылкой на закон и рекомендацией.</span></div><div class="pi-step"><span class="pi-n">4</span><span>Переписку можно сохранить и использовать в переговорах.</span></div><div class="pi-meta">⏱ Ответ в течение 2 часов · Подходит если есть конкретные вопросы</div>`,
2: `<b>Что вы получите</b><br>Полный AI-разбор всего договора: все риски, проблемные пункты, ответы на любые вопросы без ограничений.<br><br><b>Как работает:</b><div class="pi-step"><span class="pi-n">1</span><span>После оплаты Елена откроет чат.</span></div><div class="pi-step"><span class="pi-n">2</span><span>Отправляете договор — AI сам проходит весь текст и находит все риски.</span></div><div class="pi-step"><span class="pi-n">3</span><span>Задаёте любые вопросы — AI отвечает конкретно по вашей ситуации. Без ограничений по количеству.</span></div><div class="pi-step"><span class="pi-n">4</span><span>Понимаете что подписываете — и что делать дальше.</span></div><div class="pi-meta">⏱ Первый ответ в течение 2 часов · Вопросы без ограничений</div>`,
3: `<b>Что вы получите</b><br>Полный AI-анализ + письменное заключение: перечень всех рисков, конкретные рекомендации, ссылки на нормы закона.<br><br><span class="pi-tag pi-incl">✓ Включено</span><b>Что входит:</b><div class="pi-step"><span class="pi-n">1</span><span>AI проходит весь договор и находит все риски — критичные, средние, незначительные.</span></div><div class="pi-step"><span class="pi-n">2</span><span>Отвечает на ваши вопросы без ограничений — по каждому пункту, по вашей ситуации.</span></div><div class="pi-step"><span class="pi-n">3</span><span>Письменное заключение: риски, рекомендации, нормы закона — документ у вас на руках.</span></div><div class="pi-step"><span class="pi-n">4</span><span>Заключение можно показать другой стороне как независимую экспертизу.</span></div><div class="pi-meta">⏱ Разбор в течение 2 часов · Заключение: в течение 24 часов 💛</div>`
},
reply: {
1: `<b>Что вы получите</b><br>Готовый текст ответа на конкретный отказ или возражение контрагента — с вашей правовой позицией, в нужном тоне.<br><br><b>Как использовать:</b><div class="pi-step"><span class="pi-n">1</span><span>Пришлите нам текст возражения контрагента и ваш договор.</span></div><div class="pi-step"><span class="pi-n">2</span><span>Юрист составляет ответ: спокойный тон + чёткая позиция + ссылка на норму права.</span></div><div class="pi-step"><span class="pi-n">3</span><span>Отправляете контрагенту без изменений или адаптируете под свой стиль.</span></div><div class="pi-step"><span class="pi-n">4</span><span>Такой ответ показывает: вы знаете о чём говорите. Большинство контрагентов после этого соглашаются.</span></div><div class="pi-meta">⏱ Готово через 12 часов · Работает на любом этапе переговоров</div>`,
2: `<b>Что вы получите</b><br>Развёрнутый ответ + аргументы на 23 шага вперёд: мы предусматриваем их следующие возражения и закрываем их заранее.<br><br><b>Как использовать:</b><div class="pi-step"><span class="pi-n">1</span><span>Пришлите текст возражения контрагента и все предыдущие сообщения по переговорам.</span></div><div class="pi-step"><span class="pi-n">2</span><span>Юрист анализирует всю цепочку и составляет ответ с закрытием типичных контраргументов.</span></div><div class="pi-step"><span class="pi-n">3</span><span>В документе — основной ответ + «шпаргалка» на случай если всё же возразят снова.</span></div><div class="pi-step"><span class="pi-n">4</span><span>Вы входите в следующий раунд уже подготовленными.</span></div><div class="pi-meta">⏱ Готово через 12 часов · Включает шпаргалку для продолжения диалога</div>`,
3: `<b>Что вы получите</b><br>Елена ведёт переписку с контрагентом от вашего имени — до тех пор пока сторона не соглашается или не фиксирует официальный отказ.<br><br><span class="pi-tag pi-incl">✓ Включено</span><b>Как работает:</b><div class="pi-step"><span class="pi-n">1</span><span>Передаёте нам историю переписки и доступ к каналу общения (или пересылаете сообщения).</span></div><div class="pi-step"><span class="pi-n">2</span><span>Елена готовит каждый ответ — вы видите текст до отправки и можете скорректировать.</span></div><div class="pi-step"><span class="pi-n">3</span><span>При нестандартных ходах контрагента — юрист адаптирует стратегию в режиме реального времени.</span></div><div class="pi-step"><span class="pi-n">4</span><span>Финал: либо подписанное соглашение, либо официальный отказ — с основанием для суда если потребуется.</span></div><div class="pi-meta">⏱ Первый ответ: 4 часа · Ведём до результата 💛</div>`
},
partner: {
1: `<b>Что вы получите</b><br>Договор, переработанный с учётом интересов обеих сторон. Контрагент не чувствует давления — он видит предложение, от которого сложно отказаться.<br><br><b>Как использовать:</b><div class="pi-step"><span class="pi-n">1</span><span>Изучите договор — обратите внимание на пункты с пометкой «↔ обе стороны»: в них мы специально вписали выгоду для контрагента.</span></div><div class="pi-step"><span class="pi-n">2</span><span>Отправьте с простым сопроводительным текстом: <i>«Подготовил(а) редакцию, которая учитывает интересы обеих сторон — посмотри».</i></span></div><div class="pi-step"><span class="pi-n">3</span><span>При возражениях — обратитесь к Елене отдельно или закажите версию с сопровождением.</span></div><div class="pi-meta">⏱ Готово через 2448 часов · Партнёрские договоры подписывают без торга</div>`,
2: `<b>Что вы получите</b><br>Партнёрская редакция + к каждому пункту — аргумент, почему это выгодно для контрагента. У вас есть ответ на любое возражение ещё до того, как оно прозвучало.<br><br><b>Как использовать:</b><div class="pi-step"><span class="pi-n">1</span><span>Изучите аргументы — они написаны под вашу конкретную ситуацию, не шаблонные.</span></div><div class="pi-step"><span class="pi-n">2</span><span>Отправьте договор контрагенту. Если он не согласен с каким-то пунктом — у вас уже готов ответ.</span></div><div class="pi-step"><span class="pi-n">3</span><span>Нестандартная реакция — пришлите Елене, она поможет с ответной позицией.</span></div><div class="pi-step"><span class="pi-n">4</span><span>Вы входите в переговоры с полной картиной — спокойно и уверенно.</span></div><div class="pi-meta">⏱ Готово через 2448 часов · Поддержка по возражениям включена</div>`,
3: `<b>Что вы получите</b><br>Елена ведёт переговоры вместе с вами — от отправки договора до финальной подписи. Ваша задача: согласовать итоговый текст.<br><br><span class="pi-tag pi-incl">✓ Включено</span><b>Полное сопровождение:</b><div class="pi-step"><span class="pi-n">1</span><span>Партнёрская редакция договора + сопроводительное письмо от вашего имени.</span></div><div class="pi-step"><span class="pi-n">2</span><span>Елена анализирует ответ контрагента и готовит вашу следующую реплику.</span></div><div class="pi-step"><span class="pi-n">3</span><span>При встречных правках — определяем, что можно уступить без потерь, а что держим твёрдо.</span></div><div class="pi-step"><span class="pi-n">4</span><span>Финальная проверка перед подписанием: убеждаемся, что ваша защита сохранена в итоговом тексте.</span></div><div class="pi-meta">⏱ Первый ответ: 4 часа · Ведём до подписи · Среднее время закрытия сделки: 35 дней 💛</div>`
}
};
function selectPlan(n) {
_selPlan = n;
// подсветка
[1,2,3].forEach(i => {
const el = document.getElementById('pay-plan-' + i);
if (el) el.classList.toggle('sel', i === n);
});
// цена в кнопке
const priceEl = document.getElementById('p' + n + '-price');
if (priceEl) {
const priceText = priceEl.textContent;
const btn = document.getElementById('pay-price-btn');
if (btn) btn.textContent = 'Оплатить ' + priceText.replace('от ', '');
}
// инструкции Елены
const pitchEl = document.getElementById('pay-pitch');
if (pitchEl && PLAN_PITCH[_selDeliv] && PLAN_PITCH[_selDeliv][n]) {
pitchEl.innerHTML = PLAN_PITCH[_selDeliv][n];
}
}
/* ── ЮKASSA ВИДЖЕТ ── */
function ykOpen() {
const priceEl = document.getElementById('pay-price-btn');
const price = priceEl ? priceEl.textContent.replace('Оплатить ', '') : '';
const set = (id, v) => { const el = document.getElementById(id); if (el) el.textContent = v; };
set('yk-amount', price);
set('yk-btn-amount', price);
document.getElementById('yk-overlay').classList.add('open');
document.getElementById('yk-form').style.display = '';
document.getElementById('yk-success').style.display = 'none';
document.getElementById('yk-card').value = '';
document.getElementById('yk-exp').value = '';
document.getElementById('yk-cvv').value = '';
}
function ykClose(e) {
if (e && e.target !== document.getElementById('yk-overlay')) return;
document.getElementById('yk-overlay').classList.remove('open');
}
function ykFmtCard(el) {
let v = el.value.replace(/\D/g,'').slice(0,16);
el.value = v.match(/.{1,4}/g)?.join(' ') || v;
}
function ykFmtExp(el) {
let v = el.value.replace(/\D/g,'').slice(0,4);
if (v.length >= 3) v = v.slice(0,2) + ' / ' + v.slice(2);
el.value = v;
}
function ykPaySBP() {
// В проде: редирект на deeplink СБП с payment_id
ykFinish();
}
function ykSubmit() {
const card = document.getElementById('yk-card').value.replace(/\s/g,'');
const exp = document.getElementById('yk-exp').value;
const cvv = document.getElementById('yk-cvv').value;
let ok = true;
if (card.length < 16) { document.getElementById('yk-card').classList.add('yk-error'); ok = false; }
else document.getElementById('yk-card').classList.remove('yk-error');
if (exp.length < 7) { document.getElementById('yk-exp').classList.add('yk-error'); ok = false; }
else document.getElementById('yk-exp').classList.remove('yk-error');
if (cvv.length < 3) { document.getElementById('yk-cvv').classList.add('yk-error'); ok = false; }
else document.getElementById('yk-cvv').classList.remove('yk-error');
if (!ok) return;
const btn = document.getElementById('yk-pay-btn');
btn.disabled = true;
btn.innerHTML = '<div class="yk-spinner" style="display:inline-block"></div>';
// В проде: POST на /api/payment → получить payment_id → confirm
setTimeout(ykFinish, 1600);
}
function ykFinish() {
document.getElementById('yk-form').style.display = 'none';
document.getElementById('yk-success').style.display = 'block';
setTimeout(() => {
document.getElementById('yk-overlay').classList.remove('open');
// Сохраняем последний заказ для приветствия
try {
const d = DELIVS[_selDeliv] || {};
const p = d['p'+_selPlan] || [];
localStorage.setItem('zashita_last_order', JSON.stringify({ ttl: d.ttl||'', plan: p[1]||'', price: p[0]||'' }));
} catch(e) {}
showOrderStatus();
go('order-status');
}, 1200);
}
function checkReturning() {
const stats = JSON.parse(localStorage.getItem('zashita_intake_stats') || '[]');
const lastOrder = JSON.parse(localStorage.getItem('zashita_last_order') || 'null');
if (!stats.length && !lastOrder) return; // новый клиент
// вернувшийся
const n = document.getElementById('hero-new');
const r = document.getElementById('hero-returning');
if (n) n.style.display = 'none';
if (r) r.style.display = '';
// карточка последнего заказа
if (lastOrder) {
const el = document.getElementById('ret-last-order');
if (el) el.innerHTML =
'<div class="ret-ord-lbl">Последний заказ</div>' +
'<div class="ret-ord-name">' + lastOrder.ttl + ' · ' + lastOrder.plan + '</div>' +
'<div class="ret-ord-price">' + lastOrder.price + '</div>';
}
}
window.addEventListener('DOMContentLoaded', checkReturning);
/* ── MS-PROJECT GANTT ── */
(function(){
// Данные
var DATA = [
{ num:1, group:true, name:'🍽️ Кухня — агентский', dur:'18 дн', start:'23.05', end:'10.06', s:'2025-05-23', e:'2025-06-10', cls:'b-group', go:"tab('case')" },
{ num:2, group:false, name:' Анализ рисков', dur:'2 дн', start:'23.05', end:'24.05', s:'2025-05-23', e:'2025-05-24', cls:'b-done', go:"tab('case')" },
{ num:3, group:false, name:' Протокол разногласий', dur:'3 дн', start:'24.05', end:'27.05', s:'2025-05-24', e:'2025-05-27', cls:'b-urgent', go:"tab('case')" },
{ num:4, group:false, name:' Ответ контрагенту', dur:'2 дн', start:'27.05', end:'29.05', s:'2025-05-27', e:'2025-05-29', cls:'b-pending', go:"tab('case')" },
{ num:5, group:true, name:'💼 Трудовой договор', dur:'15 дн', start:'21.05', end:'05.06', s:'2025-05-21', e:'2025-06-05', cls:'b-group', go:"tab('case')" },
{ num:6, group:false, name:' Первичный анализ', dur:'1 дн', start:'21.05', end:'22.05', s:'2025-05-21', e:'2025-05-22', cls:'b-done', go:"tab('case')" },
{ num:7, group:false, name:' Допсоглашение', dur:'8 дн', start:'22.05', end:'30.05', s:'2025-05-22', e:'2025-05-30', cls:'b-active', go:"tab('case')" },
{ num:8, group:false, name:' Проверка финала', dur:'5 дн', start:'30.05', end:'05.06', s:'2025-05-30', e:'2025-06-05', cls:'b-pending', go:"tab('case')" },
{ num:9, group:true, name:'🏠 ДДУ (новая редакция)', dur:'17 дн', start:'19.05', end:'05.06', s:'2025-05-19', e:'2025-06-05', cls:'b-group', go:"tab('case')" },
{ num:10, group:false, name:' Сверка версий', dur:'8 дн', start:'19.05', end:'27.05', s:'2025-05-19', e:'2025-05-27', cls:'b-active', go:"tab('case')" },
{ num:11, group:false, name:' Финальное заключение', dur:'9 дн', start:'27.05', end:'05.06', s:'2025-05-27', e:'2025-06-05', cls:'b-pending', go:"tab('case')" },
];
var RS = new Date('2025-05-17T00:00:00');
var RE = new Date('2025-06-15T00:00:00');
var TOT = (RE - RS) / 86400000;
function pct(str) {
var dt = new Date(str + 'T00:00:00');
return Math.max(0, Math.min(100, (dt - RS) / 86400000 / TOT * 100));
}
// Построить тики дат
function buildDateTicks() {
var ticks = []; var cur = new Date(RS);
while(cur <= RE) { ticks.push(new Date(cur)); cur.setDate(cur.getDate()+7); }
return ticks;
}
// Построить сетку (колонки = дни)
function buildGridCols() {
var cols = ''; var cur = new Date(RS);
while(cur < RE) {
var d = cur.getDay();
cols += '<div class="msp-grid-col' + (d===0||d===6?' weekend':'') + '"></div>';
cur.setDate(cur.getDate()+1);
}
return cols;
}
function render() {
var root = document.getElementById('msp-root');
if (!root) return;
var today = new Date(); today.setHours(0,0,0,0);
var todayPct = pct(today.toISOString().slice(0,10));
var ticks = buildDateTicks();
var gridCols = buildGridCols();
var m = ['янв','фев','мар','апр','май','июн','июл','авг','сен','окт','ноя','дек'];
// Шапка дат
var ticksHTML = ticks.map(function(dt){
return '<div class="msp-date-tick" style="left:'+pct(dt.toISOString().slice(0,10)).toFixed(2)+'%">'+
dt.getDate()+' '+m[dt.getMonth()]+'</div>';
}).join('');
// HEAD
var head = '<div class="msp-head">' +
'<div class="msp-left">' +
'<div class="msp-hcol msp-c-num">#</div>' +
'<div class="msp-hcol msp-c-name">Название задачи</div>' +
'<div class="msp-hcol msp-c-dur">Длит.</div>' +
'<div class="msp-hcol msp-c-start">Начало</div>' +
'<div class="msp-hcol msp-c-end">Окончание</div>' +
'</div>' +
'<div class="msp-right">' +
'<div class="msp-date-hdr">' + ticksHTML + '</div>' +
'</div>' +
'</div>';
// ROWS
var rows = DATA.map(function(r){
var left_pct = pct(r.s);
var right_pct = pct(r.e);
var w = Math.max(0.5, right_pct - left_pct);
var barLabel = r.group ? '' : r.end;
var isDone = r.cls === 'b-done';
var isActive = r.cls === 'b-active' || r.cls === 'b-urgent';
var rowCls = 'msp-row' + (r.group?' msp-group':'') + (isDone?' msp-done':'') + (isActive?' msp-active-row':'');
return '<div class="'+rowCls+'" onclick="'+r.go+'">' +
'<div class="msp-left">' +
'<div class="msp-cell msp-c-num">'+r.num+'</div>' +
'<div class="msp-cell msp-c-name'+(r.group?'':' ind')+'">'+(isDone&&!r.group?'✅ ':'')+r.name+'</div>' +
'<div class="msp-cell msp-c-dur">'+r.dur+'</div>' +
'<div class="msp-cell msp-c-start">'+r.start+'</div>' +
'<div class="msp-cell msp-c-end">'+r.end+'</div>' +
'</div>' +
'<div class="msp-right">' +
'<div class="msp-grid-bg">'+gridCols+'</div>' +
'<div class="msp-bar-wrap">' +
'<div class="msp-today" style="left:'+todayPct.toFixed(2)+'%"></div>' +
'<div class="msp-bar '+r.cls+'" style="left:'+left_pct.toFixed(2)+'%;width:'+w.toFixed(2)+'%">'+barLabel+'</div>' +
'</div>' +
'</div>' +
'</div>';
}).join('');
root.innerHTML = head + rows;
}
// Рендерим при открытии кабинета и при tab('cases')
var _origTab = window.tab;
window.tab = function(id) {
if (_origTab) _origTab(id);
if (id === 'cases') setTimeout(render, 50);
};
var _origGo = window.go;
window.go = function(id) {
if (_origGo) _origGo(id);
if (id === 'cabinet') setTimeout(render, 80);
};
window.addEventListener('DOMContentLoaded', function(){
var el = document.getElementById('p-cases');
if (el && el.classList.contains('on')) render();
});
})();
/* ── ТАБЛИЦА ДОГОВОРОВ ── */
(function(){
var CT_DATA = [
{ ico:'🍽️', name:'Кухня — агентский (ЗОВ)', type:'Агентский', date:'23.05', dateSort:20250523, risk:'high', riskLbl:'⚠ Высокий', status:'work', open:true, go:"tab('case')" },
{ ico:'💼', name:'Трудовой договор', type:'Трудовой', date:'21.05', dateSort:20250521, risk:'mid', riskLbl:'Средний', status:'work', open:true, go:"tab('case')" },
{ ico:'🏠', name:'Квартира — ДДУ (новая ред.)',type:'ДДУ', date:'19.05', dateSort:20250519, risk:'low', riskLbl:'Низкий', status:'wait', open:true, go:"tab('case')" },
{ ico:'📄', name:'Аренда офиса 2024', type:'Аренда', date:'12.03', dateSort:20250312, risk:'low', riskLbl:'Низкий', status:'done', open:false, go:"toast('📄 Открываю архивное дело')" },
{ ico:'📄', name:'Поставка оборудования', type:'Поставка',date:'01.02', dateSort:20250201, risk:'mid', riskLbl:'Средний', status:'done', open:false, go:"toast('📄 Открываю архивное дело')" },
];
var STATUS_MAP = {
'paid': { lbl:'Оплачено', cls:'chip n' },
'wait': { lbl:'⏳ Ожидает договор', cls:'chip w' },
'work': { lbl:'🔵 В работе', cls:'chip n' },
'ready': { lbl:'📥 Готово', cls:'chip ok' },
'done': { lbl:'✅ Завершён', cls:'chip ok' },
};
var _filter = 'all';
var _sortField = 'date';
var _sortDir = -1; // -1 = desc (новые сверху)
function riskOrder(r){ return r==='high'?0:r==='mid'?1:2; }
function filtered() {
return CT_DATA.filter(function(r){
if (_filter === 'open') return r.open;
if (_filter === 'closed') return !r.open;
if (_filter === 'risk') return r.risk === 'high';
return true;
}).sort(function(a,b){
var va, vb;
if (_sortField === 'date') { va=a.dateSort; vb=b.dateSort; }
else if (_sortField === 'risk') { va=riskOrder(a.risk); vb=riskOrder(b.risk); }
else if (_sortField === 'name') { va=a.name; vb=b.name; }
else if (_sortField === 'type') { va=a.type; vb=b.type; }
else if (_sortField === 'status') { va=a.status; vb=b.status; }
else { va=a.dateSort; vb=b.dateSort; }
if (va < vb) return -1 * _sortDir;
if (va > vb) return 1 * _sortDir;
return 0;
});
}
function riskChipCls(r){ return r==='high'?'chip d':r==='mid'?'chip w':'chip n'; }
function render() {
var tbody = document.getElementById('ct-tbody');
if (!tbody) return;
var rows = filtered();
if (!rows.length) { tbody.innerHTML='<tr><td colspan="6" style="padding:20px;text-align:center;color:var(--mut)">Нет дел по фильтру</td></tr>'; return; }
tbody.innerHTML = rows.map(function(r){
return '<tr class="'+(r.open?'':'ct-closed')+'" onclick="'+r.go+'">' +
'<td class="ct-name">'+r.ico+' '+r.name+'</td>' +
'<td><span class="ct-type-badge">'+r.type+'</span></td>' +
'<td style="color:var(--mut)">'+r.date+'</td>' +
'<td><span class="'+riskChipCls(r.risk)+'">'+r.riskLbl+'</span></td>' +
'<td><span class="'+(STATUS_MAP[r.status]||{cls:'chip n'}).cls+'">'+(STATUS_MAP[r.status]||{lbl:r.status}).lbl+'</span></td>' +
'<td class="ct-open">→</td>' +
'</tr>';
}).join('');
}
window.ctFilter = function(f, btn) {
_filter = f;
document.querySelectorAll('.ct-fbtn').forEach(function(b){ b.classList.remove('act'); });
if (btn) btn.classList.add('act');
render();
};
window.ctSort = function(field, th) {
if (_sortField === field) { _sortDir *= -1; }
else { _sortField = field; _sortDir = 1; }
document.querySelectorAll('.ct-table thead th').forEach(function(h){ h.classList.remove('sort-asc','sort-desc'); });
if (th) th.classList.add(_sortDir === 1 ? 'sort-asc' : 'sort-desc');
render();
};
// Рендер при открытии вкладки cases и cabinet
var _origTab2 = window.tab;
window.tab = function(id) {
if (_origTab2) _origTab2(id);
if (id === 'cases') setTimeout(render, 50);
};
var _origGo2 = window.go;
window.go = function(id) {
if (_origGo2) _origGo2(id);
if (id === 'cabinet') setTimeout(render, 80);
};
window.addEventListener('DOMContentLoaded', function(){
var el = document.getElementById('ct-tbody');
if (el) render();
});
})();
/* ── ELENA INTAKE v2 ── */
function elenaIntent(intent) {
// cabinet — сразу в кабинет
if (intent === 'cabinet') { go('cabinet'); return; }
// question — показываем текстовое поле без загрузки
if (intent === 'question') {
document.querySelectorAll('#el-step1 .int-card').forEach(function(c){ c.style.opacity='.45'; c.style.pointerEvents='none'; });
var qBox = document.createElement('div');
qBox.className = 'msg';
qBox.innerHTML = '<div class="av"><img src="logos/elena-photo.jpg"></div><div class="bubble"><div class="nm">Елена</div>Конечно — спрашивайте 💛 Опишите ситуацию, я отвечу по нормам ГК/ТК/ЗоЗПП. Или включите микрофон 🎙</div>';
document.getElementById('el-step1').appendChild(qBox);
return;
}
// create — переходим к wizard созданию документа
if (intent === 'create') { go('cabinet'); setTimeout(function(){ tab('create'); }, 200); return; }
// check / dispute / power — переходим к загрузке
var ackMap = {
check: 'Отлично — проверю договор 📄 Найду все риски и объясню каждый понятно.',
dispute: 'Хорошо — подготовлю протокол разногласий 📋 Загрузите договор, уберём невыгодные пункты.',
power: 'Доверенность — без проблем 📑 Загрузите образец или расскажите кому и какие полномочия.',
custom: 'Понял вас. Загрузите документ или опишите подробнее — разберёмся.',
};
document.querySelectorAll('#el-step1, #el-step-create').forEach(function(el){ el.style.display='none'; });
var upload = document.getElementById('el-step-upload');
if(upload) upload.style.display='';
var ack = document.getElementById('el-ack');
if(ack) ack.innerHTML = ackMap[intent] || '';
}
function elenaCreate(type) {
var msgs = {
contract: 'Договор — отличный выбор. Уточните: какой тип и между кем? Например: «договор оказания услуг между ИП и физлицом». Чем точнее — тем лучше результат.',
power: 'Доверенность готовлю быстро. Укажите: кто доверяет, кому, и что именно разрешает делать (продать авто, представлять в суде, получить документы)?',
claim: 'Претензию составлю под вашу ситуацию. Опишите: к кому претензия, что нарушили и какой результат хотите (возврат денег, замена товара, неустойка)?',
other: 'Расскажите что нужно составить — постараюсь помочь или подберу ближайший шаблон.',
};
var msg = msgs[type] || msgs.other;
document.getElementById('el-step-create').style.display = 'none';
// Показываем ответ Елены и поле ввода
var wrap = document.querySelector('.chatwrap');
var div = document.createElement('div');
div.innerHTML = '<div class="msg"><div class="av"><img src="logos/elena-photo.jpg"></div><div class="bubble"><div class="nm">Елена</div>' + msg + '</div></div>' +
'<div class="voice-input-row" style="margin-left:0">' +
'<input id="create-input" placeholder="Опишите детали…" style="flex:1;border:1.5px solid var(--line);border-radius:11px;padding:11px 14px;font-size:14px;font-family:inherit;outline:none">' +
'<button class="voice-btn" onclick="toggleVoice(\'create-input\')" title="Голосовой ввод">🎤</button>' +
'<button class="send-btn" onclick="toast(\'✍️ Принято — начинаю составлять документ по вашему запросу\')">→</button>' +
'</div>';
wrap.appendChild(div);
div.scrollIntoView({behavior:'smooth'});
}
/* ── ГОЛОСОВОЙ ВВОД ── */
var _voiceActive = false;
var _voiceRecog = null;
function toggleVoice(targetId) {
var inputId = targetId || 'intake-custom';
var btn = document.getElementById('voice-btn');
var SR = window.SpeechRecognition || window.webkitSpeechRecognition;
if (!SR) {
var hint = document.getElementById('voice-hint');
if (hint) hint.textContent = '⚠ Голосовой ввод не поддерживается в этом браузере';
return;
}
if (_voiceActive) {
if (_voiceRecog) _voiceRecog.stop();
return;
}
_voiceRecog = new SR();
_voiceRecog.lang = 'ru-RU';
_voiceRecog.interimResults = true;
_voiceRecog.continuous = false;
_voiceRecog.onstart = function() {
_voiceActive = true;
if (btn) { btn.classList.add('recording'); btn.textContent = '🔴'; }
var hint = document.getElementById('voice-hint');
if (hint) hint.textContent = '🎙 Говорите…';
};
_voiceRecog.onresult = function(e) {
var transcript = '';
for (var i = e.resultIndex; i < e.results.length; i++) {
transcript += e.results[i][0].transcript;
}
var inp = document.getElementById(inputId);
if (inp) inp.value = transcript;
};
_voiceRecog.onend = function() {
_voiceActive = false;
if (btn) { btn.classList.remove('recording'); btn.textContent = '🎤'; }
var hint = document.getElementById('voice-hint');
if (hint) hint.textContent = '';
};
_voiceRecog.onerror = function(e) {
_voiceActive = false;
if (btn) { btn.classList.remove('recording'); btn.textContent = '🎤'; }
var hint = document.getElementById('voice-hint');
if (hint) hint.textContent = e.error === 'not-allowed' ? '⚠ Разрешите доступ к микрофону' : '⚠ Ошибка записи: ' + e.error;
};
_voiceRecog.start();
}
// Скрыть mic если нет поддержки
window.addEventListener('DOMContentLoaded', function() {
var SR = window.SpeechRecognition || window.webkitSpeechRecognition;
if (!SR) {
var btn = document.getElementById('voice-btn');
if (btn) btn.classList.add('no-support');
}
});
/* ── CRM CABINET ── */
function ctSearchFilter(q) {
q = q.toLowerCase();
var rows = document.querySelectorAll('#ct-tbody tr');
rows.forEach(function(r){ r.style.display = q && !r.textContent.toLowerCase().includes(q) ? 'none' : ''; });
}
function updateKPI() {
if (!window.CT_DATA) return;
var total = CT_DATA.length;
var work = CT_DATA.filter(function(r){ return r.status==='work'; }).length;
var urg = CT_DATA.filter(function(r){ return r.risk==='high' && r.open; }).length;
var done = CT_DATA.filter(function(r){ return r.status==='done'; }).length;
var set = function(id,v){ var el=document.getElementById(id); if(el) el.textContent=v; };
set('kpi-total', total); set('kpi-work', work); set('kpi-urg', urg); set('kpi-done', done);
var b = document.getElementById('side-badge-cases');
if(b) b.textContent = CT_DATA.filter(function(r){ return r.open; }).length;
}
var TAB_TITLES = { cases:'Мои дела', case:'Текущее дело', sroki:'Сроки', shab:'Шаблоны' };
var _origTabCRM = window.tab;
window.tab = function(id) {
if (_origTabCRM) _origTabCRM(id);
var t = document.getElementById('main-hdr-title');
if (t) t.textContent = TAB_TITLES[id] || 'Кабинет';
// Показать/скрыть пункт "Текущее дело" в сайдбаре
var caseLink = document.getElementById('t-case');
if (caseLink) caseLink.style.display = id === 'case' ? 'flex' : 'none';
if (id === 'cases') setTimeout(updateKPI, 60);
};
window.addEventListener('DOMContentLoaded', function(){
setTimeout(updateKPI, 100);
});
/* ── СОЗДАНИЕ ДОКУМЕНТА ── */
var _selectedDocType = null;
var _DOC_FORMS = {
agent: {
title: 'Агентский договор',
fields: [
{id:'df-principal',label:'Принципал (вы)',placeholder:'ИП Васильев Руслан Геннадьевич',hint:'Полное наименование или ФИО',col:'half'},
{id:'df-agent',label:'Агент (контрагент)',placeholder:'ООО «Зов Ресторанс»',hint:'Полное наименование',col:'half'},
{id:'df-subject',label:'Предмет поручения',placeholder:'Поиск и привлечение клиентов для ресторана',hint:'Что именно делает агент',col:'full'},
{id:'df-fee',label:'Вознаграждение',placeholder:'150 000 руб./мес.',hint:'Сумма и периодичность',col:'half'},
{id:'df-term',label:'Срок договора',placeholder:'1 год с даты подписания',hint:'Дата начала и окончания',col:'half'},
{id:'df-court',label:'Подсудность',placeholder:'По месту нахождения Принципала',hint:'Суд при возникновении споров',col:'half'},
{id:'df-nds',label:'НДС',placeholder:'Не облагается — УСН',hint:'Или: в т.ч. НДС 20%',col:'half'},
]
},
trust: {
title: 'Доверенность',
fields: [
{id:'df-principal',label:'Доверитель',placeholder:'ИП Васильев Руслан Геннадьевич',hint:'ФИО и паспортные данные',col:'half'},
{id:'df-attorney',label:'Поверенный',placeholder:'Иванов Иван Иванович',hint:'ФИО и паспортные данные',col:'half'},
{id:'df-powers',label:'Полномочия',placeholder:'Подписание договоров, переговоры с контрагентами',hint:'Что может делать поверенный',col:'full'},
{id:'df-term',label:'Срок действия',placeholder:'1 год',hint:'Дата выдачи и срок',col:'half'},
{id:'df-subst',label:'Передоверие',placeholder:'Без права передоверия',hint:'Разрешено ли передоверие',col:'half'},
]
},
claim: {
title: 'Претензия',
fields: [
{id:'df-sender',label:'Отправитель',placeholder:'ИП Васильев Р.Г.',hint:'Ваши данные',col:'half'},
{id:'df-receiver',label:'Получатель',placeholder:'ООО «Контрагент»',hint:'Кому направляете',col:'half'},
{id:'df-basis',label:'Основание',placeholder:'Договор поставки № 12 от 01.04.2025',hint:'Договор или обязательство',col:'full'},
{id:'df-violation',label:'Нарушение',placeholder:'Не оплачена поставка товара на сумму 500 000 руб.',hint:'Что нарушено',col:'full'},
{id:'df-demand',label:'Требование',placeholder:'Оплатить в течение 10 дней',hint:'Что требуете и в какой срок',col:'full'},
{id:'df-penalty',label:'Неустойка',placeholder:'0,1% за каждый день просрочки',hint:'Размер пени по договору или ст. 395 ГК',col:'half'},
]
},
supply: {
title: 'Договор поставки',
fields: [
{id:'df-supplier',label:'Поставщик',placeholder:'ООО «Поставщик»',hint:'Полное наименование поставщика',col:'half'},
{id:'df-buyer',label:'Покупатель (вы)',placeholder:'ИП Васильев Р.Г.',hint:'Ваши данные',col:'half'},
{id:'df-goods',label:'Товар',placeholder:'Кухонное оборудование, ассортимент по спецификации',hint:'Наименование и описание товара',col:'full'},
{id:'df-price',label:'Сумма поставки',placeholder:'850 000 руб. в т.ч. НДС 20%',hint:'Общая сумма и НДС',col:'half'},
{id:'df-shipdate',label:'Срок поставки',placeholder:'30 дней с даты оплаты',hint:'Когда должен быть доставлен товар',col:'half'},
{id:'df-quality',label:'Гарантия качества',placeholder:'12 месяцев с даты поставки',hint:'Срок гарантии и условия возврата',col:'half'},
{id:'df-penalty',label:'Неустойка за просрочку',placeholder:'0,1% в день от стоимости непоставленного',hint:'Размер пени',col:'half'},
]
},
rent: {
title: 'Договор аренды',
fields: [
{id:'df-landlord',label:'Арендодатель',placeholder:'ООО «Бизнес-Центр Плюс»',hint:'Кто сдаёт',col:'half'},
{id:'df-tenant',label:'Арендатор (вы)',placeholder:'ИП Васильев Р.Г.',hint:'Ваши данные',col:'half'},
{id:'df-object',label:'Объект аренды',placeholder:'Офис 305, ул. Красная, 1, г. Краснодар, 45 кв.м',hint:'Адрес, площадь, кадастровый номер',col:'full'},
{id:'df-rent',label:'Арендная плата',placeholder:'80 000 руб./мес. без НДС',hint:'Размер и периодичность оплаты',col:'half'},
{id:'df-term',label:'Срок аренды',placeholder:'1 год с 01.06.2025',hint:'Дата начала и конца',col:'half'},
{id:'df-deposit',label:'Обеспечительный платёж',placeholder:'160 000 руб. (2 месяца)',hint:'Размер и условия возврата',col:'half'},
{id:'df-repair',label:'Ремонт и улучшения',placeholder:'Только с письменного согласия арендодателя',hint:'Кто несёт расходы',col:'half'},
]
},
nda: {
title: 'NDA / Конфиденциальность',
fields: [
{id:'df-party1',label:'Сторона 1 (вы)',placeholder:'ИП Васильев Р.Г.',hint:'Ваши данные',col:'half'},
{id:'df-party2',label:'Сторона 2',placeholder:'ООО «Партнёр»',hint:'Контрагент',col:'half'},
{id:'df-info',label:'Что является конфиденциальным',placeholder:'Бизнес-планы, клиентская база, технологии производства',hint:'Конкретный перечень закрытой информации',col:'full'},
{id:'df-term',label:'Срок действия NDA',placeholder:'3 года с даты подписания',hint:'Период действия обязательств',col:'half'},
{id:'df-exceptions',label:'Исключения',placeholder:'Общедоступная информация, данные от третьих лиц',hint:'Что НЕ является конфиденциальным',col:'half'},
{id:'df-penalty',label:'Ответственность за разглашение',placeholder:'500 000 руб. за каждый случай',hint:'Штраф или способ расчёта убытков',col:'half'},
]
},
labor: {
title: 'Трудовой договор',
fields: [
{id:'df-employer',label:'Работодатель',placeholder:'ИП Васильев Р.Г.',hint:'Наименование или ФИО ИП',col:'half'},
{id:'df-employee',label:'Работник',placeholder:'Иванова Мария Петровна',hint:'ФИО, паспортные данные',col:'half'},
{id:'df-position',label:'Должность',placeholder:'Менеджер по работе с клиентами',hint:'Точное наименование должности',col:'full'},
{id:'df-salary',label:'Оклад',placeholder:'60 000 руб./мес. до вычета НДФЛ',hint:'Размер оклада и доп. выплаты',col:'half'},
{id:'df-schedule',label:'График работы',placeholder:'Пн–Пт, 09:0018:00',hint:'Режим рабочего времени',col:'half'},
{id:'df-start',label:'Дата начала',placeholder:'01.06.2025',hint:'Когда приступает к работе',col:'half'},
{id:'df-probation',label:'Испытательный срок',placeholder:'3 месяца',hint:'Или «без испытания»',col:'half'},
]
},
dismiss: {
title: 'Соглашение о расторжении',
fields: [
{id:'df-party1',label:'Сторона 1 (вы)',placeholder:'ИП Васильев Р.Г.',hint:'Ваши данные',col:'half'},
{id:'df-party2',label:'Сторона 2',placeholder:'ООО «Зов Ресторанс»',hint:'Контрагент',col:'half'},
{id:'df-contract',label:'Расторгаемый договор',placeholder:'Агентский договор № 5 от 01.03.2025',hint:'Название, номер, дата',col:'full'},
{id:'df-date',label:'Дата расторжения',placeholder:'01.06.2025',hint:'Когда договор прекращает действие',col:'half'},
{id:'df-settlement',label:'Взаиморасчёты',placeholder:'Стороны не имеют взаимных претензий',hint:'Долги, возвраты, штрафы',col:'half'},
{id:'df-return',label:'Возврат имущества',placeholder:'Переданные материалы возвращены по акту',hint:'Что нужно вернуть',col:'full'},
]
}
};
function selectDocType(type, el) {
_selectedDocType = type;
document.querySelectorAll('.doc-type-card').forEach(function(c){ c.classList.remove('sel'); });
if(el) el.classList.add('sel');
var btn = document.getElementById('doc-type-next');
if(btn){ btn.classList.add('show'); btn.textContent = 'Заполнить параметры →'; }
}
function goCreateStep(step) {
document.querySelectorAll('.create-pane').forEach(function(p){ p.classList.remove('on'); });
document.querySelectorAll('.cstep').forEach(function(s,i){
s.classList.toggle('act', i+1 === step);
s.classList.toggle('done', i+1 < step);
var num = s.querySelector('.cstep-num');
if(num) num.textContent = (i+1 < step) ? '✓' : (i+1);
});
if(step === 1){ document.getElementById('cp-type').classList.add('on'); }
else if(step === 2){ buildCreateForm(); document.getElementById('cp-form').classList.add('on'); }
else if(step === 3){ document.getElementById('cp-preview').classList.add('on'); startDocGeneration(); }
window.scrollTo(0,0);
}
function buildCreateForm() {
var type = _selectedDocType || 'agent';
var def = _DOC_FORMS[type] || _DOC_FORMS.agent;
var title = document.getElementById('cf-doc-title');
if(title) title.textContent = def.title;
var grid = document.getElementById('create-form-fields');
if(!grid) return;
grid.innerHTML = def.fields.map(function(f){
var cls = f.col === 'full' ? 'cf-group wide' : 'cf-group';
return '<div class="'+cls+'"><label class="cf-label">'+f.label+'</label><input class="cf-input" id="'+f.id+'" placeholder="'+f.placeholder+'"><span class="cf-hint">'+f.hint+'</span></div>';
}).join('');
}
function startDocGeneration() {
var spinner = document.getElementById('doc-generating');
var preview = document.getElementById('doc-preview-wrap');
if(spinner){ spinner.classList.add('show'); }
if(preview){ preview.classList.remove('show'); }
setTimeout(function(){
if(spinner) spinner.classList.remove('show');
if(preview) preview.classList.add('show');
}, 2200);
}
/* ── ЧАСЫ ── */
(function(){
var DAYS = ['Воскресенье','Понедельник','Вторник','Среда','Четверг','Пятница','Суббота'];
var MONTHS = ['января','февраля','марта','апреля','мая','июня','июля','августа','сентября','октября','ноября','декабря'];
function tickClock(){
var now = new Date();
var dayEl = document.getElementById('sc-day');
var dateEl = document.getElementById('sc-date');
var timeEl = document.getElementById('sc-time');
if(dayEl) dayEl.textContent = DAYS[now.getDay()];
if(dateEl) dateEl.textContent = now.getDate() + ' ' + MONTHS[now.getMonth()] + ' ' + now.getFullYear();
if(timeEl){
var h = String(now.getHours()).padStart(2,'0');
var m = String(now.getMinutes()).padStart(2,'0');
var s = String(now.getSeconds()).padStart(2,'0');
timeEl.textContent = h + ':' + m + ':' + s;
}
}
setInterval(tickClock, 1000);
window.addEventListener('DOMContentLoaded', tickClock);
})();
/* ── СЧЁТЧИК ПРОТОКОЛА ── */
var _riskApplied = new Set();
function applyRisk(num, btn) {
_riskApplied.add(num);
btn.textContent = '✅ Применено';
btn.disabled = true;
btn.style.background = '#16a34a';
btn.style.cursor = 'default';
_updateProtocolBar();
toast('✅ Пункт #' + num + ' добавлен в протокол разногласий');
}
function _updateProtocolBar() {
var n = _riskApplied.size;
var bar = document.getElementById('protocol-bar');
var sub = document.getElementById('pb-sub');
var btn = document.getElementById('pb-generate');
if (!bar) return;
if (n > 0) {
bar.classList.add('show');
if (sub) sub.textContent = 'Выбрано пунктов: ' + n + ' из 12 — готов к формированию';
if (btn) btn.textContent = 'Сформировать протокол (' + n + ') →';
}
}
/* ── RISK ACCORDION ── */
function toggleRisk(el) {
var wasOpen = el.classList.contains('expanded');
document.querySelectorAll('.risk-item.expanded').forEach(function(r){ r.classList.remove('expanded'); });
if (!wasOpen) el.classList.add('expanded');
}
/* ── CASE TABS ── */
function caseTab(id, el) {
document.querySelectorAll('.case-pane').forEach(function(p){ p.classList.remove('on'); });
document.querySelectorAll('.case-tab').forEach(function(t){ t.classList.remove('on'); });
var pane = document.getElementById('cp-' + id);
if (pane) pane.classList.add('on');
if (el) el.classList.add('on');
}
/* ── СТАТУС ЗАКАЗА ── */
const OS_DEADLINES = {
protocol: { 1:'до 12 часов', 2:'до 24 часов', 3:'до 48 часов', sub:'после получения файла договора' },
redact: { 1:'до 12 часов', 2:'до 24 часов', 3:'до 48 часов', sub:'после получения файла договора' },
clean: { 1:'до 24 часов', 2:'до 48 часов', 3:'до 72 часов', sub:'после получения файла договора' },
partner: { 1:'до 24 часов', 2:'до 48 часов', 3:'до 72 часов', sub:'после получения файла договора' },
consult: { 1:'2 часа', 2:'сегодня', 3:'24 часа', sub:'отвечаем после получения оплаты' },
reply: { 1:'до 12 часов', 2:'до 12 часов', 3:'до результата', sub:'после получения переписки с контрагентом' }
};
const OS_STEP2 = {
protocol:'Юрист изучает договор',
redact:'Юрист готовит редакцию',
clean:'Юрист чистит текст',
partner:'Юрист пишет партнёрскую версию',
consult:'Юрист готовится к консультации',
reply:'Юрист составляет ответ'
};
const OS_ELENA = {
protocol:'Заказ получен — уже передала юристу. <b>Пришлите договор</b> в Telegram <a href="https://t.me/wasrusgen1" target="_blank">@wasrusgen1</a> — без него начать не получится. Как только файл придёт — сразу приступаем 💛',
redact:'Заказ получен. <b>Пришлите договор</b> в Telegram <a href="https://t.me/wasrusgen1" target="_blank">@wasrusgen1</a> — и обозначьте что хотите изменить, если есть конкретные пункты. Начнём сразу 💛',
clean:'Заказ получен. <b>Пришлите договор</b> в Telegram <a href="https://t.me/wasrusgen1" target="_blank">@wasrusgen1</a> — юрист сделает его читаемым и структурированным. Жду файл 💛',
partner:'Заказ получен. <b>Пришлите договор</b> в Telegram <a href="https://t.me/wasrusgen1" target="_blank">@wasrusgen1</a> — и кратко опишите вашу позицию в переговорах. Это поможет сделать текст работающим 💛',
consult:'Заказ получен. <b>Пришлите договор</b> в Telegram <a href="https://t.me/wasrusgen1" target="_blank">@wasrusgen1</a> — и список вопросов, или просто напишите «разбери сам». AI найдёт все риски и ответит по вашей ситуации. Отвечаем в течение 2 часов 💛',
reply:'Заказ получен. <b>Пришлите переписку с контрагентом и текст возражения</b> в Telegram <a href="https://t.me/wasrusgen1" target="_blank">@wasrusgen1</a> — юрист составит ответ с вашей правовой позицией 💛'
};
function showOrderStatus() {
const d = DELIVS[_selDeliv] || {};
const pKey = 'p' + _selPlan;
const pArr = d[pKey] || [];
const dl = (OS_DEADLINES[_selDeliv] || {})[_selPlan] || 'уточним';
const dlSub = (OS_DEADLINES[_selDeliv] || {}).sub || '';
const set = (id, val) => { const el = document.getElementById(id); if (el) el.innerHTML = val; };
set('os-svc', d.ttl || 'Юридическая услуга');
set('os-plan-name', pArr[1] || ('Тариф ' + _selPlan));
set('os-price', pArr[0] || '');
set('os-orderid', 'Заказ #' + Math.floor(1000 + Math.random() * 8999));
set('os-step2-lbl', (OS_STEP2[_selDeliv] || 'Юрист работает').replace(' ', '<br>'));
set('os-deadline-ttl', 'Срок: ' + dl);
set('os-deadline-sub', dlSub);
set('os-elena-msg', OS_ELENA[_selDeliv] || OS_ELENA.protocol);
set('os-ok-sub', 'Заказ №' + Math.floor(1000 + Math.random() * 8999) + ' передан в работу');
}
/* ── АНАЛИТИКА CUSTOM-ЗАПРОСОВ ── */
const CA_STOPWORDS = new Set(['и','в','на','с','по','для','что','это','как','не','а','но','из','к','о','от','за','до','при','без','под','над','со','об','же','бы','ли','ещё','уже','когда','если','мне','мы','я','вы','он','она','они','то','так','ну','ладно','просто','только','очень','нет','да','быть','есть','это','свой','мой','ваш','наш','его','её','их','все','всё','один','одна','других','другой','которые','который','можно','нужно','надо','хочу','хочется','нужна','нужен','нужно','получить','сделать','чтобы','также']);
function caWordFreq(arr) {
const freq = {};
arr.forEach(r => {
const words = (r.text || '').toLowerCase()
.replace(/[^а-яёa-z\s]/g, ' ')
.split(/\s+/)
.filter(w => w.length > 3 && !CA_STOPWORDS.has(w));
words.forEach(w => { freq[w] = (freq[w] || 0) + 1; });
});
return Object.entries(freq)
.sort((a, b) => b[1] - a[1])
.slice(0, 15);
}
function caFmtDate(ts) {
try {
const d = new Date(ts);
return d.toLocaleDateString('ru-RU', {day:'2-digit',month:'short',hour:'2-digit',minute:'2-digit'});
} catch(e) { return ts; }
}
function caAddToSystem(idx) {
const arr = JSON.parse(localStorage.getItem('zashita_custom_delivs') || '[]');
if (arr[idx]) { arr[idx].added = true; localStorage.setItem('zashita_custom_delivs', JSON.stringify(arr)); }
renderCustomAdmin();
}
function caCopyText(text) {
navigator.clipboard.writeText(text).catch(() => {});
showToast('Скопировано');
}
function caExportCSV() {
const arr = JSON.parse(localStorage.getItem('zashita_custom_delivs') || '[]');
if (!arr.length) return;
const rows = [['Дата','Тип договора','Запрос','Добавлено в систему']];
arr.forEach(r => rows.push([
r.ts || '', (r.ctype || '').replace(/,/g,''),
'"' + (r.text || '').replace(/"/g,'""') + '"',
r.added ? 'да' : 'нет'
]));
const csv = rows.map(r => r.join(',')).join('\n');
const a = document.createElement('a');
a.href = 'data:text/csv;charset=utf-8,' + encodeURIComponent('' + csv);
a.download = 'zashita_custom_' + new Date().toISOString().slice(0,10) + '.csv';
a.click();
}
function caExportJSON() {
const arr = JSON.parse(localStorage.getItem('zashita_custom_delivs') || '[]');
navigator.clipboard.writeText(JSON.stringify(arr, null, 2))
.then(() => showToast('JSON скопирован в буфер'))
.catch(() => showToast('Ошибка копирования'));
}
function caClearAll() {
if (!confirm('Удалить все custom-запросы?')) return;
localStorage.removeItem('zashita_custom_delivs');
renderCustomStats();
renderCustomAdmin();
}
function renderCustomAdmin() {
const arr = JSON.parse(localStorage.getItem('zashita_custom_delivs') || '[]');
const body = document.getElementById('ca-body');
if (!body) return;
if (!arr.length) {
body.innerHTML = '<div class="ca-empty"><div class="ce-icon">📭</div>Пока нет запросов.<br>Они появятся когда клиент нажмёт «Отправить запрос».</div>';
return;
}
const ctypes = [...new Set(arr.map(r => (r.ctype||'').trim()).filter(Boolean))];
const words = caWordFreq(arr);
const added = arr.filter(r => r.added).length;
// Статистика
let html = `<div class="ca-stats">
<div class="ca-stat"><div class="sv">${arr.length}</div><div class="sl">Всего запросов</div></div>
<div class="ca-stat"><div class="sv">${ctypes.length || '—'}</div><div class="sl">Типов договора</div></div>
<div class="ca-stat"><div class="sv">${added}</div><div class="sl">Добавлено в систему</div></div>
</div>`;
// Частотный анализ
if (words.length) {
html += '<div class="ca-section">Частые темы запросов</div><div class="ca-words">';
const maxCnt = words[0][1];
words.forEach(([w, c]) => {
const isTop = c === maxCnt;
html += `<div class="ca-word${isTop?' w-top':''}">${w}<span class="wc">${c}</span></div>`;
});
html += '</div>';
}
// Список запросов
html += '<div class="ca-section">Все запросы</div>';
arr.slice().reverse().forEach((r, i) => {
const realIdx = arr.length - 1 - i;
const ctypeLabel = (r.ctype||'').trim() || 'тип не определён';
html += `<div class="ca-card${r.added?' ca-done':''}">
<div class="cc-head">
<span class="cc-ctype">${ctypeLabel}</span>
<span class="cc-ts">${caFmtDate(r.ts)}</span>
</div>
<div class="cc-text">${r.text || ''}</div>
<div class="cc-actions">
<button class="cc-add" onclick="caAddToSystem(${realIdx})" ${r.added?'disabled':''}>
${r.added ? '✓ Добавлено в систему' : '+ Добавить в систему'}
</button>
<button class="cc-copy" onclick="caCopyText(${JSON.stringify(r.text||'')})">Копировать</button>
</div>
</div>`;
});
// Экспорт
html += `<div class="ca-export">
<button onclick="caExportCSV()">⬇ Скачать CSV</button>
<button onclick="caExportJSON()">📋 Копировать JSON</button>
<button onclick="caClearAll()" style="color:#b91c1c;border-color:#fecaca">🗑 Очистить всё</button>
</div>`;
body.innerHTML = html;
}
function showToast(msg) {
let t = document.getElementById('ca-toast');
if (!t) {
t = document.createElement('div'); t.id = 'ca-toast';
t.style.cssText = 'position:fixed;bottom:90px;left:50%;transform:translateX(-50%);background:#0C0608;color:#fff;padding:9px 18px;border-radius:10px;font-size:13px;z-index:99999;pointer-events:none;transition:opacity .3s';
document.body.appendChild(t);
}
t.textContent = msg; t.style.opacity = '1';
clearTimeout(t._to); t._to = setTimeout(() => { t.style.opacity = '0'; }, 2000);
}
window.addEventListener('DOMContentLoaded', renderStats);
window.addEventListener('DOMContentLoaded', renderCustomStats);
window.addEventListener('DOMContentLoaded', renderCustomAdmin);
function handleHash() {
const h = window.location.hash.slice(1);
if (!h) return;
const [screen, deliv, plan] = h.split(':');
if (deliv) _selDeliv = deliv;
if (plan) _selPlan = parseInt(plan) || 2;
if (screen === 'order-status') { showOrderStatus(); go('order-status'); }
else if (screen) go(screen);
}
window.addEventListener('DOMContentLoaded', handleHash);
window.addEventListener('hashchange', handleHash);
function tab(name){
document.querySelectorAll('.tabpane').forEach(p=>p.classList.toggle('on',p.id==='p-'+name));
document.querySelectorAll('.side a').forEach(a=>a.classList.remove('on'));
const map={cases:'t-cases',case:'t-case',sroki:'t-sroki',shab:'t-shab',create:'t-create'};
const el=document.getElementById(map[name]); if(el) el.classList.add('on');
window.scrollTo(0,0);
}
</script>
</div>
<!-- ── ЮKASSA ВИДЖЕТ ── -->
<div class="yk-overlay" id="yk-overlay" onclick="ykClose(event)">
<div class="yk-sheet" id="yk-sheet">
<button class="yk-close" onclick="ykClose()"></button>
<div id="yk-form">
<div class="yk-header">
<div class="yk-logo">ЮMoney<span>·</span>Kassa</div>
<div class="yk-amount" id="yk-amount">2 480 ₽</div>
</div>
<button class="yk-sbp" onclick="ykPaySBP()">
<div class="yk-sbp-icon">СБП</div>
Оплатить через СБП
</button>
<div class="yk-sep">или картой</div>
<div class="yk-field">
<label>Номер карты</label>
<input id="yk-card" type="text" inputmode="numeric" placeholder="0000 0000 0000 0000" maxlength="19" oninput="ykFmtCard(this)" autocomplete="cc-number">
</div>
<div class="yk-row">
<div class="yk-field">
<label>Срок действия</label>
<input id="yk-exp" type="text" inputmode="numeric" placeholder="ММ / ГГ" maxlength="7" oninput="ykFmtExp(this)" autocomplete="cc-exp">
</div>
<div class="yk-field">
<label>CVV / CVC</label>
<input id="yk-cvv" type="password" inputmode="numeric" placeholder="•••" maxlength="4" autocomplete="cc-csc">
</div>
</div>
<button class="yk-pay-btn" id="yk-pay-btn" onclick="ykSubmit()">Оплатить <span id="yk-btn-amount">2 480 ₽</span></button>
<div class="yk-footer">
Платёж защищён · <a href="https://yookassa.ru" target="_blank">ЮKassa</a> ·
<a href="oferta.html" target="_blank">Оферта</a>
</div>
</div>
<div class="yk-success" id="yk-success">
<div class="yk-check"></div>
<div class="yk-sttl">Оплата прошла!</div>
<div class="yk-ssub">Переходим к заказу…</div>
</div>
</div>
</div>
</body></html>