<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://www.pandoraburo.ru/" xml:lang="ru">
  <id>https://www.pandoraburo.ru/schit-postavschika-3</id>
  <link href="https://www.pandoraburo.ru/schit-postavschika-3.xml" rel="self"/>
  <title>Щит поставщика 3</title>
  <subtitle type="html">
&lt;html lang="ru"&gt;
&lt;head&gt;
&lt;meta charset="UTF-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;title&gt;Щит поставщика — проверка сделки по договору&lt;/title&gt;
&lt;style&gt;
  #spApp, #spApp *{box-sizing:border-box !important;
    font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif !important;
    -webkit-font-smoothing:antialiased}
  #spApp{
    --bg:#0d1117; --panel:#161b22; --panel-2:#1c232c;
    --text:#e6edf3; --muted:#8b949e; --border:#2a323c;
    --green:#3fb950; --yellow:#d29922; --red:#f85149;
    --accent:#4493f8; --accent-2:#79b8ff;
    background:var(--bg) !important; color:var(--text) !important;
    font-size:15px !important; line-height:1.55 !important;
    padding:28px 18px 80px !important; border-radius:12px;
    text-align:left !important;
  }
  #spApp .wrap{max-width:1080px;margin:0 auto}
  #spApp h1,#spApp h2,#spApp h3{margin:0;color:var(--text) !important;
    letter-spacing:-0.01em;font-weight:600}
  #spApp p{margin:0}
  #spApp .screen{display:none}
  #spApp .screen.active{display:block}

  #spApp .hero{padding:24px 0 22px;border-bottom:1px solid var(--border);margin-bottom:24px}
  #spApp .hero h1{font-size:28px;margin-bottom:10px}
  #spApp .hero p{color:var(--muted);max-width:760px;margin-bottom:10px}
  #spApp .hero .quiet{font-size:13px;color:var(--muted);opacity:.85}
  #spApp .hero .principle{
    margin-top:14px;padding:14px 18px;
    background:rgba(68,147,248,.06);
    border:1px solid rgba(68,147,248,.35);
    border-left:3px solid var(--accent);
    border-radius:8px;font-size:14px;color:var(--text);line-height:1.6
  }
  #spApp .hero .principle strong{color:var(--accent-2)}

  #spApp button.primary{
    background:var(--accent) !important; color:#fff !important;
    border:none !important; padding:14px 28px !important;
    border-radius:8px !important; font:inherit !important;
    font-weight:700 !important; font-size:15px !important;
    cursor:pointer; transition:opacity .15s;
  }
  #spApp button.primary:hover{opacity:.9}
  #spApp button.primary:disabled{background:#2a323c !important;
    color:#6e7681 !important; cursor:not-allowed}
  #spApp button.ghost{
    background:transparent !important; color:var(--muted) !important;
    border:1px solid var(--border) !important; padding:13px 20px !important;
    border-radius:8px !important; font:inherit !important;
    font-weight:600 !important; font-size:14px !important; cursor:pointer;
  }
  #spApp button.ghost:hover{color:var(--text) !important;border-color:var(--muted) !important}
  #spApp button.blocked{
    background:#3a1d1d !important; color:#f85149 !important;
    border:1px solid #f85149 !important; padding:14px 28px !important;
    border-radius:8px !important; font:inherit !important;
    font-weight:700 !important; font-size:15px !important; cursor:not-allowed;
  }

  #spApp .progress-shell{margin:0 0 22px}
  #spApp .progress-info{display:flex;justify-content:space-between;
    font-size:13px;color:var(--muted);margin-bottom:10px;gap:12px;flex-wrap:wrap}
  #spApp .progress-info strong{color:var(--text)}
  #spApp .progress-track{height:5px;background:var(--panel-2);
    border-radius:3px;overflow:hidden}
  #spApp .progress-fill{height:100%;width:0;
    background:linear-gradient(90deg,var(--accent),var(--accent-2));
    transition:width .3s;border-radius:3px}
  #spApp .draft-note{font-size:12px;color:var(--muted);margin-top:8px;
    font-style:italic;opacity:.85;transition:opacity .4s}
  #spApp .draft-note.hidden{opacity:0}

  #spApp .flags-bar{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:22px}
  @media (max-width:960px){#spApp .flags-bar{grid-template-columns:repeat(2,1fr)}}
  @media (max-width:520px){#spApp .flags-bar{grid-template-columns:1fr}}
  #spApp .flag-card{background:var(--panel);border:1px solid var(--border);
    border-radius:10px;padding:12px 14px;display:flex;align-items:center;gap:10px}
  #spApp .flag-card .dot{width:11px;height:11px;border-radius:50%;
    background:#6e7681;flex-shrink:0;transition:background .3s}
  #spApp .flag-card.g .dot{background:var(--green);box-shadow:0 0 8px var(--green)}
  #spApp .flag-card.y .dot{background:var(--yellow);box-shadow:0 0 8px var(--yellow)}
  #spApp .flag-card.r .dot{background:var(--red);box-shadow:0 0 8px var(--red)}
  #spApp .flag-card .lbl{font-size:11px;color:var(--muted);
    text-transform:uppercase;letter-spacing:.04em;line-height:1.3}
  #spApp .flag-card .val{font-size:12.5px;font-weight:600;color:var(--text);margin-top:2px}

  #spApp .block{background:var(--panel);border:1px solid var(--border);
    border-radius:12px;padding:22px 22px 6px;margin-bottom:16px}
  #spApp .block-head{display:flex;justify-content:space-between;
    align-items:baseline;gap:12px;flex-wrap:wrap;margin-bottom:6px}
  #spApp .block-head h2{font-size:16px}
  #spApp .block-head .weight{font-size:12px;color:var(--muted);
    background:var(--panel-2);border:1px solid var(--border);
    padding:3px 10px;border-radius:20px}
  #spApp .block-desc{font-size:13px;color:var(--muted);margin-bottom:16px}
  #spApp .q{padding:14px 0;border-top:1px solid var(--border)}
  #spApp .q:first-of-type{border-top:none}
  #spApp .q-label{font-size:14px;margin-bottom:10px;display:block;
    color:var(--text);line-height:1.5}
  #spApp .q-label .num{color:var(--muted);margin-right:6px;
    font-variant-numeric:tabular-nums;font-weight:600}
  #spApp .q-critical{display:inline-block;font-size:10px;
    color:var(--red);border:1px solid var(--red);padding:1px 7px;
    border-radius:10px;margin-left:8px;font-weight:700;
    vertical-align:middle;letter-spacing:.05em}
  #spApp .q-hint{font-size:12px;color:var(--muted);margin-top:-4px;
    margin-bottom:10px;font-style:italic}

  #spApp .q-body{display:flex;gap:16px;align-items:flex-start}
  #spApp .q-answers{flex:1;min-width:0;display:flex;flex-direction:column;gap:8px}
  #spApp .q-warning{
    flex:0 0 280px;
    display:none;
    padding:12px 14px;
    background:rgba(248,81,73,.08);
    border:1px solid rgba(248,81,73,.45);
    border-left:3px solid var(--red);
    border-radius:8px;
    font-size:12.5px;
    line-height:1.55;
    color:#ffb8b0;
    animation:sp-warn-in .28s cubic-bezier(.2,.8,.3,1);
  }
  #spApp .q-warning.visible{display:block}
  #spApp .q-warning.y{
    background:rgba(210,153,34,.08);
    border-color:rgba(210,153,34,.45);
    border-left-color:var(--yellow);
    color:#f0d590;
  }
  #spApp .q-warning .wicon{
    display:inline-block;font-weight:700;
    margin-right:6px;color:var(--red);
  }
  #spApp .q-warning.y .wicon{color:var(--yellow)}
  @keyframes sp-warn-in{
    from{opacity:0;transform:translateX(8px)}
    to{opacity:1;transform:translateX(0)}
  }
  @media (max-width:900px){
    #spApp .q-body{flex-direction:column}
    #spApp .q-warning{flex:none;width:100%;order:2}
    #spApp .q-answers{order:1;width:100%}
  }

  #spApp .q-answer{padding:11px 13px;background:var(--panel-2);
    border:1px solid var(--border);border-radius:8px;font-size:14px;
    cursor:pointer;transition:.15s;display:flex;gap:10px;align-items:flex-start}
  #spApp .q-answer:hover{border-color:var(--accent)}
  #spApp .q-answer input{display:none}
  #spApp .q-answer .box{width:18px;height:18px;border:1px solid var(--border);
    border-radius:4px;flex-shrink:0;display:grid;place-items:center;
    margin-top:2px;transition:.15s}
  #spApp .q-answer .box::after{content:"";width:10px;height:10px;
    background:var(--accent);border-radius:2px;transform:scale(0);
    transition:.15s}
  #spApp .q-answer input:checked ~ .box{border-color:var(--accent);
    background:rgba(68,147,248,.1)}
  #spApp .q-answer input:checked ~ .box::after{transform:scale(1)}
  #spApp .q-answer .lbl{font-size:14px;color:var(--text);line-height:1.5}

  #spApp .consent{background:var(--panel);border:1px solid var(--border);
    border-radius:12px;padding:22px;margin-bottom:16px}
  #spApp .consent h2{font-size:16px;margin-bottom:12px}
  #spApp .consent .disclaimer{font-size:13px;color:var(--muted);
    background:var(--panel-2);border-left:3px solid var(--accent);
    padding:12px 16px;border-radius:6px;margin-bottom:14px;line-height:1.65}
  #spApp .consent label{display:flex;gap:10px;align-items:flex-start;
    font-size:13px;cursor:pointer;color:var(--text);line-height:1.6}
  #spApp .consent input[type=checkbox]{margin-top:3px;accent-color:var(--accent);
    width:16px;height:16px;flex-shrink:0;cursor:pointer}

  #spApp .info-box{background:var(--panel);border:1px solid var(--border);
    border-radius:12px;padding:22px;margin-bottom:16px}
  #spApp .info-box h2{font-size:16px;margin-bottom:14px}
  #spApp .field{margin-bottom:12px}
  #spApp .field label{display:block;font-size:13px;color:var(--muted);margin-bottom:6px}

  #spApp .actions{display:flex;gap:10px;flex-wrap:wrap;margin-top:18px}
  #spApp .actions-line{margin-top:16px;padding-top:16px;
    border-top:1px solid var(--border);display:flex;gap:10px;flex-wrap:wrap}
  #spApp .actions-title{font-size:12px;color:var(--muted);
    text-transform:uppercase;letter-spacing:.06em;font-weight:600;
    width:100%;margin-bottom:4px}

  /* Плашка про сохранение */
  #spApp .save-banner{
    position:fixed;bottom:22px;left:50%;transform:translateX(-50%);
    z-index:1000;
    background:#0f2a17;border:1px solid var(--green);border-left:4px solid var(--green);
    color:#b6f0c1;padding:14px 20px;border-radius:10px;
    box-shadow:0 10px 40px rgba(0,0,0,.5);
    max-width:min(560px,90vw);font-size:13px;line-height:1.55;
    display:none;animation:sp-banner-in .3s ease;
  }
  #spApp .save-banner.visible{display:block}
  #spApp .save-banner strong{color:#e6ffe9;display:block;margin-bottom:4px;font-size:14px}
  #spApp .save-banner .close{
    position:absolute;top:6px;right:10px;cursor:pointer;color:#6fa87a;
    background:none;border:none;font-size:18px;line-height:1;padding:4px
  }
  #spApp .save-banner .close:hover{color:#b6f0c1}
  @keyframes sp-banner-in{
    from{opacity:0;transform:translate(-50%,10px)}
    to{opacity:1;transform:translate(-50%,0)}
  }

  #spApp .report{background:var(--panel);border:1px solid var(--accent);
    border-radius:12px;padding:26px;margin-top:20px}
  #spApp .report.blocked{border-color:var(--red)}
  #spApp .report.warn{border-color:var(--yellow)}
  #spApp .report h2{font-size:19px;margin-bottom:16px}
  #spApp .report h3{font-size:12px;margin:22px 0 10px;color:var(--muted);
    text-transform:uppercase;letter-spacing:.08em;font-weight:600}
  #spApp .report .row{display:flex;justify-content:space-between;padding:9px 0;
    border-bottom:1px solid var(--border);font-size:14px;gap:12px}
  #spApp .report .row:last-child{border-bottom:none}
  #spApp .report .row span:first-child{color:var(--muted)}
  #spApp .report .row strong{color:var(--text)}
  #spApp .report .list{margin:0;padding-left:20px;font-size:13px;
    color:var(--text);line-height:1.7}
  #spApp .report .list li{margin-bottom:12px}
  #spApp .report .list.red li::marker{color:var(--red)}
  #spApp .report .list.yellow li::marker{color:var(--yellow)}
  #spApp .report .list.green li::marker{color:var(--green)}
  #spApp .report .list .warn-note{display:block;font-size:12px;
    color:var(--muted);font-style:italic;margin-top:4px}
  #spApp .report .list.red .warn-note{color:#ffb8b0}
  #spApp .report .list.yellow .warn-note{color:#f0d590}
  #spApp .report .verdict{padding:16px 20px;border-radius:10px;
    font-weight:700;font-size:15px;margin-bottom:16px;
    text-transform:uppercase;letter-spacing:.05em}
  #spApp .report .verdict.stop{background:rgba(248,81,73,.1);
    color:var(--red);border:1px solid var(--red)}
  #spApp .report .verdict.go{background:rgba(63,185,80,.1);
    color:var(--green);border:1px solid var(--green)}
  #spApp .report .verdict.wait{background:rgba(210,153,34,.1);
    color:var(--yellow);border:1px solid var(--yellow)}
  #spApp .report .discl{font-size:12px;color:var(--muted);
    background:var(--panel-2);border-left:3px solid var(--accent);
    padding:12px 16px;border-radius:6px;margin-top:20px;line-height:1.65}

  #spApp .hp-field{position:absolute;left:-9999px;top:auto}
  #spApp footer{color:var(--muted);font-size:12px;text-align:center;
    margin-top:40px;padding-top:20px;border-top:1px solid var(--border)}

  @media (max-width:640px){
    #spApp{padding:18px 12px 60px !important}
    #spApp .hero h1{font-size:24px}
    #spApp .field input{font-size:16px !important}
    #spApp button.primary,#spApp button.blocked{width:100%;padding:15px 22px !important}
    #spApp .actions,#spApp .actions-line{flex-direction:column;align-items:stretch}
  }

  /* ====== ПЕЧАТЬ ====== */
  @media print {
    #spApp{background:#fff !important;color:#000 !important;padding:0 !important}
    #spApp .sticky-bar,
    #spApp .progress-shell,
    #spApp .flags-bar,
    #spApp .actions,
    #spApp .actions-line,
    #spApp button,
    #spApp .draft-note,
    #spApp .q-warning,
    #spApp .hero .principle,
    #spApp .save-banner,
    #spApp footer{display:none !important}
    #spApp .screen{display:block !important}
    #spApp .block,
    #spApp .report,
    #spApp .info-box,
    #spApp .consent{border:1px solid #ccc !important;background:#fff !important;
      color:#000 !important;box-shadow:none !important;
      page-break-inside:avoid;margin-bottom:12px}
    #spApp h1,#spApp h2,#spApp h3,#spApp p,
    #spApp .q-label,#spApp .block-desc{color:#000 !important}
    #spApp .report .verdict{background:#f5f5f5 !important;color:#000 !important;
      border:2px solid #000 !important}
    #spApp .report .row span:first-child{color:#555 !important}
    #spApp .report .row strong{color:#000 !important}
    #spApp .report .list{color:#000 !important}
    #spApp .q-answer{background:#fff !important;border:1px solid #ccc !important;color:#000 !important}
    #spApp .q textarea,#spApp .q input[type="text"]{border:1px solid #ccc !important;
      background:#fff !important;color:#000 !important;min-height:auto}
  }
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;div id="spApp"&gt;
  &lt;div class="wrap"&gt;

    &lt;section class="screen active" id="spIntro"&gt;
      &lt;div class="hero"&gt;
        &lt;h1&gt;Щит поставщика&lt;/h1&gt;
        &lt;p&gt;Проверка сделки до отправки документов покупателю. Форма построена
        по чек-листу типового договора — каждый вопрос привязан к конкретному
        защитному пункту.&lt;/p&gt;
        &lt;div class="principle"&gt;
          &lt;strong&gt;Главный принцип:&lt;/strong&gt; наша цель — не закрыть сделку,
          а чтобы клиент вернулся второй, десятый, двадцатый раз и привёл других.
          Всё остальное время перед сделкой — подготовка к качественной
          и безопасной отгрузке. Обещаем только то, что можем выполнить.
        &lt;/div&gt;
        &lt;p class="quiet" style="margin-top:14px"&gt;
          Четыре блока: защита от покупателя, защита от менеджера,
          истинная потребность клиента, критерий возврата.
          Черновик сохраняется в вашем браузере. На любом этапе можно
          скачать протокол в TXT, HTML или PDF, а также распечатать.
        &lt;/p&gt;
      &lt;/div&gt;
      &lt;button type="button" class="primary" id="spStart"&gt;Начать проверку&lt;/button&gt;
    &lt;/section&gt;

    &lt;section class="screen" id="spForm"&gt;
      &lt;div class="progress-shell"&gt;
        &lt;div class="progress-info"&gt;
          &lt;span&gt;Отвечено: &lt;strong id="spFilled"&gt;0&lt;/strong&gt; из &lt;strong id="spTotal"&gt;0&lt;/strong&gt;&lt;/span&gt;
          &lt;span id="spTime"&gt;Осталось примерно 20 минут&lt;/span&gt;
        &lt;/div&gt;
        &lt;div class="progress-track"&gt;&lt;div class="progress-fill" id="spProgress"&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;div class="draft-note" id="spDraftNote"&gt;Ответы сохраняются автоматически&lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="flags-bar"&gt;
        &lt;div class="flag-card" id="spFlagBuyer"&gt;
          &lt;div class="dot"&gt;&lt;/div&gt;
          &lt;div&gt;
            &lt;div class="lbl"&gt;Щит от покупателя&lt;/div&gt;
            &lt;div class="val" id="spFlagBuyerVal"&gt;— не проверено&lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="flag-card" id="spFlagManager"&gt;
          &lt;div class="dot"&gt;&lt;/div&gt;
          &lt;div&gt;
            &lt;div class="lbl"&gt;Щит от менеджера&lt;/div&gt;
            &lt;div class="val" id="spFlagManagerVal"&gt;— не проверено&lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="flag-card" id="spFlagNeed"&gt;
          &lt;div class="dot"&gt;&lt;/div&gt;
          &lt;div&gt;
            &lt;div class="lbl"&gt;Истинная потребность&lt;/div&gt;
            &lt;div class="val" id="spFlagNeedVal"&gt;— не проверено&lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="flag-card" id="spFlagReturn"&gt;
          &lt;div class="dot"&gt;&lt;/div&gt;
          &lt;div&gt;
            &lt;div class="lbl"&gt;Возврат клиента&lt;/div&gt;
            &lt;div class="val" id="spFlagReturnVal"&gt;— не проверено&lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;form id="spFormEl" autocomplete="off" novalidate="novalidate"&gt;
        &lt;div class="hp-field"&gt;
          &lt;label&gt;Не заполняйте &lt;input type="text" id="spHp" tabindex="-1" /&gt;&lt;/label&gt;
        &lt;/div&gt;

        &lt;div id="spBlocks"&gt;&lt;/div&gt;

        &lt;section class="info-box"&gt;
          &lt;h2&gt;Сделка&lt;/h2&gt;
          &lt;div class="field"&gt;
            &lt;label&gt;Клиент / покупатель (обезличенно) *&lt;/label&gt;
            &lt;input type="text" id="spClient" placeholder="Например: Клиент А, металлотрейдер" /&gt;
          &lt;/div&gt;
          &lt;div class="field"&gt;
            &lt;label&gt;Суть сделки *&lt;/label&gt;
            &lt;input type="text" id="spDeal" placeholder="Например: броня 50/25/16/10/6 мм, 5 позиций" /&gt;
          &lt;/div&gt;
          &lt;div class="field"&gt;
            &lt;label&gt;Менеджер, ведущий сделку *&lt;/label&gt;
            &lt;input type="text" id="spManager" placeholder="Имя менеджера" /&gt;
          &lt;/div&gt;
        &lt;/section&gt;

        &lt;section class="consent"&gt;
          &lt;h2&gt;Дисклеймер&lt;/h2&gt;
          &lt;div class="disclaimer"&gt;
            Инструмент является структурированной проверкой фактов, предоставленных
            пользователем. Не является юридической консультацией и не заменяет
            юридическую экспертизу договора. Ответственность за решения и подписание
            документов лежит на собственнике / руководителе.
          &lt;/div&gt;
          &lt;label&gt;
            &lt;input type="checkbox" id="spConsent" /&gt;
            &lt;span&gt;Я понимаю, что это проверка фактов, а не юридическая консультация.
            Финальное решение по сделке принимаю я.&lt;/span&gt;
          &lt;/label&gt;
        &lt;/section&gt;

        &lt;div class="actions"&gt;
          &lt;button type="submit" class="primary" id="spSubmit" disabled="disabled"&gt;Проверить сделку&lt;/button&gt;
          &lt;button type="button" class="ghost" id="spSaveNow"&gt;Сохранить черновик&lt;/button&gt;
          &lt;button type="button" class="ghost" id="spReset"&gt;Очистить&lt;/button&gt;
        &lt;/div&gt;

        &lt;div class="actions-line"&gt;
          &lt;div class="actions-title"&gt;Скачать протокол на любом этапе&lt;/div&gt;
          &lt;button type="button" class="ghost" id="spDownloadTxt"&gt;Скачать TXT&lt;/button&gt;
          &lt;button type="button" class="ghost" id="spDownloadHtml"&gt;Скачать HTML (цветной)&lt;/button&gt;
          &lt;button type="button" class="ghost" id="spDownloadPdf"&gt;Скачать PDF (печать)&lt;/button&gt;
          &lt;button type="button" class="ghost" id="spPrintBtn"&gt;Распечатать на экране&lt;/button&gt;
        &lt;/div&gt;
      &lt;/form&gt;

      &lt;div class="report" id="spReport" style="display:none"&gt;&lt;/div&gt;
    &lt;/section&gt;

    &lt;footer&gt;
      Щит поставщика · Второе мнение · © &lt;span id="spYear"&gt;&lt;/span&gt;
    &lt;/footer&gt;
  &lt;/div&gt;

  &lt;div class="save-banner" id="spSaveBanner"&gt;
    &lt;button type="button" class="close" id="spSaveBannerClose" aria-label="Закрыть"&gt;×&lt;/button&gt;
    &lt;strong&gt;Черновик сохранён&lt;/strong&gt;
    Данные хранятся &lt;b&gt;в этом браузере на этом устройстве&lt;/b&gt;. Вернитесь на этот же
    адрес — ответы останутся на месте. Для переноса на другое устройство скачайте
    протокол в TXT или HTML.
  &lt;/div&gt;
