Skip to main content

<html lang="it">

<head>

<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':

new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],

j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=

'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);

})(window,document,'script','dataLayer','GTM-KMP9MMS');</script>

<meta charset="UTF-8" />

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

<title>SMS-Alert – Catena della Solidarietà</title>

<link rel="preconnect" href="https://fonts.googleapis.com">

<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

<link href="https://fonts.googleapis.com/css2?family=Platypi:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400&display=swap" rel="stylesheet">

<style>

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {

--bg: #ffffff;

--surface: #f4f2ee;

--border: rgba(170,165,155,0.45);

--text: #0b0c0d;

--text-muted: rgba(11,12,13,0.60);

--text-dim: rgba(11,12,13,0.38);

--accent: #e82340;

}

html { scroll-behavior: smooth; overflow-y: auto; }

body {

background: var(--bg);

color: var(--text);

font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif;

-webkit-font-smoothing: antialiased;

overflow-x: hidden;

}

/* ── Layout ── */

.page {

max-width: 640px;

margin: 0 auto;

padding: 0 24px 0;

position: relative;

}

/* ── Screens ── */

.screen {

display: none;

animation: screenEnter 0.42s cubic-bezier(.25,.8,.25,1) both;

}

.screen.active { display: block; }

.screen.leaving {

display: block;

position: absolute;

top: 0; left: 24px; right: 24px;

animation: screenLeave 0.3s ease forwards;

pointer-events: none;

}

@keyframes screenEnter {

from { opacity: 0; transform: translateY(24px); }

to { opacity: 1; transform: translateY(0); }

}

@keyframes screenLeave {

from { opacity: 1; transform: translateY(0); }

to { opacity: 0; transform: translateY(-14px); }

}

/* ── Header shared ── */

.pre-logo {

padding-top: 40px;

margin-bottom: 40px;

}

.pre-logo img {

width: 100%;

max-height: 80px;

object-fit: contain;

object-position: center;

display: block;

}

.pre-logo-sep {

width: 1px;

height: 28px;

background: rgba(11,12,13,0.15);

flex-shrink: 0;

}

.pre-logo-anni {

font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif;

font-size: 11px;

font-weight: 500;

letter-spacing: 0.12em;

text-transform: uppercase;

color: var(--text-dim);

white-space: nowrap;

}

/* ── Inline disaster word pill ── */

.disaster-pill {

display: inline-block;

color: #000000;

font-style: normal;

font-size: 1em;

font-weight: 700;

min-width: 5em;

text-align: left;

vertical-align: baseline;

transition: opacity 0.5s ease;

}

.disaster-pill.fade { opacity: 0; }

/* ── Typography ── */

.headline {

font-family: 'Platypi', Georgia, serif;

font-size: clamp(30px, 7.5vw, 46px);

font-weight: 300;

line-height: 1.3;

letter-spacing: -0.01em;

color: var(--text);

text-align: center;

margin-bottom: 10px;

}

.subheadline {

font-size: clamp(14px, 3.2vw, 16px);

color: var(--text-muted);

text-align: center;

line-height: 1.55;

max-width: 420px;

margin: 0 auto 28px;

}

/* ── Counter block ── */

.counter-block {

text-align: center;

margin: 0 auto 28px;

}

.counter-number {

font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif;

font-size: clamp(56px, 15vw, 96px);

font-weight: 800;

letter-spacing: -0.03em;

color: var(--text);

line-height: 1;

display: block;

font-variant-numeric: tabular-nums;

transition: color 0.15s ease;

}

