T.ME/BIBIL_0DAY
CasperSecurity


Server : Apache/2
System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64
User : gositeme ( 1004)
PHP Version : 8.2.29
Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
Directory :  /home/gositeme/.cursor-server/data/User/History/-31d25c75/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/.cursor-server/data/User/History/-31d25c75/uQ2L.php
<?php
session_start();
require_once 'config/database.php';
require_once 'includes/translations.php';
require_once 'config/event_pricing.php';

// Set page variables
$current_page = 'event-pricing';
$page_title = t('event_pricing.page_title');
$page_description = t('event_pricing.page_description');

include 'includes/header.php';

// Get pricing config
$pricing_config = getEventPricingConfig();
$tiers = $pricing_config['pricing_tiers'];
$eventbrite = $pricing_config['eventbrite_comparison'];

// Example calculations for a $50 ticket
$example_ticket_price = 50;
?>

<style>
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    background: #0a0a0a;
    color: #fff;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
    overflow-x: hidden;
}

.particle-canvas {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    pointer-events: none;
}

.content-wrapper {
    position: relative;
    z-index: 1;
}

.hero-section {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 4rem 2rem;
    position: relative;
    overflow: hidden;
}

.hero-content {
    max-width: 900px;
    z-index: 2;
    position: relative;
}

.hero-badge {
    display: inline-block;
    background: rgba(102, 126, 234, 0.2);
    border: 1px solid rgba(102, 126, 234, 0.5);
    padding: 0.5rem 1.5rem;
    border-radius: 50px;
    font-size: 0.9rem;
    margin-bottom: 2rem;
    backdrop-filter: blur(10px);
    animation: pulse 2s ease-in-out infinite;
}

@keyframes pulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.8; transform: scale(1.05); }
}

.hero-title {
    font-size: clamp(2.5rem, 8vw, 5rem);
    font-weight: 800;
    margin-bottom: 1.5rem;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    line-height: 1.1;
}

.hero-subtitle {
    font-size: clamp(1.1rem, 3vw, 1.5rem);
    color: #cbd5e0;
    margin-bottom: 3rem;
    line-height: 1.6;
}

.hero-cta {
    display: inline-flex;
    gap: 1rem;
    flex-wrap: wrap;
    justify-content: center;
}

.btn-primary {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    padding: 1rem 2.5rem;
    border-radius: 50px;
    font-weight: 600;
    font-size: 1.1rem;
    text-decoration: none;
    border: none;
    cursor: pointer;
    transition: all 0.3s ease;
    box-shadow: 0 10px 30px rgba(102, 126, 234, 0.4);
}

.btn-primary:hover {
    transform: translateY(-2px);
    box-shadow: 0 15px 40px rgba(102, 126, 234, 0.6);
}

.btn-secondary {
    background: transparent;
    color: #fff;
    padding: 1rem 2.5rem;
    border-radius: 50px;
    font-weight: 600;
    font-size: 1.1rem;
    text-decoration: none;
    border: 2px solid rgba(102, 126, 234, 0.5);
    cursor: pointer;
    transition: all 0.3s ease;
}

.btn-secondary:hover {
    background: rgba(102, 126, 234, 0.1);
    border-color: #667eea;
}

