<?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/uchk-universalnyy-raschet</id>
  <link href="https://www.pandoraburo.ru/uchk-universalnyy-raschet.xml" rel="self"/>
  <title>УЧК универсальный расчет</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;Утяжелители чугунные УЧК · Прайс-лист · PRO&lt;/title&gt;
&lt;style&gt;
  :root{
    --gold:#FFD700;--gold-light:#FFE55C;--gold-deep:#B8860B;
    --bg:#0a0a0a;--muted:#9a8040;--border:rgba(212,175,55,.35);
    --accent:#FF8C00;--ok:#b9ff9f;--bad:#ff9a9a;
  }
  *{box-sizing:border-box;margin:0;padding:0}
  body{background:#050505;color:#e8e8e8;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;padding:20px 14px;line-height:1.5;}
  .wrap{max-width:1600px;margin:0 auto}

  /* ===== БАННЕР ===== */
  .banner{max-width:640px;margin:0 auto 14px;background:radial-gradient(120% 120% at 20% 0%,rgba(255,215,0,.18),transparent 55%),linear-gradient(135deg,#111,#0a0a0a);border:1px solid var(--gold);border-radius:14px;padding:24px;text-align:center;box-shadow:0 6px 22px rgba(0,0,0,.6);}
  .banner-tag{display:inline-block;background:var(--gold);color:#0a0a0a;font-size:10px;font-weight:800;letter-spacing:2px;padding:3px 12px;border-radius:999px;margin-bottom:12px;}
  .banner-title{font-weight:800;font-size:22px;line-height:1.15;color:#fff;margin-bottom:10px;}
  .banner-phone{font-size:18px;font-weight:800;color:var(--gold);margin-bottom:4px;}
  .banner-note{font-size:12px;color:var(--muted);}

  /* ===== БЕГУЩАЯ СТРОКА ===== */
  .ticker{display:flex;align-items:stretch;background:var(--bg);border:1px solid var(--gold);border-radius:8px;overflow:hidden;margin-bottom:14px;height:44px;}
  .ticker-label{background:var(--gold);color:#0a0a0a;font-weight:800;font-size:12px;letter-spacing:1.5px;padding:0 16px;display:flex;align-items:center;white-space:nowrap;}
  .ticker-vp{flex:1;overflow:hidden;position:relative}
  .ticker-track{display:inline-flex;align-items:center;height:100%;white-space:nowrap;animation:tickerMove 50s linear infinite;padding-left:20px;}
  .ticker-item{color:var(--gold);font-size:13px;padding:0 10px}
  .ticker-item b{color:var(--gold-light);font-weight:700}
  .ticker-dot{color:var(--gold);font-size:10px}
  @keyframes tickerMove{0%{transform:translateX(0)}100%{transform:translateX(-50%)}}

  /* ===== РЕКЛАМНАЯ ПОЛОСА ===== */
  .ad-strip{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:14px;}
  @media(max-width:700px){.ad-strip{grid-template-columns:1fr}}
  .ad-item{display:flex;align-items:center;gap:12px;padding:14px 18px;background:linear-gradient(135deg,rgba(255,215,0,.1) 0%,rgba(10,15,30,.7) 100%);border:1px solid var(--border);border-radius:14px;text-decoration:none;transition:all .25s;}
  .ad-item:hover{border-color:var(--gold);box-shadow:0 0 20px rgba(255,215,0,.3);transform:translateY(-2px);}
  .ad-tag{background:var(--gold);color:#0a0a0a;font-size:.68rem;font-weight:800;letter-spacing:.8px;text-transform:uppercase;padding:4px 10px;border-radius:999px;flex-shrink:0;}
  .ad-text{color:#e8f4ff;font-size:.9rem;font-weight:600;flex:1;}
  .ad-cta{color:var(--gold);font-size:.85rem;font-weight:800;letter-spacing:.5px;white-space:nowrap;}
  .ad-item:hover .ad-cta{color:var(--gold-light);text-shadow:0 0 8px var(--gold-light);}

  /* ===== ШАПКА ===== */
  .header{background:radial-gradient(120% 120% at 20% 0%,rgba(255,215,0,.25),transparent 55%),linear-gradient(135deg,#1a1408,#0a0a0a);border:2px solid var(--gold);border-radius:14px;padding:32px 24px;text-align:center;margin-bottom:16px;box-shadow:0 0 40px rgba(255,215,0,.25),0 6px 22px rgba(0,0,0,.6);}
  .tag{display:inline-block;background:var(--gold);color:#0a0a0a;font-size:10px;font-weight:800;letter-spacing:2px;padding:4px 14px;border-radius:999px;margin-bottom:14px;box-shadow:0 0 16px rgba(255,215,0,.7);}
  .header h1{font-size:30px;font-weight:900;letter-spacing:4px;color:var(--gold);text-transform:uppercase;margin-bottom:12px;text-shadow:0 0 10px rgba(255,215,0,.95),0 0 25px rgba(255,199,0,.8),0 0 45px rgba(255,170,0,.6);animation:goldPulse 3s ease-in-out infinite;}
  @keyframes goldPulse{0%,100%{text-shadow:0 0 10px rgba(255,215,0,.95),0 0 25px rgba(255,199,0,.8),0 0 45px rgba(255,170,0,.6);}50%{text-shadow:0 0 15px rgba(255,215,0,1),0 0 35px rgba(255,199,0,.95),0 0 60px rgba(255,170,0,.8);}}
  .line{width:80px;height:3px;background:var(--gold);margin:0 auto 14px;border-radius:2px;box-shadow:0 0 15px var(--gold);}
  .header p{color:var(--gold-light);font-size:14px;opacity:.95;}

  /* ===== СТАТИСТИКА ===== */
  .stats{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:16px;}
  @media(max-width:800px){.stats{grid-template-columns:repeat(2,1fr);}}
  @media(max-width:500px){.stats{grid-template-columns:1fr;}}
  .stat{background:var(--bg);border:1px solid var(--gold);border-radius:12px;padding:16px;text-align:center;}
  .lbl{font-size:10px;font-weight:700;letter-spacing:1px;text-transform:uppercase;color:var(--gold);opacity:.7;margin-bottom:6px;}
  .val{font-size:22px;font-weight:800;color:var(--gold-light);line-height:1.1;}
  .val.sm{font-size:16px;}

  /* ===== ТУЛБАР ===== */
  .toolbar{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:16px;}
  .btn{display:inline-flex;align-items:center;gap:6px;padding:10px 16px;border-radius:9px;border:1px solid var(--gold);background:transparent;color:var(--gold);font-size:13px;font-weight:700;cursor:pointer;transition:.15s;font-family:inherit;letter-spacing:.3px;}
  .btn:hover{background:var(--gold);color:#0a0a0a;}
  .btn.primary{background:var(--gold);color:#0a0a0a;}
  .btn.primary:hover{background:var(--gold-light);border-color:var(--gold-light);}

  /* ===== ФИЛЬТР ===== */
  .filter{background:var(--bg);border:1px solid var(--gold);border-radius:14px;padding:16px;margin-bottom:16px;}
  .filter-row{display:grid;grid-template-columns:2fr 1fr;gap:12px;margin-bottom:12px;}
  @media(max-width:700px){.filter-row{grid-template-columns:1fr;}}
  .filter-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:10px;}
  @media(max-width:1000px){.filter-grid{grid-template-columns:repeat(3,1fr);}}
  @media(max-width:700px){.filter-grid{grid-template-columns:1fr 1fr;}}
  @media(max-width:450px){.filter-grid{grid-template-columns:1fr;}}
  .fld{display:flex;flex-direction:column;gap:5px;}
  .fld label{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:1px;color:var(--gold);opacity:.85;}
  .fld input,.fld select{padding:10px 12px;border:1px solid var(--gold);border-radius:9px;font-size:13px;background:var(--bg);color:var(--gold-light);outline:none;font-family:inherit;font-variant-numeric:tabular-nums;width:100%;}
  .fld input::placeholder{color:rgba(212,175,55,.35);}
  .search{width:100%;padding:13px 16px;border:2px solid var(--gold);border-radius:9px;font-size:14px;background:var(--bg);color:var(--gold-light);outline:none;font-family:inherit;font-weight:600;}
  .search::placeholder{color:rgba(212,175,55,.4);}
  .counter{color:var(--gold);font-size:14px;white-space:nowrap;padding:13px 18px;border:1px solid var(--gold);border-radius:9px;background:var(--bg);font-weight:800;display:flex;align-items:center;justify-content:center;}
  .filter-actions{display:flex;gap:8px;margin-top:10px;flex-wrap:wrap;}

  /* ===== ТАБЛИЦА ===== */
  .table-block{background:var(--bg);border:1px solid var(--gold);border-radius:14px;padding:20px;margin-bottom:16px;position:relative;}
  .block-title{color:var(--gold);font-size:12px;font-weight:800;letter-spacing:2px;text-align:center;margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid var(--border);text-transform:uppercase;text-shadow:0 0 12px rgba(255,215,0,.6);}
  .table-wrap{overflow:auto;max-height:60vh;border-radius:8px;border:1px solid var(--gold);}
  table{width:100%;table-layout:auto;border-collapse:collapse;background:var(--bg);font-size:13px;}
  th,td{padding:11px 10px;text-align:left;border-bottom:1px solid rgba(212,175,55,.2);vertical-align:middle;color:var(--gold);background:transparent;white-space:nowrap;}
  th{position:sticky;top:0;z-index:2;background:var(--bg);color:var(--gold);font-weight:800;text-transform:uppercase;font-size:10px;letter-spacing:1px;border-bottom:1px solid var(--gold);cursor:pointer;user-select:none;}
  th:hover{background:#1a1408;}
  th.sortable::after{content:' ⇅';opacity:.5;margin-left:4px;font-size:9px;}
  th.asc::after{content:' ▲';opacity:1;color:var(--gold-light);}
  th.desc::after{content:' ▼';opacity:1;color:var(--gold-light);}
  th.num,td.num{text-align:right;font-variant-numeric:tabular-nums;}
  th.col-num,td.col-num{width:38px;text-align:center;}
  th.col-star,td.col-star{width:44px;text-align:center;padding:8px 6px;}
  th.col-star{position:sticky;top:0;background:linear-gradient(180deg,#1a1408,#0a0a0a) !important;}
  th.col-star::before{content:'▼';position:absolute;top:100%;left:50%;transform:translateX(-50%);color:var(--gold);font-size:20px;line-height:1;text-shadow:0 0 12px rgba(255,215,0,1),0 0 24px rgba(255,199,0,.8);animation:arrowBounce 1s ease-in-out infinite;pointer-events:none;}
  @keyframes arrowBounce{0%,100%{transform:translateX(-50%) translateY(0);opacity:1;}50%{transform:translateX(-50%) translateY(6px);opacity:.7;}}
  .select-hint{position:absolute;top:-14px;left:0;background:linear-gradient(135deg,#FFD700,#FF8C00);color:#0a0a0a;font-size:11px;font-weight:900;letter-spacing:1.5px;padding:6px 18px;border-radius:999px;box-shadow:0 0 20px rgba(255,215,0,.7);text-transform:uppercase;animation:hintPulse 1.5s ease-in-out infinite;z-index:5;white-space:nowrap;}
  @keyframes hintPulse{0%,100%{box-shadow:0 0 20px rgba(255,215,0,.7);transform:scale(1);}50%{box-shadow:0 0 35px rgba(255,215,0,1),0 0 60px rgba(255,140,0,.6);transform:scale(1.05);}}
  tbody tr{transition:background .15s;}
  tbody tr:hover{background:#1a1408;box-shadow:inset 3px 0 0 var(--gold-light),inset -3px 0 0 var(--gold-light);}
  tbody tr.picked{background:linear-gradient(90deg,rgba(255,215,0,.15),rgba(255,215,0,.04));box-shadow:inset 4px 0 0 var(--gold);}
  td.price{font-weight:800;color:var(--gold-light);font-size:14px;}
  td.cost{font-weight:700;color:#9a9590;font-size:12px;}
  td.margin{font-weight:700;color:var(--ok);font-size:12px;}
  td.article{font-family:'Courier New',monospace;font-size:12px;color:var(--gold-light);}
  td.dims{font-weight:700;color:var(--gold-light);font-size:13px;letter-spacing:.3px;}
  td b{color:#fff;}
  .badge{display:inline-block;padding:2px 8px;border-radius:10px;font-size:10px;font-weight:800;text-transform:uppercase;background:rgba(212,175,55,.15);color:var(--gold-light);border:1px solid rgba(212,175,55,.5);letter-spacing:.3px;white-space:nowrap;}
  .badge.many{background:rgba(57,255,20,.08);color:var(--ok);border-color:rgba(57,255,20,.3);}
  .badge.zero{background:rgba(255,107,107,.12);color:var(--bad);border-color:rgba(255,107,107,.4);}
  .star{cursor:pointer;font-size:22px;color:rgba(212,175,55,.35);transition:all .2s;user-select:none;text-align:center;display:inline-block;}
  .star:hover{color:var(--gold);transform:scale(1.3);}
  .star.on{color:var(--gold-light);text-shadow:0 0 12px var(--gold-light),0 0 24px rgba(255,215,0,.5);}
  .footnote{display:flex;flex-wrap:wrap;gap:20px;margin-top:14px;padding-top:12px;border-top:1px solid var(--gold);}
  .fn{color:var(--gold);font-size:12px;position:relative;padding-left:14px;opacity:.9;}
  .fn::before{content:"◆";position:absolute;left:0;color:var(--gold);font-size:8px;top:4px;}

  /* ===== КАЛЬКУЛЯТОР ===== */
  .calc-block{background:linear-gradient(135deg,rgba(255,215,0,.08),rgba(10,10,10,.98));border:3px solid var(--gold);border-radius:18px;padding:26px 22px;margin:20px 0;box-shadow:0 0 50px rgba(255,215,0,.35),inset 0 0 30px rgba(255,215,0,.06);position:relative;}
  .calc-block::before{content:'◆ КОММЕРЧЕСКИЙ РАСЧЁТ ◆';position:absolute;top:-14px;left:50%;transform:translateX(-50%);background:var(--bg);color:var(--gold);padding:4px 20px;border:2px solid var(--gold);border-radius:999px;font-size:11px;font-weight:900;letter-spacing:3px;text-shadow:0 0 12px rgba(255,215,0,.8);white-space:nowrap;}
  .calc-header{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:16px;}
  @media(max-width:1000px){.calc-header{grid-template-columns:1fr 1fr;}}
  @media(max-width:600px){.calc-header{grid-template-columns:1fr;}}
  .calc-ctrl{background:rgba(0,0,0,.5);border:1px solid var(--gold);border-radius:12px;padding:14px 16px;display:flex;flex-direction:column;gap:8px;}
  .calc-ctrl label{font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:1.5px;color:var(--gold);}
  .calc-ctrl input{padding:10px 14px;border:2px solid var(--gold);border-radius:9px;font-size:20px;font-weight:800;background:var(--bg);color:var(--gold-light);outline:none;font-family:inherit;text-align:center;font-variant-numeric:tabular-nums;}
  .calc-ctrl input[readonly]{opacity:.7;}
  .calc-ctrl .unit{font-size:12px;color:var(--muted);text-align:center;font-weight:700;}
  .discount-panel{background:rgba(0,0,0,.5);border:1px dashed var(--gold);border-radius:12px;padding:14px 16px;margin-bottom:18px;}
  .discount-title{color:var(--gold);font-size:11px;font-weight:800;letter-spacing:1.5px;text-transform:uppercase;margin-bottom:12px;text-align:center;}
  .discount-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;}
  @media(max-width:600px){.discount-grid{grid-template-columns:1fr;}}
  .discount-item{display:flex;flex-direction:column;gap:5px;background:rgba(255,215,0,.04);border:1px solid var(--border);border-radius:8px;padding:10px;}
  .discount-item label{font-size:10px;font-weight:700;text-transform:uppercase;color:var(--gold);letter-spacing:.8px;}
  .discount-item input{padding:8px 10px;border:1px solid var(--gold);border-radius:7px;background:var(--bg);color:var(--gold-light);font-size:15px;font-weight:800;text-align:center;font-family:inherit;outline:none;}
  .calc-table-wrap{overflow:auto;max-height:50vh;border-radius:8px;border:1px solid var(--gold);background:#000;margin-bottom:16px;}
  .calc-table{width:100%;border-collapse:collapse;font-size:13px;}
  .calc-table th,.calc-table td{padding:10px 12px;text-align:left;border-bottom:1px solid rgba(212,175,55,.25);color:var(--gold);background:transparent;white-space:nowrap;}
  .calc-table th{background:var(--bg);color:var(--gold);font-weight:800;text-transform:uppercase;font-size:10px;letter-spacing:1px;border-bottom:2px solid var(--gold);position:sticky;top:0;z-index:1;}
  .calc-table td.num{text-align:right;font-variant-numeric:tabular-nums;}
  .calc-table input.qty{width:70px;padding:6px 10px;border:1px solid var(--gold);border-radius:6px;background:var(--bg);color:var(--gold-light);font-size:14px;font-weight:800;text-align:center;font-family:inherit;outline:none;}
  .calc-table .rm{cursor:pointer;color:#ff8a7a;font-weight:800;font-size:16px;text-align:center;user-select:none;}
  .calc-table .rm:hover{color:#ff5555;}
  .calc-table .disc{background:rgba(57,255,20,.08);color:var(--ok);font-weight:800;border-radius:4px;padding:2px 6px;font-size:11px;}
  .calc-empty{text-align:center;padding:40px 20px;color:var(--muted);font-size:14px;font-style:italic;}
  .calc-empty b{color:var(--gold);font-style:normal;}
  .calc-totals{display:grid;grid-template-columns:repeat(5,1fr);gap:12px;padding-top:16px;border-top:2px solid var(--gold);}
  @media(max-width:1100px){.calc-totals{grid-template-columns:repeat(3,1fr);}}
  @media(max-width:700px){.calc-totals{grid-template-columns:repeat(2,1fr);}}
  @media(max-width:450px){.calc-totals{grid-template-columns:1fr;}}
  .calc-total-item{background:rgba(0,0,0,.6);border:1px solid var(--gold);border-radius:12px;padding:14px 16px;text-align:center;}
  .calc-total-item .t-lbl{font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:1.2px;color:var(--gold);opacity:.85;margin-bottom:6px;}
  .calc-total-item .t-val{font-size:20px;font-weight:900;color:var(--gold-light);font-variant-numeric:tabular-nums;line-height:1.1;}
  .calc-total-item.margin{background:linear-gradient(135deg,rgba(57,255,20,.08),rgba(0,0,0,.6));border-color:#7dff7d;}
  .calc-total-item.margin .t-lbl{color:var(--ok);}
  .calc-total-item.margin .t-val{color:var(--ok);}
  .calc-total-item.discount{background:linear-gradient(135deg,rgba(255,87,34,.08),rgba(0,0,0,.6));border-color:#ff8a65;}
  .calc-total-item.discount .t-lbl{color:#ff8a65;}
  .calc-total-item.discount .t-val{color:#ff8a65;}
  .calc-total-item.final{background:linear-gradient(135deg,rgba(255,215,0,.15),rgba(10,10,10,.7));border:2px solid var(--gold);box-shadow:0 0 30px rgba(255,215,0,.3);}
  .calc-total-item.final .t-val{font-size:26px;color:var(--gold);text-shadow:0 0 20px rgba(255,215,0,.6);}
  .calc-actions{display:flex;gap:10px;margin-top:18px;flex-wrap:wrap;justify-content:center;}
  .calc-actions .btn{padding:12px 24px;font-size:14px;}

  /* ===== CTA ===== */
  .cta{text-align:center;background:var(--bg);border:1px solid var(--gold);border-radius:14px;padding:28px 20px;margin-top:16px;}
  .cta-text{font-size:16px;font-weight:600;color:var(--gold);margin-bottom:16px;}
  .cta-btn{display:inline-block;background:var(--gold);color:#0a0a0a;text-decoration:none;padding:16px 40px;font-size:20px;font-weight:800;letter-spacing:1px;border-radius:999px;transition:.25s;margin:0 6px;}
  .cta-btn:hover{background:var(--gold-light);transform:scale(1.03);}
  .cta-mail{display:inline-block;color:var(--gold);text-decoration:none;padding:16px 30px;font-size:16px;font-weight:700;border:1px solid var(--gold);border-radius:999px;transition:.25s;margin:0 6px;}
  .cta-mail:hover{background:var(--gold);color:#0a0a0a;}
  .manager{margin-top:16px;font-size:13px;color:var(--muted);}
  .seo{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0;}

  /* ===== СКРОЛЛБАР ===== */
  .wrap ::-webkit-scrollbar{width:14px;height:14px;}
  .wrap ::-webkit-scrollbar-track{background:#050505;border:1px solid #2a2210;border-radius:9px;}
  .wrap ::-webkit-scrollbar-thumb{background:linear-gradient(180deg,#FFE55C,#FFD700,#FF8C00);border-radius:9px;border:1px solid #FFD700;box-shadow:0 0 10px rgba(255,215,0,.9);}

  /* ===== ПЕЧАТЬ ===== */
  @media print{
    body{background:#fff;color:#000;padding:0;}
    .header{background:#000 !important;color:#FFD700 !important;-webkit-print-color-adjust:exact;print-color-adjust:exact;}
    .header h1{color:#FFD700 !important;text-shadow:none !important;animation:none !important;}
    .tag{background:#FFD700 !important;color:#000 !important;}
    .line{background:#FFD700 !important;}
    .stats,.table-block,.cta,.calc-block{background:#fff !important;border-color:#666 !important;box-shadow:none !important;}
    .toolbar,.filter,.select-hint,th.col-star::before,.banner,.ticker,.ad-strip{display:none !important;}
    .block-title{color:#000 !important;border-color:#666 !important;text-shadow:none !important;}
    .val{color:#000 !important;}
    th{background:#000 !important;color:#FFD700 !important;-webkit-print-color-adjust:exact;print-color-adjust:exact;}
    td{color:#000 !important;border-color:#ccc !important;}
    td.price,td.dims{color:#000 !important;}
    .cta-text{color:#000 !important;}
    .cta-btn{background:#000 !important;color:#fff !important;}
  }
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class="wrap" id="app"&gt;&lt;/div&gt;

&lt;script&gt;
/* ============================================================
   УНИВЕРСАЛЬНЫЙ ШАБЛОН ПРАЙС-ЛИСТА
   Для нового проекта меняем только объект PROJECT ниже.
   ============================================================ */

var PROJECT = {
  id: 'uchk',
  title: 'Утяжелители чугунные УЧК',
  subtitle: 'Для нефте- и газопроводов · Цена литья от 100 ₽/кг · НДС 22%',
  tag: 'ПРАЙС-ЛИСТ · 14 ПОЗИЦИЙ · PRO',
  vat: 22,

  /* Ценообразование (редактируется в калькуляторе) */
  costPerKg: 100,    // себестоимость, ₽/кг
  pricePerKg: 170,   // цена продажи с НДС, ₽/кг
  pricePerKgLabel: '₽/кг',

  /* Баннер */
  banner: {
    tag: 'РЕКЛАМНЫЕ ПЛОЩАДИ',
    title: 'ЗДЕСЬ МОЖЕТ БЫТЬ&lt;br&gt;ВАША РЕКЛАМА',
    phone: '8 902 873-36-90 · МАКС',
    note: 'Позвоните, а лучше пишите в МАКС'
  },

  /* Рекламная полоса */
  ads: [
    {tag:'Акция', text:'Литье чугуна · Скидки от 5 тонн', cta:'Перейти →', href:'#'},
    {tag:'Склад', text:'Утяжелители УЧК · В наличии', cta:'Перейти →', href:'#'}
  ],

  /* Колонки таблицы. key — поле в данных, label — заголовок,
     type: 'num' | 'text' | 'star' | 'badge' */
  columns: [
    {key:'num',    label:'№',              type:'num',  cls:'col-num'},
    {key:'name',   label:'Марка',          type:'text'},
    {key:'diam',   label:'Ø трубы, мм',    type:'num',  sortable:true},
    {key:'weight', label:'Масса, кг',      type:'num',  sortable:true},
    {key:'r1',     label:'R1',             type:'num',  sortable:true},
    {key:'r2',     label:'R2',             type:'num',  sortable:true},
    {key:'r3',     label:'R3',             type:'num',  sortable:true},
    {key:'a',      label:'A',              type:'num',  sortable:true},
    {key:'b',      label:'B',              type:'num',  sortable:true},
    {key:'c',      label:'C',              type:'num',  sortable:true},
    {key:'bolt',   label:'Болт, мм',       type:'text'},
    {key:'stock',  label:'Наличие, шт',    type:'badge',sortable:true},
    {key:'price',  label:'Цена с НДС, ₽',  type:'price'},
    {key:'term',   label:'Сроки',          type:'text'}
  ],

  /* Быстрые фильтры */
  quickFilters: [
    {label:'Со склада', field:'term', value:'Со склада'},
    {label:'Под заказ', field:'term', value:'Под заказ'},
    {label:'Ø до 530',  field:'diamMax', value:530},
    {label:'Ø от 720',  field:'diamMin', value:720}
  ],

  /* Данные: только вес и геометрия. Цена = weight × pricePerKg */
  data: [
    {num:1,  name:'УЧК-159', diam:159, weight:150, r1:200, r2:117, r3:109, a:330, b:185, c:430, bolt:'16×100', stock:15, term:'Со склада'},
    {num:2,  name:'УЧК-219', diam:219, weight:200, r1:249, r2:185, r3:150, a:375, b:200, c:500, bolt:'16×100', stock:12, term:'Со склада'},
    {num:3,  name:'УЧК-273', diam:273, weight:200, r1:249, r2:183, r3:175, a:375, b:234, c:497, bolt:'16×120', stock:10, term:'Со склада'},
    {num:4,  name:'УЧК-325', diam:325, weight:250, r1:275, r2:210, r3:200, a:464, b:250, c:589, bolt:'20×130', stock:8,  term:'Со склада'},
    {num:5,  name:'УЧК-377', diam:377, weight:300, r1:300, r2:235, r3:225, a:546, b:275, c:636, bolt:'20×140', stock:6,  term:'Со склада'},
    {num:6,  name:'УЧК-426', diam:426, weight:350, r1:327, r2:262, r3:252, a:490, b:302, c:694, bolt:'20×140', stock:5,  term:'Со склада'},
    {num:7,  name:'УЧК-530', diam:530, weight:450, r1:380, r2:315, r3:305, a:530, b:355, c:800, bolt:'20×180', stock:4,  term:'Со склада'},
    {num:8,  name:'УЧК-630', diam:630, weight:500, r1:430, r2:387, r3:355, a:500, b:405, c:950, bolt:'20×180', stock:3,  term:'Со склада'},
    {num:9,  name:'УЧК-720', diam:720, weight:1100, r1:470, r2:410, r3:400, a:910, b:455, c:1050, bolt:'24×190', stock:2,  term:'Под заказ'},
    {num:10, name:'УЧК-820', diam:820, weight:1100, r1:530, r2:460, r3:450, a:820, b:505, c:1100, bolt:'24×190', stock:2,  term:'Под заказ'},
    {num:11, name:'УЧК-1020', diam:1020, weight:1100, r1:735, r2:560, r3:552, a:710, b:607, c:1332, bolt:'24×190', stock:1,  term:'Под заказ'},
    {num:12, name:'УЧК-1067', diam:1067, weight:1100, r1:652, r2:590, r3:580, a:680, b:630, c:1400, bolt:'н/д', stock:1,  term:'Под заказ'},
    {num:13, name:'УЧК-1220', diam:1220, weight:2000, r1:765, r2:660, r3:655, a:770, b:740, c:1570, bolt:'30×270', stock:1,  term:'Под заказ'},
    {num:14, name:'УЧК-1420', diam:1420, weight:2200, r1:850, r2:760, r3:755, a:775, b:825, c:1785, bolt:'30×270', stock:1,  term:'Под заказ'}
  ],

  /* Контакты */
  phone: '8 (902) 873-36-90',
  phoneHref: '+79028733690',
  email: 'arsenal-detal@list.ru',
  manager: 'Менеджер: Ольга · ООО «Арсенал Деталь»'
};

/* ============================================================
   ДВИЖОК — дальше можно не менять
   ============================================================ */

/* Цена и себестоимость считаются от веса */
function calcPrice(r){ return Math.round(r.weight * PROJECT.pricePerKg); }
function calcCost(r){ return Math.round(r.weight * PROJECT.costPerKg); }
function calcMargin(r){ return calcPrice(r) - calcCost(r); }

var state = {
  search:'', sort:{key:null,dir:1},
  filters:{}, quickFilter:null
};
var fav = [];
var calcState = { qty:{} };

function fmt(n){ return Math.round(n).toLocaleString('ru-RU'); }
function num1(n){ return n.toLocaleString('ru-RU',{minimumFractionDigits:1,maximumFractionDigits:1}); }

/* ---------- РЕНДЕР СТРАНИЦЫ ---------- */
function renderApp(){
  var p = PROJECT;
  var html = '';

  /* Баннер */
  if (p.banner){
    html += '&lt;div class="banner"&gt;'+
      '&lt;div class="banner-tag"&gt;'+p.banner.tag+'&lt;/div&gt;'+
      '&lt;div class="banner-title"&gt;'+p.banner.title+'&lt;/div&gt;'+
      '&lt;div class="banner-phone"&gt;'+p.banner.phone+'&lt;/div&gt;'+
      '&lt;div class="banner-note"&gt;'+p.banner.note+'&lt;/div&gt;'+
    '&lt;/div&gt;';
  }

  /* Тикер */
  var tickerItems = p.data.map(function(r){
    return '&lt;span class="ticker-item"&gt;'+r.name+' — &lt;b&gt;'+fmt(calcPrice(r))+' ₽&lt;/b&gt;&lt;/span&gt;&lt;span class="ticker-dot"&gt;◆&lt;/span&gt;';
  }).join('');
  html += '&lt;div class="ticker"&gt;'+
    '&lt;div class="ticker-label"&gt;ЦЕНЫ&lt;/div&gt;'+
    '&lt;div class="ticker-vp"&gt;&lt;div class="ticker-track"&gt;'+tickerItems+tickerItems+'&lt;/div&gt;&lt;/div&gt;'+
  '&lt;/div&gt;';

  /* Реклама */
  if (p.ads &amp;&amp; p.ads.length){
    html += '&lt;div class="ad-strip"&gt;'+p.ads.map(function(a){
      return '&lt;a class="ad-item" href="'+(a.href||'#')+'" target="_blank" rel="noopener"&gt;'+
        '&lt;span class="ad-tag"&gt;'+a.tag+'&lt;/span&gt;'+
        '&lt;span class="ad-text"&gt;'+a.text+'&lt;/span&gt;'+
        '&lt;span class="ad-cta"&gt;'+a.cta+'&lt;/span&gt;'+
      '&lt;/a&gt;';
    }).join('')+'&lt;/div&gt;';
  }

  /* Шапка */
  html += '&lt;div class="header"&gt;'+
    '&lt;div class="tag"&gt;'+p.tag+'&lt;/div&gt;'+
    '&lt;h1&gt;'+p.title+'&lt;/h1&gt;'+
    '&lt;div class="line"&gt;&lt;/div&gt;'+
    '&lt;p&gt;'+p.subtitle+'&lt;/p&gt;'+
  '&lt;/div&gt;';

  /* Статистика */
  html += '&lt;div class="stats"&gt;'+
    '&lt;div class="stat"&gt;&lt;div class="lbl"&gt;Всего позиций&lt;/div&gt;&lt;div class="val" id="statTotal"&gt;—&lt;/div&gt;&lt;/div&gt;'+
    '&lt;div class="stat"&gt;&lt;div class="lbl"&gt;Всего на складе&lt;/div&gt;&lt;div class="val" id="statStock"&gt;—&lt;/div&gt;&lt;/div&gt;'+
    '&lt;div class="stat"&gt;&lt;div class="lbl"&gt;Диапазон Ø&lt;/div&gt;&lt;div class="val sm" id="statDiam"&gt;—&lt;/div&gt;&lt;/div&gt;'+
    '&lt;div class="stat"&gt;&lt;div class="lbl"&gt;Цена от&lt;/div&gt;&lt;div class="val sm" id="statPrice"&gt;—&lt;/div&gt;&lt;/div&gt;'+
  '&lt;/div&gt;';

  /* Тулбар */
  html += '&lt;div class="toolbar"&gt;'+
    '&lt;button class="btn primary" onclick="dlCSV()"&gt;⬇ Скачать CSV&lt;/button&gt;'+
    '&lt;button class="btn primary" onclick="dlExcel()"&gt;⬇ Скачать Excel&lt;/button&gt;'+
    '&lt;button class="btn" onclick="window.print()"&gt;? Печать&lt;/button&gt;'+
    '&lt;button class="btn" onclick="copyAll(event)"&gt;? Копировать прайс&lt;/button&gt;'+
    '&lt;button class="btn" onclick="resetAll()"&gt;✕ Сбросить&lt;/button&gt;'+
  '&lt;/div&gt;';

  /* Фильтр */
  html += '&lt;div class="filter"&gt;'+
    '&lt;div class="filter-row"&gt;'+
      '&lt;input class="search" type="text" id="search" placeholder="? Поиск: № · марка · Ø · размеры · наличие…"&gt;'+
      '&lt;div class="counter" id="counter"&gt;Найдено: 0&lt;/div&gt;'+
    '&lt;/div&gt;'+
    '&lt;div class="filter-grid"&gt;'+
      '&lt;div class="fld"&gt;&lt;label&gt;Ø трубы, мм&lt;/label&gt;&lt;input type="number" id="fDiam" placeholder="напр. 530"&gt;&lt;/div&gt;'+
      '&lt;div class="fld"&gt;&lt;label&gt;Масса, кг&lt;/label&gt;&lt;input type="number" id="fWeight" placeholder="напр. 450"&gt;&lt;/div&gt;'+
      '&lt;div class="fld"&gt;&lt;label&gt;Наличие&lt;/label&gt;&lt;select id="fStock"&gt;&lt;option value="all"&gt;Все&lt;/option&gt;&lt;option value="in"&gt;Есть на складе&lt;/option&gt;&lt;option value="out"&gt;Под заказ&lt;/option&gt;&lt;/select&gt;&lt;/div&gt;'+
      '&lt;div class="fld"&gt;&lt;label&gt;Сроки&lt;/label&gt;&lt;select id="fTerm"&gt;&lt;option value="all"&gt;Все&lt;/option&gt;&lt;option value="Со склада"&gt;Со склада&lt;/option&gt;&lt;option value="Под заказ"&gt;Под заказ&lt;/option&gt;&lt;/select&gt;&lt;/div&gt;'+
      '&lt;div class="fld"&gt;&lt;label&gt;Болт, мм&lt;/label&gt;&lt;input type="text" id="fBolt" placeholder="напр. 20×140"&gt;&lt;/div&gt;'+
    '&lt;/div&gt;'+
    '&lt;div class="filter-actions"&gt;'+
      '&lt;button class="btn" onclick="resetFilters()"&gt;✕ Очистить фильтры&lt;/button&gt;'+
      p.quickFilters.map(function(q,i){
        return '&lt;button class="btn" onclick="applyQuick('+i+')"&gt;'+q.label+'&lt;/button&gt;';
      }).join('')+
    '&lt;/div&gt;'+
  '&lt;/div&gt;';

  /* Таблица */
  html += '&lt;div class="table-block"&gt;'+
    '&lt;div class="select-hint"&gt;→ ВЫБЕРИ ПОЗИЦИИ →&lt;/div&gt;'+
    '&lt;div class="block-title"&gt;Прайс-лист · '+p.title+'&lt;/div&gt;'+
    '&lt;div class="table-wrap"&gt;&lt;table id="tbl"&gt;&lt;thead&gt;&lt;tr&gt;'+
      '&lt;th class="col-star" title="Отметь позиции для расчёта"&gt;★&lt;/th&gt;'+
      p.columns.map(function(c){
        var cls = (c.type==='num'?'num ':'') + (c.cls||'');
        if (c.sortable) cls += ' sortable';
        return '&lt;th class="'+cls+'" '+(c.sortable?'data-key="'+c.key+'"':'')+'&gt;'+c.label+'&lt;/th&gt;';
      }).join('')+
    '&lt;/tr&gt;&lt;/thead&gt;&lt;tbody id="tbody"&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;'+
    '&lt;div class="footnote"&gt;'+
      '&lt;div class="fn"&gt;Все цены указаны &lt;b&gt;с НДС '+p.vat+'%&lt;/b&gt;&lt;/div&gt;'+
      '&lt;div class="fn"&gt;Себестоимость литья: '+p.costPerKg+' ₽/кг&lt;/div&gt;'+
      '&lt;div class="fn"&gt;Цена продажи: '+p.pricePerKg+' ₽/кг с НДС&lt;/div&gt;'+
      '&lt;div class="fn"&gt;Клик по ★ — добавить в коммерческий расчёт&lt;/div&gt;'+
      '&lt;div class="fn"&gt;Отгрузка со склада / под заказ&lt;/div&gt;'+
    '&lt;/div&gt;'+
  '&lt;/div&gt;';

  /* Калькулятор */
  html += '&lt;div class="calc-block"&gt;'+
    '&lt;div class="calc-header"&gt;'+
      '&lt;div class="calc-ctrl"&gt;&lt;label&gt;◆ Себестоимость, ₽/кг&lt;/label&gt;&lt;input type="number" id="calcCost" value="'+p.costPerKg+'" min="0" step="1" oninput="onCostChange()"&gt;&lt;div class="unit"&gt;литьё, без НДС&lt;/div&gt;&lt;/div&gt;'+
      '&lt;div class="calc-ctrl"&gt;&lt;label&gt;◆ Цена продажи, ₽/кг&lt;/label&gt;&lt;input type="number" id="calcPrice" value="'+p.pricePerKg+'" min="0" step="1" oninput="onPriceChange()"&gt;&lt;div class="unit"&gt;с НДС '+p.vat+'%&lt;/div&gt;&lt;/div&gt;'+
      '&lt;div class="calc-ctrl"&gt;&lt;label&gt;◆ Маржа, ₽/кг&lt;/label&gt;&lt;input type="number" id="calcMarginKg" value="0" readonly&gt;&lt;div class="unit"&gt;авто&lt;/div&gt;&lt;/div&gt;'+
      '&lt;div class="calc-ctrl"&gt;&lt;label&gt;◆ Позиций в расчёте&lt;/label&gt;&lt;input type="number" id="calcCount" value="0" readonly&gt;&lt;div class="unit"&gt;отметьте ★ в таблице&lt;/div&gt;&lt;/div&gt;'+
    '&lt;/div&gt;'+
    '&lt;div class="discount-panel"&gt;'+
      '&lt;div class="discount-title"&gt;◆ Скидка от объёма (по количеству, компл) ◆&lt;/div&gt;'+
      '&lt;div class="discount-grid"&gt;'+
        '&lt;div class="discount-item"&gt;&lt;label&gt;От 10 шт — скидка %&lt;/label&gt;&lt;input type="number" id="disc10" value="5" min="0" max="50" step="1" oninput="calcRender()"&gt;&lt;/div&gt;'+
        '&lt;div class="discount-item"&gt;&lt;label&gt;От 50 шт — скидка %&lt;/label&gt;&lt;input type="number" id="disc50" value="10" min="0" max="50" step="1" oninput="calcRender()"&gt;&lt;/div&gt;'+
        '&lt;div class="discount-item"&gt;&lt;label&gt;От 100 шт — скидка %&lt;/label&gt;&lt;input type="number" id="disc100" value="15" min="0" max="50" step="1" oninput="calcRender()"&gt;&lt;/div&gt;'+
      '&lt;/div&gt;'+
    '&lt;/div&gt;'+
    '&lt;div class="calc-table-wrap"&gt;&lt;table class="calc-table"&gt;&lt;thead&gt;&lt;tr&gt;'+
      '&lt;th&gt;№&lt;/th&gt;&lt;th&gt;Марка&lt;/th&gt;&lt;th&gt;Ø&lt;/th&gt;&lt;th class="num"&gt;Вес, кг&lt;/th&gt;&lt;th class="num"&gt;Себест., ₽&lt;/th&gt;'+
      '&lt;th class="num"&gt;Кол-во&lt;/th&gt;&lt;th class="num"&gt;Скидка&lt;/th&gt;&lt;th class="num"&gt;Цена, ₽&lt;/th&gt;'+
      '&lt;th class="num"&gt;Итог, ₽&lt;/th&gt;&lt;th class="num"&gt;Маржа, ₽&lt;/th&gt;&lt;th&gt;&lt;/th&gt;'+
    '&lt;/tr&gt;&lt;/thead&gt;&lt;tbody id="calcBody"&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;'+
    '&lt;div id="calcEmpty" class="calc-empty"&gt;Отметьте позиции знаком &lt;b&gt;★&lt;/b&gt; в таблице выше — они появятся здесь.&lt;/div&gt;'+
    '&lt;div class="calc-totals" id="calcTotals" style="display:none"&gt;'+
      '&lt;div class="calc-total-item"&gt;&lt;div class="t-lbl"&gt;Себестоимость&lt;/div&gt;&lt;div class="t-val" id="calcTotalCost"&gt;0 ₽&lt;/div&gt;&lt;/div&gt;'+
      '&lt;div class="calc-total-item discount"&gt;&lt;div class="t-lbl"&gt;Скидка&lt;/div&gt;&lt;div class="t-val" id="calcTotalDiscount"&gt;0 ₽&lt;/div&gt;&lt;/div&gt;'+
      '&lt;div class="calc-total-item margin"&gt;&lt;div class="t-lbl"&gt;Маржа&lt;/div&gt;&lt;div class="t-val" id="calcTotalMargin"&gt;0 ₽&lt;/div&gt;&lt;/div&gt;'+
      '&lt;div class="calc-total-item"&gt;&lt;div class="t-lbl"&gt;Без НДС&lt;/div&gt;&lt;div class="t-val" id="calcTotalNoVat"&gt;0 ₽&lt;/div&gt;&lt;/div&gt;'+
      '&lt;div class="calc-total-item final"&gt;&lt;div class="t-lbl"&gt;ИТОГО с НДС '+p.vat+'%&lt;/div&gt;&lt;div class="t-val" id="calcTotalFinal"&gt;0 ₽&lt;/div&gt;&lt;/div&gt;'+
    '&lt;/div&gt;'+
    '&lt;div class="calc-actions"&gt;'+
      '&lt;button class="btn primary" onclick="calcSendQuote()"&gt;? Сформировать счёт&lt;/button&gt;'+
      '&lt;button class="btn" onclick="calcCopy()"&gt;? Копировать расчёт&lt;/button&gt;'+
      '&lt;button class="btn" onclick="calcExportExcel()"&gt;⬇ Excel расчёт&lt;/button&gt;'+
      '&lt;button class="btn" onclick="calcPDF()"&gt;? Скачать PDF&lt;/button&gt;'+
      '&lt;button class="btn" onclick="calcClear()"&gt;✕ Очистить расчёт&lt;/button&gt;'+
    '&lt;/div&gt;'+
  '&lt;/div&gt;';

  /* CTA */
  html += '&lt;div class="cta"&gt;'+
    '&lt;p class="cta-text"&gt;Уточнить наличие и оформить заказ&lt;/p&gt;'+
    '&lt;a href="tel:'+p.phoneHref+'" class="cta-btn"&gt;'+p.phone+'&lt;/a&gt;'+
    '&lt;a href="mailto:'+p.email+'?subject=Запрос%20прайса%20'+encodeURIComponent(p.title)+'" class="cta-mail"&gt;✉ '+p.email+'&lt;/a&gt;'+
    '&lt;p class="manager"&gt;'+p.manager+'&lt;/p&gt;'+
  '&lt;/div&gt;';

  /* SEO */
  html += '&lt;div class="seo"&gt;&lt;p&gt;'+p.title+'. '+p.subtitle+'. Купить оптом и в розницу. Отгрузка со склада. ООО «Арсенал Деталь».&lt;/p&gt;&lt;/div&gt;';

  document.getElementById('app').innerHTML = html;
}

/* ---------- ФИЛЬТРАЦИЯ ---------- */
function getFiltered(){
  var rows = PROJECT.data.slice();
  if (state.search){
    var q = state.search.trim().toLowerCase();
    var qn = q.replace(/\s+/g,'').replace(/₽/g,'').replace(/кг/g,'').replace(/,/g,'.');
    rows = rows.filter(function(r){
      if (String(r.num).indexOf(q)!==-1) return true;
      var fields = ['name','bolt','term'];
      for (var i=0;i&lt;fields.length;i++){
        if (r[fields[i]] &amp;&amp; String(r[fields[i]]).toLowerCase().indexOf(q)!==-1) return true;
      }
      if (String(r.diam).indexOf(qn)!==-1) return true;
      if (String(r.weight).indexOf(qn)!==-1) return true;
      if (Math.abs(r.diam - parseFloat(qn)) &lt; 0.01) return true;
      if (Math.abs(r.weight - parseFloat(qn)) &lt; 0.01) return true;
      return false;
    });
  }
  if (state.filters.diam){ var d=parseFloat(state.filters.diam); if(!isNaN(d)) rows=rows.filter(function(r){return r.diam===d;}); }
  if (state.filters.weight){ var w=parseFloat(state.filters.weight); if(!isNaN(w)) rows=rows.filter(function(r){return r.weight===w;}); }
  if (state.filters.stock==='in')  rows=rows.filter(function(r){return r.stock&gt;0;});
  if (state.filters.stock==='out') rows=rows.filter(function(r){return r.stock===0;});
  if (state.filters.term &amp;&amp; state.filters.term!=='all') rows=rows.filter(function(r){return r.term===state.filters.term;});
  if (state.filters.bolt){ var b=state.filters.bolt.toLowerCase(); rows=rows.filter(function(r){return String(r.bolt).toLowerCase().indexOf(b)!==-1;}); }
  if (state.quickFilter){
    var qf = state.quickFilter;
    if (qf.field==='term') rows=rows.filter(function(r){return r.term===qf.value;});
    else if (qf.field==='diamMax') rows=rows.filter(function(r){return r.diam&lt;=qf.value;});
    else if (qf.field==='diamMin') rows=rows.filter(function(r){return r.diam&gt;=qf.value;});
  }
  if (state.sort.key){
    var k=state.sort.key, d=state.sort.dir;
    rows.sort(function(a,b){
      var va=a[k], vb=b[k];
      if (typeof va==='number' &amp;&amp; typeof vb==='number') return (va-vb)*d;
      return String(va).localeCompare(String(vb),'ru')*d;
    });
  }
  return rows;
}

/* ---------- РЕНДЕР ТАБЛИЦЫ ---------- */
function render(){
  var rows = getFiltered();
  var tbody = document.getElementById('tbody');
  if (!tbody) return;
  tbody.innerHTML = '';
  if (!rows.length){
    tbody.innerHTML = '&lt;tr&gt;&lt;td colspan="'+(PROJECT.columns.length+1)+'" style="text-align:center;padding:40px;opacity:.6"&gt;Ничего не найдено.&lt;/td&gt;&lt;/tr&gt;';
    document.getElementById('counter').textContent = 'Найдено: 0';
    return;
  }
  rows.forEach(function(r){
    var isFav = fav.indexOf(r.num)!==-1;
    var price = calcPrice(r);
    var tr = document.createElement('tr');
    if (isFav) tr.className = 'picked';
    var cells = '&lt;td class="col-star"&gt;&lt;span class="star'+(isFav?' on':'')+'" data-num="'+r.num+'"&gt;'+(isFav?'★':'☆')+'&lt;/span&gt;&lt;/td&gt;';
    PROJECT.columns.forEach(function(c){
      var v = r[c.key];
      if (c.type==='num')       cells += '&lt;td class="num '+(c.cls||'')+'"&gt;'+v+'&lt;/td&gt;';
      else if (c.type==='price') cells += '&lt;td class="num price"&gt;'+fmt(price)+' ₽&lt;/td&gt;';
      else if (c.type==='badge'){
        var cls = v&gt;=10 ? 'badge many' : v===0 ? 'badge zero' : 'badge';
        cells += '&lt;td class="num"&gt;&lt;span class="'+cls+'"&gt;'+v+'&lt;/span&gt;&lt;/td&gt;';
      }
      else cells += '&lt;td class="'+(c.cls||'')+'"&gt;'+(c.key==='num'?'&lt;b&gt;'+v+'&lt;/b&gt;':v)+'&lt;/td&gt;';
    });
    tr.innerHTML = cells;
    tbody.appendChild(tr);
  });
  document.getElementById('counter').textContent = 'Найдено: '+rows.length;
  updateSort();
  bindStars();
}

function updateSort(){
  document.querySelectorAll('#tbl th.sortable').forEach(function(th){
    th.classList.remove('asc','desc');
    if (th.dataset.key===state.sort.key) th.classList.add(state.sort.dir===1?'asc':'desc');
  });
}

function bindStars(){
  document.querySelectorAll('.star').forEach(function(el){
    el.addEventListener('click',function(){
      var n = parseInt(this.dataset.num,10);
      var idx = fav.indexOf(n);
      if (idx===-1) fav.push(n); else fav.splice(idx,1);
      render(); calcRender();
    });
  });
}

/* ---------- СТАТИСТИКА ---------- */
function updateStats(){
  var d = PROJECT.data;
  document.getElementById('statTotal').textContent = d.length;
  document.getElementById('statStock').textContent = d.reduce(function(s,r){return s+r.stock;},0)+' компл';
  var diam = d.map(function(r){return r.diam;});
  document.getElementById('statDiam').textContent = Math.min.apply(null,diam)+'–'+Math.max.apply(null,diam)+' мм';
  var prices = d.map(calcPrice);
  document.getElementById('statPrice').textContent = fmt(Math.min.apply(null,prices))+' ₽';
}

/* ---------- КАЛЬКУЛЯТОР ---------- */
function onCostChange(){
  PROJECT.costPerKg = parseFloat(document.getElementById('calcCost').value)||0;
  calcRender();
}
function onPriceChange(){
  PROJECT.pricePerKg = parseFloat(document.getElementById('calcPrice').value)||0;
  render(); updateStats(); calcRender();
}

function getDiscount(qty){
  var d10 = parseFloat(document.getElementById('disc10').value)||0;
  var d50 = parseFloat(document.getElementById('disc50').value)||0;
  var d100 = parseFloat(document.getElementById('disc100').value)||0;
  if (qty&gt;=100) return d100;
  if (qty&gt;=50)  return d50;
  if (qty&gt;=10)  return d10;
  return 0;
}

function calcRender(){
  var tbody = document.getElementById('calcBody');
  var empty = document.getElementById('calcEmpty');
  var totals = document.getElementById('calcTotals');
  if (!tbody) return;
  tbody.innerHTML = '';
  document.getElementById('calcCount').value = fav.length;

  var markupKg = PROJECT.pricePerKg - PROJECT.costPerKg;
  document.getElementById('calcMarginKg').value = Math.round(markupKg*100)/100;

  if (!fav.length){
    empty.style.display='block'; totals.style.display='none';
    return;
  }
  empty.style.display='none'; totals.style.display='grid';

  var totalCost=0,totalMargin=0,totalSum=0,totalNoVat=0,totalDiscount=0;
  fav.forEach(function(n){
    var r = PROJECT.data.find(function(x){return x.num===n;});
    if (!r) return;
    var cost = calcCost(r);
    var price = calcPrice(r);
    var qty = calcState.qty[r.num]||1;
    var sumBefore = price*qty;
    var discPct = getDiscount(qty);
    var sumAfter = sumBefore*(1-discPct/100);
    var discAmt = sumBefore-sumAfter;
    var margin = (price-cost)*qty - discAmt;
    totalCost += cost*qty; totalMargin += margin;
    totalSum += sumAfter; totalNoVat += sumAfter/(1+PROJECT.vat/100);
    totalDiscount += discAmt;
    var discBadge = discPct ? '&lt;span class="disc"&gt;−'+discPct+'%&lt;/span&gt;' : '—';
    var tr = document.createElement('tr');
    tr.innerHTML =
      '&lt;td&gt;'+r.num+'&lt;/td&gt;'+
      '&lt;td&gt;&lt;b&gt;'+r.name+'&lt;/b&gt;&lt;/td&gt;'+
      '&lt;td class="num"&gt;'+r.diam+'&lt;/td&gt;'+
      '&lt;td class="num"&gt;'+r.weight+'&lt;/td&gt;'+
      '&lt;td class="num"&gt;'+fmt(cost)+'&lt;/td&gt;'+
      '&lt;td class="num"&gt;&lt;input type="number" class="qty" data-num="'+r.num+'" value="'+qty+'" min="1" max="9999"&gt;&lt;/td&gt;'+
      '&lt;td class="num"&gt;'+discBadge+'&lt;/td&gt;'+
      '&lt;td class="num" style="color:#FFE55C;font-weight:800"&gt;'+fmt(price)+'&lt;/td&gt;'+
      '&lt;td class="num" style="color:#b9ff9f;font-weight:800"&gt;'+fmt(sumAfter)+'&lt;/td&gt;'+
      '&lt;td class="num" style="color:#b9ff9f;font-weight:700"&gt;'+fmt(margin)+'&lt;/td&gt;'+
      '&lt;td class="rm" data-num="'+r.num+'"&gt;✕&lt;/td&gt;';
    tbody.appendChild(tr);
  });
  document.getElementById('calcTotalCost').textContent = fmt(totalCost)+' ₽';
  document.getElementById('calcTotalDiscount').textContent = '−'+fmt(totalDiscount)+' ₽';
  document.getElementById('calcTotalMargin').textContent = fmt(totalMargin)+' ₽';
  document.getElementById('calcTotalNoVat').textContent = fmt(totalNoVat)+' ₽';
  document.getElementById('calcTotalFinal').textContent = fmt(totalSum)+' ₽';

  tbody.querySelectorAll('.qty').forEach(function(inp){
    inp.addEventListener('input',function(){
      var n = parseInt(this.dataset.num,10);
      calcState.qty[n] = Math.max(1, parseInt(this.value,10)||1);
      calcRender();
    });
  });
  tbody.querySelectorAll('.rm').forEach(function(el){
    el.addEventListener('click',function(){
      var n = parseInt(this.dataset.num,10);
      var idx = fav.indexOf(n);
      if (idx!==-1) fav.splice(idx,1);
      render(); calcRender();
    });
  });
}

function calcClear(){ fav=[]; calcState.qty={}; render(); calcRender(); }

/* ---------- ЭКСПОРТ РАСЧЁТА ---------- */
function calcCopy(){
  if (!fav.length){ alert('Нет позиций в расчёте'); return; }
  var lines = ['КОММЕРЧЕСКИЙ РАСЧЁТ · '+PROJECT.title, 'Себестоимость: '+PROJECT.costPerKg+' ₽/кг · Цена: '+PROJECT.pricePerKg+' ₽/кг с НДС '+PROJECT.vat+'%', ''];
  var totalSum=0,totalCost=0,totalMargin=0,totalDiscount=0;
  fav.forEach(function(n){
    var r = PROJECT.data.find(function(x){return x.num===n;});
    var cost = calcCost(r), price = calcPrice(r), qty = calcState.qty[r.num]||1;
    var before = price*qty, discPct = getDiscount(qty), after = before*(1-discPct/100);
    totalSum+=after; totalCost+=cost*qty; totalMargin+=(price-cost)*qty-(before-after); totalDiscount+=(before-after);
    lines.push('№'+r.num+'  '+r.name+'  Ø'+r.diam+'  '+r.weight+'кг  x'+qty+(discPct?'  скидка '+discPct+'%':'')+'  =  '+fmt(price)+'₽/шт  →  '+fmt(after)+'₽');
  });
  lines.push('');
  lines.push('Себестоимость: '+fmt(totalCost)+' ₽');
  lines.push('Скидка: −'+fmt(totalDiscount)+' ₽');
  lines.push('Маржа: '+fmt(totalMargin)+' ₽');
  lines.push('ИТОГО с НДС '+PROJECT.vat+'%: '+fmt(totalSum)+' ₽');
  lines.push('');
  lines.push('ООО «Арсенал Деталь» · '+PROJECT.phone);
  var text = lines.join('\n');
  if (navigator.clipboard &amp;&amp; navigator.clipboard.writeText){
    navigator.clipboard.writeText(text).then(function(){alert('Расчёт скопирован!');});
  } else alert(text);
}

function calcExportExcel(){
  if (!fav.length){ alert('Нет позиций в расчёте'); return; }
  var rows = [['№','Марка','Ø','Вес, кг','Себест., ₽','Кол-во','Скидка, %','Цена, ₽','Сумма, ₽','Маржа, ₽']];
  var totalSum=0,totalCost=0,totalMargin=0,totalDiscount=0;
  fav.forEach(function(n){
    var r = PROJECT.data.find(function(x){return x.num===n;});
    var cost=calcCost(r), price=calcPrice(r), qty=calcState.qty[r.num]||1;
    var before=price*qty, discPct=getDiscount(qty), after=before*(1-discPct/100);
    var margin=(price-cost)*qty-(before-after);
    totalSum+=after; totalCost+=cost*qty; totalMargin+=margin; totalDiscount+=(before-after);
    rows.push([r.num,r.name,r.diam,r.weight,cost,qty,discPct,price,Math.round(after),Math.round(margin)]);
  });
  rows.push([]); rows.push(['','','','','','','Себестоимость:',totalCost]);
  rows.push(['','','','','','','Скидка:',totalDiscount]);
  rows.push(['','','','','','','Маржа:',totalMargin]);
  rows.push(['','','','','','','ИТОГО с НДС '+PROJECT.vat+'%:',totalSum]);
  var esc = function(v){return String(v==null?'':v).replace(/&amp;/g,'&amp;amp;').replace(/&lt;/g,'&amp;lt;').replace(/&gt;/g,'&amp;gt;');};
  var table = '&lt;table border="1" cellspacing="0" cellpadding="4"&gt;&lt;tbody&gt;'+rows.map(function(r){return '&lt;tr&gt;'+r.map(function(c){return '&lt;td&gt;'+esc(c)+'&lt;/td&gt;';}).join('')+'&lt;/tr&gt;';}).join('')+'&lt;/tbody&gt;&lt;/table&gt;';
  var html = '&lt;html xmlns:x="urn:schemas-microsoft-com:office:excel"&gt;&lt;head&gt;&lt;meta charset="UTF-8"&gt;&lt;style&gt;td{font-family:Arial;font-size:12px;}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;h2&gt;Коммерческий расчёт · '+PROJECT.title+'&lt;/h2&gt;'+table+'&lt;p&gt;&lt;i&gt;ООО «Арсенал Деталь» · '+PROJECT.phone+'&lt;/i&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;';
  dlBlob(new Blob(['\uFEFF'+html],{type:'application/vnd.ms-excel;charset=utf-8;'}),'raschet_'+today()+'.xls');
}

function calcPDF(){
  if (!fav.length){ alert('Нет позиций в расчёте'); return; }
  var w = window.open('','_blank');
  var html = '&lt;!DOCTYPE html&gt;&lt;html&gt;&lt;head&gt;&lt;meta charset="UTF-8"&gt;&lt;title&gt;Коммерческий расчёт&lt;/title&gt;&lt;style&gt;body{font-family:Arial,sans-serif;padding:20px;color:#222}h1{color:#B8860B;border-bottom:2px solid #FFD700;padding-bottom:10px}table{width:100%;border-collapse:collapse;font-size:12px;margin-top:16px}th{background:#FFD700;color:#000;padding:8px;border:1px solid #ccc;text-align:left}td{padding:6px 8px;border:1px solid #ccc}td.num{text-align:right}.totals{margin-top:20px;padding:16px;border:2px solid #FFD700;border-radius:8px;background:#FFFCF0}.totals div{margin:6px 0;font-size:14px}.totals .final{font-size:20px;font-weight:bold;color:#B8860B}.header-print{text-align:center;margin-bottom:20px}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;'+
    '&lt;div class="header-print"&gt;&lt;h1&gt;Коммерческий расчёт&lt;/h1&gt;&lt;p&gt;ООО «Арсенал Деталь» · '+PROJECT.phone+' · '+PROJECT.email+'&lt;/p&gt;&lt;p&gt;Дата: '+new Date().toLocaleDateString('ru-RU')+' · Себест.: '+PROJECT.costPerKg+' ₽/кг · Цена: '+PROJECT.pricePerKg+' ₽/кг с НДС '+PROJECT.vat+'%&lt;/p&gt;&lt;/div&gt;'+
    '&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;№&lt;/th&gt;&lt;th&gt;Марка&lt;/th&gt;&lt;th&gt;Ø&lt;/th&gt;&lt;th&gt;Вес, кг&lt;/th&gt;&lt;th&gt;Кол-во&lt;/th&gt;&lt;th&gt;Цена, ₽&lt;/th&gt;&lt;th&gt;Сумма, ₽&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;';
  var totalSum=0,totalCost=0,totalMargin=0,totalDiscount=0;
  fav.forEach(function(n){
    var r = PROJECT.data.find(function(x){return x.num===n;});
    var cost=calcCost(r), price=calcPrice(r), qty=calcState.qty[r.num]||1;
    var before=price*qty, discPct=getDiscount(qty), after=before*(1-discPct/100);
    totalSum+=after; totalCost+=cost*qty; totalMargin+=(price-cost)*qty-(before-after); totalDiscount+=(before-after);
    html += '&lt;tr&gt;&lt;td&gt;'+r.num+'&lt;/td&gt;&lt;td&gt;'+r.name+'&lt;/td&gt;&lt;td class="num"&gt;'+r.diam+'&lt;/td&gt;&lt;td class="num"&gt;'+r.weight+'&lt;/td&gt;&lt;td class="num"&gt;'+qty+'&lt;/td&gt;&lt;td class="num"&gt;'+fmt(price)+' ₽&lt;/td&gt;&lt;td class="num"&gt;'+fmt(after)+' ₽&lt;/td&gt;&lt;/tr&gt;';
  });
  html += '&lt;/tbody&gt;&lt;/table&gt;&lt;div class="totals"&gt;&lt;div&gt;Себестоимость: &lt;b&gt;'+fmt(totalCost)+' ₽&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Скидка: &lt;b&gt;−'+fmt(totalDiscount)+' ₽&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Маржа: &lt;b&gt;'+fmt(totalMargin)+' ₽&lt;/b&gt;&lt;/div&gt;&lt;div class="final"&gt;ИТОГО с НДС '+PROJECT.vat+'%: '+fmt(totalSum)+' ₽&lt;/div&gt;&lt;/div&gt;&lt;p style="margin-top:30px;font-size:11px;color:#888;text-align:center"&gt;Документ сформирован автоматически.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;';
  w.document.write(html); w.document.close();
  setTimeout(function(){w.print();},500);
}

function calcSendQuote(){
  if (!fav.length){ alert('Нет позиций в расчёте'); return; }
  var lines = ['Здравствуйте!','','Прошу выставить счёт:','','Себестоимость: '+PROJECT.costPerKg+' ₽/кг · Цена: '+PROJECT.pricePerKg+' ₽/кг с НДС '+PROJECT.vat+'%',''];
  var totalSum=0;
  fav.forEach(function(n){
    var r = PROJECT.data.find(function(x){return x.num===n;});
    var price=calcPrice(r), qty=calcState.qty[r.num]||1;
    var after=price*qty*(1-getDiscount(qty)/100); totalSum+=after;
    lines.push('• '+r.name+' (Ø'+r.diam+', '+r.weight+' кг) — '+qty+' компл × '+fmt(price)+' ₽ = '+fmt(after)+' ₽');
  });
  lines.push(''); lines.push('ИТОГО с НДС '+PROJECT.vat+'%: '+fmt(totalSum)+' ₽'); lines.push(''); lines.push('С уважением,');
  window.location.href = 'mailto:'+PROJECT.email+'?subject='+encodeURIComponent('Запрос счёта — '+PROJECT.title)+'&amp;body='+encodeURIComponent(lines.join('\n'));
}

/* ---------- ЭКСПОРТ ПРАЙСА ---------- */
function dlCSV(){
  var rows = getFiltered();
  var header = PROJECT.columns.map(function(c){return c.label;});
  var body = rows.map(function(r){
    return PROJECT.columns.map(function(c){
      if (c.key==='price') return calcPrice(r);
      return r[c.key];
    });
  });
  var esc = function(v){return '"'+String(v).replace(/"/g,'""')+'"';};
  var csv = [header].concat(body).map(function(r){return r.map(esc).join(';');}).join('\r\n');
  dlBlob(new Blob(['\uFEFF'+csv],{type:'text/csv;charset=utf-8;'}), PROJECT.id+'_prays_'+today()+'.csv');
}

function dlExcel(){
  var rows = getFiltered();
  var header = PROJECT.columns.map(function(c){return c.label;});
  var body = rows.map(function(r){
    return PROJECT.columns.map(function(c){
      if (c.key==='price') return calcPrice(r);
      return r[c.key];
    });
  });
  var esc = function(v){return String(v==null?'':v).replace(/&amp;/g,'&amp;amp;').replace(/&lt;/g,'&amp;lt;').replace(/&gt;/g,'&amp;gt;');};
  var table = '&lt;table border="1" cellspacing="0" cellpadding="4"&gt;&lt;thead style="background:#000;color:#FFD700;"&gt;&lt;tr&gt;'+header.map(function(h){return '&lt;th&gt;'+esc(h)+'&lt;/th&gt;';}).join('')+'&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;'+body.map(function(r){return '&lt;tr&gt;'+r.map(function(c){return '&lt;td&gt;'+esc(c)+'&lt;/td&gt;';}).join('')+'&lt;/tr&gt;';}).join('')+'&lt;/tbody&gt;&lt;/table&gt;';
  var html = '&lt;html xmlns:x="urn:schemas-microsoft-com:office:excel"&gt;&lt;head&gt;&lt;meta charset="UTF-8"&gt;&lt;style&gt;td,th{font-family:Arial;font-size:12px;}&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;h2&gt;'+PROJECT.title+' · '+today()+'&lt;/h2&gt;&lt;p&gt;Все цены с НДС '+PROJECT.vat+'%&lt;/p&gt;'+table+'&lt;p&gt;&lt;i&gt;ООО «Арсенал Деталь» · '+PROJECT.phone+'&lt;/i&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;';
  dlBlob(new Blob(['\uFEFF'+html],{type:'application/vnd.ms-excel;charset=utf-8;'}), PROJECT.id+'_prays_'+today()+'.xls');
}

function copyAll(evt){
  var rows = getFiltered();
  var lines = ['ПРАЙС — '+PROJECT.title+' (цены с НДС '+PROJECT.vat+'%)',''];
  rows.forEach(function(r){
    lines.push('№'+r.num+'  '+r.name+'  Ø'+r.diam+'  '+r.weight+' кг  —  '+fmt(calcPrice(r))+' ₽');
  });
  lines.push(''); lines.push('ООО «Арсенал Деталь» · '+PROJECT.phone);
  var text = lines.join('\n');
  if (navigator.clipboard &amp;&amp; navigator.clipboard.writeText){
    navigator.clipboard.writeText(text).then(function(){
      var btn = evt &amp;&amp; evt.target ? evt.target : null;
      if (btn){ var old = btn.textContent; btn.textContent='✓ Скопировано'; setTimeout(function(){btn.textContent=old;},1500); }
    });
  } else alert(text);
}

function dlBlob(blob,filename){
  var url = URL.createObjectURL(blob);
  var a = document.createElement('a');
  a.href=url; a.download=filename;
  document.body.appendChild(a); a.click(); a.remove();
  setTimeout(function(){URL.revokeObjectURL(url);},500);
}
function today(){
  var d=new Date(), p=function(n){return String(n).padStart(2,'0');};
  return d.getFullYear()+'-'+p(d.getMonth()+1)+'-'+p(d.getDate());
}

/* ---------- СБРОС И БЫСТРЫЕ ФИЛЬТРЫ ---------- */
function resetFilters(){
  state.search=''; state.filters={}; state.quickFilter=null;
  ['search','fDiam','fWeight','fStock','fTerm','fBolt'].forEach(function(id){
    var el = document.getElementById(id);
    if (el){ if (el.tagName==='SELECT') el.value='all'; else el.value=''; }
  });
  render();
}
function applyQuick(i){
  resetFilters();
  state.quickFilter = PROJECT.quickFilters[i];
  render();
}
function resetAll(){
  state = {search:'',sort:{key:null,dir:1},filters:{},quickFilter:null};
  fav=[]; calcState={qty:{}};
  PROJECT.costPerKg = 100;
  PROJECT.pricePerKg = 170;
  document.getElementById('calcCost').value = 100;
  document.getElementById('calcPrice').value = 170;
  document.getElementById('disc10').value = 5;
  document.getElementById('disc50').value = 10;
  document.getElementById('disc100').value = 15;
  render(); updateStats(); calcRender();
}

/* ---------- СОБЫТИЯ ---------- */
document.addEventListener('DOMContentLoaded', function(){
  renderApp();
  updateStats();
  render();
  calcRender();

  document.getElementById('search').addEventListener('input',function(e){state.search=e.target.value;render();});
  document.getElementById('fDiam').addEventListener('input',function(e){state.filters.diam=e.target.value;render();});
  document.getElementById('fWeight').addEventListener('input',function(e){state.filters.weight=e.target.value;render();});
  document.getElementById('fStock').addEventListener('change',function(e){state.filters.stock=e.target.value;render();});
  document.getElementById('fTerm').addEventListener('change',function(e){state.filters.term=e.target.value;render();});
  document.getElementById('fBolt').addEventListener('input',function(e){state.filters.bolt=e.target.value;render();});

  document.querySelectorAll('#tbl th.sortable').forEach(function(th){
    th.addEventListener('click',function(){
      var k = th.dataset.key;
      if (state.sort.key===k) state.sort.dir *= -1;
      else state.sort = {key:k, dir:1};
      render();
    });
  });
});
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</subtitle>
  <updated>2026-10-12T05:31:23Z</updated>
  <logo>https://pandoraburo.ru/ssl/u/pic/07/26436cc3c611f19d9efcd8c4a10874/-/0c723f71762611f1b3964aaba1665535.jpg</logo>
  <author>
    <name>1592962</name>
    <uri>https://www.pandoraburo.ru/</uri>
  </author>
</feed>
