{"id":167612,"date":"2026-01-03T20:35:57","date_gmt":"2026-01-03T19:35:57","guid":{"rendered":"https:\/\/www.ciclocolor.com\/?page_id=167612"},"modified":"2026-01-07T00:26:22","modified_gmt":"2026-01-06T23:26:22","slug":"calendario-nazionale-ciclismo-amatori-enti","status":"publish","type":"page","link":"https:\/\/ciclocolor.com\/calendario-nazionale-ciclismo-amatori-enti\/","title":{"rendered":"Calendario Nazionale Ciclismo Amatori Enti"},"content":{"rendered":"\n<style>\n.calendario-update-box {\n    background: #f9fbfd;\n    border: 1px solid #e0eaf3;\n    padding: 20px;\n    border-radius: 8px;\n    text-align: center;\n    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n    margin: 25px 0;\n    box-shadow: 0 2px 6px rgba(2, 119, 189, 0.08);\n}\n\n.update-title {\n    font-weight: 600;\n    font-size: 1.25em;\n    color: #0277bd;\n    margin-bottom: 15px;\n    line-height: 1.3;\n}\n\n.update-text {\n    color: #555;\n    font-size: 14px;\n    margin-bottom: 18px;\n    max-width: 600px;\n    margin-left: auto;\n    margin-right: auto;\n    line-height: 1.5;\n}\n\n.cta-container {\n    display: flex;\n    justify-content: center;\n    gap: 16px;\n    flex-wrap: wrap;\n    margin-top: 10px;\n}\n\n.cta-button {\n    text-decoration: none;\n    padding: 10px 20px;\n    border-radius: 6px;\n    font-weight: bold;\n    font-size: 14px;\n    color: white !important;\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    min-width: 140px;\n    box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n    transition: background 0.2s, transform 0.1s;\n    gap: 8px;\n}\n\n.cta-button:hover {\n    transform: translateY(-2px);\n    box-shadow: 0 4px 8px rgba(0,0,0,0.15);\n}\n\n.mail-btn {\n    background-color: #0277bd;\n}\n\n.mail-btn:hover {\n    background-color: #01579b;\n}\n\n.wa-btn {\n    background-color: #2e7d32;\n}\n\n.wa-btn:hover {\n    background-color: #1b5e20;\n}\n\n\/* Forza icone in bianco (dove supportato) *\/\n.cta-button span {\n    color: white !important;\n    filter: grayscale(100%) brightness(200%); \/* fallback per emoji colorate *\/\n}\n<\/style>\n\n<div class=\"calendario-update-box\">\n  <div class=\"update-title\">Vuoi segnalare una gara o aggiornare il calendario?<\/div>\n  <div class=\"update-text\">Contattaci per inserire nuove gare, correggere dati o collaborare all\u2019aggiornamento del Calendario Nazionale Amatori Ciclismo.<\/div>\n  <div class=\"cta-container\">\n    <a href=\"mailto:ciclocolor@gmail.com?subject=Inserimento Gara Calendario&#038;body=Buongiorno, invio la nostra gara da inserire nel calendario nazionale amatori\" class=\"cta-button mail-btn\">\n      <span>\u2709\ufe0f<\/span> Email\n    <\/a>\n    <a href=\"https:\/\/wa.me\/393332690029?text=Buongiorno,%20invio%20la%20nostra%20gara%20da%20inserire%20nel%20calendario%20nazionale\" class=\"cta-button wa-btn\">\n      <span>\ud83d\udcf1<\/span> WhatsApp\n    <\/a>\n  <\/div>\n<\/div>\n\n\n\n<div style=\"text-align: right; margin: 15px 0;\">\n  <button id=\"info-toggle\" style=\"\n    background: #e3f2fd;\n    color: #0277bd;\n    width: 32px;\n    height: 32px;\n    border-radius: 50%;\n    border: none;\n    font-weight: bold;\n    font-size: 16px;\n    cursor: pointer;\n    box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    transition: background 0.2s;\n  \" title=\"Aiuto: come usare questa pagina\">\n    ?\n  <\/button>\n<\/div>\n\n<div id=\"info-box\" style=\"\n  display: none;\n  background: #f8f9fa;\n  border: 1px solid #bbdefb;\n  border-radius: 8px;\n  padding: 20px;\n  margin: 15px 0;\n  font-size: 14px;\n  line-height: 1.6;\n  box-shadow: 0 2px 6px rgba(2, 119, 189, 0.08);\n\">\n  <h3 style=\"margin-top:0; color: #0277bd; font-size: 18px;\">Aiuto: come usare il calendario<\/h3>\n  \n  <p><strong>1. Cerca una gara<\/strong><br>\n  Scrivi nella casella <em>\u201cCerca in qualsiasi campo\u2026\u201d<\/em> il nome di un luogo, ente organizzatore o evento (es. \u201cVerona\u201d, \u201cCicloColor\u201d, \u201cTrofeo Pinarello\u201d). I risultati si aggiornano automaticamente mentre scrivi.<\/p>\n  \n  <p><strong>2. Filtra per Regione<\/strong><br>\n  Usa il menu a tendina per visualizzare solo le gare di una specifica regione (es. Veneto, Toscana). Scegli <em>\u201cTutte le regioni\u201d<\/em> per vedere l\u2019elenco completo.<\/p>\n  \n  <p><strong>3. Ordina i risultati<\/strong><br>\n  Clicca su una qualsiasi intestazione di colonna (es. <strong>DATA<\/strong>, <strong>LUOGO<\/strong>, <strong>REGIONE<\/strong>) per ordinare i dati.  \n  &#8211; Primo clic: ordine <strong>A \u2192 Z<\/strong> (o date dalla pi\u00f9 vicina)  \n  &#8211; Secondo clic: ordine <strong>Z \u2192 A<\/strong> (o date dalla pi\u00f9 lontana)  \n  Accanto all\u2019intestazione compare una freccia: <strong>\u25b2<\/strong> = crescente, <strong>\u25bc<\/strong> = decrescente.<\/p>\n  \n  <p><strong>Su smartphone<\/strong>: scorri orizzontalmente la tabella per vedere tutte le colonne.<\/p>\n  \n  <p><em>\ud83d\udccc Nota: le gare gi\u00e0 svolte non vengono mostrate. Le prossime gare (da oggi a 3 giorni) sono evidenziate con uno sfondo verde chiaro.<\/em><\/p>\n<\/div>\n\n<script>\ndocument.getElementById('info-toggle').addEventListener('click', function() {\n  const box = document.getElementById('info-box');\n  if (box.style.display === 'none' || box.style.display === '') {\n    box.style.display = 'block';\n    this.textContent = '\u2715';\n    this.title = 'Chiudi guida';\n  } else {\n    box.style.display = 'none';\n    this.textContent = '?';\n    this.title = 'Aiuto: come usare questa pagina';\n  }\n});\n<\/script>\n\n\n\n<div id=\"loader\" style=\"text-align:center; margin:30px 0; font-size:16px; color:#555;\">\r\n  <div style=\"display:inline-block; width:24px; height:24px; border:3px solid rgba(0,0,0,0.2); border-top-color:#0277bd; border-radius:50%; animation:spin 1s linear infinite; margin-bottom:10px;\"><\/div>\r\n  <div>Caricamento gare in corso\u2026<\/div>\r\n<\/div>\r\n\r\n<style>\r\n@keyframes spin {\r\n  to { transform: rotate(360deg); }\r\n}\r\n\r\n\/* Box filtri *\/\r\n#gare-filters {\r\n  background: #f9fbfd;\r\n  padding: 16px;\r\n  border-radius: 8px;\r\n  border: 1px solid #e0eaf3;\r\n  margin: 20px 0;\r\n  display: flex;\r\n  flex-wrap: wrap;\r\n  gap: 16px;\r\n  align-items: center;\r\n  box-shadow: 0 2px 6px rgba(2, 119, 189, 0.08);\r\n}\r\n#gare-filters input,\r\n#gare-filters select {\r\n  padding: 10px 12px;\r\n  font-size: 14px;\r\n  border: 1px solid #cfd8dc;\r\n  border-radius: 6px;\r\n  background: white;\r\n  min-width: 180px;\r\n  height: 42px;\r\n  box-shadow: inset 0 1px 2px rgba(0,0,0,0.06);\r\n}\r\n#gare-filters input:focus,\r\n#gare-filters select:focus {\r\n  outline: none;\r\n  border-color: #0277bd;\r\n  box-shadow: 0 0 0 2px rgba(2, 119, 189, 0.2);\r\n}\r\n#resultsCount {\r\n  font-weight: 600;\r\n  color: #0277bd;\r\n  font-size: 15px;\r\n  min-width: max-content;\r\n}\r\n\r\n\/* Tabella *\/\r\n#gare-table {\r\n  width: 100%;\r\n  border-collapse: collapse;\r\n  font-size: 14px;\r\n  margin: 20px 0;\r\n  box-shadow: 0 2px 8px rgba(0,0,0,0.08);\r\n  border-radius: 6px;\r\n  overflow: hidden;\r\n}\r\n#gare-table th {\r\n  background: #f1f8fe;\r\n  padding: 12px 14px;\r\n  text-align: left;\r\n  font-weight: 600;\r\n  color: #0277bd;\r\n  border-bottom: 2px solid #bbdefb;\r\n  position: relative;\r\n}\r\n#gare-table td {\r\n  padding: 12px 14px;\r\n  border-bottom: 1px solid #eee;\r\n  vertical-align: top;\r\n}\r\n#gare-table tr:nth-child(even):not(.month-header):not(.imminente) {\r\n  background-color: #fafcff;\r\n}\r\n#gare-table tr:hover:not(.month-header) {\r\n  background-color: #f0f7ff !important;\r\n}\r\n#gare-table .month-header td {\r\n  background: #e3f2fd !important;\r\n  font-weight: bold;\r\n  color: #01579b;\r\n  text-align: left;\r\n  border-bottom: 2px solid #90caf9;\r\n}\r\n#gare-table .imminente {\r\n  background-color: #e8f5e9 !important;\r\n}\r\n\r\n\/* Link *\/\r\n#gare-table a {\r\n  color: #0277bd;\r\n  text-decoration: underline;\r\n}\r\n#gare-table a:hover {\r\n  color: #01579b;\r\n  text-decoration: none;\r\n}\r\n\r\n\/* Ordinamento *\/\r\n.sortable {\r\n  cursor: pointer;\r\n  user-select: none;\r\n  padding-right: 24px !important;\r\n}\r\n.sort-indicator {\r\n  position: absolute;\r\n  right: 10px;\r\n  top: 50%;\r\n  transform: translateY(-50%);\r\n  font-size: 14px;\r\n  color: #78909c;\r\n}\r\n\r\n\/* Mobile *\/\r\n@media (max-width: 768px) {\r\n  .col-circuito, .col-disciplina, .col-sito {\r\n    display: none;\r\n  }\r\n  #gare-filters {\r\n    flex-direction: column;\r\n    align-items: stretch;\r\n  }\r\n  #gare-filters input,\r\n  #gare-filters select {\r\n    width: 100%;\r\n    min-width: auto;\r\n  }\r\n}\r\n<\/style>\r\n\r\n<div id=\"gare-filters\">\r\n  <input type=\"text\" id=\"searchBox\" placeholder=\"Cerca in qualsiasi campo\u2026\" autocomplete=\"off\" \/>\r\n  <select id=\"regionFilter\">\r\n    <option value=\"\">Tutte le regioni<\/option>\r\n  <\/select>\r\n  <div id=\"resultsCount\">\u2013 gare trovate<\/div>\r\n<\/div>\r\n\r\n<table id=\"gare-table\">\r\n  <thead><\/thead>\r\n  <tbody><\/tbody>\r\n<\/table>\r\n\r\n<div id=\"pagination\" style=\"text-align:center; margin:20px 0; font-size:14px;\"><\/div>\r\n\r\n<script>\r\ndocument.addEventListener('DOMContentLoaded', function() {\r\n  let allData = [];\r\n  let filteredData = [];\r\n  let currentPage = 1;\r\n  let rowsPerPage = 25;\r\n  let headers = [];\r\n  let regioneColIndex = -1;\r\n  let luogoColIndex = -1;\r\n  let currentSort = { colIndex: null, direction: 'asc' };\r\n\r\n  \/\/ --- Utility ---\r\n  const escapeHtml = (text) => {\r\n    const div = document.createElement('div');\r\n    div.textContent = text;\r\n    return div.innerHTML;\r\n  };\r\n\r\n  \/\/ \u2705 RIMOSSA: nessuna evidenziazione con <mark>!\r\n  const autoLink = (text) => {\r\n    const clean = text.trim().replace(\/^\"(.*)\"$\/, '$1');\r\n    if (\/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\/.test(clean)) {\r\n      return `<a href=\"mailto:${clean}\">${escapeHtml(clean)}<\/a>`;\r\n    }\r\n    if (clean.startsWith('http:\/\/') || clean.startsWith('https:\/\/')) {\r\n      return `<a href=\"${clean}\" target=\"_blank\" rel=\"noopener\">${escapeHtml(clean)}<\/a>`;\r\n    }\r\n    return escapeHtml(clean);\r\n  };\r\n\r\n  const parseDateItalian = (dateStr) => {\r\n    const parts = dateStr.split('\/');\r\n    if (parts.length !== 3) return null;\r\n    const [day, month, year] = parts.map(Number);\r\n    return day && month && year ? new Date(year, month - 1, day) : null;\r\n  };\r\n\r\n  \/\/ --- Caricamento dati ---\r\n  const url = 'https:\/\/docs.google.com\/spreadsheets\/d\/e\/2PACX-1vRJi3ZrQC_-DOHH1bEoFOodKC8LuL8RYRndrNtvH0LmrENW17u7q_ATl93YlGVemJZ0HXKz-QsabJ7R\/pub?gid=444887279&single=true&output=csv';\r\n\r\n  fetch(url, { mode: 'cors' })\r\n    .then(response => {\r\n      if (!response.ok) throw new Error(`Errore HTTP: ${response.status}`);\r\n      return response.text();\r\n    })\r\n    .then(text => {\r\n      const lines = text.split('\\n').filter(l => l.trim());\r\n      if (lines.length < 2) throw new Error('Dati insufficienti.');\r\n\r\n      headers = lines[0].split(',').map(h => h.trim().replace(\/^\"(.*)\"$\/, '$1'));\r\n      regioneColIndex = headers.findIndex(h => h.toUpperCase() === 'REGIONE');\r\n      luogoColIndex = headers.findIndex(h => h.toUpperCase() === 'LUOGO');\r\n\r\n      const dataRows = lines.slice(1).map(line => \r\n        line.split(',').map(cell => cell.trim().replace(\/^\"(.*)\"$\/, '$1'))\r\n      );\r\n\r\n      \/\/ Rimuovi doppioni\r\n      const seen = new Set();\r\n      const uniqueRows = [];\r\n      dataRows.forEach(row => {\r\n        const key = (row[0] || '') + '||' + (row[luogoColIndex] || '');\r\n        if (key && !seen.has(key)) {\r\n          seen.add(key);\r\n          uniqueRows.push(row);\r\n        }\r\n      });\r\n\r\n      \/\/ Filtra gare future\r\n      const today = new Date();\r\n      today.setHours(0, 0, 0, 0);\r\n      allData = uniqueRows.filter(row => {\r\n        const dateObj = parseDateItalian(row[0]);\r\n        return dateObj && dateObj >= today;\r\n      });\r\n\r\n      \/\/ Ordine iniziale: DATA\r\n      allData.sort((a, b) => {\r\n        const dateA = parseDateItalian(a[0]);\r\n        const dateB = parseDateItalian(b[0]);\r\n        return (dateA || new Date(8640000000000000)) - (dateB || new Date(8640000000000000));\r\n      });\r\n\r\n      \/\/ Popola regioni\r\n      if (regioneColIndex !== -1) {\r\n        const regioni = [...new Set(allData.map(row => (row[regioneColIndex] || '').trim()).filter(r => r))];\r\n        regioni.sort((a, b) => a.localeCompare(b, 'it'));\r\n        const select = document.getElementById('regionFilter');\r\n        regioni.forEach(region => {\r\n          const opt = document.createElement('option');\r\n          opt.value = region;\r\n          opt.textContent = region;\r\n          select.appendChild(opt);\r\n        });\r\n      }\r\n\r\n      applyFilters();\r\n      document.getElementById('loader').style.display = 'none';\r\n    })\r\n    .catch(err => {\r\n      console.error('Errore:', err);\r\n      document.getElementById('loader').innerHTML = \r\n        `<div style=\"color:#c62828; font-weight:bold; padding:16px; background:#ffebee; border-radius:8px; margin:20px 0;\">\r\n          \u274c Impossibile caricare le gare.<br>\r\n          <small>Controlla che il foglio Google sia pubblicato correttamente.<\/small>\r\n        <\/div>`;\r\n    });\r\n\r\n  \/\/ --- Filtri + ordinamento ---\r\n  function applyFilters() {\r\n    const searchTerm = document.getElementById('searchBox').value.trim().toLowerCase();\r\n    const selectedRegion = document.getElementById('regionFilter').value;\r\n\r\n    filteredData = allData.filter(row => {\r\n      if (selectedRegion && regioneColIndex !== -1 && (row[regioneColIndex] || '') !== selectedRegion) return false;\r\n      if (searchTerm && !row.some(cell => cell.toLowerCase().includes(searchTerm))) return false;\r\n      return true;\r\n    });\r\n\r\n    if (currentSort.colIndex !== null) {\r\n      const { colIndex, direction } = currentSort;\r\n      filteredData.sort((a, b) => {\r\n        let valA = (a[colIndex] || '').toString().toLowerCase();\r\n        let valB = (b[colIndex] || '').toString().toLowerCase();\r\n\r\n        if (colIndex === 0) {\r\n          const dateA = parseDateItalian(a[0]);\r\n          const dateB = parseDateItalian(b[0]);\r\n          if (dateA && dateB) {\r\n            return direction === 'asc' ? dateA - dateB : dateB - dateA;\r\n          }\r\n        }\r\n\r\n        const comp = valA.localeCompare(valB, 'it');\r\n        return direction === 'asc' ? comp : -comp;\r\n      });\r\n    }\r\n\r\n    currentPage = 1;\r\n    renderTable();\r\n  }\r\n\r\n  function setSort(colIndex) {\r\n    if (currentSort.colIndex === colIndex) {\r\n      currentSort.direction = currentSort.direction === 'asc' ? 'desc' : 'asc';\r\n    } else {\r\n      currentSort.colIndex = colIndex;\r\n      currentSort.direction = 'asc';\r\n    }\r\n    applyFilters();\r\n  }\r\n\r\n  \/\/ --- Renderizzazione ---\r\n  function renderTable() {\r\n    const tbody = document.querySelector('#gare-table tbody');\r\n    const thead = document.querySelector('#gare-table thead');\r\n    const pagination = document.getElementById('pagination');\r\n    const resultsCount = document.getElementById('resultsCount');\r\n\r\n    const colClassMap = {\r\n      'DATA': 'col-data',\r\n      'LUOGO': 'col-luogo',\r\n      'PROV': 'col-prov',\r\n      'REGIONE': 'col-regione',\r\n      'ENTE': 'col-ente',\r\n      'EVENTO': 'col-evento',\r\n      'CIRCUITO': 'col-circuito',\r\n      'DISCIPLINA': 'col-disciplina',\r\n      'SITO': 'col-sito'\r\n    };\r\n\r\n    let theadHTML = '<tr>';\r\n    headers.forEach((h, idx) => {\r\n      const cls = colClassMap[h.toUpperCase()] || '';\r\n      let indicator = '';\r\n      if (currentSort.colIndex === idx) {\r\n        indicator = `<span class=\"sort-indicator\">${currentSort.direction === 'asc' ? '\u25b2' : '\u25bc'}<\/span>`;\r\n      }\r\n      theadHTML += `<th class=\"sortable ${cls}\" onclick=\"setSort(${idx})\">${escapeHtml(h)}${indicator}<\/th>`;\r\n    });\r\n    theadHTML += '<\/tr>';\r\n    thead.innerHTML = theadHTML;\r\n\r\n    const totalCount = filteredData.length;\r\n    resultsCount.textContent = totalCount === 0 ? 'Nessuna gara trovata.' :\r\n                               totalCount === 1 ? '1 gara trovata' : `${totalCount} gare trovate`;\r\n\r\n    if (totalCount === 0) {\r\n      tbody.innerHTML = `<tr><td colspan=\"${headers.length}\" style=\"text-align:center; padding:24px; color:#666;\">Nessuna gara futura corrisponde ai filtri.<\/td><\/tr>`;\r\n      pagination.innerHTML = '';\r\n      return;\r\n    }\r\n\r\n    const totalPages = rowsPerPage === -1 ? 1 : Math.ceil(totalCount \/ rowsPerPage);\r\n    if (currentPage > totalPages) currentPage = totalPages || 1;\r\n    const start = (currentPage - 1) * rowsPerPage;\r\n    const paginatedData = filteredData.slice(start, start + rowsPerPage);\r\n\r\n    const today = new Date();\r\n    today.setHours(0, 0, 0, 0);\r\n    const threeDays = new Date();\r\n    threeDays.setDate(today.getDate() + 3);\r\n    threeDays.setHours(0, 0, 0, 0);\r\n\r\n    const monthNames = [\"Gennaio\",\"Febbraio\",\"Marzo\",\"Aprile\",\"Maggio\",\"Giugno\",\"Luglio\",\"Agosto\",\"Settembre\",\"Ottobre\",\"Novembre\",\"Dicembre\"];\r\n    let html = '';\r\n    let lastKey = '';\r\n\r\n    paginatedData.forEach(row => {\r\n      const dateObj = parseDateItalian(row[0]);\r\n      let monthHeader = '';\r\n\r\n      if (dateObj) {\r\n        const key = `${dateObj.getFullYear()}-${dateObj.getMonth()}`;\r\n        if (key !== lastKey) {\r\n          monthHeader = `<tr class=\"month-header\"><td colspan=\"${headers.length}\" style=\"padding:10px 14px;\">${monthNames[dateObj.getMonth()]} ${dateObj.getFullYear()}<\/td><\/tr>`;\r\n          lastKey = key;\r\n        }\r\n      }\r\n\r\n      const isImminente = dateObj && dateObj >= today && dateObj <= threeDays;\r\n      let cellsHTML = '';\r\n      row.forEach((cell, idx) => {\r\n        const cls = colClassMap[headers[idx].toUpperCase()] || '';\r\n        \/\/ \u2705 Nessun <mark>! Solo testo pulito + link\r\n        cellsHTML += `<td class=\"${cls}\">${autoLink(cell)}<\/td>`;\r\n      });\r\n\r\n      html += monthHeader;\r\n      html += `<tr class=\"${isImminente ? 'imminente' : ''}\">${cellsHTML}<\/tr>`;\r\n    });\r\n\r\n    tbody.innerHTML = html;\r\n\r\n    \/\/ \u2705 PAGINAZIONE CON DOPPIA FRECCIA\r\n    if (totalPages <= 1) {\r\n      pagination.innerHTML = '';\r\n      return;\r\n    }\r\n\r\n    let pgn = '<div style=\"display:inline-block; margin:15px 0; background:#f5fbff; padding:10px 14px; border-radius:8px; box-shadow:0 2px 5px rgba(0,0,0,0.08); font-size:14px;\">';\r\n\r\n    \/\/ \u00ab\u00ab Inizio\r\n    if (currentPage > 1) {\r\n      pgn += `<button onclick=\"changePage(1)\" style=\"padding:7px 10px; margin:0 4px; background:#e8f5fd; border:none; border-radius:4px; cursor:pointer; color:#0277bd; font-weight:bold;\">\u00ab\u00ab Inizio<\/button>`;\r\n    }\r\n\r\n    \/\/ \u00ab Precedente\r\n    if (currentPage > 1) {\r\n      pgn += `<button onclick=\"changePage(${currentPage - 1})\" style=\"padding:7px 10px; margin:0 4px; background:#e3f2fd; border:none; border-radius:4px; cursor:pointer; color:#0277bd; font-weight:bold;\">\u00ab Precedente<\/button>`;\r\n    }\r\n\r\n    \/\/ Pagine\r\n    const maxBtn = 5;\r\n    let startPage = Math.max(1, currentPage - Math.floor(maxBtn \/ 2));\r\n    let endPage = Math.min(totalPages, startPage + maxBtn - 1);\r\n    if (endPage - startPage + 1 < maxBtn) startPage = Math.max(1, endPage - maxBtn + 1);\r\n\r\n    for (let i = startPage; i <= endPage; i++) {\r\n      if (i === currentPage) {\r\n        pgn += `<span style=\"padding:7px 12px; margin:0 4px; background:#0277bd; color:white; border-radius:4px; font-weight:bold;\">${i}<\/span>`;\r\n      } else {\r\n        pgn += `<button onclick=\"changePage(${i})\" style=\"padding:7px 12px; margin:0 4px; background:#bbdefb; border:none; border-radius:4px; cursor:pointer; color:#01579b; font-weight:bold;\">${i}<\/button>`;\r\n      }\r\n    }\r\n\r\n    \/\/ Successivo \u00bb\r\n    if (currentPage < totalPages) {\r\n      pgn += `<button onclick=\"changePage(${currentPage + 1})\" style=\"padding:7px 10px; margin:0 4px; background:#e3f2fd; border:none; border-radius:4px; cursor:pointer; color:#0277bd; font-weight:bold;\">Successivo \u00bb<\/button>`;\r\n    }\r\n\r\n    \/\/ Fine \u00bb\u00bb\r\n    if (currentPage < totalPages) {\r\n      pgn += `<button onclick=\"changePage(${totalPages})\" style=\"padding:7px 10px; margin:0 4px; background:#e8f5fd; border:none; border-radius:4px; cursor:pointer; color:#0277bd; font-weight:bold;\">Fine \u00bb\u00bb<\/button>`;\r\n    }\r\n\r\n    pgn += '<\/div>';\r\n    pagination.innerHTML = pgn;\r\n  }\r\n\r\n  window.changePage = (page) => { currentPage = page; renderTable(); };\r\n  window.setSort = (colIndex) => { setSort(colIndex); };\r\n\r\n  document.getElementById('searchBox').addEventListener('input', applyFilters);\r\n  document.getElementById('regionFilter').addEventListener('change', applyFilters);\r\n});\r\n<\/script>\n\n\n\n<div id=\"AVVISO-DATE-CALENDARIO\" class=\"ciclocolor-alert-box\">\n  <span class=\"alert-title\">Avviso importante:<\/span>\n  Si invitano gli utenti a contattare direttamente gli organizzatori del circuito o trofeo, oppure a consultare il sito web ufficiale, poich\u00e9 date e sedi delle gare possono subire variazioni, modifiche o annullamenti nel corso della stagione.\n  <br><br>\n  <strong>Ciclocolor.com<\/strong> declina ogni responsabilit\u00e0 per aggiornamenti non pervenuti o non reperibili online.\n<\/div>\n\n<style>\n.ciclocolor-alert-box {\n    background: #fdf8f6; \/* Sfondo avorio molto chiaro \u2013 elegante e leggibile *\/\n    color: #444;\n    margin: 25px 0;\n    padding: 22px;\n    border: 2px solid #c62828; \/* Bordeaux sobrio (Google Red 800) \u2013 meno aggressivo del rosso puro *\/\n    border-radius: 8px;\n    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n    line-height: 1.6;\n    box-shadow: 0 2px 6px rgba(198, 40, 40, 0.1); \/* Ombra tono su tono *\/\n    text-align: center;\n    font-size: 14px;\n}\n\n.alert-title {\n    color: #c62828; \/* Coerente con il bordo *\/\n    font-weight: 700;\n    text-transform: uppercase;\n    display: block;\n    margin-bottom: 12px;\n    font-size: 1.15em;\n    letter-spacing: 0.5px;\n}\n\n.ciclocolor-alert-box strong {\n    color: #0277bd; \/* Blu coerente con il tuo brand (come intestazioni tabella) *\/\n    font-weight: 600;\n}\n<\/style>\n","protected":false},"excerpt":{"rendered":"<p>Vuoi segnalare una gara o aggiornare il calendario? Contattaci per inserire nuove gare, correggere dati o collaborare all\u2019aggiornamento del Calendario Nazionale Amatori Ciclismo. \u2709\ufe0f Email \ud83d\udcf1 WhatsApp ? Aiuto: come usare il calendario 1. Cerca una gara Scrivi nella casella \u201cCerca in qualsiasi campo\u2026\u201d il nome di un luogo, ente organizzatore o evento (es. \u201cVerona\u201d, &hellip;<\/p>\n","protected":false},"author":1,"featured_media":167708,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-167612","page","type-page","status-publish","has-post-thumbnail","hentry"],"_links":{"self":[{"href":"https:\/\/ciclocolor.com\/wp-json\/wp\/v2\/pages\/167612","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ciclocolor.com\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ciclocolor.com\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ciclocolor.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ciclocolor.com\/wp-json\/wp\/v2\/comments?post=167612"}],"version-history":[{"count":8,"href":"https:\/\/ciclocolor.com\/wp-json\/wp\/v2\/pages\/167612\/revisions"}],"predecessor-version":[{"id":167723,"href":"https:\/\/ciclocolor.com\/wp-json\/wp\/v2\/pages\/167612\/revisions\/167723"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ciclocolor.com\/wp-json\/wp\/v2\/media\/167708"}],"wp:attachment":[{"href":"https:\/\/ciclocolor.com\/wp-json\/wp\/v2\/media?parent=167612"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}