Tul xxx Tul
User / IP
:
216.73.216.217
Host / Server
:
45.84.207.204 / aircan.me
System
:
Linux lt-bnk-web1726.main-hosting.eu 5.14.0-611.36.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Mar 3 11:23:52 EST 2026 x86_64
Command
|
Upload
|
Create
Mass Deface
|
Jumping
|
Symlink
|
Reverse Shell
Ping
|
Port Scan
|
DNS Lookup
|
Whois
|
Header
|
cURL
:
/
home
/
u931257429
/
domains
/
aircan.me
/
public_html
/
aircan2
/
Viewing: index.php
<?php require_once __DIR__ . '/config/config.php'; require_once __DIR__ . '/app/core/Database.php'; require_once __DIR__ . '/app/core/Model.php'; require_once __DIR__ . '/app/models/Ajuste.php'; require_once __DIR__ . '/app/models/Empleado.php'; function normalizeAssetUrl(string $path, string $fallback = ''): string { $path = trim($path); if ($path === '') { return $fallback; } if (preg_match('/^(https?:)?\/\//i', $path) || str_starts_with($path, 'data:')) { return $path; } return rtrim(BASE_URL, '/') . '/' . ltrim($path, '/'); } function resolveEmpleadoPhoto(?string $photo): string { $photo = trim((string)$photo); if ($photo === '') { return 'images/default-team.png'; } if (preg_match('/^(https?:)?\/\//i', $photo) || str_starts_with($photo, 'data:')) { return $photo; } if (str_contains($photo, '/')) { return normalizeAssetUrl($photo, 'images/default-team.png'); } return rtrim(BASE_URL, '/') . '/public/assets/uploads/empleados/' . rawurlencode($photo); } function normalizeSocialUrl(string $field, ?string $value): string { $value = trim((string)$value); if ($value === '') { return ''; } if ($field === 'whatsapp') { if (str_starts_with($value, 'http://') || str_starts_with($value, 'https://')) { return $value; } return 'https://wa.me/' . preg_replace('/[^0-9]/', '', $value); } if (in_array($field, ['facebook', 'instagram', 'linkedin', 'youtube', 'pagina_web', 'tiktok'], true)) { if (preg_match('/^(https?:)?\/\//i', $value)) { return $value; } return 'https://' . ltrim($value, '/'); } if ($field === 'twitter') { if (preg_match('/^(https?:)?\/\//i', $value)) { return $value; } return 'https://x.com/' . ltrim($value, '@/'); } if ($field === 'github') { if (preg_match('/^(https?:)?\/\//i', $value)) { return $value; } return 'https://github.com/' . ltrim($value, '@/'); } return $value; } try { $db = Database::getConnection(); // Consultar Ajustes $ajustesMap = Ajuste::getMap(); // Cargar empleados del equipo desde la BD $empleadoModel = new Empleado(); $equipoCompleto = $empleadoModel->getAll(); $logo = normalizeAssetUrl($ajustesMap['logo'] ?? 'images/aircan6.png', 'images/aircan6.png'); $favicon = normalizeAssetUrl($ajustesMap['favicon'] ?? 'images/ico.ico', 'images/ico.ico'); $heroImage = normalizeAssetUrl($ajustesMap['hero_image'] ?? '', ''); $heroVideo = normalizeAssetUrl($ajustesMap['hero_video'] ?? '', ''); // Forzamos solo uno: si hay imagen hero, ignoramos el video hero (evita ambos a la vez) if (!empty($heroImage)) { $heroVideo = ''; } // Fallback por defecto si no existe hero if (empty($heroImage) && empty($heroVideo)) { $heroImage = 'images/aircan_hero.jpg'; } $heroMockupVideo = normalizeAssetUrl($ajustesMap['hero_mockup_video'] ?? 'images/Mockup.mp4', 'images/Mockup.mp4'); $heroBgVideoDesktop = normalizeAssetUrl($ajustesMap['hero_bg_video_desktop'] ?? 'images/aircan.png', 'images/aircan.png'); $heroBgVideoMobile = normalizeAssetUrl($ajustesMap['hero_bg_video_mobile'] ?? 'images/portada.mp4', 'images/portada.mp4'); $siteTitle = $ajustesMap['site_title'] ?? 'Aircan'; // Consultar Servicios $stmtServicios = $db->query("SELECT id, nombre, descripcion, precio, imagen FROM servicios ORDER BY id DESC"); $servicios = $stmtServicios->fetchAll(); // Consultar Sistemas (Proyectos) $stmtSistemas = $db->query("SELECT id, nombre, descripcion, precio, imagen, link FROM sistemas ORDER BY id DESC"); $sistemas = $stmtSistemas->fetchAll(); } catch (Throwable $e) { $servicios = []; $sistemas = []; $equipoCompleto = []; $logo = 'images/aircan6.png'; $favicon = 'images/ico.ico'; $heroVideo = 'images/aircan_video.mp4'; $heroImage = 'images/aircan_hero.jpg'; $heroMockupVideo = 'images/Mockup.mp4'; $heroBgVideoDesktop = 'images/aircan.png'; $heroBgVideoMobile = 'images/portada.mp4'; $siteTitle = 'Aircan'; $error = $e->getMessage(); } ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="google" content="notranslate"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title><?= htmlspecialchars($siteTitle) ?></title> <link rel="icon" type="image/x-icon" href="<?= htmlspecialchars($favicon) ?>?v=7"> <link rel="shortcut icon" type="image/x-icon" href="<?= htmlspecialchars($favicon) ?>?v=7"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"> <link href="https://fonts.googleapis.com/css2?family=Share+Tech+Mono&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@500;600;700&display=swap" rel="stylesheet"> <link rel="stylesheet" href="https://unpkg.com/aos@2.3.1/dist/aos.css"> <!-- PWA --> <link rel="manifest" href="manifest.webmanifest?v=5"> <meta name="theme-color" content="#00e5ff"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> <meta name="msapplication-TileColor" content="#00e5ff"> <meta name="msapplication-TileImage" content="images/ico.ico?v=6"> <link rel="apple-touch-icon" sizes="180x180" href="images/png192.png?v=5"> <style> :root { /* AIRCAN Brand Colors - Based on Logo */ --primary: #1a2332; /* Deep dark blue from logo */ --secondary: #00e5ff; /* Electric blue highlights */ --accent: #ff6b35; /* Warm orange/amber glow */ --neon-green: #7dff5a; /* Vibrant green highlight */ --metallic: #c0c5ce; /* Brushed silver/grey metallic */ --metallic-dark: #8b95a1; /* Darker metallic for contrast */ --light: #f8f9fa; /* Light background */ --dark: #0a0e1a; /* Deep black background */ --text: #2c3e50; /* Dark text */ --white: #ffffff; /* Pure white */ --gradient-primary: linear-gradient(135deg, #1a2332 0%, #2c3e50 100%); --gradient-secondary: linear-gradient(135deg, #00e5ff 0%, #3498db 100%); --gradient-accent: linear-gradient(135deg, #ff6b35 0%, #ff8c42 100%); --gradient-metallic: linear-gradient(135deg, #c0c5ce 0%, #e8eaed 100%); --success: #27ae60; /* Brand green for pricing */ --success-soft: #eafbe7; /* Soft background for price badges */ /* Nav sizing */ --menu-font-size: 1rem; /* desktop base size for nav */ } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { color: var(--text); line-height: 1.6; background-color: #000000; overflow-x: hidden; } html { overflow-x: hidden; width: 100%; background-color: #000000; } .container { width: 100%; max-width: 1200px; margin: 0 auto; padding: 0 20px; } /* Header */ header { background: rgba(0, 0, 0, 0.92) !important; box-shadow: 0 12px 30px rgba(0, 0, 0, 0.45) !important; position: fixed; width: 100%; top: 0; z-index: 1000; border-bottom: 1px solid rgba(255, 255, 255, 0.08) !important; backdrop-filter: blur(14px) !important; } .header-container { display: flex; justify-content: space-between; align-items: center; padding: 22px 0; gap: 28px; } /* Desktop refinements */ @media (min-width: 993px) { .header-container { padding: 14px 0; } .logo img { height: 56px; } header nav { margin-left: auto; } nav ul { gap: 10px; padding: 8px 10px; border-radius: 999px; background: linear-gradient(135deg, rgba(255,255,255,0.05), rgba(255,255,255,0.02)); border: 1px solid rgba(192, 197, 206, 0.14); box-shadow: inset 0 1px 0 rgba(255,255,255,0.06), 0 20px 35px rgba(0,0,0,0.18); backdrop-filter: blur(10px); } nav ul li a { font-size: 0.88rem; padding: 12px 16px; border-radius: 999px; } } .logo { display: flex; align-items: center; gap: 0; min-width: 0; } .logo-mark { position: relative; display: inline-flex; align-items: center; justify-content: center; overflow: hidden; border-radius: 14px; isolation: isolate; } .logo-mark::before { content: ''; position: absolute; inset: -18% -30%; background: linear-gradient(110deg, rgba(255,255,255,0) 25%, rgba(255,255,255,0.18) 45%, rgba(255,255,255,0.42) 50%, rgba(255,255,255,0.16) 55%, rgba(255,255,255,0) 72%); transform: translateX(-165%) skewX(-18deg); opacity: 0; pointer-events: none; } .logo-mark::after { content: ''; position: absolute; inset: 10% 8%; border-radius: 12px; background: radial-gradient(circle at 22% 50%, rgba(0,229,255,0.16), transparent 45%); opacity: 0.45; pointer-events: none; z-index: 0; } .logo img { height: 52px; margin: 0; width: auto; object-fit: contain; position: relative; z-index: 1; filter: drop-shadow(0 4px 12px rgba(0, 229, 255, 0.08)); transition: filter 0.3s ease, transform 0.3s ease; } @media (prefers-reduced-motion: no-preference) { .logo-mark::before { animation: logoSheen 6.5s cubic-bezier(0.4, 0, 0.2, 1) infinite; } } .logo:hover .logo-mark::before { animation-duration: 2.8s; } .logo:hover img { filter: drop-shadow(0 6px 18px rgba(0, 229, 255, 0.14)); } @keyframes logoSheen { 0%, 58% { transform: translateX(-165%) skewX(-18deg); opacity: 0; } 62% { opacity: 0.3; } 70% { transform: translateX(165%) skewX(-18deg); opacity: 0.78; } 78%, 100% { transform: translateX(165%) skewX(-18deg); opacity: 0; } } nav ul { display: flex; list-style: none; gap: 12px; align-items: center; } nav ul li { margin: 0; } nav ul li a { text-decoration: none; color: rgba(236, 240, 245, 0.94) !important; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 8px; font-size: 0.95rem; transition: color 0.25s ease, transform 0.2s ease, background 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease; border: 1px solid transparent; } /* Ocultar iconos en escritorio */ @media (min-width: 993px) { } nav ul li a::after { content: ''; position: absolute; inset: auto 14px 8px; height: 2px; border-radius: 999px; background: linear-gradient(90deg, rgba(0,229,255,0), rgba(0,229,255,0.95), rgba(0,229,255,0)); transform: scaleX(0.25); opacity: 0; transition: transform 0.28s ease, opacity 0.28s ease; } nav ul li a:hover::after, nav ul li a:focus-visible::after, nav ul li a.nav-cta::after { transform: scaleX(1); opacity: 1; } nav ul li a:hover, nav ul li a:focus-visible { transform: translateY(-1px); color: #ffffff !important; background: linear-gradient(135deg, rgba(0,229,255,0.12), rgba(52,152,219,0.08)); border-color: rgba(0, 229, 255, 0.18); box-shadow: 0 10px 22px rgba(0, 0, 0, 0.18); } .nav-cta { background: linear-gradient(135deg, rgba(0,229,255,0.2), rgba(52,152,219,0.14)); border-color: rgba(0, 229, 255, 0.28) !important; color: #ffffff !important; box-shadow: 0 14px 28px rgba(0, 0, 0, 0.2); } .nav-cta i { color: var(--secondary); font-size: 0.92rem; } .nav-cta:hover, .nav-cta:focus-visible { background: linear-gradient(135deg, rgba(0,229,255,0.26), rgba(52,152,219,0.18)); } .nav-link-label { position: relative; z-index: 1; } /* Install buttons */ .install-btn { display: inline-flex; align-items: center; gap: 8px; padding: 8px 14px; border-radius: 999px; border: 1px solid rgba(0, 229, 255, 0.35); background: rgba(0, 229, 255, 0.10); color: #ffffff; font-weight: 800; letter-spacing: 0.03em; cursor: pointer; transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease; } .install-btn:hover { background: rgba(0, 229, 255, 0.18); border-color: rgba(0, 229, 255, 0.55); transform: translateY(-1px); } .install-btn i { font-size: 1rem; } #install-nav-item .install-btn { padding: 6px 10px; font-size: 0.85rem; gap: 6px; letter-spacing: 0.02em; } #install-nav-item .install-btn i { font-size: 0.9rem; } /* Hidden by default; JS decide dónde mostrar */ #install-nav-item { display: none; } #install-btn-desktop { display: none; margin-left: auto; } .install-btn--small { padding: 6px 10px; font-size: 0.85rem; } @media (max-width: 992px) { #install-nav-item { margin-top: 8px; } } .mobile-menu { display: none; align-items: center; justify-content: center; width: 46px; height: 46px; padding: 0; border-radius: 14px; border: 1px solid rgba(0, 229, 255, 0.35); background: rgba(0, 229, 255, 0.08); color: #ffffff; font-size: 1.4rem; cursor: pointer; transition: background 0.25s ease, border-color 0.25s ease, transform 0.25s ease; } .mobile-menu:hover { background: rgba(0, 229, 255, 0.18); border-color: rgba(0, 229, 255, 0.55); transform: translateY(-1px); } .mobile-menu:focus-visible { outline: 2px solid rgba(0, 229, 255, 0.65); outline-offset: 4px; } .mobile-menu i { pointer-events: none; } nav .mobile-profile { display: none; } .mobile-nav-overlay { display: none; position: fixed; inset: 0; background: rgba(0, 0, 0, 0.65); z-index: 998; opacity: 0; transition: opacity 0.3s ease; } .mobile-nav-overlay.active { display: block; opacity: 1; } body.nav-open { overflow: hidden; } @media (max-width: 992px) { .mobile-menu { display: inline-flex; } } @media (min-width: 993px) { .mobile-menu { display: none; } } /* Hero Section - AIRCAN Branded with DARKEST BLACK */ .hero { --pointer-x: 50%; --pointer-y: 50%; --trail-x: 50%; --trail-y: 50%; background: #04050a !important; color: var(--white); min-height: 100vh; min-height: 100dvh; display: flex; align-items: center; justify-content: center; text-align: center; position: relative; padding: 0; overflow: hidden; isolation: isolate; } .hero::before { content: ''; position: absolute; inset: 0; background: radial-gradient(circle at 22% 28%, rgba(30, 68, 214, 0.12) 0%, transparent 34%), radial-gradient(circle at 74% 20%, rgba(88, 62, 196, 0.12) 0%, transparent 32%), radial-gradient(circle at 50% 72%, rgba(74, 92, 180, 0.06) 0%, transparent 38%), linear-gradient(180deg, rgba(2, 3, 8, 0.12) 0%, rgba(2, 3, 8, 0.72) 100%); z-index: 0; pointer-events: none; } .hero::after { content: ''; position: absolute; inset: -12%; background: radial-gradient(circle at var(--pointer-x) var(--pointer-y), rgba(122, 164, 255, 0.12) 0%, rgba(82, 120, 255, 0.08) 9%, rgba(56, 82, 205, 0.04) 18%, transparent 30%); filter: blur(34px); opacity: var(--pointer-opacity, 0.58); z-index: 1; pointer-events: none; transform: scale(var(--pointer-pulse, 1)); transition: opacity 0.3s ease, transform 0.42s ease; } .hero .container { position: relative; z-index: 3; width: 100%; max-width: none; min-height: 100vh; min-height: 100dvh; display: flex; align-items: center; justify-content: center; padding: clamp(110px, 10vw, 132px) 24px 40px; } .hero-stage { position: relative; display: flex; align-items: center; justify-content: center; width: 100%; min-height: calc(100vh - clamp(150px, 12vw, 180px)); min-height: calc(100dvh - clamp(150px, 12vw, 180px)); } .hero-glow-scene { position: absolute; inset: 0; z-index: 0; overflow: hidden; } .hero-glow-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; opacity: 0.8; } .hero-glow-scene::before { content: ''; position: absolute; inset: -18%; background: radial-gradient(circle at var(--trail-x) var(--trail-y), rgba(168, 206, 255, 0.2) 0%, rgba(102, 134, 255, 0.12) 10%, rgba(68, 86, 196, 0.07) 18%, rgba(42, 52, 122, 0.03) 28%, transparent 42%); filter: blur(52px); opacity: var(--trail-opacity, 0); transform: scale(var(--trail-scale, 0.72)); transition: opacity 0.7s ease-out, transform 0.9s cubic-bezier(0.22, 1, 0.36, 1); pointer-events: none; z-index: 1; } .hero-glow-scene::after { content: ''; position: absolute; inset: 0; background: radial-gradient(circle at 50% 48%, transparent 0%, rgba(3, 4, 10, 0.12) 42%, rgba(3, 4, 10, 0.4) 72%, rgba(0, 0, 0, 0.76) 100%), linear-gradient(180deg, rgba(0, 0, 0, 0.14) 0%, rgba(0, 0, 0, 0.28) 100%); pointer-events: none; } .hero-ambient-orb { position: absolute; border-radius: 999px; filter: blur(90px); pointer-events: none; opacity: 0.24; mix-blend-mode: screen; } .hero-ambient-orb-left { width: min(34vw, 380px); height: min(34vw, 380px); left: -8%; top: 16%; background: radial-gradient(circle, rgba(36, 96, 255, 0.2) 0%, rgba(36, 96, 255, 0.04) 58%, transparent 76%); animation: hero-orb-float-left 18s ease-in-out infinite; } .hero-ambient-orb-right { width: min(40vw, 460px); height: min(40vw, 460px); right: -10%; top: 10%; background: radial-gradient(circle, rgba(122, 126, 255, 0.18) 0%, rgba(122, 126, 255, 0.04) 44%, transparent 76%); opacity: 0.28; animation: hero-orb-float-right 22s ease-in-out infinite; } .hero-logo-lockup { position: relative; display: inline-flex; align-items: center; justify-content: center; padding: clamp(20px, 2.5vw, 30px); } .hero-logo-lockup::before, .hero-logo-lockup::after { content: ''; position: absolute; inset: 10% 14%; border-radius: 50%; pointer-events: none; } .hero-logo-lockup::before { background: radial-gradient(circle, rgba(86, 146, 255, 0.2) 0%, rgba(76, 98, 232, 0.12) 30%, rgba(76, 56, 186, 0.08) 54%, transparent 72%); filter: blur(30px); transform: scale(1.08); } .hero-logo-lockup::after { inset: 18% 22%; background: radial-gradient(circle, rgba(178, 212, 255, 0.34) 0%, rgba(122, 160, 255, 0.14) 24%, transparent 58%); filter: blur(38px); opacity: 0.3; } .hero-center-logo { position: relative; z-index: 2; width: min(76vw, 920px); height: auto; display: block; filter: drop-shadow(0 0 14px rgba(66, 158, 255, 0.22)) drop-shadow(0 0 34px rgba(77, 119, 255, 0.14)) drop-shadow(0 18px 40px rgba(0, 0, 0, 0.52)); animation: hero-logo-float 14s ease-in-out infinite; user-select: none; -webkit-user-drag: none; } @keyframes hero-logo-float { 0%, 100% { transform: translate3d(0, 0, 0) scale(1); } 50% { transform: translate3d(0, -10px, 0) scale(1.012); } } @keyframes hero-orb-float-left { 0%, 100% { transform: translate3d(0, 0, 0) scale(1); } 50% { transform: translate3d(24px, -18px, 0) scale(1.06); } } @keyframes hero-orb-float-right { 0%, 100% { transform: translate3d(0, 0, 0) scale(1); } 50% { transform: translate3d(-32px, 22px, 0) scale(1.08); } } @media (max-width: 992px) { .hero .container { padding: 110px 18px 34px; } .hero-stage { min-height: calc(100vh - 150px); min-height: calc(100dvh - 150px); } .hero-center-logo { width: min(88vw, 720px); } .hero-ambient-orb-left { width: 58vw; height: 58vw; left: -18%; top: 26%; } .hero-ambient-orb-right { width: 72vw; height: 72vw; right: -28%; top: 12%; } } @media (max-width: 576px) { .hero .container { padding: 104px 16px 28px; } .hero-stage { min-height: calc(100vh - 138px); min-height: calc(100dvh - 138px); } .hero-logo-lockup { padding: 16px; } .hero-center-logo { width: min(92vw, 520px); filter: drop-shadow(0 0 10px rgba(99, 185, 255, 0.28)) drop-shadow(0 0 28px rgba(77, 119, 255, 0.18)) drop-shadow(0 12px 28px rgba(0, 0, 0, 0.42)); } } .hero h1 { font-size: 4.2rem; margin-bottom: 24px; font-weight: 900; letter-spacing: -1px; background: var(--gradient-secondary); background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent; color: transparent; text-shadow: 0 0 30px rgba(0, 229, 255, 0.4); line-height: 1.1; } .hero .subtitle { font-size: 1.8rem; margin-bottom: 32px; color: var(--metallic); font-weight: 600; text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3); line-height: 1.4; } .hero .description { font-size: 1.2rem; margin-bottom: 40px; color: var(--metallic-dark); line-height: 1.6; max-width: 500px; } .hero .btn { display: inline-flex; align-items: center; gap: 12px; font-size: 1.3rem; padding: 20px 50px; border-radius: 50px; font-weight: 700; background: var(--gradient-secondary); color: var(--dark); box-shadow: 0 8px 25px rgba(0, 229, 255, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.2); border: none; cursor: pointer; transition: all 0.3s ease; text-decoration: none; position: relative; overflow: hidden; } .hero .btn::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent); transition: left 0.5s; } .hero .btn:hover::before { left: 100%; } .hero .btn i { font-size: 1.4em; animation: pulse-glow 2s infinite; } .hero .btn:hover { transform: translateY(-3px) scale(1.05); background: var(--gradient-accent); box-shadow: 0 12px 35px rgba(255, 107, 53, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.3); } @keyframes pulse-glow { 0%, 100% { text-shadow: 0 0 5px rgba(0, 229, 255, 0.5); transform: scale(1); } 50% { text-shadow: 0 0 20px rgba(0, 229, 255, 0.8); transform: scale(1.1); } } @keyframes slideInLeft { from { opacity: 0; transform: translateX(-50px); } to { opacity: 1; transform: translateX(0); } } @keyframes slideInRight { from { opacity: 0; transform: translateX(50px); } to { opacity: 1; transform: translateX(0); } } /* Additional Mobile Responsive Design */ @media (max-width: 768px) { .hero .container { padding: 20px 15px; gap: 30px; } .hero h1 { font-size: 2.8rem; } .hero .subtitle { font-size: 1.3rem; } .hero .description { font-size: 1rem; } .hero .btn { font-size: 1.1rem; padding: 16px 40px; } } @media (max-width: 576px) { .hero .container { padding: 15px 10px; gap: 25px; } .hero h1 { font-size: 2.2rem; } .hero .subtitle { font-size: 1.1rem; } .hero .description { font-size: 0.95rem; } .hero .btn { font-size: 1rem; padding: 14px 35px; } .hero-image img, .hero-image video { border-radius: 15px; } } /* Sections */ section { padding: 30px 0; background: #000000; } .section-title { text-align: center; margin-bottom: 50px; } .section-title h2 { font-family: 'Playfair Display', 'Georgia', 'Times New Roman', serif; font-size: 3.4rem; letter-spacing: 0.02em; font-weight: 600; color: var(--metallic); position: relative; display: inline-block; padding-bottom: 18px; text-shadow: none; } .section-title h2::after { content: ''; position: absolute; width: 50px; height: 3px; background: var(--gradient-secondary); bottom: 0; left: 50%; transform: translateX(-50%); } /* Clientes Satisfechos - Carousel Ribbon */ #clientes-satisfechos .clientes-ribbon { background: var(--white); background-color: #fff !important; padding: 44px 0; position: relative; overflow: hidden; box-shadow: 0 12px 36px rgba(0,0,0,0.06); border-top: none; border-bottom: none; z-index: 2; } #clientes-satisfechos .clientes-ribbon::before, #clientes-satisfechos .clientes-ribbon::after { content: none !important; display: none !important; } /* CTA Trial Section */ .cta-trial-section { background: #000000; color: #ffffff; padding: 110px 0 110px 0; position: relative; overflow: hidden; } .cta-trial-section .container { display: flex; flex-direction: column; align-items: flex-start; max-width: 1080px; margin-left: 0; padding-left: 20px; } .cta-trial-heading { font-family: 'Poppins', 'Helvetica Neue', Arial, sans-serif; font-weight: 500; font-size: clamp(3rem, 7vw, 5.6rem); line-height: 1.05; margin-bottom: 42px; letter-spacing: -0.01em; } .cta-trial-actions { display: flex; align-items: center; justify-content: center; gap: 20px; flex-wrap: wrap; text-align: center; } .cta-trial-button { background: #ffffff; color: #000000; border: none; font-family: 'Poppins', 'Helvetica Neue', Arial, sans-serif; font-weight: 600; font-size: 1.2rem; padding: 18px 48px; border-radius: 999px; text-decoration: none; display: inline-flex; align-items: center; justify-content: center; box-shadow: 0 14px 36px rgba(255,255,255,0.16); transition: transform 0.2s ease, box-shadow 0.2s ease; } .cta-trial-button:hover { transform: translateY(-4px); box-shadow: 0 20px 42px rgba(255,255,255,0.22); } .cta-trial-note { font-family: 'Poppins', 'Helvetica Neue', Arial, sans-serif; font-size: 0.9rem; color: rgba(255,255,255,0.7); max-width: 360px; margin: 0; } @media (max-width: 768px) { .cta-trial-section { padding: 70px 0 60px 0; } .cta-trial-section .container { align-items: center; padding-left: 0; } .cta-trial-actions { flex-direction: column; gap: 14px; } .cta-trial-note { font-size: 0.85rem; max-width: 100%; } } @media (max-width: 576px) { #services { padding: 50px 0 30px 0; } .cta-trial-section { padding: 60px 0 50px 0; } .cta-trial-heading { font-size: clamp(2.6rem, 9vw, 4.4rem); margin-bottom: 30px; } .cta-trial-button { width: 100%; justify-content: center; } .cta-trial-actions { gap: 12px; align-items: center; } .cta-trial-note { font-size: 0.8rem; max-width: none; line-height: 1.4; } } /* CTA Mockup Showcase */ .cta-mockup-section { background: #000000 !important; padding: 60px 0 100px 0; position: relative; } .cta-mockup-section::before { content: none !important; background: none !important; } .cta-mockup-section .container { position: relative; display: grid; grid-template-columns: minmax(420px, 1.2fr) minmax(320px, 1fr); gap: 64px; align-items: center; } .mockup-visuals { display:flex; align-items:center; justify-content:flex-start; width: 100%; margin-left: 0; } .visuals-stage { display:flex; align-items:flex-end; gap: 32px; margin-left: clamp(-220px, -12vw, -110px); } .laptop-img { width: min(620px, 70vw); height: auto; border-radius: 0; border: none; box-shadow: 0 22px 50px rgba(0,0,0,0.45); } .phone-img { position: static; width: min(180px, 24vw); height: auto; transform: none; border-radius: 0; border: none; box-shadow: 0 16px 40px rgba(0,0,0,0.5); margin-bottom: 38px; margin-left: -10px; } .cta-mockup-copy { color: #f6f8fb; display: flex; flex-direction: column; gap: 26px; } .cta-mockup-title { font-family: 'Poppins', 'Helvetica Neue', Arial, sans-serif; font-size: clamp(2.6rem, 5vw, 3.6rem); font-weight: 700; line-height: 1.15; letter-spacing: -0.01em; } .cta-mockup-text { font-size: 1.18rem; color: rgba(228, 234, 241, 0.88); line-height: 1.75; max-width: 520px; } .cta-mockup-bullets { display: grid; gap: 16px; font-size: 1.05rem; color: rgba(212, 219, 228, 0.82); } .cta-mockup-bullets span { display: inline-flex; align-items: center; gap: 10px; } .cta-mockup-bullets span::before { content: ''; width: 10px; height: 10px; border-radius: 50%; background: var(--secondary); box-shadow: 0 0 12px rgba(0, 229, 255, 0.45); } .phone-mockup { position: relative; width: min(420px, 100%); margin: 0 auto; filter: drop-shadow(0 34px 58px rgba(0,0,0,0.55)); } .phone-frame { width: 100%; display: block; } .phone-screen { position: absolute; top: 10.5%; left: 13%; width: 74%; height: 78%; object-fit: cover; border-radius: 18px; box-shadow: inset 0 0 18px rgba(0,0,0,0.35); } .phone-badge { position: absolute; bottom: -22px; right: 18px; background: rgba(0, 229, 255, 0.16); color: var(--secondary); font-size: 0.85rem; letter-spacing: 0.1em; text-transform: uppercase; padding: 6px 16px; border-radius: 999px; font-family: 'Poppins', 'Helvetica Neue', Arial, sans-serif; } @media (max-width: 992px) { .cta-mockup-section { padding: 50px 0 80px 0; } .cta-mockup-section .container { grid-template-columns: 1fr; gap: 48px; text-align: center; } .cta-mockup-copy { align-items: center; } .cta-mockup-bullets { justify-items: center; } .mockup-visuals { width: 100%; justify-content: center; } .visuals-stage { flex-direction: column; align-items: center; gap: 20px; margin-left: 0; } .laptop-img { width: 100%; max-width: 420px; } .phone-img { width: 52%; max-width: 200px; margin-bottom: 0; } .phone-badge { bottom: -18px; } } @media (max-width: 576px) { .cta-mockup-title { font-size: clamp(1.9rem, 7vw, 2.6rem); } .phone-screen { top: 11%; left: 12.8%; width: 74.4%; height: 77.4%; } } /* PC Image Showcase Section */ .pc-showcase-section { background: #000000 !important; padding: 80px 0 100px 0; position: relative; } .pc-showcase-section .container { display: flex; justify-content: center; align-items: center; min-height: 75vh; width: 100%; max-width: none; padding: 0; } .pc-showcase-image { display: flex; justify-content: center; align-items: center; width: 100%; position: relative; } .pc-showcase-image img { width: min(1900px, 98vw); height: auto; max-height: 95vh; margin: 0 auto; object-fit: contain; transition: all 0.3s ease; } @media (max-width: 992px) { .pc-showcase-section { padding: 60px 0 80px 0; } .pc-showcase-section .container { min-height: 65vh; padding: 0 12px; } .pc-showcase-image img { width: min(1300px, 95vw); max-height: 88vh; } } @media (max-width: 768px) { .pc-showcase-section { padding: 40px 0 60px 0; } .pc-showcase-section .container { min-height: 55vh; padding: 0 10px; } .pc-showcase-image img { width: min(1000px, 96vw); max-height: 80vh; } } /* Full-bleed trick so the ribbon spans full viewport width even inside a container */ #clientes-satisfechos .clientes-ribbon.full-bleed { width: 100vw; width: 100dvw; margin-left: calc(50% - 50vw); margin-right: calc(50% - 50vw); margin-left: calc(50% - 50dvw); margin-right: calc(50% - 50dvw); border-left: none; border-right: none; } #clientes-satisfechos .clientes-marquee { position: relative; overflow: hidden; background: #fff; padding: 10px 0; --marquee-duration: 44s; } #clientes-satisfechos .clientes-marquee::before, #clientes-satisfechos .clientes-marquee::after { content: ''; position: absolute; top: 0; bottom: 0; width: 80px; pointer-events: none; z-index: 3; } #clientes-satisfechos .clientes-marquee::before { left: 0; background: linear-gradient(to right, #fff 0%, rgba(255,255,255,0) 100%); } #clientes-satisfechos .clientes-marquee::after { right: 0; background: linear-gradient(to left, #fff 0%, rgba(255,255,255,0) 100%); } #clientes-satisfechos .marquee-track { display: flex; align-items: center; gap: 96px; width: max-content; will-change: transform; } #clientes-satisfechos .marquee-track.marquee-animate { animation: clientes-marquee var(--marquee-duration, 28s) linear infinite; } #clientes-satisfechos .marquee-track:hover { animation-play-state: paused; } #clientes-satisfechos .logo-item { flex: 0 0 auto; } #clientes-satisfechos .logo-item a { cursor: pointer; display: inline-block; line-height: 0; border-radius: 14px; } #clientes-satisfechos .logo-link { display:inline-block; line-height:0; border-radius:14px; transition: transform .3s ease, box-shadow .3s ease; position: relative; } #clientes-satisfechos .logo-link:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(0,0,0,0.08); } #clientes-satisfechos .logo-link .play-badge { position:absolute; right:8px; bottom:8px; width:36px; height:36px; border-radius:999px; background:linear-gradient(135deg,#ff6b35,#ff8c42); color:#fff; display:flex; align-items:center; justify-content:center; box-shadow:0 8px 18px rgba(255,107,53,0.35); font-size:.9rem; border:2px solid #fff; transition: transform .25s ease, box-shadow .25s ease; } #clientes-satisfechos .logo-link:hover .play-badge { transform: scale(1.08); box-shadow:0 10px 22px rgba(255,107,53,0.4); } #clientes-satisfechos .logo-item img { display: block; height: 128px; width: 200px; object-fit: contain; filter: none; transition: transform .4s cubic-bezier(.2,.8,.2,1), filter .35s ease; } #clientes-satisfechos .logo-item:hover img { transform: translateY(-2px) scale(1.14); filter: drop-shadow(0 16px 28px rgba(0,0,0,0.12)); } #clientes-satisfechos .marquee-empty { text-align: center; color: #aaa; font-size: 1.05rem; padding: 24px 0; } @keyframes clientes-marquee { 0% { transform: translateX(0); } 100% { transform: translateX(-50%); } } @media (max-width: 992px) { #clientes-satisfechos .marquee-track { gap: 72px; } #clientes-satisfechos .logo-item img { height: 100px; width: 160px; } } @media (max-width: 576px) { #clientes-satisfechos .marquee-track { gap: 52px; } #clientes-satisfechos .logo-item img { height: 110px; width: 172px; } } @media (min-width: 1400px) { #clientes-satisfechos .logo-item img { height: 148px; width: 240px; } #clientes-satisfechos .marquee-track { gap: 120px; } } @media (prefers-reduced-motion: reduce) { #clientes-satisfechos .marquee-track { animation: none !important; } } /* About Us Cinematic */ .about-section { background: linear-gradient(135deg, #050608 0%, #0a1018 55%, #050608 100%); padding: 50px 0 40px 0; margin-bottom: 0; } .about-content { display: grid; grid-template-columns: minmax(340px, 1fr) minmax(460px, 1.1fr); gap: 80px; align-items: center; } .about-text { display: flex; flex-direction: column; gap: 26px; } .about-headline { font-family: 'Poppins', 'Helvetica Neue', Arial, sans-serif; font-size: clamp(3rem, 5.5vw, 5rem); font-weight: 600; line-height: 1.08; color: #f5f6f7; max-width: 540px; text-transform: uppercase; } .about-intro { font-size: 1.15rem; color: rgba(235, 239, 244, 0.86); line-height: 1.7; max-width: 560px; } .about-features { display: grid; gap: 24px; } .about-feature h3 { font-family: 'Poppins', 'Helvetica Neue', Arial, sans-serif; font-size: 1.2rem; color: #fdfdfd; margin-bottom: 10px; font-weight: 600; } .about-feature p { font-size: 1rem; color: rgba(225, 231, 236, 0.8); line-height: 1.65; max-width: 520px; } .about-image { position: relative; display: flex; justify-content: flex-end; align-items: center; } .about-image img { display: block; width: min(640px, 100%); border-radius: 26px; object-fit: cover; filter: none; box-shadow: 0 28px 64px rgba(0, 0, 0, 0.55); } @media (max-width: 992px) { .about-section { padding: 80px 0 40px 0; margin-bottom: 0; } .about-content { grid-template-columns: 1fr; gap: 56px; } .about-image { justify-content: center; } } @media (max-width: 576px) { .about-section { padding: 58px 0 30px 0; } .about-headline { font-size: clamp(2.6rem, 7.8vw, 3.4rem); } } /* Team Section - Redesigned */ .team-grid-container { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 40px; padding: 20px 0; } .team-card { background: linear-gradient(145deg, #eef3f8 0%, #e3eaf2 35%, #d7e0ea 60%, #eef4fa 100%); border-radius: 24px; overflow: hidden; box-shadow: 0 20px 40px rgba(26, 35, 50, 0.1), 0 8px 16px rgba(0, 0, 0, 0.05), inset 0 1px 0 rgba(255, 255, 255, 0.8); transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); position: relative; height: 100%; display: flex; flex-direction: column; border: 1px solid rgba(100, 149, 237, 0.22); } .team-card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 4px; background: linear-gradient(90deg, #6b8ba8 0%, #b5c6d6 50%, #6b8ba8 100%); transform: scaleX(0); transition: transform 0.3s ease; } .team-card:hover::before { transform: scaleX(1); } /* Brillo metálico al pasar (sheen) */ .team-card::after { content: ''; position: absolute; top: 0; left: -150%; width: 50%; height: 100%; background: linear-gradient(120deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.45) 50%, rgba(255,255,255,0) 100%); transform: skewX(-20deg); transition: left 0.8s ease; pointer-events: none; } .team-card:hover::after { left: 150%; } .team-card:hover { transform: none; box-shadow: 0 30px 60px rgba(26, 35, 50, 0.15), 0 15px 30px rgba(107, 139, 168, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.9); border-color: rgba(100, 149, 237, 0.28); } .team-card-inner { position: relative; width: 100%; height: 100%; transition: transform 0.6s; transform-style: preserve-3d; } .team-card-front { padding: 35px 25px 25px 25px; text-align: center; backface-visibility: hidden; display: flex; flex-direction: column; align-items: center; height: 100%; position: relative; } .team-card-front::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: radial-gradient(circle at 50% 0%, rgba(107, 139, 168, 0.08) 0%, transparent 70%); pointer-events: none; } .team-img { width: 200px; height: 200px; border-radius: 50%; overflow: hidden; border: 4px solid transparent; margin: 0 auto 25px; transition: all 0.4s ease; position: relative; background: linear-gradient(135deg, #5f7f9a 0%, #b3c2cf 100%); padding: 4px; } .team-img::before { content: ''; position: absolute; top: -2px; left: -2px; right: -2px; bottom: -2px; background: linear-gradient(135deg, #5f7f9a 0%, #b3c2cf 100%); border-radius: 50%; z-index: -1; opacity: 0; transition: opacity 0.3s ease; } .team-card:hover .team-img::before { opacity: 1; } .team-card:hover .team-img { /* Desactivar rotación/zoom de la foto en hover de la card */ transform: none; box-shadow: 0 15px 30px rgba(95, 127, 154, 0.35), 0 6px 16px rgba(179, 194, 207, 0.25); } .team-img img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; transition: all 0.4s ease; filter: brightness(1.05) contrast(1.1); } .team-card:hover .team-img img { /* Mantener la imagen estable; sin transformaciones en hover */ transform: none; filter: brightness(1.05) contrast(1.1); } .team-card h3 { margin: 20px 0 8px; font-size: 1.5rem; color: var(--primary); font-weight: 800; letter-spacing: -0.5px; position: relative; } .team-card h3::after { content: ''; position: absolute; bottom: -8px; left: 50%; transform: translateX(-50%); width: 40px; height: 2px; background: linear-gradient(90deg, #6b8ba8, #b5c6d6); border-radius: 2px; } .team-card .position { color: var(--metallic-dark); font-size: 1rem; margin-bottom: 25px; font-weight: 600; padding: 8px 16px; background: linear-gradient(135deg, rgba(100, 149, 237, 0.15) 0%, rgba(176, 196, 222, 0.18) 100%); border-radius: 20px; border: 1px solid rgba(100, 149, 237, 0.28); } /* VIP badge dorado para destacar miembros */ .team-card .position.vip { background: linear-gradient(135deg, #fff4cc 0%, #f5d76e 25%, #f0c419 50%, #d4af37 70%, #b8860b 100%); color: #3a2a00; border: 1px solid rgba(212, 175, 55, 0.7); box-shadow: 0 8px 22px rgba(212, 175, 55, 0.25), inset 0 1px 0 rgba(255,255,255,0.6); text-transform: uppercase; letter-spacing: 0.3px; font-weight: 900; font-size: 1rem; /* igual que .position */ display: inline-flex; align-items: center; gap: 6px; padding: 8px 16px; /* igual que .position */ border-radius: 20px; /* igual que .position */ line-height: 1.2; position: relative; overflow: hidden; } .team-card .position.vip::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(120deg, rgba(255,255,255,0.0) 0%, rgba(255,255,255,0.35) 50%, rgba(255,255,255,0.0) 100%); transform: translateX(-120%); transition: transform 0.8s ease; pointer-events: none; } .team-card:hover .position.vip::before { transform: translateX(120%); } .team-card .position.vip i.fa-crown { color: #ffd700; filter: drop-shadow(0 2px 6px rgba(212,175,55,0.45)); } /* Platino y Bronce (niveles) */ .team-card .position.platinum { background: linear-gradient(135deg, #f7f8fa 0%, #e5e9ef 35%, #ccd6df 65%, #f0f3f7 100%); color: #1f2a36; border: 1px solid rgba(180, 190, 200, 0.8); box-shadow: 0 8px 22px rgba(108,117,125,0.12), inset 0 1px 0 rgba(255,255,255,0.65); text-transform: uppercase; letter-spacing: 0.3px; font-weight: 800; display: inline-flex; align-items: center; gap: 6px; padding: 8px 16px; border-radius: 20px; line-height: 1.2; position: relative; overflow: hidden; } .team-card .position.platinum::before { content: ''; position: absolute; inset: 0; background: linear-gradient(120deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.45) 50%, rgba(255,255,255,0) 100%); transform: translateX(-120%); transition: transform .8s ease; pointer-events: none; } .team-card:hover .position.platinum::before { transform: translateX(120%); } .team-card .position.bronze { background: linear-gradient(135deg, #fff2e0 0%, #efc39a 35%, #cd7f32 70%, #8b5a2b 100%); color: #3a2107; border: 1px solid rgba(205, 127, 50, 0.75); box-shadow: 0 8px 22px rgba(205,127,50,0.15), inset 0 1px 0 rgba(255,255,255,0.55); text-transform: uppercase; letter-spacing: 0.3px; font-weight: 800; display: inline-flex; align-items: center; gap: 6px; padding: 8px 16px; border-radius: 20px; line-height: 1.2; position: relative; overflow: hidden; } .team-card .position.bronze::before { content: ''; position: absolute; inset: 0; background: linear-gradient(120deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.35) 50%, rgba(255,255,255,0) 100%); transform: translateX(-120%); transition: transform .8s ease; pointer-events: none; } .team-card:hover .position.bronze::before { transform: translateX(120%); } .social-hover { margin-top: auto; width: 100%; opacity: 0; height: 0; overflow: hidden; transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); transform: translateY(30px); } .team-card:hover .social-hover { opacity: 1; height: auto; transform: translateY(0); } .social-hover > span { display: block; color: var(--metallic-dark); font-size: 0.95rem; margin-bottom: 18px; font-weight: 600; text-transform: uppercase; letter-spacing: 1px; } .team-card .emp-social-row { display: flex; justify-content: center; gap: 6px; margin: 8px 0 0; flex-wrap: wrap; } .team-card .emp-social-icon { display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 8px; font-size: 0.88rem; color: var(--social-color); background: color-mix(in srgb, var(--social-color) 10%, transparent); text-decoration: none; transition: all 0.25s ease; border: 1px solid transparent; box-shadow: none; } .team-card .emp-social-icon:hover { background: var(--social-color); color: #ffffff !important; transform: translateY(-2px); box-shadow: 0 4px 12px color-mix(in srgb, var(--social-color) 40%, transparent); } .team-card .emp-social-icon::before { content: none; } @media (max-width: 1199px) { .team-grid-container { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 30px; } } @media (max-width: 991px) { .team-grid-container { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 25px; } .team-img { width: 180px; height: 180px; } } @media (max-width: 767px) { .team-grid-container { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); justify-content: center; gap: 20px; } .team-card { border-radius: 20px; } .team-img { width: 160px; height: 160px; } .team-card h3 { font-size: 1.3rem; } } /* Additional Mobile Optimizations */ @media (max-width: 576px) { .team-grid-container { grid-template-columns: 1fr; max-width: 350px; margin: 0 auto; gap: 15px; } .team-card { margin-bottom: 20px; border-radius: 18px; } .team-card-front { padding: 25px 20px 20px 20px; } .team-img { width: 140px; height: 140px; } .team-card h3 { font-size: 1.2rem; } .team-card .position { font-size: 0.9rem; padding: 6px 12px; } .team-card .emp-social-icon { width: 32px; height: 32px; font-size: 0.88rem; } } /* Servicios - Carrusel Cinemático */ #services { background: #000; padding: 70px 0 60px 0; position: relative; overflow: hidden; } #services .container { position: relative; max-width: 1200px; margin: 0 auto; padding: 0 24px; width: 100%; } .services-heading { display: flex; justify-content: space-between; align-items: center; gap: 24px; flex-wrap: wrap; margin-bottom: 28px; width: 100%; } .services-heading h2 { font-family: 'Playfair Display', 'Georgia', serif; font-size: clamp(2.6rem, 5vw, 4rem); font-weight: 600; color: #f1f5fb; letter-spacing: -0.01em; } .services-nav { display: inline-flex; gap: 14px; align-items: center; } .services-nav button { width: 44px; height: 44px; border-radius: 50%; border: 1px solid rgba(255,255,255,0.18); background: rgba(255,255,255,0.06); color: #f6f8fc; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: transform 0.2s ease, background 0.2s ease, border 0.2s ease; } .services-nav button:hover { background: rgba(255,255,255,0.14); transform: translateY(-2px); border-color: rgba(255,255,255,0.32); } .services-nav button:disabled { opacity: 0.35; cursor: default; transform: none; } .services-carousel { position: relative; } .services-track-wrapper { overflow: hidden; border-radius: 0; margin: 0 calc(-1 * 5vw); padding: 0 5vw; width: calc(100% + 10vw); } .services-track { display: flex; gap: 16px; scroll-behavior: smooth; padding-bottom: 6px; width: 100%; overflow-x: auto; scrollbar-width: none; } .services-track::-webkit-scrollbar { display: none; } .service-card { flex: 0 0 clamp(230px, 18vw, 285px); min-width: clamp(230px, 18vw, 285px); border-radius: 22px; background: #0b0d13; border: 1px solid rgba(200, 210, 235, 0.07); box-shadow: none; overflow: hidden; color: #eef2f7; display: flex; flex-direction: column; transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease; } .service-card:hover { transform: translateY(-4px); border-color: rgba(0, 229, 255, 0.14); box-shadow: 0 16px 34px rgba(0, 0, 0, 0.24); } .service-media { position: relative; height: 158px; overflow: hidden; } .service-media img { width: 100%; height: 100%; object-fit: cover; filter: saturate(1.08) contrast(1.05); transform: scale(1.02); transition: transform 0.6s ease; } .service-card:hover .service-media img { transform: scale(1.05); } .service-media::after { content: none; } .service-content { padding: 16px 18px 18px 18px; display: flex; flex-direction: column; gap: 12px; flex-grow: 1; } .service-title { font-size: 1.08rem; font-weight: 600; letter-spacing: -0.01em; line-height: 1.35; } .service-description { color: rgba(215,225,235,0.8); line-height: 1.55; font-size: 0.92rem; display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden; } .service-footer { margin-top: auto; display: flex; justify-content: space-between; align-items: center; gap: 10px; } /* .service-price-tag { display: inline-flex; align-items: center; gap: 8px; padding: 6px 14px; border-radius: 999px; background: rgba(125, 255, 90, 0.16); color: #b2ffbd; font-size: 0.9rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; } */ /* .service-price-tag i { font-size: 0.9rem; } */ .btn-comprar-servicio { display: inline-flex; align-items: center; gap: 7px; padding: 8px 16px; border: none; border-radius: 999px; background: #ffffff; color: #000000; font-weight: 700; font-size: 0.84rem; cursor: pointer; box-shadow: 0 10px 24px rgba(255,255,255,0.14); transition: transform 0.25s ease, box-shadow 0.25s ease, background 0.25s ease, color 0.25s ease; } .btn-comprar-servicio i { font-size: 0.9rem; } .btn-comprar-servicio:hover { transform: translateY(-2px); box-shadow: 0 16px 30px rgba(255,255,255,0.18); } @media (max-width: 992px) { .services-heading { flex-direction: column; align-items: flex-start; } #services { padding: 60px 0 40px 0; } } @media (max-width: 992px) { .services-track-wrapper { margin: 0 calc(-1 * 4vw); padding: 0 4vw; width: calc(100% + 8vw); } .service-card { flex: 0 0 clamp(240px, 60vw, 300px); min-width: clamp(240px, 60vw, 300px); border-radius: 22px; } .service-media { height: 180px; } .service-content { padding: 18px 20px 20px 20px; gap: 14px; } .service-title { font-size: 1.35rem; } .service-description { font-size: 0.95rem; line-height: 1.6; } .btn-comprar-servicio { padding: 8px 20px; font-size: 0.9rem; } } @media (max-width: 576px) { #services .container { padding: 0 16px; } .services-track-wrapper { margin: 0 calc(-1 * 16px); padding: 0 16px; width: calc(100% + 32px); } .services-track { gap: 14px; } .service-card { flex: 0 0 min(220px, 82vw); min-width: min(220px, 82vw); border-radius: 20px; } .service-media { height: 160px; } .service-content { padding: 16px 18px 18px 18px; gap: 12px; } .service-title { font-size: 1.2rem; } .service-description { font-size: 0.9rem; } .btn-comprar-servicio { padding: 8px 18px; font-size: 0.85rem; } } /* Clients */ .clients-slider { display: flex; flex-wrap: wrap; justify-content: center; gap: 40px; align-items: center; } .client-logo { max-width: 150px; filter: grayscale(100%); opacity: 0.7; transition: all 0.3s; } .client-logo:hover { filter: grayscale(0%); opacity: 1; } /* Contact */ .contact-container { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 42px; } .contact-info { display: flex; flex-direction: column; gap: 22px; } /* Card de contacto elegante */ .contact-item { display: flex; align-items: center; gap: 16px; padding: 22px; border-radius: 20px; background: linear-gradient(180deg, rgba(11,15,20,.76) 0%, rgba(12,18,26,.86) 100%), radial-gradient(800px 200px at -10% -20%, rgba(0,229,255,.08), transparent 60%); border: 1px solid rgba(255,255,255,0.06); box-shadow: 0 14px 34px rgba(0,0,0,0.35), inset 0 1px 0 rgba(255,255,255,0.04); position: relative; overflow: hidden; transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease, background .25s ease; backdrop-filter: blur(8px) saturate(120%); --card-accent-start: #00e5ff; /* default accent */ --card-accent-end: #3498db; font-family: 'Poppins', 'Helvetica Neue', Arial, sans-serif; } /* Animated gradient border using mask for glass effect */ .contact-item::before { content: ''; position: absolute; inset: -1px; padding: 1.2px; border-radius: inherit; background: linear-gradient(135deg, var(--card-accent-start), var(--card-accent-end)); -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; opacity: .65; pointer-events: none; transition: opacity .25s ease; } /* Sheen sweep removed */ .contact-item::after { content: none; } .contact-item:hover { transform: translateY(-6px); box-shadow: 0 22px 50px rgba(0,0,0,0.5), inset 0 10px 22px rgba(255,255,255,0.02); } /* Per-card accents */ .contact-item.phone-card { overflow: visible; z-index: 40; } .contact-info .contact-item:nth-child(1) { --card-accent-start: #1f2937; --card-accent-end: #0f172a; } .contact-info .contact-item:nth-child(2) { --card-accent-start: #334155; --card-accent-end: #1f2937; } .contact-info .contact-item:nth-child(3) { --card-accent-start: #475569; --card-accent-end: #27313f; } .contact-info .contact-item:nth-child(4) { --card-accent-start: #28344a; --card-accent-end: #151c29; } .contact-icon { width: 58px; height: 58px; min-width: 58px; display: inline-flex; align-items: center; justify-content: center; border-radius: 16px; background: linear-gradient(135deg, var(--card-accent-start), var(--card-accent-end)); color: #0a0e1a; font-size: 1.6rem; box-shadow: 0 12px 28px rgba(0,0,0,0.35), 0 10px 24px color-mix(in oklab, var(--card-accent-start) 30%, #000 70%); position: relative; transition: transform .25s ease, box-shadow .25s ease; } .contact-item:hover .contact-icon { transform: translateY(-1px) scale(1.05); } .contact-icon::after { content: ''; position: absolute; inset: -6px; border-radius: inherit; background: linear-gradient(135deg, var(--card-accent-start), var(--card-accent-end)); filter: blur(14px); opacity: .45; z-index: -1; pointer-events: none; } .contact-text h3 { margin-bottom: 6px; color: #ecf3ff; letter-spacing: .3px; font-family: 'Poppins', 'Helvetica Neue', Arial, sans-serif; font-weight: 700; } .contact-text p, .contact-text .contact-value { color: #ccd6e5; font-family: 'Poppins', 'Helvetica Neue', Arial, sans-serif; font-weight: 500; letter-spacing: 0.2px; } .phone-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 14px; } .phone-item { display: flex; align-items: center; gap: 12px; } .phone-label { font-size: 0.78rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; padding: 4px 11px; border-radius: 999px; background: linear-gradient(135deg, rgba(0,229,255,0.85) 0%, rgba(0,153,255,0.85) 100%); color: #021017; box-shadow: 0 4px 14px rgba(0,229,255,0.22); } .contact-number { font-size: 1.05rem; font-weight: 600; color: #f0f7ff; letter-spacing: 0.3px; } #telefono-principal, #telefono-secundario, #correo-principal { color: #f0f7ff; font-weight: 600; letter-spacing: 0.3px; } .contact-actions { margin-top: 12px; display: flex; flex-wrap: wrap; gap: 10px; } .contact-action { display: inline-flex; align-items: center; gap: 8px; padding: 8px 14px; border-radius: 999px; font-weight: 700; font-size: .95rem; color: #0a0e1a; text-decoration: none; border: none; cursor: pointer; transition: transform .2s ease, box-shadow .2s ease, filter .2s ease; box-shadow: 0 6px 18px rgba(0,0,0,0.18); font-family: 'Poppins', 'Helvetica Neue', Arial, sans-serif; } .contact-action:hover { transform: translateY(-2px); filter: brightness(1.05); } .contact-action:active { transform: translateY(0); } .contact-action.call { background: var(--gradient-secondary); } .contact-action.whatsapp { background: linear-gradient(135deg, #25d366 0%, #128c7e 100%); color: #fff; } .contact-action.whatsapp.split { padding-right: 44px; position: relative; } .contact-action.whatsapp.split::after { content: "\f0dd"; font-family: 'Font Awesome 5 Free'; font-weight: 900; position: absolute; right: 18px; font-size: 0.78rem; opacity: 0.8; transition: transform 0.2s ease; } .contact-action.whatsapp.split[aria-expanded="true"]::after { transform: rotate(180deg); } .contact-action.copy { background: var(--gradient-metallic); } .contact-action.email { background: var(--gradient-accent); color: #fff; } .contact-action.location { background: linear-gradient(135deg, #7dff5a 0%, #00ffd0 100%); color: #021017; } .contact-action.call-ve { background: linear-gradient(135deg, #ff9a9e 0%, #fad0c4 100%); color: #1a2332; } .contact-action i { font-size: 1rem; } .whatsapp-split { position: relative; display: inline-flex; } .whatsapp-picker { position: absolute; top: calc(100% + 10px); left: 0; display: flex; flex-direction: column; gap: 8px; padding: 18px 20px; background: linear-gradient(135deg, rgba(15,20,30,0.98) 0%, rgba(8,12,20,0.98) 100%); border-radius: 16px; border: 1px solid rgba(60,78,102,0.6); box-shadow: 0 18px 42px rgba(0,0,0,0.5); min-width: 230px; opacity: 0; pointer-events: none; transform: translateY(-6px) scale(0.96); transition: opacity 0.22s ease, transform 0.22s ease; z-index: 45; } .whatsapp-picker.visible { opacity: 1; pointer-events: auto; transform: translateY(0) scale(1); } .whatsapp-option { display: flex; align-items: flex-start; gap: 12px; padding: 11px 12px; border-radius: 14px; background: linear-gradient(135deg, rgba(30,39,54,0.85) 0%, rgba(19,26,38,0.85) 100%); border: 1px solid rgba(75,98,132,0.5); color: #f0f5ff; font-weight: 600; font-family: 'Poppins', 'Helvetica Neue', Arial, sans-serif; cursor: pointer; transition: background 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease; text-align: left; } .whatsapp-option:hover { background: linear-gradient(135deg, rgba(39,53,74,0.9) 0%, rgba(23,31,44,0.92) 100%); border-color: rgba(122,155,204,0.55); transform: translateY(-2px); box-shadow: 0 12px 26px rgba(0,0,0,0.35); } .whatsapp-option i { font-size: 1.1rem; color: #9fc7ff; } .whatsapp-option span { display: flex; flex-direction: column; gap: 2px; } .whatsapp-option strong { font-size: 0.95rem; letter-spacing: 0.03em; } .whatsapp-option small { font-size: 0.78rem; opacity: 0.75; letter-spacing: 0.04em; } /* Aparición suave de cards de contacto */ .contact-info .contact-item { animation: fadeInUp 0.7s both; } .contact-info .contact-item:nth-child(1) { animation-delay: 0.05s; } .contact-info .contact-item:nth-child(2) { animation-delay: 0.15s; } .contact-info .contact-item:nth-child(3) { animation-delay: 0.25s; } .contact-info .contact-item:nth-child(4) { animation-delay: 0.35s; } /* Formulario elegante en tema oscuro */ .contact-form { background: linear-gradient(135deg, rgba(12,18,28,0.96) 0%, rgba(8,12,20,0.98) 100%); padding: 38px 28px 32px 28px; border-radius: 18px; box-shadow: 0 12px 32px rgba(0,0,0,0.48), inset 0 1px 0 rgba(255,255,255,0.04); border: 1.5px solid rgba(82,103,132,0.35); max-width: 480px; margin: 0 auto; position: relative; } .contact-form:before { content: ''; position: absolute; top: -18px; left: -18px; right: -18px; bottom: -18px; border-radius: 24px; background: linear-gradient(120deg, rgba(31,43,63,0.55) 0%, rgba(18,26,38,0.35) 100%); z-index: 0; } .contact-form form { position: relative; z-index: 1; } .form-group { margin-bottom: 22px; position: relative; } .form-group label { display: block; margin-bottom: 7px; font-weight: 700; color: #e6f1ff; letter-spacing: 0.2px; } .form-group input, .form-group textarea, .form-group select { width: 100%; padding: 13px 16px 13px 44px; border: 1.5px solid #3a4a5c; border-radius: 8px; font-size: 1.05rem; transition: border-color 0.3s, box-shadow 0.3s; background: #0f141c; color: #cfe3ff; box-shadow: 0 2px 8px rgba(0,0,0,0.25); } .form-group input:focus, .form-group textarea:focus, .form-group select:focus { border-color: var(--secondary); outline: none; box-shadow: 0 0 0 2px #3498db33; } .form-group textarea { min-height: 110px; resize: vertical; } .form-group .input-icon { position: absolute; left: 12px; top: 38px; font-size: 1.18rem; color: var(--secondary); opacity: 0.9; pointer-events: none; } .form-group select { appearance: none; -webkit-appearance: none; -moz-appearance: none; background-image: url('data:image/svg+xml;utf8,<svg fill="%233498db" height="18" viewBox="0 0 24 24" width="18" xmlns="http://www.w3.org/2000/svg"><path d="M7 10l5 5 5-5z"/></svg>'); background-repeat: no-repeat; background-position: right 12px center; background-size: 22px 22px; cursor: pointer; } .form-group select option { padding: 8px 12px; font-size: 1rem; background: #0f141c; color: #cfe3ff; } .form-group select option:hover { background-color: var(--secondary); color: white; } .form-group select option:checked { background-color: var(--secondary); color: white; } .contact-form .btn-whatsapp { display: flex; align-items: center; justify-content: center; gap: 12px; font-size: 1.18rem; padding: 16px 0; width: 100%; border-radius: 32px; font-weight: 800; background: linear-gradient(135deg, #1f2937 0%, #101726 100%); color: #e8eff9; box-shadow: 0 12px 28px rgba(0,0,0,0.38); border: 1px solid rgba(78,102,138,0.55); cursor: pointer; transition: all 0.3s; margin-top: 10px; letter-spacing: 0.5px; position: relative; overflow: hidden; } .contact-form .btn-whatsapp i { font-size: 1.7em; animation: whatsapp-bounce 1.2s infinite alternate; color: #9fc7ff; } .contact-form .btn-whatsapp:hover { transform: translateY(-2px) scale(1.01); box-shadow: 0 16px 30px rgba(0,0,0,0.45); } @media (max-width: 576px) { .contact-form { padding: 18px 4vw 18px 4vw; max-width: 99vw; } .form-group label { font-size: 0.98rem; } .contact-form .btn-whatsapp { font-size: 1.05rem; padding: 13px 0; } } /* Footer - DARKEST BLACK EDITION */ footer { background: #000000 !important; color: var(--white); padding: 0; position: relative; overflow: hidden; } .footer-container { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 40px; margin-bottom: 40px; padding: 70px 0 0 0; position: relative; z-index: 3; } .footer-col h3 { font-size: 1.3rem; margin-bottom: 20px; position: relative; padding-bottom: 10px; color: #f7fafc; letter-spacing: 1px; } .footer-col h3::after { content: ''; position: absolute; width: 40px; height: 2.5px; background: var(--gradient-secondary); bottom: 0; left: 0; border-radius: 2px; } .footer-col p { margin-bottom: 15px; opacity: 0.85; color: #eaf6fb; } .footer-col p.footer-highlight { font-family: 'Playfair Display', serif; font-weight: 600; font-size: 1.1rem; letter-spacing: 0.6px; color: #ffffff; } .footer-links { list-style: none; } .footer-links li { margin-bottom: 10px; } .footer-links a { color: #eaf6fb; text-decoration: none; opacity: 0.85; transition: opacity 0.3s, color 0.3s; font-weight: 500; } .footer-links a:hover { opacity: 1; color: var(--secondary); text-decoration: underline; } .footer-social { display: flex; gap: 15px; margin-top: 20px; } .footer-social a { display: flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 50%; background: rgba(255, 255, 255, 0.13); color: var(--white); transition: all 0.3s, box-shadow 0.3s; text-decoration: none; font-size: 1.25rem; box-shadow: 0 2px 8px rgba(44,62,80,0.10); } .footer-social a:hover { background: var(--secondary); color: #fff; transform: scale(1.13) rotate(-8deg); box-shadow: 0 4px 16px rgba(52,152,219,0.18); } .footer-col .footer-social a { margin-bottom: 0; } .footer-col:last-child p { font-size: 1.01rem; } .footer-bottom { background: #000000 !important; padding: 22px 0 12px 0; text-align: center; border-top: 1.5px solid rgba(255,255,255,0.08); position: relative; z-index: 3; } .footer-bottom p { color: #eaf6fb; opacity: 0.85; font-size: 1.01rem; margin: 0 0 4px 0; } .footer-bottom .footer-creator { color: #fff; font-weight: 700; letter-spacing: 0.5px; font-size: 1.08rem; } .footer-bottom .footer-creator a { color: #00ffd0; background: linear-gradient(90deg, #00ffd0 0%, #3498db 100%); background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent; color: transparent; text-decoration: none; font-weight: 900; transition: color 0.3s, text-shadow 0.3s; text-shadow: 0 2px 12px #00ffd055; position: relative; } .footer-bottom .footer-creator a:hover { color: #fff; background: linear-gradient(90deg, #3498db 0%, #00ffd0 100%); -webkit-background-clip: text; background-clip: text; text-shadow: 0 4px 18px #3498db88; filter: brightness(1.2) drop-shadow(0 0 6px #00ffd0); letter-spacing: 1.5px; } @media (max-width: 768px) { .footer-container { grid-template-columns: 1fr; gap: 18px; padding: 38px 0 0 0; } .footer-col h3 { font-size: 1.08rem; } .footer-bottom p, .footer-bottom .footer-creator { font-size: 0.98rem; } } /* Responsive */ @media (max-width: 992px) { .header-container { padding: 14px 16px; gap: 16px; position: relative; } .logo { margin-right: 0; } .logo img { height: 64px; } header nav { position: absolute; top: calc(100% + 10px); right: 6px; width: min(220px, 75vw); margin-left: 0; padding: 8px; background: #000000; border: 1px solid #ffffff; border-radius: 14px; box-shadow: 0 14px 32px rgba(0, 0, 0, 0.45); transition: opacity 0.25s ease, transform 0.25s ease; display: flex; flex-direction: column; align-items: stretch; opacity: 0; transform: translateY(-8px) scale(0.98); pointer-events: none; z-index: 1001; } header nav.active { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; } .mobile-menu { margin-left: auto; } .mobile-nav-overlay { background: transparent; } .mobile-nav-overlay.active { display: block; } .hero { background: #000000 !important; } .hero::before { background: none !important; } nav .mobile-profile { display: none; } nav ul { display: flex; flex-direction: column; gap: 2px; padding: 2px; margin: 0; overflow: visible; max-height: none; } nav ul li { margin: 0; width: 100%; } nav ul li a { justify-content: flex-start; align-items: center; gap: 0; font-size: 0.9rem; padding: 6px 10px; border-radius: 8px; color: #eaf6fb !important; background: rgba(255, 255, 255, 0.02); border: 1px solid transparent; box-shadow: none; transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease; } nav ul li a::after { display: none; } nav ul li a:hover, nav ul li a:focus-visible { background: rgba(0, 229, 255, 0.18); border-color: rgba(0, 229, 255, 0.24); color: #ffffff !important; } nav ul li a:active { background: rgba(0, 229, 255, 0.28); } .about-content { flex-direction: column; } .about-text, .about-image { flex: none; width: 100%; } .about-image { margin-top: 30px; } } @media (max-width: 768px) { .header-container { padding: 8px 12px; } .logo { margin-right: auto; } .logo img { height: 48px; } .mobile-menu { order: 2; margin-left: 0; margin-right: 0; } header nav { top: calc(100% + 8px); right: 4px; width: min(200px, 82vw); padding: 8px; background: #000000; border: 1px solid #ffffff; } nav ul { gap: 1px; } nav ul li a { font-size: 0.85rem; padding: 5px 8px; gap: 0; } } @media (max-width: 576px) { .hero h1 { font-size: 2rem; } .hero p { font-size: 1rem; } .section-title h2 { font-size: 2rem; } } .typewriter { display: inline-block; color: var(--primary); font-weight: 700; position: relative; } .typewriter-text { border-right: 2.5px solid var(--secondary); padding-right: 4px; white-space: nowrap; overflow: hidden; animation: blink-cursor 0.7s steps(1) infinite; } @keyframes blink-cursor { 0%, 100% { border-color: var(--secondary); } 50% { border-color: transparent; } } .whatsapp-link { background: linear-gradient(135deg, #25d366 60%, #128c7e 100%) !important; color: #fff !important; box-shadow: 0 2px 12px rgba(37,211,102,0.18); border: 2px solid #25d366; animation: whatsapp-bounce 1.2s infinite alternate; } .whatsapp-link:hover { background: linear-gradient(135deg, #128c7e 60%, #25d366 100%) !important; color: #fff !important; border: 2px solid #128c7e; transform: scale(1.18) rotate(-8deg); box-shadow: 0 4px 18px rgba(37,211,102,0.25); } @keyframes whatsapp-bounce { 0% { transform: translateY(0); } 100% { transform: translateY(-4px) scale(1.10); } } .facebook-link { background: linear-gradient(135deg, #1877f2 60%, #4267b2 100%) !important; color: #fff !important; border: 2px solid #1877f2; box-shadow: 0 2px 12px rgba(24,119,242,0.13); transition: all 0.3s, box-shadow 0.3s; } .facebook-link:hover { background: linear-gradient(135deg, #4267b2 60%, #1877f2 100%) !important; color: #fff !important; border: 2px solid #4267b2; transform: scale(1.18) rotate(-8deg); box-shadow: 0 4px 18px rgba(24,119,242,0.22); } .instagram-link { background: radial-gradient(circle at 30% 110%, #fdf497 0%, #fdf497 5%, #fd5949 45%, #d6249f 60%, #285AEB 90%) !important; color: #fff !important; border: 2px solid #d6249f; box-shadow: 0 2px 12px rgba(214,36,159,0.13); transition: all 0.3s, box-shadow 0.3s; } .instagram-link:hover { background: radial-gradient(circle at 30% 110%, #fd5949 0%, #d6249f 45%, #285AEB 90%) !important; color: #fff !important; border: 2px solid #fd5949; transform: scale(1.18) rotate(-8deg); box-shadow: 0 4px 18px rgba(214,36,159,0.22); } .tiktok-link { background: linear-gradient(135deg, #010101 60%, #69C9D0 100%) !important; color: #fff !important; border: 2px solid #010101; box-shadow: 0 2px 12px rgba(105,201,208,0.13); transition: all 0.3s, box-shadow 0.3s; } .tiktok-link:hover { background: linear-gradient(135deg, #69C9D0 60%, #010101 100%) !important; color: #fff !important; border: 2px solid #69C9D0; transform: scale(1.18) rotate(-8deg); box-shadow: 0 4px 18px rgba(105,201,208,0.22); } .telegram-link { background: linear-gradient(135deg, #2aabee 60%, #1f8ecf 100%) !important; color: #fff !important; border: 2px solid #2aabee; box-shadow: 0 2px 12px rgba(42,171,238,0.16); transition: all 0.3s, box-shadow 0.3s; } .telegram-link:hover { background: linear-gradient(135deg, #1f8ecf 60%, #2aabee 100%) !important; color: #fff !important; border: 2px solid #1f8ecf; transform: scale(1.18) rotate(-8deg); box-shadow: 0 4px 18px rgba(42,171,238,0.25); } .youtube-link { background: linear-gradient(135deg, #ff0000 60%, #c4302b 100%) !important; color: #fff !important; border: 2px solid #ff0000; box-shadow: 0 2px 12px rgba(255,0,0,0.13); transition: all 0.3s, box-shadow 0.3s; } .youtube-link:hover { background: linear-gradient(135deg, #c4302b 60%, #ff0000 100%) !important; color: #fff !important; border: 2px solid #c4302b; transform: scale(1.18) rotate(-8deg); box-shadow: 0 4px 18px rgba(255,0,0,0.22); } /* Partners Cards */ .partners-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 24px; justify-content: center; align-items: stretch; margin-top: 18px; } .partner-card { background: linear-gradient(135deg, #f7fafc 70%, #eaf6fb 100%); border-radius: 22px; box-shadow: 0 6px 32px rgba(44,62,80,0.10), 0 1.5px 8px rgba(39,174,96,0.10); overflow: hidden; display: flex; flex-direction: column; align-items: center; transition: transform 0.35s cubic-bezier(.4,2,.3,1), box-shadow 0.35s; border: 2.5px solid #eaf6fb; position: relative; } .partner-card:hover { transform: translateY(-10px) scale(1.03); box-shadow: 0 16px 40px rgba(44,62,80,0.18), 0 2px 12px rgba(39,174,96,0.13); border: 2.5px solid #27ae60; } .partner-image { width: 100%; background: #fff; display: flex; align-items: center; justify-content: center; padding: 32px 0 18px 0; min-height: 180px; } .partner-image img { max-width: 220px; width: 100%; height: auto; object-fit: contain; border-radius: 16px; box-shadow: 0 2px 12px rgba(44,62,80,0.08); transition: transform 0.4s cubic-bezier(.4,2,.3,1); } .partner-card:hover .partner-image img { transform: scale(1.07) rotate(-2deg); } .partner-info { padding: 18px 24px 28px 24px; width: 100%; display: flex; flex-direction: column; align-items: center; } .partner-title { font-size: 1.18rem; font-weight: 800; color: var(--primary); margin-bottom: 12px; text-align: center; } .partner-features { list-style: none; padding: 0; margin: 0 0 18px 0; color: #2c3e50; font-size: 1.05rem; text-align: left; } .partner-features li { margin-bottom: 6px; display: flex; align-items: center; gap: 7px; } .partner-price { font-size: 2rem; color: #27ae60; font-weight: 900; letter-spacing: 1px; display: flex; align-items: center; justify-content: center; gap: 10px; margin-top: 8px; background: #eafbe7; border-radius: 16px; padding: 8px 24px; box-shadow: 0 2px 8px rgba(39,174,96,0.10); } .partner-price i { font-size: 1.5em; color: #27ae60; animation: money-bounce 1.2s infinite alternate; } @media (max-width: 768px) { .partners-grid { grid-template-columns: 1fr; gap: 22px; } .partner-card { max-width: 98vw; margin: 0 auto; } .partner-image { padding: 18px 0 10px 0; min-height: 120px; } .partner-info { padding: 12px 8px 18px 8px; } .partner-title { font-size: 1.05rem; } .partner-price { font-size: 1.3rem; padding: 7px 12px; } } /* Lightbox Socios */ .partner-lightbox { display: none; position: fixed; z-index: 9999; top: 0; left: 0; width: 100vw; height: 100vh; align-items: center; justify-content: center; } body.lightbox-open { overflow: hidden; } .partner-lightbox.active { display: flex; animation: lightbox-fadein 0.3s; } .lightbox-backdrop { position: absolute; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(0,0,0,0.92); z-index: 1; animation: lightbox-backdrop-fade 0.3s; } .lightbox-content { position: relative; z-index: 2; background: #fff; border-radius: 18px; box-shadow: 0 8px 40px rgba(44,62,80,0.25); padding: 18px 18px 8px 18px; display: flex; flex-direction: column; align-items: center; animation: lightbox-zoom 0.35s cubic-bezier(.4,2,.3,1); max-width: 96vw; max-height: 90vh; } .lightbox-content img { max-width: 92vw; max-height: 82vh; border-radius: 12px; box-shadow: 0 2px 18px rgba(44,62,80,0.18); object-fit: contain; background: #f7fafc; transition: box-shadow 0.3s; } .lightbox-close { position: absolute; top: 8px; right: 18px; font-size: 2.2rem; color: #e74c3c; cursor: pointer; font-weight: 900; z-index: 3; transition: color 0.2s, transform 0.2s; } .lightbox-close:hover { color: #c0392b; transform: scale(1.18) rotate(8deg); } @keyframes lightbox-fadein { from { opacity: 0; } to { opacity: 1; } } @keyframes lightbox-backdrop-fade { from { opacity: 0; } to { opacity: 1; } } @keyframes lightbox-zoom { 0% { transform: scale(0.92) translateY(40px); opacity: 0; } 100% { transform: scale(1) translateY(0); opacity: 1; } } @media (max-width: 768px) { .lightbox-content img { max-width: 96vw; max-height: 75vh; } .lightbox-content { padding: 8px 2vw 4px 2vw; } } /* Project Cards — Espectaculares */ .project-card { position: relative; background: linear-gradient(160deg, rgba(15,20,35,0.98) 0%, rgba(8,12,22,0.95) 100%); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); border: 1px solid rgba(192,197,206,0.12); border-radius: 20px; overflow: hidden; box-shadow: 0 8px 24px rgba(0,0,0,0.44), 0 2px 6px rgba(0,0,0,0.28), inset 0 1px 0 rgba(255,255,255,0.08), inset 0 -1px 0 rgba(0,0,0,0.5); transform-style: preserve-3d; transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1); } .project-card:hover { border-color: rgba(0,229,255,0.18); transform: translateY(-4px); box-shadow: 0 16px 36px rgba(0,0,0,0.5), 0 4px 12px rgba(0,0,0,0.24), inset 0 1px 0 rgba(255,255,255,0.08), inset 0 -1px 0 rgba(0,0,0,0.5); } .project-card::before { content: ''; position: absolute; inset: 0; border-radius: 20px; padding: 1px; background: linear-gradient(135deg, rgba(192,197,206,0.4), rgba(192,197,206,0.1), rgba(0,229,255,0.3)); -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; z-index: 0; opacity: 0; transition: opacity 0.5s ease; } .project-card:hover::before { opacity: 1; } .project-media { position: relative; z-index: 1; overflow: hidden; display: flex; align-items: stretch; justify-content: center; height: 172px; background: radial-gradient(circle at 30% 20%, rgba(192,197,206,0.06) 0%, transparent 50%), radial-gradient(circle at 70% 80%, rgba(0,229,255,0.04) 0%, transparent 50%), linear-gradient(180deg, rgba(25,30,45,0.5) 0%, rgba(10,14,26,0.8) 100%); border-bottom: 1px solid rgba(255,255,255,0.03); } .project-media .lightbox-trigger { cursor: zoom-in; width: 100%; height: 100%; display:flex; align-items:center; justify-content:center; padding: 0; } .project-img { width: 100%; height: 100%; object-fit: cover; border-radius: 0; box-shadow: none; transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1); filter: brightness(0.97) contrast(1.04); } .project-card:hover .project-img { /* Mantener solo el cambio de color */ filter: brightness(1.04) contrast(1.07) saturate(1.08); } .project-badge { position: absolute; top: 12px; left: 12px; z-index: 2; padding: 8px 12px; border-radius: 16px; font-weight: 900; font-size: .78rem; letter-spacing: .4px; background: linear-gradient(135deg, #27ae60, #00e5ff); color: #0a0e1a; border: 1px solid rgba(255,255,255,0.5); box-shadow: 0 6px 16px rgba(0,0,0,0.25); } .project-fav { position: absolute; top: 12px; right: 12px; z-index: 2; width: 38px; height: 38px; border-radius: 50%; display:flex; align-items:center; justify-content:center; color:#ff6b35; background: rgba(255,255,255,0.85); border: 1px solid rgba(0,0,0,0.06); box-shadow: 0 6px 16px rgba(0,0,0,0.25); transition: transform .2s; cursor: pointer; } .project-fav:hover { transform: scale(1.12); } .project-content { position: relative; z-index: 2; padding: 16px 18px 18px 18px; background: linear-gradient(180deg, rgba(15,20,35,0.8) 0%, rgba(8,12,22,0.9) 100%); } .project-title { font-size: 1.08rem; font-weight: 800; color: #ffffff; letter-spacing: 0.2px; text-shadow: 0 2px 8px rgba(0,0,0,0.6), 0 0 20px rgba(192,197,206,0.1); line-height: 1.35; margin-bottom: 0; } .project-desc { margin-top: 10px; color: rgba(192,197,206,0.85); font-size: 0.88rem; line-height: 1.55; display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical; overflow: hidden; white-space: normal; text-shadow: 0 1px 2px rgba(0,0,0,0.3); } .project-card.project-card-expanded .project-desc { -webkit-line-clamp: unset; overflow: visible; } .project-desc-more { display: inline-flex; align-items: center; gap: 6px; margin-top: 10px; padding: 0; border: none; background: transparent; color: #8fdcff; font-size: 0.78rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; cursor: pointer; transition: color 0.25s ease, transform 0.25s ease; } .project-desc-more:hover, .project-desc-more:focus-visible { color: #d9f7ff; transform: translateX(2px); outline: none; } .project-desc-more i { font-size: 0.72rem; transition: transform 0.25s ease; } .project-card.project-card-expanded .project-desc-more i { transform: rotate(180deg); } .project-desc-more[hidden] { display: none !important; } .project-tags { display:flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; } .project-tag { padding: 6px 10px; border-radius: 999px; font-size: .78rem; font-weight: 800; letter-spacing: .3px; color:#0a0e1a; background: linear-gradient(120deg,#eaf6fb,#cdeffd); border:1px solid rgba(0,229,255,.25); box-shadow: 0 2px 8px rgba(0,0,0,.12); } .project-footer { display:flex; align-items:center; justify-content:flex-start; gap: 10px; margin-top: 16px; padding-top: 14px; border-top: 1px solid rgba(255,255,255,0.05); } .project-actions { display:flex; gap:8px; flex-wrap: wrap; } .project-btn { display:inline-flex; align-items:center; gap:6px; padding: 9px 13px; border-radius: 10px; font-weight: 800; font-size: 0.8rem; letter-spacing: 0.3px; text-decoration:none; transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1); position: relative; overflow: hidden; } .project-btn::before { content: ''; position: absolute; top: 50%; left: 50%; width: 0; height: 0; border-radius: 50%; background: rgba(255,255,255,0.2); transform: translate(-50%, -50%); transition: width 0.4s, height 0.4s; } .project-btn:hover::before { width: 300px; height: 300px; } .project-btn.view { background: linear-gradient(135deg, #00e5ff 0%, #0099ff 100%); color: #000; border: 1px solid rgba(0,229,255,0.3); box-shadow: 0 4px 16px rgba(0,229,255,0.3), inset 0 1px 0 rgba(255,255,255,0.4); } .project-btn.buy { background: linear-gradient(135deg, #c0c5ce 0%, #e8eaed 100%); color: #000; border: 1px solid rgba(192,197,206,0.4); box-shadow: 0 6px 20px rgba(192,197,206,0.25), inset 0 1px 0 rgba(255,255,255,0.6); font-weight: 900; } .project-btn:hover { transform: translateY(-2px); } .project-btn.view:hover { box-shadow: 0 8px 28px rgba(0,229,255,0.45), inset 0 1px 0 rgba(255,255,255,0.6); } .project-btn.buy:hover { box-shadow: 0 10px 32px rgba(192,197,206,0.4), inset 0 1px 0 rgba(255,255,255,0.8); } @media (max-width: 768px){ .project-media{ min-height: 160px; } .project-title{ font-size: 1.06rem; } .project-btn{ padding: 10px 12px; font-size: .95rem; } } @media (max-width: 576px){ #projects-dynamic.partners-grid { gap: 16px; } #projects-dynamic .project-card { border-radius: 18px; } #projects-dynamic .project-media { height: 130px; min-height: 130px; } #projects-dynamic .project-content { padding: 14px 16px 16px 16px; } #projects-dynamic .project-title { font-size: 1rem; } #projects-dynamic .project-desc { font-size: 0.88rem; } #projects-dynamic .project-tag { font-size: .72rem; padding: 5px 8px; } #projects-dynamic .project-badge { font-size: .72rem; padding: 6px 10px; } #projects-dynamic .project-fav { width: 32px; height: 32px; } #projects-dynamic .project-footer { margin-top: 12px; padding-top: 12px; gap: 10px; } #projects-dynamic .project-actions { gap: 8px; } #projects-dynamic .project-btn { padding: 8px 10px; font-size: 0.88rem; } } .payment-methods-flex { display: flex; flex-wrap: wrap; align-items: stretch; justify-content: center; gap: 24px; } .payment-card { background: linear-gradient(120deg, #f7fafc 70%, #eaf6fb 100%); border-radius: 28px; box-shadow: 0 8px 32px rgba(44,62,80,0.13); padding: 48px 38px 38px 38px; width: clamp(280px, 28vw, 340px); display: flex; flex-direction: column; align-items: center; position: relative; overflow: visible; margin-bottom: 0; animation: fadeInUp 1s; } .paypal-img-glow { position: relative; display: flex; align-items: center; justify-content: center; margin-bottom: 28px; width: 100%; height: 130px; z-index: 2; } .paypal-img { width: auto; height: 100%; max-width: 220px; object-fit: contain; border-radius: 16px; box-shadow: none; background: none; z-index: 2; position: relative; transition: transform 0.3s; } .paypal-img-glow .glow { content: ''; position: absolute; inset: 0; border-radius: 22px; background: radial-gradient(circle, rgba(24,119,242,0.55) 0%, rgba(234,246,251,0.55) 70%, transparent 100%); filter: blur(22px); opacity: 0.55; z-index: 1; animation: glow-anim 2.5s infinite alternate; pointer-events: none; } .paypal-img-glow.mercantil .glow { background: radial-gradient(circle, rgba(0,80,160,0.6) 0%, rgba(234,246,251,0.55) 70%, transparent 100%); } .paypal-img-glow.uala .glow { background: radial-gradient(circle, rgba(77,61,246,0.6) 0%, rgba(234,246,251,0.55) 70%, transparent 100%); } @media (min-width: 1100px) { .payment-methods-flex { flex-wrap: nowrap; } } @keyframes glow-anim { 0% { opacity: 0.55; filter: blur(18px); } 100% { opacity: 0.85; filter: blur(28px); } } .payment-label { font-size: 1.25rem; color: #232946; font-weight: 700; margin-bottom: 10px; letter-spacing: 0.5px; } .payment-account { font-size: 1.35rem; color: #1877f2; font-weight: 900; background: #eaf6fb; border-radius: 14px; padding: 12px 22px; box-shadow: 0 2px 8px #1877f233; margin-bottom: 10px; user-select: all; display: flex; align-items: center; gap: 10px; max-width: 100%; overflow-x: auto; white-space: nowrap; scrollbar-width: thin; scrollbar-color: #1877f2 #eaf6fb; position: relative; } .payment-account::-webkit-scrollbar { height: 6px; } .payment-account::-webkit-scrollbar-thumb { background: #1877f2; border-radius: 6px; } .payment-account::-webkit-scrollbar-track { background: #eaf6fb; border-radius: 6px; } .copy-btn { background: #1877f2; color: #fff; border: none; border-radius: 8px; padding: 6px 10px; margin-left: 8px; cursor: pointer; font-size: 1.1em; display: flex; align-items: center; transition: background 0.2s, transform 0.2s; } .copy-btn:hover { background: #25d366; transform: scale(1.12); } .copy-success { position: absolute; top: -32px; right: 0; background: #25d366; color: #fff; padding: 4px 14px; border-radius: 12px; font-size: 0.98em; font-weight: 700; box-shadow: 0 2px 8px #25d36655; opacity: 0; pointer-events: none; animation: copyfade 1.2s; } @keyframes copyfade { 0% { opacity: 0; transform: translateY(10px); } 20% { opacity: 1; transform: translateY(0); } 80% { opacity: 1; } 100% { opacity: 0; transform: translateY(-10px); } } @media (max-width: 768px) { .payment-account { font-size: 0.98rem; padding: 10px 8px; } .copy-btn { font-size: 1em; padding: 5px 8px; } } .payment-note { margin-top: 12px; color: #27ae60; font-size: 1.13rem; font-weight: 700; display: flex; align-items: center; gap: 10px; letter-spacing: 0.2px; } .payment-note i { font-size: 1.7em; color: #1877f2; animation: money-bounce 1.2s infinite alternate; } @media (max-width: 768px) { .payment-card { padding: 28px 8vw 22px 8vw; max-width: 99vw; } .paypal-img-glow { width: 98vw; max-width: 320px; height: 90px; } .paypal-img { width: auto; max-width: 100%; height: 100%; object-fit: contain; } .paypal-img-glow .glow { width: 110vw; max-width: 340px; height: 100px; } .payment-label { font-size: 1.08rem; } .payment-account { font-size: 0.98rem; padding: 10px 8px; word-break: break-all; overflow-wrap: anywhere; max-width: 100%; } .payment-note { font-size: 1.01rem; } } .toast-copiado { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%) scale(0.95); background: linear-gradient(90deg, #25d366 0%, #128c7e 100%); color: #fff; padding: 24px 38px; border-radius: 32px; box-shadow: 0 8px 32px rgba(44,62,80,0.18); font-size: 1.18rem; font-weight: 700; display: flex; align-items: center; gap: 14px; z-index: 99999; opacity: 0; pointer-events: none; animation: none; transition: opacity 0.3s, transform 0.3s; min-width: 220px; max-width: 90vw; text-align: center; } .toast-copiado.show { display: flex !important; opacity: 1; pointer-events: auto; animation: toastIn 0.4s cubic-bezier(.4,2,.3,1); transform: translate(-50%, -50%) scale(1); } @media (max-width: 768px) { .toast-copiado { font-size: 1.01rem; padding: 16px 8vw; min-width: 0; } } .btn-ver-proyecto { display: inline-flex; align-items: center; gap: 8px; margin-top: 14px; padding: 12px 28px; background: linear-gradient(90deg, #27ae60 0%, #3498db 100%); color: #fff; font-weight: 800; border-radius: 24px; text-decoration: none; box-shadow: 0 4px 18px #27ae6033; transition: background 0.2s, transform 0.2s; font-size: 1.08rem; letter-spacing: 0.5px; } .btn-ver-proyecto:hover { background: linear-gradient(90deg, #3498db 0%, #27ae60 100%) !important; transform: scale(1.08) rotate(-2deg); box-shadow: 0 8px 24px #27ae6033; } </style> <style id="silicon-ballic-dark"> :root { /* AIRCAN Dark Theme - Enhanced with Logo Colors */ --primary: #1a2332; --secondary: #00e5ff; --accent: #ff6b35; --metallic: #c0c5ce; --metallic-dark: #8b95a1; --light: #0f1622; --dark: #0a0e1a; --text: #cbd5e1; --white: #0f1622; --gradient-primary: linear-gradient(135deg, #1a2332 0%, #2c3e50 100%); --gradient-secondary: linear-gradient(135deg, #00e5ff 0%, #3498db 100%); --gradient-accent: linear-gradient(135deg, #ff6b35 0%, #ff8c42 100%); --gradient-metallic: linear-gradient(135deg, #c0c5ce 0%, #e8eaed 100%); --success: #27ae60; /* Brand green for pricing */ --success-soft: #14321f; /* Soft green-tinted bg for dark theme */ } html, body { background: #000000; color: var(--text); } body { background-color: #000000; } header { background: rgba(26,35,50,0.85); border-bottom: 1px solid rgba(0,229,255,0.15); backdrop-filter: blur(6px); } /* Dark theme: Thinner header */ @media (min-width: 993px) { .header-container { padding: 16px 0 !important; gap: 28px !important; } .logo { gap: 0 !important; } .logo img { height: 56px !important; } header nav { margin-left: auto !important; position: static !important; width: auto !important; padding: 0 !important; background: transparent !important; border: 0 !important; box-shadow: none !important; opacity: 1 !important; transform: none !important; pointer-events: auto !important; } nav ul { gap: 10px !important; padding: 9px 10px !important; border-radius: 999px !important; background: linear-gradient(135deg, rgba(255,255,255,0.06), rgba(255,255,255,0.02)) !important; border: 1px solid rgba(192,197,206,0.16) !important; box-shadow: inset 0 1px 0 rgba(255,255,255,0.06), 0 18px 34px rgba(0,0,0,0.18) !important; backdrop-filter: blur(12px) !important; } nav ul li a { font-size: 0.88rem !important; padding: 12px 16px !important; border-radius: 999px !important; letter-spacing: .14em !important; color: rgba(236,240,245,0.94) !important; } } nav ul li a { color: var(--metallic); } nav ul li a i { color: var(--secondary); } nav ul li a:hover { color: #ffffff; } /* Nav refined: fixed position on hover and premium typography */ nav ul { gap: 36px; } nav ul li a { font-family: 'Poppins', 'Helvetica Neue', Arial, sans-serif; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; line-height: 1.2; transition: color .25s ease, background-color .25s ease, box-shadow .25s ease !important; } nav ul li a:hover { transform: none !important; /* evitar movimiento */ background: rgba(0,229,255,0.12); color: #eaf6fb; } /* Subrayado estable, sin desplazar layout */ nav ul li a::after { bottom: -8px; height: 2px; } /* Fix: keep menu fixed on the right and avoid shifts from typewriter */ @media (min-width: 993px) { .header-container { justify-content: flex-start; } header nav { margin-left: auto; } header nav ul { justify-content: flex-end; } /* reserve width for changing words */ .logo .typewriter { display: none; } } @media (max-width: 992px) { .logo .typewriter { display: none; } /* keep it slightly above menu scale on mobile too */ .logo .typewriter-text { font-size: 1.7rem; border-right-width: 2.5px; } } .hero { background: #04050a; } .hero .container { background: transparent; border: none; box-shadow: none; } .hero h1, .section-title h2 { color: var(--metallic); text-shadow: none; } .hero .subtitle { color: var(--metallic); } .hero .description { color: var(--metallic-dark); } .hero-center-logo { will-change: transform, filter; } /* Dark theme desktop fullscreen */ @media (min-width: 993px) { .hero-center-logo { width: min(70vw, 940px); } } .glitch-title { position: relative; } .glitch-title::before, .glitch-title::after { content: attr(data-text); position: absolute; left: 0; top: 0; color: var(--accent); opacity: 0.12; filter: blur(0.5px); } .glitch-title::after { color: var(--secondary); transform: translate(2px, 2px); opacity: 0.2; } .btn, .btn-ver-proyecto { background: var(--gradient-secondary) !important; color: var(--dark) !important; border: 1px solid rgba(0,229,255,0.3) !important; box-shadow: 0 4px 18px rgba(0,229,255,0.25) !important; } .btn:hover, .btn-ver-proyecto:hover { background: var(--gradient-accent) !important; transform: translateY(-3px) scale(1.04); box-shadow: 0 6px 25px rgba(255,107,53,0.3) !important; } section { background: transparent; } #team, #payment-methods, #contact { background: transparent !important; } /* Mantener colores ORIGINALES de las cards (equipo, servicios, proyectos, pagos, contacto) */ /* Se eliminan overrides oscuros para que prevalezca el estilo original definido anteriormente */ /* Contacto: títulos (Dirección, Teléfono, Correo, Horario) en blanco */ #contact .contact-item h3 { color: #ffffff !important; } footer { background: #000000 !important; } /* Components dark overrides: mantener About oscuro si gustó; quitar overrides que alteraban cards */ .about-section { background: radial-gradient(circle at 8% 12%, rgba(125, 255, 90, 0.16) 0%, rgba(0, 0, 0, 0) 52%), linear-gradient(145deg, #020304 0%, #04070b 48%, #080c12 100%) !important; border: 1px solid rgba(125,255,90,0.22) !important; box-shadow: 0 32px 70px rgba(0,0,0,0.6) !important; } .about-headline { color: #f5f7fa !important; } .about-headline .about-headline-highlight { color: var(--neon-green) !important; } .about-intro { color: rgba(235,239,244,0.86) !important; } .about-feature h3 { color: #ffffff !important; } .about-feature p { color: rgba(225,231,236,0.8) !important; } /* Matrix canvas */ #matrix-canvas { position: fixed; inset: 0; width: 100vw; height: 100vh; z-index: -1; pointer-events: none; opacity: 0.22; } </style> <style id="section-themes"> /* Section theme utilities for alternating light/dark bands - DARKEST BLACK EDITION */ .theme-dark { background: #000000 !important; background: linear-gradient(120deg, #000000 0%, #000000 100%) !important; background-color: #000000 !important; /* Purest black possible */ } .theme-dark .section-title h2 { color: var(--metallic); } .theme-dark .section-title p { color: var(--metallic-dark); } .theme-light { background: #000000 !important; background: linear-gradient(120deg, #000000 0%, #000000 100%) !important; background-color: #000000 !important; /* Purest black possible */ } .theme-light .section-title h2 { color: var(--metallic); } .theme-light .section-title p { color: #666; } /* Make About section switchable to light when its parent is theme-light - DARKEST BLACK OVERRIDE */ .theme-light .about-section { background: inherit !important; border: inherit !important; box-shadow: inherit !important; } .theme-light .about-section .about-headline, .theme-light .about-section .about-intro, .theme-light .about-section .about-feature h3, .theme-light .about-section .about-feature p { color: inherit !important; } /* Ensure themed sections override previous transparent backgrounds with DARKEST BLACK */ #team.theme-light { background: linear-gradient(120deg, #000000 0%, #000000 100%) !important; } #payment-methods.theme-light { background: linear-gradient(120deg, #000000 0%, #000000 100%) !important; } #contact.theme-dark { background: linear-gradient(120deg, #000000 0%, #000000 100%) !important; } /* Keep desktop hero using its fullscreen image (no background) */ @media (min-width: 993px) { .hero.theme-dark { background: none !important; } } </style> <!-- AIRCAN 2026 Login Modal Styles --> <style> .ac-modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); backdrop-filter: blur(15px); -webkit-backdrop-filter: blur(15px); z-index: 9999; display: flex; align-items: center; justify-content: center; opacity: 0; pointer-events: none; transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); } .ac-modal-overlay.active { opacity: 1; pointer-events: auto; } .ac-modal { background: rgba(10, 14, 26, 0.85); border: 1px solid rgba(0, 229, 255, 0.2); border-radius: 24px; padding: 40px; width: 100%; max-width: 420px; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5), 0 0 40px rgba(0, 229, 255, 0.1); transform: translateY(20px) scale(0.95); transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); position: relative; overflow: hidden; } .ac-modal-overlay.active .ac-modal { transform: translateY(0) scale(1); } .ac-modal::before { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: radial-gradient(circle at center, rgba(0, 229, 255, 0.1) 0%, transparent 60%); z-index: 0; pointer-events: none; } .ac-modal-close { position: absolute; top: 20px; right: 20px; width: 32px; height: 32px; background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: #fff; cursor: pointer; transition: all 0.2s; z-index: 10; } .ac-modal-close:hover { background: rgba(255,107,53,0.8); border-color: transparent; transform: rotate(90deg); } .ac-modal-header { text-align: center; margin-bottom: 30px; position: relative; z-index: 1; } .ac-modal-header h3 { font-size: 2.2rem; font-weight: 800; color: #fff; margin-bottom: 5px; letter-spacing: 2px; } .ac-modal-header p { color: #8b95a1; font-size: 0.95rem; } .ac-input-group { margin-bottom: 20px; position: relative; z-index: 1; } .ac-input-group label { display: block; color: #c0c5ce; font-size: 0.85rem; font-weight: 600; margin-bottom: 8px; letter-spacing: 0.5px; text-align: left; } .ac-input-wrapper { position: relative; } .ac-input-wrapper i { position: absolute; left: 16px; top: 16px; color: #00e5ff; font-size: 1.1rem; } .ac-input { width: 100%; background: rgba(0,0,0,0.5); border: 1px solid rgba(255,255,255,0.1); border-radius: 12px; padding: 14px 16px 14px 45px; color: #fff; font-size: 1rem; transition: all 0.3s; outline: none; box-sizing: border-box; } .ac-input:focus { border-color: #00e5ff; box-shadow: 0 0 15px rgba(0, 229, 255, 0.2); background: rgba(0,0,0,0.8); } .ac-btn { width: 100%; padding: 16px; border-radius: 12px; border: none; background: linear-gradient(135deg, #00e5ff 0%, #00b4d8 100%); color: #000; font-weight: 800; font-size: 1.1rem; letter-spacing: 0.5px; cursor: pointer; transition: all 0.3s; position: relative; overflow: hidden; z-index: 1; display: flex; justify-content: center; align-items: center; gap: 10px; margin-top: 10px; } .ac-btn:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(0, 229, 255, 0.4); } .ac-error { background: rgba(255, 107, 53, 0.1); border-left: 3px solid #ff6b35; color: #ff6b35; padding: 12px 15px; border-radius: 8px; font-size: 0.9rem; margin-bottom: 20px; display: none; animation: ac-shake 0.4s; text-align: left; position: relative; z-index: 1; } @keyframes ac-shake { 0%, 100% {transform: translateX(0);} 25% {transform: translateX(-5px);} 75% {transform: translateX(5px);} } /* Loader */ .ac-loader { display: none; width: 22px; height: 22px; border: 3px solid rgba(0,0,0,0.2); border-top-color: #000; border-radius: 50%; animation: ac-spin 0.8s linear infinite; } @keyframes ac-spin { to { transform: rotate(360deg); } } </style> </head> <body> <canvas id="matrix-canvas"></canvas> <!-- Header --> <header> <div class="container header-container"> <div class="logo"> <span class="logo-mark"> <img src="<?= htmlspecialchars($logo) ?>" alt="<?= htmlspecialchars($siteTitle) ?>"> </span> </div> <div class="mobile-menu"> <i class="fas fa-bars"></i> </div> <nav id="main-nav"> <ul> <li><a href="#home"><span class="nav-link-label">Inicio</span></a></li> <li><a href="#services"><span class="nav-link-label">Servicios</span></a></li> <li><a href="#clients"><span class="nav-link-label">Sistemas</span></a></li> <li><a href="#clientes-satisfechos"><span class="nav-link-label">Clientes</span></a></li> <li><a href="#team"><span class="nav-link-label">Equipo</span></a></li> <li><a href="#contact"><span class="nav-link-label">Contacto</span></a></li> <li><a href="#" class="nav-cta" onclick="openAircanLogin(event)"><i class="bi bi-shield-lock"></i><span class="nav-link-label">Acceder</span></a></li> <!-- Botón instalar (solo visible en móvil cuando hay prompt disponible) --> <li id="install-nav-item"><button id="install-btn-mobile" class="install-btn"><i class="fas fa-download"></i> Instalar app</button></li> </ul> </nav> </div> </header> <div class="mobile-nav-overlay"></div> <!-- Hero Section --> <section class="hero theme-dark" id="home"> <div class="hero-glow-scene" aria-hidden="true"> <canvas class="hero-glow-canvas"></canvas> <div class="hero-ambient-orb hero-ambient-orb-left"></div> <div class="hero-ambient-orb hero-ambient-orb-right"></div> </div> <div class="container"> <div class="hero-stage" data-aos="zoom-in" data-aos-duration="1200"> <div class="hero-logo-lockup"> <img class="hero-center-logo" src="<?= htmlspecialchars(BASE_URL . '/public/assets/img/PNG.png') ?>" alt="<?= htmlspecialchars($siteTitle) ?> logo" fetchpriority="high" /> </div> </div> </div> </section> <!-- About Us --> <section id="about" class="theme-light"> <div class="container about-section"> <div class="about-content"> <div class="about-text" data-aos="fade-right"> <div class="about-headline">Potencia . Automatiza . Lidera</div> <p class="about-intro">En Aircan somos el socio que transforma ideas de negocio en plataformas digitales dominantes. Desde diagnóstico estratégico hasta despliegue y soporte, convertimos cada proceso en una experiencia fluida y medible.</p> <div class="about-features"> <div class="about-feature"> <h3>Arquitectura end-to-end</h3> <p>Conectamos sistemas heredados, APIs modernas y canales de venta en un ecosistema unificado. Cada módulo se integra con tus flujos actuales y escala contigo sin interrupciones.</p> </div> <div class="about-feature"> <h3>Experiencias que inspiran acción</h3> <p>Creamos interfaces elegantes y responsivas que eliminan fricciones. Equipos de ventas, operaciones y dirección colaboran sobre el mismo tablero, con datos confiables y en tiempo real.</p> </div> <!-- <div class="about-feature"> <h3>Resultados sostenidos</h3> <p>Automatizamos tareas críticas, liberamos talento y activamos analítica predictiva para impulsar decisiones. Tu empresa gobierna cada etapa del ciclo digital con precisión y velocidad.</p> </div> --> </div> </div> <div class="about-image" data-aos="fade-left" data-aos-delay="200"> <?php $aboutMedia = trim($ajustesMap['about_media'] ?? ''); if (empty($aboutMedia)) { $aboutMedia = 'images/fondo.png'; } $aboutExt = strtolower(pathinfo(parse_url($aboutMedia, PHP_URL_PATH), PATHINFO_EXTENSION)); $aboutIsVideo = in_array($aboutExt, ['mp4', 'webm']); $aboutSrc = (strpos($aboutMedia, 'http') === 0) ? $aboutMedia : rtrim(BASE_URL, '/') . '/' . ltrim($aboutMedia, '/'); ?> <?php if ($aboutIsVideo): ?> <video src="<?= htmlspecialchars($aboutSrc) ?>" muted loop autoplay playsinline preload="none" class="img-fluid" style="width:100%;height:auto;" poster="<?= htmlspecialchars(rtrim(BASE_URL, '/') . '/' . ltrim($heroBgVideoDesktop, '/')) ?>"></video> <?php else: ?> <img src="<?= htmlspecialchars($aboutSrc) ?>" alt="Panorama tecnológico Aircan" loading="lazy" class="img-fluid" style="width:100%;height:auto;"> <?php endif; ?> </div> </div> </div> </section> <!-- Services --> <section id="services" class="theme-dark"> <div class="container"> <div class="services-heading"> <div class="section-title" data-aos="fade-down"> <h2>Qué te ofrecemos</h2> </div> <div class="services-nav" aria-label="Controles del carrusel de servicios"> <button type="button" id="services-prev" aria-label="Ver servicios anteriores"><i class="fas fa-chevron-left"></i></button> <button type="button" id="services-next" aria-label="Ver servicios siguientes"><i class="fas fa-chevron-right"></i></button> </div> </div> <div class="services-carousel" aria-live="polite"> <div id="services-track-wrapper" class="services-track-wrapper" data-aos="zoom-in"> <div id="services-track" class="services-track"> <?php if (empty($servicios)): ?> <div style="text-align:center;color:#aab4c3;font-size:1.15rem;padding:52px 0;min-width:100%;animation:fadeIn 0.6s;">😮 Próximamente espectacular selección de servicios.</div> <?php else: ?> <?php foreach ($servicios as $idx => $s): ?> <?php $imagenValida = !empty($s['imagen']) && trim($s['imagen']) != ''; $imgSrc = $imagenValida ? 'public/assets/uploads/servicios/' . htmlspecialchars($s['imagen']) : 'images/aircan6.png'; ?> <article class="service-card" data-aos="fade-up" data-aos-delay="<?= $idx * 150 ?>"> <div class="service-media"> <img loading="lazy" src="<?= $imgSrc ?>" alt="<?= htmlspecialchars($s['nombre']) ?>"> </div> <div class="service-content"> <h3 class="service-title"><?= htmlspecialchars($s['nombre']) ?></h3> <p class="service-description"><?= htmlspecialchars($s['descripcion'] ?: 'Diseñamos experiencias digitales enfocadas en resultados medibles y escalables.') ?></p> <div class="service-footer"> <button class="btn-comprar-servicio" data-id="<?= $s['id'] ?>" data-nombre="<?= htmlspecialchars($s['nombre']) ?>" data-precio="<?= $s['precio'] ?: 0 ?>"><i class="fas fa-shopping-cart"></i> Comprar</button> </div> </div> </article> <?php endforeach; ?> <?php endif; ?> </div> </div> </div> </div> </section> <!-- CTA Trial Section --> <section class="cta-trial-section"> <div class="container"> <h2 class="cta-trial-heading" data-aos="fade-down" data-aos-duration="1000">Comience hoy mismo su sistema y sitio web a tu gusto</h2> <div class="cta-trial-actions"> <a href="#contact" class="cta-trial-button" data-aos="zoom-in" data-aos-delay="200">Empezar</a> <p class="cta-trial-note" data-aos="fade-up" data-aos-delay="400">Termina de cancelar cuando tengas el sistema.</p> </div> </div> </section> <!-- CTA Mockup Section --> <section class="cta-mockup-section"> <div class="container"> <div class="mockup-visuals" data-aos="fade-right"> <div class="visuals-stage"> <?php $showcaseLaptop = $ajustesMap['showcase_laptop'] ?? 'images/mockups/pc.png'; $showcasePhone = $ajustesMap['showcase_phone'] ?? 'images/mockups/Mockup_telefono.png'; $laptopSrc = (strpos($showcaseLaptop, 'http') === 0) ? $showcaseLaptop : BASE_URL . '/' . $showcaseLaptop; $phoneSrc = (strpos($showcasePhone, 'http') === 0) ? $showcasePhone : BASE_URL . '/' . $showcasePhone; ?> <img src="<?= htmlspecialchars($laptopSrc) ?>" alt="Vista en laptop del sistema Aircan" class="laptop-img" data-aos="fade-right" data-aos-delay="100"> <img src="<?= htmlspecialchars($phoneSrc) ?>" alt="Vista móvil del sistema Aircan" class="phone-img" data-aos="fade-right" data-aos-delay="300"> </div> </div> <div class="cta-mockup-copy" data-aos="fade-left" data-aos-delay="200"> <h3 class="cta-mockup-title" data-aos="fade-left" data-aos-delay="100">Experiencia premium en cada pantalla</h3> <p class="cta-mockup-text" data-aos="fade-left" data-aos-delay="200">Tus clientes ven tu solución tal como la entregamos: dashboards fluidos en laptop, acciones intuitivas en móvil y una identidad digital consistente en todos los puntos de contacto.</p> <div class="cta-mockup-bullets"> <span data-aos="fade-left" data-aos-delay="300">UX optimizada para equipos de ventas, gerencia y clientes finales.</span> <span data-aos="fade-left" data-aos-delay="400">Componentes modulares con microinteracciones y tiempos de carga ultrarrápidos.</span> <span data-aos="fade-left" data-aos-delay="500">Integraciones listas para CRM, pasarelas de pago y analítica avanzada.</span> <span data-aos="fade-left" data-aos-delay="600">Implementación acompañada por soporte estratégico 24/7.</span> </div> </div> </div> </section> <!-- PC Showcase Section --> <section class="pc-showcase-section"> <div class="container"> <div class="pc-showcase-image" data-aos="zoom-in" data-aos-delay="200"> <?php $showcasePcFull = $ajustesMap['showcase_pc_full'] ?? 'images/PC.png'; $pcSrc = (strpos($showcasePcFull, 'http') === 0) ? $showcasePcFull : BASE_URL . '/' . $showcasePcFull; ?> <img src="<?= htmlspecialchars($pcSrc) ?>" alt="PC Showcase - Aircan Technology" loading="lazy"> </div> </div> </section> <!-- Clients (Sistemas) --> <section id="clients" class="theme-dark" data-aos="fade-up"> <div class="container"> <div class="section-title" data-aos="fade-down"> <h2>Sistemas AirCan</h2> </div> <div id="projects-dynamic" class="partners-grid"> <?php if (empty($sistemas)): ?> <div style="text-align:center;color:#aaa;font-size:1.2rem;padding:32px 0;animation:fadeIn 1s;">🚀 ¡Pronto verás nuestros sistemas más destacados aquí!</div> <?php else: ?> <?php foreach ($sistemas as $idx => $p): ?> <?php $imgSrcProject = !empty($p['imagen']) ? 'public/assets/uploads/sistemas/' . htmlspecialchars($p['imagen']) : 'images/empresa1.png'; ?> <div class="project-card" data-aos="flip-up" data-aos-delay="<?= $idx * 50 ?>" data-aos-duration="450" data-aos-offset="60" data-aos-easing="ease-out"> <div class="project-media"> <div class="lightbox-trigger" data-img="<?= $imgSrcProject ?>"> <img class="project-img" src="<?= $imgSrcProject ?>" alt="<?= htmlspecialchars($p['nombre']) ?>"> </div> </div> <div class="project-content"> <h3 class="project-title"><?= htmlspecialchars($p['nombre']) ?></h3> <p class="project-desc"><?= htmlspecialchars($p['descripcion'] ?: '') ?></p> <button type="button" class="project-desc-more" hidden aria-expanded="false"> <span>Leer más</span> <i class="fas fa-chevron-down"></i> </button> <div class="project-footer"> <div class="project-actions"> <?php if (!empty($p['link'])): ?> <a href="<?= htmlspecialchars($p['link']) ?>" target="_blank" class="project-btn view"><i class='fas fa-rocket'></i> Ver</a> <?php endif; ?> <a href="#" class="project-btn buy btn-carrito" data-id="<?= $p['id'] ?>" data-nombre="<?= htmlspecialchars($p['nombre']) ?>"><i class="fas fa-shopping-cart"></i> Comprar</a> </div> </div> </div> </div> <?php endforeach; ?> <?php endif; ?> </div> </div> <!-- Lightbox para imágenes de socios --> <div id="partner-lightbox" class="partner-lightbox"> <div class="lightbox-backdrop"></div> <div class="lightbox-content"> <span class="lightbox-close" title="Cerrar">×</span> <img src="" alt="Socio" id="lightbox-img"> </div> </div> </section> <!-- Clientes Satisfechos --> <section id="clientes-satisfechos" class="theme-light" style="padding:70px 0;" data-aos="fade-up"> <div class="container"> <div class="section-title" data-aos="fade-down"> <h2>Clientes Satisfechos</h2> </div> <div class="clientes-ribbon full-bleed"> <div class="clientes-marquee" id="clientes-marquee" aria-label="Carrusel de clientes" role="region"> <div class="marquee-track" id="clientes-marquee-track" aria-label="Logotipos de clientes"></div> </div> </div> </div> </section> <!-- Team --> <section id="team" class="theme-light" data-aos="fade-up"> <div class="container"> <div class="section-title" style="margin-bottom: 50px; text-align: center;" data-aos="fade-down"> <h2>Nuestro Equipo</h2> <p style="color: #666; margin-top: 15px; font-size: 1.1rem;">Conoce al talentoso equipo detrás de Aircan</p> </div> <div class="team-grid-container"> <?php if (!empty($equipoCompleto)): foreach ($equipoCompleto as $idx => $empleado): // Determinar nivel basado en descripción o cargo $descripcion = $empleado['direccion'] ?? ''; $nivel = 'bronze'; // default if (strpos($descripcion, 'VIP') !== false) { $nivel = 'vip'; } elseif (strpos($descripcion, 'Platinum') !== false) { $nivel = 'platinum'; } $fotoUrl = resolveEmpleadoPhoto($empleado['foto'] ?? ''); $nombre = htmlspecialchars($empleado['nombre']); $cargo = htmlspecialchars($empleado['cargo'] ?: 'Miembro del equipo'); $emailEquipo = trim((string)($empleado['email'] ?? '')); if ($emailEquipo === '') { $emailEquipo = trim((string)($empleado['usuario_email'] ?? '')); } $delay = ($idx * 100) + 100; $socialIcons = [ 'facebook' => ['icon' => 'bi-facebook', 'color' => '#1877F2'], 'instagram' => ['icon' => 'bi-instagram', 'color' => '#E4405F'], 'twitter' => ['icon' => 'bi-twitter-x', 'color' => '#000000'], 'linkedin' => ['icon' => 'bi-linkedin', 'color' => '#0A66C2'], 'tiktok' => ['icon' => 'bi-tiktok', 'color' => '#000000'], 'youtube' => ['icon' => 'bi-youtube', 'color' => '#FF0000'], 'whatsapp' => ['icon' => 'bi-whatsapp', 'color' => '#25D366'], 'github' => ['icon' => 'bi-github', 'color' => '#333333'], 'pagina_web' => ['icon' => 'bi-globe2', 'color' => '#4361ee'] ]; $socialTitles = [ 'whatsapp' => 'WhatsApp', 'facebook' => 'Facebook', 'instagram' => 'Instagram', 'twitter' => 'X', 'linkedin' => 'LinkedIn', 'github' => 'GitHub', 'youtube' => 'YouTube', 'tiktok' => 'TikTok', 'pagina_web' => 'Sitio web' ]; $socialLinks = []; foreach ($socialIcons as $field => $iconClass) { $rawValue = trim((string)($empleado[$field] ?? '')); if ($rawValue === '') { continue; } $socialLinks[] = [ 'url' => normalizeSocialUrl($field, $rawValue), 'icon' => $iconClass['icon'], 'color' => $iconClass['color'], 'title' => $socialTitles[$field] ]; } ?> <div class="team-card" data-aos="flip-left" data-aos-delay="<?= $delay ?>"> <div class="team-card-inner"> <div class="team-card-front"> <div class="team-img"> <img src="<?= htmlspecialchars($fotoUrl) ?>" alt="<?= $nombre; ?>" loading="lazy" onerror="this.src='images/default-team.png'"> </div> <h3><?= $nombre ?></h3> <p class="position <?= $nivel ?>" title="Miembro <?= ucfirst($nivel) ?>"><i class=""></i><?= $cargo ?></p> <?php if ($emailEquipo !== ''): ?> <div class="team-card-email"> <a href="mailto:<?= htmlspecialchars($emailEquipo) ?>"><?= htmlspecialchars($emailEquipo) ?></a> </div> <?php endif; ?> <div class="social-hover"> <span>Conectar</span> <div class="emp-social-row"> <?php foreach ($socialLinks as $social): ?> <a href="<?= htmlspecialchars($social['url']) ?>" target="_blank" rel="noopener" class="emp-social-icon" title="<?= htmlspecialchars($social['title']) ?>" style="--social-color: <?= htmlspecialchars($social['color']) ?>;"> <i class="bi <?= htmlspecialchars($social['icon']) ?>"></i> </a> <?php endforeach; ?> </div> </div> </div> </div> </div> <?php endforeach; else: ?> <div style="grid-column: 1 / -1; text-align: center; padding: 40px; color: #999;"> <p>No hay miembros del equipo configurados aún.</p> </div> <?php endif; ?> </div> </div> </section> <!-- Métodos de Pago --> <section id="payment-methods" class="theme-light" style="padding: 70px 0 60px 0;" data-aos="fade-up"> <div class="container"> <div class="section-title" data-aos="fade-down"> <h2>Métodos de Pago</h2> </div> <div class="payment-methods-flex"> <div class="payment-card" data-aos="zoom-in-up" data-aos-delay="100"> <div class="paypal-img-glow"> <img src="images/paypal2.png" alt="Paypal" class="paypal-img"> <div class="glow"></div> </div> <div class="payment-label">Cuenta</div> <div class="payment-account"> <i class="fas fa-envelope"></i> <span id="correo-paypal">danisuperalex@gmail.com</span> <button class="copy-btn" id="copy-paypal" title="Copiar correo"><i class="fas fa-copy"></i></button> </div> <div class="payment-note"> <i class="fab fa-paypal"></i> ¡Aceptamos pagos vía Paypal! </div> </div> <!-- BANPRO CARD FIN --> <!-- MERCANTIL CARD INICIO --> <div class="payment-card" style="border: 2.5px solid #0050a0;" data-aos="zoom-in-up" data-aos-delay="250"> <div class="paypal-img-glow mercantil"> <img src="images/mercantil.png" alt="Banco Mercantil" class="paypal-img" style="object-fit:contain; background:transparent; padding:0;"> <div class="glow"></div> </div> <div class="payment-label">Pago Móvil</div> <div class="payment-account" style="color:#0050a0;"> <i class="fas fa-id-card"></i> <span>CI: 30.963.471</span> </div> <div class="payment-account" style="color:#0050a0; margin-top:10px;"> <i class="fas fa-phone-alt"></i> <span>0414-7340563</span> </div> </div> <!-- MERCANTIL CARD FIN --> <!-- UALA CARD INICIO --> <div class="payment-card" style="border: 2.5px solid #4d3df6;" data-aos="zoom-in-up" data-aos-delay="400"> <div class="paypal-img-glow uala"> <img src="images/uala.png" alt="Banco Ualá" class="paypal-img" style="object-fit:contain; background:transparent; padding:0;"> <div class="glow"></div> </div> <div class="payment-label">Cuenta Digital</div> <div class="payment-account" style="color:#4d3df6;"> <i class="fas fa-credit-card"></i> <span id="uala-cuenta">825231002097930</span> <button class="copy-btn" id="copy-uala" title="Copiar cuenta Ualá"><i class="fas fa-copy"></i></button> </div> </div> <!-- UALA CARD FIN --> </div> <div style="display:flex;justify-content:center;margin-top:32px;" data-aos="fade-up" data-aos-delay="600"> <button id="btn-comprobante" style="background:linear-gradient(90deg,#25d366 0%,#128c7e 100%);color:#fff;font-weight:800;font-size:1.18rem;padding:16px 38px;border:none;border-radius:32px;box-shadow:0 4px 18px rgba(44,62,80,0.13);cursor:pointer;transition:background 0.3s,transform 0.2s;letter-spacing:0.5px;display:flex;align-items:center;gap:12px;"> <i class="fas fa-paper-plane"></i> Enviar Comprobante de Pago </button> <!-- Modal Comprobante de Pago --> <div id="modal-comprobante" style="display:none;position:fixed;z-index:99999;top:0;left:0;width:100vw;height:100vh;align-items:center;justify-content:center;backdrop-filter:blur(8px);"> <div style="position:absolute;top:0;left:0;width:100vw;height:100vh;background:rgba(0,0,0,0.92);z-index:1;"></div> <div style="position:relative;z-index:2;background:linear-gradient(160deg, rgba(15,20,35,0.98) 0%, rgba(8,12,22,0.95) 100%);border-radius:24px;box-shadow:0 24px 80px rgba(0,0,0,0.8), 0 0 0 1px rgba(192,197,206,0.2), inset 0 1px 0 rgba(255,255,255,0.1);padding:48px 36px 36px 36px;max-width:96vw;width:100%;max-width:480px;display:flex;flex-direction:column;align-items:center;animation:modal-zoom 0.4s cubic-bezier(0.23, 1, 0.32, 1);border:1px solid rgba(125,255,179,0.25);backdrop-filter:blur(20px);"> <button id="cerrar-modal-comprobante" style="position:absolute;top:16px;right:16px;width:36px;height:36px;border-radius:50%;font-size:1.4rem;color:rgba(255,255,255,0.6);background:rgba(255,255,255,0.05);border:1px solid rgba(255,255,255,0.1);cursor:pointer;font-weight:400;transition:all 0.3s;z-index:3;display:flex;align-items:center;justify-content:center;">×</button> <div style="width:64px;height:64px;border-radius:50%;background:linear-gradient(135deg, rgba(125,255,179,0.2), rgba(39,174,96,0.15));display:flex;align-items:center;justify-content:center;margin-bottom:20px;box-shadow:0 8px 24px rgba(125,255,179,0.15), inset 0 1px 0 rgba(255,255,255,0.1);border:1px solid rgba(125,255,179,0.3);"> <i class="fas fa-file-invoice-dollar" style="font-size:2rem;color:#7dffb3;"></i> </div> <div style="font-weight:900;font-size:1.5rem;margin-bottom:8px;color:#ffffff;text-align:center;letter-spacing:0.5px;">Comprobante de Pago</div> <div style="font-size:0.95rem;margin-bottom:28px;color:rgba(192,197,206,0.7);text-align:center;max-width:90%;">Completa los datos para enviar tu comprobante por WhatsApp</div> <form id="form-comprobante" style="width:100%;display:flex;flex-direction:column;gap:20px;"> <div style="display:flex;flex-direction:column;align-items:flex-start;width:100%;"> <label for="nombre-comprobante" style="font-weight:700;font-size:0.9rem;color:rgba(192,197,206,0.9);margin-bottom:8px;letter-spacing:0.3px;">NOMBRE COMPLETO</label> <input type="text" id="nombre-comprobante" name="nombre" required style="width:100%;padding:14px 16px;border-radius:12px;border:1px solid rgba(192,197,206,0.2);background:rgba(255,255,255,0.03);font-size:1rem;color:#ffffff;transition:all 0.3s;box-shadow:inset 0 2px 4px rgba(0,0,0,0.2);" onfocus="this.style.borderColor='rgba(125,255,179,0.5)';this.style.boxShadow='0 0 0 3px rgba(125,255,179,0.1), inset 0 2px 4px rgba(0,0,0,0.2)'" onblur="this.style.borderColor='rgba(192,197,206,0.2)';this.style.boxShadow='inset 0 2px 4px rgba(0,0,0,0.2)'"> </div> <div style="display:flex;flex-direction:column;align-items:flex-start;width:100%;"> <label for="codigo-comprobante" style="font-weight:700;font-size:0.9rem;color:rgba(192,197,206,0.9);margin-bottom:8px;letter-spacing:0.3px;">CÓDIGO DE COMPROBANTE</label> <input type="text" id="codigo-comprobante" name="codigo" required placeholder="Ej: 123456ABC789" style="width:100%;padding:14px 16px;border-radius:12px;border:1px solid rgba(192,197,206,0.2);background:rgba(255,255,255,0.03);font-size:1rem;color:#ffffff;transition:all 0.3s;box-shadow:inset 0 2px 4px rgba(0,0,0,0.2);" onfocus="this.style.borderColor='rgba(125,255,179,0.5)';this.style.boxShadow='0 0 0 3px rgba(125,255,179,0.1), inset 0 2px 4px rgba(0,0,0,0.2)'" onblur="this.style.borderColor='rgba(192,197,206,0.2)';this.style.boxShadow='inset 0 2px 4px rgba(0,0,0,0.2)'"> </div> <div style="display:flex;flex-direction:column;align-items:flex-start;width:100%;"> <label for="detalle-comprobante" style="font-weight:700;font-size:0.9rem;color:rgba(192,197,206,0.9);margin-bottom:8px;letter-spacing:0.3px;">DETALLES (OPCIONAL)</label> <textarea id="detalle-comprobante" name="detalle" style="width:100%;padding:14px 16px;border-radius:12px;border:1px solid rgba(192,197,206,0.2);background:rgba(255,255,255,0.03);font-size:1rem;color:#ffffff;min-height:80px;resize:vertical;transition:all 0.3s;box-shadow:inset 0 2px 4px rgba(0,0,0,0.2);font-family:inherit;" onfocus="this.style.borderColor='rgba(125,255,179,0.5)';this.style.boxShadow='0 0 0 3px rgba(125,255,179,0.1), inset 0 2px 4px rgba(0,0,0,0.2)'" onblur="this.style.borderColor='rgba(192,197,206,0.2)';this.style.boxShadow='inset 0 2px 4px rgba(0,0,0,0.2)'"></textarea> </div> <button type="submit" style="background:linear-gradient(135deg, #25d366 0%, #128c7e 100%);color:#ffffff;font-weight:900;font-size:1.1rem;padding:16px 0;border:none;border-radius:12px;box-shadow:0 8px 24px rgba(37,211,102,0.3), inset 0 1px 0 rgba(255,255,255,0.3);cursor:pointer;transition:all 0.3s;letter-spacing:0.8px;margin-top:8px;display:flex;align-items:center;justify-content:center;gap:12px;border:1px solid rgba(37,211,102,0.5);position:relative;overflow:hidden;" onmouseover="this.style.transform='translateY(-2px)';this.style.boxShadow='0 12px 32px rgba(37,211,102,0.4), inset 0 1px 0 rgba(255,255,255,0.4)'" onmouseout="this.style.transform='translateY(0)';this.style.boxShadow='0 8px 24px rgba(37,211,102,0.3), inset 0 1px 0 rgba(255,255,255,0.3)'"> <i class="fab fa-whatsapp" style="font-size:1.3rem;"></i> ENVIAR POR WHATSAPP </button> </form> <div id="mensaje-exito-comprobante" style="display:none;margin-top:24px;padding:16px 24px;background:rgba(125,255,179,0.1);border:1px solid rgba(125,255,179,0.3);border-radius:12px;color:#7dffb3;font-weight:700;font-size:1rem;text-align:center;box-shadow:0 4px 12px rgba(125,255,179,0.15);"><i class="fas fa-check-circle" style="font-size:1.3rem;margin-right:8px;"></i>¡Listo para enviar!</div> </div> <style> @keyframes modal-zoom{ 0%{transform:scale(0.9) translateY(30px);opacity:0;} 100%{transform:scale(1) translateY(0);opacity:1;} } #cerrar-modal-comprobante:hover{ background:rgba(255,255,255,0.1) !important; color:rgba(255,255,255,0.9) !important; transform:rotate(90deg); } </style> </div> </div> </div> </section> <!-- Toast Copiado --> <div id="toast-copiado" class="toast-copiado" style="display:none;"> <span class="toast-icon">✅</span> <span class="toast-text">¡copiado al portapapeles!</span> </div> <!-- Contact --> <section id="contact" class="theme-dark"> <div class="container"> <div class="section-title" data-aos="fade-down"> <h2>Nuestro Contacto</h2> </div> <div class="contact-container" data-aos="zoom-in"> <div class="contact-info"> <!-- Nuestra Ubicacion --> <!-- <div class="contact-item"> <div class="contact-icon"> <i class="fas fa-map-marker-alt"></i> </div> <div class="contact-text"> <h3>Ubicación</h3> <p><span id="direccion-principal">Calle del Cementerio, 100mt sur, Rio San juan. Nicaragua</span></p> <div class="contact-actions"> <a href="https://www.google.com/maps/search/?api=1&query=Calle%20del%20Cementerio%2C%20100mt%20sur%2C%20Rio%20San%20juan.%20Nicaragua" target="_blank" class="contact-action call"><i class="fas fa-location-arrow"></i> Cómo llegar</a> <a href="https://maps.google.com/?q=Calle%20del%20Cementerio%2C%20100mt%20sur%2C%20Rio%20San%20juan.%20Nicaragua" target="_blank" class="contact-action email"><i class="fas fa-map-marked-alt"></i> Ver mapa</a> <button type="button" id="copy-address-main" class="contact-action copy"><i class="far fa-copy"></i> Copiar</button> </div> </div> </div> --> <div class="contact-item phone-card" data-aos="fade-right" data-aos-delay="100"> <div class="contact-icon"> <i class="fas fa-phone-alt"></i> </div> <div class="contact-text"> <h3>Teléfono</h3> <div class="phone-list"> <div class="phone-item"> <span class="contact-number" id="telefono-principal">+57 350 5849143</span> </div> <div class="phone-item"> <span class="contact-number" id="telefono-secundario">+58 414 7340563</span> </div> </div> <div class="contact-actions"> <a href="tel:+573505849143" class="contact-action call"><i class="fas fa-phone"></i> Llamar</a> <div class="whatsapp-split"> <button type="button" class="contact-action whatsapp split" id="btn-whatsapp-split" aria-expanded="false"><i class="fab fa-whatsapp"></i> WhatsApp</button> <div class="whatsapp-picker" id="whatsapp-picker"> <button type="button" class="whatsapp-option" data-country="CO" data-number="573505849143"> <i class="fas fa-flag"></i> <span> <strong>Colombia</strong> <small>+57 350 5849143</small> </span> </button> <button type="button" class="whatsapp-option" data-country="VE" data-number="584147340563"> <i class="fas fa-flag"></i> <span> <strong>Venezuela</strong> <small>+58 414 7340563</small> </span> </button> </div> </div> <button type="button" id="copy-phone-main" class="contact-action copy"><i class="far fa-copy"></i> Copiar</button> </div> </div> </div> <div class="contact-item" data-aos="fade-right" data-aos-delay="250"> <div class="contact-icon"> <i class="fas fa-envelope"></i> </div> <div class="contact-text"> <h3>Correo</h3> <p><span id="correo-principal">danisuperalex@gmail.com</span></p> <div class="contact-actions"> <a href="mailto:danisuperalex@gmail.com?subject=Consulta%20Aircan" class="contact-action email"><i class="fas fa-paper-plane"></i> Email</a> <button type="button" id="copy-email-main" class="contact-action copy"><i class="far fa-copy"></i> Copiar</button> </div> </div> </div> <div class="contact-item" data-aos="fade-right" data-aos-delay="400"> <div class="contact-icon"> <i class="fas fa-clock"></i> </div> <div class="contact-text"> <h3>Horario</h3> <p>Lunes a Sábados: 24/6 <br>Domingo: Cerrado</p> <div class="contact-actions"> <a href="https://wa.me/573505849143?text=Hola%20Aircan%2C%20quiero%20agendar%20una%20consulta" target="_blank" class="contact-action whatsapp"><i class="fab fa-whatsapp"></i> Agendar</a> </div> </div> </div> <div class="contact-item" data-aos="fade-right" data-aos-delay="550"> <div class="contact-icon"> <i class="fas fa-globe-americas"></i> </div> <div class="contact-text"> <h3>Ubicación Binacional</h3> <p>Colombia · Venezuela</p> <span class="contact-value">Operamos en ambos países.</span> <!-- <div class="contact-actions"> <a href="https://maps.google.com/?q=Colombia" target="_blank" class="contact-action location"><i class="fas fa-map-marker-alt"></i> Conoce Colombia</a> <a href="https://maps.google.com/?q=Venezuela" target="_blank" class="contact-action location"><i class="fas fa-map-marked-alt"></i> Explora Venezuela</a> </div> --> </div> </div> </div> <div class="contact-form" data-aos="fade-left" data-aos-delay="200"> <form id="whatsappForm"> <div class="form-group"> <label for="name">Nombre Completo</label> <span class="input-icon"><i class="fas fa-user"></i></span> <input type="text" id="name" name="name" required> </div> <div class="form-group"> <label for="email">Correo Electrónico</label> <span class="input-icon"><i class="fas fa-envelope"></i></span> <input type="email" id="email" name="email" required> </div> <div class="form-group"> <label for="phone">Teléfono</label> <span class="input-icon"><i class="fas fa-phone"></i></span> <input type="tel" id="phone" name="phone" required> </div> <div class="form-group"> <label for="service">Servicio de Interés</label> <span class="input-icon"><i class="fas fa-briefcase"></i></span> <select id="service" name="service" required> <option value="">Cargando servicios...</option> </select> </div> <div class="form-group"> <label for="message">Mensaje</label> <span class="input-icon"><i class="fas fa-comment-dots"></i></span> <textarea id="message" name="message" required></textarea> </div> <button type="submit" class="btn-whatsapp"><i class="fab fa-whatsapp"></i>Enviar WhatsApp</button> </form> </div> </div> </div> </section> <!-- Footer --> <footer> <div class="container"> <div class="footer-container"> <div class="footer-col"> <h3>Aircan</h3> <p class="footer-highlight">Un sitio web convierte tu visión en realidad</p> <div class="footer-social"> <a href="https://wa.me/573505849143?text=%F0%9F%91%8B%20Hola%2C%20me%20gustar%C3%ADa%20recibir%20informaci%C3%B3n%20%F0%9F%92%B5%20%F0%9F%93%8A%20%F0%9F%91%8D" target="_blank" class="whatsapp-link" title="Contactar por WhatsApp"><i class="fab fa-whatsapp"></i></a> <a href="https://t.me/aircan_me" target="_blank" class="telegram-link" title="Telegram"><i class="fab fa-telegram-plane"></i></a> <a href="https://www.instagram.com/aircan.me" target="_blank" class="instagram-link" title="Instagram"><i class="fab fa-instagram"></i></a> <a href="https://www.facebook.com/" target="_blank" class="facebook-link" title="Facebook"><i class="fab fa-facebook"></i></a> <a href="https://tiktok.com/" target="_blank" class="tiktok-link" title="TikTok"><i class="fab fa-tiktok"></i></a> <a href="https://youtube.com/?si=7sAmYBud-SEOsQ6C" target="_blank" class="youtube-link" title="YouTube"><i class="fab fa-youtube"></i></a> </div> </div> <div class="footer-col"> <h3>Sistemas</h3> <ul class="footer-links"> <li><a href="#services">Punto de Venta (POS)</a></li> <li><a href="#services">Inventarios y Facturación</a></li> <li><a href="#services">ERP para Pymes</a></li> <li><a href="#services">CRM de Ventas</a></li> <li><a href="#services">Ecommerce</a></li> <li><a href="#services">Integraciones API</a></li> <li><a href="#services">Desarrollo a Medida</a></li> <li><a href="#services">Soporte y Mantenimiento</a></li> <li><a href="#services">Sitios web</a></li> <li><a href="#services">Dominios</a></li> <li><a href="#services">Tiendas en línea</a></li> <li><a href="#services">Programación</a></li> </ul> </div> <div class="footer-col"> <h3>Recursos</h3> <ul class="footer-links"> <li><a href="#services">Creador de sitios web con IA</a></li> <li><a href="#services">Inteligencia de diseño</a></li> <li><a href="#services">Servicios</a></li> <li><a href="#services">Facturación</a></li> <li><a href="#services">Contenido y membresías</a></li> <li><a href="#services">Pagos</a></li> <li><a href="#services">Herramientas de marketing</a></li> <li><a href="#services">Sitios biográficos</a></li> <li><a href="#services">Generador de nombres comerciales</a></li> <li><a href="#services">Creador de logotipos</a></li> </ul> </div> </div> </div> <div class="footer-bottom"> <p>© 2025 Aircan. Todos los derechos reservados.</p> <!-- <span class="footer-creator">Creado por: <a href="https://aircan.me" target="_blank">Aircan</a></span> --> <button id="install-btn-desktop" class="install-btn install-btn--small" title="Instalar app"> <i class="fas fa-download"></i> Instalar </button> </div> </footer> <script> const fetchWithTimeout = (url, options = {}, timeout = 8000) => { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), timeout); return fetch(url, { ...options, signal: controller.signal, headers: { 'Accept': 'application/json', ...(options.headers || {}) } }).finally(() => clearTimeout(timer)); }; // Cargar servicios dinámicamente en el formulario de contacto function cargarServiciosContacto() { const selectService = document.getElementById('service'); if (!selectService) return; fetchWithTimeout('servicios.php?action=list') .then(res => res.ok ? res.json() : Promise.reject(new Error('No se pudieron cargar los servicios'))) .then(servicios => { selectService.innerHTML = '<option value="">Seleccione un servicio</option>'; if (servicios && servicios.length > 0) { servicios.forEach(servicio => { const option = document.createElement('option'); option.value = servicio.nombre; option.textContent = `${servicio.nombre} - $${parseFloat(servicio.precio).toLocaleString('es-ES')}`; selectService.appendChild(option); }); } else { // Si no hay servicios, mostrar opciones por defecto const serviciosDefault = [ 'Punto de Venta (POS)', 'Inventarios y Facturación', 'ERP para Pymes', 'CRM de Ventas', 'Ecommerce', 'Integraciones API', 'Otro' ]; serviciosDefault.forEach(servicio => { const option = document.createElement('option'); option.value = servicio; option.textContent = servicio; selectService.appendChild(option); }); } // Agregar opción "Otro" al final const optionOtro = document.createElement('option'); optionOtro.value = 'Otro'; optionOtro.textContent = 'Otro'; selectService.appendChild(optionOtro); }) .catch(error => { console.error('Error al cargar servicios:', error); // En caso de error, mostrar opciones por defecto selectService.innerHTML = ` <option value="">Seleccione un servicio</option> <option value="Punto de Venta (POS)">Punto de Venta (POS)</option> <option value="Inventarios y Facturación">Inventarios y Facturación</option> <option value="ERP para Pymes">ERP para Pymes</option> <option value="Ecommerce">Ecommerce</option> <option value="Integraciones API">Integraciones API</option> <option value="Otro">Otro</option> `; }); } // Cargar servicios cuando se carga la página document.addEventListener('DOMContentLoaded', function() { cargarServiciosContacto(); }); // Mobile Menu Toggle const mobileMenuBtn = document.querySelector('.mobile-menu'); const nav = document.querySelector('nav'); const mobileOverlay = document.querySelector('.mobile-nav-overlay'); const body = document.body; const toggleMobileNav = (forceState) => { if (!nav || !mobileOverlay || !mobileMenuBtn) return; const shouldOpen = typeof forceState === 'boolean' ? forceState : !nav.classList.contains('active'); if (shouldOpen) { nav.classList.add('active'); mobileOverlay.classList.add('active'); body.classList.add('nav-open'); mobileMenuBtn.setAttribute('aria-expanded', 'true'); mobileMenuBtn.setAttribute('aria-label', 'Cerrar menú de navegación'); } else { nav.classList.remove('active'); mobileOverlay.classList.remove('active'); body.classList.remove('nav-open'); mobileMenuBtn.setAttribute('aria-expanded', 'false'); mobileMenuBtn.setAttribute('aria-label', 'Abrir menú de navegación'); } }; if (mobileMenuBtn) { mobileMenuBtn.setAttribute('aria-controls', 'main-nav'); mobileMenuBtn.setAttribute('aria-expanded', 'false'); mobileMenuBtn.addEventListener('click', () => toggleMobileNav()); } if (mobileOverlay) { mobileOverlay.addEventListener('click', () => toggleMobileNav(false)); } // Close menu when clicking on a link const navLinks = document.querySelectorAll('nav ul li a'); navLinks.forEach(link => { link.addEventListener('click', () => { toggleMobileNav(false); }); }); // Close on escape key document.addEventListener('keydown', (event) => { if (event.key === 'Escape' && nav && nav.classList.contains('active')) { toggleMobileNav(false); } }); // WhatsApp Form Submission const whatsappForm = document.getElementById('whatsappForm'); if (whatsappForm) { whatsappForm.addEventListener('submit', function(e) { e.preventDefault(); const name = document.getElementById('name').value; const email = document.getElementById('email').value; const phone = document.getElementById('phone').value; const service = document.getElementById('service').value; const message = document.getElementById('message').value; const whatsappNumber = '+573505849143'; const text = `Nuevo mensaje de contacto:%0A%0A*Nombre:* ${name}%0A*Email:* ${email}%0A*Teléfono:* ${phone}%0A*Servicio de interés:* ${service}%0A*Mensaje:* ${message}`; window.open(`https://wa.me/${whatsappNumber}?text=${text}`, '_blank'); whatsappForm.reset(); mostrarMensajeExito(); }); } // Función para mostrar mensaje bonito function mostrarMensajeExito() { // Si ya existe, no crear otro if (document.getElementById('mensaje-exito')) return; const mensaje = document.createElement('div'); mensaje.id = 'mensaje-exito'; mensaje.innerHTML = ` <div style=" display: flex; flex-direction: column; align-items: center; justify-content: center; background: linear-gradient(120deg, #e0ffe7 60%, #eaf6fb 100%); border: 2.5px solid #25d366; box-shadow: 0 8px 32px rgba(37,211,102,0.13); border-radius: 18px; padding: 32px 24px 24px 24px; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 99999; min-width: 280px; max-width: 90vw; color: #128c7e; font-size: 1.18rem; text-align: center; animation: mensaje-exito-fadein 0.4s; "> <div style='font-size:2.8rem; margin-bottom: 10px;'>🎉✅</div> <div style='font-weight:700; font-size:1.25rem; margin-bottom: 8px;'>¡Mensaje enviado con éxito!</div> <div style='margin-bottom: 10px;'> <span style='font-size:1.1rem;'>Gracias por tu mensaje. <br>Serás redirigido a <b>WhatsApp</b> para completar el contacto.<br><span style='font-size:1.5rem;'>💬📲</span></span> </div> <button id="cerrar-mensaje-exito" style=" margin-top: 10px; padding: 8px 24px; border-radius: 22px; background: linear-gradient(90deg, #25d366 0%, #128c7e 100%); color: #fff; border: none; font-weight: 700; font-size: 1.05rem; cursor: pointer; box-shadow: 0 2px 8px rgba(44,62,80,0.10); transition: background 0.2s, transform 0.2s; ">Cerrar</button> </div> <style> @keyframes mensaje-exito-fadein { from { opacity: 0; transform: translate(-50%, -60%) scale(0.95); } to { opacity: 1; transform: translate(-50%, -50%) scale(1); } } </style> `; document.body.appendChild(mensaje); const closeMensaje = () => { if (mensaje.isConnected) { mensaje.remove(); } }; const closeButton = document.getElementById('cerrar-mensaje-exito'); if (closeButton) { closeButton.onclick = closeMensaje; } const handler = function(e) { if (e.key === 'Escape') { closeMensaje(); document.removeEventListener('keydown', handler); } }; document.addEventListener('keydown', handler); } // Smooth scrolling for anchor links document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { const target = document.querySelector(this.getAttribute('href')); if (!target) return; e.preventDefault(); target.scrollIntoView({ behavior: 'smooth' }); }); }); // Ensure mobile hero video remains playing const mobileHeroVideo = document.querySelector('.hero-video-mobile'); if (mobileHeroVideo) { const ensureMobileVideoPlaying = () => { if (mobileHeroVideo.paused || mobileHeroVideo.readyState < 3) { mobileHeroVideo.play().catch(() => {}); } }; ['pause', 'stalled', 'waiting', 'ended'].forEach(eventName => { mobileHeroVideo.addEventListener(eventName, ensureMobileVideoPlaying); }); document.addEventListener('visibilitychange', () => { if (!document.hidden) { setTimeout(ensureMobileVideoPlaying, 120); } }); window.addEventListener('focus', () => setTimeout(ensureMobileVideoPlaying, 120)); window.addEventListener('touchstart', ensureMobileVideoPlaying, { passive: true }); ensureMobileVideoPlaying(); } // Utilidad: igualar alturas de tarjetas para que no haya scroll interno function equalizeFlipCards() { const cards = document.querySelectorAll('.flip-card'); cards.forEach(card => { const inner = card.querySelector('.flip-card-inner'); const front = card.querySelector('.flip-card-front'); const back = card.querySelector('.flip-card-back'); if (!inner || !front || !back) return; // reset front.style.height = 'auto'; back.style.height = 'auto'; inner.style.height = 'auto'; card.style.height = 'auto'; // compute const maxH = Math.max(front.scrollHeight, back.scrollHeight); front.style.height = maxH + 'px'; back.style.height = maxH + 'px'; inner.style.height = maxH + 'px'; card.style.height = maxH + 'px'; }); } // Flip Card Servicios Mejorado (listeners básicos) document.querySelectorAll('.services-grid .flip-card').forEach(card => { const btns = card.querySelectorAll('.flip-btn'); if (btns[0]) btns[0].addEventListener('click', () => { card.classList.add('flipped'); equalizeFlipCards(); }); if (btns[1]) btns[1].addEventListener('click', () => { card.classList.remove('flipped'); equalizeFlipCards(); }); }); window.addEventListener('resize', () => { equalizeFlipCards(); // Re-inicializar carrusel en cambios de ancho clearTimeout(window.__servicesCarouselResizeTO); window.__servicesCarouselResizeTO = setTimeout(() => { if (typeof initServiciosCarousel === 'function') initServiciosCarousel(); }, 200); }); // Lightbox para imágenes de socios const lightbox = document.getElementById('partner-lightbox'); const lightboxImg = document.getElementById('lightbox-img'); if (lightbox && lightbox.parentElement !== document.body) { document.body.appendChild(lightbox); } const openLightbox = (imgSrc) => { lightboxImg.src = imgSrc; lightbox.classList.add('active'); lightbox.dataset.scrollY = String(window.scrollY || document.documentElement.scrollTop || 0); document.body.classList.add('lightbox-open'); }; const closeLightbox = () => { lightbox.classList.remove('active'); lightboxImg.src = ''; document.body.classList.remove('lightbox-open'); const storedScroll = parseInt(lightbox.dataset.scrollY || '0', 10) || 0; delete lightbox.dataset.scrollY; window.scrollTo({ top: storedScroll, behavior: 'instant' in window ? 'instant' : 'auto' }); }; document.querySelectorAll('.lightbox-trigger').forEach(el => { el.addEventListener('click', function() { const imgSrc = this.getAttribute('data-img'); openLightbox(imgSrc); }); }); document.querySelector('.lightbox-close').addEventListener('click', closeLightbox); document.querySelector('.lightbox-backdrop').addEventListener('click', closeLightbox); document.addEventListener('keydown', function(e) { if (e.key === 'Escape') { closeLightbox(); } }); // Utilidad: Carrusel móvil auto-deslizante para servicios function initServiciosCarousel() { const grid = document.getElementById('services-dynamic'); if (!grid) return; // Limpieza previa si existe if (grid._carouselCleanup) { grid._carouselCleanup(); grid._carouselCleanup = null; } // Carrusel deshabilitado por preferencia: mostrar cards completas con espacio. // Si en el futuro quieres reactivarlo, descomenta la implementación previa. grid._carouselCleanup = () => {}; return; } // Las funciones renderServiciosHome y renderProyectosHome han sido reemplazadas por renderizado directo en PHP para mejor SEO y velocidad. // --- CLIENTES SATISFECHOS DINÁMICOS EN HOME --- function renderClientesSatisfechos() { const marquee = document.getElementById('clientes-marquee'); const track = document.getElementById('clientes-marquee-track'); if (!marquee || !track) return; fetchWithTimeout('clientes_satisfechos.php?action=list') .then(res => res.ok ? res.json() : Promise.reject(new Error('No se pudieron cargar los clientes'))) .then(clientes => { // Limpiar track.classList.remove('marquee-animate'); track.style.removeProperty('--marquee-duration'); track.innerHTML = ''; if (!Array.isArray(clientes) || !clientes.length) { marquee.innerHTML = '<div class="marquee-empty">Aún no hay clientes publicados.</div>'; return; } // Preparar fuentes de logos (con fallback seguro) e incluir video si existe const sources = clientes.map(c => ({ src: (c.logo && String(c.logo).trim()) ? c.logo : 'images/aircan.png', name: c.nombre || 'Cliente', video: (c.video_url && String(c.video_url).trim()) ? String(c.video_url).trim() : '' })); // Duplicar exactamente una vez para loop perfecto (0% -> -50%) for (let k = 0; k < 2; k++) { sources.forEach(item => { const el = document.createElement('div'); el.className = 'logo-item'; const imgHtml = `<img loading="lazy" src="${item.src}" alt="${item.name}">`; if (item.video) { const href = `video.html?vid=${encodeURIComponent(item.video)}&t=${encodeURIComponent(item.name)}`; el.innerHTML = `<a class=\"logo-link\" data-video=\"1\" href=\"${href}\" target=\"_blank\" rel=\"noopener\" title=\"Ver video de ${item.name}\" aria-label=\"Ver video de ${item.name}\">${imgHtml}<span class=\"play-badge\"><i class=\"fa-solid fa-play\"></i></span></a>`; } else { el.innerHTML = imgHtml; } track.appendChild(el); }); } // Esperar a que el DOM pinte para medir ancho y calcular duración requestAnimationFrame(() => { const total = track.scrollWidth; const half = total / 2; // porque duplicamos exactamente una vez const speedPxPerSec = 80; // Ajusta la velocidad (px/s) const duration = Math.max(half / speedPxPerSec, 20); // Mínimo 20s track.style.setProperty('--marquee-duration', `${duration}s`); // Forzar reflow antes de activar animación para evitar salto void track.offsetWidth; track.classList.add('marquee-animate'); }); }) .catch(() => { marquee.innerHTML = '<div class="marquee-empty">No se pudieron cargar los clientes.</div>'; }); } // Animaciones de aparición const styleFade = document.createElement('style'); styleFade.innerHTML = ` @keyframes fadeInUp { 0% { opacity: 0; transform: translateY(40px); } 100% { opacity: 1; transform: translateY(0); } } `; document.head.appendChild(styleFade); // Llamar al cargar la página // Inicializar componentes renderizados por PHP function initPHPRendered() { // Servicios const track = document.getElementById('services-track'); if (track) { const toggleServicesNav = (disabled) => { const prev = document.getElementById('services-prev'); const next = document.getElementById('services-next'); [prev, next].forEach(btn => { if (btn) btn.disabled = !!disabled; }); }; const syncServicesNav = () => { const prev = document.getElementById('services-prev'); const next = document.getElementById('services-next'); if (!track || !prev || !next) return; const maxScroll = track.scrollWidth - track.clientWidth - 4; const tolerance = 6; prev.disabled = track.scrollLeft <= tolerance; next.disabled = track.scrollLeft >= maxScroll - tolerance; }; const centerServicesScroll = (targetIndex) => { const cards = Array.from(track.querySelectorAll('.service-card')); if (!cards.length) return; const safeIndex = Math.max(0, Math.min(targetIndex, cards.length - 1)); const card = cards[safeIndex]; const trackRect = track.getBoundingClientRect(); const cardRect = card.getBoundingClientRect(); const offset = (cardRect.left + cardRect.right) / 2 - (trackRect.left + trackRect.right) / 2; track.scrollBy({ left: offset, behavior: 'smooth' }); setTimeout(syncServicesNav, 400); }; const attachServiciosCompra = () => { document.querySelectorAll('.btn-comprar-servicio').forEach(btn => { btn.addEventListener('click', function(e) { e.preventDefault(); e.stopPropagation(); mostrarModalCompraServicio(this.getAttribute('data-id'), this.getAttribute('data-nombre'), this.getAttribute('data-precio')); }); }); }; // Navegación const prev = document.getElementById('services-prev'); const next = document.getElementById('services-next'); if (prev && next) { const getCenteredIndex = () => { const cards = Array.from(track.querySelectorAll('.service-card')); if (!cards.length) return 0; const trackRect = track.getBoundingClientRect(); const centerX = (trackRect.left + trackRect.right) / 2; let closest = 0, bestDist = Infinity; cards.forEach((card, idx) => { const rect = card.getBoundingClientRect(); const cardCenter = (rect.left + rect.right) / 2; const dist = Math.abs(cardCenter - centerX); if (dist < bestDist) { bestDist = dist; closest = idx; } }); return closest; }; prev.addEventListener('click', () => centerServicesScroll(Math.max(0, getCenteredIndex() - 1))); next.addEventListener('click', () => centerServicesScroll(Math.min(track.querySelectorAll('.service-card').length - 1, getCenteredIndex() + 1))); } track.addEventListener('scroll', syncServicesNav); new ResizeObserver(() => { toggleServicesNav(track.scrollWidth <= track.clientWidth + 4); syncServicesNav(); }).observe(track); attachServiciosCompra(); syncServicesNav(); } // Proyectos const projectGrid = document.getElementById('projects-dynamic'); if (projectGrid) { projectGrid.querySelectorAll('.lightbox-trigger').forEach(el => { el.addEventListener('click', function() { openLightbox(this.getAttribute('data-img')); }); }); projectGrid.querySelectorAll('.btn-carrito').forEach(btn => { btn.addEventListener('click', function(e) { e.preventDefault(); e.stopPropagation(); mostrarModalCompra(this.getAttribute('data-id'), this.getAttribute('data-nombre')); }); }); projectGrid.querySelectorAll('.project-card').forEach(card => { const desc = card.querySelector('.project-desc'); const toggle = card.querySelector('.project-desc-more'); if (!desc || !toggle) return; const updateToggleVisibility = () => { const isOverflowing = desc.scrollHeight > desc.clientHeight + 6; toggle.hidden = !isOverflowing && !card.classList.contains('project-card-expanded'); }; requestAnimationFrame(updateToggleVisibility); window.addEventListener('resize', updateToggleVisibility); toggle.addEventListener('click', () => { const expanded = card.classList.toggle('project-card-expanded'); toggle.setAttribute('aria-expanded', expanded ? 'true' : 'false'); const label = toggle.querySelector('span'); if (label) { label.textContent = expanded ? 'Leer menos' : 'Leer más'; } requestAnimationFrame(updateToggleVisibility); if (typeof AOS !== 'undefined') { AOS.refreshHard(); } }); }); } if (typeof AOS !== 'undefined') AOS.refresh(); } initPHPRendered(); renderClientesSatisfechos(); // Copiar correo Paypal con toast flotante const copyPaypalBtn = document.getElementById('copy-paypal'); if (copyPaypalBtn) { copyPaypalBtn.addEventListener('click', function(e) { e.preventDefault(); const correoEl = document.getElementById('correo-paypal'); const toast = document.getElementById('toast-copiado'); const correo = correoEl ? correoEl.innerText : ''; if (!correo || !toast) return; navigator.clipboard.writeText(correo).then(() => { toast.classList.add('show'); toast.style.display = 'flex'; setTimeout(() => { toast.classList.remove('show'); toast.style.display = 'none'; }, 1500); }); }); } // Copiar cuentas Banpro con toast flotante (si existen) (function(){ const btnUsd = document.getElementById('copy-banpro-usd'); if (btnUsd) { btnUsd.addEventListener('click', function(e) { e.preventDefault(); const cuenta = document.getElementById('banpro-usd').innerText; navigator.clipboard.writeText(cuenta).then(() => { const toast = document.getElementById('toast-copiado'); toast.classList.add('show'); toast.querySelector('.toast-text').textContent = '¡Cuenta USD copiada!'; toast.style.display = 'flex'; setTimeout(() => { toast.classList.remove('show'); toast.style.display = 'none'; toast.querySelector('.toast-text').textContent = '¡copiado al portapapeles!'; }, 1500); }); }); } const btnNio = document.getElementById('copy-banpro-nio'); if (btnNio) { btnNio.addEventListener('click', function(e) { e.preventDefault(); const cuenta = document.getElementById('banpro-nio').innerText; navigator.clipboard.writeText(cuenta).then(() => { const toast = document.getElementById('toast-copiado'); toast.classList.add('show'); toast.querySelector('.toast-text').textContent = '¡Cuenta NIO copiada!'; toast.style.display = 'flex'; setTimeout(() => { toast.classList.remove('show'); toast.style.display = 'none'; toast.querySelector('.toast-text').textContent = '¡copiado al portapapeles!'; }, 1500); }); }); } })(); (function(){ const copyUalaBtn = document.getElementById('copy-uala'); if (copyUalaBtn) { copyUalaBtn.addEventListener('click', function(e) { e.preventDefault(); const cuenta = document.getElementById('uala-cuenta').innerText; navigator.clipboard.writeText(cuenta).then(() => { const toast = document.getElementById('toast-copiado'); toast.classList.add('show'); toast.querySelector('.toast-text').textContent = '¡Cuenta Ualá copiada!'; toast.style.display = 'flex'; setTimeout(() => { toast.classList.remove('show'); toast.style.display = 'none'; toast.querySelector('.toast-text').textContent = '¡copiado al portapapeles!'; }, 1500); }); }); } })(); // Copiar teléfono y correo en sección Contacto reutilizando el toast (function(){ const toast = document.getElementById('toast-copiado'); function showToast(msg){ if (!toast) return; const textEl = toast.querySelector('.toast-text'); const prev = textEl ? textEl.textContent : ''; if (textEl) textEl.textContent = msg || '¡copiado al portapapeles!'; toast.classList.add('show'); toast.style.display = 'flex'; setTimeout(() => { toast.classList.remove('show'); toast.style.display = 'none'; if (textEl) textEl.textContent = prev || '¡copiado al portapapeles!'; }, 1500); } const btnPhone = document.getElementById('copy-phone-main'); if (btnPhone) { btnPhone.addEventListener('click', function(){ const telEl = document.getElementById('telefono-principal'); const tel = telEl ? (telEl.innerText || telEl.textContent).trim() : ''; if (!tel) return; navigator.clipboard.writeText(tel).then(() => showToast('¡Teléfono copiado!')); }); } const btnWhatsappSplit = document.getElementById('btn-whatsapp-split'); const whatsappPicker = document.getElementById('whatsapp-picker'); if (btnWhatsappSplit && whatsappPicker) { const whatsappOptions = whatsappPicker.querySelectorAll('.whatsapp-option'); const messages = { 'CO': 'Hola Aircan, quiero asesoría desde Colombia 🇨🇴', 'VE': 'Hola Aircan, quiero asesoría desde Venezuela 🇻🇪' }; function closePicker(){ btnWhatsappSplit.setAttribute('aria-expanded', 'false'); whatsappPicker.classList.remove('visible'); } function openPicker(){ btnWhatsappSplit.setAttribute('aria-expanded', 'true'); whatsappPicker.classList.add('visible'); } btnWhatsappSplit.addEventListener('click', function(e){ e.stopPropagation(); const expanded = this.getAttribute('aria-expanded') === 'true'; if (expanded) { closePicker(); } else { openPicker(); } }); whatsappOptions.forEach(option => { option.addEventListener('click', function(){ const country = this.dataset.country; const number = this.dataset.number; if (!number) return; const message = messages[country] || 'Hola Aircan, me gustaría más información ✨'; const extraLine = '¿Podemos hablar ahora mismo?'; const url = `https://wa.me/${number}?text=${encodeURIComponent(`${message}\n\n${extraLine}`)}`; window.open(url, '_blank'); closePicker(); }); }); document.addEventListener('click', function(e){ if (!whatsappPicker.contains(e.target) && !btnWhatsappSplit.contains(e.target)) { closePicker(); } }); document.addEventListener('keydown', function(e){ if (e.key === 'Escape') { closePicker(); } }); } const btnEmail = document.getElementById('copy-email-main'); if (btnEmail) { btnEmail.addEventListener('click', function(){ const mailEl = document.getElementById('correo-principal'); const mail = mailEl ? (mailEl.innerText || mailEl.textContent).trim() : ''; if (!mail) return; navigator.clipboard.writeText(mail).then(() => showToast('¡Correo copiado!')); }); } const btnAddress = document.getElementById('copy-address-main'); if (btnAddress) { btnAddress.addEventListener('click', function(){ const dirEl = document.getElementById('direccion-principal'); const dir = dirEl ? (dirEl.innerText || dirEl.textContent).trim() : ''; if (!dir) return; navigator.clipboard.writeText(dir).then(() => showToast('¡Dirección copiada!')); }); } })(); // Modal comprobante de pago (con validaciones) const btnComprobante = document.getElementById('btn-comprobante'); const modalComprobante = document.getElementById('modal-comprobante'); const cerrarModalComprobante = document.getElementById('cerrar-modal-comprobante'); // Asegurar que el modal esté directamente bajo <body> para que position:fixed // no se vea afectado por transformaciones (p.ej. AOS) en ancestros if (modalComprobante && modalComprobante.parentElement !== document.body) { document.body.appendChild(modalComprobante); } if (btnComprobante && modalComprobante) { btnComprobante.addEventListener('click',()=>{ modalComprobante.style.display='flex'; // Bloquear scroll de fondo mientras el modal está abierto document.body.style.overflow = 'hidden'; }); } if (modalComprobante && cerrarModalComprobante) { cerrarModalComprobante.addEventListener('click',()=>{ modalComprobante.style.display='none'; document.body.style.overflow = ''; }); const overlay = modalComprobante.querySelector('div'); if (overlay) { overlay.addEventListener('click',function(e){ if(e.target===this){ modalComprobante.style.display='none'; document.body.style.overflow = ''; } }); } document.addEventListener('keydown',function(e){ if(e.key==='Escape'){ modalComprobante.style.display='none'; document.body.style.overflow = ''; } }); } // Enviar comprobante por WhatsApp document.getElementById('form-comprobante').addEventListener('submit',function(e){ e.preventDefault(); const nombre = document.getElementById('nombre-comprobante').value.trim(); const codigo = document.getElementById('codigo-comprobante').value.trim(); const detalle = document.getElementById('detalle-comprobante').value.trim(); let mensaje = `*Comprobante de Pago*%0A%0A*Nombre y Apellido:* ${nombre}%0A*Código de Comprobante:* ${codigo}`; if(detalle) mensaje += `%0A*Detalle:* ${detalle}`; mensaje += `%0A%0A*Por favor, verifique el comprobante de pago.*`; const url = `https://wa.me/573505849143?text=${mensaje}`; window.open(url,'_blank'); document.getElementById('mensaje-exito-comprobante').style.display='block'; setTimeout(()=>{ document.getElementById('mensaje-exito-comprobante').style.display='none'; modalComprobante.style.display='none'; document.getElementById('form-comprobante').reset(); },2200); }); // MODAL DE COMPRA function mostrarModalCompra(proyectoId, proyectoNombre) { let modal = document.getElementById('modal-compra-proyecto'); if (!modal) { modal = document.createElement('div'); modal.id = 'modal-compra-proyecto'; modal.style.position = 'fixed'; modal.style.top = '0'; modal.style.left = '0'; modal.style.width = '100vw'; modal.style.height = '100vh'; modal.style.background = 'rgba(0,0,0,0.92)'; modal.style.zIndex = '99999'; modal.style.display = 'flex'; modal.style.alignItems = 'center'; modal.style.justifyContent = 'center'; modal.innerHTML = ` <div style="background:linear-gradient(160deg, rgba(15,20,35,0.98) 0%, rgba(8,12,22,0.95) 100%);border-radius:18px;box-shadow:0 18px 60px rgba(0,0,0,0.75), 0 0 0 1px rgba(192,197,206,0.18), inset 0 1px 0 rgba(255,255,255,0.08);padding:32px 26px 26px 26px;width:100%;max-width:360px;display:flex;flex-direction:column;align-items:center;animation:modal-zoom 0.35s cubic-bezier(0.23, 1, 0.32, 1);border:1px solid rgba(192,197,206,0.22);backdrop-filter:blur(18px);position:relative;"> <button id="cerrar-modal-compra-proyecto" style="position:absolute;top:12px;right:12px;width:32px;height:32px;border-radius:50%;font-size:1.2rem;color:rgba(255,255,255,0.6);background:rgba(255,255,255,0.05);border:1px solid rgba(255,255,255,0.1);cursor:pointer;font-weight:400;transition:all 0.3s;z-index:3;display:flex;align-items:center;justify-content:center;" onmouseover="this.style.background='rgba(255,255,255,0.1)';this.style.color='rgba(255,255,255,0.9)';this.style.transform='rotate(90deg)'" onmouseout="this.style.background='rgba(255,255,255,0.05)';this.style.color='rgba(255,255,255,0.6)';this.style.transform='rotate(0deg)'">×</button> <div style="width:54px;height:54px;border-radius:50%;background:linear-gradient(135deg, rgba(192,197,206,0.2), rgba(192,197,206,0.1));display:flex;align-items:center;justify-content:center;margin-bottom:16px;box-shadow:0 6px 18px rgba(192,197,206,0.14), inset 0 1px 0 rgba(255,255,255,0.1);border:1px solid rgba(192,197,206,0.28);"> <i class="fas fa-shopping-cart" style="font-size:1.6rem;color:#c0c5ce;"></i> </div> <div style="font-weight:900;font-size:1.3rem;margin-bottom:4px;color:#ffffff;text-align:center;letter-spacing:0.4px;">Comprar Proyecto</div> <div style="font-size:1rem;margin-bottom:6px;color:#c0c5ce;text-align:center;font-weight:700;" id="modal-proyecto-nombre">${proyectoNombre}</div> <div style="font-size:0.85rem;margin-bottom:20px;color:rgba(192,197,206,0.6);text-align:center;max-width:92%;">Completa tus datos para finalizar la compra</div> <form id="form-compra-proyecto" style="width:100%;display:flex;flex-direction:column;gap:16px;"> <div style="display:flex;flex-direction:column;align-items:flex-start;width:100%;"> <label for="nombre-compra-proyecto" style="font-weight:700;font-size:0.9rem;color:rgba(192,197,206,0.9);margin-bottom:8px;letter-spacing:0.3px;">NOMBRE COMPLETO</label> <input type="text" id="nombre-compra-proyecto" name="nombre" required style="width:100%;padding:12px 14px;border-radius:10px;border:1px solid rgba(192,197,206,0.18);background:rgba(255,255,255,0.03);font-size:0.95rem;color:#ffffff;transition:all 0.3s;box-shadow:inset 0 2px 4px rgba(0,0,0,0.18);" onfocus="this.style.borderColor='rgba(192,197,206,0.48)';this.style.boxShadow='0 0 0 2px rgba(192,197,206,0.1), inset 0 2px 4px rgba(0,0,0,0.2)'" onblur="this.style.borderColor='rgba(192,197,206,0.18)';this.style.boxShadow='inset 0 2px 4px rgba(0,0,0,0.18)'"> </div> <div style="display:flex;flex-direction:column;align-items:flex-start;width:100%;"> <label for="telefono-compra-proyecto" style="font-weight:700;font-size:0.9rem;color:rgba(192,197,206,0.9);margin-bottom:8px;letter-spacing:0.3px;">TELÉFONO</label> <input type="tel" id="telefono-compra-proyecto" name="telefono" required style="width:100%;padding:12px 14px;border-radius:10px;border:1px solid rgba(192,197,206,0.18);background:rgba(255,255,255,0.03);font-size:0.95rem;color:#ffffff;transition:all 0.3s;box-shadow:inset 0 2px 4px rgba(0,0,0,0.18);" onfocus="this.style.borderColor='rgba(192,197,206,0.48)';this.style.boxShadow='0 0 0 2px rgba(192,197,206,0.1), inset 0 2px 4px rgba(0,0,0,0.2)'" onblur="this.style.borderColor='rgba(192,197,206,0.18)';this.style.boxShadow='inset 0 2px 4px rgba(0,0,0,0.18)'"> </div> <div style="display:flex;flex-direction:column;align-items:flex-start;width:100%;"> <label for="direccion-compra-proyecto" style="font-weight:700;font-size:0.9rem;color:rgba(192,197,206,0.9);margin-bottom:8px;letter-spacing:0.3px;">DIRECCIÓN</label> <input type="text" id="direccion-compra-proyecto" name="direccion" required style="width:100%;padding:12px 14px;border-radius:10px;border:1px solid rgba(192,197,206,0.18);background:rgba(255,255,255,0.03);font-size:0.95rem;color:#ffffff;transition:all 0.3s;box-shadow:inset 0 2px 4px rgba(0,0,0,0.18);" onfocus="this.style.borderColor='rgba(192,197,206,0.48)';this.style.boxShadow='0 0 0 2px rgba(192,197,206,0.1), inset 0 2px 4px rgba(0,0,0,0.2)'" onblur="this.style.borderColor='rgba(192,197,206,0.18)';this.style.boxShadow='inset 0 2px 4px rgba(0,0,0,0.18)'"> </div> <div style="display:flex;flex-direction:column;align-items:flex-start;width:100%;"> <label for="descripcion-compra-proyecto" style="font-weight:700;font-size:0.9rem;color:rgba(192,197,206,0.9);margin-bottom:8px;letter-spacing:0.3px;">DESCRIPCIÓN</label> <textarea id="descripcion-compra-proyecto" name="descripcion" required style="width:100%;padding:12px 14px;border-radius:10px;border:1px solid rgba(192,197,206,0.18);background:rgba(255,255,255,0.03);font-size:0.95rem;color:#ffffff;transition:all 0.3s;box-shadow:inset 0 2px 4px rgba(0,0,0,0.18);min-height:88px;resize:vertical;font-family:inherit;" onfocus="this.style.borderColor='rgba(192,197,206,0.48)';this.style.boxShadow='0 0 0 2px rgba(192,197,206,0.1), inset 0 2px 4px rgba(0,0,0,0.2)'" onblur="this.style.borderColor='rgba(192,197,206,0.18)';this.style.boxShadow='inset 0 2px 4px rgba(0,0,0,0.18)'"></textarea> </div> <button type="submit" style="background:linear-gradient(135deg, #c0c5ce 0%, #e8eaed 100%);color:#000000;font-weight:800;font-size:1rem;padding:13px 0;border:none;border-radius:10px;box-shadow:0 6px 20px rgba(192,197,206,0.22), inset 0 1px 0 rgba(255,255,255,0.55);cursor:pointer;transition:all 0.3s;letter-spacing:0.6px;margin-top:4px;display:flex;align-items:center;justify-content:center;gap:10px;border:1px solid rgba(192,197,206,0.35);position:relative;overflow:hidden;" onmouseover="this.style.transform='translateY(-2px)';this.style.boxShadow='0 10px 26px rgba(192,197,206,0.32), inset 0 1px 0 rgba(255,255,255,0.8)'" onmouseout="this.style.transform='translateY(0)';this.style.boxShadow='0 6px 20px rgba(192,197,206,0.22), inset 0 1px 0 rgba(255,255,255,0.55)'"> <i class="fas fa-shopping-cart" style="font-size:1.2rem;"></i> CONFIRMAR COMPRA </button> </form> <div id="mensaje-exito-compra-proyecto" style="display:none;margin-top:24px;padding:16px 24px;background:rgba(192,197,206,0.1);border:1px solid rgba(192,197,206,0.3);border-radius:12px;color:#c0c5ce;font-weight:700;font-size:1rem;text-align:center;box-shadow:0 4px 12px rgba(192,197,206,0.15);"><i class="fas fa-check-circle" style="font-size:1.3rem;margin-right:8px;"></i>¡Compra registrada!</div> </div> `; document.body.appendChild(modal); } else { const nameEl = modal.querySelector('#modal-proyecto-nombre'); if (nameEl) nameEl.textContent = proyectoNombre; const formReset = modal.querySelector('#form-compra-proyecto'); if (formReset) formReset.reset(); } modal.style.display = 'flex'; document.body.style.overflow = 'hidden'; // Cerrar modal modal.querySelector('#cerrar-modal-compra-proyecto').onclick = function() { modal.style.display = 'none'; document.body.style.overflow = ''; }; modal.addEventListener('click', function(e){ if(e.target===modal){ modal.style.display='none'; document.body.style.overflow = ''; } }); document.addEventListener('keydown', function handler(e){ if(e.key==='Escape'){ modal.style.display='none'; document.body.style.overflow = ''; document.removeEventListener('keydown', handler); } }); // Enviar compra const form = modal.querySelector('#form-compra-proyecto'); form.onsubmit = function(e){ e.preventDefault(); const nombre = document.getElementById('nombre-compra-proyecto').value.trim(); const telefono = document.getElementById('telefono-compra-proyecto').value.trim(); const direccion = document.getElementById('direccion-compra-proyecto').value.trim(); const descripcion = document.getElementById('descripcion-compra-proyecto').value.trim(); if(!nombre||!telefono||!direccion||!descripcion)return; const fd = new FormData(); fd.append('nombre',nombre); fd.append('telefono',telefono); fd.append('direccion',direccion); fd.append('descripcion',descripcion); fd.append('proyecto_id',proyectoId); fetch('proyectos.php?action=comprar',{ method:'POST', body:fd }) .then(res=>res.json()) .then(data=>{ if(data.success){ form.style.display='none'; modal.querySelector('#mensaje-exito-compra-proyecto').style.display='block'; setTimeout(()=>{ modal.style.display='none'; document.body.style.overflow = ''; form.style.display='flex'; modal.querySelector('#mensaje-exito-compra-proyecto').style.display='none'; form.reset(); },1800); }else{ alert('Error al registrar la compra: '+(data.error||'')); } }); }; } // MODAL DE COMPRA DE SERVICIOS function mostrarModalCompraServicio(servicioId, servicioNombre, servicioPrecio) { let modal = document.getElementById('modal-compra-servicio'); if (!modal) { modal = document.createElement('div'); modal.id = 'modal-compra-servicio'; modal.style.position = 'fixed'; modal.style.top = '0'; modal.style.left = '0'; modal.style.width = '100vw'; modal.style.height = '100vh'; modal.style.background = 'rgba(0,0,0,0.92)'; modal.style.zIndex = '99999'; modal.style.display = 'flex'; modal.style.alignItems = 'center'; modal.style.justifyContent = 'center'; modal.innerHTML = ` <div style="background:linear-gradient(160deg, rgba(15,20,35,0.98) 0%, rgba(8,12,22,0.95) 100%);border-radius:24px;box-shadow:0 24px 80px rgba(0,0,0,0.8), 0 0 0 1px rgba(0,229,255,0.25), inset 0 1px 0 rgba(255,255,255,0.1);padding:48px 36px 36px 36px;max-width:96vw;width:100%;max-width:480px;display:flex;flex-direction:column;align-items:center;animation:modal-zoom 0.4s cubic-bezier(0.23, 1, 0.32, 1);border:1px solid rgba(0,229,255,0.3);backdrop-filter:blur(20px);position:relative;"> <button id="cerrar-modal-compra-servicio" style="position:absolute;top:16px;right:16px;width:36px;height:36px;border-radius:50%;font-size:1.4rem;color:rgba(255,255,255,0.6);background:rgba(255,255,255,0.05);border:1px solid rgba(255,255,255,0.1);cursor:pointer;font-weight:400;transition:all 0.3s;z-index:3;display:flex;align-items:center;justify-content:center;" onmouseover="this.style.background='rgba(255,255,255,0.1)';this.style.color='rgba(255,255,255,0.9)';this.style.transform='rotate(90deg)'" onmouseout="this.style.background='rgba(255,255,255,0.05)';this.style.color='rgba(255,255,255,0.6)';this.style.transform='rotate(0deg)'">×</button> <div style="width:64px;height:64px;border-radius:50%;background:linear-gradient(135deg, rgba(0,229,255,0.2), rgba(52,152,219,0.15));display:flex;align-items:center;justify-content:center;margin-bottom:20px;box-shadow:0 8px 24px rgba(0,229,255,0.2), inset 0 1px 0 rgba(255,255,255,0.1);border:1px solid rgba(0,229,255,0.35);"> <i class="fas fa-briefcase" style="font-size:2rem;color:#00e5ff;"></i> </div> <div style="font-weight:900;font-size:1.5rem;margin-bottom:4px;color:#ffffff;text-align:center;letter-spacing:0.5px;">Comprar Servicio</div> <div style="font-size:1.1rem;margin-bottom:6px;color:#00e5ff;text-align:center;font-weight:700;" id="modal-servicio-nombre">${servicioNombre}</div> <!-- <div style="font-size:1.15rem;font-weight:900;margin-bottom:24px;color:#7dffb3;text-align:center;padding:8px 20px;background:rgba(125,255,179,0.1);border-radius:12px;border:1px solid rgba(125,255,179,0.2);">$<span id="modal-servicio-precio">${parseFloat(servicioPrecio).toLocaleString('es-ES')}</span></div> --> <form id="form-compra-servicio" style="width:100%;display:flex;flex-direction:column;gap:20px;"> <div style="display:flex;flex-direction:column;align-items:flex-start;width:100%;"> <label for="nombre-compra-servicio" style="font-weight:700;font-size:0.9rem;color:rgba(192,197,206,0.9);margin-bottom:8px;letter-spacing:0.3px;">NOMBRE COMPLETO</label> <input type="text" id="nombre-compra-servicio" name="nombre" required style="width:100%;padding:14px 16px;border-radius:12px;border:1px solid rgba(192,197,206,0.2);background:rgba(255,255,255,0.03);font-size:1rem;color:#ffffff;transition:all 0.3s;box-shadow:inset 0 2px 4px rgba(0,0,0,0.2);" onfocus="this.style.borderColor='rgba(0,229,255,0.5)';this.style.boxShadow='0 0 0 3px rgba(0,229,255,0.1), inset 0 2px 4px rgba(0,0,0,0.2)'" onblur="this.style.borderColor='rgba(192,197,206,0.2)';this.style.boxShadow='inset 0 2px 4px rgba(0,0,0,0.2)'"> </div> <div style="display:flex;flex-direction:column;align-items:flex-start;width:100%;"> <label for="telefono-compra-servicio" style="font-weight:700;font-size:0.9rem;color:rgba(192,197,206,0.9);margin-bottom:8px;letter-spacing:0.3px;">TELÉFONO</label> <input type="tel" id="telefono-compra-servicio" name="telefono" required style="width:100%;padding:14px 16px;border-radius:12px;border:1px solid rgba(192,197,206,0.2);background:rgba(255,255,255,0.03);font-size:1rem;color:#ffffff;transition:all 0.3s;box-shadow:inset 0 2px 4px rgba(0,0,0,0.2);" onfocus="this.style.borderColor='rgba(0,229,255,0.5)';this.style.boxShadow='0 0 0 3px rgba(0,229,255,0.1), inset 0 2px 4px rgba(0,0,0,0.2)'" onblur="this.style.borderColor='rgba(192,197,206,0.2)';this.style.boxShadow='inset 0 2px 4px rgba(0,0,0,0.2)'"> </div> <div style="display:flex;flex-direction:column;align-items:flex-start;width:100%;"> <label for="descripcion-compra-servicio" style="font-weight:700;font-size:0.9rem;color:rgba(192,197,206,0.9);margin-bottom:8px;letter-spacing:0.3px;">DESCRIPCIÓN</label> <textarea id="descripcion-compra-servicio" name="descripcion" required style="width:100%;padding:14px 16px;border-radius:12px;border:1px solid rgba(192,197,206,0.2);background:rgba(255,255,255,0.03);font-size:1rem;color:#ffffff;transition:all 0.3s;box-shadow:inset 0 2px 4px rgba(0,0,0,0.2);min-height:100px;resize:vertical;font-family:inherit;" onfocus="this.style.borderColor='rgba(0,229,255,0.5)';this.style.boxShadow='0 0 0 3px rgba(0,229,255,0.1), inset 0 2px 4px rgba(0,0,0,0.2)'" onblur="this.style.borderColor='rgba(192,197,206,0.2)';this.style.boxShadow='inset 0 2px 4px rgba(0,0,0,0.2)'"></textarea> </div> <button type="submit" style="background:linear-gradient(135deg, #00e5ff 0%, #0099ff 100%);color:#000000;font-weight:900;font-size:1.1rem;padding:16px 0;border:none;border-radius:12px;box-shadow:0 8px 24px rgba(0,229,255,0.35), inset 0 1px 0 rgba(255,255,255,0.5);cursor:pointer;transition:all 0.3s;letter-spacing:0.8px;margin-top:8px;display:flex;align-items:center;justify-content:center;gap:12px;border:1px solid rgba(0,229,255,0.4);position:relative;overflow:hidden;" onmouseover="this.style.transform='translateY(-2px)';this.style.boxShadow='0 12px 32px rgba(0,229,255,0.5), inset 0 1px 0 rgba(255,255,255,0.7)'" onmouseout="this.style.transform='translateY(0)';this.style.boxShadow='0 8px 24px rgba(0,229,255,0.35), inset 0 1px 0 rgba(255,255,255,0.5)'"> <i class="fas fa-briefcase" style="font-size:1.2rem;"></i> CONFIRMAR COMPRA </button> </form> <div id="mensaje-exito-compra-servicio" style="display:none;margin-top:24px;padding:16px 24px;background:rgba(0,229,255,0.1);border:1px solid rgba(0,229,255,0.3);border-radius:12px;color:#00e5ff;font-weight:700;font-size:1rem;text-align:center;box-shadow:0 4px 12px rgba(0,229,255,0.15);"><i class="fas fa-check-circle" style="font-size:1.3rem;margin-right:8px;"></i>¡Compra registrada!</div> </div> `; document.body.appendChild(modal); } else { const nameEl = modal.querySelector('#modal-servicio-nombre'); if (nameEl) nameEl.textContent = servicioNombre; // const priceEl = modal.querySelector('#modal-servicio-precio'); // if (priceEl) priceEl.textContent = parseFloat(servicioPrecio).toLocaleString('es-ES'); const formReset = modal.querySelector('#form-compra-servicio'); if (formReset) formReset.reset(); } modal.style.display = 'flex'; document.body.style.overflow = 'hidden'; // Cerrar modal modal.querySelector('#cerrar-modal-compra-servicio').onclick = function() { modal.style.display = 'none'; document.body.style.overflow = ''; }; modal.addEventListener('click', function(e){ if(e.target===modal){ modal.style.display='none'; document.body.style.overflow = ''; } }); document.addEventListener('keydown', function handler(e){ if(e.key==='Escape'){ modal.style.display='none'; document.body.style.overflow = ''; document.removeEventListener('keydown', handler); } }); // Enviar compra const form = modal.querySelector('#form-compra-servicio'); form.onsubmit = function(e){ e.preventDefault(); const nombre = document.getElementById('nombre-compra-servicio').value.trim(); const telefono = document.getElementById('telefono-compra-servicio').value.trim(); const descripcion = document.getElementById('descripcion-compra-servicio').value.trim(); if(!nombre||!telefono||!descripcion)return; const fd = new FormData(); fd.append('nombre',nombre); fd.append('telefono',telefono); fd.append('descripcion',descripcion); fd.append('servicio_id',servicioId); fd.append('precio',servicioPrecio); fetch('servicios.php?action=comprar',{ method:'POST', body:fd }) .then(res=>res.json()) .then(data=>{ if(data.success){ form.style.display='none'; modal.querySelector('#mensaje-exito-compra-servicio').style.display='block'; setTimeout(()=>{ modal.style.display='none'; document.body.style.overflow = ''; form.style.display='flex'; modal.querySelector('#mensaje-exito-compra-servicio').style.display='none'; form.reset(); },1800); }else{ alert('Error al registrar la compra: '+(data.error||'')); } }); }; } </script> <script src="https://unpkg.com/three@0.160.0/build/three.min.js"></script> <script> (function(){ const hero = document.querySelector('.hero'); const canvas = document.querySelector('.hero-glow-canvas'); if (!hero || !canvas || typeof THREE === 'undefined') return; const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)'); const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true, powerPreference: 'high-performance' }); renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 1.8)); const scene = new THREE.Scene(); const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1); const uniforms = { u_time: { value: 0 }, u_resolution: { value: new THREE.Vector2(1, 1) }, u_mouse: { value: new THREE.Vector2(0.72, 0.42) } }; const material = new THREE.ShaderMaterial({ uniforms, vertexShader: ` varying vec2 vUv; void main() { vUv = uv; gl_Position = vec4(position, 1.0); } `, fragmentShader: ` precision highp float; uniform float u_time; uniform vec2 u_resolution; uniform vec2 u_mouse; varying vec2 vUv; float hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123); } float noise(vec2 p) { vec2 i = floor(p); vec2 f = fract(p); vec2 u = f * f * (3.0 - 2.0 * f); return mix( mix(hash(i + vec2(0.0, 0.0)), hash(i + vec2(1.0, 0.0)), u.x), mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), u.x), u.y ); } float fbm(vec2 p) { float value = 0.0; float amplitude = 0.5; mat2 rot = mat2(1.6, 1.2, -1.2, 1.6); for (int i = 0; i < 5; i++) { value += amplitude * noise(p); p = rot * p + vec2(0.17); amplitude *= 0.5; } return value; } void main() { vec2 uv = vUv; vec2 p = (uv - 0.5) * vec2(u_resolution.x / u_resolution.y, 1.0) * 1.38; vec2 mouse = (u_mouse - 0.5) * vec2(u_resolution.x / u_resolution.y, 1.0) * 1.38; float t = u_time * 0.045; float base = fbm(p * 1.8 + vec2(t * 0.9, -t * 0.35)); float drift = fbm((p + base * 0.45) * 2.6 + vec2(-t * 0.55, t * 0.28)); float wisps = fbm((p - drift * 0.22) * 4.1 + vec2(t * 0.18, t * 0.4)); float softNoise = fbm(p * 6.4 - drift * 0.3 + vec2(-t * 0.22, t * 0.16)); float smokeField = smoothstep(0.22, 0.88, mix(base, drift, 0.58)); float wispField = smoothstep(0.42, 0.96, wisps); float haze = smoothstep(0.18, 0.92, softNoise) * 0.36; vec3 col = vec3(0.002, 0.004, 0.012); vec3 blue = vec3(0.08, 0.18, 0.48); vec3 violet = vec3(0.18, 0.10, 0.42); vec3 mist = vec3(0.36, 0.44, 0.78); col += blue * smokeField * 0.34; col += violet * smokeField * 0.28; col += mist * wispField * 0.16; col += vec3(0.05, 0.07, 0.14) * haze; float coreGlow = exp(-3.6 * length(p - vec2(0.12, -0.02))) * 0.18; float sideGlow = exp(-4.4 * length(p - vec2(-0.52, 0.16))) * 0.1; float mouseBloom = exp(-11.0 * length(p - mouse)) * 0.18; col += vec3(0.16, 0.24, 0.62) * coreGlow; col += vec3(0.22, 0.14, 0.46) * sideGlow; col += vec3(0.34, 0.46, 0.9) * mouseBloom; float vignette = smoothstep(1.45, 0.28, length(p)); col *= vignette; col = pow(col, vec3(1.08)); gl_FragColor = vec4(col, 1.0); } ` }); const mesh = new THREE.Mesh(new THREE.PlaneGeometry(2, 2), material); scene.add(mesh); const pointer = { current: new THREE.Vector2(0.72, 0.42), target: new THREE.Vector2(0.72, 0.42) }; let pulseTimeout = null; let trailTimeout = null; const updatePointerVars = (x, y) => { hero.style.setProperty('--pointer-x', `${(x * 100).toFixed(2)}%`); hero.style.setProperty('--pointer-y', `${(y * 100).toFixed(2)}%`); }; const updateTrailVars = (x, y) => { hero.style.setProperty('--trail-x', `${(x * 100).toFixed(2)}%`); hero.style.setProperty('--trail-y', `${(y * 100).toFixed(2)}%`); }; const triggerPointerPulse = () => { hero.style.setProperty('--pointer-pulse', '1.12'); hero.style.setProperty('--pointer-opacity', '0.82'); if (pulseTimeout) { window.clearTimeout(pulseTimeout); } pulseTimeout = window.setTimeout(() => { hero.style.setProperty('--pointer-pulse', '1'); hero.style.setProperty('--pointer-opacity', '0.58'); }, 320); }; const triggerTrailPulse = (x, y) => { updateTrailVars(x, y); hero.style.setProperty('--trail-opacity', '0.7'); hero.style.setProperty('--trail-scale', '1'); if (trailTimeout) { window.clearTimeout(trailTimeout); } trailTimeout = window.setTimeout(() => { hero.style.setProperty('--trail-opacity', '0'); hero.style.setProperty('--trail-scale', '1.34'); }, 30); }; const handlePointerMove = (event) => { const rect = hero.getBoundingClientRect(); const x = (event.clientX - rect.left) / rect.width; const y = (event.clientY - rect.top) / rect.height; pointer.target.set(Math.min(Math.max(x, 0.0), 1.0), Math.min(Math.max(y, 0.0), 1.0)); updatePointerVars(pointer.target.x, pointer.target.y); }; const handlePointerDown = (event) => { const rect = hero.getBoundingClientRect(); const point = event.touches && event.touches[0] ? event.touches[0] : event; const x = (point.clientX - rect.left) / rect.width; const y = (point.clientY - rect.top) / rect.height; pointer.target.set(Math.min(Math.max(x, 0.0), 1.0), Math.min(Math.max(y, 0.0), 1.0)); updatePointerVars(pointer.target.x, pointer.target.y); triggerPointerPulse(); triggerTrailPulse(pointer.target.x, pointer.target.y); }; const handlePointerLeave = () => { pointer.target.set(0.72, 0.42); updatePointerVars(pointer.target.x, pointer.target.y); hero.style.setProperty('--pointer-pulse', '1'); hero.style.setProperty('--pointer-opacity', '0.58'); }; const resize = () => { const bounds = hero.getBoundingClientRect(); const width = Math.max(1, Math.floor(bounds.width)); const height = Math.max(1, Math.floor(bounds.height)); renderer.setSize(width, height, false); uniforms.u_resolution.value.set(width, height); }; let visible = true; const observer = new IntersectionObserver((entries) => { entries.forEach((entry) => { visible = entry.isIntersecting; }); }, { threshold: 0.08 }); observer.observe(hero); hero.addEventListener('pointermove', handlePointerMove); if (window.PointerEvent) { hero.addEventListener('pointerdown', handlePointerDown); } else { hero.addEventListener('touchstart', handlePointerDown, { passive: true }); hero.addEventListener('mousedown', handlePointerDown); } hero.addEventListener('pointerleave', handlePointerLeave); window.addEventListener('resize', resize); if (typeof prefersReducedMotion.addEventListener === 'function') { prefersReducedMotion.addEventListener('change', resize); } else if (typeof prefersReducedMotion.addListener === 'function') { prefersReducedMotion.addListener(resize); } resize(); updatePointerVars(pointer.current.x, pointer.current.y); updateTrailVars(pointer.current.x, pointer.current.y); hero.style.setProperty('--pointer-pulse', '1'); hero.style.setProperty('--pointer-opacity', '0.58'); hero.style.setProperty('--trail-opacity', '0'); hero.style.setProperty('--trail-scale', '0.72'); const clock = new THREE.Clock(); const render = () => { requestAnimationFrame(render); if (!visible) return; const delta = clock.getDelta(); if (!prefersReducedMotion.matches) { uniforms.u_time.value += delta; } pointer.current.lerp(pointer.target, prefersReducedMotion.matches ? 0.1 : 0.045); uniforms.u_mouse.value.copy(pointer.current); renderer.render(scene, camera); }; render(); })(); </script> <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script> <script> AOS.init({ duration: 900, // Duración de la animación once: true, // Animar solo una vez easing: 'ease-in-out', // Curva de aceleración offset: 100, // Desfase para disparar la animación }); </script> <!-- PWA: Service Worker + Install Prompt handling --> <script> (function(){ const navItem = document.getElementById('install-nav-item'); const mobileBtn = document.getElementById('install-btn-mobile'); const desktopBtn = document.getElementById('install-btn-desktop'); let deferredPrompt = null; function isStandalone(){ return window.matchMedia('(display-mode: standalone)').matches || window.navigator.standalone === true; } function syncButtonsVisibility(){ const installed = isStandalone(); const mobile = window.innerWidth <= 992; const available = !!deferredPrompt && !installed; if (navItem) navItem.style.display = (available && mobile) ? 'block' : 'none'; if (desktopBtn) desktopBtn.style.display = (available && !mobile) ? 'inline-flex' : 'none'; } window.addEventListener('beforeinstallprompt', (e) => { e.preventDefault(); deferredPrompt = e; syncButtonsVisibility(); }); window.addEventListener('appinstalled', () => { deferredPrompt = null; if (navItem) navItem.style.display = 'none'; if (desktopBtn) desktopBtn.style.display = 'none'; }); if (mobileBtn) mobileBtn.addEventListener('click', async () => { if (!deferredPrompt) return; deferredPrompt.prompt(); try { await deferredPrompt.userChoice; } catch(_) {} deferredPrompt = null; syncButtonsVisibility(); }); if (desktopBtn) desktopBtn.addEventListener('click', async () => { if (!deferredPrompt) return; deferredPrompt.prompt(); try { await deferredPrompt.userChoice; } catch(_) {} deferredPrompt = null; syncButtonsVisibility(); }); window.addEventListener('resize', syncButtonsVisibility); // SW register if ('serviceWorker' in navigator) { window.addEventListener('load', function(){ navigator.serviceWorker.register('service-worker.js').catch(function(){}); }); } document.addEventListener('DOMContentLoaded', function(){ if (isStandalone()) { if (navItem) navItem.style.display = 'none'; if (desktopBtn) desktopBtn.style.display = 'none'; } else { setTimeout(syncButtonsVisibility, 200); } }); })(); </script> <!-- AIRCAN 2026 Login Modal --> <div class="ac-modal-overlay" id="aircanLoginOverlay"> <div class="ac-modal"> <button class="ac-modal-close" onclick="closeAircanLogin()"><i class="fas fa-times"></i></button> <div class="ac-modal-header"> <h3>AIRCAN</h3> <p>Ingresa a tu portal inteligente</p> </div> <div class="ac-error" id="aircanLoginError"></div> <form id="aircanLoginForm" onsubmit="submitAircanLogin(event)"> <div class="ac-input-group"> <label>CORREO ELECTRÓNICO</label> <div class="ac-input-wrapper"> <i class="fas fa-envelope"></i> <input type="email" id="aircanEmail" class="ac-input" placeholder="admin@gmail.com" required> </div> </div> <div class="ac-input-group"> <label>CONTRASEÑA</label> <div class="ac-input-wrapper"> <i class="fas fa-lock"></i> <input type="password" id="aircanPassword" class="ac-input" placeholder="••••••••" required> </div> </div> <button type="submit" class="ac-btn" id="aircanSubmitBtn"> <span id="aircanBtnText">ACCEDER AL SISTEMA</span> <div class="ac-loader" id="aircanBtnLoader"></div> </button> </form> </div> </div> <script> function openAircanLogin(e) { e.preventDefault(); document.getElementById('aircanLoginOverlay').classList.add('active'); setTimeout(() => document.getElementById('aircanEmail').focus(), 100); } function closeAircanLogin() { document.getElementById('aircanLoginOverlay').classList.remove('active'); document.getElementById('aircanLoginForm').reset(); document.getElementById('aircanLoginError').style.display = 'none'; } // Close on esc or outside click document.addEventListener('keydown', (e) => { if (e.key === 'Escape') closeAircanLogin(); }); document.getElementById('aircanLoginOverlay').addEventListener('mousedown', (e) => { if (e.target === document.getElementById('aircanLoginOverlay')) closeAircanLogin(); }); async function submitAircanLogin(e) { e.preventDefault(); const btnText = document.getElementById('aircanBtnText'); const btnLoader = document.getElementById('aircanBtnLoader'); const errorDiv = document.getElementById('aircanLoginError'); errorDiv.style.display = 'none'; btnText.style.display = 'none'; btnLoader.style.display = 'block'; const formData = new URLSearchParams(); formData.append('email', document.getElementById('aircanEmail').value); formData.append('password', document.getElementById('aircanPassword').value); try { // Ensure the path is correct dynamically based on location const loginPath = window.location.origin + '/aircan/public/auth/authenticate'; const response = await fetch(loginPath, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest' }, body: formData }); const data = await response.json(); if (data.success) { btnText.style.display = 'block'; btnLoader.style.display = 'none'; btnText.innerText = '¡BIENVENIDO!'; setTimeout(() => window.location.href = data.redirect, 500); } else { errorDiv.innerText = data.message; errorDiv.style.display = 'block'; btnText.style.display = 'block'; btnLoader.style.display = 'none'; } } catch (err) { errorDiv.innerText = 'Error de conexión. Intente nuevamente.'; errorDiv.style.display = 'block'; btnText.style.display = 'block'; btnLoader.style.display = 'none'; } } </script> </body> </html>
Coded With 💗 by
0x6ick