.comparison-badge {
    background: linear-gradient(135deg, #48bb78 0%, #38a169 100%);
    color: white;
    padding: 1.5rem 2rem;
    border-radius: 20px;
    text-align: center;
    max-width: 800px;
    margin: -3rem auto 4rem;
    position: relative;
    z-index: 2;
    box-shadow: 0 20px 60px rgba(72, 187, 120, 0.3);
}

.comparison-badge h2 {
    font-size: clamp(1.5rem, 4vw, 2.5rem);
    margin-bottom: 0.5rem;
}

.comparison-badge p {
    font-size: 1.1rem;
    opacity: 0.95;
}

.section {
    padding: 5rem 2rem;
    max-width: 1400px;
    margin: 0 auto;
}

.section-title {
    text-align: center;
    font-size: clamp(2rem, 5vw, 3.5rem);
    font-weight: 700;
    margin-bottom: 1rem;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.section-subtitle {
    text-align: center;
    font-size: 1.2rem;
    color: #a0aec0;
    margin-bottom: 4rem;
    max-width: 700px;
    margin-left: auto;
    margin-right: auto;
}

.pricing-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 2rem;
    margin-bottom: 5rem;
}

.pricing-card {
    background: rgba(255, 255, 255, 0.05);
    backdrop-filter: blur(20px);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 24px;
    padding: 2.5rem;
    transition: all 0.3s ease;
    position: relative;
    overflow: hidden;
}

.pricing-card::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 4px;
    background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
    transform: scaleX(0);
    transition: transform 0.3s ease;
}

.pricing-card:hover {
    transform: translateY(-10px);
    border-color: rgba(102, 126, 234, 0.5);
    box-shadow: 0 20px 60px rgba(102, 126, 234, 0.2);
}

.pricing-card:hover::before {
    transform: scaleX(1);
}

.pricing-card.featured {
    background: linear-gradient(135deg, rgba(102, 126, 234, 0.15) 0%, rgba(118, 75, 162, 0.15) 100%);
    border-color: rgba(102, 126, 234, 0.5);
    transform: scale(1.05);
}

.pricing-card.featured::before {
    transform: scaleX(1);
}

