<?php 
session_start();
error_reporting(E_ALL & ~E_NOTICE); 
include_once "utils_database.php";
include_once "utils.php";

// Extract request variables with prefix
$prefix = "P";
foreach ($_REQUEST as $key => $value) {
    $varname = $prefix . '_' . $key;
    $$varname = $value;
}

// Initialize variables to avoid undefined errors
$P_usr = isset($P_usr) ? $P_usr : "";
$P_psw = isset($P_psw) ? $P_psw : "";

// Session validation and login check
if (!isset($_SESSION['DatosIngresados'])) {
    $_SESSION['AccesoConcedido'] = false;
    $_SESSION['DatosIngresados'] = false;
    $_SESSION['estado_acceso'] = 0;
    $_SESSION['usr'] = "";
    $psw = "";
} else {
    $_SESSION['DatosIngresados'] = true;
    $_SESSION['usr'] = trim($P_usr);
    $_SESSION['psw'] = trim($P_psw);
    $psw = trim($P_psw);
    $vAcceso = validar_usuario();
    
    $_SESSION['AccesoConcedido'] = false;
    $_SESSION['estado_acceso'] = 2;
    if ($vAcceso == 1) {
        $_SESSION['AccesoConcedido'] = true;
        $_SESSION['estado_acceso'] = 1;
        //carga animacion antes de ir al dashboard
        header("Location: loading.php");
        exit;
    }
}

