<!-- 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>