@keyframes counterPulse {

0% { color: var(--text); }

20% { color: #e82340; }

100% { color: var(--text); }

}

.counter-pulse {

animation: counterPulse 0.9s ease-out forwards;

}

.counter-label {

font-size: clamp(14px, 3.2vw, 16px);

color: var(--text);

letter-spacing: 0.02em;

line-height: 1.7;

max-width: 380px;

margin: 10px auto 0;

}

/* ── CTA area ── */

.cta-question {

font-size: clamp(14px, 3.2vw, 16px);

color: var(--text-muted);

text-align: center;

margin: 24px auto 10px;

line-height: 1.5;

max-width: 420px;

}

.btn-primary {

display: block;

width: 100%;

max-width: 360px;

margin: 0 auto;

background: var(--accent);

border: none;

border-radius: 48px;

padding: 16px 28px;

color: #fff;

font-size: 16px;

font-weight: 600;

font-family: inherit;

cursor: pointer;

letter-spacing: 0.03em;

text-align: center;

transition: opacity 0.2s ease, transform 0.15s ease;

}

.btn-primary:hover { opacity: 0.86; }

.btn-primary:active { transform: scale(0.97); opacity: 1; }

/* ── Screen 2: Lead capture ── */

#screen-2 .headline {

margin-top: 20px;

}

.lead-sub {

font-size: 14px;

color: var(--text-muted);

text-align: center;

line-height: 1.65;

max-width: 460px;

margin: 0 auto 40px;

}

.input-wrap {

max-width: 360px;

margin: 0 auto 4px;

}

.input-field {

width: 100%;

background: #fff;

border: 1px solid rgba(11,12,13,0.3);

border-radius: 0;

padding: 12px 14px 12px 100px;

color: var(--text);

font-size: 22px;

font-family: inherit;

outline: none;

text-align: left;

transition: border-color 0.25s ease;

-webkit-appearance: none;

}

.input-field::placeholder { color: var(--text-dim); font-size: 20px; }

.input-field:focus { border-color: var(--text); }

.input-field.error {

border-color: #e82340;

animation: shake 0.3s ease;

}

@keyframes shake {

0%,100% { transform: translateX(0); }

25% { transform: translateX(-6px); }

75% { transform: translateX(6px); }

}

.input-error-msg {

font-size: 13px;

color: #e82340;

text-align: center;

margin-top: 8px;

min-height: 18px;

opacity: 0;

transition: opacity 0.25s ease;

}

.input-error-msg.visible { opacity: 1; }

.trust-line {

text-align: center;

font-size: 12px;

color: var(--text-dim);

font-weight: 400;

margin: 14px auto 28px;

letter-spacing: 0.02em;

}

.btn-wrap {

max-width: 360px;

margin: 0 auto;

}

.btn-wrap .btn-primary { max-width: 100%; }

/* ── Inline phone section ── */

#phone-section {

margin-top: 0;

}

.form-headline {

font-family: 'Platypi', Georgia, serif;

font-size: clamp(19px, 4.8vw, 27px);

font-weight: 300;

line-height: 1.3;

text-align: center;

margin-bottom: 28px;

color: var(--text);

}

/* ── Screen 3: Thank you ── */

#screen-3 {

padding-top: 48px;

text-align: center;

}

.check-icon {

width: 72px;

height: 72px;

background: #e82340;

border-radius: 50%;

display: flex;

align-items: center;

justify-content: center;

margin: 0 auto 32px;

animation: popIn 0.4s cubic-bezier(.34,1.56,.64,1) both;

}

@keyframes popIn {

from { transform: scale(0.4); opacity: 0; }

to { transform: scale(1); opacity: 1; }

}

.check-icon svg {

width: 34px;

height: 34px;

}

.check-icon .check-path {

stroke-dasharray: 30;

stroke-dashoffset: 30;

animation: drawCheck 0.5s cubic-bezier(.4,0,.2,1) 0.25s forwards;

}

@keyframes drawCheck {

to { stroke-dashoffset: 0; }

}

#screen-3 .headline {

margin-top: 0;

margin-bottom: 16px;

}

.thanks-sub {

font-size: 15px;

color: var(--text-muted);

line-height: 1.7;

max-width: 420px;

margin: 0 auto;

}

/* ── Footer ── */

.footer-glow {

margin-top: 80px;

text-align: center;

font-size: 12px;

color: var(--text-dim);

letter-spacing: 0.08em;

padding-bottom: 40px;

}

.glow-rule {

width: 60px;

height: 2px;

background: var(--accent);

margin: 0 auto 16px;

opacity: 0.7;

border-radius: 1px;

}

@media (max-width: 400px) {

.page { padding: 0 16px 0; }

}

</style>

</head>

<body>

<noscript><p> height="0" width="0" style="display:none;visibility:hidden">&lt;/iframe&gt;&lt;/noscript&gt;</p> <p> <!-- End Google Tag Manager (noscript) --></p> <div class="page"><p>&nbsp;</p> <p>&nbsp;</p> <p> <!-- ══════════ SCREEN 1 ══════════ --></p> <div id="screen-1" class="screen active"><p>&nbsp;</p> <p>&nbsp;</p> <div class="pre-logo"><p>&nbsp;</p></div> <p>&nbsp;</p> <h1 class="headline">In caso di <span class="disaster-pill" id="disaster-word">Terremoti</span><br>ogni minuto conta.</h1> <p>&nbsp;</p> <p class="subheadline">Permetti alla <strong>Catena della Solidarietà</strong> di<br>informarti quando è necessario un aiuto rapido?</p> <p>&nbsp;</p> <div class="counter-block"><p>&nbsp;</p> <p> <span class="counter-number" id="counter-num">0</span></p> <p class="counter-label">sono già iscritti.</p></div> <p>&nbsp;</p> <p class="cta-question">Il tuo numero di cellulare:</p> <p>&nbsp;</p> <div id="phone-section"><p>&nbsp;</p> <div class="input-wrap"><p>&nbsp;</p> <p> <input</p> <p> class="input-field"</p> <p> type="tel"</p> <p> id="phone-input"</p> <p> placeholder="079 123 45 67"</p> <p> inputmode="tel"</p> <p> autocomplete="tel"</p> <p> /></p></div> <p> &lt;input type="text" name="website" id="hp-website" tabindex="-1" autocomplete="off" style="position:absolute;left:-9999px;width:1px;height:1px;opacity:0" aria-hidden="true"&gt;</p> <p class="input-error-msg" id="phone-error-msg">Inserisci un numero di cellulare svizzero (07X XXX XX XX)</p> <p class="trust-line">Nessuna chiamata · nessuna pubblicità · nessuna condivisione con terzi</p> <p class="trust-line" style="margin-top:4px">Un'azione per l'80° anniversario della Catena della Solidarietà</p> <div class="btn-wrap"><p>&nbsp;</p> <p> &lt;button class="btn-primary" id="btn-submit"&gt;Attiva l'avviso SMS&lt;/button&gt;</p></div> <p>&nbsp;</p></div> <p>&nbsp;</p></div> <p>&nbsp;</p> <p> <!-- ══════════ SCREEN 3 ══════════ --></p> <div id="screen-3" class="screen"><p>&nbsp;</p> <div class="check-icon"><p>&nbsp;</p> <p> &lt;svg viewBox="0 0 34 34" fill="none" xmlns="http://www.w3.org/2000/svg"&gt;</p> <p> &lt;path class="check-path" d="M7 18L14 25L27 10" stroke="#ffffff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/&gt;</p> <p> &lt;/svg&gt;</p></div> <p>&nbsp;</p> <h1 class="headline">Grazie.<br>La tua solidarietà conta.</h1> <p>&nbsp;</p> <p> <p class="thanks-sub"></p> <p> È fantastico che possiamo contare su di te in caso di emergenza.<br><br></p> <p> Quando la Catena della Solidarietà lancia una grande campagna di solidarietà, ti informiamo via SMS.</p> <p> </p></p> <p>&nbsp;</p></div> <p>&nbsp;</p></div> <p>&nbsp;</p> <p>&lt;script&gt;</p> <p>// ── Disaster word crossfade ────────────────────────────────</p> <p>(function() {</p> <p> const WORDS = ['Terremoti','disastri naturali','frane','tempeste','alluvioni','siccità'];</p> <p> const el = document.getElementById('disaster-word');</p> <p> let idx = 0;</p> <p>&nbsp;</p> <p> setInterval(() => {</p> <p> el.classList.add('fade');</p> <p> setTimeout(() => {</p> <p> idx = (idx + 1) % WORDS.length;</p> <p> el.textContent = WORDS[idx];</p> <p> el.classList.remove('fade');</p> <p> }, 500);</p> <p> }, 3400);</p> <p>})();</p> <p>&nbsp;</p> <p>// ── Counter animation ───────────────────────────────────────</p> <p>(function() {</p> <p> const el = document.getElementById('counter-num');</p> <p> const DURATION = 2200;</p> <p>&nbsp;</p> <p> function easeOut(t) { return 1 - Math.pow(1 - t, 18); }</p> <p>&nbsp;</p> <p> function runAnimation(target) {</p> <p> const TARGET = target;</p> <p> const start = performance.now();</p> <p>&nbsp;</p> <p> function step(ts) {</p> <p> const t = Math.min(1, (ts - start) / DURATION);</p> <p> const val = Math.round(easeOut(t) * TARGET);</p> <p> el.textContent = val.toLocaleString('it-IT');</p> <p> if (t < 1) { requestAnimationFrame(step); } else { startLiveTicker(TARGET); }</p> <p> }</p> <p> requestAnimationFrame(step);</p> <p>&nbsp;</p> <p> function startLiveTicker(count) {</p> <p> revealPhoneSection();</p> <p> let first = true;</p> <p> function tick() {</p> <p> const delay = first ? 400 : 2000 + Math.random() * 13000;</p> <p> first = false;</p> <p> setTimeout(() => {</p> <p> count++;</p> <p> el.textContent = count.toLocaleString('it-IT');</p> <p> el.classList.remove('counter-pulse');</p> <p> void el.offsetWidth;</p> <p> el.classList.add('counter-pulse');</p> <p> setTimeout(() => el.classList.remove('counter-pulse'), 900);</p> <p> tick();</p> <p> }, delay);</p> <p> }</p> <p> tick();</p> <p> }</p> <p> }</p> <p>&nbsp;</p> <p> // Load real count from server; fall back to hardcoded value</p> <p> fetch('api/count.php')</p> <p> .then(r => r.ok ? r.json() : Promise.reject())</p> <p> .then(data => runAnimation(data.count || 24096))</p> <p> .catch(() => runAnimation(24096));</p> <p>})();</p> <p>&nbsp;</p> <p>// ── Screen transitions ──────────────────────────────────────</p> <p>function showScreen(id) {</p> <p> const current = document.querySelector('.screen.active');</p> <p> const next = document.getElementById(id);</p> <p> window.scrollTo({ top: 0, behavior: 'instant' });</p> <p> if (current && current !== next) {</p> <p> current.classList.add('leaving');</p> <p> current.classList.remove('active');</p> <p> setTimeout(() => current.classList.remove('leaving'), 320);</p> <p> setTimeout(() => next.classList.add('active'), 200);</p> <p> } else {</p> <p> next.classList.add('active');</p> <p> }</p> <p>}</p> <p>&nbsp;</p> <p>function revealPhoneSection() {</p> <p> const s = document.getElementById('phone-section');</p> <p> if (s.classList.contains('visible')) return;</p> <p> s.classList.add('visible');</p> <p> setTimeout(() => s.scrollIntoView({ behavior: 'smooth', block: 'nearest' }), 200);</p> <p>}</p> <p>&nbsp;</p> <p>// ── UTM-Parameter aus URL ────────────────────────────────────</p> <p>function getUtm() {</p> <p> const p = new URLSearchParams(location.search);</p> <p> const utm = {};</p> <p> ['utm_source','utm_medium','utm_campaign'].forEach(k => {</p> <p> const v = p.get(k);</p> <p> if (v) utm[k] = v.slice(0, 100);</p> <p> });</p> <p> return utm;</p> <p>}</p> <p>&nbsp;</p> <p>// ── Telefonnummer-Format ────────────────────────────────────</p> <p>function formatPhoneInput(e) {</p> <p> const input = e.target;</p> <p> const isPlus = input.value.startsWith('+');</p> <p> const digits = input.value.replace(/\D/g, '');</p> <p> let f = '';</p> <p> if (isPlus) {</p> <p> if (digits.length <= 2) f = '+' + digits;</p> <p> else if (digits.length <= 4) f = '+' + digits.slice(0,2) + ' ' + digits.slice(2);</p> <p> else if (digits.length <= 7) f = '+' + digits.slice(0,2) + ' ' + digits.slice(2,4) + ' ' + digits.slice(4);</p> <p> else if (digits.length <= 9) f = '+' + digits.slice(0,2) + ' ' + digits.slice(2,4) + ' ' + digits.slice(4,7) + ' ' + digits.slice(7);</p> <p> else f = '+' + digits.slice(0,2) + ' ' + digits.slice(2,4) + ' ' + digits.slice(4,7) + ' ' + digits.slice(7,9) + ' ' + digits.slice(9,11);</p> <p> } else {</p> <p> if (digits.length <= 3) f = digits;</p> <p> else if (digits.length <= 6) f = digits.slice(0,3) + ' ' + digits.slice(3);</p> <p> else if (digits.length <= 8) f = digits.slice(0,3) + ' ' + digits.slice(3,6) + ' ' + digits.slice(6);</p> <p> else f = digits.slice(0,3) + ' ' + digits.slice(3,6) + ' ' + digits.slice(6,8) + ' ' + digits.slice(8,10);</p> <p> }</p> <p> input.value = f;</p> <p>}</p> <p>&nbsp;</p> <p>// ── Phone submit ──────────────────────────────────────────</p> <p>const phoneInput = document.getElementById('phone-input');</p> <p>const btnSubmit = document.getElementById('btn-submit');</p> <p>const phoneErrorMsg = document.getElementById('phone-error-msg');</p> <p>&nbsp;</p> <p>phoneInput.addEventListener('input', formatPhoneInput);</p> <p>&nbsp;</p> <p>function submitPhone() {</p> <p> const val = phoneInput.value.trim().replace(/\s/g, '');</p> <p> // Validation: Swiss phone numbers only</p> <p> if (!/^(\+41|07)\d{7,9}$/.test(val)) {</p> <p> phoneInput.classList.add('error');</p> <p> phoneErrorMsg.classList.add('visible');</p> <p> setTimeout(() => { phoneInput.classList.remove('error'); phoneErrorMsg.classList.remove('visible'); }, 3000);</p> <p> return;</p> <p> }</p> <p> try { localStorage.setItem('glueckskette_phone', val); } catch(e) {}</p> <p> // Send to server: subscribe.php</p> <p> fetch('/alert/api/subscribe.php', {</p> <p> method: 'POST',</p> <p> headers: { 'Content-Type': 'application/json' },</p> <p> body: JSON.stringify({ phone: val, lang: 'IT', source: 'c-i', hp: document.getElementById('hp-website').value, ...getUtm() })</p> <p> }).then(() => {</p> <p> // Success: show thank you screen</p> <p> showScreen('screen-3');</p> <p> }).catch(err => {</p> <p> console.error('Errore:', err);</p> <p> // On error: still show thank you to avoid blocking user</p> <p> showScreen('screen-3');</p> <p> });</p> <p>}</p> <p>&nbsp;</p> <p>btnSubmit.addEventListener('click', submitPhone);</p> <p>phoneInput.addEventListener('keydown', e => { if (e.key === 'Enter') submitPhone(); });</p> <p>&lt;/script&gt;</p> <p>&lt;/body&gt;</p> <p>&lt;/html&gt;</p> </body>

Donare ora