<!-- UTM Builder для Tilda (вставьте целиком в блок T123: HTML) -->
<style>
  .utm-wrap{font-family:Inter,system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;max-width:980px;margin:0 auto;padding:24px}
  .utm-title{font-size:28px;font-weight:600;margin:0 0 4px}
  .utm-sub{color:#475569;margin:0 0 20px}
  .utm-grid{display:grid;grid-template-columns:1fr;gap:16px}
  @media(min-width:700px){.utm-grid{grid-template-columns:1fr 1fr}}
  .utm-card{background:#fff;border:1px solid #e5e7eb;border-radius:16px;box-shadow:0 1px 2px rgba(0,0,0,.04);padding:18px}
  .utm-field{display:grid;gap:6px}
  .utm-label{font-size:13px;color:#334155}
  .utm-input{height:40px;border:1px solid #cbd5e1;border-radius:10px;padding:0 12px;font-size:14px;outline:none}
  .utm-input:focus{border-color:#2563eb;box-shadow:0 0 0 3px rgba(37,99,235,.12)}
  .utm-bad{border-color:#f87171 !important}
  .utm-row{display:flex;flex-wrap:wrap;gap:10px;align-items:center}
  .utm-spacer{flex:1 1 auto}
  .utm-btn{height:40px;padding:0 14px;border-radius:10px;border:1px solid #cbd5e1;background:#0f172a;color:#fff;font-size:14px;cursor:pointer}
  .utm-btn[disabled]{opacity:.6;cursor:not-allowed}
  .utm-btn.secondary{background:#fff;color:#0f172a}
  .utm-chip{display:flex;align-items:center;gap:8px}
  .utm-switch{width:36px;height:22px;background:#e2e8f0;border-radius:999px;position:relative;cursor:pointer;border:1px solid #cbd5e1}
  .utm-switch input{display:none}
  .utm-switch i{position:absolute;top:2px;left:2px;width:18px;height:18px;background:#fff;border-radius:50%;transition:.2s}
  .utm-switch input:checked + i{left:16px;background:#2563eb}
  .utm-code{background:#0b1220;color:#e5e7eb;border-radius:12px;padding:12px;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:12px;overflow:auto}
  .utm-qr{display:flex;align-items:center;justify-content:center;border:1px solid #e5e7eb;border-radius:16px;background:#fff;padding:12px}
</style>

<div class="utm-wrap" id="utm-builder">
  <h1 class="utm-title">UTM Builder</h1>
  <p class="utm-sub">Инструмент для быстрого построения UTM‑ссылок. Вставьте этот блок на любую страницу Tilda.</p>

  <div class="utm-card" style="margin-bottom:16px">
    <div class="utm-field" style="margin-bottom:12px">
      <label class="utm-label" for="baseUrl">Базовая ссылка <span style="color:#ef4444">*</span></label>
      <input id="baseUrl" class="utm-input" placeholder="https://example.com/landing">
    </div>

    <div class="utm-grid" style="margin-bottom:12px">
      <div class="utm-field">
        <label class="utm-label" for="utm_source">utm_source <span style="color:#ef4444">*</span></label>
        <input id="utm_source" class="utm-input" placeholder="google, vk, tg">
      </div>
      <div class="utm-field">
        <label class="utm-label" for="utm_medium">utm_medium <span style="color:#ef4444">*</span></label>
        <input id="utm_medium" class="utm-input" placeholder="cpc, cpm, referral">
      </div>
      <div class="utm-field">
        <label class="utm-label" for="utm_campaign">utm_campaign <span style="color:#ef4444">*</span></label>
        <input id="utm_campaign" class="utm-input" placeholder="summer_sale_2025">
      </div>
      <div class="utm-field">
        <label class="utm-label" for="utm_term">utm_term</label>
        <input id="utm_term" class="utm-input" placeholder="ключевые слова">
      </div>
      <div class="utm-field">
        <label class="utm-label" for="utm_content">utm_content</label>
        <input id="utm_content" class="utm-input" placeholder="вариант креатива">
      </div>
    </div>

    <div class="utm-row" style="margin-bottom:8px">
      <label class="utm-chip">
        <span class="utm-switch"><input id="lowercase" type="checkbox" checked><i></i></span>
        <span class="utm-label">Приводить к нижнему регистру</span>
      </label>
      <label class="utm-chip">
        <span class="utm-switch"><input id="kebab" type="checkbox" checked><i></i></span>
        <span class="utm-label">Пробелы → дефисы</span>
      </label>
      <span class="utm-spacer"></span>
      <button class="utm-btn secondary" id="resetBtn" type="button">Сбросить</button>
    </div>
  </div>

  <div class="utm-grid">
    <div class="utm-card">
      <div class="utm-field" style="margin-bottom:10px">
        <label class="utm-label" for="resultUrl">Готовая ссылка</label>
        <input id="resultUrl" class="utm-input" readonly>
      </div>
      <div class="utm-row">
        <button class="utm-btn" id="copyBtn" type="button">Скопировать</button>
        <button class="utm-btn secondary" id="openBtn" type="button">Открыть</button>
      </div>
      <p id="warn" style="color:#ef4444;font-size:12px;margin:8px 0 0;display:none">Введите корректный URL со схемой http(s).</p>
    </div>

    <div class="utm-card">
      <div class="utm-label" style="margin-bottom:8px">Параметры</div>
      <pre class="utm-code" id="paramsBox">{}</pre>
    </div>

    <div class="utm-card" style="grid-column:1/-1">
      <div class="utm-row" style="margin-bottom:10px"><div class="utm-label">QR для кампании</div></div>
      <div class="utm-qr"><div id="qrcode"></div></div>
    </div>
  </div>
</div>

<!-- QRCode.js из CDN (разрешено Tilda) -->
<script src="https://unpkg.com/qrcodejs@1.0.0/qrcode.min.js"></script>
<script>
(function(){
  var el = function(id){return document.getElementById(id)};
  var baseUrl=el('baseUrl'), source=el('utm_source'), medium=el('utm_medium'), campaign=el('utm_campaign'), term=el('utm_term'), content=el('utm_content');
  var lowercase=el('lowercase'), kebab=el('kebab');
  var resultUrl=el('resultUrl'), warn=el('warn');

  function isValidHttpUrl(str){
    if(!str) return true;
    try{ var u=new URL(str); return u.protocol==='http:'||u.protocol==='https:'; }catch(e){ return false; }
  }
  function normalize(v){
    var out = (v||'').trim();
    if(lowercase.checked) out = out.toLowerCase();
    if(kebab.checked) out = out.replace(/\s+/g,'-');
    return out;
  }
  function buildUtmUrl(){
    var base = baseUrl.value.trim();
    if(!base) { resultUrl.value=''; setQR('https://example.com'); return; }
    try{
      var url = new URL(base);
      var params = {
        utm_source: normalize(source.value),
        utm_medium: normalize(medium.value),
        utm_campaign: normalize(campaign.value),
        utm_term: normalize(term.value),
        utm_content: normalize(content.value)
      };
      // обновим JSON бокс
      el('paramsBox').textContent = JSON.stringify(params, null, 2);
      Object.keys(params).forEach(function(k){ if(params[k]) url.searchParams.set(k, params[k]); });
      var out = url.toString();
      resultUrl.value = out;
      setQR(out);
      warn.style.display = isValidHttpUrl(base) ? 'none' : 'block';
    }catch(e){
      resultUrl.value='';
      setQR('https://example.com');
      warn.style.display = 'block';
    }
  }

  // QR
  var qr;
  function setQR(text){
    var box = el('qrcode');
    if(!qr){ qr = new QRCode(box, {text:text, width:164, height:164, correctLevel: QRCode.CorrectLevel.M}); }
    else { qr.clear(); qr.makeCode(text||'https://example.com'); }
  }
  setQR('https://example.com');

  // События
  [baseUrl, source, medium, campaign, term, content, lowercase, kebab].forEach(function(i){ i.addEventListener('input', buildUtmUrl); i.addEventListener('change', buildUtmUrl); });

  // Кнопки
  el('copyBtn').addEventListener('click', function(){
    if(!resultUrl.value) return;
    resultUrl.select();
    try{ document.execCommand('copy'); }catch(e){}
  });
  el('openBtn').addEventListener('click', function(){ if(resultUrl.value) window.open(resultUrl.value, '_blank'); });
  el('resetBtn').addEventListener('click', function(){
    [baseUrl, source, medium, campaign, term, content].forEach(function(i){ i.value=''; });
    resultUrl.value='';
    el('paramsBox').textContent = '{}';
    setQR('https://example.com');
    warn.style.display = 'none';
  });
})();
</script>