{"id":231,"date":"2026-06-23T08:18:42","date_gmt":"2026-06-23T08:18:42","guid":{"rendered":"https:\/\/chill-lab.eu\/?page_id=231"},"modified":"2026-06-25T14:32:06","modified_gmt":"2026-06-25T14:32:06","slug":"environmental-rights","status":"publish","type":"page","link":"https:\/\/chill-lab.eu\/it\/environmental-rights\/","title":{"rendered":"Environmental Rights"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"231\" class=\"elementor elementor-231\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5de8a46 e-flex e-con-boxed e-con e-parent\" data-id=\"5de8a46\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-be5fc1d elementor-widget elementor-widget-html\" data-id=\"be5fc1d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<section \n  id=\"chill-environmental-atlas\"\n  class=\"chill-env-page\"\n  data-post-type=\"posts\"\n  data-taxonomy=\"area_tematica\"\n  data-term=\"diritti-ambientali\"\n>\n  <div class=\"chill-env-hero\">\n    <p class=\"chill-eyebrow\">CHILL Atlas \u00b7 Focus tematico<\/p>\n    <h1>Diritti ambientali<\/h1>\n    <p class=\"chill-hero-text\">\n      Questa pagina raccoglie i casi in cui danno ambientale, crisi climatica, vulnerabilit\u00e0 ecologica\n      e potere pubblico si intrecciano con i diritti fondamentali, l\u2019accesso alla giustizia,\n      la partecipazione democratica e il possibile effetto dissuasivo sulla libert\u00e0 di espressione,\n      associazione e protesta.\n    <\/p>\n\n    <div class=\"chill-hero-tags\">\n      <span>Protesta climatica<\/span>\n      <span>SLAPP ambientali<\/span>\n      <span>Obblighi positivi<\/span>\n      <span>Accesso alla giustizia<\/span>\n      <span>Difensori ambientali<\/span>\n    <\/div>\n  <\/div>\n\n  <div class=\"chill-env-insights\">\n    <article>\n      <span>01<\/span>\n      <h3>Ambiente e libert\u00e0 democratiche<\/h3>\n      <p>\n        I conflitti ambientali riguardano spesso attivisti, comunit\u00e0 locali, ONG, giornalisti\n        e ricercatori che contestano decisioni pubbliche o private ad alto impatto ecologico.\n      <\/p>\n    <\/article>\n\n    <article>\n      <span>02<\/span>\n      <h3>Misure che possono dissuadere<\/h3>\n      <p>\n        Procedimenti penali, sanzioni amministrative, azioni risarcitorie, SLAPP, arresti,\n        divieti di manifestazione e sorveglianza possono produrre effetti intimidatori.\n      <\/p>\n    <\/article>\n\n    <article>\n      <span>03<\/span>\n      <h3>Diritti e strumenti coinvolti<\/h3>\n      <p>\n        I casi possono richiamare la CEDU, la Carta dei diritti fondamentali dell\u2019UE,\n        la Convenzione di Aarhus, il Patto sui diritti civili e politici e altri strumenti.\n      <\/p>\n    <\/article>\n  <\/div>\n\n  <div class=\"chill-env-dashboard\">\n    <div class=\"chill-stat-card\">\n      <span class=\"chill-stat-number\" id=\"chill-total-cases\">\u2014<\/span>\n      <span class=\"chill-stat-label\">Casi raccolti<\/span>\n    <\/div>\n\n    <div class=\"chill-stat-card\">\n      <span class=\"chill-stat-number\" id=\"chill-total-countries\">\u2014<\/span>\n      <span class=\"chill-stat-label\">Paesi \/ giurisdizioni<\/span>\n    <\/div>\n\n    <div class=\"chill-stat-card\">\n      <span class=\"chill-stat-number\" id=\"chill-latest-year\">\u2014<\/span>\n      <span class=\"chill-stat-label\">Anno pi\u00f9 recente<\/span>\n    <\/div>\n\n    <div class=\"chill-stat-card\">\n      <span class=\"chill-stat-number\" id=\"chill-repressive-measures\">\u2014<\/span>\n      <span class=\"chill-stat-label\">Misure dissuasive<\/span>\n    <\/div>\n  <\/div>\n\n  <div class=\"chill-env-research-note\">\n    <p class=\"chill-eyebrow\">Chiave di lettura<\/p>\n    <h2>Perch\u00e9 questi casi sono rilevanti<\/h2>\n    <p>\n      I casi raccolti in questa sezione sono selezionati automaticamente dal CHILL Atlas generale\n      attraverso l\u2019area tematica <strong>Diritti ambientali<\/strong>. La pagina non \u00e8 un archivio separato:\n      rilegge i casi ambientali dal punto di vista del chilling effect, evidenziando misure,\n      diritti coinvolti, attori, fonti ed esiti.\n    <\/p>\n  <\/div>\n\n  <div class=\"chill-env-toolbar\">\n    <div>\n      <h2>Casi dal CHILL Atlas<\/h2>\n      <p class=\"chill-atlas-status\">Caricamento dei casi...<\/p>\n    <\/div>\n\n    <div class=\"chill-env-filters\">\n      <input id=\"chill-case-search\" type=\"search\" placeholder=\"Cerca tra i casi...\" \/>\n\n      <select id=\"chill-status-filter\">\n        <option value=\"\">Tutti gli stati<\/option>\n      <\/select>\n\n      <select id=\"chill-measure-filter\">\n        <option value=\"\">Tutte le misure<\/option>\n      <\/select>\n\n      <select id=\"chill-right-filter\">\n        <option value=\"\">Tutti i diritti<\/option>\n      <\/select>\n    <\/div>\n  <\/div>\n\n  <div class=\"chill-atlas-grid\"><\/div>\n\n  <div class=\"chill-env-empty\" style=\"display:none;\">\n    Nessun caso corrisponde ai filtri selezionati.\n  <\/div>\n<\/section>\n\n<style>\n  .chill-env-page {\n    width: 100%;\n    padding: 40px 0 80px 0;\n    color: #eaf2ff;\n  }\n\n  .chill-env-page * {\n    box-sizing: border-box;\n  }\n\n  .chill-env-hero {\n    max-width: 1050px;\n    padding: 56px 0 36px 0;\n  }\n\n  .chill-eyebrow {\n    margin: 0 0 12px 0;\n    text-transform: uppercase;\n    letter-spacing: 0.12em;\n    font-size: 13px;\n    font-weight: 800;\n    color: #6ee7df;\n  }\n\n  .chill-env-hero h1 {\n    margin: 0 0 20px 0;\n    font-size: clamp(48px, 7vw, 92px);\n    line-height: 0.95;\n    color: #ffffff;\n  }\n\n  .chill-hero-text {\n    max-width: 900px;\n    margin: 0;\n    font-size: clamp(19px, 2vw, 26px);\n    line-height: 1.55;\n    color: #b9c7dc;\n  }\n\n  .chill-hero-tags {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 10px;\n    margin-top: 28px;\n  }\n\n  .chill-hero-tags span {\n    border: 1px solid rgba(110, 231, 223, 0.42);\n    background: rgba(110, 231, 223, 0.08);\n    color: #c9fffb;\n    border-radius: 999px;\n    padding: 8px 13px;\n    font-size: 14px;\n    font-weight: 700;\n  }\n\n  .chill-env-insights {\n    display: grid;\n    grid-template-columns: repeat(3, minmax(0, 1fr));\n    gap: 18px;\n    margin: 34px 0;\n  }\n\n  .chill-env-insights article {\n    border: 1px solid rgba(255, 255, 255, 0.12);\n    background: linear-gradient(180deg, rgba(255,255,255,0.075), rgba(255,255,255,0.035));\n    border-radius: 22px;\n    padding: 24px;\n    min-height: 230px;\n  }\n\n  .chill-env-insights article span {\n    display: inline-flex;\n    width: 34px;\n    height: 34px;\n    align-items: center;\n    justify-content: center;\n    border-radius: 50%;\n    background: #6ee7df;\n    color: #07111f;\n    font-weight: 900;\n    margin-bottom: 20px;\n  }\n\n  .chill-env-insights h3 {\n    color: #ffffff;\n    margin: 0 0 12px 0;\n    font-size: 22px;\n    line-height: 1.25;\n  }\n\n  .chill-env-insights p {\n    color: #aebdd2;\n    margin: 0;\n    font-size: 15px;\n    line-height: 1.65;\n  }\n\n  .chill-env-dashboard {\n    display: grid;\n    grid-template-columns: repeat(4, minmax(0, 1fr));\n    gap: 18px;\n    margin: 34px 0 50px 0;\n  }\n\n  .chill-stat-card {\n    border-radius: 22px;\n    padding: 26px;\n    background: #ffffff;\n    color: #07111f;\n  }\n\n  .chill-stat-number {\n    display: block;\n    font-size: 42px;\n    line-height: 1;\n    font-weight: 900;\n    color: #0b1b31;\n  }\n\n  .chill-stat-label {\n    display: block;\n    margin-top: 8px;\n    font-size: 13px;\n    font-weight: 800;\n    text-transform: uppercase;\n    letter-spacing: 0.08em;\n    color: #526178;\n  }\n\n  .chill-env-research-note {\n    max-width: 980px;\n    border-left: 4px solid #6ee7df;\n    padding: 4px 0 4px 24px;\n    margin: 52px 0;\n  }\n\n  .chill-env-research-note h2 {\n    color: #ffffff;\n    margin: 0 0 14px 0;\n    font-size: clamp(30px, 4vw, 48px);\n    line-height: 1.05;\n  }\n\n  .chill-env-research-note p {\n    color: #b9c7dc;\n    margin: 0;\n    font-size: 18px;\n    line-height: 1.7;\n  }\n\n  .chill-env-toolbar {\n    display: flex;\n    align-items: flex-end;\n    justify-content: space-between;\n    gap: 24px;\n    margin: 40px 0 24px 0;\n  }\n\n  .chill-env-toolbar h2 {\n    margin: 0 0 6px 0;\n    color: #ffffff;\n    font-size: 34px;\n  }\n\n  .chill-atlas-status {\n    margin: 0;\n    color: #8fa0b8;\n    font-size: 15px;\n  }\n\n  .chill-env-filters {\n    display: flex;\n    flex-wrap: wrap;\n    justify-content: flex-end;\n    gap: 10px;\n    max-width: 720px;\n  }\n\n  .chill-env-filters input,\n  .chill-env-filters select {\n    width: 220px;\n    border: 1px solid rgba(255,255,255,0.18);\n    background: rgba(255,255,255,0.08);\n    color: #ffffff;\n    border-radius: 999px;\n    padding: 13px 16px;\n    outline: none;\n    font-size: 14px;\n  }\n\n  .chill-env-filters input::placeholder {\n    color: #8fa0b8;\n  }\n\n  .chill-env-filters select option {\n    color: #07111f;\n  }\n\n  .chill-atlas-grid {\n    display: grid;\n    grid-template-columns: repeat(3, minmax(0, 1fr));\n    gap: 24px;\n  }\n\n  .chill-case-card {\n    position: relative;\n    overflow: hidden;\n    border: 1px solid rgba(255,255,255,0.13);\n    border-radius: 24px;\n    padding: 26px;\n    background: linear-gradient(180deg, rgba(255,255,255,0.105), rgba(255,255,255,0.04));\n    min-height: 420px;\n    display: flex;\n    flex-direction: column;\n    gap: 16px;\n    transition: transform 0.22s ease, border-color 0.22s ease, background 0.22s ease;\n  }\n\n  .chill-case-card::before {\n    content: \"\";\n    position: absolute;\n    right: -60px;\n    top: -60px;\n    width: 150px;\n    height: 150px;\n    border-radius: 50%;\n    background: rgba(110, 231, 223, 0.13);\n  }\n\n  .chill-case-card:hover {\n    transform: translateY(-4px);\n    border-color: rgba(110, 231, 223, 0.48);\n    background: linear-gradient(180deg, rgba(255,255,255,0.14), rgba(255,255,255,0.055));\n  }\n\n  .chill-case-card > * {\n    position: relative;\n    z-index: 1;\n  }\n\n  .chill-case-meta,\n  .chill-case-chips {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 8px;\n  }\n\n  .chill-case-meta span {\n    border-radius: 999px;\n    padding: 6px 10px;\n    background: rgba(110, 231, 223, 0.12);\n    color: #c9fffb;\n    font-size: 12px;\n    font-weight: 800;\n  }\n\n  .chill-case-chips span {\n    border-radius: 999px;\n    padding: 6px 10px;\n    background: rgba(255,255,255,0.08);\n    color: #d9e5f7;\n    font-size: 12px;\n    font-weight: 700;\n  }\n\n  .chill-case-card h3 {\n    color: #ffffff !important;\n    margin: 0;\n    font-size: 24px;\n    line-height: 1.2;\n  }\n\n  .chill-case-section {\n    margin: 0;\n  }\n\n  .chill-case-label {\n    display: block;\n    margin-bottom: 5px;\n    color: #6ee7df;\n    font-size: 12px;\n    text-transform: uppercase;\n    letter-spacing: 0.08em;\n    font-weight: 900;\n  }\n\n  .chill-case-text {\n    color: #b9c7dc;\n    font-size: 15px;\n    line-height: 1.62;\n    margin: 0;\n  }\n\n  .chill-case-outcome {\n    border-left: 3px solid rgba(110, 231, 223, 0.75);\n    padding-left: 12px;\n  }\n\n  .chill-case-actions {\n    margin-top: auto;\n    display: flex;\n    gap: 14px;\n    align-items: center;\n    flex-wrap: wrap;\n  }\n\n  .chill-case-actions a {\n    color: #6ee7df !important;\n    text-decoration: none;\n    font-weight: 900;\n    font-size: 14px;\n    border-bottom: 2px solid currentColor;\n  }\n\n  .chill-env-empty {\n    margin-top: 24px;\n    color: #b9c7dc;\n    font-size: 16px;\n  }\n\n  @media (max-width: 1180px) {\n    .chill-env-dashboard {\n      grid-template-columns: repeat(2, minmax(0, 1fr));\n    }\n\n    .chill-atlas-grid,\n    .chill-env-insights {\n      grid-template-columns: repeat(2, minmax(0, 1fr));\n    }\n\n    .chill-env-toolbar {\n      align-items: flex-start;\n      flex-direction: column;\n    }\n\n    .chill-env-filters {\n      justify-content: flex-start;\n    }\n  }\n\n  @media (max-width: 700px) {\n    .chill-env-dashboard,\n    .chill-atlas-grid,\n    .chill-env-insights {\n      grid-template-columns: 1fr;\n    }\n\n    .chill-env-filters input,\n    .chill-env-filters select {\n      width: 100%;\n    }\n\n    .chill-env-hero {\n      padding-top: 34px;\n    }\n\n    .chill-case-card {\n      min-height: auto;\n    }\n  }\n<\/style>\n\n<script>\n(function () {\n  const root = document.getElementById(\"chill-environmental-atlas\");\n  if (!root) return;\n\n  const config = {\n    postType: root.dataset.postType || \"posts\",\n    taxonomy: root.dataset.taxonomy || \"area_tematica\",\n    termSlug: root.dataset.term || \"diritti-ambientali\",\n    countryTaxonomy: \"paese\",\n    perPage: 100\n  };\n\n  const fields = {\n    paese: \"paese\",\n    anno: \"anno\",\n    attori: \"attori\",\n    fonte: \"fonte\",\n    stato: \"stato_caso\",\n    tipoMisura: \"tipo_misura\",\n    dirittiCoinvolti: \"diritti_coinvolti\",\n    esito: \"esito\",\n    sintesi: \"sintesi\",\n    dirittiCategoria: \"diritti_coinvolti_categoria\"\n  };\n\n  const apiBase = window.location.origin + \"\/wp-json\/wp\/v2\";\n\n  const statusEl = root.querySelector(\".chill-atlas-status\");\n  const gridEl = root.querySelector(\".chill-atlas-grid\");\n  const emptyEl = root.querySelector(\".chill-env-empty\");\n\n  const searchInput = root.querySelector(\"#chill-case-search\");\n  const statusFilter = root.querySelector(\"#chill-status-filter\");\n  const measureFilter = root.querySelector(\"#chill-measure-filter\");\n  const rightFilter = root.querySelector(\"#chill-right-filter\");\n\n  const totalCasesEl = root.querySelector(\"#chill-total-cases\");\n  const totalCountriesEl = root.querySelector(\"#chill-total-countries\");\n  const latestYearEl = root.querySelector(\"#chill-latest-year\");\n  const repressiveMeasuresEl = root.querySelector(\"#chill-repressive-measures\");\n\n  let allPosts = [];\n\n  function stripHtml(html) {\n    const div = document.createElement(\"div\");\n    div.innerHTML = html || \"\";\n    return (div.textContent || div.innerText || \"\").trim();\n  }\n\n  function escapeHtml(value) {\n    return String(value || \"\").replace(\/[&<>\"']\/g, function (match) {\n      return {\n        \"&\": \"&amp;\",\n        \"<\": \"&lt;\",\n        \">\": \"&gt;\",\n        '\"': \"&quot;\",\n        \"'\": \"&#039;\"\n      }[match];\n    });\n  }\n\n  function escapeAttr(value) {\n    return escapeHtml(value).replace(\/`\/g, \"&#096;\");\n  }\n\n  function normalizeValue(value) {\n    if (value === null || value === undefined || value === false) return \"\";\n\n    if (Array.isArray(value)) {\n      return value\n        .map(normalizeValue)\n        .filter(Boolean)\n        .join(\", \");\n    }\n\n    if (typeof value === \"object\") {\n      if (value.label && value.value) return stripHtml(value.label);\n      if (value.name) return stripHtml(value.name);\n      if (value.label) return stripHtml(value.label);\n      if (value.value) return stripHtml(value.value);\n      if (value.post_title) return stripHtml(value.post_title);\n      if (value.title && value.title.rendered) return stripHtml(value.title.rendered);\n      return \"\";\n    }\n\n    return stripHtml(String(value));\n  }\n\n  function normalizeList(value) {\n    if (value === null || value === undefined || value === false) return [];\n\n    if (Array.isArray(value)) {\n      return value\n        .map(normalizeList)\n        .flat()\n        .filter(Boolean);\n    }\n\n    if (typeof value === \"object\") {\n      const normalized = normalizeValue(value);\n      return normalized ? [normalized] : [];\n    }\n\n    const text = stripHtml(String(value));\n    return text ? [text] : [];\n  }\n\n  function getAcf(post) {\n    return post.acf || {};\n  }\n\n  function getEmbeddedTerms(post, taxonomy) {\n    const embedded = post._embedded && post._embedded[\"wp:term\"];\n    if (!embedded || !Array.isArray(embedded)) return [];\n\n    return embedded\n      .flat()\n      .filter(function (term) {\n        return term && term.taxonomy === taxonomy;\n      })\n      .map(function (term) {\n        return term.name;\n      })\n      .filter(Boolean);\n  }\n\n  function getFieldText(post, fieldName) {\n    const acf = getAcf(post);\n    return normalizeValue(acf[fieldName]);\n  }\n\n  function getFieldList(post, fieldName) {\n    const acf = getAcf(post);\n    return normalizeList(acf[fieldName]);\n  }\n\n  async function fetchJson(url) {\n    const response = await fetch(url, {\n      headers: { \"Accept\": \"application\/json\" }\n    });\n\n    if (!response.ok) {\n      throw new Error(\"Errore REST API: \" + response.status + \" \" + response.statusText);\n    }\n\n    return response.json();\n  }\n\n  async function fetchAllPosts(baseUrl) {\n    let page = 1;\n    let totalPages = 1;\n    let results = [];\n\n    do {\n      const url = new URL(baseUrl.toString());\n      url.searchParams.set(\"page\", page);\n\n      const response = await fetch(url.toString(), {\n        headers: { \"Accept\": \"application\/json\" }\n      });\n\n      if (!response.ok) {\n        throw new Error(\"Errore REST API posts: \" + response.status + \" \" + response.statusText);\n      }\n\n      totalPages = parseInt(response.headers.get(\"X-WP-TotalPages\") || \"1\", 10);\n      const data = await response.json();\n      results = results.concat(data);\n      page++;\n    } while (page <= totalPages);\n\n    return results;\n  }\n\n  function getPostData(post) {\n    const title = stripHtml(post.title && post.title.rendered ? post.title.rendered : \"Caso senza titolo\");\n    const link = post.link || \"#\";\n\n    const paeseFromAcf = getFieldText(post, fields.paese);\n    const paeseFromTax = getEmbeddedTerms(post, config.countryTaxonomy).join(\", \");\n    const paese = paeseFromAcf || paeseFromTax;\n\n    const anno = getFieldText(post, fields.anno);\n    const attori = getFieldText(post, fields.attori);\n    const fonte = getFieldText(post, fields.fonte);\n    const stato = getFieldText(post, fields.stato);\n\n    const tipoMisura = getFieldList(post, fields.tipoMisura);\n    const dirittiCategoria = getFieldList(post, fields.dirittiCategoria);\n\n    const dirittiCoinvolti = getFieldText(post, fields.dirittiCoinvolti);\n    const esito = getFieldText(post, fields.esito);\n\n    const sintesi =\n      getFieldText(post, fields.sintesi) ||\n      stripHtml(post.excerpt && post.excerpt.rendered ? post.excerpt.rendered : \"\");\n\n    const content = stripHtml(post.content && post.content.rendered ? post.content.rendered : \"\");\n\n    return {\n      id: post.id,\n      title,\n      link,\n      paese,\n      anno,\n      attori,\n      fonte,\n      stato,\n      tipoMisura,\n      dirittiCategoria,\n      dirittiCoinvolti,\n      esito,\n      sintesi,\n      content,\n      searchText: [\n        title,\n        paese,\n        anno,\n        attori,\n        fonte,\n        stato,\n        tipoMisura.join(\" \"),\n        dirittiCategoria.join(\" \"),\n        dirittiCoinvolti,\n        esito,\n        sintesi,\n        content\n      ].join(\" \").toLowerCase()\n    };\n  }\n\n  function limitText(text, maxLength) {\n    if (!text) return \"\";\n    if (text.length <= maxLength) return text;\n    return text.slice(0, maxLength).trim() + \"...\";\n  }\n\n  function renderChips(items, maxItems) {\n    const clean = (items || []).filter(Boolean);\n    if (!clean.length) return \"\";\n\n    const visible = clean.slice(0, maxItems || 4);\n    const remaining = clean.length - visible.length;\n\n    let html = visible\n      .map(function (item) {\n        return \"<span>\" + escapeHtml(item) + \"<\/span>\";\n      })\n      .join(\"\");\n\n    if (remaining > 0) {\n      html += \"<span>+\" + remaining + \"<\/span>\";\n    }\n\n    return \"<div class='chill-case-chips'>\" + html + \"<\/div>\";\n  }\n\n  function renderCard(post) {\n    const data = getPostData(post);\n\n    const metaItems = [data.paese, data.anno, data.stato].filter(Boolean);\n\n    const metaHtml = metaItems.length\n      ? \"<div class='chill-case-meta'>\" + metaItems.map(function (item) {\n          return \"<span>\" + escapeHtml(item) + \"<\/span>\";\n        }).join(\"\") + \"<\/div>\"\n      : \"\";\n\n    const measuresHtml = data.tipoMisura.length\n      ? \"<div class='chill-case-section'><span class='chill-case-label'>Tipo di misura<\/span>\" +\n        renderChips(data.tipoMisura, 4) +\n        \"<\/div>\"\n      : \"\";\n\n    const rightsCategoryHtml = data.dirittiCategoria.length\n      ? \"<div class='chill-case-section'><span class='chill-case-label'>Diritti \/ strumenti<\/span>\" +\n        renderChips(data.dirittiCategoria, 3) +\n        \"<\/div>\"\n      : \"\";\n\n    const actorsHtml = data.attori\n      ? \"<div class='chill-case-section'><span class='chill-case-label'>Attori<\/span><p class='chill-case-text'>\" +\n        escapeHtml(limitText(data.attori, 180)) +\n        \"<\/p><\/div>\"\n      : \"\";\n\n    const summaryHtml = data.sintesi\n      ? \"<div class='chill-case-section'><span class='chill-case-label'>Sintesi<\/span><p class='chill-case-text'>\" +\n        escapeHtml(limitText(data.sintesi, 430)) +\n        \"<\/p><\/div>\"\n      : \"<div class='chill-case-section'><span class='chill-case-label'>Sintesi<\/span><p class='chill-case-text'>Sintesi non ancora disponibile.<\/p><\/div>\";\n\n    const outcomeHtml = data.esito\n      ? \"<div class='chill-case-section chill-case-outcome'><span class='chill-case-label'>Esito<\/span><p class='chill-case-text'>\" +\n        escapeHtml(limitText(data.esito, 250)) +\n        \"<\/p><\/div>\"\n      : \"\";\n\n    const sourceHtml = data.fonte\n      ? \"<a href='\" + escapeAttr(data.fonte) + \"' target='_blank' rel='noopener noreferrer'>Fonte<\/a>\"\n      : \"\";\n\n    return `\n      <article class=\"chill-case-card\">\n        ${metaHtml}\n        <h3>${escapeHtml(data.title)}<\/h3>\n        ${measuresHtml}\n        ${rightsCategoryHtml}\n        ${actorsHtml}\n        ${summaryHtml}\n        ${outcomeHtml}\n        <div class=\"chill-case-actions\">\n          <a href=\"${escapeAttr(data.link)}\">Leggi il caso<\/a>\n          ${sourceHtml}\n        <\/div>\n      <\/article>\n    `;\n  }\n\n  function isPotentiallyRepressive(data) {\n    const text = data.tipoMisura.join(\" \").toLowerCase();\n\n    const keywords = [\n      \"slapp\",\n      \"procedimento penale\",\n      \"indagine penale\",\n      \"arresto\",\n      \"detenzione\",\n      \"custodia cautelare\",\n      \"sanzione\",\n      \"multa\",\n      \"ammenda\",\n      \"perquisizione\",\n      \"sequestro\",\n      \"sorveglianza\",\n      \"divieto di manifestazione\",\n      \"limitazione di assemblea\",\n      \"scioglimento di associazione\",\n      \"misura ambientale repressiva\",\n      \"misura contro protesta climatica\",\n      \"pressione istituzionale\",\n      \"pressione regolatoria\",\n      \"pressione economica\"\n    ];\n\n    return keywords.some(function (keyword) {\n      return text.indexOf(keyword) !== -1;\n    });\n  }\n\n  function updateStats(posts) {\n    const data = posts.map(getPostData);\n\n    const countries = new Set(\n      data.map(function (item) { return item.paese; }).filter(Boolean)\n    );\n\n    const years = data\n      .map(function (item) { return parseInt(item.anno, 10); })\n      .filter(function (year) { return !isNaN(year); });\n\n    const repressiveCount = data.filter(isPotentiallyRepressive).length;\n\n    totalCasesEl.textContent = posts.length;\n    totalCountriesEl.textContent = countries.size || \"\u2014\";\n    latestYearEl.textContent = years.length ? Math.max.apply(null, years) : \"\u2014\";\n    repressiveMeasuresEl.textContent = repressiveCount || \"\u2014\";\n  }\n\n  function populateSelect(selectEl, values, placeholder) {\n    if (!selectEl) return;\n\n    const currentValue = selectEl.value;\n\n    selectEl.innerHTML = \"\";\n    const defaultOption = document.createElement(\"option\");\n    defaultOption.value = \"\";\n    defaultOption.textContent = placeholder;\n    selectEl.appendChild(defaultOption);\n\n    Array.from(values)\n      .filter(Boolean)\n      .sort(function (a, b) {\n        return a.localeCompare(b, \"it\");\n      })\n      .forEach(function (value) {\n        const option = document.createElement(\"option\");\n        option.value = value;\n        option.textContent = value;\n        selectEl.appendChild(option);\n      });\n\n    selectEl.value = currentValue;\n  }\n\n  function setupFilters(posts) {\n    const statuses = new Set();\n    const measures = new Set();\n    const rights = new Set();\n\n    posts.forEach(function (post) {\n      const data = getPostData(post);\n\n      if (data.stato) statuses.add(data.stato);\n\n      data.tipoMisura.forEach(function (item) {\n        measures.add(item);\n      });\n\n      data.dirittiCategoria.forEach(function (item) {\n        rights.add(item);\n      });\n    });\n\n    populateSelect(statusFilter, statuses, \"Tutti gli stati\");\n    populateSelect(measureFilter, measures, \"Tutte le misure\");\n    populateSelect(rightFilter, rights, \"Tutti i diritti\");\n  }\n\n  function renderPosts(posts) {\n    gridEl.innerHTML = posts.map(renderCard).join(\"\");\n\n    emptyEl.style.display = posts.length ? \"none\" : \"block\";\n  }\n\n  function applyFilters() {\n    const query = (searchInput && searchInput.value ? searchInput.value : \"\").toLowerCase().trim();\n    const selectedStatus = statusFilter ? statusFilter.value : \"\";\n    const selectedMeasure = measureFilter ? measureFilter.value : \"\";\n    const selectedRight = rightFilter ? rightFilter.value : \"\";\n\n    const filtered = allPosts.filter(function (post) {\n      const data = getPostData(post);\n\n      const matchesSearch = !query || data.searchText.indexOf(query) !== -1;\n      const matchesStatus = !selectedStatus || data.stato === selectedStatus;\n      const matchesMeasure = !selectedMeasure || data.tipoMisura.indexOf(selectedMeasure) !== -1;\n      const matchesRight = !selectedRight || data.dirittiCategoria.indexOf(selectedRight) !== -1;\n\n      return matchesSearch && matchesStatus && matchesMeasure && matchesRight;\n    });\n\n    renderPosts(filtered);\n  }\n\n  async function init() {\n    try {\n      statusEl.textContent = \"Caricamento dei casi...\";\n\n      const termUrl =\n        apiBase +\n        \"\/\" +\n        encodeURIComponent(config.taxonomy) +\n        \"?slug=\" +\n        encodeURIComponent(config.termSlug);\n\n      const terms = await fetchJson(termUrl);\n\n      if (!terms || !terms.length) {\n        statusEl.innerHTML =\n          \"Nessuna area tematica trovata con slug: <strong>\" +\n          escapeHtml(config.termSlug) +\n          \"<\/strong>.\";\n        return;\n      }\n\n      const termId = terms[0].id;\n\n      const postsUrl = new URL(apiBase + \"\/\" + config.postType);\n      postsUrl.searchParams.set(config.taxonomy, termId);\n      postsUrl.searchParams.set(\"per_page\", config.perPage);\n      postsUrl.searchParams.set(\"orderby\", \"date\");\n      postsUrl.searchParams.set(\"order\", \"desc\");\n      postsUrl.searchParams.set(\"_embed\", \"1\");\n\n      allPosts = await fetchAllPosts(postsUrl);\n\n      if (!allPosts || !allPosts.length) {\n        statusEl.textContent = \"Nessun caso trovato per questa area tematica.\";\n        totalCasesEl.textContent = \"0\";\n        totalCountriesEl.textContent = \"\u2014\";\n        latestYearEl.textContent = \"\u2014\";\n        repressiveMeasuresEl.textContent = \"\u2014\";\n        return;\n      }\n\n      updateStats(allPosts);\n      setupFilters(allPosts);\n      renderPosts(allPosts);\n\n      statusEl.textContent =\n        allPosts.length + \" \" + (allPosts.length === 1 ? \"caso trovato.\" : \"casi trovati.\");\n\n      [searchInput, statusFilter, measureFilter, rightFilter].forEach(function (el) {\n        if (el) el.addEventListener(\"input\", applyFilters);\n        if (el) el.addEventListener(\"change\", applyFilters);\n      });\n    } catch (error) {\n      console.error(error);\n      statusEl.innerHTML =\n        \"Impossibile caricare i casi. Controlla che la tassonomia, lo slug del termine e i campi ACF siano esposti nella REST API.\";\n    }\n  }\n\n  init();\n})();\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>CHILL Atlas \u00b7 Focus tematico Diritti ambientali Questa pagina raccoglie i casi in cui danno ambientale, crisi climatica, vulnerabilit\u00e0 ecologica e potere pubblico si intrecciano con i diritti fondamentali, l\u2019accesso alla giustizia, la partecipazione democratica e il possibile effetto dissuasivo sulla libert\u00e0 di espressione, associazione e protesta. Protesta climatica SLAPP ambientali Obblighi positivi Accesso alla [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"ai_generated_summary":"","wpai_meta_description":"","footnotes":""},"class_list":["post-231","page","type-page","status-publish","hentry"],"acf":[],"_hostinger_reach_plugin_has_subscription_block":false,"_hostinger_reach_plugin_is_elementor":false,"_links":{"self":[{"href":"https:\/\/chill-lab.eu\/it\/wp-json\/wp\/v2\/pages\/231","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/chill-lab.eu\/it\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/chill-lab.eu\/it\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/chill-lab.eu\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/chill-lab.eu\/it\/wp-json\/wp\/v2\/comments?post=231"}],"version-history":[{"count":7,"href":"https:\/\/chill-lab.eu\/it\/wp-json\/wp\/v2\/pages\/231\/revisions"}],"predecessor-version":[{"id":279,"href":"https:\/\/chill-lab.eu\/it\/wp-json\/wp\/v2\/pages\/231\/revisions\/279"}],"wp:attachment":[{"href":"https:\/\/chill-lab.eu\/it\/wp-json\/wp\/v2\/media?parent=231"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}