.card-header {
    text-align: center;
    margin-bottom: 2rem;
    padding-bottom: 2rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.plan-name {
    font-size: 1.8rem;
    font-weight: 700;
    margin-bottom: 0.5rem;
    color: #fff;
}

.plan-desc {
    font-size: 0.95rem;
    color: #a0aec0;
}

.fee-list {
    margin-bottom: 2rem;
}

.fee-item {
    display: flex;
    justify-content: space-between;
    padding: 1rem 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

.fee-item:last-child {
    border-bottom: none;
}

.fee-label {
    color: #cbd5e0;
    font-size: 1rem;
}

.fee-value {
    font-weight: 600;
    color: #fff;
    font-size: 1.1rem;
}

.fee-total {
    margin-top: 1.5rem;
    padding-top: 1.5rem;
    border-top: 2px solid rgba(102, 126, 234, 0.3);
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.fee-total-label {
    font-weight: 700;
    font-size: 1.2rem;
    color: #fff;
}

.fee-total-value {
    font-weight: 700;
    font-size: 1.8rem;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.savings-badge {
    text-align: center;
    margin-top: 1.5rem;
    padding: 1rem;
    background: rgba(72, 187, 120, 0.1);
    border: 1px solid rgba(72, 187, 120, 0.3);
    border-radius: 12px;
}

.savings-badge .label {
    font-size: 0.85rem;
    color: #a0aec0;
    margin-bottom: 0.5rem;
}

.savings-badge .amount {
    font-size: 1.5rem;
    font-weight: 700;
    color: #48bb78;
}

.example-section {
    background: rgba(255, 255, 255, 0.03);
    border-radius: 32px;
    padding: 4rem 2rem;
    margin: 5rem 0;
    border: 1px solid rgba(255, 255, 255, 0.1);
}

.example-header {
    text-align: center;
    margin-bottom: 3rem;
}

.example-ticket {
    background: rgba(255, 255, 255, 0.05);
    border-radius: 24px;
    padding: 3rem;
    margin-bottom: 2rem;
}

.example-comparison {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 2rem;
    margin-top: 2rem;
}

.example-column {
    background: rgba(255, 255, 255, 0.03);
    border-radius: 20px;
    padding: 2rem;
    border: 1px solid rgba(255, 255, 255, 0.1);
}

.example-column h3 {
    font-size: 1.3rem;
    margin-bottom: 1.5rem;
    text-align: center;
}

.example-row {
    display: flex;
    justify-content: space-between;
    padding: 0.75rem 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.05);
    font-size: 1rem;
}

.example-row.total {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 2px solid rgba(102, 126, 234, 0.3);
    font-weight: 700;
    font-size: 1.2rem;
}

.example-savings {
    background: linear-gradient(135deg, #48bb78 0%, #38a169 100%);
    color: white;
    padding: 2rem;
    border-radius: 20px;
    text-align: center;
    margin-top: 2rem;
}

.example-savings .label {
    font-size: 1rem;
    opacity: 0.9;
    margin-bottom: 0.5rem;
}

.example-savings .amount {
    font-size: 2.5rem;
    font-weight: 800;
    margin-bottom: 0.5rem;
}

.comparison-table-wrapper {
    background: rgba(255, 255, 255, 0.03);
    border-radius: 32px;
    padding: 4rem 2rem;
    border: 1px solid rgba(255, 255, 255, 0.1);
}

.comparison-table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 2rem;
}

.comparison-table th,
.comparison-table td {
    padding: 1.5rem;
    text-align: left;
    border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

.comparison-table th {
    background: rgba(102, 126, 234, 0.1);
    font-weight: 700;
    font-size: 1.1rem;
    color: #fff;
}

.comparison-table td {
    color: #cbd5e0;
    font-size: 1rem;
}

.comparison-table tr:last-child td {
    border-bottom: none;
}

.comparison-table .better {
    color: #48bb78;
    font-weight: 700;
}

.comparison-table .worse {
    color: #f56565;
}

.final-cta {
    text-align: center;
    padding: 6rem 2rem;
    background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%);
    border-radius: 32px;
    margin: 5rem 0;
    border: 1px solid rgba(102, 126, 234, 0.3);
}

.final-cta h2 {
    font-size: clamp(2rem, 5vw, 3.5rem);
    margin-bottom: 1rem;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.final-cta p {
    font-size: 1.3rem;
    color: #cbd5e0;
    margin-bottom: 2.5rem;
    max-width: 600px;
    margin-left: auto;
    margin-right: auto;
}

@media (max-width: 768px) {
    .hero-section {
        min-height: 80vh;
        padding: 2rem 1rem;
    }
    
    .pricing-grid {
        grid-template-columns: 1fr;
    }
    
    .pricing-card.featured {
        transform: scale(1);
    }
    
    .example-comparison {
        grid-template-columns: 1fr;
    }
    
    .hero-cta {
        flex-direction: column;
    }
    
    .btn-primary,
    .btn-secondary {
        width: 100%;
    }
}
</style>

<canvas class="particle-canvas" id="pricingParticles"></canvas>

<div class="content-wrapper">
    <!-- Hero Section -->
    <section class="hero-section">
        <div class="hero-content">
            <div class="hero-badge"><?= t('event_pricing.comparison_title') ?></div>
            <h1 class="hero-title"><?= t('event_pricing.hero_title') ?></h1>
            <p class="hero-subtitle"><?= t('event_pricing.hero_subtitle') ?></p>
            <div class="hero-cta">
                <a href="/events.php" class="btn-primary"><?= t('event_pricing.create_event') ?></a>
                <a href="/subscribe.php" class="btn-secondary"><?= t('event_pricing.upgrade_plan') ?></a>
            </div>
        </div>
    </section>

    <div class="section">
        <div class="comparison-badge">
            <h2><?= t('event_pricing.comparison_message') ?></h2>
            <p><?= t('event_pricing.comparison_title') ?></p>
        </div>

        <!-- Pricing Tiers -->
        <h2 class="section-title"><?= t('event_pricing.pricing_tiers') ?></h2>
        <p class="section-subtitle"><?= t('event_pricing.choose_plan') ?></p>
        
        <div class="pricing-grid">
            <?php foreach ($tiers as $tier_key => $tier): 
                $example_fees = calculateEventTicketFees($example_ticket_price, $tier_key, false, false);
                $eventbrite_fees = ($example_ticket_price * ($eventbrite['eventbrite_service_fee'] / 100)) + $eventbrite['eventbrite_fixed_fee'] + ($example_ticket_price * ($eventbrite['eventbrite_payment_processing'] / 100));
                $savings = $eventbrite_fees - $example_fees['total_fees'];
            ?>
            <div class="pricing-card <?= $tier_key === 'pro' ? 'featured' : '' ?>">
                <div class="card-header">
                    <div class="plan-name"><?= t('event_pricing.tier.' . $tier_key . '.name') ?></div>
                    <div class="plan-desc"><?= t('event_pricing.tier.' . $tier_key . '.description') ?></div>
                </div>
                
                <div class="fee-list">
                    <div class="fee-item">
                        <span class="fee-label"><?= t('event_pricing.service_fee') ?></span>
                        <span class="fee-value"><?= number_format($tier['service_fee_percentage'], 1) ?>% + $<?= number_format($tier['fixed_fee_per_ticket'], 2) ?></span>
                    </div>
                    <div class="fee-item">
                        <span class="fee-label"><?= t('event_pricing.payment_processing') ?></span>
                        <span class="fee-value"><?= number_format($tier['payment_processing_percentage'], 1) ?>%</span>
                    </div>
                    <div class="fee-total">
                        <span class="fee-total-label"><?= t('event_pricing.total_fees') ?></span>
                        <span class="fee-total-value">$<?= number_format($example_fees['total_fees'], 2) ?></span>
                    </div>
                </div>
                
                <div class="savings-badge">
                    <div class="label"><?= t('event_pricing.on_ticket') ?> $<?= number_format($example_ticket_price, 0) ?></div>
                    <div class="amount"><?= t('event_pricing.save') ?> $<?= number_format($savings, 2) ?></div>
                </div>
            </div>
            <?php endforeach; ?>
        </div>

        <!-- Example Calculations -->
        <div class="example-section">
            <div class="example-header">
                <h2 class="section-title"><?= t('event_pricing.example_title') ?></h2>
                <p class="section-subtitle"><?= t('event_pricing.example_subtitle') ?></p>
            </div>
            
            <div class="example-ticket">
                <div style="text-align: center; margin-bottom: 2rem;">
                    <div style="font-size: 3rem; font-weight: 800; margin-bottom: 0.5rem;">$<?= number_format($example_ticket_price, 0) ?></div>
                    <div style="color: #a0aec0;"><?= t('event_pricing.ticket') ?></div>
                </div>
                
                <div class="example-comparison">
                    <div class="example-column">
                        <h3><?= t('event_pricing.our_platform') ?></h3>
                        <?php 
                        $our_fees = calculateEventTicketFees($example_ticket_price, 'pro', false, false);
                        ?>
                        <div class="example-row">
                            <span><?= t('event_pricing.ticket_price') ?></span>
                            <span>$<?= number_format($example_ticket_price, 2) ?></span>
                        </div>
                        <div class="example-row">
                            <span><?= t('event_pricing.service_fee') ?> (2.0% + $0.99)</span>
                            <span>$<?= number_format($our_fees['service_fee'], 2) ?></span>
                        </div>
                        <div class="example-row">
                            <span><?= t('event_pricing.payment_processing') ?> (2.9%)</span>
                            <span>$<?= number_format($our_fees['payment_processing_fee'], 2) ?></span>
                        </div>
                        <div class="example-row total" style="color: #48bb78;">
                            <span><?= t('event_pricing.attendee_pays') ?></span>
                            <span>$<?= number_format($our_fees['attendee_pays'], 2) ?></span>
                        </div>
                        <div class="example-row total" style="color: #667eea;">
                            <span><?= t('event_pricing.organizer_receives') ?></span>
                            <span>$<?= number_format($our_fees['organizer_receives'], 2) ?></span>
                        </div>
                    </div>
                    
                    <div class="example-column">
                        <h3><?= t('event_pricing.competitor') ?></h3>
                        <?php 
                        $eb_service = ($example_ticket_price * ($eventbrite['eventbrite_service_fee'] / 100)) + $eventbrite['eventbrite_fixed_fee'];
                        $eb_processing = $example_ticket_price * ($eventbrite['eventbrite_payment_processing'] / 100);
                        $eb_total = $eb_service + $eb_processing;
                        $eb_attendee_pays = $example_ticket_price + $eb_total;
                        ?>
                        <div class="example-row">
                            <span><?= t('event_pricing.ticket_price') ?></span>
                            <span>$<?= number_format($example_ticket_price, 2) ?></span>
                        </div>
                        <div class="example-row">
                            <span><?= t('event_pricing.service_fee') ?> (3.7% + $1.79)</span>
                            <span>$<?= number_format($eb_service, 2) ?></span>
                        </div>
                        <div class="example-row">
                            <span><?= t('event_pricing.payment_processing') ?> (2.9%)</span>
                            <span>$<?= number_format($eb_processing, 2) ?></span>
                        </div>
                        <div class="example-row total" style="color: #f56565;">
                            <span><?= t('event_pricing.attendee_pays') ?></span>
                            <span>$<?= number_format($eb_attendee_pays, 2) ?></span>
                        </div>
                        <div class="example-row total" style="color: #cbd5e0;">
                            <span><?= t('event_pricing.organizer_receives') ?></span>
                            <span>$<?= number_format($example_ticket_price, 2) ?></span>
                        </div>
                    </div>
                </div>
                
                <div class="example-savings">
                    <div class="label"><?= t('event_pricing.you_save') ?></div>
                    <div class="amount">$<?= number_format($eb_total - $our_fees['total_fees'], 2) ?></div>
                    <div style="font-size: 1rem; opacity: 0.9;"><?= t('event_pricing.per_ticket') ?></div>
                    <div style="margin-top: 1rem; font-size: 0.9rem; opacity: 0.8;"><?= t('event_pricing.savings_message') ?></div>
                </div>
            </div>
        </div>

        <!-- Comparison Table -->
        <div class="comparison-table-wrapper">
            <h2 class="section-title"><?= t('event_pricing.comparison_table_title') ?></h2>
            <p class="section-subtitle"><?= t('event_pricing.comparison_table_subtitle') ?></p>
            
            <table class="comparison-table">
                <thead>
                    <tr>
                        <th><?= t('event_pricing.feature') ?></th>
                        <th><?= t('event_pricing.soundstudiopro') ?></th>
                        <th><?= t('event_pricing.eventbrite') ?></th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td><?= t('event_pricing.service_fee') ?></td>
                        <td class="better">1.5% - 2.5% + $0.99</td>
                        <td class="worse">3.7% + $1.79</td>
                    </tr>
                    <tr>
                        <td><?= t('event_pricing.payment_processing') ?></td>
                        <td>2.9%</td>
                        <td>2.9%</td>
                    </tr>
                    <tr>
                        <td><?= t('event_pricing.fixed_fee') ?></td>
                        <td class="better">$0.99</td>
                        <td class="worse">$1.79</td>
                    </tr>
                    <tr>
                        <td><?= t('event_pricing.free_events') ?></td>
                        <td class="better"><?= t('event_pricing.no_fees') ?></td>
                        <td class="worse"><?= t('event_pricing.still_charged') ?></td>
                    </tr>
                    <tr>
                        <td><?= t('event_pricing.pricing_tiers') ?></td>
                        <td class="better"><?= t('event_pricing.five_tiers') ?></td>
                        <td><?= t('event_pricing.standard_rates_only') ?></td>
                    </tr>
                </tbody>
            </table>
        </div>

        <!-- Final CTA -->
        <div class="final-cta">
            <h2><?= t('event_pricing.cta_title') ?></h2>
            <p><?= t('event_pricing.cta_message') ?></p>
            <div class="hero-cta">
                <a href="/events.php" class="btn-primary"><?= t('event_pricing.create_event') ?></a>
                <a href="/subscribe.php" class="btn-secondary"><?= t('event_pricing.upgrade_plan') ?></a>
            </div>
        </div>
    </div>
</div>

<script>
// Particle System
(function() {
    const canvas = document.getElementById('pricingParticles');
    if (!canvas) return;
    
    const ctx = canvas.getContext('2d');
    let particles = [];
    let animationId;
    
    function resizeCanvas() {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
    }
    
    resizeCanvas();
    window.addEventListener('resize', resizeCanvas);
    
    class Particle {
        constructor() {
            this.reset();
            this.y = Math.random() * canvas.height;
        }
        
        reset() {
            this.x = Math.random() * canvas.width;
            this.y = -10;
            this.size = Math.random() * 3 + 1;
            this.speedY = Math.random() * 2 + 0.5;
            this.speedX = (Math.random() - 0.5) * 0.5;
            this.opacity = Math.random() * 0.5 + 0.2;
            this.color = this.getRandomColor();
            this.wobble = Math.random() * Math.PI * 2;
            this.wobbleSpeed = Math.random() * 0.02 + 0.01;
        }
        
        getRandomColor() {
            const colors = [
                { r: 102, g: 126, b: 234 }, // #667eea
                { r: 118, g: 75, b: 162 }, // #764ba2
                { r: 240, g: 147, b: 251 }, // #f093fb
                { r: 79, g: 172, b: 254 },  // #4facfe
                { r: 72, g: 187, b: 120 }   // #48bb78
            ];
            return colors[Math.floor(Math.random() * colors.length)];
        }
        
        update() {
            this.y += this.speedY;
            this.x += this.speedX + Math.sin(this.wobble) * 0.5;
            this.wobble += this.wobbleSpeed;
            this.opacity -= 0.002;
            
            if (this.y > canvas.height + 10 || this.opacity <= 0) {
                this.reset();
            }
        }
        
        draw() {
            ctx.save();
            ctx.globalAlpha = this.opacity;
            ctx.fillStyle = `rgb(${this.color.r}, ${this.color.g}, ${this.color.b})`;
            ctx.shadowBlur = 20;
            ctx.shadowColor = `rgba(${this.color.r}, ${this.color.g}, ${this.color.b}, 0.8)`;
            
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
            ctx.fill();
            
            // Add glow effect
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.size * 2.5, 0, Math.PI * 2);
            ctx.fillStyle = `rgba(${this.color.r}, ${this.color.g}, ${this.color.b}, 0.15)`;
            ctx.fill();
            
            ctx.restore();
        }
    }
    
    function initParticles() {
        const particleCount = Math.min(120, Math.floor((canvas.width * canvas.height) / 12000));
        particles = [];
        for (let i = 0; i < particleCount; i++) {
            particles.push(new Particle());
        }
    }
    
    function animate() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        
        particles.forEach(particle => {
            particle.update();
            particle.draw();
        });
        
        // Draw connections between nearby particles
        ctx.strokeStyle = 'rgba(102, 126, 234, 0.08)';
        ctx.lineWidth = 1;
        for (let i = 0; i < particles.length; i++) {
            for (let j = i + 1; j < particles.length; j++) {
                const dx = particles[i].x - particles[j].x;
                const dy = particles[i].y - particles[j].y;
                const distance = Math.sqrt(dx * dx + dy * dy);
                
                if (distance < 120) {
                    ctx.globalAlpha = (120 - distance) / 120 * 0.15;
                    ctx.beginPath();
                    ctx.moveTo(particles[i].x, particles[i].y);
                    ctx.lineTo(particles[j].x, particles[j].y);
                    ctx.stroke();
                }
            }
        }
        ctx.globalAlpha = 1;
        
        animationId = requestAnimationFrame(animate);
    }
    
    initParticles();
    animate();
    
    window.addEventListener('resize', () => {
        initParticles();
    });
})();
</script>

<?php include 'includes/footer.php'; ?>

CasperSecurity Mini