&lt;/div&gt;

&lt;script&gt;
(function(){
  "use strict";

  var STORAGE_KEY = "shchit_postavshchika_v8";
  var RECIPIENT_EMAIL = "setipandorra@internet.ru";

  var BLOCKS = [
    {
      title:"Блок 1. Щит от покупателя — защитные пункты договора",
      weight:40,
      desc:"Проверка договора по чек-листу. Каждый пункт привязан к защитному пункту типового договора. Если пункта нет — красный флаг, отправлять нельзя.",
      questions:[
        { id:"c_signed", type:"choice", critical:true,
          text:"Договор подписан покупателем?",
          hint:"Если нет — счёт и спецификацию отправлять нельзя.",
          warn:"Менеджер, нельзя отправлять счёт и спецификацию без подписанного договора. Покупатель получит обязательство без защиты.",
          options:[
            { v:"yes", l:"Да, получен подписанный экземпляр" },
            { v:"no", l:"Нет, покупатель не подписал" },
            { v:"dont", l:"Пришлёт протокол разногласий" }
          ]},
        { id:"c_max", type:"choice", critical:true,
          text:"Клиент подписался на МАКС организации?",
          hint:"Электронный документооборот. Без подписки — договор не имеет юридической силы в ЭДО.",
          warn:"Клиент не подключён к МАКС. Юридически значимый обмен документами невозможен. Подписание через ЭДО не работает.",
          options:[
            { v:"yes", l:"Да, подключён и подписан" },
            { v:"no", l:"Нет, не подключён" },
            { v:"dont", l:"В процессе подключения" }
          ]},
        { id:"c_export_notice", type:"choice", critical:true,
          text:"Клиент ознакомлен вами, что экспорт запрещён?",
          hint:"Аналог п. 4.5.",
          warn:"Клиент не ознакомлен с запретом экспорта. Риск вывоза и штраф 2% не сработает — нечем доказать.",
          options:[
            { v:"yes", l:"Да, ознакомлен письменно" },
            { v:"no", l:"Нет, не ознакомлен" },
            { v:"dont", l:"Устно, без подтверждения" }
          ]},
        { id:"c_tu_notice", type:"choice", critical:true,
          text:"Клиент ознакомлен вами с ТУ и образцом паспорта на продукцию?",
          hint:"Аналог п. 5.1 и 5.8.",
          warn:"Клиент не ознакомлен с ТУ и паспортом. Позже будет требовать ГОСТ и сертификаты.",
          options:[
            { v:"yes", l:"Да, ознакомлен с ТУ и паспортом" },
            { v:"partial", l:"Ознакомлен с ТУ, но без паспорта" },
            { v:"no", l:"Нет, не ознакомлен" },
            { v:"dont", l:"Устно" }
          ]},
        { id:"c_test_report", type:"choice", critical:true,
          text:"На позицию есть протокол испытаний?",
          hint:"Обязательный документ до отгрузки.",
          warn:"Нет протокола испытаний. Если возникнет спор по качеству — нечем подтвердить.",
          options:[
            { v:"yes", l:"Да, есть на все позиции" },
            { v:"partial", l:"Есть не на все позиции" },
            { v:"no", l:"Нет" },
            { v:"dont", l:"В процессе оформления" }
          ]},
        { id:"c_prepay", type:"choice", critical:true,
          text:"Есть ли пункт о 100% предоплате?",
          hint:"Аналог п. 2.2.",
          warn:"Без 100% предоплаты сделка превращается в кредитование покупателя.",
          options:[
            { v:"yes", l:"Да, 100% предоплата" },
            { v:"partial", l:"Частичная предоплата (не менее 50%)" },
            { v:"no", l:"Отсрочка / оплата по факту" }
          ]},
        { id:"c_offset", type:"choice", critical:true,
          text:"Есть ли запрет на односторонний зачёт, удержание, приостановку оплаты?",
          hint:"Аналог п. 2.3.",
          warn:"Покупатель может односторонне уменьшить оплату или зачесть претензии.",
          options:[
            { v:"yes", l:"Да, запрет прописан" },
            { v:"no", l:"Нет" },
            { v:"dont", l:"Есть, но формальный" }
          ]},
        { id:"c_igk", type:"choice", critical:true,
          text:"Есть ли гарантия покупателя об отсутствии ИГК и ГОЗ?",
          hint:"Аналог п. 2.5.",
          warn:"Платёж с ИГК = блокировка счёта и казначейское сопровождение.",
          options:[
            { v:"yes", l:"Да, гарантия прописана" },
            { v:"no", l:"Нет" },
            { v:"dont", l:"Есть упоминание без гарантии" }
          ]},
        { id:"c_goz", type:"choice", critical:true,
          text:"Есть ли пункт: Поставщик не участвует в ГОЗ и казначейском сопровождении?",
          hint:"Аналог п. 2.4 и 2.6.",
          warn:"Без прямой оговорки Поставщик будет втянут в ГОЗ-процедуры.",
          options:[
            { v:"yes", l:"Да, прописан" },
            { v:"no", l:"Нет" },
            { v:"dont", l:"Есть, но неполный" }
          ]},
        { id:"c_digital", type:"choice", critical:true,
          text:"Есть ли пункт: цифровой рубль — только по письменному соглашению?",
          hint:"Аналог п. 2.7.",
          warn:"Покупатель оплатит цифровым рублём, и вы не сможете отказаться.",
          options:[
            { v:"yes", l:"Да, только по письменному соглашению" },
            { v:"no", l:"Нет ограничения" },
            { v:"dont", l:"Есть, но неполный" }
          ]},
        { id:"c_smart", type:"choice", critical:true,
          text:"Есть ли запрет на смарт-контракт цифрового рубля с отложенным переходом права собственности?",
          hint:"Аналог п. 2.8.",
          warn:"Смарт-контракт отложит переход денег до приёмки.",
          options:[
            { v:"yes", l:"Да, запрет прописан" },
            { v:"no", l:"Нет" },
            { v:"dont", l:"Не проработано" }
          ]},
        { id:"c_invoice_offer", type:"choice", critical:true,
          text:"Есть ли пункт: счёт без подписанного договора не является офертой?",
          hint:"ПРОБЕЛ — добавить п. 2.9.",
          warn:"ПРОБЕЛ. Счёт без договора = покупатель оплатит и будет требовать поставки.",
          options:[
            { v:"yes", l:"Да, пункт добавлен" },
            { v:"no", l:"Нет — ЭТО ПРОБЕЛ, добавить п. 2.9" },
            { v:"dont", l:"Есть похожий, но неполный" }
          ]},
        { id:"c_start", type:"choice", critical:true,
          text:"Есть ли пункт: срок начала изготовления = 100% оплата?",
          hint:"Аналог п. 3.1.",
          warn:"Менеджер запустит производство без денег.",
          options:[
            { v:"yes", l:"Да, срок = оплата" },
            { v:"no", l:"Нет, срок фиксированный" },
            { v:"dont", l:"Смешанно" }
          ]},
        { id:"c_tu", type:"choice", critical:true,
          text:"Есть ли пункт: ТУ — единственный документ качества, ГОСТ не применяется?",
          hint:"Аналог п. 5.1.",
          warn:"Покупатель предъявит претензии по ГОСТ, которого вы не обязаны соблюдать.",
          options:[
            { v:"yes", l:"Да, ТУ как единственный документ" },
            { v:"no", l:"Нет" },
            { v:"dont", l:"ТУ есть, про ГОСТ не сказано" }
          ]},
        { id:"c_10days", type:"choice", critical:true,
          text:"Есть ли срок рекламации 10 рабочих дней?",
          hint:"Аналог п. 5.3.",
          warn:"Покупатель вернёт товар через месяц.",
          options:[
            { v:"yes", l:"Да, 10 рабочих дней" },
            { v:"no", l:"Нет, дольше или не установлен" },
            { v:"dont", l:"Есть, но другой" }
          ]},
        { id:"c_passport", type:"choice", critical:true,
          text:"Есть ли пункт: только Паспорт качества формы Поставщика?",
          hint:"Аналог п. 5.8.",
          warn:"Покупатель потребует сертификаты, декларации, паспорта ГОСТ.",
          options:[
            { v:"yes", l:"Да, только наш Паспорт" },
            { v:"no", l:"Нет" },
            { v:"dont", l:"Частично" }
          ]},
        { id:"c_warranty", type:"choice", critical:true,
          text:"Есть ли пункт: гарантийный срок не устанавливается?",
          hint:"Аналог п. 5.12.",
          warn:"Гарантия = бесконечные претензии.",
          options:[
            { v:"yes", l:"Да, гарантия не устанавливается" },
            { v:"no", l:"Нет, гарантия есть" },
            { v:"dont", l:"Не указан" }
          ]},
        { id:"c_limit", type:"choice", critical:true,
          text:"Есть ли лимит совокупных неустоек не более 10%?",
          hint:"Аналог п. 6.4.",
          warn:"Без лимита неустойка может обрушить сделку.",
          options:[
            { v:"yes", l:"Да, лимит есть" },
            { v:"no", l:"Нет лимита" },
            { v:"dont", l:"Лимит другой" }
          ]},
        { id:"c_indirect", type:"choice", critical:true,
          text:"Есть ли пункт: упущенная выгода и косвенные убытки не возмещаются?",
          hint:"Аналог п. 6.5.",
          warn:"Покупатель потребует упущенную выгоду и убытки третьих лиц.",
          options:[
            { v:"yes", l:"Да, не возмещаются" },
            { v:"no", l:"Нет" },
            { v:"dont", l:"Частично" }
          ]},
        { id:"c_refusal", type:"choice", critical:true,
          text:"Есть ли право одностороннего отказа Поставщика (ст. 450.1, 523 ГК)?",
          hint:"Аналог п. 6.8.",
          warn:"Без права отказа Поставщик не сможет выйти из невыгодной сделки.",
          options:[
            { v:"yes", l:"Да, право есть" },
            { v:"no", l:"Нет" },
            { v:"dont", l:"Есть, но ограничено" }
          ]},
        { id:"c_annul", type:"choice", critical:true,
          text:"Есть ли пункт об аннулировании Спецификации при неоплате в срок?",
          hint:"ПРОБЕЛ — добавить п. 6.11.",
          warn:"ПРОБЕЛ. Нет аннулирования — придётся возвращать предоплату и терять время.",
          options:[
            { v:"yes", l:"Да, пункт добавлен" },
            { v:"no", l:"Нет — ЭТО ПРОБЕЛ, добавить п. 6.11" },
            { v:"dont", l:"Есть 6.7, но без слова аннулирование" }
          ]},
        { id:"c_refund", type:"choice", critical:true,
          text:"Есть ли фиксированный срок возврата предоплаты (10 рабочих дней)?",
          hint:"ПРОБЕЛ: п. 6.9 не устанавливает срок.",
          warn:"ПРОБЕЛ. Размытый срок = покупатель потребует немедленный возврат.",
          options:[
            { v:"yes", l:"Да, конкретный срок есть" },
            { v:"no", l:"Нет — ЭТО ПРОБЕЛ, добавить" },
            { v:"dont", l:"Есть, но размытый" }
          ]},
        { id:"c_buyer_check_who", type:"choice", critical:true,
          text:"Кто со стороны Покупателя проверит соответствие ТУ при приёмке?",
          hint:"Если не указано — при приёмке могут появиться любые претензии.",
          warn:"Не известно, кто со стороны покупателя принимает продукцию.",
          options:[
            { v:"yes", l:"Инженер или технолог — указано в договоре" },
            { v:"partial", l:"Снабженец — указан" },
            { v:"no", l:"ОТК покупателя — указан" },
            { v:"dont", l:"Не указано — риск претензий" }
          ]},
        { id:"c_buyer_check_how", type:"textarea", critical:false,
          text:"Какими средствами будет проверять покупатель?",
          hint:"Инструмент, лаборатория, визуально, по документам." },
        { id:"c_accept_agreed", type:"choice", critical:true,
          text:"Покупатель согласен с процедурой приёмки из п. 5.2 — на складе Поставщика?",
          hint:"Приёмка на складе Поставщика — ваша защита.",
          warn:"Покупатель не согласен с приёмкой на складе Поставщика. Спорные замеры в его пользу.",
          options:[
            { v:"yes", l:"Да, согласен — на складе Поставщика" },
            { v:"partial", l:"Хочет компромисс — часть у себя" },
            { v:"no", l:"Нет, хочет приёмку у себя" },
            { v:"dont", l:"Не обсуждали" }
          ]},
        { id:"c_court", type:"choice", critical:true,
          text:"Подсудность по месту Поставщика?",
          hint:"Аналог п. 7.4.",
          warn:"Споры будут идти в регионе покупателя.",
          options:[
            { v:"yes", l:"Да, суд по месту Поставщика" },
            { v:"no", l:"Нет, по месту Покупателя" },
            { v:"dont", l:"Нейтральная / по закону" }
          ]},
        { id:"c_force", type:"choice", critical:false,
          text:"Учтён ли форс-мажор с санкциями и запретом вывоза металлопродукции?",
          hint:"Аналог п. 7.9.",
          warn:"Санкции и ограничения вывоза не учтены.",
          options:[
            { v:"yes", l:"Да, санкции и ограничения учтены" },
            { v:"no", l:"Нет" },
            { v:"dont", l:"Стандартный форс-мажор" }
          ]},
        { id:"c_third", type:"choice", critical:false,
          text:"Есть ли запрет передачи Товара третьим лицам до приёмки?",
          hint:"Аналог п. 5.9.",
          warn:"Покупатель передаст товар третьим лицам до приёмки.",
          options:[
            { v:"yes", l:"Да, запрет прописан" },
            { v:"no", l:"Нет" },
            { v:"dont", l:"Есть, но неполный" }
          ]},
        { id:"c_accept", type:"choice", critical:false,
          text:"Порядок приёмки — на складе Поставщика?",
          hint:"Аналог п. 5.2.",
          warn:"Приёмка у покупателя = вы не контролируете условия.",
          options:[
            { v:"yes", l:"Да, на складе Поставщика" },
            { v:"no", l:"У покупателя" },
            { v:"dont", l:"Смешанный" }
          ]},
        { id:"c_notes", type:"textarea", critical:false,
          text:"Что ещё вызывает сомнения в договоре или в позиции покупателя?" }
      ]
    },
    {
      title:"Блок 2. Щит от менеджера — производство, сроки, документы",
      weight:25,
      desc:"Проверка реалистичности сделки и внутреннего контроля до отправки документов.",
      questions:[
        { id:"m_promise", type:"choice", critical:true,
          text:"Срок, который обещал менеджер покупателю, реалистичен?",
          hint:"Реальная прокатка нового сырья — 90 рабочих дней.",
          warn:"Менеджер, обещанные 25 дней нереальны. Реальная прокатка — 90 рабочих дней.",
          options:[
            { v:"yes", l:"Да, соответствует производству" },
            { v:"no", l:"Нет, обещал нереалистично" },
            { v:"dont", l:"Ещё не называл" }
          ]},
        { id:"m_prod_ok", type:"choice", critical:true,
          text:"Срок согласован с начальником производства письменно?",
          hint:"Менеджер обещает — производство выполняет.",
          warn:"Менеджер, срок не согласован с производством.",
          options:[
            { v:"yes", l:"Да, есть письменное согласование" },
            { v:"no", l:"Нет, только менеджер" },
            { v:"dont", l:"Устно" }
          ]},
        { id:"m_stock", type:"choice", critical:true,
          text:"Сырьё в наличии и зарезервировано?",
          hint:"Нет сырья — нечего закаливать.",
          warn:"Нет сырья — нечего закаливать. Сделка сорвётся.",
          options:[
            { v:"yes", l:"Да, в наличии и зарезервировано" },
            { v:"no", l:"Нет, нужно заказывать" },
            { v:"dont", l:"Частично" }
          ]},
        { id:"m_guarantee", type:"choice", critical:true,
          text:"Есть ли письменная гарантия завода о резервировании?",
          hint:"Слова без документа — не гарантия.",
          warn:"Слова менеджера без документа от завода.",
          options:[
            { v:"yes", l:"Да, письменная гарантия есть" },
            { v:"no", l:"Нет, только устно" },
            { v:"dont", l:"Предварительная заявка" }
          ]},
        { id:"m_positions", type:"choice", critical:true,
          text:"Все позиции (50/25/16/10/6 мм) обеспечены сырьём?",
          hint:"Проверьте по каждой позиции.",
          warn:"Не по всем позициям есть сырьё. Часть заказа повиснет.",
          options:[
            { v:"yes", l:"Все закрыты" },
            { v:"no", l:"Не все" },
            { v:"dont", l:"Не проверял по позициям" }
          ]},
        { id:"m_send", type:"choice", critical:true,
          text:"Что именно отправляем покупателю прямо сейчас?",
          hint:"Счёт без договора = обязательство без защиты.",
          warn:"СТОП. Счёт и спецификация без подписанного договора. Сначала договор.",
          options:[
            { v:"yes", l:"Только договор на подпись" },
            { v:"no", l:"Договор + счёт + спецификация (после подписания)" },
            { v:"dont", l:"Счёт и спецификация БЕЗ договора — СТОП" }
          ]},
        { id:"m_digital_consent", type:"choice", critical:true,
          text:"Есть ли письменное согласие покупателя на цифровой рубль?",
          hint:"Без письменного согласия оплата цифровым рублём недопустима.",
          warn:"Без письменного согласия оплата цифровым рублём недопустима.",
          options:[
            { v:"yes", l:"Согласия нет, оплата обычная" },
            { v:"no", l:"Есть, но не письменное" },
            { v:"dont", l:"Не обсуждали" }
          ]},
        { id:"m_marka", type:"choice", critical:false,
          text:"Марка стали и класс защиты указаны в Спецификации?",
          hint:"Без марки — риск подмены.",
          warn:"Без марки стали — риск подмены материала.",
          options:[
            { v:"yes", l:"Да, точно указаны" },
            { v:"no", l:"Нет, только размеры" },
            { v:"dont", l:"Варианты" }
          ]},
        { id:"m_reserve", type:"choice", critical:false,
          text:"Есть ли резервный поставщик сырья?",
          warn:"Один завод = один риск.",
          options:[
            { v:"yes", l:"Да, есть альтернатива" },
            { v:"no", l:"Нет" },
            { v:"dont", l:"Один завод, давно" }
          ]},
        { id:"m_warehouse_offer", type:"choice", critical:true,
          text:"Вы предлагали клиенту складские позиции?",
          hint:"Склад — быстрая отгрузка, часто дешевле, документы готовы.",
          warn:"Менеджер, ты не предложил клиенту складские позиции. Возможно, сделка могла закрыться сегодня.",
          options:[
            { v:"yes", l:"Да, клиент согласился" },
            { v:"partial", l:"Да, но клиент отказался" },
            { v:"no", l:"Нет, не предлагали" },
            { v:"dont", l:"На складе нет подходящего" }
          ]},
        { id:"m_warehouse_benefits", type:"textarea", critical:false,
          text:"Какие преимущества складских позиций подсветили клиенту?",
          hint:"Скорость отгрузки, цена, наличие документов." },
        { id:"m_warehouse_discount", type:"choice", critical:false,
          text:"Вы дали скидку на складские позиции?",
          hint:"Скидка на склад — дешевле, чем скидка на заказ.",
          warn:"Скидка на склад не дана. Клиент может уйти к конкуренту.",
          options:[
            { v:"yes", l:"Да, клиент согласился" },
            { v:"partial", l:"Да, но клиент всё равно просит ещё" },
            { v:"no", l:"Нет, скидку не дали" },
            { v:"dont", l:"Скидка не требуется" }
          ]},
        { id:"m_max_discount", type:"choice", critical:true,
          text:"Клиент просит скидку, а вы заставили его зарегистрироваться в МАКС на нашем сайте?",
          hint:"Скидка в обмен на регистрацию — win-win.",
          warn:"Менеджер, скидка дана без условий. Можно было обменять на регистрацию в МАКС.",
          options:[
            { v:"yes", l:"Да, клиент согласился — скидка в обмен на регистрацию" },
            { v:"partial", l:"Да, но клиент отказался" },
            { v:"no", l:"Нет, дали скидку без условий" },
            { v:"dont", l:"Клиент не просил скидку" }
          ]},
        { id:"m_warehouse_replace", type:"choice", critical:true,
          text:"Можно ли закрыть потребность клиента складской позицией вместо заказной?",
          hint:"Проверьте по каждой позиции: 50, 25, 16, 10, 6 мм.",
          warn:"Заказная позиция — 90 рабочих дней. Складская — сегодня.",
          options:[
            { v:"yes", l:"Да, полностью" },
            { v:"partial", l:"Частично — не все позиции" },
            { v:"no", l:"Нет, нужна только заказная" },
            { v:"dont", l:"Не проверяли" }
          ]},
        { id:"m_tu_check_who", type:"choice", critical:true,
          text:"Кто со стороны Поставщика проверит соответствие продукции ТУ перед отгрузкой?",
          hint:"Без ответственного — никто не проверит.",
          warn:"Нет ответственного за проверку ТУ. Риск отгрузить несоответствующую продукцию.",
          options:[
            { v:"yes", l:"ОТК — отдел технического контроля" },
            { v:"partial", l:"Начальник производства или технолог" },
            { v:"no", l:"Менеджер — не его работа" },
            { v:"dont", l:"Никто не проверяет" }
          ]},
        { id:"m_tu_check_how", type:"textarea", critical:false,
          text:"Как проверит? Какими средствами и методами?",
          hint:"Замеры поверенным инструментом, визуальный осмотр, лабораторный анализ." },
        { id:"m_passport_ready", type:"choice", critical:true,
          text:"Есть ли Паспорт качества по форме Поставщика на эту партию?",
          hint:"Паспорт — единственный документ качества по п. 5.8.",
          warn:"Нет Паспорта качества на партию. Отгрузка без обязательного документа.",
          options:[
            { v:"yes", l:"Да, готов" },
            { v:"partial", l:"В процессе оформления" },
            { v:"no", l:"Нет" },
            { v:"dont", l:"Не проверяли" }
          ]},
        { id:"m_responsibility", type:"choice", critical:false,
          text:"Есть ли у менеджера ответственность за нереалистичные обещания?",
          hint:"Внутренний регламент.",
          warn:"Без регламента менеджер снова пообещает невыполнимое.",
          options:[
            { v:"yes", l:"Да, регламент и последствия" },
            { v:"no", l:"Нет" },
            { v:"dont", l:"Устно" }
          ]},
        { id:"m_notes", type:"textarea", critical:false,
          text:"Дополнительные сомнения по производству?" }
      ]
    },
    {
      title:"Блок 3. Истинная потребность клиента",
      weight:20,
      desc:"Что клиент на самом деле покупает. Для чего, как использует, куда поедет, кто решает, по какому ТУ.",
      questions:[
        { id:"n_purpose", type:"textarea", critical:true,
          text:"Для чего клиент берёт товар? Опишите применение.",
          hint:"Изделие, конструкция, конечный продукт.",
          warn:"Без понимания применения мы не знаем реальную потребность клиента." },
        { id:"n_usage", type:"textarea", critical:true,
          text:"Как клиент будет использовать товар? Условия эксплуатации.",
          hint:"Нагрузка, среда, температура, влажность.",
          warn:"Без понимания условий эксплуатации мы не знаем, подходит ли материал." },
        { id:"n_processing", type:"choice", critical:false,
          text:"Как клиент планирует обрабатывать товар?",
          hint:"Это определяет требования к марке.",
          warn:"Без понимания обработки можем отгрузить неподходящий материал.",
          options:[
            { v:"yes", l:"Резать / гнуть / варить / штамповать" },
            { v:"partial", l:"Часть операций, есть нюансы" },
            { v:"no", l:"Не обрабатывает, ставит как есть" },
            { v:"dont", l:"Не уточняли" }
          ]},
        { id:"n_drawing", type:"choice", critical:true,
          text:"Есть ли у клиента чертёж или конечные габариты детали?",
          hint:"Иногда просит «лист 100 мм», а нужна деталь 40×60 см из 20 мм.",
          warn:"Нет чертежа — риск продать лишний объём и толщину.",
          options:[
            { v:"yes", l:"Да, есть чертёж или габариты" },
            { v:"partial", l:"Частично — общие размеры" },
            { v:"no", l:"Нет, только описание" },
            { v:"dont", l:"Не запрашивали" }
          ]},
        { id:"n_fastening", type:"choice", critical:false,
          text:"Как клиент будет крепить деталь?",
          hint:"От этого зависит требование к свариваемости.",
          warn:"Без понимания крепления можем продать несвариваемую марку.",
          options:[
            { v:"yes", l:"Сварка — свариваемость критична" },
            { v:"partial", l:"Болты / заклёпки / фланцы" },
            { v:"no", l:"Без крепления" },
            { v:"dont", l:"Не уточняли" }
          ]},
        { id:"n_city", type:"text", critical:true,
          text:"В какой город поедет товар? Конечная точка доставки.",
          hint:"Логистика, срок, стоимость, риски.",
          warn:"Без конечной точки не знаем реальную логистику." },
        { id:"n_lpr", type:"text", critical:true,
          text:"Кто руководитель клиента? ФИО и телефон секретаря.",
          hint:"Для эскалации и проверки реальности клиента.",
          warn:"Без ЛПР нельзя согласовать спорные вопросы." },
        { id:"n_role", type:"choice", critical:true,
          text:"Он посредник или конечный потребитель?",
          hint:"Посредники капризнее и часто не знают деталей.",
          warn:"Без понимания роли клиента не знаем, как строить работу.",
          options:[
            { v:"yes", l:"Конечный потребитель" },
            { v:"partial", l:"Посредник с контрактом с конечником" },
            { v:"no", l:"Посредник без конечного контракта — риск" },
            { v:"dont", l:"Не уточняли" }
          ]},
        { id:"n_experience", type:"choice", critical:false,
          text:"Есть ли у клиента опыт работы с таким товаром?",
          hint:"Первая покупка = больше вопросов.",
          warn:"Клиент покупает впервые — будет много уточнений.",
          options:[
            { v:"yes", l:"Да, работает давно" },
            { v:"partial", l:"Опыт небольшой" },
            { v:"no", l:"Первый раз" },
            { v:"dont", l:"Не уточняли" }
          ]},
        { id:"n_priority", type:"choice", critical:false,
          text:"Что для клиента критично?",
          hint:"От этого зависит, чем можно поступиться.",
          warn:"Без понимания приоритетов можем промахнуться по ключевому критерию.",
          options:[
            { v:"yes", l:"Цена — ищем дешевле" },
            { v:"partial", l:"Срок — нужно быстро" },
            { v:"no", l:"Качество и документы" },
            { v:"dont", l:"Всё вместе" }
          ]},
        { id:"n_deadline", type:"text", critical:true,
          text:"Когда товар нужен у него на складе?",
          hint:"Не когда мы отгрузим, а когда ему надо получить.",
          warn:"Без срока на складе клиента не понимаем реальный дедлайн." },
        { id:"n_tu_which", type:"choice", critical:true,
          text:"По какому ТУ интересует клиента товар?",
          hint:"Наше ТУ / своё ТУ клиента / ГОСТ.",
          warn:"Не знаем, по какому ТУ клиент ожидает товар.",
          options:[
            { v:"yes", l:"По нашему ТУ — клиент ознакомлен" },
            { v:"partial", l:"По нашему ТУ, но клиент хочет уточнить" },
            { v:"no", l:"У клиента своё ТУ — нужно согласование" },
            { v:"dont", l:"По ГОСТ — не прорабатывали" }
          ]},
        { id:"n_tu_notice", type:"choice", critical:true,
          text:"Клиент ознакомлен с нашим ТУ до заказа?",
          hint:"Ознакомление до заказа = клиент не сможет потом требовать ГОСТ.",
          warn:"Клиент не ознакомлен с ТУ до заказа.",
          options:[
            { v:"yes", l:"Да, письменно" },
            { v:"partial", l:"Отправили, но подтверждения нет" },
            { v:"no", l:"Нет, не отправляли" },
            { v:"dont", l:"Устно" }
          ]},
        { id:"n_competitors", type:"textarea", critical:false,
          text:"Кто ещё претендует на этот заказ?",
          hint:"Конкуренты, альтернативные поставщики." },
        { id:"n_notes", type:"textarea", critical:false,
          text:"Что ещё важно знать о клиенте или его потребности?" }
      ]
    },
    {
      title:"Блок 4. Критерий возврата клиента",
      weight:15,
      desc:"Наша цель — чтобы клиент вернулся.",
      questions:[
        { id:"r_typical", type:"choice", critical:false,
          text:"Это типовая, беспроблемная сделка?",
          hint:"Обычные сделки двигаем вперёд. Сложные — по отдельному регламенту.",
          warn:"Сделка нетиповая. Двигаем по расширенному регламенту.",
          options:[
            { v:"yes", l:"Да, обычная сделка" },
            { v:"no", l:"Нет, есть нюансы" },
            { v:"dont", l:"Пока не понятно" }
          ]},
        { id:"r_promise", type:"choice", critical:true,
          text:"Что мы обещаем клиенту по срокам, качеству, упаковке, документам?",
          hint:"Перечислите все обещания до отправки документов.",
          warn:"Менеджер, сначала зафиксируй все обещания клиенту.",
          options:[
            { v:"yes", l:"Всё перечислено и зафиксировано" },
            { v:"no", l:"Не всё — есть устные" },
            { v:"dont", l:"Обещания размыты" }
          ]},
        { id:"r_can_do", type:"choice", critical:true,
          text:"Всё ли из обещанного мы можем выполнить?",
          hint:"Если хотя бы одно обещание под вопросом — сделка не готова.",
          warn:"Обещаем то, что не можем выполнить. Путь к рекламации.",
          options:[
            { v:"yes", l:"Да, всё можем" },
            { v:"no", l:"Не всё — есть сомнения" },
            { v:"dont", l:"Не проверяли по пунктам" }
          ]},
        { id:"r_safe", type:"choice", critical:true,
          text:"Будет ли отгрузка качественной и безопасной?",
          hint:"Упаковка, документы, транспорт, страхование.",
          warn:"Отгрузка небезопасна.",
          options:[
            { v:"yes", l:"Да, всё готово" },
            { v:"no", l:"Есть риски" },
            { v:"dont", l:"Не проверяли" }
          ]},
        { id:"r_return", type:"choice", critical:true,
          text:"Готовы ли мы сделать так, чтобы клиент вернулся?",
          hint:"Сервис, качество, коммуникация на следующую сделку.",
          warn:"Без готовности к возврату первая сделка станет последней.",
          options:[
            { v:"yes", l:"Да, готовы" },
            { v:"no", l:"Нужно доработать" },
            { v:"dont", l:"Не думали" }
          ]},
        { id:"r_objection", type:"textarea", critical:false,
          text:"Что может помешать клиенту вернуться?",
          hint:"Честно: что может его разочаровать или увести к конкурентам." }
      ]
    }
  ];

  var app = document.getElementById("spApp");
  var introScreen = app.querySelector("#spIntro");
  var formScreen  = app.querySelector("#spForm");
  var startBtn = app.querySelector("#spStart");
  var form = app.querySelector("#spFormEl");
  var blocksContainer = app.querySelector("#spBlocks");
  var filledEl = app.querySelector("#spFilled");
  var totalEl = app.querySelector("#spTotal");
  var progressFill = app.querySelector("#spProgress");
  var timeEl = app.querySelector("#spTime");
  var draftNote = app.querySelector("#spDraftNote");
  var flagBuyer = app.querySelector("#spFlagBuyer");
  var flagBuyerVal = app.querySelector("#spFlagBuyerVal");
  var flagManager = app.querySelector("#spFlagManager");
  var flagManagerVal = app.querySelector("#spFlagManagerVal");
  var flagNeed = app.querySelector("#spFlagNeed");
  var flagNeedVal = app.querySelector("#spFlagNeedVal");
  var flagReturn = app.querySelector("#spFlagReturn");
  var flagReturnVal = app.querySelector("#spFlagReturnVal");
  var submitBtn = app.querySelector("#spSubmit");
  var resetBtn = app.querySelector("#spReset");
  var consent = app.querySelector("#spConsent");
  var clientEl = app.querySelector("#spClient");
  var dealEl = app.querySelector("#spDeal");
  var managerEl = app.querySelector("#spManager");
  var hpField = app.querySelector("#spHp");
  var reportBox = app.querySelector("#spReport");
  var yearEl = app.querySelector("#spYear");
  var saveBanner = app.querySelector("#spSaveBanner");
  var saveBannerClose = app.querySelector("#spSaveBannerClose");

  yearEl.textContent = new Date().getFullYear();

  var allTextareas = [];
  var allTextInputs = [];
  var allChoices = [];
  var draftTimer = null;
  var bannerTimer = null;

  var MISSING_CRIT = "⚠ НЕОБХОДИМО ЗАПОЛНИТЬ — КРИТИЧНО";
  var MISSING_OPT = "— не заполнено —";
  var MISSING_CHOICE_CRIT = "⚠ НЕОБХОДИМО ЗАПОЛНИТЬ — КРИТИЧНО";
  var MISSING_CHOICE_OPT = "— не проверено —";

  function showScreen(el){
    [introScreen, formScreen].forEach(function(s){
      s.classList.toggle("active", s === el);
    });
    window.scrollTo({ top:0, behavior:"smooth" });
  }

  function buildForm(){
    blocksContainer.innerHTML = "";
    var total = 0;

    BLOCKS.forEach(function(block, bi){
      var sec = document.createElement("section");
      sec.className = "block";
      sec.setAttribute("data-block", bi);
      sec.setAttribute("data-weight", block.weight);

      var html = '&lt;div class="block-head"&gt;&lt;h2&gt;' + block.title + '&lt;/h2&gt;'
               + '&lt;span class="weight"&gt;Вес: ' + block.weight + '%&lt;/span&gt;&lt;/div&gt;'
               + '&lt;p class="block-desc"&gt;' + block.desc + '&lt;/p&gt;';

      block.questions.forEach(function(q, qi){
        var qnum = (bi+1) + "." + (qi+1);
        total++;
        var critBadge = q.critical ? '&lt;span class="q-critical"&gt;КРИТИЧНО&lt;/span&gt;' : '';

        html += '&lt;div class="q" data-qid="' + q.id + '" data-critical="' + (q.critical ? "1" : "0") + '"&gt;';
        html += '&lt;label class="q-label"&gt;&lt;span class="num"&gt;' + qnum + '&lt;/span&gt;'
             +  q.text + critBadge + '&lt;/label&gt;';
        if (q.hint) html += '&lt;div class="q-hint"&gt;' + q.hint + '&lt;/div&gt;';

        if (q.type === "textarea") {
          html += '&lt;textarea data-id="' + q.id + '" placeholder="Опишите факты..."&gt;&lt;/textarea&gt;';
          if (q.warn) {
            html += '&lt;div class="q-body" style="margin-top:8px"&gt;&lt;div class="q-warning" data-qwarn="' + q.id + '"&gt;&lt;/div&gt;&lt;/div&gt;';
          }
        } else if (q.type === "text") {
          html += '&lt;input type="text" data-id="' + q.id + '" placeholder="Введите данные..."&gt;';
          if (q.warn) {
            html += '&lt;div class="q-body" style="margin-top:8px"&gt;&lt;div class="q-warning" data-qwarn="' + q.id + '"&gt;&lt;/div&gt;&lt;/div&gt;';
          }
        } else if (q.type === "choice") {
          html += '&lt;div class="q-body"&gt;';
          html += '&lt;div class="q-answers"&gt;';
          q.options.forEach(function(opt){
            html += '&lt;label class="q-answer"&gt;'
                 +  '&lt;input type="radio" name="' + q.id + '" value="' + opt.v + '"&gt;'
                 +  '&lt;span class="box"&gt;&lt;/span&gt;'
                 +  '&lt;span class="lbl"&gt;' + opt.l + '&lt;/span&gt;'
                 +  '&lt;/label&gt;';
          });
          html += '&lt;/div&gt;';
          html += '&lt;div class="q-warning" data-qwarn="' + q.id + '"&gt;&lt;/div&gt;';
          html += '&lt;/div&gt;';
        }
        html += '&lt;/div&gt;';
      });

      sec.innerHTML = html;
      blocksContainer.appendChild(sec);
    });

    allTextareas = Array.prototype.slice.call(blocksContainer.querySelectorAll("textarea[data-id]"));
    allTextInputs = Array.prototype.slice.call(blocksContainer.querySelectorAll("input[type=text][data-id]"));
    allChoices = Array.prototype.slice.call(blocksContainer.querySelectorAll("input[type=radio]"));
    totalEl.textContent = total;

    allTextareas.forEach(function(t){
      t.addEventListener("input", function(){ updateUI(); saveDraft(); });
    });
    allTextInputs.forEach(function(t){
      t.addEventListener("input", function(){ updateUI(); saveDraft(); });
    });
    allChoices.forEach(function(c){
      c.addEventListener("change", function(){ updateUI(); saveDraft(); });
    });
  }

  function getAnswers(){
    var data = {};
    allTextareas.forEach(function(t){ data[t.getAttribute("data-id")] = t.value; });
    allTextInputs.forEach(function(t){ data[t.getAttribute("data-id")] = t.value; });
    allChoices.forEach(function(c){
      if (c.checked) data[c.name] = c.value;
    });
    return data;
  }

  function countFilled(){
    var count = 0;
    allTextareas.forEach(function(t){ if ((t.value || "").trim()) count++; });
    allTextInputs.forEach(function(t){ if ((t.value || "").trim()) count++; });
    var groups = {};
    allChoices.forEach(function(c){ if (c.checked) groups[c.name] = true; });
    count += Object.keys(groups).length;
    return count;
  }

  function computeTotal(){
    var n = 0;
    BLOCKS.forEach(function(b){ b.questions.forEach(function(){ n++; }); });
    return n;
  }

  function scoreAnswer(q, value){
    if (value === undefined || value === null || value === "") return null;
    if (value === "yes") return "g";
    if (value === "partial") return "y";
    if (value === "no") return q.critical ? "r" : "y";
    if (value === "dont") return q.critical ? "r" : "y";
    return "y";
  }

  function evaluateBlock(bi){
    var answers = getAnswers();
    var block = BLOCKS[bi];
    var counts = { g:0, y:0, r:0 };
    block.questions.forEach(function(q){
      if (q.type !== "choice") return;
      var s = scoreAnswer(q, answers[q.id]);
      if (s === null) return;
      counts[s]++;
    });
    var status;
    if (counts.r &gt; 0) status = "r";
    else if (counts.y &gt; 0) status = "y";
    else if (counts.g &gt; 0) status = "g";
    else status = null;
    return { status: status, counts: counts };
  }

  function applyFlag(cardEl, valEl, status, ready){
    cardEl.classList.remove("g","y","r");
    if (!ready || !status) { valEl.textContent = "— не проверено"; return; }
    if (status === "g") { cardEl.classList.add("g"); valEl.textContent = "Готово"; }
    else if (status === "y") { cardEl.classList.add("y"); valEl.textContent = "Есть пробелы"; }
    else if (status === "r") { cardEl.classList.add("r"); valEl.textContent = "КРИТИЧНО: не готово"; }
  }

  function updateWarnings(){
    var answers = getAnswers();
    BLOCKS.forEach(function(block){
      block.questions.forEach(function(q){
        var wrap = blocksContainer.querySelector('[data-qwarn="' + q.id + '"]');
        if (!wrap) return;

        var a = answers[q.id];
        var s;

        if (q.type === "choice") {
          s = scoreAnswer(q, a);
        } else if (q.type === "textarea" || q.type === "text") {
          if (a === undefined || !(a || "").trim()) {
            s = q.critical ? "r" : "y";
          } else {
            s = "g";
          }
        }

        if (s === null || !q.warn) {
          wrap.classList.remove("visible", "y");
          wrap.innerHTML = "";
          return;
        }

        if (s === "r") {
          wrap.classList.remove("y");
          wrap.innerHTML = '&lt;span class="wicon"&gt;⚠&lt;/span&gt;' + q.warn;
          wrap.classList.add("visible");
        } else if (s === "y") {
          wrap.classList.add("y");
          wrap.innerHTML = '&lt;span class="wicon"&gt;⚠&lt;/span&gt;' + q.warn;
          wrap.classList.add("visible");
        } else {
          wrap.classList.remove("visible", "y");
          wrap.innerHTML = "";
        }
      });
    });
  }

  function updateUI(){
    var filled = countFilled();
    var total = computeTotal();
    filledEl.textContent = filled;
    progressFill.style.width = ((filled / total) * 100) + "%";

    var remaining = Math.max(0, total - filled);
    var minutesLeft = Math.ceil(remaining * 0.3);
    if (minutesLeft &lt;= 0) timeEl.textContent = "Почти готово";
    else if (minutesLeft === 1) timeEl.textContent = "Осталась примерно 1 минута";
    else if (minutesLeft &lt; 5) timeEl.textContent = "Осталось примерно " + minutesLeft + " минуты";
    else timeEl.textContent = "Осталось примерно " + minutesLeft + " минут";

    var ready = filled &gt;= 15;
    var b1 = evaluateBlock(0);
    var b2 = evaluateBlock(1);
    var b3 = evaluateBlock(2);
    var b4 = evaluateBlock(3);
    applyFlag(flagBuyer, flagBuyerVal, b1.status, ready);
    applyFlag(flagManager, flagManagerVal, b2.status, ready);
    applyFlag(flagNeed, flagNeedVal, b3.status, ready);
    applyFlag(flagReturn, flagReturnVal, b4.status, ready);

    updateWarnings();

    var contactOk = clientEl.value.trim().length &gt; 0
                 &amp;&amp; dealEl.value.trim().length &gt; 0
                 &amp;&amp; managerEl.value.trim().length &gt; 0;

    submitBtn.disabled = !(consent.checked &amp;&amp; contactOk &amp;&amp; filled &gt;= 15);

    if (b1.status === "r" || b2.status === "r" || b3.status === "r" || b4.status === "r") {
      submitBtn.className = "blocked";
      submitBtn.textContent = "СТОП: красные флаги. Отправлять нельзя";
    } else if (ready &amp;&amp; filled &gt;= 15) {
      submitBtn.className = "primary";
      submitBtn.textContent = "Проверить сделку";
    }
  }

  function saveDraft(){
    try {
      var data = {
        answers: getAnswers(),
        client: clientEl.value,
        deal: dealEl.value,
        manager: managerEl.value
      };
      localStorage.setItem(STORAGE_KEY, JSON.stringify(data));
      showDraftNote();
    } catch(e){}
  }

  function loadDraft(){
    try {
      var raw = localStorage.getItem(STORAGE_KEY);
      if (!raw) return false;
      var data = JSON.parse(raw);
      var restored = 0;
      if (data.answers) {
        allTextareas.forEach(function(t){
          var k = t.getAttribute("data-id");
          if (data.answers[k]) { t.value = data.answers[k]; restored++; }
        });
        allTextInputs.forEach(function(t){
          var k = t.getAttribute("data-id");
          if (data.answers[k]) { t.value = data.answers[k]; restored++; }
        });
        allChoices.forEach(function(c){
          if (data.answers[c.name] === c.value) c.checked = true;
        });
      }
      if (data.client) clientEl.value = data.client;
      if (data.deal) dealEl.value = data.deal;
      if (data.manager) managerEl.value = data.manager;
      if (restored &gt; 0) showDraftNote("Черновик восстановлен");
      return restored &gt; 0;
    } catch(e){ return false; }
  }

  function showDraftNote(text){
    if (!draftNote) return;
    if (text) draftNote.textContent = text;
    draftNote.classList.remove("hidden");
    if (draftTimer) clearTimeout(draftTimer);
    draftTimer = setTimeout(function(){ draftNote.classList.add("hidden"); }, 2500);
  }

  function showSaveBanner(){
    if (!saveBanner) return;
    saveBanner.classList.add("visible");
    if (bannerTimer) clearTimeout(bannerTimer);
    bannerTimer = setTimeout(function(){
      saveBanner.classList.remove("visible");
    }, 8000);
  }

  function hideSaveBanner(){
    if (!saveBanner) return;
    saveBanner.classList.remove("visible");
  }

  function collectFlags(){
    var answers = getAnswers();
    var red = [];
    var yellow = [];
    var green = [];

    BLOCKS.forEach(function(block, bi){
      block.questions.forEach(function(q, qi){
        var qnum = (bi+1) + "." + (qi+1);
        var a = answers[q.id];
        var s;

        if (q.type === "choice") {
          s = scoreAnswer(q, a);
          var optLabel = q.critical ? MISSING_CHOICE_CRIT : MISSING_CHOICE_OPT;
          if (a !== undefined) {
            var opt = q.options.filter(function(o){ return o.v === a; })[0];
            if (opt) optLabel = opt.l;
          }
          var line = { num: qnum, text: q.text, answer: optLabel, warn: q.warn || "", block: bi };
          if (s === "r") red.push(line);
          else if (s === "y") yellow.push(line);
          else if (s === "g") green.push(line);
        } else if (q.type === "textarea" || q.type === "text") {
          var txt = (a || "").trim();
          if (!txt) {
            var ansText = q.critical ? MISSING_CRIT : MISSING_OPT;
            var line2 = { num: qnum, text: q.text, answer: ansText, warn: q.warn || "", block: bi };
            if (q.critical) red.push(line2);
            else yellow.push(line2);
          } else {
            green.push({ num: qnum, text: q.text, answer: txt.slice(0, 120), warn: "", block: bi });
          }
        }
      });
    });

    return { red: red, yellow: yellow, green: green };
  }

  function statusLabel(status){
    if (status === "r") return "КРИТИЧНО";
    if (status === "y") return "Пробелы";
    if (status === "g") return "Готово";
    return "—";
  }

  function getVerdict(){
    var flags = collectFlags();
    if (flags.red.length &gt; 0) return { text:"СТОП. Сделку отправлять нельзя, пока не закрыты красные флаги.", cls:"stop" };
    if (flags.yellow.length &gt; 0) return { text:"ЖДАТЬ. Есть пробелы. Устранить до отправки документов.", cls:"wait" };
    return { text:"МОЖНО ОТПРАВЛЯТЬ. Все критичные пункты закрыты. Клиент вернётся.", cls:"go" };
  }

  function renderReport(){
    var flags = collectFlags();
    var b1 = evaluateBlock(0);
    var b2 = evaluateBlock(1);
    var b3 = evaluateBlock(2);
    var b4 = evaluateBlock(3);
    var v = getVerdict();

    var html = '&lt;h2&gt;Протокол проверки сделки&lt;/h2&gt;';
    html += '&lt;div class="verdict ' + v.cls + '"&gt;' + v.text + '&lt;/div&gt;';

    html += '&lt;div class="row"&gt;&lt;span&gt;Клиент&lt;/span&gt;&lt;strong&gt;' + (clientEl.value.trim() || "—") + '&lt;/strong&gt;&lt;/div&gt;';
    html += '&lt;div class="row"&gt;&lt;span&gt;Сделка&lt;/span&gt;&lt;strong&gt;' + (dealEl.value.trim() || "—") + '&lt;/strong&gt;&lt;/div&gt;';
    html += '&lt;div class="row"&gt;&lt;span&gt;Менеджер&lt;/span&gt;&lt;strong&gt;' + (managerEl.value.trim() || "—") + '&lt;/strong&gt;&lt;/div&gt;';
    html += '&lt;div class="row"&gt;&lt;span&gt;Щит от покупателя&lt;/span&gt;&lt;strong&gt;' + statusLabel(b1.status) + '&lt;/strong&gt;&lt;/div&gt;';
    html += '&lt;div class="row"&gt;&lt;span&gt;Щит от менеджера&lt;/span&gt;&lt;strong&gt;' + statusLabel(b2.status) + '&lt;/strong&gt;&lt;/div&gt;';
    html += '&lt;div class="row"&gt;&lt;span&gt;Истинная потребность&lt;/span&gt;&lt;strong&gt;' + statusLabel(b3.status) + '&lt;/strong&gt;&lt;/div&gt;';
    html += '&lt;div class="row"&gt;&lt;span&gt;Возврат клиента&lt;/span&gt;&lt;strong&gt;' + statusLabel(b4.status) + '&lt;/strong&gt;&lt;/div&gt;';

    if (flags.red.length &gt; 0) {
      html += '&lt;h3&gt;Красные флаги — стоп (' + flags.red.length + ')&lt;/h3&gt;&lt;ul class="list red"&gt;';
      flags.red.forEach(function(r){
        html += '&lt;li&gt;' + r.num + ' ' + r.text + ' → ' + r.answer;
        if (r.warn) html += '&lt;span class="warn-note"&gt;⚠ ' + r.warn + '&lt;/span&gt;';
        html += '&lt;/li&gt;';
      });
      html += '&lt;/ul&gt;';
    }

    if (flags.yellow.length &gt; 0) {
      html += '&lt;h3&gt;Жёлтые флаги — устранить до отправки (' + flags.yellow.length + ')&lt;/h3&gt;&lt;ul class="list yellow"&gt;';
      flags.yellow.forEach(function(r){
        html += '&lt;li&gt;' + r.num + ' ' + r.text + ' → ' + r.answer;
        if (r.warn) html += '&lt;span class="warn-note"&gt;⚠ ' + r.warn + '&lt;/span&gt;';
        html += '&lt;/li&gt;';
      });
      html += '&lt;/ul&gt;';
    }

    if (flags.green.length &gt; 0) {
      html += '&lt;h3&gt;Закрытые пункты (' + flags.green.length + ')&lt;/h3&gt;&lt;ul class="list green"&gt;';
      flags.green.forEach(function(r){ html += '&lt;li&gt;' + r.num + ' ' + r.text + '&lt;/li&gt;'; });
      html += '&lt;/ul&gt;';
    }

    html += '&lt;div class="discl"&gt;'
         +  'Документ является структурированной проверкой фактов, предоставленных '
         +  'пользователем. Не является юридической консультацией и не заменяет '
         +  'юридическую экспертизу договора. Ответственность за решения и подписание '
         +  'документов лежит на собственнике / руководителе.'
         +  '&lt;/div&gt;';

    reportBox.innerHTML = html;
    reportBox.className = "report" + (v.cls === "stop" ? " blocked" :
                                       v.cls === "wait" ? " warn" : "");
    reportBox.style.display = "block";
  }

  function buildProtocolText(){
    var answers = getAnswers();
    var flags = collectFlags();
    var b1 = evaluateBlock(0);
    var b2 = evaluateBlock(1);
    var b3 = evaluateBlock(2);
    var b4 = evaluateBlock(3);
    var v = getVerdict();
    var now = new Date();

    var L = [];
    L.push("ЩИТ ПОСТАВЩИКА");
    L.push("Протокол проверки сделки");
    L.push("================================");
    L.push("Дата: " + now.toLocaleString("ru-RU"));
    L.push("Клиент: " + clientEl.value.trim());
    L.push("Сделка: " + dealEl.value.trim());
    L.push("Менеджер: " + managerEl.value.trim());
    L.push("");
    L.push("Главный принцип: цель — не закрыть сделку, а чтобы клиент вернулся.");
    L.push("Обещаем только то, что можем выполнить.");
    L.push("");
    L.push("Щит от покупателя: " + statusLabel(b1.status));
    L.push("Щит от менеджера: " + statusLabel(b2.status));
    L.push("Истинная потребность: " + statusLabel(b3.status));
    L.push("Возврат клиента: " + statusLabel(b4.status));
    L.push("");
    L.push("РЕШЕНИЕ: " + v.text);
    L.push("");
    L.push("================================");

    BLOCKS.forEach(function(block, bi){
      L.push("");
      L.push(block.title.toUpperCase());
      L.push("---------------------------------");
      block.questions.forEach(function(q, qi){
        var qnum = (bi+1) + "." + (qi+1);
        var a = answers[q.id];
        var out;
        if (q.type === "choice") {
          if (a === undefined) {
            out = q.critical ? MISSING_CHOICE_CRIT : MISSING_CHOICE_OPT;
          } else {
            var opt = q.options.filter(function(o){ return o.v === a; })[0];
            out = opt ? opt.l : a;
          }
        } else {
          var txt = (a || "").trim();
          if (!txt) {
            out = q.critical ? MISSING_CRIT : MISSING_OPT;
          } else {
            out = txt;
          }
        }
        L.push("");
        L.push(qnum + " " + q.text + (q.critical ? " [КРИТИЧНО]" : ""));
        L.push("Ответ: " + out);
      });
    });

    L.push("");
    L.push("================================");
    L.push("КРАСНЫЕ ФЛАГИ (" + flags.red.length + ")");
    flags.red.forEach(function(r){
      L.push("  • " + r.num + " " + r.text + " → " + r.answer);
      if (r.warn) L.push("    ⚠ " + r.warn);
    });
    L.push("");
    L.push("ЖЁЛТЫЕ ФЛАГИ (" + flags.yellow.length + ")");
    flags.yellow.forEach(function(r){
      L.push("  • " + r.num + " " + r.text + " → " + r.answer);
      if (r.warn) L.push("    ⚠ " + r.warn);
    });
    L.push("");
    L.push("ЗАКРЫТЫЕ ПУНКТЫ (" + flags.green.length + ")");
    flags.green.forEach(function(r){ L.push("  • " + r.num + " " + r.text); });
    L.push("");
    L.push("================================");
    L.push("ДИСКЛЕЙМЕР");
    L.push("Документ является структурированной проверкой фактов, предоставленных");
    L.push("пользователем. Не является юридической консультацией и не заменяет");
    L.push("юридическую экспертизу договора. Ответственность за решения и подписание");
    L.push("документов лежит на собственнике / руководителе.");
    L.push("");
    L.push("Связаться: " + RECIPIENT_EMAIL);
    return L.join("\n");
  }

  function escapeHtml(s){
    return String(s || "")
      .replace(/&amp;/g, "&amp;amp;")
      .replace(/&lt;/g, "&amp;lt;")
      .replace(/&gt;/g, "&amp;gt;")
      .replace(/"/g, "&amp;quot;");
  }

  function buildProtocolHtml(){
    var answers = getAnswers();
    var flags = collectFlags();
    var b1 = evaluateBlock(0);
    var b2 = evaluateBlock(1);
    var b3 = evaluateBlock(2);
    var b4 = evaluateBlock(3);
    var v = getVerdict();
    var now = new Date();

    var colorMap = {
      stop: { bg:"#3a1d1d", fg:"#f85149", border:"#f85149", label:"СТОП" },
      wait: { bg:"#3a2f10", fg:"#d29922", border:"#d29922", label:"ЖДАТЬ" },
      go:   { bg:"#0f2a17", fg:"#3fb950", border:"#3fb950", label:"МОЖНО ОТПРАВЛЯТЬ" }
    };
    var vc = colorMap[v.cls];

    var html = '';
    html += '&lt;!DOCTYPE html&gt;&lt;html lang="ru"&gt;&lt;head&gt;&lt;meta charset="UTF-8"&gt;';
    html += '&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;';
    html += '&lt;title&gt;Щит поставщика — протокол&lt;/title&gt;';
    html += '&lt;style&gt;';
    html += 'body{margin:0;padding:32px 24px;background:#0d1117;color:#e6edf3;';
    html += 'font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif;';
    html += 'line-height:1.55;font-size:15px}';
    html += '.wrap{max-width:900px;margin:0 auto}';
    html += 'h1{font-size:24px;margin:0 0 6px;color:#e6edf3}';
    html += 'h2{font-size:16px;margin:28px 0 12px;color:#79b8ff}';
    html += 'h3{font-size:14px;margin:22px 0 10px;color:#79b8ff}';
    html += '.sub{color:#8b949e;font-size:13px;margin-bottom:22px}';
    html += '.meta{background:#161b22;border:1px solid #2a323c;border-radius:10px;padding:16px 18px;margin-bottom:18px}';
    html += '.meta .row{display:flex;justify-content:space-between;padding:6px 0;font-size:14px;gap:12px;border-bottom:1px solid #2a323c}';
    html += '.meta .row:last-child{border-bottom:none}';
    html += '.meta .row span:first-child{color:#8b949e}';
    html += '.meta .row strong{color:#e6edf3}';
    html += '.verdict{padding:16px 20px;border-radius:10px;font-weight:700;font-size:15px;';
    html += 'margin:16px 0 22px;text-transform:uppercase;letter-spacing:.05em}';
    html += '.block{background:#161b22;border:1px solid #2a323c;border-radius:12px;';
    html += 'padding:20px 22px 8px;margin-bottom:16px}';
    html += '.block h3{margin:0 0 12px;color:#79b8ff}';
    html += '.q{padding:12px 0;border-top:1px solid #2a323c}';
    html += '.q:first-of-type{border-top:none}';
    html += '.q-label{font-size:14px;margin-bottom:6px;color:#e6edf3}';
    html += '.q-label .num{color:#8b949e;margin-right:6px;font-weight:600}';
    html += '.q-critical{display:inline-block;font-size:10px;color:#f85149;';
    html += 'border:1px solid #f85149;padding:1px 7px;border-radius:10px;margin-left:8px;font-weight:700}';
    html += '.q-answer{font-size:14px;padding:8px 12px;background:#1c232c;border-radius:8px;';
    html += 'border-left:3px solid #4493f8;margin-top:6px;white-space:pre-wrap;word-break:break-word}';
    html += '.q-answer.missing{border-left-color:#f85149;color:#ffb8b0;font-weight:600}';
    html += '.q-answer.ok{border-left-color:#3fb950}';
    html += '.q-answer.partial{border-left-color:#d29922;color:#f0d590}';
    html += '.flags{margin-top:24px}';
    html += '.flags h3{margin:18px 0 10px}';
    html += '.flag-list{margin:0;padding-left:20px;font-size:13px;line-height:1.7}';
    html += '.flag-list.red li::marker{color:#f85149}';
    html += '.flag-list.yellow li::marker{color:#d29922}';
    html += '.flag-list.green li::marker{color:#3fb950}';
    html += '.flag-list li{margin-bottom:10px;color:#e6edf3}';
    html += '.warn-note{display:block;font-size:12px;font-style:italic;margin-top:4px}';
    html += '.red .warn-note{color:#ffb8b0}';
    html += '.yellow .warn-note{color:#f0d590}';
    html += '.discl{font-size:12px;color:#8b949e;background:#1c232c;';
    html += 'border-left:3px solid #4493f8;padding:12px 16px;border-radius:6px;margin-top:24px;line-height:1.65}';
    html += '&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;div class="wrap"&gt;';
    html += '&lt;h1&gt;Щит поставщика — протокол проверки сделки&lt;/h1&gt;';
    html += '&lt;div class="sub"&gt;' + escapeHtml(now.toLocaleString("ru-RU")) + '&lt;/div&gt;';

    html += '&lt;div class="verdict" style="background:' + vc.bg + ';color:' + vc.fg + ';border:1px solid ' + vc.border + '"&gt;' + v.text + '&lt;/div&gt;';

    html += '&lt;div class="meta"&gt;';
    html += '&lt;div class="row"&gt;&lt;span&gt;Клиент&lt;/span&gt;&lt;strong&gt;' + escapeHtml(clientEl.value.trim() || "—") + '&lt;/strong&gt;&lt;/div&gt;';
    html += '&lt;div class="row"&gt;&lt;span&gt;Сделка&lt;/span&gt;&lt;strong&gt;' + escapeHtml(dealEl.value.trim() || "—") + '&lt;/strong&gt;&lt;/div&gt;';
    html += '&lt;div class="row"&gt;&lt;span&gt;Менеджер&lt;/span&gt;&lt;strong&gt;' + escapeHtml(managerEl.value.trim() || "—") + '&lt;/strong&gt;&lt;/div&gt;';
    html += '&lt;div class="row"&gt;&lt;span&gt;Щит от покупателя&lt;/span&gt;&lt;strong&gt;' + statusLabel(b1.status) + '&lt;/strong&gt;&lt;/div&gt;';
    html += '&lt;div class="row"&gt;&lt;span&gt;Щит от менеджера&lt;/span&gt;&lt;strong&gt;' + statusLabel(b2.status) + '&lt;/strong&gt;&lt;/div&gt;';
    html += '&lt;div class="row"&gt;&lt;span&gt;Истинная потребность&lt;/span&gt;&lt;strong&gt;' + statusLabel(b3.status) + '&lt;/strong&gt;&lt;/div&gt;';
    html += '&lt;div class="row"&gt;&lt;span&gt;Возврат клиента&lt;/span&gt;&lt;strong&gt;' + statusLabel(b4.status) + '&lt;/strong&gt;&lt;/div&gt;';
    html += '&lt;/div&gt;';

    html += '&lt;div class="sub"&gt;Главный принцип: цель — не закрыть сделку, а чтобы клиент вернулся. Обещаем только то, что можем выполнить.&lt;/div&gt;';

    BLOCKS.forEach(function(block, bi){
      html += '&lt;div class="block"&gt;&lt;h3&gt;' + escapeHtml(block.title) + '&lt;/h3&gt;';
      block.questions.forEach(function(q, qi){
        var qnum = (bi+1) + "." + (qi+1);
        var a = answers[q.id];
        var out, cls;

        if (q.type === "choice") {
          var s = scoreAnswer(q, a);
          if (a === undefined) {
            out = q.critical ? MISSING_CHOICE_CRIT : MISSING_CHOICE_OPT;
            cls = q.critical ? "missing" : "";
          } else {
            var opt = q.options.filter(function(o){ return o.v === a; })[0];
            out = opt ? opt.l : a;
            cls = s === "g" ? "ok" : (s === "y" ? "partial" : "missing");
          }
        } else {
          var txt = (a || "").trim();
          if (!txt) {
            out = q.critical ? MISSING_CRIT : MISSING_OPT;
            cls = q.critical ? "missing" : "";
          } else {
            out = txt;
            cls = "ok";
          }
        }

        html += '&lt;div class="q"&gt;';
        html += '&lt;div class="q-label"&gt;&lt;span class="num"&gt;' + qnum + '&lt;/span&gt;' + escapeHtml(q.text)
             +  (q.critical ? '&lt;span class="q-critical"&gt;КРИТИЧНО&lt;/span&gt;' : '') + '&lt;/div&gt;';
        html += '&lt;div class="q-answer ' + cls + '"&gt;' + escapeHtml(out) + '&lt;/div&gt;';
        html += '&lt;/div&gt;';
      });
      html += '&lt;/div&gt;';
    });

    html += '&lt;div class="flags"&gt;';
    if (flags.red.length &gt; 0) {
      html += '&lt;h3 style="color:#f85149"&gt;Красные флаги — стоп (' + flags.red.length + ')&lt;/h3&gt;';
      html += '&lt;ul class="flag-list red"&gt;';
      flags.red.forEach(function(r){
        html += '&lt;li&gt;' + escapeHtml(r.num + " " + r.text + " → " + r.answer);
        if (r.warn) html += '&lt;span class="warn-note"&gt;⚠ ' + escapeHtml(r.warn) + '&lt;/span&gt;';
        html += '&lt;/li&gt;';
      });
      html += '&lt;/ul&gt;';
    }
    if (flags.yellow.length &gt; 0) {
      html += '&lt;h3 style="color:#d29922"&gt;Жёлтые флаги (' + flags.yellow.length + ')&lt;/h3&gt;';
      html += '&lt;ul class="flag-list yellow"&gt;';
      flags.yellow.forEach(function(r){
        html += '&lt;li&gt;' + escapeHtml(r.num + " " + r.text + " → " + r.answer);
        if (r.warn) html += '&lt;span class="warn-note"&gt;⚠ ' + escapeHtml(r.warn) + '&lt;/span&gt;';
        html += '&lt;/li&gt;';
      });
      html += '&lt;/ul&gt;';
    }
    if (flags.green.length &gt; 0) {
      html += '&lt;h3 style="color:#3fb950"&gt;Закрытые пункты (' + flags.green.length + ')&lt;/h3&gt;';
      html += '&lt;ul class="flag-list green"&gt;';
      flags.green.forEach(function(r){
        html += '&lt;li&gt;' + escapeHtml(r.num + " " + r.text) + '&lt;/li&gt;';
      });
      html += '&lt;/ul&gt;';
    }
    html += '&lt;/div&gt;';

    html += '&lt;div class="discl"&gt;Документ является структурированной проверкой фактов, предоставленных пользователем. Не является юридической консультацией и не заменяет юридическую экспертизу договора. Ответственность за решения и подписание документов лежит на собственнике / руководителе.&lt;/div&gt;';
    html += '&lt;div class="discl"&gt;Связаться: ' + escapeHtml(RECIPIENT_EMAIL) + '&lt;/div&gt;';

    html += '&lt;/div&gt;&lt;/body&gt;&lt;/html&gt;';
    return html;
  }

  function downloadFile(name, text, mime){
    var blob = new Blob([text], { type: mime || "text/plain;charset=utf-8" });
    var url = URL.createObjectURL(blob);
    var a = document.createElement("a");
    a.href = url; a.download = name;
    document.body.appendChild(a); a.click(); document.body.removeChild(a);
    setTimeout(function(){ URL.revokeObjectURL(url); }, 2000);
  }

  function safeFileName(){
    var raw = dealEl.value.trim() || "deal";
    return raw.replace(/[^\wа-яА-Я0-9\-_]+/g, "_").slice(0, 60) || "protocol";
  }

  startBtn.addEventListener("click", function(){ showScreen(formScreen); });

  form.addEventListener("submit", function(e){
    e.preventDefault();
    if (hpField.value.trim() !== "") return;
    if (countFilled() &lt; 15) {
      alert("Пожалуйста, ответьте хотя бы на 15 вопросов.");
      return;
    }
    var name = "shchit_postavshchika_" + safeFileName() + "_" + Date.now() + ".txt";
    downloadFile(name, buildProtocolText(), "text/plain;charset=utf-8");
    renderReport();
    reportBox.scrollIntoView({ behavior:"smooth", block:"start" });
  });

  resetBtn.addEventListener("click", function(){
    if (!confirm("Очистить все ответы?")) return;
    allTextareas.forEach(function(t){ t.value = ""; });
    allTextInputs.forEach(function(t){ t.value = ""; });
    allChoices.forEach(function(c){ c.checked = false; });
    consent.checked = false;
    clientEl.value = ""; dealEl.value = ""; managerEl.value = "";
    try { localStorage.removeItem(STORAGE_KEY); } catch(e){}
    reportBox.style.display = "none";
    updateUI();
  });

  document.getElementById("spSaveNow").addEventListener("click", function(){
    saveDraft();
    showSaveBanner();
  });

  saveBannerClose.addEventListener("click", hideSaveBanner);

  document.getElementById("spDownloadTxt").addEventListener("click", function(){
    var name = "shchit_postavshchika_" + safeFileName() + "_" + Date.now() + ".txt";
    downloadFile(name, buildProtocolText(), "text/plain;charset=utf-8");
  });

  document.getElementById("spDownloadHtml").addEventListener("click", function(){
    var name = "shchit_postavshchika_" + safeFileName() + "_" + Date.now() + ".html";
    downloadFile(name, buildProtocolHtml(), "text/html;charset=utf-8");
  });

  document.getElementById("spDownloadPdf").addEventListener("click", function(){
    renderReport();
    reportBox.style.display = "block";
    setTimeout(function(){
      window.print();
    }, 200);
  });

  document.getElementById("spPrintBtn").addEventListener("click", function(){
    window.print();
  });

  [consent, clientEl, dealEl, managerEl].forEach(function(el){
    el.addEventListener("input", updateUI);
    el.addEventListener("change", updateUI);
  });

  buildForm();
  var restored = loadDraft();
  updateUI();

  // Показываем плашку про сохранение при восстановлении
  if (restored) {
    showSaveBanner();
  }
})();
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</subtitle>
  <updated>2026-09-23T08:34:46Z</updated>
  <logo>https://pandoraburo.ru/ssl/u/pic/ef/f66878aa6d11f1abb9f7ceed6face4/-/image%20%284%29.jpg</logo>
  <author>
    <name>1592962</name>
    <uri>https://www.pandoraburo.ru/</uri>
  </author>
</feed>