// Define system close date - removed duplicate declarations
$fecha_cierre = "2095-03-06"; // Fecha lejana para mantener el sistema abierto
$fecha_actual = date("Y-m-d");
$sistema_cerrado = strtotime($fecha_actual) > strtotime($fecha_cierre);
?>
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Panamtrauma Admin Portal">
    <meta name="author" content="Contactos SAS">
    <title>Panamtrauma 2025 - Portal Administrativo</title>
    
    <!-- CSS -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
    
    <style>
        :root {
            --primary: #34846c;
            --primary-dark: #2a6a56;
            --secondary: #377970;
            --accent: #53CDE5;
        }
        
        body {
            font-family: 'Poppins', sans-serif;
            background: #015a5e;
            margin: 0;
            padding: 0;
            overflow-x: hidden;
            min-height: 100vh;
        }
        
        /* Animación de Fondo */
        .animated-background {
            position: fixed;
            width: 100%;
            height: 100%;
            top: 0;
            left: 0;
            z-index: -3;
            background: linear-gradient(135deg, #007dd9, #37b698, #427d6e);
            background-size: 400% 400%;
            animation: gradient 15s ease infinite;
        }
        
        @keyframes gradient {
            0% {
                background-position: 0% 50%;
            }
            50% {
                background-position: 100% 50%;
            }
            100% {
                background-position: 0% 50%;
            }
        }
        
        /* Burbujas flotantes */
        .bubbles {
            position: fixed;
            width: 100%;
            height: 100%;
            top: 0;
            left: 0;
            z-index: -2;
            overflow: hidden;
        }
        
        .bubble {
            position: absolute;
            border-radius: 50%;
            background: rgba(255, 255, 255, 0.1);
            backdrop-filter: blur(1px);
            box-shadow: inset 0 0 10px rgba(255, 255, 255, 0.5);
            animation: float 8s ease-in infinite;
            bottom: -50px;
        }
        
        .bubble:nth-child(1) {
            width: 80px;
            height: 80px;
            left: 10%;
            animation-duration: 12s;
        }
        
        .bubble:nth-child(2) {
            width: 50px;
            height: 50px;
            left: 20%;
            animation-delay: 2s;
            animation-duration: 16s;
        }
        
        .bubble:nth-child(3) {
            width: 65px;
            height: 65px;
            left: 35%;
            animation-delay: 4s;
            animation-duration: 13s;
        }
        
        .bubble:nth-child(4) {
            width: 70px;
            height: 70px;
            left: 50%;
            animation-delay: 6s;
            animation-duration: 15s;
        }
        
        .bubble:nth-child(5) {
            width: 45px;
            height: 45px;
            left: 65%;
            animation-delay: 3s;
            animation-duration: 12s;
        }
        
        .bubble:nth-child(6) {
            width: 55px;
            height: 55px;
            left: 80%;
            animation-delay: 5s;
            animation-duration: 18s;
        }
        
        .bubble:nth-child(7) {
            width: 90px;
            height: 90px;
            left: 90%;
            animation-delay: 7s;
            animation-duration: 14s;
        }
        
        @keyframes float {
            0% {
                transform: translateY(0) rotate(0deg);
                opacity: 1;
            }
            100% {
                transform: translateY(-1000px) rotate(720deg);
                opacity: 0;
            }
        }
        
        /* Patrón de moléculas */
        .molecule-pattern {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MCIgaGVpZ2h0PSI1MCIgdmlld0JveD0iMCAwIDUwIDUwIiBvcGFjaXR5PSIwLjEiPjxwYXRoIGQ9Ik0xMCAxMEwyMCAxME0xMCAxNUwyMCAxNU0xMCAyMEwyMCAyME0zMCAxMEw0MCAxME0zMCAxNUw0MCAxNU0zMCAyMEw0MCAyME0xMCAzMEwyMCAzME0xMCAzNUwyMCAzNU0xMCA0MEwyMCA0ME0zMCAzMEw0MCAzME0zMCAzNUw0MCAzNU0zMCA0MEw0MCA0MCIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiLz48Y2lyY2xlIGN4PSI1IiBjeT0iNSIgcj0iMyIgZmlsbD0iI2ZmZiIvPjxjaXJjbGUgY3g9IjI1IiBjeT0iNSIgcj0iMyIgZmlsbD0iI2ZmZiIvPjxjaXJjbGUgY3g9IjQ1IiBjeT0iNSIgcj0iMyIgZmlsbD0iI2ZmZiIvPjxjaXJjbGUgY3g9IjUiIGN5PSIyNSIgcj0iMyIgZmlsbD0iI2ZmZiIvPjxjaXJjbGUgY3g9IjI1IiBjeT0iMjUiIHI9IjMiIGZpbGw9IiNmZmYiLz48Y2lyY2xlIGN4PSI0NSIgY3k9IjI1IiByPSIzIiBmaWxsPSIjZmZmIi8+PGNpcmNsZSBjeD0iNSIgY3k9IjQ1IiByPSIzIiBmaWxsPSIjZmZmIi8+PGNpcmNsZSBjeD0iMjUiIGN5PSI0NSIgcj0iMyIgZmlsbD0iI2ZmZiIvPjxjaXJjbGUgY3g9IjQ1IiBjeT0iNDUiIHI9IjMiIGZpbGw9IiNmZmYiLz48L3N2Zz4=');
            opacity: 0.1;
            z-index: -1;
        }
        
        /* Moléculas conectándose */
        #moleculeCanvas {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: -1;
        }
        
        /* Moléculas animadas */
        .floating-molecules {
            position: fixed;
            width: 100%;
            height: 100%;
            top: 0;
            left: 0;
            z-index: -1;
            overflow: hidden;
        }
        
        .molecule {
            position: absolute;
            opacity: 0.07;
            animation: molecule-float 15s infinite linear;
        }
        
        .molecule-1 {
            top: 10%;
            left: 5%;
            animation-duration: 20s;
        }
        
        .molecule-2 {
            top: 30%;
            right: 10%;
            animation-duration: 25s;
        }
        
        .molecule-3 {
            bottom: 15%;
            left: 15%;
            animation-duration: 22s;
        }
        
        .molecule-4 {
            bottom: 25%;
            right: 15%;
            animation-duration: 18s;
        }
        
        @keyframes molecule-float {
            0% {
                transform: translateY(0) rotate(0deg);
                opacity: 0.05;
            }
            25% {
                opacity: 0.1;
            }
            50% {
                transform: translateY(-20px) rotate(10deg);
                opacity: 0.05;
            }
            75% {
                opacity: 0.1;
            }
            100% {
                transform: translateY(0) rotate(0deg);
                opacity: 0.05;
            }
        }
        
        /* Efecto de luz radial */
        .light-effect {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 100%;
            height: 100%;
            background: radial-gradient(circle, rgba(166, 209, 196, 0.2) 0%, rgba(1, 90, 94, 0) 70%);
            z-index: -2;
            animation: pulse 8s infinite alternate;
        }
        
        @keyframes pulse {
            0% {
                opacity: 0.3;
                transform: translate(-50%, -50%) scale(1);
            }
            100% {
                opacity: 0.7;
                transform: translate(-50%, -50%) scale(1.2);
            }
        }
        
        .login-container {
            max-width: 450px;
            margin: 50px auto;
            padding: 30px;
            border-radius: 12px;
            box-shadow: 0 15px 35px rgba(0, 0, 0, 0.15);
            background: rgba(255, 255, 255, 0.9);
            backdrop-filter: blur(10px);
            position: relative;
            z-index: 10;
            overflow: hidden;
        }
        
        .login-container::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(255, 255, 255, 0.1);
            backdrop-filter: blur(5px);
            z-index: -1;
        }
        
        .floating-elements {
            position: fixed;
            width: 100%;
            height: 100%;
            top: 0;
            left: 0;
            z-index: 5;
            overflow: hidden;
            pointer-events: none;
        }
        
        .floating-element {
            position: absolute;
            opacity: 0.07;
            animation: float 15s infinite linear;
        }
        
        .logo-container {
            display: flex;
            justify-content: center;
            align-items: center;
            margin-bottom: 25px;
            position: relative;
        }
        
        .logo-shield {
            width: 120px;
            height: 120px;
            display: flex;
            justify-content: center;
            align-items: center;
            position: relative;
        }
        
        .logo-inner-circle {
            width: 80px;
            height: 80px;
            background: linear-gradient(135deg, #007dd9, #37b698);
            border-radius: 50%;
            display: flex;
            justify-content: center;
            align-items: center;
            box-shadow: 0 4px 15px rgba(66, 125, 110, 0.4);
            color: white;
            font-size: 28px;
            z-index: 2;
            position: relative;
            overflow: hidden;
        }
        
        .logo-outer-ring {
            position: absolute;
            width: 110px;
            height: 110px;
            border: 3px solid #3f51b5;
            border-radius: 50%;
            opacity: 0.6;
        }
        
        .logo-badge {
            position: absolute;
            top: -5px;
            right: -5px;
            background: linear-gradient(135deg, #fcb917, #f8a100);
            color: white;
            border-radius: 50%;
            width: 35px;
            height: 35px;
            display: flex;
            justify-content: center;
            align-items: center;
            box-shadow: 0 3px 10px rgba(252, 185, 23, 0.4);
            z-index: 3;
        }
        
        .scientific-icon {
            position: absolute;
            bottom: -5px;
            left: -5px;
            background: linear-gradient(135deg, #198754, #478576);
            color: white;
            border-radius: 50%;
            width: 30px;
            height: 30px;
            display: flex;
            justify-content: center;
            align-items: center;
            box-shadow: 0 3px 10px rgba(71, 133, 118, 0.4);
            z-index: 3;
        }
        
        .logo-orbit {
            position: absolute;
            width: 100%;
            height: 100%;
            animation: rotate 20s linear infinite;
        }
        
        .logo-dot {
            position: absolute;
            width: 15px;
            height: 15px;
            background: #3f51b5;
            border-radius: 50%;
            top: 10px;
            left: 50%;
            transform: translateX(-50%);
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
        }
        
        .input-group {
            border-radius: 8px;
            overflow: hidden;
        }
        
        .input-group-text {
            background-color: #f8f9fa;
            border-color: #dee2e6;
        }
        
        .form-control {
            border-color: #dee2e6;
        }
        
        .btn-primary {
            background: linear-gradient(135deg, #198754, #427d6e);
            border: none;
            box-shadow: 0 4px 15px rgba(25, 135, 84, 0.3);
            transition: all 0.3s ease;
            position: relative;
            overflow: hidden;
        }
        
        .btn-primary:hover {
            background: linear-gradient(135deg, #007dd9, #37b698);
            transform: translateY(-2px);
            box-shadow: 0 6px 18px rgba(0, 125, 217, 0.4);
        }
        
        .evaluation-banner {
            background: linear-gradient(135deg, rgba(55, 182, 152, 0.1), rgba(66, 125, 110, 0.1));
            border-radius: 8px;
            padding: 10px 15px;
            margin-bottom: 20px;
            border-left: 4px solid #37b698;
            display: flex;
            align-items: center;
        }
        
        .evaluation-banner i {
            color: #37b698;
            font-size: 24px;
            margin-right: 10px;
        }
        
        .forgot-password {
            color: #666;
            text-decoration: none;
            font-size: 0.9rem;
            transition: all 0.3s ease;
        }
        
        .forgot-password:hover {
            color: #198754;
        }
        
        .browser-note {
            color: #888;
        }
        
        .alert-danger {
            border-left: 4px solid #dc3545;
        }
        
        .system-closed {
            background-color: rgba(248, 249, 250, 0.9);
            backdrop-filter: blur(10px);
            border: 1px solid #dee2e6;
            border-radius: 8px;
            padding: 30px;
            max-width: 650px;
            margin: 0 auto;
            box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
        }
        
        .system-closed .logo-icon {
            font-size: 3rem;
        }
        
        @keyframes rotate {
            from { transform: rotate(0deg); }
            to { transform: rotate(360deg); }
        }
        
        @keyframes float {
            0% {
                transform: translateY(0) rotate(0deg);
                opacity: 0.05;
            }
            25% {
                opacity: 0.1;
            }
            50% {
                transform: translateY(-15px) rotate(5deg);
                opacity: 0.05;
            }
            75% {
                opacity: 0.1;
            }
            100% {
                transform: translateY(0) rotate(0deg);
                opacity: 0.05;
            }
        }
    </style>
</head>
<body>
    <!-- Elementos de Fondo Animados -->
    <div class="animated-background"></div>
    
    <!-- Efecto de luz radial pulsante -->
    <div class="light-effect"></div>
    
    <!-- Burbujas flotantes -->
    <div class="bubbles">
        <div class="bubble"></div>
        <div class="bubble"></div>
        <div class="bubble"></div>
        <div class="bubble"></div>
        <div class="bubble"></div>
        <div class="bubble"></div>
        <div class="bubble"></div>
    </div>
    
    <!-- Patrón de moléculas de fondo -->
    <div class="molecule-pattern"></div>
    
    <!-- Moléculas conectándose en el fondo -->
    <canvas id="moleculeCanvas"></canvas>
    
    <!-- Moléculas flotantes -->
    <div class="floating-molecules">
        <svg class="molecule molecule-1" width="60" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
            <path fill="#ffffff" d="M11,17h2v4h-2V17z M7,19h2v2H7V19z M15,19h2v2h-2V19z M11,11h2v4h-2V11z M7,13h2v4H7V13z M15,13h2v4h-2V13z M11,5h2v4h-2V5z M7,7h2v4H7V7z M15,7h2v4h-2V7z"/>
        </svg>
        <svg class="molecule molecule-2" width="70" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
            <path fill="#ffffff" d="M19.35,10.04C18.67,6.59,15.64,4,12,4C9.11,4,6.6,5.64,5.35,8.04C2.34,8.36,0,10.91,0,14c0,3.31,2.69,6,6,6h13c2.76,0,5-2.24,5-5C24,12.36,21.95,10.22,19.35,10.04z"/>
        </svg>
        <svg class="molecule molecule-3" width="80" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
            <path fill="#ffffff" d="M12,3c0,0-6.186,5.34-9.643,8.232C2.154,11.416,2,11.684,2,12c0,0.553,0.447,1,1,1h2v7c0,0.553,0.447,1,1,1h3c0.553,0,1-0.447,1-1v-4h4v4c0,0.553,0.447,1,1,1h3c0.553,0,1-0.447,1-1v-7h2c0.553,0,1-0.447,1-1c0-0.316-0.154-0.584-0.383-0.768C18.184,8.34,12,3,12,3z"/>
        </svg>
        <svg class="molecule molecule-4" width="65" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
            <path fill="#ffffff" d="M13 3a9 9 0 00-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42A8.954 8.954 0 0013 21a9 9 0 000-18zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z"/>
        </svg>
    </div>

    <div class="container my-5">
        <?php 
        // Login form if not authorized
        if (!isset($_SESSION['AccesoConcedido']) || !$_SESSION['AccesoConcedido']):
            
            // El sistema_cerrado ya está definido arriba
            
            // Verificar si el sistema está cerrado
            if ($sistema_cerrado): 
        ?>
            <div class="login-container system-closed">
                <div class="logo-container mb-4">
                    <i class="fas fa-lock text-danger logo-icon"></i>
                </div>
                
                <h2 class="text-center mb-3">Portal de Calificaciones Cerrado</h2>
                <p class="text-center lead mb-4">El período para el proceso de calificaciones ha finalizado el <?php echo date("d/m/Y", strtotime($fecha_cierre)); ?>.</p>
                
                <div class="alert alert-info">
                    <i class="fas fa-info-circle me-2"></i>
                    Si necesita acceso o tiene alguna consulta, por favor contacte al departamento de administración académica.
                </div>
                
                <div class="d-grid gap-2 mt-4">
                    <a href="../" class="btn btn-outline-secondary py-2">
                        <i class="fas fa-home me-2"></i>Volver al Inicio
                    </a>
                </div>
            </div>
        <?php else: ?>
            <div class="login-container">
                <div class="logo-container">
                    <div class="logo-shield">
                        <div class="logo-orbit">
                            <div class="logo-dot"></div>
                        </div>
                        <div class="logo-outer-ring"></div>
                        <div class="logo-inner-circle">
                            <i class="fas fa-microscope"></i>
                        </div>
                        <div class="logo-badge">
                            <i class="fas fa-award" style="font-size: 16px;"></i>
                        </div>
                        <div class="scientific-icon">
                            <i class="fas fa-atom" style="font-size: 14px;"></i>
                        </div>
                    </div>
                </div>
                
                <h2 class="text-center mb-3">Sistema de Evaluación</h2>
                <p class="text-center text-secondary mb-4">Plataforma para Evaluadores de Trabajos Científicos</p>
                
                <div class="evaluation-banner">
                    <i class="fas fa-clipboard-check"></i>
                    <div>
                        <strong>Portal de Evaluación Científica</strong><br>
                        <small>Acceso a revisión de artículos y documentos de investigación</small>
                    </div>
                </div>
                
                <form method="post" action="">
                    <div class="mb-4 position-relative">
                        <label for="usr" class="form-label">Usuario</label>
                        <div class="input-group">
                            <span class="input-group-text"><i class="fas fa-user"></i></span>
                            <input type="text" class="form-control" id="usr" name="usr" placeholder="Ingrese su usuario" required>
                        </div>
                    </div>
                    
                    <div class="mb-4 position-relative">
                        <label for="psw" class="form-label">Contraseña</label>
                        <div class="input-group">
                            <span class="input-group-text"><i class="fas fa-lock"></i></span>
                            <input type="password" class="form-control" id="psw" name="psw" placeholder="Ingrese su contraseña" required>
                        </div>
                    </div>
                    
                    <div class="d-grid gap-2 mt-4">
                        <button type="submit" class="btn btn-primary py-2">
                            <i class="fas fa-sign-in-alt me-2"></i>Ingresar al Sistema
                        </button>
                    </div>
                    
                    <div class="text-center mt-3">
                        <a href="olvidocontrasena.php" class="forgot-password">
                            <i class="fas fa-question-circle me-1"></i>¿Olvidaste tu contraseña?
                        </a>
                    </div>
                    
                    <div class="alert alert-danger mt-4" id="errorAlert" style="display: <?php echo (isset($_POST['usr']) && isset($_POST['psw'])) ? 'block' : 'none'; ?>">
                        <i class="fas fa-exclamation-triangle me-2"></i>
                        Usuario y/o Clave incorrectos.
                    </div>
                    
                    <div class="mt-4 text-center browser-note">
                        <i class="fas fa-info-circle me-1"></i>
                        <small>Para visualizar esta página correctamente, favor ingresar desde los exploradores 
                        "Chrome", "Firefox" o "Edge"</small>
                    </div>
                </form>
            </div>
        <?php 
            endif;
        endif; 
        ?>
    </div>
    
    <script>
    document.addEventListener('DOMContentLoaded', function() {
        // Verificar si hay datos de login enviados (post)
        const loginAttempted = <?php echo (!empty($_POST['usr']) && !empty($_POST['psw'])) ? 'true' : 'false'; ?>;
        
        // Si hubo un intento de login y estamos todavía en la página de login, significa que falló
        if (loginAttempted) {
            document.getElementById('errorAlert').style.display = 'block';
        }
        
        // También capturamos el envío del formulario para validar antes de enviar
        const loginForm = document.querySelector('form');
        if (loginForm) {
            loginForm.addEventListener('submit', function(event) {
                const username = document.getElementById('usr').value.trim();
                const password = document.getElementById('psw').value.trim();
                
                if (username === '' || password === '') {
                    event.preventDefault();
                    document.getElementById('errorAlert').style.display = 'block';
                }
            });
        }
        
        // Inicializar el canvas de moléculas conectándose
        initMoleculeNetwork();
    });
    
    // Función para inicializar la red de moléculas
    function initMoleculeNetwork() {
        const canvas = document.getElementById('moleculeCanvas');
        const ctx = canvas.getContext('2d');
        
        // Establecer tamaño del canvas al tamaño de la ventana
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        
        // Ajustar canvas cuando cambie el tamaño de la ventana
        window.addEventListener('resize', function() {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
        });
        
        // Configuración de las partículas
        const particlesArray = [];
        const numberOfParticles = 80;
        
        // Definir colores para partículas
        const colors = ['#427d6e', '#015a5e', '#478576', '#198754', '#5f7b87', '#007dd9', '#a6d1c4', '#327063', '#d0bf6f'];
        
        // Clase para las partículas (moléculas)
        class Particle {
            constructor() {
                this.x = Math.random() * canvas.width;
                this.y = Math.random() * canvas.height;
                this.size = Math.random() * 5 + 2; // Tamaño entre 2 y 7
                this.speedX = (Math.random() - 0.5) * 1.5;
                this.speedY = (Math.random() - 0.5) * 1.5;
                this.color = colors[Math.floor(Math.random() * colors.length)];
                this.opacity = Math.random() * 0.5 + 0.2; // Opacidad entre 0.2 y 0.7
            }
            
            // Actualiza la posición de la partícula
            update() {
                this.x += this.speedX;
                this.y += this.speedY;
                
                // Rebote en los bordes del canvas
                if (this.x > canvas.width || this.x < 0) {
                    this.speedX = -this.speedX;
                }
                if (this.y > canvas.height || this.y < 0) {
                    this.speedY = -this.speedY;
                }
            }
            
            // Dibuja la partícula
            draw() {
                ctx.beginPath();
                ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
                ctx.fillStyle = this.color;
                ctx.globalAlpha = this.opacity;
                ctx.fill();
                ctx.globalAlpha = 1;
            }
        }
        
        // Crear partículas
        for (let i = 0; i < numberOfParticles; i++) {
            particlesArray.push(new Particle());
        }
        
        // Función para animar las partículas
        function animate() {
            // Limpiar canvas con un fondo semitransparente para crear efecto de desvanecimiento
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            
            // Actualizar y dibujar cada partícula
            for (let i = 0; i < particlesArray.length; i++) {
                particlesArray[i].update();
                particlesArray[i].draw();
                
                // Conectar partículas con líneas si están lo suficientemente cerca
                connectParticles(particlesArray[i], particlesArray);
            }
            
            requestAnimationFrame(animate);
        }
        
        // Función para conectar partículas
        function connectParticles(particle, particles) {
            const connectionDistance = 150; // Distancia máxima para conectar partículas
            
            for (let i = 0; i < particles.length; i++) {
                // Calcular distancia entre partículas
                const dx = particle.x - particles[i].x;
                const dy = particle.y - particles[i].y;
                const distance = Math.sqrt(dx * dx + dy * dy);
                
                // Si están lo suficientemente cerca, dibujar una línea entre ellas
                if (distance < connectionDistance) {
                    // La opacidad de la línea disminuye con la distancia
                    const opacity = 1 - (distance / connectionDistance);
                    
                    ctx.beginPath();
                    ctx.strokeStyle = particle.color;
                    ctx.globalAlpha = opacity * 0.2; // Reducir opacidad para un efecto más sutil
                    ctx.lineWidth = 0.5;
                    ctx.moveTo(particle.x, particle.y);
                    ctx.lineTo(particles[i].x, particles[i].y);
                    ctx.stroke();
                    ctx.globalAlpha = 1;
                }
            }
        }
        
        // Iniciar animación
        animate();
    }
    </script>
</body>
</html>