1<!DOCTYPE html> 2<html lang="es"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta name="description" content="Calendario Lunar Mensual"> 7 <meta name="theme-color" content="#1a1a2e"> 8 9 <title>Calendario - Lunar App</title> 10 11 <!-- Google Fonts --> 12 <link rel="preconnect" href="https://fonts.googleapis.com"> 13 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 14 <link href="https://fonts.googleapis.com/css2?family=Cinzel:wght@400;600&family=Cormorant+Garamond:wght@300;400;600&display=swap" rel="stylesheet"> 15 16 <link rel="manifest" href="/static/manifest.json"> 17 <link rel="stylesheet" href="/static/css/style.css"> 18 19
19<script src="/static/js/luna-realista.js"></script>
19 20
20<script src="https://unpkg.com/@astrodraw/astrochart"></script>
20 21 <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" /> 22
22<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
22 23 24 <style> 25 * { 26 box-sizing: border-box; 27 } 28 29 body { 30 overflow-x: hidden; 31 } 32 33 .main-container { 34 width: 100%; 35 max-width: 100%; 36 overflow-x: hidden; 37 padding: 1rem; 38 } 39 40 .card { 41 width: 100%; 42 max-width: 100%; 43 overflow-x: hidden; 44 } 45 46 .calendario-controles { 47 display: flex; 48 justify-content: space-between; 49 align-items: center; 50 margin-bottom: 2rem; 51 flex-wrap: wrap; 52 gap: 1rem; 53 } 54 55 .calendario-mes { 56 font-size: 1.5rem; 57 color: var(--color-luna); 58 } 59 60 .calendario-botones button { 61 background: var(--color-acento); 62 color: var(--color-texto); 63 border: none; 64 padding: 0.5rem 1rem; 65 margin: 0 0.25rem; 66 border-radius: 6px; 67 cursor: pointer; 68 transition: var(--transicion); 69 } 70 71 .calendario-botones button:hover { 72 background: var(--color-destacado); 73 } 74 75 .calendario-grid { 76 display: grid; 77 grid-template-columns: repeat(7, 1fr); 78 gap: 0.5rem; 79 width: 100%; 80 max-width: 100%; 81 overflow-x: hidden; 82 } 83 84 .calendario-header { 85 background: var(--color-acento); 86 padding: 0.75rem; 87 text-align: center; 88 font-weight: bold; 89 border-radius: 6px; 90 font-size: 0.9rem; 91 } 92 93 .calendario-dia { 94 background: var(--color-secundario); 95 padding: 1rem; 96 border-radius: 8px; 97 text-align: center; 98 min-height: 100px; 99 display: flex; 100 flex-direction: column; 101 justify-content: space-between; 102 transition: var(--transicion); 103 cursor: pointer; 104 } 105 106 .calendario-dia:hover { 107 background: var(--color-acento); 108 transform: translateY(-2px); 109 } 110 111 .dia-numero { 112 font-size: 1.2rem; 113 font-weight: bold; 114 color: var(--color-texto); 115 } 116 117 .dia-fase { 118 width: 50px; 119 height: 50px; 120 margin: 0.5rem auto; 121 display: flex; 122 align-items: center; 123 justify-content: center; 124 } 125 126 .dia-fase canvas { 127 max-width: 100%; 128 max-height: 100%; 129 } 130 131 .dia-signo { 132 font-size: 1.2rem; 133 color: var(--color-texto-secundario); 134 } 135 136 .dia-otro-mes { 137 opacity: 0.3; 138 } 139 140 @media (max-width: 768px) { 141 .calendario-grid { 142 grid-template-columns: repeat(7, 1fr); 143 gap: 2px; 144 width: 100%; 145 padding: 0; 146 } 147 148 .calendario-header { 149 padding: 0.4rem 0.1rem; 150 font-size: 0.65rem; 151 border-radius: 4px; 152 } 153 154 .calendario-dia { 155 padding: 0.3rem 0.1rem; 156 min-height: 60px; 157 border-radius: 4px; 158 } 159 160 .dia-numero { 161 font-size: 0.85rem; 162 } 163 164 .dia-fase { 165 width: 30px; 166 height: 30px; 167 margin: 0.2rem auto; 168 } 169 170 .dia-signo { 171 font-size: 0.6rem; 172 display: none; /* Ocultar en móvil para ahorrar espacio */ 173 } 174 175 .main-container { 176 padding: 0.5rem; 177 } 178 179 .calendario-controles { 180 flex-direction: column; 181 gap: 1rem; 182 } 183 184 .calendario-mes { 185 font-size: 1.2rem; 186 order: -1; 187 } 188 189 .calendario-botones { 190 width: 100%; 191 display: flex; 192 justify-content: space-between; 193 } 194 195 .calendario-botones button { 196 font-size: 0.8rem; 197 padding: 0.5rem 0.8rem; 198 } 199 } 200 </style> 201</head> 202<body> 203 <!-- Header --> 204 <header class="header"> 205 <div class="container"> 206 <div class="logo-section"> 207 <img src="/static/images/logo_urania.png" alt="La Nación de Urania" class="logo-img"> 208 <div class="logo-text-container"> 209 <h1 class="logo">LA NACIÃN DE URANIA</h1> 210 <p class="logo-subtitle">Organización Astrológica</p> 211 </div> 212 </div> 213 214 <!-- Botón hamburguesa (solo móvil) --> 215 <button class="menu-toggle" id="menu-toggle">
216 <span class="hamburger-line"></span> 217 <span class="hamburger-line"></span> 218 <span class="hamburger-line"></span> 219 </button> 220 221 <nav class="nav" id="main-nav"> 222 <a href="/" class="nav-link">Inicio</a> 223 <a href="/calendario" class="nav-link active">Calendario</a> 224 <a href="/eclipses" class="nav-link">Eclipses</a> 225 <a href="/streaming" class="nav-link">Streaming</a> 226 <a href="/carta-natal" class="nav-link">Carta Natal</a> 227 <a href="/notificaciones" class="nav-link">Notificaciones</a> 228 </nav> 229 </div> 230 </header> 231 232 <!-- Overlay para cerrar menú al hacer click fuera (solo móvil) --> 233 <div class="menu-overlay" id="menu-overlay"></div> 234 235 <!-- Contenedor Principal --> 236 <main class="main-container"> 237 <section class="card"> 238 <div class="calendario-controles"> 239 <div class="calendario-botones"> 240 <button onclick="cambiarMes(-1)">â Anterior</button> 241 <button onclick="mesActual()">Hoy</button> 242 <button onclick="cambiarMes(1)">Siguiente â</button> 243 </div> 244 <input type="month" id="selector-mes" onchange="irAMesSeleccionado()" 245 style="padding: 0.7rem 1rem; border-radius: 8px; background: #ffffff; color: #000000; border: 3px solid #d4af37; font-family: 'Cormorant Garamond', serif; cursor: pointer; font-size: 1.1rem; font-weight: 600; box-shadow: 0 4px 12px rgba(212, 175, 55, 0.5); min-width: 180px;"> 246 <h2 class="calendario-mes" id="titulo-mes">Cargando...</h2> 247 </div> 248 249 <!-- DÃas de la semana --> 250 <div class="calendario-grid"> 251 <div class="calendario-header">Dom</div> 252 <div class="calendario-header">Lun</div> 253 <div class="calendario-header">Mar</div> 254 <div class="calendario-header">Mié</div> 255 <div class="calendario-header">Jue</div> 256 <div class="calendario-header">Vie</div> 257 <div class="calendario-header">Sáb</div> 258 </div> 259 260 <!-- DÃas del mes --> 261 <div class="calendario-grid" id="calendario-dias"> 262 <!-- Se llenará con JavaScript --> 263 </div> 264 </section> 265 266 <!-- Volver a inicio --> 267 <div class="acciones"> 268 <button class="btn-actualizar" onclick="window.location.href='/'"> 269 â Volver a Inicio 270 </button> 271 </div> 272 </main> 273 274 <!-- Footer --> 275 <footer class="footer"> 276 <p style="font-family: 'Cinzel', serif; color: var(--color-dorado); margin-bottom: 0.5rem;">© 2025 La Nación de Urania</p> 277 <p style="margin: 0.25rem 0;"> 278 <a href="https://www.escuelaurania.com" target="_blank" style="color: var(--color-enlace); text-decoration: none;">www.escuelaurania.com</a> 279 - 280 <a id="email-link" style="color: var(--color-enlace); text-decoration: none; cursor: pointer;">cargando...</a> 281 </p> 282 <p style="margin: 0.25rem 0;"> 283 ð± <a href="https://wa.me/5492944312096" target="_blank" style="color: var(--color-enlace); text-decoration: none;">WhatsApp: +54 9 294 431-2096</a> 284 </p> 285 </footer> 286 287
287<script> 288 // Detectar zona horaria del usuario automáticamente 289 const userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone; 290 console.log(`ð Zona horaria detectada: ${userTimezone}`); 291 292 let mesActualVista = new Date().getMonth() + 1; 293 let yearActualVista = new Date().getFullYear(); 294 295 const meses = [ 296 'Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 297 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre' 298 ]; 299 300 async function cargarCalendario() { 301 try { 302 const response = await fetch(`/api/calendario/mes?year=${yearActualVista}&month=${mesActualVista}`); 303 const data = await response.json(); 304 305 if (data.exito) { 306 document.getElementById('titulo-mes').textContent = 307 `${meses[mesActualVista - 1]} ${yearActualVista}`; 308 309 const calendarioDias = document.getElementById('calendario-dias'); 310 calendarioDias.innerHTML = ''; 311 312 // Calcular dÃa de la semana del primer dÃa del mes 313 const primerDia = new Date(yearActualVista, mesActualVista - 1, 1); 314 const diaSemana = primerDia.getDay(); 315 316 // Agregar dÃas vacÃos al inicio 317 for (let i = 0; i < diaSemana; i++) { 318 const diaVacio = document.createElement('div'); 319 diaVacio.className = 'calendario-dia dia-otro-mes'; 320 calendarioDias.appendChild(diaVacio); 321 } 322 323 // Agregar dÃas del mes 324 data.dias.forEach((dia, index) => { 325 const diaDiv = document.createElement('div'); 326 diaDiv.className = 'calendario-dia'; 327 diaDiv.style.cursor = 'pointer'; // Indicar que es clickeable 328 329 // Crear estructura HTML 330 diaDiv.innerHTML = ` 331 <div class="dia-numero">${dia.dia}</div> 332 <div class="dia-fase" id="dia-fase-${index}"></div> 333 <div class="dia-signo">${dia.signo}</div> 334 `; 335 336 calendarioDias.appendChild(diaDiv); 337 338 // Agregar evento click para abrir modal DESPUÃS de agregar al DOM 339 diaDiv.addEventListener('click', () => { 340 abrirModalDia(yearActualVista, mesActualVista, dia.dia); 341 }); 342 343 // Renderizar luna realista después de agregar al DOM 344 setTimeout(() => { 345 const faseContainer = document.getElementById(`dia-fase-${index}`); 346 if (window.lunaRealista && faseContainer) { 347 window.lunaRealista.renderizar( 348 faseContainer, 349 dia.dia_ciclo, 350 50 // Tamaño pequeño para calendario 351 ); 352 } 353 }, 10); 354 }); 355 } 356 } catch (error) { 357 console.error('Error al cargar calendario:', error); 358 document.getElementById('calendario-dias').innerHTML = 359 '<div class="loading" style="grid-column: 1/-1;">Error al cargar calendario</div>'; 360 } 361 } 362 363 function cambiarMes(incremento) { 364 mesActualVista += incremento; 365 366 if (mesActualVista > 12) { 367 mesActualVista = 1; 368 yearActualVista++; 369 } else if (mesActualVista < 1) { 370 mesActualVista = 12; 371 yearActualVista--; 372 } 373 374 cargarCalendario(); 375 actualizarSelectorMes(); 376 } 377 378 function mesActual() { 379 mesActualVista = new Date().getMonth() + 1; 380 yearActualVista = new Date().getFullYear(); 381 cargarCalendario(); 382 actualizarSelectorMes(); 383 } 384 385 function irAMesSeleccionado() { 386 const selector = document.getElementById('selector-mes'); 387 if (!selector.value) return; // Si no hay valor, salir 388 389 const [year, month] = selector.value.split('-'); 390 const yearNum = parseInt(year); 391 const monthNum = parseInt(month); 392 393 // Validar valores 394 if (isNaN(yearNum) || isNaN(monthNum)) return; 395 if (yearNum < 1900 || yearNum > 2100) return; 396 if (monthNum < 1 || monthNum > 12) return; 397 398 yearActualVista = yearNum; 399 mesActualVista = monthNum; 400 cargarCalendario(); 401 } 402 403 function actualizarSelectorMes() { 404 const selector = document.getElementById('selector-mes'); 405 const mesStr = mesActualVista.toString().padStart(2, '0'); 406 selector.value = `${yearActualVista}-${mesStr}`; 407 } 408 409 // ===== MODAL DE DATOS DEL DÃA ===== 410 411 let modalDiaActual = { year: null, month: null, day: null }; 412 413 async function abrirModalDia(year, month, day) { 414 modalDiaActual = { year, month, day }; 415 const modal = document.getElementById('modal-dia');
416 const overlay = document.getElementById('modal-dia-overlay'); 417 const titulo = document.getElementById('modal-dia-titulo'); 418 const body = document.getElementById('modal-dia-body'); 419 420 // Mostrar modal con loading 421 overlay.classList.add('active'); 422 document.body.style.overflow = 'hidden'; 423 titulo.textContent = `${day} de ${meses[month - 1]} ${year}`; 424 body.innerHTML = ` 425 <div class="loading-container"> 426 <div class="loading-spinner"> 427 <div class="loading-spinner-luna">ð</div> 428 </div> 429 <div class="loading-text">Cargando datos lunares...</div> 430 </div> 431 `; 432 433 try { 434 // Llamar a la API 435 const response = await fetch(`/api/calendario/dia?year=${year}&month=${month}&day=${day}&timezone=${encodeURIComponent(userTimezone)}`); 436 const data = await response.json(); 437 438 if (data.exito) { 439 mostrarDatosEnModal(data); 440 } else { 441 body.innerHTML = '<div class="error">Error al cargar datos</div>'; 442 } 443 } catch (error) { 444 console.error('Error al cargar datos del dÃa:', error); 445 body.innerHTML = '<div class="error">Error al cargar datos</div>'; 446 } 447 } 448 449 // Función GLOBAL para sÃmbolos 450 function getSignoSimbolo(signo) { 451 const simbolos = { 452 'Aries': 'â', 'Tauro': 'â', 'Géminis': 'â', 'Cáncer': 'â', 453 'Leo': 'â', 'Virgo': 'â', 'Libra': 'â', 'Escorpio': 'â', 454 'Sagitario': 'â', 'Capricornio': 'â', 'Acuario': 'â', 'Piscis': 'â' 455 }; 456 return simbolos[signo] || signo; 457 } 458 459 // Función GLOBAL para sÃmbolos zodiacales 460 function getSignoSimbolo(signo) { 461 const simbolos = { 462 'Aries': 'â', 'Tauro': 'â', 'Géminis': 'â', 'Cáncer': 'â', 463 'Leo': 'â', 'Virgo': 'â', 'Libra': 'â', 'Escorpio': 'â', 464 'Sagitario': 'â', 'Capricornio': 'â', 'Acuario': 'â', 'Piscis': 'â' 465 }; 466 return simbolos[signo] || signo; 467 } 468 469 // Formatear fecha legible (24/dic/2025 - 22:54:13) 470 function formatearFecha(fechaStr) { 471 if (!fechaStr) return ""; 472 const meses = ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"]; 473 const partes = fechaStr.split(" "); 474 if (partes.length !== 2) return fechaStr; 475 const [fecha, hora] = partes; 476 const [año, mes, dia] = fecha.split("-"); 477 return `${dia}/${meses[parseInt(mes)-1]}/${año} - ${hora}`; 478 } 479 480 function mostrarDatosEnModal(data) { 481 const body = document.getElementById('modal-dia-body'); 482 483 const LILITH = 'â¸'; 484 const PRIAPO = 'â®'; 485 486 const tipoIcono = data.tipo_modal === 'actual' ? 'â°' : 487 data.tipo_modal === 'futuro' ? 'ð®' : 'ð '; 488 const tipoTexto = data.tipo_modal === 'actual' ? 'Tiempo Real' : 489 data.tipo_modal === 'futuro' ? 'Datos Futuros' : 'Datos Pasados'; 490 491 let html = ` 492 <div style="display: flex; justify-content: space-between; margin-bottom: 1rem; gap: 1rem;"> 493 <button onclick="navegarModalDia(-1)" style="flex: 1; padding: 0.5rem; cursor: pointer; background: var(--color-acento); border: none; border-radius: 6px; color: var(--color-texto); font-weight: bold;">â Anterior</button> 494 <button onclick="navegarModalDia(1)" style="flex: 1; padding: 0.5rem; cursor: pointer; background: var(--color-acento); border: none; border-radius: 6px; color: var(--color-texto); font-weight: bold;">Siguiente â</button> 495 </div> 496 497 <div class="modal-luna-visual"> 498 <div class="modal-luna-container" id="modal-luna-render"></div> 499 </div> 500 501 <div style="text-align: center; padding: 0.5rem; background: rgba(100, 149, 237, 0.1); border-radius: 6px; margin-bottom: 1rem; font-size: 0.9rem;"> 502 ${tipoIcono} ${tipoTexto}${data.hora_calculo ? ': ' + data.hora_calculo : ''} 503 </div> 504 `; 505 506 if (data.fase_lunar.es_fase_exacta) { 507 html += ` 508 <div style="background: rgba(212, 175, 55, 0.2); border: 2px solid var(--color-dorado); border-radius: 6px; padding: 0.8rem; margin-bottom: 1rem;"> 509 <div style="font-weight: bold; margin-bottom: 0.5rem;">â Fase Exacta</div> 510 <div style="font-size: 0.9rem;">${data.fase_lunar.emoji} ${data.fase_lunar.nombre} a las ${data.fase_lunar.hora_exacta}</div> 511 <div style="font-size: 0.85rem; color: var(--color-texto-secundario);">Posición: <span class="signo-simbolo">${getSignoSimbolo(data.fase_lunar.signo_fase_exacta)}</span> ${data.fase_lunar.grado_fase_exacta}</div> 512 </div> 513 `; 514 } 515 516 html += ` 517 <div style="background: var(--color-secundario); padding: 1rem; border-radius: 8px; line-height: 2; font-size: 0.95rem;"> 518 <div><strong>ð Fase:</strong> ${data.fase_lunar.emoji} ${data.fase_lunar.nombre}</div> 519 <div><strong>ð¡ Iluminación:</strong> ${data.fase_lunar.iluminacion}%</div> 520 `; 521 522 if (data.posicion) { 523 if (data.tipo_modal === 'actual') { 524 html += `<div><strong>Signo:</strong> <span class="signo-simbolo">
524${getSignoSimbolo(data.posicion.signo)}</span> ${data.posicion.signo} ${data.posicion.grado_sexagesimal}</div>`; 525 } else { 526 html += `<div><strong>Signo:</strong> <span class="signo-simbolo">${getSignoSimbolo(data.posicion.signo)}</span> ${data.posicion.signo} <em>(valor medio)</em></div>`; 527 } 528 } 529 530 html += `<div><strong>ð DÃa Lunar:</strong> ${data.fase_lunar.dia_lunar}</div>`; 531 532 if (data.nodo_norte) { 533 if (data.tipo_modal === 'actual') { 534 html += `<div><strong>â Nodo Norte:</strong> <span class="signo-simbolo">${getSignoSimbolo(data.nodo_norte.signo)}</span> ${data.nodo_norte.signo} ${data.nodo_norte.grado_sexagesimal}</div>`; 535 } else { 536 html += `<div><strong>â Nodo Norte:</strong> <span class="signo-simbolo">${getSignoSimbolo(data.nodo_norte.signo)}</span> ${data.nodo_norte.signo} <em>(valor medio)</em></div>`; 537 } 538 } 539 540 if (data.distancia) { 541 html += `<div><strong>ð Valor Distancia:</strong> ${data.distancia.porcentaje}%`; 542 if (data.distancia.lilith) { 543 html += ` ${LILITH} <strong style="color: #D4AF37;">Luna con Lilith</strong>`; 544 } 545 if (data.distancia.priapo) { 546 html += ` ${PRIAPO} <strong style="color: #D4AF37;">Luna con PrÃapo</strong>`; 547 } 548 html += `</div>`; 549 } 550 551 if (data.proximo_ingreso) { 552 html += `<div><strong>ðª Próximo Ingreso:</strong> ${formatearFecha(data.proximo_ingreso.fecha + " " + data.proximo_ingreso.hora)} â <span class="signo-simbolo">${getSignoSimbolo(data.proximo_ingreso.signo)}</span> ${data.proximo_ingreso.signo} 0°00'00"</div>`; 553 } 554 555 if (data.void_of_course) { 556 if (data.void_of_course.mayores.activo) { 557 html += `<div><strong>ð VacÃa de Curso (Aspectos Mayores):</strong> <span style="color: #FF6347;">ACTIVA</span> ${formatearFecha(data.void_of_course.mayores.inicio)} hasta ${formatearFecha(data.void_of_course.mayores.fin)}</div>`; 558 } else { 559 html += `<div><strong>ð VacÃa de Curso (Aspectos Mayores):</strong> <span style="color: #90EE90;">No activa</span></div>`; 560 } 561 562 if (data.void_of_course.todos.activo) { 563 html += `<div><strong>ð VacÃa de Curso (Menores y Mayores):</strong> <span style="color: #FF6347;">ACTIVA</span> ${formatearFecha(data.void_of_course.todos.inicio)} hasta ${formatearFecha(data.void_of_course.todos.fin)}</div>`; 564 } else { 565 html += `<div><strong>ð VacÃa de Curso (Menores y Mayores):</strong> <span style="color: #90EE90;">No activa</span></div>`; 566 } 567 } 568 569 // Tithi Hindú 570 if (data.fase_lunar.tithi_nombre) { 571 html += ` 572 <div style="margin-top: 1rem; padding: 0.8rem; background: rgba(255, 165, 0, 0.1); border-radius: 6px;"> 573 <div style="font-weight: bold; margin-bottom: 0.5rem;">ðï¸ Zodiaco Hindú (Tithi): ${data.fase_lunar.tithi_nombre}</div> 574 <div style="font-size: 0.85rem; font-style: italic; color: var(--color-texto-secundario);"> 575 ${data.fase_lunar.tithi_interpretacion} 576 </div> 577 </div> 578 `; 579 } 580 581 html += `</div>`; 582 583 // BOTON VER CARTA NATAL para TODOS los dias 584 if (data.fase_lunar.es_fase_exacta && data.fase_lunar.jd_fase_exacta) { 585 // Fases exactas: usar JD del momento exacto de la fase 586 html += `<div style="text-align:center;margin-top:1rem;"><button onclick="cfAbrirCarta(${data.fase_lunar.jd_fase_exacta}, '${data.fase_lunar.emoji} ${data.fase_lunar.nombre}')" style="background:linear-gradient(135deg,#d4af37,#b8962e);color:#0f0f1e;border:none;padding:0.6rem 1.5rem;border-radius:8px;font-weight:700;font-size:0.9rem;cursor:pointer;font-family:Cinzel,serif;">🔮 VER CARTA NATAL</button></div>`; 587 } else if (typeof cfJDParaDia === 'function') { 588 // Dias normales: usar hora local del momento de consulta 589 var jdLocal = cfJDParaDia(modalDiaActual.year, modalDiaActual.month, modalDiaActual.day); 590 html += `<div style="text-align:center;margin-top:1rem;"><button onclick="cfAbrirCarta(${jdLocal}, '${data.fase_lunar.emoji} ${data.fase_lunar.nombre} (hora local)')" style="background:linear-gradient(135deg,#d4af37,#b8962e);color:#0f0f1e;border:none;padding:0.6rem 1.5rem;border-radius:8px;font-weight:700;font-size:0.9rem;cursor:pointer;font-family:Cinzel,serif;">🔮 VER CARTA NATAL</button></div>`; 591 } 592 593 body.innerHTML = html; 594 595 setTimeout(() => { 596 const lunaContainer = document.getElementById('modal-luna-render'); 597 if (window.lunaRealista && lunaContainer) { 598 window.lunaRealista.renderizar(lunaContainer, data.fase_lunar.dia_ciclo, 150); 599 } 600 }, 50); 601 } 602
603 function navegarModalDia(direccion) { 604 let { year, month, day } = modalDiaActual; 605 let fecha = new Date(year, month - 1, day); 606 fecha.setDate(fecha.getDate() + direccion); 607 abrirModalDia(fecha.getFullYear(), fecha.getMonth() + 1, fecha.getDate()); 608 } 609 610 function cerrarModal() { 611 const overlay = document.getElementById('modal-dia-overlay'); 612 overlay.classList.remove('active'); 613 document.body.style.overflow = ''; 614 } 615 616 // Cargar calendario al iniciar 617 window.onload = function() { 618 // Inicializar variables con mes actual 619 const hoy = new Date(); 620 currentMonth = hoy.getMonth() + 1; 621 currentYear = hoy.getFullYear(); 622 623 // Inicializar selector de fecha 624 actualizarSelectorMes(); 625 626 // Cargar calendario 627 cargarCalendario(currentMonth, currentYear); 628 629 // Event listeners del modal (después de que el DOM esté listo) 630 document.getElementById('modal-dia-close').addEventListener('click', cerrarModal); 631 document.getElementById('modal-dia-overlay').addEventListener('click', function(e) { 632 if (e.target === this) { 633 cerrarModal(); 634 } 635 }); 636 }; 637 </script>
637 638 639 <!-- JavaScript del menú hamburguesa --> 640
640<script> 641 const menuToggle = document.getElementById('menu-toggle'); 642 const mainNav = document.getElementById('main-nav'); 643 const menuOverlay = document.getElementById('menu-overlay'); 644 645 // Abrir/cerrar menú 646 menuToggle.addEventListener('click', function() { 647 menuToggle.classList.toggle('active'); 648 mainNav.classList.toggle('active'); 649 menuOverlay.classList.toggle('active'); 650 651 // Bloquear scroll del body cuando menú abierto 652 document.body.style.overflow = mainNav.classList.contains('active') ? 'hidden' : ''; 653 654 // Tracking Firebase (si está disponible) 655 if (window.trackEvent) { 656 window.trackEvent('menu_toggle', { 657 accion: mainNav.classList.contains('active') ? 'abrir' : 'cerrar' 658 }); 659 } 660 }); 661 662 // Cerrar al hacer click en overlay 663 menuOverlay.addEventListener('click', function() { 664 menuToggle.classList.remove('active'); 665 mainNav.classList.remove('active'); 666 menuOverlay.classList.remove('active'); 667 document.body.style.overflow = ''; 668 }); 669 670 // Cerrar al hacer click en un link 671 mainNav.querySelectorAll('.nav-link').forEach(link => { 672 link.addEventListener('click', function() { 673 menuToggle.classList.remove('active'); 674 mainNav.classList.remove('active'); 675 menuOverlay.classList.remove('active'); 676 document.body.style.overflow = ''; 677 }); 678 }); 679 </script>
679 680 681 <!-- Modal de datos del dÃa --> 682 <div class="modal-overlay" id="modal-dia-overlay"> 683 <div class="modal-calendario" id="modal-dia"> 684 <div class="modal-header"> 685 <h2 class="modal-titulo" id="modal-dia-titulo">Cargando...</h2> 686 <button class="modal-close" id="modal-dia-close">Ã</button> 687 </div> 688 <div class="modal-body" id="modal-dia-body"> 689 <div class="loading-container"> 690 <div class="loading-spinner"> 691 <div class="loading-spinner-luna">ð</div> 692 </div> 693 <div class="loading-text">Cargando fases lunares...</div> 694 </div> 695 </div> 696 </div> 697 </div> 698 699<!-- Modal Carta Natal Fases (z-index 10000 > modal calendario 9998) --> 700<div id="cf-modal-carta" style="display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.92);z-index:10000;overflow-y:auto;padding:0.5rem;"> 701 <div style="max-width:960px;margin:0 auto;background:#0f0f1e;border-radius:12px;border:1px solid #2a2a4a;overflow:hidden;"> 702 <div style="display:flex;justify-content:space-between;align-items:center;padding:1rem 1.5rem;background:linear-gradient(135deg,#1a1a3e,#0d0d2a);border-bottom:1px solid #d4af37;"> 703 <h2 id="cf-carta-titulo" style="color:#d4af37;font-family:'Cinzel',serif;font-size:1.1rem;margin:0;">Carta Natal</h2> 704 <button id="cf-btn-cerrar" style="background:none;border:none;color:#eee;font-size:2rem;cursor:pointer;padding:0 0.5rem;">×</button> 705 </div> 706 <div style="padding:1rem 1.5rem;"> 707 <div style="display:flex;gap:0.5rem;align-items:center;flex-wrap:wrap;margin-bottom:1rem;padding:0.7rem;background:#1a1a3e;border-radius:8px;font-size:0.85rem;"> 708 <span style="color:#888;">📍</span> 709 <strong id="cf-ubicacion-texto" style="color:#d4af37;">Detectando...</strong> 710 <button onclick="cfCambiarUbicacion()" style="padding:0.35rem 0.7rem;background:#2a2a4a;border:none;border-radius:4px;color:#ccc;cursor:pointer;font-size:0.8rem;">📍 Cambiar</button> 711 <button onclick="cfUsarGPS()" style="padding:0.35rem 0.7rem;background:#2a2a4a;border:none;border-radius:4px;color:#ccc;cursor:pointer;font-size:0.8rem;">🛰 GPS</button> 712 </div> 713 <div style="display:flex;gap:0.4rem;margin-bottom:1.2rem;flex-wrap:wrap;"> 714 <button class="cf-tab-btn" data-tab="cf-carta" style="padding:0.5rem 1rem;background:linear-gradient(135deg,#d4af37,#b8962e);border:1px solid #d4af37;border-radius:6px;color:#0f0f1e;cursor:pointer;font-size:0.85rem;font-weight:600;">🔮 Carta</button> 715 <button class="cf-tab-btn" data-tab="cf-posiciones" style="padding:0.5rem 1rem;background:#1a1a3e;border:1px solid #2a2a4a;border-radius:6px;color:#ccc;cursor:pointer;font-size:0.85rem;">📊 Posiciones</button> 716 <button class="cf-tab-btn" data-tab="cf-aspectos" style="padding:0.5rem 1rem;background:#1a1a3e;border:1px solid #2a2a4a;border-radius:6px;color:#ccc;cursor:pointer;font-size:0.85rem;">⚡ Aspectos</button> 717 <button class="cf-tab-btn" data-tab="cf-casas" style="padding:0.5rem 1rem;background:#1a1a3e;border:1px solid #2a2a4a;border-radius:6px;color:#ccc;cursor:pointer;font-size:0.85rem;">🏠 Casas</button> 718 <button class="cf-tab-btn" data-tab="cf-tecnicos" style="padding:0.5rem 1rem;background:#1a1a3e;border:1px solid #2a2a4a;border-radius:6px;color:#ccc;cursor:pointer;font-size:0.85rem;">📋 Tecnicos</button> 719 <button class="cf-tab-btn" data-tab="cf-astrocarto" style="padding:0.5rem 1rem;background:#1a1a3e;border:1px solid #2a2a4a;border-radius:6px;color:#ccc;cursor:pointer;font-size:0.85rem;">🌍 Astrocartografia</button> 720 </div> 721 <div class="cf-tab-content" id="cf-carta" style="display:block;"><div id="cf-astrochart-container" style="display:flex;justify-content:center;overflow:hidden;"></div></div> 722 <div class="cf-tab-content" id="cf-posiciones" style="display:none;"><table id="cf-tabla-planetas" style="width:100%;border-collapse:collapse;font-size:0.9rem;"><thead><tr style="background:#1a1a3e;"><th style="color:#d4af37;padding:0.6rem;text-align:left;">Planeta</th><th style="color:#d4af37;padding:0.6rem;text-align:left;">Signo</th><th style="color:#d4af37;padding:0.6rem;text-align:left;">Grado</th><th style="color:#d4af37;padding:0.6rem;text-align:left;">Long.</th><th style="color:#d4af37;padding:0.6rem;"></th></tr></thead><tbody></tbody></table></div> 723 <div class="cf-tab-content" id="cf-aspectos" style="display:none;"><div id="cf-aspectos-lista"></div></div> 724 <div class="cf-tab-content" id="cf-casas" style="display:none;"><div id="cf-casas-info"></div></div> 725 <div class="cf-tab-content" id="cf-tecnicos" style="display:none;"><div id="cf-datos-tecnicos"></div></div> 726 <div class="cf-tab-content" id="cf-astrocarto" style="display:none;"> 727 <div id="cf-astrocarto-map" style="width:100%;height:450px;border-radius:8px;background:#1a2332;"></div> 728 <div id="cf-astrocarto-leyenda" style="display:flex;flex-wrap:wrap;gap:0.6rem;margin-top:0.8rem;padding:0.6rem;background:rgba(0,0,0,0.3);border-radius:6px;font-size:0.78rem;"></div> 729 <div style="margin-top:0.6rem;padding:0.6rem;background:rgba(212,175,55,0.06);border-radius:6px;font-size:0.8rem;color:#888;border-left:3px solid #d4af37;">Las lineas muestran donde cada planeta es angular (ASC subiendo, DSC poniendose, MC culminando, IC en nadir). Tu ubicacion actual esta marcada con 📍.</div> 730 </div> 731 </div> 732 </div> 733</div> 734 735
735<script src="/static/js/carta-fase.js"></script>
735 736 737
737<script> 738 // Email anti-obfuscation 739 (function(){ 740 var e=document.getElementById('email-link'); 741 if(e){var u='informes',d='urania.ar';e.textContent=u+'@'+d;e.href='mai'+'lto:'+u+'@'+d;e.onclick=function(){window.location.href=this.href;};} 742 })(); 743 </script>
vendor: 1 bytes, line 743
743
744<script src="/static/js/capacitor-fcm-init.js"></script>
744</body> 745</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.