Fattore Famiglia – Il Primo Sportello digitale familiare
  • Chi siamo
  • Eventi
  • Rete FF
    • Piacenza
    • Italia
  • Aree Tematiche
    • Civis Family
    • Smart Family
    • Lex Family
    • F.A.R.M.A.
    • Sani Family
    • Fisco Family
  • Convenzioni
  • Contatti
Sign In

Eventi

Benvenuto nella sezione eventi di Fattore Famiglia. Qui trovi tutte le iniziative dedicate alle famiglie: appuntamenti speciali, attività per grandi e piccoli, esperienze pensate per stare insieme in modo autentico e significativo. Ogni evento nasce dalla convinzione che la famiglia meriti momenti di qualità, vissuti con cura e allegria.

/* ===== FF EVENTI v1 — stile pagina eventi (inizio) ===== */
#ffe{--r:#c8102e;--r2:#b14147;--rd:#9e0c24;--ink:#1a1a1a;--tx:#2b2b2b;--mu:#6b6b6b;--bg:#f6f6f6;--ln:#e6e6e6;font-family:Montserrat,sans-serif;color:var(--tx);margin:0 0 40px}
#ffe *{box-sizing:border-box}
#ffe h1,#ffe h2,#ffe h3{font-family:Montserrat,sans-serif;color:var(--ink);margin:0}
#ffe a{text-decoration:none}
#ffe svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;flex:none}
.ffe-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;border-radius:999px;padding:13px 24px;font-weight:700;font-size:15px;line-height:1.1;border:2px solid transparent;cursor:pointer;transition:transform .15s,background .15s,color .15s;font-family:inherit}
.ffe-btn:hover{transform:translateY(-2px)}
.ffe-btn-white{background:#fff;color:var(--r)!important}
.ffe-btn-ghost{border-color:rgba(255,255,255,.75);color:#fff!important;background:transparent}
.ffe-btn-ghost:hover{background:rgba(255,255,255,.12)}
.ffe-btn-red{background:var(--r);color:#fff!important}
.ffe-btn-red:hover{background:var(--rd)}
.ffe-btn-line{background:#fff;border-color:var(--ln);color:var(--ink)}
.ffe-btn-line:hover{border-color:var(--ink)}
.ffe-sm{padding:9px 18px;font-size:14px}
/* hero */
.ffe-hero{position:relative;overflow:hidden;border-radius:26px;background:linear-gradient(135deg,#c8102e 0%,#9e0c24 100%);color:#fff;padding:clamp(28px,5vw,56px);display:grid;grid-template-columns:1.6fr 1fr;gap:28px;align-items:center}
.ffe-hero:before,.ffe-hero:after{content:"";position:absolute;border-radius:50%;background:rgba(255,255,255,.08)}
.ffe-hero:before{width:380px;height:380px;right:-120px;top:-140px}
.ffe-hero:after{width:220px;height:220px;right:180px;bottom:-130px}
.ffe-hero>*{position:relative;z-index:1}
.ffe-kicker{display:inline-block;background:rgba(255,255,255,.16);border-radius:999px;padding:6px 14px;font-size:13px;font-weight:700;letter-spacing:.08em;text-transform:uppercase}
#ffe .ffe-hero h1{color:#fff;font-size:clamp(30px,4.6vw,52px);line-height:1.05;font-weight:800;margin:16px 0 14px;letter-spacing:-.02em}
.ffe-hero h1 span{display:block;color:#ffd9de}
.ffe-hero p{font-size:clamp(16px,1.2vw + 10px,19px);line-height:1.55;max-width:560px;margin:0 0 24px;opacity:.95}
.ffe-hero-cta{display:flex;flex-wrap:wrap;gap:12px}
.ffe-hero-stats{display:grid;gap:12px}
.ffe-hero-stats div{background:rgba(255,255,255,.12);backdrop-filter:blur(4px);border:1px solid rgba(255,255,255,.18);border-radius:18px;padding:14px 20px;display:flex;align-items:baseline;gap:12px}
.ffe-hero-stats b{font-size:34px;font-weight:800;line-height:1}
.ffe-hero-stats span{font-size:15px;font-weight:600;opacity:.92}
/* in evidenza */
.ffe-feat{margin:-34px clamp(10px,3vw,40px) 0;position:relative;z-index:2}
.ffe-feat-card{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.35fr);background:#fff;border-radius:24px;overflow:hidden;box-shadow:0 18px 50px rgba(0,0,0,.14)}
.ffe-feat-img{background:#2b2b2b center/cover no-repeat;min-height:280px;display:flex;align-items:center;justify-content:center}
.ffe-feat-img span{color:#fff;font-size:84px;font-weight:800;line-height:1;text-align:center}
.ffe-feat-img small{display:block;font-size:22px;text-transform:uppercase;letter-spacing:.12em}
.ffe-feat-body{padding:clamp(20px,3vw,36px)}
#ffe .ffe-feat-body h2{font-size:clamp(22px,2vw + 8px,32px);line-height:1.15;margin:12px 0 8px;font-weight:800}
.ffe-feat-body h2 a{color:var(--ink)}
.ffe-feat-meta{color:var(--mu);font-size:16px;margin:0 0 18px;text-transform:none}
.ffe-feat-meta b{color:var(--ink)}
.ffe-card-body .ffe-badge,.ffe-feat-body .ffe-badge{align-self:flex-start}
.ffe-cd{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:20px;max-width:440px}
.ffe-cd div{background:var(--ink);color:#fff;border-radius:14px;text-align:center;padding:12px 4px 10px}
.ffe-cd div:first-child{background:var(--r)}
.ffe-cd b{display:block;font-size:clamp(26px,3vw,38px);font-weight:800;line-height:1;font-variant-numeric:tabular-nums}
.ffe-cd span{font-size:11.5px;text-transform:uppercase;letter-spacing:.1em;opacity:.85;font-weight:600}
.ffe-live-msg{display:none;background:#e8f7ee;color:#11713a;border-radius:14px;padding:14px 18px;font-weight:700;margin-bottom:20px}
.is-live .ffe-cd{display:none}.is-live .ffe-live-msg{display:block}
.ffe-feat-act{display:flex;flex-wrap:wrap;gap:10px}
.ffe-empty-feat{background:#fff;border-radius:24px;padding:30px;box-shadow:0 18px 50px rgba(0,0,0,.12);text-align:center}
/* badge */
.ffe-badge{display:inline-flex;align-items:center;gap:6px;border-radius:999px;padding:5px 12px;font-size:12.5px;font-weight:700;letter-spacing:.02em}
.ffe-b-ff{background:#fde8eb;color:var(--r)}
.ffe-b-terr{background:#ececec;color:#3a3a3a}
.ffe-dot{display:inline-block;width:10px;height:10px;border-radius:50%;margin-right:6px;vertical-align:middle}
.ffe-dot-ff{background:var(--r)}.ffe-dot-terr{background:#3a3a3a}
/* strumenti */
.ffe-tools{margin:38px 0 18px;display:grid;gap:12px}
.ffe-chips{display:flex;gap:8px;overflow-x:auto;padding-bottom:2px;scrollbar-width:none}
.ffe-chips::-webkit-scrollbar{display:none}
.ffe-chips button,.ffe-switch button,.ffe-near{flex:none;font-family:inherit;font-size:14.5px;font-weight:600;border:1.5px solid var(--ln);background:#fff;color:var(--ink);border-radius:999px;padding:9px 16px;cursor:pointer;transition:all .15s;display:inline-flex;align-items:center;gap:6px}
.ffe-chips button:hover,.ffe-near:hover{border-color:var(--ink)}
.ffe-chips button.on,.ffe-switch button.on,.ffe-near.on{background:var(--ink);border-color:var(--ink);color:#fff}
.ffe-chips button.on .ffe-dot-terr{background:#fff}
.ffe-row2{display:flex;gap:10px;flex-wrap:wrap}
.ffe-search{flex:1 1 260px;display:flex;align-items:center;gap:8px;border:1.5px solid var(--ln);border-radius:999px;padding:0 16px;background:#fff;margin:0}
.ffe-search:focus-within{border-color:var(--ink)}
.ffe-search input{border:0!important;outline:0;box-shadow:none!important;background:transparent!important;font:500 15px Montserrat,sans-serif;padding:11px 0!important;width:100%;height:auto!important;margin:0}
.ffe-eta{border:1.5px solid var(--ln)!important;border-radius:999px!important;padding:10px 38px 10px 16px!important;font:600 14.5px Montserrat,sans-serif!important;background-color:#fff;color:var(--ink);height:auto!important;width:auto!important;max-width:100%}
.ffe-near.loading{opacity:.6;pointer-events:none}
.ffe-switch{display:none;background:var(--bg);border-radius:999px;padding:4px;width:max-content}
.ffe-switch button{border:0;background:transparent;padding:9px 26px}
/* contenuto */
.ffe-main{display:grid;grid-template-columns:minmax(0,1fr) minmax(320px,42%);gap:28px;align-items:start}
.ffe-list{display:grid;gap:18px}
#ffe .ffe-month{font-size:15px;text-transform:uppercase;letter-spacing:.12em;color:var(--r);font-weight:800;margin:10px 0 -4px;display:flex;align-items:center;gap:12px}
.ffe-month:after{content:"";flex:1;height:1px;background:var(--ln)}
.ffe-card{display:grid;grid-template-columns:220px minmax(0,1fr);background:#fff;border:1px solid var(--ln);border-radius:20px;overflow:hidden;transition:box-shadow .2s,transform .2s}
.ffe-card:hover{box-shadow:0 12px 32px rgba(0,0,0,.09);transform:translateY(-2px)}
.ffe-card.is-ff{border-color:#f3c3cb;box-shadow:inset 5px 0 0 var(--r)}
.ffe-card-img{position:relative;display:block;min-height:190px;background:linear-gradient(135deg,#3a3a3a,#1a1a1a) center/cover no-repeat}
.ffe-card.is-ff .ffe-card-img:not([style]){background:linear-gradient(135deg,#c8102e,#9e0c24)}
.ffe-date{position:absolute;top:12px;left:12px;background:#fff;border-radius:14px;padding:8px 10px 6px;text-align:center;color:var(--r);font-weight:800;font-size:12px;text-transform:uppercase;letter-spacing:.08em;line-height:1;box-shadow:0 4px 14px rgba(0,0,0,.18);min-width:54px}
.ffe-date b{display:block;font-size:26px;color:var(--ink);letter-spacing:0;margin-bottom:2px}
.ffe-when{position:absolute;left:12px;bottom:12px;background:rgba(26,26,26,.85);color:#fff;font-size:12.5px;font-weight:700;border-radius:999px;padding:5px 11px}
.ffe-w-today,.ffe-w-soon{background:var(--r)}
.ffe-w-live{background:#11813f;animation:ffe-p 1.6s infinite}
@keyframes ffe-p{0%,100%{box-shadow:0 0 0 0 rgba(17,129,63,.6)}50%{box-shadow:0 0 0 7px rgba(17,129,63,0)}}
.ffe-card-body{padding:18px 20px 16px;display:flex;flex-direction:column;gap:9px}
#ffe .ffe-card h3{font-size:clamp(18px,.6vw + 14px,21px);line-height:1.25;font-weight:800}
.ffe-card h3 a{color:var(--ink)}
.ffe-card h3 a:hover{color:var(--r)}
.ffe-meta{list-style:none;margin:0;padding:0;display:grid;gap:5px;font-size:14.5px;color:var(--tx)}
.ffe-meta li{display:flex;gap:8px;align-items:flex-start;line-height:1.4;margin:0}
.ffe-meta li:first-letter{text-transform:uppercase}
.ffe-meta svg{color:var(--r);width:17px;height:17px;margin-top:1px}
.ffe-meta em{color:var(--r);font-style:normal;font-weight:700}
.ffe-intro{font-size:14.5px;line-height:1.55;color:var(--mu);margin:0}
.ffe-tags{display:flex;flex-wrap:wrap;gap:6px}
.ffe-tags:empty{display:none}
.ffe-tag{background:var(--bg);border-radius:8px;padding:4px 9px;font-size:12.5px;font-weight:600;color:#444}
.ffe-tag-cost{background:#e8f7ee;color:#11713a}
.ffe-act{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:4px}
.ffe-ico{width:40px;height:40px;border-radius:50%;border:1.5px solid var(--ln);background:#fff;color:var(--ink)!important;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:all .15s;padding:0}
.ffe-ico:hover{border-color:var(--r);color:var(--r)!important}
.ffe-wa:hover{border-color:#1faa53;color:#1faa53!important}
.ffe-link{font-size:14px;font-weight:700;color:var(--r)!important;margin-left:4px}
.ffe-empty{text-align:center;background:var(--bg);border-radius:20px;padding:44px 24px}
.ffe-empty-ico{font-size:44px}
#ffe .ffe-empty h3{margin:8px 0}
.ffe-empty p{color:var(--mu);max-width:420px;margin:0 auto 18px}
/* mappa */
.ffe-mapwrap{position:sticky;top:100px;border-radius:20px;overflow:hidden;border:1px solid var(--ln);background:var(--bg)}
#ffe-map{height:min(72vh,640px);width:100%;z-index:0}
.ffe-legend{display:flex;gap:16px;padding:10px 16px;font-size:13px;font-weight:600;background:#fff;border-top:1px solid var(--ln)}
.ffe-mk span{display:flex;flex-direction:column;align-items:center;justify-content:center;width:42px;height:42px;border-radius:50% 50% 50% 4px;transform:rotate(-45deg);background:#3a3a3a;color:#fff;font:800 15px/1 Montserrat,sans-serif;box-shadow:0 4px 12px rgba(0,0,0,.3);border:3px solid #fff}
.ffe-mk span>i{transform:rotate(45deg);display:flex;flex-direction:column;align-items:center;font-style:normal;line-height:1}
.ffe-mk span b{font-size:15px;font-weight:800}
.ffe-mk span small{font-size:8.5px;text-transform:uppercase;letter-spacing:.05em;margin-top:1px}
.ffe-mk{background:none;border:0}
.ffe-mk-ff span{background:#c8102e}
.ffe-pop{display:grid;gap:4px;font-family:Montserrat,sans-serif;font-size:13px}
.ffe-pop img{width:100%;height:110px;object-fit:cover;border-radius:10px;margin-bottom:4px}
.ffe-pop b{font-size:15px;line-height:1.25;color:#1a1a1a}
.ffe-pop a{color:#c8102e!important;font-weight:700}
.ffe-pop .ffe-badge{justify-self:start;padding:3px 9px;font-size:11px}
/* segnala */
.ffe-submit{margin-top:40px;border-radius:24px;background:#1a1a1a;color:#fff;padding:clamp(24px,4vw,44px);display:flex;align-items:center;justify-content:space-between;gap:24px;flex-wrap:wrap}
#ffe .ffe-submit h2{color:#fff;font-size:clamp(22px,2vw + 10px,30px);font-weight:800;margin-bottom:8px}
.ffe-submit p{margin:0;max-width:640px;opacity:.85;line-height:1.55}
/* responsive */
@media (max-width:999px){
 .ffe-hero{grid-template-columns:1fr}
 .ffe-hero-stats{grid-template-columns:repeat(3,1fr)}
 .ffe-hero-stats div{flex-direction:column;gap:4px;padding:12px}
 .ffe-hero-stats b{font-size:26px}.ffe-hero-stats span{font-size:12.5px}
 .ffe-feat{margin:-24px 8px 0}
 .ffe-feat-card{grid-template-columns:1fr}
 .ffe-feat-img{min-height:200px}
 .ffe-switch{display:flex}
 .ffe-main{grid-template-columns:1fr}
 .ffe-main[data-view=list] .ffe-mapwrap{display:none}
 .ffe-main[data-view=map] .ffe-list{display:none}
 .ffe-mapwrap{position:relative;top:0}
 #ffe-map{height:70vh}
}
@media (max-width:620px){
 .ffe-hero{border-radius:20px}
 .ffe-hero-cta .ffe-btn{flex:1 1 100%}
 .ffe-card{grid-template-columns:1fr}
 .ffe-card-img{min-height:170px}
 .ffe-cd{gap:6px}
 .ffe-feat-act .ffe-btn{flex:1 1 100%}
 .ffe-submit .ffe-btn{width:100%}
}
/* in primo piano + archivio */
.ffe-ffnext,.ffe-past{margin-top:44px}
.ffe-sec-head{margin-bottom:18px}
.ffe-kicker2{display:inline-block;color:var(--r);font-weight:800;font-size:13px;letter-spacing:.1em;text-transform:uppercase}
#ffe .ffe-sec-head h2{font-size:clamp(22px,1.6vw + 12px,30px);font-weight:800;margin:6px 0 4px}
.ffe-sec-head p{color:var(--mu);margin:0;font-size:16px}
.ffe-mini-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:18px}
.ffe-mini{display:flex;flex-direction:column;background:#fff;border-radius:20px;overflow:hidden;border:1px solid var(--ln);color:var(--tx)!important;transition:transform .2s,box-shadow .2s}
.ffe-mini:hover{transform:translateY(-3px);box-shadow:0 14px 34px rgba(0,0,0,.1)}
.ffe-ffnext .ffe-mini{border:2px solid var(--r)}
.ffe-mini-img{position:relative;display:block;height:170px;background:linear-gradient(135deg,#c8102e,#9e0c24) center/cover no-repeat}
.ffe-mini-body{display:flex;flex-direction:column;gap:6px;padding:16px 18px 18px}
.ffe-mini-body b{font-size:17px;line-height:1.3;color:var(--ink)}
.ffe-mini-body small{font-size:14px;color:var(--mu)}
.ffe-mini-body em{font-style:normal;font-weight:700;color:var(--r);font-size:14px;margin-top:2px}
.ffe-more{text-align:center;margin-top:22px}
/* nel singolo articolo nascondo i campi tecnici */
.field-entry.coordinate,.field-entry.tipo-evento{display:none!important}
/* ===== FF EVENTI v1 (fine) ===== */
/* ===== FF EVENTI v1 — pagina eventi Fattore Famiglia (inizio) ===== */
(function () {
  'use strict';
  function boot() {
    var blog = document.querySelector('.com-content-category-blog');
    if (!blog) return;
    var isEventi = document.getElementById('ff-eventi') || document.body.classList.contains('itemid-451');
    if (!isEventi) return;
    if (document.getElementById('ffe')) return;

    var SUBMIT_URL = '/segnala-evento';
    var MESI = ['gen', 'feb', 'mar', 'apr', 'mag', 'giu', 'lug', 'ago', 'set', 'ott', 'nov', 'dic'];
    var MESI_L = ['gennaio', 'febbraio', 'marzo', 'aprile', 'maggio', 'giugno', 'luglio', 'agosto', 'settembre', 'ottobre', 'novembre', 'dicembre'];
    var GIORNI = ['domenica', 'lunedì', 'martedì', 'mercoledì', 'giovedì', 'venerdì', 'sabato'];

    function esc(s) { return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) { return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]; }); }
    function pad(n) { return (n < 10 ? '0' : '') + n; }
    function parseDate(t) {
      if (!t) return null;
      t = t.trim();
      var m = t.match(/(\d{1,2})[-\/.](\d{1,2})[-\/.](\d{4})(?:[ T,]+(\d{1,2})[:.](\d{2}))?/);
      if (m) return { d: new Date(+m[3], +m[2] - 1, +m[1], m[4] ? +m[4] : 0, m[5] ? +m[5] : 0), time: !!m[4] };
      m = t.match(/(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{2}):(\d{2}))?/);
      if (m) return { d: new Date(+m[1], +m[2] - 1, +m[3], m[4] ? +m[4] : 0, m[5] ? +m[5] : 0), time: !!m[4] };
      return null;
    }
    function sameDay(a, b) { return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate(); }
    function hhmm(d) { return pad(d.getHours()) + ':' + pad(d.getMinutes()); }
    function store(k, v) { try { if (v === undefined) return JSON.parse(localStorage.getItem(k) || 'null'); localStorage.setItem(k, JSON.stringify(v)); } catch (e) { return null; } }

    /* ---------- 1. Leggo gli eventi dall'elenco Joomla ---------- */
    var arts = blog.querySelectorAll('.article-list .article, .blog-items .blog-item, .items-leading > div, .items-row .item');
    var now = new Date();
    var events = [];
    Array.prototype.forEach.call(arts, function (a, i) {
      var link = a.querySelector('.article-header a, h2 a, .page-header a');
      if (!link) return;
      var f = {};
      a.querySelectorAll('.field-entry').forEach(function (li) {
        var name = li.className.replace('field-entry', '').trim().split(/\s+/)[0];
        var v = li.querySelector('.field-value');
        if (name && v) f[name] = v;
      });
      var txt = function (k) { return f[k] ? f[k].textContent.replace(/\s+/g, ' ').trim() : ''; };
      var href = function (k) { var x = f[k] && f[k].querySelector('a'); return x ? x.href : (txt(k).indexOf('http') === 0 ? txt(k) : ''); };
      var st = parseDate(txt('data-evento'));
      if (!st) return;
      var en = parseDate(txt('data-fine'));
      var start = st.d, end;
      if (en && en.d > start) end = en.d;
      else if (st.time && (st.d.getHours() || st.d.getMinutes())) end = new Date(start.getTime() + 3 * 3600e3);
      else end = new Date(start.getFullYear(), start.getMonth(), start.getDate(), 23, 59);
      if (en && !en.time) end = new Date(en.d.getFullYear(), en.d.getMonth(), en.d.getDate(), 23, 59);
      var past = end < now; // evento concluso: esce dall'agenda (se è di Fattore Famiglia va nell'archivio)
      var img = a.querySelector('.article-intro-image img, .item-image img, img');
      var introEl = a.querySelector('.article-introtext, .item-content, .article-intro');
      var intro = '';
      if (introEl) {
        var c = introEl.cloneNode(true);
        c.querySelectorAll('.readmore, .fields-container, script, style').forEach(function (n) { n.remove(); });
        intro = c.textContent.replace(/\s+/g, ' ').trim();
      }
      var tipo = txt('tipo-evento').toLowerCase();
      var coord = txt('coordinate').match(/(-?\d+(?:\.\d+)?)\s*[,; ]\s*(-?\d+(?:\.\d+)?)/);
      var eta = txt('eta');
      events.push({
        id: 'e' + i, past: past,
        title: link.textContent.replace(/\s+/g, ' ').trim(),
        url: link.href,
        img: img ? img.currentSrc || img.src : '',
        intro: intro,
        start: start, end: end, hasTime: st.time && (st.d.getHours() || st.d.getMinutes()),
        ff: tipo ? tipo.indexOf('fattore') > -1 : !!(a.querySelector('.createdby') && a.querySelector('.createdby').textContent.trim()), // senza tipo: è FF se inserito dalla redazione
        luogo: txt('luogo'), indirizzo: txt('indirizzo'),
        lat: coord ? +coord[1] : null, lng: coord ? +coord[2] : null,
        costo: txt('costo'), org: txt('organizzatore'),
        info: href('link-info'), locandina: href('locandina-evento'),
        eta: eta ? eta.split(/\s*,\s*/) : [],
        etaRaw: eta.toLowerCase()
      });
    });
    var pastFF = events.filter(function (e) { return e.past && e.ff; }).sort(function (x, y) { return y.start - x.start; });
    events = events.filter(function (e) { return !e.past; });
    events.sort(function (x, y) { var d = new Date(x.start.getFullYear(), x.start.getMonth(), x.start.getDate()) - new Date(y.start.getFullYear(), y.start.getMonth(), y.start.getDate()); return d || (y.ff - x.ff) || (x.start - y.start); });

    /* ---------- 2. Costruisco la pagina ---------- */
    var oldRow = blog.querySelector(':scope > .row');
    var oldH1 = blog.querySelector(':scope > h1, :scope > .page-header');
    var oldDesc = blog.querySelector(':scope > .category-desc');
    var oldPag = blog.querySelector(':scope > .pagination, :scope > .com-content-category-blog__navigation, .pagination-wrapper');
    [oldRow, oldH1, oldDesc, oldPag].forEach(function (n) { if (n) n.style.display = 'none'; });

    var ffCount = events.filter(function (e) { return e.ff; }).length;
    var root = document.createElement('div');
    root.id = 'ffe';
    root.innerHTML =
      '<section class="ffe-hero">' +
        '<div class="ffe-hero-txt">' +
          '<span class="ffe-kicker">Agenda delle famiglie</span>' +
          '<h1>Eventi per <span>tutta la famiglia</span></h1>' +
          '<p>Gli appuntamenti di Fattore Famiglia e le migliori iniziative del territorio pensate per grandi e piccoli. Scegli, segna in calendario e… ci vediamo lì!</p>' +
          '<div class="ffe-hero-cta">' +
            '<a class="ffe-btn ffe-btn-white" href=\"#ffe-lista">Scopri gli eventi</a>' +
            '<a class="ffe-btn ffe-btn-ghost" href=\"' + SUBMIT_URL + '">+ Segnala un evento</a>' +
          '</div>' +
        '</div>' +
        '<div class="ffe-hero-stats">' +
          '<div><b>' + events.length + '</b><span>eventi in arrivo</span></div>' +
          '<div><b>' + ffCount + '</b><span>di Fattore Famiglia</span></div>' +
          '<div><b>' + (events.length - ffCount) + '</b><span>dal territorio</span></div>' +
        '</div>' +
      '</section>' +
      '<section class="ffe-feat" id="ffe-feat"></section>' +
      '<section class="ffe-ffnext" id="ffe-ffnext"></section>' +
      '<section class="ffe-tools" id="ffe-lista">' +
        '<div class="ffe-chips" data-group="tipo">' +
          '<button class="on" data-v="all">Tutti</button>' +
          '<button data-v="ff"><i class="ffe-dot ffe-dot-ff"></i>Fattore Famiglia</button>' +
          '<button data-v="terr"><i class="ffe-dot ffe-dot-terr"></i>Dal territorio</button>' +
        '</div>' +
        '<div class="ffe-chips" data-group="quando">' +
          '<button class="on" data-v="all">Sempre</button>' +
          '<button data-v="oggi">Oggi</button>' +
          '<button data-v="weekend">Questo weekend</button>' +
          '<button data-v="7">Prossimi 7 giorni</button>' +
          '<button data-v="30">Prossimi 30 giorni</button>' +
        '</div>' +
        '<div class="ffe-row2">' +
          '<label class="ffe-search"><svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg><input type="search" placeholder="Cerca evento, luogo, comune…" aria-label="Cerca"></label>' +
          '<select class="ffe-eta" aria-label="Età dei bambini"><option value="">Tutte le età</option><option value="0-3">0-3 anni</option><option value="3-6">3-6 anni</option><option value="6-10">6-10 anni</option><option value="11-14">11-14 anni</option><option value="15+">Ragazzi 15+</option><option value="genitori">Genitori</option></select>' +
          '<button class="ffe-near" type="button"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 2v3M12 19v3M2 12h3M19 12h3"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/></svg>Vicino a me</button>' +
        '</div>' +
        '<div class="ffe-switch" role="tablist"><button class="on" data-view="list">Elenco</button><button data-view="map">Mappa</button></div>' +
      '</section>' +
      '<section class="ffe-main" data-view="list">' +
        '<div class="ffe-list" id="ffe-cards"></div>' +
        '<div class="ffe-mapwrap"><div id="ffe-map" role="region" aria-label="Mappa degli eventi"></div><div class="ffe-legend"><span><i class="ffe-dot ffe-dot-ff"></i>Fattore Famiglia</span><span><i class="ffe-dot ffe-dot-terr"></i>Territorio</span></div></div>' +
      '</section>' +
      '<section class="ffe-past" id="ffe-past"></section>' +
      '<section class="ffe-submit">' +
        '<div><h2>Organizzi un evento per famiglie?</h2><p>Parrocchie, associazioni, comuni, scuole, biblioteche: segnalateci le vostre iniziative. Dopo una rapida verifica della redazione le pubblichiamo qui e sulla mappa, gratis.</p></div>' +
        '<a class="ffe-btn ffe-btn-white" href=\"' + SUBMIT_URL + '">Segnala il tuo evento</a>' +
      '</section>';
    blog.insertBefore(root, blog.firstChild);

    var $ = function (s) { return root.querySelector(s); };
    var state = { tipo: 'all', quando: 'all', q: '', eta: '', pos: null, view: 'list' };

    /* ---------- 3. Etichette tempo ---------- */
    function whenLabel(e) {
      var n = new Date();
      if (e.start <= n && e.end >= n) return { cls: 'live', t: 'In corso adesso' };
      var tom = new Date(n.getFullYear(), n.getMonth(), n.getDate() + 1);
      if (sameDay(e.start, n)) return { cls: 'today', t: 'Oggi' + (e.hasTime ? ' alle ' + hhmm(e.start) : '') };
      if (sameDay(e.start, tom)) return { cls: 'soon', t: 'Domani' + (e.hasTime ? ' alle ' + hhmm(e.start) : '') };
      var days = Math.ceil((new Date(e.start.getFullYear(), e.start.getMonth(), e.start.getDate()) - new Date(n.getFullYear(), n.getMonth(), n.getDate())) / 864e5);
      if (days <= 7) return { cls: 'soon', t: 'Tra ' + days + ' giorni' };
      return { cls: '', t: 'Tra ' + days + ' giorni' };
    }
    function dateLong(e) {
      var s = e.start, en = e.end;
      var out = GIORNI[s.getDay()] + ' ' + s.getDate() + ' ' + MESI_L[s.getMonth()];
      if (!sameDay(s, en) && (en - s) > 20 * 3600e3) out = 'dal ' + s.getDate() + (s.getMonth() !== en.getMonth() ? ' ' + MESI_L[s.getMonth()] : '') + ' al ' + en.getDate() + ' ' + MESI_L[en.getMonth()];
      else if (e.hasTime) out += ', ore ' + hhmm(s) + (sameDay(s, en) && (en - s) !== 3 * 3600e3 ? '–' + hhmm(en) : '');
      return out.charAt(0).toUpperCase() + out.slice(1);
    }

    /* ---------- 4. Evento in evidenza con countdown ---------- */
    function renderFeat() {
      var box = $('#ffe-feat');
      var e = events.filter(function (x) { return x.ff; })[0] || events[0];
      if (!e) {
        box.innerHTML = '<div class="ffe-empty-feat"><h2>Nuovi eventi in arrivo!</h2><p>Stiamo preparando i prossimi appuntamenti. Iscriviti al nostro canale WhatsApp per non perderli.</p></div>';
        return;
      }
      box.innerHTML =
        '<div class="ffe-feat-card">' +
          '<div class="ffe-feat-img"' + (e.img ? ' style="background-image:url(\'' + esc(e.img) + '\')"' : '') + '>' + (e.img ? '' : '<span>' + e.start.getDate() + '<small>' + MESI[e.start.getMonth()] + '</small></span>') + '</div>' +
          '<div class="ffe-feat-body">' +
            '<span class="ffe-badge ' + (e.ff ? 'ffe-b-ff' : 'ffe-b-terr') + '">' + (e.ff ? '★ Prossimo evento Fattore Famiglia' : 'Prossimo evento') + '</span>' +
            '<h2><a href=\"' + esc(e.url) + '">' + esc(e.title) + '</a></h2>' +
            '<p class="ffe-feat-meta"><b>' + esc(dateLong(e)) + '</b>' + (e.luogo || e.indirizzo ? ' · ' + esc(e.luogo || e.indirizzo) : '') + '</p>' +
            '<div class="ffe-cd" aria-live="polite">' +
              '<div><b data-u="d">0</b><span>giorni</span></div><div><b data-u="h">0</b><span>ore</span></div><div><b data-u="m">0</b><span>minuti</span></div><div><b data-u="s">0</b><span>secondi</span></div>' +
            '</div>' +
            '<div class="ffe-live-msg">🎉 L\'evento è in corso adesso: vi aspettiamo!</div>' +
            '<div class="ffe-feat-act">' +
              '<a class="ffe-btn ffe-btn-red" href=\"' + esc(e.url) + '">Tutti i dettagli</a>' +
              '<button class="ffe-btn ffe-btn-line" data-ics="' + e.id + '">📅 Aggiungi al calendario</button>' +
            '</div>' +
          '</div>' +
        '</div>';
      var cd = box.querySelector('.ffe-cd'), card = box.querySelector('.ffe-feat-card');
      function tick() {
        var diff = e.start - new Date();
        if (diff <= 0) { card.classList.add('is-live'); return; }
        var d = Math.floor(diff / 864e5), h = Math.floor(diff % 864e5 / 36e5), m = Math.floor(diff % 36e5 / 6e4), s = Math.floor(diff % 6e4 / 1e3);
        cd.querySelector('[data-u=d]').textContent = d;
        cd.querySelector('[data-u=h]').textContent = pad(h);
        cd.querySelector('[data-u=m]').textContent = pad(m);
        cd.querySelector('[data-u=s]').textContent = pad(s);
      }
      tick(); setInterval(tick, 1000);
    }

    /* ---------- 4b. In primo piano (prossimi eventi FF) e archivio (eventi FF passati) ---------- */
    function miniCard(e, past) {
      var w = whenLabel(e);
      return '<a class="ffe-mini' + (past ? ' is-past' : '') + '" href=\"' + esc(e.url) + '">' +
        '<span class="ffe-mini-img"' + (e.img ? ' style="background-image:url(\'' + esc(e.img) + '\')"' : '') + '>' +
          '<span class="ffe-date"><b>' + e.start.getDate() + '</b>' + MESI[e.start.getMonth()] + (past ? ' ' + e.start.getFullYear() : '') + '</span>' +
          (past ? '' : '<span class="ffe-when ffe-w-' + w.cls + '">' + esc(w.t) + '</span>') +
        '</span>' +
        '<span class="ffe-mini-body"><b>' + esc(e.title) + '</b><small>' + esc(past ? dateLong({ start: e.start, end: e.end, hasTime: false }) : dateLong(e)) + (e.luogo ? ' · ' + esc(e.luogo) : '') + '</small><em>' + (past ? 'Guarda com\'è andata →' : 'Scopri e partecipa →') + '</em></span>' +
      '</a>';
    }
    function renderFFNext() {
      var box = $('#ffe-ffnext');
      var list = events.filter(function (x) { return x.ff; }).slice(1);
      if (!list.length) { box.innerHTML = ''; box.style.display = 'none'; return; }
      box.style.display = '';
      box.innerHTML = '<div class="ffe-sec-head"><span class="ffe-kicker2">★ In primo piano</span><h2>I prossimi appuntamenti di Fattore Famiglia</h2></div><div class="ffe-mini-grid">' + list.map(function (e) { return miniCard(e, false); }).join('') + '</div>';
    }
    function renderPast() {
      var box = $('#ffe-past');
      if (!pastFF.length) { box.innerHTML = ''; box.style.display = 'none'; return; }
      box.style.display = '';
      var all = box.getAttribute('data-all') === '1';
      var list = all ? pastFF : pastFF.slice(0, 6);
      box.innerHTML = '<div class="ffe-sec-head"><span class="ffe-kicker2">Archivio</span><h2>Rivivi gli eventi di Fattore Famiglia</h2><p>Gli appuntamenti che abbiamo già vissuto insieme: racconti, foto e ricordi.</p></div><div class="ffe-mini-grid">' + list.map(function (e) { return miniCard(e, true); }).join('') + '</div>' +
        (pastFF.length > 6 && !all ? '<div class="ffe-more"><button class="ffe-btn ffe-btn-line" data-more="1">Mostra tutti (' + pastFF.length + ')</button></div>' : '');
    }

    /* ---------- 5. Filtri ---------- */
    function inRange(e) {
      var n = new Date(), t0 = new Date(n.getFullYear(), n.getMonth(), n.getDate());
      if (state.quando === 'all') return true;
      if (state.quando === 'oggi') return e.start < new Date(t0.getTime() + 864e5) && e.end >= n;
      if (state.quando === 'weekend') {
        var dow = n.getDay();
        var sat = new Date(t0.getTime() + ((6 - dow + 7) % 7) * 864e5);
        if (dow === 0) sat = new Date(t0.getTime() - 864e5);
        var mon = new Date(sat.getTime() + 2 * 864e5);
        return e.start < mon && e.end >= sat;
      }
      var lim = new Date(t0.getTime() + (+state.quando + 1) * 864e5);
      return e.start < lim;
    }
    function filtered() {
      var q = state.q.toLowerCase();
      var list = events.filter(function (e) {
        if (state.tipo === 'ff' && !e.ff) return false;
        if (state.tipo === 'terr' && e.ff) return false;
        if (!inRange(e)) return false;
        if (state.eta && e.etaRaw && e.etaRaw.indexOf(state.eta) === -1 && e.etaRaw.indexOf('tutte') === -1) return false;
        if (q && (e.title + ' ' + e.luogo + ' ' + e.indirizzo + ' ' + e.org + ' ' + e.intro).toLowerCase().indexOf(q) === -1) return false;
        return true;
      });
      if (state.pos) list = list.slice().sort(function (a, b) { return (a.dist == null ? 1e9 : a.dist) - (b.dist == null ? 1e9 : b.dist); });
      return list;
    }

    /* ---------- 6. Schede evento ---------- */
    function card(e) {
      var w = whenLabel(e);
      var maps = 'https://www.google.com/maps/dir/?api=1&destination=' + encodeURIComponent(e.lat != null ? e.lat + ',' + e.lng : (e.luogo + ' ' + e.indirizzo));
      var share = 'https://wa.me/?text=' + encodeURIComponent('👨‍👩‍👧‍👦 ' + e.title + '\n📅 ' + dateLong(e) + (e.luogo ? '\n📍 ' + e.luogo : '') + '\n' + e.url);
      return '<article class="ffe-card' + (e.ff ? ' is-ff' : '') + '" data-id="' + e.id + '">' +
        '<a class="ffe-card-img" href=\"' + esc(e.url) + '"' + (e.img ? ' style="background-image:url(\'' + esc(e.img) + '\')"' : '') + ' aria-label="' + esc(e.title) + '">' +
          '<span class="ffe-date"><b>' + e.start.getDate() + '</b>' + MESI[e.start.getMonth()] + '</span>' +
          '<span class="ffe-when ffe-w-' + w.cls + '">' + esc(w.t) + '</span>' +
        '</a>' +
        '<div class="ffe-card-body">' +
          '<span class="ffe-badge ' + (e.ff ? 'ffe-b-ff' : 'ffe-b-terr') + '">' + (e.ff ? '★ Fattore Famiglia' : 'Dal territorio') + '</span>' +
          '<h3><a href=\"' + esc(e.url) + '">' + esc(e.title) + '</a></h3>' +
          '<ul class="ffe-meta">' +
            '<li><svg viewBox="0 0 24 24"><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 10h18M8 3v4M16 3v4"/></svg>' + esc(dateLong(e)) + '</li>' +
            (e.luogo || e.indirizzo ? '<li><svg viewBox="0 0 24 24"><path d="M12 22s7-6.2 7-12a7 7 0 1 0-14 0c0 5.8 7 12 7 12z"/><circle cx="12" cy="10" r="2.5"/></svg>' + esc([e.luogo, e.indirizzo].filter(Boolean).join(' · ')) + (e.dist != null ? ' <em>· ' + (e.dist < 10 ? e.dist.toFixed(1) : Math.round(e.dist)) + ' km</em>' : '') + '</li>' : '') +
            (e.org ? '<li><svg viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M4 21c1.5-4 4.5-6 8-6s6.5 2 8 6"/></svg>' + esc(e.org) + '</li>' : '') +
          '</ul>' +
          (e.intro ? '<p class="ffe-intro">' + esc(e.intro.length > 170 ? e.intro.slice(0, 165).replace(/\s\S*$/, '') + '…' : e.intro) + '</p>' : '') +
          '<div class="ffe-tags">' +
            (e.costo ? '<span class="ffe-tag ffe-tag-cost">' + esc(e.costo) + '</span>' : '') +
            e.eta.map(function (x) { return '<span class="ffe-tag">' + esc(x) + '</span>'; }).join('') +
          '</div>' +
          '<div class="ffe-act">' +
            '<a class="ffe-btn ffe-btn-red ffe-sm" href=\"' + esc(e.url) + '">Dettagli</a>' +
            '<button class="ffe-ico" data-ics="' + e.id + '" title="Aggiungi al calendario" aria-label="Aggiungi al calendario"><svg viewBox="0 0 24 24"><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 10h18M8 3v4M16 3v4M12 13v5M9.5 15.5h5"/></svg></button>' +
            '<a class="ffe-ico" href=\"' + esc(maps) + '" target="_blank" rel="noopener" title="Indicazioni stradali" aria-label="Indicazioni stradali"><svg viewBox="0 0 24 24"><path d="m3 11 18-8-8 18-2-8z"/></svg></a>' +
            '<a class="ffe-ico ffe-wa" href=\"' + esc(share) + '" target="_blank" rel="noopener" title="Condividi su WhatsApp" aria-label="Condividi su WhatsApp"><svg viewBox="0 0 24 24"><path d="M4 20l1.3-3.9A8 8 0 1 1 8 19.1z"/><path d="M9 9.5c.3 2 2.5 4.6 5 5l1-1.2-1.6-.9-.7.7c-1-.4-2-1.4-2.4-2.4l.7-.7-.9-1.6z"/></svg></a>' +
            ((e.lat != null || e.geo) ? '<button class="ffe-ico ffe-pin" data-pin="' + e.id + '" title="Vedi sulla mappa" aria-label="Vedi sulla mappa"><svg viewBox="0 0 24 24"><path d="M9 4 3 6v14l6-2 6 2 6-2V4l-6 2z"/><path d="M9 4v14M15 6v14"/></svg></button>' : '') +
            (e.info ? '<a class="ffe-link" href=\"' + esc(e.info) + '" target="_blank" rel="noopener">Info e iscrizioni ↗</a>' : '') +
          '</div>' +
        '</div>' +
      '</article>';
    }
    function renderList() {
      var list = filtered();
      var box = $('#ffe-cards');
      if (!list.length) {
        box.innerHTML = '<div class="ffe-empty"><div class="ffe-empty-ico">🗓️</div><h3>Nessun evento con questi filtri</h3><p>Prova a cambiare periodo o tipo di evento, oppure segnalaci tu un\'iniziativa per famiglie.</p><a class="ffe-btn ffe-btn-red" href=\"' + SUBMIT_URL + '">Segnala un evento</a></div>';
      } else {
        var html = '', lastKey = '';
        list.forEach(function (e) {
          var key = state.pos ? '' : MESI_L[e.start.getMonth()] + ' ' + e.start.getFullYear();
          if (key && key !== lastKey) { html += '<h2 class="ffe-month">' + key + '</h2>'; lastKey = key; }
          html += card(e);
        });
        box.innerHTML = html;
      }
      renderMarkers(list);
    }

    /* ---------- 7. Mappa (Leaflet + OpenStreetMap) ---------- */
    var map = null, layer = null, markers = {};
    function loadLeaflet(cb) {
      if (window.L) return cb();
      var css = document.createElement('link');
      css.rel = 'stylesheet'; css.href = 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.min.css';
      document.head.appendChild(css);
      var s = document.createElement('script');
      s.src = 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.min.js';
      s.onload = cb; document.head.appendChild(s);
    }
    function icon(e) {
      return L.divIcon({ className: 'ffe-mk' + (e.ff ? ' ffe-mk-ff' : ''), html: '<span><i><b>' + e.start.getDate() + '</b><small>' + MESI[e.start.getMonth()] + '</small></i></span>', iconSize: [42, 50], iconAnchor: [21, 50], popupAnchor: [0, -46] });
    }
    function renderMarkers(list) {
      if (!map) return;
      layer.clearLayers(); markers = {};
      var seen = {};
      list.forEach(function (e) {
        if (e.lat == null) return;
        var k = e.lat.toFixed(4) + ',' + e.lng.toFixed(4), n = seen[k] = (seen[k] || 0) + 1;
        var lat = e.lat + (n - 1) * 0.0004, lng = e.lng + (n - 1) * 0.0004;
        var m = L.marker([lat, lng], { icon: icon(e), title: e.title, riseOnHover: true, zIndexOffset: e.ff ? 1000 : 0 })
          .bindPopup('<div class="ffe-pop">' + (e.img ? '<img src=\"' + esc(e.img) + '" alt="">' : '') + '<span class="ffe-badge ' + (e.ff ? 'ffe-b-ff' : 'ffe-b-terr') + '">' + (e.ff ? '★ Fattore Famiglia' : 'Dal territorio') + '</span><b>' + esc(e.title) + '</b><span>' + esc(dateLong(e)) + '</span><span>' + esc(e.luogo || e.indirizzo) + '</span><a href=\"' + esc(e.url) + '">Vedi dettagli →</a></div>', { maxWidth: 260 });
        m.addTo(layer); markers[e.id] = m;
      });
    }
    function initMap() {
      if (map) return;
      loadLeaflet(function () {
        map = L.map('ffe-map', { scrollWheelZoom: false, zoomControl: true }).setView([42.4, 12.6], 6);
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 19, attribution: '&copy; OpenStreetMap' }).addTo(map);
        layer = L.layerGroup().addTo(map);
        map.on('click', function () { map.scrollWheelZoom.enable(); });
        renderMarkers(filtered());
        geocodeMissing();
      });
    }
    // Se mancano le coordinate le ricavo dall'indirizzo (una volta sola, poi restano in memoria nel browser)
    function geocodeMissing() {
      var cache = store('ffe-geo') || {};
      var todo = events.filter(function (e) { return e.lat == null && (e.indirizzo || e.luogo); });
      todo.forEach(function (e) {
        var key = (e.indirizzo || e.luogo).toLowerCase();
        if (cache[key]) { e.lat = cache[key][0]; e.lng = cache[key][1]; e.geo = 1; }
      });
      var rest = todo.filter(function (e) { return e.lat == null; });
      if (!rest.length) { renderList(); return; }
      var i = 0;
      (function next() {
        if (i >= rest.length) { store('ffe-geo', cache); renderList(); return; }
        var e = rest[i++], q = (e.indirizzo || e.luogo);
        fetch('https://nominatim.openstreetmap.org/search?format=json&limit=1&countrycodes=it&q=' + encodeURIComponent(q))
          .then(function (r) { return r.json(); })
          .then(function (j) { if (j && j[0]) { e.lat = +j[0].lat; e.lng = +j[0].lon; e.geo = 1; cache[q.toLowerCase()] = [e.lat, e.lng]; } })
          .catch(function () {})
          .then(function () { setTimeout(next, 1100); });
      })();
    }
    var mapObs = new IntersectionObserver(function (en) { if (en[0].isIntersecting) { initMap(); mapObs.disconnect(); } }, { rootMargin: '300px' });
    mapObs.observe($('#ffe-map'));

    /* ---------- 8. Calendario (.ics) ---------- */
    function ics(e) {
      function f(d) { return d.getUTCFullYear() + pad(d.getUTCMonth() + 1) + pad(d.getUTCDate()) + 'T' + pad(d.getUTCHours()) + pad(d.getUTCMinutes()) + '00Z'; }
      var body = ['BEGIN:VCALENDAR', 'VERSION:2.0', 'PRODID:-//Fattore Famiglia//Eventi//IT', 'BEGIN:VEVENT',
        'UID:' + e.id + '-' + e.start.getTime() + '-fattorefamiglia-eventi', 'DTSTAMP:' + f(new Date()),
        'DTSTART:' + f(e.start), 'DTEND:' + f(e.end), 'SUMMARY:' + e.title.replace(/[,;]/g, ' '),
        'LOCATION:' + [e.luogo, e.indirizzo].filter(Boolean).join(' - ').replace(/[,;]/g, ' '),
        'DESCRIPTION:' + (e.url), 'URL:' + e.url,
        'BEGIN:VALARM', 'TRIGGER:-P1D', 'ACTION:DISPLAY', 'DESCRIPTION:Domani: ' + e.title.replace(/[,;]/g, ' '), 'END:VALARM',
        'END:VEVENT', 'END:VCALENDAR'].join('\r\n');
      var a = document.createElement('a');
      a.href = URL.createObjectURL(new Blob([body], { type: 'text/calendar;charset=utf-8' }));
      a.download = e.title.replace(/[^\wàèéìòù ]+/gi, '').trim().replace(/\s+/g, '-').slice(0, 50) + '.ics';
      document.body.appendChild(a); a.click(); setTimeout(function () { a.remove(); }, 500);
    }

    /* ---------- 9. Interazioni ---------- */
    root.addEventListener('click', function (ev) {
      var b = ev.target.closest('button');
      if (!b) return;
      if (b.hasAttribute('data-more')) { $('#ffe-past').setAttribute('data-all', '1'); renderPast(); return; }
      var grp = b.parentElement.getAttribute('data-group');
      if (grp) {
        b.parentElement.querySelectorAll('button').forEach(function (x) { x.classList.toggle('on', x === b); });
        state[grp] = b.getAttribute('data-v'); renderList(); return;
      }
      if (b.hasAttribute('data-view')) {
        state.view = b.getAttribute('data-view');
        b.parentElement.querySelectorAll('button').forEach(function (x) { x.classList.toggle('on', x === b); });
        $('.ffe-main').setAttribute('data-view', state.view);
        if (state.view === 'map') { initMap(); setTimeout(function () { map && map.invalidateSize(); }, 200); }
        return;
      }
      if (b.hasAttribute('data-ics')) { var e = events.filter(function (x) { return x.id === b.getAttribute('data-ics'); })[0]; if (e) ics(e); return; }
      if (b.hasAttribute('data-pin')) {
        var id = b.getAttribute('data-pin');
        if (window.matchMedia('(max-width: 999px)').matches) root.querySelector('.ffe-switch [data-view=map]').click();
        initMap();
        var go = function () { var m = markers[id]; if (!m) return; map.setView(m.getLatLng(), 14); m.openPopup(); $('.ffe-mapwrap').scrollIntoView({ behavior: 'smooth', block: 'center' }); };
        if (map) go(); else setTimeout(go, 1200);
        return;
      }
      if (b.classList.contains('ffe-near')) {
        if (!navigator.geolocation) return;
        b.classList.add('loading');
        navigator.geolocation.getCurrentPosition(function (p) {
          b.classList.remove('loading'); b.classList.add('on');
          state.pos = [p.coords.latitude, p.coords.longitude];
          events.forEach(function (e) {
            if (e.lat == null) return;
            var R = 6371, dLat = (e.lat - state.pos[0]) * Math.PI / 180, dLng = (e.lng - state.pos[1]) * Math.PI / 180;
            var x = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(state.pos[0] * Math.PI / 180) * Math.cos(e.lat * Math.PI / 180) * Math.sin(dLng / 2) * Math.sin(dLng / 2);
            e.dist = R * 2 * Math.atan2(Math.sqrt(x), Math.sqrt(1 - x));
          });
          renderList();
          if (map) { map.setView(state.pos, 10); L.circleMarker(state.pos, { radius: 8, color: '#fff', weight: 3, fillColor: '#1a73e8', fillOpacity: 1 }).addTo(map).bindTooltip('Sei qui'); }
        }, function () { b.classList.remove('loading'); alert('Non riesco a leggere la tua posizione. Controlla i permessi del browser.'); }, { timeout: 10000 });
      }
    });
    var qt;
    $('.ffe-search input').addEventListener('input', function (ev) { clearTimeout(qt); qt = setTimeout(function () { state.q = ev.target.value.trim(); renderList(); }, 200); });
    $('.ffe-eta').addEventListener('change', function (ev) { state.eta = ev.target.value; renderList(); });

    renderFeat();
    renderFFNext();
    renderPast();
    renderList();
    setInterval(function () { // aggiorna "tra X giorni / in corso" e toglie gli eventi appena terminati
      var n = new Date(), before = events.length;
      events = events.filter(function (e) { if (e.end < n && e.ff) pastFF.unshift(e); return e.end >= n; });
      if (events.length !== before) { renderFeat(); renderFFNext(); renderPast(); }
      renderList();
    }, 60000);
  }
  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', boot); else boot();
})();
/* ===== FF EVENTI v1 (fine) ===== */
Gli strumenti solari di Piazza Cavalli – incontro guidato

Gli strumenti solari di Piazza Cavalli – incontro guidato

Mariano Aliberti Eventi 15 Ottobre 2026

L'ing. Mario Gioia guida alla scoperta di meridiana, orologio solare e calendario progettati da Gian Francesco Barattieri: come funzionano, la loro storia e il loro valore scientifico.

Leggi tutto: Gli strumenti solari di Piazza Cavalli – incontro guidato
&quot;Liberi di esporre&quot; – mostra fotografica collettiva

"Liberi di esporre" – mostra fotografica collettiva

Mariano Aliberti Eventi 15 Ottobre 2026

Seconda edizione: 35 fotografie di 21 autori italiani e stranieri, senza tema fisso. Ultimo weekend: sabato 17 e domenica 18 ottobre, 10–12 e 15–18; sabato pomeriggio evento fotografico.

Leggi tutto: "Liberi di esporre" – mostra fotografica collettiva
Mostra fotografica &quot;Vigolzone: dai campi alle fabbriche&quot;

Mostra fotografica "Vigolzone: dai campi alle fabbriche"

Mariano Aliberti Eventi 15 Ottobre 2026

Mostra fotografica sulla trasformazione di Vigolzone dal mondo agricolo alle prime fabbriche. Visitabile fino al 1° novembre.

Leggi tutto: Mostra fotografica "Vigolzone: dai campi alle fabbriche"
Mostra &quot;Pertini 100 – Sandro Pertini attraverso gli occhi dei ragazzi&quot;

Mostra "Pertini 100 – Sandro Pertini attraverso gli occhi dei ragazzi"

Mariano Aliberti Eventi 15 Ottobre 2026

Mostra dei lavori degli alunni dell'IC "Parini" dedicati a Sandro Pertini, nata dall'incontro con lo scrittore Luigi Garlando. Aperta fino al 25 ottobre negli orari della biblioteca.

Leggi tutto: Mostra "Pertini 100 – Sandro Pertini attraverso gli occhi dei ragazzi"
&quot;Di felci di faggi di dune&quot; – mostra fotografica di Luca Capuano

"Di felci di faggi di dune" – mostra fotografica di Luca Capuano

Mariano Aliberti Eventi 15 Ottobre 2026

23 fotografie dedicate al patrimonio paesaggistico tutelato dell'Emilia-Romagna. Visitabile fino al 22 ottobre, orario 10–18.

Leggi tutto: "Di felci di faggi di dune" – mostra fotografica di Luca Capuano
&quot;Siam figli dell'aria, siam figli dell'onda&quot; – mostra sulle colonie estive

"Siam figli dell'aria, siam figli dell'onda" – mostra sulle colonie estive

Mariano Aliberti Eventi 15 Ottobre 2026

Mostra sulle colonie estive per bambini in epoca fascista, in Romagna e nel Piacentino. Visite guidate su prenotazione dal lunedì al venerdì, 9–14. Chiude sabato 17 ottobre.

Leggi tutto: "Siam figli dell'aria, siam figli dell'onda" – mostra sulle colonie estive
Spooky Season – Tributo all'autunno (mostra)

Spooky Season – Tributo all'autunno (mostra)

Mariano Aliberti Eventi 15 Ottobre 2026

Mostra dedicata all'autunno e alle sue tradizioni, con fotografie, dipinti e sculture di Riccardo Biavati e una sezione sugli scritti di Carmen Artocchini. Ultimi giorni: chiude sabato 17 ottobre. Orario 15.30–19.

Leggi tutto: Spooky Season – Tributo all'autunno (mostra)
Presentazione del libro &quot;Se bastasse l'amore. Una storia vera di anoressia e speranza&quot;

Presentazione del libro "Se bastasse l'amore. Una storia vera di anoressia e speranza"

Mariano Aliberti Eventi 15 Ottobre 2026

Presentazione di una storia vera sui disturbi della nutrizione e dell'alimentazione, che in Italia riguardano oltre tre milioni di persone e colpiscono sempre più i giovani. Un'occasione di ascolto per genitori ed educatori.

Leggi tutto: Presentazione del libro "Se bastasse l'amore. Una storia vera di anoressia e speranza"
Presentazione del libro &quot;Guerre in codice. Come le intelligenze artificiali resettano la democrazia&quot;

Presentazione del libro "Guerre in codice. Come le intelligenze artificiali resettano la democrazia"

Mariano Aliberti Eventi 15 Ottobre 2026

Chi controlla gli algoritmi e quale potere esercitano sulle nostre vite? Presentazione di un libro su come l'intelligenza artificiale cambia informazione, conflitti e democrazia.

Leggi tutto: Presentazione del libro "Guerre in codice. Come le intelligenze artificiali resettano la democrazia"
Presentazione dell'opera &quot;(Cercare) Raffaello in carcere&quot;

Presentazione dell'opera "(Cercare) Raffaello in carcere"

Mariano Aliberti Eventi 15 Ottobre 2026

Inaugurazione e presentazione dell'opera "(Cercare) Raffaello in carcere" nella Sala degli Arazzi della Galleria Alberoni.

Leggi tutto: Presentazione dell'opera "(Cercare) Raffaello in carcere"
Attraverso il Novecento – &quot;Parigi e Vienna all'inizio del Novecento&quot; con Lucia Pini

Attraverso il Novecento – "Parigi e Vienna all'inizio del Novecento" con Lucia Pini

Mariano Aliberti Eventi 15 Ottobre 2026

Primo dei dieci incontri storico-artistici del giovedì tenuti dalla direttrice Lucia Pini (fino al 22 aprile 2027): si parte dalla cultura di Parigi e Vienna all'inizio del Novecento. Durata un'ora.

Leggi tutto: Attraverso il Novecento – "Parigi e Vienna all'inizio del Novecento" con Lucia Pini
Crescere attraverso lo sport: seminario CONI sull'attività multidisciplinare

Crescere attraverso lo sport: seminario CONI sull'attività multidisciplinare

Mariano Aliberti Eventi 15 Ottobre 2026

Incontro con Fabio Bovo e Giovanni Tieghi sul valore della multidisciplinarità e sullo sviluppo motorio nello sport giovanile, fino alla scuola secondaria di primo grado. Per genitori, allenatori e cittadini.

Leggi tutto: Crescere attraverso lo sport: seminario CONI sull'attività multidisciplinare
Iceberg, giocare per perdere – Non è gioco se è d'azzardo

Iceberg, giocare per perdere – Non è gioco se è d'azzardo

Mariano Aliberti Eventi 15 Ottobre 2026

Serata di sensibilizzazione sul gioco d'azzardo patologico: segnali d'allarme, meccanismi psicologici e dove chiedere aiuto. Intervengono Maurizio Avanzi (AUSL), le psicologhe Monica Francani e Maria Rizzi, Fausta Fagnoni e la giornalista Nicoletta Marenghi.

Leggi tutto: Iceberg, giocare per perdere – Non è gioco se è d'azzardo
Fattore Famiglia alla 11ª Festa della Zucca di Muradolo! 🎃

Fattore Famiglia alla 11ª Festa della Zucca di Muradolo! 🎃

Redazione Eventi 19 Agosto 2026
  • #festadellazucca #piacenza #bambini

C'è un profumo inconfondibile che annuncia la fine dell'estate a Caorso: quello della zucca! Dal 21 al 24 agosto torna la 11ª Festa della Zucca presso il Circolo Anspi di Muradolo, e quest'anno ci saremo anche noi.

Quattro serate di gusto e musica

Gli stand gastronomici aprono tutte le sere dalle 19:00 (domenica anche a pranzo), con posti garantiti al coperto in caso di maltempo. Il menù è un trionfo di zucca in tutte le sue forme: gnocchi, tortelli, lasagne con taleggio e salsiccia, tortino con fonduta di gorgonzola, zucca fritta e alla piastra, senza dimenticare i pisarei e fasö e la torta fritta con salumi.

E ogni sera un motivo in più per restare:

Programma delle Serate

  • Venerdì 21 agosto: Apertura stand alle 19:00; ore 21:00 concerto live dei DejaVu e DJ set con DJ Shell.

  • Sabato 22 agosto: Apertura stand alle 19:00; serata musica anni '90 con i Cani Sciolti e tributo a Max Pezzali, a seguire DJ set.

  • Domenica 23 agosto: Raduno Fiat 500 d'epoca e apertura straordinaria degli stand a pranzo (ore 12:00); la sera piano bar con i Fuoriservizio, concerto dei Cisco & The Cockerels e DJ set.

  • Lunedì 24 agosto: Apertura stand alle 19:00; serata karaoke con Gianluca "Zanza" Capra e chiusura musicale.

Specialità Gastronomiche

  • Primi: Tortelli di zucca fatti a mano, gnocchi di zucca, lasagna zucca, taleggio e salsiccia, cannelloni zucca e gorgonzola, pisarei e fasö.

  • Secondi e sfizi: Zucca fritta, tortino di zucca con fonduta di gorgonzola, spiedini e grigliata di carne.

Informazioni e Contatti

    • Dove: Circolo ANSPI Muradolo – Strada Provinciale Muradolo 15, Caorso (PC).

    • Orari: Stand gastronomici aperti dalle 19:00 (domenica anche a pranzo). Posti al coperto in caso di maltempo.

    • Contatti: 333 4094514 | Questo indirizzo email è protetto dagli spambots. È necessario abilitare JavaScript per vederlo.

Il nostro stand: api, colori e sorrisi

Fattore Famiglia vi aspetta con un angolo pensato per i più piccoli e per tutta la famiglia:

  • Truccabimbi e palloncini

    per trasformare ogni bambino in un piccolo protagonista della festa
  • Miele e prodotti di cera d'api

    , genuini e a chilometro zero e l'acquisto aiuta a sostenere le spese dell'associazione
  • Giochi semplici e divertenti

    per far scoprire ai bambini il mondo affascinante delle api e della loro cera

Vantaggi per i tesserati

Chi ha la tessera Fattore Famiglia ha diritto allo sconto del 5% su tutti i nostri prodotti, che sale al 10% per acquisti superiori a 50 euro. Non sei ancora tesserato? Passa a trovarci allo stand: ti spieghiamo come entrare nella nostra grande famiglia.

Vi aspettiamo a Muradolo per festeggiare insieme la regina dell'autunno! 🎃🐝

Pic-Nic vista Eclissi Solare

Pic-Nic vista Eclissi Solare

Sara Bucaria Eventi 09 Agosto 2026
  • Data e ora di inizio: 12-08-2026 10:39

Unisciti a noi per un insolito pic-nic. (Posti limitati - MAX 20 PERSONE)

Leggi tutto: Pic-Nic vista Eclissi Solare
La Vacanza Estiva di Fattore Famiglia sarà a NUMANA

La Vacanza Estiva di Fattore Famiglia sarà a NUMANA

Mariano Aliberti Eventi 13 Maggio 2026

Dopo il grande successo della vacanza invernale — che ha visto oltre 20 famiglie di Fattore Famiglia condividere giorni indimenticabili in Valcamonica — tantissimi di voi ci hanno chiesto di ripetere l'esperienza anche d'estate! ☀️

In un periodo in cui la crisi energetica rende meno sicure e più complicate le destinazioni raggiungibili in nave o aereo, abbiamo scelto di puntare su una meta vicina, comoda e di grande fascino, ideale per tutti: il Centro Vacanze De Angelis di Numana, perla della Riviera del Conero 💙

Leggi tutto: La Vacanza Estiva di Fattore Famiglia sarà a NUMANA
FAMIGLIA SENZA FRONTIERE 01 Aprile 2026

Famiglia senza frontiere

Fabio Pedrocca Eventi 01 Aprile 2026
  • Data e ora di inizio: 09-05-2026 09:35
  • Download volantino.pdf

Sabato 9 maggio 2026, dalle 14:30 alle 19:00, all'Arena Daturi di Piacenza: truccabimbi e gonfiabili per tutti i bambini.

Ti aspettiamo allo stand di Fattore Famiglia!

Il primo sportello digitale dedicato alle famiglie

Il primo sportello digitale dedicato alle famiglie
Un click che informa, supporta e semplifica
Associati
Image

Associazione

Chi siamo
Eventi
Rete FF
Convenzioni
Contatti

Aree Tematiche

  • Civis Family
  • Smart Family
  • Lex Family
  • F.A.R.M.A.
  • Sani Family
  • Fisco Family
Copyright Fattore Famiglia © 2026 - Fattore Famiglia APS , Via Galileo Galilei 15h — 29122 Piacenza (PC) ,Tel. 351 436 6266 Email info@fattorefamiglia.it
  • Chi siamo
  • Eventi
  • Rete FF
    • Piacenza
    • Italia
  • Aree Tematiche
    • Civis Family
    • Smart Family
    • Lex Family
    • F.A.R.M.A.
    • Sani Family
    • Fisco Family
  • Convenzioni
  • Contatti