Skip to content

Instantly share code, notes, and snippets.

@orfeomorello
Created January 3, 2026 13:01
Show Gist options
  • Select an option

  • Save orfeomorello/d021460156e47478ba7d86da52651202 to your computer and use it in GitHub Desktop.

Select an option

Save orfeomorello/d021460156e47478ba7d86da52651202 to your computer and use it in GitHub Desktop.
Calendario 2026 personalizzabile con santi e fasi lunari
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<title>Calendario 2026 - Personalizzabile</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto+Condensed:wght@400;700&family=Roboto:wght@400;700;900&display=swap');
:root {
/* Variabili modificabili via JS */
--primary-color: #c00d0d;
--sidebar-bg: #f0e6dd;
--sidebar-header-bg: #dcbfa8;
--text-main: #000;
--border-color: #000;
--holiday-color: var(--primary-color);
}
/* Classe per modalitΓ  Bianco e Nero */
body.monochrome {
--primary-color: #000000;
--sidebar-bg: #f5f5f5;
--sidebar-header-bg: #e0e0e0;
--holiday-color: #000000;
}
/* Stili per evidenziare le domeniche in B/N in modo diverso (opzionale, qui uso grassetto/grigio) */
body.monochrome .is-sunday .day-big-num,
body.monochrome .is-holiday .day-big-num {
text-decoration: underline; /* Esempio per distinguere senza colore */
}
body {
margin: 0;
padding: 0;
font-family: 'Roboto Condensed', sans-serif;
background: #eee;
}
/* TOOLBAR (Non stampabile) */
#toolbar {
position: fixed;
top: 0;
left: 0;
width: 100%;
background: #333;
color: white;
padding: 10px 20px;
box-shadow: 0 2px 5px rgba(0,0,0,0.3);
z-index: 1000;
display: flex;
align-items: center;
gap: 20px;
font-family: 'Roboto', sans-serif;
}
#toolbar span { font-weight: bold; margin-right: 10px; }
.color-btn {
width: 30px;
height: 30px;
border-radius: 50%;
border: 2px solid white;
cursor: pointer;
transition: transform 0.2s;
}
.color-btn:hover { transform: scale(1.2); }
.action-btn {
padding: 8px 15px;
background: #fff;
color: #333;
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
margin-left: auto;
}
.action-btn:hover { background: #ddd; }
.bw-toggle {
display: flex;
align-items: center;
cursor: pointer;
background: #555;
padding: 5px 10px;
border-radius: 20px;
}
.bw-toggle input { margin-right: 8px; }
/* Contenitore principale pagine */
#calendar-root {
margin-top: 60px; /* Spazio per la toolbar */
}
/* Layout A4 */
.page {
width: 210mm;
height: 297mm;
background: white;
margin: 20px auto;
position: relative;
box-sizing: border-box;
page-break-after: always;
display: flex;
flex-direction: column;
overflow: hidden;
border: 1px solid #ddd;
}
/* HEADER */
header {
background: var(--primary-color);
color: white;
height: 35mm;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10mm;
border-bottom: 2px solid var(--border-color);
transition: background 0.3s;
}
.zodiac {
width: 15%;
text-align: center;
font-size: 10px;
background: white;
color: black;
border-radius: 5px;
padding: 5px;
height: 25mm;
display: flex;
flex-direction: column;
justify-content: center;
border: 1px solid black;
}
.zodiac img, .zodiac span { display: block; }
.zodiac-icon { font-size: 20px; }
.month-title {
text-align: center;
text-transform: uppercase;
font-family: 'Roboto', sans-serif;
font-weight: 900;
font-size: 48pt;
text-shadow: 2px 2px 0px rgba(0,0,0,0.1);
letter-spacing: -2px;
flex-grow: 1;
}
/* MAIN BODY GRID */
.main-container {
display: flex;
height: 100%;
border-bottom: 2px solid var(--border-color);
}
/* SIDEBARS */
.sidebar {
width: 12%;
background: var(--sidebar-bg);
border-right: 1px solid var(--border-color);
border-left: 1px solid var(--border-color);
display: flex;
flex-direction: column;
padding-top: 5px;
transition: background 0.3s;
}
.sidebar:first-child { border-left: none; }
.sidebar:last-child { border-right: none; border-left: 1px solid var(--border-color); }
.sidebar-header {
background: var(--sidebar-header-bg);
color: var(--primary-color);
text-align: center;
font-weight: bold;
font-size: 10px;
padding: 2px;
text-transform: uppercase;
border-bottom: 1px solid var(--border-color);
margin-bottom: 2px;
transition: color 0.3s, background 0.3s;
}
.mini-day-row {
display: flex;
font-size: 8px;
padding: 1px 2px;
line-height: 1.1;
border-bottom: 1px solid #ccc;
}
.mini-day-row.sunday { color: var(--primary-color); font-weight: bold; }
.mini-day-num { width: 15px; font-weight: bold; text-align: right; margin-right: 4px; }
.mini-day-name { text-transform: capitalize; }
/* CENTER CONTENT */
.content {
width: 76%;
display: flex;
}
.column {
width: 50%;
display: flex;
flex-direction: column;
}
.column:first-child { border-right: 1px solid var(--border-color); }
/* DAY ROW STYLING */
.day-row {
flex-grow: 1;
display: flex;
align-items: center;
border-bottom: 1px solid #000;
padding: 0 5px;
position: relative;
}
.day-row:last-child { border-bottom: none; }
.day-big-num {
font-family: 'Roboto', sans-serif;
font-size: 32pt;
font-weight: 900;
width: 50px;
text-align: center;
line-height: 1;
}
.day-info {
flex-grow: 1;
padding-left: 10px;
display: flex;
flex-direction: column;
justify-content: center;
overflow: hidden; /* Evita testo lungo che rompe layout */
}
.day-name {
font-size: 14pt;
font-weight: 700;
text-transform: uppercase;
}
.day-saint {
font-size: 8pt;
color: #444;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding-right: 5px;
}
.day-meta {
font-size: 7pt;
text-align: right;
display: flex;
flex-direction: column;
justify-content: center;
min-width: 30px;
}
/* FestivitΓ  e Domeniche */
.is-sunday, .is-holiday {
color: var(--holiday-color);
}
.is-sunday .day-big-num, .is-holiday .day-big-num {
color: var(--holiday-color);
}
.is-sunday .day-name, .is-holiday .day-name {
color: var(--holiday-color);
}
/* FOOTER */
footer {
height: 15mm;
border-top: 2px solid var(--border-color);
display: flex;
font-size: 8px;
align-items: center;
justify-content: space-around;
padding: 0 10px;
}
.moon-phase {
font-size: 14px;
}
/* MEDIA QUERY PER STAMPA */
@media print {
@page {
size: A4;
margin: 0;
}
body {
background: white;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
#toolbar {
display: none;
}
#calendar-root {
margin-top: 0;
}
.page {
margin: 0;
border: none;
width: 210mm;
height: 297mm;
}
}
</style>
</head>
<body>
<div id="toolbar">
<span>Tema:</span>
<div class="color-btn" style="background:#c00d0d" onclick="setTheme('#c00d0d', '#f0e6dd', '#dcbfa8')" title="Rosso Classico"></div>
<div class="color-btn" style="background:#0056b3" onclick="setTheme('#0056b3', '#e3f2fd', '#bbdefb')" title="Blu"></div>
<div class="color-btn" style="background:#2e7d32" onclick="setTheme('#2e7d32', '#e8f5e9', '#c8e6c9')" title="Verde"></div>
<div class="color-btn" style="background:#e65100" onclick="setTheme('#e65100', '#fff3e0', '#ffe0b2')" title="Arancione"></div>
<div class="color-btn" style="background:#6a1b9a" onclick="setTheme('#6a1b9a', '#f3e5f5', '#e1bee7')" title="Viola"></div>
<div style="width: 20px;"></div> <label class="bw-toggle">
<input type="checkbox" id="bwCheckbox" onchange="toggleBW()">
Stampa B/N
</label>
<button class="action-btn" style="margin-right:30px" onclick="window.print()">πŸ–¨οΈ STAMPA</button>
</div>
<div id="calendar-root"></div>
<script>
// --- DATI SANTI (Estratti da img34.jpg) ---
// Formato chiave: "M-D" (Mese 0-11, Giorno 1-31)
const saintsData = {
// GENNAIO
"0-1": "Maria Madre di Dio", "0-2": "S. Basilio Vescovo", "0-3": "S. Genoveffa", "0-4": "S. Ermete", "0-5": "S. Amelia",
"0-6": "Epifania di N.S.", "0-7": "S. Luciano, S. Raimondo", "0-8": "S. Massimo, S. Severino", "0-9": "S. Giuliano Martire", "0-10": "S. Aldo Eremita",
"0-11": "S. Igino Papa", "0-12": "S. Modesto M.", "0-13": "S. Ilario", "0-14": "S. Felice M., S. Bianca", "0-15": "S. Mauro Abate",
"0-16": "S. Marcello Papa", "0-17": "S. Antonio Abate", "0-18": "S. Liberata", "0-19": "S. Mario Martire", "0-20": "S. Sebastiano",
"0-21": "S. Agnese", "0-22": "S. Vincenzo Martire", "0-23": "S. Emerenziana", "0-24": "S. Francesco di Sales", "0-25": "Conversione di S. Paolo",
"0-26": "SS. Tito e Timoteo, S. Paola", "0-27": "S. Angela Merici", "0-28": "S. Tommaso d'Aq., S. Valerio", "0-29": "S. Costanzo, S. Cesario", "0-30": "S. Martina, S. Savina",
"0-31": "S. Giovanni Bosco",
// FEBBRAIO
"1-1": "S. Verdiana", "1-2": "Pres. del Signore", "1-3": "S. Biagio, S. Oscar", "1-4": "S. Gilberto", "1-5": "S. Agata",
"1-6": "S. Paolo Miki", "1-7": "S. Teodoro Martire", "1-8": "S. Girolamo Em.", "1-9": "S. Apollonia", "1-10": "S. Arnaldo, S. Scolastica",
"1-11": "B.V. di Lourdes", "1-12": "S. Eulalia", "1-13": "S. Maura", "1-14": "S. Valentino Martire", "1-15": "S. Faustino",
"1-16": "S. Giuliana Vergine", "1-17": "S. Donato Martire", "1-18": "Le Ceneri", "1-19": "S. Mansueto, S. Tullio", "1-20": "S. Silvano, S. Eleuterio",
"1-21": "S. Pier Damiani, S. Eleonora", "1-22": "I di Quaresima", "1-23": "S. Renzo", "1-24": "S. Edilberto Re", "1-25": "S. Cesario, S. Vittorino",
"1-26": "S. Romeo", "1-27": "S. Leandro", "1-28": "S. Romano Abate",
// MARZO
"2-1": "II di Quaresima", "2-2": "S. Basileo Martire", "2-3": "S. Cunegonda", "2-4": "S. Casimiro, S. Lucio", "2-5": "S. Adriano",
"2-6": "S. Giordano", "2-7": "S. Felicita, S. Perpetua", "2-8": "III di Quaresima", "2-9": "S. Francesca R.", "2-10": "S. Simplicio Papa",
"2-11": "S. Costantino", "2-12": "S. Massimiliano", "2-13": "S. Arrigo, S. Eufrasia", "2-14": "S. Matilde Regina", "2-15": "IV di Quaresima",
"2-16": "S. Eriberto Vescovo", "2-17": "S. Patrizio", "2-18": "S. Salvatore, S. Cirillo", "2-19": "S. Giuseppe", "2-20": "S. Alessandra Martire",
"2-21": "S. Benedetto", "2-22": "V di Quaresima", "2-23": "S. Turibio di M.", "2-24": "S. Romolo", "2-25": "Annunc. del Signore",
"2-26": "S. Teodoro, S. Emanuele", "2-27": "S. Augusto", "2-28": "S. Sisto III Papa", "2-29": "Le Palme", "2-30": "S. Amedeo", "2-31": "S. Beniamino Martire",
// APRILE
"3-1": "Merc. Santo", "3-2": "Giov. Santo", "3-3": "Ven. Santo", "3-4": "Sab. Santo", "3-5": "Pasqua di Resurrezione",
"3-6": "Lunedì dell'Angelo", "3-7": "S. Ermanno", "3-8": "S. Alberto Dionigi", "3-9": "S. Maria Cleofe", "3-10": "S. Terenzio Martire",
"3-11": "S. Stanislao Vescovo", "3-12": "Dom. in Albis", "3-13": "S. Martino Papa", "3-14": "S. Abbondio", "3-15": "S. Annibale",
"3-16": "S. Lamberto", "3-17": "S. Aniceto Papa", "3-18": "S. Galdino Vescovo", "3-19": "S. Ermogene Martire", "3-20": "S. Adalgisa Vergine",
"3-21": "S. Anselmo, S. Silvio", "3-22": "S. Caio", "3-23": "S. Giorgio Martire", "3-24": "S. Fedele, S. Gastone", "3-25": "S. Marco Evangelista",
"3-26": "S. Cleto, S. Marcellino", "3-27": "S. Zita", "3-28": "S. Valeria, S. Pietro Chanel", "3-29": "S. Caterina da Siena", "3-30": "S. Pio V Papa, S. Mariano",
// MAGGIO
"4-1": "S. Giuseppe Art.", "4-2": "S. Cesare, S. Atanasio", "4-3": "SS. Filippo e Giacomo", "4-4": "S. Silvano, S. Nereo", "4-5": "S. Pellegrino Martire",
"4-6": "S. Giuditta Martire", "4-7": "S. Flavia, S. Fulvio", "4-8": "S. Desiderato, S. Vittore", "4-9": "S. Gregorio V., S. Duilio", "4-10": "S. Antonino, S. Cataldo",
"4-11": "S. Fabio Martire", "4-12": "S. Rossana", "4-13": "S. Emma", "4-14": "S. Mattia Ap.", "4-15": "S. Torquato, S. Achille",
"4-16": "S. Ubaldo Vescovo", "4-17": "Ascensione del Signore", "4-18": "S. Giovanni I Papa", "4-19": "S. Pietro di M.", "4-20": "S. Bernardino da S.",
"4-21": "S. Vittorio Martire", "4-22": "S. Rita da Cascia", "4-23": "S. Desiderio Vescovo", "4-24": "Pentecoste", "4-25": "S. Beda Conf., S. Urbano",
"4-26": "S. Filippo Neri", "4-27": "S. Agostino", "4-28": "S. Emilio M., S. Ercole", "4-29": "S. Massimo Vescovo", "4-30": "S. Felice I Papa", "4-31": "SS. TrinitΓ ",
// GIUGNO
"5-1": "S. Giustino Martire", "5-2": "Festa della Repubblica", "5-3": "S. Carlo Lwanga", "5-4": "S. Quirino Vescovo", "5-5": "S. Bonifacio Vescovo",
"5-6": "S. Norberto Vescovo", "5-7": "Corpus Domini", "5-8": "S. Medardo Vescovo", "5-9": "S. Primo, S. Efrem", "5-10": "S. Diana, S. Marcella",
"5-11": "S. Barnaba Ap.", "5-12": "S. Guido, S. Onofrio", "5-13": "S. Antonio da Padova", "5-14": "S. Eliseo", "5-15": "S. Germana, S. Vito",
"5-16": "S. Aureliano", "5-17": "S. Gregorio B., S. Adolfo", "5-18": "S. Marina", "5-19": "S. Gervasio, S. Romualdo", "5-20": "S. Silverio Papa",
"5-21": "S. Luigi Gonzaga", "5-22": "S. Paolino da Nola", "5-23": "S. Lanfranco Vescovo", "5-24": "Nativ. S. Giovanni B.", "5-25": "S. Guglielmo Ab.",
"5-26": "S. Vigilio Vescovo", "5-27": "S. Cirillo d'Aless.", "5-28": "S. Attilio", "5-29": "SS. Pietro e Paolo", "5-30": "SS. Primi Martiri",
// LUGLIO
"6-1": "S. Teobaldo Erem.", "6-2": "S. Ottone", "6-3": "S. Tommaso Ap.", "6-4": "S. Elisabetta, S. Rossella", "6-5": "S. Antonio M.Z.",
"6-6": "S. Maria Goretti", "6-7": "S. Edda, S. Claudio", "6-8": "S. Adriano, S. Priscilla", "6-9": "S. Armando, S. Letizia", "6-10": "S. Felicita, S. Silvana",
"6-11": "S. Benedetto, S. Olga", "6-12": "S. Fortunato Martire", "6-13": "S. Enrico Imp.", "6-14": "S. Camillo de Lellis", "6-15": "S. Bonaventura",
"6-16": "N.S. del Carmelo", "6-17": "S. Alessio Conf.", "6-18": "S. Calogero, S. Federico", "6-19": "S. Giusta, S. Simmaco", "6-20": "S. Elia Prof., S. Margherita",
"6-21": "S. Lorenzo da B.", "6-22": "S. Maria Maddalena", "6-23": "S. Brigida", "6-24": "S. Cristina", "6-25": "S. Giacomo Ap.",
"6-26": "SS. Anna e Gioacchino", "6-27": "S. Liliana, S. Aurelio", "6-28": "S. Nazario, S. Innocenzo", "6-29": "S. Marta", "6-30": "S. Pietro Crisologo", "6-31": "S. Ignazio di L.",
// AGOSTO
"7-1": "S. Alfonso", "7-2": "S. Eusebio, S. Gustavo", "7-3": "S. Lidia", "7-4": "S. Nicodemo, S. Giovanni M.V.", "7-5": "S. Osvaldo",
"7-6": "Trasfiguraz. N.S.", "7-7": "S. Gaetano da T.", "7-8": "S. Domenico Conf.", "7-9": "S. Romano, S. Fermo", "7-10": "S. Lorenzo Martire",
"7-11": "S. Chiara", "7-12": "S. Giuliano", "7-13": "S. Ippolito, S. Ponziano", "7-14": "S. Alfredo", "7-15": "Assunzione Maria Vergine",
"7-16": "S. Stefano, S. Rocco", "7-17": "S. Giacinto Confessore", "7-18": "S. Elena Imp.", "7-19": "S. Ludovico, S. Italo", "7-20": "S. Bernardo Abate",
"7-21": "S. Pio X", "7-22": "S. Maria Regina", "7-23": "S. Rosa da Lima, S. Manlio", "7-24": "S. Bartolomeo Ap.", "7-25": "S. Ludovico",
"7-26": "S. Alessandro Martire", "7-27": "S. Monica, S. Anita", "7-28": "S. Agostino", "7-29": "Martirio S. Giovanni B.", "7-30": "S. Faustina, S. Tecla", "7-31": "S. Aristide Martire",
// SETTEMBRE
"8-1": "S. Egidio Abate", "8-2": "S. Elpidio Vescovo", "8-3": "S. Gregorio M., S. Marino", "8-4": "S. Rosalia", "8-5": "S. Vittorino Vescovo",
"8-6": "S. Petronio, S. Umberto", "8-7": "S. Regina", "8-8": "Nativ. B.V. Maria", "8-9": "S. Sergio Papa", "8-10": "S. Nicola da Tol.",
"8-11": "S. Diomede Martire", "8-12": "SS. Nome di Maria", "8-13": "S. Maurilio, S. Giovanni Cris.", "8-14": "Esaltaz. S. Croce", "8-15": "B.V. Addolorata",
"8-16": "S. Cornelio e Cipriano", "8-17": "S. Roberto B.", "8-18": "S. Sofia M.", "8-19": "S. Gennaro Vescovo", "8-20": "S. Eustachio, S. Candida",
"8-21": "S. Matteo Apostolo", "8-22": "S. Maurizio Martire", "8-23": "S. Pio da Pietrelcina", "8-24": "S. Pacifico Conf.", "8-25": "S. Aurelia",
"8-26": "SS. Cosma e Damiano", "8-27": "S. Vincenzo de P.", "8-28": "S. Venceslao Martire", "8-29": "SS. Michele, Gabriele, Raffaele", "8-30": "S. Girolamo Dottore",
// OTTOBRE
"9-1": "S. Teresa del B.G.", "9-2": "SS. Angeli Custodi", "9-3": "S. Gerardo Ab.", "9-4": "S. Francesco d'Assisi", "9-5": "S. Placido Martire",
"9-6": "S. Bruno Ab.", "9-7": "B.V. del Rosario", "9-8": "S. Pelagia, S. Reparata", "9-9": "S. Dionigi, S. Ferruccio", "9-10": "S. Daniele M.",
"9-11": "S. Firmino Vescovo", "9-12": "S. Serafino Capp.", "9-13": "S. Edoardo Re", "9-14": "S. Callisto I Papa", "9-15": "S. Teresa d'Avila",
"9-16": "S. Edvige, S. Margherita", "9-17": "S. Ignazio d'A.", "9-18": "S. Luca Evang.", "9-19": "S. Isacco M., S. Laura", "9-20": "S. Irene",
"9-21": "S. Orsola", "9-22": "S. Donato Vescovo", "9-23": "S. Giovanni da C.", "9-24": "S. Antonio M.C.", "9-25": "S. Crispino, S. Daria",
"9-26": "S. Evaristo Papa", "9-27": "S. Fiorenzo Vescovo", "9-28": "S. Simone", "9-29": "S. Ermelinda, S. Massimiliano", "9-30": "S. Germano Vescovo", "9-31": "S. Lucilla, S. Quintino",
// NOVEMBRE
"10-1": "Tutti i Santi", "10-2": "Commemoraz. Defunti", "10-3": "S. Martino, S. Silvia", "10-4": "S. Carlo Borromeo", "10-5": "S. Zaccaria Prof.",
"10-6": "S. Leonardo Abate", "10-7": "S. Ernesto Abate", "10-8": "S. Goffredo Vescovo", "10-9": "S. Oreste, S. Ornella", "10-10": "S. Leone Magno",
"10-11": "S. Martino di Tours", "10-12": "S. Renato M., S. Elsa", "10-13": "S. Diego, S. Omobono", "10-14": "S. Giocondo Vescovo", "10-15": "S. Alberto M., S. Arturo",
"10-16": "S. Margherita di S.", "10-17": "S. Elisabetta", "10-18": "S. Oddone Ab.", "10-19": "S. Fausto Martire", "10-20": "S. Benigno",
"10-21": "Presentaz. B.V. Maria", "10-22": "S. Cecilia V.", "10-23": "S. Clemente Papa", "10-24": "Cristo Re, S. Flora", "10-25": "S. Caterina d'Aless.",
"10-26": "S. Corrado Vescovo", "10-27": "S. Massimo, S. Virgilio", "10-28": "S. Giacomo Franc.", "10-29": "I d'Avvento", "10-30": "S. Andrea Ap., S. Duccio",
// DICEMBRE
"11-1": "S. Ansano", "11-2": "S. Bibiana, S. Savino", "11-3": "S. Francesco Saverio", "11-4": "S. Barbara, S. Giovanni Dam.", "11-5": "S. Giulio M.",
"11-6": "II d'Avvento", "11-7": "S. Ambrogio Vescovo", "11-8": "Immacolata Concezione", "11-9": "S. Siro", "11-10": "N.S. di Loreto",
"11-11": "S. Damaso Papa", "11-12": "S. Giovanna F.", "11-13": "III d'Avvento", "11-14": "S. Giovanni d.Cr.", "11-15": "S. Valeriano",
"11-16": "S. Albina", "11-17": "S. Lazzaro", "11-18": "S. Graziano Vescovo", "11-19": "S. Fausta, S. Dario", "11-20": "IV d'Avvento",
"11-21": "S. Pietro Canisio", "11-22": "S. Francesca Cabrini", "11-23": "S. Giovanni da K.", "11-24": "S. Delfino", "11-25": "Natale del Signore",
"11-26": "S. Stefano Protom.", "11-27": "S. Giovanni Ap.", "11-28": "SS. Innocenti Martiri", "11-29": "S. Tommaso Becket", "11-30": "S. Eugenio V., S. Ruggero", "11-31": "S. Silvestro Papa"
};
// Feste "rosse" fisse e mobili principali (oltre le domeniche)
const redDays = [
"0-1", "0-6", "3-5", "3-6", "3-25", "4-1", "5-2", "7-15", "10-1", "11-8", "11-25", "11-26"
];
const months = [
"Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno",
"Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"
];
const daysOfWeek = ["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"];
const daysOfWeekShort = ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"];
const zodiacSigns = [
{ name: "Capricorno", startMonth: 11, startDay: 22, endMonth: 0, endDay: 20, icon: "β™‘" },
{ name: "Acquario", startMonth: 0, startDay: 21, endMonth: 1, endDay: 19, icon: "β™’" },
{ name: "Pesci", startMonth: 1, startDay: 20, endMonth: 2, endDay: 20, icon: "β™“" },
{ name: "Ariete", startMonth: 2, startDay: 21, endMonth: 3, endDay: 20, icon: "β™ˆ" },
{ name: "Toro", startMonth: 3, startDay: 21, endMonth: 4, endDay: 20, icon: "♉" },
{ name: "Gemelli", startMonth: 4, startDay: 21, endMonth: 5, endDay: 21, icon: "β™Š" },
{ name: "Cancro", startMonth: 5, startDay: 22, endMonth: 6, endDay: 22, icon: "β™‹" },
{ name: "Leone", startMonth: 6, startDay: 23, endMonth: 7, endDay: 23, icon: "β™Œ" },
{ name: "Vergine", startMonth: 7, startDay: 24, endMonth: 8, endDay: 22, icon: "♍" },
{ name: "Bilancia", startMonth: 8, startDay: 23, endMonth: 9, endDay: 22, icon: "β™Ž" },
{ name: "Scorpione", startMonth: 9, startDay: 23, endMonth: 10, endDay: 22, icon: "♏" },
{ name: "Sagittario", startMonth: 10, startDay: 23, endMonth: 11, endDay: 21, icon: "♐" }
];
// --- FUNZIONI UTILI ---
function setTheme(primary, sidebar, sidebarHeader) {
const r = document.querySelector(':root');
r.style.setProperty('--primary-color', primary);
r.style.setProperty('--sidebar-bg', sidebar);
r.style.setProperty('--sidebar-header-bg', sidebarHeader);
// Se siamo in B/N, disattiviamolo quando si sceglie un colore
document.getElementById('bwCheckbox').checked = false;
document.body.classList.remove('monochrome');
}
function toggleBW() {
document.body.classList.toggle('monochrome');
}
function getDaysInMonth(month, year) {
return new Date(year, month + 1, 0).getDate();
}
function isHoliday(day, month) {
return redDays.includes(`${month}-${day}`);
}
function getSaintName(day, month) {
const key = `${month}-${day}`;
return saintsData[key] || "";
}
function getDayOfYear(day, month, year) {
const start = new Date(year, 0, 0);
const diff = (new Date(year, month, day) - start) + ((start.getTimezoneOffset() - new Date(year, month, day).getTimezoneOffset()) * 60 * 1000);
const oneDay = 1000 * 60 * 60 * 24;
return Math.floor(diff / oneDay);
}
function getZodiac(month, day) {
for (let z of zodiacSigns) {
if (z.startMonth === month && day >= z.startDay) return z;
if (z.endMonth === month && day <= z.endDay) return z;
if (z.startMonth === 11 && month === 11 && day >= z.startDay) return z;
if (z.endMonth === 0 && month === 0 && day <= z.endDay) return z;
}
return zodiacSigns[0];
}
function getZodiacForMonthHeader(month) {
let sign1 = zodiacSigns.find(z => z.endMonth === month);
let sign2 = zodiacSigns.find(z => z.startMonth === month);
return [sign1, sign2];
}
// --- GENERATORE DI HTML ---
function createMiniSidebar(monthIndex, year) {
let targetYear = year;
if (monthIndex < 0) { monthIndex = 11; targetYear--; }
if (monthIndex > 11) { monthIndex = 0; targetYear++; }
const days = getDaysInMonth(monthIndex, targetYear);
const monthName = months[monthIndex];
let html = `<div class="sidebar">`;
html += `<div class="sidebar-header">${monthName} ${targetYear}</div>`;
for (let i = 1; i <= days; i++) {
let date = new Date(targetYear, monthIndex, i);
let dayOfWeek = date.getDay();
let isSun = dayOfWeek === 0;
let isHol = isHoliday(i, monthIndex);
let rowClass = (isSun || isHol) ? 'sunday' : '';
html += `
<div class="mini-day-row ${rowClass}">
<span class="mini-day-num">${i}</span>
<span class="mini-day-name">${daysOfWeekShort[dayOfWeek]}</span>
</div>
`;
}
html += `</div>`;
return html;
}
function createMainColumn(startDay, endDay, month, year) {
let html = `<div class="column">`;
for (let i = startDay; i <= endDay; i++) {
if (i > getDaysInMonth(month, year)) {
html += `<div class="day-row" style="border-bottom:none"></div>`;
continue;
}
let date = new Date(year, month, i);
let dayIdx = date.getDay();
let isSun = dayIdx === 0;
let isHol = isHoliday(i, month);
let rowClass = (isSun || isHol) ? 'is-sunday' : '';
let dayName = daysOfWeek[dayIdx];
let saint = getSaintName(i, month);
let doY = getDayOfYear(i, month, year);
let daysLeft = 365 - doY;
// Fasi lunari simulate
let moonIcon = "";
if (i === 3 || i === 18) moonIcon = "πŸŒ‘";
if (i === 10 || i === 25) moonIcon = "πŸŒ•";
html += `
<div class="day-row ${rowClass}">
<div class="day-big-num">${i}</div>
<div class="day-info">
<div class="day-name">${dayName}</div>
<div class="day-saint">${saint}</div>
</div>
<div class="day-meta">
${moonIcon ? `<span class="moon-phase">${moonIcon}</span>` : ''}
<span>${doY}-${daysLeft}</span>
</div>
</div>
`;
}
html += `</div>`;
return html;
}
function generateCalendar() {
const root = document.getElementById('calendar-root');
root.innerHTML = '';
const year = 2026;
for (let m = 0; m < 12; m++) {
const page = document.createElement('div');
page.className = 'page';
const [z1, z2] = getZodiacForMonthHeader(m);
const headerHTML = `
<header>
<div class="zodiac">
<span class="zodiac-icon">${z1.icon}</span>
<span>${z1.name.toUpperCase()}</span>
<span style="font-size:8px">fino al ${z1.endDay}</span>
</div>
<div class="month-title">${months[m]} ${year}</div>
<div class="zodiac">
<span class="zodiac-icon">${z2.icon}</span>
<span>${z2.name.toUpperCase()}</span>
<span style="font-size:8px">dal ${z2.startDay}</span>
</div>
</header>
`;
const sidebarLeft = createMiniSidebar(m - 1, year);
const sidebarRight = createMiniSidebar(m + 1, year);
const col1 = createMainColumn(1, 16, m, year);
const col2 = createMainColumn(17, 31, m, year);
const bodyHTML = `
<div class="main-container">
${sidebarLeft}
<div class="content">
${col1}
${col2}
</div>
${sidebarRight}
</div>
`;
const footerHTML = `
<footer>
<div>Sole: Sorge 07:30 - Tramonta 16:50 (Orari indicativi Roma)</div>
<div>πŸŒ‘ Luna Nuova πŸŒ• Luna Piena</div>
<div>Calendario generato per l'anno 2026</div>
</footer>
`;
page.innerHTML = headerHTML + bodyHTML + footerHTML;
root.appendChild(page);
}
}
generateCalendar();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment